diff --git a/src/r_things.cpp b/src/r_things.cpp index dae30ae1c..276cbd8b7 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -424,13 +424,18 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop { R_CheckOffscreenBuffer(RenderTarget->GetWidth(), RenderTarget->GetHeight(), !!(flags & DVF_SPANSONLY)); } + if (spr->bInMirror) + { + flags |= DVF_MIRRORED; + } // Render the voxel, either directly to the screen or offscreen. - R_DrawVoxel(spr->gx, spr->gy, spr->gz, spr->angle, spr->xscale, spr->yscale, spr->voxel, spr->Style.colormap, cliptop, clipbot, + R_DrawVoxel(spr->vx, spr->vy, spr->vz, spr->vang, spr->gx, spr->gy, spr->gz, spr->angle, + spr->xscale, spr->yscale, spr->voxel, spr->Style.colormap, cliptop, clipbot, minslabz, maxslabz, flags); // Blend the voxel, if that's what we need to do. - if (flags != 0) + if ((flags & ~DVF_MIRRORED) != 0) { for (int x = 0; x < viewwidth; ++x) { @@ -760,10 +765,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->angle -= angle_t(ang * (4294967296.f / 360)); } - // These are irrelevant for voxels. - vis->texturemid = 0x1CEDBEEF; - vis->startfrac = 0x1CEDBEEF; - vis->xiscale = 0x1CEDBEEF; + vis->vx = viewx; + vis->vy = viewy; + vis->vz = viewz; + vis->vang = viewangle; } // killough 3/27/98: save sector for special clipping later @@ -787,6 +792,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->fakefloor = fakefloor; vis->fakeceiling = fakeceiling; vis->ColormapNum = 0; + vis->bInMirror = MirrorFlags & RF_XFLIP; if (voxel != NULL) { @@ -1897,6 +1903,16 @@ void R_DrawSprite (vissprite_t *spr) return; } } + // Add everything outside the left and right edges to the clipping array + // for R_DrawVisVoxel(). + if (x1 > 0) + { + clearbufshort(cliptop, x1, viewheight); + } + if (x2 < viewwidth - 1) + { + clearbufshort(cliptop + x2 + 1, viewwidth - x2 - 1, viewheight); + } int minvoxely = spr->gzt <= hzt ? 0 : (spr->gzt - hzt) / spr->yscale; int maxvoxely = spr->gzb > hzb ? INT_MAX : (spr->gzt - hzb) / spr->yscale; R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot); @@ -2228,7 +2244,8 @@ void R_DrawParticle (vissprite_t *vis) extern fixed_t baseyaspectmul; -void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang, +void R_DrawVoxel(fixed_t globalposx, fixed_t globalposy, fixed_t globalposz, angle_t viewang, + fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang, fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj, lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags) { @@ -2244,12 +2261,14 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran const int nytooclose = centerxwide * 2100, nytoofar = 32768*32768 - 1048576; const int xdimenscale = Scale(centerxwide, yaspectmul, 160); - const fixed_t globalposx = viewx >> 12; - const fixed_t globalposy = -viewy >> 12; - const fixed_t globalposz = -viewz >> 8; const double centerxwide_f = centerxwide; const double centerxwidebig_f = centerxwide_f * 65536*65536*8; + // Convert to Build's coordinate system. + globalposx = globalposx >> 12; + globalposy = -globalposy >> 12; + globalposz = -globalposz >> 8; + dasprx = dasprx >> 12; daspry = -daspry >> 12; dasprz = -dasprz >> 8; @@ -2259,20 +2278,19 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran daxscale = daxscale / (0xC000 >> 6); dayscale = dayscale / (0xC000 >> 6); - cosang = viewcos >> 2; - sinang = -viewsin >> 2; + cosang = finecosine[viewang >> ANGLETOFINESHIFT] >> 2; + sinang = -finesine[viewang >> ANGLETOFINESHIFT] >> 2; sprcosang = finecosine[dasprang >> ANGLETOFINESHIFT] >> 2; sprsinang = -finesine[dasprang >> ANGLETOFINESHIFT] >> 2; R_SetupDrawSlab(colormap); // Select mip level - i = abs(DMulScale8(dasprx - globalposx, viewcos, daspry - globalposy, -viewsin)); + i = abs(DMulScale6(dasprx - globalposx, cosang, daspry - globalposy, sinang)); i = DivScale6(i, MIN(daxscale, dayscale)); j = FocalLengthX >> 3; - for (k = 0; k < voxobj->NumMips; ++k) + for (k = 0; i >= j && k < voxobj->NumMips; ++k) { - if (i < j) { break; } i >>= 1; } if (k >= voxobj->NumMips) k = voxobj->NumMips - 1; @@ -2404,6 +2422,13 @@ void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t daspran if (rx > viewwidth) rx = viewwidth; if (rx <= lx) continue; + if (flags & DVF_MIRRORED) + { + int t = viewwidth - lx; + lx = viewwidth - rx; + rx = t; + } + fixed_t l1 = xs_RoundToInt(centerxwidebig_f / (ny - yoff)); fixed_t l2 = xs_RoundToInt(centerxwidebig_f / (ny + yoff)); for (; voxptr < voxend; voxptr = (kvxslab_t *)((BYTE *)voxptr + voxptr->zleng + 3)) diff --git a/src/r_things.h b/src/r_things.h index 92428b639..14ed8afc9 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -35,25 +35,36 @@ struct vissprite_t fixed_t gx, gy, gz; // origin in world coordinates angle_t angle; fixed_t gzb, gzt; // global bottom / top for silhouette clipping - fixed_t startfrac; // horizontal position of x1 fixed_t xscale, yscale; - fixed_t xiscale; // negative if flipped fixed_t depth; fixed_t idepth; // 1/z - fixed_t texturemid; DWORD FillColor; + fixed_t floorclip; + union + { + // Used by regular sprites + struct + { + FTexture *pic; + fixed_t texturemid; + fixed_t startfrac; // horizontal position of x1 + fixed_t xiscale; // negative if flipped + }; + // Used by voxels + struct + { + struct FVoxel *voxel; + fixed_t vx, vy, vz; // view origin + angle_t vang; // view angle + }; + }; sector_t *heightsec; // killough 3/27/98: height sector for underwater/fake ceiling sector_t *sector; // [RH] sector this sprite is in F3DFloor *fakefloor; F3DFloor *fakeceiling; - fixed_t floorclip; - union - { - FTexture *pic; - struct FVoxel *voxel; - }; BYTE bIsVoxel:1; // [RH] Use voxel instead of pic BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg + BYTE bInMirror:1; // [RH] Sprite is "inside" a mirror BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on BYTE ColormapNum; // Which colormap is rendered (needed for shaded drawer) short renderflags; @@ -102,9 +113,10 @@ void R_DrawRemainingPlayerSprites (); void R_CheckOffscreenBuffer(int width, int height, bool spansonly); -enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2 }; +enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 }; -void R_DrawVoxel(fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang, +void R_DrawVoxel(fixed_t viewx, fixed_t viewy, fixed_t viewz, angle_t viewangle, + fixed_t dasprx, fixed_t daspry, fixed_t dasprz, angle_t dasprang, fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj, lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags);