📄 r_draw.c
字号:
{ // Translation tables are used // to map certain colorramps to other ones, // used with PLAY sprites. // Thus the "green" ramp of the player 0 sprite // is mapped to gray, red, black/indigo. *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 profilingint 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 0void 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 hazzles// for getting the framebuffer address// of a pixel to draw.//voidR_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; // 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; } //// 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 == 320) 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 (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); } } 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.//voidR_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, screens[1]+ofs, count); } //// R_DrawViewBorder// Draws the border around the view// for different size windows?//voidV_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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -