/******************************************************************************************
	AM2 PS   (c) 1999-2001 ISL

	psfont.c:			Font support
******************************************************************************************/

//#include "..\shell\shell.h"
//#include "..\isltex\isltex.h"
//#include "..\islmem\islmem.h"
//#include "..\islfile\islfile.h"
//#include "islfont.h"
#include "include.h"
#include "main.h"

// Richard's funky macros for calculating vram related stuff

#define VRAM_PAGECOLS		8
#define VRAM_PAGEROWS		2
#define VRAM_PAGES			16
#define VRAM_PAGEW			32
#define VRAM_PAGEH			32
#define VRAM_SETX(X)		(X)
#define VRAM_SETY(Y)		((Y)*VRAM_PAGEW)
#define VRAM_SETXY(X,Y)		((X)+((Y)*VRAM_PAGEW))
#define VRAM_SETPAGE(P)		((P)<<16)
#define VRAM_GETX(HND)		((HND) & (VRAM_PAGEW-1))
#define VRAM_GETY(HND)		(((HND)/VRAM_PAGEW) & (VRAM_PAGEW-1))
#define VRAM_GETXY(HND)		((HND) & 0xffff)
#define VRAM_GETPAGE(HND)	((HND)>>16)
#define VRAM_CALCVRAMX(HND)	(512+((VRAM_GETPAGE(HND)%(VRAM_PAGECOLS))*64)+(VRAM_GETX(HND)*2))
#define VRAM_CALCVRAMY(HND)	(((VRAM_GETPAGE(HND)/(VRAM_PAGECOLS))*256)+(VRAM_GETY(HND)*8))

#define ANG2FIX(a)		(((a)*4096)/360)

static TextureType	*buttonSprites[4];

static TextureType	*otherSprites[16];
static char			otherChars[16];
static int			numOtherSprites;
static UBYTE			redidx[16];
static UBYTE			greenidx[16];
static UBYTE			blueidx[16];



unsigned char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-=+[]{}:;\"'|\\,<.>/?"
					"\xe0\xe8\xec\xf2\xf9\xc0\xc8\xcc\xd2\xd9\xe1\xe9\xed\xf3\xfa\xfd\xc1\xc9\xcd\xd3\xda\xdd\xe2\xea\xee\xf4\xfb\xc2\xca\xce\xd4\xdb\xe3\xf1\xf5\xc3\xd1\xd5\xe4\xeb\xef\xf6\xfc\xff\xc4\xcb\xcf\xd6\xdc\xe5\xc5\xe6\xc6\xe7\xc7\xf0\xd0\xf8\xd8\xbf\xa1\xdf";


static void fontDispSprite(TextureType *tex, short x,short y);




void fontProcessPart2(psFont *font, USHORT *bitmap, int x1, int x2, int width, int height)
{
	int					i,j,y1,y2,clear,h,w,x,y;
	int					newW,newH;
	static int			character=0;
	unsigned short		*bitmapPtr,*pixelPtr,index=0;
	TextureType			*texPtr;
 	KMSTATUS 			tflag;

	texPtr = &DCKtextureList[character];				
	/*
	y1=-1;
	y2=-1;
	for(j=0;j<height;j++)
	{
		clear=1;
		for(i=x1;i<x2;i++)
		{
			if(bitmap[i+(j*width)]!=64543 && bitmap[i+(j*width)]!=31775)clear=0;
		}
		if(y1==-1 && !clear)y1=j;
		if(y1!=-1 && y2==-1 && clear)y2=j;
	}
	*/
//now build the surface
	w = x2-x1;
//	h = y2-y1; //this clips the font exactly
	h = height;//24//this takes the entire width of the font 
	font->height=height;
	
   //	if(character==22 || character==21)debug_printf("w=%d h=%d\n",w,h);

	font->pixelwidth[character]=w-4;
	if(character==22)font->pixelwidth[character]-=8;//W
	if(character==48)font->pixelwidth[character]-=8;//w

	if(w<8)newW=8;
	else
	if(w<16)newW=16;
	else
	if(w<32)newW=32;
	else
	if(w<64)newW=64;

	if(h<8)newH=8;
	else
	if(h<16)newH=16;
	else
	if(h<32)newH=32;
	else
	if(h<64)newH=64;

	//if(newH>newW)
	//	newW=newH;
	//else
	//	newH=newW;
  
	x=x1;

	//y=y1;//only if clipping to font exactly
	y=0;   //else, start at the top of the block

	bitmapPtr = Align32Malloc(newW*newH*sizeof(USHORT));
	pixelPtr = bitmapPtr;

	for(j=0;j<newW;j++)
	{
		for(i=0;i<newH;i++)
		{
			if(j<w && i<h)
				*pixelPtr++ = bitmap[j+x+((i+y)*width)];
  			else
				*pixelPtr++ = 0;
		}
	}

	tflag = kmCreateTextureSurface(&texPtr->surface, newH, newW,KM_TEXTURE_ARGB1555|KM_TEXTURE_RECTANGLE);
	if(tflag != KMSTATUS_SUCCESS)debug_printf("failure 1\n");
	tflag = kmLoadTexture(&texPtr->surface, (PKMDWORD)bitmapPtr);
	if(tflag != KMSTATUS_SUCCESS)debug_printf("failure 2\n");

	texPtr->colourKey=TRUE;
//	texPtr->colourKey = FALSE;
	texPtr->surfacePtr = &texPtr->surface;
	texPtr->imageCRC = 0;
	texPtr->bpp = 4;   
	texPtr->x = 0;
	texPtr->y = 0;
	texPtr->w = w;//newWidth;	
	texPtr->h = h;//newHeight;	
	texPtr->u0 = 0;
	texPtr->v0 = 0;
	texPtr->u1 = w-1;
	texPtr->v1 = 0;
	texPtr->u2 = 0;
	texPtr->v2 = h-1;
	texPtr->u3 = w-1;
	texPtr->v3 = h-1;
	texPtr->tpage = DCKnumTextures;

//	if(texPtr->colourKey)
//	{
   //		debug_printf("trans ok\n");
		memcpy(&texPtr->stripHead,&StripHead_GT4_Alpha,sizeof(StripHead_GT4_Alpha));
		kmChangeStripTextureSurface(&texPtr->stripHead,KM_IMAGE_PARAM1,&texPtr->surface);
//	}
//	else
//	{
//		memcpy(&texPtr->stripHead,&StripHead_GT4_FMA,sizeof(StripHead_GT4_FMA));
//		kmChangeStripTextureSurface(&texPtr->stripHead,KM_IMAGE_PARAM1,&texPtr->surface);
//	}
	Align32Free(bitmapPtr);
	character++;
	DCKnumTextures++;
	font->numchars=character;
//	font->charlookup[character]=character;
	font->charlookup[alphabet[character]] = character;
}


void fontProcess(psFont *font, char *fontdata)
{
	int				i,j,size, x,y;
	char			buf[256],*headerPtr,*dataPtr,*palPtr,*pptr,index;
    PKMDWORD   		TexturePtr,TwiddledPtr;
  	USHORT			width,height,bpp,*pixelPtr,*newPixelPtr;
  	int				headerSize,colFormat,texFormat,texAttrib,attrib;
  	UCHAR			r,g,b,a;
  	BMPHeaderType	*bmpHeader;
	USHORT			*tempBitmap;
	int				x1,x2,clear;


	//// load texture file
	dataPtr = (char*)fontdata;
	bmpHeader = (BMPHeaderType*)(dataPtr+2);
	dataPtr += getInt((char*)&bmpHeader->headersize);
	width = getShort((char*)&bmpHeader->width);
	height = getShort((char*)&bmpHeader->depth);		
	bpp = getShort((char*)&bmpHeader->bits);		
	
	tempBitmap = Align32Malloc(width*height*sizeof(USHORT));  //holds entire font strip!
	
	pixelPtr = (tempBitmap + ((width*(height-1))) );
	palPtr = (char*)bmpHeader+(sizeof(BMPHeaderType));			

	for(i=0;i<height;i++)
	{
		for(j=0;j<(width/2);j++)
		{
			index = *dataPtr++;
			
			pptr = palPtr+(((index>>4)&0x0f)*4);
			b = (*pptr++) >> 3;
			g = (*pptr++) >> 2;
			r = (*pptr++) >> 3;
			r/=8;
			g/=8;
			b/=8;
//		 	*pixelPtr++ = RGB565(r,g,b);			   
			if((r == 31)&&(g == 0)&&(b == 31))					
  	  			*pixelPtr++ = RGBA1555(r,g,b,0);
	  		else
   				*pixelPtr++ = RGBA1555(r,g,b,1);	
			
			pptr = palPtr+((index&0x0f)*4);
			b = (*pptr++) >> 3;
			g = (*pptr++) >> 2;
			r = (*pptr++) >> 3;
			r/=8;
			g/=8;
			b/=8;
//		 	*pixelPtr++ = RGB565(r,g,b);			   
			if((r == 31)&&(g == 0)&&(b == 31))					
	  			*pixelPtr++ = RGBA1555(r,g,b,0);
	  		else
   				*pixelPtr++ = RGBA1555(r,g,b,1);	

		}
		pixelPtr -= (width*2);
	}

	//pink colour = 63743
	x1=-1;
	x2=-1;
	debug_printf("w=%d h=%d\n",width,height);


  //	debug_printf("check for trans 1= %d\n",RGBA1555(31,0,31,0) );
  //	debug_printf("check for trans 2= %d\n",RGBA1555(31,0,31,1) );

	for(j=0;j<width;j++)
	{
		clear=1;
		for(i=0;i<height;i++)
		{
			if(tempBitmap[j+(i*width)]!=64543 && tempBitmap[j+(i*width)]!=31775)
			{
				clear=0;
			}
		}

	   	if(!clear && x1==-1)x1=j;
		if( clear && x1!=-1)
		{
			x2=j;
		   	//now clip top and bottom and make into a surface
			fontProcessPart2(font, tempBitmap, x1,x2, width, height);
			//debug_printf("%d %d\n",x1,x2);
			x1=-1;
			x2=-1;
		}
	}

	Align32Free(tempBitmap);
}


psFont *fontLoad(char *fontname)
{
	int				loop,col;
	unsigned char	*fontdata;
	long			*fontptr;
	psFont			*fontl;
	int				filelength;

	return jim_fontLoad(fontname);

	fontl = (psFont *)MALLOC0(sizeof(psFont));

	gdFsChangeDir("\\");
	gdFsChangeDir("TEXTURES");

	debug_printf("name=%s\n",fontname);

   //	pNSprite = (NSPRITE *)fileLoad(fontname, &filelength);

	if((fontdata = (unsigned char*)fileLoad(fontname, &filelength))==NULL)
		return NULL;

	debug_printf("ok\n");
	fontProcess(fontl,fontdata);
	syFree(fontdata);

	return fontl;
}


/**************************************************************************
	FUNCTION:	fontUnload()
	PURPOSE:	Unload font from VRAM and free info
	PARAMETERS:	Font ptr
	RETURNS:	
**************************************************************************/

void fontUnload(psFont *font)
{
	int loop;

	for(loop=0; loop<font->numchars; loop++)
		textureUnload(&font->txPtr[loop]);
	FREE(font->txPtr);
	font->txPtr = NULL;
	FREE(font);
}


static void fontDispChar(TextureType *tex, short x,short y, unsigned char r, unsigned char g, unsigned char b, unsigned char alpha)
{ 
float tx, ty, tw, th;

	POLY_GT4 	*si; 
	int w,h;

	w=tex->u1 - tex->u0+1;
	h=tex->v2 - tex->v0+1;

	w = (((float) w) * 1.25);
	h = (((float) h) * 1.85);

	BEGINPRIM(si, POLY_GT4);

	setPolyGT4(si);

	si->tpage = tex->tpage;

	setXY4(si,
			x  ,y,
			x+w,y,
			x,  y+h,
			x+w,y+h);
	setUV4(si, 
			tex->u0, tex->v0,
			tex->u1, tex->v1,
			tex->u2, tex->v2,
			tex->u3, tex->v3);
					    
	setRGB0(si,r,g,b);
	setRGB1(si,r,g,b);
	setRGB2(si,r,g,b);
	setRGB3(si,r,g,b);

	ENDPRIM(si, 1, POLY_GT4);
}


/**************************************************************************
	FUNCTION:	fontPrint()
	PURPOSE:	Display string in font at pos in colour
	PARAMETERS:	font ptr, x,y, string, r,g,b
	RETURNS:	
**************************************************************************/

void fontPrint(psFont *font, short x,short y, char *text, unsigned char r, unsigned char g, unsigned char b)
{
	unsigned char	*strPtr, c;
	int				cx,cy, loop;
	TextureType		*letter;

	x = 320 + (((float) x) * 1.25f);
	y = 240 + (((float) y) * 1.85f);

	strPtr = text;
	cx = x;
	cy = y;
	while(*strPtr)
	{
		c = *strPtr;
		switch(c)
		{
		case '\n':
			y += font->height;
			cx = x;
			cy = y;
			break;
		case ' ':
			x += font->height/2;
			break;
		case '@':
			switch(*(strPtr+1))
			{
			case 'X':
			    fontDispSprite(buttonSprites[2], x+3,y-3 + font->spriteYOffset);
				strPtr++;
				x += buttonSprites[2]->w+6;
				break;
			case 'C':
			   	fontDispSprite(buttonSprites[1], x+3,y-3 + font->spriteYOffset);
				strPtr++;
				x += buttonSprites[1]->w+6;
				break;
			case 'S':
			   	fontDispSprite(buttonSprites[3], x+3,y-3 + font->spriteYOffset);
				strPtr++;
				x += buttonSprites[3]->w+6;
				break;
			case 'T':
			   	fontDispSprite(buttonSprites[0], x+3,y-3 + font->spriteYOffset);
				strPtr++;
				x += buttonSprites[0]->w+6;
				break;
			}

			for(loop = 0; loop < numOtherSprites; loop ++)
			{
				if((*(strPtr+1)) == otherChars[loop])
				{
					fontDispSprite(otherSprites[loop], x+3,y-3 + font->spriteYOffset);
					strPtr++;
					x += ((float)otherSprites[loop]->w * 1.25f) + 6;
					break;
				}
			}

			break;

		default:

			loop = font->charlookup[c];

			if (loop<font->numchars)
			{
//				letter = &font->txPtr[loop];
				letter = &DCKtextureList[loop];
//				if ((x>-350)&&(x<320))
				if ((x>-font->pixelwidth[loop])&&(x<640))
					fontDispChar(letter, x,y-((c>127)?(1):(0)), r,g,b, font->alpha);

				x += ((float)font->pixelwidth[loop] * 1.25f);
			}
		}
		strPtr++;
	}
}


/**************************************************************************
	FUNCTION:	fontExtentW()
	PURPOSE:	Get width of string using font
	PARAMETERS:	font ptr, string
	RETURNS:	Width in pixels
**************************************************************************/

int fontExtentW(psFont *font, char *text)
{
	unsigned char	*strPtr, c;
	int		loop, x, maxW = 0;

	strPtr = text;
	x = 0;
	while(*strPtr)
	{
		c = *strPtr;
		switch(c)
		{
		case '\n':
			if (x>maxW)
				maxW = x;
			x = 0;
			break;
		case ' ':
			x += font->height/2;
			break;
		case '@':
			switch(*(strPtr+1))
			{
			case 'X':
				strPtr++;
				x += buttonSprites[2]->w+6;
				break;
			case 'C':
				strPtr++;
				x += buttonSprites[1]->w+6;
				break;
			case 'S':
				strPtr++;
				x += buttonSprites[3]->w+6;
				break;
			case 'T':
				strPtr++;
				x += buttonSprites[0]->w+6;
				break;
			}

			for(loop = 0; loop < numOtherSprites; loop ++)
			{
				if((*(strPtr+1)) == otherChars[loop])
				{
					strPtr++;
					x += otherSprites[loop]->w+6;
					break;
				}
			}

			break;
		default:
			loop = font->charlookup[c];
			if (loop<font->numchars)
				x += font->pixelwidth[loop]+2;
		}
		strPtr++;
	}
	if (x>maxW)
		maxW = x;
	return maxW;
}


/**************************************************************************
	FUNCTION:	fontFitToWidth()
	PURPOSE:	Wrap string to width into buffer
	PARAMETERS:	font ptr, width, string, buffer
	RETURNS:	Number of lines
**************************************************************************/

int fontFitToWidth(psFont *font, int width, char *text, char *buffer)
{
	char	buf[256], *bufPtr, *outPtr = buffer;
	int		pixLen, lines = 0;

	memset(buf, 0, sizeof(buf));
	bufPtr = buf;
	while(1)
	{
		if (*text>=' ')
			*bufPtr++ = *text;
		pixLen = fontExtentW(font, buf);
		if ((pixLen>width)||(*text=='\0'))
		{
			if (pixLen>width)
			{
				while(*bufPtr!=' ')
				{
					bufPtr--;
					text--;
				}
				text++;
			}
			*bufPtr = '\0';
			strcpy(outPtr, buf);
			outPtr += strlen(buf)+1;
			lines++;
			bufPtr = buf;
			memset(buf, 0, sizeof(buf));
			if (*text=='\0')
				break;
		}
		text++;
	}
/*	debugPrintf("%d lines: \n", lines);
	outPtr = buffer;
	for(pixLen=0; pixLen<lines; pixLen++)
	{
		debugPrintf("  '%s'\n", outPtr);
		outPtr += strlen(outPtr)+1;
	}*/
	return lines;
}



/**************************************************************************
	FUNCTION:	fontPrintN()
	PURPOSE:	Display (partial) string in font at pos in colour
	PARAMETERS:	font ptr, x,y, string, r,g,b, max chars
	RETURNS:	
**************************************************************************/

void fontPrintN(psFont *font, short x,short y, char *text, unsigned char r, unsigned char g, unsigned char b, int n)
{
	unsigned char		*strPtr, c;
	int			cx,cy, loop;
	TextureType	*letter;

	strPtr = text;
	cx = x;
	cy = y;
	while ((*strPtr) && (n>0))
	{
		c = *strPtr;
		switch(c)
		{
		case '\n':
			y += font->height;
			cx = x;
			cy = y;
			break;
		case ' ':
			x += font->height/2;
			break;
		case '@':
			switch(*(strPtr+1))
			{
			case 'X':
			    fontDispSprite(buttonSprites[2], x+3,y-3 + font->spriteYOffset);
				strPtr++;
				x += buttonSprites[2]->w+6;
				break;
			case 'C':
			   	fontDispSprite(buttonSprites[1], x+3,y-3 + font->spriteYOffset);
				strPtr++;
				x += buttonSprites[1]->w+6;
				break;
			case 'S':
			   	fontDispSprite(buttonSprites[3], x+3,y-3 + font->spriteYOffset);
				strPtr++;
				x += buttonSprites[3]->w+6;
				break;
			case 'T':
			   	fontDispSprite(buttonSprites[0], x+3,y-3 + font->spriteYOffset);
				strPtr++;
				x += buttonSprites[0]->w+6;
				break;
			}

			for(loop = 0; loop < numOtherSprites; loop ++)
			{
				if((*(strPtr+1)) == otherChars[loop])
				{
					fontDispSprite(otherSprites[loop], x+3,y-3 + font->spriteYOffset);
					strPtr++;
					x += otherSprites[loop]->w+6;
					break;
				}
			}

			break;
		default:
			loop = font->charlookup[c];
			if (loop<font->numchars)
			{
				letter = &font->txPtr[loop];
				if ((x>-350)&&(x<320))
					fontDispChar(letter, x,y-((c>127)?(1):(0)), r,g,b,font->alpha);
				x += font->pixelwidth[loop];
			}
		}
		strPtr++;
		n--;
	}
}

static void fontDispSprite(TextureType *tex, short x,short y)
{
	POLY_FT4 	*si;
	USHORT		w,h;

	
	BEGINPRIM(si, POLY_FT4);

	w = tex->w;
	
	if(buttonSprites[0]==tex || buttonSprites[1]==tex || buttonSprites[2]==tex || buttonSprites[3]==tex)
		h = tex->h;	 //don't need to stretch these!
	else
		h = tex->h*2;

	si->x0 = x;
	si->y0 = y;
	si->x1 = x+w-1;
	si->y1 = y;
	si->x2 = x;
	si->y2 = y+h-1;
	si->x3 = x+w-1;
	si->y3 = y+h-1;
		
	si->r0 = 128;
	si->g0 = 128;
	si->b0 = 128;
	si->u0 = tex->u0;
	si->v0 = tex->v0;
	si->u1 = tex->u1;
	si->v1 = tex->v1;
	si->u2 = tex->u2;
	si->v2 = tex->v2;
	si->u3 = tex->u3;
	si->v3 = tex->v3;
	si->tpage = tex->tpage;
	si->clut = tex->clut;
	setPolyFT4(si);
	ENDPRIM(si, 1, POLY_FT4);
}


