// Caption.c

#include "ult_64.h"
#include "main.h"
#include "file.h"
#include "define.h"
#include "ml.h"

#include "misc.h"
#include "playgfx.h"
#include "caption.h"


#define KERN_FULL	0
#define KERN_TOP	1
#define KERN_BOT	2
#define KERN_NONE	3


typedef struct SPassIcons
{
	RGBA16
		Pal[16];
	u8
		Tex[5][16*8/2];
} SPassIcons;

typedef struct SLetter
{
	u8
		Width,
		Height,
		Drop,
		pad,
		KernLeft,
		KernRight;
	u16
		Offset;
} SLetter;


static SPassIcons
	*PassIcons;

static u8
	*Font,
	*Texture;

static s32
	Width,
	Player;


void Caption_Init( void *workspace )
{
	s32
		i;

	Texture = MemMalloc( 128*8, MEM_ANY );
	Font = AllocAndLoadFile( "PCapName.FNT", MEM_ANY );

	Player = -1;


	PassIcons = AllocAndLoadFile( "PassIcon.TEX", MEM_ANY );
	PassIcons->Pal[0].a = 0;
}


void Caption_Deinit()
{
	MemFree( PassIcons );
	MemFree( Font );
	MemFree( Texture );
}


static void DrawLetter( SLetter *letter, s32 pos )
{
	u8
		x,
		y,
		*src,
		*dst;

	if (letter->Offset)
	{
		src = &Font[letter->Offset];

		dst = &Texture[pos];
		dst += (u32)letter->Drop * 128;

		for (y=0; y<letter->Height; y++)
		{
			for (x=0; x<letter->Width; x++)
			{
				dst[x] = *src++;
			}

			dst += 128;
		}
	}
}


static void DrawName( char *name )
{
	SLetter
		*letter;
	u32
		kern = KERN_NONE;
	s32
		x = 0;
	char
		c;

	while (*name)
	{
		c = *name++;
		if (c >= 'a' && c <= 'z')
			c -= ('a' - 'A');

		letter = (SLetter *)&Font[4*4];
		letter += (c - ' ');

		if (kern != KERN_NONE)
		{
			if (!((kern == KERN_TOP && letter->KernLeft == KERN_BOT) ||
						(kern == KERN_BOT && letter->KernLeft == KERN_TOP)))
				x++;
		}

		DrawLetter( letter, x );

		kern = letter->KernRight;
		x += letter->Width;
	}

	Width = x;
}


Gfx *Caption_Draw( Gfx *gp, dyn *d, playert *plyr )
{
	SPlayerInfo
		*pi;
	char
		name[32];
	s32
		i,
		b,
		t,
		x,
		y,
		z;

	if (replay_flag)
		return( gp );


	if (plyr->no != Player)
	{
		Player = plyr->no;
		GetProperName( plyr->no, name );
		Set32s( Texture, 0, 128*8/4 );
		DrawName( name );
	}

	x = (plyr->flip_xco)>>10;
	y = (plyr->flip_zco)>>10;
	z = (plyr->flip_yco)>>10;

	if (!VertexProject2( x, y, z, &x, &y, &z , d ))
	{
		gDPPipeSync(gp++);
		gDPSetRenderMode( gp++, G_RM_XLU_SURF, G_RM_XLU_SURF2 );
		gDPSetTextureLUT( gp++, G_TT_NONE );
		gDPSetCombineMode( gp++, G_CC_DECALRGBA, G_CC_DECALRGBA );
		gDPSetTexturePersp( gp++, G_TP_NONE );
	//	gDPSetTextureFilter( gp++, G_TF_POINT );
		gDPLoadTextureBlock( gp++,
												 Texture,
												 G_IM_FMT_IA,
												 G_IM_SIZ_8b,
												 128, 8,
												 0,
												 G_TX_CLAMP, G_TX_CLAMP,
												 7, 3,
												 G_TX_NOLOD, G_TX_NOLOD );
		gDPSetAlphaCompare( gp++, G_AC_NONE );

		x -= Width/2;
		gSPTextureRectangle( gp++, x<<2, y<<2, (x+Width)<<2, (y+8)<<2, 0, 0<<5, 0<<5, (1<<10), (1<<10) );
	}


	if (icon_flag)
	{
		b = plyr->base;
		plyr = &player[b];
		pi = &PlayerInfos[b];

		gDPPipeSync(gp++);
		gDPSetRenderMode( gp++, G_RM_OPA_SURF, G_RM_OPA_SURF2 );
		gDPSetCombineMode( gp++, G_CC_DECALRGBA, G_CC_DECALRGBA );
		gDPSetAlphaCompare( gp++, G_AC_THRESHOLD );
		gDPSetBlendColor( gp++, 0, 0, 0, 128 );
		gDPSetTextureLUT( gp++, G_TT_RGBA16 );
		gDPLoadTLUT_pal16( gp++, 0, PassIcons->Pal );

		gDPLoadTextureBlock_4b( gp++,
														PassIcons->Tex,
														G_IM_FMT_CI,
														16, 5*8,
														0,
														G_TX_CLAMP, G_TX_CLAMP,
														4, 6,
														G_TX_NOLOD, G_TX_NOLOD );

		for (i=0; i<5; i++)
		{
			if (bhp != plyr && pi->Display)
			{
				x = (plyr->flip_xco)>>10;
				y = ((plyr->flip_zco)>>10) + 2048;
				z = (plyr->flip_yco)>>10;

				if (!VertexProject2( x, y, z, &x, &y, &z , d ))
				{
					switch (pass_mask[i])
					{
						case CTRL_C_DOWN:		t = (1*8);		break;
						case CTRL_C_LEFT:		t = (2*8);		break;
						case CTRL_C_UP:			t = (0*8);		break;
						case CTRL_C_RIGHT:	t = (3*8);		break;
						case CTRL_FIRE_A:		t = (4*8);		break;
					}

					x -= 12/2;
					gSPTextureRectangle( gp++, x<<2, y<<2, (x+12)<<2, (y+8)<<2, 0, 0<<5, t<<5, (16<<10)/12, (1<<10) );
				}
			}

			plyr++;
			pi++;
		}
	}

	return( gp );
}


void Caption_Reset()
{
	Player = -1;
}
