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

#ifdef PSX_VERSION
#include <sys\types.h>
#include <stdio.h>
#include "../spec_psx/typedefs.h"
#include "../spec_psx/memory.h"
#include "../spec_psx/gen_draw.h"
#include "../spec_psx/profile.h"
#define SHOW_ROOM_INFO
#else
#include "../specific/stypes.h"
#endif

#include "objects.h"
#include "anim.h"
#include "camera.h"
#include "inventry.h"
#include "health.h"
#include "text.h"


#define	SECRETS_WIDTH	16
#define SECRET_CODE1	127
#define SECRET_CODE2	128
#define SECRET_CODE3	129


#ifdef GAMEDEBUG
TEXTSTRING	*displaytext = NULL, *message_text1=NULL, *message_text2=NULL, *message_text3=NULL;
int			displaytext_count = 0;
char		display_string[128] = "", message_str1[128]="", message_str2[128]="", message_str3[128]="";
#endif

TEXTSTRING	T_textStrings[MAX_TEXT_STRINGS];
sint16		T_numStrings;

char		T_theStrings[MAX_TEXT_STRINGS*MAX_STRING_SIZE];

char	T_textSpacing[]={
	14/*A*/, 13/*B*/, 14/*C*/, 14/*D*/, 13/*E*/,
	12/*F*/, 15/*G*/, 15/*H*/,  9/*I*/, 12/*J*/,
	15/*K*/, 14/*L*/, 17/*M*/, 14/*N*/, 15/*O*/,
	13/*P*/, 15/*Q*/, 14/*R*/, 11/*S*/, 13/*T*/,
	13/*U*/, 15/*V*/, 17/*W*/, 14/*X*/, 14/*Y*/, 13/*Z*/,

	10/*a*/, 11/*b*/,  9/*c*/, 10/*d*/,  9/*e*/,
	 9/*f*/, 10/*g*/, 11/*h*/,  6/*i*/,  7/*j*/,
	12/*k*/,  7/*l*/, 16/*m*/, 11/*n*/, 10/*o*/,
	11/*p*/, 11/*q*/,  9/*r*/,  8/*s*/,  8/*t*/,
	11/*u*/, 10/*v*/, 15/*w*/, 10/*x*/, 10/*y*/, 10/*z*/,

   12/*0*/, 7/*1*/,10/*2*/,10/*3*/,10/*4*/,
   10/*5*/,10/*6*/, 9/*7*/,10/*8*/,10/*9*/,

    5/*.*/, 5/*,*/, 5/*!*/,11/*?*/, 9/*"*/,
   10/*"*/, 8/**/,  6/*(*/, 6/*)*/, 7/*-*/,		// /
    7/*=*/, 3/*:*/,11/*%*/, 8/*+*/,13/*(c)*/,
   16/*tm*/,9/*&*/, 4/*'*/,
   12,12,
   7,5,7,7,7,7,7,7,7,7,
   16,14,14,14,14,14,14,14,14,
   12,14,
   8,8,8,8,8,8,8
};


