home *** CD-ROM | disk | FTP | other *** search
- /* Emacs style mode select -*- C++ -*- */
- /* ----------------------------------------------------------------------------- */
- /* */
- /* $Id:$ */
- /* */
- /* Copyright (C) 1993-1996 by id Software, Inc. */
- /* */
- /* This source is available for distribution and/or modification */
- /* only under the terms of the DOOM Source Code License as */
- /* published by id Software. All rights reserved. */
- /* */
- /* The source is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License */
- /* for more details. */
- /* */
- /* $Log:$ */
- /* */
- /* DESCRIPTION: */
- /* The actual span/column drawing functions. */
- /* Here find the main potential for optimization, */
- /* e.g. inline assembly, different algorithms. */
- /* */
- /* ----------------------------------------------------------------------------- */
-
-
- static const char
- rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
-
-
- #include "doomdef.h"
-
- #include "i_system.h"
- #include "z_zone.h"
- #include "w_wad.h"
-
- #include "r_local.h"
-
- /* Needs access to LFB (guess what). */
- #include "v_video.h"
- #include "i_video.h"
-
- /* State. */
- #include "doomstat.h"
-
- /* */
- /* R_DrawColumn */
- /* Source is the top of the column to scale. */
- /* */
-
- /* */
- /* A column is a vertical slice/span from a wall texture that, */
- /* given the DOOM style restrictions on the view orientation, */
- /* will always have constant z depth. */
- /* Thus a special case loop for very fast rendering can */
- /* be used. It has also been used with Wolfenstein 3D. */
- /* */
- void R_DrawColumn24 (void)
- {
- int count;
- unsigned char *dest;
- fixed_t frac;
- fixed_t fracstep;
- unsigned long couleur;
-
- count = dc_yh - dc_yl;
-
- /* Zero length, column does not exceed a pixel. */
- if (count < 0)
- return;
-
- #ifdef RANGECHECK
- if ((unsigned)dc_x >= SCREENWIDTH
- || dc_yl < 0
- || dc_yh >= SCREENHEIGHT)
- I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
- #endif
-
- /* Framebuffer destination address. */
- /* Use ylookup LUT to avoid multiply with ScreenWidth. */
- /* Use columnofs LUT for subwindows? */
- dest = ylookup[dc_yl] + columnofs[dc_x];
-
- /* Determine scaling, */
- /* which is the only mapping to be done. */
- fracstep = dc_iscale;
- frac = dc_texturemid + (dc_yl-centery)*fracstep;
-
- /* Inner loop that does the actual texture mapping, */
- /* e.g. a DDA-lile scaling. */
- /* This is as fast as it gets. */
- do
- {
- /* Re-map color indices from wall texture column */
- /* using a lighting/special effects LUT. */
- couleur = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- dest += (SCREENWIDTH*3)-3;
- frac += fracstep;
-
- } while (count--);
- }
-
-
- void R_DrawColumnLow24 (void)
- {
- int count;
- unsigned char *dest;
- fixed_t frac;
- fixed_t fracstep;
- unsigned long couleur;
-
- count = dc_yh - dc_yl;
-
- /* Zero length. */
- if (count < 0)
- return;
-
- #ifdef RANGECHECK
- if ((unsigned)dc_x >= SCREENWIDTH
- || dc_yl < 0
- || dc_yh >= SCREENHEIGHT)
- {
-
- I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
- }
- /* dccount++; */
- #endif
- /* Blocky mode, need to multiply by 2. */
-
- dest = ylookup[dc_yl] + columnofs[dc_x << 1];
-
- fracstep = dc_iscale;
- frac = dc_texturemid + (dc_yl-centery)*fracstep;
-
- do
- {
- /* Hack. Does not work corretly. */
- couleur = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- dest += (SCREENWIDTH*3)-6;
- frac += fracstep;
-
- } while (count--);
- }
-
-
- /* */
- /* Spectre/Invisibility. */
- /* */
-
- /* */
- /* Framebuffer postprocessing. */
- /* Creates a fuzzy image by copying pixels */
- /* from adjacent ones to left and right. */
- /* Used with an all black colormap, this */
- /* could create the SHADOW effect, */
- /* i.e. spectres and invisible players. */
- /* */
- void R_DrawFuzzColumn24 (void)
- {
- int count;
- unsigned char *dest;
- fixed_t frac;
- fixed_t fracstep;
-
- count = dc_yh - dc_yl;
-
- /* Zero length. */
- if (count < 0)
- return;
-
-
- #ifdef RANGECHECK
- if ((unsigned)dc_x >= SCREENWIDTH
- || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
- {
- I_Error ("R_DrawFuzzColumn: %i to %i at %i",
- dc_yl, dc_yh, dc_x);
- }
- #endif
-
- /* Does not work with blocky mode. */
- dest = ylookup[dc_yl] + columnofs[dc_x];
-
- /* Looks familiar. */
- fracstep = dc_iscale;
- frac = dc_texturemid + (dc_yl-centery)*fracstep;
-
- /* Looks like an attempt at dithering, */
- /* using the colormap #6 (of 0-31, a bit */
- /* brighter than average). */
- do
- {
- /* Lookup framebuffer, and retrieve */
- /* a pixel that is either one column */
- /* left or right of the current one. */
- /* Add index from colormap to index. */
- *dest++ >>= 1;
- *dest++ >>= 1;
- *dest++ >>= 1;
-
- dest += (SCREENWIDTH*3) -3;
-
- frac += fracstep;
- } while (count--);
- }
-
- void R_DrawFuzzColumnLow24 (void)
- {
- int count;
- unsigned char *dest;
- fixed_t frac;
- fixed_t fracstep;
-
- count = dc_yh - dc_yl;
-
- /* Zero length. */
- if (count < 0)
- return;
-
-
- #ifdef RANGECHECK
- if ((unsigned)dc_x >= SCREENWIDTH
- || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
- {
- I_Error ("R_DrawFuzzColumn: %i to %i at %i",
- dc_yl, dc_yh, dc_x);
- }
- #endif
- /* dc_x <<= 1; */
-
- /* Does not work with blocky mode. */
- dest = ylookup[dc_yl] + columnofs[dc_x << 1];
-
- /* Looks familiar. */
- fracstep = dc_iscale;
- frac = dc_texturemid + (dc_yl-centery)*fracstep;
-
- /* Looks like an attempt at dithering, */
- /* using the colormap #6 (of 0-31, a bit */
- /* brighter than average). */
- do
- {
- /* Lookup framebuffer, and retrieve */
- /* a pixel that is either one column */
- /* left or right of the current one. */
- /* Add index from colormap to index. */
- *dest++ >>= 1;
- *dest++ >>= 1;
- *dest++ >>= 1;
-
- *dest++ >>= 1;
- *dest++ >>= 1;
- *dest++ >>= 1;
-
- dest += (SCREENWIDTH*3)-6;
-
- frac += fracstep;
- } while (count--);
- }
-
-
-
- /* */
- /* R_DrawTranslatedColumn */
- /* Used to draw player sprites */
- /* with the green colorramp mapped to others. */
- /* Could be used with different translation */
- /* tables, e.g. the lighter colored version */
- /* of the BaronOfHell, the HellKnight, uses */
- /* identical sprites, kinda brightened up. */
- /* */
-
- void R_DrawTranslatedColumn24 (void)
- {
- int count;
- unsigned char *dest;
- fixed_t frac;
- fixed_t fracstep;
- unsigned long couleur;
-
- count = dc_yh - dc_yl;
- if (count < 0)
- return;
-
- #ifdef RANGECHECK
- if ((unsigned)dc_x >= SCREENWIDTH
- || dc_yl < 0
- || dc_yh >= SCREENHEIGHT)
- {
- I_Error ( "R_DrawColumn: %i to %i at %i",
- dc_yl, dc_yh, dc_x);
- }
-
- #endif
-
- /* FIXME. As above. */
- dest = ylookup[dc_yl] + columnofs[dc_x];
-
- /* Looks familiar. */
- fracstep = dc_iscale;
- frac = dc_texturemid + (dc_yl-centery)*fracstep;
-
- /* Here we do an additional index re-mapping. */
- do
- {
- /* Translation tables are used */
- /* to map certain colorramps to other ones, */
- /* used with PLAY sprites. */
- /* Thus the "green" ramp of the player 0 sprite */
- /* is mapped to gray, red, black/indigo. */
- couleur = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- dest += (SCREENWIDTH*3)-3;
-
- frac += fracstep;
- } while (count--);
- }
-
- void R_DrawTranslatedColumnLow24 (void)
- {
- int count;
- unsigned char *dest;
- fixed_t frac;
- fixed_t fracstep;
- unsigned long couleur;
-
- count = dc_yh - dc_yl;
- if (count < 0)
- return;
-
- #ifdef RANGECHECK
- if ((unsigned)dc_x >= SCREENWIDTH
- || dc_yl < 0
- || dc_yh >= SCREENHEIGHT)
- {
- I_Error ( "R_DrawColumn: %i to %i at %i",
- dc_yl, dc_yh, dc_x);
- }
-
- #endif
- /* dc_x <<= 1; */
-
- /* FIXME. As above. */
- dest = (unsigned char *) (ylookup[dc_yl] + columnofs[dc_x << 1]);
-
- /* Looks familiar. */
- fracstep = dc_iscale;
- frac = dc_texturemid + (dc_yl-centery)*fracstep;
-
- /* Here we do an additional index re-mapping. */
- do
- {
- /* Translation tables are used */
- /* to map certain colorramps to other ones, */
- /* used with PLAY sprites. */
- /* Thus the "green" ramp of the player 0 sprite */
- /* is mapped to gray, red, black/indigo. */
- couleur = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- dest += (SCREENWIDTH*3)-6;
-
- frac += fracstep;
- } while (count--);
- }
-
- /* */
- /* R_DrawSpan */
- /* With DOOM style restrictions on view orientation, */
- /* the floors and ceilings consist of horizontal slices */
- /* or spans with constant z depth. */
- /* However, rotation around the world z axis is possible, */
- /* thus this mapping, while simpler and faster than */
- /* perspective correct texture mapping, has to traverse */
- /* the texture at an angle in all but a few cases. */
- /* In consequence, flats are not stored by column (like walls), */
- /* and the inner loop has to step in texture space u and v. */
- /* */
-
- /* */
- /* Draws the actual span. */
- void R_DrawSpan24 (void)
- {
- fixed_t xfrac;
- fixed_t yfrac;
- unsigned char *dest;
- int count;
- int spot;
- unsigned long couleur;
-
- #ifdef RANGECHECK
- if (ds_x2 < ds_x1
- || ds_x1<0
- || ds_x2>=SCREENWIDTH
- || (unsigned)ds_y>SCREENHEIGHT)
- {
- I_Error( "R_DrawSpan: %i to %i at %i",
- ds_x1,ds_x2,ds_y);
- }
- /* dscount++; */
- #endif
-
-
- xfrac = ds_xfrac;
- yfrac = ds_yfrac;
-
- dest = (unsigned char *) (ylookup[ds_y] + columnofs[ds_x1]);
-
- /* We do not check for zero spans here? */
- count = ds_x2 - ds_x1;
-
- do
- {
- /* Current texture index in u,v. */
- spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
-
- /* Lookup pixel from flat texture tile, */
- /* re-index using light/colormap. */
- couleur = ds_colormap[ds_source[spot]];
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- /* Next step in u,v. */
- xfrac += ds_xstep;
- yfrac += ds_ystep;
-
- } while (count--);
- }
-
-
-
-
- /* */
- /* Again.. */
- /* */
- void R_DrawSpanLow24 (void)
- {
- fixed_t xfrac;
- fixed_t yfrac;
- unsigned char *dest;
- int count;
- int spot;
- unsigned long couleur;
-
- #ifdef RANGECHECK
- if (ds_x2 < ds_x1
- || ds_x1<0
- || ds_x2>=SCREENWIDTH
- || (unsigned)ds_y>SCREENHEIGHT)
- {
- I_Error( "R_DrawSpan: %i to %i at %i",
- ds_x1,ds_x2,ds_y);
- }
- /* dscount++; */
- #endif
-
- xfrac = ds_xfrac;
- yfrac = ds_yfrac;
-
- /* Blocky mode, need to multiply by 2. */
- /* ds_x1 <<= 1; */
- /* ds_x2 <<= 1; */
-
- dest = (unsigned char *) (ylookup[ds_y] + columnofs[ds_x1 << 1]);
-
-
- /* count = (ds_x2 - ds_x1) >> 1; */
- count = ds_x2 - ds_x1;
- do
- {
- spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
- /* Lowres/blocky mode does it twice, */
- /* while scale is adjusted appropriately. */
- couleur = ds_colormap[ds_source[spot]];
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- *dest++ = couleur;
- *dest++ = couleur >> 8;
- *dest++ = couleur >> 16;
-
- xfrac += ds_xstep;
- yfrac += ds_ystep;
-
- } while (count--);
- }
-