Annotation of doom/netold.c, revision 1.1.1.1

1.1       root        1: // I_pcnet.m
                      2: 
                      3: #include "DoomDef.h"
                      4: #include "P_local.h"
                      5: #include "soundst.h"
                      6: 
                      7: #define NCMD_EXIT               0x80000000
                      8: #define NCMD_RETRANSMIT 0x40000000
                      9: #define NCMD_SETUP              0x20000000
                     10: #define NCMD_KILL               0x10000000              // kill game
                     11: #define NCMD_CHECKSUM   0x0fffffff
                     12: 
                     13:  
                     14: doomcom_t               *doomcom;       
                     15: doomdata_t              *netbuffer;             // points inside doomcom
                     16: 
                     17: 
                     18: /*
                     19: ==============================================================================
                     20: 
                     21:                                                        NETWORKING
                     22: 
                     23: gametic is the tic about to (or currently being) run
                     24: maketic is the tick that hasn't had control made for it yet
                     25: nettics[] has the maketics for all players 
                     26: 
                     27: a gametic cannot be run until nettics[] > gametic for all players
                     28: 
                     29: ==============================================================================
                     30: */
                     31: 
                     32: #define RESENDCOUNT     10
                     33: #define PL_DRONE        0x80                            // bit flag in doomdata->player
                     34: 
                     35: ticcmd_t                localcmds[BACKUPTICS];
                     36: 
                     37: ticcmd_t        netcmds[MAXPLAYERS][BACKUPTICS];
                     38: int             nettics[MAXNETNODES];
                     39: boolean                 nodeingame[MAXNETNODES];        // set false as nodes leave game
                     40: boolean                 remoteresend[MAXNETNODES];      // set when local needs tics
                     41: int                             resendto[MAXNETNODES];                  // set when remote needs tics
                     42: int                             resendcount[MAXNETNODES];
                     43: 
                     44: int                             nodeforplayer[MAXPLAYERS];
                     45: 
                     46: int             maketic;
                     47: int                             lastnettic, skiptics;
                     48: int                             ticdup;         
                     49: int                             maxsend;        // BACKUPTICS/(2*ticdup)-1
                     50: 
                     51: void D_ProcessEvents (void); 
                     52: void G_BuildTiccmd (ticcmd_t *cmd); 
                     53: void D_DoAdvanceDemo (void);
                     54:  
                     55: boolean                 reboundpacket;
                     56: doomdata_t              reboundstore;
                     57: 
                     58: 
                     59: int     NetbufferSize (void)
                     60: {
                     61:        return (int)&(((doomdata_t *)0)->cmds[netbuffer->numtics]); 
                     62: }
                     63: 
                     64: unsigned NetbufferChecksum (void)
                     65: {
                     66:        unsigned                c;
                     67:        int             i,l;
                     68: 
                     69:        c = 0x1234567;
                     70: 
                     71: #ifdef NeXT
                     72:        return 0;                       // byte order problems
                     73: #endif
                     74: 
                     75:        l = (NetbufferSize () - (int)&(((doomdata_t *)0)->retransmitfrom))/4;
                     76:        for (i=0 ; i<l ; i++)
                     77:                c += ((unsigned *)&netbuffer->retransmitfrom)[i] * (i+1);
                     78: 
                     79:        return c & NCMD_CHECKSUM;
                     80: }
                     81: 
                     82: int ExpandTics (int low)
                     83: {
                     84:        int     delta;
                     85:        
                     86:        delta = low - (maketic&0xff);
                     87:        
                     88:        if (delta >= -64 && delta <= 64)
                     89:                return (maketic&~0xff) + low;
                     90:        if (delta > 64)
                     91:                return (maketic&~0xff) - 256 + low;
                     92:        if (delta < -64)
                     93:                return (maketic&~0xff) + 256 + low;
                     94:                
                     95:        I_Error ("ExpandTics: strange value %i at maketic %i",low,maketic);
                     96:        return 0;
                     97: }
                     98: 
                     99: 
                    100: //============================================================================
                    101: 
                    102: 
                    103: /*
                    104: ==============
                    105: =
                    106: = HSendPacket
                    107: =
                    108: ==============
                    109: */
                    110: 
                    111: void HSendPacket (int node, int flags)
                    112: {
                    113:        netbuffer->checksum = NetbufferChecksum () | flags;
                    114: 
                    115:        if (!node)
                    116:        {
                    117:                reboundstore = *netbuffer;
                    118:                reboundpacket = true;
                    119:                return;
                    120:        }
                    121: 
                    122:        if (demoplayback)
                    123:                return;
                    124: 
                    125:        if (!netgame)
                    126:                I_Error ("Tried to transmit to another node");
                    127:                
                    128:        doomcom->command = CMD_SEND;
                    129:        doomcom->remotenode = node;
                    130:        doomcom->datalength = NetbufferSize ();
                    131:        
                    132: if (debugfile)
                    133: {
                    134:        int             i;
                    135:        int             realretrans;
                    136:        if (netbuffer->checksum & NCMD_RETRANSMIT)
                    137:                realretrans = ExpandTics (netbuffer->retransmitfrom);
                    138:        else
                    139:                realretrans = -1;
                    140:        fprintf (debugfile,"send (%i + %i, R %i) [%i] "
                    141:        ,ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength);
                    142:        for (i=0 ; i<doomcom->datalength ; i++)
                    143:                fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
                    144:        fprintf (debugfile,"\n");
                    145: }
                    146: 
                    147:        I_NetCmd ();
                    148: }
                    149: 
                    150: /*
                    151: ==============
                    152: =
                    153: = HGetPacket
                    154: =
                    155: = Returns false if no packet is waiting
                    156: =
                    157: ==============
                    158: */
                    159: 
                    160: boolean HGetPacket (void)
                    161: {       
                    162:        if (reboundpacket)
                    163:        {
                    164:                *netbuffer = reboundstore;
                    165:                doomcom->remotenode = 0;
                    166:                reboundpacket = false;
                    167:                return true;
                    168:        }
                    169: 
                    170:        if (!netgame)
                    171:                return false;
                    172:        if (demoplayback)
                    173:                return false;
                    174:                
                    175:        doomcom->command = CMD_GET;
                    176:        I_NetCmd ();
                    177:        if (doomcom->remotenode == -1)
                    178:                return false;
                    179: 
                    180:        if (doomcom->datalength != NetbufferSize ())
                    181:        {
                    182:                if (debugfile)
                    183:                        fprintf (debugfile,"bad packet length %i\n",doomcom->datalength);
                    184:                return false;
                    185:        }
                    186:        
                    187:        if (NetbufferChecksum () != (netbuffer->checksum&NCMD_CHECKSUM) )
                    188:        {
                    189:                if (debugfile)
                    190:                        fprintf (debugfile,"bad packet checksum\n");
                    191:                return false;
                    192:        }
                    193: 
                    194: if (debugfile)
                    195: {
                    196:        int             realretrans;
                    197:                        int     i;
                    198:                        
                    199:        if (netbuffer->checksum & NCMD_SETUP)
                    200:                fprintf (debugfile,"setup packet\n");
                    201:        else
                    202:        {
                    203:                if (netbuffer->checksum & NCMD_RETRANSMIT)
                    204:                        realretrans = ExpandTics (netbuffer->retransmitfrom);
                    205:                else
                    206:                        realretrans = -1;
                    207:                fprintf (debugfile,"get %i = (%i + %i, R %i)[%i] ",doomcom->remotenode,
                    208:                ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength);
                    209:                for (i=0 ; i<doomcom->datalength ; i++)
                    210:                        fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
                    211:                fprintf (debugfile,"\n");
                    212:        }
                    213: }
                    214:        return true;    
                    215: }
                    216: 
                    217: 
                    218: /*
                    219: ===================
                    220: =
                    221: = GetPackets
                    222: =
                    223: ===================
                    224: */
                    225: 
                    226: char    exitmsg[80];
                    227: 
                    228: void GetPackets (void)
                    229: {
                    230:        int             netconsole;
                    231:        int             netnode;
                    232:        ticcmd_t        *src, *dest;
                    233:        int             realend;
                    234:        int             realstart;
                    235:                                 
                    236:        while (HGetPacket ())
                    237:        {
                    238:                if (netbuffer->checksum & NCMD_SETUP)
                    239:                        continue;               // extra setup packet
                    240:                        
                    241:                netconsole = netbuffer->player & ~PL_DRONE;
                    242:                netnode = doomcom->remotenode;
                    243:                //
                    244:                // to save bytes, only the low byte of tic numbers are sent
                    245:                // Figure out what the rest of the bytes are
                    246:                //
                    247:                realstart = ExpandTics (netbuffer->starttic);           
                    248:                realend = (realstart+netbuffer->numtics);
                    249:                
                    250:                //
                    251:                // check for exiting the game
                    252:                //
                    253:                if (netbuffer->checksum & NCMD_EXIT)
                    254:                {
                    255:                        if (!nodeingame[netnode])
                    256:                                continue;
                    257:                        nodeingame[netnode] = false;
                    258:                        playeringame[netconsole] = false;
                    259:                        strcpy(exitmsg, "PLAYER 1 LEFT THE GAME");
                    260:                        S_StartSound(NULL, sfx_chat);
                    261:                        exitmsg[7] += netconsole;
                    262:                        //players[consoleplayer].message = exitmsg;
                    263:                        P_SetMessage(&players[consoleplayer], exitmsg, true);
                    264: /*                      if (demorecording)
                    265:                                G_CheckDemoStatus ();
                    266: */ // DEBUG
                    267:                        continue;
                    268:                }
                    269: 
                    270:                //
                    271:                // check for a remote game kill
                    272:                //
                    273:                if (netbuffer->checksum & NCMD_KILL)
                    274:                        I_Error ("Killed by network driver");
                    275: 
                    276:                nodeforplayer[netconsole] = netnode;
                    277:                
                    278:                //
                    279:                // check for retransmit request
                    280:                //
                    281:                if ( resendcount[netnode] <= 0 
                    282:                && (netbuffer->checksum & NCMD_RETRANSMIT) )
                    283:                {
                    284:                        resendto[netnode] = ExpandTics(netbuffer->retransmitfrom);
                    285: if (debugfile)
                    286: fprintf (debugfile,"retransmit from %i\n", resendto[netnode]);
                    287:                        resendcount[netnode] = RESENDCOUNT;
                    288:                }
                    289:                else
                    290:                        resendcount[netnode]--;
                    291: 
                    292:                //
                    293:                // check for out of order / duplicated packet
                    294:                //              
                    295:                if (realend == nettics[netnode])
                    296:                        continue;
                    297:                        
                    298:                if (realend < nettics[netnode])
                    299:                {
                    300: if (debugfile)
                    301: fprintf (debugfile,"out of order packet (%i + %i)\n" ,realstart,netbuffer->numtics);
                    302:                        continue;
                    303:                }
                    304: 
                    305:                //
                    306:                // check for a missed packet
                    307:                //
                    308:                if (realstart > nettics[netnode])
                    309:                {
                    310:                // stop processing until the other system resends the missed tics
                    311: if (debugfile)
                    312: fprintf (debugfile,"missed tics from %i (%i - %i)\n", netnode, realstart, nettics[netnode]);
                    313:                        remoteresend[netnode] = true;
                    314:                        continue;
                    315:                }
                    316:        
                    317: //
                    318: // update command store from the packet
                    319: //
                    320: {
                    321:        int             start;
                    322: 
                    323:                remoteresend[netnode] = false;
                    324:                
                    325:                start = nettics[netnode] - realstart;           
                    326:                src = &netbuffer->cmds[start];
                    327: 
                    328:                while (nettics[netnode] < realend)
                    329:                {
                    330:                        dest = &netcmds[netconsole][nettics[netnode]%BACKUPTICS];
                    331:                        nettics[netnode]++;
                    332:                        *dest = *src;
                    333:                        src++;
                    334:                }
                    335:        }
                    336: }
                    337: 
                    338: }
                    339: 
                    340: /*
                    341: =============
                    342: =
                    343: = NetUpdate
                    344: =
                    345: = Builds ticcmds for console player
                    346: = sends out a packet
                    347: =============
                    348: */
                    349: 
                    350: int      gametime;
                    351: 
                    352: void NetUpdate (void)
                    353: {
                    354:        int             nowtime;
                    355:        int             newtics;
                    356:        int                             i,j;
                    357:        int                             realstart;
                    358:        int                             gameticdiv;
                    359:                        
                    360: //
                    361: // check time
                    362: //  
                    363:        nowtime = I_GetTime ()/ticdup;
                    364:        newtics = nowtime - gametime;
                    365:        gametime = nowtime;
                    366:        
                    367:        if (newtics <= 0)                       // nothing new to update
                    368:                goto listen; 
                    369: 
                    370:        if (skiptics <= newtics)
                    371:        {
                    372:                newtics -= skiptics;
                    373:                skiptics = 0;
                    374:        }
                    375:        else
                    376:        {
                    377:                skiptics -= newtics;
                    378:                newtics = 0;
                    379:        }
                    380:        
                    381:                
                    382:        netbuffer->player = consoleplayer;
                    383:                
                    384: //
                    385: // build new ticcmds for console player
                    386: //
                    387:        gameticdiv = gametic/ticdup;
                    388:        for (i=0 ; i<newtics ; i++)
                    389:        {
                    390:                I_StartTic ();
                    391:                D_ProcessEvents ();
                    392:                if (maketic - gameticdiv >= BACKUPTICS/2-1)
                    393:                        break;          // can't hold any more
                    394: //printf ("mk:%i ",maketic);
                    395:                G_BuildTiccmd (&localcmds[maketic%BACKUPTICS]);
                    396:                maketic++;
                    397:        }
                    398: 
                    399: 
                    400:        if (singletics)
                    401:                return;         // singletic update is syncronous
                    402:                
                    403: //
                    404: // send the packet to the other nodes
                    405: //
                    406:        for (i=0 ; i<doomcom->numnodes ; i++)
                    407:                if (nodeingame[i])
                    408:                {
                    409:                        netbuffer->starttic = realstart = resendto[i];
                    410:                        netbuffer->numtics = maketic - realstart;
                    411:                        if (netbuffer->numtics > BACKUPTICS)
                    412:                                I_Error ("NetUpdate: netbuffer->numtics > BACKUPTICS");
                    413: 
                    414:                        resendto[i] = maketic - doomcom->extratics;
                    415:        
                    416: 
                    417:                        for (j=0 ; j< netbuffer->numtics ; j++)
                    418:                                netbuffer->cmds[j] = 
                    419:                                        localcmds[(realstart+j)%BACKUPTICS];
                    420:                                        
                    421:                        if (remoteresend[i])
                    422:                        {
                    423:                                netbuffer->retransmitfrom = nettics[i];
                    424:                                HSendPacket (i, NCMD_RETRANSMIT);
                    425:                        }
                    426:                        else
                    427:                        {
                    428:                                netbuffer->retransmitfrom = 0;
                    429:                                HSendPacket (i, 0);
                    430:                        }
                    431:                }
                    432: 
                    433: //
                    434: // listen for other packets
                    435: //              
                    436: listen:
                    437: 
                    438:        GetPackets ();
                    439: }
                    440: 
                    441: 
                    442: /*
                    443: =====================
                    444: =
                    445: = CheckAbort
                    446: =
                    447: =====================
                    448: */
                    449: 
                    450: void CheckAbort (void)
                    451: {
                    452:        event_t *ev;
                    453:        int             stoptic;
                    454:        
                    455:        stoptic = I_GetTime () + 2; 
                    456:        while (I_GetTime() < stoptic) 
                    457:                I_StartTic (); 
                    458:        
                    459:        I_StartTic ();
                    460:        for ( ; eventtail != eventhead 
                    461:        ; eventtail = (++eventtail)&(MAXEVENTS-1) ) 
                    462:        { 
                    463:                ev = &events[eventtail]; 
                    464:                if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE)
                    465:                        I_Error ("Network game synchronization aborted.");
                    466:        } 
                    467: }
                    468: 
                    469: /*
                    470: =====================
                    471: =
                    472: = D_ArbitrateNetStart
                    473: =
                    474: =====================
                    475: */
                    476: 
                    477: void D_ArbitrateNetStart (void)
                    478: {
                    479:        int             i;
                    480:        boolean gotinfo[MAXNETNODES];
                    481:        
                    482:        autostart = true;
                    483:        memset (gotinfo,0,sizeof(gotinfo));
                    484:        
                    485:        if (doomcom->consoleplayer)
                    486:        {       // listen for setup info from key player
                    487:                while (1)
                    488:                {
                    489:                        CheckAbort ();
                    490:                        if (!HGetPacket ())
                    491:                                continue;
                    492:                        if (netbuffer->checksum & NCMD_SETUP)
                    493:                        {
                    494:                                if (netbuffer->player != VERSION)
                    495:                                        I_Error ("Different DOOM versions cannot play a net game!");
                    496:                                startskill = netbuffer->retransmitfrom & 15;
                    497:                                deathmatch = (netbuffer->retransmitfrom & 0xc0) >> 6;
                    498:                                nomonsters = (netbuffer->retransmitfrom & 0x20) > 0;
                    499:                                respawnparm = (netbuffer->retransmitfrom & 0x10) > 0;
                    500:                                startmap = netbuffer->starttic & 0x3f;
                    501:                                startepisode = netbuffer->starttic >> 6;
                    502:                                return;
                    503:                        }
                    504:                }
                    505:        }
                    506:        else
                    507:        {       // key player, send the setup info
                    508:                do
                    509:                {
                    510:                        CheckAbort ();
                    511:                        for (i=0 ; i<doomcom->numnodes ; i++)
                    512:                        {
                    513:                                netbuffer->retransmitfrom = startskill;
                    514:                                if (deathmatch)
                    515:                                        netbuffer->retransmitfrom |= (deathmatch<<6);
                    516:                                if (nomonsters)
                    517:                                        netbuffer->retransmitfrom |= 0x20;
                    518:                                if (respawnparm)
                    519:                                        netbuffer->retransmitfrom |= 0x10;
                    520:                                netbuffer->starttic = startepisode * 64 + startmap;
                    521:                                netbuffer->player = VERSION;
                    522:                                netbuffer->numtics = 0;
                    523:                                HSendPacket (i, NCMD_SETUP);
                    524:                        }
                    525: 
                    526: #if 1
                    527:                        for(i = 10 ; i  &&  HGetPacket(); --i)
                    528:                        {
                    529:  if((netbuffer->player&0x7f) < MAXNETNODES)
                    530:                                gotinfo[netbuffer->player&0x7f] = true;
                    531:                        }
                    532: #else
                    533:                        while (HGetPacket ())
                    534:                        {
                    535:                                gotinfo[netbuffer->player&0x7f] = true;
                    536:                        }
                    537: #endif
                    538: 
                    539:                        for (i=1 ; i<doomcom->numnodes ; i++)
                    540:                                if (!gotinfo[i])
                    541:                                        break;
                    542:                } while (i < doomcom->numnodes);
                    543:        }
                    544: }
                    545: 
                    546: /*
                    547: ===================
                    548: =
                    549: = D_CheckNetGame
                    550: =
                    551: = Works out player numbers among the net participants
                    552: ===================
                    553: */
                    554: 
                    555: extern  int                     viewangleoffset;
                    556: 
                    557: void D_CheckNetGame (void)
                    558: {
                    559:        int             i;
                    560:        
                    561:        for (i=0 ; i<MAXNETNODES ; i++)
                    562:        {
                    563:                nodeingame[i] = false;
                    564:        nettics[i] = 0;
                    565:                remoteresend[i] = false;        // set when local needs tics
                    566:                resendto[i] = 0;                        // which tic to start sending
                    567:        }
                    568:        
                    569: // I_InitNetwork sets doomcom and netgame
                    570:        I_InitNetwork ();
                    571:        if (doomcom->id != DOOMCOM_ID)
                    572:                I_Error ("Doomcom buffer invalid!");
                    573:        netbuffer = &doomcom->data;
                    574:        consoleplayer = displayplayer = doomcom->consoleplayer;
                    575:        if (netgame)
                    576:                D_ArbitrateNetStart ();
                    577: //printf ("startskill %i  deathmatch: %i  startmap: %i  startepisode: %i\n", startskill, deathmatch, startmap, startepisode);
                    578:        
                    579: // read values out of doomcom
                    580:        ticdup = doomcom->ticdup;
                    581:        maxsend = BACKUPTICS/2-1;
                    582:        if (maxsend<1)
                    583:                maxsend = 1;
                    584:                        
                    585:        for (i=0 ; i<doomcom->numplayers ; i++)
                    586:                playeringame[i] = true;
                    587:        for (i=0 ; i<doomcom->numnodes ; i++)
                    588:                nodeingame[i] = true;
                    589:        
                    590: //printf ("player %i of %i (%i nodes)\n", consoleplayer+1, doomcom->numplayers, doomcom->numnodes);
                    591: 
                    592: }
                    593: 
                    594: /*
                    595: ==================
                    596: =
                    597: = D_QuitNetGame
                    598: =
                    599: = Called before quitting to leave a net game without hanging the
                    600: = other players
                    601: =
                    602: ==================
                    603: */
                    604: 
                    605: void D_QuitNetGame (void)
                    606: {
                    607:        int             i, j;
                    608:        
                    609:        if (debugfile)
                    610:                fclose (debugfile);
                    611:                
                    612:        if (!netgame || !usergame || consoleplayer == -1 || demoplayback)
                    613:                return;
                    614:        
                    615: // send a bunch of packets for security
                    616:        netbuffer->player = consoleplayer;
                    617:        netbuffer->numtics = 0;
                    618:        for (i=0 ; i<4 ; i++)
                    619:        {
                    620:                for (j=1 ; j<doomcom->numnodes ; j++)
                    621:                        if (nodeingame[j])
                    622:                                HSendPacket (j, NCMD_EXIT);
                    623:                I_WaitVBL (1);
                    624:        }
                    625: }
                    626: 
                    627: 
                    628: 
                    629: /*
                    630: ===============
                    631: =
                    632: = TryRunTics
                    633: =
                    634: ===============
                    635: */
                    636: 
                    637: int     frametics[4], frameon;
                    638: int     frameskip[4];
                    639: int             oldnettics;
                    640: extern  boolean advancedemo;
                    641: 
                    642: void TryRunTics (void)
                    643: {
                    644:        int             i;
                    645:        int             lowtic;
                    646:        int             entertic;
                    647:        static int              oldentertics;
                    648:        int                             realtics, availabletics;
                    649:        int                             counts;
                    650:        int                             numplaying;
                    651: 
                    652: //
                    653: // get real tics
                    654: //                      
                    655:        entertic = I_GetTime ()/ticdup;
                    656:        realtics = entertic - oldentertics;
                    657:        oldentertics = entertic;
                    658: 
                    659: //
                    660: // get available tics
                    661: //
                    662:        NetUpdate ();
                    663:        
                    664:        lowtic = MAXINT;
                    665:        numplaying = 0;
                    666:        for (i=0 ; i<doomcom->numnodes ; i++)
                    667:                if (nodeingame[i])
                    668:                {
                    669:                        numplaying++;
                    670:                        if (nettics[i] < lowtic)
                    671:                                lowtic = nettics[i];
                    672:                }
                    673:        availabletics = lowtic - gametic/ticdup;
                    674:        
                    675: 
                    676: //
                    677: // decide how many tics to run
                    678: //
                    679:        if (realtics < availabletics-1)
                    680:                counts = realtics+1;
                    681:        else if (realtics < availabletics)
                    682:                counts = realtics;
                    683:        else
                    684:                counts = availabletics;
                    685:        if (counts < 1)
                    686:                counts = 1;
                    687:                
                    688:        frameon++;
                    689: 
                    690: if (debugfile)
                    691:        fprintf (debugfile,"=======real: %i  avail: %i  game: %i\n",realtics, availabletics,counts);
                    692: 
                    693:        if (!demoplayback)
                    694:        {       
                    695:        //=============================================================================
                    696:        //
                    697:        //      ideally nettics[0] should be 1 - 3 tics above lowtic
                    698:        //      if we are consistantly slower, speed up time
                    699:        //
                    700:                for (i=0 ; i<MAXPLAYERS ; i++)
                    701:                        if (playeringame[i])
                    702:                                break;
                    703:                if (consoleplayer == i)
                    704:                {       // the key player does not adapt
                    705:                }
                    706:                else
                    707:                {
                    708:                        if (nettics[0] <= nettics[nodeforplayer[i]])
                    709:                        {
                    710:                                gametime--;
                    711:        //                      printf ("-");
                    712:                        }
                    713:                        frameskip[frameon&3] = (oldnettics > nettics[nodeforplayer[i]]);
                    714:                        oldnettics = nettics[0];
                    715:                        if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3])
                    716:                        {
                    717:                                skiptics = 1;
                    718:        //                      printf ("+");
                    719:                        }
                    720:                }
                    721:        //============================================================================= 
                    722:        }       // demoplayback                 
                    723: 
                    724:        //
                    725:        // wait for new tics if needed
                    726:        //
                    727:                while (lowtic < gametic/ticdup + counts)        
                    728:                {
                    729:        
                    730:                        NetUpdate ();   
                    731:                        lowtic = MAXINT;
                    732:                        
                    733:                        for (i=0 ; i<doomcom->numnodes ; i++)
                    734:                                if (nodeingame[i] && nettics[i] < lowtic)
                    735:                                        lowtic = nettics[i];
                    736:        
                    737:                        if (lowtic < gametic/ticdup)
                    738:                                I_Error ("TryRunTics: lowtic < gametic");
                    739:                                
                    740:                        // don't stay in here forever -- give the menu a chance to work
                    741:                        if (I_GetTime ()/ticdup - entertic >= 20)
                    742:                        {
                    743:                                MN_Ticker ();
                    744:                                return;
                    745:                        } 
                    746:                }
                    747: 
                    748: //
                    749: // run the count * ticdup dics
                    750: //
                    751:        while (counts--)
                    752:        {
                    753:                for (i=0 ; i<ticdup ; i++)
                    754:                {
                    755:                        if (gametic/ticdup > lowtic)
                    756:                                I_Error ("gametic>lowtic");
                    757:                        if (advancedemo)
                    758:                                D_DoAdvanceDemo ();
                    759:                        MN_Ticker ();
                    760:                        G_Ticker ();
                    761:                        gametic++;
                    762:                        //
                    763:                        // modify command for duplicated tics
                    764:                        //
                    765:                        if (i != ticdup-1)
                    766:                        {
                    767:                                ticcmd_t        *cmd;
                    768:                                int                     buf;
                    769:                                int                     j;
                    770:                                
                    771:                                buf = (gametic/ticdup)%BACKUPTICS; 
                    772:                                for (j=0 ; j<MAXPLAYERS ; j++)
                    773:                                {
                    774:                                        cmd = &netcmds[j][buf];
                    775:                                        cmd->chatchar = 0;
                    776:                                        if (cmd->buttons & BT_SPECIAL)
                    777:                                                cmd->buttons = 0;
                    778:                                }
                    779:                        }
                    780:                }
                    781:                NetUpdate ();                                   // check for new console commands
                    782:        }
                    783: }

unix.superglobalmegacorp.com

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