the cutting room mirror

Uncompiled Source Code

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