summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/id_vl.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/id_vl.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/id_vl.c727
1 files changed, 727 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/id_vl.c b/apps/plugins/sdl/progs/wolf3d/id_vl.c
new file mode 100644
index 0000000000..0152e17218
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/id_vl.c
@@ -0,0 +1,727 @@
1// ID_VL.C
2
3#include <string.h>
4#include "wl_def.h"
5#pragma hdrstop
6
7// Uncomment the following line, if you get destination out of bounds
8// assertion errors and want to ignore them during debugging
9//#define IGNORE_BAD_DEST
10
11#ifdef IGNORE_BAD_DEST
12#undef assert
13#define assert(x) if(!(x)) return
14#define assert_ret(x) if(!(x)) return 0
15#else
16#define assert_ret(x) assert(x)
17#endif
18
19boolean fullscreen = true;
20boolean usedoublebuffering = true;
21unsigned screenWidth = 320; // SDL will scale for us
22unsigned screenHeight = 200;
23unsigned screenBits = LCD_DEPTH; // use "best" color depth according to libSDL
24
25SDL_Surface *screen = NULL;
26unsigned screenPitch;
27
28SDL_Surface *screenBuffer = NULL;
29unsigned bufferPitch;
30
31SDL_Surface *curSurface = NULL;
32unsigned curPitch;
33
34unsigned scaleFactor;
35
36boolean screenfaded;
37unsigned bordercolor;
38
39SDL_Color palette1[256], palette2[256];
40SDL_Color curpal[256];
41
42
43#define CASSERT(x) extern int ASSERT_COMPILE[((x) != 0) * 2 - 1];
44#define RGB(r, g, b) {(r)*255/63, (g)*255/63, (b)*255/63, 0}
45
46SDL_Color gamepal[]={
47#ifdef SPEAR
48 #include "sodpal.inc"
49#else
50 #include "wolfpal.inc"
51#endif
52};
53
54CASSERT(lengthof(gamepal) == 256)
55
56//===========================================================================
57
58
59/*
60=======================
61=
62= VL_Shutdown
63=
64=======================
65*/
66
67void VL_Shutdown (void)
68{
69 //VL_SetTextMode ();
70}
71
72
73/*
74=======================
75=
76= VL_SetVGAPlaneMode
77=
78=======================
79*/
80
81void VL_SetVGAPlaneMode (void)
82{
83#ifdef SPEAR
84 SDL_WM_SetCaption("Spear of Destiny", NULL);
85#else
86 SDL_WM_SetCaption("Wolfenstein 3D", NULL);
87#endif
88
89 if(screenBits == -1)
90 {
91 const SDL_VideoInfo *vidInfo = SDL_GetVideoInfo();
92 screenBits = vidInfo->vfmt->BitsPerPixel;
93 }
94
95 screen = SDL_SetVideoMode(screenWidth, screenHeight, screenBits,
96 (usedoublebuffering ? SDL_HWSURFACE | SDL_DOUBLEBUF : 0)
97 | (screenBits == 8 ? SDL_HWPALETTE : 0)
98 | (fullscreen ? SDL_FULLSCREEN : 0));
99 if(!screen)
100 {
101 printf("Unable to set %ix%ix%i video mode: %s\n", screenWidth,
102 screenHeight, screenBits, SDL_GetError());
103 exit(1);
104 }
105 if((screen->flags & SDL_DOUBLEBUF) != SDL_DOUBLEBUF)
106 usedoublebuffering = false;
107 SDL_ShowCursor(SDL_DISABLE);
108
109 SDL_SetColors(screen, gamepal, 0, 256);
110 memcpy(curpal, gamepal, sizeof(SDL_Color) * 256);
111
112 screenBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth,
113 screenHeight, 8, 0, 0, 0, 0);
114 if(!screenBuffer)
115 {
116 printf("Unable to create screen buffer surface: %s\n", SDL_GetError());
117 exit(1);
118 }
119 SDL_SetColors(screenBuffer, gamepal, 0, 256);
120
121 screenPitch = screen->pitch;
122 bufferPitch = screenBuffer->pitch;
123
124 curSurface = screenBuffer;
125 curPitch = bufferPitch;
126
127 scaleFactor = screenWidth/320;
128 if(screenHeight/200 < scaleFactor) scaleFactor = screenHeight/200;
129
130 pixelangle = (short *) malloc(screenWidth * sizeof(short));
131 CHECKMALLOCRESULT(pixelangle);
132 wallheight = (int *) malloc(screenWidth * sizeof(int));
133 CHECKMALLOCRESULT(wallheight);
134}
135
136/*
137=============================================================================
138
139 PALETTE OPS
140
141 To avoid snow, do a WaitVBL BEFORE calling these
142
143=============================================================================
144*/
145
146/*
147=================
148=
149= VL_ConvertPalette
150=
151=================
152*/
153
154void VL_ConvertPalette(byte *srcpal, SDL_Color *destpal, int numColors)
155{
156 for(int i=0; i<numColors; i++)
157 {
158 destpal[i].r = *srcpal++ * 255 / 63;
159 destpal[i].g = *srcpal++ * 255 / 63;
160 destpal[i].b = *srcpal++ * 255 / 63;
161 }
162}
163
164/*
165=================
166=
167= VL_FillPalette
168=
169=================
170*/
171
172void VL_FillPalette (int red, int green, int blue)
173{
174 int i;
175 SDL_Color pal[256];
176
177 for(i=0; i<256; i++)
178 {
179 pal[i].r = red;
180 pal[i].g = green;
181 pal[i].b = blue;
182 }
183
184 VL_SetPalette(pal, true);
185}
186
187//===========================================================================
188
189/*
190=================
191=
192= VL_SetColor
193=
194=================
195*/
196
197void VL_SetColor (int color, int red, int green, int blue)
198{
199 SDL_Color col = { red, green, blue };
200 curpal[color] = col;
201
202 if(screenBits == 8)
203 SDL_SetPalette(screen, SDL_PHYSPAL, &col, color, 1);
204 else
205 {
206 SDL_SetPalette(curSurface, SDL_LOGPAL, &col, color, 1);
207 SDL_BlitSurface(curSurface, NULL, screen, NULL);
208 SDL_Flip(screen);
209 }
210}
211
212//===========================================================================
213
214/*
215=================
216=
217= VL_GetColor
218=
219=================
220*/
221
222void VL_GetColor (int color, int *red, int *green, int *blue)
223{
224 SDL_Color *col = &curpal[color];
225 *red = col->r;
226 *green = col->g;
227 *blue = col->b;
228}
229
230//===========================================================================
231
232/*
233=================
234=
235= VL_SetPalette
236=
237=================
238*/
239
240void VL_SetPalette (SDL_Color *palette, bool forceupdate)
241{
242 memcpy(curpal, palette, sizeof(SDL_Color) * 256);
243
244 if(screenBits == 8)
245 SDL_SetPalette(screen, SDL_PHYSPAL, palette, 0, 256);
246 else
247 {
248 SDL_SetPalette(curSurface, SDL_LOGPAL, palette, 0, 256);
249 if(forceupdate)
250 {
251 SDL_BlitSurface(curSurface, NULL, screen, NULL);
252 SDL_Flip(screen);
253 }
254 }
255}
256
257
258//===========================================================================
259
260/*
261=================
262=
263= VL_GetPalette
264=
265=================
266*/
267
268void VL_GetPalette (SDL_Color *palette)
269{
270 memcpy(palette, curpal, sizeof(SDL_Color) * 256);
271}
272
273
274//===========================================================================
275
276/*
277=================
278=
279= VL_FadeOut
280=
281= Fades the current palette to the given color in the given number of steps
282=
283=================
284*/
285
286void VL_FadeOut (int start, int end, int red, int green, int blue, int steps)
287{
288 int i,j,orig,delta;
289 SDL_Color *origptr, *newptr;
290
291 red = red * 255 / 63;
292 green = green * 255 / 63;
293 blue = blue * 255 / 63;
294
295 // rockbox
296 steps = steps / 2;
297
298 VL_WaitVBL(1);
299 VL_GetPalette(palette1);
300 memcpy(palette2, palette1, sizeof(SDL_Color) * 256);
301
302//
303// fade through intermediate frames
304//
305 for (i=0;i<steps;i++)
306 {
307 origptr = &palette1[start];
308 newptr = &palette2[start];
309 for (j=start;j<=end;j++)
310 {
311 orig = origptr->r;
312 delta = red-orig;
313 newptr->r = orig + delta * i / steps;
314 orig = origptr->g;
315 delta = green-orig;
316 newptr->g = orig + delta * i / steps;
317 orig = origptr->b;
318 delta = blue-orig;
319 newptr->b = orig + delta * i / steps;
320 origptr++;
321 newptr++;
322 }
323
324 if(!usedoublebuffering || screenBits == 8) VL_WaitVBL(1);
325 VL_SetPalette (palette2, true);
326 rb->yield();
327 }
328
329//
330// final color
331//
332 VL_FillPalette (red,green,blue);
333
334 screenfaded = true;
335}
336
337
338/*
339=================
340=
341= VL_FadeIn
342=
343=================
344*/
345
346void VL_FadeIn (int start, int end, SDL_Color *palette, int steps)
347{
348 int i,j,delta;
349
350 VL_WaitVBL(1);
351 VL_GetPalette(palette1);
352 memcpy(palette2, palette1, sizeof(SDL_Color) * 256);
353
354 steps = steps / 2;
355
356//
357// fade through intermediate frames
358//
359 for (i=0;i<steps;i++)
360 {
361 for (j=start;j<=end;j++)
362 {
363 delta = palette[j].r-palette1[j].r;
364 palette2[j].r = palette1[j].r + delta * i / steps;
365 delta = palette[j].g-palette1[j].g;
366 palette2[j].g = palette1[j].g + delta * i / steps;
367 delta = palette[j].b-palette1[j].b;
368 palette2[j].b = palette1[j].b + delta * i / steps;
369 }
370
371 if(!usedoublebuffering || screenBits == 8) VL_WaitVBL(1);
372 VL_SetPalette(palette2, true);
373 }
374
375//
376// final color
377//
378 VL_SetPalette (palette, true);
379 screenfaded = false;
380}
381
382/*
383=============================================================================
384
385 PIXEL OPS
386
387=============================================================================
388*/
389
390byte *VL_LockSurface(SDL_Surface *surface)
391{
392 if(SDL_MUSTLOCK(surface))
393 {
394 if(SDL_LockSurface(surface) < 0)
395 return NULL;
396 }
397 return (byte *) surface->pixels;
398}
399
400void VL_UnlockSurface(SDL_Surface *surface)
401{
402 if(SDL_MUSTLOCK(surface))
403 {
404 SDL_UnlockSurface(surface);
405 }
406}
407
408/*
409=================
410=
411= VL_Plot
412=
413=================
414*/
415
416void VL_Plot (int x, int y, int color)
417{
418 assert(x >= 0 && (unsigned) x < screenWidth
419 && y >= 0 && (unsigned) y < screenHeight
420 && "VL_Plot: Pixel out of bounds!");
421
422 VL_LockSurface(curSurface);
423 ((byte *) curSurface->pixels)[y * curPitch + x] = color;
424 VL_UnlockSurface(curSurface);
425}
426
427/*
428=================
429=
430= VL_GetPixel
431=
432=================
433*/
434
435byte VL_GetPixel (int x, int y)
436{
437 assert_ret(x >= 0 && (unsigned) x < screenWidth
438 && y >= 0 && (unsigned) y < screenHeight
439 && "VL_GetPixel: Pixel out of bounds!");
440
441 VL_LockSurface(curSurface);
442 byte col = ((byte *) curSurface->pixels)[y * curPitch + x];
443 VL_UnlockSurface(curSurface);
444 return col;
445}
446
447
448/*
449=================
450=
451= VL_Hlin
452=
453=================
454*/
455
456void VL_Hlin (unsigned x, unsigned y, unsigned width, int color)
457{
458 assert(x >= 0 && x + width <= screenWidth
459 && y >= 0 && y < screenHeight
460 && "VL_Hlin: Destination rectangle out of bounds!");
461
462 VL_LockSurface(curSurface);
463 Uint8 *dest = ((byte *) curSurface->pixels) + y * curPitch + x;
464 memset(dest, color, width);
465 VL_UnlockSurface(curSurface);
466}
467
468
469/*
470=================
471=
472= VL_Vlin
473=
474=================
475*/
476
477void VL_Vlin (int x, int y, int height, int color)
478{
479 assert(x >= 0 && (unsigned) x < screenWidth
480 && y >= 0 && (unsigned) y + height <= screenHeight
481 && "VL_Vlin: Destination rectangle out of bounds!");
482
483 VL_LockSurface(curSurface);
484 Uint8 *dest = ((byte *) curSurface->pixels) + y * curPitch + x;
485
486 while (height--)
487 {
488 *dest = color;
489 dest += curPitch;
490 }
491 VL_UnlockSurface(curSurface);
492}
493
494
495/*
496=================
497=
498= VL_Bar
499=
500=================
501*/
502
503void VL_BarScaledCoord (int scx, int scy, int scwidth, int scheight, int color)
504{
505 assert(scx >= 0 && (unsigned) scx + scwidth <= screenWidth
506 && scy >= 0 && (unsigned) scy + scheight <= screenHeight
507 && "VL_BarScaledCoord: Destination rectangle out of bounds!");
508
509 VL_LockSurface(curSurface);
510 Uint8 *dest = ((byte *) curSurface->pixels) + scy * curPitch + scx;
511
512 while (scheight--)
513 {
514 memset(dest, color, scwidth);
515 dest += curPitch;
516 }
517 VL_UnlockSurface(curSurface);
518}
519
520/*
521============================================================================
522
523 MEMORY OPS
524
525============================================================================
526*/
527
528/*
529=================
530=
531= VL_MemToLatch
532=
533=================
534*/
535
536void VL_MemToLatch(byte *source, int width, int height,
537 SDL_Surface *destSurface, int x, int y)
538{
539 assert(x >= 0 && (unsigned) x + width <= screenWidth
540 && y >= 0 && (unsigned) y + height <= screenHeight
541 && "VL_MemToLatch: Destination rectangle out of bounds!");
542
543 VL_LockSurface(destSurface);
544 int pitch = destSurface->pitch;
545 byte *dest = (byte *) destSurface->pixels + y * pitch + x;
546 for(int ysrc = 0; ysrc < height; ysrc++)
547 {
548 for(int xsrc = 0; xsrc < width; xsrc++)
549 {
550 dest[ysrc * pitch + xsrc] = source[(ysrc * (width >> 2) + (xsrc >> 2))
551 + (xsrc & 3) * (width >> 2) * height];
552 }
553 }
554 VL_UnlockSurface(destSurface);
555}
556
557//===========================================================================
558
559
560/*
561=================
562=
563= VL_MemToScreenScaledCoord
564=
565= Draws a block of data to the screen with scaling according to scaleFactor.
566=
567=================
568*/
569
570void VL_MemToScreenScaledCoord (byte *source, int width, int height, int destx, int desty)
571{
572 assert(destx >= 0 && destx + width * scaleFactor <= screenWidth
573 && desty >= 0 && desty + height * scaleFactor <= screenHeight
574 && "VL_MemToScreenScaledCoord: Destination rectangle out of bounds!");
575
576 VL_LockSurface(curSurface);
577 byte *vbuf = (byte *) curSurface->pixels;
578 for(int j=0,scj=0; j<height; j++, scj+=scaleFactor)
579 {
580 for(int i=0,sci=0; i<width; i++, sci+=scaleFactor)
581 {
582 byte col = source[(j*(width>>2)+(i>>2))+(i&3)*(width>>2)*height];
583 for(unsigned m=0; m<scaleFactor; m++)
584 {
585 for(unsigned n=0; n<scaleFactor; n++)
586 {
587 vbuf[(scj+m+desty)*curPitch+sci+n+destx] = col;
588 }
589 }
590 }
591 }
592 VL_UnlockSurface(curSurface);
593}
594
595/*
596=================
597=
598= VL_MemToScreenScaledCoord
599=
600= Draws a part of a block of data to the screen.
601= The block has the size origwidth*origheight.
602= The part at (srcx, srcy) has the size width*height
603= and will be painted to (destx, desty) with scaling according to scaleFactor.
604=
605=================
606*/
607
608void VL_MemToScreenScaledCoord_ex (byte *source, int origwidth, int origheight, int srcx, int srcy,
609 int destx, int desty, int width, int height)
610{
611 assert(destx >= 0 && destx + width * scaleFactor <= screenWidth
612 && desty >= 0 && desty + height * scaleFactor <= screenHeight
613 && "VL_MemToScreenScaledCoord: Destination rectangle out of bounds!");
614
615 VL_LockSurface(curSurface);
616 byte *vbuf = (byte *) curSurface->pixels;
617 for(int j=0,scj=0; j<height; j++, scj+=scaleFactor)
618 {
619 for(int i=0,sci=0; i<width; i++, sci+=scaleFactor)
620 {
621 byte col = source[((j+srcy)*(origwidth>>2)+((i+srcx)>>2))+((i+srcx)&3)*(origwidth>>2)*origheight];
622 for(unsigned m=0; m<scaleFactor; m++)
623 {
624 for(unsigned n=0; n<scaleFactor; n++)
625 {
626 vbuf[(scj+m+desty)*curPitch+sci+n+destx] = col;
627 }
628 }
629 }
630 }
631 VL_UnlockSurface(curSurface);
632}
633
634//==========================================================================
635
636/*
637=================
638=
639= VL_LatchToScreen
640=
641=================
642*/
643
644void VL_LatchToScreenScaledCoord(SDL_Surface *source, int xsrc, int ysrc,
645 int width, int height, int scxdest, int scydest)
646{
647 assert(scxdest >= 0 && scxdest + width * scaleFactor <= screenWidth
648 && scydest >= 0 && scydest + height * scaleFactor <= screenHeight
649 && "VL_LatchToScreenScaledCoord: Destination rectangle out of bounds!");
650
651 if(scaleFactor == 1)
652 {
653 // HACK: If screenBits is not 8 and the screen is faded out, the
654 // result will be black when using SDL_BlitSurface. The reason
655 // is that the logical palette needed for the transformation
656 // to the screen color depth is not equal to the logical
657 // palette of the latch (the latch is not faded). Therefore,
658 // SDL tries to map the colors...
659 // The result: All colors are mapped to black.
660 // So, we do the blit on our own...
661 if(screenBits != 8)
662 {
663 VL_LockSurface(source);
664 byte *src = (byte *) source->pixels;
665 unsigned srcPitch = source->pitch;
666
667 VL_LockSurface(curSurface);
668 byte *vbuf = (byte *) curSurface->pixels;
669 for(int j=0,scj=0; j<height; j++, scj++)
670 {
671 for(int i=0,sci=0; i<width; i++, sci++)
672 {
673 byte col = src[(ysrc + j)*srcPitch + xsrc + i];
674 vbuf[(scydest+scj)*curPitch+scxdest+sci] = col;
675 }
676 }
677 VL_UnlockSurface(curSurface);
678 VL_UnlockSurface(source);
679 }
680 else
681 {
682 SDL_Rect srcrect = { xsrc, ysrc, width, height };
683 SDL_Rect destrect = { scxdest, scydest, 0, 0 }; // width and height are ignored
684 SDL_BlitSurface(source, &srcrect, curSurface, &destrect);
685 }
686 }
687 else
688 {
689 VL_LockSurface(source);
690 byte *src = (byte *) source->pixels;
691 unsigned srcPitch = source->pitch;
692
693 VL_LockSurface(curSurface);
694 byte *vbuf = (byte *) curSurface->pixels;
695 for(int j=0,scj=0; j<height; j++, scj+=scaleFactor)
696 {
697 for(int i=0,sci=0; i<width; i++, sci+=scaleFactor)
698 {
699 byte col = src[(ysrc + j)*srcPitch + xsrc + i];
700 for(unsigned m=0; m<scaleFactor; m++)
701 {
702 for(unsigned n=0; n<scaleFactor; n++)
703 {
704 vbuf[(scydest+scj+m)*curPitch+scxdest+sci+n] = col;
705 }
706 }
707 }
708 }
709 VL_UnlockSurface(curSurface);
710 VL_UnlockSurface(source);
711 }
712}
713
714//===========================================================================
715
716/*
717=================
718=
719= VL_ScreenToScreen
720=
721=================
722*/
723
724void VL_ScreenToScreen (SDL_Surface *source, SDL_Surface *dest)
725{
726 SDL_BlitSurface(source, NULL, dest, NULL);
727}