From 59c7b8446575847ddf9b22b9b93a4eb58b7fe042 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 30 Oct 2005 19:56:15 +0000 Subject: Add foundation code for the new networking system Subversion-branch: /trunk/chocolate-doom Subversion-revision: 229 --- src/Makefile.am | 5 +- src/net_defs.h | 93 ++++++++++++++++++ src/net_io.c | 122 +++++++++++++++++++++++ src/net_io.h | 48 ++++++++++ src/net_loop.c | 227 +++++++++++++++++++++++++++++++++++++++++++ src/net_loop.h | 42 ++++++++ src/net_packet.c | 190 ++++++++++++++++++++++++++++++++++++ src/net_packet.h | 49 ++++++++++ src/net_sdl.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/net_sdl.h | 41 ++++++++ 10 files changed, 1102 insertions(+), 2 deletions(-) create mode 100644 src/net_defs.h create mode 100644 src/net_io.c create mode 100644 src/net_io.h create mode 100644 src/net_loop.c create mode 100644 src/net_loop.h create mode 100644 src/net_packet.c create mode 100644 src/net_packet.h create mode 100644 src/net_sdl.c create mode 100644 src/net_sdl.h diff --git a/src/Makefile.am b/src/Makefile.am index e6472901..8939131b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,8 +31,9 @@ d_textur.h i_system.h p_enemy.c p_telept.c r_things.c mmus2mid.h \ deh_defs.h deh_frame.c deh_main.c deh_ptr.c deh_text.c deh_thing.c \ deh_io.c deh_io.h deh_ammo.c deh_cheat.c deh_weapon.c \ deh_misc.c deh_misc.h deh_sound.c deh_main.h doomfeatures.h \ -w_merge.c w_merge.h deh_mapping.c deh_mapping.h - +w_merge.c w_merge.h deh_mapping.c deh_mapping.h \ +net_defs.h net_io.h net_loop.h net_packet.h net_sdl.h \ +net_io.c net_loop.c net_packet.c net_sdl.c if HAVE_WINDRES chocolate_doom_SOURCES=$(SOURCE_FILES) chocolate-doom-res.rc diff --git a/src/net_defs.h b/src/net_defs.h new file mode 100644 index 00000000..8478f1f3 --- /dev/null +++ b/src/net_defs.h @@ -0,0 +1,93 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_defs.h 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Definitions for use in networking code. +// +//----------------------------------------------------------------------------- + +#ifndef NET_DEFS_H +#define NET_DEFS_H + +#include "doomtype.h" + +typedef struct _net_module_s net_module_t; +typedef struct _net_packet_s net_packet_t; +typedef struct _net_addr_s net_addr_t; +typedef struct _net_context_s net_context_t; + +struct _net_packet_s +{ + byte *data; + int len; + int alloced; + int pos; +}; + +struct _net_module_s +{ + // Initialise this module for use as a client + + boolean (*InitClient)(void); + + // Initialise this module for use as a server + + boolean (*InitServer)(void); + + // Send a packet + + void (*SendPacket)(net_addr_t *addr, net_packet_t *packet); + + // Check for new packets to receive + // + // Returns true if packet received + + boolean (*RecvPacket)(net_addr_t **addr, net_packet_t **packet); + + // Converts an address to a string + + void (*AddrToString)(net_addr_t *addr, char *buffer, int buffer_len); + + // Free back an address when no longer in use + + void (*FreeAddress)(net_addr_t *addr); + + // Try to resolve a name to an address + + net_addr_t *(*ResolveAddress)(char *addr); +}; + +// net_addr_t + +struct _net_addr_s +{ + net_module_t *module; + void *handle; +}; + +#endif /* #ifndef NET_DEFS_H */ + diff --git a/src/net_io.c b/src/net_io.c new file mode 100644 index 00000000..b0a56025 --- /dev/null +++ b/src/net_io.c @@ -0,0 +1,122 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_io.c 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Network packet I/O. Base layer for sending/receiving packets, +// through the network module system +// +//----------------------------------------------------------------------------- + +#include "i_system.h" +#include "net_defs.h" +#include "net_io.h" +#include "z_zone.h" + +#define MAX_MODULES 16 + +struct _net_context_s +{ + net_module_t *modules[MAX_MODULES]; + int num_modules; +}; + +net_context_t *NET_NewContext(void) +{ + net_context_t *context; + + context = Z_Malloc(sizeof(net_context_t), PU_STATIC, 0); + context->num_modules = 0; + + return context; +} + +void NET_AddModule(net_context_t *context, net_module_t *module) +{ + if (context->num_modules >= MAX_MODULES) + { + I_Error("NET_AddModule: No more modules for context"); + } + + context->modules[context->num_modules] = module; + ++context->num_modules; +} + +net_addr_t *NET_ResolveAddress(net_context_t *context, char *addr) +{ + int i; + net_addr_t *result; + + result = NULL; + + for (i=0; inum_modules; ++i) + { + result = context->modules[i]->ResolveAddress(addr); + + if (result != NULL) + { + break; + } + } + + return result; +} + +void NET_SendPacket(net_addr_t *addr, net_packet_t *packet) +{ + addr->module->SendPacket(addr, packet); +} + +boolean NET_RecvPacket(net_context_t *context, + net_addr_t **addr, + net_packet_t **packet) +{ + int i; + + // check all modules for new packets + + for (i=0; inum_modules; ++i) + { + if (context->modules[i]->RecvPacket(addr, packet)) + { + return true; + } + } + + return false; +} + +void NET_AddrToString(net_addr_t *addr, char *buffer, int buffer_len) +{ + addr->module->AddrToString(addr, buffer, buffer_len); +} + +void NET_FreeAddress(net_addr_t *addr) +{ + addr->module->FreeAddress(addr); +} + + diff --git a/src/net_io.h b/src/net_io.h new file mode 100644 index 00000000..ca6f1562 --- /dev/null +++ b/src/net_io.h @@ -0,0 +1,48 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_io.h 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Network packet manipulation (net_packet_t) +// +//----------------------------------------------------------------------------- + +#ifndef NET_IO_H +#define NET_IO_H + +#include "net_defs.h" + +net_context_t *NET_NewContext(void); +void NET_AddModule(net_context_t *context, net_module_t *module); +void NET_SendPacket(net_addr_t *addr, net_packet_t *packet); +boolean NET_RecvPacket(net_context_t *context, net_addr_t **addr, + net_packet_t **packet); +void NET_AddrToString(net_addr_t *addr, char *buffer, int buffer_len); +void NET_FreeAddress(net_addr_t *addr); +net_addr_t *NET_ResolveAddress(net_context_t *context, char *address); + +#endif /* #ifndef NET_IO_H */ + diff --git a/src/net_loop.c b/src/net_loop.c new file mode 100644 index 00000000..5dc3bbf8 --- /dev/null +++ b/src/net_loop.c @@ -0,0 +1,227 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_loop.c 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Loopback network module for server compiled into the client +// +//----------------------------------------------------------------------------- + +#include +#include + +#include "i_system.h" +#include "net_defs.h" +#include "net_loop.h" +#include "net_packet.h" + +#define MAX_QUEUE_SIZE 16 + +typedef struct +{ + net_packet_t *packets[MAX_QUEUE_SIZE]; + int head, tail; +} packet_queue_t; + +static packet_queue_t client_queue; +static packet_queue_t server_queue; +static net_addr_t client_addr; +static net_addr_t server_addr; + +static void QueueInit(packet_queue_t *queue) +{ + queue->head = queue->tail = 0; +} + +static void QueuePush(packet_queue_t *queue, net_packet_t *packet) +{ + int new_tail; + + new_tail = (queue->tail + 1) % MAX_QUEUE_SIZE; + + if (new_tail == queue->head) + { + // queue is full + + return; + } + + queue->packets[queue->tail] = packet; + queue->tail = new_tail; +} + +static net_packet_t *QueuePop(packet_queue_t *queue) +{ + net_packet_t *packet; + + if (queue->tail == queue->head) + { + // queue empty + + return NULL; + } + + packet = queue->packets[queue->head]; + queue->head = (queue->head + 1) % MAX_QUEUE_SIZE; + + return packet; +} + +//----------------------------------------------------------------------------- +// +// Client end code +// +//----------------------------------------------------------------------------- + +static boolean NET_CL_InitClient(void) +{ + QueueInit(&client_queue); + client_addr.module = &net_loop_client_module; + + return true; +} + +static boolean NET_CL_InitServer(void) +{ + I_Error("NET_CL_InitServer: attempted to initialise client pipe end as a server!"); + return false; +} + +static void NET_CL_SendPacket(net_addr_t *addr, net_packet_t *packet) +{ + QueuePush(&server_queue, NET_PacketDup(packet)); +} + +static boolean NET_CL_RecvPacket(net_addr_t **addr, net_packet_t **packet) +{ + net_packet_t *popped; + + popped = QueuePop(&client_queue); + + if (popped != NULL) + { + *packet = popped; + *addr = &client_addr; + + return true; + } + + return false; +} + +static void NET_CL_AddrToString(net_addr_t *addr, char *buffer, int buffer_len) +{ + snprintf(buffer, buffer_len, "local server"); +} + +static void NET_CL_FreeAddress(net_addr_t *addr) +{ +} + +static net_addr_t *NET_CL_ResolveAddress(char *address) +{ + return &client_addr; +} + +net_module_t net_loop_client_module = +{ + NET_CL_InitClient, + NET_CL_InitServer, + NET_CL_SendPacket, + NET_CL_RecvPacket, + NET_CL_AddrToString, + NET_CL_FreeAddress, + NET_CL_ResolveAddress, +}; + +//----------------------------------------------------------------------------- +// +// Server end code +// +//----------------------------------------------------------------------------- + +static boolean NET_SV_InitClient(void) +{ + I_Error("NET_SV_InitClient: attempted to initialise server pipe end as a client!"); + return false; +} + +static boolean NET_SV_InitServer(void) +{ + QueueInit(&server_queue); + server_addr.module = &net_loop_server_module; + + return true; +} + +static void NET_SV_SendPacket(net_addr_t *addr, net_packet_t *packet) +{ + QueuePush(&client_queue, NET_PacketDup(packet)); +} + +static boolean NET_SV_RecvPacket(net_addr_t **addr, net_packet_t **packet) +{ + net_packet_t *popped; + + popped = QueuePop(&server_queue); + + if (popped != NULL) + { + *packet = popped; + *addr = &server_addr; + + return true; + } + + return false; +} + +static void NET_SV_AddrToString(net_addr_t *addr, char *buffer, int buffer_len) +{ + snprintf(buffer, buffer_len, "local client"); +} + +static void NET_SV_FreeAddress(net_addr_t *addr) +{ +} + +static net_addr_t *NET_SV_ResolveAddress(char *address) +{ + return &server_addr; +} + +net_module_t net_loop_server_module = +{ + NET_SV_InitClient, + NET_SV_InitServer, + NET_SV_SendPacket, + NET_SV_RecvPacket, + NET_SV_AddrToString, + NET_SV_FreeAddress, + NET_SV_ResolveAddress, +}; + + diff --git a/src/net_loop.h b/src/net_loop.h new file mode 100644 index 00000000..62ad4b17 --- /dev/null +++ b/src/net_loop.h @@ -0,0 +1,42 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_loop.h 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Loopback network module for server compiled into the client +// +//----------------------------------------------------------------------------- + +#ifndef NET_LOOP_H +#define NET_LOOP_H + +#include "net_defs.h" + +extern net_module_t net_loop_client_module; +extern net_module_t net_loop_server_module; + +#endif /* #ifndef NET_LOOP_H */ + diff --git a/src/net_packet.c b/src/net_packet.c new file mode 100644 index 00000000..923f92bc --- /dev/null +++ b/src/net_packet.c @@ -0,0 +1,190 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_packet.c 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Network packet manipulation (net_packet_t) +// +//----------------------------------------------------------------------------- + +#include +#include "net_packet.h" +#include "z_zone.h" + +net_packet_t *NET_NewPacket(int initial_size) +{ + net_packet_t *packet; + + packet = (net_packet_t *) Z_Malloc(sizeof(net_packet_t), PU_STATIC, 0); + + if (initial_size == 0) + initial_size = 256; + + packet->alloced = initial_size; + packet->data = Z_Malloc(initial_size, PU_STATIC, 0); + packet->len = 0; + packet->pos = 0; + + return packet; +} + +// duplicates an existing packet + +net_packet_t *NET_PacketDup(net_packet_t *packet) +{ + net_packet_t *newpacket; + + newpacket = NET_NewPacket(packet->len); + memcpy(newpacket->data, packet->data, packet->len); + newpacket->len = packet->len; + + return newpacket; +} + +void NET_FreePacket(net_packet_t *packet) +{ + Z_Free(packet->data); + Z_Free(packet); +} + +// Read a byte from the packet, returning true if read +// successfully + +boolean NET_ReadInt8(net_packet_t *packet, unsigned int *data) +{ + if (packet->pos + 1 > packet->len) + return false; + + *data = packet->data[packet->pos]; + + packet->pos += 1; + + return true; +} + +// Read a 16-bit integer from the packet, returning true if read +// successfully + +boolean NET_ReadInt16(net_packet_t *packet, unsigned int *data) +{ + byte *p; + + if (packet->pos + 2 > packet->len) + return false; + + p = packet->data + packet->pos; + + *data = (p[0] << 8) | p[1]; + packet->pos += 2; + + return true; +} + +// Read a 32-bit integer from the packet, returning true if read +// successfully + +boolean NET_ReadInt32(net_packet_t *packet, unsigned int *data) +{ + byte *p; + + if (packet->pos + 4 > packet->len) + return false; + + p = packet->data + packet->pos; + + *data = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + packet->pos += 4; + + return true; +} + +// Dynamically increases the size of a packet + +static void NET_IncreasePacket(net_packet_t *packet) +{ + byte *newdata; + + packet->alloced *= 2; + + newdata = Z_Malloc(packet->alloced, PU_STATIC, 0); + + memcpy(newdata, packet->data, packet->len); + + Z_Free(packet->data); + packet->data = newdata; +} + +// Write a single byte to the packet + +void NET_WriteInt8(net_packet_t *packet, unsigned int i) +{ + if (packet->len + 1 > packet->alloced) + NET_IncreasePacket(packet); + + packet->data[packet->len] = i; + packet->len += 1; +} + +// Write a 16-bit integer to the packet + +void NET_WriteInt16(net_packet_t *packet, unsigned int i) +{ + byte *p; + + if (packet->len + 2 > packet->alloced) + NET_IncreasePacket(packet); + + p = packet->data + packet->len; + + p[0] = (i >> 8) & 0xff; + p[1] = i & 0xff; + + packet->len += 2; +} + + +// Write a single byte to the packet + +void NET_WriteInt32(net_packet_t *packet, unsigned int i) +{ + byte *p; + + if (packet->len + 4 > packet->alloced) + NET_IncreasePacket(packet); + + p = packet->data + packet->len; + + p[0] = (i >> 24) & 0xff; + p[1] = (i >> 16) & 0xff; + p[2] = (i >> 8) & 0xff; + p[3] = i & 0xff; + + packet->len += 4; +} + + + + diff --git a/src/net_packet.h b/src/net_packet.h new file mode 100644 index 00000000..f2b19052 --- /dev/null +++ b/src/net_packet.h @@ -0,0 +1,49 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_packet.h 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Definitions for use in networking code. +// +//----------------------------------------------------------------------------- + +#ifndef NET_PACKET_H +#define NET_PACKET_H + +#include "net_defs.h" + +net_packet_t *NET_NewPacket(int initial_size); +net_packet_t *NET_PacketDup(net_packet_t *packet); +void NET_FreePacket(net_packet_t *packet); +boolean NET_ReadInt8(net_packet_t *packet, unsigned int *data); +boolean NET_ReadInt16(net_packet_t *packet, unsigned int *data); +boolean NET_ReadInt32(net_packet_t *packet, unsigned int *data); +void NET_WriteInt8(net_packet_t *packet, unsigned int i); +void NET_WriteInt16(net_packet_t *packet, unsigned int i); +void NET_WriteInt32(net_packet_t *packet, unsigned int i); + +#endif /* #ifndef NET_PACKET_H */ + diff --git a/src/net_sdl.c b/src/net_sdl.c new file mode 100644 index 00000000..5eb26dfe --- /dev/null +++ b/src/net_sdl.c @@ -0,0 +1,287 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_sdl.c 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Networking module which uses SDL_net +// +//----------------------------------------------------------------------------- + +#include +#include +#include + +#include "i_net.h" +#include "i_system.h" +#include "m_argv.h" +#include "net_defs.h" +#include "net_packet.h" +#include "net_sdl.h" +#include "z_zone.h" + +// +// NETWORKING +// + +#include + +static int port = 2342; +static UDPsocket udpsocket; +static UDPpacket *recvpacket; + +typedef struct +{ + net_addr_t net_addr; + IPaddress sdl_addr; +} addrpair_t; + +static addrpair_t **addr_table; +static int addr_table_size; + +// Initialises the address table + +static void NET_SDL_InitAddrTable(void) +{ + addr_table_size = 16; + + addr_table = Z_Malloc(sizeof(addrpair_t *) * addr_table_size, + PU_STATIC, 0); + memset(addr_table, 0, sizeof(addrpair_t *) * addr_table_size); +} + +static boolean AddressesEqual(IPaddress *a, IPaddress *b) +{ + return a->host == b->host + && a->port == b->port; +} + +// Finds an address by searching the table. If the address is not found, +// it is added to the table. + +static net_addr_t *NET_SDL_FindAddress(IPaddress *addr) +{ + addrpair_t *new_entry; + int empty_entry = -1; + int i; + + for (i=0; isdl_addr)) + { + return &addr_table[i]->net_addr; + } + + if (empty_entry < 0 && addr_table[i] == NULL) + empty_entry = i; + } + + // Was not found in list. We need to add it. + + // Is there any space in the table? If not, increase the table size + + if (empty_entry < 0) + { + addrpair_t **new_addr_table; + int new_addr_table_size; + + // after reallocing, we will add this in as the first entry + // in the new block of memory + + empty_entry = addr_table_size; + + // allocate a new array twice the size, init to 0 and copy + // the existing table in. replace the old table. + + new_addr_table_size = addr_table_size * 2; + new_addr_table = Z_Malloc(sizeof(addrpair_t *) * new_addr_table_size, + PU_STATIC, 0); + memset(new_addr_table, 0, sizeof(addrpair_t *) * new_addr_table_size); + memcpy(new_addr_table, addr_table, + sizeof(addrpair_t *) * addr_table_size); + Z_Free(addr_table); + addr_table = new_addr_table; + addr_table_size = new_addr_table_size; + } + + // Add a new entry + + new_entry = Z_Malloc(sizeof(addrpair_t), PU_STATIC, 0); + + new_entry->sdl_addr = *addr; + new_entry->net_addr.handle = &new_entry->sdl_addr; + new_entry->net_addr.module = &i_net_module; + + addr_table[empty_entry] = new_entry; + + return &new_entry->net_addr; +} + +static void NET_SDL_FreeAddress(net_addr_t *addr) +{ + int i; + + for (i=0; inet_addr) + { + Z_Free(addr_table[i]); + addr_table[i] = NULL; + return; + } + } + + I_Error("NET_SDL_FreeAddress: Attempted to remove an unused address!"); +} + +static boolean NET_SDL_InitClient(void) +{ + SDLNet_Init(); + + udpsocket = SDLNet_UDP_Open(0); + + if (udpsocket == NULL) + { + I_Error("NET_SDL_InitClient: Unable to open a socket!"); + } + + NET_SDL_InitAddrTable(); + recvpacket = SDLNet_AllocPacket(1500); + + return true; +} + +static boolean NET_SDL_InitServer(void) +{ + int p; + + p = M_CheckParm("-port"); + if (p > 0) + port = atoi(myargv[p+1]); + + SDLNet_Init(); + + udpsocket = SDLNet_UDP_Open(port); + + if (udpsocket == NULL) + { + I_Error("NET_SDL_InitServer: Unable to bind to port %i", port); + } + + NET_SDL_InitAddrTable(); + recvpacket = SDLNet_AllocPacket(1500); + + return true; +} + +static void NET_SDL_SendPacket(net_addr_t *addr, net_packet_t *packet) +{ + UDPpacket sdl_packet; + IPaddress *ip = (IPaddress *) addr->handle; + + sdl_packet.channel = 0; + sdl_packet.data = packet->data; + sdl_packet.len = packet->len; + sdl_packet.address = *ip; + + if (!SDLNet_UDP_Send(udpsocket, -1, &sdl_packet)) + { + I_Error("NET_SDL_SendPacket: Error transmitting packet: %s", + SDLNet_GetError()); + } +} + +static boolean NET_SDL_RecvPacket(net_addr_t **addr, net_packet_t **packet) +{ + int result; + + result = SDLNet_UDP_Recv(udpsocket, recvpacket); + + if (result < 0) + { + I_Error("NET_SDL_RecvPacket: Error receiving packet: %s", + SDLNet_GetError()); + } + + // no packets received + + if (result == 0) + return false; + + // Put the data into a new packet structure + + *packet = NET_NewPacket(recvpacket->len); + memcpy((*packet)->data, recvpacket->data, recvpacket->len); + (*packet)->len = recvpacket->len; + + // Address + + *addr = NET_SDL_FindAddress(&recvpacket->address); + + return true; +} + +void NET_SDL_AddrToString(net_addr_t *addr, char *buffer, int buffer_len) +{ + IPaddress *ip; + + ip = (IPaddress *) addr->handle; + + snprintf(buffer, buffer_len, + "%i.%i.%i.%i", + (ip->host >> 24) & 0xff, + (ip->host >> 16) & 0xff, + (ip->host >> 8) & 0xff, + ip->host & 0xff); +} + +net_addr_t *NET_SDL_ResolveAddress(char *address) +{ + IPaddress ip; + + if (SDLNet_ResolveHost(&ip, address, port)) + { + // unable to resolve + + return NULL; + } + + return NET_SDL_FindAddress(&ip); +} + +// Complete module + +net_module_t i_net_module = +{ + NET_SDL_InitClient, + NET_SDL_InitServer, + NET_SDL_SendPacket, + NET_SDL_RecvPacket, + NET_SDL_AddrToString, + NET_SDL_FreeAddress, + NET_SDL_ResolveAddress, +}; + diff --git a/src/net_sdl.h b/src/net_sdl.h new file mode 100644 index 00000000..edc3c000 --- /dev/null +++ b/src/net_sdl.h @@ -0,0 +1,41 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id: net_sdl.h 229 2005-10-30 19:56:15Z fraggle $ +// +// Copyright(C) 2005 Simon Howard +// +// 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., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// $Log$ +// Revision 1.1 2005/10/30 19:56:15 fraggle +// Add foundation code for the new networking system +// +// +// DESCRIPTION: +// Networking module which uses SDL_net +// +//----------------------------------------------------------------------------- + +#ifndef NET_SDL_H +#define NET_SDL_H + +#include "net_defs.h" + +extern net_module_t i_net_module; + +#endif /* #ifndef NET_SDL_H */ + -- cgit v1.2.3