📄 r_draw.c
字号:
*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
dest += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
//
// 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;
translationtables = Z_Malloc (256*3+255, PU_STATIC, 0);
translationtables = (byte *)(( (int)translationtables + 255 )& ~255);
// 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;
//
// Draws the actual span.
void R_DrawSpan (void)
{
fixed_t xfrac;
fixed_t yfrac;
byte* 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 = 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--);
}
// UNUSED.
// Loop unrolled by 4.
#if 0
void R_DrawSpan (void)
{
unsigned position, step;
byte* source;
byte* colormap;
byte* dest;
unsigned count;
usingned spot;
unsigned value;
unsigned temp;
unsigned xtemp;
unsigned ytemp;
position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff);
step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff);
source = ds_source;
colormap = ds_colormap;
dest = ylookup[ds_y] + columnofs[ds_x1];
count = ds_x2 - ds_x1 + 1;
while (count >= 4)
{
ytemp = position>>4;
ytemp = ytemp & 4032;
xtemp = position>>26;
spot = xtemp | ytemp;
position += step;
dest[0] = colormap[source[spot]];
ytemp = position>>4;
ytemp = ytemp & 4032;
xtemp = position>>26;
spot = xtemp | ytemp;
position += step;
dest[1] = colormap[source[spot]];
ytemp = position>>4;
ytemp = ytemp & 4032;
xtemp = position>>26;
spot = xtemp | ytemp;
position += step;
dest[2] = colormap[source[spot]];
ytemp = position>>4;
ytemp = ytemp & 4032;
xtemp = position>>26;
spot = xtemp | ytemp;
position += step;
dest[3] = colormap[source[spot]];
count -= 4;
dest += 4;
}
while (count > 0)
{
ytemp = position>>4;
ytemp = ytemp & 4032;
xtemp = position>>26;
spot = xtemp | ytemp;
position += step;
*dest++ = colormap[source[spot]];
count--;
}
}
#endif
//
// Again..
//
void R_DrawSpanLow (void)
{
fixed_t xfrac;
fixed_t yfrac;
byte* 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 = ylookup[ds_y] + columnofs[ds_x1];
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]];
*dest++ = ds_colormap[ds_source[spot]];
xfrac += ds_xstep;
yfrac += ds_ystep;
} while (count--);
}
//
// R_InitBuffer
// Creats lookup tables that avoid
// multiplies and other hassles
// 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;
// Same with base row offset.
if (width == SCREENWIDTH)
viewwindowy = 0;
else
viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
// Precalculate all row offsets.
for (i = 0; i < height; i++)
ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH;
}
//
// R_FillBackScreen
// Fills the back screen with a pattern for variable screen sizes
// Also draws a beveled edge.
//
void R_FillBackScreen (void)
{
byte* src;
byte* dest;
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 == SCREENWIDTH)&&(viewheight == SCREENHEIGHT))
return;
if (gamemode == commercial)
name = name2;
else
name = name1;
src = W_CacheLumpName(name, PU_CACHE);
dest = screens[1];
//for (y = 0; y < SCREENHEIGHT-SBARHEIGHT; y++)
for (y = 0; y < SCREENHEIGHT; 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);
}
}
if (scaledviewwidth == SCREENWIDTH)
return;
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 optimal, e.g. byte by byte on
// a 32bit CPU, as GNU GCC/Linux libc did at one point.
memcpy(screens[0]+ofs, screens[1]+ofs, count);
}
//
// 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, side2;
int ofs;
int i;
if ((SCREENWIDTH > 320) && (SCREENHEIGHT != viewheight))
{
ofs = (SCREENHEIGHT-SBARHEIGHT) * SCREENWIDTH;
side = ((SCREENWIDTH - 320) / 2);
side2 = side * 2;
R_VideoErase(ofs, side);
ofs += (SCREENWIDTH - side);
for (i = 1;i < SBARHEIGHT;i++)
{
R_VideoErase(ofs, side2);
ofs += SCREENWIDTH;
}
R_VideoErase(ofs, side);
}
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -