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 "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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue