//-----------------------------------------------------------------------------
// FILE: BITFONT.CPP
//
// Desc: bit font rasterizer (Adapted from the Xbox vstune sample application).
//
// Copyright (c) 2001 Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
#include <xtl.h>

// pack the structure as we're reading it from the disk
#pragma pack( 1 )

// disable C4200: nonstandard extension used : zero-sized array in struct/union
#pragma warning( push )
#pragma warning( disable:4200 )

//----------------------------------------------------------------------------
struct BitFontCharInfo
{
    BYTE bWidth;
    BYTE dwOffset[4];
};

//----------------------------------------------------------------------------
struct BitFontInfo
{
    DWORD   dwSig;
    DWORD   dwFontHeight;
    DWORD   cBfis;
    BitFontCharInfo rgBfi[1];
};

#pragma warning( pop )
#pragma pack( )

//----------------------------------------------------------------------------
// default font
static const BYTE rgSmallFont[] =
{
0x30, 0x30, 0x42, 0x46, 0x00, 0x00, 0x00, 0x0f,  0x00, 0x00, 0x00, 0x60,  0x08, 0x00, 0x00, 0x00,
0x00, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x1e, 0x00, 0x00, 0x00, 0x08, 0x2d, 0x00, 0x00, 0x00,
0x08, 0x3c, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x00, 0x00, 0x00, 0x08, 0x5a, 0x00, 0x00, 0x00, 0x08,
0x69, 0x00, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x08, 0x87, 0x00, 0x00, 0x00, 0x08, 0x96,
0x00, 0x00, 0x00, 0x08, 0xa5, 0x00, 0x00, 0x00, 0x08, 0xb4, 0x00, 0x00, 0x00, 0x08, 0xc3, 0x00,
0x00, 0x00, 0x08, 0xd2, 0x00, 0x00, 0x00, 0x08, 0xe1, 0x00, 0x00, 0x00, 0x08, 0xf0, 0x00, 0x00,
0x00, 0x08, 0xff, 0x00, 0x00, 0x00, 0x08, 0x0e, 0x01, 0x00, 0x00, 0x08, 0x1d, 0x01, 0x00, 0x00,
0x08, 0x2c, 0x01, 0x00, 0x00, 0x08, 0x3b, 0x01, 0x00, 0x00, 0x08, 0x4a, 0x01, 0x00, 0x00, 0x08,
0x59, 0x01, 0x00, 0x00, 0x08, 0x68, 0x01, 0x00, 0x00, 0x08, 0x77, 0x01, 0x00, 0x00, 0x08, 0x86,
0x01, 0x00, 0x00, 0x08, 0x95, 0x01, 0x00, 0x00, 0x08, 0xa4, 0x01, 0x00, 0x00, 0x08, 0xb3, 0x01,
0x00, 0x00, 0x08, 0xc2, 0x01, 0x00, 0x00, 0x08, 0xd1, 0x01, 0x00, 0x00, 0x08, 0xe0, 0x01, 0x00,
0x00, 0x08, 0xef, 0x01, 0x00, 0x00, 0x08, 0xfe, 0x01, 0x00, 0x00, 0x08, 0x0d, 0x02, 0x00, 0x00,
0x08, 0x1c, 0x02, 0x00, 0x00, 0x08, 0x2b, 0x02, 0x00, 0x00, 0x08, 0x3a, 0x02, 0x00, 0x00, 0x08,
0x49, 0x02, 0x00, 0x00, 0x08, 0x58, 0x02, 0x00, 0x00, 0x08, 0x67, 0x02, 0x00, 0x00, 0x08, 0x76,
0x02, 0x00, 0x00, 0x08, 0x85, 0x02, 0x00, 0x00, 0x08, 0x94, 0x02, 0x00, 0x00, 0x08, 0xa3, 0x02,
0x00, 0x00, 0x08, 0xb2, 0x02, 0x00, 0x00, 0x08, 0xc1, 0x02, 0x00, 0x00, 0x08, 0xd0, 0x02, 0x00,
0x00, 0x08, 0xdf, 0x02, 0x00, 0x00, 0x08, 0xee, 0x02, 0x00, 0x00, 0x08, 0xfd, 0x02, 0x00, 0x00,
0x08, 0x0c, 0x03, 0x00, 0x00, 0x08, 0x1b, 0x03, 0x00, 0x00, 0x08, 0x2a, 0x03, 0x00, 0x00, 0x08,
0x39, 0x03, 0x00, 0x00, 0x08, 0x48, 0x03, 0x00, 0x00, 0x08, 0x57, 0x03, 0x00, 0x00, 0x08, 0x66,
0x03, 0x00, 0x00, 0x08, 0x75, 0x03, 0x00, 0x00, 0x08, 0x84, 0x03, 0x00, 0x00, 0x08, 0x93, 0x03,
0x00, 0x00, 0x08, 0xa2, 0x03, 0x00, 0x00, 0x08, 0xb1, 0x03, 0x00, 0x00, 0x08, 0xc0, 0x03, 0x00,
0x00, 0x08, 0xcf, 0x03, 0x00, 0x00, 0x08, 0xde, 0x03, 0x00, 0x00, 0x08, 0xed, 0x03, 0x00, 0x00,
0x08, 0xfc, 0x03, 0x00, 0x00, 0x08, 0x0b, 0x04, 0x00, 0x00, 0x08, 0x1a, 0x04, 0x00, 0x00, 0x08,
0x29, 0x04, 0x00, 0x00, 0x08, 0x38, 0x04, 0x00, 0x00, 0x08, 0x47, 0x04, 0x00, 0x00, 0x08, 0x56,
0x04, 0x00, 0x00, 0x08, 0x65, 0x04, 0x00, 0x00, 0x08, 0x74, 0x04, 0x00, 0x00, 0x08, 0x83, 0x04,
0x00, 0x00, 0x08, 0x92, 0x04, 0x00, 0x00, 0x08, 0xa1, 0x04, 0x00, 0x00, 0x08, 0xb0, 0x04, 0x00,
0x00, 0x08, 0xbf, 0x04, 0x00, 0x00, 0x08, 0xce, 0x04, 0x00, 0x00, 0x08, 0xdd, 0x04, 0x00, 0x00,
0x08, 0xec, 0x04, 0x00, 0x00, 0x08, 0xfb, 0x04, 0x00, 0x00, 0x08, 0x0a, 0x05, 0x00, 0x00, 0x08,
0x19, 0x05, 0x00, 0x00, 0x08, 0x28, 0x05, 0x00, 0x00, 0x08, 0x37, 0x05, 0x00, 0x00, 0x08, 0x46,
0x05, 0x00, 0x00, 0x08, 0x55, 0x05, 0x00, 0x00, 0x08, 0x64, 0x05, 0x00, 0x00, 0x08, 0x73, 0x05,
0x00, 0x00, 0x08, 0x82, 0x05, 0x00, 0x00, 0x08, 0x91, 0x05, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3,
0xc3, 0xc3, 0xe7, 0xe7, 0xff, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x99,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0xc9, 0x80, 0xc9,
0xc9, 0xc9, 0x80, 0xc9, 0xc9, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xe7, 0xc3, 0x99, 0x9f, 0xcf, 0xe7,
0xf3, 0xf9, 0x99, 0xc3, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0x8f, 0x27, 0x25, 0x89, 0xf3, 0xe7, 0xcf,
0x91, 0xa4, 0xe4, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0x93, 0x93, 0xc7, 0x9f, 0x90, 0x99,
0x99, 0xc4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xe7, 0xe7, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xe7,
0xe7, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xe7, 0xe7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xe7, 0xe7,
0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0xe3, 0x80, 0xe3, 0xc9, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xe7, 0x81, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xe3, 0xf3, 0xe7, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf9, 0xf9, 0xf3, 0xf3, 0xe7, 0xe7, 0xcf, 0xcf, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1,
0xcc, 0xc8, 0xc8, 0xcc, 0xc4, 0xc4, 0xcc, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xe3,
0x83, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0x99,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0xf9,
0xe3, 0xf9, 0x99, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xcf, 0xc9, 0xc9, 0xc9,
0x99, 0x80, 0xf9, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x9f, 0x9f, 0x9f, 0x83, 0xf9,
0xf9, 0xf3, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xe7, 0xcf, 0x83, 0x99, 0x99, 0x99,
0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xf9, 0xf3, 0xf3, 0xe7, 0xe7, 0xcf, 0xcf,
0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0x89, 0xc3, 0x91, 0x99, 0x99, 0xc3,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0x99, 0x99, 0xc1, 0xf3, 0xe7, 0xc7, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xe3, 0xff, 0xff, 0xff, 0xe3, 0xe3, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xe3, 0xff, 0xff, 0xff, 0xe3, 0xe3, 0xf3, 0xe7, 0xff,
0xff, 0xff, 0xff, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc3, 0x99, 0x99, 0xf3, 0xe7, 0xe7, 0xff, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81,
0x3c, 0x3c, 0x30, 0x24, 0x24, 0x30, 0x3f, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3,
0x99, 0x99, 0x99, 0x81, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0x99, 0x99,
0x99, 0x83, 0x99, 0x99, 0x99, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0x9f,
0x9f, 0x9f, 0x99, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x93, 0x99, 0x99, 0x99,
0x99, 0x99, 0x93, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x9f, 0x9f, 0x9f, 0x83, 0x9f,
0x9f, 0x9f, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x9f, 0x9f, 0x9f, 0x83, 0x9f, 0x9f,
0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0x9f, 0x9f, 0x91, 0x99, 0x99,
0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x81, 0x99, 0x99, 0x99, 0x99,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xc3, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0x99, 0x99, 0xc3, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x93, 0x93, 0x87, 0x93, 0x93, 0x99, 0x99, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x81, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x9c, 0x9c, 0x88, 0x94, 0x94, 0x94, 0x9c, 0x9c, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x9c, 0x9c, 0x8c, 0x84, 0x90, 0x98, 0x9c, 0x9c, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83,
0x99, 0x99, 0x99, 0x83, 0x9f, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xf3, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x83, 0x99, 0x99,
0x99, 0x83, 0x93, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0x9f, 0xcf,
0xe7, 0xf3, 0xf9, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xe7, 0xe7, 0xe7, 0xe7,
0xe7, 0xe7, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9c, 0x9c, 0x9c, 0x94, 0x94, 0x94, 0xc9, 0xc9,
0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0xcb, 0xe7, 0xe7, 0xd3, 0x99, 0x99, 0x99,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xe7, 0xe7, 0xe7, 0xe7, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xf9, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x9f, 0x81, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc3, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xc3,
0xff, 0xff, 0xff, 0x9f, 0x9f, 0xcf, 0xcf, 0xe7, 0xe7, 0xf3, 0xf3, 0xf9, 0xf9, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xc3, 0xff, 0xe7,
0xc3, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xc7, 0xe7, 0xf3,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc3, 0xf9, 0xf9, 0xc1, 0x99, 0x99, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f, 0x83,
0x99, 0x99, 0x99, 0x99, 0x99, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99,
0x9f, 0x9f, 0x9f, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf9, 0xc1, 0x99, 0x99,
0x99, 0x99, 0x99, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0x81,
0x9f, 0x9f, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xcf, 0xcf, 0xcf, 0x81, 0xcf, 0xcf,
0xcf, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0x99, 0x99, 0x99, 0x99, 0x99,
0xc1, 0xf9, 0xf9, 0x83, 0xff, 0xff, 0xff, 0x9f, 0x9f, 0x83, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xe7, 0xff, 0x87, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0x81, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0xff, 0xc3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3,
0x87, 0xff, 0xff, 0xff, 0x9f, 0x9f, 0x99, 0x99, 0x93, 0x87, 0x93, 0x99, 0x99, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x87, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0x81, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x81, 0x94, 0x94, 0x94, 0x94, 0x94, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x83, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x83, 0x99, 0x99, 0x99, 0x99, 0x99, 0x83, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc1, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc1, 0xf9, 0xf9, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99,
0x91, 0x8f, 0x9f, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0x9f,
0x9f, 0xc3, 0xf9, 0xf9, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xcf, 0x81, 0xcf, 0xcf,
0xcf, 0xcf, 0xcf, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99,
0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9c, 0x94, 0x94, 0x94, 0x94, 0xc9,
0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0xc3, 0xe7, 0xc3, 0x99, 0x99,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xf3,
0xe7, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x81, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf3, 0xe7, 0xe7, 0xe7, 0xcf, 0x9f, 0xcf, 0xe7, 0xe7, 0xe7, 0xf3, 0xff,
0xff, 0xff, 0xff, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xff,
0xff, 0xff, 0xcf, 0xe7, 0xe7, 0xe7, 0xf3, 0xf9, 0xf3, 0xe7, 0xe7, 0xe7, 0xcf, 0xff, 0xff, 0xff,
0xff, 0x8e, 0x24, 0x71, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xff, 0xff, 0xff
};

BitFontInfo *m_pBitFontInfo = (BitFontInfo *)rgSmallFont;

//----------------------------------------------------------------------------
// Name: GetTextStringLength
//
// Desc: Returns pixel height and width of string
//----------------------------------------------------------------------------
void GetTextStringLength( DWORD *pdwWidth, DWORD *pdwHeight,
                                   const char *str )
{
  if( pdwWidth )
    *pdwWidth = 0;
  if( pdwHeight )
    *pdwHeight = 0;

  const char *sz = str;

  do
  {
    DWORD dwWidth = 0;

    // go through the string adding up the widths
    for( ; *sz; sz++ )
    {
      if ( *sz == '\n' )
      {
        ++sz;
        break;
      }

      DWORD iBfi = *sz - 32;

      if( iBfi >= m_pBitFontInfo->cBfis )
        iBfi = 0;
  
      dwWidth += m_pBitFontInfo->rgBfi[iBfi].bWidth;
    }
    
    if( pdwHeight )
      *pdwHeight += m_pBitFontInfo->dwFontHeight;
    
    if( pdwWidth )
      if ( dwWidth > *pdwWidth )
        *pdwWidth = dwWidth;
  } while ( *sz );
}

#include <ppcintrinsics.h>

//----------------------------------------------------------------------------
// Name: DrawText32
//
// Desc: Renders the font to a 32-bit surface
//----------------------------------------------------------------------------
void DrawText32( DWORD twidth, DWORD theight, D3DLOCKED_RECT* pLock,
                 BitFontInfo* m_pBitFontInfo, const char* str, 
                 DWORD dwcolFore, DWORD dwcolBack)
{
  int iY = 0;
  DWORD rgColor[2] = { dwcolBack, dwcolFore };

  BYTE *lpData = (BYTE *)&m_pBitFontInfo->rgBfi[m_pBitFontInfo->cBfis];
  DWORD *pdwSurfaceMaxY = (DWORD *)( (BYTE *)pLock->pBits + pLock->Pitch
                                     * theight );

  const char *sz = str;
  do
  {
    int iX = 0;

    for( ; *sz; sz++ )
    {
      DWORD *pdwSurface = (DWORD *)( (BYTE *)pLock->pBits + pLock->Pitch
                                     * iY ) + iX;
      DWORD *pdwSurfaceMaxX = (DWORD *)( (BYTE *)pLock->pBits + pLock->Pitch
                                         * iY ) + twidth;

      DWORD iBfi = *sz - 32;

      if ( *sz == '\n' )
      {
        if ( pdwSurface == pdwSurfaceMaxX )
        {
          ++sz;
          break;
        }
        --sz;
        iBfi = 0;
      }
      else     
        if( iBfi >= m_pBitFontInfo->cBfis )
          iBfi = 0;

      BitFontCharInfo *pbfi = &m_pBitFontInfo->rgBfi[iBfi];
      BYTE *lpBits = &lpData[__loadwordbytereverse(0,pbfi->dwOffset)];

      for( DWORD y = 0; y < m_pBitFontInfo->dwFontHeight; y++ )
      {
        DWORD dwWidth = pbfi->bWidth;

        while( dwWidth )
        {
          DWORD dwByte = *lpBits++;
          DWORD dwNumBits = min( dwWidth, 8 );

          dwWidth -= dwNumBits;

          while( dwNumBits-- && ( pdwSurface < pdwSurfaceMaxX ) )
          {
            DWORD iIndex = !( dwByte & 0x80 );

            *pdwSurface = rgColor[iIndex];

            pdwSurface++;
            dwByte <<= 1;
          }
        }

        pdwSurface = (DWORD *)( (BYTE *)(pdwSurface - pbfi->bWidth - dwWidth )
                                 + pLock->Pitch );
        pdwSurfaceMaxX = (DWORD *)( (BYTE *)pdwSurfaceMaxX + pLock->Pitch );
        if( pdwSurface >= pdwSurfaceMaxY )
         break;
      }

      iX += pbfi->bWidth;
    }
    iY += m_pBitFontInfo->dwFontHeight;
  } while ( *sz );
}


static LPDIRECT3DTEXTURE9 text = 0;
static D3DPixelShader  * PixelPassThrough = 0;
static D3DVertexShader * PositionAndTexCoordPassThrough = 0;
static DWORD twidth = 0, theight = 0;

//
// structure and definition for uploading our texture verts
//

#define POS_TC_VERTEX_FVF ( D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2( 0 ) )
typedef struct POS_TC_VERTEX 
{
  float sx, sy, sz;  // Screen coordinates
  float tu, tv;      // Texture coordinates 
} POS_TC_VERTEX;

static void draw_texture( LPDIRECT3DDEVICE9 d3d_device, int x_offset, int y_offset, DWORD width, DWORD height )
{
  POS_TC_VERTEX vertices[ 4 ];

  //
  // Turn on texture filtering and texture clamping
  //

  d3d_device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
  d3d_device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
  d3d_device->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
  d3d_device->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
  d3d_device->SetSamplerState( 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP );

  //
  // Select the texture.
  //

  d3d_device->SetTexture( 0, text );

  //
  // turn off Z buffering, culling, and projection (since we are drawing orthographically)
  //
  
  d3d_device->SetRenderState( D3DRS_ZENABLE, FALSE );
  d3d_device->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
  d3d_device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  d3d_device->SetRenderState( D3DRS_VIEWPORTENABLE, 0 );

  
  //
  // set the vertex format and turn on our vertex shader
  //
  
  d3d_device->SetFVF( POS_TC_VERTEX_FVF );
  d3d_device->SetVertexShader( PositionAndTexCoordPassThrough );

  
  //
  // turn on our pixel shader
  //
  
  d3d_device->SetPixelShader( PixelPassThrough );

  //
  // are we completely opaque or somewhat transparent?
  //
  
  d3d_device->SetRenderState( D3DRS_ALPHABLENDENABLE, 0 );
  
  //
  // Setup up the vertices.
  //

  vertices[ 0 ].sx = (float) x_offset;
  vertices[ 0 ].sy = (float) y_offset;
  vertices[ 0 ].sz = 0.0F;
  vertices[ 0 ].tu = 0.0f;
  vertices[ 0 ].tv = 0.0f;
  vertices[ 1 ] = vertices[ 0 ];
  vertices[ 1 ].sx = vertices[ 0 ].sx + ( (float)(int) width );
  vertices[ 1 ].tu = ( (float)(int) width ) / ( (float)(int) twidth );
  vertices[ 2 ] = vertices[0];
  vertices[ 2 ].sy = vertices[ 0 ].sy + ( (float)(int) height ) ;
  vertices[ 2 ].tv = ( (float)(int) height ) / ( (float)(int) theight );
  vertices[ 3 ] = vertices[ 1 ];
  vertices[ 3 ].sy = vertices[ 2 ].sy;
  vertices[ 3 ].tv = vertices[ 2 ].tv;

  //
  // Draw the vertices.
  //

  d3d_device->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, vertices, sizeof( vertices[ 0 ] ) );

  //
  // clear the texture
  //
  
  d3d_device->SetTexture( 0, 0 );
}

//
// simple pass through vertex shader
//

static CONST CHAR StrPositionAndTexCoordPassThrough[] = 
" struct VS_DATA                                        "
" {                                                     "
"     float4 Pos : POSITION;                            "
"     float4 T0: TEXCOORD0;                             "
" };                                                    "
"                                                       "
" VS_DATA main( VS_DATA In )                            "
" {                                                     "
"     return In;                                        "
" }                                                     ";

//
// simple pixel shader to apply the yuvtorgb matrix
//

static const char StrPixelPassThrough[] =
" sampler tex0   : register( s0 );      "
"                                       "
" struct VS_OUT                         "
" {                                     "
"     float2 T0: TEXCOORD0;             "
" };                                    "
"                                       "
" float4 main( VS_OUT In ) : COLOR      "
" {                                     "
"   float4 c;                           "
"   c = tex2D( tex0, In.T0 );           "
"   return c;                           "
" }                                     ";



//----------------------------------------------------------------------------
// Name: DrawText
//
// Desc: Draw the specified text to a surface
//----------------------------------------------------------------------------
void DrawText( LPDIRECT3DDEVICE9 d3d_device, const char* str, int iX, int iY,
               DWORD colFore, DWORD colBack )
{
  D3DLOCKED_RECT lockRect;
  DWORD width, height;
  
  GetTextStringLength( &width, &height, str );
  
  if ( ( twidth < width ) || ( theight < height ) )
  {
    if ( text )
    {
      text->Release();
      text = 0;
      twidth = 0;
      theight = 0;
    }

    d3d_device->CreateTexture( width, height, 1, 0, D3DFMT_LIN_X8R8G8B8, 0, &text, 0 );
    if ( text )
    {
      //
      // create a pixel shader that passes straight through
      //
      HRESULT hr;
      LPD3DXBUFFER buffer;

      twidth = width;
      theight = height;

      if ( PixelPassThrough == 0 )
      {
        hr = D3DXCompileShader( StrPixelPassThrough, sizeof( StrPixelPassThrough ),
                                0, 0, "main", "ps_2_0", 0, &buffer, NULL, NULL );
        if ( SUCCEEDED( hr ) )
        {
          hr = d3d_device->CreatePixelShader( (DWORD*) buffer->GetBufferPointer(), &PixelPassThrough );
          buffer->Release();
    
          if ( FAILED( hr ) )
          {
            return;
          }
        }
      }
        
      //
      // create a vertex shader that just passes the vertices straight through
      //
      
      if ( PositionAndTexCoordPassThrough == 0 )
      {
        hr = D3DXCompileShader( StrPositionAndTexCoordPassThrough, sizeof( StrPositionAndTexCoordPassThrough ),
                                0, 0, "main", "vs_2_0", 0, &buffer, NULL, NULL );
        if ( SUCCEEDED( hr ) )
        {
          hr = d3d_device->CreateVertexShader( (DWORD*) buffer->GetBufferPointer(), &PositionAndTexCoordPassThrough );
          buffer->Release();
    
          if ( FAILED( hr ) )
          {
            return;
          }
        }
      }
      // create pixel, create vertex
    }
  }

  text->LockRect( 0, &lockRect, NULL, 0 );

  DrawText32( twidth, theight, &lockRect, m_pBitFontInfo, str, 
              colFore, colBack );

  // Relase the lock on the surface
  text->UnlockRect( 0 );

  draw_texture( d3d_device, iX, iY, width, height );
}

void FreeDrawTextResources( void )
{
  if ( text )
  {
    text->Release();
    text = 0;
    twidth = 0;
    theight = 0;
  }

  if ( PixelPassThrough )
  {
    PixelPassThrough->Release();
    PixelPassThrough = 0;
  }

  if ( PositionAndTexCoordPassThrough )
  {
    PositionAndTexCoordPassThrough->Release();
    PositionAndTexCoordPassThrough = 0;
  }
}
