Example #1
0
bool MappyLevel::Load(char* levelName, GameObject* cameraTarget){

	char path[MAX_PATH_LENGTH];

	for(int i = 0; i < MAX_PATH_LENGTH; i++)
		path[i] = '\0';

	strcat(path, LEVEL_DIRECTORY);
	strcat(path, levelName);
	strcat(path, LEVEL_EXTENSION);

	bool successful = false;
	if(!MapLoad(path, 1))
		successful = true;
	
	layerCount = 0;
	while(MapChangeLayer(layerCount) != -1)
		layerCount++;
	MapChangeLayer(0);


	this->cameraTarget = cameraTarget;

	GraphicsCore::SetMapDimensions(mapwidth, mapheight);
	GraphicsCore::SetMapTileDimensions(mapblockwidth, mapblockheight);

	return successful;
		
	
	
}
Example #2
0
void loadlevel()
{extern int level;
if (level == 1)
   { //load the map
	if (MapLoad("reallevel.fmp")) exit(0);	

    //create the double buffer
	buffer = create_bitmap (WIDTH, HEIGHT);
	clear(buffer);}
if (level == 2)
    {//load the map
	if (MapLoad("tst.fmp")) exit(0);	

    //create the double buffer
	buffer = create_bitmap (WIDTH, HEIGHT);
	clear(buffer);}     
}
Example #3
0
bool RunGame(const CampaignOptions *co, struct MissionOptions *m, Map *map)
{
	// Clear the background
	DrawRectangle(
		&gGraphicsDevice, Vec2iZero(), gGraphicsDevice.cachedConfig.Res,
		colorBlack, 0);
	SDL_UpdateTexture(
		gGraphicsDevice.bkg, NULL, gGraphicsDevice.buf,
		gGraphicsDevice.cachedConfig.Res.x * sizeof(Uint32));

	MapLoad(map, m, co);

	// Seed random if PVP mode (otherwise players will always spawn in same
	// position)
	if (IsPVP(co->Entry.Mode))
	{
		srand((unsigned int)time(NULL));
	}

	if (!co->IsClient)
	{
		MapLoadDynamic(map, m, &co->Setting.characters);

		// For PVP modes, mark all map as explored
		if (IsPVP(co->Entry.Mode))
		{
			MapMarkAllAsVisited(map);
		}

		// Reset players for the mission
		CA_FOREACH(const PlayerData, p, gPlayerDatas)
			// Only reset for local players; for remote ones wait for the
			// client ready message
			if (!p->IsLocal) continue;
			GameEvent e = GameEventNew(GAME_EVENT_PLAYER_DATA);
			e.u.PlayerData = PlayerDataMissionReset(p);
			GameEventsEnqueue(&gGameEvents, e);
		CA_FOREACH_END()
		// Process the events to force add the players
		HandleGameEvents(&gGameEvents, NULL, NULL, NULL);

		// Note: place players first,
		// as bad guys are placed away from players
		Vec2i firstPos = Vec2iZero();
		CA_FOREACH(const PlayerData, p, gPlayerDatas)
			if (!p->Ready) continue;
			firstPos = PlacePlayer(&gMap, p, firstPos, true);
		CA_FOREACH_END()
		if (!IsPVP(co->Entry.Mode))
		{
			InitializeBadGuys();
			CreateEnemies();
		}
	}
Example #4
0
void GrafxMakeBackground(
	GraphicsDevice *device, DrawBuffer *buffer,
	CampaignOptions *co, struct MissionOptions *mo, Map *map, HSV tint,
	int isEditor, int buildTables, Vec2i pos, GrafxDrawExtra *extra)
{
	CampaignAndMissionSetup(buildTables, co, mo);
	MapLoad(&gMap, mo, &co->Setting.characters);
	InitializeBadGuys();
	CreateEnemies();
	MapMarkAllAsVisited(map);
	if (isEditor)
	{
		MapShowExitArea(map);
	}

	GrafxDrawBackground(device, buffer, tint, pos, extra);
}
int initialize(){
    allegro_init();
    install_timer();
    install_keyboard();
    set_color_depth(16);
    set_gfx_mode(MODE,WIDTH,HEIGHT,0,0);
    srand(time(NULL));
    buffer=create_bitmap(SCREEN_W,SCREEN_H);
    clear(buffer);
    if(install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,"")!=0){
        allegro_message("Error initializing sound system");
        return 0;
    }
    welcome=load_bitmap("welcome.bmp",NULL);
     instruction1=load_bitmap("instruction1.bmp",NULL);
     instruction2=load_bitmap("instruction2.bmp",NULL);
      instruction3=load_bitmap("instruction3.bmp",NULL);
       gameoverscreen=load_bitmap("gameover.bmp",NULL);
       if(!welcome || !instruction2 || ! instruction3 || !instruction1 || ! gameoverscreen){
        set_gfx_mode(GFX_TEXT,0,0,0,0);
        allegro_message("WELCOME BMPS MISSING");
        return 0;
       }
    //level1=load_sample("stage1.wav");
    /*if(!level1){
        allegro_message("No sound file");
        return 0;
    }*/
        if(MapLoad("level1.fmp")){
        set_gfx_mode(GFX_TEXT,0,0,0,0);
        allegro_message("Can't find level1.fmp");
        return 0;
    }
    LOCK_FUNCTION(timer1);
    LOCK_VARIABLE(ticks);
    LOCK_VARIABLE(framerate);
    LOCK_VARIABLE(counter);
    install_int(timer1,100);
    return 1;
}
int main(int argc, char *argv[])
{//start of main function

	//set gameover = true to stop the game from loading before the player plays
	GAMEOVER=true;

	//variable declerations
	int id;

	//variables used for the threads
	pthread_t pthread0;
    pthread_t pthread1;
    int threadid0 = 0;
	int threadid1 = 1;
	int threadid2 = 2;
	int threadid3 = 3;
	int threadid4 = 4;
	int threadid5 = 5;
	int threadid6 = 6;


	//set is intro to true to play the intro
	bool inIntro =true; 

	//variable used to display the players message
	char *playermessage;

	//map variables 
	int mapxoff = 0;
	int mapyoff = 0;

	//game speed variables declerations and initalization
	int frames_per_sec=0;
	int frames_done=0;
	int old_time =0;
	int totaltime=0;

	//declare allegro variables
	//BITMAP *buffer;
	BITMAP *intro;

	//initalize the classes
	//player *owl;
	sprite *hearts[3];
	sprhandler = new spritehandler();
	snake *snakeboss;

	//initalize allegro
	allegro_init();
	install_keyboard();
	install_timer();
	set_keyboard_rate(1000,1000);
	install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,NULL);

	//initalize the screen
	set_color_depth(COLORDEPTH);
	set_gfx_mode(MODE,WIDTH,HEIGHT,0,0);

	//lock both the varibale and the funciton to be used by the interrupt handler
	LOCK_VARIABLE(ticks);
	LOCK_FUNCTION(ticker);
	//install the interrupt handler which calls the ticker 60 times a second
	install_int_ex(ticker,BPS_TO_TIMER(FPS));
	
	//lock both the varibale and the funciton to be used by the interrupt handler
	//these 
	LOCK_VARIABLE(gametime);
	LOCK_FUNCTION(game_time_ticker);
	
	//install the interrupt handler which calls the game time ticker
	//game time ticker is in 10ths of seconds
	install_int_ex(game_time_ticker,BPS_TO_TIMER(10));

	//create back buffer
    buffer = create_bitmap(SCREEN_W, SCREEN_H);

	//create the intro screen by loading the bitmap into the intro buffer
	intro = load_bitmap("flightless title.bmp",NULL);
	if(!intro){
		allegro_message("Error loading intro image");
		return 1;
	}

	//seed the random function
	srand(time(NULL));
	
	//load fonts
	FONT *dicot_22_font;
	PALETTE palette;
	
	//load the the font for the header of the application
	dicot_22_font = load_font("dicot_22.pcx", palette, NULL);
	
	//load and display the intro screen
	while(inIntro)
	{
		//display the intro screen for the game
		blit(intro,screen,0,0,0,0,SCREEN_W,SCREEN_H);
		
		//wait for the player to press enter to start the game
		if(key[KEY_ENTER]){
			inIntro=false;
			GAMEOVER=false;
		}
		
		//if the player presses esc then exit the game and the intro
		if(key[KEY_ESC]){
			inIntro=false;
			GAMEOVER=true;
		}
	}
	//for as many badies make sprites to hold the bugs
	for(int i=0;i<BADIES;i++)
	{
			//initalize the bug sprite
			 bug[i] = new bugs();

			//load the bug sprite sheet
			if(!bug[i]->load("bug.bmp")){
			allegro_message("Error loading bug sprite");
			return 1;
			}

			//initalize the bug propertys
			bug[i]->init();
			
			//add sprites to the sprite handler
			sprhandler->addbugs(bug[i]);
	}
	//initalize the player
	owl = new player();

	//load the players sprite sheet
	if(!owl->load("owl sprite_new.bmp")){
		allegro_message("Error loading owl sprite");
		return 1;
	}
	
	//initalize the sprite properties
	owl->init();

	//add the player object to the sprite handler
	sprhandler->addsprite(owl);

	//create the new snake object
	snakeboss = new snake();

	//load the snake
	if(!snakeboss->load("snake_Tiles.bmp")){
		allegro_message("Error loading snake sprite");
		return 1;
	}
	//initalize the snake
	snakeboss->init();
	//snakeboss->alive=false;

	//add the snake to the sprite handler
	sprhandler->addboss(snakeboss);

	//create for loop to load the players health indicator
	for(int i=1;i<4;i++)
	{
		//create new sprite objects to hold the images
		hearts[i-1] = new sprite();

		//load the players health image
		if(!hearts[i-1]->load("FullHealth.bmp")){
			allegro_message("Error loading player Health");
			return 1;
		}
			//set sprite properties
			hearts[i-1]->x = SCREEN_W-35*i;
			hearts[i-1]->y = 10;
			hearts[i-1]->width = 30;
			hearts[i-1]->height = 30;
			hearts[i-1]->velx = 0;
			hearts[i-1]->vely = 0;
			hearts[i-1]->animcolumns = 0;
			hearts[i-1]->curframe = 0;
			hearts[i-1]->totalframes =1;
			hearts[i-1]->animdir = 0;
			//object type of non moving sprite
			hearts[i-1]->objecttype=2;
			hearts[i-1]->alive=0;

		//add the players health to the sprite handler
		sprhandler->addsprite(hearts[i-1]);
	}
	

	//create the music samples
	SAMPLE *ingamesong;

	//load the wav file into the samples
	//main game soundtrack
	ingamesong=load_sample("melo-24_Clip.wav");
	if(ingamesong==NULL){
			allegro_message("Error loading game soundtrack");
			return 1;
	}

	//use mappy.h global function MapLoad to load the .FMP file
	MapLoad("flightless.FMP");
	
	//play the sample music
	int playing = play_sample(ingamesong,150,125,1000,true);

	//start the clock to time the player
	startTime = time(NULL);

	//create the thread for player
    id = pthread_create(&pthread0, NULL, playerdraw_thread, (void*)&threadid5);

	//create the thread for the bugs
	id = pthread_create(&pthread1, NULL, wormdraw_thread, (void*)&threadid0);
	id = pthread_create(&pthread1, NULL, wormdraw_thread, (void*)&threadid1);
	id = pthread_create(&pthread1, NULL, wormdraw_thread, (void*)&threadid2);
	id = pthread_create(&pthread1, NULL, wormdraw_thread, (void*)&threadid3);
	id = pthread_create(&pthread1, NULL, wormdraw_thread, (void*)&threadid4);

	//create the thread to draw the snake
	id = pthread_create(&pthread1, NULL, snakedraw_thread, (void*)&threadid0);

	//main game loop
	while (!GAMEOVER)
	{		

		while (ticks==0)
		{
			rest(1);
		}
		while(ticks>0)
		{
			if(key[KEY_ESC])
			{
				playermessage="You quit :( Please come back again.";
				GAMEOVER=true;
			}
			
			//get the previous value of ticks and store them
			old_ticks=ticks;

			//each time we hit this loop we increment the mapxoffset +1 			
			if(mapxoff<mapwidth*mapblockwidth)
			{
				//if the player is not hiding update the map
				if(owl->state!=2)
				{
					mapxoff++;
				}
			}
			//draw the background tiles via the mappy global funciton MapDrawBG
			MapDrawBG(buffer,mapxoff,0,0,0,WIDTH-1,HEIGHT-1);
	
			//draw the players health indicator based on the owls health/30
			for (int i=0;i<((owl->health)/30);i++)
			{
				hearts[i]->draw(buffer);
			}
			
			//lock the varibales to protect them from the unsynced threads
			pthread_mutex_lock(&threadsafe);

			//get the player input
			owl->getinput();	

			sprhandler->updatebugs();
			sprhandler->updatesnake();

			//decrement the ticks
			ticks--;
			
			//unlock the mutex
			pthread_mutex_unlock(&threadsafe);
			//if the logic is taking too long abort and draw the screen
			if(old_ticks<=ticks)
				break;
		}
		//for every second that passess we need to call this function
		if(gametime - old_time >= 10)
		{
			//frames_per_sec holds the number of frames drawn in the last sec
			frames_per_sec = frames_done;

			//reset these variables for the next second
			frames_done =0;
			old_time=gametime;
		}
		//Decrement the players health
		if(gametime%120==0)
		{
 			owl->takedamage(2);
		}
		if(sprhandler->getsnakes(0)->alive==false && gametime%400==0)
		{
			sprhandler->getsnakes(0)->resurrect();
		}
		//check players health
		if(owl->health<=0)
		{
			playermessage="You have died...please remeber to eat next time.";
			GAMEOVER=true;
		}
		//stop the window from scrolling
		if(GAMEOVER==true ||mapxoff>=mapwidth*mapblockwidth-WIDTH)
		{
			if(mapxoff>=mapwidth*mapblockwidth-WIDTH)
				playermessage="Great job player you passed the game! Way to go.";
			//stop the map from moving
			mapxoff=mapwidth*mapblockwidth-WIDTH;
			
			//stop the music from playing
			stop_sample(ingamesong);

			//create the music samples
			SAMPLE *cheer=NULL;
	
			//load the wav file into the sample
			cheer=load_sample("app.wav");
			if(cheer==NULL){
					allegro_message("Error loading game soundtrack");
					return 1;
				}

			//play the sample music
			play_sample(cheer,255,125,1000,true);

			//message the player...even if they are a quiter!
			textprintf_ex(screen,dicot_22_font,200,SCREEN_H/2,makecol(255,0,0),-1,playermessage);

			rest(2000);
 	  	 	GAMEOVER=true;
		}
		//show frames fer second on the screen by pressing "cntrl f"
		if(key[KEY_F])
		{
			if(key_shifts & KB_CTRL_FLAG)
			{
				//switch the showFPS flag to display the FPS
				SHOWFPS=!SHOWFPS;
			}
			//SHOWFPS=SHOWFPS;
		}
		if(SHOWFPS==true)
			textprintf_ex(buffer,font,20,20,WHITE,0,"frames= :%d",frames_per_sec);

		if(key[KEY_H])
		{
			if(key_shifts & KB_CTRL_FLAG)
			{
				//switch the SHOWHEALTH flag to display the FPS
				SHOWHEALTH=!SHOWHEALTH;
			}
			//SHOWHEALTH=SHOWHEALTH;
		}
		
      
		//update the screen using a double buffering technique
		acquire_screen();

		blit(buffer,screen,0,0,0,0,WIDTH,HEIGHT);
		release_screen();
		
		//everytime we bilt from buffer to screen increase frames_done
		frames_done++;
    }
	
	//find the time that the game ended
	endTime = time(NULL);

		//kill the mutex (thread protection)
    pthread_mutex_destroy(&threadsafe);

	//call to create the final image to present to the user
 	create_close(buffer,dicot_22_font,owl);
	
	//Garbage Collection clean up all of the objects that are being used in memory
	remove_keyboard();
	remove_timer();
	
	//destory the bitmaps that we are using
	destroy_bitmap(buffer);
	destroy_bitmap(intro);

	//destroy the map
	MapFreeMem();

	//delete the sprites
	delete sprhandler;

	//call to allegro exit
	allegro_exit();
	return 0;

}//end of main
Example #7
0
//Main codee
//
int main(void){

	int mapxoff, mapyoff;
	int oldpy, oldpx;
	int titleX, titleY;
	int facing = 0;
	int jump = JUMPIT;
	int n, VOLUME = 128, PAN = 128, PITCH = 1000;

	//general initialize
	allegro_init();

	install_timer();

	install_keyboard();

	set_color_depth(16);

	set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0);
	
	set_window_title(" . . .J.U.M.P.E.R. . .     :: Ryan Bridglal ::");


	
	//
	//sound init
	install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, "");

	//load title
	title = load_bitmap("title.bmp", NULL);
	
	//gameOver = load_bitmap("gameover.bmp", NULL);

	// load the player sprite
	temp = load_bitmap("player.bmp", NULL);
	for (n=0; n < 8; n++)
	player_image[n] = grabframe(temp, 50, 64, 0, 0, 8, n);
	destroy_bitmap(temp);


	// load the sound file
	music = load_sample("music.wav");
	
	//jumpSound = load_sample("jump.wav");

	// initialize the sprite
	player = new SPRITE;
	player->x = 80;
	player->y = 100;
	player->curframe = 0;
	player->framecount = 0;
	player->framedelay = 6;
	player->maxframe = 7;
	player->width = player_image[0]->w;
	player->height = player_image[0]->h;


	// load the map
	MapLoad("map.FMP");

	// create the double buffer
	buffer = create_bitmap(WIDTH, HEIGHT);
	clear(buffer);
	
	//always play background music
	play_sample(music, VOLUME, PAN, PITCH, FALSE);



	// main loop
	while(!key[KEY_ESC]) {
		
		oldpy = player->y;
		oldpx = player->x;


		//
		// PLAYER controls
		//
		//right keypress
		if (key[KEY_RIGHT]) {
			clear_to_color(title, makecol(80, 80, 248));
			facing = 1;
			player->x += 2;
			
			if (++player->framecount > player->framedelay) {
				player->framecount = 0;
				
				if (++player->curframe > player->maxframe)
					player->curframe = 1;
			}
		}
		
		
		//left keypress
		else if (key[KEY_LEFT]) {
			clear_to_color(title, makecol(80, 80, 248));
			facing = 0;
			player->x -= 2;
			
			if (++player->framecount > player->framedelay) {
				player->framecount = 0;
				
				if (++player->curframe > player->maxframe)
					player->curframe = 1;
			}
		}
		
		
		else player->curframe = 0;

		// handle jumping
		if (jump == JUMPIT){
		
			if (!collided(player->x + player->width/2, player->y + player->height + 5))
				jump = 0;

			if (key[KEY_SPACE]) 
				jump = 30;
			//play_sample(jumpSound, VOLUME, PAN, PITCH, FALSE);
			    
		}
		
		else {
		     	player->y -= jump/3;
		     	jump--;
		}

		if (jump < 0){
			
			if (collided(player->x + player->width/2, player->y + player->height)) {
				jump = JUMPIT;
				while (collided(player->x + player->width/2, player->y + player->height))
					player->y -= 2;
			}
		}
		
		
		///
		//collision detection
		// player collision detect with map
		if (!facing) {
		
			if (collided(player->x, player->y + player->height))
				player->x = oldpx;
		}
		
		else {
		
			if (collided(player->x + player->width, player->y + player->height))
				player->x = oldpx;
		}


		// update the map scroll position
		mapxoff = player->x + player->width/2 - WIDTH/2 + 10;
		mapyoff = player->y + player->height/2 - HEIGHT/2 + 10;

		// avoid moving beyond the map edge
		if (mapxoff < 0) 
			mapxoff = 0;
		
		if (mapxoff > (mapwidth * mapblockwidth - WIDTH))
			mapxoff = mapwidth * mapblockwidth - WIDTH;
		
		if (mapyoff < 0) 
			mapyoff = 0;
		
		if (mapyoff > (mapheight * mapblockheight - HEIGHT))
			mapyoff = mapheight * mapblockheight - HEIGHT;


		//
		//Draw things

		// draw the background tiles
		MapDrawBG(buffer, mapxoff, mapyoff, 0, 0, WIDTH - 1, HEIGHT - 1);

		// draw the foreground tiles
		MapDrawFG(buffer, mapxoff, mapyoff, 0, 0, WIDTH - 1, HEIGHT - 1, 0);

		// draw the player's sprite
		if (facing)
			draw_sprite(buffer, player_image[player->curframe], (player->x - mapxoff), (player->y - mapyoff));
		
		else
			draw_sprite_h_flip(buffer, player_image[player->curframe], (player->x - mapxoff), (player->y - mapyoff));


		//load title
		//draw_sprite(screen, title, 160, 20);
		 //draw_sprite(buffer, title[titleSprite->curframe], (title->titleX - mapxoff), (title->y - mapyoff));
		blit(title, screen, 0, 0, 0, 0, 640, 480);


		// blit the double buffer
		vsync();
		acquire_screen();
		blit(buffer, screen, 0, 0, 0, 0, WIDTH - 1, HEIGHT - 1);
		release_screen();


		
	}// endwhile
	//	else {
	//				blit(gameOver, screen, 0, 0, 0, 0, 640, 480); 
	//}

	gameOver();


	// clean up
	for (n = 0; n < 8; n++)
		destroy_bitmap(player_image[n]);
		delete player;
		delete title;

	//	for (n=0; n<NUM_SOUNDS; n++)
	//		destroy_sample(sounds[n]);


		destroy_sample(music);
	//	destroy_sample(jumpSound);
		destroy_bitmap(title);
		destroy_bitmap(buffer);
		
		MapFreeMem();

		remove_sound();
		allegro_exit();

		return 0;

}
Example #8
0
static void Campaign(GraphicsDevice *graphics, CampaignOptions *co)
{
	if (IsPasswordAllowed(co->Entry.Mode))
	{
		MissionSave m;
		AutosaveLoadMission(
			&gAutosave, &m, co->Entry.Path, co->Entry.BuiltinIndex);
		co->MissionIndex = EnterPassword(graphics, &m);
	}
	else
	{
		co->MissionIndex = 0;
	}

	bool run = false;
	bool gameOver = true;
	do
	{
		CampaignAndMissionSetup(1, co, &gMission);

		if (IsGameOptionsNeeded(gCampaign.Entry.Mode))
		{
			debug(D_NORMAL, ">> Game options\n");
			if (!GameOptions(gCampaign.Entry.Mode))
			{
				run = false;
				goto bail;
			}
			gCampaign.OptionsSet = true;
		}

		// Mission briefing
		if (IsMissionBriefingNeeded(co->Entry.Mode))
		{
			if (!ScreenMissionBriefing(&gMission))
			{
				run = false;
				goto bail;
			}
		}

		// Equip guns
		if (!PlayerEquip())
		{
			run = false;
			goto bail;
		}

		// Initialise before waiting for game start;
		// server will send us messages
		GameEventsInit(&gGameEvents);

		if (gCampaign.IsClient)
		{
			if (!ScreenWaitForGameStart())
			{
				run = false;
				goto bail;
			}
		}

		MapLoad(&gMap, &gMission, co);

		// Seed random if PVP mode (otherwise players will always spawn in same
		// position)
		if (IsPVP(co->Entry.Mode))
		{
			srand((unsigned int)time(NULL));
		}

		if (!gCampaign.IsClient)
		{
			MapLoadDynamic(&gMap, &gMission, &co->Setting.characters);
			// Note: place players first,
			// as bad guys are placed away from players
			StartPlayers(ModeMaxHealth(co->Entry.Mode), co->MissionIndex);
			AddAndPlacePlayers();
			if (!IsPVP(co->Entry.Mode))
			{
				InitializeBadGuys();
				CreateEnemies();
			}
		}
		MusicPlayGame(
			&gSoundDevice, gCampaign.Entry.Path, gMission.missionData->Song);
		run = RunGame(&gMission, &gMap);
		// Don't quit if all players died, that's normal for PVP modes
		if (IsPVP(co->Entry.Mode) && GetNumPlayers(true, false, false) == 0)
		{
			run = true;
		}
		GameEventsTerminate(&gGameEvents);

		const int survivingPlayers = GetNumPlayers(true, false, false);
		// In co-op (non-PVP) modes, at least one player must survive
		if (!IsPVP(co->Entry.Mode))
		{
			gameOver = survivingPlayers == 0 ||
				co->MissionIndex == (int)gCampaign.Setting.Missions.size - 1;
		}

		int maxScore = 0;
		for (int i = 0; i < (int)gPlayerDatas.size; i++)
		{
			PlayerData *p = CArrayGet(&gPlayerDatas, i);
			p->survived = IsPlayerAlive(p);
			if (IsPlayerAlive(p))
			{
				TActor *player = CArrayGet(&gActors, p->Id);
				p->hp = player->health;
				p->RoundsWon++;
				maxScore = MAX(maxScore, p->RoundsWon);
			}
		}
		if (IsPVP(co->Entry.Mode))
		{
			gameOver = maxScore == ModeMaxRoundsWon(co->Entry.Mode);
			CASSERT(maxScore <= ModeMaxRoundsWon(co->Entry.Mode),
				"score exceeds max rounds won");
		}

		MissionEnd();
		MusicPlayMenu(&gSoundDevice);

		if (run)
		{
			switch (co->Entry.Mode)
			{
			case GAME_MODE_DOGFIGHT:
				ScreenDogfightScores();
				break;
			case GAME_MODE_DEATHMATCH:
				ScreenDeathmatchFinalScores();
				break;
			default:
				ScreenMissionSummary(&gCampaign, &gMission);
				// Note: must use cached value because players get cleaned up
				// in CleanupMission()
				if (gameOver && survivingPlayers > 0)
				{
					ScreenVictory(&gCampaign);
				}
				break;
			}
		}

		// Check if any scores exceeded high scores, if we're not a PVP mode
		if (!IsPVP(co->Entry.Mode))
		{
			bool allTime = false;
			bool todays = false;
			for (int i = 0; i < (int)gPlayerDatas.size; i++)
			{
				PlayerData *p = CArrayGet(&gPlayerDatas, i);
				if (((run && !p->survived) || gameOver) && p->IsLocal)
				{
					EnterHighScore(p);
					allTime |= p->allTime >= 0;
					todays |= p->today >= 0;
				}

				if (!p->survived)
				{
					p->totalScore = 0;
					p->missions = 0;
				}
				else
				{
					p->missions++;
				}
				p->lastMission = co->MissionIndex;
			}
			if (allTime)
			{
				DisplayAllTimeHighScores(graphics);
			}
			if (todays)
			{
				DisplayTodaysHighScores(graphics);
			}
		}
		if (!HasRounds(co->Entry.Mode))
		{
			co->MissionIndex++;
		}

	bail:
		// Need to terminate the mission later as it is used in calculating scores
		MissionOptionsTerminate(&gMission);
	} while (run && !gameOver);

	// Final screen
	if (run)
	{
		switch (co->Entry.Mode)
		{
		case GAME_MODE_DOGFIGHT:
			ScreenDogfightFinalScores();
			break;
		default:
			// no end screen
			break;
		}
	}
}