diff --git a/src/gba/GBALink.cpp b/src/gba/GBALink.cpp index 376a3af4..dcf78c37 100644 --- a/src/gba/GBALink.cpp +++ b/src/gba/GBALink.cpp @@ -29,6 +29,9 @@ const char *MakeInstanceFilename(const char *Input) #include "GBA.h" #include "GBALink.h" #include "GBASockClient.h" + +#include + #ifdef ENABLE_NLS #include #define _(x) gettext(x) @@ -145,6 +148,27 @@ int WaitForSingleObject(sem_t *s, int t) #endif #endif +#define UNSUPPORTED -1 +#define MULTIPLAYER 0 +#define NORMAL8 1 +#define NORMAL32 2 +#define UART 3 +#define JOYBUS 4 +#define GP 5 + +#define RFU_INIT 0 +#define RFU_COMM 1 +#define RFU_SEND 2 +#define RFU_RECV 3 + +enum +{ + JOY_CMD_RESET = 0xff, + JOY_CMD_STATUS = 0x00, + JOY_CMD_READ = 0x14, + JOY_CMD_WRITE = 0x15 +}; + #define UPDATE_REG(address, value) WRITE16LE(((u16 *)&ioMem[address]),value) typedef struct { @@ -162,6 +186,15 @@ typedef struct { u32 rfu_data[4][32]; } LINKDATA; +typedef struct { + sf::SocketTCP tcpsocket; + int numslaves; + int connectedSlaves; + int type; + bool server; + bool speed; +} LANLINKDATA; + class lserver{ int numbytes; sf::Selector fdset; @@ -238,7 +271,7 @@ char linkevent[] = "VBA link event "; static int i, j; int linktimeout = 1000; -LANLINKDATA lanlink; +static LANLINKDATA lanlink; u16 linkdata[4]; static lserver ls; static lclient lc; @@ -295,7 +328,7 @@ void StartLink(u16 value) switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) { case MULTIPLAYER: { - bool start = (value & 0x80) && !linkid && !transfer && GetLinkMode() != LINK_DISCONNECTED; + bool start = (value & 0x80) && !linkid && !transfer; // clear start, seqno, si (RO on slave, start = pulse on master) value &= 0xff4b; // get current si. This way, on slaves, it is low during xfer @@ -322,7 +355,7 @@ void StartLink(u16 value) after = false; value &= ~0x40; } - else if (linkmem->numgbas > 1) + else if (GetLinkMode() == LINK_CABLE_IPC && linkmem->numgbas > 1) { // find first active attached GBA // doing this first reduces the potential @@ -1275,6 +1308,15 @@ ConnectionState ConnectLinkUpdate(char * const message, size_t size) return gba_connection_state; } +void EnableLinkServer(bool enable, int numSlaves) { + lanlink.server = enable; + lanlink.numslaves = numSlaves; +} + +void EnableSpeedHacks(bool enable) { + lanlink.speed = enable; +} + bool SetLinkServerHost(const char *host) { sf::IPAddress addr = sf::IPAddress(host); diff --git a/src/gba/GBALink.h b/src/gba/GBALink.h index 320ab3d5..fcc06ea7 100644 --- a/src/gba/GBALink.h +++ b/src/gba/GBALink.h @@ -47,6 +47,21 @@ extern ConnectionState ConnectLinkUpdate(char * const message, size_t size); */ extern LinkMode GetLinkMode(); +/** + * Is this instance going to host a LAN link server? + * + * @param enabled Server mode + * @param numSlaves Number of expected clients + */ +extern void EnableLinkServer(bool enable, int numSlaves); + +/** + * Should speed hacks be used? + * + * @param enabled Speed hacks + */ +extern void EnableSpeedHacks(bool enable); + /** * Set the host to connect to when in socket mode * @@ -74,30 +89,16 @@ extern void CheckLinkConnection(); */ extern void CloseLink(); -// register definitions; these are always present - -#define UNSUPPORTED -1 -#define MULTIPLAYER 0 -#define NORMAL8 1 -#define NORMAL32 2 -#define UART 3 -#define JOYBUS 4 -#define GP 5 - -#define RFU_INIT 0 -#define RFU_COMM 1 -#define RFU_SEND 2 -#define RFU_RECV 3 - +// register definitions #define COMM_SIODATA32_L 0x120 #define COMM_SIODATA32_H 0x122 #define COMM_SIOCNT 0x128 #define COMM_SIODATA8 0x12a -#define COMM_SIOMLT_SEND 0x12a -#define COMM_SIOMULTI0 0x120 -#define COMM_SIOMULTI1 0x122 -#define COMM_SIOMULTI2 0x124 -#define COMM_SIOMULTI3 0x126 +#define COMM_SIOMLT_SEND 0x12a +#define COMM_SIOMULTI0 0x120 +#define COMM_SIOMULTI1 0x122 +#define COMM_SIOMULTI2 0x124 +#define COMM_SIOMULTI3 0x126 #define COMM_RCNT 0x134 #define COMM_JOYCNT 0x140 #define COMM_JOY_RECV_L 0x150 @@ -114,34 +115,17 @@ extern void CloseLink(); #define JOYCNT_SEND_COMPLETE 4 #define JOYCNT_INT_ENABLE 0x40 -enum -{ - JOY_CMD_RESET = 0xff, - JOY_CMD_STATUS = 0x00, - JOY_CMD_READ = 0x14, - JOY_CMD_WRITE = 0x15 -}; + extern const char *MakeInstanceFilename(const char *Input); #ifndef NO_LINK // Link implementation -#include - -typedef struct { - sf::SocketTCP tcpsocket; - int numslaves; - int connectedSlaves; - int type; - bool server; - bool speed; -} LANLINKDATA; extern void StartLink(u16); extern void StartGPLink(u16); extern void LinkUpdate(int); extern void CleanLocalLink(); -extern LANLINKDATA lanlink; extern int vbaid; extern int linktimeout; extern int linkid; diff --git a/src/wx/cmdevents.cpp b/src/wx/cmdevents.cpp index 351dcead..0a01d393 100644 --- a/src/wx/cmdevents.cpp +++ b/src/wx/cmdevents.cpp @@ -2124,6 +2124,14 @@ EVT_HANDLER(LinkConfigure, "Link options...") wxDialog *dlg = GetXRCDialog("LinkConfig"); if (ShowModal(dlg) != wxID_OK) return; + + bool valid = SetLinkServerHost(gopts.joybus_host.mb_str()); + if (!valid) { + wxMessageBox(_("You must enter a valid host name"), + _("Host name invalid"), wxICON_ERROR | wxOK); + return; + } + update_opts(); LinkMode oldLinkMode = GetLinkMode(); @@ -2131,7 +2139,6 @@ EVT_HANDLER(LinkConfigure, "Link options...") bool dolphinHostChanged = jh != gopts.joybus_host; if (newLinkMode != oldLinkMode || dolphinHostChanged) { - SetLinkServerHost(gopts.joybus_host.mb_str()); CloseLink(); InitLink(newLinkMode); } diff --git a/src/wx/guiinit.cpp b/src/wx/guiinit.cpp index 6573200c..40c7a781 100644 --- a/src/wx/guiinit.cpp +++ b/src/wx/guiinit.cpp @@ -50,7 +50,8 @@ static class NetLink_t : public wxEvtHandler public: wxDialog *dlg; int n_players; - NetLink_t() : n_players(2) {} + bool server; + NetLink_t() : n_players(2), server(false) {} wxButton *okb; void ServerOKButton(wxCommandEvent &ev) { @@ -66,25 +67,34 @@ public: static const int length = 256; if(!dlg->Validate() || !dlg->TransferDataFromWindow()) return; + + if (!server) { + bool valid = SetLinkServerHost(gopts.link_host.mb_str()); + if (!valid) { + wxMessageBox(_("You must enter a valid host name"), + _("Host name invalid"), wxICON_ERROR | wxOK); + return; + } + } + update_opts(); // save fast flag and client host - // Close any previous link + // Close any previous link CloseLink(); wxString connmsg; wxString title; - if(lanlink.server) { + EnableSpeedHacks(gopts.lanlink_speed); + EnableLinkServer(server, n_players - 1); + + if (server) { char host[length]; GetLinkServerHost(host, length); - lanlink.numslaves = n_players - 1; - title.Printf(_("Waiting for clients...")); connmsg.Printf(_("Server IP address is: %s\n"), wxString(host, wxConvLibc).c_str()); } else { - SetLinkServerHost(gopts.link_host.mb_str()); - title.Printf(_("Waiting for connection...")); connmsg.Printf(_("Connecting to %s\n"), gopts.link_host.c_str()); } @@ -1357,45 +1367,6 @@ public: } } JoyPadConfigHandler[4]; -#ifndef NO_LINK -// tc validator for IP addresses using SFML for validation instead of wx -class IPHostValidator : public wxValidator -{ - wxString *valp; -public: - IPHostValidator(wxString *v) : wxValidator(), valp(v) {} - IPHostValidator(const IPHostValidator &e) : wxValidator(), valp(e.valp) {} - wxObject *Clone() const { return new IPHostValidator(*this); } - bool Validate(wxWindow *p) { - wxTextCtrl *tc = wxStaticCast(GetWindow(), wxTextCtrl); - if(!tc->IsEnabled()) - return true; - wxString val = tc->GetValue(); - bool isv = true; - if(val.empty()) - isv = false; - else { - sf::IPAddress srv = std::string(val.mb_str()); - isv = srv.IsValid(); - } - if(!isv) - wxMessageBox(_("You must enter a valid host name"), - _("Host name invalid"), wxICON_ERROR|wxOK); - return isv; - } - bool TransferToWindow() { - wxTextCtrl *tc = wxStaticCast(GetWindow(), wxTextCtrl); - tc->SetValue(*valp); - return true; - } - bool TransferFromWindow() { - wxTextCtrl *tc = wxStaticCast(GetWindow(), wxTextCtrl); - *valp = tc->GetValue(); - return true; - } -}; -#endif - // manage fullscreen mode widget // technically, it's more than a validator: it modifies the widget as well class ScreenModeList : public wxValidator @@ -2383,8 +2354,8 @@ bool MainFrame::InitMore(void) #ifndef NO_LINK { net_link_handler.dlg = d; - getrbbe("Server", lanlink.server); - getrbbd("Client", lanlink.server); + getrbbe("Server", net_link_handler.server); + getrbbd("Client", net_link_handler.server); getlab("PlayersLab"); addrber(lab, false); getrbi("Link2P", net_link_handler.n_players, 2); @@ -2397,9 +2368,8 @@ bool MainFrame::InitMore(void) addrber(lab, true); gettc("ServerIP", gopts.link_host); addrber(tc, true); - tc->SetValidator(IPHostValidator(&gopts.link_host)); - getrbbr("SpeedOff", lanlink.speed); - getrbb("SpeedOn", lanlink.speed); + getrbbr("SpeedOff", gopts.lanlink_speed); + getrbb("SpeedOn", gopts.lanlink_speed); wxWindow *okb = d->FindWindow(wxID_OK); if(okb) { // may be gone if style guidlines removed it net_link_handler.okb = wxStaticCast(okb, wxButton); @@ -2995,7 +2965,6 @@ bool MainFrame::InitMore(void) getlab("JoybusHostLab"); addbe(lab); gettc("JoybusHost", gopts.joybus_host); - tc->SetValidator(IPHostValidator(&gopts.joybus_host)); addbe(tc); getcbbe("Link", gopts.gba_link_enabled); getcbb("RFU", gopts.rfu_enabled);