summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/id_vh.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2019-07-07 22:00:20 -0400
committerFranklin Wei <git@fwei.tk>2019-07-09 11:20:55 -0400
commit3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch)
treee0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/id_vh.c
parent439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff)
downloadrockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz
rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
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}