summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--build.zig1
-rw-r--r--src/GameDraw.cpp466
-rw-r--r--src/GameInitDispose.cpp7
-rw-r--r--src/Text.cpp68
-rw-r--r--src/Text.h23
-rw-r--r--src/misc.zig77
6 files changed, 204 insertions, 438 deletions
diff --git a/build.zig b/build.zig
index 5093398..85f9c22 100644
--- a/build.zig
+++ b/build.zig
@@ -48,7 +48,6 @@ pub fn build(b: *Builder) void {
     exe.addCSourceFile("src/Quaternions.cpp", &cxxflags);
     exe.addCSourceFile("src/Skeleton.cpp", &cxxflags);
     exe.addCSourceFile("src/Sprites.cpp", &cxxflags);
-    exe.addCSourceFile("src/Text.cpp", &cxxflags);
 
     exe.addPackagePath("gfz", "lib/gfz/src/gfz.zig");
     @import("lib/gfz/build.zig").link(exe);
diff --git a/src/GameDraw.cpp b/src/GameDraw.cpp
index f68ff54..1094dc7 100644
--- a/src/GameDraw.cpp
+++ b/src/GameDraw.cpp
@@ -21,6 +21,8 @@
 
 #include <stdio.h>
 
+#include <GL/glu.h>
+
 #include "Game.h"
 #include "misc.h"
 
@@ -58,15 +60,10 @@ void Game::DrawGLScene(void)
 		//Setup fast sine fluctuation
 		sinefluct=sin(sinefluctprog);
 		sinefluctprog+=multiplier*1.5;
-
 		glLoadIdentity();
-
 		glClearColor(0,0,0,1);
-
 		glDisable(GL_CLIP_PLANE0);
-
 		glDisable(GL_FOG);
-
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 		//"Black Shades"
@@ -76,444 +73,241 @@ void Game::DrawGLScene(void)
 		glDisable(GL_LIGHTING);
 		glBlendFunc(GL_SRC_ALPHA,GL_ONE);
 		glDepthMask(0);
-
 		glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-
 		glPushMatrix();										// Store The Projection Matrix
-
 		glLoadIdentity();									// Reset The Projection Matrix
-
 		glOrtho(0,640,0,480,-100,100);						// Set Up An Ortho Screen
-
 		glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
 
 		//Draw smoke
-
 		glPushMatrix();										// Store The Modelview Matrix
-
 			glLoadIdentity();								// Reset The Modelview Matrix
-
 			glTranslatef(60+sinefluct*40,335-sinefluct*9,0);
-
 			glScalef(500-sinefluct*80,70+sinefluct*18,1);
-
 			glTranslatef(.5,.5,0);
-
 			glScalef(.5,.5,1);
-
 			glRotatef(sinefluctprog*50,0,0,1);
-
 			glEnable(GL_TEXTURE_2D);
-
 			glBindTexture(GL_TEXTURE_2D,  sprites.smoketextureptr);
-
 			glEnable(GL_BLEND);
-
 			glColor4f(1,1,1,.4+sinefluct/8);
-
 			glBegin(GL_TRIANGLES);
-
 				glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
-
 				glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 			glEnd();
-
 		glPopMatrix();
-
 		glPushMatrix();										// Store The Modelview Matrix
-
 			glLoadIdentity();								// Reset The Modelview Matrix
-
 			glTranslatef(60+sinefluct*40,335-sinefluct*9,0);
-
 			glScalef(530-sinefluct*80,50+sinefluct*18,1);
-
 			glTranslatef(.5,.5,0);
-
 			glScalef(.5,.5,1);
-
 			glRotatef(-sinefluctprog*50,0,0,1);
-
 			glEnable(GL_TEXTURE_2D);
-
 			glBindTexture(GL_TEXTURE_2D,  sprites.smoketextureptr);
-
 			glEnable(GL_BLEND);
-
 			glColor4f(1,1,1,.4-sinefluct/8);
-
 			glBegin(GL_TRIANGLES);
-
 				glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
-
 				glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 			glEnd();
-
 		glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-
 		glPopMatrix();										// Restore The Old Projection Matrix
-
 		glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
-
 		glPopMatrix();										// Restore The Old Projection Matrix
-
 		glDepthMask(1);
 
-		//Text
-
+		// Text
+		static char str[256];
 		glEnable(GL_TEXTURE_2D);
+		glColor4f(0, 0, 0, 1);
+		glPrint(&this->text, 100, 175, "Black Shades", 1, 2, 640, 480);
 
-		glColor4f(0,0,0,1);
-
-		static char string[256]="";
-
-		sprintf (string, "Black Shades");
-
-		text.glPrint(100,175,string,1,2,640,480);
-
-		//"New Game"
-
+		// "New Game"
 		glDisable(GL_TEXTURE_2D);
-
-		glDisable(GL_DEPTH_TEST);							// Disables Depth Testing
-
+		glDisable(GL_DEPTH_TEST);
 		glDisable(GL_CULL_FACE);
-
 		glDisable(GL_LIGHTING);
-
 		glBlendFunc(GL_SRC_ALPHA,GL_ONE);
-
 		glDepthMask(0);
-
-		glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-
-		glPushMatrix();										// Store The Projection Matrix
-
-		glLoadIdentity();									// Reset The Projection Matrix
-
-		glOrtho(0,640,0,480,-100,100);						// Set Up An Ortho Screen
-
-		glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
+		glMatrixMode(GL_PROJECTION);
+		glPushMatrix();
+		glLoadIdentity();
+		glOrtho(0, 640, 0, 480, -100, 100);
+		glMatrixMode(GL_MODELVIEW);
 
 		//Draw smoke
-
-		glPushMatrix();										// Store The Modelview Matrix
-
-			glLoadIdentity();								// Reset The Modelview Matrix
-
+		glPushMatrix();
+			glLoadIdentity();
 			glTranslatef(120-sinefluct*40,235+sinefluct*9,0);
-
 			glScalef(440+sinefluct*80,70-sinefluct*18,1);
-
 			glTranslatef(.5,.5,0);
-
 			glScalef(.5,.5,1);
-
 			glRotatef(sinefluctprog*50,0,0,1);
-
 			glEnable(GL_TEXTURE_2D);
-
 			if(mouseoverbutton!=1)glBindTexture(GL_TEXTURE_2D,  sprites.smoketextureptr);
-
 			if(mouseoverbutton==1)glBindTexture(GL_TEXTURE_2D,  flaretextureptr);
-
 			glEnable(GL_BLEND);
-
 			glColor4f(1,0,0,.5+sinefluct/6);
-
 			glBegin(GL_TRIANGLES);
-
 				glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
-
 				glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 			glEnd();
-
 		glPopMatrix();
-
 		glPushMatrix();										// Store The Modelview Matrix
-
 			glLoadIdentity();								// Reset The Modelview Matrix
-
 			glTranslatef(120-sinefluct*40,235+sinefluct*9,0);
-
 			glScalef(460+sinefluct*80,50-sinefluct*18,1);
-
 			glTranslatef(.5,.5,0);
-
 			glScalef(.5,.5,1);
-
 			glRotatef(-sinefluctprog*50,0,0,1);
-
 			glEnable(GL_TEXTURE_2D);
-
 			if(mouseoverbutton!=1)glBindTexture(GL_TEXTURE_2D,  sprites.smoketextureptr);
-
 			if(mouseoverbutton==1)glBindTexture(GL_TEXTURE_2D,  flaretextureptr);
-
 			glEnable(GL_BLEND);
-
 			glColor4f(1,0,0,.5-sinefluct/6);
-
 			glBegin(GL_TRIANGLES);
-
 				glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
-
 				glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 			glEnd();
-
 		glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-
 		glPopMatrix();										// Restore The Old Projection Matrix
-
 		glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
-
 		glPopMatrix();										// Restore The Old Projection Matrix
-
 		glDepthMask(1);
 
-		//Text
-
+		// Text
 		glEnable(GL_TEXTURE_2D);
-
 		glColor4f(0,0,0,1);
+		glPrint(&this->text, 190 - this->gameinprogress * 10, 170,
+			this->gameinprogress ? "Resume Game" : "New Game",
+			1, 1.5, 640, 480);
 
-		if(!gameinprogress)sprintf (string, "New Game");
-
-		if(gameinprogress)sprintf (string, "Resume Game");
-
-		text.glPrint(190-gameinprogress*10,170,string,1,1.5,640,480);
-
-		//"Quit"
-
+		// "Quit"
 		glDisable(GL_TEXTURE_2D);
-
 		glDisable(GL_DEPTH_TEST);							// Disables Depth Testing
-
 		glDisable(GL_CULL_FACE);
-
 		glDisable(GL_LIGHTING);
-
 		glBlendFunc(GL_SRC_ALPHA,GL_ONE);
-
 		glDepthMask(0);
-
 		glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-
 		glPushMatrix();										// Store The Projection Matrix
-
 		glLoadIdentity();									// Reset The Projection Matrix
-
 		glOrtho(0,640,0,480,-100,100);						// Set Up An Ortho Screen
-
 		glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
 
-		//Draw smoke
-
+		// Draw smoke
 		glPushMatrix();										// Store The Modelview Matrix
-
 			glLoadIdentity();								// Reset The Modelview Matrix
-
 			glTranslatef(120-sinefluct*40,112+sinefluct*9,0);
-
 			glScalef(440+sinefluct*80,70-sinefluct*18,1);
-
 			glTranslatef(.5,.5,0);
-
 			glScalef(.5,.5,1);
-
 			glRotatef(sinefluctprog*50,0,0,1);
-
 			glEnable(GL_TEXTURE_2D);
 
 			if(mouseoverbutton!=2)glBindTexture(GL_TEXTURE_2D,  sprites.smoketextureptr);
-
 			if(mouseoverbutton==2)glBindTexture(GL_TEXTURE_2D,  flaretextureptr);
 
 			glEnable(GL_BLEND);
-
 			glColor4f(1,0,0,.5+sinefluct/6);
-
 			glBegin(GL_TRIANGLES);
-
 				glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
-
 				glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 			glEnd();
-
 		glPopMatrix();
-
 		glPushMatrix();										// Store The Modelview Matrix
-
 			glLoadIdentity();								// Reset The Modelview Matrix
-
 			glTranslatef(120-sinefluct*40,112+sinefluct*9,0);
-
 			glScalef(460+sinefluct*80,50-sinefluct*18,1);
-
 			glTranslatef(.5,.5,0);
-
 			glScalef(.5,.5,1);
-
 			glRotatef(-sinefluctprog*50,0,0,1);
-
 			glEnable(GL_TEXTURE_2D);
-
 			if(mouseoverbutton!=2)glBindTexture(GL_TEXTURE_2D,  sprites.smoketextureptr);
-
 			if(mouseoverbutton==2)glBindTexture(GL_TEXTURE_2D,  flaretextureptr);
-
 			glEnable(GL_BLEND);
-
 			glColor4f(1,0,0,.5-sinefluct/6);
-
 			glBegin(GL_TRIANGLES);
-
 				glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
-
 				glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
-
 				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
-
 				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
-
 			glEnd();
-
 		glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-
 		glPopMatrix();										// Restore The Old Projection Matrix
-
 		glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
-
 		glPopMatrix();										// Restore The Old Projection Matrix
-
 		glDepthMask(1);
 
 		// Text
 		glEnable(GL_TEXTURE_2D);
-		glColor4f(0.0f ,0.0f ,0.0f ,1.0f);
-		sprintf(string, gameinprogress ? "End Game" : "Quit");
-		text.glPrint(197 - gameinprogress * 15, 87, string, 1, 1.5, 640, 480);
+		glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+		glPrint(&this->text, 197 - this->gameinprogress * 15, 87,
+			this->gameinprogress ? "End Game" : "Quit",
+			1, 1.5, 640, 480);
 
 		// High score
 		glColor4f(0.5f + sinefluct / 5.0f, 0.0f, 0.0f, 1.0f);
-		sprintf(string, "High Score: %d%s", highscore,
+		sprintf(str, "High Score: %d%s", highscore,
 			beatgame ? " *COMPLETED*" : "");
-		text.glPrint(0, 0, string, 1, 0.8, 640, 480);
+		glPrint(&this->text, 0, 0, str, 1, 0.8, 640, 480);
 
 		// Flash
-		if(flashamount>0){
-
+		if (flashamount > 0) {
 			if(flashamount>1)flashamount=1;
-
 			flashamount-=multiplier;
-
 			if(flashamount<0)flashamount=0;
-
 			glDisable(GL_DEPTH_TEST);							// Disables Depth Testing
-
 			glDisable(GL_CULL_FACE);
-
 			glDisable(GL_LIGHTING);
-
 			glDepthMask(0);
-
 			glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-
 			glPushMatrix();										// Store The Projection Matrix
-
 			glLoadIdentity();									// Reset The Projection Matrix
-
 			glOrtho(0,screenwidth,0,screenheight,-100,100);						// Set Up An Ortho Screen
-
 			glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
-
 			glPushMatrix();										// Store The Modelview Matrix
-
 			glLoadIdentity();								// Reset The Modelview Matrix
-
 			glScalef(screenwidth,screenheight,1);
-
 			glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
-
 			glEnable(GL_BLEND);
-
 			glColor4f(flashr,flashg,flashb,flashamount);
-
 			glBegin(GL_QUADS);
-
 				glVertex3f(0,		0, 	 0.0f);
-
 				glVertex3f(256,	0, 	 0.0f);
-
 				glVertex3f(256,	256, 0.0f);
-
 				glVertex3f(0, 	256, 0.0f);
-
 			glEnd();
-
 			glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-
 			glPopMatrix();										// Restore The Old Projection Matrix
-
 			glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
-
 			glPopMatrix();										// Restore The Old Projection Matrix
-
 			glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
-
 			glEnable(GL_CULL_FACE);
-
 			glDisable(GL_BLEND);
-
 			glDepthMask(1);
 		}
 	} else { // in-game
@@ -1294,129 +1088,95 @@ void Game::DrawGLScene(void)
 		}
 
 		//Text
-
 		glEnable(GL_TEXTURE_2D);
-
-		glColor4f(1,1,1,1);
-
-		static char string[256]="";
-
-		if(!debug){
-
-		if(person[0].whichgun==nogun)sprintf (string, "UNARMED");
-
-		if(person[0].whichgun==knife)sprintf (string, "KNIFE");
-
-		if(person[0].whichgun==assaultrifle)sprintf (string, "ASSAULT RIFLE");
-
-		if(person[0].whichgun==shotgun)sprintf (string, "SHOTGUN");
-
-		if(person[0].whichgun==sniperrifle)sprintf (string, "SNIPER RIFLE");
-
-		if(person[0].whichgun==grenade)sprintf (string, "HAND GRENADE");
-
-		if(person[0].whichgun==handgun1)sprintf (string, "MAGNUM");
-
-		if(person[0].whichgun==handgun2)sprintf (string, "HANDGUN");
-
-		text.glPrint(10,90,string,1,.8,640,480);
-
-		if(person[0].whichgun!=nogun&&person[0].whichgun!=knife&&person[0].whichgun!=grenade){
-
-			glColor4f(0,1,0,1);
-
-			sprintf (string, "Magazines");
-
-			text.glPrint(10,30,string,0,.8,640,480);
-
-			glColor4f(1,1,1,1);
-
-			sprintf (string, "0%d",(int)person[0].reloads[person[0].whichgun]);
-
-			text.glPrint(10,10,string,1,1,640,480);
-
-			if(person[0].ammo>=0){
-
+		glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+		static char str[256] = "";
+
+		if (!debug) {
+			char *s;
+			switch (person[0].whichgun) {
+			case nogun:
+				s = "UNARMED";
+				break;
+			case knife:
+				s = "KNIFE";
+				break;
+			case assaultrifle:
+				s = "ASSAULT RIFLE";
+				break;
+			case shotgun:
+				s = "SHOTGUN";
+				break;
+			case sniperrifle:
+				s = "SNIPER RIFLE";
+				break;
+			case grenade:
+				s = "HAND GRENADE";
+				break;
+			case handgun1:
+				s = "MAGNUM";
+				break;
+			case handgun2:
+				s = "HANDGUN";
+				break;
+			}
+			glPrint(&this->text, 10, 90, s, 1, 0.8, 640, 480);
+			if(person[0].whichgun!=nogun&&person[0].whichgun!=knife&&person[0].whichgun!=grenade){
 				glColor4f(0,1,0,1);
-
-				sprintf (string, "Ammo");
-
-				text.glPrint(10,65,string,0,.8,640,480);
-
+				glPrint(&this->text, 10, 30, "Magazines",
+					0, 0.8, 640, 480);
 				glColor4f(1,1,1,1);
-
-				if(person[0].ammo>=10)sprintf (string, "%d",(int)person[0].ammo);
-
-				if(person[0].ammo<10)sprintf (string, "0%d",(int)person[0].ammo);
-
-				text.glPrint(10,40,string,1,1,640,480);
-
+				sprintf (str, "0%d",(int)person[0].reloads[person[0].whichgun]);
+				glPrint(&this->text, 10,10,str,1,1,640,480);
+				if(person[0].ammo>=0){
+					glColor4f(0,1,0,1);
+					glPrint(&this->text, 10, 65, "Ammo",
+						0, 0.8, 640, 480);
+					glColor4f(1,1,1,1);
+					if(person[0].ammo>=10)sprintf (str, "%d",(int)person[0].ammo);
+					if(person[0].ammo<10)sprintf (str, "0%d",(int)person[0].ammo);
+					glPrint(&this->text, 10,40,str,1,1,640,480);
+				}
 			}
-
-		}
-
-		if(person[0].whichgun==grenade){
-
-			sprintf (string, "Grenades Left:  %d",(int)person[0].reloads[person[0].whichgun]+1);
-
-			text.glPrint(10,20,string,0,.8,640,480);
-
-		}
-
-		glColor4f(1,1,0,1);
-
-		sprintf (string, "Score");
-
-		text.glPrint(725,575,string,0,.8,640,480);
-
-		glColor4f(1,1,1,1);
-
-		sprintf (string, "%d", score);
-
-		text.glPrint(580,440,string,1,1,640,480);
-
-		glColor4f(1,1,0,1);
-
-		sprintf (string, "Time Remaining");
-
-		text.glPrint(50,575,string,0,.8,640,480);
-
-		glColor4f(1,1,1,1);
-
-		if((int)timeremaining%60>=10)sprintf (string, "%d:%d", (int)(timeremaining/60),(int)timeremaining%60);
-
-		if((int)timeremaining%60<10)sprintf (string, "%d:0%d", (int)(timeremaining/60),(int)timeremaining%60);
-
-		text.glPrint(72, 440, string, 1, 1, 640, 480);
-
-		}
-
-		if(debug){
-
-		sprintf (string, "FPS: %.0f", 1.0f / multiplier);
-
-		text.glPrint(10,30,string,0,.8,screenwidth,screenheight);
-
-		if(enemystate==0)sprintf (string, "Enemies are in random assassination mode.");
-
-		if(enemystate==1)sprintf (string, "Enemies are in passive mode.");
-
-		if(enemystate==2)sprintf (string, "Enemies are in DIE!!!! mode.");
-
-		text.glPrint(10,20,string,0,.8,screenwidth,screenheight);
-
-		sprintf (string, "You have pointlessly shot or beaten %d unarmed civilians.",civkills);
-
-		text.glPrint(10,60,string,0,.8,screenwidth,screenheight);
-
-		sprintf (string, "You have incapacitated %d assassins.",goodkills);
-
-		text.glPrint(10,70,string,0,.8,screenwidth,screenheight);
-
-		sprintf (string, "You have allowed %d successful murders.",badkills);
-
-		text.glPrint(10,80,string,0,.8,screenwidth,screenheight);
-
+			if(person[0].whichgun==grenade){
+				sprintf (str, "Grenades Left:  %d",(int)person[0].reloads[person[0].whichgun]+1);
+				glPrint(&this->text, 10,20,str,0,.8,640,480);
+			}
+			glColor4f(1,1,0,1);
+			glPrint(&this->text, 725, 575, "Score", 0, 0.8, 640, 480);
+			glColor4f(1,1,1,1);
+			sprintf(str, "%d", score);
+			glPrint(&this->text, 580,440,str,1,1,640,480);
+			glColor4f(1,1,0,1);
+			glPrint(&this->text, 50, 575, "Time Remaining",
+				0, 0.8, 640, 480);
+			glColor4f(1,1,1,1);
+			if((int)timeremaining%60>=10)sprintf (str, "%d:%d", (int)(timeremaining/60),(int)timeremaining%60);
+			if((int)timeremaining%60<10)sprintf (str, "%d:0%d", (int)(timeremaining/60),(int)timeremaining%60);
+			glPrint(&this->text, 72, 440, str, 1, 1, 640, 480);
+		} else {
+			sprintf(str, "FPS: %.0f", 1.0f / multiplier);
+			glPrint(&this->text, 10,30,str,0,.8,screenwidth,screenheight);
+			char *s;
+			switch (enemystate) {
+			case 0:
+				s = "Enemies are in random assassination mode.";
+				break;
+			case 1:
+				s = "Enemies are in passive mode.";
+				break;
+			case 2:
+				s = "Enemies are in DIE!!!! mode.";
+				break;
+			}
+			glPrint(&this->text, 10, 20, s, 0, 0.8,
+				screenwidth, screenheight);
+			sprintf(str, "You have pointlessly shot or beaten %d unarmed civilians.", civkills);
+			glPrint(&this->text, 10,60,str,0,.8,screenwidth,screenheight);
+			sprintf(str, "You have incapacitated %d assassins.", goodkills);
+			glPrint(&this->text, 10,70,str,0,.8,screenwidth,screenheight);
+			sprintf(str, "You have allowed %d successful murders.", badkills);
+			glPrint(&this->text, 10,80,str,0,.8,screenwidth,screenheight);
 		}
 	}
 }
diff --git a/src/GameInitDispose.cpp b/src/GameInitDispose.cpp
index d4319b5..d31829b 100644
--- a/src/GameInitDispose.cpp
+++ b/src/GameInitDispose.cpp
@@ -1018,8 +1018,8 @@ void initGl(Game* game)
 	glPolygonOffset(-8,0);
 	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 
-	game->text.FontTexture = loadTexture("font.qoi");
-	game->text.BuildFont();
+	game->text.texture = loadTexture("font.qoi");
+	buildFont(&game->text);
 	game->personspritetextureptr = loadTexture("sprites/person.qoi");
 	game->deadpersonspritetextureptr = loadTexture("sprites/person-dead.qoi");
 	game->scopetextureptr = loadTexture("scope.qoi");
@@ -1058,12 +1058,13 @@ struct Scores getScores(Game* game)
 void closeGame(Game* game)
 {
 	const GLuint textures[] {
+		game->text.texture,
 		game->personspritetextureptr,
 		game->deadpersonspritetextureptr,
 		game->scopetextureptr,
 		game->flaretextureptr,
 	};
-	glDeleteTextures(4, textures);
+	glDeleteTextures(5, textures);
 	alDeleteSources(33 + game->musictoggle * 4, gSourceID);
 	alDeleteBuffers(33 + game->musictoggle * 4, gSampleSet);
 }
diff --git a/src/Text.cpp b/src/Text.cpp
deleted file mode 100644
index afb6fe2..0000000
--- a/src/Text.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <string.h>
-
-#include "Text.h"
-
-void Text::BuildFont()								// Build Our Font Display List
-{
-	float	cx;											// Holds Our X Character Coord
-	float	cy;											// Holds Our Y Character Coord
-	int loop;
-
-	base=glGenLists(256);								// Creating 256 Display Lists
-	glBindTexture(GL_TEXTURE_2D, FontTexture);			// Select Our Font Texture
-	for (loop=0; loop<256; loop++)						// Loop Through All 256 Lists
-	{
-		cx=float(loop%16)/16.0f;						// X Position Of Current Character
-		cy=float(loop/16)/16.0f;						// Y Position Of Current Character
-
-		glNewList(base+loop,GL_COMPILE);				// Start Building A List
-			glBegin(GL_QUADS);							// Use A Quad For Each Character
-				glTexCoord2f(cx,1-cy-0.0625f+.001);			// Texture Coord (Bottom Left)
-				glVertex2i(0,0);						// Vertex Coord (Bottom Left)
-				glTexCoord2f(cx+0.0625f,1-cy-0.0625f+.001);	// Texture Coord (Bottom Right)
-				glVertex2i(16,0);						// Vertex Coord (Bottom Right)
-				glTexCoord2f(cx+0.0625f,1-cy-.001);			// Texture Coord (Top Right)
-				glVertex2i(16,16);						// Vertex Coord (Top Right)
-				glTexCoord2f(cx,1-cy-+.001);					// Texture Coord (Top Left)
-				glVertex2i(0,16);						// Vertex Coord (Top Left)
-			glEnd();									// Done Building Our Quad (Character)
-			glTranslated(10,0,0);						// Move To The Right Of The Character
-		glEndList();									// Done Building The Display List
-	}													// Loop Until All 256 Are Built
-}
-
-void Text::glPrint(GLint x, GLint y, char *string, int set, float size, float width, float height)	// Where The Printing Happens
-{
-	if (set>1)
-	{
-		set=1;
-	}
-	glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
-	glBindTexture(GL_TEXTURE_2D, FontTexture);			// Select Our Font Texture
-	glDisable(GL_DEPTH_TEST);							// Disables Depth Testing
-	glDisable(GL_LIGHTING);
-	glEnable(GL_BLEND);
-	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
-	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-	glPushMatrix();										// Store The Projection Matrix
-	glLoadIdentity();									// Reset The Projection Matrix
-	glOrtho(0,width,0,height,-100,100);						// Set Up An Ortho Screen
-	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
-	glPushMatrix();										// Store The Modelview Matrix
-	glLoadIdentity();
-	glScalef(size,size,1);									// Reset The Modelview Matrix
-	glTranslated(x,y,0);								// Position The Text (0,0 - Bottom Left)
-	glListBase(base-32+(128*set));						// Choose The Font Set (0 or 1)
-	glCallLists(strlen(string),GL_BYTE,string);			// Write The Text To The Screen
-	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
-	glPopMatrix();										// Restore The Old Projection Matrix
-	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
-	glPopMatrix();										// Restore The Old Projection Matrix
-	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
-	glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
-}
-
-Text::~Text()
-{
-	glDeleteTextures(1, &FontTexture);
-}
diff --git a/src/Text.h b/src/Text.h
index 6fa4e35..9fe45be 100644
--- a/src/Text.h
+++ b/src/Text.h
@@ -23,18 +23,19 @@
 #define BLACKSHADES_TEXT_H
 
 #include <GL/gl.h>
-#include <GL/glu.h>
 
-#include "Quaternions.h"
-
-class Text{
-public:
-	GLuint FontTexture;
+struct Text {
+	GLuint texture;
 	GLuint base;
-
-	void BuildFont();
-	void glPrint(GLint x, GLint y, char *string, int set,
-		float size, float width, float height);
-	~Text();
 };
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+	void buildFont(struct Text*);
+	void glPrint(struct Text*, GLdouble, GLdouble, const char*, int,
+		float, float, float);
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
 #endif // BLACKSHADES_TEXT_H
diff --git a/src/misc.zig b/src/misc.zig
index d6063eb..6f1d893 100644
--- a/src/misc.zig
+++ b/src/misc.zig
@@ -1,4 +1,5 @@
 // Miscellaneous functions
+// Copyright (C) 2002  David Rosen
 // Copyright (C) 2021-2023  Nguyễn Gia Phong
 //
 // This file is part of Black Shades.
@@ -27,6 +28,7 @@ const endsWith = std.mem.endsWith;
 const eql = std.mem.eql;
 const free = std.c.free;
 const join = std.fs.path.joinZ;
+const len = std.mem.len;
 const maxInt = std.math.maxInt;
 const parseFloat = std.fmt.parseFloat;
 const parseInt = std.fmt.parseInt;
@@ -375,6 +377,77 @@ pub fn saveScores(base_dir: []const u8, current: Scores) !void {
     try dir.writeFile("scores.ini", data);
 }
 
+const Text = struct {
+    texture: u32,
+    base: u32,
+};
+
+export fn buildFont(text: *Text) void {
+    text.base = c.glGenLists(256);
+    c.glBindTexture(c.GL_TEXTURE_2D, text.texture);
+    var i = @as(u16, 0);
+    while (i < 256) : (i += 1) {
+        // Character coords
+        const x = @intToFloat(f32, i % 16) / 16.0;
+        const y = @intToFloat(f32, i / 16) / 16.0;
+        c.glNewList(text.base + i, c.GL_COMPILE);
+        // Use A Quad For Each Character
+        c.glBegin(c.GL_QUADS);
+        // Bottom left
+        c.glTexCoord2f(x, 1 - y - 0.0625 + 0.001);
+        c.glVertex2i(0,0);
+        // Bottom right
+        c.glTexCoord2f(x + 0.0625, 1 - y - 0.0625 + 0.001);
+        c.glVertex2i(16, 0);
+        // Top right
+        c.glTexCoord2f(x + 0.0625, 1 - y - 0.001);
+        c.glVertex2i(16, 16);
+        // Top left
+        c.glTexCoord2f(x, 1 - y - 0.001);
+        c.glVertex2i(0, 16);
+        c.glEnd();
+        // Move to the right of the character
+        c.glTranslated(10, 0, 0);
+        c.glEndList();
+    }
+}
+
+export fn glPrint(text: *const Text, x: f64, y: f64, str: [*:0]const u8,
+                  set: bool, size: f32, width: f32, height: f32) void {
+    c.glTexEnvi(c.GL_TEXTURE_ENV, c.GL_TEXTURE_ENV_MODE, c.GL_MODULATE);
+    c.glBindTexture(c.GL_TEXTURE_2D, text.texture);
+    c.glDisable(c.GL_DEPTH_TEST);
+    c.glDisable(c.GL_LIGHTING);
+    c.glEnable(c.GL_BLEND);
+    c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
+    c.glMatrixMode(c.GL_PROJECTION);
+    c.glPushMatrix();
+    c.glLoadIdentity();
+    c.glOrtho(0, width, 0, height, -100, 100);
+    c.glMatrixMode(c.GL_MODELVIEW);
+    c.glPushMatrix();
+    c.glLoadIdentity();
+
+    c.glScalef(size, size, 1);
+    // Position the text (0,0 - bottom left)
+    c.glTranslated(x, y, 0);
+    // Choose the font set (0 or 1)
+    if (set)
+        c.glListBase(text.base + 128 - 32)
+    else
+        c.glListBase(text.base -% 32);
+    // Write to screen
+    c.glCallLists(@intCast(c_int, len(str)), c.GL_BYTE, str);
+
+    // Restore
+    c.glMatrixMode(c.GL_PROJECTION);
+    c.glPopMatrix();
+    c.glMatrixMode(c.GL_MODELVIEW);
+    c.glPopMatrix();
+    c.glEnable(c.GL_DEPTH_TEST);
+    c.glTexEnvi(c.GL_TEXTURE_ENV, c.GL_TEXTURE_ENV_MODE, c.GL_MODULATE);
+}
+
 /// OpenGL fog state.
 const Fog = extern struct {
     color: [4]f32,
@@ -394,7 +467,7 @@ export fn setFog(fog: *Fog, r: f32, g: f32, b: f32,
 }
 
 /// Set temporary fog effect.
-export fn tempFog(fog: *Fog, r: f32, g: f32, b: f32) void {
+export fn tempFog(fog: *const Fog, r: f32, g: f32, b: f32) void {
     const color = [4]f32{r, g, b, 1.0};
     c.glFogi(c.GL_FOG_MODE, c.GL_LINEAR);
     c.glFogfv(c.GL_FOG_COLOR, &color);
@@ -406,7 +479,7 @@ export fn tempFog(fog: *Fog, r: f32, g: f32, b: f32) void {
 }
 
 /// Reset fog effect.
-export fn resetFog(fog: *Fog) void {
+export fn resetFog(fog: *const Fog) void {
     c.glFogi(c.GL_FOG_MODE, c.GL_LINEAR);
     c.glFogfv(c.GL_FOG_COLOR, &fog.color);
     c.glFogf(c.GL_FOG_DENSITY, fog.density);