Annotation of doom/g_game.c, revision 1.1.1.4

1.1.1.4 ! root        1: // Emacs style mode select   -*- C++ -*- 
        !             2: //-----------------------------------------------------------------------------
1.1.1.2   root        3: //
1.1.1.4 ! root        4: // $Id:$
1.1.1.2   root        5: //
1.1.1.4 ! root        6: // Copyright (C) 1993-1996 by id Software, Inc.
1.1.1.2   root        7: //
1.1.1.4 ! root        8: // This source is available for distribution and/or modification
        !             9: // only under the terms of the DOOM Source Code License as
        !            10: // published by id Software. All rights reserved.
1.1.1.2   root       11: //
1.1.1.4 ! root       12: // The source is distributed in the hope that it will be useful,
        !            13: // but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14: // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
        !            15: // for more details.
1.1.1.2   root       16: //
1.1.1.4 ! root       17: // $Log:$
1.1.1.2   root       18: //
1.1.1.4 ! root       19: // DESCRIPTION:  none
1.1.1.2   root       20: //
1.1.1.4 ! root       21: //-----------------------------------------------------------------------------
1.1.1.2   root       22: 
                     23: 
1.1.1.4 ! root       24: static const char
        !            25: rcsid[] = "$Id: g_game.c,v 1.8 1997/02/03 22:45:09 b1 Exp $";
1.1.1.2   root       26: 
1.1.1.4 ! root       27: #include <string.h>
        !            28: #include <stdlib.h>
1.1       root       29: 
1.1.1.4 ! root       30: #include "doomdef.h" 
        !            31: #include "doomstat.h"
1.1       root       32: 
1.1.1.4 ! root       33: #include "z_zone.h"
        !            34: #include "f_finale.h"
        !            35: #include "m_argv.h"
        !            36: #include "m_misc.h"
        !            37: #include "m_menu.h"
        !            38: #include "m_random.h"
        !            39: #include "i_system.h"
        !            40: 
        !            41: #include "p_setup.h"
        !            42: #include "p_saveg.h"
        !            43: #include "p_tick.h"
        !            44: 
        !            45: #include "d_main.h"
        !            46: 
        !            47: #include "wi_stuff.h"
        !            48: #include "hu_stuff.h"
        !            49: #include "st_stuff.h"
        !            50: #include "am_map.h"
        !            51: 
        !            52: // Needs access to LFB.
        !            53: #include "v_video.h"
        !            54: 
        !            55: #include "w_wad.h"
        !            56: 
        !            57: #include "p_local.h" 
        !            58: 
        !            59: #include "s_sound.h"
        !            60: 
        !            61: // Data.
        !            62: #include "dstrings.h"
        !            63: #include "sounds.h"
        !            64: 
        !            65: // SKY handling - still the wrong place.
        !            66: #include "r_data.h"
        !            67: #include "r_sky.h"
        !            68: 
        !            69: 
        !            70: 
        !            71: #include "g_game.h"
        !            72: 
        !            73: 
        !            74: #define SAVEGAMESIZE   0x2c000
        !            75: #define SAVESTRINGSIZE 24
        !            76: 
        !            77: 
        !            78: 
        !            79: boolean        G_CheckDemoStatus (void); 
        !            80: void   G_ReadDemoTiccmd (ticcmd_t* cmd); 
        !            81: void   G_WriteDemoTiccmd (ticcmd_t* cmd); 
        !            82: void   G_PlayerReborn (int player); 
        !            83: void   G_InitNew (skill_t skill, int episode, int map); 
        !            84:  
        !            85: void   G_DoReborn (int playernum); 
        !            86:  
        !            87: void   G_DoLoadLevel (void); 
        !            88: void   G_DoNewGame (void); 
        !            89: void   G_DoLoadGame (void); 
        !            90: void   G_DoPlayDemo (void); 
        !            91: void   G_DoCompleted (void); 
        !            92: void   G_DoVictory (void); 
        !            93: void   G_DoWorldDone (void); 
        !            94: void   G_DoSaveGame (void); 
        !            95:  
        !            96:  
        !            97: gameaction_t    gameaction; 
        !            98: gamestate_t     gamestate; 
        !            99: skill_t         gameskill; 
        !           100: boolean                respawnmonsters;
        !           101: int             gameepisode; 
        !           102: int             gamemap; 
        !           103:  
        !           104: boolean         paused; 
        !           105: boolean         sendpause;                     // send a pause event next tic 
        !           106: boolean         sendsave;              // send a save event next tic 
        !           107: boolean         usergame;               // ok to save / end game 
        !           108:  
        !           109: boolean         timingdemo;             // if true, exit with report on completion 
        !           110: boolean         nodrawers;              // for comparative timing purposes 
        !           111: boolean         noblit;                 // for comparative timing purposes 
        !           112: int             starttime;             // for comparative timing purposes       
        !           113:  
        !           114: boolean         viewactive; 
        !           115:  
        !           116: boolean         deathmatch;            // only if started as net death 
        !           117: boolean         netgame;                // only true if packets are broadcast 
        !           118: boolean         playeringame[MAXPLAYERS]; 
        !           119: player_t        players[MAXPLAYERS]; 
        !           120:  
        !           121: int             consoleplayer;          // player taking events and displaying 
        !           122: int             displayplayer;          // view being displayed 
        !           123: int             gametic; 
        !           124: int             levelstarttic;          // gametic at level start 
        !           125: int             totalkills, totalitems, totalsecret;    // for intermission 
        !           126:  
        !           127: char            demoname[32]; 
        !           128: boolean         demorecording; 
        !           129: boolean         demoplayback; 
        !           130: boolean                netdemo; 
        !           131: byte*          demobuffer;
        !           132: byte*          demo_p;
        !           133: byte*          demoend; 
        !           134: boolean         singledemo;                    // quit after playing a demo from cmdline 
        !           135:  
        !           136: boolean         precache = true;        // if true, load all graphics at start 
        !           137:  
        !           138: wbstartstruct_t wminfo;                // parms for world map / intermission 
        !           139:  
        !           140: short          consistancy[MAXPLAYERS][BACKUPTICS]; 
        !           141:  
        !           142: byte*          savebuffer;
        !           143:  
        !           144:  
        !           145: // 
        !           146: // controls (have defaults) 
        !           147: // 
        !           148: int             key_right;
        !           149: int            key_left;
