doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

f_wipe.c (3813B)


      1 #include "z_zone.h"
      2 #include "i_video.h"
      3 #include "v_video.h"
      4 #include "m_random.h"
      5 
      6 #include "doomdef.h"
      7 #include "f_wipe.h"
      8 
      9 static boolean	go = 0;
     10 static byte*	wipe_scr_start;
     11 static byte*	wipe_scr_end;
     12 static byte*	wipe_scr;
     13 
     14 void
     15 wipe_shittyColMajorXform(short* array, int width, int height)
     16 {
     17     int		x;
     18     int		y;
     19     short*	dest;
     20 
     21     dest = (short*) Z_Malloc(width*height*2, PU_STATIC, 0);
     22 
     23     for(y=0;y<height;y++)
     24 	for(x=0;x<width;x++)
     25 	    dest[x*height+y] = array[y*width+x];
     26 
     27     memcpy(array, dest, width*height*2);
     28 
     29     Z_Free(dest);
     30 
     31 }
     32 
     33 int
     34 wipe_initColorXForm(int width, int height, int ticks)
     35 {
     36     memcpy(wipe_scr, wipe_scr_start, width*height);
     37     return 0;
     38 }
     39 
     40 int
     41 wipe_doColorXForm( int	width,
     42   int	height,
     43   int	ticks )
     44 {
     45     byte*	w;
     46     byte*	e;
     47     boolean changed;
     48     int     newval;
     49 
     50     changed = false;
     51     w = wipe_scr;
     52     e = wipe_scr_end;
     53     
     54     while (w!=wipe_scr+width*height)
     55     {
     56 	if (*w != *e) {
     57 	    if (*w > *e)
     58 	    {
     59 		newval = *w - ticks;
     60 		if (newval < *e)
     61 		    *w = *e;
     62 		else
     63 		    *w = newval;
     64 		changed = true;
     65 	    }
     66 	    else if (*w < *e)
     67 	    {
     68 		newval = *w + ticks;
     69 		if (newval > *e)
     70 		    *w = *e;
     71 		else
     72 		    *w = newval;
     73 		changed = true;
     74 	    }
     75 	}
     76 	w++;
     77 	e++;
     78     }
     79 
     80     return !changed;
     81 
     82 }
     83 
     84 int
     85 wipe_exitColorXForm
     86 ( int	width,
     87   int	height,
     88   int	ticks )
     89 {
     90     return 0;
     91 }
     92 
     93 
     94 static int*	y;
     95 
     96 int
     97 wipe_initMelt
     98 ( int	width,
     99   int	height,
    100   int	ticks )
    101 {
    102     int i, r;
    103     
    104     
    105     memcpy(wipe_scr, wipe_scr_start, width*height);
    106     
    107     
    108     
    109     wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
    110     wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
    111     
    112     
    113     
    114     y = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0);
    115     y[0] = -(M_Random()%16);
    116     for (i=1;i<width;i++)
    117     {
    118 	r = (M_Random()%3) - 1;
    119 	y[i] = y[i-1] + r;
    120 	if (y[i] > 0) y[i] = 0;
    121 	else if (y[i] == -16) y[i] = -15;
    122     }
    123 
    124     return 0;
    125 }
    126 
    127 int
    128 wipe_doMelt
    129 ( int	width,
    130   int	height,
    131   int	ticks )
    132 {
    133     int		i;
    134     int		j;
    135     int		dy;
    136     int		idx;
    137     
    138     short*	s;
    139     short*	d;
    140     boolean	done = true;
    141 
    142     width/=2;
    143 
    144     while (ticks--)
    145     {
    146 	for (i=0;i<width;i++)
    147 	{
    148 	    if (y[i]<0)
    149 	    {
    150 		y[i]++; done = false;
    151 	    }
    152 	    else if (y[i] < height)
    153 	    {
    154 		dy = (y[i] < 16) ? y[i]+1 : 8;
    155 		if (y[i]+dy >= height) dy = height - y[i];
    156 		s = &((short *)wipe_scr_end)[i*height+y[i]];
    157 		d = &((short *)wipe_scr)[y[i]*width+i];
    158 		idx = 0;
    159 		for (j=dy;j;j--)
    160 		{
    161 		    d[idx] = *(s++);
    162 		    idx += width;
    163 		}
    164 		y[i] += dy;
    165 		s = &((short *)wipe_scr_start)[i*height];
    166 		d = &((short *)wipe_scr)[y[i]*width+i];
    167 		idx = 0;
    168 		for (j=height-y[i];j;j--)
    169 		{
    170 		    d[idx] = *(s++);
    171 		    idx += width;
    172 		}
    173 		done = false;
    174 	    }
    175 	}
    176     }
    177 
    178     return done;
    179 
    180 }
    181 
    182 int
    183 wipe_exitMelt
    184 ( int	width,
    185   int	height,
    186   int	ticks )
    187 {
    188     Z_Free(y);
    189     return 0;
    190 }
    191 
    192 int
    193 wipe_StartScreen
    194 ( int	x,
    195   int	y,
    196   int	width,
    197   int	height )
    198 {
    199     wipe_scr_start = screens[2];
    200     I_ReadScreen(wipe_scr_start);
    201     return 0;
    202 }
    203 
    204 int
    205 wipe_EndScreen
    206 ( int	x,
    207   int	y,
    208   int	width,
    209   int	height )
    210 {
    211     wipe_scr_end = screens[3];
    212     I_ReadScreen(wipe_scr_end);
    213     V_DrawBlock(x, y, 0, width, height, wipe_scr_start); 
    214     return 0;
    215 }
    216 
    217 int
    218 wipe_ScreenWipe
    219 ( int	wipeno,
    220   int	x,
    221   int	y,
    222   int	width,
    223   int	height,
    224   int	ticks )
    225 {
    226     int rc;
    227     static int (*wipes[])(int, int, int) =
    228     {
    229 	wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm,
    230 	wipe_initMelt, wipe_doMelt, wipe_exitMelt
    231     };
    232 
    233     void V_MarkRect(int, int, int, int);
    234 
    235     
    236     if (!go)
    237     {
    238 	go = 1;
    239 	
    240 	wipe_scr = screens[0];
    241 	(*wipes[wipeno*3])(width, height, ticks);
    242     }
    243 
    244     
    245     V_MarkRect(0, 0, width, height);
    246     rc = (*wipes[wipeno*3+1])(width, height, ticks);
    247     
    248 
    249     
    250     if (rc)
    251     {
    252 	go = 0;
    253 	(*wipes[wipeno*3+2])(width, height, ticks);
    254     }
    255 
    256     return !go;
    257 
    258 }