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 }