1.1       root      150: 
1.1.1.4 ! root      151: int            key_up;
        !           152: int            key_down; 
        !           153: int             key_strafeleft;
        !           154: int            key_straferight; 
        !           155: int             key_fire;
        !           156: int            key_use;
        !           157: int            key_strafe;
        !           158: int            key_speed; 
        !           159:  
        !           160: int             mousebfire; 
        !           161: int             mousebstrafe; 
        !           162: int             mousebforward; 
        !           163:  
        !           164: int             joybfire; 
        !           165: int             joybstrafe; 
        !           166: int             joybuse; 
        !           167: int             joybspeed; 
        !           168:  
        !           169:  
        !           170:  
        !           171: #define MAXPLMOVE              (forwardmove[1]) 
        !           172:  
        !           173: #define TURBOTHRESHOLD 0x32
        !           174: 
        !           175: fixed_t                forwardmove[2] = {0x19, 0x32}; 
        !           176: fixed_t                sidemove[2] = {0x18, 0x28}; 
        !           177: fixed_t                angleturn[3] = {640, 1280, 320};        // + slow turn 
        !           178: 
        !           179: #define SLOWTURNTICS   6 
        !           180:  
        !           181: #define NUMKEYS                256 
        !           182: 
        !           183: boolean         gamekeydown[NUMKEYS]; 
        !           184: int             turnheld;                              // for accelerative turning 
        !           185:  
        !           186: boolean                mousearray[4]; 
        !           187: boolean*       mousebuttons = &mousearray[1];          // allow [-1]
        !           188: 
        !           189: // mouse values are used once 
        !           190: int             mousex;
        !           191: int            mousey;         
        !           192: 
        !           193: int             dclicktime;
        !           194: int            dclickstate;
        !           195: int            dclicks; 
        !           196: int             dclicktime2;
        !           197: int            dclickstate2;
        !           198: int            dclicks2;
        !           199: 
        !           200: // joystick values are repeated 
        !           201: int             joyxmove;
        !           202: int            joyymove;
        !           203: boolean         joyarray[5]; 
        !           204: boolean*       joybuttons = &joyarray[1];              // allow [-1] 
        !           205:  
        !           206: int            savegameslot; 
        !           207: char           savedescription[32]; 
        !           208:  
        !           209:  
        !           210: #define        BODYQUESIZE     32
        !           211: 
        !           212: mobj_t*                bodyque[BODYQUESIZE]; 
        !           213: int            bodyqueslot; 
        !           214:  
        !           215: void*          statcopy;                               // for statistics driver
        !           216:  
        !           217:  
        !           218:  
        !           219: int G_CmdChecksum (ticcmd_t* cmd) 
        !           220: { 
        !           221:     int                i;
        !           222:     int                sum = 0; 
        !           223:         
        !           224:     for (i=0 ; i< sizeof(*cmd)/4 - 1 ; i++) 
        !           225:        sum += ((int *)cmd)[i]; 
        !           226:                 
        !           227:     return sum; 
        !           228: } 
        !           229:  
        !           230: 
        !           231: //
        !           232: // G_BuildTiccmd
        !           233: // Builds a ticcmd from all of the available inputs
        !           234: // or reads it from the demo buffer. 
        !           235: // If recording a demo, write it out 
        !           236: // 
        !           237: void G_BuildTiccmd (ticcmd_t* cmd) 
        !           238: { 
        !           239:     int                i; 
        !           240:     boolean    strafe;
        !           241:     boolean    bstrafe; 
        !           242:     int                speed;
        !           243:     int                tspeed; 
        !           244:     int                forward;
        !           245:     int                side;
        !           246:     
        !           247:     ticcmd_t*  base;
1.1.1.2   root      248: 
1.1.1.4 ! root      249:     base = I_BaseTiccmd ();            // empty, or external driver
        !           250:     memcpy (cmd,base,sizeof(*cmd)); 
1.1.1.3   root      251:        
1.1.1.4 ! root      252:     cmd->consistancy = 
        !           253:        consistancy[consoleplayer][maketic%BACKUPTICS]; 
1.1.1.2   root      254: 
1.1.1.4 ! root      255:  
        !           256:     strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe] 
        !           257:        || joybuttons[joybstrafe]; 
        !           258:     speed = gamekeydown[key_speed] || joybuttons[joybspeed];
        !           259:  
        !           260:     forward = side = 0;
        !           261:     
        !           262:     // use two stage accelerative turning
        !           263:     // on the keyboard and joystick
        !           264:     if (joyxmove < 0
        !           265:        || joyxmove > 0  
        !           266:        || gamekeydown[key_right]
        !           267:        || gamekeydown[key_left]) 
        !           268:        turnheld += ticdup; 
        !           269:     else 
        !           270:        turnheld = 0; 
        !           271: 
        !           272:     if (turnheld < SLOWTURNTICS) 
        !           273:        tspeed = 2;             // slow turn 
        !           274:     else 
        !           275:        tspeed = speed;
        !           276:     
        !           277:     // let movement keys cancel each other out
        !           278:     if (strafe) 
        !           279:     { 
        !           280:        if (gamekeydown[key_right]) 
        !           281:        {
        !           282:            // fprintf(stderr, "strafe right\n");
        !           283:            side += sidemove[speed]; 
        !           284:        }
        !           285:        if (gamekeydown[key_left]) 
        !           286:        {
        !           287:            //  fprintf(stderr, "strafe left\n");
        !           288:            side -= sidemove[speed]; 
        !           289:        }
        !           290:        if (joyxmove > 0) 
        !           291:            side += sidemove[speed]; 
        !           292:        if (joyxmove < 0) 
        !           293:            side -= sidemove[speed]; 
        !           294:  
        !           295:     } 
        !           296:     else 
        !           297:     { 
        !           298:        if (gamekeydown[key_right]) 
        !           299:            cmd->angleturn -= angleturn[tspeed]; 
        !           300:        if (gamekeydown[key_left]) 
        !           301:            cmd->angleturn += angleturn[tspeed]; 
        !           302:        if (joyxmove > 0) 
        !           303:            cmd->angleturn -= angleturn[tspeed]; 
        !           304:        if (joyxmove < 0) 
        !           305:            cmd->angleturn += angleturn[tspeed]; 
        !           306:     } 
        !           307:  
        !           308:     if (gamekeydown[key_up]) 
        !           309:     {
        !           310:        // fprintf(stderr, "up\n");
        !           311:        forward += forwardmove[speed]; 
        !           312:     }
        !           313:     if (gamekeydown[key_down]) 
        !           314:     {
        !           315:        // fprintf(stderr, "down\n");
        !           316:        forward -= forwardmove[speed]; 
        !           317:     }
        !           318:     if (joyymove < 0) 
        !           319:        forward += forwardmove[speed]; 
        !           320:     if (joyymove > 0) 
        !           321:        forward -= forwardmove[speed]; 
        !           322:     if (gamekeydown[key_straferight]) 
        !           323:        side += sidemove[speed]; 
        !           324:     if (gamekeydown[key_strafeleft]) 
        !           325:        side -= sidemove[speed];
        !           326:     
        !           327:     // buttons
        !           328:     cmd->chatchar = HU_dequeueChatChar(); 
        !           329:  
        !           330:     if (gamekeydown[key_fire] || mousebuttons[mousebfire] 
        !           331:        || joybuttons[joybfire]) 
        !           332:        cmd->buttons |= BT_ATTACK; 
        !           333:  
        !           334:     if (gamekeydown[key_use] || joybuttons[joybuse] ) 
        !           335:     { 
        !           336:        cmd->buttons |= BT_USE;
        !           337:        // clear double clicks if hit use button 
        !           338:        dclicks = 0;                   
        !           339:     } 
        !           340: 
        !           341:     // chainsaw overrides 
        !           342:     for (i=0 ; i<NUMWEAPONS-1 ; i++)        
        !           343:        if (gamekeydown['1'+i]) 
        !           344:        { 
        !           345:            cmd->buttons |= BT_CHANGE; 
        !           346:            cmd->buttons |= i<<BT_WEAPONSHIFT; 
        !           347:            break; 
        !           348:        }
        !           349:     
        !           350:     // mouse
        !           351:     if (mousebuttons[mousebforward]) 
        !           352:        forward += forwardmove[speed];
        !           353:     
        !           354:     // forward double click
        !           355:     if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 ) 
        !           356:     { 
        !           357:        dclickstate = mousebuttons[mousebforward]; 
        !           358:        if (dclickstate) 
        !           359:            dclicks++; 
        !           360:        if (dclicks == 2) 
        !           361:        { 
        !           362:            cmd->buttons |= BT_USE; 
        !           363:            dclicks = 0; 
        !           364:        } 
        !           365:        else 
        !           366:            dclicktime = 0; 
        !           367:     } 
        !           368:     else 
        !           369:     { 
        !           370:        dclicktime += ticdup; 
        !           371:        if (dclicktime > 20) 
        !           372:        { 
        !           373:            dclicks = 0; 
        !           374:            dclickstate = 0; 
        !           375:        } 
        !           376:     }
        !           377:     
        !           378:     // strafe double click
        !           379:     bstrafe =
        !           380:        mousebuttons[mousebstrafe] 
        !           381:        || joybuttons[joybstrafe]; 
        !           382:     if (bstrafe != dclickstate2 && dclicktime2 > 1 ) 
        !           383:     { 
        !           384:        dclickstate2 = bstrafe; 
        !           385:        if (dclickstate2) 
        !           386:            dclicks2++; 
        !           387:        if (dclicks2 == 2) 
        !           388:        { 
        !           389:            cmd->buttons |= BT_USE; 
        !           390:            dclicks2 = 0; 
        !           391:        } 
        !           392:        else 
        !           393:            dclicktime2 = 0; 
        !           394:     } 
        !           395:     else 
        !           396:     { 
        !           397:        dclicktime2 += ticdup; 
        !           398:        if (dclicktime2 > 20) 
        !           399:        { 
        !           400:            dclicks2 = 0; 
        !           401:            dclickstate2 = 0; 
        !           402:        } 
        !           403:     } 
        !           404:  
        !           405:     forward += mousey; 
        !           406:     if (strafe) 
        !           407:        side += mousex*2; 
        !           408:     else 
        !           409:        cmd->angleturn -= mousex*0x8; 
        !           410: 
        !           411:     mousex = mousey = 0; 
        !           412:         
        !           413:     if (forward > MAXPLMOVE) 
        !           414:        forward = MAXPLMOVE; 
        !           415:     else if (forward < -MAXPLMOVE) 
        !           416:        forward = -MAXPLMOVE; 
        !           417:     if (side > MAXPLMOVE) 
        !           418:        side = MAXPLMOVE; 
        !           419:     else if (side < -MAXPLMOVE) 
        !           420:        side = -MAXPLMOVE; 
        !           421:  
        !           422:     cmd->forwardmove += forward; 
        !           423:     cmd->sidemove += side;
        !           424:     
        !           425:     // special buttons
        !           426:     if (sendpause) 
        !           427:     { 
        !           428:        sendpause = false; 
        !           429:        cmd->buttons = BT_SPECIAL | BTS_PAUSE; 
        !           430:     } 
        !           431:  
        !           432:     if (sendsave) 
        !           433:     { 
        !           434:        sendsave = false; 
        !           435:        cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT); 
        !           436:     } 
        !           437: } 
        !           438:  
        !           439: 
        !           440: //
        !           441: // G_DoLoadLevel 
        !           442: //
        !           443: extern  gamestate_t     wipegamestate; 
        !           444:  
        !           445: void G_DoLoadLevel (void) 
        !           446: { 
        !           447:     int             i; 
        !           448: 
        !           449:     // Set the sky map.
        !           450:     // First thing, we have a dummy sky texture name,
        !           451:     //  a flat. The data is in the WAD only because
        !           452:     //  we look for an actual index, instead of simply
        !           453:     //  setting one.
        !           454:     skyflatnum = R_FlatNumForName ( SKYFLATNAME );
        !           455: 
        !           456:     // DOOM determines the sky texture to be used
        !           457:     // depending on the current episode, and the game version.
        !           458:     if ( (gamemode == commercial)
        !           459:         || ( gamemode == pack_tnt )
        !           460:         || ( gamemode == pack_plut ) )
        !           461:     {
        !           462:        skytexture = R_TextureNumForName ("SKY3");
        !           463:        if (gamemap < 12)
        !           464:            skytexture = R_TextureNumForName ("SKY1");
        !           465:        else
        !           466:            if (gamemap < 21)
        !           467:                skytexture = R_TextureNumForName ("SKY2");
        !           468:     }
        !           469: 
        !           470:     levelstarttic = gametic;        // for time calculation
        !           471:     
        !           472:     if (wipegamestate == GS_LEVEL) 
        !           473:        wipegamestate = -1;             // force a wipe 
        !           474: 
        !           475:     gamestate = GS_LEVEL; 
        !           476: 
        !           477:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !           478:     { 
        !           479:        if (playeringame[i] && players[i].playerstate == PST_DEAD) 
        !           480:            players[i].playerstate = PST_REBORN; 
        !           481:        memset (players[i].frags,0,sizeof(players[i].frags)); 
        !           482:     } 
        !           483:                 
        !           484:     P_SetupLevel (gameepisode, gamemap, 0, gameskill);    
        !           485:     displayplayer = consoleplayer;             // view the guy you are playing    
        !           486:     starttime = I_GetTime (); 
        !           487:     gameaction = ga_nothing; 
        !           488:     Z_CheckHeap ();
        !           489:     
        !           490:     // clear cmd building stuff
        !           491:     memset (gamekeydown, 0, sizeof(gamekeydown)); 
        !           492:     joyxmove = joyymove = 0; 
        !           493:     mousex = mousey = 0; 
        !           494:     sendpause = sendsave = paused = false; 
        !           495:     memset (mousebuttons, 0, sizeof(mousebuttons)); 
        !           496:     memset (joybuttons, 0, sizeof(joybuttons)); 
        !           497: } 
        !           498:  
        !           499:  
1.1.1.2   root      500: //
1.1.1.4 ! root      501: // G_Responder  
        !           502: // Get info needed to make ticcmd_ts for the players.
1.1.1.3   root      503: // 
1.1.1.4 ! root      504: boolean G_Responder (event_t* ev) 
        !           505: { 
        !           506:     // allow spy mode changes even during the demo
        !           507:     if (gamestate == GS_LEVEL && ev->type == ev_keydown 
        !           508:        && ev->data1 == KEY_F12 && (singledemo || !deathmatch) )
        !           509:     {
        !           510:        // spy mode 
        !           511:        do 
        !           512:        { 
        !           513:            displayplayer++; 
        !           514:            if (displayplayer == MAXPLAYERS) 
        !           515:                displayplayer = 0; 
        !           516:        } while (!playeringame[displayplayer] && displayplayer != consoleplayer); 
        !           517:        return true; 
        !           518:     }
        !           519:     
        !           520:     // any other key pops up menu if in demos
        !           521:     if (gameaction == ga_nothing && !singledemo && 
        !           522:        (demoplayback || gamestate == GS_DEMOSCREEN) 
        !           523:        ) 
        !           524:     { 
        !           525:        if (ev->type == ev_keydown ||  
        !           526:            (ev->type == ev_mouse && ev->data1) || 
        !           527:            (ev->type == ev_joystick && ev->data1) ) 
        !           528:        { 
        !           529:            M_StartControlPanel (); 
        !           530:            return true; 
        !           531:        } 
        !           532:        return false; 
        !           533:     } 
        !           534:  
        !           535:     if (gamestate == GS_LEVEL) 
        !           536:     { 
        !           537: #if 0 
        !           538:        if (devparm && ev->type == ev_keydown && ev->data1 == ';') 
        !           539:        { 
        !           540:            G_DeathMatchSpawnPlayer (0); 
        !           541:            return true; 
        !           542:        } 
        !           543: #endif 
        !           544:        if (HU_Responder (ev)) 
        !           545:            return true;        // chat ate the event 
        !           546:        if (ST_Responder (ev)) 
        !           547:            return true;        // status window ate it 
        !           548:        if (AM_Responder (ev)) 
        !           549:            return true;        // automap ate it 
        !           550:     } 
        !           551:         
        !           552:     if (gamestate == GS_FINALE) 
        !           553:     { 
        !           554:        if (F_Responder (ev)) 
        !           555:            return true;        // finale ate the event 
        !           556:     } 
        !           557:         
        !           558:     switch (ev->type) 
        !           559:     { 
        !           560:       case ev_keydown: 
        !           561:        if (ev->data1 == KEY_PAUSE) 
        !           562:        { 
        !           563:            sendpause = true; 
        !           564:            return true; 
        !           565:        } 
        !           566:        if (ev->data1 <NUMKEYS) 
        !           567:            gamekeydown[ev->data1] = true; 
        !           568:        return true;    // eat key down events 
        !           569:  
        !           570:       case ev_keyup: 
        !           571:        if (ev->data1 <NUMKEYS) 
        !           572:            gamekeydown[ev->data1] = false; 
        !           573:        return false;   // always let key up events filter down 
        !           574:                 
        !           575:       case ev_mouse: 
        !           576:        mousebuttons[0] = ev->data1 & 1; 
        !           577:        mousebuttons[1] = ev->data1 & 2; 
        !           578:        mousebuttons[2] = ev->data1 & 4; 
        !           579:        mousex = ev->data2*(mouseSensitivity+5)/10; 
        !           580:        mousey = ev->data3*(mouseSensitivity+5)/10; 
        !           581:        return true;    // eat events 
        !           582:  
        !           583:       case ev_joystick: 
        !           584:        joybuttons[0] = ev->data1 & 1; 
        !           585:        joybuttons[1] = ev->data1 & 2; 
        !           586:        joybuttons[2] = ev->data1 & 4; 
        !           587:        joybuttons[3] = ev->data1 & 8; 
        !           588:        joyxmove = ev->data2; 
        !           589:        joyymove = ev->data3; 
        !           590:        return true;    // eat events 
        !           591:  
        !           592:       default: 
        !           593:        break; 
        !           594:     } 
        !           595:  
        !           596:     return false; 
        !           597: } 
        !           598:  
        !           599:  
        !           600:  
1.1.1.3   root      601: //
                    602: // G_Ticker
