diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index aa2f803be3fe8070e10e340d00f3ff9122ac4be7..db6ed72285eff52cb18f458c837054c7525be311 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2789,7 +2789,7 @@ static void HWR_LinkDrawHackFinish(void) linkdrawcount = 0; } -static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) +static void HWR_DrawDropShadow(mobj_t *thing, gl_vissprite_t *spr, fixed_t scale) { patch_t *gpatch; FOutVector shadowVerts[4]; @@ -2807,7 +2807,6 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) UINT16 alpha; fixed_t floordiff; fixed_t groundz; - fixed_t slopez; pslope_t *groundslope; // uncapped/interpolation @@ -2848,7 +2847,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) if (alpha >= 255) return; alpha = 255 - alpha; - gpatch = (patch_t *)W_CachePatchName("DSHADOW", PU_SPRITE); + gpatch = (cv_shadow.value == 2) ? spr->gpatch : (patch_t *)W_CachePatchName("DSHADOW", PU_SPRITE); if (!(gpatch && ((GLPatch_t *)gpatch->hardware)->mipmap->format)) return; HWR_GetPatch(gpatch); @@ -2874,19 +2873,62 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) shadowVerts[1].z = shadowVerts[2].z = fy - offset; shadowVerts[0].z = shadowVerts[3].z = fy + offset; + if (cv_shadow.value == 2) + { + shadowVerts[0].x = shadowVerts[3].x = spr->x1; + shadowVerts[2].x = shadowVerts[1].x = spr->x2; + shadowVerts[0].z = shadowVerts[3].z = spr->z1; + shadowVerts[2].z = shadowVerts[1].z = spr->z2; + + // Always a pixel above the floor, perfectly flat. + for (i = 0; i < 4; i++) + { + if (groundslope) + { + fixed_t slopez = P_GetSlopeZAt(groundslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); + shadowVerts[i].y = FIXED_TO_FLOAT(slopez)/2 + flip * 0.05f; + } + else + { + shadowVerts[i].y = FIXED_TO_FLOAT(groundz)/2 + flip * 0.05f; + } + } + + if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) + { + + // Now transform the TOP vertices along the floor in the direction of the camera + shadowVerts[3].x = spr->x1 + (gpatch->height + fscale + offset) * gl_viewcos; + shadowVerts[2].x = spr->x2 + (gpatch->height + fscale + offset) * gl_viewcos; + shadowVerts[3].z = spr->z1 + (gpatch->height + fscale + offset) * gl_viewsin; + shadowVerts[2].z = spr->z2 + (gpatch->height + fscale + offset) * gl_viewsin; + } + else + { + // Now transform the TOP vertices along the floor in the direction of the camera + shadowVerts[3].x = spr->x1 + (gpatch->height + offset) * gl_viewcos; + shadowVerts[2].x = spr->x2 + (gpatch->height + offset) * gl_viewcos; + shadowVerts[3].z = spr->z1 + (gpatch->height + offset) * gl_viewsin; + shadowVerts[2].z = spr->z2 + (gpatch->height + offset) * gl_viewsin; + } + } + for (i = 0; i < 4; i++) { float oldx = shadowVerts[i].x; float oldy = shadowVerts[i].z; - shadowVerts[i].x = fx + ((oldx - fx) * gl_viewcos) - ((oldy - fy) * gl_viewsin); - shadowVerts[i].z = fy + ((oldx - fx) * gl_viewsin) + ((oldy - fy) * gl_viewcos); + if(!(cv_shadow.value == 2)) + { + shadowVerts[i].x = fx + ((oldx - fx) * gl_viewcos) - ((oldy - fy) * gl_viewsin); + shadowVerts[i].z = fy + ((oldx - fx) * gl_viewsin) + ((oldy - fy) * gl_viewcos); + } } if (groundslope) { for (i = 0; i < 4; i++) { - slopez = P_GetSlopeZAt(groundslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); + fixed_t slopez = P_GetSlopeZAt(groundslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + flip * 0.05f; } } @@ -2902,6 +2944,21 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) shadowVerts[3].t = shadowVerts[2].t = 0; shadowVerts[0].t = shadowVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t; + + if (cv_shadow.value == 2) + { + if (spr->flip) + { + shadowVerts[0].s = shadowVerts[3].s = ((GLPatch_t *)gpatch->hardware)->max_s; + shadowVerts[2].s = shadowVerts[1].s = 0; + } + else + { + shadowVerts[0].s = shadowVerts[3].s = 0; + shadowVerts[2].s = shadowVerts[1].s = ((GLPatch_t *)gpatch->hardware)->max_s; + } + } + if (!(thing->renderflags & RF_NOCOLORMAPS)) { if (thing->subsector->sector->numlights) @@ -2925,6 +2982,13 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) blendmode |= PF_ColorMapped; } + if (cv_shadow.value == 2) + { + sSurf.PolyColor.s.red = 0x00; + sSurf.PolyColor.s.blue = 0x00; + sSurf.PolyColor.s.green = 0x00; + } + HWR_ProcessPolygon(&sSurf, shadowVerts, 4, blendmode, shader, false); } @@ -4174,7 +4238,7 @@ static void HWR_DrawSprites(void) { if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value && !skipshadow) { - HWR_DrawDropShadow(spr->mobj, spr->mobj->shadowscale); + HWR_DrawDropShadow(spr->mobj, spr, spr->mobj->shadowscale); } if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer) @@ -4184,10 +4248,11 @@ static void HWR_DrawSprites(void) // the linkdraw sprite because the linkdraw sprite does not modify the z-buffer. // The !skipshadow check is there in case there are multiple linkdraw sprites connected // to the same tracer, so the tracer's shadow only gets drawn once. - if (cv_shadow.value && !skipshadow && spr->dispoffset < 0 && spr->mobj->tracer->shadowscale) + if (cv_shadow.value && !skipshadow && (spr->dispoffset < 0 || cv_shadow.value == 2) && spr->mobj->tracer->shadowscale) { - HWR_DrawDropShadow(spr->mobj->tracer, spr->mobj->tracer->shadowscale); - skipshadow = true; + HWR_DrawDropShadow(spr->mobj->tracer, spr, spr->mobj->tracer->shadowscale); + if (cv_shadow.value == 1) + skipshadow = true; // The next sprite in this loop should be either another linkdraw sprite or the tracer. // When the tracer is inevitably encountered, skipshadow will cause it's shadow // to get skipped and skipshadow will get set to false by the 'else' clause below. diff --git a/src/r_main.c b/src/r_main.c index 2d19c7303c1d579ebcde838bc4a3214ce435ad15..819dcce761109e30bb0f5dcb3dc0c1cd54032557 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -134,6 +134,7 @@ static CV_PossibleValue_t fov_cons_t[] = {{MINFOV, "MIN"}, {MAXFOV, "MAX"}, {0, static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}}; +static CV_PossibleValue_t shadow_cons_t[] = {{0, "Off"}, {1, "Drop"}, {2, "Sprite"}}; static void R_SetFov(fixed_t playerfov); @@ -151,7 +152,7 @@ consvar_t cv_chasecam2 = CVAR_INIT ("chasecam2", "On", NULL, CV_CALL, CV_OnOff, consvar_t cv_flipcam = CVAR_INIT ("flipcam", "No", NULL, CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange); consvar_t cv_flipcam2 = CVAR_INIT ("flipcam2", "No", NULL, CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange); -consvar_t cv_shadow = CVAR_INIT ("shadow", "On", NULL, CV_SAVE, CV_OnOff, NULL); +consvar_t cv_shadow = CVAR_INIT ("shadow", "Drop", NULL, CV_SAVE, shadow_cons_t, NULL); consvar_t cv_skybox = CVAR_INIT ("skybox", "On", NULL, CV_SAVE, CV_OnOff, NULL); consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", NULL, CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", NULL, CV_CALL|CV_ALLOWLUA, CV_YesNo, R_SetViewSize); diff --git a/src/r_things.c b/src/r_things.c index e0ed15706184f45f5679454f3c6962fe89c23cd0..fa2c54e6e9aa2fa655e67d7c224567690a45dc48 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1556,7 +1556,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - patch = W_CachePatchName("DSHADOW", PU_SPRITE); + patch = (cv_shadow.value == 2) ? vis->patch : W_CachePatchName("DSHADOW", PU_SPRITE); xscale = FixedDiv(projection, tz); yscale = FixedDiv(projectiony, tz); shadowxscale = FixedMul(interp.radius*2, scalemul); @@ -1593,7 +1593,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->gy = interp.y; shadow->gzt = (isflipped ? shadow->pzt : shadow->pz) + patch->height * shadowyscale / 2; shadow->gz = shadow->gzt - patch->height * shadowyscale; - shadow->texturemid = FixedMul(interp.scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); + shadow->texturemid = FixedMul(interp.scale, FixedDiv(shadow->gzt - viewz, shadowyscale * (cv_shadow.value == 2 ? 1.15 : 1))); if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale); shadow->scalestep = 0;