wi_stuff.cpp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757
  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_session.h"
  24. #include "sys/sys_signin.h"
  25. #include "DoomLeaderboards.h"
  26. #include "d3xp/Game_Local.h"
  27. #include <stdio.h>
  28. #include "z_zone.h"
  29. #include "m_random.h"
  30. #include "m_swap.h"
  31. #include "i_system.h"
  32. #include "w_wad.h"
  33. #include "g_game.h"
  34. #include "r_local.h"
  35. #include "s_sound.h"
  36. #include "doomstat.h"
  37. // Data.
  38. #include "sounds.h"
  39. // Needs access to LFB.
  40. #include "v_video.h"
  41. #include "wi_stuff.h"
  42. //
  43. // Data needed to add patches to full screen intermission pics.
  44. // Patches are statistics messages, and animations.
  45. // Loads of by-pixel layout and placement, offsets etc.
  46. //
  47. //
  48. // Different vetween registered DOOM (1994) and
  49. // Ultimate DOOM - Final edition (retail, 1995?).
  50. // This is supposedly ignored for commercial
  51. // release (aka DOOM II), which had 34 maps
  52. // in one episode. So there.
  53. // in tics
  54. //U #define PAUSELEN (TICRATE*2)
  55. //U #define SCORESTEP 100
  56. //U #define ANIMPERIOD 32
  57. // pixel distance from "(YOU)" to "PLAYER N"
  58. //U #define STARDIST 10
  59. //U #define WK 1
  60. // GLOBAL LOCATIONS
  61. // SINGPLE-PLAYER STUFF
  62. // NET GAME STUFF
  63. // DEATHMATCH STUFF
  64. //
  65. // Animation.
  66. // There is another anim_t used in p_spec.
  67. //
  68. const point_t lnodes[NUMEPISODES][NUMMAPS] =
  69. {
  70. // Episode 0 World Map
  71. {
  72. { 185, 164 }, // location of level 0 (CJ)
  73. { 148, 143 }, // location of level 1 (CJ)
  74. { 69, 122 }, // location of level 2 (CJ)
  75. { 209, 102 }, // location of level 3 (CJ)
  76. { 116, 89 }, // location of level 4 (CJ)
  77. { 166, 55 }, // location of level 5 (CJ)
  78. { 71, 56 }, // location of level 6 (CJ)
  79. { 135, 29 }, // location of level 7 (CJ)
  80. { 71, 24 } // location of level 8 (CJ)
  81. },
  82. // Episode 1 World Map should go here
  83. {
  84. { 254, 25 }, // location of level 0 (CJ)
  85. { 97, 50 }, // location of level 1 (CJ)
  86. { 188, 64 }, // location of level 2 (CJ)
  87. { 128, 78 }, // location of level 3 (CJ)
  88. { 214, 92 }, // location of level 4 (CJ)
  89. { 133, 130 }, // location of level 5 (CJ)
  90. { 208, 136 }, // location of level 6 (CJ)
  91. { 148, 140 }, // location of level 7 (CJ)
  92. { 235, 158 } // location of level 8 (CJ)
  93. },
  94. // Episode 2 World Map should go here
  95. {
  96. { 156, 168 }, // location of level 0 (CJ)
  97. { 48, 154 }, // location of level 1 (CJ)
  98. { 174, 95 }, // location of level 2 (CJ)
  99. { 265, 75 }, // location of level 3 (CJ)
  100. { 130, 48 }, // location of level 4 (CJ)
  101. { 279, 23 }, // location of level 5 (CJ)
  102. { 198, 48 }, // location of level 6 (CJ)
  103. { 140, 25 }, // location of level 7 (CJ)
  104. { 281, 136 } // location of level 8 (CJ)
  105. }
  106. };
  107. //
  108. // Animation locations for episode 0 (1).
  109. // Using patches saves a lot of space,
  110. // as they replace 320x200 full screen frames.
  111. //
  112. extern const anim_t temp_epsd0animinfo[10];
  113. const anim_t temp_epsd0animinfo[10] =
  114. {
  115. { ANIM_ALWAYS, TICRATE/3, 3, { 224, 104 } },
  116. { ANIM_ALWAYS, TICRATE/3, 3, { 184, 160 } },
  117. { ANIM_ALWAYS, TICRATE/3, 3, { 112, 136 } },
  118. { ANIM_ALWAYS, TICRATE/3, 3, { 72, 112 } },
  119. { ANIM_ALWAYS, TICRATE/3, 3, { 88, 96 } },
  120. { ANIM_ALWAYS, TICRATE/3, 3, { 64, 48 } },
  121. { ANIM_ALWAYS, TICRATE/3, 3, { 192, 40 } },
  122. { ANIM_ALWAYS, TICRATE/3, 3, { 136, 16 } },
  123. { ANIM_ALWAYS, TICRATE/3, 3, { 80, 16 } },
  124. { ANIM_ALWAYS, TICRATE/3, 3, { 64, 24 } }
  125. };
  126. extern const anim_t temp_epsd1animinfo[9];
  127. const anim_t temp_epsd1animinfo[9] =
  128. {
  129. { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 1 },
  130. { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 2 },
  131. { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 3 },
  132. { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 4 },
  133. { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 5 },
  134. { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 6 },
  135. { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 7 },
  136. { ANIM_LEVEL, TICRATE/3, 3, { 192, 144 }, 8 },
  137. { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 8 }
  138. };
  139. extern const anim_t temp_epsd2animinfo[6];
  140. const anim_t temp_epsd2animinfo[6] =
  141. {
  142. { ANIM_ALWAYS, TICRATE/3, 3, { 104, 168 } },
  143. { ANIM_ALWAYS, TICRATE/3, 3, { 40, 136 } },
  144. { ANIM_ALWAYS, TICRATE/3, 3, { 160, 96 } },
  145. { ANIM_ALWAYS, TICRATE/3, 3, { 104, 80 } },
  146. { ANIM_ALWAYS, TICRATE/3, 3, { 120, 32 } },
  147. { ANIM_ALWAYS, TICRATE/4, 3, { 40, 0 } }
  148. };
  149. //
  150. // GENERAL DATA
  151. //
  152. //
  153. // Locally used stuff.
  154. //
  155. // States for single-player
  156. // in seconds
  157. //#define SHOWLASTLOCDELAY SHOWNEXTLOCDELAY
  158. // used to accelerate or skip a stage
  159. // ::g->wbs->pnum
  160. // specifies current ::g->state
  161. // contains information passed into intermission
  162. const wbplayerstruct_t* plrs; // ::g->wbs->plyr[]
  163. // used for general timing
  164. // used for timing of background animation
  165. // signals to refresh everything for one frame
  166. // # of commercial levels
  167. //
  168. // GRAPHICS
  169. //
  170. //
  171. // CODE
  172. //
  173. void localCalculateAchievements(bool epComplete)
  174. {
  175. if( !common->IsMultiplayer() ) {
  176. player_t *player = &::g->players[::g->consoleplayer];
  177. // Calculate Any Achievements earned from stat cumulation.
  178. idAchievementManager::CheckDoomClassicsAchievements( player->killcount, player->itemcount, player->secretcount, ::g->gameskill, ::g->gamemission, ::g->gamemap, ::g->gameepisode, ::g->totalkills, ::g->totalitems, ::g->totalsecret );
  179. }
  180. }
  181. // slam background
  182. // UNUSED static unsigned char *background=0;
  183. void WI_slamBackground(void)
  184. {
  185. memcpy(::g->screens[0], ::g->screens[1], SCREENWIDTH * SCREENHEIGHT);
  186. V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
  187. }
  188. // The ticker is used to detect keys
  189. // because of timing issues in netgames.
  190. qboolean WI_Responder(event_t* ev)
  191. {
  192. return false;
  193. }
  194. // Draws "<Levelname> Finished!"
  195. void WI_drawLF(void)
  196. {
  197. int y = WI_TITLEY;
  198. // draw <LevelName>
  199. V_DrawPatch((ORIGINAL_WIDTH - SHORT(::g->lnames[::g->wbs->last]->width))/2,
  200. y, FB, ::g->lnames[::g->wbs->last]);
  201. // draw "Finished!"
  202. y += (5*SHORT(::g->lnames[::g->wbs->last]->height))/4;
  203. V_DrawPatch((ORIGINAL_WIDTH - SHORT(::g->finished->width))/2,
  204. y, FB, ::g->finished);
  205. }
  206. // Draws "Entering <LevelName>"
  207. void WI_drawEL(void)
  208. {
  209. int y = WI_TITLEY;
  210. // draw "Entering"
  211. V_DrawPatch((ORIGINAL_WIDTH - SHORT(::g->entering->width))/2,
  212. y, FB, ::g->entering);
  213. // draw level
  214. y += (5*SHORT(::g->lnames[::g->wbs->next]->height))/4;
  215. V_DrawPatch((ORIGINAL_WIDTH - SHORT(::g->lnames[::g->wbs->next]->width))/2,
  216. y, FB, ::g->lnames[::g->wbs->next]);
  217. }
  218. void
  219. WI_drawOnLnode
  220. ( int n,
  221. patch_t* c[] )
  222. {
  223. int i;
  224. int left;
  225. int top;
  226. int right;
  227. int bottom;
  228. qboolean fits = false;
  229. i = 0;
  230. do
  231. {
  232. left = lnodes[::g->wbs->epsd][n].x - SHORT(c[i]->leftoffset);
  233. top = lnodes[::g->wbs->epsd][n].y - SHORT(c[i]->topoffset);
  234. right = left + SHORT(c[i]->width);
  235. bottom = top + SHORT(c[i]->height);
  236. if (left >= 0
  237. && right < SCREENWIDTH
  238. && top >= 0
  239. && bottom < SCREENHEIGHT)
  240. {
  241. fits = true;
  242. }
  243. else
  244. {
  245. i++;
  246. }
  247. } while (!fits && i!=2);
  248. if (fits && i<2)
  249. {
  250. V_DrawPatch(lnodes[::g->wbs->epsd][n].x, lnodes[::g->wbs->epsd][n].y,
  251. FB, c[i]);
  252. }
  253. else
  254. {
  255. // DEBUG
  256. I_Printf("Could not place patch on level %d", n+1);
  257. }
  258. }
  259. void WI_initAnimatedBack(void)
  260. {
  261. int i;
  262. anim_t* a;
  263. if (::g->gamemode == commercial)
  264. return;
  265. if (::g->wbs->epsd > 2)
  266. return;
  267. for (i=0;i < ::g->NUMANIMS[::g->wbs->epsd];i++)
  268. {
  269. a = &::g->wi_stuff_anims[::g->wbs->epsd][i];
  270. // init variables
  271. a->ctr = -1;
  272. // specify the next time to draw it
  273. if (a->type == ANIM_ALWAYS)
  274. a->nexttic = ::g->bcnt + 1 + (M_Random()%a->period);
  275. else if (a->type == ANIM_RANDOM)
  276. a->nexttic = ::g->bcnt + 1 + a->data2+(M_Random()%a->data1);
  277. else if (a->type == ANIM_LEVEL)
  278. a->nexttic = ::g->bcnt + 1;
  279. }
  280. }
  281. void WI_updateAnimatedBack(void)
  282. {
  283. int i;
  284. anim_t* a;
  285. if (::g->gamemode == commercial)
  286. return;
  287. if (::g->wbs->epsd > 2)
  288. return;
  289. for (i=0;i < ::g->NUMANIMS[::g->wbs->epsd];i++)
  290. {
  291. a = &::g->wi_stuff_anims[::g->wbs->epsd][i];
  292. if (::g->bcnt == a->nexttic)
  293. {
  294. switch (a->type)
  295. {
  296. case ANIM_ALWAYS:
  297. if (++a->ctr >= a->nanims) a->ctr = 0;
  298. a->nexttic = ::g->bcnt + a->period;
  299. break;
  300. case ANIM_RANDOM:
  301. a->ctr++;
  302. if (a->ctr == a->nanims)
  303. {
  304. a->ctr = -1;
  305. a->nexttic = ::g->bcnt+a->data2+(M_Random()%a->data1);
  306. }
  307. else a->nexttic = ::g->bcnt + a->period;
  308. break;
  309. case ANIM_LEVEL:
  310. // gawd-awful hack for level anims
  311. if (!(::g->state == StatCount && i == 7)
  312. && ::g->wbs->next == a->data1)
  313. {
  314. a->ctr++;
  315. if (a->ctr == a->nanims) a->ctr--;
  316. a->nexttic = ::g->bcnt + a->period;
  317. }
  318. break;
  319. }
  320. }
  321. }
  322. }
  323. void WI_drawAnimatedBack(void)
  324. {
  325. int i;
  326. anim_t* a;
  327. if (commercial)
  328. return;
  329. if (::g->wbs->epsd > 2)
  330. return;
  331. for (i=0 ; i < ::g->NUMANIMS[::g->wbs->epsd] ; i++)
  332. {
  333. a = &::g->wi_stuff_anims[::g->wbs->epsd][i];
  334. if (a->ctr >= 0)
  335. V_DrawPatch(a->loc.x, a->loc.y, FB, a->p[a->ctr]);
  336. }
  337. }
  338. //
  339. // Draws a number.
  340. // If digits > 0, then use that many digits minimum,
  341. // otherwise only use as many as necessary.
  342. // Returns new x position.
  343. //
  344. int
  345. WI_drawNum
  346. ( int x,
  347. int y,
  348. int n,
  349. int digits )
  350. {
  351. int fontwidth = SHORT(::g->num[0]->width);
  352. int neg;
  353. int temp;
  354. if (digits < 0)
  355. {
  356. if (!n)
  357. {
  358. // make variable-length zeros 1 digit long
  359. digits = 1;
  360. }
  361. else
  362. {
  363. // figure out # of digits in #
  364. digits = 0;
  365. temp = n;
  366. while (temp)
  367. {
  368. temp /= 10;
  369. digits++;
  370. }
  371. }
  372. }
  373. neg = n < 0;
  374. if (neg)
  375. n = -n;
  376. // if non-number, do not draw it
  377. if (n == 1994)
  378. return 0;
  379. // draw the new number
  380. while (digits--)
  381. {
  382. x -= fontwidth;
  383. V_DrawPatch(x, y, FB, ::g->num[ n % 10 ]);
  384. n /= 10;
  385. }
  386. // draw a minus sign if necessary
  387. if (neg)
  388. V_DrawPatch(x-=8, y, FB, ::g->wiminus);
  389. return x;
  390. }
  391. void
  392. WI_drawPercent
  393. ( int x,
  394. int y,
  395. int p )
  396. {
  397. if (p < 0)
  398. return;
  399. V_DrawPatch(x, y, FB, ::g->percent);
  400. WI_drawNum(x, y, p, -1);
  401. }
  402. //
  403. // Display level completion time and par,
  404. // or "sucks" message if overflow.
  405. //
  406. void
  407. WI_drawTime
  408. ( int x,
  409. int y,
  410. int t )
  411. {
  412. int div;
  413. int n;
  414. if (t<0)
  415. return;
  416. if (t <= 61*59)
  417. {
  418. div = 1;
  419. do
  420. {
  421. n = (t / div) % 60;
  422. x = WI_drawNum(x, y, n, 2) - SHORT(::g->colon->width);
  423. div *= 60;
  424. // draw
  425. if (div==60 || t / div)
  426. V_DrawPatch(x, y, FB, ::g->colon);
  427. } while (t / div);
  428. }
  429. else
  430. {
  431. // "sucks"
  432. V_DrawPatch(x - SHORT(::g->sucks->width), y, FB, ::g->sucks);
  433. }
  434. }
  435. void WI_End(void)
  436. {
  437. void WI_unloadData(void);
  438. WI_unloadData();
  439. }
  440. void WI_initNoState(void)
  441. {
  442. ::g->state = NoState;
  443. ::g->acceleratestage = 0;
  444. ::g->cnt = 10;
  445. }
  446. void WI_updateNoState(void) {
  447. WI_updateAnimatedBack();
  448. if (!--::g->cnt) {
  449. // Unload data
  450. WI_End();
  451. G_WorldDone();
  452. }
  453. DoomLib::ActivateGame();
  454. }
  455. void WI_initShowNextLoc(void)
  456. {
  457. ::g->state = ShowNextLoc;
  458. ::g->acceleratestage = 0;
  459. ::g->cnt = SHOWNEXTLOCDELAY * TICRATE;
  460. WI_initAnimatedBack();
  461. DoomLib::ActivateGame();
  462. }
  463. void WI_updateShowNextLoc(void)
  464. {
  465. WI_updateAnimatedBack();
  466. if (!--::g->cnt || ::g->acceleratestage) {
  467. WI_initNoState();
  468. DoomLib::ShowXToContinue( false );
  469. } else {
  470. ::g->snl_pointeron = (::g->cnt & 31) < 20;
  471. }
  472. }
  473. void WI_drawShowNextLoc(void)
  474. {
  475. int i;
  476. int last;
  477. WI_slamBackground();
  478. // draw animated background
  479. WI_drawAnimatedBack();
  480. if ( ::g->gamemode != commercial)
  481. {
  482. if (::g->wbs->epsd > 2)
  483. {
  484. WI_drawEL();
  485. return;
  486. }
  487. last = (::g->wbs->last == 8) ? ::g->wbs->next - 1 : ::g->wbs->last;
  488. // don't draw any splats for extra secret levels
  489. if( last == 9 ) {
  490. for (i=0 ; i<MAXPLAYERS ; i++) {
  491. ::g->players[i].didsecret = false;
  492. }
  493. ::g->wbs->didsecret = false;
  494. last = -1;
  495. }
  496. // draw a splat on taken cities.
  497. for (i=0 ; i<=last ; i++)
  498. WI_drawOnLnode(i, &::g->splat);
  499. // splat the secret level?
  500. if (::g->wbs->didsecret)
  501. WI_drawOnLnode(8, &::g->splat);
  502. // draw flashing ptr
  503. if (::g->snl_pointeron)
  504. WI_drawOnLnode(::g->wbs->next, ::g->yah);
  505. }
  506. // draws which level you are entering..
  507. if ( (::g->gamemode != commercial)
  508. || ::g->wbs->next != 30)
  509. WI_drawEL();
  510. }
  511. void WI_drawNoState(void)
  512. {
  513. ::g->snl_pointeron = true;
  514. WI_drawShowNextLoc();
  515. }
  516. int WI_fragSum(int playernum)
  517. {
  518. int i;
  519. int frags = 0;
  520. for (i=0 ; i<MAXPLAYERS ; i++)
  521. {
  522. if (/*::g->playeringame[i] &&*/ i!=playernum)
  523. {
  524. frags += plrs[playernum].frags[i];
  525. }
  526. }
  527. // JDC hack - negative frags.
  528. frags -= plrs[playernum].frags[playernum];
  529. // UNUSED if (frags < 0)
  530. // frags = 0;
  531. return frags;
  532. }
  533. int WI_fragOnlySum(int playernum)
  534. {
  535. int i;
  536. int frags = 0;
  537. for (i=0 ; i<MAXPLAYERS ; i++)
  538. {
  539. if (/*::g->playeringame[i] &&*/ i!=playernum)
  540. {
  541. frags += plrs[playernum].frags[i];
  542. }
  543. }
  544. return frags;
  545. }
  546. int WI_deathSum(int playernum)
  547. {
  548. int i;
  549. int deaths = 0;
  550. for (i=0 ; i<MAXPLAYERS ; i++)
  551. {
  552. if ( 1 /*::g->playeringame[i]*/)
  553. {
  554. deaths += plrs[i].frags[playernum];
  555. }
  556. }
  557. return deaths;
  558. }
  559. void WI_initDeathmatchStats(void)
  560. {
  561. int i;
  562. int j;
  563. ::g->state = StatCount;
  564. ::g->acceleratestage = 0;
  565. ::g->dm_state = 1;
  566. ::g->cnt_pause = TICRATE;
  567. for (i=0 ; i<MAXPLAYERS ; i++)
  568. {
  569. if (::g->playeringame[i])
  570. {
  571. for (j=0 ; j<MAXPLAYERS ; j++)
  572. if (::g->playeringame[j])
  573. ::g->dm_frags[i][j] = 0;
  574. ::g->dm_totals[i] = 0;
  575. }
  576. }
  577. WI_initAnimatedBack();
  578. if ( common->IsMultiplayer() ) {
  579. localCalculateAchievements(false);
  580. /* JAF PS3
  581. gameLocal->liveSession.GetDMSession().SetEndOfMatchStats();
  582. gameLocal->liveSession.GetDMSession().WriteTrueskill();
  583. // Write stats
  584. if ( gameLocal->liveSession.IsHost( ::g->consoleplayer ) ) {
  585. gameLocal->liveSession.GetDMSession().BeginEndLevel();
  586. }
  587. */
  588. }
  589. DoomLib::ShowXToContinue( true );
  590. }
  591. void WI_updateDeathmatchStats(void)
  592. {
  593. int i;
  594. int j;
  595. qboolean stillticking;
  596. WI_updateAnimatedBack();
  597. if (::g->acceleratestage && ::g->dm_state != 4)
  598. {
  599. ::g->acceleratestage = 0;
  600. for (i=0 ; i<MAXPLAYERS ; i++)
  601. {
  602. if (::g->playeringame[i])
  603. {
  604. for (j=0 ; j<MAXPLAYERS ; j++)
  605. if (::g->playeringame[j])
  606. ::g->dm_frags[i][j] = plrs[i].frags[j];
  607. ::g->dm_totals[i] = WI_fragSum(i);
  608. }
  609. }
  610. S_StartSound(0, sfx_barexp);
  611. ::g->dm_state = 4;
  612. }
  613. if (::g->dm_state == 2)
  614. {
  615. if (!(::g->bcnt&3))
  616. S_StartSound(0, sfx_pistol);
  617. stillticking = false;
  618. for (i=0 ; i<MAXPLAYERS ; i++)
  619. {
  620. if (::g->playeringame[i])
  621. {
  622. for (j=0 ; j<MAXPLAYERS ; j++)
  623. {
  624. if (::g->playeringame[j]
  625. && ::g->dm_frags[i][j] != plrs[i].frags[j])
  626. {
  627. if (plrs[i].frags[j] < 0)
  628. ::g->dm_frags[i][j]--;
  629. else
  630. ::g->dm_frags[i][j]++;
  631. if (::g->dm_frags[i][j] > 99)
  632. ::g->dm_frags[i][j] = 99;
  633. if (::g->dm_frags[i][j] < -99)
  634. ::g->dm_frags[i][j] = -99;
  635. stillticking = true;
  636. }
  637. }
  638. ::g->dm_totals[i] = WI_fragSum(i);
  639. if (::g->dm_totals[i] > 99)
  640. ::g->dm_totals[i] = 99;
  641. if (::g->dm_totals[i] < -99)
  642. ::g->dm_totals[i] = -99;
  643. }
  644. }
  645. if (!stillticking)
  646. {
  647. S_StartSound(0, sfx_barexp);
  648. ::g->dm_state++;
  649. }
  650. }
  651. else if (::g->dm_state == 4)
  652. {
  653. if (::g->acceleratestage)
  654. {
  655. if ( !::g->demoplayback && ( ::g->usergame || ::g->netgame ) ) {
  656. // This sound plays repeatedly after a player continues at the end of a deathmatch,
  657. // and sounds bad. Quick fix is to just not play it.
  658. //S_StartSound(0, sfx_slop);
  659. DoomLib::HandleEndMatch();
  660. }
  661. }
  662. }
  663. else if (::g->dm_state & 1)
  664. {
  665. if (!--::g->cnt_pause)
  666. {
  667. ::g->dm_state++;
  668. ::g->cnt_pause = TICRATE;
  669. }
  670. }
  671. }
  672. void WI_drawDeathmatchStats(void)
  673. {
  674. int i;
  675. int j;
  676. int x;
  677. int y;
  678. int w;
  679. int lh; // line height
  680. lh = WI_SPACINGY;
  681. WI_slamBackground();
  682. // draw animated background
  683. WI_drawAnimatedBack();
  684. WI_drawLF();
  685. // draw stat titles (top line)
  686. V_DrawPatch(DM_TOTALSX-SHORT(::g->total->width)/2,
  687. DM_MATRIXY-WI_SPACINGY+10,
  688. FB,
  689. ::g->total);
  690. V_DrawPatch(DM_KILLERSX, DM_KILLERSY, FB, ::g->killers);
  691. V_DrawPatch(DM_VICTIMSX, DM_VICTIMSY, FB, ::g->victims);
  692. // draw P?
  693. x = DM_MATRIXX + DM_SPACINGX;
  694. y = DM_MATRIXY;
  695. for (i=0 ; i<MAXPLAYERS ; i++)
  696. {
  697. if (::g->playeringame[i])
  698. {
  699. V_DrawPatch(x-SHORT(::g->wistuff_p[i]->width)/2,
  700. DM_MATRIXY - WI_SPACINGY,
  701. FB,
  702. ::g->wistuff_p[i]);
  703. V_DrawPatch(DM_MATRIXX-SHORT(::g->wistuff_p[i]->width)/2,
  704. y,
  705. FB,
  706. ::g->wistuff_p[i]);
  707. // No splitscreen on PC currently
  708. if (i == ::g->me /* && !gameLocal->IsSplitscreen() */ )
  709. {
  710. V_DrawPatch(x-SHORT(::g->wistuff_p[i]->width)/2,
  711. DM_MATRIXY - WI_SPACINGY,
  712. FB,
  713. ::g->bstar);
  714. V_DrawPatch(DM_MATRIXX-SHORT(::g->wistuff_p[i]->width)/2,
  715. y,
  716. FB,
  717. ::g->star);
  718. }
  719. }
  720. else
  721. {
  722. //V_DrawPatch(x-SHORT(::g->wistuff_bp[i]->width)/2,
  723. // DM_MATRIXY - WI_SPACINGY, FB, ::g->wistuff_bp[i]);
  724. //V_DrawPatch(DM_MATRIXX-SHORT(::g->wistuff_bp[i]->width)/2,
  725. // y, FB, ::g->wistuff_bp[i]);
  726. }
  727. x += DM_SPACINGX;
  728. y += WI_SPACINGY;
  729. }
  730. // draw stats
  731. y = DM_MATRIXY+10;
  732. w = SHORT(::g->num[0]->width);
  733. for (i=0 ; i<MAXPLAYERS ; i++)
  734. {
  735. x = DM_MATRIXX + DM_SPACINGX;
  736. if (::g->playeringame[i])
  737. {
  738. for (j=0 ; j<MAXPLAYERS ; j++)
  739. {
  740. if (::g->playeringame[j])
  741. WI_drawNum(x+w, y, ::g->dm_frags[i][j], 2);
  742. x += DM_SPACINGX;
  743. }
  744. WI_drawNum(DM_TOTALSX+w, y, ::g->dm_totals[i], 2);
  745. }
  746. y += WI_SPACINGY;
  747. }
  748. }
  749. void WI_initNetgameStats(void)
  750. {
  751. int i;
  752. ::g->state = StatCount;
  753. ::g->acceleratestage = 0;
  754. ::g->ng_state = 1;
  755. ::g->cnt_pause = TICRATE;
  756. for (i=0 ; i<MAXPLAYERS ; i++)
  757. {
  758. if (!::g->playeringame[i])
  759. continue;
  760. ::g->cnt_kills[i] = ::g->cnt_items[i] = ::g->cnt_secret[i] = ::g->cnt_frags[i] = 0;
  761. ::g->dofrags += WI_fragSum(i);
  762. }
  763. ::g->dofrags = !!::g->dofrags;
  764. WI_initAnimatedBack();
  765. // JAF PS3
  766. /*
  767. if ( gameLocal->IsMultiplayer() ) {
  768. if(gameLocal->IsFullVersion() && gameLocal->liveSession.IsHost( ::g->consoleplayer )) {
  769. bool endOfMission = false;
  770. if ( ::g->gamemission == 0 && ::g->gamemap == 30 ) {
  771. endOfMission = true;
  772. }
  773. else if ( ::g->gamemission > 0 && ::g->gamemap == 8 ) {
  774. endOfMission = true;
  775. }
  776. gameLocal->liveSession.GetCoopSession().BeginEndLevel( endOfMission );
  777. }
  778. }
  779. */
  780. DoomLib::ShowXToContinue( true );
  781. }
  782. void WI_updateNetgameStats(void)
  783. {
  784. int i;
  785. int fsum;
  786. qboolean stillticking;
  787. WI_updateAnimatedBack();
  788. if (::g->acceleratestage && ::g->ng_state != 10)
  789. {
  790. ::g->acceleratestage = 0;
  791. for (i=0 ; i<MAXPLAYERS ; i++)
  792. {
  793. if (!::g->playeringame[i])
  794. continue;
  795. ::g->cnt_kills[i] = (plrs[i].skills * 100) / ::g->wbs->maxkills;
  796. ::g->cnt_items[i] = (plrs[i].sitems * 100) / ::g->wbs->maxitems;
  797. ::g->cnt_secret[i] = (plrs[i].ssecret * 100) / ::g->wbs->maxsecret;
  798. if (::g->dofrags)
  799. ::g->cnt_frags[i] = WI_fragSum(i);
  800. }
  801. S_StartSound(0, sfx_barexp);
  802. ::g->ng_state = 10;
  803. }
  804. if (::g->ng_state == 2)
  805. {
  806. if (!(::g->bcnt&3))
  807. S_StartSound(0, sfx_pistol);
  808. stillticking = false;
  809. for (i=0 ; i<MAXPLAYERS ; i++)
  810. {
  811. if (!::g->playeringame[i])
  812. continue;
  813. ::g->cnt_kills[i] += 2;
  814. if (::g->cnt_kills[i] >= (plrs[i].skills * 100) / ::g->wbs->maxkills)
  815. ::g->cnt_kills[i] = (plrs[i].skills * 100) / ::g->wbs->maxkills;
  816. else
  817. stillticking = true;
  818. }
  819. if (!stillticking)
  820. {
  821. S_StartSound(0, sfx_barexp);
  822. ::g->ng_state++;
  823. }
  824. }
  825. else if (::g->ng_state == 4)
  826. {
  827. if (!(::g->bcnt&3))
  828. S_StartSound(0, sfx_pistol);
  829. stillticking = false;
  830. for (i=0 ; i<MAXPLAYERS ; i++)
  831. {
  832. if (!::g->playeringame[i])
  833. continue;
  834. ::g->cnt_items[i] += 2;
  835. if (::g->cnt_items[i] >= (plrs[i].sitems * 100) / ::g->wbs->maxitems)
  836. ::g->cnt_items[i] = (plrs[i].sitems * 100) / ::g->wbs->maxitems;
  837. else
  838. stillticking = true;
  839. }
  840. if (!stillticking)
  841. {
  842. S_StartSound(0, sfx_barexp);
  843. ::g->ng_state++;
  844. }
  845. }
  846. else if (::g->ng_state == 6)
  847. {
  848. if (!(::g->bcnt&3))
  849. S_StartSound(0, sfx_pistol);
  850. stillticking = false;
  851. for (i=0 ; i<MAXPLAYERS ; i++)
  852. {
  853. if (!::g->playeringame[i])
  854. continue;
  855. ::g->cnt_secret[i] += 2;
  856. if (::g->cnt_secret[i] >= (plrs[i].ssecret * 100) / ::g->wbs->maxsecret)
  857. ::g->cnt_secret[i] = (plrs[i].ssecret * 100) / ::g->wbs->maxsecret;
  858. else
  859. stillticking = true;
  860. }
  861. if (!stillticking)
  862. {
  863. S_StartSound(0, sfx_barexp);
  864. ::g->ng_state += 1 + 2*!::g->dofrags;
  865. }
  866. }
  867. else if (::g->ng_state == 8)
  868. {
  869. if (!(::g->bcnt&3))
  870. S_StartSound(0, sfx_pistol);
  871. stillticking = false;
  872. for (i=0 ; i<MAXPLAYERS ; i++)
  873. {
  874. if (!::g->playeringame[i])
  875. continue;
  876. ::g->cnt_frags[i] += 1;
  877. if (::g->cnt_frags[i] >= (fsum = WI_fragSum(i)))
  878. ::g->cnt_frags[i] = fsum;
  879. else
  880. stillticking = true;
  881. }
  882. if (!stillticking)
  883. {
  884. S_StartSound(0, sfx_pldeth);
  885. ::g->ng_state++;
  886. }
  887. }
  888. else if (::g->ng_state == 10)
  889. {
  890. if (::g->acceleratestage)
  891. {
  892. if ( !::g->demoplayback && ( ::g->usergame || ::g->netgame ) ) {
  893. S_StartSound(0, sfx_sgcock);
  894. // need to do this again if they buy it
  895. localCalculateAchievements(false);
  896. if (::g->gamemode == commercial){
  897. WI_initNoState();
  898. DoomLib::ShowXToContinue( false );
  899. }
  900. else{
  901. WI_initShowNextLoc();
  902. }
  903. }
  904. }
  905. }
  906. else if (::g->ng_state & 1)
  907. {
  908. if (!--::g->cnt_pause)
  909. {
  910. ::g->ng_state++;
  911. ::g->cnt_pause = TICRATE;
  912. }
  913. }
  914. }
  915. void WI_drawNetgameStats(void)
  916. {
  917. int i;
  918. int x;
  919. int y;
  920. int pwidth = SHORT(::g->percent->width);
  921. WI_slamBackground();
  922. // draw animated background
  923. WI_drawAnimatedBack();
  924. WI_drawLF();
  925. // draw stat titles (top line)
  926. V_DrawPatch(NG_STATSX+NG_SPACINGX-SHORT(::g->kills->width),
  927. NG_STATSY, FB, ::g->kills);
  928. V_DrawPatch(NG_STATSX+2*NG_SPACINGX-SHORT(::g->items->width),
  929. NG_STATSY, FB, ::g->items);
  930. V_DrawPatch(NG_STATSX+3*NG_SPACINGX-SHORT(::g->secret->width),
  931. NG_STATSY, FB, ::g->secret);
  932. if (::g->dofrags)
  933. V_DrawPatch(NG_STATSX+4*NG_SPACINGX-SHORT(::g->wistuff_frags->width),
  934. NG_STATSY, FB, ::g->wistuff_frags);
  935. // draw stats
  936. y = NG_STATSY + SHORT(::g->kills->height);
  937. for (i=0 ; i<MAXPLAYERS ; i++)
  938. {
  939. if (!::g->playeringame[i])
  940. continue;
  941. x = NG_STATSX;
  942. V_DrawPatch(x-SHORT(::g->wistuff_p[i]->width), y, FB, ::g->wistuff_p[i]);
  943. // No splitscreen on PC
  944. if (i == ::g->me /* && !gameLocal->IsSplitscreen() */ )
  945. V_DrawPatch(x-SHORT(::g->wistuff_p[i]->width), y, FB, ::g->star);
  946. x += NG_SPACINGX;
  947. WI_drawPercent(x-pwidth, y+10, ::g->cnt_kills[i]); x += NG_SPACINGX;
  948. WI_drawPercent(x-pwidth, y+10, ::g->cnt_items[i]); x += NG_SPACINGX;
  949. WI_drawPercent(x-pwidth, y+10, ::g->cnt_secret[i]); x += NG_SPACINGX;
  950. if (::g->dofrags)
  951. WI_drawNum(x, y+10, ::g->cnt_frags[i], -1);
  952. y += WI_SPACINGY;
  953. }
  954. }
  955. void WI_initStats(void)
  956. {
  957. ::g->state = StatCount;
  958. ::g->acceleratestage = 0;
  959. ::g->sp_state = 1;
  960. ::g->cnt_kills[0] = ::g->cnt_items[0] = ::g->cnt_secret[0] = -1;
  961. ::g->cnt_time = ::g->cnt_par = -1;
  962. ::g->cnt_pause = TICRATE;
  963. WI_initAnimatedBack();
  964. DoomLib::ShowXToContinue( true );
  965. }
  966. void WI_updateStats(void)
  967. {
  968. WI_updateAnimatedBack();
  969. if (::g->acceleratestage && ::g->sp_state != 10)
  970. {
  971. ::g->acceleratestage = 0;
  972. ::g->cnt_kills[0] = (plrs[::g->me].skills * 100) / ::g->wbs->maxkills;
  973. ::g->cnt_items[0] = (plrs[::g->me].sitems * 100) / ::g->wbs->maxitems;
  974. ::g->cnt_secret[0] = (plrs[::g->me].ssecret * 100) / ::g->wbs->maxsecret;
  975. ::g->cnt_time = plrs[::g->me].stime / TICRATE;
  976. ::g->cnt_par = ::g->wbs->partime / TICRATE;
  977. S_StartSound(0, sfx_barexp);
  978. ::g->sp_state = 10;
  979. }
  980. if (::g->sp_state == 2)
  981. {
  982. ::g->cnt_kills[0] += 2;
  983. if (!(::g->bcnt&3))
  984. S_StartSound(0, sfx_pistol);
  985. if (::g->cnt_kills[0] >= (plrs[::g->me].skills * 100) / ::g->wbs->maxkills)
  986. {
  987. ::g->cnt_kills[0] = (plrs[::g->me].skills * 100) / ::g->wbs->maxkills;
  988. S_StartSound(0, sfx_barexp);
  989. ::g->sp_state++;
  990. }
  991. }
  992. else if (::g->sp_state == 4)
  993. {
  994. ::g->cnt_items[0] += 2;
  995. if (!(::g->bcnt&3))
  996. S_StartSound(0, sfx_pistol);
  997. if (::g->cnt_items[0] >= (plrs[::g->me].sitems * 100) / ::g->wbs->maxitems)
  998. {
  999. ::g->cnt_items[0] = (plrs[::g->me].sitems * 100) / ::g->wbs->maxitems;
  1000. S_StartSound(0, sfx_barexp);
  1001. ::g->sp_state++;
  1002. }
  1003. }
  1004. else if (::g->sp_state == 6)
  1005. {
  1006. ::g->cnt_secret[0] += 2;
  1007. if (!(::g->bcnt&3))
  1008. S_StartSound(0, sfx_pistol);
  1009. if (::g->cnt_secret[0] >= (plrs[::g->me].ssecret * 100) / ::g->wbs->maxsecret)
  1010. {
  1011. ::g->cnt_secret[0] = (plrs[::g->me].ssecret * 100) / ::g->wbs->maxsecret;
  1012. S_StartSound(0, sfx_barexp);
  1013. ::g->sp_state++;
  1014. }
  1015. }
  1016. else if (::g->sp_state == 8)
  1017. {
  1018. if (!(::g->bcnt&3))
  1019. S_StartSound(0, sfx_pistol);
  1020. ::g->cnt_time += 3;
  1021. if (::g->cnt_time >= plrs[::g->me].stime / TICRATE)
  1022. ::g->cnt_time = plrs[::g->me].stime / TICRATE;
  1023. ::g->cnt_par += 3;
  1024. if (::g->cnt_par >= ::g->wbs->partime / TICRATE)
  1025. {
  1026. ::g->cnt_par = ::g->wbs->partime / TICRATE;
  1027. if (::g->cnt_time >= plrs[::g->me].stime / TICRATE)
  1028. {
  1029. S_StartSound(0, sfx_barexp);
  1030. ::g->sp_state++;
  1031. }
  1032. }
  1033. }
  1034. else if (::g->sp_state == 10)
  1035. {
  1036. if (::g->acceleratestage)
  1037. {
  1038. if ( !::g->demoplayback && ( ::g->usergame || ::g->netgame ) ) {
  1039. S_StartSound(0, sfx_sgcock);
  1040. // need to do this again if they buy it
  1041. localCalculateAchievements(false);
  1042. if (::g->gamemode == commercial) {
  1043. WI_initNoState();
  1044. }
  1045. else{
  1046. WI_initShowNextLoc();
  1047. }
  1048. }
  1049. }
  1050. }
  1051. else if (::g->sp_state & 1)
  1052. {
  1053. if (!--::g->cnt_pause)
  1054. {
  1055. ::g->sp_state++;
  1056. ::g->cnt_pause = TICRATE;
  1057. }
  1058. }
  1059. }
  1060. void WI_drawStats(void)
  1061. {
  1062. // line height
  1063. int lh;
  1064. lh = (3*SHORT(::g->num[0]->height))/2;
  1065. WI_slamBackground();
  1066. // draw animated background
  1067. WI_drawAnimatedBack();
  1068. WI_drawLF();
  1069. V_DrawPatch(SP_STATSX, SP_STATSY, FB, ::g->kills);
  1070. WI_drawPercent(ORIGINAL_WIDTH - SP_STATSX, SP_STATSY, ::g->cnt_kills[0]);
  1071. V_DrawPatch(SP_STATSX, SP_STATSY+lh, FB, ::g->items);
  1072. WI_drawPercent(ORIGINAL_WIDTH - SP_STATSX, SP_STATSY+lh, ::g->cnt_items[0]);
  1073. V_DrawPatch(SP_STATSX, SP_STATSY+2*lh, FB, ::g->sp_secret);
  1074. WI_drawPercent(ORIGINAL_WIDTH - SP_STATSX, SP_STATSY+2*lh, ::g->cnt_secret[0]);
  1075. V_DrawPatch(SP_TIMEX, SP_TIMEY, FB, ::g->time);
  1076. WI_drawTime(ORIGINAL_WIDTH/2 - SP_TIMEX, SP_TIMEY, ::g->cnt_time);
  1077. // DHM - Nerve :: Added episode 4 par times
  1078. //if (::g->wbs->epsd < 3)
  1079. //{
  1080. V_DrawPatch(ORIGINAL_WIDTH/2 + SP_TIMEX, SP_TIMEY, FB, ::g->par);
  1081. WI_drawTime(ORIGINAL_WIDTH - SP_TIMEX, SP_TIMEY, ::g->cnt_par);
  1082. //}
  1083. }
  1084. void WI_checkForAccelerate(void)
  1085. {
  1086. int i;
  1087. player_t *player;
  1088. // check for button presses to skip delays
  1089. for (i=0, player = ::g->players ; i<MAXPLAYERS ; i++, player++)
  1090. {
  1091. if (::g->playeringame[i])
  1092. {
  1093. if (player->cmd.buttons & BT_ATTACK)
  1094. {
  1095. if (!player->attackdown) {
  1096. ::g->acceleratestage = 1;
  1097. }
  1098. player->attackdown = true;
  1099. } else {
  1100. player->attackdown = false;
  1101. }
  1102. if (player->cmd.buttons & BT_USE)
  1103. {
  1104. if (!player->usedown) {
  1105. ::g->acceleratestage = 1;
  1106. }
  1107. player->usedown = true;
  1108. } else {
  1109. player->usedown = false;
  1110. }
  1111. }
  1112. }
  1113. }
  1114. // Updates stuff each tick
  1115. void WI_Ticker(void)
  1116. {
  1117. // counter for general background animation
  1118. ::g->bcnt++;
  1119. if (::g->bcnt == 1)
  1120. {
  1121. // intermission music
  1122. if ( ::g->gamemode == commercial )
  1123. S_ChangeMusic(mus_dm2int, true);
  1124. else
  1125. S_ChangeMusic(mus_inter, true);
  1126. }
  1127. WI_checkForAccelerate();
  1128. switch (::g->state)
  1129. {
  1130. case StatCount:
  1131. if (::g->deathmatch) WI_updateDeathmatchStats();
  1132. else if (::g->netgame) WI_updateNetgameStats();
  1133. else WI_updateStats();
  1134. break;
  1135. case ShowNextLoc:
  1136. WI_updateShowNextLoc();
  1137. break;
  1138. case NoState:
  1139. WI_updateNoState();
  1140. break;
  1141. }
  1142. }
  1143. void WI_loadData(void)
  1144. {
  1145. int i;
  1146. int j;
  1147. char name[9];
  1148. anim_t* a;
  1149. if (::g->gamemode == commercial)
  1150. strcpy(name, "INTERPIC");
  1151. // DHM - Nerve :: Use our background image
  1152. //strcpy(name, "DMENUPIC");
  1153. else
  1154. sprintf(name, "WIMAP%d", ::g->wbs->epsd);
  1155. if ( ::g->gamemode == retail )
  1156. {
  1157. if (::g->wbs->epsd == 3)
  1158. strcpy(name,"INTERPIC");
  1159. }
  1160. // background
  1161. ::g->bg = (patch_t*)W_CacheLumpName(name, PU_LEVEL_SHARED);
  1162. V_DrawPatch(0, 0, 1, ::g->bg);
  1163. // UNUSED unsigned char *pic = ::g->screens[1];
  1164. // if (::g->gamemode == commercial)
  1165. // {
  1166. // darken the background image
  1167. // while (pic != ::g->screens[1] + SCREENHEIGHT*SCREENWIDTH)
  1168. // {
  1169. // *pic = ::g->colormaps[256*25 + *pic];
  1170. // pic++;
  1171. // }
  1172. //}
  1173. if (::g->gamemode == commercial)
  1174. {
  1175. ::g->NUMCMAPS = 32;
  1176. ::g->lnames = (patch_t **) DoomLib::Z_Malloc(sizeof(patch_t*) * ::g->NUMCMAPS, PU_LEVEL_SHARED, 0);
  1177. for (i=0 ; i < ::g->NUMCMAPS ; i++)
  1178. {
  1179. sprintf(name, "CWILV%2.2d", i);
  1180. ::g->lnames[i] = (patch_t*)W_CacheLumpName(name, PU_LEVEL_SHARED);
  1181. }
  1182. }
  1183. else
  1184. {
  1185. ::g->lnames = (patch_t **) DoomLib::Z_Malloc(sizeof(patch_t*) * ( NUMMAPS ), PU_LEVEL_SHARED, 0);
  1186. for (i=0 ; i<NUMMAPS ; i++)
  1187. {
  1188. sprintf(name, "WILV%d%d", ::g->wbs->epsd, i);
  1189. ::g->lnames[i] = (patch_t*)W_CacheLumpName(name, PU_LEVEL_SHARED);
  1190. }
  1191. // you are here
  1192. ::g->yah[0] = (patch_t*)W_CacheLumpName("WIURH0", PU_LEVEL_SHARED);
  1193. // you are here (alt.)
  1194. ::g->yah[1] = (patch_t*)W_CacheLumpName("WIURH1", PU_LEVEL_SHARED);
  1195. // splat
  1196. ::g->splat = (patch_t*)W_CacheLumpName("WISPLAT", PU_LEVEL_SHARED);
  1197. if (::g->wbs->epsd < 3)
  1198. {
  1199. for (j=0;j < ::g->NUMANIMS[::g->wbs->epsd];j++)
  1200. {
  1201. a = &::g->wi_stuff_anims[::g->wbs->epsd][j];
  1202. for (i=0;i<a->nanims;i++)
  1203. {
  1204. // MONDO HACK!
  1205. if (::g->wbs->epsd != 1 || j != 8)
  1206. {
  1207. // animations
  1208. sprintf(name, "WIA%d%.2d%.2d", ::g->wbs->epsd, j, i);
  1209. a->p[i] = (patch_t*)W_CacheLumpName(name, PU_LEVEL_SHARED);
  1210. }
  1211. else
  1212. {
  1213. // HACK ALERT!
  1214. a->p[i] = ::g->wi_stuff_anims[1][4].p[i];
  1215. }
  1216. }
  1217. }
  1218. }
  1219. }
  1220. // More hacks on minus sign.
  1221. ::g->wiminus = (patch_t*)W_CacheLumpName("WIMINUS", PU_LEVEL_SHARED);
  1222. for (i=0;i<10;i++)
  1223. {
  1224. // numbers 0-9
  1225. sprintf(name, "WINUM%d", i);
  1226. ::g->num[i] = (patch_t*)W_CacheLumpName(name, PU_LEVEL_SHARED);
  1227. }
  1228. // percent sign
  1229. ::g->percent = (patch_t*)W_CacheLumpName("WIPCNT", PU_LEVEL_SHARED);
  1230. // "finished"
  1231. ::g->finished = (patch_t*)W_CacheLumpName("WIF", PU_LEVEL_SHARED);
  1232. // "entering"
  1233. ::g->entering = (patch_t*)W_CacheLumpName("WIENTER", PU_LEVEL_SHARED);
  1234. // "kills"
  1235. ::g->kills = (patch_t*)W_CacheLumpName("WIOSTK", PU_LEVEL_SHARED);
  1236. // "scrt"
  1237. ::g->secret = (patch_t*)W_CacheLumpName("WIOSTS", PU_LEVEL_SHARED);
  1238. // "secret"
  1239. ::g->sp_secret = (patch_t*)W_CacheLumpName("WISCRT2", PU_LEVEL_SHARED);
  1240. ::g->items = (patch_t*)W_CacheLumpName("WIOSTI", PU_LEVEL_SHARED);
  1241. // "frgs"
  1242. ::g->wistuff_frags = (patch_t*)W_CacheLumpName("WIFRGS", PU_LEVEL_SHARED);
  1243. // ":"
  1244. ::g->colon = (patch_t*)W_CacheLumpName("WICOLON", PU_LEVEL_SHARED);
  1245. // "time"
  1246. ::g->time = (patch_t*)W_CacheLumpName("WITIME", PU_LEVEL_SHARED);
  1247. // "sucks"
  1248. ::g->sucks = (patch_t*)W_CacheLumpName("WISUCKS", PU_LEVEL_SHARED);
  1249. // "par"
  1250. ::g->par = (patch_t*)W_CacheLumpName("WIPAR", PU_LEVEL_SHARED);
  1251. // "killers" (vertical)
  1252. ::g->killers = (patch_t*)W_CacheLumpName("WIKILRS", PU_LEVEL_SHARED);
  1253. // "victims" (horiz)
  1254. ::g->victims = (patch_t*)W_CacheLumpName("WIVCTMS", PU_LEVEL_SHARED);
  1255. // "total"
  1256. ::g->total = (patch_t*)W_CacheLumpName("WIMSTT", PU_LEVEL_SHARED);
  1257. // your face
  1258. ::g->star = (patch_t*)W_CacheLumpName("STFST01", PU_STATIC_SHARED); // ALAN: this is statically in the game...
  1259. // dead face
  1260. ::g->bstar = (patch_t*)W_CacheLumpName("STFDEAD0", PU_STATIC_SHARED);
  1261. for (i=0 ; i<MAXPLAYERS ; i++)
  1262. {
  1263. // "1,2,3,4"
  1264. sprintf(name, "STPB%d", i);
  1265. ::g->wistuff_p[i] = (patch_t*)W_CacheLumpName(name, PU_LEVEL_SHARED);
  1266. // "1,2,3,4"
  1267. sprintf(name, "WIBP%d", i+1);
  1268. ::g->wistuff_bp[i] = (patch_t*)W_CacheLumpName(name, PU_LEVEL_SHARED);
  1269. }
  1270. }
  1271. void WI_unloadData(void)
  1272. {
  1273. Z_FreeTags( PU_LEVEL_SHARED, PU_LEVEL_SHARED );
  1274. // HACK ALERT - reset these to help stability? they are used for consistency checking
  1275. for (int i=0 ; i<MAXPLAYERS ; i++)
  1276. {
  1277. if (::g->playeringame[i])
  1278. {
  1279. ::g->players[i].mo = NULL;
  1280. }
  1281. }
  1282. ::g->bg = NULL;
  1283. }
  1284. void WI_Drawer (void)
  1285. {
  1286. switch (::g->state)
  1287. {
  1288. case StatCount:
  1289. if (::g->deathmatch)
  1290. WI_drawDeathmatchStats();
  1291. else if (::g->netgame)
  1292. WI_drawNetgameStats();
  1293. else
  1294. WI_drawStats();
  1295. break;
  1296. case ShowNextLoc:
  1297. WI_drawShowNextLoc();
  1298. break;
  1299. case NoState:
  1300. WI_drawNoState();
  1301. break;
  1302. }
  1303. }
  1304. void WI_initVariables(wbstartstruct_t* wbstartstruct)
  1305. {
  1306. ::g->wbs = wbstartstruct;
  1307. #ifdef RANGECHECKING
  1308. if (::g->gamemode != commercial)
  1309. {
  1310. if ( ::g->gamemode == retail )
  1311. RNGCHECK(::g->wbs->epsd, 0, 3);
  1312. else
  1313. RNGCHECK(::g->wbs->epsd, 0, 2);
  1314. }
  1315. else
  1316. {
  1317. RNGCHECK(::g->wbs->last, 0, 8);
  1318. RNGCHECK(::g->wbs->next, 0, 8);
  1319. }
  1320. RNGCHECK(::g->wbs->pnum, 0, MAXPLAYERS);
  1321. RNGCHECK(::g->wbs->pnum, 0, MAXPLAYERS);
  1322. #endif
  1323. ::g->acceleratestage = 0;
  1324. ::g->cnt = ::g->bcnt = 0;
  1325. ::g->firstrefresh = 1;
  1326. ::g->me = ::g->wbs->pnum;
  1327. plrs = ::g->wbs->plyr;
  1328. if (!::g->wbs->maxkills)
  1329. ::g->wbs->maxkills = 1;
  1330. if (!::g->wbs->maxitems)
  1331. ::g->wbs->maxitems = 1;
  1332. if (!::g->wbs->maxsecret)
  1333. ::g->wbs->maxsecret = 1;
  1334. if ( ::g->gamemode != retail )
  1335. if (::g->wbs->epsd > 2)
  1336. ::g->wbs->epsd -= 3;
  1337. }
  1338. void WI_Start(wbstartstruct_t* wbstartstruct)
  1339. {
  1340. WI_initVariables(wbstartstruct);
  1341. WI_loadData();
  1342. if (::g->deathmatch)
  1343. WI_initDeathmatchStats();
  1344. else if (::g->netgame)
  1345. WI_initNetgameStats();
  1346. else
  1347. WI_initStats();
  1348. }