// Remap ASCII code to order of Heather's alphabet, ignoring 0-32
#ifdef PC_VERSION
char	T_remapASCII[]={
	  0/* */,
	 64/*!*/, 66/*"*/, 78/*#*/, 77/*$*/, 74/*%*/, 78/*&*/, 79/*'*/, 69/*(*/,
	 70/*)*/, 92/***/, 72/*+*/, 63/*,*/, 71/*-*/, 62/*.*/, 68/**/,  52/*0*/,
	 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/, 60/*8*/,
	 61/*9*/, 73/*:*/, 73/*;*/, 66/*<*/, 74/*=*/, 75/*>*/, 65/*?*/,  0/**/,
	  0/*A*/,  1/*B*/,  2/*C*/,  3/*D*/,  4/*E*/,  5/*F*/,  6/*G*/, 7/*H*/,
	  8/*I*/,  9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/, 15/*P*/,
	 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/, 23/*X*/,
	 24/*Y*/, 25/*Z*/, 80/*[*/, 76/*\*/, 81/*]*/, 97/*^*/, 98/*_*/, 77/*`*/,
	 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/, 33/*h*/,
	 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/, 41/*p*/,
	 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/, 49/*x*/,
	 50/*y*/, 51/*z*/,100/*{*/,101/*|*/,102/*}*/, 67/*~*/
};
#else
char	T_remapASCII[]={
	  0/* */,
	 64/*!*/, 66/*"*/, 76/*#*/, 77/*$*/, 74/*%*/, 78/*&*/, 79/*'*/, 69/*(*/,
	 70/*)*/, 92/***/, 75/*+*/, 63/*,*/, 71/*-*/, 62/*.*/, 68/**/,  52/*0*/,
	 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/, 60/*8*/,
	 61/*9*/, 73/*:*/, 93/*;*/, 94/*<*/, 74/*=*/, 95/*>*/, 65/*?*/,  0/**/,
	  0/*A*/,  1/*B*/,  2/*C*/,  3/*D*/,  4/*E*/,  5/*F*/,  6/*G*/,  7/*H*/,
	  8/*I*/,  9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/, 15/*P*/,
	 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/, 23/*X*/,
	 24/*Y*/, 25/*Z*/, 80/*[*/, 96/*\*/, 81/*]*/, 97/*^*/, 98/*_*/, 99/*`*/,
	 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/, 33/*h*/,
	 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/, 41/*p*/,
	 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/, 49/*x*/,
	 50/*y*/, 51/*z*/,100/*{*/,101/*|*/,102/*}*/, 67/*~*/
};
#endif

extern int GetRenderHeight( void );
extern int GetRenderWidth( void );

void	T_InitPrint(void)
{
	int	n;
	TEXTSTRING	*textString = T_textStrings;

	DisplayModeInfo(0);

	for (n=0;n<MAX_TEXT_STRINGS;n++)
	{
		textString->flags = 0;
		textString++;
	}
	T_numStrings = 0;
#ifdef GAMEDEBUG
	displaytext = NULL; // only needed for FRAME_COUNTER
#endif

#if defined(GAMEDEBUG)
	RemoveDbugs();
#endif
}



TEXTSTRING *T_Print(sint32 xpos, sint32 ypos, sint32 zpos, char *string)
{
#ifdef PC_VERSION
	uint32		scaleV,scaleH;
//	int			width,height;
#endif
	int			n,length;
	TEXTSTRING	*textString = T_textStrings;


	// Gav
	if (string == NULL)
	{
#if defined(GAMEDEBUG) && defined(PSX_VERSION)
		printf("ERROR: Can't print a NULL string\n");
#endif
		return(0);
	}

	if (T_numStrings>=MAX_TEXT_STRINGS)
	{
#if defined(GAMEDEBUG) && defined(PSX_VERSION)
		printf("ERROR: Too many strings\n");
#endif
		return(0);
	}
	for (n=0;n<MAX_TEXT_STRINGS;n++)
	{
		if (!(textString->flags&T_ACTIVE))
			break;
		textString++;
	}
	if (n>=MAX_TEXT_STRINGS)
	{
#if defined(GAMEDEBUG) && defined(PSX_VERSION)
		printf("ERROR: Too many strings too\n");
#endif
		return(0);
	}

//#if defined(GAMEDEBUG) && defined(PSX_VERSION)
//		printf("T_numStrings: %d '%s'\n", T_numStrings, string);
//#endif
	length = T_GetStringLen( string );
	if ( length>=MAX_STRING_SIZE)
		length = MAX_STRING_SIZE-1;
	textString->string = &T_theStrings[n*MAX_STRING_SIZE];

//#ifdef PC_VERSION
/*	height = GetRenderHeight();
	if (height<480)
		height=480;
	width = GetRenderWidth();
	if (width<640)
		width=640;
	textString->scaleV = (height<<16)/480;
	textString->scaleH = (width<<16)/640;
*/
/*
	textString->scaleH = 0x10000;
	textString->scaleV = 0x10000;
	scaleH = GetTextScaleH(0x10000);
	scaleV = GetTextScaleV(0x10000);
	textString->xpos = (sint16)((xpos*scaleH)>>16);
	textString->ypos = (sint16)((ypos*scaleV)>>16);
	textString->zpos = 0;
	textString->letterSpacing = 1;
	textString->wordSpacing = 6;
*/
//#else

	textString->xpos = (sint16)xpos;
	textString->ypos = (sint16)ypos;
	textString->zpos = 0;
	textString->letterSpacing = 0;	// 1
	textString->wordSpacing = 6;
	textString->scaleV = 0x10000;
	textString->scaleH = 0x10000;
	textString->Colour = zpos;
//#endif

/* PAUL changed sprintf to S_MemCpy cos quicker-->Dont need any text formatting!! */
	S_MemCpy( textString->string,string,length+1);
//	textString->string[length] = 0;

//	sprintf(textString->string, string);
	textString->flags = T_ACTIVE;
	textString->textflags = 0;
	textString->outlflags = 0;
	textString->bgndflags = 0;

	textString->bgndSizeX = 0;
	textString->bgndSizeY = 0;
	textString->bgndOffX = 0;
	textString->bgndOffY = 0;
	textString->bgndOffZ = 0;

	T_numStrings++;

	return(textString);
}

void	T_MovePrint(TEXTSTRING *textString, sint32 xpos, sint32 ypos, sint32 zpos)
{
	textString->xpos = (sint16)xpos;
	textString->ypos = (sint16)ypos;
	textString->zpos = (sint16)zpos;
}

void	T_ChangeText(TEXTSTRING *textString, char *string)
{
	if (string == NULL || textString == NULL)
		return;

	if (textString->flags&T_ACTIVE)
	{
		if (T_GetStringLen(string)>MAX_STRING_SIZE)
			string[MAX_STRING_SIZE-1] = 0;

		S_MemCpy(textString->string, string, MAX_STRING_SIZE);
	}
}


void	T_SetFlags(TEXTSTRING *textString, uint16 flags)
{
	if (textString)
		textString->flags = flags;
}
void	T_SetBgndFlags(TEXTSTRING *textString, uint16 flags)
{
	if (textString)
		textString->bgndflags = flags;
}
void	T_SetOutlFlags(TEXTSTRING *textString, uint16 flags)
{
	if (textString)
		textString->outlflags = flags;
}


void	T_SetScale(TEXTSTRING *textString, sint32 scaleH, sint32 scaleV)
{
	if (textString)
	{
		textString->scaleH = scaleH;
		textString->scaleV = scaleV;
	}
}
void	T_LetterSpacing(TEXTSTRING *textString, sint16 pixels)
{
	if (textString)
		textString->letterSpacing = pixels*8;
}
void	T_WordSpacing(TEXTSTRING *textString, sint16 pixels)
{
	if (textString)
		textString->wordSpacing = pixels*8;
}
void	T_FlashText(TEXTSTRING *textString, sint16 bool, sint16	rate)
{
	if (textString == NULL)
		return;

	if (bool)
	{
		textString->flags |= T_FLASH;
		textString->flashRate = rate;
		textString->flashCount = rate;
	}
	else
	{
		textString->flags &= ~T_FLASH;
	}
}

void	T_AddBackground(TEXTSTRING *textString, sint16 xsize, sint16 ysize, sint16 xoff, sint16 yoff, sint16 zoff, sint16 colour, SG_COL *gourptr, uint16 flags)
{
	uint32	scaleV,scaleH;

#ifdef PC_VERSION
	scaleH = GetTextScaleH(textString->scaleH);
	scaleV = GetTextScaleV(textString->scaleV);
#else
	scaleH = textString->scaleH;
	scaleV = textString->scaleV;
#endif

	if (textString)
	{
		textString->flags |= T_ADDBACKGROUND;
		textString->bgndSizeX = (sint16)((xsize*scaleH)>>16);
		textString->bgndSizeY = (sint16)((ysize*scaleV)>>16);
		textString->bgndOffX = (sint16)((xoff*scaleH)>>16);
		textString->bgndOffY = (sint16)((yoff*scaleV)>>16);
		textString->bgndOffZ = zoff;
		textString->bgndColour = colour;
		textString->bgndGour = gourptr;
		textString->bgndflags = flags;
	}
}

void	T_RemoveBackground(TEXTSTRING *textString)
{
	if (textString)
		textString->flags &= ~T_ADDBACKGROUND;
}

void	T_AddOutline(TEXTSTRING *textString, sint16 bool, sint16 colour, SG_COL *gourptr, uint16 flags)
{
	if (textString)
	{
		textString->flags |= T_ADDOUTLINE;
		textString->outlColour = colour;
		textString->outlGour = gourptr;
		textString->outlflags = flags;
	}
}

void	T_RemoveOutline(TEXTSTRING *textString)
{
	if (textString)
		textString->flags &= ~T_ADDOUTLINE;
}


void	T_CentreH(TEXTSTRING *textString, sint16 bool)
{
	if (textString == NULL)
		return;

	if (bool)
		textString->flags |= T_CENTRE_H;
	else
		textString->flags &= ~T_CENTRE_H;
}
void	T_CentreV(TEXTSTRING *textString, sint16 bool)
{
	if (textString == NULL)
		return;

	if (bool)
		textString->flags |= T_CENTRE_V;
	else
		textString->flags &= ~T_CENTRE_V;
}
void	T_RightAlign(TEXTSTRING *textString, sint16 bool)
{
	if (textString == NULL)
		return;

	if (bool)
		textString->flags |= T_RIGHTALIGN;
	else
		textString->flags &= ~T_RIGHTALIGN;
}
void	T_BottomAlign(TEXTSTRING *textString, sint16 bool)
{
	if (textString == NULL)
		return;

	if (bool)
		textString->flags |= T_BOTTOMALIGN;
	else
		textString->flags &= ~T_BOTTOMALIGN;
}

sint32	T_GetTextWidth(TEXTSTRING *textString)
{
#ifdef LOAD_KANJI
	int		i;
	uint16	*kanji, kanjitxt[64];
	uint8	*str, *str2;
#endif
	uint8	*string;
	uint32	letter=0;
	sint32	width=0;
	uint32	scaleV,scaleH;
//	int		height;


#ifdef PC_VERSION
	scaleH = GetTextScaleH(textString->scaleH);
	scaleV = GetTextScaleV(textString->scaleV);
#else
	scaleH = textString->scaleH;
	scaleV = textString->scaleV;
#endif

	width = 0;
	string = textString->string;

	while (*string)
	{
		letter = *(string++);

#ifdef LOAD_KANJI
		if (letter=='@')		// Start of special kanji sequence
		{
			str = string;
			str2 = (char*) kanjitxt;
			for (i=0;i<64;i++)
			{
				str2[0] = str[0];
				str2[1] = str[1];
				if (str[0]==0xff &&str[1]==0xff)
					break;
				str+=2;
				str2+=2;
			}
			string = str+2;
			kanji = (uint16*) kanjitxt;


			// Japanese Kanji follows
			while(*kanji++ !=0xffff)
			{
				if (scaleH==0x10000)
					width += 16;
				else
					width += ((16*scaleH)>>16);
			}
//			return(width);
			continue;
		}
#endif
		if (letter == 17 || letter == 18)	// Arrows
		{
			width+=14;
			continue;
		}
		if (letter>129)
			continue;
		if (letter>10 && letter<32)
			continue;
		if (letter=='(' || letter==')' || letter=='$' || letter=='~')
			continue;
		if (letter==32)
		{
			if (scaleH==0x10000)
				width += textString->wordSpacing;
			else
				width += ((textString->wordSpacing*scaleH)>>16);
			continue;
		}
		// Secret Sprites
		if (letter>=SECRET_CODE1 && letter<=SECRET_CODE3)
		{
			if (scaleH==0x10000)
				width += SECRETS_WIDTH;
			else
				width += ((SECRETS_WIDTH*scaleH)>>16);
			continue;
		}

		if (letter<11)
			letter += 81;
		else if (letter<16)
			letter += 91;
		else
			letter = T_remapASCII[letter-32];


		if (letter>='0' && letter<='9')
			width += ((12*scaleH)>>16);
		else
		{
//#ifdef LOAD_KANJI
//			if (textString->scaleH==0x10000)
//				width += 16;
//			else
//				width += ((16*textString->scaleH)>>16);
//#else
		if (scaleH==0x10000)
			width += (T_textSpacing[letter]+textString->letterSpacing);
		else
			width += ((((sint32)T_textSpacing[letter]+textString->letterSpacing)*scaleH)>>16);
//#endif
		}
	}

	width -= textString->letterSpacing;
	width &= 0xfffe;
	return(width);
}






int	T_RemovePrint(TEXTSTRING *textString)
{
	if (!textString)
		return(0);
	if (!(textString->flags&T_ACTIVE))
		return(0);
	textString->flags &= ~T_ACTIVE;
	T_numStrings--;
	return(1);
}

void T_RemoveAllPrints(void)
{
	T_InitPrint();
}




sint16	T_GetStringLen(char *string)
{
	sint16	len=1;

	while (*string++)
	{
		len++;
		if (len > MAX_STRING_SIZE)
			return(MAX_STRING_SIZE);
	}
	return(len);
}

#ifdef GAMEDEBUG
/******************************************************************************
 *			Display FPS
 *****************************************************************************/
void	DisplayFPS( void )
{
#if defined(PC_VERSION) || defined(PROFILE_ME)
	static	int	framecount=0;
	static	int updatecount=0;
	static int av[10]={0,0,0,0,0,0,0,0,0,0}, av_pos=0;
	int i;
	int average;

//return;
	displaytext_count = 30;
	updatecount++;
	framecount += camera.number_frames;

	// frame count averager
	av[av_pos++] = camera.number_frames;
	if (av_pos==10)
		av_pos = 0;

	if ( framecount>=60 )
	{
		/* Calculate average frame rate over last 10 counts */
		for (i=1, average=av[0]; i<10; i++)
			average += av[i];

		sprintf(display_string, "%d %d.%d", updatecount, average/10,average%10);
//		PrintDbug(3,1,display_string);
		if (!displaytext)
			displaytext = T_Print(10,30,0, display_string);
		else
			T_ChangeText(displaytext, display_string);
		updatecount = 0;
		framecount = 0;
	}
#endif
}
#endif

int DS_HowManySlotsPlaying();
extern int GnSpriteZPos;

void	T_DrawText(void)
{
	int	n;
	TEXTSTRING	*textString = T_textStrings;

#ifdef GAMEDEBUG
#ifdef PSX_VERSION

	DisplayFPS();				// TEMP TEMP
//	sprintf(GszDudeDebugMessage,"%d",DS_HowManySlotsPlaying());
//	sprintf(GszDudeDebugMessage,"%d %d %d",GnSpriteZPos,phd_znear,phd_zfar);
//	PrintDbug(5,15,GszDudeDebugMessage);
	displaytext_count -= camera.number_frames;
	if ( displaytext_count<0 || save_toggle)
	{
		displaytext_count = 0;
		if ( displaytext )
		{
			T_RemovePrint( displaytext );
			displaytext = NULL;
		}
	}
#endif
#endif

	for (n=0;n<MAX_TEXT_STRINGS;n++)
	{
		if (textString)
		{
			if (textString->flags&T_ACTIVE)
				T_DrawThisText(textString);
		}
		textString++;
	}
#if defined(GAMEDEBUG)
	RemoveDbugs();
#endif

}


#ifdef PC_VERSION

void	draw_border(sint32 xpos, sint32 ypos, sint32 zpos, sint32 width, sint32 height)
{
#ifdef GAMEDEBUG
	if (!objects[BORDERS].loaded)
		return;
#endif
	width -= 8;
	height -= 8;
	xpos += 4;
	ypos += 4;


   	S_DrawScreenSprite2d(xpos,ypos,zpos, 0x10000, 0x10000,
   					   (sint16)(objects[BORDERS].mesh_index + 0), 7, -1);
   	S_DrawScreenSprite2d(xpos+width,ypos,zpos, 0x10000, 0x10000,
   					   (sint16)(objects[BORDERS].mesh_index + 1), 7, -1);
   	S_DrawScreenSprite2d(xpos+width,ypos+height,zpos, 0x10000, 0x10000,
   					   (sint16)(objects[BORDERS].mesh_index + 2), 7, -1);
   	S_DrawScreenSprite2d(xpos,ypos+height,zpos, 0x10000, 0x10000,
   					   (sint16)(objects[BORDERS].mesh_index + 3), 7, -1);

   	S_DrawScreenSprite2d(xpos,ypos,zpos, width*0x2000, 0x10000,
   					   (sint16)(objects[BORDERS].mesh_index + 4), 7, -1);
   	S_DrawScreenSprite2d(xpos+width,ypos,zpos, 0x10000, height*0x2000,
   					   (sint16)(objects[BORDERS].mesh_index + 5), 7, -1);
   	S_DrawScreenSprite2d(xpos,ypos+height,zpos, width*0x2000, 0x10000,
   					   (sint16)(objects[BORDERS].mesh_index + 6), 7, -1);
   	S_DrawScreenSprite2d(xpos,ypos,zpos, 0x10000, height*0x2000,
   					   (sint16)(objects[BORDERS].mesh_index + 7), 7, -1);
}

#endif



void T_RightJustify(TEXTSTRING *textString)
{
	textString->flags |= T_RIGHTJUSTIFY;
}

void	T_DrawThisText(TEXTSTRING *textString)
{
#ifdef LOAD_KANJI
	int		i;
	uint8	*str, *str2;
	uint16	*kanji,kanji_char, kanjitxt[64];
#endif
	uint8	*string;
	uint32	letter=0;
	int		sprite;
	int		hw, hh, hw2,hh2,textheight;
	sint32	xpos, ypos, zpos;
	sint32	bxpos, bypos, bwidth=0, bheight=0;
	sint32	pixWidth;
	uint32	scaleV,scaleH;
//	uint32	scaleV2,scaleH2;
//	int		width,height;


#ifdef PC_VERSION
	scaleH = GetTextScaleH(textString->scaleH);
	scaleV = GetTextScaleV(textString->scaleV);
#else
	scaleH = textString->scaleH;
	scaleV = textString->scaleV;
#endif


	textheight = (TEXT_HEIGHT*scaleV)>>16;

	// do flashing text: count down from +rate to -rate (no text when -ve)
	if (textString->flags & T_FLASH)
	{
		textString->flashCount -= (sint16)camera.number_frames;
		if (textString->flashCount <= -textString->flashRate)
			textString->flashCount = textString->flashRate;
		else if (textString->flashCount < 0)
			return;
	}

	string = textString->string;
	xpos	= textString->xpos + SCR_LEFT;
	ypos	= textString->ypos + SCR_TOP;
	zpos	= textString->zpos;

	// Coords for top left of text

	pixWidth = T_GetTextWidth(textString);

	if (textString->flags&T_CENTRE_H)
		xpos += (((SCR_RIGHT-SCR_LEFT) - pixWidth)/2);

	else if (textString->flags & T_RIGHTALIGN)
		xpos += ((SCR_RIGHT-SCR_LEFT) - pixWidth);

	else if (textString->flags & T_RIGHTJUSTIFY)
		xpos -= pixWidth;

	if (textString->flags&T_CENTRE_V)
		ypos += ((SCR_BOTTOM-SCR_TOP)/2);
	else if (textString->flags&T_BOTTOMALIGN)
		ypos += (SCR_BOTTOM-SCR_TOP);

	bxpos = xpos-((2*scaleH)>>16)+textString->bgndOffX;
	bypos = ypos-((4*scaleV)>>16)-textheight+textString->bgndOffY;

	while (*string)
	{
		letter = *(string++);

#ifdef LOAD_KANJI
		if (letter=='@')  // Start of special kanji sequence
		{
			str = string;
			str2 = (char*) kanjitxt;
			for (i=0;i<64;i++)
			{
				str2[0] = str[0];
				str2[1] = str[1];
				if (str[0]==0xff &&str[1]==0xff)
					break;
				str+=2;
				str2+=2;
			}
			string = str+2;
			kanji = (uint16*) kanjitxt;

			// Japanese Kanji follows
			while(1)
			{
				kanji_char=*kanji++;
				if (kanji_char==0xffff)
					break;

				kanji_char = (kanji_char&0x7fff)>>4;
				S_DrawKanji(xpos,ypos,zpos, scaleH, scaleV, (sint16)kanji_char, 16<<8, textString->textflags);

				if (scaleH==0x10000)
					xpos += 16;
				else
					xpos += ((16*scaleH)>>16);
			}
//			return;
			continue;
		}
#endif

		if (letter>18 && letter <32)
			continue;
		if (letter==32)
		{
			xpos += ((textString->wordSpacing*scaleH)>>16);
			continue;
		}
		if (letter>=SECRET_CODE1 && letter<=SECRET_CODE3)
		{
//##			S_DrawPickup( xpos+10, ypos, /*12288*/7144, (sint16)(objects[SECRET_ITEM1+(letter-SECRET_CODE1)].mesh_index), 16<<8, 0 );
			xpos += ((SECRETS_WIDTH*scaleH)>>16);
			continue;
		}
		if (letter>=SECRET_CODE1)
			continue;

		/* Gav: remap 'letter' to 'sprite' (remember letter so can do accents) */
		if (letter<11)
			sprite = letter + 81;
		else if (letter<=18)
			sprite = letter + 91;
		else
			sprite = T_remapASCII[letter-32];

		if (letter>='0' && letter<='9')
			xpos += ((((12-T_textSpacing[sprite])/2)*scaleH)>>16);

		if ((xpos > 0)	&& (xpos < SCR_RIGHT) && (ypos > 0) && (ypos < SCR_BOTTOM))
		{
			S_DrawScreenSprite2d(xpos, ypos, zpos, scaleH, scaleV, (sint16)(objects[ALPHABET].mesh_index + sprite),
								textString->Colour, textString->textflags);
		}

		/* Gav: don't shift text pos after a foriegn accent character */
		if (letter=='(' || letter==')' || letter=='$' || letter=='~')
			continue;

		if (letter>='0' && letter<='9')
			xpos += (((12-(12-T_textSpacing[sprite])/2)*scaleH)>>16);
		else
		{
			if (scaleH==0x10000)
			{
				if (sprite == 108 || sprite == 109)	// Arrows.
					xpos += 14;
				else
					xpos += (T_textSpacing[sprite]+textString->letterSpacing);
			}
			else
				xpos += ((((sint32)T_textSpacing[sprite]+textString->letterSpacing)*scaleH)>>16);
		}
	}


	if (textString->flags&T_ADDBACKGROUND || textString->flags&T_ADDOUTLINE)
	{
		if (textString->bgndSizeX)
		{
			bxpos += (pixWidth/2);
			pixWidth = textString->bgndSizeX;
			bxpos -= (pixWidth/2);
		}
		bwidth = pixWidth+4;

		if (textString->bgndSizeY)
			bheight = textString->bgndSizeY;
		else
			bheight = ((TEXT_HEIGHT+5)*scaleV)>>16;
	}


	if (textString->flags&T_ADDBACKGROUND)
	{
		if (textString->bgndGour)
		{
			hw = bwidth/2;
			hh = bheight/2;
			hw2 = bwidth - hw;
			hh2 = bheight - hh;

#ifdef PC_VERSION
			S_DrawScreenFBox( bxpos, bypos, zpos+textString->bgndOffZ+2, hw+hw2, hh+hh2, textString->bgndColour, textString->bgndGour, textString->bgndflags);
#else
			S_DrawScreenFBox( bxpos, bypos, zpos+textString->bgndOffZ+2, hw, hh, textString->bgndColour, textString->bgndGour, textString->bgndflags);
			S_DrawScreenFBox( bxpos+hw, bypos, zpos+textString->bgndOffZ+2, hw2, hh, textString->bgndColour, textString->bgndGour+4, textString->bgndflags);
			S_DrawScreenFBox( bxpos+hw, bypos+hh, zpos+textString->bgndOffZ+2, hw, hh2, textString->bgndColour, textString->bgndGour+8, textString->bgndflags);
			S_DrawScreenFBox( bxpos, bypos+hh, zpos+textString->bgndOffZ+2, hw2, hh2, textString->bgndColour, textString->bgndGour+12, textString->bgndflags);
#endif
		}
		else
		{
			S_DrawScreenFBox( bxpos, bypos, zpos+textString->bgndOffZ+2, bwidth, bheight, textString->bgndColour, textString->bgndGour, textString->bgndflags);
#ifndef PC_VERSION
			S_DrawScreenBox( bxpos, bypos, zpos+textString->bgndOffZ+1, bwidth, bheight, C_BLACK, NULL, 0);
#endif
		}
	}
	if (textString->flags&T_ADDOUTLINE)
	{
#ifndef PC_VERSION
		if (textString->outlGour)
		{
			hw = bwidth/2;
			hh = bheight/2;
			hw2 = bwidth - hw;
			hh2 = bheight - hh;
			S_DrawScreenLine( bxpos, bypos, zpos+textString->bgndOffZ, hw, 0, textString->outlColour, textString->outlGour, textString->outlflags);
			S_DrawScreenLine( bxpos+hw, bypos, zpos+textString->bgndOffZ, hw2, 0, textString->outlColour, textString->outlGour+1, textString->outlflags);
			S_DrawScreenLine( bxpos+bwidth, bypos, zpos+textString->bgndOffZ, 0, hh, textString->outlColour, textString->outlGour+2, textString->outlflags);
			S_DrawScreenLine( bxpos+bwidth, bypos+hh, zpos+textString->bgndOffZ, 0, hh2, textString->outlColour, textString->outlGour+3, textString->outlflags);
			S_DrawScreenLine( bxpos+bwidth, bypos+bheight, zpos+textString->bgndOffZ, -hw2, 0, textString->outlColour, textString->outlGour+4, textString->outlflags);
			S_DrawScreenLine( bxpos+hw, bypos+bheight, zpos+textString->bgndOffZ, -hw, 0, textString->outlColour, textString->outlGour+5, textString->outlflags);
			S_DrawScreenLine( bxpos, bypos+bheight, zpos+textString->bgndOffZ, 0, -hh2, textString->outlColour, textString->outlGour+6, textString->outlflags);
			S_DrawScreenLine( bxpos, bypos+hh, zpos+textString->bgndOffZ, 0, -hh, textString->outlColour, textString->outlGour+7, textString->outlflags);
		}
		else
			S_DrawScreenBox( bxpos, bypos, zpos+textString->bgndOffZ, bwidth, bheight, textString->outlColour, textString->outlGour, textString->outlflags);
#else
		draw_border(bxpos,bypos,0,bwidth,bheight);
#endif
	}
}


#ifdef GAMEDEBUG
#if (defined(PC_VERSION) && defined(GAMEDEBUG)) || defined(SHOW_ROOM_INFO) || defined(GAMEDEBUG)

#define NUM_DBUGS	32
int		tot_dbugs=0;
TEXTSTRING	*dbug_txt[NUM_DBUGS]={NULL};

void	PrintDbug(int x, int y, char *text)
{
	if (tot_dbugs>=NUM_DBUGS)
		return;
	dbug_txt[tot_dbugs] = T_Print(x*14,y*14+14,0,text);
//	T_SetScale(dbug_txt[tot_dbugs], 0x10000, 0x10000);
	tot_dbugs++;
}

void	RemoveDbugs(void)
{
	int	n;
	for (n=0;n<NUM_DBUGS;n++)
	{
		T_RemovePrint(dbug_txt[n]);
		dbug_txt[n]=NULL;
	}
	tot_dbugs=0;
}
#endif
#endif

#ifdef PC_VERSION
uint32 GetTextScaleH(uint32 scaleH)
{
	uint32	scale;
	int		width;

	width = GetRenderWidth();
	if (width<640)
		width=640;

	scale = (width<<16)/width;
	scaleH = (scaleH>>8) * (scale>>8);

	return(scaleH);
}

uint32 GetTextScaleV(uint32 scaleV)
{
	uint32	scale;
	int		height;

	height = GetRenderHeight();
	if (height<480)
		height=480;

	scale = (height<<16)/height;
	scaleV = (scaleV>>8) * (scale>>8);

	return(scaleV);
}
#endif



