diff options
| author | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2013-02-22 07:21:16 +0000 |
|---|---|---|
| committer | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2013-02-22 07:21:16 +0000 |
| commit | 475272e1981632d3a844f0323b3ee54cf1c420c9 (patch) | |
| tree | d6d1352150777707736e64026d392d41b272df31 /plugins | |
| parent | cd8a6db7e6736696f77c7935dffb883aa5c2996a (diff) | |
| download | pcsxr-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.am | 20 | ||||
| -rwxr-xr-x | plugins/bladesio1/cfg.c | 63 | ||||
| -rwxr-xr-x | plugins/bladesio1/connection.c | 146 | ||||
| -rwxr-xr-x | plugins/bladesio1/connection.h | 35 | ||||
| -rw-r--r-- | plugins/bladesio1/fifo.c | 124 | ||||
| -rw-r--r-- | plugins/bladesio1/fifo.h | 47 | ||||
| -rw-r--r-- | plugins/bladesio1/gui.c | 207 | ||||
| -rwxr-xr-x | plugins/bladesio1/sio1.c | 596 | ||||
| -rwxr-xr-x | plugins/bladesio1/sio1.h | 59 | ||||
| -rwxr-xr-x | plugins/bladesio1/sio1.ui | 292 | ||||
| -rwxr-xr-x | plugins/bladesio1/typedefs.h | 35 |
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_ |
