f_wipe.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2000 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION:
  30. * Mission begin melt/wipe screen special effect.
  31. *
  32. *-----------------------------------------------------------------------------
  33. */
  34. #ifdef HAVE_CONFIG_H
  35. #include "config.h"
  36. #endif
  37. #include "z_zone.h"
  38. #include "doomdef.h"
  39. #include "i_video.h"
  40. #include "v_video.h"
  41. #include "m_random.h"
  42. #include "f_wipe.h"
  43. //
  44. // SCREEN WIPE PACKAGE
  45. //
  46. // Parts re-written to support true-color video modes. Column-major
  47. // formatting removed. - POPE
  48. // CPhipps - macros for the source and destination screens
  49. #define SRC_SCR 2
  50. #define DEST_SCR 3
  51. static screeninfo_t wipe_scr_start;
  52. static screeninfo_t wipe_scr_end;
  53. static screeninfo_t wipe_scr;
  54. static int y_lookup[MAX_SCREENWIDTH];
  55. static int wipe_initMelt(int ticks)
  56. {
  57. int i;
  58. // copy start screen to main screen
  59. for(i=0;i<SCREENHEIGHT;i++)
  60. memcpy(wipe_scr.data+i*wipe_scr.byte_pitch,
  61. wipe_scr_start.data+i*wipe_scr.byte_pitch,
  62. SCREENWIDTH*V_GetPixelDepth());
  63. // setup initial column positions (y<0 => not ready to scroll yet)
  64. y_lookup[0] = -(M_Random()%16);
  65. for (i=1;i<SCREENWIDTH;i++)
  66. {
  67. int r = (M_Random()%3) - 1;
  68. y_lookup[i] = y_lookup[i-1] + r;
  69. if (y_lookup[i] > 0)
  70. y_lookup[i] = 0;
  71. else
  72. if (y_lookup[i] == -16)
  73. y_lookup[i] = -15;
  74. }
  75. return 0;
  76. }
  77. static int wipe_doMelt(int ticks)
  78. {
  79. boolean done = true;
  80. int i;
  81. const int depth = V_GetPixelDepth();
  82. while (ticks--) {
  83. for (i=0;i<(SCREENWIDTH);i++) {
  84. if (y_lookup[i]<0) {
  85. y_lookup[i]++;
  86. done = false;
  87. continue;
  88. }
  89. if (y_lookup[i] < SCREENHEIGHT) {
  90. byte *s, *d;
  91. int j, k, dy;
  92. /* cph 2001/07/29 -
  93. * The original melt rate was 8 pixels/sec, i.e. 25 frames to melt
  94. * the whole screen, so make the melt rate depend on SCREENHEIGHT
  95. * so it takes no longer in high res
  96. */
  97. dy = (y_lookup[i] < 16) ? y_lookup[i]+1 : SCREENHEIGHT/25;
  98. if (y_lookup[i]+dy >= SCREENHEIGHT)
  99. dy = SCREENHEIGHT - y_lookup[i];
  100. s = wipe_scr_end.data + (y_lookup[i]*wipe_scr_end.byte_pitch+(i*depth));
  101. d = wipe_scr.data + (y_lookup[i]*wipe_scr.byte_pitch+(i*depth));
  102. for (j=dy;j;j--) {
  103. for (k=0; k<depth; k++)
  104. d[k] = s[k];
  105. d += wipe_scr.byte_pitch;
  106. s += wipe_scr_end.byte_pitch;
  107. }
  108. y_lookup[i] += dy;
  109. s = wipe_scr_start.data + (i*depth);
  110. d = wipe_scr.data + (y_lookup[i]*wipe_scr.byte_pitch+(i*depth));
  111. for (j=SCREENHEIGHT-y_lookup[i];j;j--) {
  112. for (k=0; k<depth; k++)
  113. d[k] = s[k];
  114. d += wipe_scr.byte_pitch;
  115. s += wipe_scr_end.byte_pitch;
  116. }
  117. done = false;
  118. }
  119. }
  120. }
  121. return done;
  122. }
  123. // CPhipps - modified to allocate and deallocate screens[2 to 3] as needed, saving memory
  124. static int wipe_exitMelt(int ticks)
  125. {
  126. V_FreeScreen(&wipe_scr_start);
  127. wipe_scr_start.width = 0;
  128. wipe_scr_start.height = 0;
  129. V_FreeScreen(&wipe_scr_end);
  130. wipe_scr_end.width = 0;
  131. wipe_scr_end.height = 0;
  132. // Paranoia
  133. screens[SRC_SCR] = wipe_scr_start;
  134. screens[DEST_SCR] = wipe_scr_end;
  135. return 0;
  136. }
  137. int wipe_StartScreen(void)
  138. {
  139. wipe_scr_start.width = SCREENWIDTH;
  140. wipe_scr_start.height = SCREENHEIGHT;
  141. wipe_scr_start.byte_pitch = screens[0].byte_pitch;
  142. wipe_scr_start.short_pitch = screens[0].short_pitch;
  143. wipe_scr_start.int_pitch = screens[0].int_pitch;
  144. wipe_scr_start.not_on_heap = false;
  145. V_AllocScreen(&wipe_scr_start);
  146. screens[SRC_SCR] = wipe_scr_start;
  147. V_CopyRect(0, 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, SRC_SCR, VPT_NONE ); // Copy start screen to buffer
  148. return 0;
  149. }
  150. int wipe_EndScreen(void)
  151. {
  152. wipe_scr_end.width = SCREENWIDTH;
  153. wipe_scr_end.height = SCREENHEIGHT;
  154. wipe_scr_end.byte_pitch = screens[0].byte_pitch;
  155. wipe_scr_end.short_pitch = screens[0].short_pitch;
  156. wipe_scr_end.int_pitch = screens[0].int_pitch;
  157. wipe_scr_end.not_on_heap = false;
  158. V_AllocScreen(&wipe_scr_end);
  159. screens[DEST_SCR] = wipe_scr_end;
  160. V_CopyRect(0, 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, DEST_SCR, VPT_NONE); // Copy end screen to buffer
  161. V_CopyRect(0, 0, SRC_SCR, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0 , VPT_NONE); // restore start screen
  162. return 0;
  163. }
  164. // killough 3/5/98: reformatted and cleaned up
  165. int wipe_ScreenWipe(int ticks)
  166. {
  167. static boolean go; // when zero, stop the wipe
  168. if (!go) // initial stuff
  169. {
  170. go = 1;
  171. wipe_scr = screens[0];
  172. wipe_initMelt(ticks);
  173. }
  174. // do a piece of wipe-in
  175. if (wipe_doMelt(ticks)) // final stuff
  176. {
  177. wipe_exitMelt(ticks);
  178. go = 0;
  179. }
  180. return !go;
  181. }