/*===========================================================================*/
/*                                                                           */
/* Mesa-3.0 DirectX 6 Driver                                                 */
/*                                                                           */
/* By Leigh McRae                                                            */
/*                                                                           */
/* http://www.altsoftware.com/                                               */
/*                                                                           */
/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */
/*===========================================================================*/
#include "d3dText.h"

/*=============================================================================

       1     
     ------
    |      | 
  6 |      | 2
    |  7   |
     ------  
    |      |
  5 |      | 3
    |      |
     ------ 
       4 

	    TL_0		TR_0
TLL		TL_1		TR_1	TRR

MLL_0   ML_0		MR_0	MRR_0
MLL_1   ML_1		MR_1	MRR_1

BLL		BL_0		BR_0	BRR
        BL_1		BR_1

=============================================================================*/

#define TLL		0
#define TRR		1
#define TL_0	2
#define TL_1	3
#define TR_0	4
#define TR_1	5

#define	MLL_0	6
#define	MLL_1	7
#define	MRR_0	8
#define	MRR_1	9

#define	ML_0	10
#define	ML_1	11
#define	MR_0	12
#define	MR_1	13

#define	BL_0	14
#define	BL_1	15
#define	BR_0	16
#define	BR_1	17
#define	BLL		18
#define	BRR		19

#define	BIT1	0x00000001
#define	BIT2	0x00000002
#define	BIT3	0x00000004
#define	BIT4	0x00000008
#define	BIT5	0x00000010
#define	BIT6	0x00000020
#define	BIT7	0x00000040

#define TOP		BIT4
#define MIDDLE		BIT7
#define BOTTOM		BIT1
#define TLEFT 		BIT5
#define BLEFT   	BIT6
#define LEFT		(TLEFT|BLEFT)
#define TRIGHT		BIT3
#define BRIGHT		BIT2
#define RIGHT		(TRIGHT|BRIGHT)
#define ALL		0xFFFFFFFF

/*===========================================================================*/
/*  This is the static array that will map the ASCII value of the character  */
/* being draw to the bit mask that will be scan converted to the LED display.*/
/*===========================================================================*/
DWORD	textBitMasks[] = 
{
  0xFFFFFFFF, // 000
  0xFFFFFFFF, // 001
  0xFFFFFFFF, // 002
  0xFFFFFFFF, // 003  
  0xFFFFFFFF, // 004
  0xFFFFFFFF, // 005
  0xFFFFFFFF, // 006
  0xFFFFFFFF, // 007  
  0xFFFFFFFF, // 008
  0xFFFFFFFF, // 009
  0xFFFFFFFF, // 010
  0xFFFFFFFF, // 011
  0xFFFFFFFF, // 012
  0xFFFFFFFF, // 013
  0xFFFFFFFF, // 014
  0xFFFFFFFF, // 015
  0xFFFFFFFF, // 016
  0xFFFFFFFF, // 017
  0xFFFFFFFF, // 018
  0xFFFFFFFF, // 019
  0xFFFFFFFF, // 020
  0xFFFFFFFF, // 021
  0xFFFFFFFF, // 022
  0xFFFFFFFF, // 023 
  0xFFFFFFFF, // 024
  0xFFFFFFFF, // 025
  0xFFFFFFFF, // 026
  0xFFFFFFFF, // 027
  0xFFFFFFFF, // 028
  0xFFFFFFFF, // 029
  0xFFFFFFFF, // 030
  0XFFFFFFFF, // 031 
  0x00000000, // 032 'SPC'
  0xFFFFFFFF, // 033
  0xFFFFFFFF, // 034
  0xFFFFFFFF, // 035
  0xFFFFFFFF, // 036
  0xFFFFFFFF, // 037
  0xFFFFFFFF, // 038
  0xFFFFFFFF, // 039
  0xFFFFFFFF, // 040
  0xFFFFFFFF, // 041
  0xFFFFFFFF, // 042
  0xFFFFFFFF, // 043
  0xFFFFFFFF, // 044
  0xFFFFFFFF, // 045
  0xFFFFFFFF, // 046
  0xFFFFFFFF, // 047 
  (ALL &~ MIDDLE), 			// 048	'0'
  (RIGHT),     				// 049	'1'
  (ALL &~ TLEFT &~ BRIGHT), // 050	'2'
  (ALL &~ LEFT), 			// 051	'3'
  (TLEFT | MIDDLE | RIGHT), // 052	'4'
  (ALL &~ TRIGHT &~ BLEFT), // 053	'5'
  (ALL &~ TRIGHT), 			// 054	'6'
  (TOP | RIGHT), 			// 055	'7'
  (ALL), 					// 056	'8'
  (ALL &~ BOTTOM &~ BLEFT), // 057	'9'
  0xFFFFFFFF, // 058
  0xFFFFFFFF, // 059
  0xFFFFFFFF, // 060
  0XFFFFFFFF, // 061
  0xFFFFFFFF, // 062
  0xFFFFFFFF, // 063
  0xFFFFFFFF, // 064
  (ALL &~ BOTTOM),			// 065	'A'
  (ALL), 					// 066	'B'
  (TOP | LEFT | BOTTOM), 	// 067	'C'
  (ALL &~ MIDDLE), 			// 068	'D'
  (ALL &~ RIGHT), 			// 069	'E'
  (LEFT | TOP | MIDDLE), 	// 070	'F'
  0x00000000,  				// 071	'G'
  (ALL &~ TOP &~ BOTTOM), 	// 072	'H'
  (RIGHT), 					// 073	'I'
  (RIGHT | BOTTOM),			// 074	'J'
  0x00000000,  				// 075	'K'
  (LEFT | BOTTOM),			// 076	'L'
  0x00000000, 				// 088	'M'
  0x00000000, 				// 089	'N'
  (ALL &~ MIDDLE),  		// 090	'O'
  (ALL &~ BRIGHT &~ BOTTOM),// 091	'P'
  0x00000000, 				// 092	'Q'
  0x00000000,				// 093	'R'
  (ALL &~ TRIGHT &~ BLEFT),	// 094	'S'
  0X00000000, 				// 095	'T'
  (LEFT | RIGHT | BOTTOM),  // 096	'U'
  0x00000000, 				// 097	'V'
  0x00000000, 				// 098	'W'
  0x00000000, 				// 099	'X'
  0x00000000,  				// 1000	'Z'
  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 100 
  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 104 
  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 108 
  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 112 
  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 116 
  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 120 
  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF   // 124 
};

#define	CT	1.0f
#define	CX	7.0f
#define	CY	13.0f
#define CM	((CY-(CT*3.0f))/2.0f)

float lCoords[][2] = 
{
  /* Top outsides. */
  { 0,  		(CY-CT) },		
  { CX, 		(CY-CT) },

  /* Top Line. */
  { CT, 		CY },
  { CT, 		(CY-CT) },
  { (CX-CT), 	CY },
  { (CX-CT), 	(CY-CT) },

  /* Middle outsides. */
  { 0.0f,		(CT+CM+CT) },
  { 0.0f,		(CT+CM) },
  { CX,			(CT+CM+CT) },
  { CX,			(CT+CM) },

  /* Middle Line. */
  { CT,			(CT+CM+CT) },	
  { CT,			(CT+CM)	},	
  { (CX-CT),	(CT+CM+CT) },
  { (CX-CT),	(CT+CM) },

  /* Bottom line. */
  { CT,			CT },
  { CT,			0.0f },
  { (CX-CT),	CT },
  { (CX-CT),	0.0f },

  /* Bottom outsides. */
  { 0.0f,		CT},
  { CX,			CT }
};

static int	ConvertCharacter( char *c, int cIndex,  PD3DFONTMETRICS pfntMetrics );

D3DTLVERTEX TextVertices[MAX_VERTICES];
/*===========================================================================*/
/*  When we attach I will zero out the whole D3D vertex buffer I'm using for */
/* the text.  This way I don't need to set all the redundant values.  I also */
/* set all the oow values to 1 as I will be doing direct rendering.          */
/*===========================================================================*/
/* RETURN: TRUE, FALSE.                                                      */
/*===========================================================================*/
extern "C" BOOL InitD3DText( void )
{
  int	index;

  /* Set the D3D Vertex Buffer up once so we don't do redundant changes. */
  memset( &TextVertices[0], 0, sizeof(TextVertices) );
  for( index = 0; index < MAX_VERTICES; index++ )
	TextVertices[index].rhw	= D3DVAL( 1.0 );

  return TRUE;
}
/*===========================================================================*/
/*  This function takes a single character and draw it using the supplied    */
/* fontmetrics structure.                                                    */
/*===========================================================================*/
/* RETURN:                                                                   */
/*===========================================================================*/
extern "C" void d3dTextDrawString( char *pszString, int x, int y, PD3DFONTMETRICS pfntMetrics )
{
  int	cIndex,
	     nIndex,
	     index;
  float	cWidth = CX,
	     cHeight = CY;

  /*  Find the max width/height of a character and add the spacing so */
  /* that we can use this value to calculate the x,y of the character.*/
  cWidth  = (cWidth  * pfntMetrics->fntXScale)  + pfntMetrics->fntXSpacing;
  cHeight = (cHeight * pfntMetrics->fntYScale) + pfntMetrics->fntYSpacing;

  /* Walk the string.  This must be NULL terminated. */
  for( cIndex = 0, nIndex = 0; *pszString; pszString++, cIndex = nIndex, x++ )
  {
	/* Convert the character and get the index into the text vertex buffer. */
	nIndex = ConvertCharacter( &pszString[0], cIndex, pfntMetrics );
	if ( (nIndex - cIndex) > 2 )
    {
	  /* Modify the text vertex buffer based on the fntMetrics structure. */
	  for( index = cIndex; index < nIndex; index++ )
	  {
		/* Scale the character. */
		TextVertices[index].sx	*= pfntMetrics->fntXScale;
		TextVertices[index].sy   *= pfntMetrics->fntYScale;
		
		/* Move the character. */
		TextVertices[index].sx	+= (cWidth*x);
		TextVertices[index].sy   += (cHeight*y);

		/* Set the color. */
		TextVertices[index].color = pfntMetrics->dwColor;
	  }
	}
  }

  if ( nIndex < 3 )
	return;

  /* Set the states that slim things down. */
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, 			D3DCULL_NONE );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_FILLMODE, 			D3DFILL_SOLID );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, 			FALSE );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE , 		FALSE );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, 	FALSE );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, 	FALSE );

  /* Blast them baby... */
  pfntMetrics->lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST,
										   D3DFVF_TLVERTEX,
										   (LPVOID)&TextVertices[0],
										   nIndex, 
										   (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) );
}
/*===========================================================================*/
/*  This function takes a single character and draw it directly to the screen*/
/* unsing the supplied fntMetrics structure.  The character will be drawn at */
/* the supplied x,y.  The x,y position is relative to the top left and uses  */
/* the spacing in the fntMetrics structure.                                  */
/*===========================================================================*/
/* RETURN:                                                                   */
/*===========================================================================*/
extern "C" void d3dTextDrawCharacter( char *c, int x, int y, PD3DFONTMETRICS pfntMetrics )
{
  int	cIndex = 0,
	    index;
  float	cWidth = CX,
	    cHeight = CY;

  /* Convert the character and get the index into the text vertex buffer. */
  cIndex = ConvertCharacter( c, 0, pfntMetrics );
  if ( cIndex < 3 )
	return;

  /*  Find the max width/height of a character and add the spacing so */
  /* that we can use this value to calculate the x,y of the character.*/
  cWidth  = (cWidth  * pfntMetrics->fntXScale)  + pfntMetrics->fntXSpacing;
  cHeight = (cHeight * pfntMetrics->fntYScale) + pfntMetrics->fntYSpacing;

  /* Modify the text vertex buffer based on the fntMetrics structure. */
  for( index = 0; index < cIndex; index++ )
  {
	/* Scale the character. */
	TextVertices[index].sx	*= pfntMetrics->fntXScale;
	TextVertices[index].sy   *= pfntMetrics->fntYScale;

	/* Move the character. */
	TextVertices[index].sx	+= (cWidth*x);
	TextVertices[index].sy   += (cHeight*y);

	/* Set the color. */
	TextVertices[index].color = pfntMetrics->dwColor;
  }
 

  /* Set the states that slim things down. */
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, 			D3DCULL_NONE );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_FILLMODE, 			D3DFILL_SOLID );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, 			FALSE );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE , 		FALSE );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, 	FALSE );
  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, 	FALSE );

  /* Blast them baby... */
  pfntMetrics->lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST,
										   D3DFVF_TLVERTEX,
										   (LPVOID)&TextVertices[0],
										   cIndex, 
										   (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) );
}
/*===========================================================================*/
/*  This function takes a single character and draw it using the supplied    */
/* fontmetrics structure.                                                    */
/*===========================================================================*/
/* RETURN:                                                                   */
/*===========================================================================*/
static int	ConvertCharacter( char *c, int cIndex,  PD3DFONTMETRICS pfntMetrics )
{
  DWORD	asciiChar = (int)(*c);

  /* Handle the TOP line. */
  if ( textBitMasks[asciiChar] & BIT1 )
  { 
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TL_0][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_0][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TR_0][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_0][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TR_1][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TR_1][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TL_1][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_1][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TL_0][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_0][1] );
  }

  /* Handle the TOP/BOTTOM RIGHT lines. */
  //  if ( textBitMasks[index] & (BIT2|BIT3) )
  if ( 1 == 0 )
  {
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TR_1][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TRR][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TRR][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[BRR][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[BRR][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[BRR][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[BRR][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[BR_0][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_0][1] );
    TextVertices[cIndex].sx	= D3DVAL( lCoords[TR_1][0] );
    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] );
  }
  else 
  {
	if ( textBitMasks[asciiChar] & BIT2 )
	{
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[TR_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[TR_1][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[TRR][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[TRR][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MRR_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MRR_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MRR_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MRR_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MR_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MR_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[TR_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[TR_1][1] );
	}
	if ( textBitMasks[asciiChar] & BIT3 )
	{
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MR_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MR_1][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MRR_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MRR_1][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[BRR][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[BRR][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[BRR][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[BRR][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[BR_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[BR_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MR_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MR_1][1] );
	}
  }

  /* Handle the TOP/BOTTOM LEFT lines. */
  //  if ( textBitMasks[asciiChar] & (BIT5|BIT6) )
  if ( 1 == 0 )
  {
	TextVertices[cIndex].sx	= D3DVAL( lCoords[TLL][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[TLL][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[TL_1][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_1][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BL_0][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BL_0][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BLL][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BLL][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[TLL][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[TLL][1] );
  }
  else 
  {
	if ( textBitMasks[asciiChar] & BIT5 )
	{
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MLL_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MLL_1][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[ML_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[ML_1][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[BL_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[BL_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[BL_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[BL_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[BLL][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[BLL][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MLL_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MLL_1][1] );
	}
	if ( textBitMasks[asciiChar] & BIT6 )
	{
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[TLL][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[TLL][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[TL_1][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[TL_1][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[ML_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[ML_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[ML_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[ML_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[MLL_0][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[MLL_0][1] );
	  TextVertices[cIndex].sx	= D3DVAL( lCoords[TLL][0] );
	  TextVertices[cIndex++].sy	= D3DVAL( lCoords[TLL][1] );
	}
  }

  /* Handle the MIDDLE line. */
  if ( textBitMasks[asciiChar] & BIT7 )
  {
	TextVertices[cIndex].sx	= D3DVAL( lCoords[ML_0][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_0][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[MR_0][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_0][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[MR_1][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_1][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[MR_1][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_1][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[ML_1][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_1][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[ML_0][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_0][1] );
  }

  /* Handle the BOTTOM line. */
  if ( textBitMasks[asciiChar] & BIT4 )
  {
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BL_0][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BR_0][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_0][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BR_1][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_1][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BR_1][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_1][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BL_1][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_1][1] );
	TextVertices[cIndex].sx	= D3DVAL( lCoords[BL_0][0] );
	TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] );
  }
  
  return cIndex;
}

#undef CM
#undef CY
#undef CX
#undef CT

#undef TLL
#undef TRR
#undef TL_0
#undef TL_1
#undef TR_0
#undef TR_1

#undef	MLL_0
#undef	MLL_1
#undef	MRR_0
#undef	MRR_1

#undef	ML_0
#undef	ML_1
#undef	MR_0
#undef	MR_1

#undef	BL_0
#undef	BL_1
#undef	BR_0
#undef	BR_1
#undef	BLL
#undef	BRR

#undef	BIT1
#undef	BIT2
#undef	BIT3
#undef	BIT4
#undef	BIT5
#undef	BIT6
#undef	BIT7

#undef TOP
#undef MIDDLE
#undef BOTTOM
#undef TLEFT
#undef BLEFT
#undef LEFT
#undef TRIGHT
#undef BRIGHT
#undef RIGHT
#undef ALL