void fontRegisterButtonSprites(TextureType *triangle, TextureType *circle, TextureType *cross, TextureType *square)
{
	buttonSprites[0] = triangle;
	buttonSprites[1] = circle;
	buttonSprites[2] = cross;
	buttonSprites[3] = square;
}


void fontRegisterOtherSprites(char code, TextureType *sprite)
{

	if(numOtherSprites < 16)
	{
		otherSprites[numOtherSprites] = sprite;
		otherChars[numOtherSprites] = code;
		numOtherSprites ++;
	}
}


// =================================================================================================
// =============================================================== Jim's spiffy font loading code ==

typedef struct
{
	unsigned long pixelDatOffset;	// Offset from start of file of pixel data
	unsigned long width;			// width of the pixel data in bytes (pitch)
	unsigned long pixelWidth;		// width of the pixel data in pixels...
} PSFONTINF;


void jim_buildCharTexture(psFont *font, PSFONTINF *inf, int charHeight, unsigned short *bitmap, int character)
{
unsigned short *tmpSrf, *pixel;
int newW, newH;
TextureType			*texPtr;
KMSTATUS 			tflag;
int x, y;

	// ==== Create a buffer for the character bitmap that's a power of 2 in width and height
	if (inf->pixelWidth<8)						
		newW=8;
	else if (inf->pixelWidth<16)
		newW=16;
	else if (inf->pixelWidth<32)
		newW=32;
	else if (inf->pixelWidth<64)
		newW=64;

	if (charHeight<8)
		newH = 8;
	else if (charHeight<16)
		newH = 16;
	else if (charHeight<32)
		newH = 32;
	else if (charHeight<64)
		newH = 64;


	tmpSrf = Align32Malloc(sizeof(short)*newW*newH);		// Alloc the memory for a temp surface
	ASSERT(tmpSrf);
	pixel = tmpSrf;

	for(x=0; x < newW; x++)							// Copy over the characters bitmap data
	{												// filling in the extra pixels
		for(y=0; y < newH; y++)
		{
			if (x < inf->pixelWidth && y < font->height)
			{
				*pixel = bitmap[(y * inf->pixelWidth) + x];
				pixel++;				
			} else {
				*pixel = 0;
				pixel++;
			}
		} // end-for
	} // end-for


	// ==== Create the texture used for the character
	texPtr = &DCKtextureList[DCKnumTextures];
	tflag = kmCreateTextureSurface(&texPtr->surface, newH, newW,KM_TEXTURE_ARGB1555|KM_TEXTURE_RECTANGLE);
	if(tflag != KMSTATUS_SUCCESS)
		debug_printf("islfont.c - Could not create surface for character 1\n");

	// ==== Copy over the bitmap in main RAM to video RAM.......
	tflag = kmLoadTexture(&texPtr->surface, (PKMDWORD)tmpSrf);
	if(tflag != KMSTATUS_SUCCESS)
		debug_printf("islfont.c - Could not load bitmap for character\n");

	// === Ummm....not exactly sure what's happening here......a standard texture description 
	// === being copied maybe ?
	memcpy(&texPtr->stripHead,&StripHead_GT4_Alpha,sizeof(StripHead_GT4_Alpha));
	kmChangeStripTextureSurface(&texPtr->stripHead,KM_IMAGE_PARAM1,&texPtr->surface);


	texPtr->colourKey	= TRUE;
	texPtr->surfacePtr	= &texPtr->surface;
	texPtr->imageCRC	= 0;
	texPtr->bpp			= 16;   
	texPtr->x 			= 0;
	texPtr->y			= 0;
	texPtr->w			= inf->pixelWidth;	// newW;	
	texPtr->h			= charHeight;	// newH;	
	texPtr->u0			= 0;
	texPtr->v0			= 0;
	texPtr->u1			= inf->pixelWidth-1;
	texPtr->v1			= 0;
	texPtr->u2			= 0;
	texPtr->v2			= charHeight-1;
	texPtr->u3			= inf->pixelWidth-1;
	texPtr->v3			= charHeight-1;
	texPtr->tpage		= DCKnumTextures;

	DCKnumTextures++;
	font->numchars=character;
	font->charlookup[alphabet[character]] = character;
	font->pixelwidth[character]=inf->pixelWidth;

	Align32Free(tmpSrf);
}


