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];  | 
