/* * file network.c - shared functions for server and clients * * $Id: network.c,v 1.3 2004/05/14 10:00:35 alfie Exp $ * * Program XBLAST * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net) * * 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; or (at your option) * any later version * * This program is distributed in the hope that it will be entertaining, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILTY 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 */ #include "network.h" #include "atom.h" #include "cfg_game.h" /* * local types */ typedef struct _network_event { struct _network_event *next; XBNetworkEvent msg; unsigned id; } XBNetworkEventQueue; /* * local variables */ static XBNetworkEventQueue *queueFirst = NULL; static XBNetworkEventQueue *queueLast = NULL; static XBAtom hostPlayer[MAX_HOSTS][MAX_PLAYER]; #ifdef DEBUG_NETWORK /* * network event to string */ static const char * EventName (XBNetworkEvent msg) { switch (msg) { case XBNW_None: return "None"; case XBNW_Accepted: return "Accepted"; case XBNW_GameConfig: return "GameConfig"; case XBNW_RightPlayerConfig: return "RightPlayerConfig"; case XBNW_LeftPlayerConfig: return "LeftPlayerConfig"; case XBNW_Joy1PlayerConfig: return "Joy1PlayerConfig"; case XBNW_Joy2PlayerConfig: return "Joy2PlayerConfig"; case XBNW_Disconnected: return "Disconnected"; case XBNW_StartGame: return "StartGame"; case XBNW_EndOfInit: return "EndOfInit"; case XBNW_LevelConfig: return "LevelConfig"; case XBNW_SyncEndOfInit: return "SyncEndOfInit"; case XBNW_SyncLevelIntro: return "SyncLevelIntro"; case XBNW_SyncLevelResult: return "SyncLevelResult"; case XBNW_SyncLevelEnd: return "SyncLevelEnd"; case XBNW_SyncScoreboard: return "SyncScoreboard"; case XBNW_HostIsIn: return "HostIsIn"; case XBNW_HostIsOut: return "HostIsOut"; case XBNW_Error: return "Error"; case XBNW_PingReceived: return "PingReceived"; case XBNW_NetworkGame: return "NetworkGame"; default: return "unknown"; } } /* EventName */ #endif /* * add event to queue */ void Network_QueueEvent (XBNetworkEvent msg, unsigned id) { /* alloc data */ XBNetworkEventQueue *ptr = calloc (1, sizeof (*ptr) ); assert (ptr != NULL); /* set values */ ptr->msg = msg; ptr->id = id; /* put in queue */ if (queueLast != NULL) { queueLast->next = ptr; } else { queueFirst = ptr; } queueLast = ptr; #ifdef DEBUG_NETWORK Dbg_Out ("queue network event %s %u\n", EventName (msg), id); #endif } /* QueueEvent */ /* * check for event in queue */ XBNetworkEvent Network_GetEvent (unsigned *pId) { XBNetworkEventQueue *ptr; XBNetworkEvent msg; assert (NULL != pId); if (NULL == queueFirst) { return XBNW_None; } /* take element from list */ ptr = queueFirst; queueFirst = queueFirst->next; if (NULL == queueFirst) { queueLast = NULL; } /* set results */ msg = ptr->msg; *pId = ptr->id; #ifdef DEBUG_NETWORK Dbg_Out ("get network event %s %u\n", EventName (msg), *pId); #endif /* free element */ free (ptr); /* that's all */ return msg; } /* Network_GetEvent */ /* * get player atom */ XBAtom Network_GetPlayer (unsigned id, int player) { assert (id < MAX_HOSTS); assert (player < MAX_PLAYER); return hostPlayer[id][player]; } /* Network_GetPlayer */ /* * set player atom */ void Network_SetPlayer (unsigned id, int player, XBAtom atom) { assert (id < MAX_HOSTS); assert (player < MAX_PLAYER); hostPlayer[id][player] = atom; } /* Network_GetPlayer */ /* * receive game config from server */ XBAtom Network_ReceiveGameConfig (unsigned id, const char *data, int *pNum) { CFGGamePlayers cfgPlayers; XBAtom atom; unsigned i; char name[256]; char tmp[256]; assert (id < MAX_HOSTS); assert (pNum != NULL); atom = atomArrayHost0[id]; if (NULL != data) { AddToGameConfig (CT_Remote, atom, data); return ATOM_INVALID; } /* yes, all data received */ Dbg_Out ("peer send game (%u) config\n", id); (void) RetrieveGamePlayers (CT_Remote, atom, &cfgPlayers); *pNum = cfgPlayers.num; /* init player configs */ for (i = 0; i < *pNum; i ++) { assert (ATOM_INVALID != cfgPlayers.player[i]); strcpy (name, GUI_AtomToString (cfgPlayers.player[i]) ); strcpy (tmp, name); if (id != 0) { strcat (tmp, "@"); strcat (tmp, GetHostName (CT_Remote, atom) ); } Network_SetPlayer (id, i, GUI_StringToAtom (tmp) ); Dbg_Out ("hostPlayer[%u][%d] = \"%s\" \"%s\"\n", id, i, tmp, name); /* set name */ } /* clear other players */ for (; i < NUM_LOCAL_PLAYER; i ++) { Network_SetPlayer (id, i, ATOM_INVALID); } /* inform user interface */ Network_QueueEvent (XBNW_GameConfig, id); /* that's all */ return atom; } /* Network_ReceiveGameConfig */ /* * player config received from client */ XBAtom Network_ReceivePlayerConfig (CFGType cfgType, unsigned id, int player, const char *line) // XBCC { XBAtom atom; assert (id < MAX_HOSTS); assert (player < NUM_LOCAL_PLAYER); /* get player for config */ atom = Network_GetPlayer (id, player); if (ATOM_INVALID == atom) { return ATOM_INVALID; } /* check if there is any data */ if (NULL != line) { /* AddToPlayerConfig (CT_Remote, atom, line); */ AddToPlayerConfig (cfgType, atom, line); // XBCC /* ok that's all for now */ return ATOM_INVALID; } /* all data received */ /* create message */ if(cfgType!=CT_Central) { Dbg_Out ("peer id=%u send player %d config\n", id, player); switch (player) { case 0: Network_QueueEvent (XBNW_RightPlayerConfig, id); break; case 1: Network_QueueEvent (XBNW_LeftPlayerConfig, id); break; case 2: Network_QueueEvent (XBNW_Joy1PlayerConfig, id); break; case 3: Network_QueueEvent (XBNW_Joy2PlayerConfig, id); break; default: break; } } else { // Dbg_Out ("peer id=%u send player %d config\n", id, player); } return atom; } /* Network_ReceivePlayerConfig */ /* * end of file network.c */