g_game.cpp 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "Precompiled.h"
  21. #include "globaldata.h"
  22. #include "Main.h"
  23. #include "sys/sys_signin.h"
  24. #include "d3xp/Game_local.h"
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include "doomdef.h"
  28. #include "doomstat.h"
  29. #include "z_zone.h"
  30. #include "f_finale.h"
  31. #include "m_argv.h"
  32. #include "m_misc.h"
  33. #include "m_menu.h"
  34. #include "m_random.h"
  35. #include "i_system.h"
  36. #include "p_setup.h"
  37. #include "p_saveg.h"
  38. #include "p_tick.h"
  39. #include "d_main.h"
  40. #include "wi_stuff.h"
  41. #include "hu_stuff.h"
  42. #include "st_stuff.h"
  43. #include "am_map.h"
  44. // Needs access to LFB.
  45. #include "v_video.h"
  46. #include "w_wad.h"
  47. #include "p_local.h"
  48. #include "s_sound.h"
  49. // Data.
  50. #include "dstrings.h"
  51. #include "sounds.h"
  52. // SKY handling - still the wrong place.
  53. #include "r_data.h"
  54. #include "r_sky.h"
  55. #include "g_game.h"
  56. #include "framework/Common.h"
  57. #include "sys/sys_lobby.h"
  58. #include <limits>
  59. extern bool waitingForWipe;
  60. bool loadingGame = false;
  61. byte demoversion = 0;
  62. qboolean G_CheckDemoStatus (void);
  63. void G_ReadDemoTiccmd (ticcmd_t* cmd);
  64. void G_WriteDemoTiccmd (ticcmd_t* cmd);
  65. void G_PlayerReborn (int player);
  66. void G_InitNew (skill_t skill, int episode, int map );
  67. void G_DoReborn (int playernum);
  68. void G_DoLoadLevel ();
  69. void G_DoNewGame (void);
  70. qboolean G_DoLoadGame ();
  71. void G_DoPlayDemo (void);
  72. void G_DoCompleted (void);
  73. void G_DoVictory (void);
  74. void G_DoWorldDone (void);
  75. qboolean G_DoSaveGame (void);
  76. #define DEBUG_DEMOS
  77. #define DEBUG_DEMOS_WRITE
  78. #ifdef DEBUG_DEMOS
  79. unsigned char testprndindex = 0;
  80. int printErrorCount = 0;
  81. bool demoDebugOn = false;
  82. #endif
  83. //
  84. // controls (have defaults)
  85. //
  86. // mouse values are used once
  87. // joystick values are repeated
  88. int G_CmdChecksum (ticcmd_t* cmd)
  89. {
  90. int i;
  91. int sum = 0;
  92. for (i=0 ; i< sizeof(*cmd)/4 - 1 ; i++)
  93. sum += ((int *)cmd)[i];
  94. return sum;
  95. }
  96. // jedi academy meets doom hehehehehehehe
  97. void G_MouseClamp(int *x, int *y)
  98. {
  99. float ax = (float)fabs((float)*x);
  100. float ay = (float)fabs((float)*y);
  101. ax = (ax-10)*(0.04676) * (ax-10) * (ax > 10);
  102. ay = (ay-10)*(0.04676) * (ay-10) * (ay > 10);
  103. if (*x < 0)
  104. *x = static_cast<int>(-ax);
  105. else
  106. *x = static_cast<int>(ax);
  107. if (*y < 0)
  108. *y = static_cast<int>(-ay);
  109. else
  110. *y = static_cast<int>(ay);
  111. }
  112. /*
  113. ========================
  114. Returns true if the player is holding down the run button, or
  115. if they have set "Always run" in the options. Returns false otherwise.
  116. ========================
  117. */
  118. bool IsPlayerRunning( const usercmd_t & command ) {
  119. if( DoomLib::GetPlayer() < 0 ) {
  120. return false;
  121. }
  122. // DHM - Nerve :: Always Run setting
  123. idLocalUser * user = session->GetSignInManager().GetLocalUserByIndex( DoomLib::GetPlayer() );
  124. bool autorun = false;
  125. // TODO: PC
  126. #if 0
  127. if( user ) {
  128. idPlayerProfileDoom * profile = static_cast< idPlayerProfileDoom * >( user->GetProfile() );
  129. if( profile && profile->GetAlwaysRun() ) {
  130. autorun = true;
  131. }
  132. }
  133. #endif
  134. if ( command.buttons & BUTTON_RUN ) {
  135. return !autorun;
  136. }
  137. return autorun;
  138. }
  139. /*
  140. ========================
  141. G_PerformImpulse
  142. ========================
  143. */
  144. void G_PerformImpulse( const int impulse, ticcmd_t* cmd ) {
  145. if( impulse == IMPULSE_15 ) {
  146. cmd->buttons |= BT_CHANGE;
  147. cmd->nextPrevWeapon = 1 ;
  148. } else if( impulse == IMPULSE_14 ) {
  149. cmd->buttons |= BT_CHANGE;
  150. cmd->nextPrevWeapon = 2 ;
  151. }
  152. }
  153. /*
  154. ========================
  155. Converts a degree value to DOOM format angle value.
  156. ========================
  157. */
  158. fixed_t DegreesToDoomAngleTurn( float degrees ) {
  159. const float anglefrac = degrees / 360.0f;
  160. const fixed_t doomangle = anglefrac * std::numeric_limits<unsigned short>::max();
  161. return doomangle;
  162. }
  163. //
  164. // G_BuildTiccmd
  165. // Builds a ticcmd from all of the available inputs
  166. // or reads it from the demo buffer.
  167. // If recording a demo, write it out
  168. //
  169. void G_BuildTiccmd (ticcmd_t* cmd, idUserCmdMgr * userCmdMgr, int newTics )
  170. {
  171. int i;
  172. int speed;
  173. int tspeed;
  174. int forward;
  175. int side;
  176. ticcmd_t* base;
  177. base = I_BaseTiccmd (); // empty, or external driver
  178. memcpy (cmd,base,sizeof(*cmd));
  179. cmd->consistancy = ::g->consistancy[::g->consoleplayer][::g->maketic%BACKUPTICS];
  180. // Grab the tech5 tic so we can convert it to a doom tic.
  181. if ( userCmdMgr != NULL ) {
  182. const int playerIndex = DoomLib::GetPlayer();
  183. if( playerIndex < 0 ) {
  184. return;
  185. }
  186. #ifdef ID_ENABLE_NETWORKING
  187. const int lobbyIndex = gameLocal->GetLobbyIndexFromDoomLibIndex( playerIndex );
  188. const idLocalUser * const localUser = session->GetGameLobbyBase().GetLocalUserFromLobbyUser( lobbyIndex );
  189. #else
  190. const int lobbyIndex = 0;
  191. const idLocalUser * const localUser = session->GetSignInManager().GetMasterLocalUser();
  192. #endif
  193. if ( localUser == NULL ) {
  194. return;
  195. }
  196. usercmd_t * tech5commands[2] = { 0, 0 };
  197. const int numCommands = userCmdMgr->GetPlayerCmds( lobbyIndex, tech5commands, 2 );
  198. usercmd_t prevTech5Command;
  199. usercmd_t curTech5Command;
  200. // Use default commands if the manager didn't have enough.
  201. if ( numCommands == 1 ) {
  202. curTech5Command = *(tech5commands)[0];
  203. }
  204. if ( numCommands == 2 ) {
  205. prevTech5Command = *(tech5commands)[0];
  206. curTech5Command = *(tech5commands)[1];
  207. }
  208. const bool isRunning = IsPlayerRunning( curTech5Command );
  209. // tech5 move commands range from -127 o 127. Scale to doom range of -25 to 25.
  210. const float scaledForward = curTech5Command.forwardmove / 127.0f;
  211. if ( isRunning ) {
  212. cmd->forwardmove = scaledForward * 50.0f;
  213. } else {
  214. cmd->forwardmove = scaledForward * 25.0f;
  215. }
  216. // tech5 move commands range from -127 o 127. Scale to doom range of -24 to 24.
  217. const float scaledSide = curTech5Command.rightmove / 127.0f;
  218. if ( isRunning ) {
  219. cmd->sidemove = scaledSide * 40.0f;
  220. } else {
  221. cmd->sidemove = scaledSide * 24.0f;
  222. }
  223. idAngles angleDelta;
  224. angleDelta.pitch = SHORT2ANGLE( curTech5Command.angles[ 0 ] ) - SHORT2ANGLE( prevTech5Command.angles[ 0 ] );
  225. angleDelta.yaw = SHORT2ANGLE( curTech5Command.angles[ 1 ] ) - SHORT2ANGLE( prevTech5Command.angles[ 1 ] );
  226. angleDelta.roll = 0.0f;
  227. angleDelta.Normalize180();
  228. // We will be running a number of tics equal to newTics before we get a new command from tech5.
  229. // So to keep input smooth, divide the angles between all the newTics.
  230. if ( newTics > 0 ) {
  231. angleDelta.yaw /= newTics;
  232. }
  233. // idAngles is stored in degrees. Convert to doom format.
  234. cmd->angleturn = DegreesToDoomAngleTurn( angleDelta.yaw );
  235. // Translate buttons
  236. //if ( curTech5Command.inhibited == false ) {
  237. // Attack 1 attacks always, whether in the automap or not.
  238. if ( curTech5Command.buttons & BUTTON_ATTACK ) {
  239. cmd->buttons |= BT_ATTACK;
  240. }
  241. #if 0
  242. // Attack 2 only attacks if not in the automap, because when in the automap,
  243. // it is the zoom function.
  244. if ( curTech5Command.buttons & BUTTON_ATTACK2 ) {
  245. if ( !::g->automapactive ) {
  246. cmd->buttons |= BT_ATTACK;
  247. }
  248. }
  249. #endif
  250. // Try to read any impulses that have happened.
  251. static int oldImpulseSequence = 0;
  252. if( oldImpulseSequence != curTech5Command.impulseSequence ) {
  253. G_PerformImpulse( curTech5Command.impulse, cmd );
  254. }
  255. oldImpulseSequence = curTech5Command.impulseSequence;
  256. // weapon toggle
  257. for (i=0 ; i<NUMWEAPONS-1 ; i++)
  258. {
  259. if ( usercmdGen->KeyState( i + 1 ) )
  260. {
  261. cmd->buttons |= BT_CHANGE;
  262. cmd->buttons |= (i - 1) <<BT_WEAPONSHIFT;
  263. break;
  264. }
  265. }
  266. if ( curTech5Command.buttons & BUTTON_USE || curTech5Command.buttons & BUTTON_JUMP ) {
  267. cmd->buttons |= BT_USE;
  268. }
  269. // TODO: PC
  270. #if 0
  271. if ( curTech5Command.buttons & BUTTON_WEAP_NEXT ) {
  272. cmd->buttons |= BT_CHANGE;
  273. cmd->buttons |= 1 << BT_WEAPONSHIFT;
  274. }
  275. if ( curTech5Command.buttons & BUTTON_WEAP_PREV ) {
  276. cmd->buttons |= BT_CHANGE;
  277. cmd->buttons |= 0 << BT_WEAPONSHIFT;
  278. }
  279. if( curTech5Command.buttons & BUTTON_WEAP_0 ) {
  280. cmd->buttons |= BT_CHANGE;
  281. cmd->buttons |= 2 << BT_WEAPONSHIFT;
  282. }
  283. if( curTech5Command.buttons & BUTTON_WEAP_1 ) {
  284. cmd->buttons |= BT_CHANGE;
  285. cmd->buttons |= 3 << BT_WEAPONSHIFT;
  286. }
  287. if( curTech5Command.buttons & BUTTON_WEAP_2 ) {
  288. cmd->buttons |= BT_CHANGE;
  289. cmd->buttons |= 4 << BT_WEAPONSHIFT;
  290. }
  291. if( curTech5Command.buttons & BUTTON_WEAP_3 ) {
  292. cmd->buttons |= BT_CHANGE;
  293. cmd->buttons |= 5 << BT_WEAPONSHIFT;
  294. }
  295. #endif
  296. //}
  297. return;
  298. }
  299. // DHM - Nerve :: Always Run setting
  300. idLocalUser * user = session->GetSignInManager().GetLocalUserByIndex( DoomLib::GetPlayer() );
  301. if( user ) {
  302. // TODO: PC
  303. #if 0
  304. idPlayerProfileDoom * profile = static_cast< idPlayerProfileDoom * >( user->GetProfile() );
  305. if( profile && profile->GetAlwaysRun() ) {
  306. speed = !::g->gamekeydown[::g->key_speed];
  307. } else
  308. #endif
  309. {
  310. speed = ::g->gamekeydown[::g->key_speed];
  311. }
  312. } else {
  313. // Should not happen.
  314. speed = !::g->gamekeydown[::g->key_speed];
  315. }
  316. forward = side = 0;
  317. // use two stage accelerative turning
  318. // on the keyboard and joystick
  319. if (/*:g->joyxmove != 0 ||*/ ::g->gamekeydown[::g->key_right] || ::g->gamekeydown[::g->key_left] || ::g->mousex != 0)
  320. ::g->turnheld += ::g->ticdup;
  321. else
  322. ::g->turnheld = 0;
  323. if (::g->turnheld < SLOWTURNTICS)
  324. tspeed = 2; // slow turn
  325. else
  326. tspeed = speed;
  327. // clamp for turning
  328. int mousex = ::g->mousex;
  329. int mousey = ::g->mousey;
  330. G_MouseClamp( &mousex, &mousey );
  331. if (::g->gamekeydown[::g->key_right] /*|| ::g->joyxmove > 0*/)
  332. cmd->angleturn -= ::g->angleturn[tspeed];
  333. else if (::g->mousex > 0) {
  334. cmd->angleturn -= tspeed == 1 ? 2 * mousex : mousex;
  335. }
  336. if (::g->gamekeydown[::g->key_left] /*|| ::g->joyxmove < 0*/)
  337. cmd->angleturn += ::g->angleturn[tspeed];
  338. else if (::g->mousex < 0) {
  339. cmd->angleturn += tspeed == 1 ? -2 * mousex : -mousex;
  340. }
  341. if (::g->mousey > 0 || ::g->mousey < 0) {
  342. //forward += ::g->forwardmove[speed];
  343. forward += speed == 1 ? 2 * ::g->mousey : ::g->mousey;
  344. }
  345. /*
  346. if (::g->mousey < 0) {
  347. forward -= ::g->forwardmove[speed];
  348. }
  349. */
  350. /*
  351. if (::g->gamekeydown[::g->key_straferight])
  352. side += ::g->sidemove[speed];
  353. if (::g->gamekeydown[::g->key_strafeleft])
  354. side -= ::g->sidemove[speed];
  355. */
  356. if ( ::g->joyxmove > 0 || ::g->joyxmove < 0 ) {
  357. side += speed == 1 ? 2 * ::g->joyxmove : ::g->joyxmove;
  358. }
  359. // buttons
  360. if (::g->gamekeydown[::g->key_fire] || ::g->mousebuttons[::g->mousebfire] || ::g->joybuttons[::g->joybfire])
  361. cmd->buttons |= BT_ATTACK;
  362. if (::g->gamekeydown[::g->key_use] || ::g->joybuttons[::g->joybuse] )
  363. cmd->buttons |= BT_USE;
  364. // DHM - Nerve :: In the intermission or finale screens, make START also create a 'use' command.
  365. if ( (::g->gamestate == GS_INTERMISSION || ::g->gamestate == GS_FINALE) && ::g->gamekeydown[KEY_ESCAPE] ) {
  366. cmd->buttons |= BT_USE;
  367. }
  368. // weapon toggle
  369. for (i=0 ; i<NUMWEAPONS-1 ; i++)
  370. {
  371. if (::g->gamekeydown['1'+i])
  372. {
  373. cmd->buttons |= BT_CHANGE;
  374. cmd->buttons |= i<<BT_WEAPONSHIFT;
  375. break;
  376. }
  377. }
  378. ::g->mousex = ::g->mousey = 0;
  379. if (forward > MAXPLMOVE)
  380. forward = MAXPLMOVE;
  381. else if (forward < -MAXPLMOVE)
  382. forward = -MAXPLMOVE;
  383. if (side > MAXPLMOVE)
  384. side = MAXPLMOVE;
  385. else if (side < -MAXPLMOVE)
  386. side = -MAXPLMOVE;
  387. cmd->forwardmove += forward;
  388. cmd->sidemove += side;
  389. // special buttons
  390. if (::g->sendpause)
  391. {
  392. ::g->sendpause = false;
  393. cmd->buttons = BT_SPECIAL | BTS_PAUSE;
  394. }
  395. if (::g->sendsave)
  396. {
  397. ::g->sendsave = false;
  398. cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (::g->savegameslot<<BTS_SAVESHIFT);
  399. }
  400. }
  401. //
  402. // G_DoLoadLevel
  403. //
  404. void G_DoLoadLevel ()
  405. {
  406. int i;
  407. M_ClearRandom();
  408. // Set the sky map.
  409. // First thing, we have a dummy sky texture name,
  410. // a flat. The data is in the WAD only because
  411. // we look for an actual index, instead of simply
  412. // setting one.
  413. ::g->skyflatnum = R_FlatNumForName ( SKYFLATNAME );
  414. // DOOM determines the sky texture to be used
  415. // depending on the current episode, and the game version.
  416. if ( ::g->gamemode == commercial )
  417. {
  418. ::g->skytexture = R_TextureNumForName ("SKY3");
  419. if (::g->gamemap < 12) {
  420. ::g->skytexture = R_TextureNumForName ("SKY1");
  421. }
  422. else if (::g->gamemap < 21) {
  423. ::g->skytexture = R_TextureNumForName ("SKY2");
  424. }
  425. }
  426. ::g->levelstarttic = ::g->gametic; // for time calculation
  427. if (::g->wipegamestate == GS_LEVEL) {
  428. ::g->wipegamestate = (gamestate_t)-1; // force a wipe
  429. } else if ( ::g->netgame ) {
  430. ::g->wipegamestate = GS_LEVEL;
  431. }
  432. ::g->gamestate = GS_LEVEL;
  433. for (i=0 ; i<MAXPLAYERS ; i++)
  434. {
  435. if (::g->playeringame[i] && ::g->players[i].playerstate == PST_DEAD)
  436. ::g->players[i].playerstate = PST_REBORN;
  437. memset (::g->players[i].frags,0,sizeof(::g->players[i].frags));
  438. memset (&(::g->players[i].cmd),0,sizeof(::g->players[i].cmd));
  439. }
  440. const char * difficultyNames[] = { "I'm Too Young To Die!", "Hey, Not Too Rough!", "Hurt Me Plenty!", "Ultra-Violence", "Nightmare" };
  441. const ExpansionData * expansion = DoomLib::GetCurrentExpansion();
  442. int truemap = ::g->gamemap;
  443. if( ::g->gamemission == doom ) {
  444. truemap = ( ::g->gameepisode - 1 ) * 9 + ( ::g->gamemap );
  445. }
  446. idMatchParameters newParms = session->GetActingGameStateLobbyBase().GetMatchParms();
  447. DoomLib::SetCurrentMapName( expansion->mapNames[ truemap - 1 ] );
  448. DoomLib::SetCurrentDifficulty( difficultyNames[ ::g->gameskill ] );
  449. P_SetupLevel (::g->gameepisode, ::g->gamemap, 0, ::g->gameskill);
  450. ::g->displayplayer = ::g->consoleplayer; // view the guy you are playing
  451. ::g->starttime = I_GetTime ();
  452. ::g->gameaction = ga_nothing;
  453. // clear cmd building stuff
  454. memset (::g->gamekeydown, 0, sizeof(::g->gamekeydown));
  455. ::g->joyxmove = ::g->joyymove = 0;
  456. ::g->mousex = ::g->mousey = 0;
  457. ::g->sendpause = ::g->sendsave = ::g->paused = false;
  458. memset (::g->mousebuttons, 0, sizeof(::g->mousebuttons));
  459. memset (::g->joybuttons, 0, sizeof(::g->joybuttons));
  460. }
  461. //
  462. // G_Responder
  463. // Get info needed to make ticcmd_ts for the ::g->players.
  464. //
  465. qboolean G_Responder (event_t* ev)
  466. {
  467. // allow spy mode changes even during the demo
  468. if (::g->gamestate == GS_LEVEL && ev->type == ev_keydown
  469. && ev->data1 == KEY_F12 && (::g->singledemo || !::g->deathmatch) )
  470. {
  471. // spy mode
  472. do
  473. {
  474. ::g->displayplayer++;
  475. if (::g->displayplayer == MAXPLAYERS)
  476. ::g->displayplayer = 0;
  477. } while (!::g->playeringame[::g->displayplayer] && ::g->displayplayer != ::g->consoleplayer);
  478. return true;
  479. }
  480. // any other key pops up menu if in demos
  481. if (::g->gameaction == ga_nothing && !::g->singledemo &&
  482. (::g->demoplayback || ::g->gamestate == GS_DEMOSCREEN)
  483. )
  484. {
  485. if (ev->type == ev_keydown ||
  486. (ev->type == ev_mouse && ev->data1) ||
  487. (ev->type == ev_joystick && ev->data1) )
  488. {
  489. M_StartControlPanel ();
  490. return true;
  491. }
  492. return false;
  493. }
  494. if (::g->gamestate == GS_LEVEL && ( ::g->usergame || ::g->netgame || ::g->demoplayback ))
  495. {
  496. #if 0
  497. if (::g->devparm && ev->type == ev_keydown && ev->data1 == ';')
  498. {
  499. G_DeathMatchSpawnPlayer (0);
  500. return true;
  501. }
  502. #endif
  503. if (HU_Responder (ev))
  504. return true; // chat ate the event
  505. if (ST_Responder (ev))
  506. return true; // status window ate it
  507. if (AM_Responder (ev))
  508. return true; // automap ate it
  509. }
  510. if (::g->gamestate == GS_FINALE)
  511. {
  512. if (F_Responder (ev))
  513. return true; // finale ate the event
  514. }
  515. switch (ev->type)
  516. {
  517. case ev_keydown:
  518. if (ev->data1 == KEY_PAUSE)
  519. {
  520. ::g->sendpause = true;
  521. return true;
  522. }
  523. if (ev->data1 <NUMKEYS)
  524. ::g->gamekeydown[ev->data1] = true;
  525. return true; // eat key down ::g->events
  526. case ev_keyup:
  527. // DHM - Nerve :: Old School!
  528. //if ( ev->data1 == '-' ) {
  529. //App->Renderer->oldSchool = !App->Renderer->oldSchool;
  530. //}
  531. if (ev->data1 <NUMKEYS)
  532. ::g->gamekeydown[ev->data1] = false;
  533. return false; // always let key up ::g->events filter down
  534. case ev_mouse:
  535. ::g->mousebuttons[0] = ev->data1 & 1;
  536. ::g->mousebuttons[1] = ev->data1 & 2;
  537. ::g->mousebuttons[2] = ev->data1 & 4;
  538. ::g->mousex = ev->data2*(::g->mouseSensitivity+5)/10;
  539. ::g->mousey = ev->data3*(::g->mouseSensitivity+5)/10;
  540. return true; // eat ::g->events
  541. case ev_joystick:
  542. ::g->joybuttons[0] = ev->data1 & 1;
  543. ::g->joybuttons[1] = ev->data1 & 2;
  544. ::g->joybuttons[2] = ev->data1 & 4;
  545. ::g->joybuttons[3] = ev->data1 & 8;
  546. ::g->joyxmove = ev->data2;
  547. /*
  548. ::g->gamekeydown[::g->key_straferight] = ::g->gamekeydown[::g->key_strafeleft] = 0;
  549. if (ev->data2 > 0)
  550. ::g->gamekeydown[::g->key_straferight] = 1;
  551. else if (ev->data2 < 0)
  552. ::g->gamekeydown[::g->key_strafeleft] = 1;
  553. */
  554. ::g->joyymove = ev->data3;
  555. return true; // eat ::g->events
  556. default:
  557. break;
  558. }
  559. return false;
  560. }
  561. //
  562. // G_Ticker
  563. // Make ticcmd_ts for the ::g->players.
  564. //
  565. void G_Ticker (void)
  566. {
  567. int i;
  568. int buf;
  569. ticcmd_t* cmd;
  570. // do player reborns if needed
  571. for (i=0 ; i<MAXPLAYERS ; i++)
  572. if (::g->playeringame[i] && ::g->players[i].playerstate == PST_REBORN)
  573. G_DoReborn (i);
  574. // do things to change the game state
  575. while (::g->gameaction != ga_nothing)
  576. {
  577. switch (::g->gameaction)
  578. {
  579. case ga_loadlevel:
  580. G_DoLoadLevel ();
  581. break;
  582. case ga_newgame:
  583. G_DoNewGame ();
  584. break;
  585. case ga_loadgame:
  586. G_DoLoadGame ();
  587. break;
  588. case ga_savegame:
  589. G_DoSaveGame ();
  590. break;
  591. case ga_playdemo:
  592. G_DoPlayDemo ();
  593. break;
  594. case ga_completed:
  595. G_DoCompleted ();
  596. break;
  597. case ga_victory:
  598. F_StartFinale ();
  599. break;
  600. case ga_worlddone:
  601. G_DoWorldDone ();
  602. break;
  603. case ga_screenshot:
  604. M_ScreenShot ();
  605. ::g->gameaction = ga_nothing;
  606. break;
  607. case ga_nothing:
  608. break;
  609. }
  610. }
  611. // get commands, check ::g->consistancy,
  612. // and build new ::g->consistancy check
  613. buf = (::g->gametic/::g->ticdup)%BACKUPTICS;
  614. for (i=0 ; i<MAXPLAYERS ; i++)
  615. {
  616. if (::g->playeringame[i])
  617. {
  618. cmd = &::g->players[i].cmd;
  619. memcpy (cmd, &::g->netcmds[i][buf], sizeof(ticcmd_t));
  620. if ( ::g->demoplayback ) {
  621. G_ReadDemoTiccmd( cmd );
  622. #ifdef DEBUG_DEMOS
  623. if ( demoDebugOn && testprndindex != ::g->prndindex && printErrorCount++ < 10 ) {
  624. I_Printf( "time: %d, g->prndindex(%d) does not match demo prndindex(%d)!\n", ::g->leveltime, ::g->prndindex, testprndindex );
  625. }
  626. #endif
  627. }
  628. if ( ::g->demorecording ) {
  629. G_WriteDemoTiccmd (cmd);
  630. }
  631. // HACK ALERT ( the GS_FINALE CRAP IS A HACK.. )
  632. if (::g->netgame && !::g->netdemo && !(::g->gametic % ::g->ticdup) && !(::g->gamestate == GS_FINALE ) )
  633. {
  634. if (::g->gametic > BACKUPTICS && ::g->consistancy[i][buf] != cmd->consistancy)
  635. {
  636. printf ("consistency failure (%i should be %i)",
  637. cmd->consistancy, ::g->consistancy[i][buf]);
  638. // TODO: If we ever support splitscreen and online,
  639. // we'll have to call D_QuitNetGame for all local players.
  640. D_QuitNetGame();
  641. session->QuitMatch();
  642. common->Dialog().AddDialog( GDM_CONNECTION_LOST_HOST, DIALOG_ACCEPT, NULL, NULL, false );
  643. }
  644. if (::g->players[i].mo)
  645. ::g->consistancy[i][buf] = ::g->players[i].mo->x;
  646. else
  647. ::g->consistancy[i][buf] = ::g->rndindex;
  648. }
  649. }
  650. }
  651. // check for special buttons
  652. for (i=0 ; i<MAXPLAYERS ; i++)
  653. {
  654. if (::g->playeringame[i])
  655. {
  656. if (::g->players[i].cmd.buttons & BT_SPECIAL)
  657. {
  658. switch (::g->players[i].cmd.buttons & BT_SPECIALMASK)
  659. {
  660. case BTS_PAUSE:
  661. ::g->paused ^= 1;
  662. // DHM - Nerve :: Don't pause the music
  663. /*
  664. if (::g->paused)
  665. S_PauseSound ();
  666. else
  667. S_ResumeSound ();
  668. */
  669. break;
  670. case BTS_SAVEGAME:
  671. if (!::g->savedescription[0])
  672. strcpy (::g->savedescription, "NET GAME");
  673. ::g->savegameslot = (::g->players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT;
  674. ::g->gameaction = ga_savegame;
  675. break;
  676. }
  677. }
  678. }
  679. }
  680. // do main actions
  681. switch (::g->gamestate)
  682. {
  683. case GS_LEVEL:
  684. P_Ticker ();
  685. ST_Ticker ();
  686. AM_Ticker ();
  687. HU_Ticker ();
  688. break;
  689. case GS_INTERMISSION:
  690. WI_Ticker ();
  691. break;
  692. case GS_FINALE:
  693. F_Ticker ();
  694. break;
  695. case GS_DEMOSCREEN:
  696. D_PageTicker ();
  697. break;
  698. }
  699. }
  700. //
  701. // PLAYER STRUCTURE FUNCTIONS
  702. // also see P_SpawnPlayer in P_Things
  703. //
  704. //
  705. // G_InitPlayer
  706. // Called at the start.
  707. // Called by the game initialization functions.
  708. //
  709. void G_InitPlayer (int player)
  710. {
  711. player_t* p;
  712. // set up the saved info
  713. p = &::g->players[player];
  714. // clear everything else to defaults
  715. G_PlayerReborn (player);
  716. }
  717. //
  718. // G_PlayerFinishLevel
  719. // Can when a player completes a level.
  720. //
  721. void G_PlayerFinishLevel (int player)
  722. {
  723. player_t* p;
  724. p = &::g->players[player];
  725. memset (p->powers, 0, sizeof (p->powers));
  726. memset (p->cards, 0, sizeof (p->cards));
  727. p->mo->flags &= ~MF_SHADOW; // cancel invisibility
  728. p->extralight = 0; // cancel gun flashes
  729. p->fixedcolormap = 0; // cancel ir gogles
  730. p->damagecount = 0; // no palette changes
  731. p->bonuscount = 0;
  732. }
  733. //
  734. // G_PlayerReborn
  735. // Called after a player dies
  736. // almost everything is cleared and initialized
  737. //
  738. void G_PlayerReborn (int player)
  739. {
  740. player_t* p;
  741. int i;
  742. int frags[MAXPLAYERS];
  743. int killcount;
  744. int itemcount;
  745. int secretcount;
  746. // DHM - Nerve :: cards are saved across death in coop multiplayer
  747. qboolean cards[NUMCARDS];
  748. bool hasMapPowerup = false;
  749. hasMapPowerup = ::g->players[player].powers[pw_allmap] != 0;
  750. memcpy( cards, ::g->players[player].cards, sizeof(cards) );
  751. memcpy( frags, ::g->players[player].frags, sizeof(frags) );
  752. killcount = ::g->players[player].killcount;
  753. itemcount = ::g->players[player].itemcount;
  754. secretcount = ::g->players[player].secretcount;
  755. p = &::g->players[player];
  756. memset (p, 0, sizeof(*p));
  757. // DHM - Nerve :: restore cards in multiplayer
  758. // TODO: Networking
  759. #ifdef ID_ENABLE_DOOM_CLASSIC_NETWORKING
  760. if ( common->IsMultiplayer() || gameLocal->IsSplitscreen() || (::g->demoplayback && ::g->netdemo) ) {
  761. if ( hasMapPowerup ) {
  762. ::g->players[player].powers[pw_allmap] = 1;
  763. }
  764. memcpy (::g->players[player].cards, cards, sizeof(::g->players[player].cards));
  765. }
  766. #endif
  767. memcpy (::g->players[player].frags, frags, sizeof(::g->players[player].frags));
  768. ::g->players[player].killcount = killcount;
  769. ::g->players[player].itemcount = itemcount;
  770. ::g->players[player].secretcount = secretcount;
  771. p->usedown = p->attackdown = true; // don't do anything immediately
  772. p->playerstate = PST_LIVE;
  773. p->health = MAXHEALTH;
  774. p->readyweapon = p->pendingweapon = wp_pistol;
  775. p->weaponowned[wp_fist] = true;
  776. p->weaponowned[wp_pistol] = true;
  777. p->ammo[am_clip] = 50;
  778. // TODO: PC
  779. #if 0
  780. p->cheats = gameLocal->cheats;
  781. #else
  782. p->cheats = 0;
  783. #endif
  784. for (i=0 ; i<NUMAMMO ; i++)
  785. p->maxammo[i] = maxammo[i];
  786. }
  787. //
  788. // G_CheckSpot
  789. // Returns false if the player cannot be respawned
  790. // at the given mapthing_t spot
  791. // because something is occupying it
  792. //
  793. void P_SpawnPlayer (mapthing_t* mthing);
  794. qboolean
  795. G_CheckSpot
  796. ( int playernum,
  797. mapthing_t* mthing )
  798. {
  799. fixed_t x;
  800. fixed_t y;
  801. subsector_t* ss;
  802. unsigned an;
  803. mobj_t* mo;
  804. int i;
  805. if (!::g->players[playernum].mo)
  806. {
  807. // first spawn of level, before corpses
  808. for (i=0 ; i<playernum ; i++)
  809. if (::g->players[i].mo->x == mthing->x << FRACBITS
  810. && ::g->players[i].mo->y == mthing->y << FRACBITS)
  811. return false;
  812. return true;
  813. }
  814. x = mthing->x << FRACBITS;
  815. y = mthing->y << FRACBITS;
  816. if (!P_CheckPosition (::g->players[playernum].mo, x, y) )
  817. return false;
  818. // flush an old corpse if needed
  819. if (::g->bodyqueslot >= BODYQUESIZE)
  820. P_RemoveMobj (::g->bodyque[::g->bodyqueslot%BODYQUESIZE]);
  821. ::g->bodyque[::g->bodyqueslot%BODYQUESIZE] = ::g->players[playernum].mo;
  822. ::g->bodyqueslot++;
  823. // spawn a teleport fog
  824. ss = R_PointInSubsector (x,y);
  825. an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT;
  826. mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an]
  827. , ss->sector->floorheight
  828. , MT_TFOG);
  829. if (::g->players[::g->consoleplayer].viewz != 1 && (playernum == ::g->consoleplayer))
  830. S_StartSound (::g->players[::g->consoleplayer].mo, sfx_telept); // don't start sound on first frame
  831. return true;
  832. }
  833. //
  834. // G_DeathMatchSpawnPlayer
  835. // Spawns a player at one of the random death match spots
  836. // called at level load and each death
  837. //
  838. void G_DeathMatchSpawnPlayer (int playernum)
  839. {
  840. int i,j;
  841. int selections;
  842. selections = ::g->deathmatch_p - ::g->deathmatchstarts;
  843. if (selections < 4)
  844. I_Error ("Only %i ::g->deathmatch spots, 4 required", selections);
  845. for (j=0 ; j<20 ; j++)
  846. {
  847. i = P_Random() % selections;
  848. if (G_CheckSpot (playernum, &::g->deathmatchstarts[i]) )
  849. {
  850. ::g->deathmatchstarts[i].type = playernum+1;
  851. P_SpawnPlayer (&::g->deathmatchstarts[i]);
  852. return;
  853. }
  854. }
  855. // no good spot, so the player will probably get stuck
  856. P_SpawnPlayer (&::g->playerstarts[playernum]);
  857. }
  858. //
  859. // G_DoReborn
  860. //
  861. void G_DoReborn (int playernum)
  862. {
  863. int i;
  864. if (!::g->netgame)
  865. {
  866. // reload the level from scratch
  867. ::g->gameaction = ga_loadlevel;
  868. }
  869. else
  870. {
  871. // respawn at the start
  872. // first dissasociate the corpse
  873. ::g->players[playernum].mo->player = NULL;
  874. // spawn at random spot if in death match
  875. if (::g->deathmatch)
  876. {
  877. G_DeathMatchSpawnPlayer (playernum);
  878. return;
  879. }
  880. if (G_CheckSpot (playernum, &::g->playerstarts[playernum]) )
  881. {
  882. P_SpawnPlayer (&::g->playerstarts[playernum]);
  883. return;
  884. }
  885. // try to spawn at one of the other ::g->players spots
  886. for (i=0 ; i<MAXPLAYERS ; i++)
  887. {
  888. if (G_CheckSpot (playernum, &::g->playerstarts[i]) )
  889. {
  890. ::g->playerstarts[i].type = playernum+1; // fake as other player
  891. P_SpawnPlayer (&::g->playerstarts[i]);
  892. ::g->playerstarts[i].type = i+1; // restore
  893. return;
  894. }
  895. // he's going to be inside something. Too bad.
  896. }
  897. P_SpawnPlayer (&::g->playerstarts[playernum]);
  898. }
  899. }
  900. void G_ScreenShot (void)
  901. {
  902. ::g->gameaction = ga_screenshot;
  903. }
  904. // DHM - Nerve :: Added episode 4 par times
  905. // DOOM Par Times
  906. const int pars[5][10] =
  907. {
  908. {0},
  909. {0,30,75,120,90,165,180,180,30,165},
  910. {0,90,90,90,120,90,360,240,30,170},
  911. {0,90,45,90,150,90,90,165,30,135},
  912. {0,165,255,135,150,180,390,135,360,180}
  913. };
  914. // DOOM II Par Times
  915. const int cpars[32] =
  916. {
  917. 30,90,120,120,90,150,120,120,270,90, // 1-10
  918. 210,150,150,150,210,150,420,150,210,150, // 11-20
  919. 240,150,180,150,150,300,330,420,300,180, // 21-30
  920. 120,30 // 31-32
  921. };
  922. //
  923. // G_DoCompleted
  924. //
  925. void G_ExitLevel (void)
  926. {
  927. ::g->secretexit = false;
  928. ::g->gameaction = ga_completed;
  929. }
  930. // Here's for the german edition.
  931. void G_SecretExitLevel (void)
  932. {
  933. // IF NO WOLF3D LEVELS, NO SECRET EXIT!
  934. if ( (::g->gamemode == commercial)
  935. && (W_CheckNumForName("map31")<0))
  936. ::g->secretexit = false;
  937. else
  938. ::g->secretexit = true;
  939. ::g->gameaction = ga_completed;
  940. }
  941. void G_DoCompleted (void)
  942. {
  943. int i;
  944. ::g->gameaction = ga_nothing;
  945. for (i=0 ; i<MAXPLAYERS ; i++) {
  946. if (::g->playeringame[i]) {
  947. G_PlayerFinishLevel (i); // take away cards and stuff
  948. }
  949. }
  950. if (::g->automapactive) {
  951. AM_Stop();
  952. }
  953. if ( ::g->demoplayback ) {
  954. G_CheckDemoStatus();
  955. return;
  956. }
  957. if ( ::g->demorecording ) {
  958. G_CheckDemoStatus();
  959. }
  960. // DHM - Nerve :: Deathmatch doesn't go to finale screen, just do intermission
  961. if ( ::g->gamemode != commercial && !::g->deathmatch ) {
  962. switch(::g->gamemap) {
  963. case 8:
  964. ::g->gameaction = ga_victory;
  965. return;
  966. case 9:
  967. for (i=0 ; i<MAXPLAYERS ; i++)
  968. ::g->players[i].didsecret = true;
  969. break;
  970. }
  971. }
  972. ::g->wminfo.didsecret = ::g->players[::g->consoleplayer].didsecret;
  973. ::g->wminfo.epsd = ::g->gameepisode -1;
  974. ::g->wminfo.last = ::g->gamemap -1;
  975. // ::g->wminfo.next is 0 biased, unlike ::g->gamemap
  976. if ( ::g->gamemode == commercial)
  977. {
  978. if (::g->secretexit) {
  979. if ( ::g->gamemission == doom2 ) {
  980. switch(::g->gamemap)
  981. {
  982. case 15: ::g->wminfo.next = 30; break;
  983. case 31: ::g->wminfo.next = 31; break;
  984. }
  985. } else if( ::g->gamemission == pack_nerve ) {
  986. // DHM - Nerve :: Secret level is always level 9 on extra Doom2 missions
  987. ::g->wminfo.next = 8;
  988. }
  989. }
  990. else {
  991. if ( ::g->gamemission == doom2 ) {
  992. switch(::g->gamemap)
  993. {
  994. case 31:
  995. case 32: ::g->wminfo.next = 15; break;
  996. default: ::g->wminfo.next = ::g->gamemap;
  997. }
  998. }
  999. else if( ::g->gamemission == pack_nerve) {
  1000. switch(::g->gamemap)
  1001. { case 9:
  1002. ::g->wminfo.next = 4;
  1003. break;
  1004. default:
  1005. ::g->wminfo.next = ::g->gamemap;
  1006. break;
  1007. }
  1008. } else {
  1009. ::g->wminfo.next = ::g->gamemap;
  1010. }
  1011. }
  1012. }
  1013. else
  1014. {
  1015. if (::g->secretexit) {
  1016. ::g->wminfo.next = 8; // go to secret level
  1017. }
  1018. else if (::g->gamemap == 9 )
  1019. {
  1020. // returning from secret level
  1021. switch (::g->gameepisode)
  1022. {
  1023. case 1:
  1024. ::g->wminfo.next = 3;
  1025. break;
  1026. case 2:
  1027. ::g->wminfo.next = 5;
  1028. break;
  1029. case 3:
  1030. ::g->wminfo.next = 6;
  1031. break;
  1032. case 4:
  1033. ::g->wminfo.next = 2;
  1034. break;
  1035. }
  1036. }
  1037. else
  1038. ::g->wminfo.next = ::g->gamemap; // go to next level
  1039. }
  1040. // DHM - Nerve :: In deathmatch, repeat the current level. User must exit and choose a new level.
  1041. if ( ::g->deathmatch ) {
  1042. ::g->wminfo.next = ::g->wminfo.last;
  1043. }
  1044. ::g->wminfo.maxkills = ::g->totalkills;
  1045. ::g->wminfo.maxitems = ::g->totalitems;
  1046. ::g->wminfo.maxsecret = ::g->totalsecret;
  1047. ::g->wminfo.maxfrags = 0;
  1048. if ( ::g->gamemode == commercial ) {
  1049. ::g->wminfo.partime = TICRATE *cpars[::g->gamemap-1];
  1050. }
  1051. else
  1052. ::g->wminfo.partime = TICRATE * pars[::g->gameepisode][::g->gamemap];
  1053. ::g->wminfo.pnum = ::g->consoleplayer;
  1054. for (i=0 ; i<MAXPLAYERS ; i++)
  1055. {
  1056. ::g->wminfo.plyr[i].in = ::g->playeringame[i];
  1057. ::g->wminfo.plyr[i].skills = ::g->players[i].killcount;
  1058. ::g->wminfo.plyr[i].sitems = ::g->players[i].itemcount;
  1059. ::g->wminfo.plyr[i].ssecret = ::g->players[i].secretcount;
  1060. ::g->wminfo.plyr[i].stime = ::g->leveltime;
  1061. memcpy (::g->wminfo.plyr[i].frags, ::g->players[i].frags
  1062. , sizeof(::g->wminfo.plyr[i].frags));
  1063. }
  1064. ::g->gamestate = GS_INTERMISSION;
  1065. ::g->viewactive = false;
  1066. ::g->automapactive = false;
  1067. WI_Start (&::g->wminfo);
  1068. }
  1069. //
  1070. // G_WorldDone
  1071. //
  1072. void G_WorldDone (void)
  1073. {
  1074. ::g->gameaction = ga_worlddone;
  1075. if (::g->secretexit)
  1076. ::g->players[::g->consoleplayer].didsecret = true;
  1077. if ( ::g->gamemode == commercial )
  1078. {
  1079. if ( ::g->gamemission == doom2 || ::g->gamemission == pack_tnt || ::g->gamemission == pack_plut ) {
  1080. switch (::g->gamemap)
  1081. {
  1082. case 15:
  1083. case 31:
  1084. if (!::g->secretexit)
  1085. break;
  1086. case 6:
  1087. case 11:
  1088. case 20:
  1089. case 30:
  1090. F_StartFinale ();
  1091. break;
  1092. }
  1093. }
  1094. else if ( ::g->gamemission == pack_nerve ) {
  1095. if ( ::g->gamemap == 8 ) {
  1096. F_StartFinale();
  1097. }
  1098. }
  1099. else if ( ::g->gamemission == pack_master ) {
  1100. if ( ::g->gamemap == 21 ) {
  1101. F_StartFinale();
  1102. }
  1103. }
  1104. else {
  1105. // DHM - NERVE :: Downloadable content needs to set these up if different than initial extended episode
  1106. if ( ::g->gamemap == 8 ) {
  1107. F_StartFinale();
  1108. }
  1109. }
  1110. }
  1111. }
  1112. void G_DoWorldDone (void)
  1113. {
  1114. ::g->gamestate = GS_LEVEL;
  1115. ::g->gamemap = ::g->wminfo.next+1;
  1116. M_ClearRandom();
  1117. for ( int i = 0; i < MAXPLAYERS; i++ ) {
  1118. if ( ::g->playeringame[i] ) {
  1119. ::g->players[i].usedown = ::g->players[i].attackdown = true; // don't do anything immediately
  1120. }
  1121. }
  1122. G_DoLoadLevel ();
  1123. ::g->gameaction = ga_nothing;
  1124. ::g->viewactive = true;
  1125. }
  1126. //
  1127. // G_InitFromSavegame
  1128. // Can be called by the startup code or the menu task.
  1129. //
  1130. void R_ExecuteSetViewSize (void);
  1131. void G_LoadGame (char* name)
  1132. {
  1133. strcpy (::g->savename, name);
  1134. ::g->gameaction = ga_loadgame;
  1135. }
  1136. qboolean G_DoLoadGame ()
  1137. {
  1138. int i;
  1139. int a,b,c;
  1140. char vcheck[VERSIONSIZE];
  1141. loadingGame = true;
  1142. ::g->gameaction = ga_nothing;
  1143. M_ReadFile (::g->savename, &::g->savebuffer);
  1144. waitingForWipe = true;
  1145. // DHM - Nerve :: Clear possible net demo state
  1146. ::g->netdemo = false;
  1147. ::g->netgame = false;
  1148. ::g->deathmatch = false;
  1149. ::g->playeringame[1] = ::g->playeringame[2] = ::g->playeringame[3] = 0;
  1150. ::g->respawnparm = false;
  1151. ::g->fastparm = false;
  1152. ::g->nomonsters = false;
  1153. ::g->consoleplayer = 0;
  1154. ::g->save_p = ::g->savebuffer + SAVESTRINGSIZE;
  1155. // skip the description field
  1156. memset (vcheck,0,sizeof(vcheck));
  1157. sprintf (vcheck,"version %i",VERSION);
  1158. if (strcmp ((char *)::g->save_p, vcheck)) {
  1159. loadingGame = false;
  1160. waitingForWipe = false;
  1161. return FALSE; // bad version
  1162. }
  1163. ::g->save_p += VERSIONSIZE;
  1164. ::g->gameskill = (skill_t)*::g->save_p++;
  1165. ::g->gameepisode = *::g->save_p++;
  1166. ::g->gamemission = *::g->save_p++;
  1167. ::g->gamemap = *::g->save_p++;
  1168. for (i=0 ; i<MAXPLAYERS ; i++)
  1169. ::g->playeringame[i] = *::g->save_p++;
  1170. // load a base level
  1171. G_InitNew (::g->gameskill, ::g->gameepisode, ::g->gamemap );
  1172. // get the times
  1173. a = *::g->save_p++;
  1174. b = *::g->save_p++;
  1175. c = *::g->save_p++;
  1176. ::g->leveltime = (a<<16) + (b<<8) + c;
  1177. // dearchive all the modifications
  1178. P_UnArchivePlayers ();
  1179. P_UnArchiveWorld ();
  1180. P_UnArchiveThinkers ();
  1181. // specials are archived with thinkers
  1182. //P_UnArchiveSpecials ();
  1183. if (*::g->save_p != 0x1d)
  1184. I_Error ("Bad savegame");
  1185. if (::g->setsizeneeded)
  1186. R_ExecuteSetViewSize ();
  1187. // draw the pattern into the back screen
  1188. R_FillBackScreen ();
  1189. loadingGame = false;
  1190. Z_Free(g->savebuffer);
  1191. return TRUE;
  1192. }
  1193. //
  1194. // G_SaveGame
  1195. // Called by the menu task.
  1196. // Description is a 24 byte text string
  1197. //
  1198. void
  1199. G_SaveGame
  1200. ( int slot,
  1201. char* description )
  1202. {
  1203. ::g->savegameslot = slot;
  1204. strcpy (::g->savedescription, description);
  1205. ::g->sendsave = true;
  1206. ::g->gameaction = ga_savegame;
  1207. }
  1208. qboolean G_DoSaveGame (void)
  1209. {
  1210. char name[100];
  1211. char name2[VERSIONSIZE];
  1212. char* description;
  1213. int length;
  1214. int i;
  1215. qboolean bResult = true;
  1216. if ( ::g->gamestate != GS_LEVEL ) {
  1217. return false;
  1218. }
  1219. description = ::g->savedescription;
  1220. if( common->GetCurrentGame() == DOOM_CLASSIC ) {
  1221. sprintf(name,"DOOM\\%s%d.dsg", SAVEGAMENAME,::g->savegameslot );
  1222. } else {
  1223. if( DoomLib::expansionSelected == doom2 ) {
  1224. sprintf(name,"DOOM2\\%s%d.dsg", SAVEGAMENAME,::g->savegameslot );
  1225. } else {
  1226. sprintf(name,"DOOM2_NRFTL\\%s%d.dsg", SAVEGAMENAME,::g->savegameslot );
  1227. }
  1228. }
  1229. ::g->save_p = ::g->savebuffer = ::g->screens[1];
  1230. memcpy (::g->save_p, description, SAVESTRINGSIZE);
  1231. ::g->save_p += SAVESTRINGSIZE;
  1232. memset (name2,0,sizeof(name2));
  1233. sprintf (name2,"version %i",VERSION);
  1234. memcpy (::g->save_p, name2, VERSIONSIZE);
  1235. ::g->save_p += VERSIONSIZE;
  1236. *::g->save_p++ = ::g->gameskill;
  1237. *::g->save_p++ = ::g->gameepisode;
  1238. *::g->save_p++ = ::g->gamemission;
  1239. *::g->save_p++ = ::g->gamemap;
  1240. for (i=0 ; i<MAXPLAYERS ; i++) {
  1241. *::g->save_p++ = ::g->playeringame[i];
  1242. }
  1243. *::g->save_p++ = ::g->leveltime>>16;
  1244. *::g->save_p++ = ::g->leveltime>>8;
  1245. *::g->save_p++ = ::g->leveltime;
  1246. P_ArchivePlayers ();
  1247. P_ArchiveWorld ();
  1248. P_ArchiveThinkers ();
  1249. // specials are archived with thinkers
  1250. //P_ArchiveSpecials ();
  1251. *::g->save_p++ = 0x1d; // ::g->consistancy marker
  1252. length = ::g->save_p - ::g->savebuffer;
  1253. if (length > SAVEGAMESIZE)
  1254. I_Error ("Savegame buffer overrun");
  1255. ::g->savebufferSize = length;
  1256. M_WriteFile (name, ::g->savebuffer, length);
  1257. ::g->gameaction = ga_nothing;
  1258. ::g->savedescription[0] = 0;
  1259. // draw the pattern into the back screen
  1260. R_FillBackScreen ();
  1261. return bResult;
  1262. }
  1263. //
  1264. // G_InitNew
  1265. // Can be called by the startup code or the menu task,
  1266. // ::g->consoleplayer, ::g->displayplayer, ::g->playeringame[] should be set.
  1267. //
  1268. void
  1269. G_DeferedInitNew
  1270. ( skill_t skill,
  1271. int episode,
  1272. int map)
  1273. {
  1274. ::g->d_skill = skill;
  1275. ::g->d_episode = episode;
  1276. ::g->d_map = map;
  1277. //::g->d_map = 30;
  1278. ::g->gameaction = ga_newgame;
  1279. }
  1280. void G_DoNewGame (void)
  1281. {
  1282. ::g->demoplayback = false;
  1283. ::g->netdemo = false;
  1284. ::g->netgame = false;
  1285. ::g->deathmatch = false;
  1286. ::g->playeringame[1] = ::g->playeringame[2] = ::g->playeringame[3] = 0;
  1287. ::g->respawnparm = false;
  1288. ::g->fastparm = false;
  1289. ::g->nomonsters = false;
  1290. ::g->consoleplayer = 0;
  1291. G_InitNew (::g->d_skill, ::g->d_episode, ::g->d_map );
  1292. ::g->gameaction = ga_nothing;
  1293. }
  1294. // The sky texture to be used instead of the F_SKY1 dummy.
  1295. void
  1296. G_InitNew
  1297. ( skill_t skill,
  1298. int episode,
  1299. int map
  1300. )
  1301. {
  1302. int i;
  1303. m_inDemoMode.SetBool( false );
  1304. R_SetViewSize (::g->screenblocks, ::g->detailLevel);
  1305. if (::g->paused)
  1306. {
  1307. ::g->paused = false;
  1308. S_ResumeSound ();
  1309. }
  1310. if (skill > sk_nightmare)
  1311. skill = sk_nightmare;
  1312. // This was quite messy with SPECIAL and commented parts.
  1313. // Supposedly hacks to make the latest edition work.
  1314. // It might not work properly.
  1315. if (episode < 1)
  1316. episode = 1;
  1317. if ( ::g->gamemode == retail )
  1318. {
  1319. if (episode > 4)
  1320. episode = 4;
  1321. }
  1322. else if ( ::g->gamemode == shareware )
  1323. {
  1324. if (episode > 1)
  1325. episode = 1; // only start episode 1 on shareware
  1326. }
  1327. else
  1328. {
  1329. if (episode > 3)
  1330. episode = 3;
  1331. }
  1332. if (map < 1)
  1333. map = 1;
  1334. if (skill == sk_nightmare || ::g->respawnparm )
  1335. ::g->respawnmonsters = true;
  1336. else
  1337. ::g->respawnmonsters = false;
  1338. // force ::g->players to be initialized upon first level load
  1339. for (i=0 ; i<MAXPLAYERS ; i++)
  1340. ::g->players[i].playerstate = PST_REBORN;
  1341. ::g->usergame = true; // will be set false if a demo
  1342. ::g->paused = false;
  1343. ::g->demoplayback = false;
  1344. ::g->advancedemo = false;
  1345. ::g->automapactive = false;
  1346. ::g->viewactive = true;
  1347. ::g->gameepisode = episode;
  1348. //::g->gamemission = expansion->pack_type;
  1349. ::g->gamemap = map;
  1350. ::g->gameskill = skill;
  1351. ::g->viewactive = true;
  1352. // set the sky map for the episode
  1353. if ( ::g->gamemode == commercial)
  1354. {
  1355. ::g->skytexture = R_TextureNumForName ("SKY3");
  1356. if (::g->gamemap < 12) {
  1357. ::g->skytexture = R_TextureNumForName ("SKY1");
  1358. }
  1359. else if (::g->gamemap < 21) {
  1360. ::g->skytexture = R_TextureNumForName ("SKY2");
  1361. }
  1362. }
  1363. else {
  1364. switch (episode)
  1365. {
  1366. case 1:
  1367. ::g->skytexture = R_TextureNumForName ("SKY1");
  1368. break;
  1369. case 2:
  1370. ::g->skytexture = R_TextureNumForName ("SKY2");
  1371. break;
  1372. case 3:
  1373. ::g->skytexture = R_TextureNumForName ("SKY3");
  1374. break;
  1375. case 4: // Special Edition sky
  1376. ::g->skytexture = R_TextureNumForName ("SKY4");
  1377. break;
  1378. default:
  1379. ::g->skytexture = R_TextureNumForName ("SKY1");
  1380. break;
  1381. }
  1382. }
  1383. G_DoLoadLevel( );
  1384. }
  1385. //
  1386. // DEMO RECORDING
  1387. //
  1388. void G_ReadDemoTiccmd (ticcmd_t* cmd)
  1389. {
  1390. if (*::g->demo_p == DEMOMARKER)
  1391. {
  1392. // end of demo data stream
  1393. G_CheckDemoStatus ();
  1394. return;
  1395. }
  1396. cmd->forwardmove = ((signed char)*::g->demo_p++);
  1397. cmd->sidemove = ((signed char)*::g->demo_p++);
  1398. if ( demoversion == VERSION ) {
  1399. short *temp = (short *)(::g->demo_p);
  1400. cmd->angleturn = *temp;
  1401. ::g->demo_p += 2;
  1402. }
  1403. else {
  1404. // DHM - Nerve :: Old format
  1405. cmd->angleturn = ((unsigned char)*::g->demo_p++)<<8;
  1406. }
  1407. cmd->buttons = (unsigned char)*::g->demo_p++;
  1408. #ifdef DEBUG_DEMOS
  1409. // TESTING
  1410. if ( demoDebugOn ) {
  1411. testprndindex = (unsigned char)*::g->demo_p++;
  1412. }
  1413. #endif
  1414. }
  1415. void G_WriteDemoTiccmd (ticcmd_t* cmd)
  1416. {
  1417. *::g->demo_p++ = cmd->forwardmove;
  1418. *::g->demo_p++ = cmd->sidemove;
  1419. // NEW VERSION
  1420. short *temp = (short *)(::g->demo_p);
  1421. *temp = cmd->angleturn;
  1422. ::g->demo_p += 2;
  1423. // OLD VERSION
  1424. //*::g->demo_p++ = (cmd->angleturn+128)>>8;
  1425. *::g->demo_p++ = cmd->buttons;
  1426. int cmdSize = 5;
  1427. #ifdef DEBUG_DEMOS_WRITE
  1428. // TESTING
  1429. *::g->demo_p++ = ::g->prndindex;
  1430. cmdSize++;
  1431. #endif
  1432. ::g->demo_p -= cmdSize;
  1433. if (::g->demo_p > ::g->demoend - (cmdSize * 4))
  1434. {
  1435. // no more space
  1436. G_CheckDemoStatus ();
  1437. return;
  1438. }
  1439. G_ReadDemoTiccmd (cmd); // make SURE it is exactly the same
  1440. }
  1441. //
  1442. // G_RecordDemo
  1443. //
  1444. void G_RecordDemo (char* name)
  1445. {
  1446. //::g->usergame = false;
  1447. strcpy( ::g->demoname, name );
  1448. strcat( ::g->demoname, ".lmp" );
  1449. ::g->demobuffer = new byte[ MAXDEMOSIZE ];
  1450. ::g->demoend = ::g->demobuffer + MAXDEMOSIZE;
  1451. demoversion = VERSION;
  1452. ::g->demorecording = true;
  1453. }
  1454. void G_BeginRecording (void)
  1455. {
  1456. int i;
  1457. ::g->demo_p = ::g->demobuffer;
  1458. #ifdef DEBUG_DEMOS
  1459. #ifdef DEBUG_DEMOS_WRITE
  1460. demoDebugOn = true;
  1461. *::g->demo_p++ = VERSION + 1;
  1462. #else
  1463. *::g->demo_p++ = VERSION;
  1464. #endif
  1465. #endif
  1466. *::g->demo_p++ = ::g->gameskill;
  1467. *::g->demo_p++ = ::g->gameepisode;
  1468. *::g->demo_p++ = ::g->gamemission;
  1469. *::g->demo_p++ = ::g->gamemap;
  1470. *::g->demo_p++ = ::g->deathmatch;
  1471. *::g->demo_p++ = ::g->respawnparm;
  1472. *::g->demo_p++ = ::g->fastparm;
  1473. *::g->demo_p++ = ::g->nomonsters;
  1474. *::g->demo_p++ = ::g->consoleplayer;
  1475. for ( i=0 ; i<MAXPLAYERS ; i++ ) {
  1476. *::g->demo_p++ = ::g->playeringame[i];
  1477. }
  1478. for ( i=0 ; i<MAXPLAYERS ; i++ ) {
  1479. // Archive player state to demo
  1480. if ( ::g->playeringame[i] ) {
  1481. int* dest = (int *)::g->demo_p;
  1482. *dest++ = ::g->players[i].health;
  1483. *dest++ = ::g->players[i].armorpoints;
  1484. *dest++ = ::g->players[i].armortype;
  1485. *dest++ = ::g->players[i].readyweapon;
  1486. for ( int j = 0; j < NUMWEAPONS; j++ ) {
  1487. *dest++ = ::g->players[i].weaponowned[j];
  1488. }
  1489. for ( int j = 0; j < NUMAMMO; j++ ) {
  1490. *dest++ = ::g->players[i].ammo[j];
  1491. *dest++ = ::g->players[i].maxammo[j];
  1492. }
  1493. ::g->demo_p = (byte *)dest;
  1494. }
  1495. }
  1496. }
  1497. //
  1498. // G_PlayDemo
  1499. //
  1500. void G_DeferedPlayDemo (char* name)
  1501. {
  1502. ::g->defdemoname = name;
  1503. ::g->gameaction = ga_playdemo;
  1504. }
  1505. void G_DoPlayDemo (void)
  1506. {
  1507. skill_t skill;
  1508. int i, episode, map, mission;
  1509. ::g->gameaction = ga_nothing;
  1510. // TODO: Networking
  1511. #if ID_ENABLE_DOOM_CLASSIC_NETWORKING
  1512. if ( gameLocal->IsSplitscreen() && DoomLib::GetPlayer() > 0 ) {
  1513. return;
  1514. }
  1515. #endif
  1516. // DEMO Testing
  1517. bool useOriginalDemo = true;
  1518. if ( useOriginalDemo ) {
  1519. int demolump = W_GetNumForName( ::g->defdemoname );
  1520. int demosize = W_LumpLength( demolump );
  1521. ::g->demobuffer = ::g->demo_p = new byte[ demosize ];
  1522. W_ReadLump( demolump, ::g->demobuffer );
  1523. }
  1524. // DHM - Nerve :: We support old and new demo versions
  1525. demoversion = *::g->demo_p++;
  1526. skill = (skill_t)*::g->demo_p++;
  1527. episode = *::g->demo_p++;
  1528. if ( demoversion == VERSION ) {
  1529. mission = *::g->demo_p++;
  1530. }
  1531. else {
  1532. mission = 0;
  1533. }
  1534. map = *::g->demo_p++;
  1535. ::g->deathmatch = *::g->demo_p++;
  1536. ::g->respawnparm = *::g->demo_p++;
  1537. ::g->fastparm = *::g->demo_p++;
  1538. ::g->nomonsters = *::g->demo_p++;
  1539. ::g->consoleplayer = *::g->demo_p++;
  1540. for ( i=0 ; i<MAXPLAYERS ; i++ ) {
  1541. ::g->playeringame[i] = *::g->demo_p++;
  1542. }
  1543. ::g->netgame = false;
  1544. ::g->netdemo = false;
  1545. if (::g->playeringame[1])
  1546. {
  1547. ::g->netgame = true;
  1548. ::g->netdemo = true;
  1549. }
  1550. // don't spend a lot of time in loadlevel
  1551. ::g->precache = false;
  1552. G_InitNew (skill, episode, map );
  1553. R_SetViewSize (::g->screenblocks + 1, ::g->detailLevel);
  1554. m_inDemoMode.SetBool( true );
  1555. // JAF - Dont show messages when in Demo Mode. ::g->showMessages = false;
  1556. ::g->precache = true;
  1557. // DHM - Nerve :: We now read in the player state from the demo
  1558. if ( demoversion == VERSION ) {
  1559. for ( i=0 ; i<MAXPLAYERS ; i++ ) {
  1560. if ( ::g->playeringame[i] ) {
  1561. int* src = (int *)::g->demo_p;
  1562. ::g->players[i].health = *src++;
  1563. ::g->players[i].mo->health = ::g->players[i].health;
  1564. ::g->players[i].armorpoints = *src++;
  1565. ::g->players[i].armortype = *src++;
  1566. ::g->players[i].readyweapon = (weapontype_t)*src++;
  1567. for ( int j = 0; j < NUMWEAPONS; j++ ) {
  1568. ::g->players[i].weaponowned[j] = *src++;
  1569. }
  1570. for ( int j = 0; j < NUMAMMO; j++ ) {
  1571. ::g->players[i].ammo[j] = *src++;
  1572. ::g->players[i].maxammo[j] = *src++;
  1573. }
  1574. ::g->demo_p = (byte *)src;
  1575. P_SetupPsprites( &::g->players[i] );
  1576. }
  1577. }
  1578. }
  1579. ::g->usergame = false;
  1580. ::g->demoplayback = true;
  1581. }
  1582. //
  1583. // G_TimeDemo
  1584. //
  1585. void G_TimeDemo (char* name)
  1586. {
  1587. ::g->nodrawers = M_CheckParm ("-nodraw");
  1588. ::g->noblit = M_CheckParm ("-noblit");
  1589. ::g->timingdemo = true;
  1590. ::g->singletics = true;
  1591. ::g->defdemoname = name;
  1592. ::g->gameaction = ga_playdemo;
  1593. }
  1594. /*
  1595. ===================
  1596. =
  1597. = G_CheckDemoStatus
  1598. =
  1599. = Called after a death or level completion to allow demos to be cleaned up
  1600. = Returns true if a new demo loop action will take place
  1601. ===================
  1602. */
  1603. qboolean G_CheckDemoStatus (void)
  1604. {
  1605. if (::g->demoplayback)
  1606. {
  1607. delete ::g->demobuffer;
  1608. ::g->demobuffer = NULL;
  1609. ::g->demo_p = NULL;
  1610. ::g->demoend = NULL;
  1611. ::g->demoplayback = false;
  1612. ::g->netdemo = false;
  1613. ::g->netgame = false;
  1614. ::g->deathmatch = false;
  1615. ::g->playeringame[1] = ::g->playeringame[2] = ::g->playeringame[3] = 0;
  1616. ::g->respawnparm = false;
  1617. ::g->fastparm = false;
  1618. ::g->nomonsters = false;
  1619. ::g->consoleplayer = 0;
  1620. D_AdvanceDemo ();
  1621. return true;
  1622. }
  1623. /*
  1624. if (::g->demorecording) {
  1625. *::g->demo_p++ = DEMOMARKER;
  1626. if ( ::g->leveltime > (TICRATE * 9) ) {
  1627. gameLocal->DoomStoreDemoBuffer( gameLocal->GetPortForPlayer( DoomLib::GetPlayer() ), ::g->demobuffer, ::g->demo_p - ::g->demobuffer );
  1628. }
  1629. delete ::g->demobuffer;
  1630. ::g->demobuffer = NULL;
  1631. ::g->demo_p = NULL;
  1632. ::g->demoend = NULL;
  1633. ::g->demorecording = false;
  1634. }
  1635. */
  1636. return false;
  1637. }