MenuTrans.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // MenuTrans.cpp
  19. // Project: Nostril (aka Postal)
  20. //
  21. // This module sets up the system and RSPiX.
  22. //
  23. // History:
  24. // 11/19/96 MJR Started.
  25. //
  26. // 08/04/97 JMI Although the Remap() function was calling
  27. // rspLockVideoBuffer(), it was effectively ignoring it. That
  28. // is, it passed 'dummy' vars which it did not use to access
  29. // the screen. These values MUST be used or there is very
  30. // little point in locking the video buffer in the first place.
  31. // This probably occurs all over the place. I'm pretty sure
  32. // I've done it this way in spots.
  33. //
  34. // 08/21/97 JMI Changed occurrences of rspUpdateDisplay() to
  35. // UpdateDisplay().
  36. //
  37. // 08/22/97 JMI Changed to use rspLockBuffer() (the BLiT library version
  38. // of locking the composite buffer).
  39. //
  40. // 08/22/97 JMI Changed calls to UpdateDisplay() back to rspUpdateDisplay()
  41. // since we no longer need UpdateDisplay() now that we are
  42. // using rspLock/Unlock* functions properly.
  43. // Also, put locks around accesses (Blits, Rects, etc.) to the
  44. // composite buffer.
  45. //
  46. ////////////////////////////////////////////////////////////////////////////////
  47. //
  48. // Things to change:
  49. //
  50. // I don't currently care much for the fade to red -- it looks pretty damn
  51. // plain.
  52. //
  53. // This currently requires a huge amount of memory since it needs to save the
  54. // screen data so that the effect can be run backwards. The problem with this
  55. // is that it means we're always wasting alot more memory while running the
  56. // game than we would otherwise need to, because we have to be ready to pop up
  57. // the menu (and hence to use this effect) at any time.
  58. //
  59. // One possible way to use less memory is to save the screen data to the
  60. // hard drive and load it back when we need it. I'm not sure how slow this
  61. // will be, and I'm also not sure what's involved in actually doing this since
  62. // the buffer is really just a stub, which may not support saving properly.
  63. //
  64. // Not sure what to do about EndMenuTrans(). Original idea was to be able to
  65. // call it at any time, and you could either tell it finish the effect as
  66. // quickly as possible or to abort, which might leave the screen in an ugly
  67. // state. The idea was that if the user hit a key or something that meant
  68. // "skip this stupid effect", that we could quickly do so. I'm not sure how
  69. // actual usage will turn out, so for now, I'm ignoring the flag being passed
  70. // to this function.
  71. //
  72. ////////////////////////////////////////////////////////////////////////////////
  73. #include "RSPiX.h"
  74. #ifdef PATHS_IN_INCLUDES
  75. #else
  76. #endif
  77. #include "game.h"
  78. #include "MenuTrans.h"
  79. #include "update.h"
  80. ////////////////////////////////////////////////////////////////////////////////
  81. // Macros/types/etc.
  82. ////////////////////////////////////////////////////////////////////////////////
  83. // Define number of shades along with mask that will create that many shades
  84. //#define NUM_SHADES 32
  85. //#define SHADE_MASK 0xf8
  86. #define NUM_SHADES 16
  87. #define SHADE_MASK 0xf0
  88. // Define range of palette indices to be affected (inclusive).
  89. // THIS RANGE MUST BE AT LEAST TWICE AS LARGE AS NUM_SHADES!!!
  90. #define EFFECT_BEG 10
  91. #define EFFECT_END 245
  92. #define EFFECT_LEN ((EFFECT_END - EFFECT_BEG) + 1)
  93. #define SHADE_BEG ((EFFECT_END + 1) - NUM_SHADES)
  94. #define SHADE_END (EFFECT_END)
  95. #define SHADE_LEN ((SHADE_END - SHADE_BEG) + 1)
  96. #define NONSHADE_BEG EFFECT_BEG
  97. #define NONSHADE_END (SHADE_BEG - 1)
  98. #define NONSHADE_LEN ((NONSHADE_END - NONSHADE_BEG) + 1)
  99. // Simple struct for working with palettes
  100. typedef struct
  101. {
  102. unsigned char r;
  103. unsigned char g;
  104. unsigned char b;
  105. unsigned char x;
  106. } rgb;
  107. ////////////////////////////////////////////////////////////////////////////////
  108. // Variables/data
  109. ////////////////////////////////////////////////////////////////////////////////
  110. static rgb* m_pOrig;
  111. static rgb* m_pWork;
  112. static rgb* m_pSaveStep4;
  113. static unsigned char* m_pUnmapStep4;
  114. static unsigned char* m_pUnmapStep5;
  115. static RImage* m_pim;
  116. static short m_sStep;
  117. static bool m_bFinishASAP;
  118. static long m_lTotalTime;
  119. static long m_lBaseTime;
  120. static double m_dReduce = 1.0;
  121. ////////////////////////////////////////////////////////////////////////////////
  122. // Function prototypes
  123. ////////////////////////////////////////////////////////////////////////////////
  124. static void Remap(
  125. unsigned char* aucMap);
  126. ////////////////////////////////////////////////////////////////////////////////
  127. // Call this to start the menu transition effect
  128. ////////////////////////////////////////////////////////////////////////////////
  129. extern void StartMenuTrans(
  130. long lTotalTime) // In: Effect time (in ms) must be >= 0
  131. {
  132. // Default to step 0 (nothing) in case something goes wrong
  133. m_sStep = 0;
  134. // Save total time
  135. if (lTotalTime < 0)
  136. {
  137. TRACE("StartMenuTransIn(): Moronic time specified: %ld -- changed to 0!\n", lTotalTime);
  138. lTotalTime = 0;
  139. }
  140. m_lTotalTime = lTotalTime;
  141. // Clear finish flag
  142. m_bFinishASAP = false;
  143. // Allocate lots of stuff
  144. m_pOrig = new rgb[256];
  145. m_pWork = new rgb[256];
  146. m_pSaveStep4 = new rgb[256];
  147. m_pUnmapStep4 = new unsigned char[256];
  148. m_pUnmapStep5 = new unsigned char[256];
  149. m_pim = new RImage;
  150. if (m_pOrig && m_pWork && m_pSaveStep4 && m_pUnmapStep4 && m_pUnmapStep5 && m_pim)
  151. {
  152. // Setup image to match screen buffer
  153. if (m_pim->CreateImage(g_pimScreenBuf->m_sWidth, g_pimScreenBuf->m_sHeight, RImage::BMP8) == 0)
  154. {
  155. // Everything's cool, so set for first step
  156. m_sStep = 1;
  157. }
  158. else
  159. TRACE("StartMenuTrans(): Error returned by RImage::CreateImage()!\n");
  160. }
  161. else
  162. TRACE("StartMenuTrans(): Couldn't allocate memory!\n");
  163. }
  164. ////////////////////////////////////////////////////////////////////////////////
  165. //
  166. // The starting time of the effect is considered to be the first time this
  167. // function is called (NOT when InitMenuTransIn() is called!)
  168. //
  169. // The return value is true when the effect has completed, false otherwise.
  170. ////////////////////////////////////////////////////////////////////////////////
  171. extern bool DoPreMenuTrans(void)
  172. {
  173. //---------------------------------------------------------------------------
  174. // Step 1: Start
  175. //
  176. // Get the current palette and the current time and go on to the next step.
  177. // This could have been done in the init function, but I didn't want the
  178. // timing to start then, but rather on the first call to this function.
  179. //---------------------------------------------------------------------------
  180. if (m_sStep == 1)
  181. {
  182. // Get the "original" palette
  183. rspGetPaletteEntries(0, 256, &(m_pOrig[0].r), &(m_pOrig[0].g), &(m_pOrig[0].b), sizeof(rgb));
  184. // Lock the buffer before reading from it.
  185. rspLockBuffer();
  186. // Copy the screen into our image
  187. rspBlitA(g_pimScreenBuf, m_pim, 0, 0, m_pim->m_sWidth, m_pim->m_sHeight);
  188. // Unlock now that we're done with the composite buffer.
  189. rspUnlockBuffer();
  190. // Calculate goal for each color's red component. We use the otherwise
  191. // unused member of the struct to store the goal.
  192. for (short i = EFFECT_BEG; i <= EFFECT_END; i++)
  193. // m_pOrig[i].x = (unsigned char)((double)(255 - m_pOrig[i].r) * m_dReduce) & SHADE_MASK;
  194. m_pOrig[i].x = (unsigned char)((double)(m_pOrig[i].r) * m_dReduce) & SHADE_MASK;
  195. // Get base time for next step
  196. m_lBaseTime = rspGetMilliseconds();
  197. // Go to next step
  198. m_sStep = 2;
  199. }
  200. //---------------------------------------------------------------------------
  201. // Step 2: Fade colors
  202. //
  203. // Over the specified period of time, we transform the original palette
  204. // entries into MAX_SHADES shades of red.
  205. //---------------------------------------------------------------------------
  206. else if (m_sStep == 2)
  207. {
  208. // Calculate how far into the effect we are based on the elapsed time
  209. // since we started. If the total time specified by the user was 0, or
  210. // if we're being asked to finish the effect ASAP, we go right to 100%.
  211. double dPercent;
  212. if ((m_lTotalTime == 0) || m_bFinishASAP)
  213. {
  214. dPercent = 1.0;
  215. }
  216. else
  217. {
  218. dPercent = (double)(rspGetMilliseconds() - m_lBaseTime) / (double)m_lTotalTime;
  219. if (dPercent > 1.0)
  220. dPercent = 1.0;
  221. }
  222. // Update all colors to where they should be based on given percentage
  223. for (short i = EFFECT_BEG; i <= EFFECT_END; i++)
  224. {
  225. double dRedDiff = m_pOrig[i].r - m_pOrig[i].x;
  226. m_pWork[i].r = m_pOrig[i].x + (unsigned char)(dRedDiff * (1.0 - dPercent));
  227. m_pWork[i].g = (unsigned char)((double)m_pOrig[i].g * (1.0 - dPercent));
  228. m_pWork[i].b = (unsigned char)((double)m_pOrig[i].b * (1.0 - dPercent));
  229. }
  230. // Set new palette
  231. rspSetPaletteEntries(EFFECT_BEG, EFFECT_LEN, &(m_pWork[EFFECT_BEG].r), &(m_pWork[EFFECT_BEG].g), &(m_pWork[EFFECT_BEG].b), sizeof(rgb));
  232. rspUpdatePalette();
  233. // If we're done with the fade, go to next step
  234. if (dPercent == 1.0)
  235. m_sStep = 3;
  236. }
  237. //---------------------------------------------------------------------------
  238. // Step 3: Consolidate
  239. //
  240. // At this point, the palette entries are all set to any of several shades of
  241. // red. Since the range of entries we're dealing with is at least twice the
  242. // maximum number of shades of red, there will definitely be some duplicate
  243. // entries. We remap the pixels to get rid of the duplicates, at the same
  244. // time creating some unused entries. We set flags showing which entries are
  245. // used and which are free in preperation for the next step.
  246. //---------------------------------------------------------------------------
  247. else if (m_sStep == 3)
  248. {
  249. // Start mapping table out as an "identity map" (pixels map to themselves)
  250. unsigned char aucMap[256];
  251. for (short m = 0; m < 256; m++)
  252. aucMap[m] = m;
  253. // Scan through the palette mapping each entry onto the first entry with the
  254. // same color. Only checks red since blue and green are always 0.
  255. for (short i = EFFECT_BEG; i <= EFFECT_END; i++)
  256. {
  257. // Loop ends on first match - worst case is that entry matches itself
  258. short j;
  259. for (j = EFFECT_BEG; m_pWork[i].r != m_pWork[j].r; j++) ;
  260. aucMap[i] = j;
  261. // Set flag to 0 if this entry will be free after remapping, 1 otherwise.
  262. // The next step relies on this!
  263. m_pWork[i].x = (j < i) ? 0 : 1;
  264. }
  265. // Remap screen pixels
  266. Remap(aucMap);
  267. rspUpdateDisplay();
  268. // Go to next step
  269. m_sStep = 4;
  270. }
  271. //---------------------------------------------------------------------------
  272. // Step 4: Clear Official Area
  273. //
  274. // The image is now only using a small number of entries, and there are at
  275. // least that many unused entries. Unfortunately, the used and unused
  276. // entries are scattered around in no particular order, so some of the used
  277. // entries may be where we eventually want the "official" set of shades to
  278. // reside. We remap the pixels to move any such entries into unused entries
  279. // outside of that "official" area.
  280. //---------------------------------------------------------------------------
  281. else if (m_sStep == 4)
  282. {
  283. // Start mapping table out as an "identity map" (pixels map to themselves)
  284. unsigned char aucMap[256];
  285. for (short m = 0; m < 256; m++)
  286. {
  287. aucMap[m] = m;
  288. m_pUnmapStep4[m] = m;
  289. }
  290. // Go through area reserved for "official" shades looking for used entries
  291. // and, if found, remap them to unused entries outside of that range.
  292. for (short s = SHADE_BEG; s <= SHADE_END; s++)
  293. {
  294. if (m_pWork[s].x)
  295. {
  296. short i;
  297. for (i = NONSHADE_BEG; i <= NONSHADE_END; i++)
  298. {
  299. if (m_pWork[i].x == 0)
  300. {
  301. aucMap[s] = i;
  302. m_pUnmapStep4[i] = s;
  303. m_pWork[i].r = m_pWork[s].r;
  304. m_pWork[i].x = 1;
  305. m_pWork[s].x = 0; // not required but makes table easier to "read" in debugger
  306. break;
  307. }
  308. }
  309. // Make sure we found an unused entry to map onto
  310. ASSERT(i <= NONSHADE_END);
  311. }
  312. }
  313. // Set new palette (some entries may have been changed by the above remapping)
  314. rspSetPaletteEntries(NONSHADE_BEG, NONSHADE_LEN, &(m_pWork[NONSHADE_BEG].r), &(m_pWork[NONSHADE_BEG].g), &(m_pWork[NONSHADE_BEG].b), sizeof(rgb));
  315. rspUpdatePalette();
  316. // Remap screen pixels
  317. Remap(aucMap);
  318. rspUpdateDisplay();
  319. // Save current palette so we can run the effect backwards
  320. for (short p = 0; p < 256; p++)
  321. m_pSaveStep4[p] = m_pWork[p];
  322. // Go to next step
  323. m_sStep = 5;
  324. }
  325. //---------------------------------------------------------------------------
  326. // Step 5: Pack Into Official Area
  327. //
  328. // We now put the full set of shades at the specified section of the palette
  329. // and remap the image so that only those "official" entries are used.
  330. //---------------------------------------------------------------------------
  331. else if (m_sStep == 5)
  332. {
  333. // Put full set of shades at proper position in palette
  334. for (short s = 0; s < SHADE_LEN; s++)
  335. m_pWork[SHADE_BEG + s].r = s * (~SHADE_MASK + 1);
  336. // Set new palette (do this before remapping so the shades will be there before they're needed)
  337. rspSetPaletteEntries(SHADE_BEG, SHADE_LEN, &(m_pWork[SHADE_BEG].r), &(m_pWork[SHADE_BEG].g), &(m_pWork[SHADE_BEG].b), sizeof(rgb));
  338. rspUpdatePalette();
  339. // Start mapping table out as an "identity map" (pixels map to themselves)
  340. unsigned char aucMap[256];
  341. for (short m = 0; m < 256; m++)
  342. {
  343. aucMap[m] = m;
  344. m_pUnmapStep5[m] = m;
  345. }
  346. // Scan through the palette mapping each used entry onto the first
  347. // "official" shade entry with the same color.
  348. for (short i = NONSHADE_BEG; i <= NONSHADE_END; i++)
  349. {
  350. // Only do this for used entries (the mapping would work without
  351. // this check, since it wouldn't hurt to map unused entries, but
  352. // the unmapping table would be screwed up -- it's really bizarre
  353. // to think about, but eventually it makes sense)
  354. if (m_pWork[i].x)
  355. {
  356. // Loop ends on first match (and there always will be a match)
  357. short j;
  358. for (j = SHADE_BEG; m_pWork[i].r != m_pWork[j].r; j++) ;
  359. aucMap[i] = j;
  360. m_pUnmapStep5[j] = i;
  361. }
  362. }
  363. // Remap screen pixels
  364. Remap(aucMap);
  365. rspUpdateDisplay();
  366. // Go to next step
  367. m_sStep = 6;
  368. }
  369. // Condition return value based on whether or not we're done
  370. if (m_sStep == 6)
  371. return true;
  372. return false;
  373. }
  374. ////////////////////////////////////////////////////////////////////////////////
  375. //
  376. // The starting time of the effect is considered to be the first time this
  377. // function is called (NOT when InitMenuTransIn() is called!)
  378. //
  379. // The return value is true when the effect has completed, false otherwise.
  380. ////////////////////////////////////////////////////////////////////////////////
  381. extern bool DoPostMenuTrans(void)
  382. {
  383. //---------------------------------------------------------------------------
  384. // Step 6: Undo Step 5
  385. //---------------------------------------------------------------------------
  386. if (m_sStep == 6)
  387. {
  388. // Restore palette to where it was prior to step 5
  389. for (short p = 0; p < 256; p++)
  390. m_pWork[p] = m_pSaveStep4[p];
  391. // Set only the non-shade portion of the palette until we remap the pixels
  392. rspSetPaletteEntries(NONSHADE_BEG, NONSHADE_LEN, &(m_pWork[NONSHADE_BEG].r), &(m_pWork[NONSHADE_BEG].g), &(m_pWork[NONSHADE_BEG].b), sizeof(rgb));
  393. rspUpdatePalette();
  394. // Remap screen pixels
  395. Remap(m_pUnmapStep5);
  396. rspUpdateDisplay();
  397. // Go to next step
  398. m_sStep = 7;
  399. }
  400. //---------------------------------------------------------------------------
  401. // Step 7: Undo Step 4
  402. //---------------------------------------------------------------------------
  403. else if (m_sStep == 7)
  404. {
  405. // Set the remainder of the palette now that the pixels are no longer using that part
  406. rspSetPaletteEntries(SHADE_BEG, SHADE_LEN, &(m_pWork[SHADE_BEG].r), &(m_pWork[SHADE_BEG].g), &(m_pWork[SHADE_BEG].b), sizeof(rgb));
  407. rspUpdatePalette();
  408. // Remap screen pixels
  409. Remap(m_pUnmapStep4);
  410. rspUpdateDisplay();
  411. // Go to next step
  412. m_sStep = 8;
  413. }
  414. //---------------------------------------------------------------------------
  415. // Step 8:
  416. //---------------------------------------------------------------------------
  417. else if (m_sStep == 8)
  418. {
  419. // Use the original palette to figure out what the colors should be like
  420. // as we start the reverse fade effect. If everything went right, we should
  421. // come up with the same values that already exist for those entries that
  422. // are actually being used by the pixels, and for those entries that aren't
  423. // being used, we're getting them ready for when we go back to the original
  424. // image.
  425. for (short i = EFFECT_BEG; i <= EFFECT_END; i++)
  426. {
  427. m_pWork[i].r = m_pOrig[i].x;
  428. m_pWork[i].g = (unsigned char)0;
  429. m_pWork[i].b = (unsigned char)0;
  430. }
  431. rspSetPaletteEntries(EFFECT_BEG, EFFECT_LEN, &(m_pWork[EFFECT_BEG].r), &(m_pWork[EFFECT_BEG].g), &(m_pWork[EFFECT_BEG].b), sizeof(rgb));
  432. rspUpdatePalette();
  433. // Lock the buffer before writing to it.
  434. rspLockBuffer();
  435. // Restore the original image
  436. rspBlitA(m_pim, g_pimScreenBuf, 0, 0, m_pim->m_sWidth, m_pim->m_sHeight);
  437. // Unlock now that we're done with the composite buffer.
  438. rspUnlockBuffer();
  439. rspUpdateDisplay();
  440. // Get base time for next step
  441. m_lBaseTime = rspGetMilliseconds();
  442. // Go to next step
  443. m_sStep = 9;
  444. }
  445. //---------------------------------------------------------------------------
  446. // Step 9: Do a reverse-fade of the colors
  447. //---------------------------------------------------------------------------
  448. else if (m_sStep == 9)
  449. {
  450. // Calculate how far into the effect we are based on the elapsed time
  451. // since we started. If the total time specified by the user was 0, or
  452. // if we're being asked to finish the effect ASAP, we go right to 100%.
  453. double dPercent;
  454. if ((m_lTotalTime == 0) || m_bFinishASAP)
  455. {
  456. dPercent = 1.0;
  457. }
  458. else
  459. {
  460. dPercent = (double)(rspGetMilliseconds() - m_lBaseTime) / (double)m_lTotalTime;
  461. if (dPercent > 1.0)
  462. dPercent = 1.0;
  463. }
  464. // Update all colors to where they should be based on given percentage
  465. for (short i = EFFECT_BEG; i <= EFFECT_END; i++)
  466. {
  467. double dRedDiff = m_pOrig[i].r - m_pOrig[i].x;
  468. m_pWork[i].r = m_pOrig[i].x + (unsigned char)(dRedDiff * dPercent);
  469. m_pWork[i].g = (unsigned char)((double)m_pOrig[i].g * dPercent);
  470. m_pWork[i].b = (unsigned char)((double)m_pOrig[i].b * dPercent);
  471. }
  472. // Set new palette
  473. rspSetPaletteEntries(EFFECT_BEG, EFFECT_LEN, &(m_pWork[EFFECT_BEG].r), &(m_pWork[EFFECT_BEG].g), &(m_pWork[EFFECT_BEG].b), sizeof(rgb));
  474. rspUpdatePalette();
  475. // If we're done with the fade, go to next step
  476. if (dPercent == 1.0)
  477. m_sStep = 10;
  478. }
  479. // Condition return value based on whether or not we're done
  480. if (m_sStep == 10)
  481. return true;
  482. return false;
  483. }
  484. ////////////////////////////////////////////////////////////////////////////////
  485. //
  486. ////////////////////////////////////////////////////////////////////////////////
  487. extern void EndMenuTrans(
  488. bool bFinish) // In: true to finish effect, false to abort it
  489. {
  490. // If step isn't over 0 then there's nothing to do
  491. if (m_sStep > 0)
  492. {
  493. // Check if caller wants to finish effect
  494. if (bFinish)
  495. {
  496. // Finish the effect
  497. m_bFinishASAP = bFinish;
  498. // while (!DoMenuTrans())
  499. // ;
  500. }
  501. // Free lots of stuff
  502. delete []m_pOrig;
  503. delete []m_pWork;
  504. delete []m_pSaveStep4;
  505. delete []m_pUnmapStep4;
  506. delete []m_pUnmapStep5;
  507. delete m_pim;
  508. // Reset step to "nothing"
  509. m_sStep = 0;
  510. }
  511. }
  512. ////////////////////////////////////////////////////////////////////////////////
  513. // Remap the pixels using the specified map
  514. ////////////////////////////////////////////////////////////////////////////////
  515. static void Remap(
  516. unsigned char* aucMap)
  517. {
  518. // Jon brought up a potential problem with calling rspLockBuffer(), which
  519. // is BLiT's version of this. In debug mode, it apparently doesn't do
  520. // anything because it assumes you will be calling a BLiT function, which
  521. // would actually do the locking. Since we don't call a BLiT function
  522. // here, the end result would be no locking. This is only a problem in
  523. // debug mode. We'll have to check into a better solution, but for now
  524. // I'm just calling the "real" buffer lock.
  525. U8* pu8VideoBuf;
  526. long lPitch;
  527. // Note that we only need to do this in the case that the buffer is not already
  528. // locked. Since we keep it locked while the game is running now, we don't need
  529. // it (note also regarding the lock comment above that currently rspLockBuffer()
  530. // does the lock even in DEBUG mode)
  531. // IF you comment this back in, remember to comment in the unlock as well!
  532. #if 0
  533. if (rspLockVideoBuffer((void**)&pu8VideoBuf, &lPitch) ) == 0)
  534. {
  535. #else
  536. if (rspLockBuffer() == 0)
  537. {
  538. pu8VideoBuf = g_pimScreenBuf->m_pData;
  539. lPitch = g_pimScreenBuf->m_lPitch;
  540. #endif
  541. short sHeight = g_pimScreenBuf->m_sHeight;
  542. short sWidth = g_pimScreenBuf->m_sWidth;
  543. short sWidth2;
  544. long lNextRow = lPitch - (long)sWidth;
  545. unsigned char* pBuf = pu8VideoBuf;
  546. if ((sHeight > 0) && (sWidth > 0))
  547. {
  548. do {
  549. sWidth2 = sWidth;
  550. do {
  551. *pBuf = *(aucMap + (long)*pBuf); // may be faster than aucMap[*pBuf]
  552. pBuf++;
  553. } while (--sWidth2);
  554. pBuf += lNextRow;
  555. } while (--sHeight);
  556. }
  557. #if 0
  558. rspUnlockVideoBuffer();
  559. #else
  560. rspUnlockBuffer();
  561. #endif
  562. }
  563. }
  564. ////////////////////////////////////////////////////////////////////////////////
  565. // EOF
  566. ////////////////////////////////////////////////////////////////////////////////