// font.c #ifdef JA2_PRECOMPILED_HEADERS #include "JA2 SGP ALL.H" #elif defined( WIZ8_PRECOMPILED_HEADERS ) #include "WIZ8 SGP ALL.H" #else #include "types.h" #include #include #include #include #include #include #include "sgp.h" #include "pcx.h" #include "memman.h" #include "fileman.h" #include "Font.h" #include "Debug.h" #if defined( JA2 ) || defined( UTIL ) #include "video.h" #else #include "video2.h" #endif #include "himage.h" #include "vobject.h" #include "vobject_blitters.h" #endif //******************************************************* // // Defines // //******************************************************* #define PALETTE_SIZE 768 #define STRING_DELIMITER 0 #define ID_BLACK 0 #define MAX_FONTS 25 //******************************************************* // // Typedefs // //******************************************************* SGPPaletteEntry gSgpPalette[256]; typedef struct { UINT16 usDefaultPixelDepth; FontTranslationTable *pTranslationTable; } FontManager; FontManager *pFManager; HVOBJECT FontObjs[MAX_FONTS]; INT32 FontsLoaded=0; // Destination printing parameters INT32 FontDefault=(-1); UINT32 FontDestBuffer=BACKBUFFER; UINT32 FontDestPitch=640*2; UINT32 FontDestBPP=16; SGPRect FontDestRegion={0,0,640,480}; BOOLEAN FontDestWrap=FALSE; UINT16 FontForeground16=0; UINT16 FontBackground16=0; UINT16 FontShadow16=DEFAULT_SHADOW; UINT8 FontForeground8=0; UINT8 FontBackground8=0; // Temp, for saving printing parameters INT32 SaveFontDefault=(-1); UINT32 SaveFontDestBuffer=BACKBUFFER; UINT32 SaveFontDestPitch=640*2; UINT32 SaveFontDestBPP=16; SGPRect SaveFontDestRegion={0,0,640,480}; BOOLEAN SaveFontDestWrap=FALSE; UINT16 SaveFontForeground16=0; UINT16 SaveFontShadow16=0; UINT16 SaveFontBackground16=0; UINT8 SaveFontForeground8=0; UINT8 SaveFontBackground8=0; //***************************************************************************** // SetFontColors // // Sets both the foreground and the background colors of the current font. The // top byte of the parameter word is the background color, and the bottom byte // is the foreground. // //***************************************************************************** void SetFontColors(UINT16 usColors) { UINT8 ubForeground, ubBackground; ubForeground=(UINT8)(usColors&0xff); ubBackground=(UINT8)((usColors&0xff00)>>8); SetFontForeground(ubForeground); SetFontBackground(ubBackground); } //***************************************************************************** // SetFontForeground // // Sets the foreground color of the currently selected font. The parameter is // the index into the 8-bit palette. In 8BPP mode, that index number is used // for the pixel value to be drawn for nontransparent pixels. In 16BPP mode, // the RGB values from the palette are used to create the pixel color. Note // that if you change fonts, the selected foreground/background colors will // stay at what they are currently set to. // //***************************************************************************** void SetFontForeground(UINT8 ubForeground) { UINT32 uiRed, uiGreen, uiBlue; if((FontDefault < 0) || (FontDefault > MAX_FONTS)) return; FontForeground8=ubForeground; uiRed=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubForeground].peRed; uiGreen=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubForeground].peGreen; uiBlue=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubForeground].peBlue; FontForeground16=Get16BPPColor(FROMRGB(uiRed, uiGreen, uiBlue)); } void SetFontShadow(UINT8 ubShadow ) { UINT32 uiRed, uiGreen, uiBlue; if((FontDefault < 0) || (FontDefault > MAX_FONTS)) return; //FontForeground8=ubForeground; uiRed=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubShadow].peRed; uiGreen=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubShadow].peGreen; uiBlue=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubShadow].peBlue; FontShadow16=Get16BPPColor(FROMRGB(uiRed, uiGreen, uiBlue)); if ( ubShadow != 0 ) { if ( FontShadow16 == 0 ) { FontShadow16 = 1; } } } //***************************************************************************** // SetFontBackground // // Sets the Background color of the currently selected font. The parameter is // the index into the 8-bit palette. In 8BPP mode, that index number is used // for the pixel value to be drawn for nontransparent pixels. In 16BPP mode, // the RGB values from the palette are used to create the pixel color. If the // background value is zero, the background of the font will be transparent. // Note that if you change fonts, the selected foreground/background colors will // stay at what they are currently set to. // //***************************************************************************** void SetFontBackground(UINT8 ubBackground) { UINT32 uiRed, uiGreen, uiBlue; if((FontDefault < 0) || (FontDefault > MAX_FONTS)) return; FontBackground8=ubBackground; uiRed=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubBackground].peRed; uiGreen=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubBackground].peGreen; uiBlue=(UINT32)FontObjs[FontDefault]->pPaletteEntry[ubBackground].peBlue; FontBackground16=Get16BPPColor(FROMRGB(uiRed, uiGreen, uiBlue)); } //Kris: These are new counterparts to the above functions. They won't // effect an 8BPP font, only 16. void SetRGBFontForeground( UINT32 uiRed, UINT32 uiGreen, UINT32 uiBlue ) { if((FontDefault < 0) || (FontDefault > MAX_FONTS)) return; FontForeground16 = Get16BPPColor( FROMRGB( uiRed, uiGreen, uiBlue ) ); } void SetRGBFontBackground( UINT32 uiRed, UINT32 uiGreen, UINT32 uiBlue ) { if((FontDefault < 0) || (FontDefault > MAX_FONTS)) return; FontBackground16 = Get16BPPColor( FROMRGB( uiRed, uiGreen, uiBlue ) ); } void SetRGBFontShadow( UINT32 uiRed, UINT32 uiGreen, UINT32 uiBlue ) { if((FontDefault < 0) || (FontDefault > MAX_FONTS)) return; FontShadow16 = Get16BPPColor( FROMRGB( uiRed, uiGreen, uiBlue ) ); } //end Kris //***************************************************************************** // ResetFontObjectPalette // // Sets the palette of a font, using an 8 bit palette (which is converted to // the appropriate 16-bit palette, and assigned to the HVOBJECT). // //***************************************************************************** BOOLEAN ResetFontObjectPalette(INT32 iFont) { Assert(iFont >= 0); Assert(iFont <= MAX_FONTS); Assert(FontObjs[iFont] !=NULL); SetFontObjectPalette8BPP(iFont, FontObjs[iFont]->pPaletteEntry); return(TRUE); } //***************************************************************************** // SetFontObjectPalette8BPP // // Sets the palette of a font, using an 8 bit palette (which is converted to // the appropriate 16-bit palette, and assigned to the HVOBJECT). // //***************************************************************************** UINT16 *SetFontObjectPalette8BPP(INT32 iFont, SGPPaletteEntry *pPal8) { UINT16 *pPal16; Assert(iFont >= 0); Assert(iFont <= MAX_FONTS); Assert(FontObjs[iFont] !=NULL); if((pPal16=Create16BPPPalette(pPal8))==NULL) return(NULL); FontObjs[iFont]->p16BPPPalette=pPal16; FontObjs[iFont]->pShadeCurrent=pPal16; return(pPal16); } //***************************************************************************** // SetFontObjectPalette16BPP // // Sets the palette of a font, using a 16 bit palette. // //***************************************************************************** UINT16 *SetFontObjectPalette16BPP(INT32 iFont, UINT16 *pPal16) { Assert(iFont >= 0); Assert(iFont <= MAX_FONTS); Assert(FontObjs[iFont] !=NULL); FontObjs[iFont]->p16BPPPalette=pPal16; FontObjs[iFont]->pShadeCurrent=pPal16; return(pPal16); } //***************************************************************************** // GetFontObjectPalette16BPP // // Sets the palette of a font, using a 16 bit palette. // //***************************************************************************** UINT16 *GetFontObjectPalette16BPP(INT32 iFont) { Assert(iFont >= 0); Assert(iFont <= MAX_FONTS); Assert(FontObjs[iFont] !=NULL); return(FontObjs[iFont]->p16BPPPalette); } //***************************************************************************** // GetFontObject // // Returns the VOBJECT pointer of a font. // //***************************************************************************** HVOBJECT GetFontObject(INT32 iFont) { Assert(iFont >= 0); Assert(iFont <= MAX_FONTS); Assert(FontObjs[iFont] !=NULL); return(FontObjs[iFont]); } //***************************************************************************** // FindFreeFont // // Locates an empty slot in the font table. // //***************************************************************************** INT32 FindFreeFont(void) { int count; for(count=0; count < MAX_FONTS; count++) if(FontObjs[count]==NULL) return(count); return(-1); } //***************************************************************************** // LoadFontFile // // Loads a font from an ETRLE file, and inserts it into one of the font slots. // This function returns (-1) if it fails, and debug msgs for a reason. // Otherwise the font number is returned. //***************************************************************************** INT32 LoadFontFile(UINT8 *filename) { VOBJECT_DESC vo_desc; UINT32 LoadIndex; Assert(filename!=NULL); Assert(strlen(filename)); if((LoadIndex=FindFreeFont())==(-1)) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, String("Out of font slots (%s)", filename)); #ifdef JA2 FatalError( "Cannot init FONT file %s", filename ); #endif return(-1); } vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE; strcpy(vo_desc.ImageFile, filename); if((FontObjs[LoadIndex]=CreateVideoObject(&vo_desc))==NULL) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, String("Error creating VOBJECT (%s)", filename)); #ifdef JA2 FatalError( "Cannot init FONT file %s", filename ); #endif return(-1); } if(FontDefault==(-1)) FontDefault=LoadIndex; return(LoadIndex); } //***************************************************************************** // UnloadFont - Delete the font structure // // Deletes the video object of a particular font. Frees up the memory and // resources allocated for it. // //***************************************************************************** void UnloadFont(UINT32 FontIndex) { Assert(FontIndex >= 0); Assert(FontIndex <= MAX_FONTS); Assert(FontObjs[FontIndex]!=NULL); DeleteVideoObject(FontObjs[FontIndex]); FontObjs[FontIndex]=NULL; } //***************************************************************************** // GetWidth // // Returns the width of a given character in the font. // //***************************************************************************** UINT32 GetWidth(HVOBJECT hSrcVObject, INT16 ssIndex) { ETRLEObject *pTrav; // Assertions Assert( hSrcVObject != NULL ); if ( ssIndex < 0 || ssIndex > 92 ) { int i=0; } // Get Offsets from Index into structure pTrav = &(hSrcVObject->pETRLEObject[ ssIndex ] ); return((UINT32)(pTrav->usWidth+pTrav->sOffsetX)); } //***************************************************************************** // StringPixLengthArg // // Returns the length of a string with a variable number of arguments, in // pixels, using the current font. Maximum length in characters the string can // evaluate to is 512. // 'uiCharCount' specifies how many characters of the string are counted. //***************************************************************************** INT16 StringPixLengthArg(INT32 usUseFont, UINT32 uiCharCount, UINT16 *pFontString, ...) { va_list argptr; wchar_t string[512]; Assert(pFontString!=NULL); va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); // make sure the character count is legal if (uiCharCount > wcslen(string)) { uiCharCount = wcslen(string); } else { if (uiCharCount < wcslen(string)) { // less than the full string, so whack off the end of it (it's temporary anyway) string[uiCharCount] = '\0'; } } return(StringPixLength(string, usUseFont)); } //***************************************************************************** // StringPixLengthArg // // Returns the length of a string with a variable number of arguments, in // pixels, using the current font. Maximum length in characters the string can // evaluate to is 512. Because this is for fast help text, all '|' characters are ignored for the // width calculation. // 'uiCharCount' specifies how many characters of the string are counted. // YOU HAVE TO PREBUILD THE FAST HELP STRING! //***************************************************************************** INT16 StringPixLengthArgFastHelp(INT32 usUseFont, INT32 usBoldFont, UINT32 uiCharCount, UINT16 *pFontString ) { wchar_t string[512]; UINT32 i, index; INT16 sBoldDiff = 0; UINT16 str[2]; Assert(pFontString!=NULL); wcscpy( string, pFontString ); // make sure the character count is legal if (uiCharCount > wcslen(string)) { uiCharCount = wcslen(string); } else { if (uiCharCount < wcslen(string)) { // less than the full string, so whack off the end of it (it's temporary anyway) string[uiCharCount] = '\0'; } } //now eliminate all '|' characters from the string. i = 0; while( i < uiCharCount ) { if( string[ i ] == '|' ) { for( index = i; index < uiCharCount; index++ ) { string[ index ] = string[ index + 1 ]; } uiCharCount--; //now we have eliminated the '|' character, so now calculate the size difference of the //bolded character. str[ 0 ] = string[ i ]; str[ 1 ] = 0; sBoldDiff += StringPixLength( str, usBoldFont ) - StringPixLength( str, usUseFont ); } i++; } return StringPixLength(string, usUseFont) + sBoldDiff; } //***************************************************************************************** // // StringNPixLength // // Return the length of the of the string or count characters in the // string, which ever comes first. // // Returns INT16 // // Created by: Gilles Beauparlant // Created on: 12/1/99 // //***************************************************************************************** INT16 StringNPixLength(UINT16 *string, UINT32 uiMaxCount, INT32 UseFont) { UINT32 Cur, uiCharCount; UINT16 *curletter,transletter; Cur = 0; uiCharCount = 0; curletter = string; while((*curletter) != L'\0' && uiCharCount < uiMaxCount ) { transletter=GetIndex(*curletter++); Cur+=GetWidth(FontObjs[UseFont], transletter); uiCharCount++; } return((INT16)Cur); } //***************************************************************************** // // StringPixLength // // Returns the length of a string in pixels, depending on the font given. // //***************************************************************************** INT16 StringPixLength(UINT16 *string, INT32 UseFont) { UINT32 Cur; UINT16 *curletter,transletter; if (string == NULL) { return(0); } Cur=0; curletter=string; while((*curletter) != L'\0') { transletter=GetIndex(*curletter++); Cur+=GetWidth(FontObjs[UseFont], transletter); } return((INT16)Cur); } //***************************************************************************** // // SaveFontSettings // // Saves the current font printing settings into temporary locations. // //***************************************************************************** void SaveFontSettings(void) { SaveFontDefault=FontDefault; SaveFontDestBuffer=FontDestBuffer; SaveFontDestPitch=FontDestPitch; SaveFontDestBPP=FontDestBPP; SaveFontDestRegion=FontDestRegion; SaveFontDestWrap=FontDestWrap; SaveFontForeground16 = FontForeground16; SaveFontShadow16 = FontShadow16; SaveFontBackground16 = FontBackground16; SaveFontForeground8 = FontForeground8; SaveFontBackground8 = FontBackground8; } //***************************************************************************** // // RestoreFontSettings // // Restores the last saved font printing settings from the temporary lactions // //***************************************************************************** void RestoreFontSettings(void) { FontDefault=SaveFontDefault; FontDestBuffer=SaveFontDestBuffer; FontDestPitch=SaveFontDestPitch; FontDestBPP=SaveFontDestBPP; FontDestRegion=SaveFontDestRegion; FontDestWrap=SaveFontDestWrap; FontForeground16 = SaveFontForeground16; FontShadow16 = SaveFontShadow16; FontBackground16 = SaveFontBackground16; FontForeground8 = SaveFontForeground8; FontBackground8 = SaveFontBackground8; } //***************************************************************************** // GetHeight // // Returns the height of a given character in the font. // //***************************************************************************** UINT32 GetHeight(HVOBJECT hSrcVObject, INT16 ssIndex) { ETRLEObject *pTrav; // Assertions Assert( hSrcVObject != NULL ); // Get Offsets from Index into structure pTrav = &(hSrcVObject->pETRLEObject[ ssIndex ] ); return((UINT32)(pTrav->usHeight+pTrav->sOffsetY)); } //***************************************************************************** // // GetFontHeight // // Returns the height of the first character in a font. // //***************************************************************************** UINT16 GetFontHeight(INT32 FontNum) { Assert(FontNum >= 0); Assert(FontNum <= MAX_FONTS); Assert(FontObjs[FontNum]!=NULL); return((UINT16)GetHeight(FontObjs[FontNum], 0)); } //***************************************************************************** // GetIndex // // Given a word-sized character, this function returns the index of the // cell in the font to print to the screen. The conversion table is built by // CreateEnglishTransTable() // //***************************************************************************** INT16 GetIndex(UINT16 siChar) { UINT16 *pTrav; UINT16 ssCount=0; UINT16 usNumberOfSymbols = pFManager->pTranslationTable->usNumberOfSymbols; // search the Translation Table and return the index for the font pTrav = pFManager->pTranslationTable->DynamicArrayOf16BitValues; while (ssCount < usNumberOfSymbols ) { if (siChar == *pTrav) { return ssCount; } ssCount++; pTrav++; } // If here, present warning and give the first index DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, String("Error: Invalid character given %d", siChar)); // Return 0 here, NOT -1 - we should see A's here now... return 0; } //***************************************************************************** // SetFont // // Sets the current font number. // //***************************************************************************** BOOLEAN SetFont(INT32 iFontIndex) { Assert(iFontIndex >= 0); Assert(iFontIndex <= MAX_FONTS); Assert(FontObjs[iFontIndex]!=NULL); FontDefault=iFontIndex; return(TRUE); } //***************************************************************************** // SetFontDestBuffer // // Sets the destination buffer for printing to, the clipping rectangle, and // sets the line wrap on/off. DestBuffer is a VOBJECT handle, not a pointer. // //***************************************************************************** BOOLEAN SetFontDestBuffer(UINT32 DestBuffer, INT32 x1, INT32 y1, INT32 x2, INT32 y2, BOOLEAN wrap) { Assert(x2 > x1); Assert(y2 > y1); FontDestBuffer=DestBuffer; FontDestRegion.iLeft=x1; FontDestRegion.iTop=y1; FontDestRegion.iRight=x2; FontDestRegion.iBottom=y2; FontDestWrap=wrap; return(TRUE); } //***************************************************************************** // mprintf // // Prints to the currently selected destination buffer, at the X/Y coordinates // specified, using the currently selected font. Other than the X/Y coordinates, // the parameters are identical to printf. The resulting string may be no longer // than 512 word-characters. Uses monochrome font color settings //***************************************************************************** UINT32 mprintf(INT32 x, INT32 y, UINT16 *pFontString, ...) { INT32 destx, desty; UINT16 *curletter, transletter; va_list argptr; wchar_t string[512]; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; Assert(pFontString!=NULL); va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); curletter=string; destx=x; desty=y; // Lock the dest buffer pDestBuf = LockVideoSurface( FontDestBuffer, &uiDestPitchBYTES ); while((*curletter)!=0) { transletter=GetIndex(*curletter++); if(FontDestWrap && BltIsClipped(FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion)) { destx=x; desty+=GetHeight(FontObjs[FontDefault], transletter); } // Blit directly if ( gbPixelDepth == 8 ) { Blt8BPPDataTo8BPPBufferMonoShadowClip(pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion, FontForeground8, FontBackground8); } else { Blt8BPPDataTo16BPPBufferMonoShadowClip((UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion, FontForeground16, FontBackground16, FontShadow16 ); } destx+=GetWidth(FontObjs[FontDefault], transletter); } // Unlock buffer UnLockVideoSurface( FontDestBuffer ); return(0); } void VarFindFontRightCoordinates( INT16 sLeft, INT16 sTop, INT16 sWidth, INT16 sHeight, INT32 iFontIndex, INT16 *psNewX, INT16 *psNewY, UINT16 *pFontString, ... ) { wchar_t string[512]; va_list argptr; va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); FindFontRightCoordinates( sLeft, sTop, sWidth, sHeight, string, iFontIndex, psNewX, psNewY ); } void VarFindFontCenterCoordinates( INT16 sLeft, INT16 sTop, INT16 sWidth, INT16 sHeight, INT32 iFontIndex, INT16 *psNewX, INT16 *psNewY, UINT16 *pFontString, ... ) { wchar_t string[512]; va_list argptr; va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, string, iFontIndex, psNewX, psNewY ); } void FindFontRightCoordinates( INT16 sLeft, INT16 sTop, INT16 sWidth, INT16 sHeight, UINT16 *pStr, INT32 iFontIndex, INT16 *psNewX, INT16 *psNewY ) { INT16 xp,yp; // Compute the coordinates to right justify the text xp = ((sWidth-StringPixLength(pStr,iFontIndex))) + sLeft; yp = ((sHeight-GetFontHeight(iFontIndex)) / 2) + sTop; *psNewX = xp; *psNewY = yp; } void FindFontCenterCoordinates( INT16 sLeft, INT16 sTop, INT16 sWidth, INT16 sHeight, UINT16 *pStr, INT32 iFontIndex, INT16 *psNewX, INT16 *psNewY ) { INT16 xp,yp; // Compute the coordinates to center the text xp = ((sWidth-StringPixLength(pStr,iFontIndex) + 1) / 2) + sLeft; yp = ((sHeight-GetFontHeight(iFontIndex)) / 2) + sTop; *psNewX = xp; *psNewY = yp; } //***************************************************************************** // gprintf // // Prints to the currently selected destination buffer, at the X/Y coordinates // specified, using the currently selected font. Other than the X/Y coordinates, // the parameters are identical to printf. The resulting string may be no longer // than 512 word-characters. //***************************************************************************** UINT32 gprintf(INT32 x, INT32 y, UINT16 *pFontString, ...) { INT32 destx, desty; UINT16 *curletter, transletter; va_list argptr; wchar_t string[512]; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; Assert(pFontString!=NULL); va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); curletter=string; destx=x; desty=y; // Lock the dest buffer pDestBuf = LockVideoSurface( FontDestBuffer, &uiDestPitchBYTES ); while((*curletter)!=0) { transletter=GetIndex(*curletter++); if(FontDestWrap && BltIsClipped(FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion)) { destx=x; desty+=GetHeight(FontObjs[FontDefault], transletter); } // Blit directly if ( gbPixelDepth == 8 ) { Blt8BPPDataTo8BPPBufferTransparentClip( (UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion ); } else { Blt8BPPDataTo16BPPBufferTransparentClip( (UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion ); } destx+=GetWidth(FontObjs[FontDefault], transletter); } // Unlock buffer UnLockVideoSurface( FontDestBuffer ); return(0); } UINT32 gprintfDirty(INT32 x, INT32 y, UINT16 *pFontString, ...) { INT32 destx, desty; UINT16 *curletter, transletter; va_list argptr; wchar_t string[512]; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; Assert(pFontString!=NULL); va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); curletter=string; destx=x; desty=y; // Lock the dest buffer pDestBuf = LockVideoSurface( FontDestBuffer, &uiDestPitchBYTES ); while((*curletter)!=0) { transletter=GetIndex(*curletter++); if(FontDestWrap && BltIsClipped(FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion)) { destx=x; desty+=GetHeight(FontObjs[FontDefault], transletter); } // Blit directly if ( gbPixelDepth == 8 ) { Blt8BPPDataTo8BPPBufferTransparentClip( (UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion ); } else { Blt8BPPDataTo16BPPBufferTransparentClip( (UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion ); } destx+=GetWidth(FontObjs[FontDefault], transletter); } // Unlock buffer UnLockVideoSurface( FontDestBuffer ); #if defined ( JA2 ) || defined( UTIL ) InvalidateRegion(x, y, x + StringPixLength(string, FontDefault), y + GetFontHeight(FontDefault)); #else InvalidateRegion(x, y, x + StringPixLength(string, FontDefault), y + GetFontHeight(FontDefault), INVAL_SRC_TRANS); #endif return(0); } //***************************************************************************** // gprintf_buffer // // Prints to the currently selected destination buffer, at the X/Y coordinates // specified, using the currently selected font. Other than the X/Y coordinates, // the parameters are identical to printf. The resulting string may be no longer // than 512 word-characters. //***************************************************************************** UINT32 gprintf_buffer( UINT8 *pDestBuf, UINT32 uiDestPitchBYTES, UINT32 FontType, INT32 x, INT32 y, UINT16 *pFontString, ...) { INT32 destx, desty; UINT16 *curletter, transletter; va_list argptr; wchar_t string[512]; Assert(pFontString!=NULL); va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); curletter=string; destx=x; desty=y; while((*curletter)!=0) { transletter=GetIndex(*curletter++); if(FontDestWrap && BltIsClipped(FontObjs[FontType], destx, desty, transletter, &FontDestRegion)) { destx=x; desty+=GetHeight(FontObjs[FontType], transletter); } // Blit directly if ( gbPixelDepth == 8 ) { Blt8BPPDataTo8BPPBufferTransparentClip( (UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion ); } else { Blt8BPPDataTo16BPPBufferTransparentClip( (UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion ); } destx+=GetWidth(FontObjs[FontType], transletter); } return(0); } UINT32 mprintf_buffer( UINT8 *pDestBuf, UINT32 uiDestPitchBYTES, UINT32 FontType, INT32 x, INT32 y, UINT16 *pFontString, ...) { INT32 destx, desty; UINT16 *curletter, transletter; va_list argptr; wchar_t string[512]; Assert(pFontString!=NULL); va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); curletter=string; destx=x; desty=y; while((*curletter)!=0) { transletter=GetIndex(*curletter++); if(FontDestWrap && BltIsClipped(FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion)) { destx=x; desty+=GetHeight(FontObjs[FontDefault], transletter); } // Blit directly if ( gbPixelDepth == 8 ) { Blt8BPPDataTo8BPPBufferMonoShadowClip(pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion, FontForeground8, FontBackground8); } else { Blt8BPPDataTo16BPPBufferMonoShadowClip((UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion, FontForeground16, FontBackground16, FontShadow16 ); } destx+=GetWidth(FontObjs[FontDefault], transletter); } return(0); } UINT32 mprintf_buffer_coded( UINT8 *pDestBuf, UINT32 uiDestPitchBYTES, UINT32 FontType, INT32 x, INT32 y, UINT16 *pFontString, ...) { INT32 destx, desty; UINT16 *curletter, transletter; va_list argptr; wchar_t string[512]; UINT16 usOldForeColor; Assert(pFontString!=NULL); va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); curletter=string; destx=x; desty=y; usOldForeColor = FontForeground16; while((*curletter)!=0) { if ( (*curletter) == 180 ) { curletter++; SetFontForeground( (UINT8)(*curletter) ); curletter++; } else if ( (*curletter) == 181 ) { FontForeground16 = usOldForeColor; curletter++; } transletter=GetIndex(*curletter++); if(FontDestWrap && BltIsClipped(FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion)) { destx=x; desty+=GetHeight(FontObjs[FontDefault], transletter); } // Blit directly if ( gbPixelDepth == 8 ) { Blt8BPPDataTo8BPPBufferMonoShadowClip(pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion, FontForeground8, FontBackground8); } else { Blt8BPPDataTo16BPPBufferMonoShadowClip((UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion, FontForeground16, FontBackground16, FontShadow16 ); } destx+=GetWidth(FontObjs[FontDefault], transletter); } return(0); } UINT32 mprintf_coded( INT32 x, INT32 y, UINT16 *pFontString, ...) { INT32 destx, desty; UINT16 *curletter, transletter; va_list argptr; wchar_t string[512]; UINT16 usOldForeColor; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; Assert(pFontString!=NULL); va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); curletter=string; destx=x; desty=y; usOldForeColor = FontForeground16; // Lock the dest buffer pDestBuf = LockVideoSurface( FontDestBuffer, &uiDestPitchBYTES ); while((*curletter)!=0) { if ( (*curletter) == 180 ) { curletter++; SetFontForeground( (UINT8)(*curletter) ); curletter++; } else if ( (*curletter) == 181 ) { FontForeground16 = usOldForeColor; curletter++; } transletter=GetIndex(*curletter++); if(FontDestWrap && BltIsClipped(FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion)) { destx=x; desty+=GetHeight(FontObjs[FontDefault], transletter); } // Blit directly if ( gbPixelDepth == 8 ) { Blt8BPPDataTo8BPPBufferMonoShadowClip(pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion, FontForeground8, FontBackground8); } else { Blt8BPPDataTo16BPPBufferMonoShadowClip((UINT16*)pDestBuf, uiDestPitchBYTES, FontObjs[FontDefault], destx, desty, transletter, &FontDestRegion, FontForeground16, FontBackground16, FontShadow16 ); } destx+=GetWidth(FontObjs[FontDefault], transletter); } // Unlock buffer UnLockVideoSurface( FontDestBuffer ); return(0); } //***************************************************************************** // InitializeFontManager // // Starts up the font manager system with the appropriate translation table. // //***************************************************************************** BOOLEAN InitializeFontManager(UINT16 usDefaultPixelDepth, FontTranslationTable *pTransTable) { FontTranslationTable *pTransTab; int count; UINT16 uiRight, uiBottom; UINT8 uiPixelDepth; FontDefault=(-1); FontDestBuffer=BACKBUFFER; FontDestPitch=0; // FontDestBPP=0; GetCurrentVideoSettings( &uiRight, &uiBottom, &uiPixelDepth ); FontDestRegion.iLeft = 0; FontDestRegion.iTop = 0; FontDestRegion.iRight=(INT32)uiRight; FontDestRegion.iBottom=(INT32)uiBottom; FontDestBPP=(UINT32)uiPixelDepth; FontDestWrap=FALSE; // register the appropriate debug topics if(pTransTable == NULL) { return FALSE; } RegisterDebugTopic(TOPIC_FONT_HANDLER, "Font Manager"); if ((pFManager = (FontManager *)MemAlloc(sizeof(FontManager)))==NULL) { return FALSE; } if((pTransTab = (FontTranslationTable *)MemAlloc(sizeof(FontTranslationTable)))==NULL) { return FALSE; } pFManager->pTranslationTable = pTransTab; pFManager->usDefaultPixelDepth = usDefaultPixelDepth; pTransTab->usNumberOfSymbols = pTransTable->usNumberOfSymbols; pTransTab->DynamicArrayOf16BitValues = pTransTable->DynamicArrayOf16BitValues; // Mark all font slots as empty for(count=0; count < MAX_FONTS; count++) FontObjs[count]=NULL; return TRUE; } //***************************************************************************** // ShutdownFontManager // // Shuts down, and deallocates all fonts. //***************************************************************************** void ShutdownFontManager(void) { INT32 count; UnRegisterDebugTopic(TOPIC_FONT_HANDLER, "Font Manager"); if(pFManager) MemFree(pFManager); for(count=0; count < MAX_FONTS; count++) { if(FontObjs[count]!=NULL) UnloadFont(count); } } //***************************************************************************** // DestroyEnglishTransTable // // Destroys the English text->font map table. //***************************************************************************** void DestroyEnglishTransTable( void ) { if(pFManager) { if (pFManager->pTranslationTable != NULL) { if (pFManager->pTranslationTable->DynamicArrayOf16BitValues != NULL) { MemFree( pFManager->pTranslationTable->DynamicArrayOf16BitValues ); } MemFree( pFManager->pTranslationTable ); pFManager->pTranslationTable = NULL; } } } //***************************************************************************** // CreateEnglishTransTable // // Creates the English text->font map table. //***************************************************************************** FontTranslationTable *CreateEnglishTransTable( ) { FontTranslationTable *pTable = NULL; UINT16 *temp; pTable = (FontTranslationTable *)MemAlloc(sizeof(FontTranslationTable)); #ifdef JA2 // ha ha, we have more than Wizardry now (again) pTable->usNumberOfSymbols = 172; #else pTable->usNumberOfSymbols = 155; #endif pTable->DynamicArrayOf16BitValues = (UINT16 *)MemAlloc(pTable->usNumberOfSymbols * 2); temp = pTable->DynamicArrayOf16BitValues; *temp = 'A'; temp++; *temp='B'; temp++; *temp ='C'; temp++; *temp ='D'; temp++; *temp = 'E'; temp++; *temp = 'F'; temp++; *temp='G'; temp++; *temp ='H'; temp++; *temp ='I'; temp++; *temp = 'J'; temp++; *temp = 'K'; temp++; *temp='L'; temp++; *temp ='M'; temp++; *temp ='N'; temp++; *temp = 'O'; temp++; *temp = 'P'; temp++; *temp='Q'; temp++; *temp ='R'; temp++; *temp ='S'; temp++; *temp = 'T'; temp++; *temp ='U'; temp++; *temp ='V'; temp++; *temp = 'W'; temp++; *temp = 'X'; temp++; *temp='Y'; temp++; *temp ='Z'; temp++; *temp ='a'; temp++; *temp = 'b'; temp++; *temp ='c'; temp++; *temp = 'd'; temp++; *temp ='e'; temp++; *temp = 'f'; temp++; *temp ='g'; temp++; *temp = 'h'; temp++; *temp ='i'; temp++; *temp = 'j'; temp++; *temp ='k'; temp++; *temp = 'l'; temp++; *temp ='m'; temp++; *temp = 'n'; temp++; *temp ='o'; temp++; *temp = 'p'; temp++; *temp ='q'; temp++; *temp = 'r'; temp++; *temp ='s'; temp++; *temp = 't'; temp++; *temp ='u'; temp++; *temp = 'v'; temp++; *temp ='w'; temp++; *temp = 'x'; temp++; *temp ='y'; temp++; *temp = 'z'; temp++; *temp ='0'; temp++; *temp = '1'; temp++; *temp ='2'; temp++; *temp = '3'; temp++; *temp ='4'; temp++; *temp = '5'; temp++; *temp ='6'; temp++; *temp = '7'; temp++; *temp ='8'; temp++; *temp = '9'; temp++; *temp ='!'; temp++; *temp = '@'; temp++; *temp ='#'; temp++; *temp = '$'; temp++; *temp ='%'; temp++; *temp = '^'; temp++; *temp ='&'; temp++; *temp = '*'; temp++; *temp ='('; temp++; *temp = ')'; temp++; *temp ='-'; temp++; *temp = '_'; temp++; *temp ='+'; temp++; *temp = '='; temp++; *temp ='|'; temp++; *temp = '\\'; temp++; *temp ='{'; temp++; *temp = '}';// 80 temp++; *temp = '['; temp++; *temp =']'; temp++; *temp = ':'; temp++; *temp =';'; temp++; *temp = '"'; temp++; *temp ='\''; temp++; *temp = '<'; temp++; *temp = '>'; temp++; *temp =','; temp++; *temp = '.'; temp++; *temp ='?'; temp++; *temp = '/'; temp++; *temp = ' '; //93 temp++; #ifdef JA2 *temp = 196; // "A" umlaut temp++; *temp = 214; // "O" umlaut temp++; *temp = 220; // "U" umlaut temp++; *temp = 228; // "a" umlaut temp++; *temp = 246; // "o" umlaut temp++; *temp = 252; // "u" umlaut temp++; *temp = 223; // double-s that looks like a beta/B // 100 temp++; // START OF FUNKY RUSSIAN STUFF *temp = 1101; temp++; *temp = 1102; temp++; *temp = 1103; temp++; *temp = 1104; temp++; *temp = 1105; temp++; *temp = 1106; temp++; *temp = 1107; temp++; *temp = 1108; temp++; *temp = 1109; temp++; *temp = 1110; temp++; *temp = 1111; temp++; *temp = 1112; temp++; *temp = 1113; temp++; *temp = 1114; temp++; *temp = 1115; temp++; *temp = 1116; temp++; *temp = 1117; temp++; *temp = 1118; temp++; *temp = 1119; temp++; *temp = 1120; temp++; *temp = 1121; temp++; *temp = 1122; temp++; *temp = 1123; temp++; *temp = 1124; temp++; *temp = 1125; temp++; *temp = 1126; temp++; *temp = 1127; temp++; *temp = 1128; temp++; *temp = 1129; temp++; *temp = 1130; // 130 temp++; *temp = 1131; temp++; *temp = 1132; temp++; // END OF FUNKY RUSSIAN STUFF *temp = 196; // Ä temp++; *temp = 192; // À temp++; *temp = 193; // Á temp++; *temp = 194; // Â temp++; *temp = 199; // Ç temp++; *temp = 203; // Ë temp++; *temp = 200; // È temp++; *temp = 201; // É 140 temp++; *temp = 202; // Ê temp++; *temp = 207; // Ï temp++; *temp = 214; // Ö temp++; *temp = 210; // Ò temp++; *temp = 211; // Ó temp++; *temp = 212; // Ô temp++; *temp = 220; // Ü temp++; *temp = 217; // Ù temp++; *temp = 218; // Ú temp++; *temp = 219; // Û 150 temp++; *temp = 228; // ä temp++; *temp = 224; // à temp++; *temp = 225; // á temp++; *temp = 226; // â temp++; *temp = 231; // ç temp++; *temp = 235; // ë temp++; *temp = 232; // è temp++; *temp = 233; // é temp++; *temp = 234; // ê temp++; *temp = 239; // ï 160 temp++; *temp = 246; // ö temp++; *temp = 242; // ò temp++; *temp = 243; // ó temp++; *temp = 244; // ô temp++; *temp = 252; // ü temp++; *temp = 249; // ù temp++; *temp = 250; // ú temp++; *temp = 251; // û temp++; *temp = 204; // Ì temp++; *temp = 206; // Î 170 temp++; *temp = 236; // ì temp++; *temp = 238; // î temp++; #else // Windows Code Page 1252 Western Standard Character Set *temp = 193; // "A" acute temp++; *temp = 192; // "A" grave temp++; *temp = 193; // "A" circumflex temp++; *temp = 196; // "A" umlaut temp++; *temp = 195; // "A" tilde temp++; *temp = 197; // "A" ring temp++; *temp = 199; // "C" cedile temp++; *temp = 201; // "E" acute temp++; *temp = 200; // "E" grave temp++; *temp = 202; // "E" circumflex temp++; *temp = 203; // "E" umlaut temp++; *temp = 205; // "I" acute temp++; *temp = 204; // "I" grave temp++; *temp = 206; // "I" circumflex temp++; *temp = 207; // "I" umlaut temp++; *temp = 209; // "N" tilde temp++; *temp = 211; // "O" acute temp++; *temp = 210; // "O" grave temp++; *temp = 212; // "O" circumflex temp++; *temp = 214; // "O" umlaut temp++; *temp = 213; // "O" tilde temp++; *temp = 216; // "0" O strike-through temp++; *temp = 218; // "U" acute temp++; *temp = 217; // "U" grave temp++; *temp = 219; // "U" circumflex temp++; *temp = 220; // "U" umlaut temp++; *temp = 221; // "Y" acute temp++; *temp = 225; // "a" acute temp++; *temp = 224; // "a" grave temp++; *temp = 226; // "a" circumflex temp++; *temp = 228; // "a" umlaut temp++; *temp = 227; // "a" tilde temp++; *temp = 229; // "a" ring temp++; *temp = 231; // "c" cedile temp++; *temp = 233; // "e" acute temp++; *temp = 232; // "e" grave temp++; *temp = 234; // "e" circumflex temp++; *temp = 235; // "e" umlaut temp++; *temp = 237; // "i" acute temp++; *temp = 236; // "i" grave temp++; *temp = 238; // "i" circumflex temp++; *temp = 239; // "i" umlaut temp++; *temp = 241; // "n" tilde temp++; *temp = 243; // "o" acute temp++; *temp = 242; // "o" grave temp++; *temp = 244; // "o" circumflex temp++; *temp = 246; // "o" umlaut temp++; *temp = 245; // "o" tilde temp++; *temp = 248; // "o" strike-through temp++; *temp = 250; // "u" acute temp++; *temp = 249; // "u" grave temp++; *temp = 251; // "u" circumflex temp++; *temp = 252; // "u" umlaut temp++; *temp = 254; // "y" acute temp++; *temp = 255; // "y" umlaut temp++; *temp = 223; // beta // Font glyphs for spell targeting icons //ATE: IMPORTANT! INcreate the array above if you add any new items here... temp++; *temp = FONT_GLYPH_TARGET_POINT; temp++; *temp = FONT_GLYPH_TARGET_CONE; temp++; *temp = FONT_GLYPH_TARGET_SINGLE; temp++; *temp = FONT_GLYPH_TARGET_GROUP; temp++; *temp = FONT_GLYPH_TARGET_NONE; // 154 #endif return pTable; } //***************************************************************************** // // LoadFontFile // // Parameter List : filename - File created by the utility tool to open // // Return Value pointer to the base structure // // Modification History : // Dec 15th 1996 -> modified for use by Wizardry // //***************************************************************************** /*FontBase *LoadFontFile(UINT8 *pFilename) { HWFILE hFileHandle; UINT32 uiFileSize; UINT32 uiHeightEach; UINT32 uiTotalSymbol; UINT32 uiNewoffst, uiOldoffst; FontBase *pFontBase; SGPPaletteEntry *pNewPalette; UINT8 *pPalette; if (pFManager == NULL) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Did not Initialize Font Manager"); return NULL; } // Open and read in the file if ((hFileHandle = FileOpen(pFilename, FILE_ACCESS_READ, FALSE)) == 0) { // damn we failed to open the file DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Cannot open font file"); return NULL; } uiFileSize = FileGetSize(hFileHandle); if (uiFileSize == 0) { // we failed to size up the file DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Font file is empty"); FileClose(hFileHandle); return NULL; } // Allocate memory for the font header file if ((pFontBase = (FontBase *)MemAlloc(sizeof(FontBase))) == NULL) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not malloc memory"); FileClose(hFileHandle); } // read in these values from the file if (FileRead(hFileHandle, &uiHeightEach, sizeof(UINT32), NULL) == FALSE) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not read Height from File"); FileClose(hFileHandle); return NULL; } if (FileRead(hFileHandle, &uiTotalSymbol, sizeof(UINT32), NULL) == FALSE) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not read Total Symbol from File"); FileClose(hFileHandle); return NULL; } // Assign the proper values to the Base structure pFontBase->uiHeightEach = uiHeightEach; pFontBase->uiTotalElements = uiTotalSymbol; pFontBase->pFontObject = (FontObject *)MemAlloc(uiTotalSymbol * sizeof(FontHeader)); pPalette = (UINT8 *)MemAlloc(PALETTE_SIZE); uiOldoffst = (sizeof(FontHeader) + sizeof(FontObject)*pFontBase->uiTotalElements); uiNewoffst = uiFileSize - uiOldoffst; pFontBase->pPixData8 = (UINT8 *)MemAlloc(uiNewoffst); //seek past the FontHeader if (FileSeek(hFileHandle, sizeof(FontHeader), FILE_SEEK_FROM_START) == FALSE) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not seek FileHeader"); FileClose(hFileHandle); return NULL; } //read in the FontObject if (FileRead(hFileHandle, pFontBase->pFontObject, (uiTotalSymbol)*sizeof(FontHeader), NULL) == FALSE) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not seek Font Objects"); FileClose(hFileHandle); return NULL; } if (FileSeek(hFileHandle, uiOldoffst, FILE_SEEK_FROM_START) == FALSE) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not seek Old offset"); FileClose(hFileHandle); return NULL; } // read in the Pixel data if (FileRead(hFileHandle, pFontBase->pPixData8, uiNewoffst, NULL) == FALSE) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not seek Pixel data"); FileClose(hFileHandle); return NULL; } // seek proper position to read in Palette if (FileSeek(hFileHandle, sizeof(UINT32)*3, FILE_SEEK_FROM_START) == FALSE) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not seek Palette Start"); FileClose(hFileHandle); return NULL; } // read in Palette if (FileRead(hFileHandle, pPalette, PALETTE_SIZE, NULL) == FALSE) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not read Palette"); FileClose(hFileHandle); return NULL; } // set the default pixel depth pFontBase->siPixelDepth = pFManager->usDefaultPixelDepth; FileClose(hFileHandle); // convert from RGB to SGPPaletteEntry pNewPalette = ConvertToPaletteEntry(0, 255, pPalette); pFontBase->pPalette = pNewPalette; // create the 16BPer Pixel palette if ((pFontBase->pPalet16 = Create16BPPPalette(pNewPalette)) == NULL) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Could not create 16 bit palette"); return NULL; } // return the FontBase structure return pFontBase; } */ /*void UnloadFont(FontBase *pFontBase) { // free allocated memory in FontBase if(pFontBase!=NULL) { if(pFontBase->pPalette!=NULL) MemFree(pFontBase->pPalette); if(pFontBase->pPalet16!=NULL) MemFree(pFontBase->pPalet16); if(pFontBase->pFontObject!=NULL) MemFree(pFontBase->pFontObject); if(pFontBase->pPixData8!=NULL) MemFree(pFontBase->pPixData8); if(pFontBase->pPixData16!=NULL) MemFree(pFontBase->pPixData16); MemFree(pFontBase); } } */ //***************************************************************************** // // GetMaxFontWidth - Gets the maximum font width // // Parameter List : pointer to the base structure // // Return Value Maximum font width // // Modification History : // Dec 15th 1996 -> modified for use by Wizardry // //***************************************************************************** /*UINT16 GetMaxFontWidth(FontBase *pFontBase) { FontObject *pWidth; UINT32 siBiggest = 0; UINT16 siCount; Assert(pFontBase != NULL); pWidth = pFontBase->pFontObject; // traverse the FontObject structure to find the biggest width for(siCount = 0; siCount < pFontBase->uiTotalElements; siCount++) { if( pWidth->uiFontWidth > siBiggest) { siBiggest = pWidth->uiFontWidth; } pWidth++; } // return the max width return (UINT16)siBiggest; } */ //***************************************************************************** // // ConvertToPaletteEntry // // Parameter List : Converts from RGB to SGPPaletteEntry // // Return Value pointer to the SGPPaletteEntry // // Modification History : // Dec 15th 1996 -> modified for use by Wizardry // //***************************************************************************** /* SGPPaletteEntry *ConvertToPaletteEntry(UINT8 sbStart, UINT8 sbEnd, UINT8 *pOldPalette) { UINT16 Index; SGPPaletteEntry *pPalEntry; SGPPaletteEntry *pInitEntry; pPalEntry = (SGPPaletteEntry *)MemAlloc(sizeof(SGPPaletteEntry) * 256); pInitEntry = pPalEntry; DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Converting RGB palette to SGPPaletteEntry"); for(Index=0; Index <= (sbEnd-sbStart);Index++) { pPalEntry->peRed = *(pOldPalette + (Index*3)); pPalEntry->peGreen = *(pOldPalette + (Index*3) + 1); pPalEntry->peBlue = *(pOldPalette + (Index*3) + 2); pPalEntry->peFlags = 0; pPalEntry++; } return pInitEntry; } */ //***************************************************************************** // // SetFontPalette - Sets the Palette // // Parameter List : pointer to the base structure // new pixel depth // new Palette size // pointer to palette data // // Return Value BOOLEAN // // Modification History : // Dec 15th 1996 -> modified for use by Wizardry // //***************************************************************************** /*BOOLEAN SetFontPalette(FontBase *pFontBase, UINT16 siPixelDepth, SGPPaletteEntry *pPalData) { Assert(pFontBase != NULL); Assert(pPalData != NULL); MemFree(pFontBase->pPalette); // assign the new palette to the Base structure pFontBase->pPalette = pPalData; pFontBase->siPixelDepth = siPixelDepth; return TRUE; } */ //***************************************************************************** // // SetFont16BitData - Sets the font structure to hold 16 bit data // // Parameter List : pointer to the base structure // pointer to new 16 bit data // // Return Value BOOLEAN // // Modification History : // Dec 15th 1996 -> modified for use by Wizardry // //***************************************************************************** /*BOOLEAN SetFont16BitData(FontBase *pFontBase, UINT16 *pData16) { Assert(pFontBase != NULL); Assert(pData16 != NULL); MemFree(pFontBase->pPixData16); pFontBase->pPixData16 = pData16; return TRUE; } */ //***************************************************************************** // // Blt8Imageto16Dest // // Parameter List : Start offset // End Offset // Dest x, y // Font Width // Pointer to Base structure // Pointer to destination buffer // Destination Pitch // Height of Each element // // Return Value : BOOLEAN // // Modification History : // Nov 26th 1996 -> modified for use by Wizardry // //***************************************************************************** /*BOOLEAN Blt8Imageto16Dest(UINT32 uiOffStart, UINT32 uiOffEnd, UINT16 siX, UINT16 siY, UINT32 uiWidth, FontBase *pFontBase, UINT8 *pFrameBuffer, UINT16 siDestPitch, UINT16 siHeightEach) { UINT8 *pTrav; UINT16 *pFrameTrav; UINT16 *p16BPPPalette; UINT16 usEffectiveWidth; UINT32 uiFrameCount; UINT8 amount; UINT32 row, count; UINT16 modamount, divamount; UINT32 trace,modtrace; UINT8 sub=0; pTrav = pFontBase->pPixData8; pFrameTrav = (UINT16 *)pFrameBuffer; p16BPPPalette = pFontBase->pPalet16; trace = 0; modtrace = 0; // effective width is pitch/2 as 16 bits per pixel usEffectiveWidth = (UINT16)(siDestPitch / 2); uiFrameCount = siY*usEffectiveWidth + siX; trace += uiFrameCount; modtrace = trace % 640; pFrameTrav += uiFrameCount; pTrav += uiOffStart; count = 0; row = 0; amount = 0; while (count < (uiOffEnd-uiOffStart)) { amount = 0; if (*pTrav == ID_BLACK) { pTrav++; count++; amount = *pTrav; modamount = (UINT8)(amount) % (UINT8) uiWidth; divamount = (UINT8)(amount) / (UINT8) uiWidth; if ((divamount == 0) && ((row+amount) < (UINT16)uiWidth)) { pFrameTrav += amount; trace += amount; modtrace = trace % 640; row += amount; row++; } else { if (((row+amount) >= (UINT16)uiWidth) && (divamount ==0)) { pFrameTrav -= row; trace -= row; modtrace = trace % 640; row = amount-((UINT16)uiWidth-row); pFrameTrav += usEffectiveWidth+row; trace += usEffectiveWidth+row; modtrace = trace % 640; row++; } else { pFrameTrav += (divamount*usEffectiveWidth); trace += (divamount*usEffectiveWidth); modtrace = trace % 640; if(row+modamount > uiWidth) { sub = (UINT8)((row+modamount) % uiWidth); pFrameTrav -= row; trace -= row; modtrace = trace % 640; pFrameTrav += usEffectiveWidth+sub; trace += usEffectiveWidth + sub; modtrace = trace % 640; row = sub; row++; }else { pFrameTrav += modamount; trace += modamount; modtrace = trace % 640; row = modamount; row++; } } } } else { if(row >= uiWidth) { pFrameTrav += (usEffectiveWidth-uiWidth); trace += (usEffectiveWidth-uiWidth); modtrace = trace % 640; *pFrameTrav = p16BPPPalette[*pTrav]; row = 1; } else { *pFrameTrav = p16BPPPalette[*pTrav]; row++; } } pFrameTrav++; trace++; modtrace = trace % 640; pTrav++; count++; } return TRUE; } */ //***************************************************************************** // // Blt8Imageto8Dest // // Parameter List : Start offset // End Offset // Dest x, y // Font Width // Pointer to Base structure // Pointer to destination buffer // Destination Pitch // Height of Each element // // Return Value : BOOLEAN // // Modification History : // Nov 26th 1996 -> modified for use by Wizardry // //***************************************************************************** /*BOOLEAN Blt8Imageto8Dest(UINT32 uiOffStart, UINT32 uiOffEnd, UINT16 siX, UINT16 siY, UINT32 uiWidth, FontBase *pFontBase, UINT8 *pFrameBuffer, UINT16 siDestPitch, UINT16 siHeightEach) { UINT8 *pTrav; UINT32 uiFrameCount; UINT8 *pFrameTrav; UINT8 amount; UINT32 row,count; UINT16 modamount,divamount; DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Blitting 8 to 8"); Assert(pFontBase != NULL); Assert(pFrameBuffer != NULL); // get the pointers pTrav = pFontBase->pPixData8; pFrameTrav = (UINT8 *)pFrameBuffer; uiFrameCount = siY*siDestPitch + siX; pFrameTrav +=uiFrameCount; pTrav += uiOffStart; // perform blitting count=0; row = 0; amount = 0; while (count < (uiOffEnd-uiOffStart)) { amount = 0; if (*pTrav == ID_BLACK) { pTrav++; count++; amount = *pTrav; modamount = amount % (UINT8) uiWidth; divamount = amount / (UINT8) uiWidth; if ((divamount == 0) && ((row+amount) < (UINT16)uiWidth)) { pFrameTrav += amount; row += amount; row++; } else { if (((row+amount) >= (UINT16)uiWidth) && (divamount ==0)) { pFrameTrav -= row; row = amount-((UINT16)uiWidth-row); pFrameTrav += siDestPitch+row; row++; } else { pFrameTrav += (divamount*siDestPitch)+modamount; row = modamount; row++; } } } else { if (row >= uiWidth) { pFrameTrav += (siDestPitch-uiWidth); *pFrameTrav = *pTrav; row = 1; } else { *pFrameTrav = *pTrav; row++; } } pFrameTrav++; pTrav++; count++; } return TRUE; } */ //***************************************************************************** // // Blt16Imageto16Dest // // Parameter List : Start offset // End Offset // Dest x, y // Font Width // Pointer to Base structure // Pointer to destination buffer // Destination Pitch // Height of Each element // // Return Value : BOOLEAN // // Modification History : // Nov 26th 1996 -> modified for use by Wizardry // //***************************************************************************** /*BOOLEAN Blt16Imageto16Dest(UINT32 uiOffStart, UINT32 uiOffEnd, UINT16 siX, UINT16 siY, UINT32 uiWidth, FontBase *pFontBase, UINT8 *pFrameBuffer, UINT16 siDestPitch, UINT16 siHeightEach) { UINT16 *pTrav; UINT32 uiFrameCount; UINT16 *pFrameTrav; UINT16 amount; UINT32 row,count; UINT16 modamount,divamount; UINT16 usEffectiveWidth; DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Blitting 16 to 16"); Assert(pFontBase != NULL); Assert(pFrameBuffer != NULL); //get the pointers pTrav = pFontBase->pPixData16; pFrameTrav = (UINT16 *)pFrameBuffer; // effective width is pitch/2 as 16 bits per pixel usEffectiveWidth = (UINT16)(siDestPitch / 2); uiFrameCount = siY*usEffectiveWidth + siX; pFrameTrav +=uiFrameCount; pTrav += uiOffStart; count=0; row = 0; amount = 0; while (count < (uiOffEnd-uiOffStart)) { amount = 0; if (*pTrav == ID_BLACK) { pTrav++; count++; amount = *pTrav; modamount = amount % (UINT8) uiWidth; divamount = amount / (UINT8) uiWidth; if ((divamount == 0) && ((row+amount) < (UINT16)uiWidth)) { pFrameTrav += amount; row += amount; row++; } else { if (((row+amount) >= (UINT16)uiWidth) && (divamount ==0)) { pFrameTrav -= row; row = amount-((UINT16)uiWidth-row); pFrameTrav += usEffectiveWidth+row; row++; } else { pFrameTrav += (divamount*usEffectiveWidth)+modamount; row = modamount; row++; } } } else { if(row >= uiWidth) { pFrameTrav += (usEffectiveWidth-uiWidth); *pFrameTrav = *pTrav; row = 1; } else { *pFrameTrav = *pTrav; row++; } } pFrameTrav++; pTrav++; count++; } return TRUE; } */ //***************************************************************************** // // GetOffset // // Parameter List : Given the index, gets the corresponding offset // // Return Value : offset // // Modification History : // Nov 26th 1996 -> modified for use by Wizardry // //***************************************************************************** /*UINT32 GetOffset(FontBase *pFontBase, INT16 ssIndex) { FontObject *pTrav; UINT16 siCount=0; Assert(pFontBase != NULL); // gets the offset based on the index if (((UINT32)ssIndex > pFontBase->uiTotalElements) || (ssIndex < 0)) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Incorrect index value passed"); return 0; } pTrav = pFontBase->pFontObject; while (siCount != ssIndex) { siCount++; pTrav++; } return pTrav->uiFontOffset; } */ //***************************************************************************** // // GetOffLen // // Parameter List : Given the index, gets the corresponding offset // length which is the number of compressed pixels // // Return Value : offset // // Modification History : // Nov 26th 1996 -> modified for use by Wizardry // //***************************************************************************** /*UINT32 GetOffLen(FontBase *pFontBase, INT16 ssIndex) { FontObject *pTrav; UINT16 siCount=0; Assert(pFontBase != NULL); // gets the offset based on the index if (((UINT32)ssIndex > pFontBase->uiTotalElements) || (ssIndex < 0)) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Incorrect index value passed"); return 0; } pTrav = pFontBase->pFontObject; while(siCount != ssIndex) { siCount++; pTrav++; } return pTrav->uiOffLen; } */ //***************************************************************************** // // PrintFontString // // Parameter List : pointer to \0 (NULL) terminated font string // x,y,TotalWidth, TotalHeight is the bounding rectangle where // the font is to be printed // Multiline if true will print on multiple lines otherwise on 1 line // Pointer to base structure // // Return Value : BOOLEAN // // Modification History : // Nov 26th 1996 -> modified for use by Wizardry // //***************************************************************************** /*BOOLEAN PrintFontString(UINT16 *pFontString, UINT8 *pDestBuffer, UINT16 siDestWidth, UINT16 siDestPixelDepth, UINT16 siDestPitch, UINT16 siDestHeight, UINT16 siX, UINT16 siY, UINT16 siTotalWidth, UINT16 siTotalHeight, BOOLEAN fMultiLine, FontBase *pFontBase) { UINT16 siScreenHt; UINT16 siScreenWt; UINT16 siChar, siHeightEach; INT16 ssIndex; UINT32 uiWidth, uiOffsetSt, uiOffsetEnd, uiOldoffst; UINT16 *pTempFStr; UINT16 siNewX, siNewY; UINT16 siInitX, siInitY; UINT32 uiLen; // check for NULL pointers passed in Assert(pFontBase != NULL); Assert(pFontString != NULL); Assert(pDestBuffer != NULL); siScreenWt = siDestWidth; siScreenHt = siDestHeight; // check for invalid coordinates if((siX<0) || (siX>siScreenWt) || (siY<0) || (siY>siScreenHt) || (siTotalWidth<0) || (siTotalWidth>siScreenWt) || (siTotalHeight<0) || (siTotalHeight>siScreenHt)) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Invalid coordinates passed in"); return FALSE; } pTempFStr = pFontString; siNewX = siX; siNewY = siY; siInitX = siX; siInitY = siY; // Get the height of each font and the offset siHeightEach = GetFontHeight(pFontBase); uiOldoffst = (sizeof(FontHeader) + sizeof(FontObject)*pFontBase->uiTotalElements); // calls the blt routine until the string != to \0 while(*pTempFStr != STRING_DELIMITER) { siChar = *pTempFStr; // get the index value for the font if((ssIndex = GetIndex(siChar)) == -1) { return FALSE; } // get the width of the font uiWidth = GetWidth(pFontBase, ssIndex); // get the font offset uiOffsetSt = GetOffset(pFontBase, ssIndex); uiLen = GetOffLen(pFontBase,ssIndex); // uiOffsetSt -= uiOldoffst; uiOffsetEnd = uiOffsetSt + uiLen; // if Multiline = FALSE and reached the end of line - cannot continue if ((((siNewX+uiWidth) > siScreenWt) || ((siNewX+uiWidth) >= siTotalWidth)) && (fMultiLine == FALSE)) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Cannot continue writing"); return FALSE; } // check if boundary is reached if ((((siNewX+uiWidth) >= siScreenWt) || ((siNewX+uiWidth) >= siTotalWidth)) && (fMultiLine == TRUE)) { if (((siInitY+siHeightEach) > siScreenHt) || ((siInitY+siHeightEach) >= siTotalHeight)) { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Cannot continue writing"); return FALSE; } //call the appropriate blit routines siNewX = siInitX; siNewY += siHeightEach; siInitY = siNewY; if ((siDestPixelDepth == 16) && (pFontBase->siPixelDepth == 16)) { Blt16Imageto16Dest(uiOffsetSt, uiOffsetEnd, siNewX, siNewY, uiWidth, pFontBase, pDestBuffer, siDestPitch, siHeightEach); } else { if ((siDestPixelDepth == 16) && (pFontBase->siPixelDepth == 8)) { Blt8Imageto16Dest(uiOffsetSt, uiOffsetEnd, siNewX, siNewY, uiWidth, pFontBase, pDestBuffer, siDestPitch, siHeightEach); } else { if ((siDestPixelDepth == 8) && (pFontBase->siPixelDepth == 8)) { // if(SetPalette(pFontBase->pPalette) == FALSE) // return FALSE; Blt8Imageto8Dest(uiOffsetSt, uiOffsetEnd, siNewX, siNewY, uiWidth, pFontBase, pDestBuffer, siDestPitch, siHeightEach); } else { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Invalid pixel depth / destination surface depth"); return FALSE; } } siNewX += (UINT16)uiWidth; } } else { // if it isnt end of boundary copy at current location if((siDestPixelDepth == 16) && (pFontBase->siPixelDepth == 16)) { Blt16Imageto16Dest(uiOffsetSt, uiOffsetEnd, siNewX, siNewY, uiWidth, pFontBase, pDestBuffer, siDestPitch, siHeightEach); } else { if((siDestPixelDepth == 16) && (pFontBase->siPixelDepth == 8)) { Blt8Imageto16Dest(uiOffsetSt, uiOffsetEnd, siNewX, siNewY, uiWidth, pFontBase, pDestBuffer, siDestPitch, siHeightEach); } else { if ((siDestPixelDepth == 8) && (pFontBase->siPixelDepth == 8)) { Blt8Imageto8Dest(uiOffsetSt, uiOffsetEnd, siNewX, siNewY, uiWidth, pFontBase, pDestBuffer, siDestPitch, siHeightEach); } else { DbgMessage(TOPIC_FONT_HANDLER, DBG_LEVEL_0, "Invalid pixel depth / destination surface depth"); return FALSE; } } siNewX += (UINT16)uiWidth; } } // increment string pointer pTempFStr++; } return TRUE; } */ /*BOOLEAN InitializeFontManager(UINT16 usDefaultPixelDepth, FontTranslationTable *pTransTable) { FontTranslationTable *pTransTab; // register the appropriate debug topics if(pTransTable == NULL) { return FALSE; } RegisterDebugTopic(TOPIC_FONT_HANDLER, "Font Manager"); if ((pFManager = (FontManager *)MemAlloc(sizeof(FontManager)))==NULL) { return FALSE; } if((pTransTab = (FontTranslationTable *)MemAlloc(sizeof(FontTranslationTable)))==NULL) { return FALSE; } pFManager->pTranslationTable = pTransTab; pFManager->usDefaultPixelDepth = usDefaultPixelDepth; pTransTab->usNumberOfSymbols = pTransTable->usNumberOfSymbols; pTransTab->DynamicArrayOf16BitValues = pTransTable->DynamicArrayOf16BitValues; return TRUE; } */ /*void ShutdownFontManager(void) { UnRegisterDebugTopic(TOPIC_FONT_HANDLER, "Font Manager"); MemFree(pFManager); } */