g_game.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:48k
源码类别:

射击游戏

开发平台:

Visual C++

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