font.cpp

00001 /*
00002 * "PS2" Application Framework
00003 *
00004 * University of Abertay Dundee
00005 * May be used for educational purposed only
00006 *
00007 * Author - Dr Henry S Fortuna
00008 *
00009 * $Revision: 1.2 $
00010 * $Date: 2007/08/19 12:45:10 $
00011 *
00012 */
00013 
00014 #include "font.h"
00015 
00016 #define LETTERSPERROW 16
00017 
00018 CFont::CFont()
00019 {
00020         m_DoubleHeight = false;
00021         
00022         m_FontWidths = new unsigned char[256];
00023 
00024         for(int i = 0; i < 256; i++)
00025                 m_FontWidths[i] = 16;
00026 }
00027 
00028 CFont::~CFont()
00029 {
00030         if(m_FontWidths)
00031                 delete [] m_FontWidths;
00032 }
00033 
00034 bool CFont::Load(const char * strWidths, bool DoubleHeight)
00035 {
00036         m_DoubleHeight = DoubleHeight;
00037         
00038         // Load the font widths from the file
00039         FILE * fp = fopen(strWidths, "rb");
00040 
00041         if(fp == NULL)
00042                 return false;
00043 
00044         if(m_FontWidths)
00045                 delete [] m_FontWidths;
00046 
00047         m_FontWidths = new unsigned char[256];
00048         fread(m_FontWidths, sizeof(unsigned char), 256, fp);
00049         fclose(fp);
00050 
00051         return true;
00052 }
00053 
00054 // Get the width of the first line of the string in pixels
00055 int CFont::GetStringWidth(const char * strText)
00056 {
00057         size_t textlen = strlen(strText);
00058         int size = 0;
00059 
00060         for(uint32 letter = 0; letter < textlen; letter++)
00061         {
00062                 if(strText[letter] == '\n')
00063                         break;
00064 
00065                 size += m_FontWidths[strText[letter]];
00066         }
00067 
00068         return size;
00069 }
00070 
00071 void CFont::RenderL(const int x, const int y, const char * strText, uint8 R, uint8 G, uint8 B, uint8 A)
00072 {
00073         // How many sprites we have to render
00074         size_t textlen = strlen(strText);
00075 
00076         if(textlen == 0)
00077                 return;
00078 
00079         VIFDynamicDMA.StartDirect();
00080         VIFDynamicDMA.StartAD();
00081         VIFDynamicDMA.AddAD(RGBAQ_SET(R,G,B,A,0), RGBAQ);
00082         VIFDynamicDMA.AddAD(GS_PRIM(GS_SPRITE, 0, 1, 0, 1, 0, 1, 0, 0), PRIM);
00083         VIFDynamicDMA.EndAD();
00084 
00085         VIFDynamicDMA.Add128(GS_GIFTAG_BATCH(textlen, 1, 0, 0, GIF_FLG_REGLIST, GS_BATCH_4(GIF_REG_UV,
00086                                                  GIF_REG_XYZ2, GIF_REG_UV, GIF_REG_XYZ2)));
00087 
00088         uint32 lastx = x;
00089         uint32 line = 0;
00090         uint32 uvOffset = 0;
00091         uint32 lineHeight = 16;
00092 
00093         if(m_DoubleHeight)
00094         {
00095                 uvOffset = 8;
00096                 lineHeight = 32;
00097         }
00098 
00099         // Loop through all the letters
00100         for(uint32 letter = 0; letter < textlen; letter++)
00101         {
00102                 char cLetter = strText[letter];
00103 
00104                 // If the letter is 'Newline' move down a line
00105                 if(cLetter == '\n')
00106                 {
00107                         ++line;
00108                         lastx = x;
00109                 }
00110 
00111                 // The width of the letter in pixels
00112                 int letterwidth = m_FontWidths[cLetter];
00113 
00114                 // Make the letterwidth even
00115                 letterwidth = (letterwidth % 2) ? letterwidth + 1 : letterwidth;
00116 
00117                 // Get the texture coordinates of the letter
00118                 int tx = cLetter % LETTERSPERROW;
00119                 int ty = cLetter / LETTERSPERROW;
00120 
00121                 // The texture coordinates of the center of the letter
00122                 int cx = (tx * 16) + 8;
00123         
00124                 // Work out the texture coordinates from the center of the letter
00125                 int u0 = ((cx - ((letterwidth) / 2)) << 4);
00126                 int v0 = ((ty * 16) << 4) + uvOffset;
00127 
00128                 int u1 = ((letterwidth) << 4) + u0;
00129                 int v1 = ((16) << 4) + v0 - uvOffset;
00130 
00131                 // Work out the positions of the corners of the sprites
00132                 int left        = lastx;
00133                 int right       = lastx + letterwidth;
00134                 int top         = y + (line * lineHeight);
00135                 int bottom      = y + (line * lineHeight) + lineHeight;
00136 
00137                 VIFDynamicDMA.Add64(UV_SET(u0, v0));
00138                 VIFDynamicDMA.Add64(XYZ2_SET(((left + 2048) << 4) - 8,
00139                                                                          ((top  + 2048) << 4) - 8,
00140                                                                          0xFFFFFF));
00141                 VIFDynamicDMA.Add64(UV_SET(u1, v1));
00142                 VIFDynamicDMA.Add64(XYZ2_SET(((right  + 2048) << 4) - 8,
00143                                                                          ((bottom + 2048) << 4) - 8,
00144                                                                          0xFFFFFF));
00145 
00146                 // Move the sprite position forward the size of the letter we just drew
00147                 lastx += letterwidth;
00148         }
00149 
00150         VIFDynamicDMA.EndDirect();
00151 }
00152 
00153 void CFont::RenderC(const int x, const int y, const char * strText, uint8 R = 0x80, uint8 G = 0x80, uint8 B = 0x80, uint8 A = 0x80)
00154 {
00155         RenderL(x - (GetStringWidth(strText) >> 1), y, strText, R, G, B, A);
00156 }
00157 
00158 void CFont::RenderR(const int x, const int y, const char * strText, uint8 R = 0x80, uint8 G = 0x80, uint8 B = 0x80, uint8 A = 0x80)
00159 {
00160         RenderL(x - GetStringWidth(strText), y, strText, R, G, B, A);
00161 }
00162 
00163 // A printf wrapper that uses our Render function.
00164 void CFont::printfL(const int x, const int y, uint8 R, uint8 G, uint8 B, uint8 A, const char * strText, ...)
00165 {
00166         // Unpack the extra arguments (...) using the format specificiation in 
00167         // strText into strBuffer
00168         va_list args;
00169         char strBuffer[4096];
00170 
00171         if (!strText)
00172                 return;
00173 
00174         va_start(args, strText);
00175         vsprintf(strBuffer, strText, args);
00176         va_end(args);
00177 
00178         RenderL(x, y, strBuffer, R, G, B, A);
00179 }
00180 
00181 // A printf wrapper that uses our Render function.
00182 void CFont::printfR(const int x, const int y, uint8 R, uint8 G, uint8 B, uint8 A, const char * strText, ...)
00183 {
00184         // Unpack the extra arguments (...) using the format specificiation in 
00185         // strText into strBuffer
00186         va_list args;
00187         char strBuffer[4096];
00188 
00189         if (!strText)
00190                 return;
00191 
00192         va_start(args, strText);
00193         vsprintf(strBuffer, strText, args);
00194         va_end(args);
00195 
00196         RenderL(x - GetStringWidth(strBuffer), y, strBuffer, R, G, B, A);
00197 }
00198 
00199 void CFont::printfC(const int x, const int y, uint8 R, uint8 G, uint8 B, uint8 A, const char * strText, ...)
00200 {
00201         // Unpack the extra arguments (...) using the format specificiation in 
00202         // strText into strBuffer
00203         va_list args;
00204         char strBuffer[4096];
00205 
00206         if (!strText)
00207                 return;
00208 
00209         va_start(args, strText);
00210         vsprintf(strBuffer, strText, args);
00211         va_end(args);
00212 
00213         RenderL(x - (GetStringWidth(strBuffer) >> 1), y, strBuffer, R, G, B, A);
00214 }

Generated on Sun May 18 21:45:08 2008 for PS2X by  doxygen 1.5.4