We just released a Feb. 5 '89 prototype of DuckTales for the NES!
If you'd like to support our preservation efforts (and this wasn't cheap), please consider donating or supporting us on Patreon. Thank you!

NHL Breakaway 99 (Nintendo 64)/Uncompiled Source Code

From The Cutting Room Floor
Jump to navigation Jump to search

This is a sub-page of NHL Breakaway 99 (Nintendo 64).

One thing that NHL Breakaway 99 has that its predecessor didn't is source code remnants. Not only are remnants of the dev environment used to compile the game still on the ROM, but so is a large amount of code, and definitely more than enough so to justify this subpage. These fragments can be found at the hex addresses listed below.


(Source: Shygoo)

0xB35E6:

y=4096/15;

	while (1)  	{

		(*screenTask)();

		FntFlush(-1);
		Sleep(1);
	}

	Display_off();
	Die();

}






///////////////////////////////////////////////////////////////////////////
//
//	initFluff(void)
//
//	inits fluff stuff (menuing and crap)
//
///////////////////////////////////////////////////////////////////////////
void initFluff(void)
{
	int 	i;

	//
	// sound

	Debug_print(DEBUG_PRINT_SWITCH,"Fluff Init");

	WHICHOVERLAY = OVERLAY__FLUFF;

	//init cursor to 0
	scaleIn=1;
	cursorPos = 0;
	noWrap=0;  //init update cursor to wrap by default
	noStart=0;
	globalTintDup=0;
	fromMatchup=0;
	writeSettings=0;

	for(i=0;i<NUM_MENUS;++i)
		lastCursorPos[i]=0;
	for(i=0;i<MAX_FLUFF_ACTORS;++i)
		fluffActors[i]=NULL;
	for(i=0;i<8;++i)
		cardWriteActors[i]=NULL;

	simSeries=0;

	globalLeavingMenu=0;
	acceptingInput=0;
	//no BG's
	drawBG = 0;

	refName=(char *)allocMem(40);
	//NO menu currently defined...
	fluffMenuID = -1;

//init with no bg to free (in load BG)
	bgActor=(SIMPLE_ACTOR *)-1;
	bgActor1=(SIMPLE_ACTOR *)-1;


	playoffPlayMode=PLAYOFF_PLAY_GAME;
	getDefaultTeamStrategies();
	tradeTeamIDs[0]=TEAM_DETROIT;
	tradeTeamIDs[1]=TEAM_PHILADELPHIA;
	playoffTeamID=teamAlphaOrder[0];
	seasonTeamID=teamAlphaOrder[0];



	//load the settings file if there is one that contains these settings

	if (firstTimeEver) {
		Init_memcard_handler();
		// setup defaults
		Save_settings(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, DONT_WRITE_TO_CARD);
		initialAccessFailed = 1;

	}
	else {
		Reinit_memcard_handler();	// doesn't destroy current resident files
	}

	//default teams and options

	get_settings_last_teams(exhibitionTeamIDs);
	get_settings_options(exhibitionOptions);
	setVolume(exhibitionOptions);
	get_settings_buttons(&gamebut[0][0]);

	Set_digital_stick(ON);

	getDefaultCheats();
}


void initFluffFonts()
{
	font14 = Open_font((u_long)&FLFONT14);
	Font_spacing(-1);
	Font_linefeed(10);
	Font_pal16(0);
	Font_ot(hi_ot);
	Font_camera(fluffCamera);
	Font_window(-320,-120,320,240);

	font18 = Open_font((u_long)&FLFONT18);
	Font_spacing(-2);
	Font_pal16(0);
	Font_ot(hi_ot);
	Font_camera(fluffCamera);
	Font_window(-320,-120,320,240);

	font24 = Open_font((u_long)&FLFONT24);
	Font_spacing(-1);
	Font_pal16(0);
	Font_ot(hi_ot);
	Font_camera(fluffCamera);
	Font_window(-320,-120,320,240);
}

void fillDefaultRosters()
{
	int i;
	GenPtr	team_file;

	team_file.c	= Load_cdrom_file((u_long)&TEAM_ATTRIBUTES);
	team = team_file;
	check_file(&team, CDROM_TEAM_FILE_TYPE, sizeof(TEAM_INFO));

	for (i=0; i<TEAM_MAX; i++)
		*(teamInfo + i) =  *((TEAM_INFO*) (team.c + *(team.ul + i)));

	Unload_cdrom_file((u_long)&TEAM_ATTRIBUTES);
}

void fillDefaultAttributes()
{
	int i;

	for (i=0; i<numRomPlayers; i++) {
		Load_player_attribute(&playerAttributes[i],i);
	}
	for (; i<PLAYERS_MAX; i++) {
		playerAttributes[i].player_leagueid = i;
	}
}
void fillDefaultStats(int unload)
{
	int i;

	statsFilePtr = Load_cdrom_file((u_long)&ROM_STATS_FILE);
	ptr.v = statsFilePtr;
	if (!check_file(&ptr, CDROM_STAT_FILE_TYPE, sizeof(P_STAT)))
	{
		printf("Bad version");
	}
	ptr.l++;					// skip num_players
	players = (P_STAT*) ptr.v;

	for (i=0; i<numRomPlayers; i++)
		playerAttributes[i].stat = players[i];

//	if (unload)
//		Unload_cdrom_file((u_long)&ROM_STATS_FILE);
}

void zeroOutPlayerStats() {
	int	i;

	for (i=0; i<PLAYERS_MAX; i++) {
		memset(&playerAttributes[i].stat, 0, sizeof(P_STAT));
		playerAttributes[i].stat.status = STATUS_ON_BENCH;
	}
}


void loadFluffFiles(void)
{
	Load_cdrom_file((u_long)&DESCRBOX);	//loads the big file


//	initFluffFonts();

	teamInfo = (TEAM_INFO *) allocMem(sizeof(TEAM_INFO) * TEAM_MAX);
	get_settings_team_info(teamInfo);

//	attributeFilePtr = Load_cdrom_file((u_long)&PLAYER_ATTRIBUTES);
	attributeFilePtr = (GenPtr)Load_cdrom_file((u_long)&PLAYER_ATTRIBUTES);	//ASL
	Load_cdrom_file((u_long)&ROM_STATS_FILE);

	playerAttributes = (P_INFO *) allocMem(sizeof(P_INFO) * PLAYERS_MAX);
	memset(playerAttributes, 0, sizeof(P_INFO)*PLAYERS_MAX);

	numRomPlayers=Get_num_rom_players();
	fillDefaultAttributes();

	initHometowns();

// FRAG
	seasonTeamStats=allocMem(sizeof(TEAM_STAT)*(TEAM_MAX));
	//biggest schedule is 2690, so alloc 3K here to avoid fragmenting
	schedule_buffer = allocMem(3 * 1024);
//FRAG

//	Free_default_vram();
//	Init_palettes();			// PRW Free all palettes
//	Clear_vram(0,0,0);		// Clear VRAM
//	Auto_erase_on();

	initFluffFonts();

}

///////////////////////////////////////////////////////////////////////////
//
//	exitFluff(void)
//
//	deallocates all FLUFF stuff (menuing and crap)
//
///////////////////////////////////////////////////////////////////////////
void exitFluff(void)
{

	gf_draw_ready=0;
	Sleep(6);


	Save_settings(exhibitionOptions, NULL,
					  NULL, NULL,
					  NULL, NULL, exhibitionTeamIDs, NULL, DONT_WRITE_TO_CARD);

	if(playMode==PLAY_MODE_SEASON) {
		saveCompleteSeason(DONT_WRITE_TO_CARD);
	}
	else if (playMode == PLAY_MODE_PLAYOFFS) {
		saveCompletePlayoffs(DONT_WRITE_TO_CARD);
	}


	Shutdown_memcard_handler();

	//no BGs
	drawBG = 0;

	//close all fonts
	Close_all_fonts();

	//kill any global fluff cameras created
	Kill_actor(fluffCamera);

	Free_default_vram();
	Init_palettes();	// PRW Free all palettes


	freeMem(teamInfo);
	freeMem(playerAttributes);

	if(seasonTeamStats!=NULL)
		seasonTeamStats=freeMem(seasonTeamStats);
	free_schedule_data(&season);

	//FRAG
	if (schedule_buffer)
		schedule_buffer = freeMem(schedule_buffer);
	//FRAG

	killAllFluffActors();
	Kill_task(speedMenuTaskPtr);

	freeMem(refName);
	Unload_cdrom_file((u_long)&DESCRBOX);	//loads the big one
	Unload_cdrom_file((u_long)&ROM_STATS_FILE);
	Unload_cdrom_file((u_long)&TEAM_ATTRIBUTES);
	Unload_cdrom_file((u_long)&PLAYER_ATTRIBUTES);
	Unload_cdrom_file((u_long)&PLAYOFF_TICKER_STRING_FILE);
//	Unload_cdrom_file(currentBG);  //put it in the main fluff file


	Sleep(3);
#if DEBUG_PRINT_SWITCH
	ShowMemSysInfo2();
#endif
	if (WHICHOVERLAY == OVERLAY__MISC) {
		if (misc_menu != PF_GAME_CREDITS) {
			ie_SND_FadeOut ();
		}
	}
	else {
		ie_SND_FadeOut ();
		WHICHOVERLAY = OVERLAY__GAME;
	}�   È–B 				draw_firetrail = 0;
				break;
			}

			for ( i = MAX_TRAIL-1; (i > 0) && (!gf_pause) ; i--)
			{
				position[i].x = position[i-1].x;			
				position[i].y = position[i-1].y;			
				position[i].z = position[i-1].z;			
			}			

			position[0].x = FROM_PETES_COORD_SYS_2_MINE(puck->s3d.pos.x);
			position[0].y = FROM_PETES_COORD_SYS_2_MINE(puck->s3d.pos.y);
			position[0].z = FROM_PETES_COORD_SYS_2_MINE(puck->s3d.pos.z);

//			Debug_print(DEBUG_PRINT_SWITCH,"\npuck:%d, %d\n", position[0].x, position[0].y);
			
//			index = (index+1)&15;
			if ( (!gf_pause) && (++index == MAX_TRAIL) )
			{
				index = MAX_TRAIL - 1;
			}

			for ( i = 0; i < 3; i++)
			{
				(*dynamicp).firepuck[i].v.ob[0] = position[0].x;
				(*dynamicp).firepuck[i].v.ob[1] = position[0].y;
				(*dynamicp).firepuck[i].v.ob[2] = position[0].z;
				(*dynamicp).firepuck[i].v.flag = 0;
				(*dynamicp).firepuck[i].v.tc[0] = 3 << 6; 
				(*dynamicp).firepuck[i].v.tc[1] = 3 << 6;
				(*dynamicp).firepuck[i].v.cn[0] = r; 
				(*dynamicp).firepuck[i].v.cn[1] = g;
				(*dynamicp).firepuck[i].v.cn[2] = b;
				(*dynamicp).firepuck[i].v.cn[3] = 200;
			}


			(*dynamicp).firepuck[2].v.ob[0] = position[index].x;
			(*dynamicp).firepuck[2].v.ob[1] = position[index].y;
			(*dynamicp).firepuck[2].v.ob[2] = position[index].z;

			(*dynamicp).firepuck[0].v.ob[0] += xsize;
			(*dynamicp).firepuck[1].v.ob[0] -= xsize;
			(*dynamicp).firepuck[0].v.ob[1] += ysize;
			(*dynamicp).firepuck[1].v.ob[1] -= ysize;

			Sleep(1);
		}
	}
#ifdef __psx__

	Vector		position[MAX_TRAIL];
	POLY_G3		g3[2];

	long		i;
	short		angle;
	short		index;

	short		xsize;
	short		ysize;

	short		r,g,b;
	short 		transparent_rate;

	SVECTOR		pos[3];
	long		p,flag;




	transparent_rate = TRANSON2-1;

	for (i=0; i<2; i++)
		{
		SetPolyG3	(&g3[i]);
		SetShadeTex (&g3[i],SHADEON);
		SetSemiTrans(&g3[i],TRANSON);
		}

	while (1)
		{

		//
		// Bring on new FIREPUCKS, if puck is moving fast & free

		while ( (puck->control) || (puck->s3d.vel.x < INCH*6) )
			Sleep(1);


		for (i=0; i<MAX_TRAIL; i++)
			position[i] = puck->s3d.pos;

		angle = puck->s3d.move.z;

		//
		// What color should trail be?

		if (puck->s3d.vel.x > FOOT*3)
			{
			r = 255;
			g = 128;
			b = 0;
			}
		else
			{
			r = 0;
			g = 64;
			b = 255;
			}

		index = 0;

		//
		// Grow trail, until puck hits something

		while (1)
			{

			if ( (puck->control) || (angle != puck->s3d.move.z) || (puck->s3d.vel.x < INCH*6) )
				break;

			xsize	= Cos(ANGLE090 + puck->s3d.move.z) >>6;
			ysize	= Sin(ANGLE090 + puck->s3d.move.z) >>6;

			SetRotMatrix(&camera3d->rot);
			SetTransMatrix(&camera3d->rot);

			global_svector.vx	= (position[index].x - camera3d->s3d.pos.x) >>12;
			global_svector.vy	= (position[index].y - camera3d->s3d.pos.y) >>12;
			global_svector.vz	= (position[index].z - camera3d->s3d.pos.z) >>12;

			pos[0].vx = global_svector.vx;
			pos[0].vy = global_svector.vy;
			pos[0].vz = global_svector.vz;
			setRGB0(&g3[activeBuff], 0, 0, 0);


			global_svector.vx	= (puck->s3d.pos.x - camera3d->s3d.pos.x) >>12;
			global_svector.vy	= (puck->s3d.pos.y - camera3d->s3d.pos.y) >>12;
			global_svector.vz	= (puck->s3d.pos.z - camera3d->s3d.pos.z) >>12;

			pos[1].vx = global_svector.vx + xsize;
			pos[1].vy = global_svector.vy + ysize;
			pos[1].vz = global_svector.vz;

			pos[2].vx = global_svector.vx - xsize;
			pos[2].vy = global_svector.vy - ysize;
			pos[2].vz = global_svector.vz;

			setRGB1(&g3[activeBuff], r, g, b);
			setRGB2(&g3[activeBuff], r, g, b);

			RotTransPers3(	&pos[0],
							&pos[1],
							&pos[2],
							&g3[activeBuff].x0,
							&g3[activeBuff].x1,
							&g3[activeBuff].x2,
							&p, &flag);

			AddPrim(lo_ot->ot[activeBuff], &g3[activeBuff]);

			position[index] = puck->s3d.pos;
			index = (index+1)&15;

			Sleep(1);
			}
		}
#endif
}


///////////////////////////////////////////////////////////////////////////
//
//	void Task_players_faces(void)
//
//
///////////////////////////////////////////////////////////////////////////
#if 0

