doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

r_draw.c (6745B)


      1 #include "doomdef.h"
      2 #include "i_system.h"
      3 #include "z_zone.h"
      4 #include "w_wad.h"
      5 #include "r_local.h"
      6 #include "v_video.h"
      7 #include "doomstat.h"
      8 
      9 #define MAXWIDTH			1120
     10 #define MAXHEIGHT			832
     11 #define SBARHEIGHT		32
     12 #define FUZZTABLE		50
     13 #define FUZZOFF	(SCREENWIDTH)
     14 
     15 lighttable_t* dc_colormap;
     16 lighttable_t* ds_colormap;
     17 byte*			ds_source;
     18 byte*   viewimage;
     19 byte*   ylookup[MAXHEIGHT];
     20 byte*			dc_source;
     21 byte*	dc_translation;
     22 byte*	translationtables;
     23 int		viewwidth;
     24 int		scaledviewwidth;
     25 int		viewheight;
     26 int		viewwindowx;
     27 int		viewwindowy;
     28 int		columnofs[MAXWIDTH];
     29 byte		translations[3][256];
     30 int			dc_x;
     31 int			dc_yl;
     32 int			dc_yh;
     33 fixed_t			dc_iscale;
     34 fixed_t			dc_texturemid;
     35 int			dccount;
     36 int			ds_y;
     37 int			ds_x1;
     38 int			ds_x2;
     39 fixed_t			ds_xfrac;
     40 fixed_t			ds_yfrac;
     41 fixed_t			ds_xstep;
     42 fixed_t			ds_ystep;
     43 int			dscount;
     44 int	fuzzpos = 0;
     45 int	fuzzoffset[FUZZTABLE] = {
     46 	FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
     47 	FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
     48 	FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
     49 	FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
     50 	FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
     51 	FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
     52 	FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
     53 };
     54 
     55 void
     56 R_DrawColumn()
     57 {
     58 	int     count;
     59 	byte*   dest;
     60 	fixed_t frac, fracstep;
     61 
     62 	count = dc_yh - dc_yl;
     63 	if (count < 0)
     64 		return;
     65 	dest = ylookup[dc_yl] + columnofs[dc_x];
     66 	fracstep = dc_iscale;
     67 	frac = dc_texturemid + (dc_yl-centery)*fracstep;
     68 	do {
     69 		*dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
     70 		dest += SCREENWIDTH;
     71 		frac += fracstep;
     72 	} while (count--);
     73 }
     74 
     75 void
     76 R_DrawColumnLow()
     77 {
     78 	byte*   dest, *dest2;
     79 	fixed_t frac, fracstep;
     80 	int     count;
     81 
     82 	count = dc_yh - dc_yl;
     83 	if (count < 0)
     84 		return;
     85 	dc_x <<= 1;
     86 	dest = ylookup[dc_yl] + columnofs[dc_x];
     87 	dest2 = ylookup[dc_yl] + columnofs[dc_x+1];
     88 	fracstep = dc_iscale;
     89 	frac = dc_texturemid + (dc_yl-centery)*fracstep;
     90 	do {
     91 		*dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
     92 		dest += SCREENWIDTH;
     93 		dest2 += SCREENWIDTH;
     94 		frac += fracstep;
     95 	} while (count--);
     96 }
     97 
     98 void
     99 R_DrawFuzzColumn()
    100 {
    101 	byte*		dest;
    102 	fixed_t		frac, fracstep;
    103 	int			count;
    104 
    105 	if (!dc_yl) dc_yl = 1;
    106 	if (dc_yh == viewheight-1) dc_yh = viewheight - 2;
    107 	count = dc_yh - dc_yl;
    108 	if (count < 0)
    109 		return;
    110 	dest = ylookup[dc_yl] + columnofs[dc_x];
    111 	fracstep = dc_iscale;
    112 	frac = dc_texturemid + (dc_yl-centery)*fracstep;
    113 	do {
    114 		*dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];
    115 		if (++fuzzpos == FUZZTABLE)
    116 			fuzzpos = 0;
    117 		dest += SCREENWIDTH;
    118 		frac += fracstep;
    119 	} while (count--);
    120 }
    121 
    122 void
    123 R_DrawTranslatedColumn()
    124 {
    125 	byte*		dest;
    126 	fixed_t		frac, fracstep;
    127 	int			count;
    128 
    129 	count = dc_yh - dc_yl;
    130 	if (count < 0)
    131 		return;
    132 	dest = ylookup[dc_yl] + columnofs[dc_x];
    133 	fracstep = dc_iscale;
    134 	frac = dc_texturemid + (dc_yl-centery)*fracstep;
    135 	do {
    136 		*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
    137 		dest += SCREENWIDTH;
    138 		frac += fracstep;
    139 	} while (count--);
    140 }
    141 
    142 void
    143 R_InitTranslationTables()
    144 {
    145 	int i;
    146 
    147 	translationtables = Z_Malloc (256*3+255, PU_STATIC, 0);
    148 	translationtables = (byte*)(((long)translationtables + 255 )& ~255);
    149 	for (i = 0; i < 256; ++i) {
    150 		if (i >= 0x70 && i<= 0x7f) {
    151 			translationtables[i] = 0x60 + (i&0xf);
    152 			translationtables [i+256] = 0x40 + (i&0xf);
    153 			translationtables [i+512] = 0x20 + (i&0xf);
    154 		} else translationtables[i] = translationtables[i+256] = translationtables[i+512] = i;
    155 	}
    156 }
    157 
    158 
    159 void
    160 R_DrawSpan()
    161 {
    162 	byte*		dest;
    163 	fixed_t		xfrac, yfrac;
    164 	int			count, spot;
    165 
    166 	xfrac = ds_xfrac;
    167 	yfrac = ds_yfrac;
    168 	dest = ylookup[ds_y] + columnofs[ds_x1];
    169 	count = ds_x2 - ds_x1;
    170 	do {
    171 		spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
    172 		*dest++ = ds_colormap[ds_source[spot]];
    173 		xfrac += ds_xstep;
    174 		yfrac += ds_ystep;
    175 	} while (count--);
    176 }
    177 
    178 void
    179 R_DrawSpanLow()
    180 {
    181 	byte*		dest;
    182 	fixed_t		xfrac, yfrac;
    183 	int			count, spot;
    184 
    185 	xfrac = ds_xfrac;
    186 	yfrac = ds_yfrac;
    187 	ds_x1 <<= 1;
    188 	ds_x2 <<= 1;
    189 	dest = ylookup[ds_y] + columnofs[ds_x1];
    190 	count = ds_x2 - ds_x1;
    191 	do {
    192 		spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
    193 		*dest++ = ds_colormap[ds_source[spot]];
    194 		*dest++ = ds_colormap[ds_source[spot]];
    195 		xfrac += ds_xstep;
    196 		yfrac += ds_ystep;
    197 	} while (count--);
    198 }
    199 
    200 void
    201 R_InitBuffer(int width, int height)
    202 {
    203 	int i;
    204 
    205 	viewwindowx = (SCREENWIDTH-width) >> 1;
    206 	for (i = 0; i < width; ++i)
    207 		columnofs[i] = viewwindowx + i;
    208 	if (width == SCREENWIDTH)
    209 		viewwindowy = 0;
    210 	else
    211 		viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
    212 	for (i=0 ; i<height ; i++)
    213 	ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH;
    214 }
    215 
    216 void
    217 R_FillBackScreen()
    218 {
    219 	patch_t*	patch;
    220 	byte*	src, *dest;
    221 	char*	name;
    222 	int		x, y;
    223 	char	name1[] = "FLOOR7_2";
    224 
    225 	if (scaledviewwidth == 320)
    226 		return;
    227 	name = name1;
    228 	src = W_CacheLumpName (name, PU_CACHE);
    229 	dest = screens[1];
    230 	for (y = 0; y < SCREENHEIGHT-SBARHEIGHT; ++y) {
    231 		for (x = 0; x < SCREENWIDTH/64; ++x) {
    232 			memcpy(dest, src+((y&63)<<6), 64);
    233 			dest += 64;
    234 		}
    235 		if (SCREENWIDTH&63) 	{
    236 			memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
    237 			dest += (SCREENWIDTH&63);
    238 		}
    239 	}
    240 	patch = W_CacheLumpName("brdr_t",PU_CACHE);
    241 	for (x = 0; x < scaledviewwidth; x += 8) V_DrawPatch(viewwindowx+x,viewwindowy-8,1,patch);
    242 	patch = W_CacheLumpName ("brdr_b",PU_CACHE);
    243 	for (x = 0; x < scaledviewwidth; x += 8) V_DrawPatch(viewwindowx+x,viewwindowy+viewheight,1,patch);
    244 	patch = W_CacheLumpName ("brdr_l",PU_CACHE);
    245 	for (y = 0; y < viewheight; y += 8) V_DrawPatch(viewwindowx-8,viewwindowy+y,1,patch);
    246 	patch = W_CacheLumpName ("brdr_r",PU_CACHE);
    247 	for (y = 0; y < viewheight; y += 8) V_DrawPatch(viewwindowx+scaledviewwidth,viewwindowy+y,1,patch);
    248 	V_DrawPatch(viewwindowx-8, viewwindowy-8, 1, W_CacheLumpName("brdr_tl",PU_CACHE));
    249 	V_DrawPatch(viewwindowx+scaledviewwidth, viewwindowy-8, 1, W_CacheLumpName("brdr_tr",PU_CACHE));
    250 	V_DrawPatch(viewwindowx-8, viewwindowy + viewheight, 1, W_CacheLumpName("brdr_bl",PU_CACHE));
    251 	V_DrawPatch(viewwindowx+scaledviewwidth, viewwindowy+viewheight, 1, W_CacheLumpName("brdr_br",PU_CACHE));
    252 }
    253 
    254 void
    255 R_VideoErase(unsigned ofs, int count)
    256 {
    257 	memcpy(screens[0]+ofs, screens[1]+ofs, count);
    258 }
    259 
    260 void V_MarkRect(int x, int y, int width, int height);
    261 
    262 void
    263 R_DrawViewBorder()
    264 {
    265 	int		top, side, ofs, i;
    266 
    267 	if (scaledviewwidth == SCREENWIDTH)
    268 		return;
    269 	top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2;
    270 	side = (SCREENWIDTH-scaledviewwidth)/2;
    271 	R_VideoErase(0, top*SCREENWIDTH+side);
    272 	ofs = (viewheight+top)*SCREENWIDTH-side;
    273 	R_VideoErase(ofs, top*SCREENWIDTH+side);
    274 	ofs = top*SCREENWIDTH + SCREENWIDTH-side;
    275 	side <<= 1;
    276 	for (i = 1; i < viewheight; ++i) {
    277 		R_VideoErase(ofs, side);
    278 		ofs += SCREENWIDTH;
    279 	}
    280 	V_MarkRect(0, 0, SCREENWIDTH, SCREENHEIGHT - SBARHEIGHT);
    281 }