summaryrefslogtreecommitdiffstats
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 @@
+// ID_VL.C
+
+#include <string.h>
+#include "wl_def.h"
+#pragma hdrstop
+
+// Uncomment the following line, if you get destination out of bounds
+// assertion errors and want to ignore them during debugging
+//#define IGNORE_BAD_DEST
+
+#ifdef IGNORE_BAD_DEST
+#undef assert
+#define assert(x) if(!(x)) return
+#define assert_ret(x) if(!(x)) return 0
+#else
+#define assert_ret(x) assert(x)
+#endif
+
+boolean fullscreen = true;
+boolean usedoublebuffering = true;
+unsigned screenWidth = 320; // SDL will scale for us
+unsigned screenHeight = 200;
+unsigned screenBits = LCD_DEPTH; // use "best" color depth according to libSDL
+
+SDL_Surface *screen = NULL;
+unsigned screenPitch;
+
+SDL_Surface *screenBuffer = NULL;
+unsigned bufferPitch;
+
+SDL_Surface *curSurface = NULL;
+unsigned curPitch;
+
+unsigned scaleFactor;
+
+boolean screenfaded;
+unsigned bordercolor;
+
+SDL_Color palette1[256], palette2[256];
+SDL_Color curpal[256];
+
+
+#define CASSERT(x) extern int ASSERT_COMPILE[((x) != 0) * 2 - 1];
+#define RGB(r, g, b) {(r)*255/63, (g)*255/63, (b)*255/63, 0}
+
+SDL_Color gamepal[]={
+#ifdef SPEAR
+ #include "sodpal.inc"
+#else
+ #include "wolfpal.inc"
+#endif
+};
+
+CASSERT(lengthof(gamepal) == 256)
+
+//===========================================================================
+
+
+/*
+=======================
+=
+= VL_Shutdown
+=
+=======================
+*/
+
+void VL_Shutdown (void)
+{
+ //VL_SetTextMode ();
+}
+
+
+/*
+=======================
+=
+= VL_SetVGAPlaneMode
+=
+=======================
+*/
+
+void VL_SetVGAPlaneMode (void)
+{
+#ifdef SPEAR
+ SDL_WM_SetCaption("Spear of Destiny", NULL);
+#else
+ SDL_WM_SetCaption("Wolfenstein 3D", NULL);
+#endif
+
+ if(screenBits == -1)
+ {
+ const SDL_VideoInfo *vidInfo = SDL_GetVideoInfo();
+ screenBits = vidInfo->vfmt->BitsPerPixel;
+ }
+
+ screen = SDL_SetVideoMode(screenWidth, screenHeight, screenBits,
+ (usedoublebuffering ? SDL_HWSURFACE | SDL_DOUBLEBUF : 0)
+ | (screenBits == 8 ? SDL_HWPALETTE : 0)
+ | (fullscreen ? SDL_FULLSCREEN : 0));
+ if(!screen)
+ {
+ printf("Unable to set %ix%ix%i video mode: %s\n", screenWidth,
+ screenHeight, screenBits, SDL_GetError());
+ exit(1);
+ }
+ if((screen->flags & SDL_DOUBLEBUF) != SDL_DOUBLEBUF)
+ usedoublebuffering = false;
+ SDL_ShowCursor(SDL_DISABLE);
+
+ SDL_SetColors(screen, gamepal, 0, 256);
+ memcpy(curpal, gamepal, sizeof(SDL_Color) * 256);
+
+ screenBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth,
+ screenHeight, 8, 0, 0, 0, 0);
+ if(!screenBuffer)
+ {
+ printf("Unable to create screen buffer surface: %s\n", SDL_GetError());
+ exit(1);
+ }
+ SDL_SetColors(screenBuffer, gamepal, 0, 256);
+
+ screenPitch = screen->pitch;
+ bufferPitch = screenBuffer->pitch;
+
+ curSurface = screenBuffer;
+ curPitch = bufferPitch;
+
+ scaleFactor = screenWidth/320;
+ if(screenHeight/200 < scaleFactor) scaleFactor = screenHeight/200;
+
+ pixelangle = (short *) malloc(screenWidth * sizeof(short));
+ CHECKMALLOCRESULT(pixelangle);
+ wallheight = (int *) malloc(screenWidth * sizeof(int));
+ CHECKMALLOCRESULT(wallheight);
+}
+
+/*
+=============================================================================
+
+ PALETTE OPS
+
+ To avoid snow, do a WaitVBL BEFORE calling these
+
+=============================================================================
+*/
+
+/*
+=================
+=
+= VL_ConvertPalette
+=
+=================
+*/
+
+void VL_ConvertPalette(byte *srcpal, SDL_Color *destpal, int numColors)
+{
+ for(int i=0; i<numColors; i++)
+ {
+ destpal[i].r = *srcpal++ * 255 / 63;
+ destpal[i].g = *srcpal++ * 255 / 63;
+ destpal[i].b = *srcpal++ * 255 / 63;
+ }
+}
+
+/*
+=================
+=
+= VL_FillPalette
+=
+=================
+*/
+
+void VL_FillPalette (int red, int green, int blue)
+{
+ int i;
+ SDL_Color pal[256];
+
+ for(i=0; i<256; i++)
+ {
+ pal[i].r = red;
+ pal[i].g = green;
+ pal[i].b = blue;
+ }
+
+ VL_SetPalette(pal, true);
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_SetColor
+=
+=================
+*/
+
+void VL_SetColor (int color, int red, int green, int blue)
+{
+ SDL_Color col = { red, green, blue };
+ curpal[color] = col;
+
+ if(screenBits == 8)
+ SDL_SetPalette(screen, SDL_PHYSPAL, &col, color, 1);
+ else
+ {
+ SDL_SetPalette(curSurface, SDL_LOGPAL, &col, color, 1);
+ SDL_BlitSurface(curSurface, NULL, screen, NULL);
+ SDL_Flip(screen);
+ }
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_GetColor
+=
+=================
+*/
+
+void VL_GetColor (int color, int *red, int *green, int *blue)
+{
+ SDL_Color *col = &curpal[color];
+ *red = col->r;
+ *green = col->g;
+ *blue = col->b;
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_SetPalette
+=
+=================
+*/
+
+void VL_SetPalette (SDL_Color *palette, bool forceupdate)
+{
+ memcpy(curpal, palette, sizeof(SDL_Color) * 256);
+
+ if(screenBits == 8)
+ SDL_SetPalette(screen, SDL_PHYSPAL, palette, 0, 256);
+ else
+ {
+ SDL_SetPalette(curSurface, SDL_LOGPAL, palette, 0, 256);
+ if(forceupdate)
+ {
+ SDL_BlitSurface(curSurface, NULL, screen, NULL);
+ SDL_Flip(screen);
+ }
+ }
+}
+
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_GetPalette
+=
+=================
+*/
+
+void VL_GetPalette (SDL_Color *palette)
+{
+ memcpy(palette, curpal, sizeof(SDL_Color) * 256);
+}
+
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_FadeOut
+=
+= Fades the current palette to the given color in the given number of steps
+=
+=================
+*/
+
+void VL_FadeOut (int start, int end, int red, int green, int blue, int steps)
+{
+ int i,j,orig,delta;
+ SDL_Color *origptr, *newptr;
+
+ red = red * 255 / 63;
+ green = green * 255 / 63;
+ blue = blue * 255 / 63;
+
+ // rockbox
+ steps = steps / 2;
+
+ VL_WaitVBL(1);
+ VL_GetPalette(palette1);
+ memcpy(palette2, palette1, sizeof(SDL_Color) * 256);
+
+//
+// fade through intermediate frames
+//
+ for (i=0;i<steps;i++)
+ {
+ origptr = &palette1[start];
+ newptr = &palette2[start];
+ for (j=start;j<=end;j++)
+ {
+ orig = origptr->r;
+ delta = red-orig;
+ newptr->r = orig + delta * i / steps;
+ orig = origptr->g;
+ delta = green-orig;
+ newptr->g = orig + delta * i / steps;
+ orig = origptr->b;
+ delta = blue-orig;
+ newptr->b = orig + delta * i / steps;
+ origptr++;
+ newptr++;
+ }
+
+ if(!usedoublebuffering || screenBits == 8) VL_WaitVBL(1);
+ VL_SetPalette (palette2, true);
+ rb->yield();
+ }
+
+//
+// final color
+//
+ VL_FillPalette (red,green,blue);
+
+ screenfaded = true;
+}
+
+
+/*
+=================
+=
+= VL_FadeIn
+=
+=================
+*/
+
+void VL_FadeIn (int start, int end, SDL_Color *palette, int steps)
+{
+ int i,j,delta;
+
+ VL_WaitVBL(1);
+ VL_GetPalette(palette1);
+ memcpy(palette2, palette1, sizeof(SDL_Color) * 256);
+
+ steps = steps / 2;
+
+//
+// fade through intermediate frames
+//
+ for (i=0;i<steps;i++)
+ {
+ for (j=start;j<=end;j++)
+ {
+ delta = palette[j].r-palette1[j].r;
+ palette2[j].r = palette1[j].r + delta * i / steps;
+ delta = palette[j].g-palette1[j].g;
+ palette2[j].g = palette1[j].g + delta * i / steps;
+ delta = palette[j].b-palette1[j].b;
+ palette2[j].b = palette1[j].b + delta * i / steps;
+ }
+
+ if(!usedoublebuffering || screenBits == 8) VL_WaitVBL(1);
+ VL_SetPalette(palette2, true);
+ }
+
+//
+// final color
+//
+ VL_SetPalette (palette, true);
+ screenfaded = false;
+}
+
+/*
+=============================================================================
+
+ PIXEL OPS
+
+=============================================================================
+*/
+
+byte *VL_LockSurface(SDL_Surface *surface)
+{
+ if(SDL_MUSTLOCK(surface))
+ {
+ if(SDL_LockSurface(surface) < 0)
+ return NULL;
+ }
+ return (byte *) surface->pixels;
+}
+
+void VL_UnlockSurface(SDL_Surface *surface)
+{
+ if(SDL_MUSTLOCK(surface))
+ {
+ SDL_UnlockSurface(surface);
+ }
+}
+
+/*
+=================
+=
+= VL_Plot
+=
+=================
+*/
+
+void VL_Plot (int x, int y, int color)
+{
+ assert(x >= 0 && (unsigned) x < screenWidth
+ && y >= 0 && (unsigned) y < screenHeight
+ && "VL_Plot: Pixel out of bounds!");
+
+ VL_LockSurface(curSurface);
+ ((byte *) curSurface->pixels)[y * curPitch + x] = color;
+ VL_UnlockSurface(curSurface);
+}
+
+/*
+=================
+=
+= VL_GetPixel
+=
+=================
+*/
+
+byte VL_GetPixel (int x, int y)
+{
+ assert_ret(x >= 0 && (unsigned) x < screenWidth
+ && y >= 0 && (unsigned) y < screenHeight
+ && "VL_GetPixel: Pixel out of bounds!");
+
+ VL_LockSurface(curSurface);
+ byte col = ((byte *) curSurface->pixels)[y * curPitch + x];
+ VL_UnlockSurface(curSurface);
+ return col;
+}
+
+
+/*
+=================
+=
+= VL_Hlin
+=
+=================
+*/
+
+void VL_Hlin (unsigned x, unsigned y, unsigned width, int color)
+{
+ assert(x >= 0 && x + width <= screenWidth
+ && y >= 0 && y < screenHeight
+ && "VL_Hlin: Destination rectangle out of bounds!");
+
+ VL_LockSurface(curSurface);
+ Uint8 *dest = ((byte *) curSurface->pixels) + y * curPitch + x;
+ memset(dest, color, width);
+ VL_UnlockSurface(curSurface);
+}
+
+
+/*
+=================
+=
+= VL_Vlin
+=
+=================
+*/
+
+void VL_Vlin (int x, int y, int height, int color)
+{
+ assert(x >= 0 && (unsigned) x < screenWidth
+ && y >= 0 && (unsigned) y + height <= screenHeight
+ && "VL_Vlin: Destination rectangle out of bounds!");
+
+ VL_LockSurface(curSurface);
+ Uint8 *dest = ((byte *) curSurface->pixels) + y * curPitch + x;
+
+ while (height--)
+ {
+ *dest = color;
+ dest += curPitch;
+ }
+ VL_UnlockSurface(curSurface);
+}
+
+
+/*
+=================
+=
+= VL_Bar
+=
+=================
+*/
+
+void VL_BarScaledCoord (int scx, int scy, int scwidth, int scheight, int color)
+{
+ assert(scx >= 0 && (unsigned) scx + scwidth <= screenWidth
+ && scy >= 0 && (unsigned) scy + scheight <= screenHeight
+ && "VL_BarScaledCoord: Destination rectangle out of bounds!");
+
+ VL_LockSurface(curSurface);
+ Uint8 *dest = ((byte *) curSurface->pixels) + scy * curPitch + scx;
+
+ while (scheight--)
+ {
+ memset(dest, color, scwidth);
+ dest += curPitch;
+ }
+ VL_UnlockSurface(curSurface);
+}
+
+/*
+============================================================================
+
+ MEMORY OPS
+
+============================================================================
+*/
+
+/*
+=================
+=
+= VL_MemToLatch
+=
+=================
+*/
+
+void VL_MemToLatch(byte *source, int width, int height,
+ SDL_Surface *destSurface, int x, int y)
+{
+ assert(x >= 0 && (unsigned) x + width <= screenWidth
+ && y >= 0 && (unsigned) y + height <= screenHeight
+ && "VL_MemToLatch: Destination rectangle out of bounds!");
+
+ VL_LockSurface(destSurface);
+ int pitch = destSurface->pitch;
+ byte *dest = (byte *) destSurface->pixels + y * pitch + x;
+ for(int ysrc = 0; ysrc < height; ysrc++)
+ {
+ for(int xsrc = 0; xsrc < width; xsrc++)
+ {
+ dest[ysrc * pitch + xsrc] = source[(ysrc * (width >> 2) + (xsrc >> 2))
+ + (xsrc & 3) * (width >> 2) * height];
+ }
+ }
+ VL_UnlockSurface(destSurface);
+}
+
+//===========================================================================
+
+
+/*
+=================
+=
+= VL_MemToScreenScaledCoord
+=
+= Draws a block of data to the screen with scaling according to scaleFactor.
+=
+=================
+*/
+
+void VL_MemToScreenScaledCoord (byte *source, int width, int height, int destx, int desty)
+{
+ assert(destx >= 0 && destx + width * scaleFactor <= screenWidth
+ && desty >= 0 && desty + height * scaleFactor <= screenHeight
+ && "VL_MemToScreenScaledCoord: Destination rectangle out of bounds!");
+
+ VL_LockSurface(curSurface);
+ byte *vbuf = (byte *) curSurface->pixels;
+ for(int j=0,scj=0; j<height; j++, scj+=scaleFactor)
+ {
+ for(int i=0,sci=0; i<width; i++, sci+=scaleFactor)
+ {
+ byte col = source[(j*(width>>2)+(i>>2))+(i&3)*(width>>2)*height];
+ for(unsigned m=0; m<scaleFactor; m++)
+ {
+ for(unsigned n=0; n<scaleFactor; n++)
+ {
+ vbuf[(scj+m+desty)*curPitch+sci+n+destx] = col;
+ }
+ }
+ }
+ }
+ VL_UnlockSurface(curSurface);
+}
+
+/*
+=================
+=
+= VL_MemToScreenScaledCoord
+=
+= Draws a part of a block of data to the screen.
+= The block has the size origwidth*origheight.
+= The part at (srcx, srcy) has the size width*height
+= and will be painted to (destx, desty) with scaling according to scaleFactor.
+=
+=================
+*/
+
+void VL_MemToScreenScaledCoord_ex (byte *source, int origwidth, int origheight, int srcx, int srcy,
+ int destx, int desty, int width, int height)
+{
+ assert(destx >= 0 && destx + width * scaleFactor <= screenWidth
+ && desty >= 0 && desty + height * scaleFactor <= screenHeight
+ && "VL_MemToScreenScaledCoord: Destination rectangle out of bounds!");
+
+ VL_LockSurface(curSurface);
+ byte *vbuf = (byte *) curSurface->pixels;
+ for(int j=0,scj=0; j<height; j++, scj+=scaleFactor)
+ {
+ for(int i=0,sci=0; i<width; i++, sci+=scaleFactor)
+ {
+ byte col = source[((j+srcy)*(origwidth>>2)+((i+srcx)>>2))+((i+srcx)&3)*(origwidth>>2)*origheight];
+ for(unsigned m=0; m<scaleFactor; m++)
+ {
+ for(unsigned n=0; n<scaleFactor; n++)
+ {
+ vbuf[(scj+m+desty)*curPitch+sci+n+destx] = col;
+ }
+ }
+ }
+ }
+ VL_UnlockSurface(curSurface);
+}
+
+//==========================================================================
+
+/*
+=================
+=
+= VL_LatchToScreen
+=
+=================
+*/
+
+void VL_LatchToScreenScaledCoord(SDL_Surface *source, int xsrc, int ysrc,
+ int width, int height, int scxdest, int scydest)
+{
+ assert(scxdest >= 0 && scxdest + width * scaleFactor <= screenWidth
+ && scydest >= 0 && scydest + height * scaleFactor <= screenHeight
+ && "VL_LatchToScreenScaledCoord: Destination rectangle out of bounds!");
+
+ if(scaleFactor == 1)
+ {
+ // HACK: If screenBits is not 8 and the screen is faded out, the
+ // result will be black when using SDL_BlitSurface. The reason
+ // is that the logical palette needed for the transformation
+ // to the screen color depth is not equal to the logical
+ // palette of the latch (the latch is not faded). Therefore,
+ // SDL tries to map the colors...
+ // The result: All colors are mapped to black.
+ // So, we do the blit on our own...
+ if(screenBits != 8)
+ {
+ VL_LockSurface(source);
+ byte *src = (byte *) source->pixels;
+ unsigned srcPitch = source->pitch;
+
+ VL_LockSurface(curSurface);
+ byte *vbuf = (byte *) curSurface->pixels;
+ for(int j=0,scj=0; j<height; j++, scj++)
+ {
+ for(int i=0,sci=0; i<width; i++, sci++)
+ {
+ byte col = src[(ysrc + j)*srcPitch + xsrc + i];
+ vbuf[(scydest+scj)*curPitch+scxdest+sci] = col;
+ }
+ }
+ VL_UnlockSurface(curSurface);
+ VL_UnlockSurface(source);
+ }
+ else
+ {
+ SDL_Rect srcrect = { xsrc, ysrc, width, height };
+ SDL_Rect destrect = { scxdest, scydest, 0, 0 }; // width and height are ignored
+ SDL_BlitSurface(source, &srcrect, curSurface, &destrect);
+ }
+ }
+ else
+ {
+ VL_LockSurface(source);
+ byte *src = (byte *) source->pixels;
+ unsigned srcPitch = source->pitch;
+
+ VL_LockSurface(curSurface);
+ byte *vbuf = (byte *) curSurface->pixels;
+ for(int j=0,scj=0; j<height; j++, scj+=scaleFactor)
+ {
+ for(int i=0,sci=0; i<width; i++, sci+=scaleFactor)
+ {
+ byte col = src[(ysrc + j)*srcPitch + xsrc + i];
+ for(unsigned m=0; m<scaleFactor; m++)
+ {
+ for(unsigned n=0; n<scaleFactor; n++)
+ {
+ vbuf[(scydest+scj+m)*curPitch+scxdest+sci+n] = col;
+ }
+ }
+ }
+ }
+ VL_UnlockSurface(curSurface);
+ VL_UnlockSurface(source);
+ }
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_ScreenToScreen
+=
+=================
+*/
+
+void VL_ScreenToScreen (SDL_Surface *source, SDL_Surface *dest)
+{
+ SDL_BlitSurface(source, NULL, dest, NULL);
+}