void Task_players_faces(void)
{
	#define MV_OUT		1
	#define MV_IN		2
	#define MV_TIME 	8
	#define MV_SPEED	(( (230<<12)-(190<<12) )/MV_TIME)

	long	i,j;

	long	ypos;
	short	team;
	short	angle;
	long	leagueid;

	LIST	*list;
	PLAYER	*player;

	FACE	*faces[ (TEAMS*PLAYERS) ];
	FACE	*thisface;
	char	*buffer;

	buffer	= allocMem(2048*3);

	//
	// Grab PAL & VRAM we need

	for (i=0;i<TEAMS;i++)
		{

		ypos	= -60<<12;

		for (j=0; j<PLAYERS; j++)
			{

			thisface = (FACE *) allocMem(sizeof(FACE));

			faces[ (i*PLAYERS)+j ] = thisface;

			memset(thisface,0,sizeof(FACE));

			Add_display_list(thisface, NULL);

			thisface->s3d.face.y	= ANGLE000;

			if (i == HOME)
				thisface->s3d.pos.x =-230<<12;
			else
				thisface->s3d.pos.x = 230<<12;

			thisface->s3d.pos.y = ypos;
			thisface->s3d.pos.z = SCR_Z<<12;

			thisface->pos_orig		= thisface->s3d.pos;
			thisface->pos_new		= thisface->s3d.pos;

			thisface->direction 	= MV_IN;
			thisface->location		= 0;
			thisface->playerid		= 0xff;	// Not assigned

			Set_display(thisface,BODY,camera2d);
			Set_prim(thisface,BODY,PRIM_POLYFT4);
			Set_scale(thisface,BODY,ONE/2,ONE/2,ONE/2);

			Allocate_vram(&last_sprite->vram, 40, 48, BIT8);

			last_sprite->vramdisplay.x = last_sprite->vram.x;
			last_sprite->vramdisplay.y = last_sprite->vram.y;
			last_sprite->vramdisplay.w = 40;
			last_sprite->vramdisplay.h = 48;

			last_sprite->bit		= BIT8;
			last_sprite->palette	= Get_unique_palette(NULL, 256);

			Set_frame(thisface,BODY,&SHRECTV);

			ypos += 28<<12;
			list = list->next;
			}
		}

	while (1)
		{

		list = allplayers;

		while (list)
			{
			player	= (PLAYER *) list->data;

			thisface	= faces[player->actor];

			if (thisface->playerid != player->playerid)
				{
				TIM_IMAGE	tim_image;

				thisface->playerid = player->playerid;

				leagueid = player_info[player->team][player->playerid].player_leagueid;


				Load_file(DATA_TFLUFF_FACES_FACES_BIN, buffer, leagueid*3, 2048*3);
				CQ_sleep(NONE);

				Set_display(thisface,BODY,camera2d);

				OpenTIM(buffer);
				ReadTIM(&tim_image);
				LoadImage(&last_sprite->vramdisplay, tim_image.paddr);

				//
				// Download new PALETTE
		
				Get_palette_vram_location(last_sprite->palette);
				global_numcolors = 256;
				Download_palette(tim_image.caddr);
				Sleep(1);
				}
			angle		= thisface->s3d.face.y;

			//
			// Where should face be?

			if (player->ai.control < CONTROL_CPU)
				thisface->direction = MV_OUT;
			else
				thisface->direction = MV_IN;


			if ( (thisface->direction == MV_IN) && (thisface->location > 0) )
				{
				thisface->location--;

				if (player->team == HOME)
					thisface->s3d.pos.x -= MV_SPEED;
				else
					thisface->s3d.pos.x += MV_SPEED;
				}

			if ( (thisface->direction == MV_OUT) && (thisface->location < MV_TIME) )
				{
				thisface->location++;

				if (player->team == HOME)
					thisface->s3d.pos.x += MV_SPEED;
				else
					thisface->s3d.pos.x -= MV_SPEED;
				}

			list = list->next;

			}
		Sleep(1);
		}
}
#endif


///////////////////////////////////////////////////////////////////////////
//
// void Task_spray_ice
//
// Sprays a bunch of ice chips, caused by a player STOPPING hard.
//
//	For optimal speed, icesprays are specific to PSX
//
///////////////////////////////////////////////////////////////////////////

ICESPRAY	*icememory	= NULL;
ICESPRAY	*icefree	= NULL;
ICESPRAY	*iceactive	= NULL;

void Init_ice_spray(void)
{
	#ifdef __psx__
	ICESPRAY	*ice;
	long		i,j;

	//Debug_print(ON,"Allocating ICESPRAY BUFFER %d\n",sizeof(ICESPRAY)*MAX_ICE_SPRAY);

	icememory 	= allocMem( sizeof(ICESPRAY)*MAX_ICE_SPRAY );

	icefree		= icememory;

	iceactive	= NULL;

	ice = icefree;

	for (i=0; i<MAX_ICE_SPRAY; i++)
		{

		ice->next = ice+1;

		for (j=0; j<2; j++)
			{
			SetPolyG3	(&ice->polyg3[j]);				// Init this poly�   <„B ��þ.      ��(&«` -----------------------------------

	// PRW
	// Auto bg erase ON
	Auto_erase_on();

	Add_display_list(camera3d, Scan_all);





	if (playMode == PLAY_MODE_SHOOTOUT)
		gf_shootout = ON;
	else
		gf_shootout = OFF;


	Xfer(Task_hockey);

human_linechange(player);
				else
					Test_auto_linechange(player->team);

				list = list->next;
				}

			Sleep(1);
			}

//		gf_goal_scored	= NO;

		}
}


///////////////////////////////////////////////////////////////////////////
//
// void Kill_hockey(void)
//
//	Kill the whole damm thing.
//
///////////////////////////////////////////////////////////////////////////

void Kill_hockey(void)
{
	LIST	*list;
	PLAYER	*player;
	char	i;
	int j;
	TASK *message_task;

	Set_digital_stick(OFF);	//fix preston's bug with analog controller stuck in down

	ie_CNT_InitFeedback();  //initialize rumble packs
	for(i=0;i<MAX_PADS;++i)
	ie_CNT_Feedback(i,FEEDBACK_HIT_OFF);
	message_task=Spawn256(TID_FLUFF,Task_message_card);
	Pass_task1( (TASK*)task_spawn, 1);
	while (Find_task(message_task))Sleep(1);
	gf_waiting_for_message=OFF;

	//
	// Wait until CDROM QUEUE is empty

//	CQ_sleep(NONE);

	Display_off();		

	gf_draw_ready=0;
	Sleep(6);
	gf_in_fluff=1;


	glass_broken_tris=0;
	for ( j = 0; j < NUMBER_OF_FRAME_BUFFERS; j++)
	{
		if((*dynamic[j]).glass_verts)
			(*dynamic[j]).glass_verts=freeMem( (*dynamic[j]).glass_verts );
		if((*dynamic[j]).glass_dl)
			(*dynamic[j]).glass_dl=freeMem( (*dynamic[j]).glass_dl );
	}

	if(broken_glass_tri_list)
		broken_glass_tri_list=freeMem(broken_glass_tri_list);


	//
	// Kill announcer

//	Kill_Speaker();

	//
	// Kill misc memory related to players.

	list = allplayers;
	while (list)
		{
		player = (PLAYER*) list->data;

		Kill_picon(player);

		Kill_arrow(player);

		list = list->next;
		}

	for (i=0;i<TEAMS;i++)
		{
		while (1)
			{

			player = Add_player(i);

			if (player)
				Kill_actor (player);
			else
				break;

			}
		}

	//
	// Kill all children task of the main hockey task. This kills
	// a shit load of junk (cameras, ai tasks, track tasks, etc etc etc)
	//
	// Should only leave the following tasks.
	//
	// 1: This task
	// 2: Joypad reader
	// 3: Draw task (draw task)

	Kill_children(n64Main,TID_MASK_ALL,TID_MASK_ALL);
	Kill_children(task_draw,TID_MASK_ALL,TID_MASK_ALL);
	Kill_children(task_main,TID_MASK_ALL,TID_MASK_ALL);
	Clear_display_list();

	//
	// Kill PAUSE menu stuff

	Kill_pause_menu();

	//
	// Kill the 2d camera

	Kill_actor_fast(camera2d);
	Kill_icon_passing();
	Kill_ice_spray();
	Kill_stancup();
	IR_kill();						// Kill IR buffer

	Free_bjersey_memory();			// Free memory used to store textures of players BACK JERSEYS

//	freeMem(amp_buffer);			// Free buffer for MOTION DATA
  Unload_cdrom_file((u_long)&s60104a);
	
	Unload_cdrom_file((u_long)(&GAMELOGOS+_SETFILE((teamid[HOME]*2)+PAL_MODE_HOCKEY)));
	Unload_cdrom_file((u_long)(&GAMELOGOS+_SETFILE((teamid[AWAY]*2)+PAL_MODE_HOCKEY)));


//	Unload_cdrom_file(&RINK_GLASS);		// Unload models

//	Unload_cdrom_file((u_long)&REF_ANIM);			// Unload fluff
	Unload_cdrom_file((u_long)&FONT_5);
	Unload_cdrom_file((u_long)&FONT_7);
	Unload_cdrom_file((u_long)&FONT_SCORE);
	Unload_cdrom_file((u_long)&FONT_NEWSHIRT4);
	Unload_cdrom_file((u_long)&FONT_MONO4);
	Unload_cdrom_file((u_long)&FONT24NEW);
	Unload_cdrom_file((u_long)&N64SCOREBOX);
  Unload_cdrom_file((u_long)&GAME_FACE);
  Unload_cdrom_file((u_long)&STICK3_REPLAY);
  Unload_cdrom_file((u_long)&PAUSE_TINT_BOX);

	Unload_cdrom_file((u_long)&REFEREE_DL);
	Unload_cdrom_file((u_long)&PUCK_DL);
	Unload_stadium();

//	Unload_cdrom_file(&SPOTLITE_VTX);
//	Unload_cdrom_file(&STANCUP_VTX);

	Init_font_driver(0);				// Clr font memory

	//
	// STOP all sounds


	if (Won_stanley_cup(HOME) || Won_stanley_cup(AWAY) )
		{
			//
			// we won the cup

//			WHICHOVERLAY	=	OVERLAY__MISC;
//			misc_menu = PF_STANLEY_CUP_MOVIE;
				gf_fluff_stanley_cup_won=1;
	�   D„B ; // Count # wins, for all periods thus far.
		total	= 0; // Total faceoffs thus far.

		for (i=0; i<period; i++)
			{
			won		+= game_stat[team][i].faceoff_won;
			total	+= game_stat[team][i].faceoff;
			}

		percent = (won*100)/total;
		sprintf(string2,"%s %d for %d (%d{)",STR_TEAM_CITY[teamid[team]],won,total,percent);

		//
		// Add scorebox watermark

		Set_display(message,BODY,camera2d);
		Set_prim(message,BODY,PRIM_POLYFT4);
		Set_scale(message,BODY,12000,2*ONE,ONE);
		Set_OT(message,BODY,hi_ot);
//		Set_ftex(message, BODY, FTEX_MESSAGE);
		Set_frame(message, BODY, &N64MESSAGE);

		//
		// Add team logo

		Set_display(message,HEAD,camera2d);
		Set_prim(message,HEAD,PRIM_SPRT);
		Set_OT(message,HEAD,hi_ot);
		last_sprite->vramdisplay = teamlogo_rect[team];
		last_sprite->bit		 = BIT8;
		last_sprite->palette	 = teamlogo_pal[team];
		Set_frame(message,HEAD,&SHRECTV);
		last_sprite->palette	 = -1;
		Set_offset(message,HEAD,-120,0,0);

		Add_display_list(message,Scan_message);

		Set_position (message,-512<<12, 80<<12, SCR_Z<<12);
		Message_track(message,   0<<12, 80<<12,4);

		for (i=0; i<HOLDTIME+30;i++)
			{
			Select_font(font7);
			if (i&4)
				Font_rgb(0,0,-128);
			Font_position_actor(message,-String_width(string1)/2,-10);
			Font_scale(ONE,ONE);
		  	Font_print(string1);
			Font_rgb(0,0,0);

			Select_font(font5);
			if (i&2)
				Font_rgb(-128,0,-128);
			Font_position_actor(message,-String_width(string2)/2, 2);
			Font_scale(ONE,ONE);
		  	Font_print(string2);
			Font_rgb(0,0,0);

			if (i==HOLDTIME)
				Message_track(message, 512<<12, 80<<12,4);

			Sleep(1);
			}
		Kill_actor(message);
		}
	gf_bottom_message_up=0;

	Die();
}


////////////////////////////////////////////////////////////
//
//	void Task_message_penalty_report(PENALTY *pen)
//
//
//
////////////////////////////////////////////////////////////

void Task_message_penalty_report(PENALTY *pen)
{
	#define	HOLDTIME	120

	FACE_ACTOR	*message;
	char		*fname;
	char		*lname;
	char		*penalty;

	char		string1[128];
	char		string2[128];

	char		clock[16];
	char		time[16];
	long		i;
	long		id_local;
	short		elapsed;
	short		leagueid;

	id_local = ++id_message_big;

	message = (FACE_ACTOR *) Create_actor( sizeof(FACE_ACTOR), NULL);
	gf_bottom_message_up=1;

	if (message)
		{

		Set_position (message,-512<<12, 80<<12, SCR_Z<<12);

		Add_display_list(message,Scan_message);

		//
		// Load players face
		leagueid= player_info[pen->team][pen->playerid].player_leagueid;
		Load_player_face(gameFacePtr, leagueid);

		//
		// Grab some info about penalty
		fname	= player_info[pen->team][pen->playerid].attrib.fname;
		lname	= player_info[pen->team][pen->playerid].attrib.lname;
		penalty	= STR_PENALTY[pen->call];
		elapsed = Elapsed_time(game_clock,period);

		//
		// Generate a string for the TIME OF PENALTY
		sprintf(clock,"%d:%02d",elapsed/60, elapsed%60);


		// Generate a string for the DURATION of penalty
		sprintf(time,"%d:%02d",pen->timer/60, pen->timer%60);

		sprintf(string1,"%s for %s", time, STR_PENALTY[pen->call] );
		sprintf(string2,"%s %s at %s",fname,lname,clock);

		//
		// Add scorebox watermark

		Set_display(message,BODY,camera2d);
		Set_prim(message,BODY,PRIM_POLYFT4);
		Set_scale(message,BODY,7168*2,ONE*2,ONE);
		Set_OT(message,BODY,hilo_ot);
//		Set_ftex(message, BODY, FTEX_MESSAGE);
		Set_frame(message, BODY, &N64MESSAGE);

		//
		// Add team logo

		Set_display(message,HEAD,camera2d);
		Set_prim(message,HEAD,PRIM_SPRT);
		Set_OT(message,HEAD,hilo_ot);
		last_sprite->vramdisplay = teamlogo_rect[pen->team];
		last_sprite->bit		 = BIT8;
		last_sprite->palette	 = teamlogo_pal[pen->team];
		Set_frame(message,HEAD,&SHRECTV);
		last_sprite->palette	 = -1;
		Set_offset(message,HEAD,-150,0,0);

		//
		// Add player face

		Set_display(message,LEG,camera2d);
		Set_prim(message,LEG,PRIM_POLYFT4);
		Set_offset(message,LEG,176,0,0);
		Set_OT(message,LEG,hi_ot);
//		Set_scale(message,LEG, 2731, 2731, 2731);
		Set_scale(message,LEG, 2731, 2700, 2731);
		Set_frame(message,LEG,&GAME_FACE);	// A dummy TIM

		//
		// Bring on the message...

		Message_track(message,   0<<12, 80<<12,4);

		for (i=0; i<HOLDTIME+30;i++)
			{
			Select_font(font7);

		

0xD9018:

//
					// Any special collision checks needed?

					switch (Action(player,BODY))
						{
						case ACT_PLAYER_CHECK_STICK:

							if ((player->interact == NULL) || (player->interact == player2) )
								{
								distx = ABS(player->stick.x - player2->s3d.pos.x);
								disty = ABS(player->stick.y - player2->s3d.pos.y);

								if ( (distx < FOOT*4) && (disty < FOOT*4) )
									{
									Change_action_fall(player,player2);

									Set_parse_var(player2,BODY,(Get_parse_var(player2,BODY)+4)&7);

									player->interact = player2;
									Lock_player(player2, player, &player->stick, 2);
									}
								}
							break;

						case ACT_PLAYER_CHECK_PUSH:
							distx = ABS(player->stick.x - player2->s3d.pos.x);
							disty = ABS(player->stick.y - player2->s3d.pos.y);

							if ( (distx < FOOT*4) && (disty < FOOT*4) )
								{
								Change_action_fall(player,player2);
								player2->s3d.vel.x	= Random_min_max(INCHs*2,INCHs*4)<<12;
								player2->s3d.move.z	= Bearing(&player->s3d.pos,&player2->s3d.pos);
								}
							break;

						case ACT_PLAYER_CHECK_HOLD:

							if ((player->interact == NULL) || (player->interact == player2))
								{
								if (Action_type2(player2,BODY) != ACT_PLAYER_DISABLED_DOWN)
									{
									distx = ABS(player->stick.x - player2->s3d.pos.x);
									disty = ABS(player->stick.y - player2->s3d.pos.y);

									if ( (distx < FOOT*6) && (disty < FOOT*6) )
										{
										player->interact = player2;
										Lock_player(player2, player, &player->stick, 2);
										}
									}
								}
							break;

						default:
							player->interact = NULL;
						}
					}
				}

			list2 = list2->next;
			}


		for (i=0;i<TEAMS;i++)
			{
			if (Test_collision(s3d, &nets[i]->s3d, &player->collision, &nets[i]->collision) )
				{
				vel= player->s3d.vel.x + player->s3d.vel.y;
				if(vel>16*INCH)feedback_strength=FEEDBACK_HIT_STRONGEST;
				else if(vel>6*INCH)feedback_strength=FEEDBACK_HIT_STRONG;
				else if(vel>2*INCH)feedback_strength=FEEDBACK_HIT_NORMAL;
				else if(vel>1*INCH)feedback_strength=FEEDBACK_HIT_WEAK;
				else feedback_strength=FEEDBACK_HIT_WEAKEST;
				ie_CNT_Feedback(player->ai.control,feedback_strength);

				Place_outside_collision(s3d, &nets[i]->s3d, &player->collision, &nets[i]->collision);
				Bump_net(s3d, &player->collision, nets[i]);


				if ( (nets[i]->offpeg == YES) && (gf_gameon) )
					{
					Call_penalty(PENALTY_NET_OFF_PEGS,player,NULL);
					}
				}
			}

		//
		// Test for collision between players & ref

		if ( (Test_collision(s3d, &ref->s3d, &player->collision, &ref->collision)) && (ref->collision.on & CC_ACTOR) )
			{
			vel= player->s3d.vel.x + player->s3d.vel.y;
			if(vel>16*INCH)feedback_strength=FEEDBACK_HIT_STRONGEST;
			else if(vel>6*INCH)feedback_strength=FEEDBACK_HIT_STRONG;
			else if(vel>2*INCH)feedback_strength=FEEDBACK_HIT_NORMAL;
			else if(vel>1*INCH)feedback_strength=FEEDBACK_HIT_WEAK;
			else feedback_strength=FEEDBACK_HIT_WEAKEST;
			ie_CNT_Feedback(player->ai.control,feedback_strength);

			Place_outside_collision(s3d, &ref->s3d, &player->collision, &ref->collision);
			Bump(s3d, &ref->s3d, &player->collision,&ref->collision);
			
			if (s3d->vel.x > FOOT)
				Change_action(ref,BODY,ACT_REF_FALL);
			}

		Do_player_puck_collision(player);
		}



	if (player->locktime)
		{
		if (--player->locktime == 0)
			s3d->vel.x	= s3d->vel.x/4;
		}

	//
	// Test for collision against boards
	//
	// NOTE:
	// Board collisions are always on for players, except when they
	// are entering/exiting BENCH or PENALTYBOX

	if (player->collision.on & CC_BOARD)
		{



		vector.x = s3d->pos.x + Copy_sign(s3d->pos.x, FOOT*2);
		vector.y = s3d->pos.y + Copy_sign(s3d->pos.y, FOOT*2);

		if (Check_rink_collision(&vector))
			{
			Put_inside_rink(&vector, &new);

			Actor_sfx_limit(player,BODYCHK1);

			angle = Rink_tangent(&new);
			s3d->pos.x += new.x - vector.x;
			s3d->pos.y += new.y - vector.y;

			delta = Deflect(angle, s3d->move.z);
			angle = (s3d->move.z-delta)&0xfff;
			if (angle > ANGLE180) angle = ANGLE360-angle;


			player->collision.bump=3;
			vel= player->s3d.vel.x + player->s3d.vel.y;
			if(vel>16*INCH)feedback_strength=FEEDBACK_HIT_STRONGEST;
			else if(vel>6*INCH)feedback_strength=FEEDBACK_HIT_STRONG;
			else if(vel>2*INCH)feedback_strength=FEEDBACK_HIT_NORMAL;
			else if(vel>1*INCH)feedback_strength=FEEDBACK_HIT_WEAK;
			else feedback_strength=FEEDBACK_HIT_WEAKEST;

			ie_CNT_Feedback(player->ai.control,feedback_strength);

			//
			// Break glass 12.5% of the time when we are HARD CHECKED into it.
			// otherwise, just shake it a bit
			breakit=0;
			if(cheat_options[CHEAT_GLASS_BREAK]!=12)
			{
				if(Random_percent(cheat_options[CHEAT_GLASS_BREAK],100))breakit=1;
			}
			if ( ((Action(player,BODY) == ACT_PLAYER_CHECKED_HARD) && (Random_percent(12,100)) || (breakit) )
				)
//			if ( (Action(player,BODY) == ACT_PLAYER_CHECKED_HARD) )
//			if ( 1 )
				{
				if (Find_taskid(TID_GLASS) == NULL)
					{
					Spawn_task(TID_GLASS,PRI_GENERIC, (task_type) Task_break_glass,NULL,256,CHILD);
					Pass_task2(task_spawn,s3d->pos.x>>12,s3d->pos.y>>12);
					}
				}
			else
				{
				if ( (player->s3d.vel.x > INCH*6) && (Find_taskid(TID_GLASS) == NULL) )
					{
					Spawn_task(TID_GLASS,PRI_GENERIC, (task_type) Task_shake_glass,NULL,256,CHILD);
					Pass_task2(task_spawn,s3d->pos.x>>12,s3d->pos.y>>12);
  					}
				}

			//
			// Slow player down depending how sharp incidence angle was

			angle = (angle>>8);
			if (angle == 0) angle = 1;
			s3d->vel.x = s3d->vel.x / angle;
			s3d->move.z = delta;
			}
		}
}


