]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/f_wipe.c
games/doom:
[plan9front.git] / sys / src / games / doom / f_wipe.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
24
25 static const char rcsid[] = "$Id: f_wipe.c,v 1.2 1997/02/03 22:45:09 b1 Exp $";
26
27
28 #include "doomdef.h"
29
30 #include "z_zone.h"
31 #include "i_video.h"
32 #include "v_video.h"
33 #include "m_random.h"
34
35 #include "f_wipe.h"
36
37 //
38 //                       SCREEN WIPE PACKAGE
39 //
40
41 // when zero, stop the wipe
42 static boolean  go = 0;
43
44 static byte*    wipe_scr_start;
45 static byte*    wipe_scr_end;
46 static byte*    wipe_scr;
47
48
49 void
50 wipe_shittyColMajorXform
51 ( short*        array,
52   int           width,
53   int           height )
54 {
55     int         x;
56     int         y;
57     short*      dest;
58
59     dest = (short*) Z_Malloc(width*height*2, PU_STATIC, 0);
60
61     for(y=0;y<height;y++)
62         for(x=0;x<width;x++)
63             dest[x*height+y] = array[y*width+x];
64
65     memcpy(array, dest, width*height*2);
66
67     Z_Free(dest);
68
69 }
70
71 int
72 wipe_initColorXForm
73 ( int   width,
74   int   height,
75   int   /*ticks*/ )
76 {
77     memcpy(wipe_scr, wipe_scr_start, width*height);
78     return 0;
79 }
80
81 int
82 wipe_doColorXForm
83 ( int   width,
84   int   height,
85   int   ticks )
86 {
87     boolean     changed;
88     byte*       w;
89     byte*       e;
90     int         newval;
91
92     changed = false;
93     w = wipe_scr;
94     e = wipe_scr_end;
95     
96     while (w!=wipe_scr+width*height)
97     {
98         if (*w != *e)
99         {
100             if (*w > *e)
101             {
102                 newval = *w - ticks;
103                 if (newval < *e)
104                     *w = *e;
105                 else
106                     *w = newval;
107                 changed = true;
108             }
109             else if (*w < *e)
110             {
111                 newval = *w + ticks;
112                 if (newval > *e)
113                     *w = *e;
114                 else
115                     *w = newval;
116                 changed = true;
117             }
118         }
119         w++;
120         e++;
121     }
122
123     return !changed;
124
125 }
126
127 int
128 wipe_exitColorXForm
129 ( int   /*width*/,
130   int   /*height*/,
131   int   /*ticks*/ )
132 {
133     return 0;
134 }
135
136
137 static int*     y;
138
139 int
140 wipe_initMelt
141 ( int   width,
142   int   height,
143   int   /*ticks*/ )
144 {
145     int i, r;
146     
147     // copy start screen to main screen
148     memcpy(wipe_scr, wipe_scr_start, width*height);
149     
150     // makes this wipe faster (in theory)
151     // to have stuff in column-major format
152     wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
153     wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
154     
155     // setup initial column positions
156     // (y<0 => not ready to scroll yet)
157     y = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0);
158     y[0] = -(M_Random()%16);
159     for (i=1;i<width;i++)
160     {
161         r = (M_Random()%3) - 1;
162         y[i] = y[i-1] + r;
163         if (y[i] > 0) y[i] = 0;
164         else if (y[i] == -16) y[i] = -15;
165     }
166
167     return 0;
168 }
169
170 int
171 wipe_doMelt
172 ( int   width,
173   int   height,
174   int   ticks )
175 {
176     int         i;
177     int         j;
178     int         dy;
179     int         idx;
180     
181     short*      s;
182     short*      d;
183     boolean     done = true;
184
185     width/=2;
186
187     while (ticks--)
188     {
189         for (i=0;i<width;i++)
190         {
191             if (y[i]<0)
192             {
193                 y[i]++; done = false;
194             }
195             else if (y[i] < height)
196             {
197                 dy = (y[i] < 16) ? y[i]+1 : 8;
198                 if (y[i]+dy >= height) dy = height - y[i];
199                 s = &((short *)wipe_scr_end)[i*height+y[i]];
200                 d = &((short *)wipe_scr)[y[i]*width+i];
201                 idx = 0;
202                 for (j=dy;j;j--)
203                 {
204                     d[idx] = *(s++);
205                     idx += width;
206                 }
207                 y[i] += dy;
208                 s = &((short *)wipe_scr_start)[i*height];
209                 d = &((short *)wipe_scr)[y[i]*width+i];
210                 idx = 0;
211                 for (j=height-y[i];j;j--)
212                 {
213                     d[idx] = *(s++);
214                     idx += width;
215                 }
216                 done = false;
217             }
218         }
219     }
220
221     return done;
222
223 }
224
225 int
226 wipe_exitMelt
227 ( int   /*width*/,
228   int   /*height*/,
229   int   /*ticks*/ )
230 {
231     Z_Free(y);
232     return 0;
233 }
234
235 int
236 wipe_StartScreen
237 ( int   /*x*/,
238   int   /*y*/,
239   int   /*width*/,
240   int   /*height*/ )
241 {
242     wipe_scr_start = screens[2];
243     I_ReadScreen(wipe_scr_start);
244     return 0;
245 }
246
247 int
248 wipe_EndScreen
249 ( int   x,
250   int   y,
251   int   width,
252   int   height )
253 {
254     wipe_scr_end = screens[3];
255     I_ReadScreen(wipe_scr_end);
256     V_DrawBlock(x, y, 0, width, height, wipe_scr_start); // restore start scr.
257     return 0;
258 }
259
260 int
261 wipe_ScreenWipe
262 ( int   wipeno,
263   int   /*x*/,
264   int   /*y*/,
265   int   width,
266   int   height,
267   int   ticks )
268 {
269     int rc;
270     static int (*wipes[])(int, int, int) =
271     {
272         wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm,
273         wipe_initMelt, wipe_doMelt, wipe_exitMelt
274     };
275
276     void V_MarkRect(int, int, int, int);
277
278     // initial stuff
279     if (!go)
280     {
281         go = 1;
282         // wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG
283         wipe_scr = screens[0];
284         (*wipes[wipeno*3])(width, height, ticks);
285     }
286
287     // do a piece of wipe-in
288     V_MarkRect(0, 0, width, height);
289     rc = (*wipes[wipeno*3+1])(width, height, ticks);
290     //  V_DrawBlock(x, y, 0, width, height, wipe_scr); // DEBUG
291
292     // final stuff
293     if (rc)
294     {
295         go = 0;
296         (*wipes[wipeno*3+2])(width, height, ticks);
297     }
298
299     return !go;
300
301 }