Annotation of doom/g_game.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com

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