first implementation of support for multi GBAs. Probably something wrong with thread safety or something - but hey, it works...and I would need help to make it threadsafe *hint* :)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5111 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
303769d31c
commit
a4e9bf3fd2
|
@ -19,26 +19,66 @@
|
|||
#include "SI_DeviceGBA.h"
|
||||
|
||||
#include "SFML/Network.hpp"
|
||||
#include <algorithm>
|
||||
#include "Thread.h"
|
||||
#include <queue>
|
||||
|
||||
static Common::Thread *connectionThread = NULL;
|
||||
static std::queue<sf::SocketTCP> waiting_socks;
|
||||
|
||||
// --- GameBoy Advance "Link Cable" ---
|
||||
|
||||
THREAD_RETURN ConnectionWaiter(void*)
|
||||
{
|
||||
Common::SetCurrentThreadName("GBA Connection Waiter");
|
||||
|
||||
sf::SocketTCP server;
|
||||
if (!server.Listen(0xd6ba))
|
||||
return 0;
|
||||
|
||||
server.SetBlocking(false);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
sf::SocketTCP new_client;
|
||||
if (server.Accept(new_client) == sf::Socket::Done)
|
||||
{
|
||||
waiting_socks.push(new_client);
|
||||
PanicAlert("Connected");
|
||||
}
|
||||
}
|
||||
server.Close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GetAvailableSock(sf::SocketTCP& sock_to_fill)
|
||||
{
|
||||
if (waiting_socks.size() > 0)
|
||||
{
|
||||
sock_to_fill = waiting_socks.front();
|
||||
waiting_socks.pop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
GBASockServer::GBASockServer()
|
||||
{
|
||||
if (!server.Listen(8080))
|
||||
return;
|
||||
|
||||
server.Accept(client, &client_addr);
|
||||
if (!connectionThread)
|
||||
connectionThread = new Common::Thread(ConnectionWaiter, (void*)0);
|
||||
}
|
||||
|
||||
GBASockServer::~GBASockServer()
|
||||
{
|
||||
client.Close();
|
||||
server.Close();
|
||||
}
|
||||
|
||||
// Blocking, since GBA must always send lower byte of REG_JOYSTAT
|
||||
void GBASockServer::Transfer(char* si_buffer)
|
||||
{
|
||||
if (!client.IsValid())
|
||||
if (!GetAvailableSock(client))
|
||||
return;
|
||||
|
||||
current_data[0] = si_buffer[3];
|
||||
current_data[1] = si_buffer[2];
|
||||
current_data[2] = si_buffer[1];
|
||||
|
@ -87,23 +127,8 @@ CSIDevice_GBA::CSIDevice_GBA(int _iDeviceNumber)
|
|||
{
|
||||
}
|
||||
|
||||
CSIDevice_GBA::~CSIDevice_GBA()
|
||||
{
|
||||
}
|
||||
|
||||
int CSIDevice_GBA::RunBuffer(u8* _pBuffer, int _iLength)
|
||||
{
|
||||
Transfer((char*)_pBuffer);
|
||||
return _iLength;
|
||||
}
|
||||
|
||||
bool CSIDevice_GBA::GetData(u32& _Hi, u32& _Low)
|
||||
{
|
||||
DEBUG_LOG(SERIALINTERFACE, "GBA %i GetData Hi: 0x%08x Low: 0x%08x", m_iDeviceNumber, _Hi, _Low);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSIDevice_GBA::SendCommand(u32 _Cmd, u8 _Poll)
|
||||
{
|
||||
DEBUG_LOG(SERIALINTERFACE, "GBA %i SendCommand: (0x%08x)", m_iDeviceNumber, _Cmd);
|
||||
}
|
||||
|
|
|
@ -30,10 +30,8 @@ public:
|
|||
|
||||
void Transfer(char* si_buffer);
|
||||
|
||||
char current_data[5];
|
||||
|
||||
private:
|
||||
enum EBufferCommands
|
||||
enum EJoybusCmds
|
||||
{
|
||||
CMD_RESET = 0xff,
|
||||
CMD_STATUS = 0x00,
|
||||
|
@ -41,25 +39,21 @@ private:
|
|||
CMD_WRITE = 0x15
|
||||
};
|
||||
|
||||
sf::SocketTCP server;
|
||||
sf::SocketTCP client;
|
||||
sf::IPAddress client_addr;
|
||||
char current_data[5];
|
||||
};
|
||||
|
||||
class CSIDevice_GBA : public ISIDevice, private GBASockServer
|
||||
{
|
||||
public:
|
||||
CSIDevice_GBA(int _iDeviceNumber);
|
||||
~CSIDevice_GBA();
|
||||
~CSIDevice_GBA() {}
|
||||
|
||||
// Run the SI Buffer
|
||||
virtual int RunBuffer(u8* _pBuffer, int _iLength);
|
||||
|
||||
// Return true on new data
|
||||
virtual bool GetData(u32& _Hi, u32& _Low);
|
||||
|
||||
// Send a command directly
|
||||
virtual void SendCommand(u32 _Cmd, u8 _Poll);
|
||||
virtual bool GetData(u32& _Hi, u32& _Low) { return true; }
|
||||
virtual void SendCommand(u32 _Cmd, u8 _Poll) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue