From 78c2fec5916b1260d1ecfb2f93a97c079ea8def4 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 21 Oct 2011 23:44:08 -0400
Subject: [PATCH] Preallocate the fonts up front, and free them when we're all
done.
---
Maelstrom_Globals.h | 8 ++++++
controls.cpp | 19 ++++----------
init.cpp | 30 +++++++++++++++-------
maclib/Mac_FontServ.cpp | 35 +-------------------------
maclib/Mac_FontServ.h | 6 -----
main.cpp | 55 +++++++++--------------------------------
netlogic/about.cpp | 8 +-----
netlogic/game.cpp | 23 +++--------------
scores.cpp | 14 ++---------
9 files changed, 53 insertions(+), 145 deletions(-)
diff --git a/Maelstrom_Globals.h b/Maelstrom_Globals.h
index a4694bce..ee90ee24 100644
--- a/Maelstrom_Globals.h
+++ b/Maelstrom_Globals.h
@@ -17,6 +17,14 @@
// The Font Server :)
extern FontServ *fontserv;
+enum {
+ CHICAGO_12,
+ GENEVA_9,
+ NEWYORK_14,
+ NEWYORK_18,
+ NUM_FONTS
+};
+extern MFont *fonts[NUM_FONTS];
// The Sound Server *grin*
extern Sound *sound;
diff --git a/controls.cpp b/controls.cpp
index 73ad84a9..9e31f34f 100644
--- a/controls.cpp
+++ b/controls.cpp
@@ -164,7 +164,6 @@ static struct {
static int X=0;
static int Y=0;
-static MFont *chicago;
static SDL_Texture *keynames[NUM_CTLS];
static int currentbox, valid;
@@ -196,7 +195,7 @@ static void BoxKeyPress(const SDL_Keysym &key, int *doneflag)
/* Blit the new message */
strcpy(keyname, "That key is in use!");
keynames[currentbox] = fontserv->TextImage(keyname,
- chicago, STYLE_NORM, 0x00, 0x00, 0x00);
+ fonts[CHICAGO_12], STYLE_NORM, 0x00, 0x00, 0x00);
screen->QueueBlit(
X+96+(BOX_WIDTH-screen->GetImageWidth(keynames[currentbox]))/2,
Y+75+SP+checkboxes[currentbox].yoffset,
@@ -214,7 +213,7 @@ static void BoxKeyPress(const SDL_Keysym &key, int *doneflag)
*checkboxes[currentbox].control = sym;
KeyName(*checkboxes[currentbox].control, keyname);
keynames[currentbox] = fontserv->TextImage(keyname,
- chicago, STYLE_NORM, 0x00, 0x00, 0x00);
+ fonts[CHICAGO_12], STYLE_NORM, 0x00, 0x00, 0x00);
screen->QueueBlit(X+96+(BOX_WIDTH-screen->GetImageWidth(keynames[currentbox]))/2,
Y+75+SP+checkboxes[currentbox].yoffset,
keynames[currentbox], NOCLIP);
@@ -230,6 +229,7 @@ void ConfigureControls(void)
"ESC aborts the game.";
SDL_Texture *text1, *text2;
#endif
+ MFont *chicago;
Uint32 black;
int i;
char keyname[128];
@@ -242,13 +242,9 @@ void ConfigureControls(void)
/* Set up all the components of the dialog box */
black = screen->MapRGB(0x00, 0x00, 0x00);
- if ( (chicago = fontserv->NewFont("Chicago", 12)) == NULL ) {
- error("Can't use Chicago font!\n");
- return;
- }
+ chicago = fonts[CHICAGO_12];
if ( (splash = Load_Title(screen, 100)) == NULL ) {
error("Can't load configuration splash!\n");
- fontserv->FreeFont(chicago);
return;
}
X=(SCREEN_WIDTH-CTL_DIALOG_WIDTH)/2;
@@ -310,7 +306,6 @@ void ConfigureControls(void)
for ( i=0; i<NUM_CTLS; ++i ) {
fontserv->FreeText(keynames[i]);
}
- fontserv->FreeFont(chicago);
delete dialog;
if ( valid ) {
memcpy(&controls, &newcontrols, sizeof(controls));
@@ -500,10 +495,7 @@ void ShowDawn(void)
X=160;
Y=73;
#endif
- if ( (chicago = fontserv->NewFont("Chicago", 12)) == NULL ) {
- error("Can't use Chicago font!\n");
- return;
- }
+ chicago = fonts[CHICAGO_12];
if ( (splash = GetCIcon(screen, 103)) == NULL ) {
error("Can't load alien dawn splash!\n");
return;
@@ -534,7 +526,6 @@ void ShowDawn(void)
screen->FreeImage(splash);
for ( i=0; i<6; ++i )
fontserv->FreeText(text[i]);
- fontserv->FreeFont(chicago);
delete dialog;
return;
}
diff --git a/init.cpp b/init.cpp
index a55b5d72..fdfdc58f 100644
--- a/init.cpp
+++ b/init.cpp
@@ -13,6 +13,7 @@
// Global variables set in this file...
Sound *sound = NULL;
FontServ *fontserv = NULL;
+MFont *fonts[NUM_FONTS];
FrameBuf *screen = NULL;
Sint32 gLastHigh;
@@ -76,7 +77,6 @@ void DoSplash(void)
void DoIntroScreen(void)
{
- MFont *geneva;
SDL_Texture *intro, *text;
Uint16 Yoff, Xoff;
Uint32 clr, ltClr, ltrClr;
@@ -112,19 +112,13 @@ void DoIntroScreen(void)
/* -- Draw the loading message */
- geneva = fontserv->NewFont("Geneva", 9);
- if ( geneva == NULL ) {
- error("Warning: %s\n", fontserv->Error());
- return;
- }
- text = fontserv->TextImage("Loading...", geneva, STYLE_BOLD,
+ text = fontserv->TextImage("Loading...", fonts[GENEVA_9], STYLE_BOLD,
0xFF, 0xFF, 0x00);
if ( text ) {
screen->QueueBlit(SCREEN_WIDTH/2-screen->GetImageWidth(text)/2,
Yoff+20-screen->GetImageHeight(text)/2, text, NOCLIP);
fontserv->FreeText(text);
}
- fontserv->FreeFont(geneva);
screen->Update();
} // -- DoIntroScreen
@@ -696,8 +690,15 @@ static void BuildVelocityTable(void)
*/
extern "C" void CleanUp(void)
{
+ int i;
+
HaltLogic();
if ( fontserv ) {
+ for ( i = 0; i < NUM_FONTS; ++i ) {
+ if ( fonts[i] ) {
+ fontserv->FreeFont(fonts[i]);
+ }
+ }
delete fontserv;
fontserv = NULL;
}
@@ -770,12 +771,23 @@ int DoInitializations(Uint32 video_flags)
atexit(CleanUp); // Need to reset this under X11 DGA
SDL_FreeSurface(icon);
- /* Load the Font Server */
+ /* Load the Font Server and fonts */
fontserv = new FontServ(screen, "Maelstrom Fonts");
if ( fontserv->Error() ) {
error("Fatal: %s\n", fontserv->Error());
return(-1);
}
+ memset(fonts, 0, sizeof(fonts));
+ fonts[CHICAGO_12] = fontserv->NewFont("Chicago", 12);
+ fonts[GENEVA_9] = fontserv->NewFont("Geneva", 9);
+ fonts[NEWYORK_14] = fontserv->NewFont("New York", 14);
+ fonts[NEWYORK_18] = fontserv->NewFont("New York", 18);
+ for ( i = 0; i < NUM_FONTS; ++i ) {
+ if ( !fonts[i] ) {
+ error("Fatal: Couldn't load fonts");
+ return(-1);
+ }
+ }
/* Load the Sound Server and initialize sound */
sound = new Sound("Maelstrom Sounds", gSoundLevel);
diff --git a/maclib/Mac_FontServ.cpp b/maclib/Mac_FontServ.cpp
index ea3c9c66..71977e85 100644
--- a/maclib/Mac_FontServ.cpp
+++ b/maclib/Mac_FontServ.cpp
@@ -85,7 +85,6 @@ FontServ:: FontServ(FrameBuf *_screen, const char *fontfile)
{
screen = _screen;
fontres = new Mac_Resource(fontfile);
- fonts = NULL;
strings = hash_create(screen, hash_hash_string, hash_keymatch_string, hash_nuke_string_texture);
if ( fontres->Error() ) {
@@ -101,11 +100,6 @@ FontServ:: FontServ(FrameBuf *_screen, const char *fontfile)
FontServ:: ~FontServ()
{
- while (fonts) {
- MFont *next = fonts->next;
- delete fonts;
- fonts = next;
- }
hash_destroy(strings);
delete fontres;
@@ -124,20 +118,6 @@ FontServ:: NewFont(const char *fontname, int ptsize)
int i, swapfont;
MFont *prev, *font;
- /* First see if we can find the font in our cache */
- prev = NULL;
- for (font = fonts; font; prev = font, font = font->next) {
- if (strcmp(fontname, font->name) == 0 && ptsize == font->ptsize) {
- /* Move this font to the front so it's found faster */
- if (prev) {
- prev->next = font->next;
- font->next = fonts;
- fonts = font;
- }
- return font;
- }
- }
-
/* Get the font family */
fond = fontres->Resource("FOND", fontname);
if ( fond == NULL ) {
@@ -235,18 +215,13 @@ FontServ:: NewFont(const char *fontname, int ptsize)
byteswap((Uint16 *)font->owTable, nchars);
}
- /* Save this font in the cache */
- font->next = fonts;
- fonts = font;
-
return(font);
}
void
FontServ:: FreeFont(MFont *font)
{
- /* We'll likely be asked for this again soon, leave it alone */
- return;
+ delete font;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -453,11 +428,3 @@ FontServ:: FreeText(SDL_Texture *text)
/* We'll likely be asked for this again soon, leave it alone */
return;
}
-
-void
-FontServ:: FlushCache(void)
-{
- /* We'll flush any strings in the cache and leave the fonts around */
- hash_destroy(strings);
- strings = hash_create(screen, hash_hash_string, hash_keymatch_string, hash_nuke_string_texture);
-}
diff --git a/maclib/Mac_FontServ.h b/maclib/Mac_FontServ.h
index a4142f83..3a1ebce7 100644
--- a/maclib/Mac_FontServ.h
+++ b/maclib/Mac_FontServ.h
@@ -74,11 +74,8 @@ struct FontHdr {
};
typedef struct MFont {
- /* Data useful for caching */
const char *name;
int ptsize;
- struct MFont *next;
-
struct FontHdr *header; /* The NFNT header! */
/* Variable-length tables */
@@ -125,8 +122,6 @@ class FontServ {
}
void FreeText(SDL_Texture *text);
- void FlushCache();
-
/* Returns NULL if everything is okay, or an error message if not */
char *Error(void) {
return(errstr);
@@ -135,7 +130,6 @@ class FontServ {
private:
FrameBuf *screen;
Mac_Resource *fontres;
- MFont *fonts;
HashTable *strings;
/* Useful for getting error feedback */
diff --git a/main.cpp b/main.cpp
index c5b2cf9c..18b144ca 100644
--- a/main.cpp
+++ b/main.cpp
@@ -448,21 +448,14 @@ int DrawText(int x, int y, const char *text, MFont *font, Uint8 style,
/* -- Draw the current sound volume */
static void DrawSoundLevel(void)
{
- MFont *geneva;
char text[12];
int xOff, yOff;
- if ( (geneva = fontserv->NewFont("Geneva", 9)) == NULL ) {
- error("Can't use Geneva font! -- Exiting.\n");
- exit(255);
- }
-
xOff = (SCREEN_WIDTH - 512) / 2;
yOff = (SCREEN_HEIGHT - 384) / 2;
sprintf(text, "%d", gSoundLevel);
- DrawText(xOff+309-7, yOff+240-6, text, geneva, STYLE_BOLD,
+ DrawText(xOff+309-7, yOff+240-6, text, fonts[GENEVA_9], STYLE_BOLD,
30000>>8, 30000>>8, 0xFF);
- fontserv->FreeFont(geneva);
} /* -- DrawSoundLevel */
@@ -522,11 +515,8 @@ void DrawMainScreen(void)
/* -- Draw the high scores */
- /* -- First the headings -- fontserv() isn't elegant, but hey.. */
- if ( (bigfont = fontserv->NewFont("New York", 18)) == NULL ) {
- error("Can't use New York (18) font! -- Exiting.\n");
- exit(255);
- }
+ /* -- First the headings */
+ bigfont = fonts[NEWYORK_18];
DrawText(xOff+5, botDiv+22, "Name", bigfont, STYLE_ULINE,
0xFF, 0xFF, 0x00);
sRt = xOff+185;
@@ -540,10 +530,7 @@ void DrawMainScreen(void)
/* -- Now the scores */
LoadScores();
- if ( (font = fontserv->NewFont("New York", 14)) == NULL ) {
- error("Can't use New York (14) font! -- Exiting.\n");
- exit(255);
- }
+ font = fonts[NEWYORK_14];
for (index = 0; index < 10; index++) {
Uint8 R, G, B;
@@ -568,7 +555,6 @@ void DrawMainScreen(void)
DrawText(wRt-sw, botDiv+42+(index*18), buffer,
font, STYLE_BOLD, R, G, B);
}
- fontserv->FreeFont(font);
DrawText(xOff+5, botDiv+46+(10*18)+3, "Last Score: ",
bigfont, STYLE_NORM, 0xFF, 0xFF, 0xFF);
@@ -576,7 +562,6 @@ void DrawMainScreen(void)
sw = fontserv->TextWidth("Last Score: ", bigfont, STYLE_NORM);
DrawText(xOff+5+sw, botDiv+46+(index*18)+3, buffer,
bigfont, STYLE_NORM, 0xFF, 0xFF, 0xFF);
- fontserv->FreeFont(bigfont);
/* -- Draw the Instructions */
offset = 34;
@@ -607,10 +592,7 @@ void DrawMainScreen(void)
pt.v += offset;
DrawKey(&pt, "0", " ", DecrementSound);
- if ( (font = fontserv->NewFont("Geneva", 9)) == NULL ) {
- error("Can't use Geneva font! -- Exiting.\n");
- exit(255);
- }
+ font = fonts[GENEVA_9];
DrawText(pt.h+screen->GetImageWidth(gKeyIcon)+3, pt.v+19, "-",
font, STYLE_NORM, 0xFF, 0xFF, 0x00);
@@ -628,7 +610,6 @@ void DrawMainScreen(void)
DrawText(xOff+20, yOff+151, VERSION_STRING,
font, STYLE_NORM, 0xFF, 0xFF, 0xFF);
- fontserv->FreeFont(font);
DrawSoundLevel();
@@ -644,20 +625,14 @@ void DrawMainScreen(void)
static void DrawKey(MPoint *pt, const char *key, const char *text, void (*callback)(void))
{
- MFont *geneva;
-
- if ( (geneva = fontserv->NewFont("Geneva", 9)) == NULL ) {
- error("Can't use Geneva font! -- Exiting.\n");
- exit(255);
- }
+ MFont *font = fonts[GENEVA_9];
screen->QueueBlit(pt->h, pt->v, gKeyIcon);
- DrawText(pt->h+14, pt->v+20, key, geneva, STYLE_BOLD, 0xFF, 0xFF, 0xFF);
- DrawText(pt->h+13, pt->v+19, key, geneva, STYLE_BOLD, 0x00, 0x00, 0x00);
+ DrawText(pt->h+14, pt->v+20, key, font, STYLE_BOLD, 0xFF, 0xFF, 0xFF);
+ DrawText(pt->h+13, pt->v+19, key, font, STYLE_BOLD, 0x00, 0x00, 0x00);
DrawText(pt->h+screen->GetImageWidth(gKeyIcon)+3, pt->v+19, text,
- geneva, STYLE_BOLD, 0xFF, 0xFF, 0x00);
- fontserv->FreeFont(geneva);
+ font, STYLE_BOLD, 0xFF, 0xFF, 0x00);
buttons.Add_Button(pt->h, pt->v, screen->GetImageWidth(gKeyIcon), screen->GetImageHeight(gKeyIcon), callback);
} /* -- DrawKey */
@@ -665,22 +640,14 @@ static void DrawKey(MPoint *pt, const char *key, const char *text, void (*callba
void Message(const char *message)
{
- MFont *font;
int xOff;
if (!message) {
return;
}
- if ( (font = fontserv->NewFont("New York", 14)) == NULL ) {
- error("Can't use New York(14) font! -- Exiting.\n");
- exit(255);
- }
-
/* This was taken from the DrawMainScreen function */
xOff = (SCREEN_WIDTH - 512) / 2;
- DrawText(xOff, 25, message, font, STYLE_BOLD, 0xCC,0xCC,0xCC);
-
- fontserv->FreeFont(font);
+ DrawText(xOff, 25, message, fonts[NEWYORK_14], STYLE_BOLD,
+ 0xCC, 0xCC, 0xCC);
}
-
diff --git a/netlogic/about.cpp b/netlogic/about.cpp
index d48c53ae..aa321f0f 100644
--- a/netlogic/about.cpp
+++ b/netlogic/about.cpp
@@ -175,12 +175,7 @@ void DoAbout(void)
/* Put in the right credits / mask the old... */
clr = screen->MapRGB(0x00, 0x00, 0x00);
screen->FillRect(xOff+166,yOff+282,338,62,clr);
- font = fontserv->NewFont("New York", 18);
- if ( font == NULL ) {
- error(
- "Can't use New York(18) font! -- Exiting.\n");
- exit(255);
- }
+ font = fonts[NEWYORK_18];
text1 = fontserv->TextImage("Port to Linux: ",
font, STYLE_NORM, 0xFF, 0xFF, 0x55);
text2 = fontserv->TextImage("Sam Lantinga",
@@ -191,7 +186,6 @@ void DoAbout(void)
text2, NOCLIP);
fontserv->FreeText(text1);
fontserv->FreeText(text2);
- fontserv->FreeFont(font);
}
screen->Update();
screen->Fade();
diff --git a/netlogic/game.cpp b/netlogic/game.cpp
index 5177473d..ff34fe87 100644
--- a/netlogic/game.cpp
+++ b/netlogic/game.cpp
@@ -116,7 +116,7 @@ Object *gEnemySprite;
int gWhenEnemy;
// Local global variables;
-static MFont *geneva=NULL;
+static MFont *geneva;
static Uint32 ourGrey, ourWhite;
static int text_height;
@@ -278,10 +278,7 @@ void NewGame(void)
}
/* Load the font and colors we use everywhere */
- if ( (geneva = fontserv->NewFont("Geneva", 9)) == NULL ) {
- error("Can't use Geneva font! -- Exiting.\n");
- exit(255);
- }
+ geneva = fonts[GENEVA_9];
text_height = fontserv->TextHeight(geneva);
ourGrey = screen->MapRGB(30000>>8, 30000>>8, 0xFF);
ourWhite = screen->MapRGB(0xFF, 0xFF, 0xFF);
@@ -327,7 +324,6 @@ void NewGame(void)
DoGameOver();
screen->ShowCursor();
- fontserv->FreeFont(geneva);
} /* -- NewGame */
@@ -405,9 +401,6 @@ static void NextWave(void)
int NewRoids;
short temp;
- /* Flush the font text cache */
- fontserv->FlushCache();
-
gEnemySprite = NULL;
/* -- Initialize some variables */
@@ -580,10 +573,7 @@ static void DoGameOver(void)
/* Show the player ranking */
if ( gNumPlayers > 1 ) {
- if ( (newyork = fontserv->NewFont("New York", 18)) == NULL ) {
- error("Can't use New York font! -- Exiting.\n");
- exit(255);
- }
+ newyork = fonts[NEWYORK_18];
newyork_height = fontserv->TextHeight(newyork);
for ( i=0; i<gNumPlayers; ++i ) {
char buffer[BUFSIZ], num1[12], num2[12];
@@ -595,7 +585,6 @@ static void DoGameOver(void)
DrawText(160, 380+i*newyork_height, buffer,
newyork, STYLE_NORM, 30000>>8, 30000>>8, 0xFF);
}
- fontserv->FreeFont(newyork);
}
screen->Update();
@@ -628,10 +617,7 @@ static void DoGameOver(void)
}
/* -- Draw the "Enter your name" string */
- if ( (newyork = fontserv->NewFont("New York", 18)) == NULL ) {
- error("Can't use New York font! -- Exiting.\n");
- exit(255);
- }
+ newyork = fonts[NEWYORK_18];
newyork_height = fontserv->TextHeight(newyork);
x = (SCREEN_WIDTH-(fontserv->TextWidth("Enter your name: ",
newyork, STYLE_NORM)*2))/2;
@@ -683,7 +669,6 @@ static void DoGameOver(void)
screen->Update();
}
}
- fontserv->FreeFont(newyork);
SDL_StopTextInput();
/* In case the user just pressed <Return> */
diff --git a/scores.cpp b/scores.cpp
index 4108e686..126d60dc 100644
--- a/scores.cpp
+++ b/scores.cpp
@@ -130,13 +130,9 @@ int ZapHighScores(void)
X=179;
Y=89;
#endif
- if ( (chicago = fontserv->NewFont("Chicago", 12)) == NULL ) {
- error("Can't use Chicago font!\n");
- return(0);
- }
+ chicago = fonts[CHICAGO_12];
if ( (splash = Load_Title(screen, 102)) == NULL ) {
error("Can't load score zapping splash!\n");
- delete chicago;
return(0);
}
dialog = new Maclike_Dialog(X, Y, CLR_DIALOG_WIDTH, CLR_DIALOG_HEIGHT,
@@ -156,7 +152,6 @@ int ZapHighScores(void)
/* Clean up and return */
screen->FreeImage(splash);
- fontserv->FreeFont(chicago);
delete dialog;
if ( do_clear ) {
memset(hScores, 0, sizeof(hScores));
@@ -202,13 +197,9 @@ int GetStartLevel(void)
int startlevel=10, startlives=5, turbofunk=0;
/* Set up all the components of the dialog box */
- if ( (chicago = fontserv->NewFont("Chicago", 12)) == NULL ) {
- error("Can't use Chicago font!\n");
- return(0);
- }
+ chicago = fonts[CHICAGO_12];
if ( (splash = GetCIcon(screen, 103)) == NULL ) {
error("Can't load alien level splash!\n");
- delete chicago;
return(0);
}
X=(SCREEN_WIDTH-LVL_DIALOG_WIDTH)/2;
@@ -252,7 +243,6 @@ int GetStartLevel(void)
fontserv->FreeText(text2);
fontserv->FreeText(text3);
fontserv->FreeText(text4);
- fontserv->FreeFont(chicago);
delete dialog;
if ( do_level ) {
if ( ! startlives || (startlives > 40) )