Browse Source

added bdf font support

Wei Mingzhi 7 years ago
parent
commit
db959a75bb
8 changed files with 212 additions and 77 deletions
  1. 2 1
      common.h
  2. 170 70
      font.c
  3. 7 2
      font.h
  4. 1 0
      global.c
  5. 15 3
      main.c
  6. 14 0
      palcfg.c
  7. 2 0
      palcfg.h
  8. 1 1
      unix/Makefile

+ 2 - 1
common.h

@@ -401,7 +401,8 @@ typedef enum tagCODEPAGE {
 	CP_MIN = 0,
 	CP_BIG5 = 0,
 	CP_GBK = 1,
-	//CP_SHIFTJIS = 2,
+	CP_SHIFTJIS = 2,
+	CP_JISX0208 = 3,
 	CP_MAX = CP_GBK + 1,
 	CP_UTF_8 = CP_MAX + 1
 } CODEPAGE;

+ 170 - 70
font.c

@@ -33,8 +33,8 @@
 static int _font_height = 16;
 
 INT
-PAL_InitFont(
-   BOOL      fUseEmbeddedFonts
+PAL_InitEmbeddedFont(
+   VOID
 )
 /*++
   Purpose:
@@ -51,90 +51,190 @@ PAL_InitFont(
 
 --*/
 {
-	if (fUseEmbeddedFonts)
-	{
-		FILE *fp;
-		char *char_buf;
-		wchar_t *wchar_buf;
-		int nBytes, nChars, i;
-
-		//
-		// Load the wor16.asc file.
-		//
-		if (NULL == (fp = UTIL_OpenFile("wor16.asc")))
-		{
-			return 0;
-		}
+	FILE *fp;
+	char *char_buf;
+	wchar_t *wchar_buf;
+	int nBytes, nChars, i;
 
-		//
-		// Get the size of wor16.asc file.
-		//
-		fseek(fp, 0, SEEK_END);
-		nBytes = ftell(fp);
+	//
+	// Load the wor16.asc file.
+	//
+	if (NULL == (fp = UTIL_OpenFile("wor16.asc")))
+	{
+		return 0;
+	}
 
-		//
-		// Allocate buffer & read all the character codes.
-		//
-		if (NULL == (char_buf = (char *)malloc(nBytes)))
-		{
-			fclose(fp);
-			return 0;
-		}
-		fseek(fp, 0, SEEK_SET);
-		fread(char_buf, 1, nBytes, fp);
+	//
+	// Get the size of wor16.asc file.
+	//
+	fseek(fp, 0, SEEK_END);
+	nBytes = ftell(fp);
 
-		//
-		// Close wor16.asc file.
-		//
+	//
+	// Allocate buffer & read all the character codes.
+	//
+	if (NULL == (char_buf = (char *)malloc(nBytes)))
+	{
 		fclose(fp);
+		return 0;
+	}
+	fseek(fp, 0, SEEK_SET);
+	fread(char_buf, 1, nBytes, fp);
 
-		//
-		// Convert characters into unicode
-		//
-		nChars = PAL_MultiByteToWideChar(char_buf, nBytes, NULL, 0);
-		if (NULL == (wchar_buf = (wchar_t *)malloc(nChars * sizeof(wchar_t))))
-		{
-			free(char_buf);
-			return 0;
-		}
-		PAL_MultiByteToWideChar(char_buf, nBytes, wchar_buf, nChars);
+	//
+	// Close wor16.asc file.
+	//
+	fclose(fp);
+
+	//
+	// Convert characters into unicode
+	//
+	nChars = PAL_MultiByteToWideChar(char_buf, nBytes, NULL, 0);
+	if (NULL == (wchar_buf = (wchar_t *)malloc(nChars * sizeof(wchar_t))))
+	{
 		free(char_buf);
+		return 0;
+	}
+	PAL_MultiByteToWideChar(char_buf, nBytes, wchar_buf, nChars);
+	free(char_buf);
 
-		//
-		// Read bitmaps from wor16.fon file.
-		//
-		fp = UTIL_OpenFile("wor16.fon");
+	//
+	// Read bitmaps from wor16.fon file.
+	//
+	fp = UTIL_OpenFile("wor16.fon");
 
-		//
-		// The font glyph data begins at offset 0x682 in wor16.fon.
-		//
-		fseek(fp, 0x682, SEEK_SET);
+	//
+	// The font glyph data begins at offset 0x682 in wor16.fon.
+	//
+	fseek(fp, 0x682, SEEK_SET);
 
-		//
-		// Replace the original fonts
-		//
-		for (i = 0; i < nChars; i++)
-		{
-			wchar_t w = (wchar_buf[i] >= unicode_upper_base) ? (wchar_buf[i] - unicode_upper_base + 0xd800) : wchar_buf[i];
-			fread(unicode_font[w], 30, 1, fp);
-			unicode_font[w][30] = 0;
-			unicode_font[w][31] = 0;
-		}
-		free(wchar_buf);
+	//
+	// Replace the original fonts
+	//
+	for (i = 0; i < nChars; i++)
+	{
+		wchar_t w = (wchar_buf[i] >= unicode_upper_base) ? (wchar_buf[i] - unicode_upper_base + 0xd800) : wchar_buf[i];
+		fread(unicode_font[w], 30, 1, fp);
+		unicode_font[w][30] = 0;
+		unicode_font[w][31] = 0;
+	}
+	free(wchar_buf);
 
-		fclose(fp);
+	fclose(fp);
 
-		for (i = 0; i < 0x80; i++)
-		{
-			memcpy(unicode_font[i], &iso_font[i * 15], 15);
-			unicode_font[i][15] = 0;
-		}
-		_font_height = 15;
+	for (i = 0; i < 0x80; i++)
+	{
+		memcpy(unicode_font[i], &iso_font[i * 15], 15);
+		unicode_font[i][15] = 0;
 	}
+	_font_height = 15;
 
 	return 0;
 }
 
+INT
+PAL_LoadBdfFont(
+   LPCSTR      pszBdfFileName
+)
+/*++
+  Purpose:
+
+    Loads a BDF bitmap font file.
+
+  Parameters:
+
+    [IN]  pszBdfFileName - Name of BDF bitmap font file..
+
+  Return value:
+
+    0 = success, -1 = failure.
+
+--*/
+{
+   char buf[4096];
+   int state = 0;
+   int codepage = -1;
+
+   DWORD dwEncoding = 0;
+   BYTE bFontGlyph[32] = {0};
+   int iCurHeight = 0;
+
+   FILE *fp = UTIL_OpenFileForMode(pszBdfFileName, "r");
+
+   if (fp == NULL)
+   {
+      return -1;
+   }
+
+   while (fgets(buf, 4096, fp) != NULL)
+   {
+      if (state == 0)
+      {
+         if (strncmp(buf, "CHARSET_REGISTRY", 16) == 0)
+         {
+            if (strstr(buf, "Big5") != NULL)
+            {
+               codepage = CP_BIG5;
+            }
+            else if (strstr(buf, "BIG5") != NULL)
+            {
+               codepage = CP_BIG5;
+            }
+            //else if (strstr(buf, "JISX0208") != NULL)
+            //
+            //  codepage = CP_JISX0208;
+            //}
+         }
+         else if (strncmp(buf, "ENCODING", 8) == 0)
+         {
+            dwEncoding = atoi(buf + 8);
+         }
+         else if (strncmp(buf, "BITMAP", 6) == 0)
+         {
+            state = 1;
+            iCurHeight = 0;
+            memset(bFontGlyph, 0, sizeof(bFontGlyph));
+         }
+      }
+      else if (state == 1)
+      {
+         if (strncmp(buf, "ENDCHAR", 7) == 0)
+         {
+            //
+            // Replace the original fonts
+            //
+            BYTE szCp[3];
+            szCp[0] = (dwEncoding >> 8) & 0xFF;
+            szCp[1] = dwEncoding & 0xFF;
+            szCp[2] = 0;
+            wchar_t wc[2] = { 0 };
+            PAL_MultiByteToWideCharCP(codepage, (LPCSTR)szCp, 2, wc, 1);
+            if (wc[0] != 0)
+            {
+               wchar_t w = (wc[0] >= unicode_upper_base) ? (wc[0] - unicode_upper_base + 0xd800) : wc[0];
+               memcpy(unicode_font[w], bFontGlyph, sizeof(bFontGlyph));
+            }
+
+            state = 0;
+         }
+         else
+         {
+            if (iCurHeight < 16)
+            {
+               WORD wCode = strtoul(buf, NULL, 16);
+               bFontGlyph[iCurHeight * 2] = (wCode >> 8);
+               bFontGlyph[iCurHeight * 2 + 1] = (wCode & 0xFF);
+               iCurHeight++;
+            }
+         }
+      }
+   }
+
+   _font_height = 16;
+   fclose(fp);
+   return 0;
+}
+
 VOID
 PAL_FreeFont(
    VOID

+ 7 - 2
font.h

@@ -33,8 +33,13 @@ extern "C"
 #endif
 
 INT
-PAL_InitFont(
-   BOOL      fUseEmbeddedFonts
+PAL_InitEmbeddedFont(
+   VOID
+);
+
+INT
+PAL_LoadBdfFont(
+   LPCSTR      pszBdfFileName
 );
 
 VOID

+ 1 - 0
global.c

@@ -212,6 +212,7 @@ PAL_FreeGlobals(
    free(gConfig.dwExtraLength);
 #endif
    free(gConfig.pszMsgFile);
+   free(gConfig.pszBdfFile);
    free(gConfig.pszGamePath);
 
    //

+ 15 - 3
main.c

@@ -110,10 +110,22 @@ PAL_Init(
 
    SDL_WM_SetCaption("Loading...", NULL);
 
-   e = PAL_InitFont(!gConfig.fIsWIN95 && gConfig.fUseEmbeddedFonts);
-   if (e != 0)
+   if (!gConfig.fIsWIN95 && gConfig.fUseEmbeddedFonts)
+   {
+      e = PAL_InitEmbeddedFont();
+      if (e != 0)
+      {
+         TerminateOnError("Could not load fonts: %d.\n", e);
+      }
+   }
+
+   if (gConfig.pszBdfFile != NULL)
    {
-      TerminateOnError("Could not load fonts: %d.\n", e);
+	  e = PAL_LoadBdfFont(gConfig.pszBdfFile);
+      if (e != 0)
+      {
+         TerminateOnError("Could not load BDF fonts: %d.\n", e);
+      }
    }
 
    e = PAL_InitUI();

+ 14 - 0
palcfg.c

@@ -33,6 +33,7 @@ static const ConfigItem gConfigItems[PALCFG_ALL_MAX] = {
 	{ PALCFG_CD,                PALCFG_STRING,   "CD",                 2, "OGG", NULL, NULL },
 	{ PALCFG_GAMEPATH,          PALCFG_STRING,   "GAMEPATH",           8, NULL, NULL, NULL },
 	{ PALCFG_MESSAGEFILE,       PALCFG_STRING,   "MESSAGEFILENAME",   15, NULL, NULL, NULL },
+	{ PALCFG_BDFFILE,           PALCFG_STRING,   "BDFFILENAME",       11, NULL, NULL, NULL },
 	{ PALCFG_MUSIC,             PALCFG_STRING,   "MUSIC",              5, "RIX", NULL, NULL },
 	{ PALCFG_OPL,               PALCFG_STRING,   "OPL",                3, "DOSBOX", NULL, NULL },
 	{ PALCFG_RIXEXTRAINIT,      PALCFG_STRING,   "RIXEXTRAINIT",      12, NULL, NULL, NULL },
@@ -253,6 +254,18 @@ PAL_LoadConfig(
 					}
 					break;
 				}
+				case PALCFG_BDFFILE:
+				{
+					int n = strlen(value.sValue);
+					while (n > 0 && isspace(value.sValue[n - 1])) n--;
+					if (n > 0)
+					{
+						gConfig.pszBdfFile = (char *)realloc(gConfig.pszBdfFile, n + 1);
+						memcpy(gConfig.pszBdfFile, value.sValue, n);
+						gConfig.pszBdfFile[n] = '\0';
+					}
+					break;
+				}
 				case PALCFG_GAMEPATH:
 				{
 					int n = strlen(value.sValue);
@@ -434,6 +447,7 @@ PAL_SaveConfig(
 
 		if (gConfig.pszGamePath) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_GAMEPATH), gConfig.pszGamePath); fputs(buf, fp); }
 		if (gConfig.pszMsgFile) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_MESSAGEFILE), gConfig.pszMsgFile); fputs(buf, fp); }
+		if (gConfig.pszBdfFile) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_BDFFILE), gConfig.pszBdfFile); fputs(buf, fp); }
 
 		fclose(fp);
 

+ 2 - 0
palcfg.h

@@ -73,6 +73,7 @@ typedef enum tagPALCFG_ITEM
 	PALCFG_CD = PALCFG_STRING_MIN,
 	PALCFG_GAMEPATH,
 	PALCFG_MESSAGEFILE,
+	PALCFG_BDFFILE,
 	PALCFG_MUSIC,
 	PALCFG_OPL,
 	PALCFG_RIXEXTRAINIT,
@@ -160,6 +161,7 @@ typedef struct tagCONFIGURATION
 	/* Configurable options */
 	char            *pszGamePath;
 	char            *pszMsgFile;
+	char            *pszBdfFile;
 	CODEPAGE         uCodePage;
 	DWORD            dwWordLength;
 	DWORD            dwScreenWidth;

+ 1 - 1
unix/Makefile

@@ -8,7 +8,7 @@ CFILES = $(wildcard ../adplug/*.c) $(wildcard ../libmad/*.c) $(wildcard ../libog
 CPPFILES = $(wildcard ../adplug/*.cpp) $(wildcard ../*.cpp) $(wildcard ./*.cpp)
 OBJFILES = $(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
 
-CCFLAGS = `sdl2-config --cflags` -g -Wall -O2 -fno-strict-aliasing -I../ -I../liboggvorbis/include -I../liboggvorbis/src -DPAL_CLASSIC -DPAL_HAS_PLATFORM_SPECIFIC_UTILS
+CCFLAGS = `sdl2-config --cflags` -g -Wall -O2 -fno-strict-aliasing -I../ -I../liboggvorbis/include -I../liboggvorbis/src -DPAL_HAS_PLATFORM_SPECIFIC_UTILS
 CXXFLAGS = $(CCFLAGS) -std=c++11 `fltk-config --cxxflags`
 CFLAGS = $(CCFLAGS) -std=gnu99 `fltk-config --cflags`
 LDFLAGS = `sdl2-config --libs` `fltk-config --ldflags` -lstdc++ -lm