///////////////////////////////////////////////////////////////////////////
//
//	void Dec_player_bump(void)
//
//	Called at begining of main cycle.
//
//	Clears the collision 'bump' flag for all players.
//
// NOTE:
// This 'bump' flag is kept just in case we want to know if player
// has collided with something, so that certain AI tasks can take measures
//	to prevent repeated bumping into objects.
//
///////////////////////////////////////////////////////////////////////////

void Dec_player_bump(void)
{
	LIST	*list;
	PLAYER	*player;

	list	= allplayers;

	while (list)
		{
		player = (PLAYER *) list->data;

		//
		// Dec BUMP counter

		if (player->collision.bump)
			player->collision.bump--;

		if (player->ai.bump_counter)
			player->ai.bump_counter--;

		list = list->next;
		}
}



///////////////////////////////////////////////////////////////////////////
//
//	void Clear_player_pass(void)
//
//	Clear all players 'pass' evaluations to 0
//
//	Called whenever puck is released
//
///////////////////////////////////////////////////////////////////////////

void Clear_player_pass(void)
{
	LIST	*list;
	PLAYER	*player;

	list	= allplayers;

	while (list)
		{
		player = (PLAYER *) list->data;

		player->ai.pass			= 0;
		player->ai.pass_dir		= 0;
		player->ai.danger		= 0;

		list = list->next;
		}
}


///////////////////////////////////////////////////////////////////////////
//
//	void Sleep_player_ai(PLAYER *player,long time)
//
//	Sets players AI to sleep for 'time' cycles.
//
//	Effectively, shuts off mainlevel AI for said duration
//
///////////////////////////////////////////////////////////////////////////

void Sleep_player_ai(PLAYER *player,long time)
{
	TASK *task;

	task = player->ai.task;	// Get AI task (if any)

	if (task == task_active)
		Sleep(time);

	else if (task)
		task->waitState = time;
}



///////////////////////////////////////////////////////////////////////////
//
//	Lock_player
//
//	Locks player to 'Vector' positon for 'time' gamecycles
//
//	Used to lock a player to an opponents limb (stick or arm) during
// hooks/holds, etc
//
///////////////////////////////////////////////////////////////////////////

void Lock_player(PLAYER *player, PLAYER *enemy, Vector *vector, long time)
{
	player->locktim������������������      ��                      �   ü˜B //
//	File	   	-> tfexhib.c
//	Created		-> Nov 29, 1997
//	Author 		-> Tom Carbone
//	Description	-> Fluff Exhibition Menus Handler
//

#define TFEXHIB_C

#include "project.h"
#include "include\strings.h"

#include "drv\font.h"
#include "drv\thing.h"
#include "drv\pad.h"
#include "drv\task.h"
#include "drv\ot.h"
#include "drv\cache.h"
#include "drv\sprite.h"
#include "drv\palette.h"
#include "drv\parse.h"
#include "drv\devapor.h"
#include "drv\init.h"
#include "drv\vram.h"
#include "drv\sound.h"
#include "drv\display.h"
#include "drv\sprite\pfont.h"
#include "drv\memory.h"
#include "drv\util.h"
#include "drv\cdrom.h"
#include "drv\debug.h"

#include "source\pfluff.h"
#include "source\fluff.h"
#include "source\player.h"
#include "source\attrib.h"
#include "source\tid.h"
#include "source\puck.h"
#include "source\rink.h"
#include "source\team.h"
#include "source\cdromdat.h"
#include "source\action.h"
#include "source\tfluff.h"
#include "source\cam.h"
#include "source\stadium.h"
#include "source\score.h"
#include "source\memcard.h"
#include "drv\memcard.h"
#include "source\season.h"

#include "source\ai\ai.h"
#include "drv\problem.h"
#include "drv\random.h"


#include "source\chkfile.h"
#include "source\global.h"
#include "source\common.h"

#include "source\sim.h"

#include "source\tplayer.h"



#include "files.h"
#include "files\test\sfx.h"

#include "source\feedback.h"
#include "x:\drv\ie_cont.h"
#include <ultra64.h>



extern void SetAudioVolume(float Music, float Sfx);
extern short Play_sfx_volume1(long fx, float vol);
extern MEMCARD_FILENAME memcard_filenames[];
extern FONT *fontopen;


char colors[50][3]={	
	{224,208,48},		//"Panthers]",
	{173,0,44},			//"Devils]",
//	{8,8,88},			//"Islanders]",
	{152,56,56},			//"Islanders]",
//	{16,8,136},			//"Rangers]",
	{72,88,232},			//"Rangers]",
	{248,120,8},		//"Flyers]",
	{123,132,140},		//"Lightning]",
	{140,99,79},		//"Capitals]",
	{248,248,72},		//"Bruins]",
	{160,8,8},			//"Sabres]",
	{210,45,54},		//"Hurricanes]",
	{216,8,8},			//"Canadiens]",
	{175,126,38},		//"Senators]",
//	{240,232,32},		//"Penguins]",
	{224,136,56},		//"Penguins]",
	{194,117,0},		//"Blackhawks]",
	{8,176,16},			//"Stars]",
	{219,0,54},			//"Red Wings]",
	{8,8,248},			//"Blues]",
//	{0,28,66},			//"Maple Leafs]",
	{104,80,160},			//"Maple Leafs]",
	{229,216,179},		//"Coyotes]",
	{8,104,80},			//"Mighty Ducks]",
	{248,32,32},		//"Flames]",
	{144,8,80},			//"Avalanche]",
	{40,24,216},		//"Oilers]",
	{240,240,240},		//"Kings]",
	{0,117,133},		//"Sharks]",
	{8,8,232},			//"Canucks]",
//	{255,159,172},		//"Predators]",
	{128,104,88},		//"Predators]",
	{0,82,208},			//"Iguanas]",
//	{8,192,224},		//"AllStars",
	{184,112,112},		//"North AllStars",
//	{215,23,148},		//"AllStars",
	{120,96,128},		//"World AllStars",
	{1,1,1},				//"Sports]",
	{255,0,0},			//"Canada",
	{8,0,184},			//"USA",
	{156,222,242},		//"Finland",
	{255,227,0},		//"Germany",
	{255,0,0},			//"Russia",
	{180,180,180},		//"Slovakia",
	{255,0,0},			//"Czech Rep",
	{255,227,0},		//"Sweden",
	{0,255,0},			
	{2,58,1},
	{113,113,113},
	{84,3,79},
	{199,114,3},
	{0,131,0},
	{110,0,5},
	{6,0,87},
	{222,173,0},
	{188,0,0},
	{177,177,177}

	};


int cartFlag;
/******************************************************************
* mainMenu -
* NOTE: firstTimeEver is cleared only if user dismisses a memory card
*		  warning or exits the mainMenu to somewhere other than the demo.
*		  This is so the memory card warnings will keep popping up
*		  unless the user explicitly gets past them.
******************************************************************/

void mainMenu(void)
{
	int i;

#define NUM_MODE_SELECTIONS	7
	char menuToPlayMode[] = {
		PLAY_MODE_EXHIBITION,
		PLAY_MODE_SEASON,
		PLAY_MODE_PLAYOFFS,
		PLAY_MODE_PLAYOFFS,
		PLAY_MODE_SHOOTOUT,
		PLAY_MODE_PRACTICE,
		PLAY_MODE_CREDITS
	};

	char playModeToMenu[] = {
		-1,0,1,2,4,�����������������������������������������������������������������   ð™B t_camera_task(camera3d, cam_tasks[camera3d->id]);

									break;

				#endif
							case 4:

									if (to_prompt == TRUE)
										{

										if (to_val == YES)
											{
												(timeouts[team])--;
												to_delay = 6*30;
												Init_random();
												items = PAUSE_TEAMOPTIONS_ITEMS-1;
												local_select = 0;
												to_prompt = NO;
												to_val = NO;

												Speech_TimeoutTaken(team);

												Reset_team_energy(HOME);
												Reset_team_energy(AWAY);
											}
										else
											{
											to_prompt = NO;
											}
										}
									else
										to_prompt = TRUE;

									break;



						};



				}


	 		if ( !(local_select == 4 && to_prompt == YES ) )
				PM_Up_Down (team,&local_select,items,PM_WRAP_ON);

//			PM_scroll_window (local_select,&menu_dsp);

			if ( PM_TRIANGLE(team) == TRUE)
				{

					if (to_prompt == YES)
						{
						to_prompt = NO;
						to_val = NO;
						}
					else
						{
						PauseMenu[team].id = PAUSE_HEAD;
						return;
						}
				}


			PM_START (team);


			} // to_delay


	}



}

///////////////////////////////////////////////////////////////////////////
//
//
//	void PM_UserStats (char team)
//
//
///////////////////////////////////////////////////////////////////////////

void PM_UserStats (char team)
{
 char			local_select=0;
 short			y_offset;
 PDISPLAY		menu_dsp;
 short 		i;
 char			str[180];
 short			y_space;
 s_char		curspc=-20;
 char			bigx,bigy;
 USER_STAT		*stat;
 short			lines,curuser;
 char			team_dsp=team;

 #define	PM_US_LEFT		-512/2 + 130

	if (team == HOME)
		{
		y_offset = -125+5+5;
		PauseMenu[team].ly  = -77;
		}
	else
		{
		y_offset = -5+5+5;
		PauseMenu[team].ly  = 42;
		}

	PauseMenu[team].lx  = 139;

	menu_dsp.sx   		= 5.8*ONE;
	menu_dsp.sy   		= 5.6*ONE;			//4.9
	menu_dsp.im_w     	= 5.8*PM_SHADE_X;
	menu_dsp.im_h   	= 5.6*PM_SHADE_Y;
	menu_dsp.numlines	=  5;
	menu_dsp.height_spc =  12;

	Set_display_pause(&menu_dsp, team, YES);
	local_select = PauseMenu[team].select = 0;
	Set_scale_up_down(&menu_dsp,&bigx,&bigy);

	curuser = 0;
	stat = Get_user_stat(&curuser,0);

	while (1) {



			team_dsp = padTeamAssignment[curuser];
			Set_on_off(PauseMenu[team].logo[team_dsp],BODY, ON);
 			Set_on_off(PauseMenu[team].logo[team_dsp^1],BODY, OFF);


			BG_Scale_fx (&menu_dsp,bigx,bigy,ONE/4,ONE/4);

			Select_font(font5_pause);

			Font_spacing(curspc);
			curspc += PAUSE_SPACE_SPEED;
			if (curspc >= -2)
				curspc = -2;


		    ///

			lines = 0;

			///

			strcpy(str,stat->user_name);
			Font_ot(hi_ot);
			Font_camera(NULL);
			Font_position(-512/2 + 80 + 10,y_offset+20);
			PM_blue_font ();
			Font_print(str);
			PM_white_font ();

			///

			// Rules

			Font_camera(PauseMenu[team].cam);
			Font_ot(PauseMenu[team].ot);
			y_space = 10+20;

			///


			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
					sprintf(str,"GOALS^t32 %d } %d",stat->goals, stat->shots);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}


			y_space += menu_dsp.height_spc;
			lines++;

			///

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
		  			Percent_short2string (Pause_strings[PS_SHOT], 32, stat->goals, stat->shots,str);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}


			y_space += menu_dsp.height_spc;
			lines++;

			///


			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{

					sprintf(str,"ASSISTS^t32 %d",stat->assists);

					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}

			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{

					sprintf(str,"POINTS^t32 %d",stat->points);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}

			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
					Time_short2string ("PUCK POSSESSION", 32, stat->puck_time, str);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}

			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
					sprintf(str,"ONE TIMERS^t32 %d } %d",stat->one_timers_goals,stat->one_timers);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}

			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
		  			Percent_short2string ("ONE TIMER", 32, stat->one_timers_goals, stat->one_timers,str);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}


			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{

					sprintf(str,"BREAKAWAYS ^t32 %d } %d",stat->breakaway_goals, stat->breakaways);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);

				}

			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
		  			Percent_short2string ("BREAKAWAY", 32, stat->breakaway_goals, stat->breakaways,str);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}


			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
					sprintf(str,"CHECKS^t32 %d",stat->checks);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}


			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
					sprintf(str,"PASSES^t32 %d } %d",stat->pass_complete,
													 stat->pass);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}



			///


			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
		  			Percent_short2string ("PASS", 32, stat->pass_complete, stat->pass,str);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}


			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
					sprintf(str,"FIGHTS^t32 %d } %d",stat->fights_won, stat->fights);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}

			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
					sprintf(str,"FACEOFFS^t32 %d } %d",stat->faceoff_won,stat->faceoff);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}


			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{
		  			Percent_short2string ("FACEOFF", 32, stat->faceoff_won, stat->faceoff,str);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}


			///

			y_space += menu_dsp.height_spc;
			lines++;

			if (PM_clip_line (lines, &menu_dsp) == FALSE )
				{

					Time_short2string ("PENALTY MINUTES", 32, stat->PIM*60, str);
					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
				}

			///


			Sleep(1);


			//
			// Buttons
			//

			PM_Page_Up_Down (&local_select, PAUSE_USERSTATS_ITEMS, &menu_dsp, PM_WRAP_OFF);

			if (PM_Right(team) == TRUE)
				{

				if (local_select == menu_dsp.numlines)
					{

					for (i=0;i<=menu_dsp.numlines;i++)
							PM_scroll_up_immediate (&menu_dsp);

					local_select = 0;
					}


				stat = Get_user_stat(&curuser,1);

			 //	curuser++;

			 //	if (curuser > 7)
			 //		curuser--;
			 //	else
					MIDIPlaySound(PM_SOUND_SELECT);


				}
			else
			if (PM_Left(team) == TRUE)
				{

					if (local_select == menu_dsp.numlines)
						{

						for (i=0;i<=menu_dsp.numlines;i++)
								PM_scroll_up_immediate (&menu_dsp);

						local_select = 0;
						}

					//curuser--;

					stat = Get_user_stat(&curuser,-1);

					MIDIPlaySound(PM_SOUND_SELECT);


				}


			if ( PM_TRIANGLE(team) == TRUE)
				{
				   	PauseMenu[team].id = PAUSE_STATS;
				   	return;
				}


			PM_START (team);


	}



}


////////////////////////////////////�   `™B 
void PM_EditLines (char team)
{
 char			local_select=0;
 short			y_offset;
 PDISPLAY		menu_dsp;
 short 		i;
 char			str[180];
 short			y_space;
 s_char		curspc=-20;
 char			bigx,bigy;
 USER_STAT		*stat;
 short			curline=0;
 LINE			*line_ptr;
 char			swap=OFF;
 char			sub_select=0;
 short			j,l_start, l_end, l_line=0;
 char			defensive_line;

 #define	PM_US_LEFT		-512/2 + 40

	if (team == HOME)
		{
		y_offset = -125+5;
		PauseMenu[team].ly  = -24;
		}
	else
		{
		y_offset = -5+5;
		PauseMenu[team].ly  = 95;
		}

	PauseMenu[team].lx  = 183;

	menu_dsp.sx   		= 7.0*ONE;
	menu_dsp.sy   		= 5.9*ONE;
	menu_dsp.im_w     	= 7.0*PM_SHADE_X;
	menu_dsp.im_h   	= 5.9*PM_SHADE_Y;
	menu_dsp.numlines	=  5;
	menu_dsp.height_spc =  12;

	Set_display_pause(&menu_dsp, team, YES);
	local_select = PauseMenu[team].select = 0;
	Set_scale_up_down(&menu_dsp,&bigx,&bigy);

	while (1) {


			BG_Scale_fx (&menu_dsp,bigx,bigy,ONE/4,ONE/4);

			Select_font(font5_pause);

			Font_spacing(curspc);
			curspc += PAUSE_SPACE_SPEED;
			if (curspc >= -2)
				curspc = -2;


		    ///

//ASL			sprintf(str,"%s ^t24 STATUS   OVERALL",Pause_strings[PS_Lines[curline]]);
			sprintf(str,"%s ^t26 STATUS   OVERALL",Pause_strings[PS_Lines[curline]]);
			Font_ot(hi_ot);
			Font_camera(NULL);
//			Font_position(-512/2 + 60,y_offset+20);
			Font_position(PM_US_LEFT,y_offset+20);
			PM_blue_font ();
			Font_print(str);
			PM_white_font ();

			///

			defensive_line = NO;

			if (curline <= 2)
				{
					//
					// Scoring line 1,2,3

					l_line = curline;
					l_start = 0;
					l_end	= 2;

				}
			else
			if (curline == 3)
				{
					//
					// Checking line

					l_line = curline;
					l_start = 0;
					l_end	= 2;

				}
			else
			if (curline >= 4 && curline <=6)
				{
					//
					// Defensive line

					l_line = curline-4;
					l_start = 3;
					l_end	= 4;

					defensive_line = YES;


				}
			else
			if (curline <= 8)
				{
					//
					// Powerplay

					l_line  = curline-3;
					l_start = 0;
					l_end	= 4;

				}
			else
				{
					//
					// Penalty Kill

					l_line  = curline-3;
					l_start = 0;
					l_end	= 3;

				}


//			printf("curline %d, l_line %d, l_start %d, l_end %d\n",
//				curline,l_line,l_start,l_end);

			line_ptr = &team_info[team].line_list[l_line];

			///

			// Rules

			Font_camera(PauseMenu[team].cam);
			Font_ot(PauseMenu[team].ot);
			y_space = 10+20;

			///

			for (j=l_start;j<=l_end;j++)
				{


				if (defensive_line == NO)
					{



					}


//				if (PM_clip_line (j, &menu_dsp) == FALSE )
					{

//ASL					sprintf(str,"%s %s ^t24 %s ^t12 %d %s",
					sprintf(str,"%s %s ^t26 %s ^t12 %d %s",
						player_info[team][line_ptr->playerid[j]].attrib.fname,
						player_info[team][line_ptr->playerid[j]].attrib.lname,
						Pause_strings[PS_Status[player_info[team][line_ptr->playerid[j]].stat.status]],
						Overall_rating2(team,line_ptr->playerid[j]),
						Pause_strings[PS_Positions[Decode_position(player_info[team][line_ptr->playerid[j]].attrib.position)]]
						);


					Font_option_select (team, local_select, j-l_start);

					if (player_info[team][line_ptr->playerid[j]].stat.status > STATUS_ON_ICE)
						 PM_red_font ();

					PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
					}


				y_space += menu_dsp.height_spc;

				}

			//
			// Restore Defaults

			Font_option_select (team, local_select, (l_end-l_start+1));
			strcpy(str,"Restore Line");
			PM_pos_print (PM_US_LEFT, y_offset+y_space, str);
			y_space += menu_dsp.height_spc;

			if (swap == ON)
 				{
				 PM_green_font ();

//ASL					sprintf(str,"%s %s ^t24 %s ^t12 %d",
					sprintf(str,"%s %s ^t26 %s ^t12 %d %s",		//ASL
						player_info[team][sub_select].attrib.fname,
						player_info[team][sub_select].attrib.lname,
						Pause_strings[PS_Status[player_info[team][sub_select].stat.status]],
						Overall_rating2(team,sub_select),
						Pause_strings[PS_Positions[Decode_position(player_info[team][sub_select].attrib.position)]]	//ASL
						);

				 if (player_info[team][sub_select].stat.status > STATUS_ON_ICE)
				 	PM_red_font();

				 PM_pos_print (PM_US_LEFT, y_offset+y_space, str);

				}


			Sleep(1);


			//
			// Buttons
			//

			if (local_select == (l_end-l_start+1))
				{

					if ( PM_X(team) )
						{
						 // restore original line

						 PM_Restore_default_line (line_ptr, team, l_line, l_start, l_end);

						}

					PM_Up_Down (team,&local_select,(l_end-l_start+1),PM_WRAP_OFF);

				}


			else
				{
				short pad_pressed;

				if (Any_teammate_control_pressed(team,&pad_pressed,MAPPED_PADRdown))
							{

								if (swap == OFF)
									{
										swap = ON;
										MIDIPlaySound(PM_SOUND_SELECT);
										Check_sub_select(&sub_select,team);	//ASL Verify not a goalie

									}
								else
									{
									 //
									 // wants to swap!

									 if (On_this_line(team,l_line,sub_select,l_start,l_end) == TRUE)
										MIDIPlaySound(PM_SOUND_BACK);
									 else
									 if ((player_info[team][sub_select].stat.status <= STATUS_ON_ICE))
										 {
										 line_ptr->playerid[local_select+l_start] = sub_select;
										 swap = OFF;
										 MIDIPlaySound(PM_SOUND_SELECT);
										 }
									 else
				    		    		 MIDIPlaySound(PM_SOUND_SELECT);


									}

							}


						if (swap == OFF)
							{

								PM_Up_Down (team,&local_select,(l_end-l_start+1),PM_WRAP_OFF);

								if (PM_Right(team) == TRUE)
									{

										if (++curline > 10)
											curline = 0;

										local_select = 0;
										MIDIPlaySound(PM_SOUND_SELECT);

									}
								else
								if (PM_Left(team) == TRUE)
									{

										if (curline)
											curline--;

										local_select = 0;
										MIDIPlaySound(PM_SOUND_SELECT);

									}
							}
						else
							{

								if (PM_Right(team) == TRUE)
									{

										Inc_sub_select(&sub_select,team);

										#if 0
										sub_select++;
										if (sub_select > team_info[team].num_players-1)
											sub_select--;
										else
											MIDIPlaySound(PM_SOUND_SELECT);
										#endif

									}
								else
								if (PM_Left(team) == TRUE)
									{


										Dec_sub_select(&sub_select,team);

										#if 0
										if (sub_select)
											sub_select--;

										MIDIPlaySound(PM_SOUND_SELECT);
										#endif
									}


							}


				} // else local_select == 5


			if ( PM_TRIANGLE(team) == TRUE)
				{
					if (swap == ON)
						{
						swap = OFF;
						MIDIPlaySound(PM_SOUND_BACK);
						}
					else
						{
					   	PauseMenu[team].id = PAUSE_TEAMOPTIONS;
					   	return;
						}
				}


			PM_START (team);


	}



}


void Dec_sub_select (char *sub, char team)
{
 s_char dir=-1;


	do {
			if (*sub || dir==1)
				*sub+=dir;
			else
				dir = 1;

		} while (player_info[team][*sub].attrib.position == P_GOALIE);

	MIDIPlaySound(PM_SOUND_SELECT);

}

void Inc_sub_select (char *sub, char team)
{
 s_char dir=1;


	do {
			*sub+=dir;

			if (*sub > team_info[team].num_players-1)
				{
				dir = -1;
				*sub= team_info[team].num_players-1;
				}

		} while (player_info[team][*sub].attrib.position == P_GOALIE);

	MIDIPlaySound(PM_SOUND_SELECT);

}



///////////////////////////////////////////////////////////////////////////
//
//
//	void PM_TeamStats (char team)
//
//
///////////////////////////////////////////////////////////////////////////

void PM_TeamStats (char team)
{
 char			local_select;
 short			y_offset;
 CAMERA		*cam;
 PDISPLAY		menu_dsp;
 short 		i;
 char			str[180],*str_ptr;
 short			y_space;
 s_char		curspc=-20;
 char			bigx,bigy;
 char			per_ind=0;
 GAME_STAT		*data,total;
 char			team_dsp=team,update_total=TRUE;

 #define	PM_US_LEFT		-512/2 + 80
 #define	PM_LEFT_ICON	-512/2 + 80 + 40

	if (team == HOME)
		{
		y_offset =

0xF3F60:

[i+1],0<<12,(((312-240)/2)+(i*16))<<12,SCR_Z<<12);
	}

 	startGenericFluffActor(5,(u_long)&N64_CONTROLLER_PICTURE,lo_ot,TRANSON,PRIM_SPRT,0,1,0);
	Set_positer:	Chris Braymen
*********************************************************************
* Provides file access to memcard
* Derived from Sean Igo's work on Mustache Red
*********************************************************************/

#ifndef DRV_MEMCARD_H
#define DRV_MEMCARD_H

#define	CARD_NOT_SHARED	0
#define	CARD_SHARED			1

#define	IGNORE_UNFORMATTED_CARDS	0
#define	REPORT_UNFORMATTED_CARDS	1

#define	CARD_BLOCK_SIZE				256
#define	MAX_CARD_PORTS					1

#define	SEASON_FILE_BLOCKS		SEASON_FILE_BUF_SIZE/CARD_BLOCK_SIZE
#define	SETTINGS_FILE_BLOCKS		SETTINGS_FILE_BUF_SIZE/CARD_BLOCK_SIZE

#define	MAX_CARDS_PER_PORT		4

#define	MAX_CARDS						MAX_CARD_PORTS * MAX_CARDS_PER_PORT


#define SEASON_FILE_TYPE 	'S'
#define SETTINGS_FILE_TYPE 'U'
#define PLAYOFF_FILE_TYPE  'P'


typedef struct
{
	OSPfsState State;
	char	 description[32];		// file name converted from nintendo font code
	u_long slots_used;			// pages (128 byte sectors)
	u_long slots_free;	
} MEMCARD_FILENAME;


enum {
	CARD_NO_ERROR,
	CARD_NO_SPACE,
	CARD_NO_DRIVE,
	CARD_OPEN_ERROR,
	CARD_WRITE_ERROR,
	CARD_READ_ERROR,
	CARD_ALLOC_ERROR,
	CARD_FILE_SIZE_ERROR,
	CARD_NOT_FORMATTED,
	CARD_FORMAT_ERROR,
	CARD_SYSTEM_ERROR,
	CARD_NOT_INSERTED,
	CARD_DELETE_ERROR
};

#define	FILE_STRING_LEN				21+5

extern	int			card_last_error;
extern	int			card_was_exchanged;

// public protos

void	timedShake(int controllerNumber,int shakeVBL, int mag);
void	stopShaking(int controllerNumber);
int 	init_card(void);
void 	de_init_card(void);
long 	find_cards(int unfo);
int 	find_space(long card_bit, int size, OSPfsState *intended_fname, u_long *freeBlocks);
int 	find_card_files(long card_bit, MEMCARD_HEADER *card_files, MEMCARD_FILENAME *filenames);
int 	delete_card_file(long card_bit, OSPfsState *pState);
int 	write_card_file(char *data, int size, long card_bit);
char 	*read_card_file(int filenum, long card_bit, long size, char filetype, int max_blocks);
int 	format_card(long card_bit);
int 	get_memcard_filename(long card_bit, long slotid, int filenum, OSPfsState *stringPtr);
int 	card_inserted_or_removed(long card_bit, int was_inserted, int do_logged_check);
long 	is_card_inserted(long card_bit);
long 	is_rumble_pak(long card_bit);

#endif
                                                                             
;         db "1996-97 Season Record: 31-36-15.  Key Players: Daniel Alfredsson, Alexander Daigle, Alexi Yashin and Damian Rhodes." 
; 	db 0                                                                                                                       
;                                                                                                                                  
; string18a:                                                                                                                       
;         db "1996-97 Season Record: 45-24-13.  Key Players: Eric Lindros, John LeClair, Eric Desjardin and Ron Hextall."          
; 	db 0                                                                                                                       
;                                                                                                                                  
; string19a:                                                                                                                       
;         db "1996-97 Season Record: 38-37-7.  Key Players: Keith Tkachuk, Jeremy Roenick and Nikolai Khabibulin."                 
; 	db 0                                                                                                                       
;                                                                                                                                  
; string20a:                                                                                                                       
;         db "1996-97 Season Record: 38-36-8.  Key Players:  Ron Francis and Jaromir Jagr."                                        
; 	db 0                                                                                                                       
;                                                                                                                                  
; string21a:                                                                                                                       
;         db "1996-97 Season Record: 27-47-8.  Key Players: Owen Nolan and Jeff Friesen."                                          
; 	db 0                                                                                                                       
;                                                                                                                                  
; string22a:                                                                                                                       
;         db "1996-97 Season Record: 36-35-11.  Key Players: Brett Hull, Pierre Turgeon and Grant Fuhr."                           
; 	db 0                                                                                                                       
;                                                                                                                                  
; string23a:                                                                                                                       
;         db "1996-97 Season Record: 32-40-10.  Key Players: Mikael Renberg, Dino Ciccarelli, and Rob Zamuner."                    
; 	db 0                                                                                                                       
;                                                                                                                                  
; string24a:                                                                                                                       
;         db "1996-97 Season Record: 30-44-8.  Key Players: Mats Sundin and Felix Potvin."                                         
; 	db 0                                                                                                                       
;                                                                                                                                  
; string25a:                                                                                                                 
;         db "1996-97 Season Record: 35-40-7.  Key Players: Mark Messier, Alexander Mogilny, Pavel Bure and Martin Gelinas." 
; 	db 0                                                                                                                 
;                                                                                                                            
; string26a:                                                                                                                 
;         db "1996-97 Season Record: 33-40-9.  Key Players: Peter Bondra, Adam Oates and Bill Ranford."                      
; 	db 0                                                                                                                 

;string27: 		; dummy All Star
;	db 0
stringAS:		; dummy All Star
	db 0
string29:		; Intl playoff teams added for N64
	db "Team Canada is the perennial powerhouse of the International Playoffs. Team"
	db " Canada features strong goaltending from Martin Brodeur and powerhouse lines"
	db " with players such as Eric Lindros, Wayne Gretzky, and Joe Sakic."
	db 0
string30:
	db "Team Czech has recently become one of the better teams in international competition.   "
	db "Team Czech sports one of the best goaltenders in the NHL with Dominik Hasek and "
	db "one of the premiere forwards with Jaromir Jagr.   Their deep roster has many players "
	db "with NHL experience, which makes this t�   D—B

0xF7000:

PADS;++i)
			padTeamAssignment[i]=-1;

//	padTeamAssignment[0]=0;
//	padTeamAssignment[1]=1;

	fluffTeamIDs[0]=team1;
	fluffTeamIDs[1]=team2;

	for(i=0;i<NUM_OPTIONS;++i)
	{
		options[i]=defaultOptions1[i];
	}


	for(i=0;i<4;++i)
	{
		gamebut[i][GB_SHOOT]		= BUT_SHOOT;

		gamebut[i][GB_DUMP]			= BUT_DUMP;			
		gamebut[i][GB_HOOK]			= BUT_HOOK;			

		gamebut[i][GB_BACKWARDS]	= BUT_BACKWARDS;
		gamebut[i][GB_ICON_PASSING]	= BUT_ICON_PASSING;
		gamebut[i][GB_CHECK]		= BUT_CHECK;

		gamebut[i][GB_PASS]			= BUT_PASS;
		gamebut[i][GB_DIVE]			= BUT_DIVE;

		gamebut[i][GB_CHANGEPLAYER]	= BUT_CHANGEPLAYER;
		gamebut[i][GB_LINECHANGE]	= BUT_LINECHANGE;
	}

	memset(goalsSeason,0,sizeof(char)*PLAYERS_TEAM*TEAMS);
}
throwbackMode[0]=throwbackMode[1]=-1;

#endif
	Xfer(Task_main_game2);
}

///////////////////////////////////////////////////////////////////////////
//
//	void Update_loading_bar(long max)
//
//	'max' is number of sectors which represents 100% loaded.
//
//	Update 'loading' bar to should a percentage of 'max' which is loaded.
//
///////////////////////////////////////////////////////////////////////////

void Update_loading_bar(long max)
{

}




///////////////////////////////////////////////////////////////////////////
//
//	void Task_main_game2(void)
//
// Continuation point from TOMS fluff
//
///////////////////////////////////////////////////////////////////////////

void Task_main_game2(void)
{
	SPACE3D DEFAULT_CAMERA3D =
	{
		{-SCORE_LINE+FOOT*5,0,2*FOOT},			// Position x-y-z
		{0,0,0},								// Velocity
		{0,0,0},								// Direction moving
		{ANGLE090-DEGREE*8,ANGLE000,ANGLE000}	// Direction FACING
	};

// --------------------------------------------------------------
//
//	Display LOADING screen.
//
// --------------------------------------------------------------
{

	Reset_graphics_system(512,240,300,NO); 	// Init GPU/GTE (screen width/height/scrz)
	Auto_erase_off();

	//
	// RESET sector counter. How many sectors have we loaded?
	//
	// We use this to draw a 'LOADING BAR'

	cdrom_sector_count = 0;
}

// --------------------------------------------------------------

//	Init_font_driver(0);	// Clear fonts
	Init_things();


	gf_waiting_for_message=ON;  //make sure you can't pause the game 
															//before rumble pak message comes up

// --------------------------------------------------------------
//
//	Load GAME overlay (NON BLOCKING)
//
//	CAUTION: Dont execute any code until its loaded!
//
// --------------------------------------------------------------

//	Debug_print(DEBUG_PRINT_SWITCH,"Loading MAINGAME overlay\n");
//	Load_file(DATA_OVERLAYS_GAME_OVR,Overlay1Address,0,0);

// --------------------------------------------------------------
//
//	Load font driver. Keep it mininal. Only # characters that
//	we need.
//
// --------------------------------------------------------------

	Init_font_driver(400);
	Sleep(3);
// --------------------------------------------------------------
//	Init lots of stuff (vram allocation tables/sprite tables/OT tables/cdrom files loaded)
//
// --------------------------------------------------------------

	Init_rgb(128,128,128);

	Init_fsp(FPS_30);		// Place restrictions to run at 30fps

	Init_graphics_lists(0);

	zero_ot = Get_ot_slot(0,OT_REVERSE,0);	// Lowest OT. Everything is drawn in front of this.

	lo_ot	= Get_ot_slot(0,OT_REVERSE,20);	// Constant LO OT

	lohi_ot	= Get_ot_slot(0,OT_REVERSE,10);	// Below 'lo'
	hilo_ot	= Get_ot_slot(0,OT_REVERSE,100);// Above 'lo'

	hi_ot	= Get_ot_slot(0,OT_REVERSE,200);// Constant HI OT (Drawn ontop of everthing)
	hi_hi_ot	= Get_ot_slot(0,OT_REVERSE,201);// Constant HI OT (Drawn ontop of everthing, including hi_ot)

	Init_game_constants();
	Init_game_variables();

	#ifdef __psx__
	Free_default_vram();
	#endif

// -------------------------------------�   `—B //
//	File		-> fluff.c
//	Created 	-> Apr 09, 1996
//	Author		-> Peter Ward
//	Description -> Misc fluff
//

#include "project.h"

#include "drv\font.h"
#include "drv\thing.h"
#include "drv\pad.h"
#include "drv\task.h"
#include "drv\ot.h"
#include "drv\cache.h"
#include "drv\sprite.h"
#include "drv\palette.h"
#include "drv\physics.h"
#include "drv\parse.h"
#include "drv\actor.h"
#include "drv\devapor.h"
#include "drv\memory.h"
#include "drv\cdrom.h"
#include "drv\xa_audio.h"

#include "source\fluff.h"
#include "source\tfluff.h"
#include "source\player.h"
#include "source\goalie.h"
#include "source\attrib.h"
#include "source\tid.h"
#include "source\puck.h"
#include "source\rink.h"
#include "source\team.h"
#include "source\cdromdat.h"
#include "source\action.h"
#include "source\cam.h"
#include "source\stadium.h"
#include "source\score.h"
#include "source\board.h"
#include "source\penalty.h"
#include "source\pause.h"
#include "source\team.h"

#include "source\file_num.h"

#include "source\ai\ai.h"
#include "source\ai\puckfree.h"

#include "drv\problem.h"

#include "source\global.h"

#include "source\replay.h"

#include "source\files.h"
#include "source\sim.h"

#include "source\fight.h"
#include "drv\memcard.h"	//ASL




// =========================================================================
//
//					 LOCAL CONSTANTS
//
// =========================================================================


// =========================================================================
//
//					 GLOBAL VARIABLES
//
// =========================================================================

SCORE		game_score;
SCORE		*Gamescore;
GAMEFLUFF  gameplay_fluff;
char		Secret_team=OFF;

TASK		*TaskPtr_firepuck;
TASK		*TaskPtr_passline;

// =========================================================================

long	id_message_big;
long	id_message_red;

long	id_message_offside;

// =========================================================================

RECT		ftex_rect[FTEX_MAX];
short		ftex_pal[FTEX_MAX];
char		ftex_bit[FTEX_MAX];
extern 	char	_PERIOD_LENGTH[];
extern char	*STR_PERIOD[];

// =========================================================================
//
//					 LOCAL VARIABLES/FUNCTIONS
//
// =========================================================================

void Task_kill_hockey_attract(void);

///////////////////////////////////////////////////////////////////////////
//
//	Init_fluff(void)
//
//	Tests fluff tasks by starting them up regardless.
//
///////////////////////////////////////////////////////////////////////////

void Init_fluff(void)
{

//	Spawn512(TID_FLUFF,Task_players_faces);

	Spawn256(TID_FLUFF,Task_scorebox);

	if (Humans_on_team (HOME) == TRUE || Humans_on_team(AWAY) == TRUE)
	{
		if(options[OPTION_TICKERBAR_FREQUENCY]!=0 && playMode==PLAY_MODE_SEASON  && num_day_highlights>0/*|| (playMode==PLAY_MODE_PLAYOFFS*/)Spawn256(TID_FLUFF,Task_tickerbar);
	}
	Spawn64(TID_FLUFF,Task_message_attack_type);

//Spawn256(TID_FLUFF,Task_net_target);

//	Spawn256(TID_FLUFF,Task_puck_shadow_and_highlight);

//	TaskPtr_passline = Spawn256(TID_FLUFF,Task_draw_passline);
//	Suspend_task(TaskPtr_passline);

	TaskPtr_firepuck = Spawn256(TID_FLUFF,Task_firepuck);
	if (options[OPTION_FIREPUCK] == NO)
		Suspend_task(TaskPtr_firepuck);

	//
	// If no humans playing, START returns to Fluff

	if (Humans_on_team (HOME) == FALSE)
		{
		if (Humans_on_team (AWAY) == FALSE)
			Spawn256(TID_FLUFF,(task_type)Task_no_humans);
		}
	gf_bottom_message_up=0;
}


///////////////////////////////////////////////////////////////////////////
//
//	Start returns to fluff & Handles Attract mode
//
//	--pat
///////////////////////////////////////////////////////////////////////////

void Task_no_humans(void)
{
 short 	contr;
 short		sleeps;
 short		changecam;
 char		toggle=OFF;
 u_short	sleep_ticks;
 char killed;



// 	sleeps=200*30;

//	sleeps = Random_min_max(45,90)*30;	  //45 sec - 1.5 min
	sleeps = Random_min_max(15,30)*30;	  //45 sec - 1.5 min

	// DEBUG
	//sleeps = 60*10*30;

	changecam = Random_min_max(10,25)*30;


	if (gf_game_attract_mode == YES)
		{
		short	i;

			//
			// scramble goals scored this season

			for (i=0;i<PLAYERS_TEAM;i++)
				{
					goalsSeason[HOME][i] = Random_min_max(0,180);
					goalsSeason[AWAY][i] = Random_min_max(0,180);
				}

		}
	killed=0;
	while (1)
		{

			if (Any_control_button_pressed() == TRUE)
				{
					//
					// two-cpu game
					if(!killed)Task_xfer(TID_DRAW,n64Main,Task_kill_hockey);
					killed=1;
					Sleep(1);
				}
			

			if (gf_game_attract_mode == YES)
				{

					//
					// print DEMO PRESS START

					if (sleep_ticks >= 15)
						{
							toggle ^=1;
							sleep_ticks = 0;
						}

					Select_font(font7);
					Font_ot(hi_ot);
					Font_camera(NULL);
					Font_rgb(-48,-48,0);
					
					if (toggle)
						{
						Font_position(-32-16-48+5,-7);
						Font_print("DEMO MODE");
						}
					else
						{
						Font_position(-32-16-48+5,-7);
						Font_print("DEMO MODE");

						Font_position(-39-16-48-4,8);
						Font_print("PRESS START");
						}
					Select_font(font7);
					Font_window(-SCREEN_WIDTH/2,-SCREEN_HEIGHT/2,SCREEN_WIDTH,SCREEN_HEIGHT);
					Font_rgb(0,0,0);


					//
					// attract mode

					if (--sleeps == 0)
						{
							Task_xfer(TID_DRAW,n64Main,Task_kill_hockey_attract);
							Sleep(1);
						}


					if (--changecam == 0)
						{
							Set_camera_task(camera3d,CAM_TASKS[Random_min_max(0,4)]);
							changecam = Random_min_max(10,25)*30;
						}


				}
			

			sleep_ticks++;
			Sleep(1);


		}
}



///////////////////////////////////////////////////////////////////////////
//
//
//	void Task_kill_hockey_attract(void)
//
//
///////////////////////////////////////////////////////////////////////////

void Task_kill_hockey_attract(void)
{
	gameAbortedFlag = 0;	//back to fluff knowing came from attract mode
	gf_pause		= OFF;
	Kill_hockey();	// Never returns.
}



///////////////////////////////////////////////////////////////////////////
//
// void Init_fluff_texture(void)
//
// Load fluff textures to vram.
//
// Remembers their VRAM location, and their PALETTE
//
///////////////////////////////////////////////////////////////////////////

void Init_fluff_texture(void)
{

#ifdef __psx__
	long		i;
	GenPtr		base;
	GenPtr		tex;
	char		*tim_addr;
	long		*ptr;
	TIM_IMAGE	tim_image;
	GenPtr		buffer;


	//
	// No decomp buffer allocated

	buffer.c	= NULL;


	tex.c = base.c = Load_cdrom_file(&FLUFF_TEX);

	i=0;
	while (*tex.l)
		{

		tim_addr = base.c + *tex.l++;

		//
		// Is this a TIM or a COMPRESSED TIM?

		ptr	= (long*) tim_addr;

		if (*ptr != 0x00000010)
			{

			SetFitMethod(FIT_LAST);
			buffer.c=allocMem(*ptr);
			RestoreFitMethod();
			devapor (ptr,buffer.c);
			ptr=buffer.l;
			}

		Load_tim(ptr,&ftex_rect[i]);
		OpenTIM(ptr);
		ReadTIM(&tim_image);

		//
		// Get the TRUE display size of the tim, since our
		// vram always allocates in cache sized chunks

		ftex_rect[i].w	= tim_image.prect->w;
		ftex_rect[i].h	= tim_image.prect->h;
		ftex_bit[i]		= tim_image.mode&7;	// Get bitmode for this tim

		//
		// Get the palette the TIM was assigned.
		ftex_pal[i]		= global_slot;
		i++;

		//
		// Free the DECOMP buffer (if any)

		if (buffer.c)
			{
			DrawSync(0);
			buffer.c	= freeMem(buffer.c);
			}
		}
#endif
}

void Set_ftex(void *act, char name, long ftex)
{
#ifdef __psx__
	SPRITE	*sprite;

	sprite = Find_sprite(act,name);

	if (sprite)
		{
		sprite->bit				= ftex_bit[ftex];
		sprite->palette			= ftex_pal[ftex];

		sprite->vramdisplay.x	= ftex_rect[ftex].x;
		sprite->vramdisplay.y	= ftex_rect[ftex].y;
		sprite->vramdisplay.w	= ftex_rect[ftex].w;
		sprite->vramdisplay.h	= ftex_rect[ftex].h;
		Set_frame(act,name,&SHRECTV);

		sprite->palette			= -1;
		}
#endif
}

///////////////////////////////

0x1227D2:

/**********************************************************************\
**
** vapor.c - Vapor data compressor by Rob Nelson 3/22/94
**
** This program utilizes "chisel" and "eclipse" type compression.
** Data will be compressed both ways and the most optimal output
** will be used.  Note that the data output isn't identical to 
** either of these programs because it has been rearranged to be
** faster to decompress on the 68000.
**
** Revision 1.0 (3/22/94) - Initial release
** Revision 1.1 (3/23/94) - Fixed patterns over midpoint boundary
** Revision 1.2 (3/24/94) - Constant screen output so you can abort.
** Revision 1.3 (4/10/94) - Improved compression speed.
** Revision 1.4 (6/05/94) - Commands may be specific per header
** Revision 1.5 (7/08/94) - Labels may start with an underscore
**                          Sections of 0 size will display.
** Revision 1.6 (7/10/94) - Added compressed size and ratio to output
** Revision 1.7 (8/17/94) - Labels may start with a period.
** Revision 1.8 (11/15/94)- Added CNOP 0,2 as align option.
** Revision 1.9m(12/1/94) - Switched to 32bit (mars)
** Revision 1.10m (1/17/95) - Asterisk as comment allowed (mars)
**
** BIG CHANGE:  First word is now compressed length, not uncompressed
** lenght  - MWC  1/18/96
\**********************************************************************/

/**********************************************************************
*	2/13/97	CGB	Extracted eclipse compressor section for Hockey
***********************************************************************/

#include "project.h"
#include "source\eclipse.h"
#include "drv\memory.h"

#define UPDATE_INTERVAL 1000

u_char *scanbuf = NULL, *skipbuf = NULL, *bestcompbuf = NULL, *curcompbuf = NULL;
u_long scanbuflen, bestcompbuflen, curcompbuflen, curchar;
u_char sectionlabel[256], bestcompname[32], bestcompabbr[5];
u_char bestcompnum, bestxsize, *runbuf, *deltabuf;
u_char *infilename = NULL, *outfilename = NULL;
u_char forcedxsize = 0, xdef = 0, saveforcedxsize = 0, savexdef = 0;
u_long firstpos[256], nextc

0x133000:

lines

			sim_delete_player_from_lines(match_index, guy_index,0);
		}
	}

	// install a valid defensive line into the checking line

	get_line(match_index, LINE_CHECKING) -> playerid[3] = 
		get_line(match_index, LINE_SCORING1) -> playerid[3];
	get_line(match_index, LINE_CHECKING) -> playerid[4] = 
		get_line(match_index, LINE_SCORING1) -> playerid[4];


	// mark games played
	for (i = 0; i < get_num_players(match_index); i++) {
		if (player_on_ice(match_index, i)) {
			played_in_game[match_index][i] = TRUE;;
		}
	}
	played_in_game[match_index][(int)get_team_ptr(match_index)->starting_goalie] = TRUE;

}

/**********************************************************************
* sim_delete_player_from_lines
**********************************************************************/
void sim_delete_player_from_lines(int match_index, int guy_index, int copyLines)
{
	delete_player_from_lines(guy_index, get_team_ptr(match_index), sim_players, 1);

	// If we are not allowing line changes then copy line 1 to the others
	// We only want to do this if we are called during penalties because
	// our real lines have been saved off then.  If called from determine_injury
	// don't copy the lines.

	if (copyLines) {
		if (match_index == HOME_TEAM) {
			if (!g_line_change_home_flag) {
				copy_line_1(HOME_TEAM);
			}
		}
		else if (!g_line_change_away_flag) {
			copy_line_1(HOME_TEAM);
		}
	}
}


/**********************************************************************
* sim_remove_line_player
* WARNING - special function called by routines in common.c
* 				when inserting a player into a line
**********************************************************************/
//void sim_remove_line_player(TEAM_INFO *t_info, int player_id)
//{
//	int	match_index;
//
//	if (t_info == get_team_ptr(HOME_TEAM)) {
//		match_index = HOME_TEAM;
//	}
//	else {
//		match_index = AWAY_TEAM;
//	}
//
//	set_player_status(match_index, player_id, STATUS_ON_BENCH);
//}




///**********************************************************************
//* sim_insert_line_player
//* WARNING - special function called by routines in common.c
//* 				when deleting a player from a line
//**********************************************************************/
//void sim_insert_line_player(TEAM_INFO *t_info, int new_player)
//{
//	int	match_index;
//
//	if (t_info == get_team_ptr(HOME_TEAM)) {
//		match_index = HOME_TEAM;
//	}
//	else {
//		match_index = AWAY_TEAM;
//	}
//
//	set_player_status(match_index, new_player, STATUS_ON_ICE);
//	played_in_game[match_index][new_player] = TRUE;
//}



/*********************************************************************
* determine_hot_players
*********************************************************************/
void determine_hot_players(int match_index, int team, int weWon)
{
	int			i,j;
	int			player_team_id;
	RAND_LIST	slots_replaced[MAX_HOT_PLAYERS];
	RAND_LIST	sorted_players[PLAYERS_TEAM];

	// init the slots replaced array

	for (i=0; i<MAX_HOT_PLAYERS; i++) {
		slots_replaced[i].index = i;
		slots_replaced[i].rnum = random(32767);
	}
	sort_rand_list(slots_replaced, MAX_HOT_PLAYERS, 1);

	// step through the current hot players and remove any goalies, or
	// guys who got injured or didn't score in this game.

	for (i = 0; i < MAX_HOT_PLAYERS; i++) {
		player_team_id = sim_team_stats[team].hot_players[i];
		if (player_team_id != 0) {
			player_team_id--;
			if (get_player_status(match_index, player_team_id) == STATUS_INJURED) {
				sim_team_stats[team].hot_players[i] = 0;
			}
			if (get_player_position(match_index, player_team_id) == P_GOALIE) {	
				// goalies have to requalify to stay on the hot list
				sim_team_stats[team].hot_players[i] = 0;
			}
			else {
				// regular players just have to keep getting points to stay on
				if ((match_goals[match_index][player_team_id] + match_assists[match_index][player_team_id]) == 0) {
					sim_team_stats[team].hot_players[i] = 0;
				}
			}
		}		
	}	

	// now find hot guys from this game and install them, 
	// first in open slots, then replacing random slots.
	//
	// Regular guys make the hot list if they get 3 or more points
	// or 2 points and a short goal, sort guys by points
	
	for(i=0; i<get_num_players(match_index); i++) {
		sorted_players[i].rnum  = match_goals[match_index][i] + match_assists[match_index][i];
		if (get_player_status(match_index, i) == STATUS_INJURED) {
			sorted_players[i].rnum = 0;
		}
		sorted_players[i].index = i;
	}
	sort_rand_list(sorted_players, get_num_players(match_index), 0);	

	i=0;
	while(i < MAX_HOT_PLAYERS) {
		if (sorted_players[i].rnum < 2)
			break;
		if (sorted_players[i].rnum >= 3 || match_sh_goals[match_index][sorted_players[i].index]) {
			// guy qualified, install him
			install_guy_on_hot_list(team, sorted_players[i].index, slots_replaced, sim_team_stats);
		}
		i++;
	}	
	
	// check goalies
	for (j=0; j<get_num_players(match_index); j++) {
		if (weWon && get_player_position(match_index, j) == P_GOALIE) {

			// check shutout
			if (match_goalie_minutes[match_index][j] >= 3*g_period_length) {
				if (match_goalie_goals_against[match_index][j] == 0) {
					if (i < MAX_HOT_PLAYERS) {
						install_guy_on_hot_list(team, j, slots_replaced, sim_team_stats);
						i++;
					}
				}					
			}

			// check 60+ saves
			if (match_goalie_shots_on[match_index][j] - match_goalie_goals_against[match_index][j] >= 60) {
				if (i < MAX_HOT_PLAYERS) {
					install_guy_on_hot_list(team, j, slots_replaced, sim_team_stats);
					i++;
				}
			}

			// check 30+ saves and < 2 goals against

			if ((match_goalie_shots_on[match_index][j] - match_goalie_goals_against[match_index][j] >= 30) &&
				  match_goalie_goals_against[match_index][j] < 2) {
				if (i < MAX_HOT_PLAYERS) {
					install_guy_on_hot_list(team, j, slots_replaced, sim_team_stats);
					i++;
				}
			}
		}
	}		

	Debug_print(OFF,"Hot: ");
	for (i=0; i<MAX_HOT_PLAYERS; i++) {
		if (sim_team_stats[team].hot_players[i]) {
			Debug_print(OFF,"%s %s  ",
				get_player_fname(match_index, sim_team_stats[team].hot_players[i]-1),
				get_player_lname(match_index, sim_team_stats[team].hot_players[i]-1)
			);
		}
	}	
	Debug_print(OFF,"\n");
}

/********************************************************************
* install_guy_on_hot_list
*********************************************************************/
void install_guy_on_hot_list(int team, int guy, RAND_LIST slots_replaced[], TEAM_STAT *stats)
{
	int	i,j;

	// is guy already hot? If so, replace him with himself

	i=0;
	while(i<MAX_HOT_PLAYERS) {
		if (stats[team].hot_players[i] == guy+1) { 
			// mark slot used
			for (j=0; j<MAX_HOT_PLAYERS; j++) {
				if (slots_replaced[j].index == i) {
					slots_replaced[j].index = -1;
				}
			}			
			return;
		}
		i++;
	}	

	// search for open slot

	i=0;
	while(i<MAX_HOT_PLAYERS) {
		if (stats[team].hot_players[i] == 0) {
			stats[team].hot_players[i] = guy+1;
			// mark slot used
			for (j=0; j<MAX_HOT_PLAYERS; j++) {
				if (slots_replaced[j].index == i) {
					slots_replaced[j].index = -1;
				}
			}			
			return;
		}
		i++;
	}

	// no open slots, need to replace one

	j=0;
	while (j<MAX_HOT_PLAYERS) {
		if (slots_replaced[j].index != -1) {
			stats[team].hot_players[slots_replaced[j].index] = guy+1;
			slots_replaced[j].index = -1;
			return;
		}
		j++;
	}

	Debug_print(OFF,"Huh? No open slots for hot player?\n");
}

/********************************************************************
* print_hilite
*********************************************************************/
void print_hilite(int home, int visit, int home_score, int visit_score, goal goals[2][MAX_GOALS])
{
	int	i,j;
	int gotit;

	int	hi_scorer_team = 0;
	int	hi_scorer_index = 0;
	int	hi_scorer_goals = -1;

	int	hi_points_team = 0;
	int	hi_points_index = 0;
	int	hi_points = -1;

	int	cur_team;
	int	cur_match_index;

	int	string_num;
	char	temp_string[80];


	// Do winning team first to so a stat tie will pick winning team

	if (home_score >= visit_score) {
		cur_team = home;
		cur_match_index = HOME_TEAM;
	}
	else {
		cur_team = visit;
		cur_match_index = VISITOR_TEAM;
	}

	for (i=0; i<TEAMS; i++) {
		for (j = 0; j < get_num_players(cur_match_index); j++) {

			if (match_goals[cur_match_index][j] > hi_scorer_goals) {
				hi_scorer_goals = match_goals[cur_match_index][j];
				hi_scorer_index = j;
				hi_scorer_team = cur_match_index;
			}

			if (match_goals[cur_match_index][j] + match_assists[cur_match_index][j] >= hi_points) {
				if (match_goals[cur_match_index][j] + match_assists[cur_match_index][j] > hi_points) {
					hi_points = match_goals[cur_match_index][j] + match_assists[cur_match_index][j];
					hi_points_index = j;
					hi_points_team = cur_match_index;
				}
				else if (match_goals[cur_match_index][j] > match_goals[hi_points_team][hi_points_index]){
					// give preference to hi points with most goals
					hi_points = match_goals[cur_match_index][j] + match_assists[cur_match_index][j];
					hi_points_index = j;
					hi_points_team = cur_match_index;
				}
			}
		}

		if (home_score >= visit_score) {
			cur_team = visit;
			cur_match_index = VISITOR_TEAM;
		}
		else {
			cur_team = home;
			cur_match_index = HOME_TEAM;
		}
	}

	//	***************************
	// fill in highlight structure
	//	***************************

	my_highlight -> home_score = home_score;
	my_highlight -> visit_score = visit_score;
	my_highlight -> periods = periods;

	for (i=0; i<4; i++) {
		my_highlight -> period_scores[HOME_TEAM][i] = goals_per_period[HOME_TEAM][i];
		my_highlight -> period_scores[VISITOR_TEAM][i] = goals_per_period[VISITOR_TEAM][i];
	}


	my_highlight -> highlight[0] = '\0';
	gotit=0;
	if (hi_points == 0) {
		string_num = random(NUM_HL_ZERO_ZERO_STRINGS);
		sprintf(my_highlight -> highlight, hl_zero_zero_strings[string_num],
			get_player_fname(AWAY, get_team_ptr(AWAY) -> starting_goalie),	
			get_player_lname(AWAY, get_team_ptr(AWAY) -> starting_goalie),	
			get_player_fname(HOME, get_team_ptr(HOME) -> starting_goalie),	
			get_player_lname(HOME, get_team_ptr(HOME) -> starting_goalie));
			return;
	}

	// Is there a scorer with 3 or more goals?
//TOM
//	hl_number=0;
//END TOM
	if (hi_scorer_goals >= 3) {
//TOM
			 strcpy(my_highlight->ticker_hl_name[hl_number],get_player_lname(hi_scorer_team, hi_scorer_index));
			 my_highlight->ticker_hl_number[hl_number]=hi_scorer_goals;
			 my_highlight->ticker_hl_type[hl_number]=GOAL_TYPE;
			 hl_number++;
//END TOM

		gotit=1;
		switch(string_num = random(NUM_HL_HI_SCORE_STRINGS)) {

			// Don't forget to add strings below too!!!!!

			case 0:
			case 1:
			case 3:
			case 5:
			case 6:
			case 8:
				sprintf(my_highlight -> highlight,hl_hi_score_strings[string_num],
					get_player_fname(hi_scorer_team, hi_scorer_index),
					get_player_lname(hi_scorer_team, hi_scorer_index),
					match_goals[hi_scorer_team][hi_scorer_index]);
				break;
			case 2:
				sprintf(my_highlight -> highlight,hl_hi_score_strings[string_num],
					get_modified_team_name(hi_scorer_team, temp_string),
					get_player_fname(hi_scorer_team, hi_scorer_index),
					get_player_lname(hi_scorer_team, hi_scorer_index),
					match_goals[hi_scorer_team][hi_scorer_index]);
				break;
			case 4:
				sprintf(my_highlight -> highlight,hl_hi_score_strings[string_num],
					get_player_fname(hi_scorer_team, hi_scorer_index),
					get_player_lname(hi_scorer_team, hi_scorer_index),
					get_modified_team_name(hi_scorer_team, temp_string),
					match_goals[hi_scorer_team][hi_scorer_index]);
				break;
			case 7:
				sprintf(my_highlight -> highlight,hl_hi_score_strings[string_num],
					get_player_fname(hi_scorer_team, hi_scorer_index),
					get_player_lname(hi_scorer_team, hi_scorer_index),
//					get_team_name(hi_scorer_team^1));
					get_modified_team_name(hi_scorer_team^1,temp_string));
				break;
		}
//TOM
//		return;
//END TOM
	}

	// Is there a shutout?

	if ((home_score == 0 && visit_score) ||
		 (visit_score == 0 && home_score)) {

//TOM

			 if(!gotit)
//END TOM
			 {
			 	gotit=1;
				switch(string_num = random(NUM_HL_SHUTOUT_STRINGS)) {
					case 0:
						sprintf(my_highlight -> highlight, hl_shutout_strings[string_num],
							get_player_fname(home_score == 0 ? VISITOR_TEAM : HOME_TEAM,
										  		get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM)
										  		-> starting_goalie),	
							get_player_lname(home_score == 0 ? VISITOR_TEAM : HOME_TEAM,
										  		get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM)
										  		-> starting_goalie),	
							get_modified_team_name(home_score == 0 ? HOME_TEAM : VISITOR_TEAM, temp_string));
						break;
					case 1:
						sprintf(my_highlight -> highlight, hl_shutout_strings[string_num],
							get_player_fname(home_score == 0 ? VISITOR_TEAM : HOME_TEAM,
										  		get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM)
										  		-> starting_goalie),	
							get_player_lname(home_score == 0 ? VISITOR_TEAM : HOME_TEAM,
										  		get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM)
										  		-> starting_goalie),	
							match_goalie_shots_on[home_score == 0 ? VISITOR_TEAM : HOME_TEAM]
										  		[(int)get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM) -> starting_goalie]
						);	
						break;
					case 2:
						sprintf(my_highlight -> highlight, hl_shutout_strings[string_num],
							get_player_fname(home_score == 0 ? VISITOR_TEAM : HOME_TEAM,
										  		get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM)
										  		-> starting_goalie),	
							get_player_lname(home_score == 0 ? VISITOR_TEAM : HOME_TEAM,
										  		get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM)
										  		-> starting_goalie),	
		//					get_team_name(home_score == 0 ? HOME_TEAM : VISITOR_TEAM));
							get_modified_team_name(home_score == 0 ? HOME_TEAM : VISITOR_TEAM,temp_string));
						break;
					case 3:
						sprintf(my_highlight -> highlight, hl_shutout_strings[string_num],
							get_player_fname(home_score == 0 ? VISITOR_TEAM : HOME_TEAM,
										  		get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM)
										  		-> starting_goalie),	
							get_player_lname(home_score == 0 ? VISITOR_TEAM : HOME_TEAM,
										  		get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM)
										  		-> starting_goalie),	
							get_modified_team_name(home_score == 0 ? HOME_TEAM : VISITOR_TEAM, temp_string),

							match_goalie_shots_on[home_score == 0 ? VISITOR_TEAM : HOME_TEAM]
										  		[(int)get_team_ptr(home_score == 0 ? VISITOR_TEAM : HOME_TEAM) -> starting_goalie]
						);	
						break;
					}
			 }
//TOM
//		return;
//END TOM
	}

	// Any player with 3 or more points?

	if (hi_points >= 3) 
	{
		if (match_goals[hi_points_team][hi_points_index]) 
		{
//TOM
			 strcpy(my_highlight->ticker_hl_name[hl_number],get_player_lname(hi_points_team, hi_points_index));
			 my_highlight->ticker_hl_number[hl_number]=(match_goals[hi_points_team][hi_points_index]<<4)+match_assists[hi_points_team][hi_points_index];
			 my_highlight->ticker_hl_type[hl_number]=GOAL_ASSIST_TYPE;
			 hl_number++;
			 if(!gotit)
//END TOM
			 {
			 		gotit=1;
					string_num = random(NUM_HL_MIXED_POINT_STRINGS);
					switch(string_num) {
						case 0:
						case 1:
							sprintf(my_highlight -> highlight, hl_mixed_point_strings[string_num],
								get_player_fname(hi_points_team, hi_points_index),
								get_player_lname(hi_points_team, hi_points_index),
								match_goals[hi_points_team][hi_points_index],
								match_assists[hi_points_team][hi_points_index]);
								break;
						case 2:
							sprintf(my_highlight -> highlight, hl_mixed_point_strings[string_num],
								get_player_fname(hi_points_team, hi_points_index),
								get_player_lname(hi_points_team, hi_points_index),
								match_goals[hi_points_team][hi_points_index]+
								match_assists[hi_points_team][hi_points_index]);
								break;
					}
			 }
		}
		else 
		{
//TOM
			 strcpy(my_highlight->ticker_hl_name[hl_number],get_player_lname(hi_points_team, hi_points_index));
			 my_highlight->ticker_hl_number[hl_number]=match_assists[hi_points_team][hi_points_index];
			 my_highlight->ticker_hl_type[hl_number]=ASSIST_TYPE;
			 hl_number++;
			 if(!gotit)
//END TOM
			 {
			 	gotit=1;
					string_num = random(NUM_HL_ASSIST_STRINGS);
					sprintf(my_highlight -> highlight, hl_assist_strings[string_num],
								get_player_fname(hi_points_team, hi_points_index),
								get_player_lname(hi_points_team, hi_points_index),
							match_assists[hi_points_team][hi_points_index]);
			 }
		}
	}
