summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/Game.cc2
-rw-r--r--src/Game.h4
-rw-r--r--src/GameInitDispose.cpp1371
-rw-r--r--src/GameTick.cpp6
-rw-r--r--src/Skeleton.cpp6
-rw-r--r--src/Support.h2
6 files changed, 563 insertions, 828 deletions
diff --git a/src/Game.cc b/src/Game.cc
index 34e2222..e8d722c 100644
--- a/src/Game.cc
+++ b/src/Game.cc
@@ -23,6 +23,6 @@ void run()
 {
 	Game game {};
 	initGl(&game);
-	game.InitGame();
+	initGame(&game);
 	game.EventLoop();
 }
diff --git a/src/Game.h b/src/Game.h
index bc60a3c..79162ce 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -197,12 +197,12 @@ public:
 	void EventLoop();
 	void Tick();
 	void Splat(int k);
-	void InitGame();
 	~Game();
 };
 
 extern "C" {
 	void run();
-	int initGl(Game*);
+	void initGl(Game*);
+	void initGame(Game*);
 }
 #endif // BLACKSHADES_GAME_H
diff --git a/src/GameInitDispose.cpp b/src/GameInitDispose.cpp
index 35c6ba3..814eb99 100644
--- a/src/GameInitDispose.cpp
+++ b/src/GameInitDispose.cpp
@@ -233,6 +233,9 @@ void LoadSounds(bool musictoggle)
 
 void Game::LoadingScreen(float percent)
 {
+	if (initialized)
+		return;
+
 	glLoadIdentity();
 
 	//Clear to black
@@ -341,274 +344,257 @@ void LoadPersonSpriteTexture(char *fileName, GLuint *textureid)
 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 }
 
-void Game::InitGame()
+void initGame(Game* game)
 {
-	//Setup loading screen
-	float loadingscreenamount=0;
-	float loadingscreenamounttotal=200;
-	if(initialized)loadingscreenamounttotal=20;
-	if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+	// Setup loading screen
+	float loadingscreenamount = 0.0f;
+	game->LoadingScreen(loadingscreenamount);
 
 	//Set up rain and snow
 	precipitationhorz=60;
 	precipitationvert=40;
 	precipitationdensity=25;
 
-	//Bodyguard stats
-	person[0].playercoords=camera.position;
-	person[0].oldplayercoords=person[0].playercoords;
-	person[0].type=playertype;
-	person[0].existing=1;
-
-	for(int i=0;i<10;i++){
-		person[0].reloads[i]=0;
-	}
+	//Setup camera
+	camera.position = {block_spacing * (num_blocks + 1) / 2.0f,
+		30.0f, block_spacing * (num_blocks + 1) / 2.0f};
+	camera.oldposition = camera.position;
+	game->LoadingScreen(loadingscreenamount += 2.5f);
+
+	// Bodyguard stats
+	auto& bodyguard = game->person[0];
+	bodyguard.playercoords = camera.position;
+	bodyguard.oldplayercoords = bodyguard.playercoords;
+	bodyguard.type = playertype;
+	bodyguard.existing = 1;
+	bodyguard.speedmult = 1.3f;
+
+	for (int i = 0; i < 10; ++i)
+		bodyguard.reloads[i] = 0;
+
+	// Level setup
+	game->killedinnocent = 0; // haven't shot any civilians yet...
+
+	if (game->customlevels) {
+		game->nummissions = 1; // default level in case of load failure
+		game->type = randomshoot_type;
+		game->possiblegun[0] = handgun1;
+		game->possiblegun[1] = handgun2;
+		game->possiblegun[2] = shotgun;
+		game->numpossibleguns = 3;
+		game->evilprobability = 6;
+		bodyguard.whichgun = knife;
+		bodyguard.reloads[bodyguard.whichgun] = 6;
+		if (!game->gameinprogress)
+			game->score = 0;
+		game->timeremaining = 50;
+		game->difficulty= 0.8f;
 
-	//Level setup
-	killedinnocent=0; //Haven't shot any civilians yet...
-
-	if(customlevels){ //Load custom levels
-		nummissions=1; //Default level in case of load failure
-		type=randomshoot_type;
-		possiblegun[0]=handgun1;
-		possiblegun[1]=handgun2;
-		possiblegun[2]=shotgun;
-		numpossibleguns=3;
-		evilprobability=6;
-		person[0].whichgun=knife;
-		person[0].reloads[person[0].whichgun]=6;
-		if(!gameinprogress)score=0;
-		timeremaining=50;
-		difficulty=.8;
 		ifstream ipstream {"Data/customlevels.txt"};
-
 		if (ipstream) {
 			ipstream.ignore(256,'\n');//ignore descriptive text
-			ipstream >> nummissions;
-			for(int j = 0; j < mission + 1; j++) {
+			ipstream >> game->nummissions;
+			for (int j = 0; j <= game->mission; ++j) {
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
-				ipstream >> type;
+				ipstream >> game->type;
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
 				ipstream >> environment;
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
-				ipstream >> numpossibleguns;
+				ipstream >> game->numpossibleguns;
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
 
-				for (int i = 0 ;i < numpossibleguns; i++)
-					ipstream >> possiblegun[i];
+				for (int i = 0; i < game->numpossibleguns; ++i)
+					ipstream >> game->possiblegun[i];
 
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
-				ipstream >> evilprobability;
+				ipstream >> game->evilprobability;
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
-				ipstream >> person[0].whichgun;
+				ipstream >> bodyguard.whichgun;
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
-				ipstream >> person[0].reloads[person[0].whichgun];
+				ipstream >> bodyguard.reloads[bodyguard.whichgun];
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
-				ipstream >> timeremaining;
+				ipstream >> game->timeremaining;
 				ipstream.ignore(256,'\n');
 				ipstream.ignore(256,'\n');
-				ipstream >> difficulty;
+				ipstream >> game->difficulty;
 				ipstream.ignore(256,'\n');
 			}
 			ipstream.close();
 		} else {
-			customlevels=0;
+			game->customlevels = 0;
 		}
 	}
 
-	if(!customlevels){ //Setup hardcoded default levels
-
-	if(mission==0){
-		environment=sunny_environment;
-		type=randomshoot_type;
-		possiblegun[0]=handgun1;
-		possiblegun[1]=handgun2;
-		possiblegun[2]=shotgun;
-		numpossibleguns=3;
-		evilprobability=6;
-		person[0].whichgun=assaultrifle;
-		person[0].reloads[person[0].whichgun]=6;
-		if(!gameinprogress)score=0;
-		timeremaining=50;
-		difficulty=.6;
-	}
-
-	if(mission==1){
-		environment=snowy_environment;
-		type=randomshoot_type;
-		possiblegun[0]=knife;
-		possiblegun[1]=assaultrifle;
-		numpossibleguns=2;
-		evilprobability=5;
-		person[0].whichgun=handgun2;
-		person[0].reloads[person[0].whichgun]=3;
-		if(!gameinprogress)score=0;
-		timeremaining=40;
-		difficulty=.6;
-	}
-
-	if(mission==2){
-		environment=foggy_environment;
-		type=randomshoot_type;
-		possiblegun[0]=sniperrifle;
-		numpossibleguns=1;
-		evilprobability=5;
-		person[0].whichgun=sniperrifle;
-		person[0].reloads[person[0].whichgun]=4;
-		if(!gameinprogress)score=0;
-		timeremaining=50;
-		difficulty=0.9;
-	}
-
-	if(mission==3){
-		environment=firey_environment;
-		type=zombie_type;
-		numpossibleguns=0;
-		evilprobability=5;
-		person[0].whichgun=shotgun;
-		person[0].reloads[person[0].whichgun]=5;
-		if(!gameinprogress)score=0;
-		timeremaining=35;
-		difficulty=.7;
-	}
-
-	if(mission==4){
-		environment=snowy_environment;
-		type=randomshoot_type;
-		possiblegun[0]=sniperrifle;
-		possiblegun[1]=assaultrifle;
-		numpossibleguns=2;
-		evilprobability=5;
-		person[0].whichgun=grenade;
-		person[0].reloads[person[0].whichgun]=20;
-		if(!gameinprogress)score=0;
-		timeremaining=30;
-		difficulty=.5;
-	}
-
-	if(mission==5){
-		environment=rainy_environment;
-		type=randomshoot_type;
-		possiblegun[0]=handgun1;
-		possiblegun[1]=shotgun;
-		possiblegun[2]=assaultrifle;
-		numpossibleguns=3;
-		evilprobability=6;
-		person[0].whichgun=knife;
-		person[0].reloads[person[0].whichgun]=3;
-		if(!gameinprogress)score=0;
-		timeremaining=40;
-		difficulty=.8;
-	}
-
-	if(mission==6){
-		environment=night_environment;
-		type=randomshoot_type;
-		possiblegun[1]=handgun1;
-		possiblegun[2]=handgun2;
-		possiblegun[3]=shotgun;
-		numpossibleguns=3;
-		evilprobability=5;
-		person[0].whichgun=handgun1;
-		person[0].reloads[person[0].whichgun]=4;
-		if(!gameinprogress)score=0;
-		timeremaining=30;
-		difficulty=1;
-	}
-
-	if(mission==7){
-		environment=firey_environment;
-		type=zombie_type;
-		person[0].whichgun=assaultrifle;
-		person[0].reloads[person[0].whichgun]=5;
-		if(!gameinprogress)score=0;
-		timeremaining=30;
-		difficulty=1;
-	}
-
-	if(mission==8){
-		environment=rainy_environment;
-		type=randomshoot_type;
-		possiblegun[0]=handgun1;
-		possiblegun[1]=handgun2;
-		possiblegun[2]=shotgun;
-		possiblegun[3]=sniperrifle;
-		possiblegun[4]=assaultrifle;
-		numpossibleguns=5;
-		evilprobability=5;
-		person[0].whichgun=nogun;
-		person[0].reloads[person[0].whichgun]=3;
-		if(!gameinprogress)score=0;
-		timeremaining=40;
-		difficulty=.8;
-	}
-
-	if(mission==9){
-		environment=snowy_environment;
-		type=randomshoot_type;
-		possiblegun[0]=knife;
-		possiblegun[1]=handgun1;
-		possiblegun[2]=handgun2;
-		possiblegun[3]=shotgun;
-		possiblegun[4]=sniperrifle;
-		possiblegun[5]=assaultrifle;
-		numpossibleguns=6;
-		evilprobability=4;
-		person[0].whichgun=handgun1;
-		person[0].reloads[person[0].whichgun]=3;
-		if(!gameinprogress)score=0;
-		timeremaining=90;
-		difficulty=1;
-	}
-
-	if(mission==10){
-		environment=night_environment;
-		type=randomshoot_type;
-		possiblegun[0]=sniperrifle;
-		numpossibleguns=1;
-		evilprobability=5;
-		person[0].whichgun=sniperrifle;
-		person[0].reloads[person[0].whichgun]=4;
-		if(!gameinprogress)score=0;
-		timeremaining=30;
-		difficulty=1.3;
-	}
-
-	if(mission==11){
-		environment=sunny_environment;
-		type=randomshoot_type;
-		possiblegun[0]=knife;
-		possiblegun[1]=sniperrifle;
-		numpossibleguns=2;
-		evilprobability=4;
-		person[0].whichgun=knife;
-		if(!gameinprogress)score=0;
-		timeremaining=30;
-		difficulty=1.5;
-	}
-
-	if(mission==12){
-		environment=firey_environment;
-		type=zombie_type;
-		possiblegun[0]=knife;
-		possiblegun[1]=sniperrifle;
-		person[0].whichgun=handgun2;
-		person[0].reloads[person[0].whichgun]=10;
-		if(!gameinprogress)score=0;
-		timeremaining=60;
-		difficulty=1.5;
-	}
-
-	nummissions=13;
-
+	if (!game->customlevels) {
+		game->nummissions = 13;
+		if (!game->gameinprogress)
+			game->score = 0;
+
+		switch (game->mission) {
+		case 0:
+			environment = sunny_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = handgun1;
+			game->possiblegun[1] = handgun2;
+			game->possiblegun[2] = shotgun;
+			game->numpossibleguns = 3;
+			game->evilprobability = 6;
+			bodyguard.whichgun = assaultrifle;
+			bodyguard.reloads[bodyguard.whichgun] = 6;
+			game->timeremaining = 50;
+			game->difficulty = 0.6f;
+			break;
+		case 1:
+			environment = snowy_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = knife;
+			game->possiblegun[1] = assaultrifle;
+			game->numpossibleguns = 2;
+			game->evilprobability = 5;
+			bodyguard.whichgun = handgun2;
+			bodyguard.reloads[bodyguard.whichgun] = 3;
+			game->timeremaining = 40;
+			game->difficulty = 0.6f;
+			break;
+		case 2:
+			environment = foggy_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = sniperrifle;
+			game->numpossibleguns = 1;
+			game->evilprobability = 5;
+			bodyguard.whichgun = sniperrifle;
+			bodyguard.reloads[bodyguard.whichgun] = 4;
+			game->timeremaining = 50;
+			game->difficulty = 0.9f;
+			break;
+		case 3:
+			environment = firey_environment;
+			game->type = zombie_type;
+			game->numpossibleguns = 0;
+			game->evilprobability = 5;
+			bodyguard.whichgun = shotgun;
+			bodyguard.reloads[bodyguard.whichgun] = 5;
+			game->timeremaining = 35;
+			game->difficulty = 0.7f;
+			break;
+		case 4:
+			environment = snowy_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = sniperrifle;
+			game->possiblegun[1] = assaultrifle;
+			game->numpossibleguns = 2;
+			game->evilprobability = 5;
+			bodyguard.whichgun = grenade;
+			bodyguard.reloads[bodyguard.whichgun] = 20;
+			game->timeremaining = 30;
+			game->difficulty = 0.5f;
+			break;
+		case 5:
+			environment = rainy_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = handgun1;
+			game->possiblegun[1] = shotgun;
+			game->possiblegun[2] = assaultrifle;
+			game->numpossibleguns = 3;
+			game->evilprobability = 6;
+			bodyguard.whichgun = knife;
+			bodyguard.reloads[bodyguard.whichgun] = 3;
+			game->timeremaining = 40;
+			game->difficulty = 0.8f;
+			break;
+		case 6:
+			environment = night_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[1] = handgun1;
+			game->possiblegun[2] = handgun2;
+			game->possiblegun[3] = shotgun;
+			game->numpossibleguns = 3;
+			game->evilprobability = 5;
+			bodyguard.whichgun = handgun1;
+			bodyguard.reloads[bodyguard.whichgun] = 4;
+			game->timeremaining = 30;
+			game->difficulty = 1.0f;
+			break;
+		case 7:
+			environment = firey_environment;
+			game->type = zombie_type;
+			bodyguard.whichgun = assaultrifle;
+			bodyguard.reloads[bodyguard.whichgun] = 5;
+			game->timeremaining = 30;
+			game->difficulty = 1.0f;
+			break;
+		case 8:
+			environment = rainy_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = handgun1;
+			game->possiblegun[1] = handgun2;
+			game->possiblegun[2] = shotgun;
+			game->possiblegun[3] = sniperrifle;
+			game->possiblegun[4] = assaultrifle;
+			game->numpossibleguns = 5;
+			game->evilprobability = 5;
+			bodyguard.whichgun = nogun;
+			bodyguard.reloads[bodyguard.whichgun] = 3;
+			game->timeremaining = 40;
+			game->difficulty = 0.8f;
+			break;
+		case 9:
+			environment = snowy_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = knife;
+			game->possiblegun[1] = handgun1;
+			game->possiblegun[2] = handgun2;
+			game->possiblegun[3] = shotgun;
+			game->possiblegun[4] = sniperrifle;
+			game->possiblegun[5] = assaultrifle;
+			game->numpossibleguns = 6;
+			game->evilprobability = 4;
+			bodyguard.whichgun = handgun1;
+			bodyguard.reloads[bodyguard.whichgun] = 3;
+			game->timeremaining = 90;
+			game->difficulty = 1.0f;
+			break;
+		case 10:
+			environment = night_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = sniperrifle;
+			game->numpossibleguns = 1;
+			game->evilprobability = 5;
+			bodyguard.whichgun = sniperrifle;
+			bodyguard.reloads[bodyguard.whichgun] = 4;
+			game->timeremaining = 30;
+			game->difficulty = 1.3f;
+			break;
+		case 11:
+			environment = sunny_environment;
+			game->type = randomshoot_type;
+			game->possiblegun[0] = knife;
+			game->possiblegun[1] = sniperrifle;
+			game->numpossibleguns = 2;
+			game->evilprobability = 4;
+			bodyguard.whichgun = knife;
+			game->timeremaining = 30;
+			game->difficulty = 1.5f;
+			break;
+		case 12:
+			environment = firey_environment;
+			game->type = zombie_type;
+			game->possiblegun[0] = knife;
+			game->possiblegun[1] = sniperrifle;
+			bodyguard.whichgun = handgun2;
+			bodyguard.reloads[bodyguard.whichgun] = 10;
+			game->timeremaining = 60;
+			game->difficulty = 1.5f;
+			break;
+		}
 	}
 
 	//Setup fast radian to degree conversion
@@ -618,417 +604,237 @@ void Game::InitGame()
 	//Setup bounding cylinder model
 	float boundingscale=3;
 
-	if(!initialized){
-		boundingpoints[0]=0;
-		boundingpoints[0].z=boundingscale;
-		boundingpoints[0].y=0;
-
-		for(int i=1;i<8;i++){
-			boundingpoints[i]=DoRotation(boundingpoints[0],0,i*360/7,0);
-		}
+	if (!game->initialized) {
+		auto& point0 = game->boundingpoints[0];
+		point0 = 0;
+		point0.z = boundingscale;
+		point0.y = 0;
+
+		for (int i = 1; i < 8; ++i)
+			game->boundingpoints[i] = DoRotation(point0,
+					0, i * 360 / 7, 0);
 	}
 
-	civkills=0;
-	badkills=0;
-	goodkills=0;
-	enemystate=2;
-
-	if(!initialized){
-		if(!azertykeyboard){
-			forwardskey=MAC_W_KEY;
-			backwardskey=MAC_S_KEY;
-			leftkey=MAC_A_KEY;
-			rightkey=MAC_D_KEY;
-			aimkey=MAC_Q_KEY;
-			psychicaimkey=MAC_E_KEY;
-			psychickey=MAC_Z_KEY;
-		}
+	game->civkills = 0;
+	game->badkills = 0;
+	game->goodkills = 0;
+	game->enemystate = 2;
 
-		if(azertykeyboard){
-			forwardskey=MAC_Z_KEY;
-			backwardskey=MAC_S_KEY;
-			leftkey=MAC_Q_KEY;
-			rightkey=MAC_D_KEY;
-			aimkey=MAC_A_KEY;
-			psychicaimkey=MAC_E_KEY;
-			psychickey=MAC_W_KEY;
+	if (!game->initialized) {
+		if (game->azertykeyboard) {
+			forwardskey = MAC_Z_KEY;
+			backwardskey = MAC_S_KEY;
+			leftkey = MAC_Q_KEY;
+			rightkey = MAC_D_KEY;
+			aimkey = MAC_A_KEY;
+			psychicaimkey = MAC_E_KEY;
+			psychickey = MAC_W_KEY;
+		} else {
+			forwardskey = MAC_W_KEY;
+			backwardskey = MAC_S_KEY;
+			leftkey = MAC_A_KEY;
+			rightkey = MAC_D_KEY;
+			aimkey = MAC_Q_KEY;
+			psychicaimkey = MAC_E_KEY;
+			psychickey = MAC_Z_KEY;
 		}
 
 		soundscalefactor=soundscalefactordefault; //Setup sound falloff
-		gQuit=false;
+		game->gQuit = false;
 
-		//Sounds
-		LoadSounds(musictoggle);
+		// Sounds
+		LoadSounds(game->musictoggle);
 
 		//Play correct song
-		if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]);
-		if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]);
-
-		alSourceStop(gSourceID[whichsong]);
-		alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
-		alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
-
-		whichsong=mainmenusong;
-		alSourceStop(gSourceID[whichsong]);
-		alSourcef(gSourceID[whichsong], AL_PITCH, 1);
-		alSourcePlay(gSourceID[whichsong]);
-		alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
-		alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+		if (environment == rainy_environment)
+			alSourcePlay(gSourceID[rainsound]);
+		else
+			alSourcePause(gSourceID[rainsound]);
+
+		ALuint sound_source = gSourceID[game->whichsong];
+		alSourceStop(sound_source);
+		alSourcef(sound_source, AL_MIN_GAIN, 0);
+		alSourcef(sound_source, AL_MAX_GAIN, 0);
+
+		sound_source = gSourceID[game->whichsong = mainmenusong];
+		alSourceStop(sound_source);
+		alSourcef(sound_source, AL_PITCH, 1);
+		alSourcePlay(sound_source);
+		alSourcef(sound_source, AL_MIN_GAIN, 1);
+		alSourcef(sound_source, AL_MAX_GAIN, 1);
 
 	}
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
-	loadingscreenamount+=5;
-	if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-	//Setup random seed
+	// Setup random seed
 	srand(time(NULL));
-	gamespeed=1;
-
-	//Setup camera
-	camera.position=0;
-	camera.position.x=num_blocks/2*block_spacing+block_spacing/2;
-	camera.position.z=num_blocks/2*block_spacing+block_spacing/2;
-	camera.position.y=30;
-	camera.oldposition=camera.position;
-	numpeople=1;
-
-	//Setup path to walk around blocks
-	path.load((unsigned char *)":Data:Models:path.solid");
-	path.Rotate(90,0,0);
-	path.Scale(.8,.8,.8);
-	path.CalculateNormals();
-	loadingscreenamount+=5;
-
-	if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-	person[0].speedmult=1.3;
-
-	//Add vip
-	person[numpeople].playerrotation=0;
-	person[numpeople].whichcostume=vipcostume;
-	person[numpeople].whichblockx=((person[0].playercoords.x+block_spacing/2)/block_spacing);
-	person[numpeople].whichblocky=((person[0].playercoords.x+block_spacing/2)/block_spacing);
-	person[numpeople].pathnum=-1;
-	person[numpeople].oldpathnum=-1;
-	person[numpeople].oldoldpathnum=-1;
-	person[numpeople].oldoldoldpathnum=-1;
-
-	while(person[numpeople].pathnum<0||person[numpeople].pathnum>=path.vertexNum||person[numpeople].pathnum==1){
-		person[numpeople].pathnum=Random()%path.vertexNum;
-	}
-
-	person[numpeople].pathtarget.x=path.vertex[person[numpeople].pathnum].x;
-	person[numpeople].pathtarget.z=path.vertex[person[numpeople].pathnum].z;
-	person[numpeople].pathsize=.98+float(abs(Random()%20))/400;
-	person[numpeople].pathtarget*=person[numpeople].pathsize;
-	person[numpeople].pathtarget.x+=person[numpeople].whichblockx*block_spacing;
-	person[numpeople].pathtarget.z+=person[numpeople].whichblocky*block_spacing;
-	person[numpeople].playercoords=person[numpeople].pathtarget;
-	person[numpeople].oldplayercoords=person[numpeople].playercoords;
-
-	person[0].playercoords=person[numpeople].playercoords;
-	person[0].playercoords.x+=1;
-	person[0].playercoords.z+=1;
-	person[0].oldplayercoords=person[0].playercoords;
-
-	person[numpeople].skeleton.free=0;
-	person[numpeople].targetanimation=walkanim;
-	person[numpeople].speed=1;
-	person[numpeople].existing=0;
-	person[numpeople].speedmult=1;
-	if(type==zombie_type)person[numpeople].speedmult=.8;
-
-	person[numpeople].health=100;
-	person[numpeople].playerrotation2=0;//20;
-	person[numpeople].lastdistancevictim=200000;
-
-	if(person[numpeople].skeleton.broken)person[numpeople].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
-
-	person[numpeople].type=viptype;
-	person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1;
-	person[numpeople].existing=1;
-
-	citypeoplenum[person[numpeople].whichblockx][person[numpeople].whichblocky]++;
-	numpeople++;
-	spawndelay=.1;
-
-	XYZ vipdistance;
-	vipdistance=0;
-	vipdistance.x=10000000;
-	vipgoal=person[1].playercoords+DoRotation(vipdistance,0,Random()%360,0);
-
-	//Setup block models
-
-	if(!initialized){
-
-		blocks[0].load((unsigned char *)":Data:Models:Block1.solid");
-
-		blocks[0].Rotate(90,0,0);
-
-		blocks[0].Scale(.8,.8,.8);
-
-		blocks[0].CalculateNormals();
-
-		blocks[1].load((unsigned char *)":Data:Models:Block2.solid");
-
-		blocks[1].Rotate(90,0,0);
-
-		blocks[1].Scale(.8,.8,.8);
-
-		blocks[1].CalculateNormals();
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		blocks[2].load((unsigned char *)":Data:Models:Block3.solid");
-
-		blocks[2].Rotate(90,0,0);
-
-		blocks[2].Scale(.8,.8,.8);
-
-		blocks[2].CalculateNormals();
-
-		blocks[3].load((unsigned char *)":Data:Models:Block4.solid");
-
-		blocks[3].Rotate(90,0,0);
-
-		blocks[3].Scale(.8,.8,.8);
-
-		blocks[3].CalculateNormals();
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		sidewalkcollide.load((unsigned char *)":Data:Models:Lowheightcollide.solid");
-
-		sidewalkcollide.Rotate(90,0,0);
-
-		sidewalkcollide.Scale(.8,.8,.8);
-
-		sidewalkcollide.CalculateNormals();
-
-		blockwalls[0].load((unsigned char *)":Data:Models:Block1collide.solid");
-
-		blockwalls[0].Rotate(90,0,0);
-
-		blockwalls[0].Scale(.8,.75,.8);
-
-		blockwalls[0].CalculateNormals();
-
-		blockwalls[1].load((unsigned char *)":Data:Models:Block2collide.solid");
-
-		blockwalls[1].Rotate(90,0,0);
-
-		blockwalls[1].Scale(.8,.75,.8);
-
-		blockwalls[1].CalculateNormals();
-
-		blockwalls[2].load((unsigned char *)":Data:Models:Block3collide.solid");
-
-		blockwalls[2].Rotate(90,0,0);
-
-		blockwalls[2].Scale(.8,.75,.8);
-
-		blockwalls[2].CalculateNormals();
-
-		blockwalls[3].load((unsigned char *)":Data:Models:Block4collide.solid");
-
-		blockwalls[3].Rotate(90,0,0);
-
-		blockwalls[3].Scale(.8,.75,.8);
-
-		blockwalls[3].CalculateNormals();
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		blockroofs[0].load((unsigned char *)":Data:Models:Highblock1collide.solid");
-
-		blockroofs[0].Rotate(90,0,0);
-
-		blockroofs[0].Scale(.8,.8,.8);
-
-		blockroofs[0].CalculateNormals();
-
-		blockroofs[1].load((unsigned char *)":Data:Models:Highblock2collide.solid");
-
-		blockroofs[1].Rotate(90,0,0);
-
-		blockroofs[1].Scale(.8,.8,.8);
-
-		blockroofs[1].CalculateNormals();
-
-		blockroofs[2].load((unsigned char *)":Data:Models:Highblock3collide.solid");
-
-		blockroofs[2].Rotate(90,0,0);
-
-		blockroofs[2].Scale(.8,.8,.8);
-
-		blockroofs[2].CalculateNormals();
-
-		blockroofs[3].load((unsigned char *)":Data:Models:Highblock4collide.solid");
-
-		blockroofs[3].Rotate(90,0,0);
-
-		blockroofs[3].Scale(.8,.8,.8);
-
-		blockroofs[3].CalculateNormals();
-
-		blockcollide[0].load((unsigned char *)":Data:Models:block1complete.solid");
-
-		blockcollide[0].Rotate(90,0,0);
-
-		blockcollide[0].Scale(.8,.8,.8);
-
-		blockcollide[0].CalculateNormals();
-
-		blockcollide[1].load((unsigned char *)":Data:Models:block2complete.solid");
-
-		blockcollide[1].Rotate(90,0,0);
-
-		blockcollide[1].Scale(.8,.8,.8);
-
-		blockcollide[1].CalculateNormals();
-
-		blockcollide[2].load((unsigned char *)":Data:Models:block3complete.solid");
-
-		blockcollide[2].Rotate(90,0,0);
-
-		blockcollide[2].Scale(.8,.8,.8);
-
-		blockcollide[2].CalculateNormals();
-
-		blockcollide[3].load((unsigned char *)":Data:Models:block4complete.solid");
-
-		blockcollide[3].Rotate(90,0,0);
-
-		blockcollide[3].Scale(.8,.8,.8);
-
-		blockcollide[3].CalculateNormals();
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		blocksimplecollide[0].load((unsigned char *)":Data:Models:lowsimplecollide1.solid");
-
-		blocksimplecollide[0].Rotate(90,0,0);
-
-		blocksimplecollide[0].Scale(.8,.8,.8);
-
-		blocksimplecollide[0].CalculateNormals();
-
-		blocksimplecollide[1].load((unsigned char *)":Data:Models:lowsimplecollide2.solid");
+	game->gamespeed = 1;
 
-		blocksimplecollide[1].Rotate(90,0,0);
-
-		blocksimplecollide[1].Scale(.8,.8,.8);
-
-		blocksimplecollide[1].CalculateNormals();
-
-		blocksimplecollide[2].load((unsigned char *)":Data:Models:lowsimplecollide3.solid");
-
-		blocksimplecollide[2].Rotate(90,0,0);
-
-		blocksimplecollide[2].Scale(.8,.8,.8);
-
-		blocksimplecollide[2].CalculateNormals();
-
-		blocksimplecollide[3].load((unsigned char *)":Data:Models:lowsimplecollide4.solid");
-
-		blocksimplecollide[3].Rotate(90,0,0);
-
-		blocksimplecollide[3].Scale(.8,.8,.8);
-
-		blocksimplecollide[3].CalculateNormals();
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		blockocclude.load((unsigned char *)":Data:Models:blockocclude.solid");
-
-		blockocclude.Rotate(90,0,0);
-
-		blockocclude.Scale(.8,.8,.8);
-
-		blockocclude.CalculateNormals();
-
-		blocksimple.load((unsigned char *)":Data:Models:blocksimple.solid");
-
-		blocksimple.Rotate(90,0,0);
-
-		blocksimple.Scale(.8,2,.8);
-
-		blocksimple.CalculateNormals();
-
-		street.load((unsigned char *)":Data:Models:streetsubdivided2.solid");
-
-		street.Rotate(90,0,0);
-
-		street.Scale(.01,.01,.01);
-
-		street.CalculateNormals();
-
-		Bigstreet=street;
-
-		Bigstreet.Scale(10000,10000,10000);
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		path.load((unsigned char *)":Data:Models:path.solid");
-		path.Rotate(90,0,0);
-		path.Scale(.8,.8,.8);
-		path.CalculateNormals();
-
-		// Fix block radius
-		for (int i = 0; i < 4; i++) {
-			auto& center = blocks[i].boundingspherecenter;
+	// Setup block models
+	if (!game->initialized) {
+		game->blocks[0].load((char*) ":Data:Models:Block1.solid");
+		game->blocks[1].load((char*) ":Data:Models:Block2.solid");
+		game->blocks[2].load((char*) ":Data:Models:Block3.solid");
+		game->blocks[3].load((char*) ":Data:Models:Block4.solid");
+		for (auto&& block : game->blocks) {
+			block.Rotate(90, 0, 0);
+			block.Scale(0.8f, 0.8f, 0.8f);
+			block.CalculateNormals();
+
+			// Fix block radius
+			auto& center = block.boundingspherecenter;
 			center.x = center.y = center.z = 0;
 
 			float radiusqr = 0.0;
-			for (int x = 0; x < blocks[i].vertexNum; x++) {
+			for (int x = 0; x < block.vertexNum; x++) {
 				auto distance = findDistancefast(center,
-					blocks[i].vertex[x]);
+					block.vertex[x]);
 				if (distance > radiusqr)
 					radiusqr = distance;
 			}
-			blocks[i].boundingsphereradius = sqrt(radiusqr);
+			block.boundingsphereradius = sqrt(radiusqr);
 		}
-	}
-
-	mousesensitivity=1;
-
-	//init city block rotations
-
-	for(int i=0;i<num_blocks;i++){
-
-		for(int j=0;j<num_blocks;j++){
-
-			cityrotation[i][j]=Random()%4;
-
-			citytype[i][j]=Random()%4;
-
-			citypeoplenum[i][j]=0;
-
-			if(citytype[i][j]<0)citytype[i][j]=0;
-
-			if(citytype[i][j]>3)citytype[i][j]=3;
-
+		game->LoadingScreen(loadingscreenamount += 2.5f);
+
+		game->sidewalkcollide.load((char*) ":Data:Models:Lowheightcollide.solid");
+		game->sidewalkcollide.Rotate(90, 0, 0);
+		game->sidewalkcollide.Scale(0.8f, 0.8f, 0.8f);
+		game->sidewalkcollide.CalculateNormals();
+
+		game->blockwalls[0].load((char*) ":Data:Models:Block1collide.solid");
+		game->blockwalls[1].load((char*) ":Data:Models:Block2collide.solid");
+		game->blockwalls[2].load((char*) ":Data:Models:Block3collide.solid");
+		game->blockwalls[3].load((char*) ":Data:Models:Block4collide.solid");
+		for (auto&& blockwall : game->blockwalls) {
+			blockwall.Rotate(90, 0, 0);
+			blockwall.Scale(0.8f, 0.75f, 0.8f);
+			blockwall.CalculateNormals();
+		}
+		game->LoadingScreen(loadingscreenamount += 2.5f);
+
+		game->blockroofs[0].load((char*) ":Data:Models:Highblock1collide.solid");
+		game->blockroofs[1].load((char*) ":Data:Models:Highblock2collide.solid");
+		game->blockroofs[2].load((char*) ":Data:Models:Highblock3collide.solid");
+		game->blockroofs[3].load((char*) ":Data:Models:Highblock4collide.solid");
+		for (auto&& blockroof : game->blockroofs) {
+			blockroof.Rotate(90, 0, 0);
+			blockroof.Scale(0.8f, 0.8f, 0.8f);
+			blockroof.CalculateNormals();
 		}
 
+		game->blockcollide[0].load((char*) ":Data:Models:block1complete.solid");
+		game->blockcollide[1].load((char*) ":Data:Models:block2complete.solid");
+		game->blockcollide[2].load((char*) ":Data:Models:block3complete.solid");
+		game->blockcollide[3].load((char*) ":Data:Models:block4complete.solid");
+		for (auto&& blockcollide : game->blockcollide) {
+			blockcollide.Rotate(90, 0, 0);
+			blockcollide.Scale(0.8f, 0.8f, 0.8f);
+			blockcollide.CalculateNormals();
+		}
+		game->LoadingScreen(loadingscreenamount += 2.5f);
+
+		game->blocksimplecollide[0].load((char*) ":Data:Models:lowsimplecollide1.solid");
+		game->blocksimplecollide[1].load((char*) ":Data:Models:lowsimplecollide2.solid");
+		game->blocksimplecollide[2].load((char*) ":Data:Models:lowsimplecollide3.solid");
+		game->blocksimplecollide[3].load((char*) ":Data:Models:lowsimplecollide4.solid");
+		for (auto&& blocksimplecollide : game->blocksimplecollide) {
+			blocksimplecollide.Rotate(90, 0, 0);
+			blocksimplecollide.Scale(0.8f, 0.8f, 0.8f);
+			blocksimplecollide.CalculateNormals();
+		}
+		game->LoadingScreen(loadingscreenamount += 2.5f);
+
+		game->blockocclude.load((char*) ":Data:Models:blockocclude.solid");
+		game->blockocclude.Rotate(90, 0, 0);
+		game->blockocclude.Scale(0.8f, 0.8f, 0.8f);
+		game->blockocclude.CalculateNormals();
+
+		game->blocksimple.load((char*) ":Data:Models:blocksimple.solid");
+		game->blocksimple.Rotate(90, 0, 0);
+		game->blocksimple.Scale(0.8f, 2.0f, 0.8f);
+		game->blocksimple.CalculateNormals();
+
+		game->street.load((char*) ":Data:Models:streetsubdivided2.solid");
+		game->street.Rotate(90,0,0);
+		game->street.Scale(0.01f, 0.01f, 0.01f);
+		game->street.CalculateNormals();
+
+		game->Bigstreet = game->street;
+		game->Bigstreet.Scale(10000.0f, 10000.0f, 10000.0f);
+		game->LoadingScreen(loadingscreenamount += 2.5f);
+
+		game->path.load((char*) ":Data:Models:path.solid");
+		game->path.Rotate(90,0,0);
+		game->path.Scale(0.8f, 0.8f, 0.8f);
+		game->path.CalculateNormals();
 	}
 
-		if(!initialized){
+	auto& vip = game->person[game->numpeople = 1];
+	vip.type = viptype;
+	vip.whichgun = nogun;
+	vip.aiming = 0;
+	vip.killtarget = -1;
+	vip.existing = 1;
+
+	vip.playerrotation = 0;
+	vip.whichcostume = vipcostume;
+	vip.whichblockx = (bodyguard.playercoords.x + block_spacing / 2)
+		/ block_spacing;
+	vip.whichblocky = (bodyguard.playercoords.z + block_spacing / 2)
+		/ block_spacing;
+	vip.oldoldoldpathnum = vip.oldoldpathnum
+		= vip.oldpathnum = vip.pathnum = -1;
+
+	while (vip.pathnum < 0 || vip.pathnum == 1
+	       || vip.pathnum >= game->path.vertexNum)
+		vip.pathnum = Random() % game->path.vertexNum;
+
+	vip.pathtarget.x = game->path.vertex[vip.pathnum].x;
+	vip.pathtarget.z = game->path.vertex[vip.pathnum].z;
+	vip.pathsize = 0.98f + abs(Random() % 20) / 400.0f;
+	vip.pathtarget *= vip.pathsize;
+	vip.pathtarget.x += vip.whichblockx * block_spacing;
+	vip.pathtarget.z += vip.whichblocky * block_spacing;
+	vip.oldplayercoords = vip.playercoords = vip.pathtarget;
+
+	bodyguard.playercoords = vip.playercoords;
+	bodyguard.playercoords.x += 1;
+	bodyguard.playercoords.z += 1;
+	bodyguard.oldplayercoords = bodyguard.playercoords;
+
+	vip.skeleton.free = 0;
+	vip.targetanimation = walkanim;
+	vip.speed = 1;
+	vip.existing = 0;
+	vip.speedmult = (game->type == zombie_type) ? 0.8f : 1.0f;
+
+	vip.health = 100;
+	vip.playerrotation2 = 0; // 20
+	vip.lastdistancevictim = 200000;
+
+	if (vip.skeleton.broken)
+		vip.skeleton.Load((char*) ":Data:Skeleton:Basic Figure");
+
+	game->citypeoplenum[vip.whichblockx][vip.whichblocky]++;
+	game->numpeople++;
+	game->spawndelay = 0.1f;
+
+	game->vipgoal = vip.playercoords
+		+ DoRotation({10000000.0f, 0.0f, 0.0f}, 0, Random() % 360, 0);
+
+	// Init city block rotations
+	for (int i = 0; i < num_blocks; ++i)
+		for (int j = 0; j < num_blocks; ++j) {
+			game->cityrotation[i][j] = Random() % 4;
+			game->citytype[i][j] = abs(Random()) % 4;
+			game->citypeoplenum[i][j] = 0;
+		}
+
+	if (!game->initialized) {
 
 		//Load player model
 
-		skeletonmodels[0].load((unsigned char *)":Data:Models:Head.solid");
+		skeletonmodels[0].load((char*) ":Data:Models:Head.solid");
 
 		skeletonmodels[0].Rotate(90,0,0);
 
@@ -1036,7 +842,7 @@ void Game::InitGame()
 
 		skeletonmodels[0].CalculateNormals();
 
-		skeletonmodels[1].load((unsigned char *)":Data:Models:Chest.solid");
+		skeletonmodels[1].load((char*) ":Data:Models:Chest.solid");
 
 		skeletonmodels[1].Rotate(90,0,0);
 
@@ -1044,7 +850,7 @@ void Game::InitGame()
 
 		skeletonmodels[1].CalculateNormals();
 
-		skeletonmodels[2].load((unsigned char *)":Data:Models:Abdomen.solid");
+		skeletonmodels[2].load((char*) ":Data:Models:Abdomen.solid");
 
 		skeletonmodels[2].Rotate(90,0,0);
 
@@ -1052,7 +858,7 @@ void Game::InitGame()
 
 		skeletonmodels[2].CalculateNormals();
 
-		skeletonmodels[3].load((unsigned char *)":Data:Models:Upper arm.solid");
+		skeletonmodels[3].load((char*) ":Data:Models:Upper arm.solid");
 
 		skeletonmodels[3].Rotate(90,0,0);
 
@@ -1060,7 +866,7 @@ void Game::InitGame()
 
 		skeletonmodels[3].CalculateNormals();
 
-		skeletonmodels[4].load((unsigned char *)":Data:Models:Lower arm.solid");
+		skeletonmodels[4].load((char*) ":Data:Models:Lower arm.solid");
 
 		skeletonmodels[4].Rotate(90,0,0);
 
@@ -1068,7 +874,7 @@ void Game::InitGame()
 
 		skeletonmodels[4].CalculateNormals();
 
-		skeletonmodels[5].load((unsigned char *)":Data:Models:Hand.solid");
+		skeletonmodels[5].load((char*) ":Data:Models:Hand.solid");
 
 		skeletonmodels[5].Rotate(90,0,0);
 
@@ -1076,7 +882,7 @@ void Game::InitGame()
 
 		skeletonmodels[5].CalculateNormals();
 
-		skeletonmodels[6].load((unsigned char *)":Data:Models:Upper leg.solid");
+		skeletonmodels[6].load((char*) ":Data:Models:Upper leg.solid");
 
 		skeletonmodels[6].Rotate(90,0,0);
 
@@ -1084,7 +890,7 @@ void Game::InitGame()
 
 		skeletonmodels[6].CalculateNormals();
 
-		skeletonmodels[7].load((unsigned char *)":Data:Models:Lower leg.solid");
+		skeletonmodels[7].load((char*) ":Data:Models:Lower leg.solid");
 
 		skeletonmodels[7].Rotate(90,0,0);
 
@@ -1092,7 +898,7 @@ void Game::InitGame()
 
 		skeletonmodels[7].CalculateNormals();
 
-		skeletonmodels[8].load((unsigned char *)":Data:Models:Foot.solid");
+		skeletonmodels[8].load((char*) ":Data:Models:Foot.solid");
 
 		skeletonmodels[8].Rotate(90,0,0);
 
@@ -1100,21 +906,18 @@ void Game::InitGame()
 
 		skeletonmodels[8].CalculateNormals();
 
-		skeletonmodels[9].load((unsigned char *)":Data:Models:Shades.solid");
+		skeletonmodels[9].load((char*) ":Data:Models:Shades.solid");
 
 		skeletonmodels[9].Rotate(90,0,0);
 
 		skeletonmodels[9].Scale(.02,.02,.02);
 
 		skeletonmodels[9].CalculateNormals();
+		game->LoadingScreen(loadingscreenamount += 2.5f);
 
-		//Load gun models
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
 
-		gunmodels[sniperriflemodel].load((unsigned char *)":Data:Models:sniperrifle.solid");
+		//Load gun models
+		gunmodels[sniperriflemodel].load((char*) ":Data:Models:sniperrifle.solid");
 
 		gunmodels[sniperriflemodel].Rotate(0,0,90);
 
@@ -1122,7 +925,7 @@ void Game::InitGame()
 
 		gunmodels[sniperriflemodel].CalculateNormals();
 
-		gunmodels[assaultriflemodel].load((unsigned char *)":Data:Models:assaultrifle.solid");
+		gunmodels[assaultriflemodel].load((char*) ":Data:Models:assaultrifle.solid");
 
 		gunmodels[assaultriflemodel].Rotate(0,0,90);
 
@@ -1130,7 +933,7 @@ void Game::InitGame()
 
 		gunmodels[assaultriflemodel].CalculateNormals();
 
-		gunmodels[handgunbasemodel].load((unsigned char *)":Data:Models:Handgunbase.solid");
+		gunmodels[handgunbasemodel].load((char*) ":Data:Models:Handgunbase.solid");
 
 		gunmodels[handgunbasemodel].Rotate(0,0,90);
 
@@ -1141,12 +944,9 @@ void Game::InitGame()
 		gunmodels[handgunbasemodel].CalculateNormals();
 
 		gunmodels[handgunbasemodel].MultColor(.6);
+		game->LoadingScreen(loadingscreenamount += 2.5f);
 
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		gunmodels[handgunslidemodel].load((unsigned char *)":Data:Models:Handgunslide.solid");
+		gunmodels[handgunslidemodel].load((char*) ":Data:Models:Handgunslide.solid");
 
 		gunmodels[handgunslidemodel].Rotate(0,0,90);
 
@@ -1158,7 +958,7 @@ void Game::InitGame()
 
 		gunmodels[handgunslidemodel].MultColor(.6);
 
-		gunmodels[handgun2basemodel].load((unsigned char *)":Data:Models:glockbase.solid");
+		gunmodels[handgun2basemodel].load((char*) ":Data:Models:glockbase.solid");
 
 		gunmodels[handgun2basemodel].Rotate(0,0,90);
 
@@ -1170,7 +970,7 @@ void Game::InitGame()
 
 		gunmodels[handgun2basemodel].MultColor(.6);
 
-		gunmodels[handgun2slidemodel].load((unsigned char *)":Data:Models:glockslide.solid");
+		gunmodels[handgun2slidemodel].load((char*) ":Data:Models:glockslide.solid");
 
 		gunmodels[handgun2slidemodel].Rotate(0,0,90);
 
@@ -1181,12 +981,9 @@ void Game::InitGame()
 		gunmodels[handgun2slidemodel].CalculateNormals();
 
 		gunmodels[handgun2slidemodel].MultColor(.6);
+		game->LoadingScreen(loadingscreenamount += 2.5f);
 
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		gunmodels[grenadebasemodel].load((unsigned char *)":Data:Models:grenadebase.solid");
+		gunmodels[grenadebasemodel].load((char*) ":Data:Models:grenadebase.solid");
 
 		gunmodels[grenadebasemodel].Rotate(0,0,90);
 
@@ -1196,7 +993,7 @@ void Game::InitGame()
 
 		gunmodels[grenadebasemodel].CalculateNormals();
 
-		gunmodels[grenadepinmodel].load((unsigned char *)":Data:Models:grenadepin.solid");
+		gunmodels[grenadepinmodel].load((char*) ":Data:Models:grenadepin.solid");
 
 		gunmodels[grenadepinmodel].Rotate(0,0,90);
 
@@ -1206,7 +1003,7 @@ void Game::InitGame()
 
 		gunmodels[grenadepinmodel].CalculateNormals();
 
-		gunmodels[grenadespoonmodel].load((unsigned char *)":Data:Models:grenadespoon.solid");
+		gunmodels[grenadespoonmodel].load((char*) ":Data:Models:grenadespoon.solid");
 
 		gunmodels[grenadespoonmodel].Rotate(0,0,90);
 
@@ -1216,7 +1013,7 @@ void Game::InitGame()
 
 		gunmodels[grenadespoonmodel].CalculateNormals();
 
-		gunmodels[knifemodel].load((unsigned char *)":Data:Models:Knife.solid");
+		gunmodels[knifemodel].load((char*) ":Data:Models:Knife.solid");
 
 		gunmodels[knifemodel].Rotate(0,0,90);
 
@@ -1226,7 +1023,7 @@ void Game::InitGame()
 
 		gunmodels[knifemodel].CalculateNormals();
 
-		gunmodels[shotgunmodel].load((unsigned char *)":Data:Models:shotgun.solid");
+		gunmodels[shotgunmodel].load((char*) ":Data:Models:shotgun.solid");
 
 		gunmodels[shotgunmodel].Rotate(0,0,90);
 
@@ -1236,73 +1033,58 @@ void Game::InitGame()
 
 		gunmodels[shotgunmodel].MultColor(.6);
 
-		}
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		//Setup costumes
-
-		float headcolor[3];
-
-		float footcolor[3];
-
-		float handcolor[3];
-
-		float topcolor[3];
-
-		float bottomcolor[3];
-
-		//Police
-
-		headcolor[0]=(float)240/255;
+	}
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
-		headcolor[1]=(float)183/255;
+	//Setup costumes
+	float headcolor[3];
+	float footcolor[3];
+	float handcolor[3];
+	float topcolor[3];
+	float bottomcolor[3];
 
-		headcolor[2]=(float)132/255;
+	//Police
 
-		footcolor[0]=(float)119/255;
+	headcolor[0]=(float)240/255;
 
-		footcolor[1]=(float)68/255;
+	headcolor[1]=(float)183/255;
 
-		footcolor[2]=(float)18/255;
+	headcolor[2]=(float)132/255;
 
-		handcolor[0]=(float)240/255;
+	footcolor[0]=(float)119/255;
 
-		handcolor[1]=(float)183/255;
+	footcolor[1]=(float)68/255;
 
-		handcolor[2]=(float)132/255;
+	footcolor[2]=(float)18/255;
 
-		topcolor[0]=(float)14/255;
-
-		topcolor[1]=(float)18/255;
-
-		topcolor[2]=(float)195/255;
-
-		bottomcolor[0]=(float)14/255;
-
-		bottomcolor[1]=(float)18/255;
+	handcolor[0]=(float)240/255;
 
-		bottomcolor[2]=(float)195/255;
+	handcolor[1]=(float)183/255;
 
-		//Greenish skin if zombies
+	handcolor[2]=(float)132/255;
 
-		if(type==zombie_type){
+	topcolor[0]=(float)14/255;
 
-			headcolor[0]=(float)223/255;
+	topcolor[1]=(float)18/255;
 
-			headcolor[1]=(float)243/255;
+	topcolor[2]=(float)195/255;
 
-			headcolor[2]=(float)197/255;
+	bottomcolor[0]=(float)14/255;
 
-			handcolor[0]=(float)223/255;
+	bottomcolor[1]=(float)18/255;
 
-			handcolor[1]=(float)243/255;
+	bottomcolor[2]=(float)195/255;
 
-			handcolor[2]=(float)197/255;
+	// Greenish skin if zombies
+	if (game->type == zombie_type) {
+		headcolor[0] = 223.0f / 255.0f;
+		headcolor[1] = 243.0f / 255.0f;
+		headcolor[2] = 197.0f / 255.0f;
 
-		}
+		handcolor[0] = 223.0f / 255.0f;
+		handcolor[1] = 243.0f / 255.0f;
+		handcolor[2] = 197.0f / 255.0f;
+	}
 
 		costume[policecostume].headcolor[0]=headcolor[0];
 
@@ -1642,10 +1424,7 @@ void Game::InitGame()
 
 		costume[casualcostumes+3].footcolor[2]=footcolor[2];
 
-		if(!initialized){
-
 		//vip
-
 		topcolor[0]=(float)235/255;
 
 		topcolor[1]=(float)235/255;
@@ -1809,13 +1588,9 @@ void Game::InitGame()
 		costume[bodyguardcostume].footcolor[1]=footcolor[1];
 
 		costume[bodyguardcostume].footcolor[2]=footcolor[2];
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
 		//Load animations
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
 		testskeleton.Load((char *)":Data:Skeleton:Basic Figure");
 
 		animation[idleanim].Load((char *)":Data:Animations:Breathe");
@@ -1823,10 +1598,7 @@ void Game::InitGame()
 		animation[joganim].Load((char *)":Data:Animations:Run");
 
 		animation[pistolaimanim].Load((char *)":Data:Animations:PistolAim");
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
 		animation[walkanim].Load((char *)":Data:Animations:Walk");
 
@@ -1837,10 +1609,7 @@ void Game::InitGame()
 		animation[assaultrifleaimanim].Load((char *)":Data:Animations:AssaultRifleaim");
 
 		animation[crouchanim].Load((char *)":Data:Animations:Crouch");
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
 		animation[headpainanim].Load((char *)":Data:Animations:Headshot");
 
@@ -1851,10 +1620,7 @@ void Game::InitGame()
 		animation[rightarmpainanim].Load((char *)":Data:Animations:Rightarmshot");
 
 		animation[leftarmpainanim].Load((char *)":Data:Animations:Leftarmshot");
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
 		animation[rightlegpainanim].Load((char *)":Data:Animations:Rightlegshot");
 
@@ -1865,10 +1631,7 @@ void Game::InitGame()
 		animation[grenadeaimanim].Load((char *)":Data:Animations:grenadeaim");
 
 		animation[grenadechargeanim].Load((char *)":Data:Animations:grenadecharge");
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
 		animation[grenadethrowanim].Load((char *)":Data:Animations:grenadethrow");
 
@@ -1877,10 +1640,7 @@ void Game::InitGame()
 		animation[zombiejoganim].Load((char *)":Data:Animations:ZombieRun");
 
 		animation[zombiewalkanim].Load((char *)":Data:Animations:Zombiewalk");
-
-		loadingscreenamount+=5;
-
-		if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
 		animation[getupfrontanim].Load((char *)":Data:Animations:Getupfromfront");
 
@@ -1892,61 +1652,35 @@ void Game::InitGame()
 
 		animation[thrownanim].Load((char *)":Data:Animations:Aikidothrown");
 
+	// Setup people
+	for (int i = 0; i < max_people; ++i) {
+		auto& person = game->person[i];
+		if (i == 0)
+			person.whichcostume = bodyguardcostume;
+		else if (i > 1)
+			person.whichcostume = casualcostumes
+				+ abs(Random()) % numcasual;
+
+		// person.firstlongdead = 0;
+		person.dead = 0;
+		person.health = 100;
+		person.skeleton.free = 0;
+		person.ammo = 0;
+		person.velocity = 0;
+
+		// Load skeleton structure
+		if (!game->initialized)
+			person.skeleton.Load((char*) ":Data:Skeleton:Basic Figure");
+
+		if (i % 5 == 4)
+			game->LoadingScreen(loadingscreenamount += 2.5f);
 	}
 
-	//Setup people
+	bodyguard.attackframe = -1;
+	game->spawndelay = 0;
 
-	for(int i=0;i<max_people;i++){
-
-		if(i==0){
-
-			person[i].whichcostume=bodyguardcostume;
-
-		}
-
-		if(i>1){
-
-			person[i].whichcostume=casualcostumes+abs(Random())%numcasual;
-
-		}
-
-		//person[i].firstlongdead=0;
-
-		person[i].dead=0;
-
-		person[i].health=100;
-
-		person[i].skeleton.free=0;
-
-		person[i].ammo=0;
-
-		person[i].velocity=0;
-
-		//Load skeleton structure
-
-		if(!initialized)person[i].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
-
-		if(i%5==0){
-
-			loadingscreenamount+=5;
-
-			if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-		}
-
-	}
-
-	loadingscreenamount+=5;
-
-	if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-
-	if(initialized)person[0].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
-
-	person[0].attackframe=-1;
-
-	spawndelay=0;
-
-	fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.1);
+	fog.SetFog(fogcolorr, fogcolorg, fogcolorb, 0,
+		game->viewdistance * 0.8f, 0.1f);
 
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -1956,55 +1690,56 @@ void Game::InitGame()
 	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
 	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
 	glEnable(GL_LIGHT0);
-	loadingscreenamount+=5;
-
-	//Load some textures
-	if(!initialized){
-		LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-		LoadPersonSpriteTexture(":Data:Textures:Personsprite.png",&personspritetextureptr);
-		LoadPersonSpriteTexture(":Data:Textures:DeadPersonsprite.png",&deadpersonspritetextureptr);
-		LoadPersonSpriteTexture(":Data:Textures:Scope.png",&scopetextureptr);
-		LoadPersonSpriteTexture(":Data:Textures:Flare.png",&flaretextureptr);
-		sprites.LoadFlareTexture(":Data:Textures:HitFlash.png");
-		sprites.LoadMuzzleFlareTexture(":Data:Textures:MuzzleFlash.png");
-		sprites.LoadSmokeTexture(":Data:Textures:Smoke.png");
-		sprites.LoadBloodTexture(":Data:Textures:Blood.png");
-		sprites.LoadRainTexture(":Data:Textures:rain.png");
-		sprites.LoadSnowTexture(":Data:Textures:snow.png");
-		decals.LoadBulletHoleTexture(":Data:Textures:BulletHole.png");
-		decals.LoadCraterTexture(":Data:Textures:Crater.png");
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood1.png",0);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood2.png",1);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood3.png",2);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood4.png",3);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood5.png",4);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood6.png",5);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood7.png",6);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood8.png",7);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood9.png",8);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood10.png",9);
-		decals.LoadBloodTexture(":Data:Textures:Blood:Blood11.png",10);
+	game->LoadingScreen(loadingscreenamount += 2.5f);
+
+	// Load some textures
+	if (!game->initialized) {
+		LoadPersonSpriteTexture((char*) ":Data:Textures:Personsprite.png",
+			&game->personspritetextureptr);
+		LoadPersonSpriteTexture((char*) ":Data:Textures:DeadPersonsprite.png",
+			&game->deadpersonspritetextureptr);
+		LoadPersonSpriteTexture((char*) ":Data:Textures:Scope.png",
+			&game->scopetextureptr);
+		LoadPersonSpriteTexture((char*) ":Data:Textures:Flare.png",
+			&game->flaretextureptr);
+		sprites.LoadFlareTexture((char*) ":Data:Textures:HitFlash.png");
+		sprites.LoadMuzzleFlareTexture((char*) ":Data:Textures:MuzzleFlash.png");
+		sprites.LoadSmokeTexture((char*) ":Data:Textures:Smoke.png");
+		sprites.LoadBloodTexture((char*) ":Data:Textures:Blood.png");
+		sprites.LoadRainTexture((char*) ":Data:Textures:rain.png");
+		sprites.LoadSnowTexture((char*) ":Data:Textures:snow.png");
+		decals.LoadBulletHoleTexture((char*) ":Data:Textures:BulletHole.png");
+		decals.LoadCraterTexture((char*) ":Data:Textures:Crater.png");
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood1.png", 0);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood2.png", 1);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood3.png", 2);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood4.png", 3);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood5.png", 4);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood6.png", 5);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood7.png", 6);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood8.png", 7);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood9.png", 8);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood10.png", 9);
+		decals.LoadBloodTexture((char*) ":Data:Textures:Blood:Blood11.png", 10);
 	}
 