1.1.1.4 ! root      603: // Make ticcmd_ts for the players.
1.1.1.3   root      604: //
1.1.1.4 ! root      605: void G_Ticker (void) 
        !           606: { 
        !           607:     int                i;
        !           608:     int                buf; 
        !           609:     ticcmd_t*  cmd;
        !           610:     
        !           611:     // do player reborns if needed
        !           612:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !           613:        if (playeringame[i] && players[i].playerstate == PST_REBORN) 
        !           614:            G_DoReborn (i);
        !           615:     
        !           616:     // do things to change the game state
        !           617:     while (gameaction != ga_nothing) 
        !           618:     { 
        !           619:        switch (gameaction) 
        !           620:        { 
        !           621:          case ga_loadlevel: 
        !           622:            G_DoLoadLevel (); 
        !           623:            break; 
        !           624:          case ga_newgame: 
        !           625:            G_DoNewGame (); 
        !           626:            break; 
        !           627:          case ga_loadgame: 
        !           628:            G_DoLoadGame (); 
        !           629:            break; 
        !           630:          case ga_savegame: 
        !           631:            G_DoSaveGame (); 
        !           632:            break; 
        !           633:          case ga_playdemo: 
        !           634:            G_DoPlayDemo (); 
        !           635:            break; 
        !           636:          case ga_completed: 
        !           637:            G_DoCompleted (); 
        !           638:            break; 
        !           639:          case ga_victory: 
        !           640:            F_StartFinale (); 
        !           641:            break; 
        !           642:          case ga_worlddone: 
        !           643:            G_DoWorldDone (); 
        !           644:            break; 
        !           645:          case ga_screenshot: 
        !           646:            M_ScreenShot (); 
        !           647:            gameaction = ga_nothing; 
        !           648:            break; 
        !           649:          case ga_nothing: 
        !           650:            break; 
        !           651:        } 
        !           652:     }
        !           653:     
        !           654:     // get commands, check consistancy,
        !           655:     // and build new consistancy check
        !           656:     buf = (gametic/ticdup)%BACKUPTICS; 
        !           657:  
        !           658:     for (i=0 ; i<MAXPLAYERS ; i++)
        !           659:     {
        !           660:        if (playeringame[i]) 
        !           661:        { 
        !           662:            cmd = &players[i].cmd; 
        !           663:  
        !           664:            memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t)); 
        !           665:  
        !           666:            if (demoplayback) 
        !           667:                G_ReadDemoTiccmd (cmd); 
        !           668:            if (demorecording) 
        !           669:                G_WriteDemoTiccmd (cmd);
        !           670:            
        !           671:            // check for turbo cheats
        !           672:            if (cmd->forwardmove > TURBOTHRESHOLD 
        !           673:                && !(gametic&31) && ((gametic>>5)&3) == i )
        !           674:            {
        !           675:                static char turbomessage[80];
        !           676:                extern char *player_names[4];
        !           677:                sprintf (turbomessage, "%s is turbo!",player_names[i]);
        !           678:                players[consoleplayer].message = turbomessage;
        !           679:            }
1.1.1.3   root      680:                        
1.1.1.4 ! root      681:            if (netgame && !netdemo && !(gametic%ticdup) ) 
        !           682:            { 
        !           683:                if (gametic > BACKUPTICS 
        !           684:                    && consistancy[i][buf] != cmd->consistancy) 
        !           685:                { 
        !           686:                    I_Error ("consistency failure (%i should be %i)",
        !           687:                             cmd->consistancy, consistancy[i][buf]); 
        !           688:                } 
        !           689:                if (players[i].mo) 
        !           690:                    consistancy[i][buf] = players[i].mo->x; 
        !           691:                else 
        !           692:                    consistancy[i][buf] = rndindex; 
        !           693:            } 
        !           694:        }
        !           695:     }
        !           696:     
        !           697:     // check for special buttons
        !           698:     for (i=0 ; i<MAXPLAYERS ; i++)
        !           699:     {
        !           700:        if (playeringame[i]) 
        !           701:        { 
        !           702:            if (players[i].cmd.buttons & BT_SPECIAL) 
        !           703:            { 
        !           704:                switch (players[i].cmd.buttons & BT_SPECIALMASK) 
        !           705:                { 
        !           706:                  case BTS_PAUSE: 
        !           707:                    paused ^= 1; 
        !           708:                    if (paused) 
        !           709:                        S_PauseSound (); 
        !           710:                    else 
        !           711:                        S_ResumeSound (); 
        !           712:                    break; 
        !           713:                                         
        !           714:                  case BTS_SAVEGAME: 
        !           715:                    if (!savedescription[0]) 
        !           716:                        strcpy (savedescription, "NET GAME"); 
        !           717:                    savegameslot =  
        !           718:                        (players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT; 
        !           719:                    gameaction = ga_savegame; 
        !           720:                    break; 
        !           721:                } 
        !           722:            } 
        !           723:        }
        !           724:     }
        !           725:     
        !           726:     // do main actions
        !           727:     switch (gamestate) 
        !           728:     { 
        !           729:       case GS_LEVEL: 
        !           730:        P_Ticker (); 
        !           731:        ST_Ticker (); 
        !           732:        AM_Ticker (); 
        !           733:        HU_Ticker ();            
        !           734:        break; 
        !           735:         
        !           736:       case GS_INTERMISSION: 
        !           737:        WI_Ticker (); 
        !           738:        break; 
        !           739:                         
        !           740:       case GS_FINALE: 
        !           741:        F_Ticker (); 
        !           742:        break; 
        !           743:  
        !           744:       case GS_DEMOSCREEN: 
        !           745:        D_PageTicker (); 
        !           746:        break; 
        !           747:     }        
        !           748: } 
        !           749:  
        !           750:  
        !           751: //
        !           752: // PLAYER STRUCTURE FUNCTIONS
        !           753: // also see P_SpawnPlayer in P_Things
        !           754: //
        !           755: 
        !           756: //
        !           757: // G_InitPlayer 
        !           758: // Called at the start.
        !           759: // Called by the game initialization functions.
        !           760: //
        !           761: void G_InitPlayer (int player) 
        !           762: { 
        !           763:     player_t*  p; 
        !           764:  
        !           765:     // set up the saved info         
        !           766:     p = &players[player]; 
        !           767:         
        !           768:     // clear everything else to defaults 
        !           769:     G_PlayerReborn (player); 
        !           770:         
        !           771: } 
        !           772:  
        !           773:  
        !           774: 
        !           775: //
        !           776: // G_PlayerFinishLevel
        !           777: // Can when a player completes a level.
        !           778: //
        !           779: void G_PlayerFinishLevel (int player) 
        !           780: { 
        !           781:     player_t*  p; 
        !           782:         
        !           783:     p = &players[player]; 
        !           784:         
        !           785:     memset (p->powers, 0, sizeof (p->powers)); 
        !           786:     memset (p->cards, 0, sizeof (p->cards)); 
        !           787:     p->mo->flags &= ~MF_SHADOW;                // cancel invisibility 
        !           788:     p->extralight = 0;                 // cancel gun flashes 
        !           789:     p->fixedcolormap = 0;              // cancel ir gogles 
        !           790:     p->damagecount = 0;                        // no palette changes 
        !           791:     p->bonuscount = 0; 
        !           792: } 
        !           793:  
1.1.1.2   root      794: 
1.1.1.3   root      795: //
                    796: // G_PlayerReborn
1.1.1.4 ! root      797: // Called after a player dies 
        !           798: // almost everything is cleared and initialized 
1.1.1.3   root      799: //
1.1.1.4 ! root      800: void G_PlayerReborn (int player) 
        !           801: { 
        !           802:     player_t*  p; 
        !           803:     int                i; 
        !           804:     int                frags[MAXPLAYERS]; 
        !           805:     int                killcount;
        !           806:     int                itemcount;
        !           807:     int                secretcount; 
        !           808:         
        !           809:     memcpy (frags,players[player].frags,sizeof(frags)); 
        !           810:     killcount = players[player].killcount; 
        !           811:     itemcount = players[player].itemcount; 
        !           812:     secretcount = players[player].secretcount; 
        !           813:         
        !           814:     p = &players[player]; 
        !           815:     memset (p, 0, sizeof(*p)); 
        !           816:  
        !           817:     memcpy (players[player].frags, frags, sizeof(players[player].frags)); 
        !           818:     players[player].killcount = killcount; 
        !           819:     players[player].itemcount = itemcount; 
        !           820:     players[player].secretcount = secretcount; 
        !           821:  
        !           822:     p->usedown = p->attackdown = true; // don't do anything immediately 
        !           823:     p->playerstate = PST_LIVE;       
        !           824:     p->health = MAXHEALTH; 
        !           825:     p->readyweapon = p->pendingweapon = wp_pistol; 
        !           826:     p->weaponowned[wp_fist] = true; 
        !           827:     p->weaponowned[wp_pistol] = true; 
        !           828:     p->ammo[am_clip] = 50; 
        !           829:         
        !           830:     for (i=0 ; i<NUMAMMO ; i++) 
        !           831:        p->maxammo[i] = maxammo[i]; 
        !           832:                 
1.1.1.2   root      833: }
                    834: 
