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:
parent
1aac546185
commit
5341bbad3a
|
@ -59,6 +59,8 @@ namespace Core
|
||||||
// Get core parameters kill use SConfig instead
|
// Get core parameters kill use SConfig instead
|
||||||
extern SCoreStartupParameter g_CoreStartupParameter;
|
extern SCoreStartupParameter g_CoreStartupParameter;
|
||||||
|
|
||||||
|
void Callback_WiimoteInterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size);
|
||||||
|
|
||||||
void* GetWindowHandle();
|
void* GetWindowHandle();
|
||||||
#if defined HAVE_X11 && HAVE_X11
|
#if defined HAVE_X11 && HAVE_X11
|
||||||
void* GetXWindow();
|
void* GetXWindow();
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "HW/EXI_DeviceIPL.h"
|
#include "HW/EXI_DeviceIPL.h"
|
||||||
// to start/stop game
|
// to start/stop game
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
// for OSD msgs
|
// for wiimote/ OSD messages
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
|
|
||||||
Common::CriticalSection crit_netplay_ptr;
|
Common::CriticalSection crit_netplay_ptr;
|
||||||
|
@ -44,17 +44,6 @@ THREAD_RETURN NetPlayThreadFunc(void* arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//CritLocker::CritLocker(Common::CriticalSection& crit)
|
|
||||||
// : m_crit(crit)
|
|
||||||
//{
|
|
||||||
// m_crit.Enter();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//CritLocker::~CritLocker()
|
|
||||||
//{
|
|
||||||
// m_crit.Leave();
|
|
||||||
//}
|
|
||||||
|
|
||||||
// called from ---GUI--- thread
|
// called from ---GUI--- thread
|
||||||
NetPlay::NetPlay()
|
NetPlay::NetPlay()
|
||||||
: m_is_running(false), m_do_loop(true)
|
: m_is_running(false), m_do_loop(true)
|
||||||
|
@ -80,6 +69,10 @@ NetPlay::~NetPlay()
|
||||||
{
|
{
|
||||||
CritLocker crit(crit_netplay_ptr);
|
CritLocker crit(crit_netplay_ptr);
|
||||||
::netplay_ptr = NULL;
|
::netplay_ptr = NULL;
|
||||||
|
|
||||||
|
// not perfect
|
||||||
|
if (m_is_running)
|
||||||
|
StopGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetPlay::Player::Player()
|
NetPlay::Player::Player()
|
||||||
|
@ -145,6 +138,9 @@ void NetPlay::ClearBuffers()
|
||||||
{
|
{
|
||||||
while (m_pad_buffer[i].size())
|
while (m_pad_buffer[i].size())
|
||||||
m_pad_buffer[i].pop();
|
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
|
// called from ---CPU--- thread
|
||||||
void NetPlay::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
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
|
//// 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?
|
// does this local pad map in game?
|
||||||
//if (in_game_num < 4)
|
if (in_game_num < 4)
|
||||||
//{
|
{
|
||||||
// //NetPad np(pad_status);
|
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
|
m_crit.buffer.Leave();
|
||||||
// // 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.players.Leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---CPU--- thread
|
// called from ---CPU--- thread
|
||||||
void NetPlay::WiimoteUpdate(int _number)
|
void NetPlay::WiimoteUpdate(int _number)
|
||||||
{
|
{
|
||||||
// temporary
|
m_crit.players.Enter(); // lock players
|
||||||
if (_number)
|
|
||||||
|
// 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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_crit.buffer.Enter(); // lock buffer
|
NetWiimote& nw = m_wiimote_buffer[_number].front();
|
||||||
++m_wiimote_update_frame;
|
|
||||||
|
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();
|
m_crit.buffer.Leave();
|
||||||
|
|
||||||
// TODO: prolly do some wiimote input here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---GUI--- thread
|
// called from ---GUI--- thread
|
||||||
|
@ -274,6 +287,14 @@ bool NetPlay::StartGame(const std::string &path)
|
||||||
::main_frame->BootGame(path);
|
::main_frame->BootGame(path);
|
||||||
//BootManager::BootCore(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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,20 +374,21 @@ u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD)
|
||||||
// wiimote update / used for frame counting
|
// 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 _number)
|
||||||
{
|
{
|
||||||
CritLocker crit(::crit_netplay_ptr);
|
//CritLocker crit(::crit_netplay_ptr);
|
||||||
|
|
||||||
return;
|
//if (::netplay_ptr)
|
||||||
|
// ::netplay_ptr->WiimoteUpdate(_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---CPU--- thread
|
// called from ---CPU--- thread
|
||||||
//
|
//
|
||||||
int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number)
|
int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number)
|
||||||
{
|
{
|
||||||
CritLocker crit(::crit_netplay_ptr);
|
//CritLocker crit(::crit_netplay_ptr);
|
||||||
|
|
||||||
if (::netplay_ptr)
|
//if (::netplay_ptr)
|
||||||
return ::netplay_ptr->GetPadNum(_number); // just using gcpad mapping for now
|
// return ::netplay_ptr->GetPadNum(_number); // just using gcpad mapping for now
|
||||||
else
|
//else
|
||||||
return _number;
|
return _number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,18 +399,19 @@ bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int _number, u16 _channelID, con
|
||||||
CritLocker crit(::crit_netplay_ptr);
|
CritLocker crit(::crit_netplay_ptr);
|
||||||
|
|
||||||
if (::netplay_ptr)
|
if (::netplay_ptr)
|
||||||
{
|
//{
|
||||||
if (_Size >= RPT_SIZE_HACK)
|
// if (_Size >= RPT_SIZE_HACK)
|
||||||
{
|
// {
|
||||||
_Size -= RPT_SIZE_HACK;
|
// _Size -= RPT_SIZE_HACK;
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
::netplay_ptr->WiimoteInput(_number, _channelID, _pData, _Size);
|
// ::netplay_ptr->WiimoteInput(_number, _channelID, _pData, _Size);
|
||||||
|
// // don't use this packet
|
||||||
return true;
|
return true;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,16 +32,13 @@ public:
|
||||||
u32 nLo;
|
u32 nLo;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetWiimote
|
struct Rpt : public std::vector<u8>
|
||||||
{
|
{
|
||||||
public:
|
u16 channel;
|
||||||
NetWiimote& operator=(const NetWiimote&);
|
|
||||||
NetWiimote(const u32 _size) : size(_size), data(new u8[size]) {}
|
|
||||||
|
|
||||||
const u32 size;
|
|
||||||
u8* const data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::vector<Rpt> NetWiimote;
|
||||||
|
|
||||||
#define NETPLAY_VERSION "Dolphin NetPlay 2.2"
|
#define NETPLAY_VERSION "Dolphin NetPlay 2.2"
|
||||||
|
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
|
@ -124,7 +121,7 @@ public:
|
||||||
void WiimoteUpdate(int _number);
|
void WiimoteUpdate(int _number);
|
||||||
bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||||
virtual bool ChangeGame(const std::string& game) = 0;
|
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 void SendChatMessage(const std::string& msg) = 0;
|
||||||
|
|
||||||
virtual bool StartGame(const std::string &path);
|
virtual bool StartGame(const std::string &path);
|
||||||
|
@ -161,11 +158,10 @@ protected:
|
||||||
std::string revision;
|
std::string revision;
|
||||||
};
|
};
|
||||||
|
|
||||||
//LockingQueue<NetPad> m_pad_buffer[4];
|
std::queue<NetPad> m_pad_buffer[4];
|
||||||
std::queue<NetPad> m_pad_buffer[4];
|
std::queue<NetWiimote> m_wiimote_buffer[4];
|
||||||
std::map<FrameNum, NetWiimote> m_wiimote_buffer[4];
|
|
||||||
|
|
||||||
FrameNum m_wiimote_update_frame;
|
NetWiimote m_wiimote_input[4];
|
||||||
|
|
||||||
NetPlayDiag* m_dialog;
|
NetPlayDiag* m_dialog;
|
||||||
sf::SocketTCP m_socket;
|
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(const u16 port, const std::string& name, NetPlayDiag* const npd = NULL, const std::string& game = "");
|
||||||
~NetPlayServer();
|
~NetPlayServer();
|
||||||
|
|
||||||
void GetPlayerList(std::string& list);
|
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||||
|
|
||||||
// Send and receive pads values
|
// 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);
|
||||||
|
@ -207,6 +203,9 @@ public:
|
||||||
bool StartGame(const std::string &path);
|
bool StartGame(const std::string &path);
|
||||||
bool StopGame();
|
bool StopGame();
|
||||||
|
|
||||||
|
bool GetPadMapping(const int pid, int map[]);
|
||||||
|
bool SetPadMapping(const int pid, const int map[]);
|
||||||
|
|
||||||
u64 CalculateMinimumBufferTime();
|
u64 CalculateMinimumBufferTime();
|
||||||
void AdjustPadBufferSize(unsigned int size);
|
void AdjustPadBufferSize(unsigned int size);
|
||||||
|
|
||||||
|
@ -226,6 +225,7 @@ private:
|
||||||
unsigned int OnConnect(sf::SocketTCP& socket);
|
unsigned int OnConnect(sf::SocketTCP& socket);
|
||||||
unsigned int OnDisconnect(sf::SocketTCP& socket);
|
unsigned int OnDisconnect(sf::SocketTCP& socket);
|
||||||
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
|
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
|
||||||
|
void UpdatePadMapping();
|
||||||
|
|
||||||
std::map<sf::SocketTCP, Client> m_players;
|
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(const std::string& address, const u16 port, const std::string& name, NetPlayDiag* const npd = NULL);
|
||||||
~NetPlayClient();
|
~NetPlayClient();
|
||||||
|
|
||||||
void GetPlayerList(std::string& list);
|
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||||
|
|
||||||
// Send and receive pads values
|
// 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);
|
||||||
|
|
|
@ -19,7 +19,7 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, const s
|
||||||
is_connected = false;
|
is_connected = false;
|
||||||
|
|
||||||
// why is false successful? documentation says true is
|
// 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
|
// send connect message
|
||||||
sf::Packet spac;
|
sf::Packet spac;
|
||||||
|
@ -193,7 +193,9 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||||
|
|
||||||
case NP_MSG_START_GAME :
|
case NP_MSG_START_GAME :
|
||||||
{
|
{
|
||||||
|
m_crit.buffer.Enter(); // lock buffer
|
||||||
packet >> m_on_game;
|
packet >> m_on_game;
|
||||||
|
m_crit.buffer.Leave();
|
||||||
|
|
||||||
wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_START_GAME);
|
wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_START_GAME);
|
||||||
m_dialog->GetEventHandler()->AddPendingEvent(evt);
|
m_dialog->GetEventHandler()->AddPendingEvent(evt);
|
||||||
|
@ -209,7 +211,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||||
|
|
||||||
case NP_MSG_DISABLE_GAME :
|
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
|
CritLocker game_lock(m_crit.game); // lock game state
|
||||||
m_is_running = false;
|
m_is_running = false;
|
||||||
NetPlay_Disable();
|
NetPlay_Disable();
|
||||||
|
@ -257,7 +259,7 @@ void NetPlayClient::Entry()
|
||||||
default :
|
default :
|
||||||
m_is_running = false;
|
m_is_running = false;
|
||||||
NetPlay_Disable();
|
NetPlay_Disable();
|
||||||
AppendChatGUI("< LOST CONNECION TO SERVER >");
|
AppendChatGUI("< LOST CONNECTION TO SERVER >");
|
||||||
PanicAlert("Lost connection to server!");
|
PanicAlert("Lost connection to server!");
|
||||||
m_do_loop = false;
|
m_do_loop = false;
|
||||||
break;
|
break;
|
||||||
|
@ -271,7 +273,7 @@ void NetPlayClient::Entry()
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---GUI--- thread
|
// 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
|
CritLocker player_lock(m_crit.players); // lock players
|
||||||
|
|
||||||
|
@ -281,7 +283,10 @@ void NetPlayClient::GetPlayerList(std::string &list)
|
||||||
i = m_players.begin(),
|
i = m_players.begin(),
|
||||||
e = m_players.end();
|
e = m_players.end();
|
||||||
for ( ; i!=e; ++i)
|
for ( ; i!=e; ++i)
|
||||||
|
{
|
||||||
ss << i->second.ToString() << '\n';
|
ss << i->second.ToString() << '\n';
|
||||||
|
pid_list.push_back(i->second.pid);
|
||||||
|
}
|
||||||
|
|
||||||
list = ss.str();
|
list = ss.str();
|
||||||
}
|
}
|
||||||
|
@ -294,9 +299,9 @@ void NetPlayClient::SendChatMessage(const std::string& msg)
|
||||||
spac << (MessageId)NP_MSG_CHAT_MESSAGE;
|
spac << (MessageId)NP_MSG_CHAT_MESSAGE;
|
||||||
spac << msg;
|
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_socket.Send(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---CPU--- thread
|
// 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 << local_nb; // local pad num
|
||||||
spac << np.nHi << np.nLo;
|
spac << np.nHi << np.nLo;
|
||||||
|
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
m_socket.Send(spac);
|
m_socket.Send(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---GUI--- thread
|
// called from ---GUI--- thread
|
||||||
|
@ -321,18 +325,15 @@ bool NetPlayClient::StartGame(const std::string &path)
|
||||||
if (false == NetPlay::StartGame(path))
|
if (false == NetPlay::StartGame(path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: i dont like this here
|
|
||||||
ClearBuffers();
|
|
||||||
m_crit.buffer.Leave();
|
|
||||||
|
|
||||||
// tell server i started the game
|
// tell server i started the game
|
||||||
sf::Packet spac;
|
sf::Packet spac;
|
||||||
spac << (MessageId)NP_MSG_START_GAME;
|
spac << (MessageId)NP_MSG_START_GAME;
|
||||||
spac << m_on_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_socket.Send(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ void NetPlayServer::Entry()
|
||||||
spac << (MessageId)NP_MSG_PING;
|
spac << (MessageId)NP_MSG_PING;
|
||||||
spac << m_ping_key;
|
spac << m_ping_key;
|
||||||
|
|
||||||
CritLocker player_lock(m_crit.players);
|
//CritLocker player_lock(m_crit.players);
|
||||||
CritLocker send_lock(m_crit.send);
|
CritLocker send_lock(m_crit.send);
|
||||||
m_ping_timer.Start();
|
m_ping_timer.Start();
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
|
@ -218,14 +218,6 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
||||||
spac << player.pid;
|
spac << player.pid;
|
||||||
socket.Send(spac);
|
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
|
// send new client the selected game
|
||||||
spac.Clear();
|
spac.Clear();
|
||||||
spac << (MessageId)NP_MSG_CHANGE_GAME;
|
spac << (MessageId)NP_MSG_CHANGE_GAME;
|
||||||
|
@ -239,13 +231,6 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
||||||
spac << (MessageId)NP_MSG_PLAYER_JOIN;
|
spac << (MessageId)NP_MSG_PLAYER_JOIN;
|
||||||
spac << i->second.pid << i->second.name << i->second.revision;
|
spac << i->second.pid << i->second.name << i->second.revision;
|
||||||
socket.Send(spac);
|
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
|
// LEAVE
|
||||||
|
@ -254,6 +239,9 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
||||||
// add client to the player list
|
// add client to the player list
|
||||||
m_crit.players.Enter(); // lock players
|
m_crit.players.Enter(); // lock players
|
||||||
m_players[socket] = player;
|
m_players[socket] = player;
|
||||||
|
m_crit.send.Enter(); // lock send
|
||||||
|
UpdatePadMapping(); // sync pad mappings with everyone
|
||||||
|
m_crit.send.Leave();
|
||||||
m_crit.players.Leave();
|
m_crit.players.Leave();
|
||||||
|
|
||||||
// add client to selector/ used for receiving
|
// add client to selector/ used for receiving
|
||||||
|
@ -277,9 +265,8 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
||||||
sf::Packet spac;
|
sf::Packet spac;
|
||||||
spac << (MessageId)NP_MSG_DISABLE_GAME;
|
spac << (MessageId)NP_MSG_DISABLE_GAME;
|
||||||
// this thread doesnt need players lock
|
// this thread doesnt need players lock
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sf::Packet spac;
|
sf::Packet spac;
|
||||||
|
@ -288,20 +275,100 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
||||||
|
|
||||||
m_selector.Remove(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_players.erase(m_players.find(socket));
|
||||||
m_crit.players.Leave();
|
|
||||||
|
|
||||||
// alert other players of disconnect
|
// alert other players of disconnect
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
|
|
||||||
UpdateGUI();
|
UpdateGUI();
|
||||||
|
|
||||||
return 0;
|
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
|
// called from ---GUI--- thread and ---NETPLAY--- thread
|
||||||
u64 NetPlayServer::CalculateMinimumBufferTime()
|
u64 NetPlayServer::CalculateMinimumBufferTime()
|
||||||
{
|
{
|
||||||
|
@ -312,7 +379,7 @@ u64 NetPlayServer::CalculateMinimumBufferTime()
|
||||||
e = m_players.end();
|
e = m_players.end();
|
||||||
std::priority_queue<unsigned int> pings;
|
std::priority_queue<unsigned int> pings;
|
||||||
for ( ;i!=e; ++i)
|
for ( ;i!=e; ++i)
|
||||||
pings.push(i->second.ping);
|
pings.push(i->second.ping/2);
|
||||||
|
|
||||||
unsigned int required_ms = pings.top();
|
unsigned int required_ms = pings.top();
|
||||||
// if there is more than 1 client, buffersize must be >= (2 highest ping times combined)
|
// 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 << (MessageId)NP_MSG_PAD_BUFFER;
|
||||||
spac << (u32)m_target_buffer_size;
|
spac << (u32)m_target_buffer_size;
|
||||||
|
|
||||||
m_crit.players.Enter(); // lock players
|
CritLocker player_lock(m_crit.players); // lock players
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
m_crit.players.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---NETPLAY--- thread
|
// called from ---NETPLAY--- thread
|
||||||
|
@ -414,9 +479,8 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
||||||
spac << map; // in game mapping
|
spac << map; // in game mapping
|
||||||
spac << np.nHi << np.nLo;
|
spac << np.nHi << np.nLo;
|
||||||
|
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac, player.pid);
|
SendToClients(spac, player.pid);
|
||||||
m_crit.send.Leave();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -452,9 +516,9 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---GUI--- thread
|
// 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;
|
std::ostringstream ss;
|
||||||
|
|
||||||
|
@ -462,7 +526,10 @@ void NetPlayServer::GetPlayerList(std::string &list)
|
||||||
i = m_players.begin(),
|
i = m_players.begin(),
|
||||||
e = m_players.end();
|
e = m_players.end();
|
||||||
for ( ; i!=e; ++i)
|
for ( ; i!=e; ++i)
|
||||||
|
{
|
||||||
ss << i->second.ToString() << " " << i->second.ping << "ms\n";
|
ss << i->second.ToString() << " " << i->second.ping << "ms\n";
|
||||||
|
pid_list.push_back(i->second.pid);
|
||||||
|
}
|
||||||
|
|
||||||
list = ss.str();
|
list = ss.str();
|
||||||
}
|
}
|
||||||
|
@ -475,9 +542,8 @@ void NetPlayServer::SendChatMessage(const std::string& msg)
|
||||||
spac << (PlayerId)0; // server id always 0
|
spac << (PlayerId)0; // server id always 0
|
||||||
spac << msg;
|
spac << msg;
|
||||||
|
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---GUI--- thread
|
// called from ---GUI--- thread
|
||||||
|
@ -492,11 +558,9 @@ bool NetPlayServer::ChangeGame(const std::string &game)
|
||||||
spac << (MessageId)NP_MSG_CHANGE_GAME;
|
spac << (MessageId)NP_MSG_CHANGE_GAME;
|
||||||
spac << game;
|
spac << game;
|
||||||
|
|
||||||
m_crit.players.Enter(); // lock players
|
CritLocker player_lock(m_crit.players); // lock players
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
m_crit.players.Leave();
|
|
||||||
|
|
||||||
return true;
|
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 << m_local_player->pad_map[local_nb]; // in-game pad num
|
||||||
spac << np.nHi << np.nLo;
|
spac << np.nHi << np.nLo;
|
||||||
|
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---GUI--- thread
|
// called from ---GUI--- thread
|
||||||
|
@ -525,7 +588,6 @@ bool NetPlayServer::StartGame(const std::string &path)
|
||||||
|
|
||||||
// TODO: i dont like this here
|
// TODO: i dont like this here
|
||||||
m_on_game = Common::Timer::GetTimeMs();
|
m_on_game = Common::Timer::GetTimeMs();
|
||||||
ClearBuffers();
|
|
||||||
m_crit.buffer.Leave();
|
m_crit.buffer.Leave();
|
||||||
|
|
||||||
// no change, just update with clients
|
// no change, just update with clients
|
||||||
|
@ -536,11 +598,9 @@ bool NetPlayServer::StartGame(const std::string &path)
|
||||||
spac << (MessageId)NP_MSG_START_GAME;
|
spac << (MessageId)NP_MSG_START_GAME;
|
||||||
spac << m_on_game;
|
spac << m_on_game;
|
||||||
|
|
||||||
m_crit.players.Enter(); // lock players
|
CritLocker player_lock(m_crit.players); // lock players
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
m_crit.send.Leave();
|
|
||||||
m_crit.players.Leave();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -556,11 +616,9 @@ bool NetPlayServer::StopGame()
|
||||||
sf::Packet spac;
|
sf::Packet spac;
|
||||||
spac << (MessageId)NP_MSG_STOP_GAME;
|
spac << (MessageId)NP_MSG_STOP_GAME;
|
||||||
|
|
||||||
m_crit.players.Enter(); // lock players
|
CritLocker player_lock(m_crit.players); // lock players
|
||||||
m_crit.send.Enter(); // lock send
|
CritLocker send_lock(m_crit.send); // lock send
|
||||||
SendToClients(spac);
|
SendToClients(spac);
|
||||||
m_crit.players.Leave();
|
|
||||||
m_crit.send.Leave();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include <FileUtil.h>
|
||||||
|
#include <IniFile.h>
|
||||||
|
|
||||||
#include "NetPlay.h"
|
#include "NetPlay.h"
|
||||||
#include "NetWindow.h"
|
#include "NetWindow.h"
|
||||||
|
|
||||||
|
@ -34,13 +37,18 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||||
: wxFrame(parent, wxID_ANY, wxT(NETPLAY_TITLEBAR), wxDefaultPosition, wxDefaultSize)
|
: wxFrame(parent, wxID_ANY, wxT(NETPLAY_TITLEBAR), wxDefaultPosition, wxDefaultSize)
|
||||||
, m_game_list(game_list)
|
, 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);
|
wxPanel* const panel = new wxPanel(this);
|
||||||
|
|
||||||
// top row
|
// top row
|
||||||
wxStaticText* const nick_lbl = new wxStaticText(panel, wxID_ANY, wxT("Nickname :"), wxDefaultPosition, wxDefaultSize);
|
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);
|
wxBoxSizer* const nick_szr = new wxBoxSizer(wxHORIZONTAL);
|
||||||
nick_szr->Add(nick_lbl, 0, wxCENTER);
|
nick_szr->Add(nick_lbl, 0, wxCENTER);
|
||||||
|
@ -58,9 +66,17 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||||
// connect tab
|
// connect tab
|
||||||
{
|
{
|
||||||
wxStaticText* const ip_lbl = new wxStaticText(connect_tab, wxID_ANY, wxT("Address :"), wxDefaultPosition, wxDefaultSize);
|
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);
|
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"));
|
wxButton* const connect_btn = new wxButton(connect_tab, wxID_ANY, wxT("Connect"));
|
||||||
_connect_macro_(connect_btn, NetPlaySetupDiag::OnJoin, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
_connect_macro_(connect_btn, NetPlaySetupDiag::OnJoin, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||||
|
@ -96,7 +112,11 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||||
// host tab
|
// host tab
|
||||||
{
|
{
|
||||||
wxStaticText* const port_lbl = new wxStaticText(host_tab, wxID_ANY, wxT("Port :"), wxDefaultPosition, wxDefaultSize);
|
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"));
|
wxButton* const host_btn = new wxButton(host_tab, wxID_ANY, wxT("Host"));
|
||||||
_connect_macro_(host_btn, NetPlaySetupDiag::OnHost, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
_connect_macro_(host_btn, NetPlaySetupDiag::OnHost, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||||
|
@ -143,6 +163,21 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||||
Show();
|
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)
|
void NetPlaySetupDiag::OnHost(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
// warning removal
|
// warning removal
|
||||||
|
@ -266,8 +301,8 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game
|
||||||
// player list
|
// player list
|
||||||
if (is_hosting)
|
if (is_hosting)
|
||||||
{
|
{
|
||||||
wxButton* const player_config_btn = new wxButton(panel, wxID_ANY, wxT("Configure Pads [not implemented]"));
|
wxButton* const player_config_btn = new wxButton(panel, wxID_ANY, wxT("Configure Pads"));
|
||||||
player_config_btn->Disable();
|
_connect_macro_(player_config_btn, NetPlayDiag::OnConfigPads, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||||
player_szr->Add(player_config_btn, 0, wxEXPAND | wxTOP, 5);
|
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();
|
const u64 time = ((NetPlayServer*)::netplay_ptr)->CalculateMinimumBufferTime();
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << "< Calculated from pings: required buffer: "
|
ss << "< Calculated from pings: required buffer: "
|
||||||
<< time * (60/1000) << "(60fps) / "
|
<< time * (60.0f/1000) << "(60fps) / "
|
||||||
<< time * (50/1000) << "(50fps) >\n";
|
<< time * (50.0f/1000) << "(50fps) >\n";
|
||||||
|
|
||||||
m_chat_text->AppendText(wxString(ss.str().c_str(), *wxConvCurrent));
|
m_chat_text->AppendText(wxString(ss.str().c_str(), *wxConvCurrent));
|
||||||
}
|
}
|
||||||
|
@ -412,14 +447,19 @@ void NetPlayDiag::OnThread(wxCommandEvent& event)
|
||||||
event.GetId();
|
event.GetId();
|
||||||
|
|
||||||
// player list
|
// player list
|
||||||
|
m_playerids.clear();
|
||||||
std::string tmps;
|
std::string tmps;
|
||||||
::netplay_ptr->GetPlayerList(tmps);
|
::netplay_ptr->GetPlayerList(tmps, m_playerids);
|
||||||
|
|
||||||
|
const int selection = m_player_lbox->GetSelection();
|
||||||
|
|
||||||
m_player_lbox->Clear();
|
m_player_lbox->Clear();
|
||||||
std::istringstream ss(tmps);
|
std::istringstream ss(tmps);
|
||||||
while (std::getline(ss, tmps))
|
while (std::getline(ss, tmps))
|
||||||
m_player_lbox->Append(wxString(tmps.c_str(), *wxConvCurrent));
|
m_player_lbox->Append(wxString(tmps.c_str(), *wxConvCurrent));
|
||||||
|
|
||||||
|
m_player_lbox->SetSelection(selection);
|
||||||
|
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
case NP_GUI_EVT_CHANGE_GAME :
|
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)
|
ChangeGameDiag::ChangeGameDiag(wxWindow* const parent, const CGameListCtrl* const game_list, wxString& game_name)
|
||||||
: wxDialog(parent, wxID_ANY, wxT("Change Game"), wxDefaultPosition, wxDefaultSize)
|
: wxDialog(parent, wxID_ANY, wxT("Change Game"), wxDefaultPosition, wxDefaultSize)
|
||||||
, m_game_name(game_name)
|
, m_game_name(game_name)
|
||||||
|
@ -510,3 +574,58 @@ void ChangeGameDiag::OnPick(wxCommandEvent& event)
|
||||||
m_game_name = m_game_lbox->GetStringSelection();
|
m_game_name = m_game_lbox->GetStringSelection();
|
||||||
Destroy();
|
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:
|
public:
|
||||||
NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* const game_list);
|
NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* const game_list);
|
||||||
|
~NetPlaySetupDiag();
|
||||||
private:
|
private:
|
||||||
void OnJoin(wxCommandEvent& event);
|
void OnJoin(wxCommandEvent& event);
|
||||||
void OnHost(wxCommandEvent& event);
|
void OnHost(wxCommandEvent& event);
|
||||||
|
@ -98,6 +98,7 @@ private:
|
||||||
void OnThread(wxCommandEvent& event);
|
void OnThread(wxCommandEvent& event);
|
||||||
void OnChangeGame(wxCommandEvent& event);
|
void OnChangeGame(wxCommandEvent& event);
|
||||||
void OnAdjustBuffer(wxCommandEvent& event);
|
void OnAdjustBuffer(wxCommandEvent& event);
|
||||||
|
void OnConfigPads(wxCommandEvent& event);
|
||||||
|
|
||||||
wxListBox* m_player_lbox;
|
wxListBox* m_player_lbox;
|
||||||
wxTextCtrl* m_chat_text;
|
wxTextCtrl* m_chat_text;
|
||||||
|
@ -106,6 +107,8 @@ private:
|
||||||
std::string m_selected_game;
|
std::string m_selected_game;
|
||||||
wxButton* m_game_btn;
|
wxButton* m_game_btn;
|
||||||
|
|
||||||
|
std::vector<int> m_playerids;
|
||||||
|
|
||||||
const CGameListCtrl* const m_game_list;
|
const CGameListCtrl* const m_game_list;
|
||||||
//NetPlay* const m_netplay;
|
//NetPlay* const m_netplay;
|
||||||
};
|
};
|
||||||
|
@ -124,5 +127,17 @@ private:
|
||||||
wxString& m_game_name;
|
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_
|
#endif // _NETWINDOW_H_
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ void ControllerInterface::Init()
|
||||||
//
|
//
|
||||||
// remove all devices/ call library cleanup functions
|
// remove all devices/ call library cleanup functions
|
||||||
//
|
//
|
||||||
void ControllerInterface::DeInit()
|
void ControllerInterface::DeInit(const bool hacks_no_sdl_quit)
|
||||||
{
|
{
|
||||||
if ( false == m_is_init )
|
if ( false == m_is_init )
|
||||||
return;
|
return;
|
||||||
|
@ -73,6 +73,13 @@ void ControllerInterface::DeInit()
|
||||||
(*d)->SetOutputState( *o, 0 );
|
(*d)->SetOutputState( *o, 0 );
|
||||||
// update output
|
// update output
|
||||||
(*d)->UpdateOutput();
|
(*d)->UpdateOutput();
|
||||||
|
|
||||||
|
// TODO: remove this
|
||||||
|
// major hacks to prevent gcpad/wiimote new from crashing eachother
|
||||||
|
if (hacks_no_sdl_quit)
|
||||||
|
if ((*d)->GetSource() == "SDL")
|
||||||
|
continue;
|
||||||
|
|
||||||
//delete device
|
//delete device
|
||||||
delete *d;
|
delete *d;
|
||||||
}
|
}
|
||||||
|
@ -92,8 +99,9 @@ void ControllerInterface::DeInit()
|
||||||
ciface::OSX::DeInit();
|
ciface::OSX::DeInit();
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_SDL
|
#ifdef CIFACE_USE_SDL
|
||||||
// there seems to be some sort of memory leak with SDL, quit isn't freeing everything up
|
// TODO: there seems to be some sort of memory leak with SDL, quit isn't freeing everything up
|
||||||
SDL_Quit();
|
if (false == hacks_no_sdl_quit)
|
||||||
|
SDL_Quit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_is_init = false;
|
m_is_init = false;
|
||||||
|
|
|
@ -240,7 +240,8 @@ public:
|
||||||
|
|
||||||
void SetHwnd( void* const hwnd );
|
void SetHwnd( void* const hwnd );
|
||||||
void Init();
|
void Init();
|
||||||
void DeInit();
|
// TODO: remove this hack param
|
||||||
|
void DeInit(const bool hacks_no_sdl_quit = false);
|
||||||
bool IsInit();
|
bool IsInit();
|
||||||
|
|
||||||
void UpdateReference( ControlReference* control );
|
void UpdateReference( ControlReference* control );
|
||||||
|
|
|
@ -20,15 +20,21 @@ namespace SDL
|
||||||
|
|
||||||
void Init( std::vector<ControllerInterface::Device*>& devices )
|
void Init( std::vector<ControllerInterface::Device*>& devices )
|
||||||
{
|
{
|
||||||
if ( SDL_Init( SDL_INIT_FLAGS ) >= 0 )
|
// just a struct with an int that is set to ZERO by default
|
||||||
|
struct ZeroedInt{ZeroedInt():value(0){}unsigned int value;};
|
||||||
|
// this is used to number the joysticks
|
||||||
|
// multiple joysticks with the same name shall get unique ids starting at 0
|
||||||
|
std::map<std::string, ZeroedInt> name_counts;
|
||||||
|
|
||||||
|
if (SDL_Init( SDL_INIT_FLAGS ) >= 0)
|
||||||
{
|
{
|
||||||
// joysticks
|
// joysticks
|
||||||
for( int i = 0; i < SDL_NumJoysticks(); ++i )
|
for(int i = 0; i < SDL_NumJoysticks(); ++i)
|
||||||
{
|
{
|
||||||
SDL_Joystick* dev = SDL_JoystickOpen( i );
|
SDL_Joystick* dev = SDL_JoystickOpen(i);
|
||||||
if ( dev )
|
if ( dev )
|
||||||
{
|
{
|
||||||
Joystick* js = new Joystick( dev, i );
|
Joystick* js = new Joystick(dev, i, name_counts[SDL_JoystickName(i)].value++);
|
||||||
// only add if it has some inputs/outputs
|
// only add if it has some inputs/outputs
|
||||||
if ( js->Inputs().size() || js->Outputs().size() )
|
if ( js->Inputs().size() || js->Outputs().size() )
|
||||||
devices.push_back( js );
|
devices.push_back( js );
|
||||||
|
@ -39,8 +45,32 @@ void Init( std::vector<ControllerInterface::Device*>& devices )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Joystick::Joystick( SDL_Joystick* const joystick, const unsigned int index ) : m_joystick(joystick), m_index(index)
|
Joystick::Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsigned int index)
|
||||||
|
: m_joystick(joystick)
|
||||||
|
, m_sdl_index(sdl_index)
|
||||||
|
, m_index(index)
|
||||||
{
|
{
|
||||||
|
// really bad HACKS:
|
||||||
|
// to not use SDL for an XInput device
|
||||||
|
// too many people on the forums pick the SDL device and ask:
|
||||||
|
// "why don't my 360 gamepad triggers/rumble work correctly"
|
||||||
|
#ifdef _WIN32
|
||||||
|
// checking the name is probably good (and hacky) enough
|
||||||
|
// but i'll double check with the num of buttons/axes
|
||||||
|
if (
|
||||||
|
("Controller (Xbox 360 Wireless Receiver for Windows)" == GetName())
|
||||||
|
&& (10 == SDL_JoystickNumButtons(joystick))
|
||||||
|
&& (5 == SDL_JoystickNumAxes(joystick))
|
||||||
|
&& (1 == SDL_JoystickNumHats(joystick))
|
||||||
|
&& (0 == SDL_JoystickNumBalls(joystick))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// this device won't be used
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// get buttons
|
// get buttons
|
||||||
for ( int i = 0; i < SDL_JoystickNumButtons( m_joystick ); ++i )
|
for ( int i = 0; i < SDL_JoystickNumButtons( m_joystick ); ++i )
|
||||||
{
|
{
|
||||||
|
@ -210,7 +240,7 @@ bool Joystick::UpdateOutput()
|
||||||
|
|
||||||
std::string Joystick::GetName() const
|
std::string Joystick::GetName() const
|
||||||
{
|
{
|
||||||
return StripSpaces(SDL_JoystickName(m_index));
|
return StripSpaces(SDL_JoystickName(m_sdl_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Joystick::GetSource() const
|
std::string Joystick::GetSource() const
|
||||||
|
|
|
@ -135,7 +135,7 @@ protected:
|
||||||
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
|
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Joystick( SDL_Joystick* const joystick, const unsigned int index );
|
Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsigned int index);
|
||||||
~Joystick();
|
~Joystick();
|
||||||
|
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
|
@ -144,6 +144,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Joystick* const m_joystick;
|
SDL_Joystick* const m_joystick;
|
||||||
|
const int m_sdl_index;
|
||||||
const unsigned int m_index;
|
const unsigned int m_index;
|
||||||
|
|
||||||
#ifdef USE_SDL_HAPTIC
|
#ifdef USE_SDL_HAPTIC
|
||||||
|
|
|
@ -373,6 +373,8 @@ void GamepadPage::ClearControl( wxCommandEvent& event )
|
||||||
btn->control_reference->device_qualifier = controller->default_device;
|
btn->control_reference->device_qualifier = controller->default_device;
|
||||||
|
|
||||||
g_plugin->controls_crit.Enter();
|
g_plugin->controls_crit.Enter();
|
||||||
|
if (btn->control_reference->is_input)
|
||||||
|
((ControllerInterface::InputReference*)btn->control_reference)->mode = 0;
|
||||||
controller->UpdateReferences( g_plugin->controller_interface );
|
controller->UpdateReferences( g_plugin->controller_interface );
|
||||||
g_plugin->controls_crit.Leave();
|
g_plugin->controls_crit.Leave();
|
||||||
|
|
||||||
|
@ -618,22 +620,33 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi
|
||||||
static_bitmap = NULL;
|
static_bitmap = NULL;
|
||||||
|
|
||||||
wxFont m_SmallFont(7, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
|
wxFont m_SmallFont(7, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
|
||||||
for ( unsigned int c = 0; c < group->controls.size(); ++c )
|
std::vector<ControllerEmu::ControlGroup::Control*>::iterator
|
||||||
|
ci = group->controls.begin(),
|
||||||
|
ce = group->controls.end();
|
||||||
|
for ( ; ci != ce; ++ci)
|
||||||
{
|
{
|
||||||
|
|
||||||
wxStaticText* const label = new wxStaticText( parent, -1, wxString::FromAscii( group->controls[c]->name )/*.append(wxT(" :"))*/ );
|
wxStaticText* const label = new wxStaticText(parent, -1, wxString::FromAscii((*ci)->name)/*.append(wxT(" :"))*/ );
|
||||||
|
|
||||||
ControlButton* const control_button = new ControlButton( parent, group->controls[c]->control_ref, 80 );
|
ControlButton* const control_button = new ControlButton(parent, (*ci)->control_ref, 80);
|
||||||
control_button->SetFont(m_SmallFont);
|
control_button->SetFont(m_SmallFont);
|
||||||
|
|
||||||
controls.push_back( control_button );
|
controls.push_back(control_button);
|
||||||
control_buttons.push_back( control_button );
|
control_buttons.push_back(control_button);
|
||||||
|
|
||||||
control_button->SetToolTip(wxT("Right-click for more options.\nMiddle-click to clear."));
|
if ((*ci)->control_ref->is_input)
|
||||||
|
{
|
||||||
|
control_button->SetToolTip(wxT("Left-click to detect input.\nMiddle-click to clear.\nRight-click for more options."));
|
||||||
|
_connect_macro_( control_button, GamepadPage::DetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
control_button->SetToolTip(wxT("Left/Right-click for more options.\nMiddle-click to clear."));
|
||||||
|
_connect_macro_( control_button, GamepadPage::ConfigControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
||||||
|
}
|
||||||
|
|
||||||
_connect_macro_( control_button, GamepadPage::DetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink );
|
|
||||||
_connect_macro_( control_button, GamepadPage::ConfigControl, wxEVT_RIGHT_UP, eventsink );
|
|
||||||
_connect_macro_( control_button, GamepadPage::ClearControl, wxEVT_MIDDLE_DOWN, eventsink );
|
_connect_macro_( control_button, GamepadPage::ClearControl, wxEVT_MIDDLE_DOWN, eventsink );
|
||||||
|
_connect_macro_( control_button, GamepadPage::ConfigControl, wxEVT_RIGHT_UP, eventsink );
|
||||||
|
|
||||||
wxBoxSizer* const control_sizer = new wxBoxSizer( wxHORIZONTAL );
|
wxBoxSizer* const control_sizer = new wxBoxSizer( wxHORIZONTAL );
|
||||||
control_sizer->AddStretchSpacer( 1 );
|
control_sizer->AddStretchSpacer( 1 );
|
||||||
|
|
|
@ -99,7 +99,9 @@ void DeInitPlugin()
|
||||||
delete *i;
|
delete *i;
|
||||||
g_plugin.controllers.clear();
|
g_plugin.controllers.clear();
|
||||||
|
|
||||||
g_plugin.controller_interface.DeInit();
|
// true parameter to make SDL not quit in the wiimote plugin,
|
||||||
|
// the old wiimote plugin uses this hack as well, to prevent crash on stop
|
||||||
|
g_plugin.controller_interface.DeInit(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +278,7 @@ void DllConfig(HWND _hParent)
|
||||||
frame->Destroy();
|
frame->Destroy();
|
||||||
// /
|
// /
|
||||||
|
|
||||||
if ( false == was_init ) // hack for showing dialog when game isnt running
|
if ( false == was_init )
|
||||||
DeInitPlugin();
|
DeInitPlugin();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue