f_wipe.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:5k
源码类别:

射击游戏

开发平台:

Visual C++

  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.     
  77.     while (w!=wipe_scr+width*height)
  78.     {
  79. if (*w != *e)
  80. {
  81.     if (*w > *e)
  82.     {
  83. newval = *w - ticks;
  84. if (newval < *e)
  85.     *w = *e;
  86. else
  87.     *w = newval;
  88. changed = true;
  89.     }
  90.     else if (*w < *e)
  91.     {
  92. newval = *w + ticks;
  93. if (newval > *e)
  94.     *w = *e;
  95. else
  96.     *w = newval;
  97. changed = true;
  98.     }
  99. }
  100. w++;
  101. e++;
  102.     }
  103.     return !changed;
  104. }
  105. int
  106. wipe_exitColorXForm
  107. ( int width,
  108.   int height,
  109.   int ticks )
  110. {
  111.     return 0;
  112. }
  113. static int* y;
  114. int
  115. wipe_initMelt
  116. ( int width,
  117.   int height,
  118.   int ticks )
  119. {
  120.     int i, r;
  121.     
  122.     // copy start screen to main screen
  123.     memcpy(wipe_scr, wipe_scr_start, width*height);
  124.     
  125.     // makes this wipe faster (in theory)
  126.     // to have stuff in column-major format
  127.     wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
  128.     wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
  129.     
  130.     // setup initial column positions
  131.     // (y<0 => not ready to scroll yet)
  132.     y = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0);
  133.     y[0] = -(M_Random()%16);
  134.     for (i=1;i<width;i++)
  135.     {
  136. r = (M_Random()%3) - 1;
  137. y[i] = y[i-1] + r;
  138. if (y[i] > 0) y[i] = 0;
  139. else if (y[i] == -16) y[i] = -15;
  140.     }
  141.     return 0;
  142. }
  143. int
  144. wipe_doMelt
  145. ( int width,
  146.   int height,
  147.   int ticks )
  148. {
  149.     int i;
  150.     int j;
  151.     int dy;
  152.     int idx;
  153.     
  154.     short* s;
  155.     short* d;
  156.     boolean done = true;
  157.     width/=2;
  158.     while (ticks--)
  159.     {
  160. for (i=0;i<width;i++)
  161. {
  162.     if (y[i]<0)
  163.     {
  164. y[i]++; done = false;
  165.     }
  166.     else if (y[i] < height)
  167.     {
  168. dy = (y[i] < 16) ? y[i]+1 : 8;
  169. if (y[i]+dy >= height) dy = height - y[i];
  170. s = &((short *)wipe_scr_end)[i*height+y[i]];
  171. d = &((short *)wipe_scr)[y[i]*width+i];
  172. idx = 0;
  173. for (j=dy;j;j--)
  174. {
  175.     d[idx] = *(s++);
  176.     idx += width;
  177. }
  178. y[i] += dy;
  179. s = &((short *)wipe_scr_start)[i*height];
  180. d = &((short *)wipe_scr)[y[i]*width+i];
  181. idx = 0;
  182. for (j=height-y[i];j;j--)
  183. {
  184.     d[idx] = *(s++);
  185.     idx += width;
  186. }
  187. done = false;
  188.     }
  189. }
  190.     }
  191.     return done;
  192. }
  193. int
  194. wipe_exitMelt
  195. ( int width,
  196.   int height,
  197.   int ticks )
  198. {
  199.     Z_Free(y);
  200.     return 0;
  201. }
  202. int
  203. wipe_StartScreen
  204. ( int x,
  205.   int y,
  206.   int width,
  207.   int height )
  208. {
  209.     wipe_scr_start = screens[2];
  210.     I_ReadScreen(wipe_scr_start);
  211.     return 0;
  212. }
  213. int
  214. wipe_EndScreen
  215. ( int x,
  216.   int y,
  217.   int width,
  218.   int height )
  219. {
  220.     wipe_scr_end = screens[3];
  221.     I_ReadScreen(wipe_scr_end);
  222.     V_DrawBlock(x, y, 0, width, height, wipe_scr_start); // restore start scr.
  223.     return 0;
  224. }
  225. int
  226. wipe_ScreenWipe
  227. ( int wipeno,
  228.   int x,
  229.   int y,
  230.   int width,
  231.   int height,
  232.   int ticks )
  233. {
  234.     int rc;
  235.     static int (*wipes[])(int, int, int) =
  236.     {
  237. wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm,
  238. wipe_initMelt, wipe_doMelt, wipe_exitMelt
  239.     };
  240.     void V_MarkRect(int, int, int, int);
  241.     // initial stuff
  242.     if (!go)
  243.     {
  244. go = 1;
  245. // wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG
  246. wipe_scr = screens[0];
  247. (*wipes[wipeno*3])(width, height, ticks);
  248.     }
  249.     // do a piece of wipe-in
  250.     V_MarkRect(0, 0, width, height);
  251.     rc = (*wipes[wipeno*3+1])(width, height, ticks);
  252.     //  V_DrawBlock(x, y, 0, width, height, wipe_scr); // DEBUG
  253.     // final stuff
  254.     if (rc)
  255.     {
  256. go = 0;
  257. (*wipes[wipeno*3+2])(width, height, ticks);
  258.     }
  259.     return !go;
  260. }