Annotation of doom/g_game.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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