📄 r_plane.c
字号:
//**************************************************************************//**//** r_plane.c : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: r_plane.c,v $//** $Revision: 1.5 $//** $Date: 95/07/13 15:17:12 $//** $Author: cjr $//**//**************************************************************************// HEADER FILES ------------------------------------------------------------#include "h2def.h"#include "r_local.h"// MACROS ------------------------------------------------------------------// TYPES -------------------------------------------------------------------// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------// EXTERNAL DATA DECLARATIONS ----------------------------------------------extern fixed_t Sky1ScrollDelta;extern fixed_t Sky2ScrollDelta;// PUBLIC DATA DEFINITIONS -------------------------------------------------int Sky1Texture;int Sky2Texture;fixed_t Sky1ColumnOffset;fixed_t Sky2ColumnOffset;int skyflatnum;int skytexturemid;fixed_t skyiscale;boolean DoubleSky;planefunction_t floorfunc, ceilingfunc;// Openingvisplane_t visplanes[MAXVISPLANES], *lastvisplane;visplane_t *floorplane, *ceilingplane;short openings[MAXOPENINGS], *lastopening;// Clip values are the solid pixel bounding the range.// floorclip start out SCREENHEIGHT// ceilingclip starts out -1short floorclip[SCREENWIDTH];short ceilingclip[SCREENWIDTH];// spanstart holds the start of a plane span, initialized to 0int spanstart[SCREENHEIGHT];int spanstop[SCREENHEIGHT];// Texture mappinglighttable_t **planezlight;fixed_t planeheight;fixed_t yslope[SCREENHEIGHT];fixed_t distscale[SCREENWIDTH];fixed_t basexscale, baseyscale;fixed_t cachedheight[SCREENHEIGHT];fixed_t cacheddistance[SCREENHEIGHT];fixed_t cachedxstep[SCREENHEIGHT];fixed_t cachedystep[SCREENHEIGHT];// PRIVATE DATA DEFINITIONS ------------------------------------------------// CODE --------------------------------------------------------------------//==========================================================================//// R_InitSky//// Called at level load.////==========================================================================void R_InitSky(int map){ Sky1Texture = P_GetMapSky1Texture(map); Sky2Texture = P_GetMapSky2Texture(map); Sky1ScrollDelta = P_GetMapSky1ScrollDelta(map); Sky2ScrollDelta = P_GetMapSky2ScrollDelta(map); Sky1ColumnOffset = 0; Sky2ColumnOffset = 0; DoubleSky = P_GetMapDoubleSky(map);}//==========================================================================//// R_InitSkyMap//// Called whenever the view size changes.////==========================================================================void R_InitSkyMap(void){ skyflatnum = R_FlatNumForName("F_SKY"); skytexturemid = 200*FRACUNIT; skyiscale = FRACUNIT;}//==========================================================================//// R_InitPlanes//// Called at game startup.////==========================================================================void R_InitPlanes(void){}//==========================================================================//// R_MapPlane//// Globals used: planeheight, ds_source, basexscale, baseyscale,// viewx, viewy.////==========================================================================void R_MapPlane(int y, int x1, int x2){ angle_t angle; fixed_t distance, length; unsigned index;#ifdef RANGECHECK if(x2 < x1 || x1 < 0 || x2 >= viewwidth || (unsigned)y > viewheight) { I_Error("R_MapPlane: %i, %i at %i", x1, x2, y); }#endif if(planeheight != cachedheight[y]) { cachedheight[y] = planeheight; distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]); ds_xstep = cachedxstep[y] = FixedMul(distance, basexscale); ds_ystep = cachedystep[y] = FixedMul(distance, baseyscale); } else { distance = cacheddistance[y]; ds_xstep = cachedxstep[y]; ds_ystep = cachedystep[y]; } length = FixedMul(distance, distscale[x1]); angle = (viewangle+xtoviewangle[x1])>>ANGLETOFINESHIFT; ds_xfrac = viewx+FixedMul(finecosine[angle], length); ds_yfrac = -viewy-FixedMul(finesine[angle], length); if(fixedcolormap) { ds_colormap = fixedcolormap; } else { index = distance >> LIGHTZSHIFT; if(index >= MAXLIGHTZ ) { index = MAXLIGHTZ-1; } ds_colormap = planezlight[index]; } ds_y = y; ds_x1 = x1; ds_x2 = x2; spanfunc(); // High or low detail}//==========================================================================//// R_ClearPlanes//// Called at the beginning of each frame.////==========================================================================void R_ClearPlanes(void){ int i; angle_t angle; // Opening / clipping determination for(i = 0; i < viewwidth; i++) { floorclip[i] = viewheight; ceilingclip[i] = -1; } lastvisplane = visplanes; lastopening = openings; // Texture calculation memset(cachedheight, 0, sizeof(cachedheight)); angle = (viewangle-ANG90)>>ANGLETOFINESHIFT; // left to right mapping // Scale will be unit scale at SCREENWIDTH/2 distance basexscale = FixedDiv(finecosine[angle], centerxfrac); baseyscale = -FixedDiv(finesine[angle], centerxfrac);}//==========================================================================//// R_FindPlane////==========================================================================visplane_t *R_FindPlane(fixed_t height, int picnum, int lightlevel, int special){ visplane_t *check; if(special < 150) { // Don't let low specials affect search special = 0; } if(picnum == skyflatnum) { // All skies map together height = 0; lightlevel = 0; } for(check = visplanes; check < lastvisplane; check++) { if(height == check->height && picnum == check->picnum && lightlevel == check->lightlevel && special == check->special) break; } if(check < lastvisplane) { return(check); } if(lastvisplane-visplanes == MAXVISPLANES) { I_Error("R_FindPlane: no more visplanes"); } lastvisplane++; check->height = height; check->picnum = picnum; check->lightlevel = lightlevel; check->special = special; check->minx = SCREENWIDTH; check->maxx = -1; memset(check->top, 0xff, sizeof(check->top)); return(check);}//==========================================================================//// R_CheckPlane////==========================================================================visplane_t *R_CheckPlane(visplane_t *pl, int start, int stop){ int intrl, intrh; int unionl, unionh; int x; if(start < pl->minx) { intrl = pl->minx; unionl = start; } else { unionl = pl->minx; intrl = start; } if(stop > pl->maxx) { intrh = pl->maxx; unionh = stop; } else { unionh = pl->maxx; intrh = stop; } for(x = intrl; x <= intrh; x++) { if(pl->top[x] != 0xff) { break; } } if(x > intrh) { pl->minx = unionl; pl->maxx = unionh; return pl; // use the same visplane } // Make a new visplane lastvisplane->height = pl->height; lastvisplane->picnum = pl->picnum; lastvisplane->lightlevel = pl->lightlevel; lastvisplane->special = pl->special; pl = lastvisplane++; pl->minx = start; pl->maxx = stop; memset(pl->top, 0xff, sizeof(pl->top)); return pl;}//==========================================================================//// R_MakeSpans////==========================================================================void R_MakeSpans(int x, int t1, int b1, int t2, int b2){ while(t1 < t2 && t1 <= b1) { R_MapPlane(t1, spanstart[t1], x-1); t1++; } while(b1 > b2 && b1 >= t1) { R_MapPlane(b1, spanstart[b1], x-1); b1--; } while(t2 < t1 && t2 <= b2) { spanstart[t2] = x; t2++; } while(b2 > b1 && b2 >= t2) { spanstart[b2] = x; b2--; }}//==========================================================================//// R_DrawPlanes////==========================================================================#define SKYTEXTUREMIDSHIFTED 200void R_DrawPlanes(void){ visplane_t *pl; int light; int x, stop; int angle; byte *tempSource; byte *source; byte *source2; byte *dest; int count; int offset; int skyTexture; int offset2; int skyTexture2; int scrollOffset; extern byte *ylookup[MAXHEIGHT]; extern int columnofs[MAXWIDTH];#ifdef RANGECHECK if(ds_p-drawsegs > MAXDRAWSEGS) { I_Error("R_DrawPlanes: drawsegs overflow (%i)", ds_p-drawsegs); } if(lastvisplane-visplanes > MAXVISPLANES) { I_Error("R_DrawPlanes: visplane overflow (%i)", lastvisplane-visplanes); } if(lastopening-openings > MAXOPENINGS) { I_Error("R_DrawPlanes: opening overflow (%i)", lastopening-openings); }#endif for(pl = visplanes; pl < lastvisplane; pl++) { if(pl->minx > pl->maxx) { continue; } if(pl->picnum == skyflatnum) { // Sky flat if(DoubleSky) { // Render 2 layers, sky 1 in front offset = Sky1ColumnOffset>>16; skyTexture = texturetranslation[Sky1Texture]; offset2 = Sky2ColumnOffset>>16; skyTexture2 = texturetranslation[Sky2Texture]; for(x = pl->minx; x <= pl->maxx; x++) { dc_yl = pl->top[x]; dc_yh = pl->bottom[x]; if(dc_yl <= dc_yh) { count = dc_yh-dc_yl; if(count < 0) { return; } angle = (viewangle+xtoviewangle[x]) >>ANGLETOSKYSHIFT; source = R_GetColumn(skyTexture, angle+offset) +SKYTEXTUREMIDSHIFTED+(dc_yl-centery); source2 = R_GetColumn(skyTexture2, angle+offset2) +SKYTEXTUREMIDSHIFTED+(dc_yl-centery); dest = ylookup[dc_yl]+columnofs[x]; do { if(*source) { *dest = *source++; source2++; } else { *dest = *source2++; source++; } dest += SCREENWIDTH; } while(count--); } } continue; // Next visplane } else { // Render single layer if(pl->special == 200) { // Use sky 2 offset = Sky2ColumnOffset>>16; skyTexture = texturetranslation[Sky2Texture]; } else { // Use sky 1 offset = Sky1ColumnOffset>>16; skyTexture = texturetranslation[Sky1Texture]; } for(x = pl->minx; x <= pl->maxx; x++) { dc_yl = pl->top[x]; dc_yh = pl->bottom[x]; if(dc_yl <= dc_yh) { count = dc_yh-dc_yl; if(count < 0) { return; } angle = (viewangle+xtoviewangle[x]) >>ANGLETOSKYSHIFT; source = R_GetColumn(skyTexture, angle+offset) +SKYTEXTUREMIDSHIFTED+(dc_yl-centery); dest = ylookup[dc_yl]+columnofs[x]; do { *dest = *source++; dest += SCREENWIDTH; } while(count--); } } continue; // Next visplane } } // Regular flat tempSource = W_CacheLumpNum(firstflat+ flattranslation[pl->picnum], PU_STATIC); scrollOffset = leveltime>>1&63; switch(pl->special) { // Handle scrolling flats case 201: case 202: case 203: // Scroll_North_xxx ds_source = tempSource+((scrollOffset <<(pl->special-201)&63)<<6); break; case 204: case 205: case 206: // Scroll_East_xxx ds_source = tempSource+((63-scrollOffset) <<(pl->special-204)&63); break; case 207: case 208: case 209: // Scroll_South_xxx ds_source = tempSource+(((63-scrollOffset) <<(pl->special-207)&63)<<6); break; case 210: case 211: case 212: // Scroll_West_xxx ds_source = tempSource+(scrollOffset <<(pl->special-210)&63); break; case 213: case 214: case 215: // Scroll_NorthWest_xxx ds_source = tempSource+(scrollOffset <<(pl->special-213)&63)+((scrollOffset <<(pl->special-213)&63)<<6); break; case 216: case 217: case 218: // Scroll_NorthEast_xxx ds_source = tempSource+((63-scrollOffset) <<(pl->special-216)&63)+((scrollOffset <<(pl->special-216)&63)<<6); break; case 219: case 220: case 221: // Scroll_SouthEast_xxx ds_source = tempSource+((63-scrollOffset) <<(pl->special-219)&63)+(((63-scrollOffset) <<(pl->special-219)&63)<<6); break; case 222: case 223: case 224: // Scroll_SouthWest_xxx ds_source = tempSource+(scrollOffset <<(pl->special-222)&63)+(((63-scrollOffset) <<(pl->special-222)&63)<<6); break; default: ds_source = tempSource; break; } planeheight = abs(pl->height-viewz); light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight; if(light >= LIGHTLEVELS) { light = LIGHTLEVELS-1; } if(light < 0) { light = 0; } planezlight = zlight[light]; pl->top[pl->maxx+1] = 0xff; pl->top[pl->minx-1] = 0xff; stop = pl->maxx+1; for(x = pl->minx; x <= stop; x++) { R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); } Z_ChangeTag(tempSource, PU_CACHE); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -