/****************************************************************************
*
* MALLOC.C
*
* PROGRAMMER : Chris
*    VERSION : 00.00
*    CREATED : 04/06/98
*   MODIFIED : 04/06/98
*       TABS : 5
*
* DESCRIPTION
*	Memory allocation routines
*
*****************************************************************************/

/*---------------------------------------------------------------------------
 *	Import Headers
\*--------------------------------------------------------------------------*/

#include <sys\types.h>
#include <stdio.h>
#include <libsn.h>
#include "typedefs.h"
#include "cd.h"
#include "file.h"
#include "malloc.h"
#include "specific.h"
#include "..\game\gameflow.h"
#include "..\game\title.h"

/*---------------------------------------------------------------------------
 *	Constants
\*--------------------------------------------------------------------------*/

#ifdef PSX_SONY_DEMO_SHELL
	#ifdef GAMEDEBUG
		#define MALLOC_SIZE (3000*1024)
	#else
		#define MALLOC_SIZE (1038*1024)
	#endif
#else
	#ifdef CD_LOAD
		#ifdef GAMEDEBUG
			#define MALLOC_SIZE (1112*1024)
		#else
			#define MALLOC_SIZE (1112*1024)
		#endif
	#else
		#ifdef EZORAY
			#define MALLOC_SIZE (1112*1024)
		#else
			#define MALLOC_SIZE (3000*1024)
		#endif
	#endif
#endif

/*---------------------------------------------------------------------------
 *	Globals
\*--------------------------------------------------------------------------*/

int malloc_used;
int script_malloc_size;
char malloc_buffer[MALLOC_SIZE];

/*---------------------------------------------------------------------------
 *	Locals
\*--------------------------------------------------------------------------*/

static char* malloc_ptr;
int malloc_free;

#ifdef GAMEDEBUG
static int game_malloc_totals[256];
#ifndef CD_LOAD
static char* game_malloc_strings[] = {
	"Temp Alloc",
	"Txtr Pages",
	"Mesh Ptrs",
	"Meshes",
	"Anims",
	"Change",
	"Ranges",
	"Commands",
	"Bones",
	"Frames",
	"Room Txtrs",
	"Room Infos",
	"Room Mesh",
	"Room Door",
	"Room Floor",
	"Room Lites",
	"SttMshInfs",
	"Floor Data",
	"ITEMS!!",
	"Cameras",
	"Sound FX",
	"Boxes",
	"Overlaps",
	"GroundZone",
	"FlyZone",
	"AniTxt Rngs",
	"Cine Frms",
	"LdDem Buf",
	"SvDem Buf",
	"Cine FX",
	"Mummy HdTn",
	"Xtra DR Stf",
	"FX_Array",
	"Creat.Data",
	"Creat.LOT",
	"Samp Infos",
	"Samples",
	"Samp Offs",
	"Rlg Ball Stf",
	"Skidoo Stuff",
	"LdPic Buf",
	"FMV Buf",
	"Poly Bufs",
	"O-Tables",
	"CLUTs",
	"Text Infos",
	"Spr Infos",
	"Script Dat",
	"NULL"
};
#endif
#endif

/*---------------------------------------------------------------------------
 *	Public Functions
\*--------------------------------------------------------------------------*/

void	init_game_malloc()
{
#ifdef GAMEDEBUG
	int i;
#endif

	malloc_free = MALLOC_SIZE - script_malloc_size;
	malloc_used = script_malloc_size;
	malloc_ptr  = malloc_buffer + script_malloc_size;

#ifdef GAMEDEBUG
	for ( i=0 ; i<256 ; i++ )
		game_malloc_totals[i] = 0;

	game_malloc_totals[SCRIPT_DATA] = script_malloc_size;

	printf("Game_Malloc Initialised -->%dK - %d bytes for script\n",MALLOC_SIZE/1024,script_malloc_size );
#endif
}

char	*game_malloc(int size, int type)
{
	char	*ptr;

	size = (size+3) & 0xfffffffc;

	if (size <= malloc_free)
	{
#ifdef GAMEDEBUG
		game_malloc_totals[type] += size;
#endif
		ptr = malloc_ptr;
		malloc_free -= size;
		malloc_used += size;
		malloc_ptr += size;
		printf("GIBBY Allocating %d\n",size);
		return( ptr );
	}

#if defined(GAMEDEBUG) || defined(EZORAY)
	printf("game_malloc() out of space!!\n");
	exit(0);
#endif
	return(NULL);
}

void	game_free(int size, int type)
{
	size = (size+3) & 0xfffffffc;

#ifdef GAMEDEBUG
	game_malloc_totals[type] -= size;
#endif

	malloc_ptr -= size;
	malloc_free += size;
	malloc_used -= size;
}

#if defined(GAMEDEBUG) || defined(EZORAY)
void	show_game_malloc_totals()
{
#ifdef EZORAY
	printf( "\n\n---->Total Memory Used %dK of %dK<----\n\n",((malloc_used+1023)/1024)-10,((malloc_used+malloc_free)/1024)-10);
#else
	printf( "\n\n---->Total Memory Used %dK of %dK<----\n\n",(malloc_used+1023)/1024,(malloc_used+malloc_free)/1024);
#endif
}
#endif

#ifdef GAMEDEBUG
void	save_game_malloc_totals(char *fname)
{
	int		file;
	int		i;
	char	*ptr,*ptr2,*ptr3;
	char	buf[256];

#ifndef CD_LOAD

#ifdef EZORAY
	file = PCcreat0(fname,0);
	PCclose0(file);
	file = PCopen0(fname,1,0);
#else
	file = PCcreat(fname,0);
	PCclose(file);
	file = PCopen(fname,1,0);
#endif
	printf("FILE: %s FD:%d\n\r",fname,file);
	if (file<=0) return;
	printf("Writing...\n");
	sprintf(buf,"Level: '%s' '%s'\n\r",GF_Level_Names[CurrentLevel],GF_levelfilenames[CurrentLevel]);
	for ( i=0; i<256; i+=3 )
	{
		ptr = game_malloc_strings[i];
		if ( *ptr=='N' && *(ptr+1)=='U' &&
		     *(ptr+2)=='L' && *(ptr+3)=='L' )
				break;

		ptr2 = game_malloc_strings[i+1];
		if ( *ptr2=='N' && *(ptr2+1)=='U' &&
		     *(ptr2+2)=='L' && *(ptr2+3)=='L' )
				break;

		ptr3 = game_malloc_strings[i+2];
		if ( *ptr3=='N' && *(ptr3+1)=='U' &&
		     *(ptr3+2)=='L' && *(ptr3+3)=='L' )
				break;


		sprintf(buf, "%8d %-10s  %8d %-10s %8d %-10s\n\r",game_malloc_totals[i],ptr, game_malloc_totals[i+1],ptr2, game_malloc_totals[i+2],ptr3 );
#ifdef EZORAY
		PCwrite0(file,buf,strlen(buf));
#else
		PCwrite(file,buf,strlen(buf));
#endif
	}

	sprintf(buf, "---->Total Memory Used %dK of %dK<----\n\r",malloc_used/1024,(malloc_used+malloc_free)/1024);
#ifdef EZORAY
	PCwrite0(file,buf,strlen(buf));
	PCclose0(file);
#else
	PCwrite(file,buf,strlen(buf));
	PCclose(file);
#endif
	printf("Closed\n\n");
#endif

}
#endif



