summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorSND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2013-02-22 07:21:16 +0000
committerSND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2013-02-22 07:21:16 +0000
commit475272e1981632d3a844f0323b3ee54cf1c420c9 (patch)
treed6d1352150777707736e64026d392d41b272df31 /plugins
parentcd8a6db7e6736696f77c7935dffb883aa5c2996a (diff)
downloadpcsxr-475272e1981632d3a844f0323b3ee54cf1c420c9.tar.gz
Link cable emulation for Linux.
pcsxr must be configured with --enable-sio1 option. Emulation accuracy is quite low, but all games work well. Around fifty games was tested. Port to Windows will be some later. git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@83091 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins')
-rw-r--r--plugins/bladesio1/Makefile.am20
-rwxr-xr-xplugins/bladesio1/cfg.c63
-rwxr-xr-xplugins/bladesio1/connection.c146
-rwxr-xr-xplugins/bladesio1/connection.h35
-rw-r--r--plugins/bladesio1/fifo.c124
-rw-r--r--plugins/bladesio1/fifo.h47
-rw-r--r--plugins/bladesio1/gui.c207
-rwxr-xr-xplugins/bladesio1/sio1.c596
-rwxr-xr-xplugins/bladesio1/sio1.h59
-rwxr-xr-xplugins/bladesio1/sio1.ui292
-rwxr-xr-xplugins/bladesio1/typedefs.h35
11 files changed, 1624 insertions, 0 deletions
diff --git a/plugins/bladesio1/Makefile.am b/plugins/bladesio1/Makefile.am
new file mode 100644
index 00000000..5b7fee43
--- /dev/null
+++ b/plugins/bladesio1/Makefile.am
@@ -0,0 +1,20 @@
+bindir = @libdir@/games/psemu/
+libdir = @libdir@/games/psemu/
+
+lib_LTLIBRARIES = libBladeSio1.la
+
+libBladeSio1_la_SOURCES = cfg.c sio1.c sio1.h fifo.c fifo.h connection.c connection.h
+libBladeSio1_la_LDFLAGS = -module -avoid-version
+
+AM_CPPFLAGS = -DLOCALE_DIR=\"${datadir}/locale/\" \
+ -DDATADIR=\"${datadir}/psemu/\" \
+ $(GTK3_CFLAGS) \
+ -I../../libpcsxcore -I../../include
+
+bin_PROGRAMS = cfgBladeSio1
+cfgBladeSio1_SOURCES = gui.c sio1.h
+cfgBladeSio1_LDADD = $(GTK3_LIBS)
+
+glade_DATA = sio1.ui
+gladedir = $(datadir)/psemu/
+EXTRA_DIST = $(glade_DATA)
diff --git a/plugins/bladesio1/cfg.c b/plugins/bladesio1/cfg.c
new file mode 100755
index 00000000..f830d7b3
--- /dev/null
+++ b/plugins/bladesio1/cfg.c
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "psxcommon.h"
+#include "psemu_plugin_defs.h"
+
+#include "sio1.h"
+
+/***************************************************************************/
+
+static const char configName[] = "bladesio1.cfg";
+
+Settings settings;
+
+/***************************************************************************/
+
+void settingsRead() {
+ FILE *file;
+
+ file = fopen(configName, "rb");
+ if(file) {
+ fread(&settings, 1, sizeof(settings), file);
+ fclose(file);
+ }
+ else {
+ settings.player = PLAYER_DISABLED;
+ strcpy(settings.ip, "127.0.0.1");
+ settings.port = 33307;
+ }
+}
+
+void settingsWrite() {
+ FILE *file;
+
+ file = fopen(configName, "wb");
+ if(file) {
+ fwrite(&settings, 1, sizeof(settings), file);
+ fclose(file);
+ }
+}
+
+/***************************************************************************/
diff --git a/plugins/bladesio1/connection.c b/plugins/bladesio1/connection.c
new file mode 100755
index 00000000..28478d80
--- /dev/null
+++ b/plugins/bladesio1/connection.c
@@ -0,0 +1,146 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#if defined _WINDOWS
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#endif
+
+#include "typedefs.h"
+#include "psemu_plugin_defs.h"
+
+#include "sio1.h"
+#include "connection.h"
+
+/***************************************************************************/
+
+static int serversock = -1;
+static int clientsock = -1;
+static struct sockaddr_in address;
+static struct hostent *hostinfo;
+
+/***************************************************************************/
+
+s32 connectionOpen() {
+ switch(settings.player) {
+ case PLAYER_MASTER: {
+ int reuse_addr = 1;
+ int one = 1;
+
+ serversock = socket(AF_INET, SOCK_STREAM, 0);
+ if(serversock == -1) {
+ fprintf(stderr, "[SIO1] ERROR: server socket()\n");
+ return -1;
+ }
+
+ setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_addr, sizeof(reuse_addr));
+ setsockopt(serversock, IPPROTO_TCP, TCP_NODELAY, (const char*)&one, sizeof(one));
+
+ memset(&address, 0, sizeof(address));
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = INADDR_ANY;
+ address.sin_port = settings.port;
+
+ if(bind(serversock,(struct sockaddr*)&address,sizeof(address)) == -1) {
+ fprintf(stderr, "[SIO1] ERROR: server bind()\n");
+ return -1;
+ }
+
+ if(listen(serversock, 1) != 0) {
+ fprintf(stderr, "[SIO1] ERROR: server listen()\n");
+ return -1;
+ }
+
+ clientsock = -1;
+ while(clientsock < 0)
+ clientsock = accept(serversock, NULL, NULL);
+ }
+ break;
+ case PLAYER_SLAVE: {
+ int one = 1;
+
+ memset(&address, 0, sizeof(address));
+ hostinfo = gethostbyname(settings.ip);
+ address.sin_family = AF_INET;
+ address.sin_addr = *((struct in_addr*)hostinfo->h_addr);
+ address.sin_port = settings.port;
+
+ clientsock = socket(AF_INET, SOCK_STREAM, 0);
+ if(clientsock == -1) {
+ fprintf(stderr, "[SIO1] ERROR: client socket()\n");
+ return -1;
+ }
+
+ setsockopt(clientsock, IPPROTO_TCP, TCP_NODELAY, (const char*)&one, sizeof(one));
+
+ if(connect(clientsock,(struct sockaddr*)&address,sizeof(address)) != 0) {
+ fprintf(stderr, "[SIO1] ERROR: client connect(%s)\n", settings.ip);
+ return -1;
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+void connectionClose() {
+ if(clientsock >= 0) {
+ close(clientsock);
+ clientsock = -1;
+ }
+
+ if(serversock >= 0) {
+ close(serversock);
+ serversock = -1;
+ }
+}
+
+/***************************************************************************/
+
+size_t connectionSend(u8 *pdata, s32 size) {
+ size_t bytes = 0;
+
+ if(clientsock >= 0)
+ if((bytes = send(clientsock, (const char*)pdata, size, 0)) < 0)
+ return 0;
+
+ return bytes;
+}
+
+size_t connectionRecv(u8 *pdata, s32 size) {
+ size_t bytes = 0;
+
+ if(clientsock >= 0)
+ if((bytes = recv(clientsock, (char*)pdata, size, 0)) < 0)
+ return 0;
+
+ return bytes;
+}
+
+/***************************************************************************/
diff --git a/plugins/bladesio1/connection.h b/plugins/bladesio1/connection.h
new file mode 100755
index 00000000..aec71b5a
--- /dev/null
+++ b/plugins/bladesio1/connection.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef _CONNECTION_H_
+#define _CONNECTION_H_
+
+/***************************************************************************/
+
+extern s32 connectionOpen();
+extern void connectionClose();
+
+/***************************************************************************/
+
+extern size_t connectionSend(u8 *pdata, s32 size);
+extern size_t connectionRecv(u8 *pdata, s32 size);
+
+/***************************************************************************/
+
+#endif // _CONNECTION_H_
diff --git a/plugins/bladesio1/fifo.c b/plugins/bladesio1/fifo.c
new file mode 100644
index 00000000..3d3a78c7
--- /dev/null
+++ b/plugins/bladesio1/fifo.c
@@ -0,0 +1,124 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "typedefs.h"
+#include "psemu_plugin_defs.h"
+
+#include "sio1.h"
+#include "fifo.h"
+#include "connection.h"
+
+/***************************************************************************/
+
+static u8 _buf[8];
+static s32 _indexw;
+static s32 _indexr;
+static s32 _employment;
+static s32 _overrun;
+
+/***************************************************************************/
+
+void fifoOpen() {
+ fifoReset();
+ fifoResetErr();
+}
+
+void fifoClose() {
+}
+
+/***************************************************************************/
+
+void fifoReset() {
+ _indexw = 0;
+ _indexr = 0;
+ _employment = 0;
+}
+
+void fifoResetErr() {
+ _overrun = 0;
+}
+
+/***************************************************************************/
+
+s32 fifoEmployment() {
+ return _employment;
+}
+
+s32 fifoEmpty() {
+ return (_employment == 0);
+}
+
+s32 fifoFull() {
+ return (_employment == 8);
+}
+
+s32 fifoOverrun() {
+ return _overrun;
+}
+
+/***************************************************************************/
+
+void fifoPush(u8 data) {
+ if(_employment > 8) {
+ _overrun = 1;
+
+ --_indexw;
+ if(_indexw < 0)
+ _indexw += 8;
+
+ --_employment;
+ }
+
+ _buf[_indexw] = data;
+
+ ++_indexw;
+ if(_indexw >= 8)
+ _indexw -= 8;
+
+ ++_employment;
+}
+
+void fifoPeek(u8 *data) {
+ if(_employment <= 0)
+ *data = 0;
+ else
+ *data = _buf[_indexr];
+}
+
+void fifoPop(u8 *data) {
+ if(_employment <= 0) {
+ *data = 0;
+ }
+ else {
+ *data = _buf[_indexr];
+
+ ++_indexr;
+ if(_indexr >= 8)
+ _indexr -= 8;
+
+ --_employment;
+ }
+}
+
+/***************************************************************************/
diff --git a/plugins/bladesio1/fifo.h b/plugins/bladesio1/fifo.h
new file mode 100644
index 00000000..d6db1373
--- /dev/null
+++ b/plugins/bladesio1/fifo.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef _FIFO_H_
+#define _FIFO_H_
+
+/***************************************************************************/
+
+extern void fifoOpen();
+extern void fifoClose();
+
+extern void fifoReset();
+extern void fifoResetErr();
+
+/***************************************************************************/
+
+extern s32 fifoEmployment();
+extern s32 fifoEmpty();
+extern s32 fifoFull();
+
+extern s32 fifoOverrun();
+
+/***************************************************************************/
+
+extern void fifoPush(u8 data);
+extern void fifoPeek(u8 *data);
+extern void fifoPop(u8 *data);
+
+/***************************************************************************/
+
+#endif // _FIFO_H_
diff --git a/plugins/bladesio1/gui.c b/plugins/bladesio1/gui.c
new file mode 100644
index 00000000..1ac5e0a8
--- /dev/null
+++ b/plugins/bladesio1/gui.c
@@ -0,0 +1,207 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <linux/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include "psxcommon.h"
+#include "psemu_plugin_defs.h"
+
+#include "cfg.c"
+#include "sio1.h"
+
+/***************************************************************************/
+
+#define MAXINTERFACES 16
+
+void sockGetIP(char *IPAddress) {
+ int fd, intrface;
+ struct ifreq buf[MAXINTERFACES];
+ struct ifconf ifc;
+ struct sockaddr_in addr;
+
+ strcpy(IPAddress, "127.0.0.1");
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = (caddr_t)buf;
+ if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc)) {
+ intrface = ifc.ifc_len / sizeof(struct ifreq);
+ while (intrface-- > 0) {
+ if (!(ioctl(fd, SIOCGIFADDR, (char *)&buf[intrface]))) {
+ memcpy(&addr, &(buf[intrface].ifr_addr), sizeof(addr));
+ strcpy(IPAddress, inet_ntoa(addr.sin_addr));
+ break;
+ }
+ }
+ }
+ close(fd);
+ }
+}
+
+void cfgSysMessage(const char *fmt, ...) {
+ GtkWidget *MsgDlg;
+ va_list list;
+ char msg[512];
+
+ va_start(list, fmt);
+ vsprintf(msg, fmt, list);
+ va_end(list);
+
+ if (msg[strlen(msg) - 1] == '\n') msg[strlen(msg) - 1] = 0;
+
+ MsgDlg = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("NetPlay"));
+ gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(MsgDlg), "%s", msg);
+
+ gtk_dialog_run(GTK_DIALOG(MsgDlg));
+ gtk_widget_destroy(MsgDlg);
+}
+
+void OnCopyIP(GtkWidget *widget, gpointer user_data) {
+ char str[256];
+
+ sockGetIP(str);
+ gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), str, strlen(str));
+ cfgSysMessage(_("IP %s"), str);
+}
+
+/***************************************************************************/
+
+static
+s32 configure() {
+ GtkBuilder *builder;
+ GtkWidget *widget, *MainWindow;
+
+ builder = gtk_builder_new();
+
+ if (!gtk_builder_add_from_file(builder, DATADIR "sio1.ui", NULL)) {
+ g_warning("We could not load the interface!");
+ return 0;
+ }
+
+ settingsRead();
+
+ MainWindow = gtk_builder_get_object(builder, "dlgStart");
+ gtk_window_set_title(GTK_WINDOW(MainWindow), _("Link Cable Configuration"));
+
+ widget = gtk_builder_get_object(builder, "btnCopyIP");
+ g_signal_connect_data(G_OBJECT(widget), "clicked",
+ G_CALLBACK(OnCopyIP), NULL, NULL, G_CONNECT_AFTER);
+
+ switch(settings.player) {
+ case PLAYER_DISABLED:
+ widget = gtk_builder_get_object(builder, "rbDisabled");
+ break;
+ case PLAYER_MASTER:
+ widget = gtk_builder_get_object(builder, "rbServer");
+ break;
+ case PLAYER_SLAVE:
+ widget = gtk_builder_get_object(builder, "rbClient");
+ break;
+ }
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
+
+ widget = gtk_builder_get_object(builder, "tbServerIP");
+ gtk_entry_set_text(GTK_ENTRY(widget), settings.ip);
+
+ widget = gtk_builder_get_object(builder, "tbPort");
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), settings.port);
+
+ if(gtk_dialog_run(GTK_DIALOG(MainWindow)) == GTK_RESPONSE_OK) {
+ widget = gtk_builder_get_object(builder, "tbServerIP");
+ strncpy(settings.ip, gtk_entry_get_text(GTK_ENTRY(widget)), sizeof(settings.ip) - 1);
+
+ widget = gtk_builder_get_object(builder, "tbPort");
+ settings.port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+
+ widget = gtk_builder_get_object(builder, "rbDisabled");
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ settings.player = PLAYER_DISABLED;
+ }
+ else {
+ widget = gtk_builder_get_object(builder, "rbServer");
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ settings.player = PLAYER_MASTER;
+ } else {
+ settings.player = PLAYER_SLAVE;
+ }
+ }
+
+ settingsWrite();
+
+ gtk_widget_destroy(MainWindow);
+ return 1;
+ }
+
+ gtk_widget_destroy(MainWindow);
+
+ return 0;
+}
+
+static
+s32 about() {
+ const char *authors[]= {"edgbla <edgbla@yandex.ru>", NULL};
+ GtkWidget *widget;
+
+ widget = gtk_about_dialog_new();
+ gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(widget), "Link Cable");
+ gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), "1.0");
+ gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(widget), authors);
+ gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget), "http://www.codeplex.com/pcsxr/");
+
+ gtk_dialog_run(GTK_DIALOG(widget));
+ gtk_widget_destroy(widget);
+}
+
+/***************************************************************************/
+
+int main(int argc, char *argv[]) {
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ textdomain(GETTEXT_PACKAGE);
+#endif
+
+ gtk_init(&argc, &argv);
+
+ if(argc > 1) {
+ if(!strcmp(argv[1], "configure"))
+ return configure();
+ if(!strcmp(argv[1], "about"))
+ return about();
+ }
+
+ return 0;
+}
+
+/***************************************************************************/
diff --git a/plugins/bladesio1/sio1.c b/plugins/bladesio1/sio1.c
new file mode 100755
index 00000000..3fb91cca
--- /dev/null
+++ b/plugins/bladesio1/sio1.c
@@ -0,0 +1,596 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#if defined _WINDOWS
+#elif defined _MACOSX
+#else
+#include <sys/stat.h>
+#endif
+
+#include "typedefs.h"
+#include "psemu_plugin_defs.h"
+
+#include "sio1.h"
+#include "fifo.h"
+#include "connection.h"
+
+/***************************************************************************/
+
+//#define SIO1_DEBUG 1
+
+static char *pluginName = N_("sio1Blade");
+
+static const unsigned char version = 1;
+static const unsigned char revision = 1;
+static const unsigned char build = 1;
+
+static void (CALLBACK *irqCallback)() = 0;
+
+Settings settings;
+
+/* sio status flags.
+ */
+enum {
+ SR_TXRDY = 0x0001,
+ SR_RXRDY = 0x0002,
+ SR_TXU = 0x0004,
+ SR_PERROR = 0x0008,
+ SR_OE = 0x0010,
+ SR_FE = 0x0020,
+ SR_0040 = 0x0040, // ?
+ SR_DSR = 0x0080,
+ SR_CTS = 0x0100,
+ SR_IRQ = 0x0200
+};
+
+/* sio mode flags.
+ */
+enum {
+ MR_BR_1 = 0x0001,
+ MR_BR_16 = 0x0002,
+ MR_BR_64 = 0x0003,
+ MR_CHLEN_5 = 0x0000,
+ MR_CHLEN_6 = 0x0004,
+ MR_CHLEN_7 = 0x0008,
+ MR_CHLEN_8 = 0x000C,
+ MR_PEN = 0x0010,
+ MR_P_EVEN = 0x0020,
+ MR_SB_00 = 0x0000,
+ MR_SB_01 = 0x0040,
+ MR_SB_10 = 0x0080,
+ MR_SB_11 = 0x00C0
+};
+
+/* sio control flags.
+ */
+enum {
+ CR_TXEN = 0x0001,
+ CR_DTR = 0x0002,
+ CR_RXEN = 0x0004,
+ CR_0008 = 0x0008, // ?
+ CR_ERRRST = 0x0010,
+ CR_RTS = 0x0020,
+ CR_RST = 0x0040,
+ CR_0080 = 0x0080, // HM?
+ CR_BUFSZ_1 = 0x0000,
+ CR_BUFSZ_2 = 0x0100,
+ CR_BUFSZ_4 = 0x0200,
+ CR_BUFSZ_8 = 0x0300,
+ CR_TXIEN = 0x0400,
+ CR_RXIEN = 0x0800,
+ CR_DSRIEN = 0x1000,
+ CR_2000 = 0x2000 // CTSIEN?
+};
+
+static u8 fifoIrqVals[] = {1, 2, 4, 8};
+static s32 slaveDelay = 1;
+
+static u16 statReg; // 0x1f801054: 0x185 SR_TXRDY | SR_TXU | SR_DSR | SR_CTS
+static u16 modeReg; // 0x1f801058: 0x0
+static u16 ctrlReg; // 0x1f80105A: 0x0
+static u16 baudReg; // 0x1f80105E: 0x0
+
+typedef struct EXC_DATA {
+ u16 reg;
+ u8 len;
+ u8 data;
+} EXC_DATA;
+
+/***************************************************************************/
+
+long CALLBACK SIO1init() {
+ return 0;
+}
+
+long CALLBACK SIO1shutdown() {
+ return 0;
+}
+
+/***************************************************************************/
+
+long CALLBACK SIO1open(unsigned long *gpuDisp) {
+ settingsRead();
+
+ statReg = SR_TXRDY | SR_TXU | SR_DSR | SR_CTS;
+ modeReg = 0x0000;
+ ctrlReg = 0x0000;
+ baudReg = 0x0000;
+
+ fifoOpen();
+
+ if(connectionOpen() < 0)
+ settings.player = PLAYER_DISABLED;
+
+ return 0;
+}
+
+long CALLBACK SIO1close() {
+ fifoClose();
+ connectionClose();
+
+ return 0;
+}
+
+/***************************************************************************/
+
+void CALLBACK SIO1pause() {
+}
+
+void CALLBACK SIO1resume() {
+}
+
+/***************************************************************************/
+
+long CALLBACK SIO1keypressed(int key) {
+ return 0;
+}
+
+/***************************************************************************/
+
+void Exchange(s32 data) {
+ EXC_DATA exc_data_send, exc_data_recv;
+
+ if(settings.player == PLAYER_DISABLED)
+ return;
+
+ if(slaveDelay && settings.player == PLAYER_SLAVE) {
+ EXC_DATA exc_data_empty;
+ s32 count;
+
+ memset(&exc_data_empty, 0x00, sizeof(exc_data_empty));
+ exc_data_empty.reg = CR_DTR | CR_RTS;
+
+ for(count = 0; count < 4; ++count) {
+ connectionRecv((u8*)&exc_data_recv, sizeof(exc_data_recv));
+ connectionSend((u8*)&exc_data_empty, sizeof(exc_data_empty));
+ }
+
+ slaveDelay = 0;
+ return;
+ }
+
+ memset(&exc_data_send, 0x00, sizeof(exc_data_send));
+ memset(&exc_data_recv, 0x00, sizeof(exc_data_recv));
+
+ exc_data_send.reg = ctrlReg;
+ exc_data_send.len = 0;
+
+ if(data >= 0) {
+ statReg |= SR_TXRDY | SR_TXU;
+
+ exc_data_send.len = 1;
+ exc_data_send.data = data;
+
+ if(ctrlReg & CR_TXIEN) {
+ if(!(statReg & SR_IRQ)) {
+#if defined SIO1_DEBUG
+ printf("irqCallback() : CR_TXIEN\n");
+#endif
+ irqCallback();
+ statReg |= SR_IRQ;
+ }
+ }
+ }
+
+ if(settings.player == PLAYER_MASTER) {
+ connectionSend((u8*)&exc_data_send, sizeof(exc_data_send));
+ connectionRecv((u8*)&exc_data_recv, sizeof(exc_data_recv));
+ }
+ else {
+ connectionRecv((u8*)&exc_data_recv, sizeof(exc_data_recv));
+ connectionSend((u8*)&exc_data_send, sizeof(exc_data_send));
+ }
+
+ if(exc_data_recv.reg & CR_DTR)
+ statReg |= SR_DSR;
+ else
+ statReg &= ~SR_DSR;
+
+ if(exc_data_recv.reg & CR_RTS)
+ statReg |= SR_CTS;
+ else
+ statReg &= ~SR_CTS;
+
+ if(exc_data_recv.len) {
+ fifoPush(exc_data_recv.data);
+
+#if defined SIO1_DEBUG
+ printf("data recieved : %.2x (%i)\n", exc_data_recv.data, fifoEmployment());
+#endif
+ }
+
+ if(ctrlReg & CR_RXIEN) {
+ if(fifoEmployment() == fifoIrqVals[(ctrlReg >> 8) & 0x03]) {
+ if(!(statReg & SR_IRQ)) {
+#if defined SIO1_DEBUG
+ printf("irqCallback() : CR_RXIEN\n");
+#endif
+ irqCallback();
+ statReg |= SR_IRQ;
+ }
+ }
+ }
+
+ if(fifoOverrun()) {
+#if defined SIO1_DEBUG
+ printf("Overrun\n");
+#endif
+ statReg |= SR_OE;
+ }
+
+ // FIXME:
+ if(fifoEmpty())
+ statReg &= ~SR_RXRDY;
+ else
+ statReg |= SR_RXRDY;
+
+ if(ctrlReg & CR_DSRIEN) {
+ if(statReg & SR_DSR) {
+ if(!(statReg & SR_IRQ)) {
+#if defined SIO1_DEBUG
+ printf("irqCallback() : CR_DSRIEN\n");
+#endif
+ irqCallback();
+ statReg |= SR_IRQ;
+ }
+ }
+ }
+}
+
+/***************************************************************************/
+
+/* Write.
+ */
+
+void CALLBACK SIO1writeData8(u8 data) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeData8(%.2x)\n", data);
+#endif
+ Exchange(data);
+}
+
+void CALLBACK SIO1writeData16(u16 data) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeData16(%.4x)\n", data);
+#endif
+ Exchange(data & 0xff);
+}
+
+void CALLBACK SIO1writeData32(u32 data) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeData32(%.8x)\n", data);
+#endif
+ Exchange(data & 0xff);
+}
+
+void CALLBACK SIO1writeStat16(u16 stat) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeStat16(%.4x)\n", stat);
+#endif
+ Exchange(-1);
+}
+
+void CALLBACK SIO1writeStat32(u32 stat) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeStat32(%.8x)\n", stat);
+#endif
+ SIO1writeStat16(stat);
+}
+
+void CALLBACK SIO1writeMode16(u16 mode) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeMode16(%.4x)\n", mode);
+#endif
+ modeReg = mode;
+ Exchange(-1);
+}
+
+void CALLBACK SIO1writeMode32(u32 mode) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeMode32(%.8x)\n", mode);
+#endif
+ SIO1writeMode16(mode);
+}
+
+void CALLBACK SIO1writeCtrl16(u16 ctrl) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeCtrl16(%.4x)\n", ctrl);
+#endif
+ u16 ctrlSaved = ctrlReg;
+
+ ctrlReg = ctrl;
+
+ if(ctrlReg & CR_ERRRST) {
+ ctrlReg &= ~CR_ERRRST;
+ statReg &= ~(SR_PERROR | SR_OE | SR_FE | SR_IRQ);
+
+ fifoResetErr();
+ }
+
+ if(ctrlReg & CR_RST) {
+ statReg &= ~SR_IRQ;
+ statReg |= SR_TXRDY | SR_TXU;
+ modeReg = 0;
+ ctrlReg = 0;
+ baudReg = 0;
+ }
+
+ // FIXME: buffer not cleared and overrun possible, but flag must be cleared.
+ //if(!(ctrlReg & CR_RXEN))
+ // statReg &= ~SR_RXRDY;
+
+ // FIXME: ugly hack for C&C: RA and C&C: RAR.
+ if(((ctrlReg >> 8) & 0x03) != ((ctrlSaved >> 8) & 0x03))
+ fifoReset();
+
+ // FIXME: move to Exchange.
+ if(ctrlReg & CR_TXIEN) {
+ if(!(statReg & SR_IRQ)) {
+#if defined SIO1_DEBUG
+ printf("irqCallback() : ctrl CR_TXIEN\n");
+#endif
+ irqCallback();
+ statReg |= SR_IRQ;
+ }
+ }
+
+ Exchange(-1);
+}
+
+void CALLBACK SIO1writeCtrl32(u32 ctrl) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeCtrl32(%.8x)\n", ctrl);
+#endif
+ SIO1writeCtrl16(ctrl);
+}
+
+void CALLBACK SIO1writeBaud16(u16 baud) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeBaud16(%.4x)\n", baud);
+#endif
+ baudReg = baud;
+ Exchange(-1);
+}
+
+void CALLBACK SIO1writeBaud32(u32 baud) {
+#if defined SIO1_DEBUG
+ printf("SIO1writeBaud32(%.8x)\n", baud);
+#endif
+ SIO1writeBaud16(baud);
+}
+
+/* Read.
+ */
+
+u8 CALLBACK SIO1readData8() {
+ u8 data[1];
+
+ fifoPop(&data[0]);
+ Exchange(-1);
+
+#if defined SIO1_DEBUG
+ printf("SIO1readData8() : %.2x\n", data[0]);
+#endif
+
+ return *(u8*)data;
+}
+
+u16 CALLBACK SIO1readData16() {
+ u8 data[2];
+
+ fifoPop(&data[0]);
+ fifoPeek(&data[1]);
+ Exchange(-1);
+
+#if defined SIO1_DEBUG
+ printf("SIO1readData16() : %.2x %.2x\n", data[0], data[1]);
+#endif
+
+ return *(u16*)data;
+}
+
+u32 CALLBACK SIO1readData32() {
+ u8 data[4];
+
+ fifoPop(&data[0]);
+ fifoPop(&data[1]);
+ fifoPop(&data[2]);
+ fifoPop(&data[3]);
+ Exchange(-1);
+
+#if defined SIO1_DEBUG
+ printf("SIO1readData32() : %.2x %.2x %.2x %.2x\n", data[0], data[1], data[2], data[3]);
+#endif
+
+ return *(u32*)data;
+}
+
+u16 CALLBACK SIO1readStat16() {
+ Exchange(-1);
+#if defined SIO1_DEBUG
+ printf("SIO1readStat16() : %.4x\n", statReg);
+#endif
+ return statReg;
+}
+
+u32 CALLBACK SIO1readStat32() {
+ Exchange(-1);
+#if defined SIO1_DEBUG
+ printf("SIO1readStat32() : %.4x\n", statReg);
+#endif
+ return statReg;
+}
+
+u16 CALLBACK SIO1readMode16() {
+ Exchange(-1);
+#if defined SIO1_DEBUG
+ printf("SIO1readMode16() : %.4x\n", modeReg);
+#endif
+ return modeReg;
+}
+
+u32 CALLBACK SIO1readMode32() {
+ Exchange(-1);
+#if defined SIO1_DEBUG
+ printf("SIO1readMode32() : %.4x\n", modeReg);
+#endif
+ return modeReg;
+}
+
+u16 CALLBACK SIO1readCtrl16() {
+ Exchange(-1);
+#if defined SIO1_DEBUG
+ printf("SIO1readCtrl16() : %.4x\n", ctrlReg);
+#endif
+ return ctrlReg;
+}
+
+u32 CALLBACK SIO1readCtrl32() {
+ Exchange(-1);
+#if defined SIO1_DEBU
+ printf("SIO1readCtrl32() : %.4x\n", ctrlReg);
+#endif
+ return ctrlReg;
+}
+
+u16 CALLBACK SIO1readBaud16() {
+ Exchange(-1);
+#if defined SIO1_DEBUG
+ printf("SIO1readBaud16() : %.4x\n", baudReg);
+#endif
+ return baudReg;
+}
+
+u32 CALLBACK SIO1readBaud32() {
+ Exchange(-1);
+#if defined SIO1_DEBUG
+ printf("SIO1readBaud32() : %.4x\n", baudReg);
+#endif
+ return baudReg;
+}
+
+/***************************************************************************/
+
+void CALLBACK SIO1update(uint32_t t) {
+ Exchange(-1);
+}
+
+void CALLBACK SIO1registerCallback(void (CALLBACK *callback)()) {
+ irqCallback = callback;
+}
+
+/***************************************************************************/
+
+unsigned long CALLBACK PSEgetLibType() {
+ return PSE_LT_SIO1;
+}
+
+char* CALLBACK PSEgetLibName() {
+ return _(pluginName);
+}
+
+unsigned long CALLBACK PSEgetLibVersion() {
+ return version << 16 | revision << 8 | build;
+}
+
+long CALLBACK SIO1test() {
+ return 0;
+}
+
+#if defined _WINDOWS
+#elif defined _MACOSX
+#else
+void ExecCfg(char *arg) {
+ char cfg[256];
+ struct stat buf;
+
+ strcpy(cfg, "./cfgBladeSio1");
+ if (stat(cfg, &buf) != -1) {
+ int pid = fork();
+ if (pid == 0) {
+ if (fork() == 0) {
+ execl(cfg, "cfgBladeSio1", arg, NULL);
+ }
+ exit(0);
+ } else if (pid > 0) {
+ waitpid(pid, NULL, 0);
+ }
+ return;
+ }
+
+ strcpy(cfg, "./cfg/cfgBladeSio1");
+ if (stat(cfg, &buf) != -1) {
+ int pid = fork();
+ if (pid == 0) {
+ if (fork() == 0) {
+ execl(cfg, "cfgBladeSio1", arg, NULL);
+ }
+ exit(0);
+ } else if (pid > 0) {
+ waitpid(pid, NULL, 0);
+ }
+ return;
+ }
+
+ fprintf(stderr, "cfgBladeSio1 file not found!\n");
+}
+#endif
+
+void CALLBACK SIO1about() {
+#if defined _WINDOWS
+#elif defined _MACOSX
+#else
+ ExecCfg("about");
+#endif
+}
+
+void CALLBACK SIO1configure() {
+#if defined _WINDOWS
+#elif defined _MACOSX
+#else
+ ExecCfg("configure");
+#endif
+}
+
+/***************************************************************************/
diff --git a/plugins/bladesio1/sio1.h b/plugins/bladesio1/sio1.h
new file mode 100755
index 00000000..f987fad2
--- /dev/null
+++ b/plugins/bladesio1/sio1.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef _SIO1_H_
+#define _SIO1_H_
+
+/***************************************************************************/
+
+#ifdef ENABLE_NLS
+#define _(s) dgettext(GETTEXT_PACKAGE, s)
+#define N_(s) (s)
+#else
+#define _(s) (s)
+#define N_(s) (s)
+#endif
+
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+enum {
+ PLAYER_DISABLED = 0,
+ PLAYER_MASTER,
+ PLAYER_SLAVE
+};
+
+typedef struct Settings {
+ s32 enabled;
+ s32 player;
+ char ip[32];
+ u16 port;
+} Settings;
+
+/******************************************************************************/
+
+extern void settingsRead();
+extern void settingsWrite();
+
+extern Settings settings;
+
+/***************************************************************************/
+
+#endif // _SIO1_H_
diff --git a/plugins/bladesio1/sio1.ui b/plugins/bladesio1/sio1.ui
new file mode 100755
index 00000000..0af7bfc1
--- /dev/null
+++ b/plugins/bladesio1/sio1.ui
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">65535</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="dlgStart">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window_position">center</property>
+ <property name="type_hint">normal</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="btnOk">
+ <property name="label" translatable="yes">OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnCancel">
+ <property name="label" translatable="yes">CANCEL</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Select here if you'll be Server (Player1) or Client (Player2).
+If you select Server you must Copy your IP address to the Clipboard and paste if (Ctrl+V) wherever the Client can see it.
+If you selected Client please enter the IP address the Server gave to you in the IP Address Control.</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">8</property>
+ <property name="row_spacing">5</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="btnCopyIP">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-copy</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Copy PC IP to Clipboard</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="tbServerIP">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">15</property>
+ <property name="invisible_char">●</property>
+ <signal name="activate" handler="on_tbServerIP_activate" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbServer">
+ <property name="label" translatable="yes">Server (Player1)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbClient">
+ <property name="label" translatable="yes">Client (Player2)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">rbServer</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbDisabled">
+ <property name="label" translatable="yes">Disabled</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">rbServer</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFixed" id="fixed1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Do not change if not necessary (remember it must be changed on both sides).</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Port Number</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="tbPort">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">btnOk</action-widget>
+ <action-widget response="-6">btnCancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/plugins/bladesio1/typedefs.h b/plugins/bladesio1/typedefs.h
new file mode 100755
index 00000000..452d2b3a
--- /dev/null
+++ b/plugins/bladesio1/typedefs.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Blade_Arma <edgbla@yandex.ru> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef _TYPEDEFS_H_
+#define _TYPEDEFS_H_
+
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+typedef intptr_t sptr;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef uintptr_t uptr;
+
+#endif // _TYPEDEFS_H_