home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / f_wipe.c < prev    next >
C/C++ Source or Header  |  1999-12-17  |  9KB  |  532 lines

  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.  
  24.  
  25. static const char rcsid[] = "$Id: f_wipe.c,v 1.2 1997/02/03 22:45:09 b1 Exp $";
  26.  
  27.  
  28.  
  29. #include "z_zone.h"
  30. #include "i_video.h"
  31. #include "v_video.h"
  32. #include "m_random.h"
  33.  
  34. #include "doomdef.h"
  35. #include "doomstat.h"
  36.  
  37. #include "f_wipe.h"
  38.  
  39. /*  */
  40. /*                        SCREEN WIPE PACKAGE */
  41. /*  */
  42.  
  43. /*  when zero, stop the wipe */
  44. static boolean    go = 0;
  45.  
  46. static byte*    wipe_scr_start;
  47. static byte*    wipe_scr_end;
  48. static byte*    wipe_scr;
  49.  
  50.  
  51. void
  52. wipe_shittyColMajorXform
  53. ( short*    array,
  54.   int        width,
  55.   int        height )
  56. {
  57. #if 0
  58.     int        x;
  59.     int        y;
  60.     short*    dest;
  61.  
  62.     dest = (short*) Z_Malloc(width*height*2, PU_STATIC, 0);
  63.  
  64.     for(y=0;y<height;y++)
  65.     for(x=0;x<width;x++)
  66.         dest[x*height+y] = array[y*width+x];
  67.  
  68.     memcpy(array, dest, width*height*2);
  69.  
  70.     Z_Free(dest);
  71. #endif
  72. }
  73.  
  74. int
  75. wipe_initColorXForm
  76. ( int    width,
  77.   int    height,
  78.   int    ticks )
  79. {
  80. #if 0
  81.     memcpy(wipe_scr, wipe_scr_start, width*height);
  82. #endif
  83.     return 0;
  84. }
  85.  
  86. int
  87. wipe_doColorXForm
  88. ( int    width,
  89.   int    height,
  90.   int    ticks )
  91. {
  92. #if 0
  93.     boolean    changed;
  94.     byte*    w;
  95.     byte*    e;
  96.     int        newval;
  97.  
  98.     changed = false;
  99.     w = wipe_scr;
  100.     e = wipe_scr_end;
  101.     
  102.     while (w!=wipe_scr+width*height)
  103.     {
  104.     if (*w != *e)
  105.     {
  106.         if (*w > *e)
  107.         {
  108.         newval = *w - ticks;
  109.         if (newval < *e)
  110.             *w = *e;
  111.         else
  112.             *w = newval;
  113.         changed = true;
  114.         }
  115.         else if (*w < *e)
  116.         {
  117.         newval = *w + ticks;
  118.         if (newval > *e)
  119.             *w = *e;
  120.         else
  121.             *w = newval;
  122.         changed = true;
  123.         }
  124.     }
  125.     w++;
  126.     e++;
  127.     }
  128.  
  129.     return !changed;
  130. #else
  131.     return true;
  132. #endif
  133. }
  134.  
  135. int
  136. wipe_exitColorXForm
  137. ( int    width,
  138.   int    height,
  139.   int    ticks )
  140. {
  141.     return 0;
  142. }
  143.  
  144.  
  145. static int*    y;
  146. extern int    fbnum;
  147.  
  148. int
  149. wipe_initMelt
  150. ( int    width,
  151.   int    height,
  152.   int    ticks )
  153. {
  154.     int i, r;
  155.     
  156.     /*  copy start screen to main screen */
  157.     memcpy(wipe_scr, wipe_scr_start, width*height*pixel_size);
  158.     
  159. #if 0
  160.     /*  makes this wipe faster (in theory) */
  161.     /*  to have stuff in column-major format */
  162.     wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
  163.     wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
  164. #endif
  165.     
  166.     /*  setup initial column positions */
  167.     /*  (y<0 => not ready to scroll yet) */
  168.     /* PM : *2 for double buffer */
  169.    y = (int *) Z_Malloc(width*sizeof(int)*2, PU_STATIC, 0);
  170.  
  171.     y[0] = -(M_Random()%16);
  172.     for (i=1;i<width;i++)
  173.     {
  174.     r = (M_Random()%3) - 1;
  175.     y[i] = y[i-1] + r;
  176.     if (y[i] > 0) y[i] = 0;
  177.     else if (y[i] == -16) y[i] = -15;
  178.     }
  179.  
  180.     if (dblbuffer)
  181.     {
  182.         /* Copie tableau pour second buffer */
  183.         for (i=0;i<width;i++)
  184.             y[i+width]=y[i];
  185.     }
  186.  
  187.     return 0;
  188. }
  189.  
  190. int
  191. wipe_doMelt8
  192. ( int    width,
  193.   int    height,
  194.   int    ticks )
  195. {
  196.     int        i;
  197.     int        j;
  198.     int        dy;
  199.     int        idx;
  200.     
  201.     short*    s;
  202.     short*    d;
  203.     boolean    done = true;
  204.     int    *yy=y+width*fbnum;
  205.  
  206.     width/=2;
  207.  
  208.     while (ticks--)
  209.     {
  210.     for (i=0;i<width;i++)
  211.     {
  212.         if (yy[i]<0)
  213.         {
  214.         yy[i]++;
  215.         done = false;
  216.         }
  217.         else if (yy[i] < height)
  218.         {
  219.         if (yy[i] < 16)
  220.             dy = yy[i]+1;
  221.         else
  222.             dy = 8;
  223.  
  224.         if (yy[i]+dy >= height)
  225.             dy = height -yy[i];
  226.  
  227.         s = &((short *)wipe_scr_end)[yy[i]*width+i];
  228.         d = &((short *)wipe_scr)[yy[i]*width+i];
  229.         idx = 0;
  230.         for (j=dy;j;j--)
  231.         {
  232.             d[idx] = s[idx];
  233.             idx += width;
  234.         }
  235.         yy[i] += dy;
  236.  
  237.         s = &((short *)wipe_scr_start)[i];
  238.         d = &((short *)wipe_scr)[yy[i]*width+i];
  239.         idx = 0;
  240.         for (j=height-yy[i];j;j--)
  241.         {
  242.             d[idx] = s[idx];
  243.             idx += width;
  244.         }
  245.         done = false;
  246.         }
  247.     }
  248.     }
  249.  
  250.     return done;
  251. }
  252.  
  253. int
  254. wipe_doMelt16
  255. ( int    width,
  256.   int    height,
  257.   int    ticks )
  258. {
  259.     int        i;
  260.     int        j;
  261.     int        dy;
  262.     int        idx;
  263.     
  264.     unsigned long    *s,*d;
  265.     boolean    done = true;
  266.     int    *yy=y+width*fbnum;
  267.  
  268.     width/=2;
  269.  
  270.     while (ticks--)
  271.     {
  272.     for (i=0;i<width;i++)
  273.     {
  274.         if (yy[i]<0)
  275.         {
  276.         yy[i]++;
  277.         done = false;
  278.         }
  279.         else if (yy[i] < height)
  280.         {
  281.         if (yy[i] < 16)
  282.             dy = yy[i]+1;
  283.         else
  284.             dy = 8;
  285.  
  286.         if (yy[i]+dy >= height)
  287.             dy = height - yy[i];
  288.  
  289.         s = &((unsigned long *)wipe_scr_end)[yy[i]*width+i];
  290.         d = &((unsigned long *)wipe_scr)[yy[i]*width+i];
  291.         idx = 0;
  292.         for (j=dy;j;j--)
  293.         {
  294.             d[idx] = s[idx];
  295.             idx += width;
  296.         }
  297.         yy[i] += dy;
  298.  
  299.         s = &((unsigned long *)wipe_scr_start)[i];
  300.         d = &((unsigned long *)wipe_scr)[yy[i]*width+i];
  301.         idx = 0;
  302.         for (j=height-yy[i];j;j--)
  303.         {
  304.             d[idx] = s[idx];
  305.             idx += width;
  306.         }
  307.  
  308.         done = false;
  309.         }
  310.     }
  311.     }
  312.  
  313.     return done;
  314. }
  315.  
  316. int
  317. wipe_doMelt24
  318. ( int    width,
  319.   int    height,
  320.   int    ticks )
  321. {
  322.     int        i;
  323.     int        j;
  324.     int        dy;
  325.     int        idx;
  326.     
  327.     short*    s;
  328.     short*    d;
  329.     boolean    done = true;
  330.     int    *yy=y+width*fbnum;
  331.  
  332.  
  333.     width/=2;
  334.  
  335.     while (ticks--)
  336.     {
  337.     for (i=0;i<width;i++)
  338.     {
  339.         if (yy[i]<0)
  340.         {
  341.         yy[i]++;
  342.         done = false;
  343.         }
  344.         else if (yy[i] < height)
  345.         {
  346.         if (yy[i] < 16)
  347.             dy = yy[i]+1;
  348.         else
  349.             dy = 8;
  350.  
  351.         if (yy[i]+dy >= height)
  352.             dy = height - yy[i];
  353.  
  354.         s = &((short *)wipe_scr_end)[(yy[i]*width+i)*3];
  355.         d = &((short *)wipe_scr)[(yy[i]*width+i)*3];
  356.         idx = 0;
  357.         for (j=dy;j;j--)
  358.         {
  359.             d[idx] = s[idx++];
  360.             d[idx] = s[idx++];
  361.             d[idx] = s[idx++];
  362.             idx += (width*3)-3;
  363.         }
  364.         yy[i] += dy;
  365.  
  366.         s = &((short *)wipe_scr_start)[i*3];
  367.         d = &((short *)wipe_scr)[(yy[i]*width+i)*3];
  368.         idx = 0;
  369.         for (j=height-yy[i];j;j--)
  370.         {
  371.             d[idx] = s[idx++];
  372.             d[idx] = s[idx++];
  373.             d[idx] = s[idx++];
  374.             idx += (width*3)-3;
  375.         }
  376.         done = false;
  377.         }
  378.     }
  379.     }
  380.  
  381.     return done;
  382. }
  383.  
  384. int
  385. wipe_doMelt32
  386. ( int    width,
  387.   int    height,
  388.   int    ticks )
  389. {
  390.     int        i;
  391.     int        j;
  392.     int        dy;
  393.     int        idx;
  394.     
  395.     unsigned long    *s,*d;
  396.     boolean    done = true;
  397.     int    *yy=y+width*fbnum;
  398.  
  399.     width/=2;
  400.  
  401.     while (ticks--)
  402.     {
  403.     for (i=0;i<width;i++)
  404.     {
  405.         if (yy[i]<0)
  406.         {
  407.         yy[i]++;
  408.         done = false;
  409.         }
  410.         else if (yy[i] < height)
  411.         {
  412.         if (yy[i] < 16)
  413.             dy = yy[i]+1;
  414.         else
  415.             dy = 8;
  416.  
  417.         if (yy[i]+dy >= height)
  418.             dy = height - yy[i];
  419.  
  420.         s = &((unsigned long *)wipe_scr_end)[(yy[i]*width+i)*2];
  421.         d = &((unsigned long *)wipe_scr)[(yy[i]*width+i)*2];
  422.         idx = 0;
  423.         for (j=dy;j;j--)
  424.         {
  425.             d[idx] = s[idx++];
  426.             d[idx] = s[idx++];
  427.             idx += (width*2)-2;
  428.         }
  429.         yy[i] += dy;
  430.  
  431.         s = &((unsigned long *)wipe_scr_start)[i*2];
  432.         d = &((unsigned long *)wipe_scr)[(yy[i]*width+i)*2];
  433.         idx = 0;
  434.         for (j=height-yy[i];j;j--)
  435.         {
  436.             d[idx] = s[idx++];
  437.             d[idx] = s[idx++];
  438.             idx += (width*2)-2;
  439.         }
  440.  
  441.         done = false;
  442.         }
  443.     }
  444.     }
  445.  
  446.     return done;
  447. }
  448.  
  449. int
  450. wipe_exitMelt
  451. ( int    width,
  452.   int    height,
  453.   int    ticks )
  454. {
  455.     Z_Free(y);
  456.     return 0;
  457. }
  458.  
  459. int
  460. wipe_StartScreen
  461. ( int    x,
  462.   int    y,
  463.   int    width,
  464.   int    height )
  465. {
  466.     wipe_scr_start = screens[2];
  467.     I_ReadScreen(wipe_scr_start);
  468.     return 0;
  469. }
  470.  
  471. int
  472. wipe_EndScreen
  473. ( int    x,
  474.   int    y,
  475.   int    width,
  476.   int    height )
  477. {
  478.     wipe_scr_end = screens[3];
  479.     I_ReadScreen(wipe_scr_end);
  480.     V_DrawBlock(x, y, 0, width, height, wipe_scr_start); /*  restore start scr. */
  481.     return 0;
  482. }
  483.  
  484. void V_MarkRect(int, int, int, int);
  485.  
  486. int
  487. wipe_ScreenWipe
  488. ( int    wipeno,
  489.   int    x,
  490.   int    y,
  491.   int    width,
  492.   int    height,
  493.   int    ticks )
  494. {
  495.     int rc;
  496.     static int (*wipes[])(int, int, int) =
  497.     {
  498.     wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm,
  499.     wipe_initMelt, wipe_doMelt8, wipe_exitMelt
  500.     };
  501.  
  502.     wipes[4]=wipe_doMelt;
  503.  
  504.  
  505.     /*  initial stuff */
  506.     if (!go)
  507.     {
  508.     go = 1;
  509.     /*  wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG */
  510.     wipe_scr = screens[0];
  511.     (*wipes[wipeno*3])(width, height, ticks);
  512.     }
  513.  
  514.     /*  do a piece of wipe-in */
  515.     if (dblbuffer)
  516.         wipe_scr=screens[0];
  517.  
  518.     V_MarkRect(0, 0, width, height);
  519.     rc = (*wipes[wipeno*3+1])(width, height, ticks);
  520.     /*   V_DrawBlock(x, y, 0, width, height, wipe_scr); // DEBUG */
  521.  
  522.     /*  final stuff */
  523.     if (rc)
  524.     {
  525.     go = 0;
  526.     (*wipes[wipeno*3+2])(width, height, ticks);
  527.     }
  528.  
  529.     return !go;
  530.  
  531. }
  532.