//TOM
//		return;
//END TOM

	// Goalie with >= 20 shots and <= 2 goals

	if (match_goalie_goals_against[cur_match_index][(int)get_team_ptr(cur_match_index) -> starting_goalie] <= 2 && 
			 match_goalie_shots_on[cur_match_index][(int)get_team_ptr(cur_match_index) -> starting_goalie] >= 20) 
		{
//TOM
			 strcpy(my_highlight->ticker_hl_name[hl_number],get_player_lname(cur_match_index, get_team_ptr(cur_match_index) -> starting_goalie));
			 my_highlight->ticker_hl_number[hl_number]=match_goalie_shots_on[cur_match_index][(int)get_team_ptr(cur_match_index) -> starting_goalie] -
						match_goalie_goals_against[cur_match_index][(int)get_team_ptr(cur_match_index) -> starting_goalie],
			 my_highlight->ticker_hl_type[hl_number]=SAVE_TYPE;
			 hl_number++;
			 if(!gotit)
//END TOM
			 {
			 		gotit=1;
					switch(string_num = random(NUM_HL_GOALIE_STRINGS)) 
					{
						case 0:
							sprintf(my_highlight -> highlight, hl_goalie_strings[string_num],
								get_player_fname(cur_match_index, get_team_ptr(cur_match_index) -> starting_goalie),	
								get_player_lname(cur_match_index, get_team_ptr(cur_match_index) -> starting_goalie),	
								match_goalie_shots_on[cur_match_index][(int)get_team_ptr(cur_match_index) -> starting_goalie] -
									match_goalie_goals_against[cur_match_index][(int)get_team_ptr(cur_match_index) -> starting_goalie],
				  
       u_long get_compressed_length char *ebuf)
{ len, u_long *compressed_len)
{ nt attrib, MESSAGE *msg)
{ e *face, int buffer)
{ nfo *bsp, int vertex_base, Gfx **work, char flags, Vtx *vwork)
{ , char injuries_flag)
{ ewport, char transmode, 
						  short rotz, char frame)
{

0x153080:

rXDest[i];

							controllerXPos[i]-=controllerVel[i];
						}
						else
						{
							if((controllerXDest[i]-controllerXPos[i])<controllerVel[i])  //limit it
								controllerVel[i]=controllerXDest[i]-controllerXPos[i];

							controllerXPos[i]+=controllerVel[i];
						}
						distanceTraveled[i]+=controllerVel[i];
						if(controllerXPos[i]==controllerXDest[i])
						{
							controllerMoving[i]=0;
							distanceTraveled[i]=0;
							controllerVel[i]=0;
						}
					}
					if(controllerPos[i]!=0 && !controllerMoving[i] && !editing[i])
					{
						if(myPressed(i,MAPPED_PADLup)==1 && !controllerLockedIn[i])
						{
							Play_sfx_volume (FX_MENU_SUB_SELECT_BEEP, options[OPTION_SFX_VOLUME]);
							if(++stringCounter[i]>stringMax) {
								stringCounter[i]=0;
							}
//check user records full...if so, skip to first user
//							else if(numUserRecords==USERS_MAX && stringCounter[i]==1) {

							else if (!offeredANewUser[i]) {
								if (newUserCount>=numNewUsersPossible) {
									if (stringCounter[i]==1) {
										stringCounter[i]=2;
									}
								}
								else {
									offeredANewUser[i] = 1;
									newUserCount++;
								}
							}
						}
						else if(myPressed(i,MAPPED_PADLdown)==1 && !controllerLockedIn[i])
						{
							Play_sfx_volume (FX_MENU_SUB_SELECT_BEEP, options[OPTION_SFX_VOLUME]);
							if(--stringCounter[i]<0) {
								stringCounter[i]=stringMax;
							}
//check user records full...if so, skip to "player x"
//							else if(numUserRecords==USERS_MAX && stringCounter[i]==1) {

							else if (!offeredANewUser[i]) {
								if (newUserCount>=numNewUsersPossible) {
									if (stringCounter[i]==1) {
										stringCounter[i]=0;
									}
								}
								else {
									offeredANewUser[i] = 1;
									newUserCount++;
								}
							}
						}

						Set_on_off(fluffActors[i+MAX_PADS],BODY,ON);   //turn on purple bar

						if(stringCounter[i]==0)
							sprintf(tempString,"^xPlayer %d",i+1);
						else if(stringCounter[i]==1)
							sprintf(tempString,"^xNew Player");
						else
						{
							sprintf(tempString,"^x");
							strcat(tempString,(userRecords[stringCounter[i]-2].name));

							sprintf(tempString1,"  %d-%d-%d",userRecords[(stringCounter[i]-2)].wins,
																		userRecords[(stringCounter[i]-2)].losses,
																		userRecords[(stringCounter[i]-2)].ties);
							strcat(tempString,tempString1);
						}
//						Select_font(font14);
						Select_font(font18);	//ASL
						Font_ot(hi_ot);
//						fontYellow1();
						fontWhite1();		//ASL

						printCentered1(320,-61+(48*i),tempString,NULL);
					}
					else if(editing[i])
					{
						p=userRecords[userRecordNumber[i]].name;
						stringCounter[i]=userRecordNumber[i]+2;  //when we lock in name, it points to this user record

						if(reptKey(i,MAPPED_PADLup,2))
						{
							doNameChange(p,currentLetter[i],1,0);
						}
						if(reptKey(i,MAPPED_PADLdown,2))
						{
							doNameChange(p,currentLetter[i],-1,0);
						}
						if(reptKey(i,MAPPED_PADLright,2))
						{
							Play_sfx_volume (FX_MENU_SUB_SELECT2_BEEP, options[OPTION_SFX_VOLUME]);
							if(currentLetter[i]<MAX_USER_NAME-1)currentLetter[i]++;
							if(p[currentLetter[i]]==0x00)p[currentLetter[i]]='a';
						}
						if(reptKey(i,MAPPED_PADLleft,2))
						{
							Play_sfx_volume (FX_MENU_SUB_SELECT2_BEEP, options[OPTION_SFX_VOLUME]);
							if(currentLetter[i]>0)currentLetter[i]--;
						}
						if(reptKey(i,MAPPED_PADRup,2))
						{
							if(currentLetter[i]!=0 || p[1]!=0) { //don't delete first letter unless another one exist
								for(j=currentLetter[i];j<MAX_USER_NAME-1;++j)p[j]=p[j+1];
								Play_sfx_volume (FX_MENU_ERASE_BEEP, options[OPTION_SFX_VOLUME]);
							}
							if(currentLetter[i]==strlen(p))currentLetter[i]-=1;
						}
						if(reptKey(i,MAPPED_PADRdown,2))
						{
							editing[i]=0;
							Play_sfx_volume (FX_MENU_SELECT_BEEP, options[OPTION_SFX_VOLUME]);
						}

						Select_font(font18);
						Font_ot(hi_ot);
//						fontYellow1();
						fontWhite1();		//ASL

						strcpy(tempString,"^x");
						k=2;
						for(j=0;j<currentLetter[i];++j)tempString[k++]=p[j];
						sprintf(&tempString[k],"^c%c%c%c",-96,0,-96);
						k+=5;
						tempString[k++]=p[currentLetter[i]];
						sprintf(&tempString[k],"^c%c%c%c",0,0,-128);
						k+=5;
						for(j=currentLetter[i]+1;j<MAX_USER_NAME;++j)tempString[k++]=p[j];

						printCentered1(320,-61+(47*i),tempString,NULL);
					}

					else
					{
						Set_on_off(fluffActors[i+MAX_PADS],BODY,OFF);
		//				stringCounter[i]=0;
					}

					if(!controllerLockedIn[i] && !controllerMoving[i] && controllerPos!=0 &&
                  ((myPressed(i,MAPPED_PADRdown)==1) || (myPressed(i,MAPPED_PADstart)==1)) && !editing[i] )
					{
						Play_sfx_volume (FX_MENU_SELECT_BEEP, options[OPTION_SFX_VOLUME]);
						controllerLockedIn[i]=1;

						if (stringCounter[i] == 0)	{	// "Player n"
							userRecordNumber[i] = -1;
						}
						else if(stringCounter[i]==1)	// new user
						{
							userRecordNumber[i]=numUserRecords++;
							editing[i]=1;
							for(j=0;j<MAX_USER_NAME;++j)
								userRecords[userRecordNumber[i]].name[j]=0x00;
							userRecords[userRecordNumber[i]].name[0]='A';
							currentLetter[i]=0;
						}
						else if (stringCounter[i] > 1) {
							userRecordNumber[i]=stringCounter[i]-2;
						}

						if (offeredANewUser[i]) {
							newUserCount--;
					  		offeredANewUser[i] = 0;
						}
						Set_rgb(fluffActors[i],BODY,-64,-64,-64);
					}
				}
				else	//ASL to have controllers change if not connected
				{
					// controller illegal
					Set_transparent(fluffActors[i],BODY,TRANSON);
				}
				if((plugUse & CONTROLLER_MASK[i]) && !controllerLockedIn[i])
				{
					Set_rgb(fluffActors[i],BODY,0,0,0);
				}
				else if (!(plugUse & CONTROLLER_MASK[i]))
				{
					Set_rgb(fluffActors[i],BODY,-64,-64,-64);
//					Set_transparent(fluffActors[i],BODY,1);
					controllerXPos[i]=controllerPos[i]=controllerLockedIn[i]=controllerMoving[i]=stringCounter[i]=editing[i]=0;
					Set_on_off(fluffActors[i+MAX_PADS],BODY,OFF);
				}
			}
	//test for timer countdown/reset

	//reset whenever anybody moves
	//or reset if somebody out of center hasn't locked in
			for(i=0;i<MAX_PADS;++i)
				if(controllerMoving[i]!=0 || (!controllerLockedIn[i] && controllerPos[i]!=0))
					timer=TIMEOUT;

	//reset if nobody has locked in
			if(!controllerLockedIn[0] && !controllerLockedIn[1] && !controllerLockedIn[2] && !controllerLockedIn[3])
          timer=TIMEOUT;

	//reset if anybody editing
			for(i=0;i<MAX_PADS;++i)
				if(editing[i])timer=TIMEOUT;


			timer--;
			if(timer==0)
			{
				acceptingInput=0;
				globalLeavingMenu=1;

				globalNextMenu=GAME_SETUP_MENU;
				if(playMode==PLAY_MODE_PLAYOFFS || playMode==PLAY_MODE_SEASON || playMode==PLAY_MODE_SHOOTOUT)
               globalNextMenu=GOTO_GAME_MENU;
				if(playMode==PLAY_MODE_PRACTICE)
					globalNextMenu=PRACTICE_SETUP_MENU;

				gotALiveOne = 0;
				for(i=0;i<MAX_PADS;i++)
				{
					if(controllerPos[i]==0)
						padTeamAssignment[i]=-1;
					if(controllerPos[i]==1) {
						padTeamAssignment[i]=HOME;
						gotALiveOne = 1;
					}
					if(controllerPos[i]==-1) {
						padTeamAssignment[i]=AWAY;
						gotALiveOne = 1;
					}
				}

				if (!gotALiveOne)
               globalNextMenu=GOTO_GAME_MENU;
			}
		}

		if(globalLeavingMenu)
		{
			fadeCounter--;
			Init_rgb(((fadeCounter-1)*128)/FADETIME,((fadeCounter-1)*128)/FADETIME,((fadeCounter-1)*128)/FADETIME);
			if(fadeCounter==0)
			{
				// init Pete's USER_STATs

				memset(user_stat,0,sizeof(USER_STAT)*MAX_PADS);
				for (i=0; i<MAX_PADS; i++) {
					user_stat[i].user_record_num = userRecordNumber[i];
					if (userRecordNumber[i] <= -1) {
						sprintf(user_stat[i].user_name,"Player %d",i+1);
					}
					else if (userRecordNumber[i] >= 0) {
						strcpy(user_stat[i].user_name, userRecords[userRecordNumber[i]].name);
					}
				}
				killAllFluffActo�   ˜B ights;++i)
	{
		tb=&tickerBarInfo[i];
		tb->last_score_home=0;
		tb->last_score_visit=0;
		tb->last_score_home=0;
		tb->last_score_visit=0;
		tb->last_period=0;
		tb->last_clock=_PERIOD_LENGTH[options[OPTION_PERIOD_LENGTH]] *60;
		tb->last_clock_60th=0;
		tb->flag=0;
		tb->periods_til_start=0;
		tb->delay=0;
		tb->last_hl_number=0;
		resetGoalClocks(tb);

		hl_ptr = &day_highlights[i];

		//get games in progress started
		timeZoneDiff=game_time_zone-time_zone_city[hl_ptr->h_team];
		if(timeZoneDiff>=3)  //more than 3 hours of difference, so end game
		{
			//50 % of the time game in third period
			//50% of the time game done
			if(Random_percent(50,100))finishGame(&tickerBarInfo[i],hl_ptr);  
			else gameInPeriod(&tickerBarInfo[i],hl_ptr,3,TOWARDS_END);
		}
		else if(timeZoneDiff==2)
		{
			//20 % of the time game over
			//20 % of the time game in 2nd period
			//60 % of the time game in 3rd period

			if(Random_percent(20,100))finishGame(&tickerBarInfo[i],hl_ptr);  
			else if(Random_percent(20,100))gameInPeriod(&tickerBarInfo[i],hl_ptr,2,TOWARDS_END);
			else gameInPeriod(&tickerBarInfo[i],hl_ptr,3,TOWARDS_BEGIN);
		}		
		else if(timeZoneDiff==1)
		{
			//20 % of the time game in end of 2nd
			//60 % of the time game in begin 2nd period
			//20 % of the time game in end of 1st period

			if(Random_percent(20,100))gameInPeriod(&tickerBarInfo[i],hl_ptr,1,TOWARDS_END);  
			else if(Random_percent(20,100))gameInPeriod(&tickerBarInfo[i],hl_ptr,2,TOWARDS_END);  
			else gameInPeriod(&tickerBarInfo[i],hl_ptr,2,TOWARDS_BEGIN);
		}		
		else if(timeZoneDiff==0)
		{
			if(Random_percent(50,100))
			{
				tb->flag=(game_time_zone<<1);
				tb->periods_til_start=1;
				tb->delay=Ranged_random(30*10,30*45);
			}
			else
			//100 % of the time game in begin of 1st
			gameInPeriod(&tickerBarInfo[i],hl_ptr,1,TOWARDS_BEGIN);
		}		
		else 
		{
			tb->flag|=(time_zone_city[hl_ptr->h_team]<<1);
			tb->periods_til_start=-(timeZoneDiff-1);
			tb->delay=PERIODS_WORTH_OF_DELAY;
		}

	}


//randomize highlights
	for(i=0;i<num_day_highlights;++i)
	{
	 	for(j=0;j<MAX_HILITES;++j)
		{
			if(Random_percent(90,100))
			{
				k=Ranged_random(0,MAX_HILITES);
				swapHighlights(&day_highlights[i],j,k);
			}
		}
	}
	
	for(i=0;i<num_day_highlights;++i)
	{
		k=0;
	 	for(j=0;j<MAX_HILITES;++j)
		{
			if(day_highlights[i].ticker_hl_type[j-k]==NO_HILITE)
			{
				removeHighlight(&day_highlights[i],j-k);
				k+=1;
			}

		}
	}

//remove 2 goals 0 assist hilite
	for(i=0;i<num_day_highlights;++i)
	{
		l=0;
	 	for(j=0;j<MAX_HILITES;++j)
		{
			if( (day_highlights[i].ticker_hl_type[j-l]==GOAL_ASSIST_TYPE) ||
					(day_highlights[i].ticker_hl_type[j-l]==GOAL_TYPE) ||
					(day_highlights[i].ticker_hl_type[j-l]==ASSIST_TYPE)) 
			{
				if ( ((day_highlights[i].ticker_hl_number[j-l]&0x0F) == 0) || 
						((day_highlights[i].ticker_hl_number[j-l]&0xF0) == 0)  )		 
				{
						removeHighlight(&day_highlights[i],j-l);
						l++;
				}
			}
		}
	}
//remove common player highlights
	for(i=0;i<num_day_highlights;++i)
	{
		l=0;
	 	for(j=0;j<MAX_HILITES;++j)
		{
			namePtr=&(day_highlights[i].ticker_hl_name[j-l]);
			m=0;
		 	for(k=j+1;k<MAX_HILITES;++k)
			{
			  if(!(strcmp(namePtr,day_highlights[i].ticker_hl_name[k-m])))
		    {
					removeHighlight(&day_highlights[i],k-m);
				 	m++;
        }
			}
		}
	}

	while (1)
	{
		if(!gf_ticker_bar_time)
		{
			Spawn512(TID_FLUFF,Task_message_tickerbar);
			gf_ticker_bar_time=MIN_TIME_BETWEEN_TICKERS;
			gf_ticker_bar_up=1;
		}
		else if(!gf_ticker_bar_up)
		{
			if(gf_pause && (ir.state != IR_PLAYBACK))gf_ticker_bar_time=0;
			else 
			{
				if(options[OPTION_TICKERBAR_FREQUENCY]==2)gf_ticker_bar_time--;
				else if(options[OPTION_TICKERBAR_FREQUENCY]==3)gf_ticker_bar_time-=2;
				if(gf_ticker_bar_time<0)gf_ticker_bar_time=0;
			}
		}

		for(i	{
		message->s3d.pos.x += (message->newpos.x - message->s3d.pos.x) / message->speed;
		message->s3d.pos.y += (message->newpos.y - message->s3d.pos.y)

0x15C090:

= gsum->period;

						if (tmp > 3)
							tmp = 4;

		 				elapsed = Elapsed_time(gsum->clock,tmp);

						if (elapsed%60 < 10)
							sprintf(anot,"%s %d:0%d",Pause_strings[(PS_Periods[tmp])],elapsed/60,elapsed%60);
						else
							sprintf(anot,"%s %d:%d",Pause_strings[(PS_Periods[tmp])],elapsed/60,elapsed%60);

						Font_position(PM_Center_Text(anot),y_offset+y_space);
						Font_print(anot);

						//

						lines++;
						y_space += menu_dsp.height_spc;

						sprintf(anot,"%s %s",
							player_info[gsum->team][gsum->playerid].attrib.fname,
							player_info[gsum->team][gsum->playerid].attrib.lname
						);

						Font_position(PM_Center_Text(anot),y_offset+y_space);
						Font_print(anot);

						lines++;
						y_space += menu_dsp.height_spc;

						// Assist 1 & 2

						if (gsum->assist1_playerid != 0xff || gsum->assist2_playerid != 0xff)
							{

							 strcpy(anot,"ASSISTED BY");
							 Font_position(PM_Center_Text(anot),y_offset+y_space);
							 Font_print(anot);

							 lines++;
							 y_space += menu_dsp.height_spc;


							 if (gsum->assist1_playerid != 0xff)
							 	{


								sprintf(anot,"%s %s",
									player_info[gsum->team][gsum->assist1_playerid].attrib.fname,
									player_info[gsum->team][gsum->assist1_playerid].attrib.lname
								);



								Font_position(PM_Center_Text(anot),y_offset+y_space);
								Font_print(anot);

								lines++;
								y_space += menu_dsp.height_spc;

								}

							 if (gsum->assist2_playerid != 0xff)
							 	{

								sprintf(anot,"%s %s",
									player_info[gsum->team][gsum->assist2_playerid].attrib.fname,
									player_info[gsum->team][gsum->assist2_playerid].attrib.lname
								);

								Font_position(PM_Center_Text(anot),y_offset+y_space);
								Font_print(anot);

								lines++;
								y_space += menu_dsp.height_spc;

								}

							}



					   lines++;
					   y_space += menu_dsp.height_spc;


					}
				else
				if (gsum->id == 2)
					{
						str = Pause_strings[PS_PENALTY];
						Font_position(PM_Center_Text(str),y_offset+y_space);
						Font_print(str);

						lines++;
						y_space += menu_dsp.height_spc;

						tmp = gsum->period;

						if (tmp > 3)
							tmp = 4;

		 				elapsed = Elapsed_time(gsum->clock,tmp);

						if (elapsed%60 < 10)
							sprintf(anot,"%s %d:0%d",Pause_strings[(PS_Periods[tmp])],elapsed/60,elapsed%60);
						else
							sprintf(anot,"%s %d:%d",Pause_strings[(PS_Periods[tmp])],elapsed/60,elapsed%60);

						Font_position(PM_Center_Text(anot),y_offset+y_space);
						Font_print(anot);

						lines++;
						y_space += menu_dsp.height_spc;

						sprintf(anot,"%s %s",
							player_info[gsum->team][gsum->playerid].attrib.fname,
							player_info[gsum->team][gsum->playerid].attrib.lname
							);

						Font_position(PM_Center_Text(anot),y_offset+y_space);
						Font_print(anot);

						lines++;
						y_space += menu_dsp.height_spc;

					    lines++;
					    y_space += menu_dsp.height_spc;


					}



			Sleep(1);


			//
			// Buttons
			//


			if (PM_Left (team))
				{
					Get_game_summary (&cursum,PM_DOWN);
					MIDIPlaySound(PM_SOUND_SELECT);
				}
			else
			if (PM_Right (team))
				{
					Get_game_summary (&cursum,PM_UP);
					MIDIPlaySound(PM_SOUND_SELECT);
				}


			if ( PM_TRIANGLE(team) == TRUE)
				{
					PauseMenu[team].id = PAUSE_STATS;
					return;
				}


			PM_START (team);


	}



}

///////////////////////////////////////////////////////////////////////////
//
//
//	void PM_PetesCheats (char team)
//
//
///////////////////////////////////////////////////////////////////////////

void PM_DavesCheats (char team)
{
 char			local_select;
 short			y_offset;
 CAMERA			*cam;
 PDISPLAY		menu_dsp;
 short 			i;
 char			str[180];
 short			y_space;
 s_char			curspc=-20;
 char			bigx,bigy;
 short			sound_number=0;
 short			control;
 short			speed;


 #define	PM_US_LEFT		-512/2 + 140

	if (team == HOME)
		y_offset = -120;
	else
		y_offset = 0;

	menu_dsp.sx   		= 5.0*ONE;
	menu_dsp.sy   		= 5.6*ONE;
	menu_dsp.im_w     	= 5.0*PM_SHADE_X;
	menu_dsp.im_h   	= 5.6*PM_SHADE_Y;
	menu_dsp.numlines	=  9;
	menu_dsp.height_spc =  12;

	Set_display_pause(&menu_dsp, team, YES);

 	cam	=	PauseMenu[team].cam;

	local_select = PauseMenu[team].select = 0;

	Set_scale_up_down(&menu_dsp,&bigx,&bigy);

	while (1) {


			BG_Scale_fx (&menu_dsp,bigx,bigy,ONE/4,ONE/4);

			Select_font(font5_pause);

			Font_spacing(curspc);
			curspc += PAUSE_SPACE_SPEED;
			if (curspc >= -2)
				curspc = -2;

			y_space = 10+20-17;

			//

			strcpy(str,Pause_strings[PS_DAVES_CHEATS]);
			Font_ot(hi_ot);
			Font_camera(NULL);
			Font_position(PM_Center_Text(str),y_offset+y_space);
			PM_blue_font ();
			Font_print(str);
			PM_white_font ();


			// Rules

			Font_camera(PauseMenu[team].cam);
			Font_ot(PauseMenu[team].ot);

			///

			y_space += menu_dsp.height_spc;

			if (PM_clip_line (0, &menu_dsp) == FALSE )
				{
//					sprintf(str,"BLOOD MODE^t32 %s",Pause_strings[PS_OnOff[AI_DIPSWITCH[DIP_OFFENSE]]]);
					sprintf(str,"AMBIENT RED  %d", ambient_red);
					Font_option_select (team, local_select, 0);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}


			y_space += menu_dsp.height_spc;

			///

			if (PM_clip_line (1, &menu_dsp) == FALSE )
				{
					sprintf(str,"AMBIENT GREEN  %d", ambient_green);
					Font_option_select (team, local_select, 1);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}


			y_space += menu_dsp.height_spc;

			if (PM_clip_line (1, &menu_dsp) == FALSE )
				{
					sprintf(str,"AMBIENT BLUE  %d", ambient_blue);
					Font_option_select (team, local_select, 2);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}

			y_space += menu_dsp.height_spc;

			if (PM_clip_line (0, &menu_dsp) == FALSE )
				{
//					sprintf(str,"BLOOD MODE^t32 %s",Pause_strings[PS_OnOff[AI_DIPSWITCH[DIP_OFFENSE]]]);
					sprintf(str,"DIRECTIONAL RED  %d", directional_red);
					Font_option_select (team, local_select, 3);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}


			y_space += menu_dsp.height_spc;

			///

			if (PM_clip_line (1, &menu_dsp) == FALSE )
				{
					sprintf(str,"DIRECTIONAL GREEN  %d", directional_green);
					Font_option_select (team, local_select, 4);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}


			y_space += menu_dsp.height_spc;

			if (PM_clip_line (1, &menu_dsp) == FALSE )
				{
					sprintf(str,"DIRECTIONAL BLUE  %d", directional_blue);
					Font_option_select (team, local_select, 5);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}

			y_space += menu_dsp.height_spc;

			if (PM_clip_line (0, &menu_dsp) == FALSE )
				{
//					sprintf(str,"BLOOD MODE^t32 %s",Pause_strings[PS_OnOff[AI_DIPSWITCH[DIP_OFFENSE]]]);
					sprintf(str,"DIRECTIONAL X  %d", directional_x);
					Font_option_select (team, local_select, 6);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}


			y_space += menu_dsp.height_spc;

			///

			if (PM_clip_line (1, &menu_dsp) == FALSE )
				{
					sprintf(str,"DIRECTIONAL Y  %d", directional_y);
					Font_option_select (team, local_select, 7);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}


			y_space += menu_dsp.height_spc;

			if (PM_clip_line (1, &menu_dsp) == FALSE )
				{
					sprintf(str,"DIRECTIONAL Z  %d", directional_z);
					Font_option_select (team, local_select, 8);
					Font_position(PM_US_LEFT,y_offset+y_space);
					Font_print(str);
				}



			Sleep(1);

			//
			// Buttons
			//

//			if ( PM_Right(team) == TRUE)
			if ( Pressed(0, MAPPED_PADLright))
			{
				switch (local_select) 
				{

					case 0:
								ambient_red++;
								break;

					case 1:
								ambient_green++;
								break

0x1600A8:


///////////////////////////////////////////////////////////////////////////

void Font_flush(void)
{
#ifdef __psx__
	long	i;
	long	buffer;
	short	ot_length;

	//
	// Reset fonts to TOP LEFT corner of their display windows.
	//

	for (i=0; i<FONT_MAX; i++)
		{
		if (fontlist[i].id)
			{
			fontlist[i].posx	= fontlist[i].window.x;
			fontlist[i].posy	= fontlist[i].window.y;
			}
		}

	buffer	= (activeBuff+1)&1;
	font_next_polyft4[buffer] = font_polyft4[buffer];
#endif
}


///////////////////////////////////////////////////////////////////////////
//
// void Font_print(char *string)
//
//	Handles printing of fonts.
//
// Prints font from whichever was last opened.
//
//	Format support
//	--------------
//	^n	New line
//	^x	Center text in X
//	^r	Right Justify in X
//	^y	Center text in Y
//	^c	Change rgb value in text...next three bytes = r,g,b
//	^tn	Tab over n spaces from start of line. (n=1-99)
//	^vn	Tab down n lines from top of page. (n=1-99)
//
///////////////////////////////////////////////////////////////////////////

void Font_print(char *string)
{

#ifdef __psx__
	short		htab;
	short		ot_length;
	short		tabs;
 	short		i,j;
	short		red,green,blue;
	long		pixils;

	RECT		rect;
	POLY_FT4	*polyft4;
	FONTMAP		*fontmap;

	POLY_FT4	*firstft4;

	char		bitmode;
	char		bitshift;
	char 		transparent_rate;

	short		ascii;
	long		width;
	long		height;

	long		display_xpos;
	long		display_ypos;

	long yoff;


	//
	// If there is no currently opened font, just return
	//

	if (fontopen == NULL)
		return;

	//
	// Get MAP of this font.
	//

	fontmap		= (*fontopen).map;

	ot_length	= (1<<(*fontopen).ot->length) -1;

	//
	// Set bit mode for this font texture.
	//

	bitmode		= (*fontopen).bitmode;
	bitshift	= 2-bitmode;

	htab		= 0;

	if ((*fontopen).display)
		{
		display_xpos= ((*fontopen).display->s3d.pos.x>>12);
		display_ypos= ((*fontopen).display->s3d.pos.y>>12);
		}
	else{
		display_xpos= 0;
		display_ypos= 0;
		}

	// Set transparent rate.

	if ((*fontopen).trans)
		transparent_rate = (*fontopen).trans-1;
	else
		transparent_rate = 0;


	red		= RED+(*fontopen).r;
	if (red > 255)	red=255;
	if (red < 0)	red=0;
	green	= GREEN+(*fontopen).g;
	if (green > 255)green=255;
	if (green < 0)	green=0;
	blue	= BLUE+(*fontopen).b;
	if (blue > 255)	blue=255;
	if (blue < 0)	blue=0;

	//
	// Set global_clutx & global_cluty is palette location
	//

	Get_palette_vram_location((*fontopen).pal);

	//
	// Parse through string.
	//

	firstft4 = font_next_polyft4[activeBuff];
	
	for (i=0; string[i]; i++)
		{
		polyft4 = font_next_polyft4[activeBuff];

		if (string[i] == '^')
			{
			switch (string[++i])
				{
				case 'n':
					htab			= 0;
					(*fontopen).posx	= (*fontopen).window.x;
					(*fontopen).posy	+= ( (*fontopen).size_linefeed * (*fontopen).scaley) >>12;
					break;

				case 'x':

					//
					// Get length of string
					//

					j		= i+1;
					pixils	= 1;

					while (string[j])
						{
						if (string[j] == '^')
							{
							++j;
							if (string[j] == 'n')
								break;
							if (string[j] == 'c')
								j+=3;
							}

						else if (string[j] == ' ')
							{
							pixils	+= ((*fontopen).size_space * (*fontopen).scalex) >>12;
							}
						else
							{
							ascii	= (string[j]-32);
							pixils += ((fontmap[ascii].w + (*fontopen).spacing) * (*fontopen).scalex) >>12;
							}
						j++;
						}

					(*fontopen).posx	= (*fontopen).window.x+((*fontopen).window.w-(*fontopen).window.x)/2 - pixils/2;
					break;

				case 'r':

					//
					// Get length of string
					//

					j		= i+1;
					pixils	= 1;

					while (string[j])
						{
						if (string[j] == '^')
							{
							if (string[++j] == 'n')
								break;
							}

						else if (string[j] 	if (!fontopen)
	{
#if DEBUG_PRINT_SWITCH
		Debug_print(DEBUG_PRINT_SWITCH,"NULL fontopen, tried to print %s\n",string);
#endif
		return;
	}

	if ((*fontopen).d

0x162F62:

e	= (short) (100.0F * sinf( PETES_ANGLE_2_RADIANS(ANGLE090 + puck->s3d.move.z) ));

		if (puck->s3d.vel.x > FOOT*3)
		{
			r = 255;
			g = 128;
			b = 0