Annotation of doom/g_game.c, revision 1.1.1.3

1.1.1.2   root        1: 
1.1.1.3 ! root        2: //**************************************************************************
        !             3: //**
        !             4: //** g_game.c : Heretic 2 : Raven Software, Corp.
        !             5: //**
        !             6: //** $RCSfile: g_game.c,v $
        !             7: //** $Revision: 1.68 $
        !             8: //** $Date: 96/01/12 13:18:07 $
        !             9: //** $Author: bgokey $
        !            10: //**
        !            11: //**************************************************************************
1.1.1.2   root       12: 
                     13: #include <string.h>
1.1.1.3 ! root       14: #include "h2def.h"
        !            15: #include "p_local.h"
1.1.1.2   root       16: #include "soundst.h"
                     17: 
1.1.1.3 ! root       18: #define AM_STARTKEY    9
1.1.1.2   root       19: 
1.1.1.3 ! root       20: // External functions
        !            21: 
        !            22: extern void R_InitSky(int map);
        !            23: extern void P_PlayerNextArtifact(player_t *player);
1.1.1.2   root       24: 
                     25: // Functions
                     26: 
                     27: boolean G_CheckDemoStatus (void);
                     28: void G_ReadDemoTiccmd (ticcmd_t *cmd);
                     29: void G_WriteDemoTiccmd (ticcmd_t *cmd);
                     30: void G_InitNew (skill_t skill, int episode, int map);
                     31: 
                     32: void G_DoReborn (int playernum);
                     33: 
1.1.1.3 ! root       34: void G_DoLoadLevel(void);
        !            35: void G_DoInitNew(void);
        !            36: void G_DoNewGame(void);
        !            37: void G_DoLoadGame(void);
        !            38: void G_DoPlayDemo(void);
        !            39: void G_DoTeleportNewMap(void);
        !            40: void G_DoCompleted(void);
        !            41: void G_DoVictory(void);
        !            42: void G_DoWorldDone(void);
        !            43: void G_DoSaveGame(void);
        !            44: void G_DoSingleReborn(void);
1.1.1.2   root       45: 
1.1.1.3 ! root       46: void H2_PageTicker(void);
        !            47: void H2_AdvanceDemo(void);
        !            48: 
        !            49: extern boolean mn_SuicideConsole;
1.1.1.2   root       50: 
                     51: gameaction_t    gameaction;
                     52: gamestate_t     gamestate;
                     53: skill_t         gameskill;
1.1.1.3 ! root       54: //boolean         respawnmonsters;
1.1.1.2   root       55: int             gameepisode;
                     56: int             gamemap;
1.1.1.3 ! root       57: int                             prevmap;
1.1.1.2   root       58: 
                     59: boolean         paused;
                     60: boolean         sendpause;              // send a pause event next tic
                     61: boolean         sendsave;               // send a save event next tic
                     62: boolean         usergame;               // ok to save / end game
                     63: 
                     64: boolean         timingdemo;             // if true, exit with report on completion
1.1.1.3 ! root       65: int             starttime;              // for comparative timing purposes      
1.1.1.2   root       66: 
                     67: boolean         viewactive;
                     68: 
                     69: boolean         deathmatch;             // only if started as net death
                     70: boolean         netgame;                // only true if packets are broadcast
                     71: boolean         playeringame[MAXPLAYERS];
                     72: player_t        players[MAXPLAYERS];
1.1.1.3 ! root       73: pclass_t               PlayerClass[MAXPLAYERS];
        !            74: 
        !            75: // Position indicator for cooperative net-play reborn
        !            76: int RebornPosition;
1.1.1.2   root       77: 
                     78: int             consoleplayer;          // player taking events and displaying
                     79: int             displayplayer;          // view being displayed
                     80: int             gametic;
                     81: int             levelstarttic;          // gametic at level start
                     82: 
                     83: char            demoname[32];
                     84: boolean         demorecording;
                     85: boolean         demoplayback;
                     86: byte            *demobuffer, *demo_p;
                     87: boolean         singledemo;             // quit after playing a demo from cmdline
                     88: 
                     89: boolean         precache = true;        // if true, load all graphics at start
                     90: 
                     91: short            consistancy[MAXPLAYERS][BACKUPTICS];
                     92: 
                     93: //
                     94: // controls (have defaults)
                     95: //
1.1.1.3 ! root       96: int key_right, key_left, key_up, key_down;
        !            97: int key_strafeleft, key_straferight, key_jump;
        !            98: int key_fire, key_use, key_strafe, key_speed;
        !            99: int    key_flyup, key_flydown, key_flycenter;
        !           100: int    key_lookup, key_lookdown, key_lookcenter;
        !           101: int    key_invleft, key_invright, key_useartifact;
        !           102: 
        !           103: int mousebfire;
        !           104: int mousebstrafe;
        !           105: int mousebforward;
        !           106: int mousebjump;
        !           107: 
        !           108: int joybfire;
        !           109: int joybstrafe;
        !           110: int joybuse;
        !           111: int joybspeed;
        !           112: int joybjump;
        !           113: 
        !           114: int LeaveMap;
        !           115: static int LeavePosition;
        !           116: 
        !           117: //#define MAXPLMOVE       0x32 // Old Heretic Max move
        !           118: 
        !           119: fixed_t MaxPlayerMove[NUMCLASSES] = { 0x3C, 0x32, 0x2D, 0x31 };
        !           120: fixed_t forwardmove[NUMCLASSES][2] = 
        !           121: {
        !           122:        { 0x1D, 0x3C },
        !           123:        { 0x19, 0x32 },
        !           124:        { 0x16, 0x2E },
        !           125:        { 0x18, 0x31 }
        !           126: };
        !           127:        
        !           128: fixed_t sidemove[NUMCLASSES][2] = 
        !           129: {
        !           130:        { 0x1B, 0x3B },
        !           131:        { 0x18, 0x28 },
        !           132:        { 0x15, 0x25 },
        !           133:        { 0x17, 0x27 }
        !           134: };
1.1.1.2   root      135: 
1.1.1.3 ! root      136: fixed_t angleturn[3] = {640, 1280, 320};     // + slow turn
1.1.1.2   root      137: #define SLOWTURNTICS    6
                    138: 
                    139: #define NUMKEYS 256
                    140: boolean         gamekeydown[NUMKEYS];
                    141: int             turnheld;                   // for accelerative turning
1.1.1.3 ! root      142: int                             lookheld;
1.1.1.2   root      143: 
                    144: 
                    145: boolean         mousearray[4];
                    146: boolean         *mousebuttons = &mousearray[1];
                    147:        // allow [-1]
                    148: int             mousex, mousey;             // mouse values are used once
                    149: int             dclicktime, dclickstate, dclicks;
                    150: int             dclicktime2, dclickstate2, dclicks2;
                    151: 
                    152: int             joyxmove, joyymove;         // joystick values are repeated
                    153: boolean         joyarray[5];
                    154: boolean         *joybuttons = &joyarray[1];     // allow [-1]
                    155: 
                    156: int     savegameslot;
                    157: char    savedescription[32];
                    158: 
                    159: int inventoryTics;
                    160: 
                    161: #ifdef __WATCOMC__
                    162: extern externdata_t *i_ExternData;
                    163: #endif
                    164: 
1.1.1.3 ! root      165: static skill_t TempSkill;
        !           166: static int TempEpisode;
        !           167: static int TempMap;
1.1.1.2   root      168: 
1.1.1.3 ! root      169: //=============================================================================
1.1.1.2   root      170: /*
                    171: ====================
                    172: =
                    173: = G_BuildTiccmd
                    174: =
                    175: = Builds a ticcmd from all of the available inputs or reads it from the
                    176: = demo buffer.
                    177: = If recording a demo, write it out
                    178: ====================
                    179: */
1.1       root      180: 
1.1.1.2   root      181: extern boolean inventory;
                    182: extern int curpos;
                    183: extern int inv_ptr;
                    184: 
                    185: extern  int             isCyberPresent;     // is CyberMan present?
                    186: boolean usearti = true;
                    187: void I_ReadCyberCmd (ticcmd_t *cmd);
                    188: 
                    189: void G_BuildTiccmd (ticcmd_t *cmd)
1.1       root      190: {
1.1.1.2   root      191:        int             i;
                    192:        boolean         strafe, bstrafe;
                    193:        int             speed, tspeed, lspeed;
                    194:        int             forward, side;
                    195:        int look, arti;
                    196:        int flyheight;
1.1.1.3 ! root      197:        int pClass;
1.1.1.2   root      198: 
1.1.1.3 ! root      199:        extern boolean artiskip;
1.1.1.2   root      200: 
                    201: #ifdef __WATCOMC__
                    202:        int angleDelta;
                    203:        static int oldAngle;
                    204:        extern int newViewAngleOff;
                    205:        static int externInvKey;
                    206:        extern boolean automapactive;
                    207:        event_t ev;
                    208: #endif
                    209: 
1.1.1.3 ! root      210:        pClass = players[consoleplayer].class;
1.1.1.2   root      211:        memset (cmd,0,sizeof(*cmd));
1.1.1.3 ! root      212: 
        !           213: //     cmd->consistancy =
        !           214: //             consistancy[consoleplayer][(maketic*ticdup)%BACKUPTICS];
        !           215: 
1.1.1.2   root      216:        cmd->consistancy =
                    217:                consistancy[consoleplayer][maketic%BACKUPTICS];
                    218:        if (isCyberPresent)
                    219:                I_ReadCyberCmd (cmd);
                    220: 
                    221: //printf ("cons: %i\n",cmd->consistancy);
1.1.1.3 ! root      222:        
1.1.1.2   root      223:        strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe]
                    224:                || joybuttons[joybstrafe];
                    225:        speed = gamekeydown[key_speed] || joybuttons[joybspeed]
                    226:                || joybuttons[joybspeed];
                    227: #ifdef __WATCOMC__
                    228:        if(useexterndriver)
                    229:        {
                    230:                speed |= (i_ExternData->buttons&EBT_SPEED);
                    231:                strafe |= (i_ExternData->buttons&EBT_STRAFE);
                    232:        }
                    233: #endif
                    234: 
                    235:        forward = side = look = arti = flyheight = 0;
1.1.1.3 ! root      236:        
1.1.1.2   root      237: //
                    238: // use two stage accelerative turning on the keyboard and joystick
                    239: //
1.1.1.3 ! root      240:        if (joyxmove < 0 || joyxmove > 0 
1.1.1.2   root      241:        || gamekeydown[key_right] || gamekeydown[key_left])
                    242:                turnheld += ticdup;
1.1       root      243:        else
1.1.1.2   root      244:                turnheld = 0;
                    245:        if (turnheld < SLOWTURNTICS)
                    246:                tspeed = 2;             // slow turn
                    247:        else
                    248:                tspeed = speed;
1.1       root      249: 
1.1.1.2   root      250:        if(gamekeydown[key_lookdown] || gamekeydown[key_lookup])
                    251:        {
                    252:                lookheld += ticdup;
                    253:        }
                    254:        else
                    255:        {
                    256:                lookheld = 0;
                    257:        }
                    258:        if(lookheld < SLOWTURNTICS)
                    259:        {
1.1.1.3 ! root      260:                lspeed = 1; // 3;
1.1.1.2   root      261:        }
                    262:        else
                    263:        {
1.1.1.3 ! root      264:                lspeed = 2; // 5;
1.1.1.2   root      265:        }
                    266: 
                    267: //
                    268: // let movement keys cancel each other out
                    269: //
                    270:        if(strafe)
                    271:        {
                    272:                if (gamekeydown[key_right])
1.1.1.3 ! root      273:                {
        !           274:                        side += sidemove[pClass][speed];
        !           275:                }
1.1.1.2   root      276:                if (gamekeydown[key_left])
1.1.1.3 ! root      277:                {
        !           278:                        side -= sidemove[pClass][speed];
        !           279:                }
1.1.1.2   root      280:                if (joyxmove > 0)
1.1.1.3 ! root      281:                {
        !           282:                        side += sidemove[pClass][speed];
        !           283:                }
1.1.1.2   root      284:                if (joyxmove < 0)
1.1.1.3 ! root      285:                {
        !           286:                        side -= sidemove[pClass][speed];
        !           287:                }
1.1.1.2   root      288:        }
                    289:        else
                    290:        {
                    291:                if (gamekeydown[key_right])
                    292:                        cmd->angleturn -= angleturn[tspeed];
                    293:                if (gamekeydown[key_left])
                    294:                        cmd->angleturn += angleturn[tspeed];
                    295:                if (joyxmove > 0)
                    296:                        cmd->angleturn -= angleturn[tspeed];
                    297:                if (joyxmove < 0)
                    298:                        cmd->angleturn += angleturn[tspeed];
                    299:        }
1.1       root      300: 
1.1.1.2   root      301:        if (gamekeydown[key_up])
1.1.1.3 ! root      302:        {
        !           303:                forward += forwardmove[pClass][speed];
        !           304:        }
1.1.1.2   root      305:        if (gamekeydown[key_down])
1.1.1.3 ! root      306:        {
        !           307:                forward -= forwardmove[pClass][speed];
        !           308:        }
1.1.1.2   root      309:        if (joyymove < 0)
1.1.1.3 ! root      310:        {
        !           311:                forward += forwardmove[pClass][speed];
        !           312:        }
1.1.1.2   root      313:        if (joyymove > 0)
1.1.1.3 ! root      314:        {
        !           315:                forward -= forwardmove[pClass][speed];
        !           316:        }
1.1.1.2   root      317:        if (gamekeydown[key_straferight])
1.1.1.3 ! root      318:        {
        !           319:                side += sidemove[pClass][speed];
        !           320:        }
1.1.1.2   root      321:        if (gamekeydown[key_strafeleft])
1.1.1.3 ! root      322:        {
        !           323:                side -= sidemove[pClass][speed];
        !           324:        }
1.1       root      325: 
1.1.1.2   root      326:        // Look up/down/center keys
                    327:        if(gamekeydown[key_lookup])
                    328:        {
                    329:                look = lspeed;
                    330:        }
                    331:        if(gamekeydown[key_lookdown])
                    332:        {
                    333:                look = -lspeed;
                    334:        }
                    335: #ifdef __WATCOMC__
                    336:        if(gamekeydown[key_lookcenter] && !useexterndriver)
                    337:        {
                    338:                look = TOCENTER;
                    339:        }
                    340: #else
                    341:        if(gamekeydown[key_lookcenter])
                    342:        {
                    343:                look = TOCENTER;
                    344:        }
                    345: #endif
                    346: 
                    347: #ifdef __WATCOMC__
                    348:        if(useexterndriver && look != TOCENTER && (gamestate == GS_LEVEL ||
                    349:                gamestate == GS_INTERMISSION))
                    350:        {
                    351:                if(i_ExternData->moveForward)
1.1       root      352:                {
1.1.1.2   root      353:                        forward += i_ExternData->moveForward;
                    354:                        if(speed)
1.1       root      355:                        {
1.1.1.2   root      356:                                forward <<= 1;
1.1       root      357:                        }
                    358:                }
1.1.1.2   root      359:                if(i_ExternData->angleTurn)
                    360:                {
                    361:                        if(strafe)
                    362:                        {
                    363:                                side += i_ExternData->angleTurn;
                    364:                        }
                    365:                        else
                    366:                        {
                    367:                                cmd->angleturn += i_ExternData->angleTurn;
                    368:                        }
                    369:                }
                    370:                if(i_ExternData->moveSideways)
                    371:                {
                    372:                        side += i_ExternData->moveSideways;
                    373:                        if(speed)
                    374:                        {
                    375:                                side <<= 1;
                    376:                        }
                    377:                }
                    378:                if(i_ExternData->buttons&EBT_CENTERVIEW)
1.1       root      379:                {
1.1.1.2   root      380:                        look = TOCENTER;
                    381:                        oldAngle = 0;
1.1       root      382:                }
1.1.1.2   root      383:                else if(i_ExternData->pitch)
                    384:                {
                    385:                        angleDelta = i_ExternData->pitch-oldAngle;
                    386:                        if(abs(angleDelta) < 35)
                    387:                        {
                    388:                                look = angleDelta/5;
                    389:                        }
                    390:                        else
                    391:                        {
                    392:                                look = 7*(angleDelta > 0 ? 1 : -1);
                    393:                        }
                    394:                        if(look == TOCENTER)
                    395:                        {
                    396:                                look++;
                    397:                        }
                    398:                        oldAngle += look*5;
                    399:                }
                    400:                if(i_ExternData->flyDirection)
                    401:                {
                    402:                        if(i_ExternData->flyDirection > 0)
                    403:                        {
                    404:                                flyheight = 5;
                    405:                        }
                    406:                        else
                    407:                        {
                    408:                                flyheight = -5;
                    409:                        }
                    410:                }
                    411:                if(abs(newViewAngleOff-i_ExternData->angleHead) < 3000)
                    412:                {
                    413:                        newViewAngleOff = i_ExternData->angleHead;
                    414:                }
                    415:                if(i_ExternData->buttons&EBT_FIRE)
1.1       root      416:                {
1.1.1.2   root      417:                        cmd->buttons |= BT_ATTACK;
                    418:                }
                    419:                if(i_ExternData->buttons&EBT_OPENDOOR)
                    420:                {
                    421:                        cmd->buttons |= BT_USE;
                    422:                }
                    423:                if(i_ExternData->buttons&EBT_PAUSE)
                    424:                {
1.1.1.3 ! root      425:                        cmd->buttons = BT_SPECIAL|BTS_PAUSE;
1.1.1.2   root      426:                        i_ExternData->buttons &= ~EBT_PAUSE;
                    427:                }
                    428:                if(externInvKey&EBT_USEARTIFACT)
                    429:                {
                    430:                        ev.type = ev_keyup;
                    431:                        ev.data1 = key_useartifact;
1.1.1.3 ! root      432:                        H2_PostEvent(&ev);
1.1.1.2   root      433:                        externInvKey &= ~EBT_USEARTIFACT;
                    434:                }
                    435:                else if(i_ExternData->buttons&EBT_USEARTIFACT)
                    436:                {
                    437:                        externInvKey |= EBT_USEARTIFACT;
                    438:                        ev.type = ev_keydown;
                    439:                        ev.data1 = key_useartifact;
1.1.1.3 ! root      440:                        H2_PostEvent(&ev);
1.1.1.2   root      441:                }
                    442:                if(externInvKey&EBT_INVENTORYRIGHT)
                    443:                {
                    444:                        ev.type = ev_keyup;
                    445:                        ev.data1 = key_invright;
1.1.1.3 ! root      446:                        H2_PostEvent(&ev);
1.1.1.2   root      447:                        externInvKey &= ~EBT_INVENTORYRIGHT;
                    448:                }
                    449:                else if(i_ExternData->buttons&EBT_INVENTORYRIGHT)
                    450:                {
                    451:                        externInvKey |= EBT_INVENTORYRIGHT;
                    452:                        ev.type = ev_keydown;
                    453:                        ev.data1 = key_invright;
1.1.1.3 ! root      454:                        H2_PostEvent(&ev);
1.1.1.2   root      455:                }
                    456:                if(externInvKey&EBT_INVENTORYLEFT)
                    457:                {
                    458:                        ev.type = ev_keyup;
                    459:                        ev.data1 = key_invleft;
1.1.1.3 ! root      460:                        H2_PostEvent(&ev);
1.1.1.2   root      461:                        externInvKey &= ~EBT_INVENTORYLEFT;
                    462:                }
                    463:                else if(i_ExternData->buttons&EBT_INVENTORYLEFT)
                    464:                {
                    465:                        externInvKey |= EBT_INVENTORYLEFT;
                    466:                        ev.type = ev_keydown;
                    467:                        ev.data1 = key_invleft;
1.1.1.3 ! root      468:                        H2_PostEvent(&ev);
1.1.1.2   root      469:                }
                    470:                if(i_ExternData->buttons&EBT_FLYDROP)
                    471:                {
                    472:                        flyheight = TOCENTER;
                    473:                }
                    474:                if(gamestate == GS_LEVEL)
                    475:                {
                    476:                        if(externInvKey&EBT_MAP)
1.1.1.3 ! root      477:                        { // automap
1.1.1.2   root      478:                                ev.type = ev_keyup;
                    479:                                ev.data1 = AM_STARTKEY;
1.1.1.3 ! root      480:                                H2_PostEvent(&ev);
1.1.1.2   root      481:                                externInvKey &= ~EBT_MAP;
                    482:                        }
                    483:                        else if(i_ExternData->buttons&EBT_MAP)
                    484:                        {
                    485:                                externInvKey |= EBT_MAP;
                    486:                                ev.type = ev_keydown;
                    487:                                ev.data1 = AM_STARTKEY;
1.1.1.3 ! root      488:                                H2_PostEvent(&ev);
1.1.1.2   root      489:                        }
                    490:                }
                    491:                if(i_ExternData->buttons&EBT_WEAPONCYCLE)
                    492:                {
                    493:                        int curWeapon;
                    494:                        player_t *pl;
1.1.1.3 ! root      495:                
1.1.1.2   root      496:                        pl = &players[consoleplayer];
                    497:                        curWeapon = pl->readyweapon;
1.1.1.3 ! root      498:                        for(curWeapon = (curWeapon+1)&3; curWeapon != pl->readyweapon;
        !           499:                                curWeapon = (curWeapon+1)&3)
1.1       root      500:                        {
1.1.1.2   root      501:                                if(pl->weaponowned[curWeapon])
                    502:                                {
1.1.1.3 ! root      503:                                        cmd->buttons |= BT_CHANGE;
        !           504:                                        cmd->buttons |= curWeapon<<BT_WEAPONSHIFT;
1.1.1.2   root      505:                                        break;
                    506:                                }
1.1       root      507:                        }
1.1.1.3 ! root      508:                }
        !           509:                if(i_ExternData->buttons&EBT_JUMP)
        !           510:                {
        !           511:                        cmd->arti |= AFLAG_JUMP;
1.1.1.2   root      512:                }
                    513:        }
1.1       root      514: #endif
                    515: 
1.1.1.2   root      516:        // Fly up/down/drop keys
                    517:        if(gamekeydown[key_flyup])
                    518:        {
                    519:                flyheight = 5; // note that the actual flyheight will be twice this
                    520:        }
                    521:        if(gamekeydown[key_flydown])
                    522:        {
                    523:                flyheight = -5;
                    524:        }
                    525:        if(gamekeydown[key_flycenter])
                    526:        {
                    527:                flyheight = TOCENTER;
                    528: #ifdef __WATCOMC__
                    529:                if(!useexterndriver)
                    530:                {
                    531:                        look = TOCENTER;
1.1       root      532:                }
1.1.1.2   root      533: #else
                    534:                look = TOCENTER;
1.1       root      535: #endif
1.1.1.2   root      536:        }
                    537:        // Use artifact key
                    538:        if(gamekeydown[key_useartifact])
                    539:        {
1.1.1.3 ! root      540:                if(gamekeydown[key_speed] && artiskip)
1.1.1.2   root      541:                {
                    542:                        if(players[consoleplayer].inventory[inv_ptr].type != arti_none)
1.1.1.3 ! root      543:                        { // Skip an artifact
1.1.1.2   root      544:                                gamekeydown[key_useartifact] = false;
1.1.1.3 ! root      545:                                P_PlayerNextArtifact(&players[consoleplayer]);                  
1.1.1.2   root      546:                        }
                    547:                }
                    548:                else
                    549:                {
                    550:                        if(inventory)
                    551:                        {
                    552:                                players[consoleplayer].readyArtifact =
                    553:                                        players[consoleplayer].inventory[inv_ptr].type;
                    554:                                inventory = false;
                    555:                                cmd->arti = 0;
                    556:                                usearti = false;
                    557:                        }
                    558:                        else if(usearti)
                    559:                        {
1.1.1.3 ! root      560:                                cmd->arti |= 
        !           561:                                        players[consoleplayer].inventory[inv_ptr].type&AFLAG_MASK;
1.1.1.2   root      562:                                usearti = false;
                    563:                        }
                    564:                }
                    565:        }
1.1.1.3 ! root      566:        if(gamekeydown[key_jump] || mousebuttons[mousebjump]
        !           567:                || joybuttons[joybjump])
1.1.1.2   root      568:        {
1.1.1.3 ! root      569:                cmd->arti |= AFLAG_JUMP;
        !           570:        }
        !           571:        if(mn_SuicideConsole)
        !           572:        {
        !           573:                cmd->arti |= AFLAG_SUICIDE;
        !           574:                mn_SuicideConsole = false;
        !           575:        }
        !           576: 
        !           577:        // Artifact hot keys
        !           578:        if(gamekeydown[KEY_BACKSPACE] && !cmd->arti)
        !           579:        {
        !           580:                gamekeydown[KEY_BACKSPACE] = false;     // Use one of each artifact
        !           581:                cmd->arti = NUMARTIFACTS;
        !           582:        }
        !           583:        else if(gamekeydown[KEY_BACKSLASH] && !cmd->arti 
        !           584:        && (players[consoleplayer].mo->health < MAXHEALTH))
        !           585:        {
        !           586:                gamekeydown[KEY_BACKSLASH] = false;
        !           587:                cmd->arti = arti_health;                                                
        !           588:        }
        !           589:        else if(gamekeydown[KEY_ZERO] && !cmd->arti)
        !           590:        {
        !           591:                gamekeydown[KEY_ZERO] = false;
        !           592:                cmd->arti = arti_poisonbag;                                             
        !           593:        }
        !           594:        else if(gamekeydown[KEY_NINE] && !cmd->arti)
        !           595:        {
        !           596:                gamekeydown[KEY_NINE] = false;
        !           597:                cmd->arti = arti_blastradius;                                   
        !           598:        }
        !           599:        else if(gamekeydown[KEY_EIGHT] && !cmd->arti)
        !           600:        {
        !           601:                gamekeydown[KEY_EIGHT] = false;
        !           602:                cmd->arti = arti_teleport;                                              
        !           603:        }
        !           604:        else if(gamekeydown[KEY_SEVEN] && !cmd->arti)
        !           605:        {
        !           606:                gamekeydown[KEY_SEVEN] = false;
        !           607:                cmd->arti = arti_teleportother;                                         
        !           608:        }
        !           609:        else if(gamekeydown[KEY_SIX] && !cmd->arti)
        !           610:        {
        !           611:                gamekeydown[KEY_SIX] = false;
        !           612:                cmd->arti = arti_egg;                                           
        !           613:        }
        !           614:        else if(gamekeydown[KEY_FIVE] && !cmd->arti
        !           615:        && !players[consoleplayer].powers[pw_invulnerability])
        !           616:        {
        !           617:                gamekeydown[KEY_FIVE] = false;
        !           618:                cmd->arti = arti_invulnerability;                               
1.1.1.2   root      619:        }
                    620: 
                    621: //
                    622: // buttons
                    623: //
                    624:        cmd->chatchar = CT_dequeueChatChar();
                    625: 
                    626:        if (gamekeydown[key_fire] || mousebuttons[mousebfire]
                    627:                || joybuttons[joybfire])
                    628:                cmd->buttons |= BT_ATTACK;
                    629: 
                    630:        if (gamekeydown[key_use] || joybuttons[joybuse] )
                    631:        {
                    632:                cmd->buttons |= BT_USE;
                    633:                dclicks = 0;                    // clear double clicks if hit use button
                    634:        }
1.1.1.3 ! root      635:        
        !           636:        for(i = 0; i < NUMWEAPONS; i++)
1.1.1.2   root      637:        {
                    638:                if(gamekeydown['1'+i])
                    639:                {
                    640:                        cmd->buttons |= BT_CHANGE;
                    641:                        cmd->buttons |= i<<BT_WEAPONSHIFT;
                    642:                        break;
                    643:                }
                    644:        }
                    645: 
                    646: //
                    647: // mouse
                    648: //
                    649:        if (mousebuttons[mousebforward])
                    650:        {
1.1.1.3 ! root      651:                forward += forwardmove[pClass][speed];
1.1.1.2   root      652:        }
1.1.1.3 ! root      653:                
1.1.1.2   root      654: //
                    655: // forward double click
                    656: //
                    657:        if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 )
                    658:        {
                    659:                dclickstate = mousebuttons[mousebforward];
                    660:                if (dclickstate)
                    661:                        dclicks++;
                    662:                if (dclicks == 2)
                    663:                {
                    664:                        cmd->buttons |= BT_USE;
                    665:                        dclicks = 0;
                    666:                }
                    667:                else
                    668:                        dclicktime = 0;
                    669:        }
                    670:        else
                    671:        {
                    672:                dclicktime += ticdup;
                    673:                if (dclicktime > 20)
                    674:                {
                    675:                        dclicks = 0;
                    676:                        dclickstate = 0;
                    677:                }
                    678:        }
1.1.1.3 ! root      679:        
1.1.1.2   root      680: //
                    681: // strafe double click
                    682: //
                    683:        bstrafe = mousebuttons[mousebstrafe]
                    684: || joybuttons[joybstrafe];
                    685:        if (bstrafe != dclickstate2 && dclicktime2 > 1 )
                    686:        {
                    687:                dclickstate2 = bstrafe;
                    688:                if (dclickstate2)
                    689:                        dclicks2++;
                    690:                if (dclicks2 == 2)
                    691:                {
                    692:                        cmd->buttons |= BT_USE;
                    693:                        dclicks2 = 0;
                    694:                }
                    695:                else
                    696:                        dclicktime2 = 0;
                    697:        }
                    698:        else
                    699:        {
                    700:                dclicktime2 += ticdup;
                    701:                if (dclicktime2 > 20)
                    702:                {
                    703:                        dclicks2 = 0;
                    704:                        dclickstate2 = 0;
                    705:                }
                    706:        }
                    707: 
                    708:        if (strafe)
                    709:        {
                    710:                side += mousex*2;
                    711:        }
                    712:        else
                    713:        {
                    714:                cmd->angleturn -= mousex*0x8;
1.1.1.3 ! root      715:        }       
1.1.1.2   root      716:        forward += mousey;
                    717:        mousex = mousey = 0;
1.1.1.3 ! root      718:        
        !           719:        if (forward > MaxPlayerMove[pClass])
        !           720:        {
        !           721:                forward = MaxPlayerMove[pClass];
        !           722:        }
        !           723:        else if (forward < -MaxPlayerMove[pClass])
        !           724:        {
        !           725:                forward = -MaxPlayerMove[pClass];
        !           726:        }
        !           727:        if (side > MaxPlayerMove[pClass])
        !           728:        {
        !           729:                side = MaxPlayerMove[pClass];
        !           730:        }
        !           731:        else if (side < -MaxPlayerMove[pClass])
        !           732:        {
        !           733:                side = -MaxPlayerMove[pClass];
        !           734:        }
1.1.1.2   root      735: 
1.1.1.3 ! root      736:        if(players[consoleplayer].powers[pw_speed]
        !           737:                && !players[consoleplayer].morphTics)
        !           738:        { // Adjust for a player with a speed artifact
        !           739:                forward = (3*forward)>>1;
        !           740:                side = (3*side)>>1;
        !           741:        }
1.1.1.2   root      742:        cmd->forwardmove += forward;
                    743:        cmd->sidemove += side;
                    744:        if(players[consoleplayer].playerstate == PST_LIVE)
                    745:        {
                    746:                if(look < 0)
                    747:                {
                    748:                        look += 16;
                    749:                }
                    750:                cmd->lookfly = look;
                    751:        }
                    752:        if(flyheight < 0)
                    753:        {
                    754:                flyheight += 16;
                    755:        }
                    756:        cmd->lookfly |= flyheight<<4;
                    757: 
                    758: //
                    759: // special buttons
                    760: //
                    761:        if (sendpause)
                    762:        {
                    763:                sendpause = false;
                    764:                cmd->buttons = BT_SPECIAL | BTS_PAUSE;
                    765:        }
1.1       root      766: 
1.1.1.2   root      767:        if (sendsave)
                    768:        {
                    769:                sendsave = false;
                    770:                cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT);
1.1       root      771:        }
                    772: }
                    773: 
                    774: 
1.1.1.2   root      775: /*
                    776: ==============
                    777: =
                    778: = G_DoLoadLevel
                    779: =
                    780: ==============
                    781: */
                    782: 
                    783: void G_DoLoadLevel (void)
                    784: {
                    785:        int             i;
1.1.1.3 ! root      786:        
        !           787:        levelstarttic = gametic;        // for time calculation 
1.1.1.2   root      788:        gamestate = GS_LEVEL;
                    789:        for (i=0 ; i<MAXPLAYERS ; i++)
                    790:        {
                    791:                if (playeringame[i] && players[i].playerstate == PST_DEAD)
                    792:                        players[i].playerstate = PST_REBORN;
                    793:                memset (players[i].frags,0,sizeof(players[i].frags));
                    794:        }
                    795: 
1.1.1.3 ! root      796:        SN_StopAllSequences();  
        !           797:        P_SetupLevel (gameepisode, gamemap, 0, gameskill);   
        !           798:        displayplayer = consoleplayer;      // view the guy you are playing   
1.1.1.2   root      799:        starttime = I_GetTime ();
                    800:        gameaction = ga_nothing;
                    801:        Z_CheckHeap ();
                    802: 
                    803: //
                    804: // clear cmd building stuff
1.1.1.3 ! root      805: // 
1.1.1.2   root      806: 
                    807:        memset (gamekeydown, 0, sizeof(gamekeydown));
                    808:        joyxmove = joyymove = 0;
                    809:        mousex = mousey = 0;
                    810:        sendpause = sendsave = paused = false;
                    811:        memset (mousebuttons, 0, sizeof(mousebuttons));
                    812:        memset (joybuttons, 0, sizeof(joybuttons));
1.1       root      813: }
                    814: 
1.1.1.2   root      815: 
1.1       root      816: /*
1.1.1.2   root      817: ===============================================================================
1.1       root      818: =
1.1.1.3 ! root      819: = G_Responder 
1.1.1.2   root      820: =
                    821: = get info needed to make ticcmd_ts for the players
1.1       root      822: =
1.1.1.2   root      823: ===============================================================================
1.1       root      824: */
                    825: 
1.1.1.2   root      826: boolean G_Responder(event_t *ev)
1.1       root      827: {
1.1.1.2   root      828:        player_t *plr;
                    829:        extern boolean MenuActive;
                    830: 
                    831:        plr = &players[consoleplayer];
                    832:        if(ev->type == ev_keyup && ev->data1 == key_useartifact)
                    833:        { // flag to denote that it's okay to use an artifact
                    834:                if(!inventory)
                    835:                {
                    836:                        plr->readyArtifact = plr->inventory[inv_ptr].type;
                    837:                }
                    838:                usearti = true;
                    839:        }
                    840: 
                    841:        // Check for spy mode player cycle
                    842:        if(gamestate == GS_LEVEL && ev->type == ev_keydown
                    843:                && ev->data1 == KEY_F12 && !deathmatch)
                    844:        { // Cycle the display player
                    845:                do
                    846:                {
                    847:                        displayplayer++;
                    848:                        if(displayplayer == MAXPLAYERS)
                    849:                        {
                    850:                                displayplayer = 0;
                    851:                        }
                    852:                } while(!playeringame[displayplayer]
                    853:                        && displayplayer != consoleplayer);
                    854:                return(true);
                    855:        }
                    856: 
1.1.1.3 ! root      857:        if(CT_Responder(ev))
        !           858:        { // Chat ate the event
        !           859:                return(true);
        !           860:        }
1.1.1.2   root      861:        if(gamestate == GS_LEVEL)
                    862:        {
                    863:                if(SB_Responder(ev))
                    864:                { // Status bar ate the event
                    865:                        return(true);
                    866:                }
                    867:                if(AM_Responder(ev))
                    868:                { // Automap ate the event
                    869:                        return(true);
                    870:                }
                    871:        }
                    872: 
                    873:        switch(ev->type)
1.1       root      874:        {
1.1.1.2   root      875:                case ev_keydown:
                    876:                        if(ev->data1 == key_invleft)
                    877:                        {
                    878:                                inventoryTics = 5*35;
                    879:                                if(!inventory)
                    880:                                {
                    881:                                        inventory = true;
                    882:                                        break;
                    883:                                }
                    884:                                inv_ptr--;
                    885:                                if(inv_ptr < 0)
                    886:                                {
                    887:                                        inv_ptr = 0;
                    888:                                }
                    889:                                else
                    890:                                {
                    891:                                        curpos--;
                    892:                                        if(curpos < 0)
                    893:                                        {
                    894:                                                curpos = 0;
                    895:                                        }
                    896:                                }
                    897:                                return(true);
                    898:                        }
                    899:                        if(ev->data1 == key_invright)
                    900:                        {
                    901:                                inventoryTics = 5*35;
                    902:                                if(!inventory)
                    903:                                {
                    904:                                        inventory = true;
                    905:                                        break;
                    906:                                }
                    907:                                inv_ptr++;
                    908:                                if(inv_ptr >= plr->inventorySlotNum)
                    909:                                {
                    910:                                        inv_ptr--;
                    911:                                        if(inv_ptr < 0)
                    912:                                                inv_ptr = 0;
                    913:                                }
                    914:                                else
                    915:                                {
                    916:                                        curpos++;
                    917:                                        if(curpos > 6)
                    918:                                        {
                    919:                                                curpos = 6;
                    920:                                        }
                    921:                                }
                    922:                                return(true);
                    923:                        }
                    924:                        if(ev->data1 == KEY_PAUSE && !MenuActive)
                    925:                        {
                    926:                                sendpause = true;
                    927:                                return(true);
                    928:                        }
                    929:                        if(ev->data1 < NUMKEYS)
                    930:                        {
                    931:                                gamekeydown[ev->data1] = true;
                    932:                        }
                    933:                        return(true); // eat key down events
                    934: 
                    935:                case ev_keyup:
                    936:                        if(ev->data1 < NUMKEYS)
                    937:                        {
                    938:                                gamekeydown[ev->data1] = false;
                    939:                        }
                    940:                        return(false); // always let key up events filter down
                    941: 
                    942:                case ev_mouse:
                    943:                        mousebuttons[0] = ev->data1&1;
                    944:                        mousebuttons[1] = ev->data1&2;
                    945:                        mousebuttons[2] = ev->data1&4;
                    946:                        mousex = ev->data2*(mouseSensitivity+5)/10;
                    947:                        mousey = ev->data3*(mouseSensitivity+5)/10;
                    948:                        return(true); // eat events
                    949: 
                    950:                case ev_joystick:
                    951:                        joybuttons[0] = ev->data1&1;
                    952:                        joybuttons[1] = ev->data1&2;
                    953:                        joybuttons[2] = ev->data1&4;
                    954:                        joybuttons[3] = ev->data1&8;
                    955:                        joyxmove = ev->data2;
                    956:                        joyymove = ev->data3;
                    957:                        return(true); // eat events
                    958: 
                    959:                default:
                    960:                        break;
1.1       root      961:        }
1.1.1.2   root      962:        return(false);
1.1       root      963: }
                    964: 
1.1.1.2   root      965: 
1.1.1.3 ! root      966: //==========================================================================
        !           967: //
        !           968: // G_Ticker
        !           969: //
        !           970: //==========================================================================
        !           971: 
        !           972: void G_Ticker(void)
1.1.1.2   root      973: {
1.1.1.3 ! root      974:        int i, buf;
        !           975:        ticcmd_t *cmd=NULL;
1.1.1.2   root      976: 
                    977: //
                    978: // do player reborns if needed
                    979: //
                    980:        for (i=0 ; i<MAXPLAYERS ; i++)
                    981:                if (playeringame[i] && players[i].playerstate == PST_REBORN)
                    982:                        G_DoReborn (i);
                    983: 
                    984: //
                    985: // do things to change the game state
                    986: //
                    987:        while (gameaction != ga_nothing)
                    988:        {
                    989:                switch (gameaction)
                    990:                {
1.1.1.3 ! root      991:                        case ga_loadlevel:
        !           992:                                G_DoLoadLevel();
        !           993:                                break;
        !           994:                        case ga_initnew:
        !           995:                                G_DoInitNew();
        !           996:                                break;
        !           997:                        case ga_newgame:
        !           998:                                G_DoNewGame();
        !           999:                                break;
        !          1000:                        case ga_loadgame:
        !          1001:                                Draw_LoadIcon();
        !          1002:                                G_DoLoadGame();
        !          1003:                                break;
        !          1004:                        case ga_savegame:
        !          1005:                                Draw_SaveIcon();
        !          1006:                                G_DoSaveGame();
        !          1007:                                break;
        !          1008:                        case ga_singlereborn:
        !          1009:                                G_DoSingleReborn();
        !          1010:                                break;
        !          1011:                        case ga_playdemo:
        !          1012:                                G_DoPlayDemo();
        !          1013:                                break;
        !          1014:                        case ga_screenshot:
        !          1015:                                M_ScreenShot();
        !          1016:                                gameaction = ga_nothing;
        !          1017:                                break;
        !          1018:                        case ga_leavemap:
        !          1019:                                Draw_TeleportIcon();
        !          1020:                                G_DoTeleportNewMap();
        !          1021:                                break;
        !          1022:                        case ga_completed:
        !          1023:                                G_DoCompleted();
        !          1024:                                break;
        !          1025:                        case ga_worlddone:
        !          1026:                                G_DoWorldDone();
        !          1027:                                break;
        !          1028:                        case ga_victory:
        !          1029:                                F_StartFinale();
        !          1030:                                break;
        !          1031:                        default:
        !          1032:                                break;
1.1.1.2   root     1033:                }
                   1034:        }
1.1.1.3 ! root     1035:        
        !          1036:                        
1.1.1.2   root     1037: //
                   1038: // get commands, check consistancy, and build new consistancy check
                   1039: //
                   1040:        //buf = gametic%BACKUPTICS;
1.1.1.3 ! root     1041: 
        !          1042: 
1.1.1.2   root     1043:        buf = (gametic/ticdup)%BACKUPTICS;
                   1044: 
                   1045:        for (i=0 ; i<MAXPLAYERS ; i++)
                   1046:                if (playeringame[i])
                   1047:                {
                   1048:                        cmd = &players[i].cmd;
                   1049: 
                   1050:                        memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t));
                   1051: 
                   1052:                        if (demoplayback)
                   1053:                                G_ReadDemoTiccmd (cmd);
                   1054:                        if (demorecording)
                   1055:                                G_WriteDemoTiccmd (cmd);
                   1056: 
                   1057:                        if (netgame && !(gametic%ticdup) )
                   1058:                        {
                   1059:                                if (gametic > BACKUPTICS
                   1060:                                && consistancy[i][buf] != cmd->consistancy)
                   1061:                                {
                   1062:                                        I_Error ("consistency failure (%i should be %i)",cmd->consistancy, consistancy[i][buf]);
                   1063:                                }
                   1064:                                if (players[i].mo)
                   1065:                                        consistancy[i][buf] = players[i].mo->x;
                   1066:                                else
                   1067:                                        consistancy[i][buf] = rndindex;
                   1068:                        }
                   1069:                }
                   1070: 
                   1071: //
                   1072: // check for special buttons
                   1073: //
                   1074:        for (i=0 ; i<MAXPLAYERS ; i++)
                   1075:                if (playeringame[i])
                   1076:                {
                   1077:                        if (players[i].cmd.buttons & BT_SPECIAL)
                   1078:                        {
                   1079:                                switch (players[i].cmd.buttons & BT_SPECIALMASK)
                   1080:                                {
                   1081:                                case BTS_PAUSE:
                   1082:                                        paused ^= 1;
                   1083:                                        if(paused)
                   1084:                                        {
                   1085:                                                S_PauseSound();
                   1086:                                        }
                   1087:                                        else
                   1088:                                        {
                   1089:                                                S_ResumeSound();
                   1090:                                        }
                   1091:                                        break;
1.1.1.3 ! root     1092:                                        
1.1.1.2   root     1093:                                case BTS_SAVEGAME:
                   1094:                                        if (!savedescription[0])
                   1095:                                        {
                   1096:                                                if(netgame)
                   1097:                                                {
                   1098:                                                        strcpy (savedescription, "NET GAME");
                   1099:                                                }
                   1100:                                                else
                   1101:                                                {
                   1102:                                                        strcpy(savedescription, "SAVE GAME");
                   1103:                                                }
                   1104:                                        }
1.1.1.3 ! root     1105:                                        savegameslot = 
1.1.1.2   root     1106:                                                (players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT;
                   1107:                                        gameaction = ga_savegame;
                   1108:                                        break;
                   1109:                                }
                   1110:                        }
                   1111:                }
1.1.1.3 ! root     1112:        
        !          1113: // turn inventory off after a certain amount of time
1.1.1.2   root     1114:        if(inventory && !(--inventoryTics))
                   1115:        {
                   1116:                players[consoleplayer].readyArtifact =
                   1117:                        players[consoleplayer].inventory[inv_ptr].type;
                   1118:                inventory = false;
                   1119:                cmd->arti = 0;
                   1120:        }
                   1121: //
                   1122: // do main actions
                   1123: //
                   1124: //
                   1125: // do main actions
                   1126: //
                   1127:        switch (gamestate)
                   1128:        {
                   1129:                case GS_LEVEL:
                   1130:                        P_Ticker ();
                   1131:                        SB_Ticker ();
                   1132:                        AM_Ticker ();
                   1133:                        CT_Ticker();
                   1134:                        break;
                   1135:                case GS_INTERMISSION:
                   1136:                        IN_Ticker ();
                   1137:                        break;
                   1138:                case GS_FINALE:
                   1139:                        F_Ticker();
                   1140:                        break;
                   1141:                case GS_DEMOSCREEN:
1.1.1.3 ! root     1142:                        H2_PageTicker ();
1.1.1.2   root     1143:                        break;
1.1.1.3 ! root     1144:        }       
1.1.1.2   root     1145: }
                   1146: 
                   1147: 
                   1148: /*
                   1149: ==============================================================================
                   1150: 
                   1151:                                                PLAYER STRUCTURE FUNCTIONS
                   1152: 
                   1153: also see P_SpawnPlayer in P_Things
                   1154: ==============================================================================
                   1155: */
                   1156: 
1.1.1.3 ! root     1157: //==========================================================================
        !          1158: //
        !          1159: // G_PlayerExitMap
        !          1160: //
        !          1161: // Called when the player leaves a map.
        !          1162: //
        !          1163: //==========================================================================
1.1.1.2   root     1164: 
1.1.1.3 ! root     1165: void G_PlayerExitMap(int playerNumber)
1.1.1.2   root     1166: {
1.1.1.3 ! root     1167:        int i;
        !          1168:        player_t *player;
        !          1169:        int flightPower;
1.1.1.2   root     1170: 
1.1.1.3 ! root     1171:        player = &players[playerNumber];
1.1.1.2   root     1172: 
1.1.1.3 ! root     1173: //     if(deathmatch)
        !          1174: //     {
        !          1175: //             // Strip all but one of each type of artifact
        !          1176: //             for(i = 0; i < player->inventorySlotNum; i++)
        !          1177: //             {
        !          1178: //                     player->inventory[i].count = 1;
        !          1179: //             }
        !          1180: //             player->artifactCount = player->inventorySlotNum;
        !          1181: //     }
        !          1182: //     else
        !          1183: 
        !          1184:        // Strip all current powers (retain flight)
        !          1185:        flightPower = player->powers[pw_flight];
        !          1186:        memset(player->powers, 0, sizeof(player->powers));
        !          1187:        player->powers[pw_flight] = flightPower;
1.1.1.2   root     1188: 
1.1.1.3 ! root     1189:        if(deathmatch)
1.1.1.2   root     1190:        {
1.1.1.3 ! root     1191:                player->powers[pw_flight] = 0;
1.1.1.2   root     1192:        }
1.1.1.3 ! root     1193:        else
1.1.1.2   root     1194:        {
1.1.1.3 ! root     1195:                if(P_GetMapCluster(gamemap) != P_GetMapCluster(LeaveMap))
        !          1196:                { // Entering new cluster
        !          1197:                        // Strip all keys
        !          1198:                        player->keys = 0;
        !          1199: 
        !          1200:                        // Strip flight artifact
        !          1201:                        for(i = 0; i < 25; i++)
        !          1202:                        {
        !          1203:                                player->powers[pw_flight] = 0;
        !          1204:                                P_PlayerUseArtifact(player, arti_fly);
        !          1205:                        }
        !          1206:                        player->powers[pw_flight] = 0;
1.1.1.2   root     1207:                }
                   1208:        }
1.1.1.3 ! root     1209: 
        !          1210:        if(player->morphTics)
1.1.1.2   root     1211:        {
1.1.1.3 ! root     1212:                player->readyweapon = player->mo->special1; // Restore weapon
        !          1213:                player->morphTics = 0;
1.1.1.2   root     1214:        }
1.1.1.3 ! root     1215:        player->messageTics = 0;
        !          1216:        player->lookdir = 0;
        !          1217:        player->mo->flags &= ~MF_SHADOW; // Remove invisibility
        !          1218:        player->extralight = 0; // Remove weapon flashes
        !          1219:        player->fixedcolormap = 0; // Remove torch
        !          1220:        player->damagecount = 0; // No palette changes
        !          1221:        player->bonuscount = 0;
        !          1222:        player->poisoncount = 0;
        !          1223:        if(player == &players[consoleplayer])
1.1.1.2   root     1224:        {
                   1225:                SB_state = -1; // refresh the status bar
1.1.1.3 ! root     1226:                viewangleoffset = 0;
1.1.1.2   root     1227:        }
                   1228: }
                   1229: 
1.1.1.3 ! root     1230: //==========================================================================
        !          1231: //
        !          1232: // G_PlayerReborn
        !          1233: //
        !          1234: // Called after a player dies.  Almost everything is cleared and
        !          1235: // initialized.
        !          1236: //
        !          1237: //==========================================================================
1.1.1.2   root     1238: 
                   1239: void G_PlayerReborn(int player)
                   1240: {
                   1241:        player_t *p;
                   1242:        int frags[MAXPLAYERS];
                   1243:        int killcount, itemcount, secretcount;
1.1.1.3 ! root     1244:        uint worldTimer;
1.1.1.2   root     1245: 
                   1246:        memcpy(frags, players[player].frags, sizeof(frags));
                   1247:        killcount = players[player].killcount;
                   1248:        itemcount = players[player].itemcount;
                   1249:        secretcount = players[player].secretcount;
1.1.1.3 ! root     1250:        worldTimer = players[player].worldTimer;
1.1.1.2   root     1251: 
                   1252:        p = &players[player];
                   1253:        memset(p, 0, sizeof(*p));
                   1254: 
                   1255:        memcpy(players[player].frags, frags, sizeof(players[player].frags));
                   1256:        players[player].killcount = killcount;
                   1257:        players[player].itemcount = itemcount;
                   1258:        players[player].secretcount = secretcount;
1.1.1.3 ! root     1259:        players[player].worldTimer = worldTimer;
        !          1260:        players[player].class = PlayerClass[player];
1.1.1.2   root     1261: 
                   1262:        p->usedown = p->attackdown = true; // don't do anything immediately
                   1263:        p->playerstate = PST_LIVE;
                   1264:        p->health = MAXHEALTH;
1.1.1.3 ! root     1265:        p->readyweapon = p->pendingweapon = WP_FIRST;
        !          1266:        p->weaponowned[WP_FIRST] = true;
1.1.1.2   root     1267:        p->messageTics = 0;
                   1268:        p->lookdir = 0;
1.1.1.3 ! root     1269:        localQuakeHappening[player] = false;
1.1.1.2   root     1270:        if(p == &players[consoleplayer])
                   1271:        {
                   1272:                SB_state = -1; // refresh the status bar
                   1273:                inv_ptr = 0; // reset the inventory pointer
                   1274:                curpos = 0;
1.1.1.3 ! root     1275:                viewangleoffset = 0;
1.1.1.2   root     1276:        }
                   1277: }
                   1278: 
                   1279: /*
                   1280: ====================
                   1281: =
1.1.1.3 ! root     1282: = G_CheckSpot 
1.1.1.2   root     1283: =
1.1.1.3 ! root     1284: = Returns false if the player cannot be respawned at the given mapthing_t spot 
1.1.1.2   root     1285: = because something is occupying it
                   1286: ====================
                   1287: */
                   1288: 
                   1289: void P_SpawnPlayer (mapthing_t *mthing);
                   1290: 
                   1291: boolean G_CheckSpot (int playernum, mapthing_t *mthing)
                   1292: {
                   1293:        fixed_t         x,y;
                   1294:        subsector_t *ss;
                   1295:        unsigned        an;
                   1296:        mobj_t      *mo;
1.1.1.3 ! root     1297:        
1.1.1.2   root     1298:        x = mthing->x << FRACBITS;
                   1299:        y = mthing->y << FRACBITS;
                   1300: 
                   1301:        players[playernum].mo->flags2 &= ~MF2_PASSMOBJ;
                   1302:        if (!P_CheckPosition (players[playernum].mo, x, y) )
                   1303:        {
                   1304:                players[playernum].mo->flags2 |= MF2_PASSMOBJ;
                   1305:                return false;
                   1306:        }
                   1307:        players[playernum].mo->flags2 |= MF2_PASSMOBJ;
                   1308: 
                   1309: // spawn a teleport fog
                   1310:        ss = R_PointInSubsector (x,y);
                   1311:        an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT;
                   1312: 
1.1.1.3 ! root     1313:        mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an],
        !          1314:                ss->sector->floorheight+TELEFOGHEIGHT, MT_TFOG);
1.1.1.2   root     1315: 
                   1316:        if (players[consoleplayer].viewz != 1)
1.1.1.3 ! root     1317:                S_StartSound (mo, SFX_TELEPORT);  // don't start sound on first frame
1.1.1.2   root     1318: 
                   1319:        return true;
                   1320: }
                   1321: 
                   1322: /*
                   1323: ====================
                   1324: =
                   1325: = G_DeathMatchSpawnPlayer
                   1326: =
                   1327: = Spawns a player at one of the random death match spots
                   1328: = called at level load and each death
                   1329: ====================
                   1330: */
                   1331: 
                   1332: void G_DeathMatchSpawnPlayer (int playernum)
                   1333: {
                   1334:        int             i,j;
                   1335:        int             selections;
1.1.1.3 ! root     1336:        
1.1.1.2   root     1337:        selections = deathmatch_p - deathmatchstarts;
1.1.1.3 ! root     1338: 
        !          1339:        // This check has been moved to p_setup.c:P_LoadThings()
        !          1340:        //if (selections < 8)
        !          1341:        //      I_Error ("Only %i deathmatch spots, 8 required", selections);
1.1.1.2   root     1342: 
                   1343:        for (j=0 ; j<20 ; j++)
                   1344:        {
                   1345:                i = P_Random() % selections;
                   1346:                if (G_CheckSpot (playernum, &deathmatchstarts[i]) )
                   1347:                {
                   1348:                        deathmatchstarts[i].type = playernum+1;
                   1349:                        P_SpawnPlayer (&deathmatchstarts[i]);
                   1350:                        return;
                   1351:                }
                   1352:        }
                   1353: 
                   1354: // no good spot, so the player will probably get stuck
1.1.1.3 ! root     1355:        P_SpawnPlayer (&playerstarts[0][playernum]);
1.1.1.2   root     1356: }
                   1357: 
1.1.1.3 ! root     1358: //==========================================================================
        !          1359: //
        !          1360: // G_DoReborn
        !          1361: //
        !          1362: //==========================================================================
1.1.1.2   root     1363: 
1.1.1.3 ! root     1364: void G_DoReborn(int playernum)
1.1.1.2   root     1365: {
1.1.1.3 ! root     1366:        int i;
        !          1367:        boolean oldWeaponowned[NUMWEAPONS];
        !          1368:        int oldKeys;
        !          1369:        int oldPieces;
        !          1370:        boolean foundSpot;
        !          1371:        int bestWeapon;
1.1.1.2   root     1372: 
1.1.1.3 ! root     1373:        if(G_CheckDemoStatus())
        !          1374:        {
1.1.1.2   root     1375:                return;
1.1.1.3 ! root     1376:        }
        !          1377:        if(!netgame)
        !          1378:        {
        !          1379:                if(SV_RebornSlotAvailable())
        !          1380:                { // Use the reborn code if the slot is available
        !          1381:                        gameaction = ga_singlereborn;
        !          1382:                }
        !          1383:                else
        !          1384:                { // Start a new game if there's no reborn info
        !          1385:                        gameaction = ga_newgame;
        !          1386:                }
        !          1387:        }
1.1.1.2   root     1388:        else
1.1.1.3 ! root     1389:        { // Net-game
        !          1390:                players[playernum].mo->player = NULL; // Dissassociate the corpse
1.1.1.2   root     1391: 
1.1.1.3 ! root     1392:                if(deathmatch)
        !          1393:                { // Spawn at random spot if in death match
        !          1394:                        G_DeathMatchSpawnPlayer(playernum);
1.1.1.2   root     1395:                        return;
                   1396:                }
                   1397: 
1.1.1.3 ! root     1398:                // Cooperative net-play, retain keys and weapons
        !          1399:                oldKeys = players[playernum].keys;
        !          1400:                oldPieces = players[playernum].pieces;
        !          1401:                for(i = 0; i < NUMWEAPONS; i++)
        !          1402:                {
        !          1403:                        oldWeaponowned[i] = players[playernum].weaponowned[i];
        !          1404:                }
        !          1405: 
        !          1406:                foundSpot = false;
        !          1407:                if(G_CheckSpot(playernum,
        !          1408:                        &playerstarts[RebornPosition][playernum]))
        !          1409:                { // Appropriate player start spot is open
        !          1410:                        P_SpawnPlayer(&playerstarts[RebornPosition][playernum]);
        !          1411:                        foundSpot = true;
        !          1412:                }
        !          1413:                else
1.1.1.2   root     1414:                {
1.1.1.3 ! root     1415:                        // Try to spawn at one of the other player start spots
        !          1416:                        for(i = 0; i < MAXPLAYERS; i++)
        !          1417:                        {
        !          1418:                                if(G_CheckSpot(playernum, &playerstarts[RebornPosition][i]))
        !          1419:                                { // Found an open start spot
        !          1420: 
        !          1421:                                        // Fake as other player
        !          1422:                                        playerstarts[RebornPosition][i].type = playernum+1;
        !          1423:                                        P_SpawnPlayer(&playerstarts[RebornPosition][i]);
        !          1424: 
        !          1425:                                        // Restore proper player type
        !          1426:                                        playerstarts[RebornPosition][i].type = i+1;
        !          1427:        
        !          1428:                                        foundSpot = true;
        !          1429:                                        break;
        !          1430:                                }
        !          1431:                        }
1.1.1.2   root     1432:                }
1.1.1.3 ! root     1433: 
        !          1434:                if(foundSpot == false)
        !          1435:                { // Player's going to be inside something
        !          1436:                        P_SpawnPlayer(&playerstarts[RebornPosition][playernum]);
        !          1437:                }
        !          1438: 
        !          1439:                // Restore keys and weapons
        !          1440:                players[playernum].keys = oldKeys;
        !          1441:                players[playernum].pieces = oldPieces;
        !          1442:                for(bestWeapon = 0, i = 0; i < NUMWEAPONS; i++)
        !          1443:                {
        !          1444:                        if(oldWeaponowned[i])
        !          1445:                        {
        !          1446:                                bestWeapon = i;
        !          1447:                                players[playernum].weaponowned[i] = true;
1.1.1.2   root     1448:                        }
1.1.1.3 ! root     1449:                }
        !          1450:                players[playernum].mana[MANA_1] = 25;
        !          1451:                players[playernum].mana[MANA_2] = 25;
        !          1452:                if(bestWeapon)
        !          1453:                { // Bring up the best weapon
        !          1454:                        players[playernum].pendingweapon = bestWeapon;
        !          1455:                }
1.1.1.2   root     1456:        }
                   1457: }
                   1458: 
                   1459: void G_ScreenShot (void)
                   1460: {
                   1461:        gameaction = ga_screenshot;
                   1462: }
                   1463: 
1.1.1.3 ! root     1464: //==========================================================================
        !          1465: //
        !          1466: // G_StartNewInit
        !          1467: //
        !          1468: //==========================================================================
1.1.1.2   root     1469: 
1.1.1.3 ! root     1470: void G_StartNewInit(void)
        !          1471: {
        !          1472:        SV_InitBaseSlot();
        !          1473:        SV_ClearRebornSlot();
        !          1474:        P_ACSInitNewGame();
        !          1475:        // Default the player start spot group to 0
        !          1476:        RebornPosition = 0;
        !          1477: }
        !          1478: 
        !          1479: //==========================================================================
        !          1480: //
        !          1481: // G_StartNewGame
        !          1482: //
        !          1483: //==========================================================================
        !          1484: 
        !          1485: void G_StartNewGame(skill_t skill)
        !          1486: {
        !          1487:        int realMap;
        !          1488: 
        !          1489:        G_StartNewInit();
        !          1490:        realMap = P_TranslateMap(1);
        !          1491:        if(realMap == -1)
        !          1492:        {
        !          1493:                realMap = 1;
        !          1494:        }
        !          1495:        G_InitNew(TempSkill, 1, realMap);
        !          1496: }
