/*****************************************************************************
  Name : KMTable.c
  Date : August 1998
  Platform : ANSI compatible
 
  * Description : 
  This file is part of the KAMUI TOOLS library (KMTools.lib) used
  with the SDK demos for PowerVR series 2.

  Set of functions used to draw a text string using 3D polygons.


  Copyright : 1998 by VideoLogic Limited. All rights reserved.
******************************************************************************/
#include "KMTools.h"

#include "KMABCTable.dat" /* This file has texture and UV data */

#define MAX_LETTERS 500

/* Globals */

KMSURFACEDESC		TexABC;
KMVERTEXCONTEXT		VertexContextABC;

/* Private Function */
void ABCTableVertexContext(PKMVERTEXCONTEXT pVertexContext, KMSURFACEDESC  *pTexSurfDesc);

/*----------------------------------------------------------------------*/
/*  Function Name   : KMABCTableInit                                    */ 
/*  Inputs          : IsTranslucent                                     */  
/*  Outputs         :                                                   */
/*  Returns         :                                                   */
/*  Globals Used    : VertexContextABC TexABC                           */
/*  Description     : Reads and loads the texture and alloc memory for  */
/*                    the vertices									    */
/*----------------------------------------------------------------------*/
KMDWORD KMABCTableInit (int IsTranslucent)
{
KMDWORD			ErrorCode;
KMTEXTURETYPE	nTextureType;

	if(IsTranslucent) nTextureType = KM_TEXTURE_TWIDDLED | KM_TEXTURE_ARGB4444; 
	else			  nTextureType = KM_TEXTURE_TWIDDLED | KM_TEXTURE_RGB565;

	ErrorCode = kmCreateTextureSurface(
		&TexABC,				/* OUT	PKMSURFACEDESC	pSurfaceDesc */
		256,					/*	IN	KMINT32			nWidth */
		256,					/*	IN	KMINT32			nHeight */
		nTextureType			/*	IN	KMTEXTURETYPE	nTextureType */
	);

	if (ErrorCode != KMSTATUS_SUCCESS) return ErrorCode;


	/* Load and set texture */
	ErrorCode = kmLoadTexture( 
		&TexABC,											/* PKMSURFACEDESC pSurfaceDesc */
		(unsigned long *)ABCTable + (16 / sizeof(KMDWORD)),	/* PKMDWORD pTexture */
		FALSE,												/* KMBOOLEAN bAutoMipMap */
		FALSE												/* KMBOOLEAN bDither */
	);

	if (ErrorCode != KMSTATUS_SUCCESS) return ErrorCode;


	ABCTableVertexContext (&VertexContextABC, &TexABC);

	/* Everything's OK */
	return KMSTATUS_SUCCESS;
}
/*----------------------------------------------------------------------*/
/*  Function Name   : KMABCTablePrint3D                                 */ 
/*  Inputs          : PosX PosY fScale Color *Format (...)              */  
/*  Outputs         : None                                              */
/*  Returns         : None                                              */
/*  Globals Used    : VertexBufferDesc VertexContextABC TexABC          */
/*  Description     : Displays text.                                    */
/*----------------------------------------------------------------------*/
void KMABCTablePrint3D (float XPos, float YPos, float fScale, int Color, char *Format, ...)
{
unsigned	i,j;
int			Val;
float		XSize,	YSize;
float		UPos,	VPos;
float		USize,	VSize;
float		CurrentPos=0.0f;
int			StripL[] = {2};
char		Text[4096];
KMVERTEX_03 vBuffer[4];
va_list		args;

/* VertexBufferDesc is used for all the polys in the scene */
extern KMVERTEXBUFFDESC VertexBufferDesc;

	/* Reading the arguments to create our Text string*/
	  va_start(args,Format);
	  vsprintf(Text, Format,args);
	  va_end(args);

      i=0;
       
	  kmSetVertexRenderState (&VertexContextABC);

	   vBuffer[0].uBaseRGB.dwPacked	= Color | 0xFF000000;
	   vBuffer[1].uBaseRGB.dwPacked	= Color | 0xFF000000;
	   vBuffer[2].uBaseRGB.dwPacked	= Color | 0xFF000000;
	   vBuffer[3].uBaseRGB.dwPacked	= Color | 0xFF000000;

	   vBuffer[0].uOffsetRGB.dwPacked	= 0x00000000;
	   vBuffer[1].uOffsetRGB.dwPacked	= 0x00000000;
	   vBuffer[2].uOffsetRGB.dwPacked	= 0x00000000;
	   vBuffer[3].uOffsetRGB.dwPacked	= 0x00000000;
	  		 
	   vBuffer[0].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	   vBuffer[1].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	   vBuffer[2].ParamControlWord	= KM_VERTEXPARAM_NORMAL;
	   vBuffer[3].ParamControlWord	= KM_VERTEXPARAM_ENDOFSTRIP;

      while (TRUE)
	  {
       Val = (int)*(Text+i++);

	    if (Val==0 || i>MAX_LETTERS) break;

	   if (Val==' ')  {XPos += (fScale < 0.0f) ? 5.0f:10.0f; continue;}

	    if (fScale < 0.0f)
	   {  
		    XPos    += CurrentPos;
			UPos    =  U_System[Val];
			VPos    =  V_System[Val];
			YSize   =  12.0f;
			XSize   =  255.0f*Size_System[Val];
			USize	=  Size_System[Val];
			VSize	=   12.0f/255.0f;
			CurrentPos = 300.0f*Size_System[Val];
	   }
	   else 
	   {
		    XPos    += CurrentPos;
			UPos    =  U_Bold[Val];
			VPos    =  V_Bold[Val];
			YSize   =  30.0f*fScale;
			XSize   =  255.0f*Size_Bold[Val]*fScale;
			USize	=  Size_Bold[Val];
			VSize	=  30.0f/255.0f;	
			CurrentPos = 255.0f*Size_Bold[Val]*fScale;
	   }
	   vBuffer[0].fX		= XPos;
	   vBuffer[0].fY		= YPos;
	   vBuffer[0].u.fZ		= 256.0f;
	   vBuffer[0].fU		= UPos;
	   vBuffer[0].fV		= VPos;

	   vBuffer[1].fX		= XPos+XSize;
	   vBuffer[1].fY		= YPos;
	   vBuffer[1].u.fZ		= 256.0f;
	   vBuffer[1].fU		= UPos+USize;
	   vBuffer[1].fV		= VPos;
	  
	   vBuffer[2].fX		= XPos;
	   vBuffer[2].fY		= YPos+YSize;
	   vBuffer[2].u.fZ		= 256.0f;
	   vBuffer[2].fU		= UPos;
	   vBuffer[2].fV		= VPos-VSize;

	   vBuffer[3].fX		= XPos+XSize;
	   vBuffer[3].fY		= YPos+YSize;
	   vBuffer[3].u.fZ		= 256.0f;
	   vBuffer[3].fU		= UPos+USize;
	   vBuffer[3].fV		= VPos-VSize;
 
	    
      kmxxGetCurrentPtr(&VertexBufferDesc);
	  kmxxStartVertexStrip(&VertexBufferDesc);

	  for(j = 0; j<4; j++)
	  {
	       kmxxSetVertex_3(vBuffer[j].ParamControlWord, 
							vBuffer[j].fX, vBuffer[j].fY, vBuffer[j].u.fZ, 
							vBuffer[j].fU, vBuffer[j].fV,
							vBuffer[j].uBaseRGB.dwPacked, vBuffer[j].uOffsetRGB.dwPacked);
	  }


	  kmxxReleaseCurrentPtr(&VertexBufferDesc);

	  } /* end of loop */
	    
} 
/*----------------------------------------------------------------------*/
/*  Function Name   : KMABCTableRelease                                 */ 
/*  Inputs          : None                                              */  
/*  Outputs         : None                                              */
/*  Returns         : None                                              */
/*  Globals Used    : TexABC											*/
/*  Description     : Deallocate the memory allocated in InitABCTable.  */
/*----------------------------------------------------------------------*/
void KMABCTableRelease (void)
{
	kmFreeTexture(&TexABC);	
}
/*----------------------------------------------------------------------*/
/*  Function Name   :  ABCTableVertexContext                            */
/*  Inputs          :  pVertexContext, *pTexSurfDesc                    */  
/*  Outputs         :  None                                             */
/*  Returns         :  None                                             */
/*  Globals Used    :  RenderInfo                                       */
/*  Description     :  Sets standard render parameters.                 */
/*----------------------------------------------------------------------*/
void ABCTableVertexContext(PKMVERTEXCONTEXT pVertexContext, KMSURFACEDESC  *pTexSurfDesc)
{
    memset(pVertexContext, 0, sizeof(KMVERTEXCONTEXT));

	/*CONTEXT*/
	pVertexContext->RenderState	= KM_DEPTHMODE  		| KM_CULLINGMODE			
								| KM_SCREENCOORDINATION	| KM_SHADINGMODE
								| KM_MODIFIER 			| KM_ZWRITEDISABLE		
								| KM_SRCBLENDINGMODE	| KM_DSTBLENDINGMODE
								| KM_SRCSELECT			| KM_DSTSELECT
								| KM_FOGMODE			| KM_USESPECULAR
		 						| KM_USEALPHA			| KM_IGNORETEXTUREALPHA
								| KM_FLIPUV 			| KM_CLAMPUV 
								| KM_FILTERMODE			| KM_SUPERSAMPLE
								| KM_MIPMAPDADJUST 		| KM_TEXTURESHADINGMODE
								| KM_PARAMTYPE 			| KM_LISTTYPE 					
								| KM_COLORTYPE			| KM_USESPECULAR
								| KM_UVFORMAT;
    /* Texture */
	if (pTexSurfDesc) pVertexContext->pTextureSurfaceDesc	= pTexSurfDesc;

	pVertexContext->ParamType			= KM_POLYGON;
	pVertexContext->ListType			= KM_TRANS_POLYGON;
	pVertexContext->ColorType			= KM_PACKEDCOLOR;
	pVertexContext->UVFormat			= KM_32BITUV;
	pVertexContext->DepthMode			= KM_GREATEREQUAL;
	pVertexContext->ScreenCoordination	= KM_SCREEN;
	pVertexContext->SelectModifier		= KM_NOMODIFIER;
	pVertexContext->bZWriteDisable		= TRUE;			/* ARC1*/
	pVertexContext->SRCBlendingMode		= KM_SRCALPHA;
	pVertexContext->DSTBlendingMode		= KM_INVSRCALPHA;
	pVertexContext->bSRCSel				= FALSE;			/* ARC1*/
	pVertexContext->bDSTSel				= FALSE;			/* ARC1*/
	pVertexContext->FlipUV				= KM_NOFLIP;
	pVertexContext->ClampUV				= KM_NOCLAMP;
	pVertexContext->FilterMode			= KM_BILINEAR;
	pVertexContext->bSuperSample		= FALSE; 
	pVertexContext->MipMapAdjust		= KM_MIPMAP_D_ADJUST_1_00;
	pVertexContext->TextureShadingMode	= KM_MODULATE_ALPHA;
	pVertexContext->CullingMode			= KM_NOCULLING;
	pVertexContext->ShadingMode			= KM_TEXTUREGOURAUD;
	pVertexContext->FogMode				= KM_NOFOG;
	pVertexContext->bUseSpecular		= FALSE;
	pVertexContext->bUseAlpha			= TRUE;


	/* No effect on ARC1 */
	pVertexContext->bColorClamp			= FALSE;
	pVertexContext->PaletteBank			= 0;

	/* for GlobalColorData */
	pVertexContext->fFaceColorAlpha		= 1.0f;		/* Face Color Alpha */
	pVertexContext->fFaceColorRed		= 1.0f;		/* Face Color Red */
	pVertexContext->fFaceColorGreen		= 1.0f;		/* Face Color Green */
	pVertexContext->fFaceColorBlue		= 1.0f;		/* Face Color Blue */
	pVertexContext->fOffsetColorAlpha	= 0.0f;		/* Specular Color Alpha */
	pVertexContext->fOffsetColorRed		= 0.0f;		/* Specular Color Red */
	pVertexContext->fOffsetColorGreen	= 0.0f;		/* Specular Color Green */
	pVertexContext->fOffsetColorBlue	= 0.0f;		/* Specular Color Blue */


	kmProcessVertexRenderState(pVertexContext);
}