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