PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/f_finale.c

https://bitbucket.org/zturtleman/srb2ztm
C | 1944 lines | 1619 code | 250 blank | 75 comment | 454 complexity | 18fbb17ece139dfecd6ad46e24ec41b0 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. // Emacs style mode select -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // Copyright (C) 1993-1996 by id Software, Inc.
  5. // Copyright (C) 1998-2000 by DooM Legacy Team.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. // GNU General Public License for more details.
  16. //-----------------------------------------------------------------------------
  17. /// \file
  18. /// \brief Title screen, intro, game evaluation, and credits.
  19. #include "doomdef.h"
  20. #include "doomstat.h"
  21. #include "am_map.h"
  22. #include "dstrings.h"
  23. #include "d_main.h"
  24. #include "f_finale.h"
  25. #include "g_game.h"
  26. #include "hu_stuff.h"
  27. #include "r_local.h"
  28. #include "s_sound.h"
  29. #include "i_video.h"
  30. #include "v_video.h"
  31. #include "w_wad.h"
  32. #include "z_zone.h"
  33. #include "i_system.h"
  34. #include "m_menu.h"
  35. #include "dehacked.h"
  36. #include "g_input.h"
  37. #include "console.h"
  38. #include "m_random.h"
  39. #include "y_inter.h"
  40. credit_t credits[19];
  41. // Stage of animation:
  42. // 0 = text, 1 = art screen
  43. static INT32 finalestage;
  44. static INT32 finalecount;
  45. INT32 titlescrollspeed = 80;
  46. static INT32 timetonext; // Delay between screen changes
  47. static INT32 finaletextcount;
  48. static tic_t animtimer; // Used for some animation timings
  49. static INT32 roidtics; // Asteroid spinning
  50. static INT32 deplete;
  51. static tic_t stoptimer;
  52. // Intro
  53. static INT32 scene;
  54. #define NUMINTROSCENES 16
  55. static tic_t introscenetime[NUMINTROSCENES] =
  56. {
  57. 5*TICRATE, // STJr Presents
  58. 10*TICRATE + (TICRATE/2), // Two months had passed since...
  59. 13*TICRATE + (TICRATE/2), // As it was about to drain the rings...
  60. 15*TICRATE, // What Sonic, Tails, and Knuckles...
  61. 15*TICRATE + (TICRATE/2), // About once every year, a strange...
  62. 18*TICRATE + (TICRATE/2), // Curses! Eggman yelled. That ridiculous...
  63. 20*TICRATE + (TICRATE/4)*3, // It was only later that he had an idea...
  64. 9*TICRATE + (TICRATE/2), // Before beginning his scheme, Eggman decided to give Sonic...
  65. 15*TICRATE, // We're ready to fire in 15 seconds, the robot said...
  66. 16*TICRATE, // Meanwhile, Sonic was tearing across the zones...
  67. 14*TICRATE, // Sonic knew he was getting closer to the city...
  68. 13*TICRATE, // Greenflower City was gone...
  69. 19*TICRATE, // You're not quite as dead as we thought, huh?...
  70. 17*TICRATE + (TICRATE/2), // Eggman took this as his cue and blasted off...
  71. 15*TICRATE, // Easy! We go find Eggman and stop his...
  72. 24*TICRATE, // I'm just finding what mission obje...
  73. };
  74. #define TEXTSPEED 3
  75. #define TEXTWAIT 250
  76. static const char *finaletext = NULL;
  77. static boolean keypressed = false;
  78. static patch_t *background;
  79. static patch_t *currentanim;
  80. static patch_t *nextanim;
  81. static patch_t *first;
  82. static patch_t *second;
  83. static patch_t *third;
  84. // De-Demo'd Title Screen
  85. static patch_t *ttbanner; // white banner with "robo blast" and "2"
  86. static patch_t *ttwing; // wing background
  87. static patch_t *ttsonic; // "SONIC"
  88. static patch_t *ttswave1; // Title Sonics
  89. static patch_t *ttswave2;
  90. static patch_t *ttswip1;
  91. static patch_t *ttsprep1;
  92. static patch_t *ttsprep2;
  93. static patch_t *ttspop1;
  94. static patch_t *ttspop2;
  95. static patch_t *ttspop3;
  96. static patch_t *ttspop4;
  97. static patch_t *ttspop5;
  98. static patch_t *ttspop6;
  99. static patch_t *ttspop7;
  100. static void F_SkyScroll(void);
  101. static boolean drawemblem = false, drawchaosemblem = false, runningprecutscene = false, precutresetplayer = false;
  102. // De-Demo'd Title Screen
  103. void F_StartTitleScreen(void)
  104. {
  105. G_SetGamestate(GS_TITLESCREEN);
  106. CON_ClearHUD();
  107. // IWAD dependent stuff.
  108. S_ChangeMusic(mus_titles, looptitle);
  109. finalecount = 0;
  110. finalestage = 0;
  111. animtimer = 0;
  112. ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL);
  113. ttwing = W_CachePatchName("TTWING", PU_LEVEL);
  114. ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL);
  115. ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL);
  116. ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL);
  117. ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL);
  118. ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL);
  119. ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL);
  120. ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL);
  121. ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL);
  122. ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL);
  123. ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL);
  124. ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL);
  125. ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL);
  126. ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL);
  127. }
  128. // Game end thingy
  129. void F_StartGameEnd(void)
  130. {
  131. G_SetGamestate(GS_GAMEEND);
  132. gameaction = ga_nothing;
  133. playerdeadview = false;
  134. paused = false;
  135. CON_ToggleOff();
  136. CON_ClearHUD();
  137. S_StopMusic();
  138. timetonext = TICRATE;
  139. }
  140. void F_StartGameEvaluation(void)
  141. {
  142. G_SetGamestate(GS_EVALUATION);
  143. gameaction = ga_nothing;
  144. playerdeadview = false;
  145. paused = false;
  146. CON_ToggleOff();
  147. CON_ClearHUD();
  148. if (ALL7EMERALDS(emeralds))
  149. animtimer = 64;
  150. finalecount = 0;
  151. }
  152. void F_StartCredits(void)
  153. {
  154. size_t i = 0;
  155. size_t j = 0;
  156. if (creditscutscene)
  157. {
  158. F_StartCustomCutscene(creditscutscene - 1, false, false);
  159. return;
  160. }
  161. G_SetGamestate(GS_CREDITS);
  162. gameaction = ga_nothing;
  163. playerdeadview = false;
  164. paused = false;
  165. CON_ToggleOff();
  166. CON_ClearHUD();
  167. S_StopMusic();
  168. if (!modifiedgame && (grade & 8) && ALL7EMERALDS(emeralds))
  169. S_ChangeMusic(mus_mapl4m, false);
  170. else
  171. S_ChangeMusic(mus_credit, false);
  172. finalecount = 0;
  173. animtimer = 0;
  174. timetonext = 5*TICRATE-1;
  175. memset(credits, 0, sizeof(credit_t)*19);
  176. // Initalize the credits table
  177. strcpy(credits[i].header, "Sonic Team Junior\n");
  178. strcpy(credits[i].fakenames[j++], "Staff\n");
  179. j = 0;
  180. strcpy(credits[i].realnames[j++], "Staff\n");
  181. credits[i].numnames = 1;
  182. i++;
  183. strcpy(credits[i].header, "Producer\n");
  184. j = 0;
  185. strcpy(credits[i].fakenames[j++], "SSNTails\n");
  186. strcpy(credits[i].fakenames[j++], "\n");
  187. strcpy(credits[i].fakenames[j++], "Director\n");
  188. strcpy(credits[i].fakenames[j++], "Sonikku\n");
  189. j = 0;
  190. strcpy(credits[i].realnames[j++], "Art Freda\n");
  191. strcpy(credits[i].realnames[j++], "\n");
  192. strcpy(credits[i].realnames[j++], "Director\n");
  193. strcpy(credits[i].realnames[j++], "Johnny Wallbank\n");
  194. credits[i].numnames = (UINT8)j;
  195. i++;
  196. strcpy(credits[i].header, "Game Designers\n");
  197. j = 0;
  198. strcpy(credits[i].fakenames[j++], "Sonikku\n");
  199. strcpy(credits[i].fakenames[j++], "SSNTails\n");
  200. strcpy(credits[i].fakenames[j++], "Mystic\n");
  201. j = 0;
  202. strcpy(credits[i].realnames[j++], "Johnny Wallbank\n");
  203. strcpy(credits[i].realnames[j++], "Art Freda\n");
  204. strcpy(credits[i].realnames[j++], "Ben Geyer\n");
  205. credits[i].numnames = (UINT8)j;
  206. i++;
  207. strcpy(credits[i].header, "Character Designers\n");
  208. j = 0;
  209. strcpy(credits[i].fakenames[j++], "Sonikku\n");
  210. strcpy(credits[i].fakenames[j++], "Instant Sonic\n");
  211. j = 0;
  212. strcpy(credits[i].realnames[j++], "Johnny Wallbank\n");
  213. strcpy(credits[i].realnames[j++], "David Spencer Jr\n");
  214. credits[i].numnames = (UINT8)j;
  215. i++;
  216. strcpy(credits[i].header, "Visual Design\n");
  217. j = 0;
  218. strcpy(credits[i].fakenames[j++], "SSNTails\n");
  219. j = 0;
  220. strcpy(credits[i].realnames[j++], "Art Freda\n");
  221. credits[i].numnames = (UINT8)j;
  222. i++;
  223. strcpy(credits[i].header, "Landscape Design\n");
  224. j = 0;
  225. strcpy(credits[i].fakenames[j++], "Sonikku\n");
  226. strcpy(credits[i].fakenames[j++], "JEV3\n");
  227. j = 0;
  228. strcpy(credits[i].realnames[j++], "Johnny Wallbank\n");
  229. strcpy(credits[i].realnames[j++], "Jarrett Voight\n");
  230. credits[i].numnames = (UINT8)j;
  231. i++;
  232. strcpy(credits[i].header, "Chief Programmer\n");
  233. j = 0;
  234. strcpy(credits[i].fakenames[j++], "SSNTails\n");
  235. j = 0;
  236. strcpy(credits[i].realnames[j++], "Art Freda\n");
  237. credits[i].numnames = (UINT8)j;
  238. i++;
  239. strcpy(credits[i].header, "Programmers\n");
  240. j = 0;
  241. strcpy(credits[i].fakenames[j++], "Alam_GBC\n");
  242. strcpy(credits[i].fakenames[j++], "Jazz\n");
  243. strcpy(credits[i].fakenames[j++], "Graue\n");
  244. strcpy(credits[i].fakenames[j++], "MattW CFI\n");
  245. strcpy(credits[i].fakenames[j++], "Orospakr\n");
  246. j = 0;
  247. strcpy(credits[i].realnames[j++], "Alam Arias\n");
  248. strcpy(credits[i].realnames[j++], "Nathan Giroux\n");
  249. strcpy(credits[i].realnames[j++], "Scott Feeney\n");
  250. strcpy(credits[i].realnames[j++], "Matthew Walsh\n");
  251. strcpy(credits[i].realnames[j++], "Andrew Clunis\n");
  252. credits[i].numnames = (UINT8)j;
  253. i++;
  254. strcpy(credits[i].header, "Coding Assistants\n");
  255. j = 0;
  256. strcpy(credits[i].fakenames[j++], "StroggOnMeth\n");
  257. strcpy(credits[i].fakenames[j++], "Cyan Helkaraxe\n");
  258. strcpy(credits[i].fakenames[j++], "Logan_GBA\n");
  259. strcpy(credits[i].fakenames[j++], "Shuffle\n");
  260. strcpy(credits[i].fakenames[j++], "Oogaland\n");
  261. strcpy(credits[i].fakenames[j++], "Jason the Echidna\n");
  262. j = 0;
  263. strcpy(credits[i].realnames[j++], "Steven McGranahan\n");
  264. strcpy(credits[i].realnames[j++], "Cyan Helkaraxe\n");
  265. strcpy(credits[i].realnames[j++], "Logan Arias\n");
  266. strcpy(credits[i].realnames[j++], "Matt Marsalko\n");
  267. strcpy(credits[i].realnames[j++], "Gregor Dick\n");
  268. strcpy(credits[i].realnames[j++], "John J. Muniz\n");
  269. credits[i].numnames = (UINT8)j;
  270. i++;
  271. strcpy(credits[i].header, "Level Designers\n");
  272. j = 0;
  273. strcpy(credits[i].fakenames[j++], "Sonikku\n");
  274. strcpy(credits[i].fakenames[j++], "Mystic\n");
  275. strcpy(credits[i].fakenames[j++], "SSNTails\n");
  276. strcpy(credits[i].fakenames[j++], "Digiku\n");
  277. strcpy(credits[i].fakenames[j++], "Torgo\n");
  278. strcpy(credits[i].fakenames[j++], "Nev3r\n");
  279. strcpy(credits[i].fakenames[j++], "JEV3\n");
  280. strcpy(credits[i].fakenames[j++], "Spazzo\n");
  281. strcpy(credits[i].fakenames[j++], "MattW CFI\n");
  282. strcpy(credits[i].fakenames[j++], "Jazz\n");
  283. strcpy(credits[i].fakenames[j++], "FoxBlitzz\n");
  284. j = 0;
  285. strcpy(credits[i].realnames[j++], "Johnny Wallbank\n");
  286. strcpy(credits[i].realnames[j++], "Ben Geyer\n");
  287. strcpy(credits[i].realnames[j++], "Art Freda\n");
  288. strcpy(credits[i].realnames[j++], "Marco Zafra\n");
  289. strcpy(credits[i].realnames[j++], "Erik Nielsen\n");
  290. strcpy(credits[i].realnames[j++], "Pedro Iceta\n");
  291. strcpy(credits[i].realnames[j++], "Jarrett Voight\n");
  292. strcpy(credits[i].realnames[j++], "Michael Antonakes\n");
  293. strcpy(credits[i].realnames[j++], "Matthew Walsh\n");
  294. strcpy(credits[i].realnames[j++], "Nathan Giroux\n");
  295. strcpy(credits[i].realnames[j++], "Dan Hagerstrand\n");
  296. credits[i].numnames = (UINT8)j;
  297. credits[i].smallnames = true;
  298. i++;
  299. strcpy(credits[i].header, "Texture Artists\n");
  300. j = 0;
  301. strcpy(credits[i].fakenames[j++], "KinkaJoy\n");
  302. strcpy(credits[i].fakenames[j++], "SSNTails\n");
  303. strcpy(credits[i].fakenames[j++], "Blaze Hedgehog\n");
  304. strcpy(credits[i].fakenames[j++], "JEV3\n");
  305. strcpy(credits[i].fakenames[j++], "Nev3r\n");
  306. j = 0;
  307. strcpy(credits[i].realnames[j++], "Buddy Fischer\n");
  308. strcpy(credits[i].realnames[j++], "Art Freda\n");
  309. strcpy(credits[i].realnames[j++], "Ryan Bloom\n");
  310. strcpy(credits[i].realnames[j++], "Jarrett Voight\n");
  311. strcpy(credits[i].realnames[j++], "Pedro Iceta\n");
  312. credits[i].numnames = (UINT8)j;
  313. i++;
  314. strcpy(credits[i].header, "Music Production\n");
  315. j = 0;
  316. strcpy(credits[i].fakenames[j++], "Bulmybag\n");
  317. strcpy(credits[i].fakenames[j++], "Arrow\n");
  318. strcpy(credits[i].fakenames[j++], "Stuf\n");
  319. strcpy(credits[i].fakenames[j++], "SSNTails\n");
  320. strcpy(credits[i].fakenames[j++], "Cyan Helkaraxe\n");
  321. strcpy(credits[i].fakenames[j++], "Red XVI\n");
  322. strcpy(credits[i].fakenames[j++], "Spazzo\n");
  323. strcpy(credits[i].fakenames[j++], "Nev3r\n");
  324. j = 0;
  325. strcpy(credits[i].realnames[j++], "David Bulmer\n");
  326. strcpy(credits[i].realnames[j++], "Jarel Jones\n");
  327. strcpy(credits[i].realnames[j++], "Stefan Rimalia\n");
  328. strcpy(credits[i].realnames[j++], "Art Freda\n");
  329. strcpy(credits[i].realnames[j++], "Cyan Helkaraxe\n");
  330. strcpy(credits[i].realnames[j++], "Malcolm Brown\n");
  331. strcpy(credits[i].realnames[j++], "Michael Antonakes\n");
  332. strcpy(credits[i].realnames[j++], "Pedro Iceta\n");
  333. credits[i].smallnames = true;
  334. credits[i].numnames = (UINT8)j;
  335. i++;
  336. strcpy(credits[i].header, "Lead Guitar\n");
  337. j = 0;
  338. strcpy(credits[i].fakenames[j++], "Big Wave Dave\n");
  339. strcpy(credits[i].fakenames[j++], "Shane Strife\n");
  340. j = 0;
  341. strcpy(credits[i].realnames[j++], "David Spencer Sr\n");
  342. strcpy(credits[i].realnames[j++], "Shane Sexton\n");
  343. credits[i].numnames = (UINT8)j;
  344. i++;
  345. strcpy(credits[i].header, "Sound Effects\n");
  346. j = 0;
  347. strcpy(credits[i].fakenames[j++], "Sega\n");
  348. strcpy(credits[i].fakenames[j++], "Instant Sonic\n");
  349. strcpy(credits[i].fakenames[j++], "Various Sources\n");
  350. j = 0;
  351. strcpy(credits[i].realnames[j++], "Sega\n");
  352. strcpy(credits[i].realnames[j++], "David Spencer Jr\n");
  353. strcpy(credits[i].realnames[j++], "Various Sources\n");
  354. credits[i].numnames = (UINT8)j;
  355. i++;
  356. strcpy(credits[i].header, "Official Mascot\n");
  357. j = 0;
  358. strcpy(credits[i].fakenames[j++], "Spazzo\n");
  359. j = 0;
  360. strcpy(credits[i].realnames[j++], "Michael Antonakes\n");
  361. credits[i].numnames = (UINT8)j;
  362. i++;
  363. strcpy(credits[i].header, "Sky Sanctuary Team\n");
  364. j = 0;
  365. strcpy(credits[i].fakenames[j++], "Boinciel\n");
  366. strcpy(credits[i].fakenames[j++], "Dark Warrior\n");
  367. strcpy(credits[i].fakenames[j++], "FoxBlitzz\n");
  368. strcpy(credits[i].fakenames[j++], "Jazz\n");
  369. strcpy(credits[i].fakenames[j++], "JEV3\n");
  370. strcpy(credits[i].fakenames[j++], "MattW CFI\n");
  371. strcpy(credits[i].fakenames[j++], "Nev3r\n");
  372. strcpy(credits[i].fakenames[j++], "Senku\n");
  373. strcpy(credits[i].fakenames[j++], "Shadow Hog\n");
  374. strcpy(credits[i].fakenames[j++], "Sonict\n");
  375. strcpy(credits[i].fakenames[j++], "Spazzo\n");
  376. strcpy(credits[i].fakenames[j++], "SRB2 Playah\n");
  377. strcpy(credits[i].fakenames[j++], "ST218\n");
  378. strcpy(credits[i].fakenames[j++], "Tets\n");
  379. strcpy(credits[i].fakenames[j++], "Torgo\n");
  380. strcpy(credits[i].fakenames[j++], "Blade\n");
  381. strcpy(credits[i].fakenames[j++], "KO.T.E\n");
  382. strcpy(credits[i].fakenames[j++], "Chaos Zero 64\n");
  383. strcpy(credits[i].fakenames[j++], "Prime 2\n");
  384. j = 0;
  385. strcpy(credits[i].realnames[j++], "Paul Clempson\n"); // Boinciel
  386. strcpy(credits[i].realnames[j++], "Rob Tisdell\n"); // Dark Warrior
  387. strcpy(credits[i].realnames[j++], "Dan Hagerstrand\n"); // Fox Blitzz
  388. strcpy(credits[i].realnames[j++], "Nathan Giroux\n"); // Jazz
  389. strcpy(credits[i].realnames[j++], "Jarrett Voight\n"); // JEV3
  390. strcpy(credits[i].realnames[j++], "Matthew Walsh\n"); // MattW_CFI
  391. strcpy(credits[i].realnames[j++], "Pedro Iceta\n"); // Nev3r
  392. strcpy(credits[i].realnames[j++], "Andrew Moran\n"); // Senku
  393. strcpy(credits[i].realnames[j++], "Thomas Igoe\n"); // Shadow Hog
  394. strcpy(credits[i].realnames[j++], "Colin Pfaff\n"); // Sonict
  395. strcpy(credits[i].realnames[j++], "Michael Antonakes\n"); // Spazzo
  396. strcpy(credits[i].realnames[j++], "Cody Koester\n"); // SRB2-Playah
  397. strcpy(credits[i].realnames[j++], "Nick Molina\n"); // ST218
  398. strcpy(credits[i].realnames[j++], "Bill Reed\n"); // Tets
  399. strcpy(credits[i].realnames[j++], "Erik Nielsen\n"); // Torgo
  400. strcpy(credits[i].realnames[j++], "Desmond D.\n"); // Blade
  401. strcpy(credits[i].realnames[j++], "Sherman D.\n"); // KO.T.E.
  402. strcpy(credits[i].realnames[j++], "Julio Guir\n"); // Chaos Zero 64
  403. strcpy(credits[i].realnames[j++], "Samuel Peters\n"); // Prime 2
  404. credits[i].numnames = (UINT8)j;
  405. credits[i].smallnames = true;
  406. i++;
  407. strcpy(credits[i].header, "Special Thanks\n");
  408. j = 0;
  409. strcpy(credits[i].fakenames[j++], "Doom Legacy Project\n");
  410. strcpy(credits[i].fakenames[j++], "iD Software\n");
  411. strcpy(credits[i].fakenames[j++], "Dave Perry\n");
  412. strcpy(credits[i].fakenames[j++], "MistaED\n");
  413. strcpy(credits[i].fakenames[j++], "Chrispy\n");
  414. j = 0;
  415. strcpy(credits[i].realnames[j++], "Doom Legacy Project\n");
  416. strcpy(credits[i].realnames[j++], "iD Software\n");
  417. strcpy(credits[i].realnames[j++], "Dave Perry\n");
  418. strcpy(credits[i].realnames[j++], "Alex Fuller\n");
  419. strcpy(credits[i].realnames[j++], "Chris Pryor\n");
  420. credits[i].numnames = (UINT8)j;
  421. i++;
  422. strcpy(credits[i].header, "In Fond Memory Of\n");
  423. j = 0;
  424. strcpy(credits[i].fakenames[j++], "Naoto Oshima\n");
  425. strcpy(credits[i].fakenames[j++], "Howard Drossin\n");
  426. strcpy(credits[i].fakenames[j++], "\n");
  427. strcpy(credits[i].fakenames[j++], "\n");
  428. j = 0;
  429. strcpy(credits[i].realnames[j++], "Naoto Oshima\n");
  430. strcpy(credits[i].realnames[j++], "Howard Drossin\n");
  431. strcpy(credits[i].realnames[j++], "\n");
  432. strcpy(credits[i].realnames[j++], "\n");
  433. credits[i].numnames = (UINT8)j;
  434. i++;
  435. if (modcredits)
  436. {
  437. strcpy(&credits[i].header[0], text[MOD_BY]);
  438. j = 0;
  439. strcpy(credits[i].fakenames[j++], modcreditname);
  440. strcpy(credits[i].fakenames[j++], "\n");
  441. strcpy(credits[i].fakenames[j++], "\n");
  442. j = 0;
  443. strcpy(credits[i].realnames[j++], modcreditname);
  444. strcpy(credits[i].realnames[j++], "\n");
  445. strcpy(credits[i].realnames[j++], "\n");
  446. credits[i].numnames = (UINT8)j;
  447. }
  448. }
  449. static INT32 scenenum, cutnum;
  450. static INT32 picxpos, picypos, picnum, pictime;
  451. static INT32 textxpos, textypos;
  452. void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer)
  453. {
  454. if (!cutscenes[cutscenenum])
  455. return;
  456. G_SetGamestate(GS_CUTSCENE);
  457. gameaction = ga_nothing;
  458. playerdeadview = false;
  459. paused = false;
  460. CON_ToggleOff();
  461. finaletext = cutscenes[cutscenenum]->scene[0].text;
  462. CON_ClearHUD();
  463. runningprecutscene = precutscene;
  464. if (runningprecutscene)
  465. precutresetplayer = resetplayer;
  466. scenenum = picnum = 0;
  467. cutnum = cutscenenum;
  468. picxpos = cutscenes[cutnum]->scene[0].xcoord[0];
  469. picypos = cutscenes[cutnum]->scene[0].ycoord[0];
  470. textxpos = cutscenes[cutnum]->scene[0].textxpos;
  471. textypos = cutscenes[cutnum]->scene[0].textypos;
  472. pictime = cutscenes[cutnum]->scene[0].picduration[0];
  473. keypressed = false;
  474. finalestage = 0;
  475. finalecount = 0;
  476. finaletextcount = 0;
  477. timetonext = 0;
  478. animtimer = cutscenes[cutnum]->scene[0].picduration[0]; // Picture duration
  479. stoptimer = 0;
  480. if (cutscenes[cutnum]->scene[scenenum].musicslot != 0)
  481. S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop);
  482. }
  483. static void F_IntroTextWrite(void);
  484. // Introduction
  485. void F_StartIntro(void)
  486. {
  487. if (introtoplay)
  488. {
  489. F_StartCustomCutscene(introtoplay - 1, false, false);
  490. return;
  491. }
  492. G_SetGamestate(GS_INTRO);
  493. gameaction = ga_nothing;
  494. playerdeadview = false;
  495. paused = false;
  496. CON_ToggleOff();
  497. CON_ClearHUD();
  498. finaletext = text[INTRO01TEXT];
  499. finalestage = finaletextcount = finalecount = animtimer = stoptimer = 0;
  500. roidtics = BASEVIDWIDTH - 64;
  501. scene = 0;
  502. timetonext = introscenetime[scene];
  503. }
  504. // Intro
  505. boolean F_IntroResponder(event_t *event)
  506. {
  507. INT32 key = event->data1;
  508. // remap virtual keys (mouse & joystick buttons)
  509. switch (key)
  510. {
  511. case KEY_MOUSE1:
  512. key = KEY_ENTER;
  513. break;
  514. case KEY_MOUSE1 + 1:
  515. key = KEY_BACKSPACE;
  516. break;
  517. case KEY_JOY1:
  518. case KEY_JOY1 + 2:
  519. key = KEY_ENTER;
  520. break;
  521. case KEY_JOY1 + 3:
  522. key = 'n';
  523. break;
  524. case KEY_JOY1 + 1:
  525. key = KEY_BACKSPACE;
  526. break;
  527. case KEY_HAT1:
  528. key = KEY_UPARROW;
  529. break;
  530. case KEY_HAT1 + 1:
  531. key = KEY_DOWNARROW;
  532. break;
  533. case KEY_HAT1 + 2:
  534. key = KEY_LEFTARROW;
  535. break;
  536. case KEY_HAT1 + 3:
  537. key = KEY_RIGHTARROW;
  538. break;
  539. }
  540. if (event->type != ev_keydown && key != 301)
  541. return false;
  542. if (key != 27 && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
  543. return false;
  544. if (keypressed)
  545. return false;
  546. keypressed = true;
  547. return true;
  548. }
  549. boolean F_CutsceneResponder(event_t *event)
  550. {
  551. if (cutnum == introtoplay-1)
  552. return F_IntroResponder(event);
  553. return false;
  554. }
  555. boolean F_CreditResponder(event_t *event)
  556. {
  557. INT32 key = event->data1;
  558. // remap virtual keys (mouse & joystick buttons)
  559. switch (key)
  560. {
  561. case KEY_MOUSE1:
  562. key = KEY_ENTER;
  563. break;
  564. case KEY_MOUSE1 + 1:
  565. key = KEY_BACKSPACE;
  566. break;
  567. case KEY_JOY1:
  568. case KEY_JOY1 + 2:
  569. key = KEY_ENTER;
  570. break;
  571. case KEY_JOY1 + 3:
  572. key = 'n';
  573. break;
  574. case KEY_JOY1 + 1:
  575. key = KEY_BACKSPACE;
  576. break;
  577. case KEY_HAT1:
  578. key = KEY_UPARROW;
  579. break;
  580. case KEY_HAT1 + 1:
  581. key = KEY_DOWNARROW;
  582. break;
  583. case KEY_HAT1 + 2:
  584. key = KEY_LEFTARROW;
  585. break;
  586. case KEY_HAT1 + 3:
  587. key = KEY_RIGHTARROW;
  588. break;
  589. }
  590. if (!(grade & 1))
  591. return false;
  592. if (event->type != ev_keydown)
  593. return false;
  594. if (key != 27 && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
  595. return false;
  596. if (keypressed)
  597. return true;
  598. keypressed = true;
  599. return true;
  600. }
  601. // De-Demo'd Title Screen
  602. void F_TitleScreenTicker(void)
  603. {
  604. finalecount++;
  605. finalestage += 8;
  606. }
  607. // Game end thingy
  608. //
  609. // F_GameEndTicker
  610. //
  611. void F_GameEndTicker(void)
  612. {
  613. if (timetonext > 0)
  614. timetonext--;
  615. else
  616. D_StartTitle();
  617. }
  618. void F_GameEvaluationTicker(void)
  619. {
  620. finalecount++;
  621. if (finalecount > 10*TICRATE)
  622. F_StartGameEnd();
  623. }
  624. void F_CreditTicker(void)
  625. {
  626. finalecount++;
  627. if (finalecount > 90*TICRATE)
  628. F_StartGameEvaluation();
  629. }
  630. //
  631. // F_IntroTicker
  632. //
  633. void F_IntroTicker(void)
  634. {
  635. // advance animation
  636. finalecount++;
  637. finaletextcount++;
  638. if (finalecount % 3 == 0)
  639. roidtics--;
  640. timetonext--;
  641. // check for skipping
  642. if (keypressed)
  643. keypressed = false;
  644. }
  645. void F_CutsceneTicker(void)
  646. {
  647. INT32 i;
  648. // advance animation
  649. finalecount++;
  650. finaletextcount++;
  651. for (i = 0; i < MAXPLAYERS; i++)
  652. {
  653. if (netgame && i != serverplayer && i != adminplayer)
  654. continue;
  655. if (players[i].cmd.buttons & BT_USE)
  656. {
  657. keypressed = false;
  658. finaletextcount += 64;
  659. if (timetonext)
  660. timetonext = 2;
  661. }
  662. }
  663. }
  664. //
  665. // F_WriteText
  666. //
  667. static void F_WriteText(INT32 cx, INT32 cy)
  668. {
  669. INT32 count, c, w, originalx = cx;
  670. const char *ch = finaletext; // draw some of the text onto the screen
  671. count = (finaletextcount - 10)/2;
  672. if (count < 0)
  673. count = 0;
  674. if (timetonext == 1 || !ch)
  675. {
  676. finaletextcount = 0;
  677. timetonext = 0;
  678. roidtics = BASEVIDWIDTH - 64;
  679. return;
  680. }
  681. for (; count; count--)
  682. {
  683. c = *ch++;
  684. if (!c)
  685. break;
  686. if (c == '#')
  687. {
  688. if (!timetonext)
  689. {
  690. if (finaletext == text[INTRO16TEXT])
  691. timetonext = 12*TICRATE + 1;
  692. else
  693. timetonext = 5*TICRATE + 1;
  694. }
  695. break;
  696. }
  697. if (c == '\n')
  698. {
  699. cx = originalx;
  700. cy += 12;
  701. continue;
  702. }
  703. c = toupper(c) - HU_FONTSTART;
  704. if (c < 0 || (c >= HU_REALFONTSIZE && c != '~' - HU_FONTSTART && c != '`' - HU_FONTSTART)) /// \note font end hack
  705. {
  706. cx += 4;
  707. continue;
  708. }
  709. w = SHORT(hu_font[c]->width);
  710. if (cx + w > vid.width)
  711. break;
  712. V_DrawScaledPatch(cx, cy, 0, hu_font[c]);
  713. cx += w;
  714. }
  715. }
  716. static void F_WriteCutsceneText(void)
  717. {
  718. INT32 count, c, w, originalx = textxpos, cx = textxpos, cy = textypos;
  719. const char *ch = finaletext; // draw some of the text onto the screen
  720. count = (finaletextcount - 10)/2;
  721. if (count < 0)
  722. count = 0;
  723. if (timetonext == 1 || !ch)
  724. {
  725. finaletextcount = 0;
  726. timetonext = 0;
  727. roidtics = BASEVIDWIDTH - 64;
  728. return;
  729. }
  730. for (; count; count--)
  731. {
  732. c = *ch++;
  733. if (!c)
  734. break;
  735. if (c == '#')
  736. {
  737. if (!timetonext)
  738. timetonext = 5*TICRATE + 1;
  739. break;
  740. }
  741. if (c == '\n')
  742. {
  743. cx = originalx;
  744. cy += 12;
  745. continue;
  746. }
  747. c = toupper(c) - HU_FONTSTART;
  748. if (c < 0 || (c >= HU_REALFONTSIZE && c != '~' - HU_FONTSTART && c != '`' - HU_FONTSTART))
  749. { /// \note font end hack
  750. cx += 4;
  751. continue;
  752. }
  753. w = SHORT(hu_font[c]->width);
  754. if (cx + w > vid.width)
  755. break;
  756. V_DrawScaledPatch(cx, cy, 0, hu_font[c]);
  757. cx += w;
  758. }
  759. }
  760. //
  761. // F_IntroTextWrite
  762. //
  763. static void F_IntroTextWrite(void)
  764. {
  765. boolean nobg = false, highres = false;
  766. INT32 cx = 8, cy = 128;
  767. // DRAW A FULL PIC INSTEAD OF FLAT!
  768. if (finaletext == text[INTRO01TEXT])
  769. nobg = true;
  770. else if (finaletext == text[INTRO02TEXT])
  771. background = W_CachePatchName("INTRO1", PU_CACHE);
  772. else if (finaletext == text[INTRO03TEXT])
  773. {
  774. background = W_CachePatchName("INTRO2", PU_CACHE);
  775. highres = true;
  776. }
  777. else if (finaletext == text[INTRO04TEXT])
  778. background = W_CachePatchName("INTRO3", PU_CACHE);
  779. else if (finaletext == text[INTRO05TEXT])
  780. background = W_CachePatchName("INTRO4", PU_CACHE);
  781. else if (finaletext == text[INTRO06TEXT])
  782. {
  783. background = W_CachePatchName("DRAT", PU_CACHE);
  784. highres = true;
  785. }
  786. else if (finaletext == text[INTRO07TEXT])
  787. {
  788. background = W_CachePatchName("INTRO6", PU_CACHE);
  789. cx = 180;
  790. cy = 8;
  791. }
  792. else if (finaletext == text[INTRO08TEXT])
  793. background = W_CachePatchName("SGRASS1", PU_CACHE);
  794. else if (finaletext == text[INTRO09TEXT])
  795. {
  796. background = W_CachePatchName("WATCHING", PU_CACHE);
  797. highres = true;
  798. }
  799. else if (finaletext == text[INTRO10TEXT])
  800. {
  801. background = W_CachePatchName("ZOOMING", PU_CACHE);
  802. highres = true;
  803. }
  804. else if (finaletext == text[INTRO11TEXT])
  805. nobg = true;
  806. else if (finaletext == text[INTRO12TEXT])
  807. background = W_CachePatchName("INTRO5", PU_CACHE);
  808. else if (finaletext == text[INTRO13TEXT])
  809. {
  810. background = W_CachePatchName("REVENGE", PU_CACHE);
  811. highres = true;
  812. }
  813. else if (finaletext == text[INTRO14TEXT])
  814. {
  815. nobg = true;
  816. cx = 8;
  817. cy = 8;
  818. }
  819. else if (finaletext == text[INTRO15TEXT])
  820. {
  821. background = W_CachePatchName("SONICDO1", PU_CACHE);
  822. highres = true;
  823. cx = 224;
  824. cy = 8;
  825. }
  826. else if (finaletext == text[INTRO16TEXT])
  827. {
  828. background = W_CachePatchName("INTRO7", PU_CACHE);
  829. highres = true;
  830. }
  831. V_DrawFill(0, 0, vid.width, vid.height, 31);
  832. if (finaletext == text[INTRO01TEXT])
  833. {
  834. V_DrawCreditString(160 - (V_CreditStringWidth("SONIC TEAM JR")/2), 80, 0, "SONIC TEAM JR");
  835. V_DrawCreditString(160 - (V_CreditStringWidth("PRESENTS")/2), 96, 0, "PRESENTS");
  836. }
  837. else if (finaletext == text[INTRO11TEXT])
  838. {
  839. if (finaletextcount > 8*TICRATE && finaletextcount < 9*TICRATE)
  840. {
  841. if (!(finalecount & 3))
  842. background = W_CachePatchName("BRITEGG1", PU_CACHE);
  843. else
  844. background = W_CachePatchName("DARKEGG1", PU_CACHE);
  845. V_DrawScaledPatch(0, 0, 0, background);
  846. }
  847. else if (finaletextcount > 10*TICRATE && finaletextcount < 11*TICRATE)
  848. {
  849. if (!(finalecount & 3))
  850. background = W_CachePatchName("BRITEGG2", PU_CACHE);
  851. else
  852. background = W_CachePatchName("DARKEGG2", PU_CACHE);
  853. V_DrawScaledPatch(0, 0, 0, background);
  854. }
  855. else if (finaletextcount > 12*TICRATE && finaletextcount < 13*TICRATE)
  856. {
  857. if (!(finalecount & 3))
  858. background = W_CachePatchName("BRITEGG3", PU_CACHE);
  859. else
  860. background = W_CachePatchName("DARKEGG3", PU_CACHE);
  861. V_DrawScaledPatch(0, 0, 0, background);
  862. }
  863. else
  864. {
  865. F_SkyScroll();
  866. if (timetonext == 6)
  867. {
  868. stoptimer = finalecount;
  869. animtimer = finalecount % 16;
  870. }
  871. else if (timetonext >= 0 && timetonext < 6)
  872. {
  873. animtimer = stoptimer;
  874. deplete -= 32;
  875. }
  876. else
  877. {
  878. animtimer = finalecount % 16;
  879. deplete = 160;
  880. }
  881. if (finalecount & 1)
  882. {
  883. V_DrawScaledPatch(deplete, 8, 0, W_CachePatchName("RUN2", PU_CACHE));
  884. V_DrawScaledPatch(deplete, 72, 0, W_CachePatchName("PEELOUT2", PU_CACHE));
  885. }
  886. else
  887. {
  888. V_DrawScaledPatch(deplete, 8, 0, W_CachePatchName("RUN1", PU_CACHE));
  889. V_DrawScaledPatch(deplete, 72, 0, W_CachePatchName("PEELOUT1", PU_CACHE));
  890. }
  891. V_DrawFill(0, 112, vid.width, (INT32)(vid.height - 112*vid.fdupy), 31);
  892. }
  893. }
  894. else if (finaletext == text[INTRO08TEXT] && timetonext > 0 && finaletextcount >= 5*TICRATE
  895. && finaletextcount > 0)
  896. {
  897. background = W_CachePatchName("SGRASS5", PU_CACHE);
  898. }
  899. if (!nobg)
  900. {
  901. if (highres)
  902. V_DrawSmallScaledPatch(0, 0, 0, background);
  903. else
  904. V_DrawScaledPatch(0, 0, 0, background);
  905. }
  906. if (finaletext == text[INTRO14TEXT])
  907. {
  908. V_DrawFill(0, 0, vid.width, vid.height, 31);
  909. V_DrawSmallScaledPatch(144, 0, 0, W_CachePatchName("TAILSSAD", PU_CACHE));
  910. }
  911. else if (finaletext == text[INTRO05TEXT]) // The asteroid SPINS!
  912. {
  913. if (roidtics >= 0)
  914. V_DrawScaledPatch(roidtics, 24, 0,
  915. W_CachePatchName(va("ROID00%.2d", finaletextcount%35), PU_CACHE));
  916. }
  917. else if (finaletext == text[INTRO06TEXT])
  918. {
  919. if (finaletextcount == 5*TICRATE + (TICRATE/5)*3)
  920. {
  921. if (rendermode != render_none)
  922. {
  923. F_WriteText(cx, cy);
  924. F_WipeStartScreen();
  925. V_DrawScaledPatch(0, 0, 0, W_CachePatchName("RADAR", PU_CACHE));
  926. // draw some of the text onto the screen
  927. F_WriteText(cx, cy);
  928. F_WipeEndScreen(0, 0, vid.width, vid.height);
  929. F_RunWipe(TICRATE, true);
  930. }
  931. }
  932. else if (finaletextcount > 5*TICRATE+(TICRATE/5)*3)
  933. V_DrawScaledPatch(0, 0, 0, W_CachePatchName("RADAR", PU_CACHE));
  934. }
  935. else if (finaletext == text[INTRO13TEXT])
  936. {
  937. if (finaletextcount == 9*TICRATE)
  938. {
  939. if (rendermode != render_none)
  940. {
  941. F_WriteText(cx, cy);
  942. F_WipeStartScreen();
  943. V_DrawSmallScaledPatch(0, 0, 0, W_CachePatchName("CONFRONT", PU_CACHE));
  944. // draw some of the text onto the screen
  945. F_WriteText(cx, cy);
  946. F_WipeEndScreen(0, 0, vid.width, vid.height);
  947. F_RunWipe(TICRATE, true);
  948. }
  949. }
  950. else if (finaletextcount > 9*TICRATE)
  951. V_DrawSmallScaledPatch(0, 0, 0, W_CachePatchName("CONFRONT", PU_CACHE));
  952. }
  953. else if (finaletext == text[INTRO15TEXT])
  954. {
  955. if (finaletextcount == 7*TICRATE)
  956. {
  957. if (rendermode != render_none)
  958. {
  959. F_WriteText(cx, cy);
  960. F_WipeStartScreen();
  961. V_DrawSmallScaledPatch(0, 0, 0, W_CachePatchName("SONICDO2", PU_CACHE));
  962. // draw some of the text onto the screen
  963. F_WriteText(cx, cy);
  964. F_WipeEndScreen(0, 0, vid.width, vid.height);
  965. F_RunWipe(TICRATE, true);
  966. }
  967. }
  968. else if (finaletextcount > 7*TICRATE)
  969. V_DrawSmallScaledPatch(0, 0, 0, W_CachePatchName("SONICDO2", PU_CACHE));
  970. }
  971. if (animtimer)
  972. animtimer--;
  973. if (finaletext == text[INTRO08TEXT] && finaletextcount > 5*TICRATE)
  974. {
  975. first = W_CachePatchName("SGRASS2", PU_CACHE);
  976. second = W_CachePatchName("SGRASS3", PU_CACHE);
  977. third = W_CachePatchName("SGRASS4", PU_CACHE);
  978. if (finaletextcount == 5*TICRATE + 1)
  979. {
  980. currentanim = first;
  981. nextanim = second;
  982. animtimer = TICRATE/7 + 1;
  983. }
  984. else if (animtimer == 1 && currentanim == first)
  985. {
  986. currentanim = second;
  987. nextanim = third;
  988. animtimer = TICRATE/7 + 1;
  989. }
  990. else if (animtimer == 1 && currentanim == second)
  991. currentanim = third;
  992. if (currentanim)
  993. V_DrawScaledPatch(123, 4, 0, currentanim);
  994. }
  995. F_WriteText(cx, cy);
  996. }
  997. //
  998. // F_DrawPatchCol
  999. //
  1000. static void F_DrawPatchCol(INT32 x, patch_t *patch, INT32 col, INT32 yrepeat)
  1001. {
  1002. const column_t *column;
  1003. const UINT8 *source;
  1004. UINT8 *desttop, *dest = NULL;
  1005. const UINT8 *deststop;
  1006. size_t count;
  1007. column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col]));
  1008. desttop = screens[0] + x*vid.dupx;
  1009. deststop = screens[0] + vid.width * vid.height * vid.bpp;
  1010. // step through the posts in a column
  1011. while (column->topdelta != 0xff)
  1012. {
  1013. source = (const UINT8 *)column + 3;
  1014. dest = desttop + column->topdelta*vid.width;
  1015. count = column->length;
  1016. while (count--)
  1017. {
  1018. INT32 dupycount = vid.dupy;
  1019. while (dupycount--)
  1020. {
  1021. INT32 dupxcount = vid.dupx;
  1022. while (dupxcount-- && dest <= deststop)
  1023. *dest++ = *source;
  1024. dest += (vid.width - vid.dupx);
  1025. }
  1026. source++;
  1027. }
  1028. column = (const column_t *)((const UINT8 *)column + column->length + 4);
  1029. }
  1030. // repeat a second time, for yrepeat number of pixels
  1031. if (yrepeat)
  1032. {
  1033. column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col]));
  1034. while (column->topdelta != 0xff)
  1035. {
  1036. source = (const UINT8 *)column + 3;
  1037. count = column->length;
  1038. while (count--)
  1039. {
  1040. INT32 dupycount = vid.dupy;
  1041. while (dupycount--)
  1042. {
  1043. INT32 dupxcount = vid.dupx;
  1044. while (dupxcount-- && dest <= deststop)
  1045. *dest++ = *source;
  1046. dest += (vid.width - vid.dupx);
  1047. }
  1048. source++;
  1049. }
  1050. if (!--yrepeat)
  1051. break;
  1052. column = (const column_t *)((const UINT8 *)column + column->length + 4);
  1053. }
  1054. }
  1055. }
  1056. //
  1057. // F_SkyScroll
  1058. //
  1059. static void F_SkyScroll(void)
  1060. {
  1061. INT32 scrolled, x, mx, fakedwidth;
  1062. patch_t *pat;
  1063. pat = W_CachePatchName("TITLESKY", PU_CACHE);
  1064. animtimer = ((finalecount*((gamestate == GS_INTRO || gamestate == GS_INTRO2) ? titlescrollspeed*4 : titlescrollspeed))/16) % SHORT(pat->width);
  1065. fakedwidth = vid.width / vid.dupx;
  1066. if (rendermode == render_soft)
  1067. {
  1068. INT32 yr = 0;
  1069. if (vid.fdupy > vid.dupy)
  1070. yr = vid.height - vid.dupy*SHORT(pat->height);
  1071. scrolled = BASEVIDWIDTH - animtimer;
  1072. if (scrolled > BASEVIDWIDTH)
  1073. scrolled = BASEVIDWIDTH;
  1074. if (scrolled < 0)
  1075. scrolled = 0;
  1076. for (x = 0, mx = 0; x < fakedwidth; x++, mx++)
  1077. {
  1078. if (mx >= SHORT(pat->width))
  1079. mx = 0;
  1080. if (mx + scrolled < SHORT(pat->width))
  1081. F_DrawPatchCol(x, pat, mx + scrolled, yr);
  1082. else
  1083. F_DrawPatchCol(x, pat, mx + scrolled - SHORT(pat->width), yr);
  1084. }
  1085. }
  1086. #ifdef HWRENDER
  1087. else if (rendermode != render_none)
  1088. { // I wish it were as easy as this for software. I really do.
  1089. scrolled = animtimer;
  1090. if (scrolled > 0)
  1091. V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat);
  1092. while(scrolled < BASEVIDWIDTH)
  1093. {
  1094. V_DrawScaledPatch(scrolled, 0, 0, pat);
  1095. scrolled += SHORT(pat->width);
  1096. }
  1097. }
  1098. #endif
  1099. }
  1100. // De-Demo'd Title Screen
  1101. void F_TitleScreenDrawer(void)
  1102. {
  1103. // Draw that sky!
  1104. F_SkyScroll();
  1105. V_DrawScaledPatch(30, 14, 0, ttwing);
  1106. if (finalecount < 57)
  1107. {
  1108. if (finalecount == 35)
  1109. V_DrawScaledPatch(115, 15, 0, ttspop1);
  1110. else if (finalecount == 36)
  1111. V_DrawScaledPatch(114, 15, 0,ttspop2);
  1112. else if (finalecount == 37)
  1113. V_DrawScaledPatch(113, 15, 0,ttspop3);
  1114. else if (finalecount == 38)
  1115. V_DrawScaledPatch(112, 15, 0,ttspop4);
  1116. else if (finalecount == 39)
  1117. V_DrawScaledPatch(111, 15, 0,ttspop5);
  1118. else if (finalecount == 40)
  1119. V_DrawScaledPatch(110, 15, 0, ttspop6);
  1120. else if (finalecount >= 41 && finalecount <= 44)
  1121. V_DrawScaledPatch(109, 15, 0, ttspop7);
  1122. else if (finalecount >= 45 && finalecount <= 48)
  1123. V_DrawScaledPatch(108, 12, 0, ttsprep1);
  1124. else if (finalecount >= 49 && finalecount <= 52)
  1125. V_DrawScaledPatch(107, 9, 0, ttsprep2);
  1126. else if (finalecount >= 53 && finalecount <= 56)
  1127. V_DrawScaledPatch(106, 6, 0, ttswip1);
  1128. V_DrawScaledPatch(93, 106, 0, ttsonic);
  1129. }
  1130. else
  1131. {
  1132. V_DrawScaledPatch(93, 106, 0,ttsonic);
  1133. if (finalecount/5 & 1)
  1134. V_DrawScaledPatch(100, 3, 0,ttswave1);
  1135. else
  1136. V_DrawScaledPatch(100,3, 0,ttswave2);
  1137. }
  1138. V_DrawScaledPatch(48, 142, 0,ttbanner);
  1139. }
  1140. // Game End Sequence
  1141. //
  1142. // F_GameEndDrawer
  1143. //
  1144. void F_GameEndDrawer(void)
  1145. {
  1146. }
  1147. #define INTERVAL 50
  1148. #define TRANSLEVEL V_8020TRANS
  1149. void F_GameEvaluationDrawer(void)
  1150. {
  1151. INT32 x, y;
  1152. const fixed_t radius = 48*FRACUNIT;
  1153. angle_t fa;
  1154. V_DrawFill(0, 0, vid.width, vid.height, 31);
  1155. // Draw all the good crap here.
  1156. if (animtimer == 64)
  1157. V_DrawString(114, 16, 0, "GOT THEM ALL!");
  1158. else
  1159. V_DrawString(124, 16, 0, "TRY AGAIN!");
  1160. finalestage++;
  1161. timetonext = finalestage;
  1162. fa = (FixedAngle(timetonext*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
  1163. x = 160 + FixedInt(FixedMul(FINECOSINE(fa),radius));
  1164. y = 100 + FixedInt(FixedMul(FINESINE(fa),radius));
  1165. if (emeralds & EMERALD1)
  1166. V_DrawScaledPatch(x, y, 0, W_CachePatchName("CEMGA0", PU_CACHE));
  1167. else
  1168. V_DrawTranslucentPatch(x, y, TRANSLEVEL|V_TOPLEFT, W_CachePatchName("CEMGA0", PU_CACHE));
  1169. timetonext += INTERVAL;
  1170. fa = (FixedAngle(timetonext*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
  1171. x = 160 + FixedInt(FixedMul(FINECOSINE(fa),radius));
  1172. y = 100 + FixedInt(FixedMul(FINESINE(fa),radius));
  1173. if (emeralds & EMERALD2)
  1174. V_DrawScaledPatch(x, y, 0, W_CachePatchName("CEMGB0", PU_CACHE));
  1175. else
  1176. V_DrawTranslucentPatch(x, y, TRANSLEVEL|V_TOPLEFT, W_CachePatchName("CEMGB0", PU_CACHE));
  1177. timetonext += INTERVAL;
  1178. fa = (FixedAngle(timetonext*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
  1179. x = 160 + FixedInt(FixedMul(FINECOSINE(fa),radius));
  1180. y = 100 + FixedInt(FixedMul(FINESINE(fa),radius));
  1181. if (emeralds & EMERALD3)
  1182. V_DrawScaledPatch(x, y, 0, W_CachePatchName("CEMGC0", PU_CACHE));
  1183. else
  1184. V_DrawTranslucentPatch(x, y, TRANSLEVEL|V_TOPLEFT, W_CachePatchName("CEMGC0", PU_CACHE));
  1185. timetonext += INTERVAL;
  1186. fa = (FixedAngle(timetonext*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
  1187. x = 160 + FixedInt(FixedMul(FINECOSINE(fa),radius));
  1188. y = 100 + FixedInt(FixedMul(FINESINE(fa),radius));
  1189. if (emeralds & EMERALD4)
  1190. V_DrawScaledPatch(x, y, 0, W_CachePatchName("CEMGD0", PU_CACHE));
  1191. else
  1192. V_DrawTranslucentPatch(x, y, TRANSLEVEL|V_TOPLEFT, W_CachePatchName("CEMGD0", PU_CACHE));
  1193. timetonext += INTERVAL;
  1194. fa = (FixedAngle(timetonext*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
  1195. x = 160 + FixedInt(FixedMul(FINECOSINE(fa),radius));
  1196. y = 100 + FixedInt(FixedMul(FINESINE(fa),radius));
  1197. if (emeralds & EMERALD5)
  1198. V_DrawScaledPatch(x, y, 0, W_CachePatchName("CEMGE0", PU_CACHE));
  1199. else
  1200. V_DrawTranslucentPatch(x, y, TRANSLEVEL|V_TOPLEFT, W_CachePatchName("CEMGE0", PU_CACHE));
  1201. timetonext += INTERVAL;
  1202. fa = (FixedAngle(timetonext*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
  1203. x = 160 + FixedInt(FixedMul(FINECOSINE(fa),radius));
  1204. y = 100 + FixedInt(FixedMul(FINESINE(fa),radius));
  1205. if (emeralds & EMERALD6)
  1206. V_DrawScaledPatch(x, y, 0, W_CachePatchName("CEMGF0", PU_CACHE));
  1207. else
  1208. V_DrawTranslucentPatch(x, y, TRANSLEVEL|V_TOPLEFT, W_CachePatchName("CEMGF0", PU_CACHE));
  1209. timetonext += INTERVAL;
  1210. fa = (FixedAngle(timetonext*FRACUNIT)>>ANGLETOFINESHIFT) & FINEMASK;
  1211. x = 160 + FixedInt(FixedMul(FINECOSINE(fa),radius));
  1212. y = 100 + FixedInt(FixedMul(FINESINE(fa),radius));
  1213. if (emeralds & EMERALD7)
  1214. V_DrawScaledPatch(x, y, 0, W_CachePatchName("CEMGG0", PU_CACHE));
  1215. else
  1216. V_DrawTranslucentPatch(x, y, TRANSLEVEL|V_TOPLEFT, W_CachePatchName("CEMGG0", PU_CACHE));
  1217. if (finalestage >= 360)
  1218. finalestage -= 360;
  1219. if (finalecount == 5*TICRATE)
  1220. {
  1221. if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && mapheaderinfo[gamemap-1].nextlevel == 1102)
  1222. {
  1223. boolean alreadyplayed = false;
  1224. INT32 bitcount = 0;
  1225. INT32 i;
  1226. if (!(emblemlocations[MAXEMBLEMS-2].collected))
  1227. {
  1228. emblemlocations[MAXEMBLEMS-2].collected = true; // For completing the game.
  1229. S_StartSound(NULL, sfx_ncitem);
  1230. alreadyplayed = true;
  1231. drawemblem = true;
  1232. }
  1233. if (ALL7EMERALDS(emeralds))
  1234. {
  1235. if (!(emblemlocations[MAXEMBLEMS-1].collected))
  1236. {
  1237. emblemlocations[MAXEMBLEMS-1].collected = true;
  1238. if (!alreadyplayed)
  1239. S_StartSound(NULL, sfx_ncitem);
  1240. drawchaosemblem = true;
  1241. }
  1242. grade |= 2;
  1243. }
  1244. for (i = 0; i < MAXEMBLEMS; i++)
  1245. {
  1246. if (emblemlocations[i].collected)
  1247. bitcount++;
  1248. }
  1249. if (bitcount >= numemblems/2) // Got half of the emblems
  1250. grade |= 4;
  1251. if (bitcount >= numemblems/4) // NiGHTS
  1252. grade |= 16;
  1253. if (bitcount == numemblems) // Got ALL emblems!
  1254. grade |= 8;
  1255. grade |= 1; // Just for completing the game.
  1256. timesbeaten++;
  1257. // An award for beating ultimate mode, perhaps?
  1258. if (ultimatemode)
  1259. grade |= 256;
  1260. // Other unlockables
  1261. if (gamemap == 29) // Cleared NiGHTS
  1262. grade |= 64;
  1263. else if (gamemap == 32) // Cleared Mario
  1264. grade |= 32;
  1265. else if (gamemap == 132) // Cleared SRB1
  1266. grade |= 1024;
  1267. if (cursaveslot != -1)
  1268. G_SaveGame((UINT32)cursaveslot);
  1269. }
  1270. }
  1271. G_SaveGameData();
  1272. if (finalecount >= 5*TICRATE)
  1273. {
  1274. if (drawemblem)
  1275. V_DrawScaledPatch(120, 192, 0, W_CachePatchName("NWNGA0", PU_CACHE));
  1276. if (drawchaosemblem)
  1277. V_DrawScaledPatch(200, 192, 0, W_CachePatchName("NWNGA0", PU_CACHE));
  1278. V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:");
  1279. if (savemoddata)
  1280. {
  1281. INT32 i;
  1282. boolean unlocked;
  1283. INT32 startcoord = 32;
  1284. for (i = 0; i < 15; i++)
  1285. {
  1286. unlocked = false;
  1287. if (customsecretinfo[i].neededemblems)
  1288. {
  1289. unlocked = M_GotEnoughEmblems(customsecretinfo[i].neededemblems);
  1290. if (unlocked && customsecretinfo[i].neededtime)
  1291. unlocked = M_GotLowEnoughTime(customsecretinfo[i].neededtime);
  1292. }
  1293. else if (customsecretinfo[i].neededtime)
  1294. unlocked = M_GotLowEnoughTime(customsecretinfo[i].neededtime);
  1295. else
  1296. unlocked = (grade & customsecretinfo[i].neededgrade);
  1297. if (unlocked)
  1298. {
  1299. V_DrawString(8, startcoord, 0, customsecretinfo[i].name);
  1300. startcoord += 8;
  1301. }
  1302. }
  1303. }
  1304. else
  1305. {
  1306. if (grade & 1)
  1307. V_DrawString(8, 32, 0, "Level Select");
  1308. if (grade & 2)
  1309. V_DrawString(8, 40, 0, "SRB1 Remake");
  1310. if (grade & 4)
  1311. V_DrawString(8, 48, 0, "Mario");
  1312. if (grade & 8)
  1313. V_DrawString(8, 56, 0, "Pandora's Box");
  1314. if (grade & 16)
  1315. V_DrawString(8, 64, 0, "NiGHTS");
  1316. if (netgame)
  1317. V_DrawString(8, 96, V_YELLOWMAP, "Prizes only\nawarded in\nsingle player!");
  1318. else if (modifiedgame)
  1319. V_DrawString(8, 96, V_YELLOWMAP, "Prizes not\nawarded in\nmodified games!");
  1320. }
  1321. }
  1322. }
  1323. static void F_DrawCreditScreen(credit_t *creditpassed)
  1324. {
  1325. INT32 i, height, y;
  1326. if (creditpassed->smallnames)
  1327. height = BASEVIDHEIGHT/((creditpassed->numnames/2)+1);
  1328. else
  1329. height = BASEVIDHEIGHT/(creditpassed->numnames+1);
  1330. switch (animtimer)
  1331. {
  1332. case 1:
  1333. case 2:
  1334. if (ultimatemode)
  1335. V_DrawSmallScaledPatch(204, 118, 0, W_CachePatchName("ACRED02", PU_CACHE));
  1336. else
  1337. V_DrawSmallScaledPatch(8, 112, 0, W_CachePatchName("CREDIT01", PU_CACHE));
  1338. break;
  1339. case 3:
  1340. case 4:
  1341. if (ultimatemode)
  1342. {
  1343. V_DrawSmallScaledPatch(234, 118, 0, W_CachePatchName("ACRED01", PU_CACHE));
  1344. V_DrawSmallScaledPatch(4, 4, 0, W_CachePatchName("ACRED03", PU_CACHE));
  1345. }
  1346. else
  1347. {
  1348. V_DrawSmallScaledPatch(4, 4, 0, W_CachePatchName("CREDIT13", PU_CACHE));
  1349. V_DrawSmallScaledPatch(250, 100, 0, W_CachePatchName("CREDIT12", PU_CACHE));
  1350. }
  1351. break;
  1352. case 5:
  1353. if (ultimatemode)
  1354. V_DrawSmallScaledPatch(4, 72, 0, W_CachePatchName("ACRED04", PU_CACHE));
  1355. else
  1356. V_DrawSmallScaledPatch(8, 0, 0, W_CachePatchName("CREDIT03", PU_CACHE));
  1357. break;
  1358. case 6:
  1359. if (ultimatemode)
  1360. V_DrawSmallScaledPatch(55, 0, 0, W_CachePatchName("ACRED05", PU_CACHE));
  1361. else
  1362. V_DrawSmallScaledPatch(248, 110, 0, W_CachePatchName("CREDIT11", PU_CACHE));
  1363. break;
  1364. case 7:
  1365. case 8:
  1366. if (ultimatemode)
  1367. V_DrawSmallScaledPatch(8, 108, 0, W_CachePatchName("ACRED06", PU_CACHE));
  1368. else
  1369. V_DrawSmallScaledPatch(8, 112, 0, W_CachePatchName("CREDIT04", PU_CACHE));
  1370. break;
  1371. case 9:
  1372. if (ultimatemode)
  1373. V_DrawSmallScaledPatch((BASEVIDWIDTH/2) - 46, 102, 0, W_CachePatchName("ACRED07", PU_CACHE));
  1374. else
  1375. V_DrawSmallScaledPatch((BASEVIDWIDTH/2) - 48, 108, 0, W_CachePatchName("CREDIT10", PU_CACHE));
  1376. break;
  1377. case 10:
  1378. if (ultimatemode)
  1379. V_DrawSmallScaledPatch(202, 128, 0, W_CachePatchName("ACRED09", PU_CACHE));
  1380. else
  1381. V_DrawSmallScaledPatch(240, 8, 0, W_CachePatchName("CREDIT05", PU_CACHE));
  1382. break;
  1383. case 11:
  1384. case 12:
  1385. if (ultimatemode)
  1386. V_DrawSmallScaledPatch((BASEVIDWIDTH/2) - 46, 102, 0, W_CachePatchName("ACRED11", PU_CACHE));
  1387. else
  1388. V_DrawSmallScaledPatch(120, 120, 0, W_CachePatchName("CREDIT06", PU_CACHE));
  1389. break;
  1390. case 13:
  1391. case 14:
  1392. if (ultimatemode)
  1393. {
  1394. V_DrawSmallScaledPatch(174, 84, 0, W_CachePatchName("ACRED08", PU_CACHE));
  1395. V_DrawSmallScaledPatch(2, 64, 0, W_CachePatchName("ACRED10", PU_CACHE));
  1396. }
  1397. else
  1398. V_DrawSmallScaledPatch(8, 100, 0, W_CachePatchName("CREDIT07", PU_CACHE));
  1399. break;
  1400. case 15:
  1401. case 16:
  1402. if (ultimatemode)
  1403. {
  1404. V_DrawSmallScaledPatch(174, 84, 0, W_CachePatchName("ACRED08", PU_CACHE));
  1405. V_DrawSmallScaledPatch(2, 52, 0, W_CachePatchName("ACRED10", PU_CACHE));
  1406. }
  1407. else
  1408. V_DrawSmallScaledPatch(8, 0, 0, W_CachePatchName("CREDIT08", PU_CACHE));
  1409. break;
  1410. case 17:
  1411. case 18:
  1412. V_DrawSmallScaledPatch(112, 104, 0, W_CachePatchName("CREDIT09", PU_CACHE));
  1413. break;
  1414. }
  1415. if (creditpassed->numnames == 1) // Shift it up a bit
  1416. height -= 16;
  1417. V_DrawCreditString((BASEVIDWIDTH - V_CreditStringWidth(creditpassed->header))/2, height, 0,
  1418. creditpassed->header);
  1419. if (creditpassed->smallnames)
  1420. height += 32;
  1421. y = 0;
  1422. for (i = 0; i < creditpassed->numnames; i++)
  1423. {
  1424. if (creditpassed->smallnames)
  1425. {
  1426. INT32 x;
  1427. if (cv_realnames.value)
  1428. {
  1429. if (i < creditpassed->numnames/2)
  1430. x = (BASEVIDWIDTH/4) - (V_StringWidth(creditpassed->realnames[i])/2);
  1431. else
  1432. x = ((BASEVIDWIDTH/4)*3) - (V_StringWidth(creditpassed->realnames[i])/2);
  1433. V_DrawString(x,
  1434. height + y - 8, 0, creditpassed->realnames[i]); //shifted up to prevent cutoff. -Spazzo
  1435. }
  1436. else
  1437. {
  1438. if (i < creditpassed->numnames/2)
  1439. x = (BASEVIDWIDTH/4) - (V_StringWidth(creditpassed->fakenames[i])/2);
  1440. else
  1441. x = ((BASEVIDWIDTH/4)*3) - (V_StringWidth(creditpassed->fakenames[i])/2);
  1442. V_DrawString(x,
  1443. height + y - 8, 0, creditpassed->fakenames[i]);
  1444. }
  1445. y += 16;
  1446. if (i + 1 == creditpassed->numnames/2)
  1447. y = 0;
  1448. }
  1449. else
  1450. {
  1451. if (cv_realnames.value)
  1452. V_DrawCreditString((BASEVIDWIDTH - V_CreditStringWidth(creditpassed->realnames[i]))/2,
  1453. height + (1+i)*24, 0, creditpassed->realnames[i]);
  1454. else
  1455. V_DrawCreditString((BASEVIDWIDTH - V_CreditStringWidth(creditpassed->fakenames[i]))/2,
  1456. height + (1+i)*24, 0, creditpassed->fakenames[i]);
  1457. }
  1458. }
  1459. }
  1460. void F_CreditDrawer(void)
  1461. {
  1462. V_DrawFill(0, 0, vid.width, vid.height, 31);
  1463. if (timetonext-- <= 0) // Fade to the next!
  1464. {
  1465. if (modcredits)
  1466. timetonext = 165*NEWTICRATERATIO;
  1467. else
  1468. timetonext = 5*TICRATE-1;
  1469. F_DrawCreditScreen(&credits[animtimer]);
  1470. animtimer++;
  1471. if (rendermode != render_none)
  1472. {
  1473. F_WipeStartScreen();
  1474. V_DrawFill(0, 0, vid.width, vid.height, 31);
  1475. F_DrawCreditScreen(&credits[animtimer]);
  1476. F_WipeEndScreen(0, 0, vid.width, vid.height);
  1477. F_RunWipe(TICRATE, true);
  1478. }
  1479. }
  1480. else
  1481. F_DrawCreditScreen(&credits[animtimer]);
  1482. }
  1483. //
  1484. // F_IntroDrawer
  1485. //
  1486. void F_IntroDrawer(void)
  1487. {
  1488. if (timetonext <= 0)
  1489. {
  1490. if (finaletext == text[INTRO01TEXT])
  1491. {
  1492. S_ChangeMusic(mus_read_m, false);
  1493. finaletext = text[INTRO02TEXT];
  1494. }
  1495. else if (finaletext == text[INTRO02TEXT])
  1496. finaletext = text[INTRO03TEXT];
  1497. else if (finaletext == text[INTRO03TEXT])
  1498. finaletext = text[INTRO04TEXT];
  1499. else if (finaletext == text[INTRO04TEXT])
  1500. {
  1501. finaletext = text[INTRO05TEXT];
  1502. roidtics = BASEVIDWIDTH - 64;
  1503. }
  1504. else if (finaletext == text[INTRO05TEXT])
  1505. finaletext = text[INTRO06TEXT];
  1506. else if (finaletext == text[INTRO06TEXT])
  1507. finaletext = text[INTRO07TEXT];
  1508. else if (finaletext == text[INTRO07TEXT])
  1509. finaletext = text[INTRO08TEXT];
  1510. else if (finaletext == text[INTRO08TEXT])
  1511. finaletext = text[INTRO09TEXT];
  1512. else if (finaletext == text[INTRO09TEXT])
  1513. finaletext = text[INTRO10TEXT];
  1514. else if (finaletext == text[INTRO10TEXT])
  1515. finaletext = text[INTRO11TEXT];
  1516. else if (finaletext == text[INTRO11TEXT])
  1517. {
  1518. if (rendermode != render_none)
  1519. {
  1520. F_WipeStartScreen();
  1521. V_DrawFill(0, 0, vid.width, vid.height, 0);
  1522. F_WipeEndScreen(0, 0, vid.width, vid.height);
  1523. F_RunWipe(TICRATE, true);
  1524. }
  1525. finaletext = text[INTRO12TEXT];
  1526. }
  1527. else if (finaletext == text[INTRO12TEXT])
  1528. finaletext = text[INTRO13TEXT];
  1529. else if (finaletext == text[INTRO13TEXT])
  1530. finaletext = text[INTRO14TEXT];
  1531. else if (finaletext == text[INTRO14TEXT])
  1532. finaletext = text[INTRO15TEXT];
  1533. else if (finaletext == text[INTRO15TEXT])
  1534. finaletext = text[INTRO16TEXT];
  1535. else if (finaletext == text[INTRO16TEXT])
  1536. {
  1537. if (rendermode != render_none)
  1538. {
  1539. F_WipeStartScreen();
  1540. V_DrawFill(0, 0, vid.width, vid.height, 31);
  1541. F_WipeEndScreen(0, 0, vid.width, vid.height);
  1542. F_RunWipe(TICRATE, true);
  1543. }
  1544. // Stay on black for a bit. =)
  1545. {
  1546. tic_t quittime;
  1547. quittime = I_GetTime() + TICRATE*2; // Shortened the quit time, used to be 2 seconds
  1548. while (quittime > I_GetTime())
  1549. {
  1550. I_OsPolling();
  1551. I_UpdateNoBlit();
  1552. M_Drawer(); // menu is drawn even on top of wipes
  1553. I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
  1554. }
  1555. }
  1556. D_StartTitle();
  1557. return;
  1558. }
  1559. if (gamestate == GS_INTRO)
  1560. G_SetGamestate(GS_INTRO2);
  1561. else
  1562. G_SetGamestate(GS_INTRO);
  1563. #ifndef SHUFFLE
  1564. if (rendermode == render_soft)
  1565. #endif
  1566. F_WipeStartScreen();
  1567. wipegamestate = -1;
  1568. finaletextcount = 0;
  1569. animtimer = 0;
  1570. stoptimer = 0;
  1571. scene++;
  1572. timetonext = introscenetime[scene];
  1573. }
  1574. if (finaletext == text[INTRO08TEXT] && finaletextcount == 5*TICRATE) // Force a wipe here
  1575. {
  1576. if (rendermode != render_none)
  1577. {
  1578. F_WipeStartScreen();
  1579. V_DrawFill(0, 0, vid.width, vid.height, 31);
  1580. V_DrawScaledPatch(0, 0, 0, W_CachePatchName("SGRASS5", PU_CACHE));
  1581. F_IntroTextWrite();
  1582. F_WipeEndScreen(0, 0, vid.width, vid.height);
  1583. F_RunWipe(TICRATE, true);
  1584. }
  1585. }
  1586. F_IntroTextWrite();
  1587. }
  1588. static void F_AdvanceToNextScene(void)
  1589. {
  1590. scenenum++;
  1591. if (scenenum < cutscenes[cutnum]->numscenes)
  1592. {
  1593. picnum = 0;
  1594. picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum];
  1595. picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
  1596. }
  1597. if (cutscenes[cutnum]->scene[scenenum].musicslot != 0)
  1598. S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop);
  1599. if (rendermode != render_none)
  1600. {
  1601. F_WipeStartScreen();
  1602. V_DrawFill(0,0, vid.width, vid.height, 31);
  1603. if (scenenum < cutscenes[cutnum]->numscenes)
  1604. {
  1605. if (cutscenes[cutnum]->scene[scenenum].pichires[picnum])
  1606. V_DrawSmallScaledPatch(picxpos, picypos, 0, W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_CACHE));
  1607. else
  1608. V_DrawScaledPatch(picxpos, picypos, 0, W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_CACHE));
  1609. }
  1610. F_WipeEndScreen(0, 0, vid.width, vid.height);
  1611. F_RunWipe(TICRATE, true);
  1612. }
  1613. finaletextcount = 0;
  1614. timetonext = 0;
  1615. stoptimer = 0;
  1616. if (scenenum >= cutscenes[cutnum]->numscenes)
  1617. {
  1618. if (cutnum == creditscutscene-1)
  1619. F_StartGameEvaluation();
  1620. else
  1621. F_EndCutScene();
  1622. return;
  1623. }
  1624. finaletext = cutscenes[cutnum]->scene[scenenum].text;
  1625. picnum = 0;
  1626. picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum];
  1627. picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
  1628. textxpos = cutscenes[cutnum]->scene[scenenum].textxpos;
  1629. textypos = cutscenes[cutnum]->scene[scenenum].textypos;
  1630. animtimer = pictime = cutscenes[cutnum]->scene[scenenum].picduration[picnum];
  1631. }
  1632. static void F_CutsceneTextWrite(void)
  1633. {
  1634. V_DrawFill(0, 0, vid.width, vid.height, 31);
  1635. if (cutscenes[cutnum]->scene[scenenum].picname[picnum][0] != '\0')
  1636. {
  1637. if (cutscenes[cutnum]->scene[scenenum].pichires[picnum])
  1638. V_DrawSmallScaledPatch(picxpos, picypos,

Large files files are truncated, but you can click here to view the full file