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:
Shawn Hoffman 2010-02-22 21:57:05 +00:00
parent 303769d31c
commit a4e9bf3fd2
2 changed files with 51 additions and 32 deletions

View File

@ -19,26 +19,66 @@
#include "SI_DeviceGBA.h" #include "SI_DeviceGBA.h"
#include "SFML/Network.hpp" #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" --- // --- 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() GBASockServer::GBASockServer()
{ {
if (!server.Listen(8080)) if (!connectionThread)
return; connectionThread = new Common::Thread(ConnectionWaiter, (void*)0);
server.Accept(client, &client_addr);
} }
GBASockServer::~GBASockServer() GBASockServer::~GBASockServer()
{ {
client.Close(); client.Close();
server.Close();
} }
// Blocking, since GBA must always send lower byte of REG_JOYSTAT // Blocking, since GBA must always send lower byte of REG_JOYSTAT
void GBASockServer::Transfer(char* si_buffer) void GBASockServer::Transfer(char* si_buffer)
{ {
if (!client.IsValid())
if (!GetAvailableSock(client))
return;
current_data[0] = si_buffer[3]; current_data[0] = si_buffer[3];
current_data[1] = si_buffer[2]; current_data[1] = si_buffer[2];
current_data[2] = si_buffer[1]; 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) int CSIDevice_GBA::RunBuffer(u8* _pBuffer, int _iLength)
{ {
Transfer((char*)_pBuffer); Transfer((char*)_pBuffer);
return _iLength; 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);
}

View File

@ -30,10 +30,8 @@ public:
void Transfer(char* si_buffer); void Transfer(char* si_buffer);
char current_data[5];
private: private:
enum EBufferCommands enum EJoybusCmds
{ {
CMD_RESET = 0xff, CMD_RESET = 0xff,
CMD_STATUS = 0x00, CMD_STATUS = 0x00,
@ -41,25 +39,21 @@ private:
CMD_WRITE = 0x15 CMD_WRITE = 0x15
}; };
sf::SocketTCP server;
sf::SocketTCP client; sf::SocketTCP client;
sf::IPAddress client_addr; char current_data[5];
}; };
class CSIDevice_GBA : public ISIDevice, private GBASockServer class CSIDevice_GBA : public ISIDevice, private GBASockServer
{ {
public: public:
CSIDevice_GBA(int _iDeviceNumber); CSIDevice_GBA(int _iDeviceNumber);
~CSIDevice_GBA(); ~CSIDevice_GBA() {}
// Run the SI Buffer // Run the SI Buffer
virtual int RunBuffer(u8* _pBuffer, int _iLength); virtual int RunBuffer(u8* _pBuffer, int _iLength);
// Return true on new data virtual bool GetData(u32& _Hi, u32& _Low) { return true; }
virtual bool GetData(u32& _Hi, u32& _Low); virtual void SendCommand(u32 _Cmd, u8 _Poll) {}
// Send a command directly
virtual void SendCommand(u32 _Cmd, u8 _Poll);
}; };
#endif #endif