-	//Setup clip plane equation
-	eqn[0]=0;
-	eqn[1]=1;
-	eqn[2]=0;
-	eqn[3]=0;
+	// Setup clip plane equation
+	game->eqn[0] = 0;
+	game->eqn[1] = 1;
+	game->eqn[2] = 0;
+	game->eqn[3] = 0;
 	glClearColor(fogcolorr,fogcolorg,fogcolorb,1);
+	game->LoadingScreen(loadingscreenamount += 2.5f);
 
-	//Draw city one frame to fix evil menu bug
-	if(!initialized)mainmenu=2;
-	if(!initialized){
-		LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
-		flashamount=1;
-		flashr=1;flashg=1;flashb=1;
+	// Draw city one frame to fix evil menu bug
+	if (!game->initialized) {
+		game->mainmenu = 2;
+		game->flashamount = 1;
+		game->flashr = game->flashg = game->flashb = 1;
 		alSourcePlay(gSourceID[soulinsound]);
 	}
 
-	initialized=1;
-	loadingscreenamount+=5;
-
+	game->initialized = true;
 	/*
 	for(int i=0;i<sprites.howmanysprites;i++){
 		sprites.DeleteSprite(0);
@@ -2015,12 +1750,13 @@ void Game::InitGame()
 
 	decals.howmanydecals=0;
 	sprites.howmanysprites=0;
-	losedelay=1;
+	game->losedelay = 1;
 }
 
-int initGl(Game* game)
+void initGl(Game* game)
 {
 	// Config
+	game->mousesensitivity = 1.0f;
 	if (!game->initialized) {
 		ifstream ipstream {"config.txt"};
 		// If no config, write one
@@ -2127,13 +1863,12 @@ int initGl(Game* game)
 	SDL_WM_SetCaption("Black Shades", "Black Shades");
 	SDL_EnableUNICODE(1); /* toggle it to ON */
 
-	game->text.LoadFontTexture(":Data:Textures:Font.png");
+	game->text.LoadFontTexture((char*) ":Data:Textures:Font.png");
 	game->text.BuildFont();
 	glAlphaFunc(GL_GREATER, 0.01);
 	glDepthFunc(GL_LESS);
 	glPolygonOffset(-8,0);
 	glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-	return TRUE;
 }
 
 GLvoid Game::ReSizeGLScene(float fov, float near)
