IN_LUDE.C 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008
  1. /*
  2. ========================
  3. =
  4. = IN_lude.c
  5. =
  6. ========================
  7. */
  8. #include "DoomDef.h"
  9. #include "soundst.h"
  10. typedef enum
  11. {
  12. SINGLE,
  13. COOPERATIVE,
  14. DEATHMATCH
  15. } gametype_t;
  16. // Public functions
  17. void IN_Start(void);
  18. void IN_Ticker(void);
  19. void IN_Drawer(void);
  20. boolean intermission;
  21. // Private functions
  22. void IN_WaitStop(void);
  23. void IN_Stop(void);
  24. void IN_LoadPics(void);
  25. void IN_UnloadPics(void);
  26. void IN_CheckForSkip(void);
  27. void IN_InitStats(void);
  28. void IN_InitDeathmatchStats(void);
  29. void IN_InitNetgameStats(void);
  30. void IN_DrawOldLevel(void);
  31. void IN_DrawYAH(void);
  32. void IN_DrawStatBack(void);
  33. void IN_DrawSingleStats(void);
  34. void IN_DrawCoopStats(void);
  35. void IN_DrawDMStats(void);
  36. void IN_DrawNumber(int val, int x, int y, int digits);
  37. void IN_DrawTime(int x, int y, int h, int m, int s);
  38. void IN_DrTextB(char *text, int x, int y);
  39. static boolean skipintermission;
  40. static int interstate = 0;
  41. static int intertime = -1;
  42. static int oldintertime = 0;
  43. static gametype_t gametype;
  44. static int cnt;
  45. static int time;
  46. static int hours;
  47. static int minutes;
  48. static int seconds;
  49. static int slaughterboy; // in DM, the player with the most kills
  50. static int killPercent[MAXPLAYERS];
  51. static int bonusPercent[MAXPLAYERS];
  52. static int secretPercent[MAXPLAYERS];
  53. static patch_t *patchINTERPIC;
  54. static patch_t *patchBEENTHERE;
  55. static patch_t *patchGOINGTHERE;
  56. static patch_t *FontBNumbers[10];
  57. static patch_t *FontBNegative;
  58. static patch_t *FontBSlash;
  59. static patch_t *FontBPercent;
  60. static int FontBLump;
  61. static int FontBLumpBase;
  62. static int patchFaceOkayBase;
  63. static int patchFaceDeadBase;
  64. static signed int totalFrags[MAXPLAYERS];
  65. static fixed_t dSlideX[MAXPLAYERS];
  66. static fixed_t dSlideY[MAXPLAYERS];
  67. static char *KillersText[] = { "K", "I", "L", "L", "E", "R", "S" };
  68. extern char *LevelNames[];
  69. typedef struct
  70. {
  71. int x;
  72. int y;
  73. } yahpt_t;
  74. static yahpt_t YAHspot[3][9] =
  75. {
  76. {
  77. { 172, 78 },
  78. { 86, 90 },
  79. { 73, 66 },
  80. { 159, 95 },
  81. { 148, 126 },
  82. { 132, 54 },
  83. { 131, 74 },
  84. { 208, 138 },
  85. { 52, 101 }
  86. },
  87. {
  88. { 218, 57 },
  89. { 137, 81 },
  90. { 155, 124 },
  91. { 171, 68 },
  92. { 250, 86 },
  93. { 136, 98 },
  94. { 203, 90 },
  95. { 220, 140 },
  96. { 279, 106 }
  97. },
  98. {
  99. { 86, 99 },
  100. { 124, 103 },
  101. { 154, 79 },
  102. { 202, 83 },
  103. { 178, 59 },
  104. { 142, 58 },
  105. { 219, 66 },
  106. { 247, 57 },
  107. { 107, 80 }
  108. }
  109. };
  110. //========================================================================
  111. //
  112. // IN_Start
  113. //
  114. //========================================================================
  115. extern void AM_Stop (void);
  116. void IN_Start(void)
  117. {
  118. I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
  119. IN_LoadPics();
  120. IN_InitStats();
  121. intermission = true;
  122. interstate = -1;
  123. skipintermission = false;
  124. intertime = 0;
  125. oldintertime = 0;
  126. AM_Stop();
  127. S_StartSong(mus_intr, true);
  128. }
  129. //========================================================================
  130. //
  131. // IN_WaitStop
  132. //
  133. //========================================================================
  134. void IN_WaitStop(void)
  135. {
  136. if(!--cnt)
  137. {
  138. IN_Stop();
  139. G_WorldDone();
  140. }
  141. }
  142. //========================================================================
  143. //
  144. // IN_Stop
  145. //
  146. //========================================================================
  147. void IN_Stop(void)
  148. {
  149. intermission = false;
  150. IN_UnloadPics();
  151. SB_state = -1;
  152. BorderNeedRefresh = true;
  153. }
  154. //========================================================================
  155. //
  156. // IN_InitStats
  157. //
  158. // Initializes the stats for single player mode
  159. //========================================================================
  160. void IN_InitStats(void)
  161. {
  162. int i;
  163. int j;
  164. signed int slaughterfrags;
  165. int posnum;
  166. int slaughtercount;
  167. int playercount;
  168. if(!netgame)
  169. {
  170. gametype = SINGLE;
  171. time = leveltime/35;
  172. hours = time/3600;
  173. time -= hours*3600;
  174. minutes = time/60;
  175. time -= minutes*60;
  176. seconds = time;
  177. }
  178. else if(netgame && !deathmatch)
  179. {
  180. gametype = COOPERATIVE;
  181. memset(killPercent, 0, MAXPLAYERS*sizeof(int));
  182. memset(bonusPercent, 0, MAXPLAYERS*sizeof(int));
  183. memset(secretPercent, 0, MAXPLAYERS*sizeof(int));
  184. for(i=0; i<MAXPLAYERS; i++)
  185. {
  186. if(playeringame[i])
  187. {
  188. if(totalkills)
  189. {
  190. killPercent[i] = players[i].killcount*100/totalkills;
  191. }
  192. if(totalitems)
  193. {
  194. bonusPercent[i] = players[i].itemcount*100/totalitems;
  195. }
  196. if(totalsecret)
  197. {
  198. secretPercent[i] = players[i].secretcount*100/totalsecret;
  199. }
  200. }
  201. }
  202. }
  203. else
  204. {
  205. gametype = DEATHMATCH;
  206. slaughterboy = 0;
  207. slaughterfrags = -9999;
  208. posnum = 0;
  209. playercount = 0;
  210. slaughtercount = 0;
  211. for(i=0; i<MAXPLAYERS; i++)
  212. {
  213. totalFrags[i] = 0;
  214. if(playeringame[i])
  215. {
  216. playercount++;
  217. for(j=0; j<MAXPLAYERS; j++)
  218. {
  219. if(playeringame[j])
  220. {
  221. totalFrags[i] += players[i].frags[j];
  222. }
  223. }
  224. dSlideX[i] = (43*posnum*FRACUNIT)/20;
  225. dSlideY[i] = (36*posnum*FRACUNIT)/20;
  226. posnum++;
  227. }
  228. if(totalFrags[i] > slaughterfrags)
  229. {
  230. slaughterboy = 1<<i;
  231. slaughterfrags = totalFrags[i];
  232. slaughtercount = 1;
  233. }
  234. else if(totalFrags[i] == slaughterfrags)
  235. {
  236. slaughterboy |= 1<<i;
  237. slaughtercount++;
  238. }
  239. }
  240. if(playercount == slaughtercount)
  241. { // don't do the slaughter stuff if everyone is equal
  242. slaughterboy = 0;
  243. }
  244. }
  245. }
  246. //========================================================================
  247. //
  248. // IN_LoadPics
  249. //
  250. //========================================================================
  251. void IN_LoadPics(void)
  252. {
  253. int i;
  254. switch(gameepisode)
  255. {
  256. case 1:
  257. patchINTERPIC = W_CacheLumpName("MAPE1", PU_STATIC);
  258. break;
  259. case 2:
  260. patchINTERPIC = W_CacheLumpName("MAPE2", PU_STATIC);
  261. break;
  262. case 3:
  263. patchINTERPIC = W_CacheLumpName("MAPE3", PU_STATIC);
  264. break;
  265. default:
  266. break;
  267. }
  268. patchBEENTHERE = W_CacheLumpName("IN_X", PU_STATIC);
  269. patchGOINGTHERE = W_CacheLumpName("IN_YAH", PU_STATIC);
  270. FontBLumpBase = W_GetNumForName("FONTB16");
  271. for(i=0; i<10; i++)
  272. {
  273. FontBNumbers[i] = W_CacheLumpNum(FontBLumpBase+i, PU_STATIC);
  274. }
  275. FontBLump = W_GetNumForName("FONTB_S")+1;
  276. FontBNegative = W_CacheLumpName("FONTB13", PU_STATIC);
  277. FontBSlash = W_CacheLumpName("FONTB15", PU_STATIC);
  278. FontBPercent = W_CacheLumpName("FONTB05", PU_STATIC);
  279. patchFaceOkayBase = W_GetNumForName("FACEA0");
  280. patchFaceDeadBase = W_GetNumForName("FACEB0");
  281. }
  282. //========================================================================
  283. //
  284. // IN_UnloadPics
  285. //
  286. //========================================================================
  287. void IN_UnloadPics(void)
  288. {
  289. int i;
  290. if(patchINTERPIC)
  291. {
  292. Z_ChangeTag(patchINTERPIC, PU_CACHE);
  293. }
  294. Z_ChangeTag(patchBEENTHERE, PU_CACHE);
  295. Z_ChangeTag(patchGOINGTHERE, PU_CACHE);
  296. for(i=0; i<10; i++)
  297. {
  298. Z_ChangeTag(FontBNumbers[i], PU_CACHE);
  299. }
  300. Z_ChangeTag(FontBNegative, PU_CACHE);
  301. Z_ChangeTag(FontBSlash, PU_CACHE);
  302. Z_ChangeTag(FontBPercent, PU_CACHE);
  303. }
  304. //========================================================================
  305. //
  306. // IN_Ticker
  307. //
  308. //========================================================================
  309. void IN_Ticker(void)
  310. {
  311. if(!intermission)
  312. {
  313. return;
  314. }
  315. if(interstate == 3)
  316. {
  317. IN_WaitStop();
  318. return;
  319. }
  320. IN_CheckForSkip();
  321. intertime++;
  322. if(oldintertime < intertime)
  323. {
  324. interstate++;
  325. if(gameepisode > 3 && interstate >= 1)
  326. { // Extended Wad levels: skip directly to the next level
  327. interstate = 3;
  328. }
  329. switch(interstate)
  330. {
  331. case 0:
  332. oldintertime = intertime+300;
  333. if(gameepisode > 3)
  334. {
  335. oldintertime = intertime+1200;
  336. }
  337. break;
  338. case 1:
  339. oldintertime = intertime+200;
  340. break;
  341. case 2:
  342. oldintertime = MAXINT;
  343. break;
  344. case 3:
  345. cnt = 10;
  346. break;
  347. default:
  348. break;
  349. }
  350. }
  351. if(skipintermission)
  352. {
  353. if(interstate == 0 && intertime < 150)
  354. {
  355. intertime = 150;
  356. skipintermission = false;
  357. return;
  358. }
  359. else if(interstate < 2 && gameepisode < 4)
  360. {
  361. interstate = 2;
  362. skipintermission = false;
  363. S_StartSound(NULL, sfx_dorcls);
  364. return;
  365. }
  366. interstate = 3;
  367. cnt = 10;
  368. skipintermission = false;
  369. S_StartSound(NULL, sfx_dorcls);
  370. }
  371. }
  372. //========================================================================
  373. //
  374. // IN_CheckForSkip
  375. //
  376. // Check to see if any player hit a key
  377. //========================================================================
  378. void IN_CheckForSkip(void)
  379. {
  380. int i;
  381. player_t *player;
  382. for (i=0, player = players ; i<MAXPLAYERS ; i++, player++)
  383. {
  384. if (playeringame[i])
  385. {
  386. if (player->cmd.buttons&BT_ATTACK)
  387. {
  388. if (!player->attackdown)
  389. {
  390. skipintermission = 1;
  391. }
  392. player->attackdown = true;
  393. }
  394. else
  395. {
  396. player->attackdown = false;
  397. }
  398. if (player->cmd.buttons&BT_USE)
  399. {
  400. if (!player->usedown)
  401. {
  402. skipintermission = 1;
  403. }
  404. player->usedown = true;
  405. }
  406. else
  407. {
  408. player->usedown = false;
  409. }
  410. }
  411. }
  412. }
  413. //========================================================================
  414. //
  415. // IN_Drawer
  416. //
  417. //========================================================================
  418. void IN_Drawer(void)
  419. {
  420. static int oldinterstate;
  421. if(!intermission)
  422. {
  423. return;
  424. }
  425. if(interstate == 3)
  426. {
  427. return;
  428. }
  429. UpdateState |= I_FULLSCRN;
  430. if(oldinterstate != 2 && interstate == 2)
  431. {
  432. S_StartSound(NULL, sfx_pstop);
  433. }
  434. oldinterstate = interstate;
  435. switch(interstate)
  436. {
  437. case 0: // draw stats
  438. IN_DrawStatBack();
  439. switch(gametype)
  440. {
  441. case SINGLE:
  442. IN_DrawSingleStats();
  443. break;
  444. case COOPERATIVE:
  445. IN_DrawCoopStats();
  446. break;
  447. case DEATHMATCH:
  448. IN_DrawDMStats();
  449. break;
  450. }
  451. break;
  452. case 1: // leaving old level
  453. if(gameepisode < 4)
  454. {
  455. V_DrawPatch(0, 0, patchINTERPIC);
  456. IN_DrawOldLevel();
  457. }
  458. break;
  459. case 2: // going to the next level
  460. if(gameepisode < 4)
  461. {
  462. V_DrawPatch(0, 0, patchINTERPIC);
  463. IN_DrawYAH();
  464. }
  465. break;
  466. case 3: // waiting before going to the next level
  467. if(gameepisode < 4)
  468. {
  469. V_DrawPatch(0, 0, patchINTERPIC);
  470. }
  471. break;
  472. default:
  473. I_Error("IN_lude: Intermission state out of range.\n");
  474. break;
  475. }
  476. }
  477. //========================================================================
  478. //
  479. // IN_DrawStatBack
  480. //
  481. //========================================================================
  482. void IN_DrawStatBack(void)
  483. {
  484. int x;
  485. int y;
  486. byte *src;
  487. byte *dest;
  488. src = W_CacheLumpName ("FLOOR16", PU_CACHE);
  489. dest = screen;
  490. for (y=0 ; y<SCREENHEIGHT ; y++)
  491. {
  492. for (x=0 ; x<SCREENWIDTH/64 ; x++)
  493. {
  494. memcpy (dest, src+((y&63)<<6), 64);
  495. dest += 64;
  496. }
  497. if (SCREENWIDTH&63)
  498. {
  499. memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
  500. dest += (SCREENWIDTH&63);
  501. }
  502. }
  503. }
  504. //========================================================================
  505. //
  506. // IN_DrawOldLevel
  507. //
  508. //========================================================================
  509. void IN_DrawOldLevel(void)
  510. {
  511. int i;
  512. int x;
  513. x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+prevmap-1]+7)/2;
  514. IN_DrTextB(LevelNames[(gameepisode-1)*9+prevmap-1]+7, x, 3);
  515. x = 160-MN_TextAWidth("FINISHED")/2;
  516. MN_DrTextA("FINISHED", x, 25);
  517. if(prevmap == 9)
  518. {
  519. for(i=0; i<gamemap-1; i++)
  520. {
  521. V_DrawPatch(YAHspot[gameepisode-1][i].x, YAHspot[gameepisode-1][i].y,
  522. patchBEENTHERE);
  523. }
  524. if(!(intertime&16))
  525. {
  526. V_DrawPatch(YAHspot[gameepisode-1][8].x, YAHspot[gameepisode-1][8].y,
  527. patchBEENTHERE);
  528. }
  529. }
  530. else
  531. {
  532. for(i=0; i<prevmap-1; i++)
  533. {
  534. V_DrawPatch(YAHspot[gameepisode-1][i].x, YAHspot[gameepisode-1][i].y,
  535. patchBEENTHERE);
  536. }
  537. if(players[consoleplayer].didsecret)
  538. {
  539. V_DrawPatch(YAHspot[gameepisode-1][8].x, YAHspot[gameepisode-1][8].y,
  540. patchBEENTHERE);
  541. }
  542. if(!(intertime&16))
  543. {
  544. V_DrawPatch(YAHspot[gameepisode-1][prevmap-1].x, YAHspot[gameepisode-1][prevmap-1].y,
  545. patchBEENTHERE);
  546. }
  547. }
  548. }
  549. //========================================================================
  550. //
  551. // IN_DrawYAH
  552. //
  553. //========================================================================
  554. void IN_DrawYAH(void)
  555. {
  556. int i;
  557. int x;
  558. x = 160-MN_TextAWidth("NOW ENTERING:")/2;
  559. MN_DrTextA("NOW ENTERING:", x, 10);
  560. x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+gamemap-1]+7)/2;
  561. IN_DrTextB(LevelNames[(gameepisode-1)*9+gamemap-1]+7, x, 20);
  562. if(prevmap == 9)
  563. {
  564. prevmap = gamemap-1;
  565. }
  566. for(i=0; i<prevmap; i++)
  567. {
  568. V_DrawPatch(YAHspot[gameepisode-1][i].x, YAHspot[gameepisode-1][i].y,
  569. patchBEENTHERE);
  570. }
  571. if(players[consoleplayer].didsecret)
  572. {
  573. V_DrawPatch(YAHspot[gameepisode-1][8].x, YAHspot[gameepisode-1][8].y,
  574. patchBEENTHERE);
  575. }
  576. if(!(intertime&16) || interstate == 3)
  577. { // draw the destination 'X'
  578. V_DrawPatch(YAHspot[gameepisode-1][gamemap-1].x,
  579. YAHspot[gameepisode-1][gamemap-1].y, patchGOINGTHERE);
  580. }
  581. }
  582. //========================================================================
  583. //
  584. // IN_DrawSingleStats
  585. //
  586. //========================================================================
  587. void IN_DrawSingleStats(void)
  588. {
  589. int x;
  590. static int sounds;
  591. IN_DrTextB("KILLS", 50, 65);
  592. IN_DrTextB("ITEMS", 50, 90);
  593. IN_DrTextB("SECRETS", 50, 115);
  594. x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+prevmap-1]+7)/2;
  595. IN_DrTextB(LevelNames[(gameepisode-1)*9+prevmap-1]+7, x, 3);
  596. x = 160-MN_TextAWidth("FINISHED")/2;
  597. MN_DrTextA("FINISHED", x, 25);
  598. if(intertime < 30)
  599. {
  600. sounds = 0;
  601. return;
  602. }
  603. if(sounds < 1 && intertime >= 30)
  604. {
  605. S_StartSound(NULL, sfx_dorcls);
  606. sounds++;
  607. }
  608. IN_DrawNumber(players[consoleplayer].killcount, 200, 65, 3);
  609. V_DrawShadowedPatch(237, 65, FontBSlash);
  610. IN_DrawNumber(totalkills, 248, 65, 3);
  611. if(intertime < 60)
  612. {
  613. return;
  614. }
  615. if(sounds < 2 && intertime >= 60)
  616. {
  617. S_StartSound(NULL, sfx_dorcls);
  618. sounds++;
  619. }
  620. IN_DrawNumber(players[consoleplayer].itemcount, 200, 90, 3);
  621. V_DrawShadowedPatch(237, 90, FontBSlash);
  622. IN_DrawNumber(totalitems, 248, 90, 3);
  623. if(intertime < 90)
  624. {
  625. return;
  626. }
  627. if(sounds < 3 && intertime >= 90)
  628. {
  629. S_StartSound(NULL, sfx_dorcls);
  630. sounds++;
  631. }
  632. IN_DrawNumber(players[consoleplayer].secretcount, 200, 115, 3);
  633. V_DrawShadowedPatch(237, 115, FontBSlash);
  634. IN_DrawNumber(totalsecret, 248, 115, 3);
  635. if(intertime < 150)
  636. {
  637. return;
  638. }
  639. if(sounds < 4 && intertime >= 150)
  640. {
  641. S_StartSound(NULL, sfx_dorcls);
  642. sounds++;
  643. }
  644. if(!ExtendedWAD || gameepisode < 4)
  645. {
  646. IN_DrTextB("TIME", 85, 160);
  647. IN_DrawTime(155, 160, hours, minutes, seconds);
  648. }
  649. else
  650. {
  651. x = 160-MN_TextAWidth("NOW ENTERING:")/2;
  652. MN_DrTextA("NOW ENTERING:", x, 160);
  653. x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+gamemap-1]+7)/2;
  654. IN_DrTextB(LevelNames[(gameepisode-1)*9+gamemap-1]+7, x, 170);
  655. skipintermission = false;
  656. }
  657. }
  658. //========================================================================
  659. //
  660. // IN_DrawCoopStats
  661. //
  662. //========================================================================
  663. void IN_DrawCoopStats(void)
  664. {
  665. int i;
  666. int x;
  667. int ypos;
  668. static int sounds;
  669. IN_DrTextB("KILLS", 95, 35);
  670. IN_DrTextB("BONUS", 155, 35);
  671. IN_DrTextB("SECRET", 232, 35);
  672. x = 160-MN_TextBWidth(LevelNames[(gameepisode-1)*9+prevmap-1]+7)/2;
  673. IN_DrTextB(LevelNames[(gameepisode-1)*9+prevmap-1]+7, x, 3);
  674. x = 160-MN_TextAWidth("FINISHED")/2;
  675. MN_DrTextA("FINISHED", x, 25);
  676. ypos = 50;
  677. for(i=0; i<MAXPLAYERS; i++)
  678. {
  679. if(playeringame[i])
  680. {
  681. V_DrawShadowedPatch(25, ypos, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE));
  682. if(intertime < 40)
  683. {
  684. sounds = 0;
  685. ypos += 37;
  686. continue;
  687. }
  688. else if(intertime >= 40 && sounds < 1)
  689. {
  690. S_StartSound(NULL, sfx_dorcls);
  691. sounds++;
  692. }
  693. IN_DrawNumber(killPercent[i], 85, ypos+10, 3);
  694. V_DrawShadowedPatch(121, ypos+10, FontBPercent);
  695. IN_DrawNumber(bonusPercent[i], 160, ypos+10, 3);
  696. V_DrawShadowedPatch(196, ypos+10, FontBPercent);
  697. IN_DrawNumber(secretPercent[i], 237, ypos+10, 3);
  698. V_DrawShadowedPatch(273, ypos+10, FontBPercent);
  699. ypos += 37;
  700. }
  701. }
  702. }
  703. //========================================================================
  704. //
  705. // IN_DrawDMStats
  706. //
  707. //========================================================================
  708. void IN_DrawDMStats(void)
  709. {
  710. int i;
  711. int j;
  712. int ypos;
  713. int xpos;
  714. int kpos;
  715. int x;
  716. static int sounds;
  717. xpos = 90;
  718. ypos = 55;
  719. IN_DrTextB("TOTAL", 265, 30);
  720. MN_DrTextA("VICTIMS", 140, 8);
  721. for(i=0; i<7; i++)
  722. {
  723. MN_DrTextA(KillersText[i], 10, 80+9*i);
  724. }
  725. if(intertime < 20)
  726. {
  727. for(i=0; i<MAXPLAYERS; i++)
  728. {
  729. if(playeringame[i])
  730. {
  731. V_DrawShadowedPatch(40, ((ypos<<FRACBITS)+dSlideY[i]*intertime)
  732. >>FRACBITS, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE));
  733. V_DrawShadowedPatch(((xpos<<FRACBITS)+dSlideX[i]*intertime)
  734. >>FRACBITS, 18, W_CacheLumpNum(patchFaceDeadBase+i, PU_CACHE));
  735. }
  736. }
  737. sounds = 0;
  738. return;
  739. }
  740. if(intertime >= 20 && sounds < 1)
  741. {
  742. S_StartSound(NULL, sfx_dorcls);
  743. sounds++;
  744. }
  745. if(intertime >= 100 && slaughterboy && sounds < 2)
  746. {
  747. S_StartSound(NULL, sfx_wpnup);
  748. sounds++;
  749. }
  750. for(i=0; i<MAXPLAYERS; i++)
  751. {
  752. if(playeringame[i])
  753. {
  754. if(intertime < 100 || i == consoleplayer)
  755. {
  756. V_DrawShadowedPatch(40, ypos, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE));
  757. V_DrawShadowedPatch(xpos, 18, W_CacheLumpNum(patchFaceDeadBase+i, PU_CACHE));
  758. }
  759. else
  760. {
  761. V_DrawFuzzPatch(40, ypos, W_CacheLumpNum(patchFaceOkayBase+i, PU_CACHE));
  762. V_DrawFuzzPatch(xpos, 18, W_CacheLumpNum(patchFaceDeadBase+i, PU_CACHE));
  763. }
  764. kpos = 86;
  765. for(j=0; j<MAXPLAYERS; j++)
  766. {
  767. if(playeringame[j])
  768. {
  769. IN_DrawNumber(players[i].frags[j], kpos, ypos+10, 3);
  770. kpos += 43;
  771. }
  772. }
  773. if(slaughterboy&(1<<i))
  774. {
  775. if(!(intertime&16))
  776. {
  777. IN_DrawNumber(totalFrags[i], 263, ypos+10, 3);
  778. }
  779. }
  780. else
  781. {
  782. IN_DrawNumber(totalFrags[i], 263, ypos+10, 3);
  783. }
  784. ypos += 36;
  785. xpos += 43;
  786. }
  787. }
  788. }
  789. //========================================================================
  790. //
  791. // IN_DrawTime
  792. //
  793. //========================================================================
  794. void IN_DrawTime(int x, int y, int h, int m, int s)
  795. {
  796. if(h)
  797. {
  798. IN_DrawNumber(h, x, y, 2);
  799. IN_DrTextB(":", x+26, y);
  800. }
  801. x += 34;
  802. if(m || h)
  803. {
  804. IN_DrawNumber(m, x, y, 2);
  805. }
  806. x += 34;
  807. if(s)
  808. {
  809. IN_DrTextB(":", x-8, y);
  810. IN_DrawNumber(s, x, y, 2);
  811. }
  812. }
  813. //========================================================================
  814. //
  815. // IN_DrawNumber
  816. //
  817. //========================================================================
  818. void IN_DrawNumber(int val, int x, int y, int digits)
  819. {
  820. patch_t *patch;
  821. int xpos;
  822. int oldval;
  823. int realdigits;
  824. boolean neg;
  825. oldval = val;
  826. xpos = x;
  827. neg = false;
  828. realdigits = 1;
  829. if(val < 0)
  830. { //...this should reflect negative frags
  831. val = -val;
  832. neg = true;
  833. if(val > 99)
  834. {
  835. val = 99;
  836. }
  837. }
  838. if(val > 9)
  839. {
  840. realdigits++;
  841. if(digits < realdigits)
  842. {
  843. realdigits = digits;
  844. val = 9;
  845. }
  846. }
  847. if(val > 99)
  848. {
  849. realdigits++;
  850. if(digits < realdigits)
  851. {
  852. realdigits = digits;
  853. val = 99;
  854. }
  855. }
  856. if(val > 999)
  857. {
  858. realdigits++;
  859. if(digits < realdigits)
  860. {
  861. realdigits = digits;
  862. val = 999;
  863. }
  864. }
  865. if(digits == 4)
  866. {
  867. patch = FontBNumbers[val/1000];
  868. V_DrawShadowedPatch(xpos+6-patch->width/2-12, y, patch);
  869. }
  870. if(digits > 2)
  871. {
  872. if(realdigits > 2)
  873. {
  874. patch = FontBNumbers[val/100];
  875. V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
  876. }
  877. xpos += 12;
  878. }
  879. val = val%100;
  880. if(digits > 1)
  881. {
  882. if(val > 9)
  883. {
  884. patch = FontBNumbers[val/10];
  885. V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
  886. }
  887. else if(digits == 2 || oldval > 99)
  888. {
  889. V_DrawShadowedPatch(xpos, y, FontBNumbers[0]);
  890. }
  891. xpos += 12;
  892. }
  893. val = val%10;
  894. patch = FontBNumbers[val];
  895. V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
  896. if(neg)
  897. {
  898. patch = FontBNegative;
  899. V_DrawShadowedPatch(xpos+6-patch->width/2-12*(realdigits), y, patch);
  900. }
  901. }
  902. //========================================================================
  903. //
  904. // IN_DrTextB
  905. //
  906. //========================================================================
  907. void IN_DrTextB(char *text, int x, int y)
  908. {
  909. char c;
  910. patch_t *p;
  911. while((c = *text++) != 0)
  912. {
  913. if(c < 33)
  914. {
  915. x += 8;
  916. }
  917. else
  918. {
  919. p = W_CacheLumpNum(FontBLump+c-33, PU_CACHE);
  920. V_DrawShadowedPatch(x, y, p);
  921. x += p->width-1;
  922. }
  923. }
  924. }