1.1.1.4 ! root      835: //
        !           836: // G_CheckSpot  
        !           837: // Returns false if the player cannot be respawned
        !           838: // at the given mapthing_t spot  
        !           839: // because something is occupying it 
        !           840: //
        !           841: void P_SpawnPlayer (mapthing_t* mthing); 
        !           842:  
        !           843: boolean
        !           844: G_CheckSpot
        !           845: ( int          playernum,
        !           846:   mapthing_t*  mthing ) 
        !           847: { 
        !           848:     fixed_t            x;
        !           849:     fixed_t            y; 
        !           850:     subsector_t*       ss; 
        !           851:     unsigned           an; 
        !           852:     mobj_t*            mo; 
        !           853:     int                        i;
1.1.1.3   root      854:        
1.1.1.4 ! root      855:     if (!players[playernum].mo)
        !           856:     {
        !           857:        // first spawn of level, before corpses
        !           858:        for (i=0 ; i<playernum ; i++)
        !           859:            if (players[i].mo->x == mthing->x << FRACBITS
        !           860:                && players[i].mo->y == mthing->y << FRACBITS)
        !           861:                return false;   
1.1.1.2   root      862:        return true;
1.1.1.4 ! root      863:     }
        !           864:                
        !           865:     x = mthing->x << FRACBITS; 
        !           866:     y = mthing->y << FRACBITS; 
        !           867:         
        !           868:     if (!P_CheckPosition (players[playernum].mo, x, y) ) 
        !           869:        return false; 
        !           870:  
        !           871:     // flush an old corpse if needed 
        !           872:     if (bodyqueslot >= BODYQUESIZE) 
        !           873:        P_RemoveMobj (bodyque[bodyqueslot%BODYQUESIZE]); 
        !           874:     bodyque[bodyqueslot%BODYQUESIZE] = players[playernum].mo; 
        !           875:     bodyqueslot++; 
1.1.1.3   root      876:        
1.1.1.4 ! root      877:     // spawn a teleport fog 
        !           878:     ss = R_PointInSubsector (x,y); 
        !           879:     an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT; 
        !           880:  
        !           881:     mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an] 
        !           882:                      , ss->sector->floorheight 
        !           883:                      , MT_TFOG); 
        !           884:         
        !           885:     if (players[consoleplayer].viewz != 1) 
        !           886:        S_StartSound (mo, sfx_telept);  // don't start sound on first frame 
        !           887:  
        !           888:     return true; 
        !           889: } 
1.1.1.2   root      890: 
                    891: 
1.1.1.3   root      892: //
1.1.1.4 ! root      893: // G_DeathMatchSpawnPlayer 
        !           894: // Spawns a player at one of the random death match spots 
        !           895: // called at level load and each death 
        !           896: //
        !           897: void G_DeathMatchSpawnPlayer (int playernum) 
        !           898: { 
        !           899:     int             i,j; 
        !           900:     int                                selections; 
        !           901:         
        !           902:     selections = deathmatch_p - deathmatchstarts; 
        !           903:     if (selections < 4) 
        !           904:        I_Error ("Only %i deathmatch spots, 4 required", selections); 
        !           905:  
        !           906:     for (j=0 ; j<20 ; j++) 
        !           907:     { 
        !           908:        i = P_Random() % selections; 
        !           909:        if (G_CheckSpot (playernum, &deathmatchstarts[i]) ) 
        !           910:        { 
        !           911:            deathmatchstarts[i].type = playernum+1; 
        !           912:            P_SpawnPlayer (&deathmatchstarts[i]); 
        !           913:            return; 
        !           914:        } 
        !           915:     } 
        !           916:  
        !           917:     // no good spot, so the player will probably get stuck 
        !           918:     P_SpawnPlayer (&playerstarts[playernum]); 
        !           919: } 
1.1.1.2   root      920: 
1.1.1.4 ! root      921: //
        !           922: // G_DoReborn 
        !           923: // 
        !           924: void G_DoReborn (int playernum) 
        !           925: { 
        !           926:     int                             i; 
        !           927:         
        !           928:     if (!netgame)
        !           929:     {
        !           930:        // reload the level from scratch
        !           931:        gameaction = ga_loadlevel;  
        !           932:     }
        !           933:     else 
        !           934:     {
        !           935:        // respawn at the start
        !           936: 
        !           937:        // first dissasociate the corpse 
        !           938:        players[playernum].mo->player = NULL;   
        !           939:                 
        !           940:        // spawn at random spot if in death match 
        !           941:        if (deathmatch) 
        !           942:        { 
        !           943:            G_DeathMatchSpawnPlayer (playernum); 
        !           944:            return; 
        !           945:        } 
        !           946:                 
        !           947:        if (G_CheckSpot (playernum, &playerstarts[playernum]) ) 
        !           948:        { 
        !           949:            P_SpawnPlayer (&playerstarts[playernum]); 
        !           950:            return; 
1.1.1.3   root      951:        }
                    952:        
1.1.1.4 ! root      953:        // try to spawn at one of the other players spots 
        !           954:        for (i=0 ; i<MAXPLAYERS ; i++)
1.1.1.3   root      955:        {
1.1.1.4 ! root      956:            if (G_CheckSpot (playernum, &playerstarts[i]) ) 
        !           957:            { 
        !           958:                playerstarts[i].type = playernum+1;     // fake as other player 
        !           959:                P_SpawnPlayer (&playerstarts[i]); 
        !           960:                playerstarts[i].type = i+1;             // restore 
        !           961:                return; 
        !           962:            }       
        !           963:            // he's going to be inside something.  Too bad.
        !           964:        }
        !           965:        P_SpawnPlayer (&playerstarts[playernum]); 
        !           966:     } 
        !           967: } 
        !           968:  
        !           969:  
        !           970: void G_ScreenShot (void) 
        !           971: { 
        !           972:     gameaction = ga_screenshot; 
        !           973: } 
        !           974:  
        !           975: 
        !           976: 
        !           977: // DOOM Par Times
        !           978: int pars[4][10] = 
        !           979: { 
        !           980:     {0}, 
        !           981:     {0,30,75,120,90,165,180,180,30,165}, 
        !           982:     {0,90,90,90,120,90,360,240,30,170}, 
        !           983:     {0,90,45,90,150,90,90,165,30,135} 
        !           984: }; 
        !           985: 
        !           986: // DOOM II Par Times
        !           987: int cpars[32] =
        !           988: {
        !           989:     30,90,120,120,90,150,120,120,270,90,       //  1-10
        !           990:     210,150,150,150,210,150,420,150,210,150,   // 11-20
        !           991:     240,150,180,150,150,300,330,420,300,180,   // 21-30
        !           992:     120,30                                     // 31-32
        !           993: };
        !           994:  
1.1.1.3   root      995: 
                    996: //