void jim_buildCharBitmap(PSFONTINF *inf, int charHeight, unsigned char *pixels, unsigned short *bitmap, unsigned short *palette)
{
unsigned char * pixelPtr, r, g, b, pixel;
int bmpW, bmpH, lsn;

	bmpH = charHeight;

	while(bmpH)
	{
		lsn=0;
		pixelPtr = pixels;
		bmpW = inf->pixelWidth;

		while(bmpW)
		{
			if (!lsn)					// Get either low or high nibble of the byte
			{
				pixel = (*pixelPtr & 0xf);
				lsn=1;
			} else {
				pixel = (*pixelPtr >> 4);
				lsn=0;
				pixelPtr++;
			} // end-if-else

			b = palette[pixel] & 0x1F;			// Get the individual rgb components of the palette
			g = (palette[pixel] >> 5) & 0x1F;	//
			r = (palette[pixel] >> 10) & 0x1F;	// 

			if ((r == 0x1f) && (g == 0) && (b == 0x1f))
			{
	  			*bitmap = RGBA1555(r,g,b,0);
			} else {
   				*bitmap = RGBA1555(r,g,b,1);	
			} // end-if-else

			bitmap++;

			bmpW--;
			
		} // end-while(bmpW)

		pixels += (inf->width >> 1);
		bmpH--;

	} // end-while(bmpH)
}



psFont * jim_fontLoad(char *fontname)
{
unsigned char * fontData, * wrkPtr, * pixelData, pixel, r, g, b;
unsigned long numChars, charHeight, i, totalWidth, filelength;
unsigned short * palette, *tmpBmp, *bmpWrk;
PSFONTINF *inf;
int tflag, maxWidth, bmpW, bmpH, lsn, character=0;
psFont *font;


	// ==== First, we need to load the complete font file into memory

	debug_printf("Loading font \"%s\" in as a binary chunk...", fontname);
	
	if((fontData = (unsigned char*)fileLoad(fontname, &filelength))==NULL)
	{
		debug_printf("FAILED :o( \n", fontname);
		return 0;
	} // end-if

	debug_printf("OK :o) \n", fontname);

	// ==== Get some information about the font...


	wrkPtr		= fontData;
	numChars	= *(unsigned long *) wrkPtr;			// Number of characters
	wrkPtr = wrkPtr + 4;		
	charHeight	= *(unsigned long *) wrkPtr;			// Height of all of the characters
	wrkPtr = wrkPtr + 4;		
	palette		= (unsigned short *) wrkPtr;			// Palette for the font pixels
	wrkPtr = wrkPtr + 32;		


	// ==== Search for the character with the biggest width and then malloc 
	// ==== the work area for building the font pixel data from the pallete.

	debug_printf("Calculating the maximum character width.....");

	i = numChars;
	inf = (PSFONTINF *) wrkPtr;
	totalWidth = 0;

	while(i)
	{
		if (inf->pixelWidth > maxWidth)
			maxWidth = inf->pixelWidth;

		i--;
		inf++;
		
	} // end-while

	debug_printf("%i texels\n", maxWidth);

	tmpBmp = Align32Malloc(sizeof(short) * charHeight * maxWidth);
	ASSERT(tmpBmp);

	// ==== Go thru all of the characters in the font file, build a 16-bit bitmap image of
	// ==== the font character and create a texture for it.

	i = numChars;
	inf = (PSFONTINF *) wrkPtr;

	font = Align32Malloc(sizeof(psFont));
	ASSERT(font);

	font->height = charHeight;

	while(i)
	{
		jim_buildCharBitmap(inf, charHeight, fontData + inf->pixelDatOffset, tmpBmp, palette);
		jim_buildCharTexture(font, inf, charHeight, tmpBmp, character);

		character++;
		i--;		// Update the loop counter
		inf++;
	} // end-while

	// ==== Free the font data allocated by fileLoad()
	Align32Free(fontData);
	Align32Free(tmpBmp);
	return font;
} 










	


