f_wipe.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // Emacs style mode select -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. // Mission begin melt/wipe screen special effect.
  21. //
  22. //-----------------------------------------------------------------------------
  23. static const char rcsid[] = "$Id: f_wipe.c,v 1.2 1997/02/03 22:45:09 b1 Exp $";
  24. #include "z_zone.h"
  25. #include "i_video.h"
  26. #include "v_video.h"
  27. #include "m_random.h"
  28. #include "doomdef.h"
  29. #include "f_wipe.h"
  30. //
  31. // SCREEN WIPE PACKAGE
  32. //
  33. // when zero, stop the wipe
  34. static boolean go = 0;
  35. static byte* wipe_scr_start;
  36. static byte* wipe_scr_end;
  37. static byte* wipe_scr;
  38. void
  39. wipe_shittyColMajorXform
  40. ( short* array,
  41. int width,
  42. int height )
  43. {
  44. int x;
  45. int y;
  46. short* dest;
  47. dest = (short*) Z_Malloc(width*height*2, PU_STATIC, 0);
  48. for(y=0;y<height;y++)
  49. for(x=0;x<width;x++)
  50. dest[x*height+y] = array[y*width+x];
  51. memcpy(array, dest, width*height*2);
  52. Z_Free(dest);
  53. }
  54. int
  55. wipe_initColorXForm
  56. ( int width,
  57. int height,
  58. int ticks )
  59. {
  60. memcpy(wipe_scr, wipe_scr_start, width*height);
  61. return 0;
  62. }
  63. int
  64. wipe_doColorXForm
  65. ( int width,
  66. int height,
  67. int ticks )
  68. {
  69. boolean changed;
  70. byte* w;
  71. byte* e;
  72. int newval;
  73. changed = false;
  74. w = wipe_scr;
  75. e = wipe_scr_end;
  76. while (w!=wipe_scr+width*height)
  77. {
  78. if (*w != *e)
  79. {
  80. if (*w > *e)
  81. {
  82. newval = *w - ticks;
  83. if (newval < *e)
  84. *w = *e;
  85. else
  86. *w = newval;
  87. changed = true;
  88. }
  89. else if (*w < *e)
  90. {
  91. newval = *w + ticks;
  92. if (newval > *e)
  93. *w = *e;
  94. else
  95. *w = newval;
  96. changed = true;
  97. }
  98. }
  99. w++;
  100. e++;
  101. }
  102. return !changed;
  103. }
  104. int
  105. wipe_exitColorXForm
  106. ( int width,
  107. int height,
  108. int ticks )
  109. {
  110. return 0;
  111. }
  112. static int* y;
  113. int
  114. wipe_initMelt
  115. ( int width,
  116. int height,
  117. int ticks )
  118. {
  119. int i, r;
  120. // copy start screen to main screen
  121. memcpy(wipe_scr, wipe_scr_start, width*height);
  122. // makes this wipe faster (in theory)
  123. // to have stuff in column-major format
  124. wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
  125. wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
  126. // setup initial column positions
  127. // (y<0 => not ready to scroll yet)
  128. y = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0);
  129. y[0] = -(M_Random()%16);
  130. for (i=1;i<width;i++)
  131. {
  132. r = (M_Random()%3) - 1;
  133. y[i] = y[i-1] + r;
  134. if (y[i] > 0) y[i] = 0;
  135. else if (y[i] == -16) y[i] = -15;
  136. }
  137. return 0;
  138. }
  139. int
  140. wipe_doMelt
  141. ( int width,
  142. int height,
  143. int ticks )
  144. {
  145. int i;
  146. int j;
  147. int dy;
  148. int idx;
  149. short* s;
  150. short* d;
  151. boolean done = true;
  152. width/=2;
  153. while (ticks--)
  154. {
  155. for (i=0;i<width;i++)
  156. {
  157. if (y[i]<0)
  158. {
  159. y[i]++; done = false;
  160. }
  161. else if (y[i] < height)
  162. {
  163. dy = (y[i] < 16) ? y[i]+1 : 8;
  164. if (y[i]+dy >= height) dy = height - y[i];
  165. s = &((short *)wipe_scr_end)[i*height+y[i]];
  166. d = &((short *)wipe_scr)[y[i]*width+i];
  167. idx = 0;
  168. for (j=dy;j;j--)
  169. {
  170. d[idx] = *(s++);
  171. idx += width;
  172. }
  173. y[i] += dy;
  174. s = &((short *)wipe_scr_start)[i*height];
  175. d = &((short *)wipe_scr)[y[i]*width+i];
  176. idx = 0;
  177. for (j=height-y[i];j;j--)
  178. {
  179. d[idx] = *(s++);
  180. idx += width;
  181. }
  182. done = false;
  183. }
  184. }
  185. }
  186. return done;
  187. }
  188. int
  189. wipe_exitMelt
  190. ( int width,
  191. int height,
  192. int ticks )
  193. {
  194. Z_Free(y);
  195. return 0;
  196. }
  197. int
  198. wipe_StartScreen
  199. ( int x,
  200. int y,
  201. int width,
  202. int height )
  203. {
  204. wipe_scr_start = screens[2];
  205. I_ReadScreen(wipe_scr_start);
  206. return 0;
  207. }
  208. int
  209. wipe_EndScreen
  210. ( int x,
  211. int y,
  212. int width,
  213. int height )
  214. {
  215. wipe_scr_end = screens[3];
  216. I_ReadScreen(wipe_scr_end);
  217. V_DrawBlock(x, y, 0, width, height, wipe_scr_start); // restore start scr.
  218. return 0;
  219. }
  220. int
  221. wipe_ScreenWipe
  222. ( int wipeno,
  223. int x,
  224. int y,
  225. int width,
  226. int height,
  227. int ticks )
  228. {
  229. int rc;
  230. static int (*wipes[])(int, int, int) =
  231. {
  232. wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm,
  233. wipe_initMelt, wipe_doMelt, wipe_exitMelt
  234. };
  235. void V_MarkRect(int, int, int, int);
  236. // initial stuff
  237. if (!go)
  238. {
  239. go = 1;
  240. // wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG
  241. wipe_scr = screens[0];
  242. (*wipes[wipeno*3])(width, height, ticks);
  243. }
  244. // do a piece of wipe-in
  245. V_MarkRect(0, 0, width, height);
  246. rc = (*wipes[wipeno*3+1])(width, height, ticks);
  247. // V_DrawBlock(x, y, 0, width, height, wipe_scr); // DEBUG
  248. // final stuff
  249. if (rc)
  250. {
  251. go = 0;
  252. (*wipes[wipeno*3+2])(width, height, ticks);
  253. }
  254. return !go;
  255. }