1.1.1.4 ! root      997: // G_DoCompleted 
1.1.1.3   root      998: //
1.1.1.4 ! root      999: boolean                secretexit; 
        !          1000: extern char*   pagename; 
        !          1001:  
        !          1002: void G_ExitLevel (void) 
        !          1003: { 
        !          1004:     secretexit = false; 
        !          1005:     gameaction = ga_completed; 
        !          1006: } 
        !          1007: 
        !          1008: // Here's for the german edition.
        !          1009: void G_SecretExitLevel (void) 
        !          1010: { 
        !          1011:     // IF NO WOLF3D LEVELS, NO SECRET EXIT!
        !          1012:     if ( (gamemode == commercial)
        !          1013:       && (W_CheckNumForName("map31")<0))
1.1.1.2   root     1014:        secretexit = false;
1.1.1.4 ! root     1015:     else
        !          1016:        secretexit = true; 
        !          1017:     gameaction = ga_completed; 
        !          1018: } 
        !          1019:  
        !          1020: void G_DoCompleted (void) 
        !          1021: { 
        !          1022:     int             i; 
        !          1023:         
        !          1024:     gameaction = ga_nothing; 
        !          1025:  
        !          1026:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1027:        if (playeringame[i]) 
        !          1028:            G_PlayerFinishLevel (i);        // take away cards and stuff 
        !          1029:         
        !          1030:     if (automapactive) 
        !          1031:        AM_Stop (); 
        !          1032:        
        !          1033:     if ( gamemode != commercial)
        !          1034:        switch(gamemap)
1.1.1.2   root     1035:        {
1.1.1.4 ! root     1036:          case 8:
        !          1037:            gameaction = ga_victory;
        !          1038:            return;
        !          1039:          case 9: 
        !          1040:            for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1041:                players[i].didsecret = true; 
        !          1042:            break;
1.1.1.2   root     1043:        }
1.1.1.4 ! root     1044:                
        !          1045: //#if 0  Hmmm - why?
        !          1046:     if ( (gamemap == 8)
        !          1047:         && (gamemode != commercial) ) 
        !          1048:     {
        !          1049:        // victory 
        !          1050:        gameaction = ga_victory; 
        !          1051:        return; 
        !          1052:     } 
        !          1053:         
        !          1054:     if ( (gamemap == 9)
        !          1055:         && (gamemode != commercial) ) 
        !          1056:     {
        !          1057:        // exit secret level 
        !          1058:        for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1059:            players[i].didsecret = true; 
        !          1060:     } 
        !          1061: //#endif
        !          1062:     
        !          1063:         
        !          1064:     wminfo.didsecret = players[consoleplayer].didsecret; 
        !          1065:     wminfo.epsd = gameepisode -1; 
        !          1066:     wminfo.last = gamemap -1;
        !          1067:     
        !          1068:     // wminfo.next is 0 biased, unlike gamemap
        !          1069:     if ( gamemode == commercial)
        !          1070:     {
        !          1071:        if (secretexit)
        !          1072:            switch(gamemap)
        !          1073:            {
        !          1074:              case 15: wminfo.next = 30; break;
        !          1075:              case 31: wminfo.next = 31; break;
        !          1076:            }
1.1.1.2   root     1077:        else
1.1.1.4 ! root     1078:            switch(gamemap)
        !          1079:            {
        !          1080:              case 31:
        !          1081:              case 32: wminfo.next = 15; break;
        !          1082:              default: wminfo.next = gamemap;
        !          1083:            }
        !          1084:     }
        !          1085:     else
        !          1086:     {
        !          1087:        if (secretexit) 
        !          1088:            wminfo.next = 8;    // go to secret level 
        !          1089:        else if (gamemap == 9) 
        !          1090:        {
        !          1091:            // returning from secret level 
        !          1092:            switch (gameepisode) 
        !          1093:            { 
        !          1094:              case 1: 
        !          1095:                wminfo.next = 3; 
        !          1096:                break; 
        !          1097:              case 2: 
        !          1098:                wminfo.next = 5; 
        !          1099:                break; 
        !          1100:              case 3: 
        !          1101:                wminfo.next = 6; 
        !          1102:                break; 
        !          1103:              case 4:
        !          1104:                wminfo.next = 2;
        !          1105:                break;
        !          1106:            }                
        !          1107:        } 
        !          1108:        else 
        !          1109:            wminfo.next = gamemap;          // go to next level 
        !          1110:     }
        !          1111:                 
        !          1112:     wminfo.maxkills = totalkills; 
        !          1113:     wminfo.maxitems = totalitems; 
        !          1114:     wminfo.maxsecret = totalsecret; 
        !          1115:     wminfo.maxfrags = 0; 
        !          1116:     if ( gamemode == commercial )
        !          1117:        wminfo.partime = 35*cpars[gamemap-1]; 
        !          1118:     else
        !          1119:        wminfo.partime = 35*pars[gameepisode][gamemap]; 
        !          1120:     wminfo.pnum = consoleplayer; 
        !          1121:  
        !          1122:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1123:     { 
        !          1124:        wminfo.plyr[i].in = playeringame[i]; 
        !          1125:        wminfo.plyr[i].skills = players[i].killcount; 
        !          1126:        wminfo.plyr[i].sitems = players[i].itemcount; 
        !          1127:        wminfo.plyr[i].ssecret = players[i].secretcount; 
        !          1128:        wminfo.plyr[i].stime = leveltime; 
        !          1129:        memcpy (wminfo.plyr[i].frags, players[i].frags 
        !          1130:                , sizeof(wminfo.plyr[i].frags)); 
        !          1131:     } 
        !          1132:  
        !          1133:     gamestate = GS_INTERMISSION; 
        !          1134:     viewactive = false; 
        !          1135:     automapactive = false; 
        !          1136:  
        !          1137:     if (statcopy)
        !          1138:        memcpy (statcopy, &wminfo, sizeof(wminfo));
        !          1139:        
        !          1140:     WI_Start (&wminfo); 
        !          1141: } 
1.1.1.3   root     1142: 
                   1143: 
1.1.1.2   root     1144: //
1.1.1.4 ! root     1145: // G_WorldDone 
1.1.1.2   root     1146: //
1.1.1.4 ! root     1147: void G_WorldDone (void) 
        !          1148: { 
        !          1149:     gameaction = ga_worlddone; 
        !          1150: 
        !          1151:     if (secretexit) 
        !          1152:        players[consoleplayer].didsecret = true; 
        !          1153: 
        !          1154:     if ( gamemode == commercial )
        !          1155:     {
        !          1156:        switch (gamemap)
        !          1157:        {
        !          1158:          case 15:
        !          1159:          case 31:
        !          1160:            if (!secretexit)
        !          1161:                break;
        !          1162:          case 6:
        !          1163:          case 11:
        !          1164:          case 20:
        !          1165:          case 30:
        !          1166:            F_StartFinale ();
        !          1167:            break;
        !          1168:        }
        !          1169:     }
        !          1170: } 
        !          1171:  
        !          1172: void G_DoWorldDone (void) 
        !          1173: {        
        !          1174:     gamestate = GS_LEVEL; 
        !          1175:     gamemap = wminfo.next+1; 
        !          1176:     G_DoLoadLevel (); 
        !          1177:     gameaction = ga_nothing; 
        !          1178:     viewactive = true; 
        !          1179: } 
        !          1180:  
        !          1181: 
        !          1182: 
        !          1183: //
        !          1184: // G_InitFromSavegame
        !          1185: // Can be called by the startup code or the menu task. 
        !          1186: //
        !          1187: extern boolean setsizeneeded;
        !          1188: void R_ExecuteSetViewSize (void);
        !          1189: 
        !          1190: char   savename[256];
        !          1191: 
        !          1192: void G_LoadGame (char* name) 
        !          1193: { 
        !          1194:     strcpy (savename, name); 
        !          1195:     gameaction = ga_loadgame; 
        !          1196: } 
        !          1197:  
        !          1198: #define VERSIONSIZE            16 
        !          1199: 
        !          1200: 
        !          1201: void G_DoLoadGame (void) 
        !          1202: { 
        !          1203:     int                length; 
        !          1204:     int                i; 
        !          1205:     int                a,b,c; 
        !          1206:     char       vcheck[VERSIONSIZE]; 
        !          1207:         
        !          1208:     gameaction = ga_nothing; 
        !          1209:         
        !          1210:     length = M_ReadFile (savename, &savebuffer); 
        !          1211:     save_p = savebuffer + SAVESTRINGSIZE;
        !          1212:     
        !          1213:     // skip the description field 
        !          1214:     memset (vcheck,0,sizeof(vcheck)); 
        !          1215:     sprintf (vcheck,"version %i",VERSION); 
        !          1216:     if (strcmp (save_p, vcheck)) 
        !          1217:        return;                         // bad version 
        !          1218:     save_p += VERSIONSIZE; 
        !          1219:                         
        !          1220:     gameskill = *save_p++; 
        !          1221:     gameepisode = *save_p++; 
        !          1222:     gamemap = *save_p++; 
        !          1223:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1224:        playeringame[i] = *save_p++; 
        !          1225: 
        !          1226:     // load a base level 
        !          1227:     G_InitNew (gameskill, gameepisode, gamemap); 
        !          1228:  
        !          1229:     // get the times 
        !          1230:     a = *save_p++; 
        !          1231:     b = *save_p++; 
        !          1232:     c = *save_p++; 
        !          1233:     leveltime = (a<<16) + (b<<8) + c; 
        !          1234:         
        !          1235:     // dearchive all the modifications
        !          1236:     P_UnArchivePlayers (); 
        !          1237:     P_UnArchiveWorld (); 
        !          1238:     P_UnArchiveThinkers (); 
        !          1239:     P_UnArchiveSpecials (); 
        !          1240:  
        !          1241:     if (*save_p != 0x1d) 
        !          1242:        I_Error ("Bad savegame");
        !          1243:     
        !          1244:     // done 
        !          1245:     Z_Free (savebuffer); 
        !          1246:  
        !          1247:     if (setsizeneeded)
        !          1248:        R_ExecuteSetViewSize ();
        !          1249:     
        !          1250:     // draw the pattern into the back screen
        !          1251:     R_FillBackScreen ();   
        !          1252: } 
        !          1253:  
1.1.1.2   root     1254: 
1.1.1.3   root     1255: //
                   1256: // G_SaveGame
1.1.1.4 ! root     1257: // Called by the menu task.
        !          1258: // Description is a 24 byte text string 
1.1.1.3   root     1259: //
1.1.1.4 ! root     1260: void
        !          1261: G_SaveGame
        !          1262: ( int  slot,
        !          1263:   char*        description ) 
        !          1264: { 
        !          1265:     savegameslot = slot; 
        !          1266:     strcpy (savedescription, description); 
        !          1267:     sendsave = true; 
        !          1268: } 
        !          1269:  
        !          1270: void G_DoSaveGame (void) 
        !          1271: { 
        !          1272:     char       name[100]; 
        !          1273:     char       name2[VERSIONSIZE]; 
        !          1274:     char*      description; 
        !          1275:     int                length; 
        !          1276:     int                i; 
        !          1277:        
        !          1278:     if (M_CheckParm("-cdrom"))
        !          1279:        sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",savegameslot);
        !          1280:     else
        !          1281:        sprintf (name,SAVEGAMENAME"%d.dsg",savegameslot); 
        !          1282:     description = savedescription; 
        !          1283:         
        !          1284:     save_p = savebuffer = screens[1]+0x4000; 
        !          1285:         
        !          1286:     memcpy (save_p, description, SAVESTRINGSIZE); 
        !          1287:     save_p += SAVESTRINGSIZE; 
        !          1288:     memset (name2,0,sizeof(name2)); 
        !          1289:     sprintf (name2,"version %i",VERSION); 
        !          1290:     memcpy (save_p, name2, VERSIONSIZE); 
        !          1291:     save_p += VERSIONSIZE; 
        !          1292:         
        !          1293:     *save_p++ = gameskill; 
        !          1294:     *save_p++ = gameepisode; 
        !          1295:     *save_p++ = gamemap; 
        !          1296:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1297:        *save_p++ = playeringame[i]; 
        !          1298:     *save_p++ = leveltime>>16; 
        !          1299:     *save_p++ = leveltime>>8; 
        !          1300:     *save_p++ = leveltime; 
        !          1301:  
        !          1302:     P_ArchivePlayers (); 
        !          1303:     P_ArchiveWorld (); 
        !          1304:     P_ArchiveThinkers (); 
        !          1305:     P_ArchiveSpecials (); 
        !          1306:         
        !          1307:     *save_p++ = 0x1d;          // consistancy marker 
        !          1308:         
        !          1309:     length = save_p - savebuffer; 
        !          1310:     if (length > SAVEGAMESIZE) 
        !          1311:        I_Error ("Savegame buffer overrun"); 
        !          1312:     M_WriteFile (name, savebuffer, length); 
        !          1313:     gameaction = ga_nothing; 
        !          1314:     savedescription[0] = 0;             
        !          1315:         
        !          1316:     players[consoleplayer].message = GGSAVED; 
        !          1317: 
        !          1318:     // draw the pattern into the back screen
        !          1319:     R_FillBackScreen ();       
        !          1320: } 
        !          1321:  
        !          1322: 
        !          1323: //
        !          1324: // G_InitNew
        !          1325: // Can be called by the startup code or the menu task,
        !          1326: // consoleplayer, displayplayer, playeringame[] should be set. 
        !          1327: //
        !          1328: skill_t        d_skill; 
        !          1329: int     d_episode; 
        !          1330: int     d_map; 
        !          1331:  
        !          1332: void
        !          1333: G_DeferedInitNew
        !          1334: ( skill_t      skill,
        !          1335:   int          episode,
        !          1336:   int          map) 
        !          1337: { 
        !          1338:     d_skill = skill; 
        !          1339:     d_episode = episode; 
        !          1340:     d_map = map; 
        !          1341:     gameaction = ga_newgame; 
        !          1342: } 
        !          1343: 
        !          1344: 
        !          1345: void G_DoNewGame (void) 
        !          1346: {
        !          1347:     demoplayback = false; 
        !          1348:     netdemo = false;
        !          1349:     netgame = false;
        !          1350:     deathmatch = false;
        !          1351:     playeringame[1] = playeringame[2] = playeringame[3] = 0;
        !          1352:     respawnparm = false;
        !          1353:     fastparm = false;
        !          1354:     nomonsters = false;
        !          1355:     consoleplayer = 0;
        !          1356:     G_InitNew (d_skill, d_episode, d_map); 
        !          1357:     gameaction = ga_nothing; 
        !          1358: } 
        !          1359: 
        !          1360: // The sky texture to be used instead of the F_SKY1 dummy.
        !          1361: extern  int    skytexture; 
        !          1362: 
        !          1363: 
        !          1364: void
        !          1365: G_InitNew
        !          1366: ( skill_t      skill,
        !          1367:   int          episode,
        !          1368:   int          map ) 
        !          1369: { 
        !          1370:     int             i; 
        !          1371:         
        !          1372:     if (paused) 
        !          1373:     { 
        !          1374:        paused = false; 
        !          1375:        S_ResumeSound (); 
        !          1376:     } 
        !          1377:        
1.1.1.2   root     1378: 
1.1.1.4 ! root     1379:     if (skill > sk_nightmare) 
        !          1380:        skill = sk_nightmare;
1.1.1.2   root     1381: 
                   1382: 
1.1.1.4 ! root     1383:     // This was quite messy with SPECIAL and commented parts.
        !          1384:     // Supposedly hacks to make the latest edition work.
        !          1385:     // It might not work properly.
        !          1386:     if (episode < 1)
        !          1387:       episode = 1; 
        !          1388: 
        !          1389:     if ( gamemode == retail )
        !          1390:     {
        !          1391:       if (episode > 4)
        !          1392:        episode = 4;
        !          1393:     }
        !          1394:     else if ( gamemode == shareware )
        !          1395:     {
        !          1396:       if (episode > 1) 
        !          1397:           episode = 1; // only start episode 1 on shareware
        !          1398:     }  
        !          1399:     else
        !          1400:     {
        !          1401:       if (episode > 3)
        !          1402:        episode = 3;
        !          1403:     }
        !          1404:     
        !          1405: 
        !          1406:   
        !          1407:     if (map < 1) 
        !          1408:        map = 1;
        !          1409:     
        !          1410:     if ( (map > 9)
        !          1411:         && ( gamemode != commercial) )
        !          1412:       map = 9; 
        !          1413:                 
        !          1414:     M_ClearRandom (); 
        !          1415:         
        !          1416:     if (skill == sk_nightmare || respawnparm )
        !          1417:        respawnmonsters = true;
        !          1418:     else
        !          1419:        respawnmonsters = false;
        !          1420:                
        !          1421:     if (fastparm || (skill == sk_nightmare && gameskill != sk_nightmare) )
        !          1422:     { 
        !          1423:        for (i=S_SARG_RUN1 ; i<=S_SARG_PAIN2 ; i++) 
        !          1424:            states[i].tics >>= 1; 
        !          1425:        mobjinfo[MT_BRUISERSHOT].speed = 20*FRACUNIT; 
        !          1426:        mobjinfo[MT_HEADSHOT].speed = 20*FRACUNIT; 
        !          1427:        mobjinfo[MT_TROOPSHOT].speed = 20*FRACUNIT; 
        !          1428:     } 
        !          1429:     else if (skill != sk_nightmare && gameskill == sk_nightmare) 
        !          1430:     { 
        !          1431:        for (i=S_SARG_RUN1 ; i<=S_SARG_PAIN2 ; i++) 
        !          1432:            states[i].tics <<= 1; 
        !          1433:        mobjinfo[MT_BRUISERSHOT].speed = 15*FRACUNIT; 
        !          1434:        mobjinfo[MT_HEADSHOT].speed = 10*FRACUNIT; 
        !          1435:        mobjinfo[MT_TROOPSHOT].speed = 10*FRACUNIT; 
        !          1436:     } 
        !          1437:         
        !          1438:                         
        !          1439:     // force players to be initialized upon first level load         
        !          1440:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1441:        players[i].playerstate = PST_REBORN; 
        !          1442:  
        !          1443:     usergame = true;                // will be set false if a demo 
        !          1444:     paused = false; 
        !          1445:     demoplayback = false; 
        !          1446:     automapactive = false; 
        !          1447:     viewactive = true; 
        !          1448:     gameepisode = episode; 
        !          1449:     gamemap = map; 
        !          1450:     gameskill = skill; 
        !          1451:  
        !          1452:     viewactive = true;
        !          1453:     
        !          1454:     // set the sky map for the episode
        !          1455:     if ( gamemode == commercial)
        !          1456:     {
        !          1457:        skytexture = R_TextureNumForName ("SKY3");
        !          1458:        if (gamemap < 12)
        !          1459:            skytexture = R_TextureNumForName ("SKY1");
        !          1460:        else
        !          1461:            if (gamemap < 21)
        !          1462:                skytexture = R_TextureNumForName ("SKY2");
        !          1463:     }
        !          1464:     else
        !          1465:        switch (episode) 
        !          1466:        { 
        !          1467:          case 1: 
        !          1468:            skytexture = R_TextureNumForName ("SKY1"); 
        !          1469:            break; 
        !          1470:          case 2: 
        !          1471:            skytexture = R_TextureNumForName ("SKY2"); 
        !          1472:            break; 
        !          1473:          case 3: 
        !          1474:            skytexture = R_TextureNumForName ("SKY3"); 
        !          1475:            break; 
        !          1476:          case 4:       // Special Edition sky
        !          1477:            skytexture = R_TextureNumForName ("SKY4");
        !          1478:            break;
        !          1479:        } 
        !          1480:  
        !          1481:     G_DoLoadLevel (); 
        !          1482: } 
        !          1483:  
