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"
-
- /* */
- /* 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);
- }
-