home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ST-Computer Leser-CD 2000 January
/
LCD_01_2000.iso
/
games
/
doom
/
pmdoom
/
src
/
r_draw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-17
|
10KB
|
406 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"
/* */
/* All drawing to the view buffer is accomplished in this file. */
/* The other refresh files only know about ccordinates, */
/* not the architecture of the frame buffer. */
/* Conveniently, the frame buffer is a linear one, */
/* and we need only the base address, */
/* and the total size == width*height*depth/8., */
/* */
byte* viewimage;
int viewwidth;
int scaledviewwidth;
int viewheight;
int viewwindowx;
int viewwindowy;
int columnofs[MAXWIDTH];
byte *ylookup[MAXHEIGHT];
/* Color tables for different players, */
/* translate a limited part to another */
/* (color ramps used for suit colors). */
/* */
byte translations[3][256];
/* */
/* R_DrawColumn */
/* Source is the top of the column to scale. */
/* */
lighttable_t* dc_colormap;
int dc_x;
int dc_yl;
int dc_yh;
fixed_t dc_iscale;
fixed_t dc_texturemid;
/* first pixel in a column (possibly virtual) */
byte* dc_source;
/* just for profiling */
int dccount;
byte* dc_translation;
byte* translationtables;
/* */
/* R_InitTranslationTables */
/* Creates the translation tables to map */
/* the green color ramp to gray, brown, red. */
/* Assumes a given structure of the PLAYPAL. */
/* Could be read from a lump instead. */
/* */
void R_InitTranslationTables (void)
{
int i;
#if 0
translationtables = Z_Malloc (256*3+255, PU_STATIC, 0);
translationtables = (byte *)(( (int)translationtables + 255 )& ~255);
#else
translationtables = Z_Malloc (256*3, PU_STATIC, 0);
#endif
/* translate just the 16 green colors */
for (i=0 ; i<256 ; i++)
{
if (i >= 0x70 && i<= 0x7f)
{
/* map green ramp to gray, brown, red */
translationtables[i] = 0x60 + (i&0xf);
translationtables [i+256] = 0x40 + (i&0xf);
translationtables [i+512] = 0x20 + (i&0xf);
}
else
{
/* Keep all other colors as is. */
translationtables[i] = translationtables[i+256]
= translationtables[i+512] = i;
}
}
}
/* */
/* 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. */
/* */
int ds_y;
int ds_x1;
int ds_x2;
lighttable_t* ds_colormap;
fixed_t ds_xfrac;
fixed_t ds_yfrac;
fixed_t ds_xstep;
fixed_t ds_ystep;
/* start of a 64*64 tile image */
byte* ds_source;
/* just for profiling */
int dscount;
/* */
/* R_InitBuffer */
/* Creats lookup tables that avoid */
/* multiplies and other hazzles */
/* for getting the framebuffer address */
/* of a pixel to draw. */
/* */
void
R_InitBuffer
( int width,
int height )
{
int i;
/* Handle resize, */
/* e.g. smaller view windows */
/* with border and/or status bar. */
viewwindowx = (SCREENWIDTH-width) >> 1;
/* Column offset. For windows. */
for (i=0 ; i<width ; i++)
columnofs[i] = (viewwindowx + i)*pixel_size;
/* Samw with base row offset. */
if (width == SCREENWIDTH)
viewwindowy = 0;
else
viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
/* Preclaculate all row offsets. */
for (i=0 ; i<height ; i++)
ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH*pixel_size;
}
/* */
/* R_FillBackScreen */
/* Fills the back screen with a pattern */
/* for variable screen sizes */
/* Also draws a beveled edge. */
/* */
void R_FillBackScreen (void)
{
byte *src,*src1;
byte *dest;
unsigned short *destsrc;
unsigned long *destsrc32;
int x;
int y;
patch_t* patch;
/* DOOM border patch. */
char name1[] = "FLOOR7_2";
/* DOOM II border patch. */
char name2[] = "GRNROCK";
char* name;
if (scaledviewwidth == 320)
return;
if ( gamemode == commercial)
name = name2;
else
name = name1;
src = W_CacheLumpName (name, PU_CACHE);
switch (pixel_size)
{
case 1:
dest = screens[1];
for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
{
for (x=0 ; x<SCREENWIDTH/64 ; x++)
{
memcpy (dest, src+((y&63)<<6), 64);
dest += 64;
}
if (SCREENWIDTH&63)
{
memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
dest += (SCREENWIDTH&63);
}
}
break;
case 2:
destsrc = (unsigned short *) screens[1];
for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
{
unsigned short *dest1;
src1 = src + ((y & 63) << 6);
dest1 = destsrc;
for (x=0; x<SCREENWIDTH ; x++)
*dest1++ = truecolor_palette[ src1[x & 63] ];
destsrc += SCREENWIDTH;
}
break;
case 3:
dest=screens[1];
for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
{
byte *dest1;
src1 = src + ((y & 63) << 6);
dest1 = dest;
for (x=0; x<SCREENWIDTH ; x++)
{
unsigned long couleur;
couleur = truecolor_palette[ src1[x & 63] ];
*dest1++ = couleur;
*dest1++ = couleur >> 8;
*dest1++ = couleur >> 16;
}
dest += SCREENWIDTH*3;
}
break;
case 4:
destsrc32 = (unsigned long *) screens[1];
for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
{
unsigned long *dest1;
src1 = src + ((y & 63) << 6);
dest1 = destsrc32;
for (x=0; x<SCREENWIDTH ; x++)
*dest1++ = truecolor_palette[ src1[x & 63] ];
destsrc32 += SCREENWIDTH;
}
break;
}
patch = W_CacheLumpName ("brdr_t",PU_CACHE);
for (x=0 ; x<scaledviewwidth ; x+=8)
V_DrawPatch (viewwindowx+x,viewwindowy-8,1,patch);
patch = W_CacheLumpName ("brdr_b",PU_CACHE);
for (x=0 ; x<scaledviewwidth ; x+=8)
V_DrawPatch (viewwindowx+x,viewwindowy+viewheight,1,patch);
patch = W_CacheLumpName ("brdr_l",PU_CACHE);
for (y=0 ; y<viewheight ; y+=8)
V_DrawPatch (viewwindowx-8,viewwindowy+y,1,patch);
patch = W_CacheLumpName ("brdr_r",PU_CACHE);
for (y=0 ; y<viewheight ; y+=8)
V_DrawPatch (viewwindowx+scaledviewwidth,viewwindowy+y,1,patch);
/* Draw beveled edge. */
V_DrawPatch (viewwindowx-8,
viewwindowy-8,
1,
W_CacheLumpName ("brdr_tl",PU_CACHE));
V_DrawPatch (viewwindowx+scaledviewwidth,
viewwindowy-8,
1,
W_CacheLumpName ("brdr_tr",PU_CACHE));
V_DrawPatch (viewwindowx-8,
viewwindowy+viewheight,
1,
W_CacheLumpName ("brdr_bl",PU_CACHE));
V_DrawPatch (viewwindowx+scaledviewwidth,
viewwindowy+viewheight,
1,
W_CacheLumpName ("brdr_br",PU_CACHE));
}
/* */
/* Copy a screen buffer. */
/* */
void
R_VideoErase
( unsigned ofs,
int count )
{
/* LFB copy. */
/* This might not be a good idea if memcpy */
/* is not optiomal, e.g. byte by byte on */
/* a 32bit CPU, as GNU GCC/Linux libc did */
/* at one point. */
memcpy (screens[0]+ofs*pixel_size, screens[1]+ofs*pixel_size, count*pixel_size);
}
/* */
/* R_DrawViewBorder */
/* Draws the border around the view */
/* for different size windows? */
/* */
void
V_MarkRect
( int x,
int y,
int width,
int height );
void R_DrawViewBorder (void)
{
int top;
int side;
int ofs;
int i;
if (scaledviewwidth == SCREENWIDTH)
return;
top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2;
side = (SCREENWIDTH-scaledviewwidth)/2;
/* copy top and one line of left side */
R_VideoErase (0, top*SCREENWIDTH+side);
/* copy one line of right side and bottom */
ofs = (viewheight+top)*SCREENWIDTH-side;
R_VideoErase (ofs, top*SCREENWIDTH+side);
/* copy sides using wraparound */
ofs = top*SCREENWIDTH + SCREENWIDTH-side;
side <<= 1;
for (i=1 ; i<viewheight ; i++)
{
R_VideoErase (ofs, side);
ofs += SCREENWIDTH;
}
/* ? */
V_MarkRect (0,0,SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT);
}