1.1.1.2   root     1497: 
1.1.1.3 ! root     1498: //==========================================================================
        !          1499: //
        !          1500: // G_TeleportNewMap
        !          1501: //
        !          1502: // Only called by the warp cheat code.  Works just like normal map to map
        !          1503: // teleporting, but doesn't do any interlude stuff.
        !          1504: //
        !          1505: //==========================================================================
        !          1506: 
        !          1507: void G_TeleportNewMap(int map, int position)
        !          1508: {
        !          1509:        gameaction = ga_leavemap;
        !          1510:        LeaveMap = map;
        !          1511:        LeavePosition = position;
        !          1512: }
        !          1513: 
        !          1514: //==========================================================================
        !          1515: //
        !          1516: // G_DoTeleportNewMap
        !          1517: //
        !          1518: //==========================================================================
        !          1519: 
        !          1520: void G_DoTeleportNewMap(void)
        !          1521: {
        !          1522:        SV_MapTeleport(LeaveMap, LeavePosition);
        !          1523:        gamestate = GS_LEVEL;
        !          1524:        gameaction = ga_nothing;
        !          1525:        RebornPosition = LeavePosition;
        !          1526: }
1.1.1.2   root     1527: 
1.1.1.3 ! root     1528: /*
        !          1529: boolean secretexit;
1.1.1.2   root     1530: void G_ExitLevel (void)
                   1531: {
                   1532:        secretexit = false;
                   1533:        gameaction = ga_completed;
                   1534: }
                   1535: void G_SecretExitLevel (void)
                   1536: {
                   1537:        secretexit = true;
                   1538:        gameaction = ga_completed;
                   1539: }
1.1.1.3 ! root     1540: */
        !          1541: 
        !          1542: //==========================================================================
        !          1543: //
        !          1544: // G_Completed
        !          1545: //
        !          1546: // Starts intermission routine, which is used only during hub exits,
        !          1547: // and DeathMatch games.
        !          1548: //==========================================================================
        !          1549: 
        !          1550: void G_Completed(int map, int position)
        !          1551: {
        !          1552:        gameaction = ga_completed;
        !          1553:        LeaveMap = map;
        !          1554:        LeavePosition = position;
        !          1555: }
1.1.1.2   root     1556: 
                   1557: void G_DoCompleted(void)
                   1558: {
                   1559:        int i;
1.1.1.3 ! root     1560: 
        !          1561:        gameaction = ga_nothing;
        !          1562:        if(G_CheckDemoStatus())
        !          1563:        {
        !          1564:                return;
        !          1565:        }
        !          1566:        for(i = 0; i < MAXPLAYERS; i++)
        !          1567:        {
        !          1568:                if(playeringame[i])
        !          1569:                {
        !          1570:                        G_PlayerExitMap(i);
        !          1571:                }
        !          1572:        }
        !          1573:        if(LeaveMap == -1 && LeavePosition == -1)
        !          1574:        {
        !          1575:                gameaction = ga_victory;
        !          1576:                return;
        !          1577:        }
        !          1578:        else
        !          1579:        {               
        !          1580:                gamestate = GS_INTERMISSION;
        !          1581:                IN_Start();
        !          1582:        }
        !          1583: 
        !          1584: /*
        !          1585:        int i;
        !          1586:        static int afterSecret[3] = { 7, 5, 5 };
1.1.1.2   root     1587: 
                   1588:        gameaction = ga_nothing;
                   1589:        if(G_CheckDemoStatus())
                   1590:        {
                   1591:                return;
                   1592:        }
                   1593:        for(i = 0; i < MAXPLAYERS; i++)
                   1594:        {
                   1595:                if(playeringame[i])
                   1596:                {
                   1597:                        G_PlayerFinishLevel(i);
                   1598:                }
                   1599:        }
                   1600:        prevmap = gamemap;
                   1601:        if(secretexit == true)
                   1602:        {
                   1603:                gamemap = 9;
                   1604:        }
                   1605:        else if(gamemap == 9)
                   1606:        { // Finished secret level
                   1607:                gamemap = afterSecret[gameepisode-1];
                   1608:        }
                   1609:        else if(gamemap == 8)
                   1610:        {
                   1611:                gameaction = ga_victory;
                   1612:                return;
                   1613:        }
                   1614:        else
                   1615:        {
                   1616:                gamemap++;
                   1617:        }
                   1618:        gamestate = GS_INTERMISSION;
                   1619:        IN_Start();
1.1.1.3 ! root     1620: */
1.1.1.2   root     1621: }
                   1622: 
                   1623: //============================================================================
                   1624: //
                   1625: // G_WorldDone
                   1626: //
                   1627: //============================================================================
                   1628: 
                   1629: void G_WorldDone(void)
                   1630: {
                   1631:        gameaction = ga_worlddone;
                   1632: }
                   1633: 
                   1634: //============================================================================
                   1635: //
                   1636: // G_DoWorldDone
                   1637: //
                   1638: //============================================================================
                   1639: 
                   1640: void G_DoWorldDone(void)
                   1641: {
                   1642:        gamestate = GS_LEVEL;
                   1643:        G_DoLoadLevel();
                   1644:        gameaction = ga_nothing;
                   1645:        viewactive = true;
                   1646: }
                   1647: 
1.1.1.3 ! root     1648: //==========================================================================
        !          1649: //
        !          1650: // G_DoSingleReborn
        !          1651: //
        !          1652: // Called by G_Ticker based on gameaction.  Loads a game from the reborn
        !          1653: // save slot.
        !          1654: //
        !          1655: //==========================================================================
        !          1656: 
        !          1657: void G_DoSingleReborn(void)
        !          1658: {
        !          1659:        gameaction = ga_nothing;
        !          1660:        SV_LoadGame(SV_GetRebornSlot());
        !          1661:        SB_SetClassData();
        !          1662: }
        !          1663: 
        !          1664: //==========================================================================
1.1.1.2   root     1665: //
1.1.1.3 ! root     1666: // G_LoadGame
1.1.1.2   root     1667: //
                   1668: // Can be called by the startup code or the menu task.
                   1669: //
1.1.1.3 ! root     1670: //==========================================================================
1.1.1.2   root     1671: 
1.1.1.3 ! root     1672: static int GameLoadSlot;
1.1.1.2   root     1673: 
1.1.1.3 ! root     1674: void G_LoadGame(int slot)
1.1.1.2   root     1675: {
1.1.1.3 ! root     1676:        GameLoadSlot = slot;
1.1.1.2   root     1677:        gameaction = ga_loadgame;
                   1678: }
                   1679: 
1.1.1.3 ! root     1680: //==========================================================================
1.1.1.2   root     1681: //
1.1.1.3 ! root     1682: // G_DoLoadGame
1.1.1.2   root     1683: //
                   1684: // Called by G_Ticker based on gameaction.
                   1685: //
1.1.1.3 ! root     1686: //==========================================================================
1.1.1.2   root     1687: 
                   1688: void G_DoLoadGame(void)
                   1689: {
1.1.1.3 ! root     1690:        gameaction = ga_nothing;
        !          1691:        SV_LoadGame(GameLoadSlot);
        !          1692:        if(!netgame)
        !          1693:        { // Copy the base slot to the reborn slot
        !          1694:                SV_UpdateRebornSlot();
        !          1695:        }
        !          1696:        SB_SetClassData();
        !          1697: }
        !          1698: 
        !          1699: //==========================================================================
        !          1700: //
        !          1701: // G_SaveGame
        !          1702: //
        !          1703: // Called by the menu task.  <description> is a 24 byte text string.
        !          1704: //
        !          1705: //==========================================================================
        !          1706: 
        !          1707: void G_SaveGame(int slot, char *description)
        !          1708: {
        !          1709:        savegameslot = slot;
        !          1710:        strcpy(savedescription, description);
        !          1711:        sendsave = true;
        !          1712: }
        !          1713: 
        !          1714: //==========================================================================
        !          1715: //
        !          1716: // G_DoSaveGame
        !          1717: //
        !          1718: // Called by G_Ticker based on gameaction.
        !          1719: //
        !          1720: //==========================================================================
1.1.1.2   root     1721: 
1.1.1.3 ! root     1722: void G_DoSaveGame(void)
        !          1723: {
        !          1724:        SV_SaveGame(savegameslot, savedescription);
1.1.1.2   root     1725:        gameaction = ga_nothing;
1.1.1.3 ! root     1726:        savedescription[0] = 0;
        !          1727:        P_SetMessage(&players[consoleplayer], TXT_GAMESAVED, true);
        !          1728: }
1.1.1.2   root     1729: 
1.1.1.3 ! root     1730: //==========================================================================
        !          1731: //
        !          1732: // G_DeferredNewGame
        !          1733: //
        !          1734: //==========================================================================
1.1.1.2   root     1735: 
1.1.1.3 ! root     1736: void G_DeferredNewGame(skill_t skill)
        !          1737: {
        !          1738:        TempSkill = skill;
        !          1739:        gameaction = ga_newgame;
1.1.1.2   root     1740: }
                   1741: 
1.1.1.3 ! root     1742: //==========================================================================
        !          1743: //
        !          1744: // G_DoNewGame
        !          1745: //
        !          1746: //==========================================================================
        !          1747: 
        !          1748: void G_DoNewGame(void)
        !          1749: {
        !          1750:        G_StartNewGame(TempSkill);
        !          1751:        gameaction = ga_nothing;
        !          1752: }
1.1.1.2   root     1753: 
                   1754: /*
                   1755: ====================
                   1756: =
                   1757: = G_InitNew
                   1758: =
                   1759: = Can be called by the startup code or the menu task
                   1760: = consoleplayer, displayplayer, playeringame[] should be set
                   1761: ====================
                   1762: */
                   1763: 