1.1.1.2   root     1484: 
1.1.1.3   root     1485: //
1.1.1.4 ! root     1486: // DEMO RECORDING 
        !          1487: // 
        !          1488: #define DEMOMARKER             0x80
1.1.1.2   root     1489: 
                   1490: 
1.1.1.4 ! root     1491: void G_ReadDemoTiccmd (ticcmd_t* cmd) 
        !          1492: { 
        !          1493:     if (*demo_p == DEMOMARKER) 
        !          1494:     {
        !          1495:        // end of demo data stream 
        !          1496:        G_CheckDemoStatus (); 
        !          1497:        return; 
        !          1498:     } 
        !          1499:     cmd->forwardmove = ((signed char)*demo_p++); 
        !          1500:     cmd->sidemove = ((signed char)*demo_p++); 
        !          1501:     cmd->angleturn = ((unsigned char)*demo_p++)<<8; 
        !          1502:     cmd->buttons = (unsigned char)*demo_p++; 
        !          1503: } 
        !          1504: 
        !          1505: 
        !          1506: void G_WriteDemoTiccmd (ticcmd_t* cmd) 
        !          1507: { 
        !          1508:     if (gamekeydown['q'])           // press q to end demo recording 
        !          1509:        G_CheckDemoStatus (); 
        !          1510:     *demo_p++ = cmd->forwardmove; 
        !          1511:     *demo_p++ = cmd->sidemove; 
        !          1512:     *demo_p++ = (cmd->angleturn+128)>>8; 
        !          1513:     *demo_p++ = cmd->buttons; 
        !          1514:     demo_p -= 4; 
        !          1515:     if (demo_p > demoend - 16)
        !          1516:     {
        !          1517:        // no more space 
        !          1518:        G_CheckDemoStatus (); 
        !          1519:        return; 
        !          1520:     } 
1.1.1.3   root     1521:        
1.1.1.4 ! root     1522:     G_ReadDemoTiccmd (cmd);         // make SURE it is exactly the same 
        !          1523: } 
        !          1524:  
        !          1525:  
        !          1526:  
        !          1527: //
        !          1528: // G_RecordDemo 
        !          1529: // 
        !          1530: void G_RecordDemo (char* name) 
        !          1531: { 
        !          1532:     int             i; 
        !          1533:     int                                maxsize;
1.1.1.3   root     1534:        
1.1.1.4 ! root     1535:     usergame = false; 
        !          1536:     strcpy (demoname, name); 
        !          1537:     strcat (demoname, ".lmp"); 
        !          1538:     maxsize = 0x20000;
        !          1539:     i = M_CheckParm ("-maxdemo");
        !          1540:     if (i && i<myargc-1)
        !          1541:        maxsize = atoi(myargv[i+1])*1024;
        !          1542:     demobuffer = Z_Malloc (maxsize,PU_STATIC,NULL); 
        !          1543:     demoend = demobuffer + maxsize;
1.1.1.3   root     1544:        
1.1.1.4 ! root     1545:     demorecording = true; 
        !          1546: } 
        !          1547:  
        !          1548:  
        !          1549: void G_BeginRecording (void) 
        !          1550: { 
        !          1551:     int             i; 
        !          1552:                
        !          1553:     demo_p = demobuffer;
1.1.1.3   root     1554:        
1.1.1.4 ! root     1555:     *demo_p++ = VERSION;
        !          1556:     *demo_p++ = gameskill; 
        !          1557:     *demo_p++ = gameepisode; 
        !          1558:     *demo_p++ = gamemap; 
        !          1559:     *demo_p++ = deathmatch; 
        !          1560:     *demo_p++ = respawnparm;
        !          1561:     *demo_p++ = fastparm;
        !          1562:     *demo_p++ = nomonsters;
        !          1563:     *demo_p++ = consoleplayer;
        !          1564:         
        !          1565:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1566:        *demo_p++ = playeringame[i];             
        !          1567: } 
        !          1568:  
        !          1569: 
        !          1570: //
        !          1571: // G_PlayDemo 
        !          1572: //
        !          1573: 
        !          1574: char*  defdemoname; 
        !          1575:  
        !          1576: void G_DeferedPlayDemo (char* name) 
        !          1577: { 
        !          1578:     defdemoname = name; 
        !          1579:     gameaction = ga_playdemo; 
        !          1580: } 
        !          1581:  
        !          1582: void G_DoPlayDemo (void) 
        !          1583: { 
        !          1584:     skill_t skill; 
        !          1585:     int             i, episode, map; 
        !          1586:         
        !          1587:     gameaction = ga_nothing; 
        !          1588:     demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC); 
        !          1589:     if ( *demo_p++ != VERSION)
        !          1590:     {
        !          1591:       fprintf( stderr, "Demo is from a different game version!\n");
        !          1592:       gameaction = ga_nothing;
        !          1593:       return;
        !          1594:     }
        !          1595:     
        !          1596:     skill = *demo_p++; 
        !          1597:     episode = *demo_p++; 
        !          1598:     map = *demo_p++; 
        !          1599:     deathmatch = *demo_p++;
        !          1600:     respawnparm = *demo_p++;
        !          1601:     fastparm = *demo_p++;
        !          1602:     nomonsters = *demo_p++;
        !          1603:     consoleplayer = *demo_p++;
1.1.1.3   root     1604:        
1.1.1.4 ! root     1605:     for (i=0 ; i<MAXPLAYERS ; i++) 
        !          1606:        playeringame[i] = *demo_p++; 
        !          1607:     if (playeringame[1]) 
        !          1608:     { 
        !          1609:        netgame = true; 
        !          1610:        netdemo = true; 
        !          1611:     }
        !          1612: 
        !          1613:     // don't spend a lot of time in loadlevel 
        !          1614:     precache = false;
        !          1615:     G_InitNew (skill, episode, map); 
        !          1616:     precache = true; 
        !          1617: 
        !          1618:     usergame = false; 
        !          1619:     demoplayback = true; 
        !          1620: } 
        !          1621: 
        !          1622: //
        !          1623: // G_TimeDemo 
        !          1624: //
        !          1625: void G_TimeDemo (char* name) 
        !          1626: {       
        !          1627:     nodrawers = M_CheckParm ("-nodraw"); 
        !          1628:     noblit = M_CheckParm ("-noblit"); 
        !          1629:     timingdemo = true; 
        !          1630:     singletics = true; 
        !          1631: 
        !          1632:     defdemoname = name; 
        !          1633:     gameaction = ga_playdemo; 
        !          1634: } 
        !          1635:  
        !          1636:  
        !          1637: /* 
        !          1638: =================== 
        !          1639: = 
        !          1640: = G_CheckDemoStatus 
        !          1641: = 
        !          1642: = Called after a death or level completion to allow demos to be cleaned up 
        !          1643: = Returns true if a new demo loop action will take place 
        !          1644: =================== 
        !          1645: */ 
        !          1646:  
        !          1647: boolean G_CheckDemoStatus (void) 
        !          1648: { 
        !          1649:     int             endtime; 
        !          1650:         
        !          1651:     if (timingdemo) 
        !          1652:     { 
        !          1653:        endtime = I_GetTime (); 
        !          1654:        I_Error ("timed %i gametics in %i realtics",gametic 
        !          1655:                 , endtime-starttime); 
        !          1656:     } 
        !          1657:         
        !          1658:     if (demoplayback) 
        !          1659:     { 
        !          1660:        if (singledemo) 
        !          1661:            I_Quit (); 
        !          1662:                         
        !          1663:        Z_ChangeTag (demobuffer, PU_CACHE); 
        !          1664:        demoplayback = false; 
        !          1665:        netdemo = false;
        !          1666:        netgame = false;
        !          1667:        deathmatch = false;
        !          1668:        playeringame[1] = playeringame[2] = playeringame[3] = 0;
        !          1669:        respawnparm = false;
        !          1670:        fastparm = false;
        !          1671:        nomonsters = false;
        !          1672:        consoleplayer = 0;
        !          1673:        D_AdvanceDemo (); 
        !          1674:        return true; 
        !          1675:     } 
        !          1676:  
        !          1677:     if (demorecording) 
        !          1678:     { 
        !          1679:        *demo_p++ = DEMOMARKER; 
        !          1680:        M_WriteFile (demoname, demobuffer, demo_p - demobuffer); 
        !          1681:        Z_Free (demobuffer); 
        !          1682:        demorecording = false; 
        !          1683:        I_Error ("Demo %s recorded",demoname); 
        !          1684:     } 
        !          1685:         
        !          1686:     return false; 
        !          1687: } 
        !          1688:  
        !          1689:  
        !          1690:  

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.