diff options
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/id_vh.c')
-rw-r--r-- | apps/plugins/sdl/progs/wolf3d/id_vh.c | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/id_vh.c b/apps/plugins/sdl/progs/wolf3d/id_vh.c new file mode 100644 index 0000000000..a63dd065a7 --- /dev/null +++ b/apps/plugins/sdl/progs/wolf3d/id_vh.c | |||
@@ -0,0 +1,435 @@ | |||
1 | #include "wl_def.h" | ||
2 | |||
3 | |||
4 | pictabletype *pictable; | ||
5 | SDL_Surface *latchpics[NUMLATCHPICS]; | ||
6 | |||
7 | int px,py; | ||
8 | byte fontcolor,backcolor; | ||
9 | int fontnumber; | ||
10 | |||
11 | //========================================================================== | ||
12 | |||
13 | void VWB_DrawPropString(const char* string) | ||
14 | { | ||
15 | fontstruct *font; | ||
16 | int width, step, height; | ||
17 | byte *source, *dest; | ||
18 | byte ch; | ||
19 | |||
20 | byte *vbuf = LOCK(); | ||
21 | |||
22 | font = (fontstruct *) grsegs[STARTFONT+fontnumber]; | ||
23 | height = font->height; | ||
24 | dest = vbuf + scaleFactor * (py * curPitch + px); | ||
25 | |||
26 | while ((ch = (byte)*string++)!=0) | ||
27 | { | ||
28 | width = step = font->width[ch]; | ||
29 | source = ((byte *)font)+font->location[ch]; | ||
30 | while (width--) | ||
31 | { | ||
32 | for(int i=0;i<height;i++) | ||
33 | { | ||
34 | if(source[i*step]) | ||
35 | { | ||
36 | for(unsigned sy=0; sy<scaleFactor; sy++) | ||
37 | for(unsigned sx=0; sx<scaleFactor; sx++) | ||
38 | dest[(scaleFactor*i+sy)*curPitch+sx]=fontcolor; | ||
39 | } | ||
40 | } | ||
41 | |||
42 | source++; | ||
43 | px++; | ||
44 | dest+=scaleFactor; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | UNLOCK(); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | ================= | ||
53 | = | ||
54 | = VL_MungePic | ||
55 | = | ||
56 | ================= | ||
57 | */ | ||
58 | |||
59 | void VL_MungePic (byte *source, unsigned width, unsigned height) | ||
60 | { | ||
61 | unsigned x,y,plane,size,pwidth; | ||
62 | byte *temp, *dest, *srcline; | ||
63 | |||
64 | size = width*height; | ||
65 | |||
66 | if (width&3) | ||
67 | Quit ("VL_MungePic: Not divisable by 4!"); | ||
68 | |||
69 | // | ||
70 | // copy the pic to a temp buffer | ||
71 | // | ||
72 | temp=(byte *) malloc(size); | ||
73 | CHECKMALLOCRESULT(temp); | ||
74 | memcpy (temp,source,size); | ||
75 | |||
76 | // | ||
77 | // munge it back into the original buffer | ||
78 | // | ||
79 | dest = source; | ||
80 | pwidth = width/4; | ||
81 | |||
82 | for (plane=0;plane<4;plane++) | ||
83 | { | ||
84 | srcline = temp; | ||
85 | for (y=0;y<height;y++) | ||
86 | { | ||
87 | for (x=0;x<pwidth;x++) | ||
88 | *dest++ = *(srcline+x*4+plane); | ||
89 | srcline+=width; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | free(temp); | ||
94 | } | ||
95 | |||
96 | void VWL_MeasureString (const char *string, word *width, word *height, fontstruct *font) | ||
97 | { | ||
98 | *height = font->height; | ||
99 | for (*width = 0;*string;string++) | ||
100 | *width += font->width[*((byte *)string)]; // proportional width | ||
101 | } | ||
102 | |||
103 | void VW_MeasurePropString (const char *string, word *width, word *height) | ||
104 | { | ||
105 | VWL_MeasureString(string,width,height,(fontstruct *)grsegs[STARTFONT+fontnumber]); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | ============================================================================= | ||
110 | |||
111 | Double buffer management routines | ||
112 | |||
113 | ============================================================================= | ||
114 | */ | ||
115 | |||
116 | void VH_UpdateScreen() | ||
117 | { | ||
118 | SDL_BlitSurface(screenBuffer, NULL, screen, NULL); | ||
119 | SDL_Flip(screen); | ||
120 | } | ||
121 | |||
122 | |||
123 | void VWB_DrawTile8 (int x, int y, int tile) | ||
124 | { | ||
125 | LatchDrawChar(x,y,tile); | ||
126 | } | ||
127 | |||
128 | void VWB_DrawTile8M (int x, int y, int tile) | ||
129 | { | ||
130 | VL_MemToScreen (((byte *)grsegs[STARTTILE8M])+tile*64,8,8,x,y); | ||
131 | } | ||
132 | |||
133 | void VWB_DrawPic (int x, int y, int chunknum) | ||
134 | { | ||
135 | int picnum = chunknum - STARTPICS; | ||
136 | unsigned width,height; | ||
137 | |||
138 | x &= ~7; | ||
139 | |||
140 | width = pictable[picnum].width; | ||
141 | height = pictable[picnum].height; | ||
142 | |||
143 | VL_MemToScreen (grsegs[chunknum],width,height,x,y); | ||
144 | } | ||
145 | |||
146 | void VWB_DrawPicScaledCoord (int scx, int scy, int chunknum) | ||
147 | { | ||
148 | int picnum = chunknum - STARTPICS; | ||
149 | unsigned width,height; | ||
150 | |||
151 | width = pictable[picnum].width; | ||
152 | height = pictable[picnum].height; | ||
153 | |||
154 | VL_MemToScreenScaledCoord (grsegs[chunknum],width,height,scx,scy); | ||
155 | } | ||
156 | |||
157 | |||
158 | void VWB_Bar (int x, int y, int width, int height, int color) | ||
159 | { | ||
160 | VW_Bar (x,y,width,height,color); | ||
161 | } | ||
162 | |||
163 | void VWB_Plot (int x, int y, int color) | ||
164 | { | ||
165 | if(scaleFactor == 1) | ||
166 | VW_Plot(x,y,color); | ||
167 | else | ||
168 | VW_Bar(x, y, 1, 1, color); | ||
169 | } | ||
170 | |||
171 | void VWB_Hlin (int x1, int x2, int y, int color) | ||
172 | { | ||
173 | if(scaleFactor == 1) | ||
174 | VW_Hlin(x1,x2,y,color); | ||
175 | else | ||
176 | VW_Bar(x1, y, x2-x1+1, 1, color); | ||
177 | } | ||
178 | |||
179 | void VWB_Vlin (int y1, int y2, int x, int color) | ||
180 | { | ||
181 | if(scaleFactor == 1) | ||
182 | VW_Vlin(y1,y2,x,color); | ||
183 | else | ||
184 | VW_Bar(x, y1, 1, y2-y1+1, color); | ||
185 | } | ||
186 | |||
187 | |||
188 | /* | ||
189 | ============================================================================= | ||
190 | |||
191 | WOLFENSTEIN STUFF | ||
192 | |||
193 | ============================================================================= | ||
194 | */ | ||
195 | |||
196 | /* | ||
197 | ===================== | ||
198 | = | ||
199 | = LatchDrawPic | ||
200 | = | ||
201 | ===================== | ||
202 | */ | ||
203 | |||
204 | void LatchDrawPic (unsigned x, unsigned y, unsigned picnum) | ||
205 | { | ||
206 | VL_LatchToScreen_ez (latchpics[2+picnum-LATCHPICS_LUMP_START], x*8, y); | ||
207 | } | ||
208 | |||
209 | void LatchDrawPicScaledCoord (unsigned scx, unsigned scy, unsigned picnum) | ||
210 | { | ||
211 | VL_LatchToScreenScaledCoord_ez (latchpics[2+picnum-LATCHPICS_LUMP_START], scx*8, scy); | ||
212 | } | ||
213 | |||
214 | |||
215 | //========================================================================== | ||
216 | |||
217 | /* | ||
218 | =================== | ||
219 | = | ||
220 | = LoadLatchMem | ||
221 | = | ||
222 | =================== | ||
223 | */ | ||
224 | |||
225 | void LoadLatchMem (void) | ||
226 | { | ||
227 | int i,width,height,start,end; | ||
228 | byte *src; | ||
229 | SDL_Surface *surf; | ||
230 | |||
231 | // | ||
232 | // tile 8s | ||
233 | // | ||
234 | surf = SDL_CreateRGBSurface(SDL_HWSURFACE, 8*8, | ||
235 | ((NUMTILE8 + 7) / 8) * 8, 8, 0, 0, 0, 0); | ||
236 | if(surf == NULL) | ||
237 | { | ||
238 | Quit("Unable to create surface for tiles!"); | ||
239 | } | ||
240 | SDL_SetColors(surf, gamepal, 0, 256); | ||
241 | |||
242 | latchpics[0] = surf; | ||
243 | CA_CacheGrChunk (STARTTILE8); | ||
244 | src = grsegs[STARTTILE8]; | ||
245 | |||
246 | for (i=0;i<NUMTILE8;i++) | ||
247 | { | ||
248 | VL_MemToLatch (src, 8, 8, surf, (i & 7) * 8, (i >> 3) * 8); | ||
249 | src += 64; | ||
250 | } | ||
251 | UNCACHEGRCHUNK (STARTTILE8); | ||
252 | |||
253 | // | ||
254 | // pics | ||
255 | // | ||
256 | start = LATCHPICS_LUMP_START; | ||
257 | end = LATCHPICS_LUMP_END; | ||
258 | |||
259 | for (i=start;i<=end;i++) | ||
260 | { | ||
261 | width = pictable[i-STARTPICS].width; | ||
262 | height = pictable[i-STARTPICS].height; | ||
263 | surf = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, 8, 0, 0, 0, 0); | ||
264 | if(surf == NULL) | ||
265 | { | ||
266 | Quit("Unable to create surface for picture!"); | ||
267 | } | ||
268 | SDL_SetColors(surf, gamepal, 0, 256); | ||
269 | |||
270 | latchpics[2+i-start] = surf; | ||
271 | CA_CacheGrChunk (i); | ||
272 | VL_MemToLatch (grsegs[i], width, height, surf, 0, 0); | ||
273 | UNCACHEGRCHUNK(i); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | //========================================================================== | ||
278 | |||
279 | /* | ||
280 | =================== | ||
281 | = | ||
282 | = FizzleFade | ||
283 | = | ||
284 | = returns true if aborted | ||
285 | = | ||
286 | = It uses maximum-length Linear Feedback Shift Registers (LFSR) counters. | ||
287 | = You can find a list of them with lengths from 3 to 168 at: | ||
288 | = http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf | ||
289 | = Many thanks to Xilinx for this list!!! | ||
290 | = | ||
291 | =================== | ||
292 | */ | ||
293 | |||
294 | // XOR masks for the pseudo-random number sequence starting with n=17 bits | ||
295 | static const uint32_t rndmasks[] = { | ||
296 | // n XNOR from (starting at 1, not 0 as usual) | ||
297 | 0x00012000, // 17 17,14 | ||
298 | 0x00020400, // 18 18,11 | ||
299 | 0x00040023, // 19 19,6,2,1 | ||
300 | 0x00090000, // 20 20,17 | ||
301 | 0x00140000, // 21 21,19 | ||
302 | 0x00300000, // 22 22,21 | ||
303 | 0x00420000, // 23 23,18 | ||
304 | 0x00e10000, // 24 24,23,22,17 | ||
305 | 0x01200000, // 25 25,22 (this is enough for 8191x4095) | ||
306 | }; | ||
307 | |||
308 | static unsigned int rndbits_y; | ||
309 | static unsigned int rndmask; | ||
310 | |||
311 | extern SDL_Color curpal[256]; | ||
312 | |||
313 | // Returns the number of bits needed to represent the given value | ||
314 | static int log2_ceil(uint32_t x) | ||
315 | { | ||
316 | int n = 0; | ||
317 | uint32_t v = 1; | ||
318 | while(v < x) | ||
319 | { | ||
320 | n++; | ||
321 | v <<= 1; | ||
322 | } | ||
323 | return n; | ||
324 | } | ||
325 | |||
326 | void VH_Startup() | ||
327 | { | ||
328 | int rndbits_x = log2_ceil(screenWidth); | ||
329 | rndbits_y = log2_ceil(screenHeight); | ||
330 | |||
331 | int rndbits = rndbits_x + rndbits_y; | ||
332 | if(rndbits < 17) | ||
333 | rndbits = 17; // no problem, just a bit slower | ||
334 | else if(rndbits > 25) | ||
335 | rndbits = 25; // fizzle fade will not fill whole screen | ||
336 | |||
337 | rndmask = rndmasks[rndbits - 17]; | ||
338 | } | ||
339 | |||
340 | boolean FizzleFade (SDL_Surface *source, int x1, int y1, | ||
341 | unsigned width, unsigned height, unsigned frames, boolean abortable) | ||
342 | { | ||
343 | unsigned x, y, frame, pixperframe; | ||
344 | int32_t rndval, lastrndval; | ||
345 | int first = 1; | ||
346 | |||
347 | lastrndval = 0; | ||
348 | pixperframe = width * height / frames; | ||
349 | |||
350 | IN_StartAck (); | ||
351 | |||
352 | frame = GetTimeCount(); | ||
353 | byte *srcptr = VL_LockSurface(source); | ||
354 | do | ||
355 | { | ||
356 | if(abortable && IN_CheckAck ()) | ||
357 | { | ||
358 | VL_UnlockSurface(source); | ||
359 | SDL_BlitSurface(source, NULL, screen, NULL); | ||
360 | SDL_Flip(screen); | ||
361 | return true; | ||
362 | } | ||
363 | |||
364 | byte *destptr = VL_LockSurface(screen); | ||
365 | |||
366 | rndval = lastrndval; | ||
367 | |||
368 | // When using double buffering, we have to copy the pixels of the last AND the current frame. | ||
369 | // Only for the first frame, there is no "last frame" | ||
370 | for(int i = first; i < 2; i++) | ||
371 | { | ||
372 | for(unsigned p = 0; p < pixperframe; p++) | ||
373 | { | ||
374 | // | ||
375 | // seperate random value into x/y pair | ||
376 | // | ||
377 | |||
378 | x = rndval >> rndbits_y; | ||
379 | y = rndval & ((1 << rndbits_y) - 1); | ||
380 | |||
381 | // | ||
382 | // advance to next random element | ||
383 | // | ||
384 | |||
385 | rndval = (rndval >> 1) ^ (rndval & 1 ? 0 : rndmask); | ||
386 | |||
387 | if(x >= width || y >= height) | ||
388 | { | ||
389 | if(rndval == 0) // entire sequence has been completed | ||
390 | goto finished; | ||
391 | p--; | ||
392 | continue; | ||
393 | } | ||
394 | |||
395 | // | ||
396 | // copy one pixel | ||
397 | // | ||
398 | |||
399 | if(screenBits == 8) | ||
400 | { | ||
401 | *(destptr + (y1 + y) * screen->pitch + x1 + x) | ||
402 | = *(srcptr + (y1 + y) * source->pitch + x1 + x); | ||
403 | } | ||
404 | else | ||
405 | { | ||
406 | byte col = *(srcptr + (y1 + y) * source->pitch + x1 + x); | ||
407 | uint32_t fullcol = SDL_MapRGB(screen->format, curpal[col].r, curpal[col].g, curpal[col].b); | ||
408 | memcpy(destptr + (y1 + y) * screen->pitch + (x1 + x) * screen->format->BytesPerPixel, | ||
409 | &fullcol, screen->format->BytesPerPixel); | ||
410 | } | ||
411 | |||
412 | if(rndval == 0) // entire sequence has been completed | ||
413 | goto finished; | ||
414 | } | ||
415 | |||
416 | if(!i || first) lastrndval = rndval; | ||
417 | } | ||
418 | |||
419 | // If there is no double buffering, we always use the "first frame" case | ||
420 | if(usedoublebuffering) first = 0; | ||
421 | |||
422 | VL_UnlockSurface(screen); | ||
423 | SDL_Flip(screen); | ||
424 | |||
425 | frame++; | ||
426 | Delay(frame - GetTimeCount()); // don't go too fast | ||
427 | } while (1); | ||
428 | |||
429 | finished: | ||
430 | VL_UnlockSurface(source); | ||
431 | VL_UnlockSurface(screen); | ||
432 | SDL_BlitSurface(source, NULL, screen, NULL); | ||
433 | SDL_Flip(screen); | ||
434 | return false; | ||
435 | } | ||