📄 r_things.c
字号:
//Fab:02-08-98: 'skin' override spritedef currently used for skin if (thing->skin) sprdef = &((skin_t *)thing->skin)->spritedef; else sprdef = &sprites[thing->sprite];#ifdef RANGECHECK if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes ) I_Error ("R_ProjectSprite: invalid sprite frame %i : %i for %s", thing->sprite, thing->frame, sprnames[thing->sprite]);#endif sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];#ifdef PARANOIA //heretic hack if( !sprframe ) I_Error("sprframes NULL for sprite %d\n", thing->sprite);#endif if (sprframe->rotate) { // choose a different rotation based on player view ang = R_PointToAngle (thing->x, thing->y); rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29; //Fab: lumpid is the index for spritewidth,spriteoffset... tables lump = sprframe->lumpid[rot]; flip = (boolean)sprframe->flip[rot]; } else { // use single rotation for all views rot = 0; //Fab: for vis->patch below lump = sprframe->lumpid[0]; //Fab: see note above flip = (boolean)sprframe->flip[0]; } // calculate edges of the shape tx -= spriteoffset[lump]; x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS; // off the right side? if (x1 > viewwidth) return; tx += spritewidth[lump]; x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1; // off the left side if (x2 < 0) return; //SoM: 3/17/2000: Disreguard sprites that are out of view.. gzt = thing->z + spritetopoffset[lump]; if(thing->subsector->sector->numlights) { int lightnum; light = R_GetPlaneLight(thing->subsector->sector, gzt, false); if(thing->subsector->sector->lightlist[light].caster && thing->subsector->sector->lightlist[light].caster->flags & FF_FOG) lightnum = (thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); else lightnum = (thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT)+extralight; if (lightnum < 0) spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS) spritelights = scalelight[LIGHTLEVELS-1]; else spritelights = scalelight[lightnum]; } heightsec = thing->subsector->sector->heightsec; if (heightsec != -1) // only clip things which are in special sectors { int phs = viewplayer->mo->subsector->sector->heightsec; if (phs != -1 && viewz < sectors[phs].floorheight ? thing->z >= sectors[heightsec].floorheight : gzt < sectors[heightsec].floorheight) return; if (phs != -1 && viewz > sectors[phs].ceilingheight ? gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight : thing->z >= sectors[heightsec].ceilingheight) return; } // store information in a vissprite vis = R_NewVisSprite (); vis->heightsec = heightsec; //SoM: 3/17/2000 vis->mobjflags = thing->flags; vis->scale = yscale; //<<detailshift; vis->gx = thing->x; vis->gy = thing->y; vis->gz = gzt - spriteheight[lump]; vis->gzt = gzt; vis->thingheight = thing->height; vis->texturemid = vis->gzt - viewz; // foot clipping if(thing->flags2&MF2_FEETARECLIPPED && thing->z <= thing->subsector->sector->floorheight) vis->texturemid -= 10*FRACUNIT; vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; vis->xscale = xscale; //SoM: 4/17/2000 vis->sector = thing->subsector->sector; vis->szt = (centeryfrac - FixedMul(vis->gzt - viewz, yscale)) >> FRACBITS; vis->sz = (centeryfrac - FixedMul(vis->gz - viewz, yscale)) >> FRACBITS; vis->cut = false; if(thing->subsector->sector->numlights) vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap; else vis->extra_colormap = thing->subsector->sector->extra_colormap; iscale = FixedDiv (FRACUNIT, xscale); if (flip) { vis->startfrac = spritewidth[lump]-1; vis->xiscale = -iscale; } else { vis->startfrac = 0; vis->xiscale = iscale; } if (vis->x1 > x1) vis->startfrac += vis->xiscale*(vis->x1-x1); //Fab: lumppat is the lump number of the patch to use, this is different // than lumpid for sprites-in-pwad : the graphics are patched vis->patch = sprframe->lumppat[rot];//// determine the colormap (lightlevel & special effects)// vis->transmap = NULL; // specific translucency if (thing->frame & FF_SMOKESHADE) // not realy a colormap ... see R_DrawVisSprite vis->colormap = VIS_SMOKESHADE; else { if (thing->frame & FF_TRANSMASK) vis->transmap = (thing->frame & FF_TRANSMASK) - 0x10000 + transtables; else if (thing->flags & MF_SHADOW) // actually only the player should use this (temporary invisibility) // because now the translucency is set through FF_TRANSMASK vis->transmap = ((tr_transhi-1)<<FF_TRANSSHIFT) + transtables; if (fixedcolormap ) { // fixed map : all the screen has the same colormap // eg: negative effect of invulnerability vis->colormap = fixedcolormap; } else if (((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK)) || (thing->flags & MF_SHADOW)) && (!vis->extra_colormap || !vis->extra_colormap->fog)) { // full bright : goggles vis->colormap = colormaps; } else { // diminished light index = xscale>>(LIGHTSCALESHIFT-detailshift); if (index >= MAXLIGHTSCALE) index = MAXLIGHTSCALE-1; vis->colormap = spritelights[index]; } } if(thing->subsector->sector->numlights) R_SplitSprite(vis, thing);}//// R_AddSprites// During BSP traversal, this adds sprites by sector.//void R_AddSprites (sector_t* sec, int lightlevel){ mobj_t* thing; int lightnum; if (rendermode != render_soft) return; // BSP is traversed by subsector. // A sector might have been split into several // subsectors during BSP building. // Thus we check whether its already added. if (sec->validcount == validcount) return; // Well, now it will be done. sec->validcount = validcount; if(!sec->numlights) { if(sec->heightsec == -1) lightlevel = sec->lightlevel; lightnum = (lightlevel >> LIGHTSEGSHIFT)+extralight; if (lightnum < 0) spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS) spritelights = scalelight[LIGHTLEVELS-1]; else spritelights = scalelight[lightnum]; } // Handle all things in sector. for (thing = sec->thinglist ; thing ; thing = thing->snext) if((thing->flags2 & MF2_DONTDRAW)==0) R_ProjectSprite (thing);}//// R_DrawPSprite//void R_DrawPSprite (pspdef_t* psp){ fixed_t tx; int x1; int x2; spritedef_t* sprdef; spriteframe_t* sprframe; int lump; boolean flip; vissprite_t* vis; vissprite_t avis; // decide which patch to use#ifdef RANGECHECK if ( (unsigned)psp->state->sprite >= numsprites) I_Error ("R_ProjectSprite: invalid sprite number %i ", psp->state->sprite);#endif sprdef = &sprites[psp->state->sprite];#ifdef RANGECHECK if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes) I_Error ("R_ProjectSprite: invalid sprite frame %i : %i for %s", psp->state->sprite, psp->state->frame, sprnames[psp->state->sprite]);#endif sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];#ifdef PARANOIA //Fab:debug if (sprframe==NULL) I_Error("sprframes NULL for state %d\n", psp->state - states);#endif //Fab: see the notes in R_ProjectSprite about lumpid,lumppat lump = sprframe->lumpid[0]; flip = (boolean)sprframe->flip[0]; // calculate edges of the shape //added:08-01-98:replaced mul by shift tx = psp->sx-((BASEVIDWIDTH/2)<<FRACBITS); //*FRACUNITS); //added:02-02-98:spriteoffset should be abs coords for psprites, based on // 320x200 tx -= spriteoffset[lump]; x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS; // off the right side if (x1 > viewwidth) return; tx += spritewidth[lump]; x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1; // off the left side if (x2 < 0) return; // store information in a vissprite vis = &avis; vis->mobjflags = 0; if(cv_splitscreen.value) vis->texturemid = (120<<(FRACBITS))+FRACUNIT/2-(psp->sy-spritetopoffset[lump]); else vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-spritetopoffset[lump]); vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; vis->scale = pspriteyscale; //<<detailshift; if (flip) { vis->xiscale = -pspriteiscale; vis->startfrac = spritewidth[lump]-1; } else { vis->xiscale = pspriteiscale; vis->startfrac = 0; } if (vis->x1 > x1) vis->startfrac += vis->xiscale*(vis->x1-x1); //Fab: see above for more about lumpid,lumppat vis->patch = sprframe->lumppat[0]; vis->transmap = NULL; if (viewplayer->mo->flags & MF_SHADOW) // invisibility effect { vis->colormap = NULL; // use translucency // in Doom2, it used to switch between invis/opaque the last seconds // now it switch between invis/less invis the last seconds if (viewplayer->powers[pw_invisibility] > 4*TICRATE || viewplayer->powers[pw_invisibility] & 8) vis->transmap = ((tr_transhi-1)<<FF_TRANSSHIFT) + transtables; else vis->transmap = ((tr_transmed-1)<<FF_TRANSSHIFT) + transtables; } else if (fixedcolormap) { // fixed color vis->colormap = fixedcolormap; } else if (psp->state->frame & FF_FULLBRIGHT) { // full bright vis->colormap = colormaps; } else { // local light vis->colormap = spritelights[MAXLIGHTSCALE-1]; } if(viewplayer->mo->subsector->sector->numlights) { int lightnum; int light = R_GetPlaneLight(viewplayer->mo->subsector->sector, viewplayer->mo->z + (41 << FRACBITS), false); vis->extra_colormap = viewplayer->mo->subsector->sector->lightlist[light].extra_colormap; lightnum = (viewplayer->mo->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT)+extralight; if (lightnum < 0) spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS) spritelights = scalelight[LIGHTLEVELS-1]; else spritelights = scalelight[lightnum]; vis->colormap = spritelights[MAXLIGHTSCALE-1]; } else vis->extra_colormap = viewplayer->mo->subsector->sector->extra_colormap; R_DrawVisSprite (vis, vis->x1, vis->x2);}//// R_DrawPlayerSprites//void R_DrawPlayerSprites (void){ int i = 0; int lightnum; int light = 0; pspdef_t* psp; int kikhak; if (rendermode != render_soft) return; // get light level if(viewplayer->mo->subsector->sector->numlights) { light = R_GetPlaneLight(viewplayer->mo->subsector->sector, viewplayer->mo->z + viewplayer->mo->info->height, false); lightnum = (viewplayer->mo->subsector->sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT) + extralight; } else lightnum = (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT) + extralight; if (lightnum < 0) spritelights = scalelight[0]; else if (lightnum >= LIGHTLEVELS) spritelights = scalelight[LIGHTLEVELS-1]; else spritelights = scalelight[lightnum]; // clip to screen bounds mfloorclip = screenheightarray; mceilingclip = negonearray; //added:06-02-98: quickie fix for psprite pos because of freelook kikhak = centery; centery = centerypsp; //for R_DrawColumn centeryfrac = centery<<FRACBITS; //for R_DrawVisSprite // add all active psprites for (i=0, psp=viewplayer->psprites; i<NUMPSPRITES; i++,psp++) { if (psp->state) R_DrawPSprite (psp); } //added:06-02-98: oooo dirty boy centery = kikhak; centeryfrac = centery<<FRACBITS;}//// R_SortVisSprites//vissprite_t vsprsortedhead;void R_SortVisSprites (void){ int i; int count; vissprite_t* ds; vissprite_t* best=NULL; //shut up compiler vissprite_t unsorted; fixed_t bestscale; //count = vissprite_p - vissprites; count = vs_end - vs_start; unsorted.next = unsorted.prev = &unsorted; if (!count) return; //for (ds=vissprites ; ds<vissprite_p ; ds++) for(ds=vs_start; ds < vs_end; ds++) { ds->next = ds+1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -