Maelstrom: The bonus score screen is switched over to use the new UI system.

https://github.com/libsdl-org/Maelstrom/commit/579199751356ab74b2717dda636b1a1b6717d581

From 579199751356ab74b2717dda636b1a1b6717d581 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 27 Oct 2011 02:38:48 -0400
Subject: [PATCH] The bonus score screen is switched over to use the new UI
 system.

---
 Maelstrom_Globals.h        |   4 +
 Makefile.am                |   2 +
 UI/bonus.xml               |  45 ++++
 UI/game.xml                |   6 +-
 UIElementSprite.cpp        |  51 ++++
 UIElementSprite.h          |  30 +++
 UIElements.cpp             |   3 +
 init.cpp                   |  23 +-
 netlogic/game.cpp          | 519 ++++++++++++++++++++-----------------
 netlogic/game.h            |   4 +
 netlogic/player.cpp        |   4 +-
 screenlib/SDL_FrameBuf.cpp |   2 +-
 screenlib/UIManager.cpp    |   4 -
 13 files changed, 443 insertions(+), 254 deletions(-)
 create mode 100644 UI/bonus.xml
 create mode 100644 UIElementSprite.cpp
 create mode 100644 UIElementSprite.h

diff --git a/Maelstrom_Globals.h b/Maelstrom_Globals.h
index c974e295..61102f92 100644
--- a/Maelstrom_Globals.h
+++ b/Maelstrom_Globals.h
@@ -40,6 +40,9 @@ extern FrameBuf *screen;
 // The UI system
 extern UIManager *ui;
 
+// The sprites
+extern Mac_Resource *spriteres;
+
 /* Boolean type */
 typedef Uint8 Bool;
 #ifndef true
@@ -101,6 +104,7 @@ extern Bool	gNetScores;
 #define PANEL_LOADING	"loading"
 #define PANEL_MAIN	"main"
 #define PANEL_GAME	"game"
+#define PANEL_BONUS	"bonus"
 #define PANEL_GAMEOVER	"gameover"
 #define PANEL_ABOUT	"about_story"
 #define PANEL_CONTROLS	"controls"
diff --git a/Makefile.am b/Makefile.am
index 6575cc6f..45d72c40 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,6 +36,8 @@ Maelstrom_SOURCES =		\
 	UIElementKeyButton.h	\
 	UIElementLabel.cpp	\
 	UIElementLabel.h	\
+	UIElementSprite.cpp	\
+	UIElementSprite.h	\
 	UIElementTitle.cpp	\
 	UIElementTitle.h	\
 	UIElements.cpp		\
diff --git a/UI/bonus.xml b/UI/bonus.xml
new file mode 100644
index 00000000..d0a15110
--- /dev/null
+++ b/UI/bonus.xml
@@ -0,0 +1,45 @@
+<UIPanel fullscreen="false" enterSound="110">
+	<Elements>
+		<Label name="wave" fontName="Geneva" fontSize="9" fontStyle="BOLD">
+			<Color r="0xFF" g="0xFF" b="0x00"/>
+			<Anchor anchorFrom="TOP" anchorTo="CENTER" y="-90"/>
+		</Label>
+		<Label name="bonus_label" fontName="Geneva" fontSize="9" fontStyle="BOLD" text="Bonus Score:     ">
+			<Color r="0x75" g="0x75" b="0xFF"/>
+			<Anchor anchorFrom="TOP" anchorTo="TOP" anchor="wave" x="-20" y="50"/>
+		</Label>
+		<Label name="bonus" fontName="Geneva" fontSize="9" fontStyle="BOLD">
+			<Color r="0xFF" g="0xFF" b="0xFF"/>
+			<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="bonus_label"/>
+		</Label>
+		<Label name="multiplied_bonus" fontName="Geneva" fontSize="9" fontStyle="BOLD">
+			<Color r="0xFF" g="0xFF" b="0xFF"/>
+			<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="bonus_label" x="75"/>
+		</Label>
+		<Label name="score_label" fontName="Geneva" fontSize="9" fontStyle="BOLD" text="Score:     ">
+			<Color r="0x75" g="0x75" b="0xFF"/>
+			<Anchor anchorFrom="TOP" anchorTo="TOP" anchor="wave" x="-3" y="70"/>
+		</Label>
+		<Label name="score" fontName="Geneva" fontSize="9" fontStyle="BOLD" text="Score:     ">
+			<Color r="0xFF" g="0xFF" b="0xFF"/>
+			<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="score_label"/>
+		</Label>
+		<Sprite name="multiplier2" id="2000">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="score_label" x="34" y="-30"/>
+		</Sprite>
+		<Sprite name="multiplier3" id="2002">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="multiplier2"/>
+		</Sprite>
+		<Sprite name="multiplier4" id="2004">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="multiplier2"/>
+		</Sprite>
+		<Sprite name="multiplier5" id="2006">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="multiplier2"/>
+		</Sprite>
+
+		<Label name="next" fontName="Geneva" fontSize="9" fontStyle="BOLD">
+			<Color r="0xFF" g="0xFF" b="0x00"/>
+			<Anchor anchorFrom="TOP" anchorTo="TOP" anchor="wave" y="109"/>
+		</Label>
+	</Elements>
+</UIPanel>
diff --git a/UI/game.xml b/UI/game.xml
index 1c3c21a8..c762d7b4 100644
--- a/UI/game.xml
+++ b/UI/game.xml
@@ -62,13 +62,13 @@
 			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="status_line" x="424" y="3"/>
 		</Icon>
 		<Icon name="multiplier3" id="131">
-			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="status_line" x="424" y="3"/>
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="multiplier2"/>
 		</Icon>
 		<Icon name="multiplier4" id="132">
-			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="status_line" x="424" y="3"/>
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="multiplier2"/>
 		</Icon>
 		<Icon name="multiplier5" id="134">
-			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="status_line" x="424" y="3"/>
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="multiplier2"/>
 		</Icon>
 
 		<Icon name="autofire" id="128">
diff --git a/UIElementSprite.cpp b/UIElementSprite.cpp
new file mode 100644
index 00000000..3ff27dbe
--- /dev/null
+++ b/UIElementSprite.cpp
@@ -0,0 +1,51 @@
+
+#include "Maelstrom_Globals.h"
+#include "UIElementSprite.h"
+
+UIElementType UIElementSprite::s_elementType;
+
+
+UIElementSprite::UIElementSprite(UIPanel *panel, const char *name) :
+	UIElementTexture(panel, name)
+{
+}
+
+static SDL_Texture *
+LoadSprite(FrameBuf *screen, int baseID)
+{
+	Mac_ResData *S, *M;
+
+	S = spriteres->Resource("icl8", baseID);
+	if ( S == NULL ) {
+		return NULL;
+	}
+
+	M = spriteres->Resource("ICN#", baseID);
+	if ( M == NULL ) {
+		return NULL;
+	}
+
+	/* Load the image */
+	return screen->LoadImage(32, 32, S->data, M->data+128);
+}
+
+bool
+UIElementSprite::Load(rapidxml::xml_node<> *node)
+{
+	rapidxml::xml_attribute<> *attr;
+
+	attr = node->first_attribute("id", 0, false);
+	if (!attr) {
+		SetError("Element '%s' missing attribute 'id'", node->name());
+		return false;
+	}
+
+	SDL_Texture *texture = LoadSprite(m_screen, atoi(attr->value()));
+	if (!texture) {
+		SetError("Unable to load sprite %d", atoi(attr->value()));
+		return false;
+	}
+	SetTexture(texture);
+
+	return UIElementTexture::Load(node);
+}
diff --git a/UIElementSprite.h b/UIElementSprite.h
new file mode 100644
index 00000000..2cf33f3b
--- /dev/null
+++ b/UIElementSprite.h
@@ -0,0 +1,30 @@
+#ifndef _UIElementSprite_h
+#define _UIElementSprite_h
+
+#include "screenlib/UIElementTexture.h"
+
+
+class UIElementSprite : public UIElementTexture
+{
+public:
+	UIElementSprite(UIPanel *panel, const char *name = "");
+
+	virtual bool IsA(UIElementType type) {
+		return UIElementTexture::IsA(type) || type == GetType();
+	}
+
+	virtual bool Load(rapidxml::xml_node<> *node);
+
+protected:
+	static UIElementType s_elementType;
+
+public:
+	static UIElementType GetType() {
+		if (!s_elementType) {
+			s_elementType = GenerateType();
+		}
+		return s_elementType;
+	}
+};
+
+#endif // _UIElementSprite_h
diff --git a/UIElements.cpp b/UIElements.cpp
index 2dd91d88..0d1563dd 100644
--- a/UIElements.cpp
+++ b/UIElements.cpp
@@ -6,6 +6,7 @@
 #include "UIElementIcon.h"
 #include "UIElementKeyButton.h"
 #include "UIElementLabel.h"
+#include "UIElementSprite.h"
 #include "UIElementTitle.h"
 
 
@@ -24,6 +25,8 @@ CreateMaelstromUIElement(UIPanel *panel, const char *type)
 		return new UIElementKeyButton(panel);
 	} else if (strcasecmp(type, "Icon") == 0) {
 		return new UIElementIcon(panel);
+	} else if (strcasecmp(type, "Sprite") == 0) {
+		return new UIElementSprite(panel);
 	} else if (strcasecmp(type, "Title") == 0) {
 		return new UIElementTitle(panel);
 	}
diff --git a/init.cpp b/init.cpp
index 0feda5f9..f92abb98 100644
--- a/init.cpp
+++ b/init.cpp
@@ -19,6 +19,7 @@ FontServ *fontserv = NULL;
 MFont    *fonts[NUM_FONTS];
 FrameBuf *screen = NULL;
 UIManager *ui = NULL;
+Mac_Resource *spriteres = NULL;
 
 Sint32	gLastHigh;
 Uint32	gLastDrawn;
@@ -620,6 +621,10 @@ static void BuildVelocityTable(void)
 void CleanUp(void)
 {
 	HaltLogic();
+	if ( spriteres ) {
+		delete spriteres;
+		spriteres = NULL;
+	}
 	if ( ui ) {
 		delete ui;
 		ui = NULL;
@@ -782,16 +787,14 @@ int DoInitializations(Uint32 window_flags, Uint32 render_flags)
 	ui->Draw();
 
 	/* -- Load in our sprites and other needed resources */
-	{
-		Mac_Resource spriteres("Maelstrom Sprites");
+	spriteres = new Mac_Resource("Maelstrom Sprites");
 
-		if ( spriteres.Error() ) {
-			error("%s\n", spriteres.Error());
-			return(-1);
-		}
-		if ( LoadBlits(&spriteres) < 0 ) {
-			return(-1);
-		}
+	if ( spriteres->Error() ) {
+		error("%s\n", spriteres->Error());
+		return(-1);
+	}
+	if ( LoadBlits(spriteres) < 0 ) {
+		return(-1);
 	}
 
 	/* -- Create the shots array */
@@ -1037,7 +1040,7 @@ static int LoadSprite(Mac_Resource *spriteres,
 	for (index = 0; index < numFrames; index++) {
 
 		M = spriteres->Resource("ICN#", baseID+index);
-		if ( M== NULL ) {
+		if ( M == NULL ) {
 			error(
 	"LoadSprite(%d+%d): Couldn't load ICN# resource!\n", baseID, index);
 			return(-1);
diff --git a/netlogic/game.cpp b/netlogic/game.cpp
index eb444eef..2b122ccd 100644
--- a/netlogic/game.cpp
+++ b/netlogic/game.cpp
@@ -129,8 +129,6 @@ static void DoBonus(void);
 
 void NewGame(void)
 {
-	int i;
-
 	/* Send a "NEW_GAME" packet onto the network */
 	if ( gNumPlayers > 1 ) {
 		if ( gOurPlayer == 0 ) {
@@ -178,6 +176,8 @@ GamePanelDelegate::OnLoad()
 	/* Load the font and colors we use everywhere */
 	geneva = fonts[GENEVA_9];
 
+	m_showingBonus = false;
+
 	/* Initialize our panel variables */
 	m_score = m_panel->GetElement<UIElementLabel>("score");
 	m_shield = m_panel->GetElement<UIElement>("shield");
@@ -230,80 +230,16 @@ GamePanelDelegate::OnHide()
 void
 GamePanelDelegate::OnTick()
 {
-	/* Don't do anything if we're paused */
-	if ( gPaused ) {
-		return;
-	}
-
-#ifdef MOVIE_SUPPORT
-	if ( gMovie )
-		screen->ScreenDump("MovieFrame", &gMovieRect);
-#endif
-	/* -- Maybe throw a multiplier up on the screen */
-	if (gMultiplierShown && (--gMultiplierShown == 0) )
-		MakeMultiplier();
-	
-	/* -- Maybe throw a prize(!) up on the screen */
-	if (gPrizeShown && (--gPrizeShown == 0) )
-		MakePrize();
-	
-	/* -- Maybe throw a bonus up on the screen */
-	if (gBonusShown && (--gBonusShown == 0) )
-		MakeBonus();
-
-	/* -- Maybe make a nasty enemy fighter? */
-	if (gWhenEnemy && (--gWhenEnemy == 0) )
-		MakeEnemy();
-
-	/* -- Maybe create a transcenfugal vortex */
-	if (gWhenGrav && (--gWhenGrav == 0) )
-		MakeGravity();
-	
-	/* -- Maybe create a recified space vehicle */
-	if (gWhenDamaged && (--gWhenDamaged == 0) )
-		MakeDamagedShip();
-	
-	/* -- Maybe create a autonominous tracking device */
-	if (gWhenHoming && (--gWhenHoming == 0) )
-		MakeHoming();
-	
-	/* -- Maybe make a supercranial destruction thang */
-	if (gWhenNova && (--gWhenNova == 0) )
-		MakeNova();
-
-	/* -- Maybe create a new star ? */
-	if ( --gLastStar == 0 ) {
-		gLastStar = STAR_DELAY;
-		SetStar(FastRandom(MAX_STARS));
-	}
-	
-	/* -- Time for the next wave? */
-	if (gNumRocks == 0) {
-		if ( gWhenDone == 0 )
-			gWhenDone = DEAD_DELAY;
-		else if ( --gWhenDone == 0 )
-			NextWave();
-	}
-}
+	int i, j;
 
-void
-GamePanelDelegate::OnDraw()
-{
-	int i, j, PlayersLeft;
+	/* -- Read in keyboard input for our ship */
+	HandleEvents(0);
 
-	/* -- Draw the star field */
-	for ( i=0; i<MAX_STARS; ++i ) {
-		screen->DrawPoint(gTheStars[i]->xCoord, 
-			gTheStars[i]->yCoord, gTheStars[i]->color);
+	if ( m_showingBonus ) {
+		return;
 	}
 
-	/* Draw the status frame */
-	DrawStatus(false);
-
-	/* Read in keyboard input for our ship */
-	HandleEvents(0);
-
-	/* Send Sync! signal to all players, and handle keyboard. */
+	/* -- Send Sync! signal to all players, and handle keyboard. */
 	if ( SyncNetwork() < 0 ) {
 		error("Game aborted!\n");
 		gGameOn = 0;
@@ -312,10 +248,11 @@ GamePanelDelegate::OnDraw()
 	OBJ_LOOP(i, gNumPlayers)
 		gPlayers[i]->HandleKeys();
 
-	if ( gPaused > 0 )
+	if ( gPaused ) {
 		return;
+	}
 
-	/* Play the boom sounds */
+	/* -- Play the boom sounds */
 	if ( --gNextBoom == 0 ) {
 		if ( gBoomPhase ) {
 			sound->PlaySound(gBoom1, 0);
@@ -327,7 +264,7 @@ GamePanelDelegate::OnDraw()
 		gNextBoom = gBoomDelay;
 	}
 
-	/* Do all hit detection */
+	/* -- Do all hit detection */
 	OBJ_LOOP(j, gNumPlayers) {
 		if ( ! gPlayers[j]->Alive() )
 			continue;
@@ -381,7 +318,7 @@ GamePanelDelegate::OnDraw()
 		}
 	}
 
-	/* Move all of the sprites */
+	/* -- Move all of the sprites */
 	OBJ_LOOP(i, gNumPlayers)
 		gPlayers[i]->Move(0);
 	OBJ_LOOP(i, gNumSprites) {
@@ -393,24 +330,38 @@ GamePanelDelegate::OnDraw()
 	if ( gFreezeTime )
 		--gFreezeTime;
 
-	/* Now Blit them all again */
+	DoHousekeeping();
+}
+
+void
+GamePanelDelegate::OnDraw()
+{
+	int i;
+
+	/* Draw the status frame */
+	DrawStatus(false);
+
+	if ( m_showingBonus ) {
+		return;
+	}
+
+	/* -- Draw the star field */
+	for ( i=0; i<MAX_STARS; ++i ) {
+		screen->DrawPoint(gTheStars[i]->xCoord, 
+			gTheStars[i]->yCoord, gTheStars[i]->color);
+	}
+
+	/* -- Blit all the sprites */
 	OBJ_LOOP(i, gNumSprites)
 		gSprites[i]->BlitSprite();
 	OBJ_LOOP(i, gNumPlayers)
 		gPlayers[i]->BlitSprite();
 
-	/* Make sure someone is still playing... */
-	for ( i=0, PlayersLeft=0; i < gNumPlayers; ++i ) {
-		if ( gPlayers[i]->Kicking() )
-			++PlayersLeft;
-	}
+	/* -- Show the player dots */
 	if ( gNumPlayers > 1 ) {
 		OBJ_LOOP(i, gNumPlayers)
 			gPlayers[i]->ShowDot();
 	}
-	if ( !PlayersLeft ) {
-		gGameOn = 0;
-	}
 }
 
 /* ----------------------------------------------------------------- */
@@ -546,6 +497,252 @@ GamePanelDelegate::DrawStatus(Bool first)
 
 }	/* -- DrawStatus */
 
+/* ----------------------------------------------------------------- */
+/* -- Do some housekeeping! */
+
+void
+GamePanelDelegate::DoHousekeeping()
+{
+	int i;
+
+#ifdef MOVIE_SUPPORT
+	if ( gMovie )
+		screen->ScreenDump("MovieFrame", &gMovieRect);
+#endif
+	/* -- Maybe throw a multiplier up on the screen */
+	if (gMultiplierShown && (--gMultiplierShown == 0) )
+		MakeMultiplier();
+	
+	/* -- Maybe throw a prize(!) up on the screen */
+	if (gPrizeShown && (--gPrizeShown == 0) )
+		MakePrize();
+	
+	/* -- Maybe throw a bonus up on the screen */
+	if (gBonusShown && (--gBonusShown == 0) )
+		MakeBonus();
+
+	/* -- Maybe make a nasty enemy fighter? */
+	if (gWhenEnemy && (--gWhenEnemy == 0) )
+		MakeEnemy();
+
+	/* -- Maybe create a transcenfugal vortex */
+	if (gWhenGrav && (--gWhenGrav == 0) )
+		MakeGravity();
+	
+	/* -- Maybe create a recified space vehicle */
+	if (gWhenDamaged && (--gWhenDamaged == 0) )
+		MakeDamagedShip();
+	
+	/* -- Maybe create a autonominous tracking device */
+	if (gWhenHoming && (--gWhenHoming == 0) )
+		MakeHoming();
+	
+	/* -- Maybe make a supercranial destruction thang */
+	if (gWhenNova && (--gWhenNova == 0) )
+		MakeNova();
+
+	/* -- Maybe create a new star ? */
+	if ( --gLastStar == 0 ) {
+		gLastStar = STAR_DELAY;
+		SetStar(FastRandom(MAX_STARS));
+	}
+	
+	/* -- Time for the next wave? */
+	if (gNumRocks == 0) {
+		if ( gWhenDone == 0 )
+			gWhenDone = DEAD_DELAY;
+		else if ( --gWhenDone == 0 )
+			NextWave();
+	}
+
+	/* -- Make sure someone is still playing... */
+	bool PlayersLeft;
+	for ( i=0; i < gNumPlayers; ++i ) {
+		if ( gPlayers[i]->Kicking() ) {
+			PlayersLeft = true;
+			break;
+		}
+	}
+	if ( !PlayersLeft ) {
+		gGameOn = 0;
+	}
+
+}	/* -- DoHousekeeping */
+
+/* ----------------------------------------------------------------- */
+/* -- Do the bonus display */
+
+void
+GamePanelDelegate::DoBonus()
+{
+	UIPanel *panel;
+	UIElement *image;
+	UIElementLabel *label;
+	UIElementLabel *bonus;
+	UIElementLabel *score;
+	int i;
+	char numbuf[128];
+
+	/* -- Now do the bonus */
+	sound->HaltSound();
+
+	panel = ui->GetPanel(PANEL_BONUS);
+	if (!panel) {
+		return;
+	}
+	panel->HideAll();
+
+	/* -- Set the wave completed message */
+	label = panel->GetElement<UIElementLabel>("wave");
+	if (label) {
+		sprintf(numbuf, "Wave %d completed.", gWave);
+		label->SetText(numbuf);
+		label->Show();
+	}
+	label = panel->GetElement<UIElementLabel>("bonus_label");
+	if (label) {
+		label->Show();
+	}
+	label = panel->GetElement<UIElementLabel>("score_label");
+	if (label) {
+		label->Show();
+	}
+		
+	m_showingBonus = true;
+
+	/* Fade out */
+	screen->FadeOut();
+
+	ui->ShowPanel(PANEL_BONUS);
+	ui->Draw();
+
+	/* Fade in */
+	screen->FadeIn();
+	while ( sound->Playing() )
+		Delay(SOUND_DELAY);
+
+	/* -- Count the score down */
+
+	bonus = panel->GetElement<UIElementLabel>("bonus");
+	score = panel->GetElement<UIElementLabel>("score");
+	OBJ_LOOP(i, gNumPlayers) {
+		if ( i != gOurPlayer ) {
+			gPlayers[i]->MultBonus();
+			continue;
+		}
+
+		if (OurShip->GetBonusMult() != 1) {
+			if (bonus) {
+				sprintf(numbuf, "%-5.1d", OurShip->GetBonus());
+				bonus->SetText(numbuf);
+				bonus->Show();
+			}
+			bonus = panel->GetElement<UIElementLabel>("multiplied_bonus");
+
+			OurShip->MultBonus();
+			Delay(SOUND_DELAY);
+			sound->PlaySound(gMultiplier, 5);
+
+			sprintf(numbuf, "multiplier%d", OurShip->GetBonusMult());
+			image = panel->GetElement<UIElement>(numbuf);
+			if (image) {
+				image->Show();
+			}
+
+			ui->Draw();
+			Delay(60);
+		}
+	}
+	Delay(SOUND_DELAY);
+	sound->PlaySound(gFunk, 5);
+
+	if (bonus) {
+		sprintf(numbuf, "%-5.1d", OurShip->GetBonus());
+		bonus->SetText(numbuf);
+		bonus->Show();
+	}
+	if (score) {
+		sprintf(numbuf, "%-5.1d", OurShip->GetScore());
+		score->SetText(numbuf);
+		score->Show();
+	}
+	ui->Draw();
+	Delay(60);
+
+	/* -- Praise them or taunt them as the case may be */
+	if (OurShip->GetBonus() == 0) {
+		Delay(SOUND_DELAY);
+		sound->PlaySound(gNoBonus, 5);
+	}
+	if (OurShip->GetBonus() > 10000) {
+		Delay(SOUND_DELAY);
+		sound->PlaySound(gPrettyGood, 5);
+	}
+	while ( sound->Playing() )
+		Delay(SOUND_DELAY);
+
+	/* -- Count the score down */
+	OBJ_LOOP(i, gNumPlayers) {
+		if ( i != gOurPlayer ) {
+			while ( gPlayers[i]->GetBonus() > 500 ) {
+				gPlayers[i]->IncrScore(500);
+				gPlayers[i]->IncrBonus(-500);
+			}
+			continue;
+		}
+
+		while (OurShip->GetBonus() > 0) {
+			while ( sound->Playing() )
+				Delay(SOUND_DELAY);
+
+			sound->PlaySound(gBonk, 5);
+			if ( OurShip->GetBonus() >= 500 ) {
+				OurShip->IncrScore(500);
+				OurShip->IncrBonus(-500);
+			} else {
+				OurShip->IncrScore(OurShip->GetBonus());
+				OurShip->IncrBonus(-OurShip->GetBonus());
+			}
+	
+			if (bonus) {
+				sprintf(numbuf, "%-5.1d", OurShip->GetBonus());
+				bonus->SetText(numbuf);
+			}
+			if (score) {
+				sprintf(numbuf, "%-5.1d", OurShip->GetScore());
+				score->SetText(numbuf);
+			}
+
+			ui->Draw();
+		}
+	}
+	while ( sound->Playing() )
+		Delay(SOUND_DELAY);
+	HandleEvents(10);
+
+	/* -- Draw the "next wave" message */
+	label = panel->GetElement<UIElementLabel>("next");
+	if (label) {
+		sprintf(numbuf, "Prepare for Wave %d...", gWave+1);
+		label->SetText(numbuf);
+		label->Show();
+	}
+	ui->Draw();
+	HandleEvents(100);
+
+	ui->HidePanel(PANEL_BONUS);
+
+	m_showingBonus = false;
+
+	screen->FadeOut();
+	ui->Draw();
+	screen->FadeIn();
+
+	/* Need to clear one more time since we're about to draw */
+	/* FIXME: This doesn't work */
+	screen->Clear();
+
+}	/* -- DoBonus */
 
 /* ----------------------------------------------------------------- */
 /* -- Start the next wave! */
@@ -624,9 +821,6 @@ GamePanelDelegate::NextWave()
 
 	NewRoids = FastRandom(temp) + (gWave / 5) + 3;
 
-	/* -- Black the screen out and draw the wave */
-	screen->Clear();
-
 	/* -- Kill any existing sprites */
 	while (gNumSprites > 0)
 		delete gSprites[gNumSprites-1];
@@ -642,7 +836,6 @@ GamePanelDelegate::NextWave()
 	for ( index=gNumPlayers; index--; )
 		gPlayers[index]->NewWave();
 	DrawStatus(true);
-	screen->Update();
 
 	/* -- Create some asteroids */
 	for (index = 0; index < NewRoids; index++) {
@@ -660,7 +853,6 @@ GamePanelDelegate::NextWave()
 			MakeLargeRock(x, y);
 	}
 
-	screen->Fade();
 }	/* -- NextWave */
 
 /* ----------------------------------------------------------------- */
@@ -792,7 +984,6 @@ static void DoGameOver(void)
 							sound->PlaySound(gExplosionSound, 5);
 							--chars_in_handle;
 							handle[chars_in_handle] = '\0';
-							label->SetText(handle);
 						}
 						break;
 					default:
@@ -806,11 +997,13 @@ static void DoGameOver(void)
 						sound->PlaySound(gShotSound, 5);
 						handle[chars_in_handle++] = key;
 						handle[chars_in_handle] = '\0';
-						label->SetText(handle);
 					} else
 						sound->PlaySound(gBonk, 5);
 				}
 			}
+			if (label ) {
+				label->SetText(handle);
+			}
 			ui->Draw();
 		}
 		SDL_StopTextInput();
@@ -838,145 +1031,3 @@ static void DoGameOver(void)
 }	/* -- DoGameOver */
 
 
-/* ----------------------------------------------------------------- */
-/* -- Do the bonus display */
-
-static void DoBonus(void)
-{
-	int i, x, sw, xs, xt;
-	char numbuf[128];
-
-	//DrawStatus(false);
-	screen->Update();
-
-	/* -- Now do the bonus */
-	sound->HaltSound();
-	sound->PlaySound(gRiff, 6);
-
-	/* Fade out */
-	screen->Fade();
-
-	/* -- Clear the screen */
-	screen->Clear();
-	
-
-	/* -- Draw the wave completed message */
-	sprintf(numbuf, "Wave %d completed.", gWave);
-	sw = fontserv->TextWidth(numbuf, geneva, STYLE_BOLD);
-	x = (SCREEN_WIDTH - sw) / 2;
-	DrawText(x,  150, numbuf, geneva, STYLE_BOLD, 0xFF, 0xFF, 0x00);
-
-	/* -- Draw the bonus */
-	sw = fontserv->TextWidth("Bonus Score:     ", geneva, STYLE_BOLD);
-	x = ((SCREEN_WIDTH - sw) / 2) - 20;
-	DrawText(x, 200, "Bonus Score:     ", geneva, STYLE_BOLD,
-						30000>>8, 30000>>8, 0xFF);
-	xt = x+sw;
-
-	/* -- Draw the score */
-	sw = fontserv->TextWidth("Score:     ", geneva, STYLE_BOLD);
-	x = ((SCREEN_WIDTH - sw) / 2) - 3;
-	DrawText(x, 220, "Score:     ", geneva, STYLE_BOLD,
-						30000>>8, 30000>>8, 0xFF);
-	xs = x+sw;
-	screen->Update();
-
-	/* Fade in */
-	screen->Fade();
-	while ( sound->Playing() )
-		Delay(SOUND_DELAY);
-
-	/* -- Count the score down */
-	x = xs;
-
-	OBJ_LOOP(i, gNumPlayers) {
-		if ( i != gOurPlayer ) {
-			gPlayers[i]->MultBonus();
-			continue;
-		}
-
-		if (OurShip->GetBonusMult() != 1) {
-			SDL_Texture *sprite;
-
-			sprintf(numbuf, "%-5.1d", OurShip->GetBonus());
-			DrawText(x, 200, numbuf, geneva, STYLE_BOLD,
-							0xFF, 0xFF, 0xFF);
-			x += 75;
-			OurShip->MultBonus();
-			Delay(SOUND_DELAY);
-			sound->PlaySound(gMultiplier, 5);
-			sprite = gMult[OurShip->GetBonusMult()-2]->sprite[0];
-			screen->QueueBlit(xs+34, 180, sprite);
-			screen->Update();
-			Delay(60);
-		}
-	}
-	Delay(SOUND_DELAY);
-	sound->PlaySound(gFunk, 5);
-
-	sprintf(numbuf, "%-5.1d", OurShip->GetBonus());
-	DrawText(x, 200, numbuf, geneva, STYLE_BOLD, 0xFF, 0xFF, 0xFF);
-	sprintf(numbuf, "%-5.1d", OurShip->GetScore());
-	DrawText(xt, 220, numbuf, geneva, STYLE_BOLD, 0xFF, 0xFF, 0xFF);
-	screen->Update();
-	Delay(60);
-
-	/* -- Praise them or taunt them as the case may be */
-	if (OurShip->GetBonus() == 0) {
-		Delay(SOUND_DELAY);
-		sound->PlaySound(gNoBonus, 5);
-	}
-	if (OurShip->GetBonus() > 10000) {
-		Delay(SOUND_DELAY);
-		sound->PlaySound(gPrettyGood, 5);
-	}
-	while ( sound->Playing() )
-		Delay(SOUND_DELAY);
-
-	/* -- Count the score down */
-	OBJ_LOOP(i, gNumPlayers) {
-		if ( i != gOurPlayer ) {
-			while ( gPlayers[i]->GetBonus() > 500 ) {
-				gPlayers[i]->IncrScore(500);
-				gPlayers[i]->IncrBonus(-500);
-			}
-			continue;
-		}
-
-		while (OurShip->GetBonus() > 0) {
-			while ( sound->Playing() )
-				Delay(SOUND_DELAY);
-
-			sound->PlaySound(gBonk, 5);
-			if ( OurShip->GetBonus() >= 500 ) {
-				OurShip->IncrScore(500);
-				OurShip->IncrBonus(-500);
-			} else {
-				OurShip->IncrScore(OurShip->GetBonus());
-				OurShip->IncrBonus(-OurShip->GetBonus());
-			}
-	
-			sprintf(numbuf, "%-5.1d", OurShip->GetBonus());
-			DrawText(x, 200, numbuf, geneva, STYLE_BOLD, 0xFF, 0xFF, 0xFF);
-			sprintf(numbuf, "%-5.1d", OurShip->GetScore());
-			DrawText(xt, 220, numbuf, geneva, STYLE_BOLD, 0xFF, 0xFF, 0xFF);
-
-			//DrawStatus(false);
-			screen->Update();
-		}
-	}
-	while ( sound->Playing() )
-		Delay(SOUND_DELAY);
-	HandleEvents(10);
-
-	/* -- Draw the "next wave" message */
-	sprintf(numbuf, "Prepare for Wave %d...", gWave+1);
-	sw = fontserv->TextWidth(numbuf, geneva, STYLE_BOLD);
-	x = (SCREEN_WIDTH - sw)/2;
-	DrawText(x, 259, numbuf, geneva, STYLE_BOLD, 0xFF, 0xFF, 0x00);
-	screen->Update();
-	HandleEvents(100);
-
-	screen->Fade();
-}	/* -- DoBonus */
-
diff --git a/netlogic/game.h b/netlogic/game.h
index 208ec8f6..387c9035 100644
--- a/netlogic/game.h
+++ b/netlogic/game.h
@@ -19,9 +19,13 @@ class GamePanelDelegate : public UIPanelDelegate
 
 protected:
 	void DrawStatus(Bool first);
+	void DoHousekeeping();
+	void DoBonus();
 	void NextWave();
 
 protected:
+	bool m_showingBonus;
+
 	UIElementLabel *m_score;
 	UIElement *m_shield;
 	UIElementLabel *m_wave;
diff --git a/netlogic/player.cpp b/netlogic/player.cpp
index 6a846b6d..5b6d45fd 100644
--- a/netlogic/player.cpp
+++ b/netlogic/player.cpp
@@ -569,13 +569,13 @@ Player::BlitSprite(void)
 		screen->QueueBlit(X, Y, gPlayerShot);
 	}
 	/* Draw the shield, if necessary */
-	if ( AutoShield || (ShieldOn && (ShieldLevel > 0)) ) {
+	if ( ! gPaused && (AutoShield || (ShieldOn && (ShieldLevel > 0))) ) {
 		screen->QueueBlit(x>>SPRITE_PRECISION, y>>SPRITE_PRECISION,
 						gShieldBlit->sprite[Sphase]);
 		Sphase = !Sphase;
 	}
 	/* Draw the thrust, if necessary */
-	if ( Thrusting && ! NoThrust ) {
+	if ( ! gPaused && Thrusting && ! NoThrust ) {
 		int thrust_x, thrust_y;
 		thrust_x = x + gThrustOrigins[phase].h;
 		thrust_y = y + gThrustOrigins[phase].v;
diff --git a/screenlib/SDL_FrameBuf.cpp b/screenlib/SDL_FrameBuf.cpp
index 9e6f1b05..a190e6c9 100644
--- a/screenlib/SDL_FrameBuf.cpp
+++ b/screenlib/SDL_FrameBuf.cpp
@@ -131,7 +131,7 @@ void
 FrameBuf:: Fade(void)
 {
 // Temporary for development
-return;
+//return;
 	const int max = 32;
 	Uint16 ramp[256];   
 
diff --git a/screenlib/UIManager.cpp b/screenlib/UIManager.cpp
index d5b8a62d..500105d4 100644
--- a/screenlib/UIManager.cpp
+++ b/screenlib/UIManager.cpp
@@ -224,10 +224,6 @@ UIManager::Draw(bool fullUpdate)
 		UIPanel *panel = m_visible[i];
 
 		panel->Draw();
-
-		if (panel->IsFullscreen()) {
-			break;
-		}
 	}
 	if (fullUpdate) {
 		m_screen->Update();