/* R_draw.c */ #include "doomdef.h" #include "r_local.h" #ifdef GL_HERETIC extern byte *p_bPalette; #endif /* 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. */ byte *viewimage; int viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy; byte *ylookup[MAXSCREENHEIGHT]; int columnofs[MAXSCREENWIDTH]; byte translations[3][256]; /* color tables for different players */ byte *tinttable; /* used for translucent sprites */ /* ================== = = 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; byte *dc_source; /* first pixel in a column (possibly virtual) */ int dccount; /* just for profiling */ byte *dc_translation; byte *translationtables; #ifndef GL_HERETIC void R_DrawColumn (void) { int count; byte *dest; fixed_t frac, 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 dest = ylookup[dc_yl] + columnofs[dc_x]; fracstep = dc_iscale; frac = dc_texturemid + (dc_yl-centery)*fracstep; do { *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; dest += screenwidth; frac += fracstep; } while (count--); } void R_DrawColumnLow (void) { int count; byte *dest; fixed_t frac, 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); /* dccount++; */ #endif dest = ylookup[dc_yl] + columnofs[dc_x]; fracstep = dc_iscale; frac = dc_texturemid + (dc_yl-centery)*fracstep; do { *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; dest += screenwidth; frac += fracstep; } while (count--); } /* * Spectre/Invisibility. */ /* #define FUZZTABLE 50 #define FUZZOFF 1 int fuzzoffset[FUZZTABLE] = { FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF }; int fuzzpos = 0; */ #define FUZZTABLE 50 #define FUZZOFF 1 int fuzzoffset[FUZZTABLE]; int fuzzpos; void resinit_r_draw_c(void) { int i; for (i=0; i= screenwidth || dc_yl < 0 || dc_yh >= screenheight) I_Error ("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); #endif dest = ylookup[dc_yl] + columnofs[dc_x]; fracstep = dc_iscale; frac = dc_texturemid + (dc_yl-centery)*fracstep; do { *dest = tinttable[((*dest)<<8)+dc_colormap[dc_source[(frac>>FRACBITS)&127]]]; dest += screenwidth; frac += fracstep; } while(count--); } /* ======================== = = R_DrawTranslatedColumn = ======================== */ void R_DrawTranslatedColumn (void) { int count; byte *dest; fixed_t frac, 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 dest = ylookup[dc_yl] + columnofs[dc_x]; fracstep = dc_iscale; frac = dc_texturemid + (dc_yl-centery)*fracstep; do { *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; dest += screenwidth; frac += fracstep; } while (count--); } void R_DrawTranslatedFuzzColumn (void) { int count; byte *dest; fixed_t frac, 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 dest = ylookup[dc_yl] + columnofs[dc_x]; fracstep = dc_iscale; frac = dc_texturemid + (dc_yl-centery)*fracstep; do { *dest = tinttable[((*dest)<<8) +dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]]; dest += screenwidth; frac += fracstep; } while (count--); } #endif /* GL_HERETIC */ /* * -------------------------------------------------------------------------- * * PROC R_InitTranslationTables * * -------------------------------------------------------------------------- */ void R_InitTranslationTables (void) { int i; /* Load tint table */ tinttable = W_CacheLumpName("TINTTAB", PU_STATIC); /* Allocate translation tables */ translationtables = Z_Malloc(256*3+255, PU_STATIC, 0); translationtables = (byte *)(((long)translationtables + 255) & ~255); /* Fill out the translation tables */ for(i = 0; i < 256; i++) { if(i >= 225 && i <= 240) { translationtables[i] = 114+(i-225); /* yellow */ translationtables[i+256] = 145+(i-225); /* red */ translationtables[i+512] = 190+(i-225); /* blue */ } else { translationtables[i] = translationtables[i+256] = translationtables[i+512] = i; } } } /* ================ = = R_DrawSpan = ================ */ 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; byte *ds_source; /* start of a 64*64 tile image */ int dscount; /* just for profiling */ void R_DrawSpan (void) { fixed_t xfrac, yfrac; byte *dest; int count, 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 = ylookup[ds_y] + columnofs[ds_x1]; count = ds_x2 - ds_x1; do { spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); *dest++ = ds_colormap[ds_source[spot]]; xfrac += ds_xstep; yfrac += ds_ystep; } while (count--); } void R_DrawSpanLow (void) { fixed_t xfrac, yfrac; byte *dest; int count, 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 = ylookup[ds_y] + columnofs[ds_x1]; count = ds_x2 - ds_x1; do { spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); *dest++ = ds_colormap[ds_source[spot]]; xfrac += ds_xstep; yfrac += ds_ystep; } while (count--); } /* ================ = = R_InitBuffer = ================= */ void R_InitBuffer (int width, int height) { int i; #ifndef GL_HERETIC viewwindowx = (screenwidth-width) >> 1; for (i=0 ; i> 1; for (i=0 ; i> 1; for (i=0 ; i> 1; for (i=0 ; i= screenwidth || dc_yl < 0 || dc_yh >= screenheight) I_Error ("R_DrawSkyColumn: %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. */ *dest = dc_colormap[dc_source[(frac>>FRACBITS)&255]]; dest += screenwidth; frac += fracstep; } while (count--); } #endif