LINK: New API to initialize link modes

git-svn-id: https://svn.code.sf.net/p/vbam/code/branches/bgk-link@1123 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
bgk 2012-09-08 17:11:07 +00:00
parent 659e71fad6
commit 4c0b34fcf4
7 changed files with 154 additions and 86 deletions

View File

@ -3442,7 +3442,7 @@ void CPULoop(int ticks)
cpuTotalTicks = 0;
// shuffle2: what's the purpose?
if(gba_link_enabled)
if(GetLinkMode() != LINK_DISCONNECTED)
cpuNextEvent = 1;
cpuBreakLoop = false;
@ -3890,10 +3890,10 @@ void CPULoop(int ticks)
ticks -= clockTicks;
if (gba_joybus_enabled)
if(GetLinkMode() == LINK_GAMECUBE_DOLPHIN)
JoyBusUpdate(clockTicks);
if (gba_link_enabled)
if(GetLinkMode() != LINK_DISCONNECTED)
LinkUpdate(clockTicks);
cpuNextEvent = CPUUpdateTicks();
@ -3911,7 +3911,7 @@ void CPULoop(int ticks)
}
// shuffle2: what's the purpose?
if(gba_link_enabled)
if(GetLinkMode() != LINK_DISCONNECTED)
cpuNextEvent = 1;
if(IF && (IME & 1) && armIrqEnable) {

View File

@ -22,12 +22,6 @@ const char *MakeInstanceFilename(const char *Input)
#ifndef NO_LINK
// Joybus
bool gba_joybus_enabled = false;
// If disabled, gba core won't call any (non-joybus) link functions
bool gba_link_enabled = false;
#define LOCAL_LINK_NAME "VBA link memory"
#define IP_LINK_PORT 5738
@ -153,6 +147,12 @@ int WaitForSingleObject(sem_t *s, int t)
#define UPDATE_REG(address, value) WRITE16LE(((u16 *)&ioMem[address]),value)
static LinkMode gba_link_mode = LINK_DISCONNECTED;
LinkMode GetLinkMode() {
return gba_link_mode;
}
int linktime = 0;
GBASockClient* dol = NULL;
@ -188,7 +188,6 @@ lclient lc;
bool oncewait = false, after = false;
// RFU crap (except for numtransfers note...should probably check that out)
bool rfu_enabled = false;
u8 rfu_cmd, rfu_qsend, rfu_qrecv;
int rfu_state, rfu_polarity, rfu_counter, rfu_masterq;
// numtransfers seems to be used interchangeably with linkmem->numtransfers
@ -237,14 +236,14 @@ void StartLink(u16 value)
if (ioMem == NULL)
return;
if (rfu_enabled) {
if (GetLinkMode() == LINK_RFU_IPC) {
UPDATE_REG(COMM_SIOCNT, StartRFU(value));
return;
}
switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) {
case MULTIPLAYER: {
bool start = (value & 0x80) && !linkid && !transfer && gba_link_enabled;
bool start = (value & 0x80) && !linkid && !transfer && GetLinkMode() != LINK_DISCONNECTED;
u16 si = value & 4;
// clear start, seqno, si (RO on slave, start = pulse on master)
value &= 0xff4b;
@ -256,7 +255,7 @@ void StartLink(u16 value)
value |= READ16LE(&ioMem[COMM_SIOCNT]) & 4;
}
if (start) {
if (lanlink.active)
if (GetLinkMode() == LINK_CABLE_SOCKET)
{
if (lanlink.connected)
{
@ -362,13 +361,13 @@ void StartGPLink(u16 value)
break;
case GP:
if (rfu_enabled)
if (GetLinkMode() == LINK_RFU_IPC)
rfu_state = RFU_INIT;
break;
}
}
void JoyBusConnect()
static void JoyBusConnect()
{
delete dol;
dol = NULL;
@ -376,7 +375,7 @@ void JoyBusConnect()
dol = new GBASockClient(joybusHostAddr);
}
void JoyBusShutdown()
static void JoyBusShutdown()
{
delete dol;
dol = NULL;
@ -450,7 +449,7 @@ void LinkUpdate(int ticks)
linktime += ticks;
if (rfu_enabled)
if (GetLinkMode() == LINK_RFU_IPC)
{
rfu_transfer_end -= ticks;
if (transfer && rfu_transfer_end <= 0)
@ -466,7 +465,7 @@ void LinkUpdate(int ticks)
return;
}
if (lanlink.active)
if (GetLinkMode() == LINK_CABLE_SOCKET)
{
if (lanlink.connected)
{
@ -961,8 +960,18 @@ u16 StartRFU(u16 value)
// Probably from here down needs to be replaced with SFML goodness :)
// tjm: what SFML goodness? SFML for network, yes, but not for IPC
bool InitLink()
bool InitLink(LinkMode mode)
{
// Do nothing if we are already connected
if (GetLinkMode() != LINK_DISCONNECTED) {
systemMessage(0, N_("Error, link already connected"));
return false;
}
if (mode == LINK_GAMECUBE_DOLPHIN) {
JoyBusConnect();
}
linkid = 0;
#if (defined __WIN32__ || defined _WIN32)
@ -1075,6 +1084,10 @@ bool InitLink()
}
for(i=0;i<4;i++)
linkdata[i] = 0xffff;
// No errors, save the link mode
gba_link_mode = mode;
return true;
}
@ -1094,6 +1107,14 @@ static void ReInitLink()
}
void CloseLink(void){
if (GetLinkMode() == LINK_DISCONNECTED) {
return; // Nothing to do
}
if (GetLinkMode() == LINK_GAMECUBE_DOLPHIN) {
JoyBusShutdown();
}
if(lanlink.connected){
if(linkid){
char outbuffer[4];
@ -1152,6 +1173,9 @@ void CloseLink(void){
munmap(linkmem, sizeof(LINKDATA));
close(mmf);
#endif
gba_link_mode = LINK_DISCONNECTED;
return;
}

View File

@ -3,6 +3,38 @@
#pragma once
/**
* Link modes to be passed to InitLink
*/
enum LinkMode
{
LINK_DISCONNECTED,
LINK_CABLE_IPC,
LINK_CABLE_SOCKET,
LINK_RFU_IPC,
LINK_GAMECUBE_DOLPHIN
};
/**
* Initialize GBA linking
*
* @param mode Device to emulate, plugged to the GBA link port.
* @return success
*/
extern bool InitLink(LinkMode mode);
/**
* Get the currently enabled link mode
*
* @return link mode
*/
extern LinkMode GetLinkMode();
/**
* Set the current link mode to LINK_DISCONNECTED
*/
extern void CloseLink();
// register definitions; these are always present
#define UNSUPPORTED -1
@ -141,26 +173,17 @@ typedef struct {
bool terminate;
bool connected;
bool speed;
bool active;
} LANLINKDATA;
extern bool gba_joybus_enabled;
extern bool gba_link_enabled;
extern sf::IPAddress joybusHostAddr;
extern void JoyBusConnect();
extern void JoyBusShutdown();
extern void JoyBusUpdate(int ticks);
extern bool InitLink();
extern void CloseLink();
extern void StartLink(u16);
extern void StartGPLink(u16);
extern void LinkUpdate(int);
extern void CleanLocalLink();
extern LANLINKDATA lanlink;
extern int vbaid;
extern bool rfu_enabled;
extern int linktimeout;
extern lclient lc;
extern lserver ls;
@ -169,9 +192,6 @@ extern int linkid;
#else
// stubs to keep #ifdef's out of mainline
const bool gba_joybus_enabled = false;
const bool gba_link_enabled = false;
inline void JoyBusConnect() { }
inline void JoyBusShutdown() { }
inline void JoyBusUpdate(int) { }

View File

@ -1159,16 +1159,18 @@ EVT_HANDLER(JoypadAutofireR, "Autofire R (toggle)")
EVT_HANDLER_MASK(LanLink, "Start LAN link", CMDEN_LINK_ANY)
{
#ifndef NO_LINK
if(lanlink.connected) {
// while we could deactivate the command when connected, it is more
// user-friendly to display a message indidcating why
wxLogError(_("LAN link is already active. Disable link mode to disconnect."));
return;
LinkMode mode = GetLinkMode();
if (mode == LINK_CABLE_SOCKET) {
// while we could deactivate the command when connected, it is more
// user-friendly to display a message indidcating why
wxLogError(_("LAN link is already active. Disable link mode to disconnect."));
return;
}
if(rfu_enabled) {
// see above comment
wxLogError(_("RFU is currently only supported in local mode."));
return;
if (mode == LINK_RFU_IPC || mode == LINK_GAMECUBE_DOLPHIN) {
// see above comment
wxLogError(_("RFU and Joybus are only supported in local mode."));
return;
}
wxDialog *dlg = GetXRCDialog("NetLink");
ShowModal(dlg);
@ -2118,33 +2120,29 @@ EVT_HANDLER(JoypadConfigure, "Joypad options...")
EVT_HANDLER(LinkConfigure, "Link options...")
{
#ifndef NO_LINK
bool jb = gba_joybus_enabled;
wxString jh = gopts.joybus_host;
wxDialog *dlg = GetXRCDialog("LinkConfig");
if(ShowModal(dlg) != wxID_OK)
return;
if (ShowModal(dlg) != wxID_OK)
return;
update_opts();
if(jb != gba_joybus_enabled) {
if(gba_joybus_enabled)
JoyBusConnect();
else
JoyBusShutdown();
} else if(jh != gopts.joybus_host) {
joybusHostAddr = std::string(gopts.joybus_host.mb_str());
JoyBusConnect();
LinkMode oldLinkMode = GetLinkMode();
LinkMode newLinkMode = getOptionsLinkMode();
bool dolphinHostChanged = jh != gopts.joybus_host;
if (newLinkMode != oldLinkMode || dolphinHostChanged) {
joybusHostAddr = std::string(gopts.joybus_host.mb_str());
CloseLink();
InitLink(newLinkMode);
}
if(gba_link_enabled != did_link_init) {
if(gba_link_enabled) {
if((did_link_init = InitLink()))
cmd_enable |= CMDEN_LINK_ANY;
} else {
did_link_init = false;
CloseLink();
lanlink.active = false;
cmd_enable &= ~CMDEN_LINK_ANY;
}
enable_menus();
cmd_enable &= ~CMDEN_LINK_ANY;
if (GetLinkMode() != LINK_DISCONNECTED) {
cmd_enable |= CMDEN_LINK_ANY;
}
enable_menus();
#endif
}

View File

@ -67,6 +67,9 @@ public:
return;
update_opts(); // save fast flag and client host
// Close any previous link
CloseLink();
wxString connmsg, pmsg;
wxMutex lock;
@ -206,7 +209,10 @@ public:
if(lanlink.connected) {
pmsg.Replace(wxT("\n"), wxT(" "));
systemScreenMessage(pmsg);
lanlink.active = true;
// Init link
InitLink(LINK_CABLE_SOCKET);
ev.Skip(); // all OK
}
}
@ -2227,7 +2233,7 @@ bool MainFrame::InitMore(void)
// so just set individual flags here
cmd_enable = CMDEN_NGDB_ANY | CMDEN_NREC_ANY;
update_state_ts(true);
enable_menus();
// set pointers for checkable menu items
// and set initial checked status
if(checkable_mi.size()) {
@ -3072,14 +3078,14 @@ bool MainFrame::InitMore(void)
#ifndef NO_LINK
LoadXRCDialog("LinkConfig");
{
getcbbe("Joybus", gba_joybus_enabled);
getcbbe("Joybus", gopts.gba_joybus_enabled);
getlab("JoybusHostLab");
addbe(lab);
gettc("JoybusHost", gopts.joybus_host);
tc->SetValidator(IPHostValidator(&gopts.joybus_host));
addbe(tc);
getcbbe("Link", gba_link_enabled);
getcbb("RFU", rfu_enabled);
getcbbe("Link", gopts.gba_link_enabled);
getcbb("RFU", gopts.rfu_enabled);
addbe(cb);
getlab("LinkTimeoutLab");
addbe(lab);
@ -3205,23 +3211,31 @@ bool MainFrame::InitMore(void)
panel->ShowFullScreen(true);
#ifndef NO_LINK
if(gba_joybus_enabled) {
bool isv = !gopts.joybus_host.empty();
if(isv) {
joybusHostAddr = std::string(gopts.joybus_host.mb_str());
isv = joybusHostAddr.IsValid();
}
if(!isv) {
wxLogError(_("JoyBus host invalid; disabling"));
gba_joybus_enabled = false;
} else
JoyBusConnect();
}
if(gba_link_enabled)
if((did_link_init = InitLink()))
cmd_enable |= CMDEN_LINK_ANY;
LinkMode linkMode = getOptionsLinkMode();
if (linkMode == LINK_GAMECUBE_DOLPHIN) {
bool isv = !gopts.joybus_host.empty();
if(isv) {
joybusHostAddr = std::string(gopts.joybus_host.mb_str());
isv = joybusHostAddr.IsValid();
}
if(!isv) {
wxLogError(_("JoyBus host invalid; disabling"));
gopts.gba_joybus_enabled = false;
} else {
linkMode = LINK_DISCONNECTED;
}
}
InitLink(linkMode);
if (GetLinkMode() != LINK_DISCONNECTED)
cmd_enable |= CMDEN_LINK_ANY;
#endif
enable_menus();
panel->SetFrameTitle();
// All OK; activate idle loop

View File

@ -391,12 +391,11 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser &cl)
return true;
}
MainFrame::MainFrame() : wxFrame(), did_link_init(false), focused(false),
MainFrame::MainFrame() : wxFrame(), focused(false),
paused(false), menus_opened(0), dialog_opened(0) {}
MainFrame::~MainFrame()
{
if(did_link_init)
CloseLink();
}
@ -642,6 +641,18 @@ void MainFrame::StopModal()
panel->Resume();
}
LinkMode MainFrame::getOptionsLinkMode() {
if (gopts.gba_joybus_enabled) {
return LINK_GAMECUBE_DOLPHIN;
} else if (gopts.rfu_enabled) {
return LINK_RFU_IPC;
} else if (gopts.gba_link_enabled) {
return LINK_CABLE_IPC;
}
return LINK_DISCONNECTED;
}
// global event filter
// apparently required for win32; just setting accel table still misses
// a few keys (e.g. only ctrl-x works for exit, but not esc & ctrl-q;

View File

@ -205,7 +205,6 @@ public:
// required for event handling
DECLARE_EVENT_TABLE();
private:
bool did_link_init;
GameArea *panel;
// the various reasons the game might be paused
@ -244,6 +243,8 @@ private:
void OnDropFile(wxDropFilesEvent&);
// pop up menu in fullscreen mode
void OnMenu(wxContextMenuEvent &);
// Returns the link mode to set according to the options
LinkMode getOptionsLinkMode();
#include "cmdhandlers.h"
};