home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ST-Computer Leser-CD 2000 January
/
LCD_01_2000.iso
/
games
/
doom
/
pmdoom
/
src
/
r_draw16.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-17
|
11KB
|
470 lines
/* 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. */
/* */
unsigned long fuzzmask;
/* */
/* 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. */
/* */
#ifndef ATARI
void R_DrawColumn16 (void)
{
int count;
unsigned short *dest;
fixed_t frac;
fixed_t fracstep;
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 = (short *) (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. */
*dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
dest += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
void R_DrawColumnLow16 (void)
{
int count;
unsigned long *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_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
}
/* dccount++; */
#endif
/* Blocky mode, need to multiply by 2. */
/* dc_x <<= 1; */
dest = (unsigned long *) (ylookup[dc_yl] + columnofs[dc_x << 1] );
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
do
{
/* Hack. Does not work corretly. */
*dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
dest += SCREENWIDTH>>1;
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_DrawFuzzColumn16 (void)
{
int count;
unsigned short *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 = (short *) (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 = (*dest >> 1) & fuzzmask;
dest += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
void R_DrawFuzzColumnLow16 (void)
{
int count;
unsigned long *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 = (unsigned long *) (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 = (*dest >> 1) & fuzzmask;
dest += SCREENWIDTH>>1;
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_DrawTranslatedColumn16 (void)
{
int count;
unsigned short *dest;
fixed_t frac;
fixed_t fracstep;
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 = (short *) (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. */
*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
dest += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
void R_DrawTranslatedColumnLow16 (void)
{
int count;
unsigned long *dest;
fixed_t frac;
fixed_t fracstep;
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 long *) (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. */
*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
dest += SCREENWIDTH>>1;
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_DrawSpan16 (void)
{
fixed_t xfrac;
fixed_t yfrac;
unsigned short *dest;
int count;
int spot;
#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 = (short *) (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. */
*dest++ = ds_colormap[ds_source[spot]];
/* Next step in u,v. */
xfrac += ds_xstep;
yfrac += ds_ystep;
} while (count--);
}
/* */
/* Again.. */
/* */
void R_DrawSpanLow16 (void)
{
fixed_t xfrac;
fixed_t yfrac;
unsigned long *dest;
int count;
int spot;
#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 long *) (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. */
*dest++ = ds_colormap[ds_source[spot]];
xfrac += ds_xstep;
yfrac += ds_ystep;
} while (count--);
}
#endif /* ATARI */