summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/id_vh.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/id_vh.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/id_vh.c435
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
4pictabletype *pictable;
5SDL_Surface *latchpics[NUMLATCHPICS];
6
7int px,py;
8byte fontcolor,backcolor;
9int fontnumber;
10
11//==========================================================================
12
13void 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
59void 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
96void 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
103void 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
116void VH_UpdateScreen()
117{
118 SDL_BlitSurface(screenBuffer, NULL, screen, NULL);
119 SDL_Flip(screen);
120}
121
122
123void VWB_DrawTile8 (int x, int y, int tile)
124{
125 LatchDrawChar(x,y,tile);
126}
127
128void VWB_DrawTile8M (int x, int y, int tile)
129{
130 VL_MemToScreen (((byte *)grsegs[STARTTILE8M])+tile*64,8,8,x,y);
131}
132
133void 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
146void 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
158void VWB_Bar (int x, int y, int width, int height, int color)
159{
160 VW_Bar (x,y,width,height,color);
161}
162
163void 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
171void 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
179void 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
204void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)
205{
206 VL_LatchToScreen_ez (latchpics[2+picnum-LATCHPICS_LUMP_START], x*8, y);
207}
208
209void 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
225void 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
295static 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
308static unsigned int rndbits_y;
309static unsigned int rndmask;
310
311extern SDL_Color curpal[256];
312
313// Returns the number of bits needed to represent the given value
314static 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
326void 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
340boolean 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
429finished:
430 VL_UnlockSurface(source);
431 VL_UnlockSurface(screen);
432 SDL_BlitSurface(source, NULL, screen, NULL);
433 SDL_Flip(screen);
434 return false;
435}