From 8bc58807aaba8668670aaf4ba25d3b932de041cc Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 31 Dec 2019 11:21:46 -0600 Subject: [PATCH 1/7] Software FOV ported from kart also fixes high software FOVs having buggy walls --- src/hardware/hw_clip.c | 3 ++- src/hardware/hw_main.c | 24 ++++++------------- src/hardware/hw_main.h | 3 +-- src/hardware/r_opengl/r_opengl.c | 40 ++++++++++++++------------------ src/m_menu.c | 2 +- src/p_user.c | 9 +------ src/r_main.c | 35 +++++++++++++++++++++------- src/r_main.h | 1 + 8 files changed, 57 insertions(+), 60 deletions(-) diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index 4bdc753ec..a63527083 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -72,6 +72,7 @@ #include "../v_video.h" #include "hw_clip.h" #include "hw_glob.h" +#include "../r_main.h" #include "../r_state.h" #include "../tables.h" #include "r_opengl/r_opengl.h" @@ -328,7 +329,7 @@ angle_t gld_FrustumAngle(void) // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function - float render_fov = FIXED_TO_FLOAT(cv_grfov.value); + float render_fov = FIXED_TO_FLOAT(cv_fov.value); float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right? float render_multiplier = 64.0f / render_fovratio / RMUL; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6ef48f222..4ebc168cc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5896,7 +5896,7 @@ static void HWR_DrawSkyBackground(player_t *player) if (cv_grskydome.value) { FTransform dometransform; - const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); + const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); postimg_t *type; if (splitscreen && player == &players[secondarydisplayplayer]) @@ -6074,7 +6074,7 @@ void HWR_SetViewSize(void) // ========================================================================== void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) { - const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); + const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); postimg_t *type; if (splitscreen && player == &players[secondarydisplayplayer]) @@ -6200,7 +6200,7 @@ if (0) viewangle = localaiming2; // Handle stuff when you are looking farther up or down. - if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) + if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); @@ -6278,7 +6278,7 @@ if (0) // ========================================================================== void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) { - const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); + const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); postimg_t *type; const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on @@ -6420,7 +6420,7 @@ if (0) viewangle = localaiming2; // Handle stuff when you are looking farther up or down. - if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) + if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); @@ -6549,9 +6549,7 @@ static void CV_grmodellighting_OnChange(void); static void CV_grfiltermode_OnChange(void); static void CV_granisotropic_OnChange(void); static void CV_grfogdensity_OnChange(void); -static void CV_grfov_OnChange(void); -static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, {HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"}, @@ -6560,7 +6558,7 @@ static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA {0, NULL}}; CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; -consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6580,7 +6578,6 @@ consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -6616,17 +6613,10 @@ static void CV_granisotropic_OnChange(void) HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); } -static void CV_grfov_OnChange(void) -{ - if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT) - CV_Set(&cv_grfov, cv_grfov.defaultvalue); -} - //added by Hurdler: console varibale that are saved void HWR_AddCommands(void) { - CV_RegisterVar(&cv_grfovchange); - CV_RegisterVar(&cv_grfov); + CV_RegisterVar(&cv_fovchange); CV_RegisterVar(&cv_grfogdensity); CV_RegisterVar(&cv_grfogcolor); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index e46aa9801..1314577cc 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -83,7 +83,6 @@ extern consvar_t cv_grstaticlighting; extern consvar_t cv_grcoronas; extern consvar_t cv_grcoronasize; #endif -extern consvar_t cv_grfov; extern consvar_t cv_grmodels; extern consvar_t cv_grmodelinterpolation; extern consvar_t cv_grmodellighting; @@ -94,7 +93,7 @@ extern consvar_t cv_grsoftwarefog; extern consvar_t cv_grfiltermode; extern consvar_t cv_granisotropicmode; extern consvar_t cv_grcorrecttricks; -extern consvar_t cv_grfovchange; +extern consvar_t cv_fovchange; extern consvar_t cv_grsolvetjoin; extern consvar_t cv_grspritebillboarding; extern consvar_t cv_grskydome; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 129bf5678..612d06c6d 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2224,11 +2224,11 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, EXPORT void HWRAPI(SetTransform) (FTransform *stransform) { static boolean special_splitscreen; + float used_fov; pglLoadIdentity(); if (stransform) { - boolean fovx90; - + used_fov = stransform->fovxangle; #ifdef USE_FTRANSFORM_MIRROR // mirroring from Kart if (stransform->mirror) @@ -2244,32 +2244,28 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f); pglTranslatef(-stransform->x, -stransform->z, -stransform->y); - pglMatrixMode(GL_PROJECTION); - pglLoadIdentity(); - fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f; - special_splitscreen = (stransform->splitscreen && fovx90); - if (special_splitscreen) - GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) - else - GLPerspective(stransform->fovxangle, ASPECT_RATIO); - pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) - pglMatrixMode(GL_MODELVIEW); + special_splitscreen = stransform->splitscreen; } else { + used_fov = fov; pglScalef(1.0f, 1.0f, -1.0f); - - pglMatrixMode(GL_PROJECTION); - pglLoadIdentity(); - if (special_splitscreen) - GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) - else - //Hurdler: is "fov" correct? - GLPerspective(fov, ASPECT_RATIO); - pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) - pglMatrixMode(GL_MODELVIEW); } + pglMatrixMode(GL_PROJECTION); + pglLoadIdentity(); + + if (special_splitscreen) + { + used_fov = atan(tan(used_fov*M_PI/360)*0.8)*360/M_PI; + GLPerspective(used_fov, 2*ASPECT_RATIO); + } + else + GLPerspective(used_fov, ASPECT_RATIO); + + pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) + pglMatrixMode(GL_MODELVIEW); + pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) } diff --git a/src/m_menu.c b/src/m_menu.c index 630f0c643..12624abb7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1311,7 +1311,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32}, {IT_HEADER, NULL, "General", NULL, 51}, - {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 63}, + {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 63}, {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73}, {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93}, diff --git a/src/p_user.c b/src/p_user.c index 20fbc99f4..a97e62052 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8648,7 +8648,7 @@ static void P_MovePlayer(player_t *player) } #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none && cv_grfovchange.value) + if (rendermode != render_soft && rendermode != render_none && cv_fovchange.value) { fixed_t speed; const fixed_t runnyspeed = 20*FRACUNIT; @@ -9884,13 +9884,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall { dist = camdist; - // x1.5 dist for splitscreen - if (splitscreen) - { - dist = FixedMul(dist, 3*FRACUNIT/2); - camheight = FixedMul(camheight, 3*FRACUNIT/2); - } - if (sign) // signpost camera has specific placement { camheight = mo->scale << 7; diff --git a/src/r_main.c b/src/r_main.c index 115db8cb5..8ee7858f9 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -57,6 +57,7 @@ INT32 centerx, centery; fixed_t centerxfrac, centeryfrac; fixed_t projection; fixed_t projectiony; // aspect ratio +fixed_t fovtan; // field of view // just for profiling purposes size_t framecount; @@ -106,10 +107,12 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = { {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, {0, "None"}, {0, NULL}}; +static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; 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 void Fov_OnChange(void); static void ChaseCam_OnChange(void); static void ChaseCam2_OnChange(void); static void FlipCam_OnChange(void); @@ -139,6 +142,7 @@ consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL, consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL}; // Okay, whoever said homremoval causes a performance hit should be shot. consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -182,6 +186,14 @@ void SplitScreen_OnChange(void) } } } +static void Fov_OnChange(void) +{ + // Shouldn't be needed with render parity? + //if ((netgame || multiplayer) && !cv_debug && cv_fov.value != 90*FRACUNIT) + // CV_Set(&cv_fov, cv_fov.defaultvalue); + + R_SetViewSize(); +} static void ChaseCam_OnChange(void) { @@ -446,8 +458,8 @@ static void R_InitTextureMapping(void) // // Calc focallength // so FIELDOFVIEW angles covers SCREENWIDTH. - focallength = FixedDiv(centerxfrac, - FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); + focallength = FixedDiv(projection, + FINETANGENT(FINEANGLES/4+FIELDOFVIEW/2)); #ifdef ESLOPE focallengthf = FIXED_TO_FLOAT(focallength); @@ -455,9 +467,9 @@ static void R_InitTextureMapping(void) for (i = 0; i < FINEANGLES/2; i++) { - if (FINETANGENT(i) > FRACUNIT*2) + if (FINETANGENT(i) > fovtan*2) t = -1; - else if (FINETANGENT(i) < -FRACUNIT*2) + else if (FINETANGENT(i) < -fovtan*2) t = viewwidth+1; else { @@ -561,6 +573,7 @@ void R_ExecuteSetViewSize(void) INT32 j; INT32 level; INT32 startmapl; + angle_t fov; setsizeneeded = false; @@ -583,9 +596,12 @@ void R_ExecuteSetViewSize(void) centerxfrac = centerx<> ANGLETOFINESHIFT); + if (splitscreen == 1) // Splitscreen FOV should be adjusted to maintain expected vertical view + fovtan = 17*fovtan/10; + + projection = projectiony = FixedDiv(centerxfrac, fovtan); R_InitViewBuffer(scaledviewwidth, viewheight); @@ -611,7 +627,7 @@ void R_ExecuteSetViewSize(void) for (i = 0; i < j; i++) { dy = ((i - viewheight*8)<>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS) +#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan) // recalc necessary stuff for mouseaiming // slopes are already calculated for the full possible view (which is 4*viewheight). @@ -1175,6 +1191,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist_nights); CV_RegisterVar(&cv_drawdist_precip); + CV_RegisterVar(&cv_fov); CV_RegisterVar(&cv_chasecam); CV_RegisterVar(&cv_chasecam2); diff --git a/src/r_main.h b/src/r_main.h index 58c23cd81..c1bb0861a 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -84,6 +84,7 @@ extern conscar_t cv_shadowoffs; #endif //#ifdef GLBADSHADOWS extern consvar_t cv_translucency; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; +extern consvar_t cv_fov; extern consvar_t cv_skybox; extern consvar_t cv_tailspickup; From c0380a30529cddce70e38fc19101e34aea24b208 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 27 Dec 2019 04:57:16 -0600 Subject: [PATCH 2/7] Make papersprite projection completely correct in software I heard properpaper had some weird crashes? I couldn't reproduce them no matter how hard I tried, but I added some bounds checking to this version too just in case. Gotta get other people's help to try to reproduce those. --- src/r_things.c | 106 ++++++++++++++++++++----------------------------- src/r_things.h | 3 ++ 2 files changed, 47 insertions(+), 62 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 2f01ac7f6..50f799d2c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -743,7 +743,8 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; -#ifdef RANGECHECK +//#ifdef RANGECHECK +#if 1 INT32 texturecolumn; #endif fixed_t frac; @@ -895,21 +896,34 @@ static void R_DrawVisSprite(vissprite_t *vis) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { -#ifdef RANGECHECK - - texturecolumn = frac>>FRACBITS; - - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); -#else - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); -#endif if (vis->scalestep) { + angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; + texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) >> FRACBITS; + + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + { + spryscale += vis->scalestep; + continue; + } + + if (vis->xiscale < 0) + texturecolumn = SHORT(patch->width) - 1 - texturecolumn; + sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); } + else + { + texturecolumn = frac>>FRACBITS; +#ifdef RANGECHECK + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); +#endif + } + + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + if (vis->cut & SC_VFLIP) R_DrawFlippedMaskedColumn(column, patch->height); else @@ -1073,8 +1087,6 @@ static void R_SplitSprite(vissprite_t *sprite) } } -//#define PROPERPAPER // This was reverted less than 7 hours before 2.2's release because of very strange, frequent crashes. - // // R_ProjectSprite // Generates a vissprite for a thing @@ -1111,7 +1123,9 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t iscale; fixed_t scalestep; fixed_t offset, offset2; + boolean papersprite = !!(thing->frame & FF_PAPERSPRITE); + fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0; INT32 dispoffset = thing->info->dispoffset; @@ -1130,10 +1144,6 @@ static void R_ProjectSprite(mobj_t *thing) UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS; #endif -#ifndef PROPERPAPER - fixed_t ang_scale = FRACUNIT; -#endif - // transform the origin point tr_x = thing->x - viewx; tr_y = thing->y - viewy; @@ -1216,13 +1226,7 @@ static void R_ProjectSprite(mobj_t *thing) #endif if (sprframe->rotate != SRF_SINGLE || papersprite) - { ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); -#ifndef PROPERPAPER - if (papersprite) - ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); -#endif - } if (sprframe->rotate == SRF_SINGLE) { @@ -1283,31 +1287,11 @@ static void R_ProjectSprite(mobj_t *thing) else offset = -spr_offset; offset = FixedMul(offset, this_scale); -#ifndef PROPERPAPER - tx += FixedMul(offset, ang_scale); - x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; - - // off the right side? - if (x1 > viewwidth) - return; -#endif offset2 = FixedMul(spr_width, this_scale); -#ifndef PROPERPAPER - tx += FixedMul(offset2, ang_scale); - x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1); - - // off the left side - if (x2 < 0) - return; -#endif if (papersprite) { - fixed_t -#ifdef PROPERPAPER - xscale2, -#endif - yscale2, cosmul, sinmul, tz2; + fixed_t xscale2, yscale2, cosmul, sinmul, tz2; INT32 range; if (ang >= ANGLE_180) @@ -1327,7 +1311,6 @@ static void R_ProjectSprite(mobj_t *thing) yscale = FixedDiv(projectiony, tz); if (yscale < 64) return; // Fix some funky visuals -#ifdef PROPERPAPER gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); tx = -(gyt + gxt); @@ -1337,7 +1320,16 @@ static void R_ProjectSprite(mobj_t *thing) // off the right side? if (x1 > viewwidth) return; -#endif + + // Get paperoffset (offset) and paperoffset (distance) + paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); + paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul); + if (paperdistance < 0) + { + paperoffset = -paperoffset; + paperdistance = -paperdistance; + } + centerangle = viewangle - thing->angle; tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); @@ -1347,36 +1339,25 @@ static void R_ProjectSprite(mobj_t *thing) yscale2 = FixedDiv(projectiony, tz2); if (yscale2 < 64) return; // ditto -#ifdef PROPERPAPER gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); tx = -(gyt + gxt); xscale2 = FixedDiv(projection, tz2); - x2 = (centerxfrac + FixedMul(tx,xscale2))>>FRACBITS; x2--; + x2 = ((centerxfrac + FixedMul(tx,xscale2))>>FRACBITS); // off the left side if (x2 < 0) return; -#endif - if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; if ((range = x2 - x1) <= 0) return; -#ifdef PROPERPAPER range++; // fencepost problem -#endif - scalestep = (yscale2 - yscale)/range; - xscale = -#ifdef PROPERPAPER - FixedDiv(range<>FRACBITS; @@ -1400,7 +1380,6 @@ static void R_ProjectSprite(mobj_t *thing) // off the left side if (x2 < 0) return; -#endif } if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) @@ -1521,6 +1500,9 @@ static void R_ProjectSprite(mobj_t *thing) vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; vis->scalestep = scalestep; + vis->paperoffset = paperoffset; + vis->paperdistance = paperdistance; + vis->centerangle = centerangle; vis->mobj = thing; // Easy access! Tails 06-07-2002 diff --git a/src/r_things.h b/src/r_things.h index 8e4a543c3..1b74dd74e 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -181,8 +181,11 @@ typedef struct vissprite_s fixed_t startfrac; // horizontal position of x1 fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW fixed_t scalestep; // only for paper sprites, 0 otherwise + fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle fixed_t xiscale; // negative if flipped + angle_t centerangle; // for paper sprites + fixed_t texturemid; patch_t *patch; From 1790891fd8f85cf91b0e4badf52e0b907e85e6d1 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 27 Dec 2019 11:42:02 -0600 Subject: [PATCH 3/7] Reduce disappearance of vissprites close to the camera --- src/r_things.c | 52 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 50f799d2c..7efa31a44 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -743,10 +743,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; -//#ifdef RANGECHECK -#if 1 INT32 texturecolumn; -#endif fixed_t frac; patch_t *patch = vis->patch; fixed_t this_scale = vis->mobj->scale; @@ -899,7 +896,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->scalestep) { angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; - texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) >> FRACBITS; + texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) { @@ -1154,7 +1151,7 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; // thing is behind view plane? - if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later + if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; gxt = -FixedMul(tr_x, viewsin); @@ -1162,7 +1159,7 @@ static void R_ProjectSprite(mobj_t *thing) tx = -(gyt + gxt); // too far off the side? - if (abs(tx) > tz<<2) + if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later return; // aspect ratio stuff @@ -1291,7 +1288,7 @@ static void R_ProjectSprite(mobj_t *thing) if (papersprite) { - fixed_t xscale2, yscale2, cosmul, sinmul, tz2; + fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2; INT32 range; if (ang >= ANGLE_180) @@ -1309,7 +1306,7 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale = FixedDiv(projectiony, tz); - if (yscale < 64) return; // Fix some funky visuals + //if (yscale < 64) return; // Fix some funky visuals gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); @@ -1317,10 +1314,6 @@ static void R_ProjectSprite(mobj_t *thing) xscale = FixedDiv(projection, tz); x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; - // off the right side? - if (x1 > viewwidth) - return; - // Get paperoffset (offset) and paperoffset (distance) paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul); @@ -1337,19 +1330,44 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz2 = gxt-gyt; yscale2 = FixedDiv(projectiony, tz2); - if (yscale2 < 64) return; // ditto + //if (yscale2 < 64) return; // ditto gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); + tx2 = -(gyt + gxt); xscale2 = FixedDiv(projection, tz2); - x2 = ((centerxfrac + FixedMul(tx,xscale2))>>FRACBITS); + x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS); + + if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier + return; + + // Needs partially clipped + if (tz < FixedMul(MINZ, this_scale)) + { + fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz); + tx += FixedDiv(tx2-tx, div); + tz = FixedMul(MINZ, this_scale); + yscale = FixedDiv(projectiony, tz); + xscale = FixedDiv(projection, tz); + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + } + else if (tz2 < FixedMul(MINZ, this_scale)) + { + fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2); + tx2 += FixedDiv(tx-tx2, div); + tz2 = FixedMul(MINZ, this_scale); + yscale2 = FixedDiv(projectiony, tz2); + xscale2 = FixedDiv(projection, tz2); + x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; + } + + // off the right side? + if (x1 > viewwidth) + return; // off the left side if (x2 < 0) return; - if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier - return; if ((range = x2 - x1) <= 0) return; From ccc473917e5133c8d862011ce6383acc5529667d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 27 Dec 2019 11:48:40 -0600 Subject: [PATCH 4/7] Check for papersprites per-sprite instead of per-row In theory, should be a performance improvement. In practice idk --- src/r_things.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 7efa31a44..c9fe795fb 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -891,41 +891,51 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->x2 >= vid.width) vis->x2 = vid.width-1; - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) + // Split drawing loops for paper and non-paper to reduce conditional checks per sprite + if (vis->scalestep) { - if (vis->scalestep) + // Papersprite drawing loop + + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep) { angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - { - spryscale += vis->scalestep; continue; - } - if (vis->xiscale < 0) + if (vis->xiscale < 0) // Flipped sprite texturecolumn = SHORT(patch->width) - 1 - texturecolumn; sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); + + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + + if (vis->cut & SC_VFLIP) + R_DrawFlippedMaskedColumn(column, patch->height); + else + R_DrawMaskedColumn(column); } - else + } + else + { + // Non-paper drawing loop + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { - texturecolumn = frac>>FRACBITS; #ifdef RANGECHECK + texturecolumn = frac>>FRACBITS; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); +#else + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); #endif + if (vis->cut & SC_VFLIP) + R_DrawFlippedMaskedColumn(column, patch->height); + else + R_DrawMaskedColumn(column); } - - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); - - if (vis->cut & SC_VFLIP) - R_DrawFlippedMaskedColumn(column, patch->height); - else - R_DrawMaskedColumn(column); - spryscale += vis->scalestep; } colfunc = colfuncs[BASEDRAWFUNC]; From 0f8c7361880c6147c4b46f7724da9d229793380f Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 20:49:38 -0800 Subject: [PATCH 5/7] Don't make player transparent if the orbital camera is looking straight down --- src/p_user.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 20fbc99f4..5bce0535d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10293,7 +10293,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall vy = player->awayviewmobj->y; } - if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale)) + /* + When the orbital camera looks straight down, its distance + will be very close to the player. So give it a threshold... + */ + if (( !( camorbit && rendermode == render_opengl ) || + focusaiming < ANGLE_90 || focusaiming > ANGLE_292h ) && + P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale)) mo->flags2 |= MF2_SHADOW; else mo->flags2 &= ~MF2_SHADOW; From 66cf1be0d85a879c844f89299ed9afb884217cf3 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 20:52:34 -0800 Subject: [PATCH 6/7] Don't clip player MD2 either! --- src/hardware/hw_main.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e8d16c092..78cdc70cc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5486,6 +5486,7 @@ static void HWR_ProjectSprite(mobj_t *thing) spritedef_t *sprdef; spriteframe_t *sprframe; spriteinfo_t *sprinfo; + md2_t *md2; size_t lumpoff; unsigned rot; UINT8 flip; @@ -5522,8 +5523,21 @@ static void HWR_ProjectSprite(mobj_t *thing) tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); // thing is behind view plane? - if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmodels.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear - return; + if (tz < ZCLIP_PLANE && !papersprite) + { + if (cv_grmodels.value) //Yellow: Only MD2's dont disappear + { + if (thing->skin && thing->sprite == SPR_PLAY) + md2 = &md2_playermodels[( (skin_t *)thing->skin - skins )]; + else + md2 = &md2_models[thing->sprite]; + + if (md2->notfound || md2->scale < 0.0f) + return; + } + else + return; + } // The above can stay as it works for cutting sprites that are too close tr_x = FIXED_TO_FLOAT(thing->x); From 2459ca255f6df5b5e5767aa3813fceed07ab1cd7 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 10 Jan 2020 00:04:17 -0800 Subject: [PATCH 7/7] Factor z distance into camera translucency --- src/p_user.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 5bce0535d..5b7e50995 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10287,19 +10287,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (!(multiplayer || netgame) && !splitscreen) { fixed_t vx = thiscam->x, vy = thiscam->y; + fixed_t vz = thiscam->z + thiscam->height / 2; if (player->awayviewtics && player->awayviewmobj != NULL && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist { vx = player->awayviewmobj->x; vy = player->awayviewmobj->y; + vz = player->awayviewmobj->z + player->awayviewmobj->height / 2; } - /* - When the orbital camera looks straight down, its distance - will be very close to the player. So give it a threshold... - */ - if (( !( camorbit && rendermode == render_opengl ) || - focusaiming < ANGLE_90 || focusaiming > ANGLE_292h ) && - P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale)) + /* check z distance too for orbital camera */ + if (P_AproxDistance(P_AproxDistance(vx - mo->x, vy - mo->y), + vz - ( mo->z + mo->height / 2 )) < FixedMul(48*FRACUNIT, mo->scale)) mo->flags2 |= MF2_SHADOW; else mo->flags2 &= ~MF2_SHADOW;