1.1.1.3 ! root     1764: void G_DeferedInitNew(skill_t skill, int episode, int map)
        !          1765: {
        !          1766:        TempSkill = skill;
        !          1767:        TempEpisode = episode;
        !          1768:        TempMap = map;
        !          1769:        gameaction = ga_initnew;
1.1.1.2   root     1770: }
                   1771: 
1.1.1.3 ! root     1772: void G_DoInitNew(void)
1.1.1.2   root     1773: {
1.1.1.3 ! root     1774:        SV_InitBaseSlot();
        !          1775:        G_InitNew(TempSkill, TempEpisode, TempMap);
1.1.1.2   root     1776:        gameaction = ga_nothing;
                   1777: }
                   1778: 
                   1779: void G_InitNew(skill_t skill, int episode, int map)
                   1780: {
                   1781:        int i;
                   1782: 
                   1783:        if(paused)
                   1784:        {
                   1785:                paused = false;
                   1786:                S_ResumeSound();
                   1787:        }
                   1788:        if(skill < sk_baby)
1.1.1.3 ! root     1789:        {
1.1.1.2   root     1790:                skill = sk_baby;
1.1.1.3 ! root     1791:        }
1.1.1.2   root     1792:        if(skill > sk_nightmare)
                   1793:        {
1.1.1.3 ! root     1794:                skill = sk_nightmare;
1.1.1.2   root     1795:        }
1.1.1.3 ! root     1796:        if(map < 1)
1.1.1.2   root     1797:        {
1.1.1.3 ! root     1798:                map = 1;
1.1.1.2   root     1799:        }
1.1.1.3 ! root     1800:        if(map > 99)
1.1.1.2   root     1801:        {
1.1.1.3 ! root     1802:                map = 99;
1.1.1.2   root     1803:        }
1.1.1.3 ! root     1804:        M_ClearRandom();
1.1.1.2   root     1805:        // Force players to be initialized upon first level load
                   1806:        for(i = 0; i < MAXPLAYERS; i++)
                   1807:        {
                   1808:                players[i].playerstate = PST_REBORN;
1.1.1.3 ! root     1809:                players[i].worldTimer = 0;
1.1.1.2   root     1810:        }
1.1.1.3 ! root     1811: 
1.1.1.2   root     1812:        // Set up a bunch of globals
                   1813:        usergame = true; // will be set false if a demo
                   1814:        paused = false;
                   1815:        demorecording = false;
                   1816:        demoplayback = false;
                   1817:        viewactive = true;
                   1818:        gameepisode = episode;
                   1819:        gamemap = map;
                   1820:        gameskill = skill;
                   1821:        BorderNeedRefresh = true;
                   1822: 
1.1.1.3 ! root     1823:        // Initialize the sky
        !          1824:        R_InitSky(map);
        !          1825: 
        !          1826:        // Give one null ticcmd_t
        !          1827:        //gametic = 0;
        !          1828:        //maketic = 1;
        !          1829:        //for (i=0 ; i<MAXPLAYERS ; i++)
        !          1830:        //      nettics[i] = 1; // one null event for this gametic
        !          1831:        //memset (localcmds,0,sizeof(localcmds));
        !          1832:        //memset (netcmds,0,sizeof(netcmds));
1.1.1.2   root     1833: 
                   1834:        G_DoLoadLevel();
                   1835: }
                   1836: 
                   1837: /*
                   1838: ===============================================================================
                   1839: 
                   1840:                                                        DEMO RECORDING
                   1841: 
                   1842: ===============================================================================
                   1843: */
                   1844: 
                   1845: #define DEMOMARKER      0x80
                   1846: 
                   1847: void G_ReadDemoTiccmd (ticcmd_t *cmd)
                   1848: {
                   1849:        if (*demo_p == DEMOMARKER)
                   1850:        {       // end of demo data stream
                   1851:                G_CheckDemoStatus ();
                   1852:                return;
                   1853:        }
                   1854:        cmd->forwardmove = ((signed char)*demo_p++);
                   1855:        cmd->sidemove = ((signed char)*demo_p++);
                   1856:        cmd->angleturn = ((unsigned char)*demo_p++)<<8;
                   1857:        cmd->buttons = (unsigned char)*demo_p++;
                   1858:        cmd->lookfly = (unsigned char)*demo_p++;
                   1859:        cmd->arti = (unsigned char)*demo_p++;
                   1860: }
                   1861: 
                   1862: void G_WriteDemoTiccmd (ticcmd_t *cmd)
                   1863: {
                   1864:        if (gamekeydown['q'])           // press q to end demo recording
                   1865:                G_CheckDemoStatus ();
                   1866:        *demo_p++ = cmd->forwardmove;
                   1867:        *demo_p++ = cmd->sidemove;
                   1868:        *demo_p++ = cmd->angleturn>>8;
                   1869:        *demo_p++ = cmd->buttons;
                   1870:        *demo_p++ = cmd->lookfly;
                   1871:        *demo_p++ = cmd->arti;
                   1872:        demo_p -= 6;
                   1873:        G_ReadDemoTiccmd (cmd);         // make SURE it is exactly the same
                   1874: }
                   1875: 
                   1876: 
                   1877: 
                   1878: /*
                   1879: ===================
                   1880: =
                   1881: = G_RecordDemo
                   1882: =
                   1883: ===================
                   1884: */
                   1885: 
                   1886: void G_RecordDemo (skill_t skill, int numplayers, int episode, int map, char *name)
                   1887: {
                   1888:        int             i;
1.1.1.3 ! root     1889:        
1.1.1.2   root     1890:        G_InitNew (skill, episode, map);
                   1891:        usergame = false;
                   1892:        strcpy (demoname, name);
                   1893:        strcat (demoname, ".lmp");
                   1894:        demobuffer = demo_p = Z_Malloc (0x20000,PU_STATIC,NULL);
                   1895:        *demo_p++ = skill;
                   1896:        *demo_p++ = episode;
                   1897:        *demo_p++ = map;
1.1.1.3 ! root     1898:        
1.1.1.2   root     1899:        for (i=0 ; i<MAXPLAYERS ; i++)
1.1.1.3 ! root     1900:        {
1.1.1.2   root     1901:                *demo_p++ = playeringame[i];
1.1.1.3 ! root     1902:                *demo_p++ = PlayerClass[i];
        !          1903:        }               
1.1.1.2   root     1904:        demorecording = true;
                   1905: }
                   1906: 
                   1907: 
                   1908: /*
                   1909: ===================
                   1910: =
                   1911: = G_PlayDemo
                   1912: =
                   1913: ===================
                   1914: */
                   1915: 
                   1916: char    *defdemoname;
                   1917: 
                   1918: void G_DeferedPlayDemo (char *name)
                   1919: {
                   1920:        defdemoname = name;
                   1921:        gameaction = ga_playdemo;
                   1922: }
                   1923: 
                   1924: void G_DoPlayDemo (void)
                   1925: {
                   1926:        skill_t skill;
                   1927:        int             i, episode, map;
1.1.1.3 ! root     1928:        
1.1.1.2   root     1929:        gameaction = ga_nothing;
                   1930:        demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC);
                   1931:        skill = *demo_p++;
                   1932:        episode = *demo_p++;
                   1933:        map = *demo_p++;
                   1934: 
                   1935:        for (i=0 ; i<MAXPLAYERS ; i++)
1.1.1.3 ! root     1936:        {
1.1.1.2   root     1937:                playeringame[i] = *demo_p++;
1.1.1.3 ! root     1938:                PlayerClass[i] = *demo_p++;
        !          1939:        }
        !          1940: 
        !          1941:        // Initialize world info, etc.
        !          1942:        G_StartNewInit();
1.1.1.2   root     1943: 
                   1944:        precache = false;               // don't spend a lot of time in loadlevel
                   1945:        G_InitNew (skill, episode, map);
                   1946:        precache = true;
                   1947:        usergame = false;
                   1948:        demoplayback = true;
                   1949: }
                   1950: 
                   1951: 
                   1952: /*
                   1953: ===================
                   1954: =
                   1955: = G_TimeDemo
                   1956: =
                   1957: ===================
                   1958: */
                   1959: 
                   1960: void G_TimeDemo (char *name)
                   1961: {
                   1962:        skill_t skill;
                   1963:        int             episode, map;
1.1.1.3 ! root     1964:        
1.1.1.2   root     1965:        demobuffer = demo_p = W_CacheLumpName (name, PU_STATIC);
                   1966:        skill = *demo_p++;
                   1967:        episode = *demo_p++;
                   1968:        map = *demo_p++;
                   1969:        G_InitNew (skill, episode, map);
                   1970:        usergame = false;
                   1971:        demoplayback = true;
                   1972:        timingdemo = true;
                   1973:        singletics = true;
                   1974: }
                   1975: 
                   1976: 
                   1977: /*
                   1978: ===================
                   1979: =
                   1980: = G_CheckDemoStatus
                   1981: =
                   1982: = Called after a death or level completion to allow demos to be cleaned up
                   1983: = Returns true if a new demo loop action will take place
                   1984: ===================
                   1985: */
                   1986: 
                   1987: boolean G_CheckDemoStatus (void)
                   1988: {
                   1989:        int             endtime;
1.1.1.3 ! root     1990:        
1.1.1.2   root     1991:        if (timingdemo)
                   1992:        {
                   1993:                endtime = I_GetTime ();
                   1994:                I_Error ("timed %i gametics in %i realtics",gametic
                   1995:                , endtime-starttime);
                   1996:        }
1.1.1.3 ! root     1997:        
1.1.1.2   root     1998:        if (demoplayback)
                   1999:        {
                   2000:                if (singledemo)
                   2001:                        I_Quit ();
1.1.1.3 ! root     2002:                        
1.1.1.2   root     2003:                Z_ChangeTag (demobuffer, PU_CACHE);
                   2004:                demoplayback = false;
1.1.1.3 ! root     2005:                H2_AdvanceDemo();
1.1.1.2   root     2006:                return true;
                   2007:        }
                   2008: 
                   2009:        if (demorecording)
                   2010:        {
                   2011:                *demo_p++ = DEMOMARKER;
                   2012:                M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
                   2013:                Z_Free (demobuffer);
                   2014:                demorecording = false;
                   2015:                I_Error ("Demo %s recorded",demoname);
                   2016:        }
                   2017: 
                   2018:        return false;
                   2019: }

unix.superglobalmegacorp.com

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