diff --git a/src/GameTick.cpp b/src/GameTick.cpp
index 8050496..483f0de 100644
--- a/src/GameTick.cpp
+++ b/src/GameTick.cpp
@@ -151,7 +151,7 @@ void Game::handleMenu(unsigned char* theKeyMap)
 
 		if (!gameinprogress) {
 			mission = 0;
-			InitGame();
+			initGame(this);
 		}
 
 		MoveMouse(oldmouseloc.h, oldmouseloc.v, &mouseloc);
@@ -444,7 +444,7 @@ void Game::Tick()
 			saveHighScore();
 		} else {
 			updateSong();
-			InitGame();
+			initGame(this);
 		}
 	}
 
@@ -456,7 +456,7 @@ void Game::Tick()
 		alSourcePlay(gSourceID[soulinsound]);
 
 		updateSong();
-		InitGame();
+		initGame(this);
 	}
 
 	sprites.DoStuff();
diff --git a/src/Skeleton.cpp b/src/Skeleton.cpp
index 2156ed5..e67b5b8 100644
--- a/src/Skeleton.cpp
+++ b/src/Skeleton.cpp
@@ -477,7 +477,7 @@ extern Skeleton testskeleton;
 
 void Animation::Load(char *fileName)
 {
-	files.OpenFile((unsigned char*)fileName);
+	files.OpenFile(fileName);
 	if(files.sFile){
 		ReadInt(files.sFile, 1, &numframes);
 		for(int i=0;i<numframes;i++){
@@ -620,7 +620,7 @@ void Animation::Load(char *fileName)
 
 void Animation::Load(char *fileName, float rotate)
 {
-	files.OpenFile((unsigned char*)fileName);
+	files.OpenFile(fileName);
 	if(files.sFile){
 		ReadInt(files.sFile, 1, &numframes);
 		for(int i=0;i<numframes;i++){
@@ -765,7 +765,7 @@ void Skeleton::Load(char *fileName)
 {
 	int parentID;
 	bool what;
-	files.OpenFile((unsigned char*)fileName);
+	files.OpenFile(fileName);
 	if(files.sFile){
 		ReadInt(files.sFile, 1, &num_joints);
 		for(int i=0;i<num_joints;i++){
diff --git a/src/Support.h b/src/Support.h
index bf0658d..d0bbd92 100644
--- a/src/Support.h
+++ b/src/Support.h
@@ -8,7 +8,7 @@
 
 #define fsFromStart SEEK_SET
 
-typedef unsigned char * Str255;
+typedef char* Str255;
 typedef int OSErr;
 typedef short int SInt16;