/* sv_entmap.c (description) Copyright (C) 1996-1997 Id Software, Inc. 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: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ static const char rcsid[] = "$Id$"; #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "server.h" /* SV_EntMap_Get Returns the network version of a given entity number for the given client, allocating one if necesary, or -1 if none are available. */ int SV_EntMap_Get (entmap_t *entmap, int entnum) { int i; // return entnum; // FIXME: hack hack hack if (entnum < 0 || entnum >= MAX_EDICTS) Sys_Error ("SV_EntMap_Get: invalid entnum: %d", entnum); i = entmap->internal[entnum]; if (i != ENTMAP_INVALID) { // check if already mapped SV_EntMap_Touch (entmap, i); return i; } // not mapped, so try to find an available number to map to for (i = 0; entmap->network[i].internal != ENTMAP_INVALID; i++) ; if (i == sizeof (entmap->network) / sizeof (entmap_item_t) - 1) return ENTMAP_INVALID; // no mappings available (ugh) SV_EntMap_Add (entmap, entnum, i); return i; } /* SV_EntMap_LookupByNetwork Returns the internal entity number assosiated with a network number, or ENTMAP_INVALID if there isn't one. */ int SV_EntMap_LookupByNetwork (entmap_t *entmap, int netnum) { int i; if (netnum < 0 || netnum >= MAX_NET_EDICTS) Sys_Error ("SV_EntMap_LookupByNetwork: invalid netnum: %d", netnum); i = entmap->network[netnum].internal; return i; } /* SV_EntMap_LookupByInternal Returns the network entity number assosiated with an internal number, or ENTMAP_INVALID if there isn't one. */ int SV_EntMap_LookupByInternal (entmap_t *entmap, int entnum) { int i; if (entnum < 0 || entnum >= MAX_EDICTS) Sys_Error ("SV_EntMap_LookupByInternal: invalid entnum: %d", entnum); i = entmap->internal[entnum]; return i; } /* SV_EntMap_Init Initializes an entmap. It does NOT release any previously allocated memory */ void SV_EntMap_Init (entmap_t *entmap) { int i; // setup world/clients for (i = 0; i <= MAX_CLIENTS; i++) { entmap->internal[i] = i; entmap->network[i].internal = i; entmap->network[i].usedtime = 0; } // clear the rest for (i = MAX_CLIENTS + 1; i < MAX_EDICTS; i++) entmap->internal[i] = ENTMAP_INVALID; for (i = MAX_CLIENTS + 1; i < sizeof (entmap->network) / sizeof (entmap_item_t); i++) { entmap->network[i].internal = ENTMAP_INVALID; entmap->network[i].usedtime = 0; } } /* SV_EntMap_Copy Copys the contents of one entmap to another. It does NOT release any previously allocated memory in the destination entmap. */ void SV_EntMap_Copy (entmap_t *dest, entmap_t *src) { // XXX: this'll be more useful when we dynamically allocate memory memcpy (dest, src, sizeof (entmap_t)); } /* SV_EntMap_Delete Releases all memory that was allocated in the entmap */ void SV_EntMap_Delete (entmap_t *entmap) { // XXX: make useful memset (entmap, 0xAF, sizeof (entmap_t)); // for debugging } /* SV_EntMap_Add Makes the given network number map to the given internal number */ void SV_EntMap_Add (entmap_t *entmap, int entnum, int netnum) { if (entnum < 0 || entnum >= MAX_EDICTS || netnum < 0 || netnum >= MAX_NET_EDICTS) Sys_Error ("SV_EntMap_Add: invalid entnum/netnum: %d/%d", entnum, netnum); entmap->network[netnum].internal = entnum; entmap->internal[entnum] = netnum; entmap->network[netnum].usedtime = realtime; } /* SV_EntMap_Touch Updates the "last used" time on the mapping */ void SV_EntMap_Touch (entmap_t *entmap, int netnum) { if (netnum < 0 || netnum >= MAX_NET_EDICTS) Sys_Error ("SV_EntMap_Touch: invalid netnum: %d", netnum); if (entmap->network[netnum].internal == ENTMAP_INVALID) Sys_Error ("SV_EntMap_Touch: netnum not mapped: %d", netnum); // update the usedtime, if it's not a permanent mapping if (entmap->network[netnum].usedtime) entmap->network[netnum].usedtime = realtime; } /* SV_EntMap_Clean Removes all mappings that havn't been used in the given number of seconds */ void SV_EntMap_Clean (entmap_t *entmap, float window) { int i; for (i = MAX_CLIENTS + 1; i < sizeof (entmap->network) / sizeof (entmap_item_t); i++) if (entmap->network[i].internal != ENTMAP_INVALID && entmap->network[i].usedtime && entmap->network[i].usedtime + window < realtime) { entmap->internal[entmap->network[i].internal] = ENTMAP_INVALID; entmap->network[i].internal = ENTMAP_INVALID; entmap->network[i].usedtime = 0; } } /* SV_EntMap_MakePermanent Makes the mapping for the given netnum permanent */ void SV_EntMap_MakePermanent (entmap_t *entmap, int netnum) { if (netnum < 0 || netnum >= MAX_NET_EDICTS) Sys_Error ("SV_EntMap_Touch: invalid netnum: %d", netnum); if (entmap->network[netnum].internal == ENTMAP_INVALID) Sys_Error ("SV_EntMap_Touch: netnum not mapped: %d", netnum); entmap->network[netnum].usedtime = 0; }