diff options
author | Tim Angus <tim@ngus.net> | 2001-07-25 19:51:49 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2001-07-25 19:51:49 +0000 |
commit | ede090a62f34f856e84904cad61670d5920cbc4d (patch) | |
tree | d2809d95b4c591d6722a708bc532d84e5f5599ef /src/game | |
parent | c4771d2a8707609f9908e4dcc5eb7cbb7c10ed36 (diff) |
QVM based MP3 player :)
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/bg_public.h | 1 | ||||
-rw-r--r-- | src/game/g_local.h | 3 | ||||
-rw-r--r-- | src/game/g_mem.c | 218 | ||||
-rw-r--r-- | src/game/q_shared.h | 5 |
4 files changed, 200 insertions, 27 deletions
diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 37a6d367..4e7c3c2b 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -1022,4 +1022,3 @@ qboolean BG_gotWeapon( int weapon, int stats[ ] );*/ void AxisToAngles( vec3_t axis[3], vec3_t angles); float arccos( float x ); #define Vector2Set(v, x, y) ((v)[0]=(x), (v)[1]=(y)) - diff --git a/src/game/g_local.h b/src/game/g_local.h index e1736309..3c49ab2f 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -728,12 +728,13 @@ void G_RunClient( gentity_t *ent ); qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 ); void Team_CheckDroppedItem( gentity_t *dropped ); - // // g_mem.c // void *G_Alloc( int size ); void G_InitMemory( void ); +void G_Free( void *ptr ); +void G_DefragmentMemory( void ); void Svcmd_GameMem_f( void ); // diff --git a/src/game/g_mem.c b/src/game/g_mem.c index 9d78e816..1e2dc24a 100644 --- a/src/game/g_mem.c +++ b/src/game/g_mem.c @@ -3,37 +3,203 @@ // // g_mem.c // +// Golliwog: All rewritten to allow deallocation -/* - * Portions Copyright (C) 2000-2001 Tim Angus - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1, 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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. - */ - -/* To assertain which portions are licensed under the LGPL and which are - * licensed by Id Software, Inc. please run a diff between the equivalent - * versions of the "Tremulous" modification and the unmodified "Quake3" - * game source code. - */ #include "g_local.h" +#define POOLSIZE (256 * 1024) +#define FREEMEMCOOKIE ((int)0xDEADBE3F) // Any unlikely to be used value +#define ROUNDBITS 31 // Round to 32 bytes -#define POOLSIZE (256 * 1024) +struct freememnode +{ + // Size of ROUNDBITS + int cookie, size; // Size includes node (obviously) + struct freememnode *prev, *next; +}; static char memoryPool[POOLSIZE]; +static struct freememnode *freehead; +static int freemem; + +void *G_Alloc( int size ) +{ + // Find a free block and allocate. + // Does two passes, attempts to fill same-sized free slot first. + + struct freememnode *fmn, *prev, *next, *smallest; + int allocsize, smallestsize; + char *endptr; + int *ptr; + + allocsize = ( size + sizeof(int) + ROUNDBITS ) & ~ROUNDBITS; // Round to 32-byte boundary + ptr = NULL; + + smallest = NULL; + smallestsize = POOLSIZE + 1; // Guaranteed not to miss any slots :) + for( fmn = freehead; fmn; fmn = fmn->next ) + { + if( fmn->cookie != FREEMEMCOOKIE ) + G_Error( "G_Alloc: Memory corruption detected!\n" ); + + if( fmn->size >= allocsize ) + { + // We've got a block + if( fmn->size == allocsize ) + { + // Same size, just remove + + prev = fmn->prev; + next = fmn->next; + if( prev ) + prev->next = next; // Point previous node to next + if( next ) + next->prev = prev; // Point next node to previous + if( fmn == freehead ) + freehead = next; // Set head pointer to next + ptr = (int *) fmn; + break; // Stop the loop, this is fine + } + else + { + // Keep track of the smallest free slot + if( fmn->size < smallestsize ) + { + smallest = fmn; + smallestsize = fmn->size; + } + } + } + } + + if( !ptr && smallest ) + { + // We found a slot big enough + smallest->size -= allocsize; + endptr = (char *) smallest + smallest->size; + ptr = (int *) endptr; + } + + if( ptr ) + { + freemem -= allocsize; + if( g_debugAlloc.integer ) + G_Printf( "G_Alloc of %i bytes (%i left)\n", allocsize, freemem ); + memset( ptr, 0, allocsize ); + *ptr++ = allocsize; // Store a copy of size for deallocation + return( (void *) ptr ); + } + + G_Error( "G_Alloc: failed on allocation of %i bytes\n", size ); + return( NULL ); +} + +void G_Free( void *ptr ) +{ + // Release allocated memory, add it to the free list. + + struct freememnode *fmn; + char *freeend; + int *freeptr; + + freeptr = ptr; + freeptr--; + + freemem += *freeptr; + if( g_debugAlloc.integer ) + G_Printf( "G_Free of %i bytes (%i left)\n", *freeptr, freemem ); + + for( fmn = freehead; fmn; fmn = fmn->next ) + { + freeend = ((char *) fmn) + fmn->size; + if( freeend == (char *) freeptr ) + { + // Released block can be merged to an existing node + + fmn->size += *freeptr; // Add size of node. + return; + } + } + // No merging, add to head of list + + fmn = (struct freememnode *) freeptr; + fmn->size = *freeptr; // Set this first to avoid corrupting *freeptr + fmn->cookie = FREEMEMCOOKIE; + fmn->prev = NULL; + fmn->next = freehead; + freehead->prev = fmn; + freehead = fmn; +} + +void G_InitMemory( void ) +{ + // Set up the initial node + + freehead = (struct freememnode *) memoryPool; + freehead->cookie = FREEMEMCOOKIE; + freehead->size = POOLSIZE; + freehead->next = NULL; + freehead->prev = NULL; + freemem = sizeof(memoryPool); +} + +void G_DefragmentMemory( void ) +{ + // If there's a frenzy of deallocation and we want to + // allocate something big, this is useful. Otherwise... + // not much use. + + struct freememnode *startfmn, *endfmn, *fmn; + + for( startfmn = freehead; startfmn; ) + { + endfmn = (struct freememnode *)(((char *) startfmn) + startfmn->size); + for( fmn = freehead; fmn; ) + { + if( fmn->cookie != FREEMEMCOOKIE ) + G_Error( "G_DefragmentMemory: Memory corruption detected!\n" ); + + if( fmn == endfmn ) + { + // We can add fmn onto startfmn. + + if( fmn->prev ) + fmn->prev->next = fmn->next; + if( fmn->next ) + { + if( !(fmn->next->prev = fmn->prev) ) + freehead = fmn->next; // We're removing the head node + } + startfmn->size += fmn->size; + memset( fmn, 0, sizeof(struct freememnode) ); // A redundant call, really. + + startfmn = freehead; + endfmn = fmn = NULL; // Break out of current loop + } + else + fmn = fmn->next; + } + + if( endfmn ) + startfmn = startfmn->next; // endfmn acts as a 'restart' flag here + } +} + +void Svcmd_GameMem_f( void ) +{ + // Give a breakdown of memory + + struct freememnode *fmn; + + G_Printf( "Game memory status: %i out of %i bytes allocated\n", POOLSIZE - freemem, POOLSIZE ); + + for( fmn = freehead; fmn; fmn = fmn->next ) + G_Printf( " %dd: %d bytes free.\n", fmn, fmn->size ); + G_Printf( "Status complete.\n" ); +} + +/* Golliwog: All rewritten static int allocPoint; void *G_Alloc( int size ) { @@ -44,7 +210,7 @@ void *G_Alloc( int size ) { } if ( allocPoint + size > POOLSIZE ) { - G_Error( "G_Alloc: failed on allocation of %u bytes\n", size ); + G_Error( "G_Alloc: failed on allocation of %i bytes\n", size ); return NULL; } @@ -62,3 +228,5 @@ void G_InitMemory( void ) { void Svcmd_GameMem_f( void ) { G_Printf( "Game memory status: %i out of %i bytes allocated\n", allocPoint, POOLSIZE ); } +// Golliwog. +*/ diff --git a/src/game/q_shared.h b/src/game/q_shared.h index 895f1961..6faaced2 100644 --- a/src/game/q_shared.h +++ b/src/game/q_shared.h @@ -366,6 +366,11 @@ typedef int fixed16_t; #define M_PI 3.14159265358979323846f // matches value in gcc v2 math.h #endif +//TA: stop telling others not to edit q_* <:) +#ifndef M_SQRT2 +#define M_SQRT2 1.414213562f +#endif + #define NUMVERTEXNORMALS 162 extern vec3_t bytedirs[NUMVERTEXNORMALS]; |