diff options
Diffstat (limited to 'apps/plugins/doom/f_wipe.c')
-rw-r--r-- | apps/plugins/doom/f_wipe.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/apps/plugins/doom/f_wipe.c b/apps/plugins/doom/f_wipe.c new file mode 100644 index 0000000000..a6251f295e --- /dev/null +++ b/apps/plugins/doom/f_wipe.c | |||
@@ -0,0 +1,193 @@ | |||
1 | /* Emacs style mode select -*- C++ -*- | ||
2 | *----------------------------------------------------------------------------- | ||
3 | * | ||
4 | * | ||
5 | * PrBoom a Doom port merged with LxDoom and LSDLDoom | ||
6 | * based on BOOM, a modified and improved DOOM engine | ||
7 | * Copyright (C) 1999 by | ||
8 | * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman | ||
9 | * Copyright (C) 1999-2000 by | ||
10 | * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
25 | * 02111-1307, USA. | ||
26 | * | ||
27 | * DESCRIPTION: | ||
28 | * Mission begin melt/wipe screen special effect. | ||
29 | * | ||
30 | *----------------------------------------------------------------------------- | ||
31 | */ | ||
32 | |||
33 | #include "rockmacros.h" | ||
34 | #include "z_zone.h" | ||
35 | #include "doomdef.h" | ||
36 | #include "i_video.h" | ||
37 | #include "v_video.h" | ||
38 | #include "m_random.h" | ||
39 | #include "f_wipe.h" | ||
40 | |||
41 | |||
42 | |||
43 | // | ||
44 | // SCREEN WIPE PACKAGE | ||
45 | // | ||
46 | |||
47 | // CPhipps - macros for the source and destination screens | ||
48 | #define SRC_SCR 2 | ||
49 | #define DEST_SCR 3 | ||
50 | |||
51 | static byte *wipe_scr_start; | ||
52 | static byte *wipe_scr_end; | ||
53 | static byte *wipe_scr; | ||
54 | |||
55 | static void wipe_shittyColMajorXform(short *array, int width, int height) | ||
56 | { | ||
57 | short *dest = Z_Malloc(width*height*sizeof(short), PU_STATIC, 0); | ||
58 | int x, y; | ||
59 | |||
60 | for(y=0;y<height;y++) | ||
61 | for(x=0;x<width;x++) | ||
62 | dest[x*height+y] = array[y*width+x]; | ||
63 | memcpy(array, dest, width*height*sizeof(short)); | ||
64 | Z_Free(dest); | ||
65 | } | ||
66 | |||
67 | static int *y; | ||
68 | |||
69 | static int wipe_initMelt(int width, int height, int ticks) | ||
70 | { | ||
71 | (void)ticks; | ||
72 | int i; | ||
73 | |||
74 | // copy start screen to main screen | ||
75 | memcpy(wipe_scr, wipe_scr_start, width*height); | ||
76 | |||
77 | // makes this wipe faster (in theory) | ||
78 | // to have stuff in column-major format | ||
79 | wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height); | ||
80 | wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height); | ||
81 | |||
82 | // setup initial column positions (y<0 => not ready to scroll yet) | ||
83 | y = (int *) malloc(width*sizeof(int)); | ||
84 | y[0] = -(M_Random()%16); | ||
85 | for (i=1;i<width;i++) | ||
86 | { | ||
87 | int r = (M_Random()%3) - 1; | ||
88 | y[i] = y[i-1] + r; | ||
89 | if (y[i] > 0) | ||
90 | y[i] = 0; | ||
91 | else | ||
92 | if (y[i] == -16) | ||
93 | y[i] = -15; | ||
94 | } | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int wipe_doMelt(int width, int height, int ticks) | ||
99 | { | ||
100 | boolean done = true; | ||
101 | int i; | ||
102 | |||
103 | width /= 2; | ||
104 | |||
105 | while (ticks--) | ||
106 | for (i=0;i<width;i++) | ||
107 | if (y[i]<0) | ||
108 | { | ||
109 | y[i]++; | ||
110 | done = false; | ||
111 | } | ||
112 | else | ||
113 | if (y[i] < height) | ||
114 | { | ||
115 | short *s, *d; | ||
116 | int j, dy, idx; | ||
117 | |||
118 | dy = (y[i] < 16) ? y[i]+1 : 8; | ||
119 | if (y[i]+dy >= height) | ||
120 | dy = height - y[i]; | ||
121 | s = &((short *)wipe_scr_end)[i*height+y[i]]; | ||
122 | d = &((short *)wipe_scr)[y[i]*width+i]; | ||
123 | idx = 0; | ||
124 | for (j=dy;j;j--) | ||
125 | { | ||
126 | d[idx] = *(s++); | ||
127 | idx += width; | ||
128 | } | ||
129 | y[i] += dy; | ||
130 | s = &((short *)wipe_scr_start)[i*height]; | ||
131 | d = &((short *)wipe_scr)[y[i]*width+i]; | ||
132 | idx = 0; | ||
133 | for (j=height-y[i];j;j--) | ||
134 | { | ||
135 | d[idx] = *(s++); | ||
136 | idx += width; | ||
137 | } | ||
138 | done = false; | ||
139 | } | ||
140 | return done; | ||
141 | } | ||
142 | |||
143 | // CPhipps - modified to allocate and deallocate screens[2 to 3] as needed, saving memory | ||
144 | |||
145 | static int wipe_exitMelt(int width, int height, int ticks) | ||
146 | { | ||
147 | (void)width; | ||
148 | (void)height; | ||
149 | (void)ticks; | ||
150 | free(y); | ||
151 | free(wipe_scr_start); | ||
152 | free(wipe_scr_end); | ||
153 | // Paranoia | ||
154 | y = NULL; | ||
155 | wipe_scr_start = wipe_scr_end = screens[SRC_SCR] = screens[DEST_SCR] = NULL; | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | int wipe_StartScreen(int x, int y, int width, int height) | ||
160 | { | ||
161 | wipe_scr_start = screens[SRC_SCR] = malloc(SCREENWIDTH * SCREENHEIGHT); | ||
162 | V_CopyRect(x, y, 0, width, height, x, y, SRC_SCR, VPT_NONE ); // Copy start screen to buffer | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | int wipe_EndScreen(int x, int y, int width, int height) | ||
167 | { | ||
168 | wipe_scr_end = screens[DEST_SCR] = malloc(SCREENWIDTH * SCREENHEIGHT); | ||
169 | V_CopyRect(x, y, 0, width, height, x, y, DEST_SCR, VPT_NONE); // Copy end screen to buffer | ||
170 | V_CopyRect(x, y, SRC_SCR, width, height, x, y, 0 , VPT_NONE); // restore start screen | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | // killough 3/5/98: reformatted and cleaned up | ||
175 | int wipe_ScreenWipe(int x, int y, int width, int height, int ticks) | ||
176 | { | ||
177 | (void)x; | ||
178 | (void)y; | ||
179 | static boolean go; // when zero, stop the wipe | ||
180 | if (!go) // initial stuff | ||
181 | { | ||
182 | go = 1; | ||
183 | wipe_scr = screens[0]; | ||
184 | wipe_initMelt(width, height, ticks); | ||
185 | } | ||
186 | V_MarkRect(0, 0, width, height); // do a piece of wipe-in | ||
187 | if (wipe_doMelt(width, height, ticks)) // final stuff | ||
188 | { | ||
189 | wipe_exitMelt(width, height, ticks); | ||
190 | go = 0; | ||
191 | } | ||
192 | return !go; | ||
193 | } | ||