home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / g_game.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-17  |  38.0 KB  |  1,689 lines

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