From 8433d133b41c22d3fc85b3abe70306b33a165325 Mon Sep 17 00:00:00 2001 From: terminx Date: Mon, 18 Feb 2019 22:02:33 +0000 Subject: [PATCH] Patch from Fox: Add a FOV option in the menu. Range from 75 to 120 degrees (at 4:3 resolution), default is 90. New userdef "fov". Equals the FOV in 360 degrees. Update Polymost projection hack, so it compensates for the FOV or height of the game view. Fix FOV in Polymer when the full status bar is visible. Now the FOV depends of the width of the game view instead of the height. git-svn-id: https://svn.eduke32.com/eduke32@7329 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/src/engine.cpp | 9 +++++---- source/build/src/polymer.cpp | 8 ++++++-- source/build/src/polymost.cpp | 13 ++++++++++--- source/duke3d/src/config.cpp | 1 + source/duke3d/src/game.cpp | 5 +++-- source/duke3d/src/game.h | 2 ++ source/duke3d/src/gamedef.h | 1 + source/duke3d/src/gamestructures.cpp | 3 +++ source/duke3d/src/menus.cpp | 7 +++++++ source/duke3d/src/osdcmds.cpp | 2 ++ 10 files changed, 40 insertions(+), 11 deletions(-) diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 28dc70c02..888107e37 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -12047,10 +12047,11 @@ void videoSetCorrectedAspect() { if (r_usenewaspect && newaspect_enable && videoGetRenderMode() != REND_POLYMER) { - // The correction factor 100/107 has been found - // out experimentally. Squares FTW! - int32_t vr, yx=(65536*4*100)/(3*107); - int32_t y, x; + // In DOS the game world is displayed with an aspect of 1.28 instead 1.333, + // meaning we have to stretch it by a factor of 1.25 instead of 1.2 + // to get perfect squares + int32_t yx = (65536 * 5) / 4; + int32_t vr, y, x; const int32_t xd = setaspect_new_use_dimen ? xdimen : xdim; const int32_t yd = setaspect_new_use_dimen ? ydimen : ydim; diff --git a/source/build/src/polymer.cpp b/source/build/src/polymer.cpp index d60844ef4..24bf81e4e 100644 --- a/source/build/src/polymer.cpp +++ b/source/build/src/polymer.cpp @@ -20,7 +20,7 @@ int32_t pr_shadowdetail = 4; int32_t pr_shadowfiltering = 1; int32_t pr_maxlightpasses = 10; int32_t pr_maxlightpriority = PR_MAXLIGHTPRIORITY; -int32_t pr_fov = 426; // appears to be the classic setting. +int32_t pr_fov = 512; double pr_customaspect = 0.0f; int32_t pr_billboardingmode = 1; int32_t pr_verbosity = 1; // 0: silent, 1: errors and one-times, 2: multiple-times, 3: flood @@ -41,7 +41,7 @@ float pr_hudxadd = 0.0f; float pr_hudyadd = 0.0f; float pr_hudzadd = 0.0f; int32_t pr_hudangadd = 0; -int32_t pr_hudfov = 426; +int32_t pr_hudfov = 512; float pr_overridemodelscale = 0.0f; int32_t pr_ati_fboworkaround = 0; int32_t pr_ati_nodepthoffset = 0; @@ -908,6 +908,10 @@ void polymer_setaspect(int32_t ang) float aspect; float fang = (float)ang * atanf(fviewingrange*(1.f/65536.f)) * (4.f/fPI); + // use horizontal fov instead of vertical + fang = atanf(tanf(fang * (PI / 2048.f)) * float(windowxy2.y - windowxy1.y + 1) / float(windowxy2.x - windowxy1.x + 1) * + float(xdim) / float(ydim) * (3.f / 4.f)) * (2048.f / PI); + if (pr_customaspect != 0.0f) aspect = pr_customaspect; else diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 7405e4092..f021c05e3 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -1438,9 +1438,17 @@ static float get_projhack_ratio(void) { if (glprojectionhacks) { - static constexpr float const projhack_zoom = 1.3f; + float const projhack_zoom = 1.4f * + // adjust for the FOV, increasing the FOV reduces the zenith glitch + // don't apply if the zenith is cut from the viewing area + (65536.f / fviewingrange) * + (float)(windowxy2.y-windowxy1.y+1) / + (float)(windowxy2.x-windowxy1.x+1) * + (float)(xdim)/(float)(ydim); + if (projhack_zoom < 1.f) + return 1.f; static constexpr float const maxcoshoriz = 0.540971179375801f; // 128/sqrt(128^2+199^2) = cos of an horiz diff of 199 - static constexpr float const factor = (projhack_zoom - 1.f) * (1.f / maxcoshoriz); + float const factor = (projhack_zoom - 1.f) * (1.f / maxcoshoriz); return 1.f + (factor * (1.f - Bfabsf(gchang))); } @@ -7958,7 +7966,6 @@ void polymost_initosdfuncs(void) { "r_pr_shadowfiltering", "enable/disable shadow edges filtering - you need to restart the renderer for it to take effect", (void *) &pr_shadowfiltering, CVAR_BOOL, 0, 1 }, { "r_pr_maxlightpasses", "the maximal amount of lights a single object can by affected by", (void *) &r_pr_maxlightpasses, CVAR_INT|CVAR_FUNCPTR, 0, PR_MAXLIGHTS }, { "r_pr_maxlightpriority", "lowering that value removes less meaningful lights from the scene", (void *) &pr_maxlightpriority, CVAR_INT, 0, PR_MAXLIGHTPRIORITY }, - { "r_pr_fov", "sets the field of vision in build angle", (void *) &pr_fov, CVAR_INT, 0, 1023}, { "r_pr_customaspect", "if non-zero, forces the 3D view aspect ratio", (void *) &pr_customaspect, CVAR_DOUBLE, 0, 3 }, { "r_pr_billboardingmode", "face sprite display method. 0: classic mode; 1: polymost mode", (void *) &pr_billboardingmode, CVAR_INT, 0, 1 }, { "r_pr_verbosity", "verbosity level of the polymer renderer", (void *) &pr_verbosity, CVAR_INT, 0, 3 }, diff --git a/source/duke3d/src/config.cpp b/source/duke3d/src/config.cpp index ac44fc8fb..55bc8058b 100644 --- a/source/duke3d/src/config.cpp +++ b/source/duke3d/src/config.cpp @@ -274,6 +274,7 @@ void CONFIG_SetDefaults(void) ud.detail = 0; ud.display_bonus_screen = 1; ud.drawweapon = 1; + ud.fov = 90; ud.hudontop = 0; ud.idplayers = 1; ud.levelstats = 0; diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 07bc96ee5..19a8ab271 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -792,11 +792,12 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio) #endif ))); + viewingRange = Blrintf(float(vr) * tanf(ud.fov * (PI/360.f))); + if (!r_usenewaspect) - renderSetAspect(vr, yxaspect); + renderSetAspect(viewingRange, yxaspect); else { - viewingRange = vr; yxAspect = tabledivide32_noinline(65536 * ydim * 8, xdim * 5); renderSetAspect(mulscale16(viewingRange,viewingrange), yxaspect); diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index 4fd0f1331..5161c0a2b 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -210,6 +210,8 @@ typedef struct { uint32_t userbytever; + int32_t fov; + #if !defined LUNATIC fix16_t cameraq16ang, cameraq16horiz; int16_t camerasect; diff --git a/source/duke3d/src/gamedef.h b/source/duke3d/src/gamedef.h index 886c0a538..fdb896ec0 100644 --- a/source/duke3d/src/gamedef.h +++ b/source/duke3d/src/gamedef.h @@ -627,6 +627,7 @@ enum UserdefsLabel_t USERDEFS_AUTOSAVE, USERDEFS_DRAW_Y, USERDEFS_DRAW_YXASPECT, + USERDEFS_FOV, USERDEFS_END }; diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index 7f06f922e..9754e1e9c 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -1346,6 +1346,7 @@ const memberlabel_t UserdefsLabels[]= { "autosave", USERDEFS_AUTOSAVE, 0, 0, -1 }, { "draw_y", USERDEFS_DRAW_Y, 0, 0, -1 }, { "draw_yxaspect", USERDEFS_DRAW_YXASPECT, 0, 0, -1 }, + { "fov", USERDEFS_FOV, 0, 0, -1 }, }; int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2) @@ -1535,6 +1536,7 @@ int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2) case USERDEFS_AUTOSAVE: labelNum = ud.autosave; break; case USERDEFS_DRAW_Y: labelNum = rotatesprite_y_offset; break; case USERDEFS_DRAW_YXASPECT: labelNum = rotatesprite_yxaspect; break; + case USERDEFS_FOV: labelNum = ud.fov; break; default: EDUKE32_UNREACHABLE_SECTION(labelNum = -1; break); } @@ -1736,6 +1738,7 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons case USERDEFS_AUTOSAVE: ud.autosave = iSet; break; case USERDEFS_DRAW_Y: rotatesprite_y_offset = iSet; break; case USERDEFS_DRAW_YXASPECT: rotatesprite_yxaspect = iSet; break; + case USERDEFS_FOV: ud.fov = iSet; break; } } diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index a5085bea4..f91987f3d 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -551,6 +551,10 @@ static MenuEntry_t ME_DISPLAYSETUP_ASPECTRATIO = MAKE_MENUENTRY( "Widescreen:", #endif +static MenuRangeInt32_t MEO_DISPLAYSETUP_FOV = MAKE_MENURANGE( &ud.fov, &MF_Redfont, 75, 120, 0, 10, 0 ); +static MenuEntry_t ME_DISPLAYSETUP_FOV = MAKE_MENUENTRY( "FOV:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_DISPLAYSETUP_FOV, RangeInt32 ); + + #ifdef USE_OPENGL static int32_t MEOSV_PaletteEmulation[] = { 0, r_usetileshades }; static MenuOptionSet_t MEOS_PaletteEmulation = MAKE_MENUOPTIONSET( MEOSN_OffOn, MEOSV_PaletteEmulation, 0x3 ); @@ -723,6 +727,7 @@ static MenuEntry_t *MEL_DISPLAYSETUP[] = { #ifndef EDUKE32_ANDROID_MENU &ME_DISPLAYSETUP_VIDEOSETUP, &ME_DISPLAYSETUP_ASPECTRATIO, + &ME_DISPLAYSETUP_FOV, #endif &ME_DISPLAYSETUP_UPSCALING, }; @@ -734,6 +739,7 @@ static MenuEntry_t *MEL_DISPLAYSETUP_GL[] = { #ifndef EDUKE32_ANDROID_MENU &ME_DISPLAYSETUP_VIDEOSETUP, &ME_DISPLAYSETUP_ASPECTRATIO, + &ME_DISPLAYSETUP_FOV, #endif #ifndef EDUKE32_STANDALONE &ME_DISPLAYSETUP_TEXFILTER, @@ -761,6 +767,7 @@ static MenuEntry_t *MEL_DISPLAYSETUP_GL_POLYMER[] = { &ME_DISPLAYSETUP_COLORCORR, #ifndef EDUKE32_ANDROID_MENU &ME_DISPLAYSETUP_VIDEOSETUP, + &ME_DISPLAYSETUP_FOV, #endif &ME_DISPLAYSETUP_TEXFILTER, &ME_DISPLAYSETUP_ANISOTROPY, diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index 5edcc1366..9d436954b 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -1591,6 +1591,8 @@ int32_t registerosdcommands(void) { "demoplay_diffs","enable/disable application of diffs in demo playback",(void *)&demoplay_diffs, CVAR_BOOL, 0, 1 }, { "demoplay_showsync","enable/disable display of sync status",(void *)&demoplay_showsync, CVAR_BOOL, 0, 1 }, + { "fov", "change the field of view", (void *)&ud.fov, CVAR_INT|CVAR_FUNCPTR, 75, 120 }, + { "hud_althud", "enable/disable alternate mini-hud", (void *)&ud.althud, CVAR_BOOL, 0, 1 }, { "hud_custom", "change the custom hud", (void *)&ud.statusbarcustom, CVAR_INT, 0, ud.statusbarrange }, { "hud_position", "aligns the status bar to the bottom/top", (void *)&ud.hudontop, CVAR_BOOL, 0, 1 },