/*--------------------------------------------------------------------*/
/*   Name   : printf3D.c                                              */
/*   Author : Carlos Sarria                                           */
/*   Date   : November 1997                                           */
/*                                                                    */
/*   Copyright : 1997 by VideoLogic Limited. All rights reserved.     */
/*--------------------------------------------------------------------*/

#include <kamui.h>

#include "ABCTable.h"
#include "printf3D.h"

/*#include <malloc.h>
*/



#define CTX_MASK_ALL   (KM_PARAMTYPE | KM_LISTTYPE | KM_COLORTYPE | KM_UVFORMAT |       \
                        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_CLAMPUV | KM_FLIPUV |                \
                        KM_FILTERMODE | KM_SUPERSAMPLE | KM_MIPMAPDADJUST |             \
                        KM_TEXTURESHADINGMODE | KM_COLORCLAMP | KM_PALETTEBANK)

KMVERTEXCONTEXT FontContext =
{
    CTX_MASK_ALL, KM_POLYGON, KM_OPAQUE_POLYGON, KM_PACKEDCOLOR, KM_32BITUV,
    KM_GREATER, KM_CULLSMALL, KM_SCREEN, KM_TEXTUREGOURAUD, KM_NOMODIFIER,
    FALSE, KM_ONE, KM_ZERO, FALSE, FALSE, KM_NOFOG, FALSE, FALSE, FALSE,
    KM_NOCLAMP, KM_NOFLIP, KM_BILINEAR /*KM_POINT_SAMPLE*/, FALSE, 0x4, KM_MODULATE, FALSE,
    0, 0, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
    0, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0.0f
};


/*--------------------------------------------------------------------*/
/*  Function Name   : printf3D                                        */ 
/*  Inputs          : PosX, PosY, Scale, Text                         */  
/*  Outputs         : None                                            */
/*  Returns         : None                                            */
/*  Globals Used    : ABCTexture, TextSize, TextU, TextV              */
/*                    (from ABCTable.h)                               */
/*  Description     :                                                 */
/*--------------------------------------------------------------------*/

void printf3D (float PosX, float PosY, float Scale, char *Text , KMVERTEXBUFFDESC *vertexBuffer )
{
	int			i = 0, Val,  CVert = 0, NumFaces;
	static int	Quad[4*MAX_LETT], bFirstTime = 1;
	float		CurPos = 0, VPos, HPos, UVHPos, UVVPos;
	float		TextColor[3] = { 1.0f, 1.0f, 1.0f };

	static KMVERTEX3 LettVert[4 * MAX_LETT];
    
    if (Scale<=0) return;

	/* The texture is created here (only once) reading data from ABCTable.h */
    if (bFirstTime) 
	{
		#define TEXTURE_RGBA(r,g,b,a)	( (int)((r)<<24) + (int)((g)<<16) + (int)((b)<<8) + (int)((a)<<0) )
		#define RGBA(r,g,b,a)	( (int)((a)<<24) + (int)((r)<<16) + (int)((g)<<8) + (int)((b)<<0) )
		#define RGB(r,g,b)	(  (0xff<<24) + ((int)(r)<<16) + ((int)(g)<<8) + ((int)(b)<<0) )
		static unsigned int texture[256*256];
		static KMWORD textureTwiddled[256*256];
		static KMSURFACEDESC SurfaceDesc;

        for (i=0; i<4*MAX_LETT; i++) Quad[i]=i;

	  	for (i=0; i<256*256; i++)
		{
			texture[i] = TEXTURE_RGBA(
				(char)((255-ABCTexture[i])*TextColor[0]), 
				(char)((255-ABCTexture[i])*TextColor[1]), 
				(char)((255-ABCTexture[i])*TextColor[2]),
				ABCTexture[i]	 );
		}

		kmCreateTextureSurface( &SurfaceDesc, 256, 256, KM_TEXTURE_TWIDDLED | KM_TEXTURE_RGB565 );
		kmuCreateTwiddledTexture( (void*)textureTwiddled, (void*)texture, 0, 0, KM_MAPSIZE_256, KM_TEXTURE_RGB565 );
		kmLoadTexture( &SurfaceDesc, (void*)textureTwiddled, 0, 0 );

		/* Initialize context */
		FontContext.bUseSpecular = TRUE;
		FontContext.pTextureSurfaceDesc = &SurfaceDesc;

		kmProcessVertexRenderState( &FontContext );

		/* Change sgl_map_trans16 to sgl_map16bit to get a opaque texture */
		bFirstTime = 0;
	}


/*	return;
*/

	NumFaces = i = CVert = 0;
	
	Scale *= SCALE_OFFSET;
	
	while (TRUE)
	{
		Val = (int)*(Text+i++);

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

	   if (Val==' ')  {CurPos += TextSize['1']*Scale; continue;}
  
	   VPos   = Scale*(30.0f/255.0f);
	   HPos   = Scale*TextSize[Val];
	   UVHPos = TextSize[Val];
	   UVVPos = (30.0f/255.0f);


	   LettVert[CVert].ParamControlWord 	= KM_VERTEXPARAM_NORMAL;
	   LettVert[CVert].fX					= PosX+CurPos;
	   LettVert[CVert].fY					= PosY;
	   LettVert[CVert].u.fInvW				= 1.0f;
	   LettVert[CVert].uBaseRGB.dwPacked	= RGB(255,255,255);
	   LettVert[CVert].uOffsetRGB.dwPacked	= RGBA(0,0,0,0);
	   LettVert[CVert].fU					= TextU[Val];
	   LettVert[CVert].fV					= TextV[Val];
		kmSetVertex( vertexBuffer, (void*)&LettVert[CVert], KM_VERTEXTYPE_03, sizeof(KMVERTEX3) );
	   CVert++;

	   LettVert[CVert].ParamControlWord 	= KM_VERTEXPARAM_NORMAL;
	   LettVert[CVert].fX					= PosX+CurPos+HPos;
	   LettVert[CVert].fY					= PosY;
	   LettVert[CVert].u.fInvW				= 1.0f;
	   LettVert[CVert].uBaseRGB.dwPacked	= RGB(255,255,255);
	   LettVert[CVert].uOffsetRGB.dwPacked	= RGBA(0,0,0,0);
	   LettVert[CVert].fU					= TextU[Val]+UVHPos;
	   LettVert[CVert].fV					= TextV[Val];
		kmSetVertex( vertexBuffer, (void*)&LettVert[CVert], KM_VERTEXTYPE_03, sizeof(KMVERTEX3) );
	   CVert++;

	   LettVert[CVert].ParamControlWord 	= KM_VERTEXPARAM_NORMAL;
	   LettVert[CVert].fX					= PosX+CurPos;
	   LettVert[CVert].fY					= PosY+VPos;
	   LettVert[CVert].u.fInvW				= 1.0f;
	   LettVert[CVert].uBaseRGB.dwPacked	= RGB(255,255,255);
	   LettVert[CVert].uOffsetRGB.dwPacked	= RGBA(0,0,0,0);
	   LettVert[CVert].fU					= TextU[Val];
	   LettVert[CVert].fV					= TextV[Val]-UVVPos;
		kmSetVertex( vertexBuffer, (void*)&LettVert[CVert], KM_VERTEXTYPE_03, sizeof(KMVERTEX3) );
	   CVert++;

	   LettVert[CVert].ParamControlWord 	= KM_VERTEXPARAM_ENDOFSTRIP;
	   LettVert[CVert].fX					= PosX+CurPos+HPos;
	   LettVert[CVert].fY					= PosY+VPos;
	   LettVert[CVert].u.fInvW				= 1.0f;
	   LettVert[CVert].uBaseRGB.dwPacked	= RGB(255,255,255);
	   LettVert[CVert].uOffsetRGB.dwPacked	= RGBA(0,0,0,0);
	   LettVert[CVert].fU					= TextU[Val]+UVHPos;
	   LettVert[CVert].fV					= TextV[Val]-UVVPos;
		kmSetVertex( vertexBuffer, (void*)&LettVert[CVert], KM_VERTEXTYPE_03, sizeof(KMVERTEX3) );
	   CVert++;



	   NumFaces++;

	   CurPos += TextSize[Val]*Scale;

	}

	kmSetVertexRenderState( &FontContext );		/* wish we had a way to restore the previous one afterwards */
	kmStartVertexStrip( vertexBuffer );


}





#if 0

void printf3D (float PosX, float PosY, float Scale, char *Text, SGLCONTEXT *SGLContext )
{
sgl_intermediate_map TempMap;
SGLVERTEX	LettVert[4*MAX_LETT];
int			i = 0, Val,  CVert = 0, FlipU, FlipV, Flags, TexName, NumFaces;
static int	Quad[4*MAX_LETT], TexID = 666; 
float		CurPos = 0, VPos, HPos, UVHPos, UVVPos;
float		TextColor[3] = { 0.0f, 0.0f, 0.0f };
    
    if (Scale<=0) return;

	/* The texture is created here (only once) reading data from ABCTable.h */
    if (TexID == 666) {

        for (i=0; i<4*MAX_LETT; i++) Quad[i]=i;

		TempMap.id[0]='I'; TempMap.id[1]='M'; TempMap.id[2]='A'; TempMap.id[3]='P';
		TempMap.x_dim = 256;
		TempMap.y_dim = 256;
		TempMap.pixels = (sgl_map_pixel *) malloc (4*256*256);

		for (i=0; i<256*256; i++)
		{
			(TempMap.pixels+i)->red   = (char) ((255-ABCTexture[i])*TextColor[0]);
			(TempMap.pixels+i)->green = (char) ((255-ABCTexture[i])*TextColor[1]);
			(TempMap.pixels+i)->blue  = (char) ((255-ABCTexture[i])*TextColor[2]);
			(TempMap.pixels+i)->alpha = ABCTexture[i];
		}

		/* Change sgl_map_trans16 to sgl_map16bit to get a opaque texture */
		TexID = sgl_create_texture (sgl_map_trans16, sgl_map_256x256, FALSE, FALSE, &TempMap, NULL);
	}

      NumFaces = i = CVert = 0;
	  
	  Scale *= SCALE_OFFSET;

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

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

	   if (Val==' ')  {CurPos += TextSize['1']*Scale; continue;}
  
	   VPos   = Scale*(30.0f/255.0f);
	   HPos   = Scale*TextSize[Val];
	   UVHPos = TextSize[Val];
	   UVVPos = (30.0f/255.0f);

	   LettVert[CVert].fX			= PosX+CurPos;
	   LettVert[CVert].fY			= PosY;
	   LettVert[CVert].fInvW		= 1.0f;
	   LettVert[CVert].u32Colour	= 0xFFFFFFFF;
	   LettVert[CVert].fUOverW		= TextU[Val];
	   LettVert[CVert].fVOverW		= TextV[Val];
	   CVert++;

	   LettVert[CVert].fX			= PosX+CurPos+HPos;
	   LettVert[CVert].fY			= PosY;
	   LettVert[CVert].fInvW		= 1.0f;
	   LettVert[CVert].u32Colour	= 0xFFFFFFFF;
	   LettVert[CVert].fUOverW		= TextU[Val]+UVHPos;
	   LettVert[CVert].fVOverW		= TextV[Val];
	   CVert++;

	   LettVert[CVert].fX			= PosX+CurPos+HPos;
	   LettVert[CVert].fY			= PosY+VPos;
	   LettVert[CVert].fInvW		= 1.0f;
	   LettVert[CVert].u32Colour	= 0xFFFFFFFF;
	   LettVert[CVert].fUOverW		= TextU[Val]+UVHPos;
	   LettVert[CVert].fVOverW		= TextV[Val]-UVVPos;
	   CVert++;

	   LettVert[CVert].fX			= PosX+CurPos;
	   LettVert[CVert].fY			= PosY+VPos;
	   LettVert[CVert].fInvW		= 1.0f;
	   LettVert[CVert].u32Colour	= 0xFFFFFFFF;
	   LettVert[CVert].fUOverW		= TextU[Val];
	   LettVert[CVert].fVOverW		= TextV[Val]-UVVPos;
       CVert++;

	   NumFaces++;

       CurPos += TextSize[Val]*Scale;

	  }

	  FlipU   = SGLContext->bFlipU;
	  FlipV   = SGLContext->bFlipV;
	  Flags   = SGLContext->u32Flags;
	  TexName = SGLContext->nTextureName;


	  SGLContext->bFlipU		= FALSE;
	  SGLContext->bFlipV		= FALSE;
	  SGLContext->nTextureName	= TexID;
	  SGLContext->u32Flags		= SGLTT_TEXTURE | SGLTT_BILINEAR ;

	  sgltri_quads (SGLContext, NumFaces, (int (*)[4])Quad, LettVert);

	  SGLContext->bFlipU		= FlipU;
	  SGLContext->bFlipV		= FlipV;
	  SGLContext->u32Flags		= Flags;
	  SGLContext->nTextureName	= TexName;

	   
	   
}
#endif

/*---------------------- End Of File -----------------------------------*/