From 303da0e071d3b6b4fac993147fe4dcdce0eb7680 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 9 Sep 2016 20:09:54 +0200 Subject: [PATCH 01/22] Fix center text alignment issue --- src/c_console.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 08f850675f..0868612292 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -811,8 +811,8 @@ static void C_DrawNotifyText () DTA_KeepRatio, true, DTA_AlphaF, alpha, TAG_DONE); else - screen->DrawText (SmallFont, color, (screen->GetWidth() / active_con_scaletext() - - SmallFont->StringWidth (NotifyStrings[i].Text))/ active_con_scaletext(), + screen->DrawText (SmallFont, color, (screen->GetWidth() - + SmallFont->StringWidth (NotifyStrings[i].Text) * active_con_scaletext()) / 2 / active_con_scaletext(), line, NotifyStrings[i].Text, DTA_VirtualWidth, screen->GetWidth() / active_con_scaletext(), DTA_VirtualHeight, screen->GetHeight() / active_con_scaletext(), From 02e4ba464ac5e1dc4e0a9c06af6949a1dcfba669 Mon Sep 17 00:00:00 2001 From: raa-eruanna Date: Fri, 9 Sep 2016 22:27:37 -0400 Subject: [PATCH 02/22] Fixed mirror angle issue, fixes rendering of mirrors --- src/r_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_main.cpp b/src/r_main.cpp index ce4841a2e7..ecbd4cb347 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -678,7 +678,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) ViewPos.X = (x1 + r * dx)*2 - x; ViewPos.Y = (y1 + r * dy)*2 - y; } - ViewAngle = pds->src->Delta().Angle() - startang; + ViewAngle = pds->src->Delta().Angle() * 2 - startang; } else { From d3d8180f578924b275defd937e10cd3cb370922e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 13:04:36 +0200 Subject: [PATCH 03/22] Resize framebuffer in windowed mode to match the client area --- src/v_video.cpp | 42 ++++++++++++++++++++++++++++++++++++------ src/v_video.h | 4 ++++ src/win32/fb_d3d9.cpp | 18 ++++++++++++++++++ src/win32/i_input.cpp | 16 ++++++++++++---- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index b9917a1cb6..9d377b7fd8 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -725,6 +725,21 @@ void DCanvas::CalcGamma (float gamma, BYTE gammalookup[256]) DSimpleCanvas::DSimpleCanvas (int width, int height) : DCanvas (width, height) { + MemBuffer = nullptr; + Resize(width, height); +} + +void DSimpleCanvas::Resize(int width, int height) +{ + Width = width; + Height = height; + + if (MemBuffer != NULL) + { + delete[] MemBuffer; + MemBuffer = NULL; + } + // Making the pitch a power of 2 is very bad for performance // Try to maximize the number of cache lines that can be filled // for each column drawing operation by making the pitch slightly @@ -761,7 +776,7 @@ DSimpleCanvas::DSimpleCanvas (int width, int height) } } MemBuffer = new BYTE[Pitch * height]; - memset (MemBuffer, 0, Pitch * height); + memset(MemBuffer, 0, Pitch * height); } //========================================================================== @@ -1259,7 +1274,6 @@ CCMD(clean) bool V_DoModeSetup (int width, int height, int bits) { DFrameBuffer *buff = I_SetMode (width, height, screen); - int cx1, cx2; if (buff == NULL) { @@ -1274,6 +1288,17 @@ bool V_DoModeSetup (int width, int height, int bits) // if D3DFB is being used for the display. FFont::StaticPreloadFonts(); + DisplayBits = bits; + V_UpdateModeSize(width, height); + + M_RefreshModesList (); + + return true; +} + +void V_UpdateModeSize (int width, int height) +{ + int cx1, cx2; V_CalcCleanFacs(320, 200, width, height, &CleanXfac, &CleanYfac, &cx1, &cx2); CleanWidth = width / CleanXfac; @@ -1314,14 +1339,19 @@ bool V_DoModeSetup (int width, int height, int bits) DisplayWidth = width; DisplayHeight = height; - DisplayBits = bits; R_OldBlend = ~0; Renderer->OnModeSet(); - - M_RefreshModesList (); +} - return true; +void V_OutputResized (int width, int height) +{ + V_UpdateModeSize(width, height); + setsizeneeded = true; + if (StatusBar != NULL) + { + StatusBar->ScreenSizeChanged(); + } } void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2) diff --git a/src/v_video.h b/src/v_video.h index 4f0a786751..11a10c8d82 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -47,6 +47,8 @@ extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1; extern int DisplayWidth, DisplayHeight, DisplayBits; bool V_DoModeSetup (int width, int height, int bits); +void V_UpdateModeSize (int width, int height); +void V_OutputResized (int width, int height); void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *cx1=NULL, int *cx2=NULL); class FTexture; @@ -300,6 +302,8 @@ public: void Unlock (); protected: + void Resize(int width, int height); + BYTE *MemBuffer; DSimpleCanvas() {} diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index efdced151c..06bfa05691 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -1220,6 +1220,24 @@ void D3DFB::Flip() CurrRenderTexture ^= RenderTextureToggle; TempRenderTexture = RenderTexture[CurrRenderTexture]; } + + if (Windowed) + { + RECT box; + GetClientRect(Window, &box); + if (box.right > 0 && box.right > 0 && (Width != box.right || Height != box.bottom)) + { + Resize(box.right, box.bottom); + + TrueHeight = Height; + PixelDoubling = 0; + LBOffsetI = 0; + LBOffset = 0.0f; + Reset(); + + V_OutputResized(Width, Height); + } + } } //========================================================================== diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index 2b0659c832..1e63903927 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -537,10 +537,18 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if (screen && !VidResizing) { LPMINMAXINFO mmi = (LPMINMAXINFO)lParam; - RECT rect = { 0, 0, screen->GetWidth(), screen->GetHeight() }; - AdjustWindowRectEx(&rect, WS_VISIBLE|WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW); - mmi->ptMinTrackSize.x = rect.right - rect.left; - mmi->ptMinTrackSize.y = rect.bottom - rect.top; + if (screen->IsFullscreen()) + { + RECT rect = { 0, 0, screen->GetWidth(), screen->GetHeight() }; + AdjustWindowRectEx(&rect, WS_VISIBLE | WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW); + mmi->ptMinTrackSize.x = rect.right - rect.left; + mmi->ptMinTrackSize.y = rect.bottom - rect.top; + } + else + { + mmi->ptMinTrackSize.x = 320; + mmi->ptMinTrackSize.y = 200; + } return 0; } break; From b003c47e3e02bed94b76757a512b195b1d7d70c8 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 13:37:05 +0200 Subject: [PATCH 04/22] Improve CheckRatio to always return the closest ratio --- src/v_video.cpp | 77 +++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index 9d377b7fd8..78995f3002 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1610,13 +1610,36 @@ CUSTOM_CVAR (Int, vid_aspect, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // 2: 16:10 // 3: 17:10 // 4: 5:4 -// 5: 17:10 (redundant) +// 5: 17:10 (redundant, never returned) // 6: 21:9 int CheckRatio (int width, int height, int *trueratio) { - int fakeratio = -1; - int ratio; + float aspect = width / (float)height; + static std::pair ratioTypes[] = + { + { 21 / 9.0f , 6 }, + { 16 / 9.0f , 1 }, + { 17 / 10.0f , 3 }, + { 16 / 10.0f , 2 }, + { 4 / 3.0f , 0 }, + { 5 / 4.0f , 4 }, + { 0.0f, 0 } + }; + + int ratio = ratioTypes[0].second; + float distance = abs(ratioTypes[0].first - aspect); + for (int i = 1; ratioTypes[i].first != 0.0f; i++) + { + float d = abs(ratioTypes[i].first - aspect); + if (d < distance) + { + ratio = ratioTypes[i].second; + distance = d; + } + } + + int fakeratio = ratio; if ((vid_aspect >= 1) && (vid_aspect <= 6)) { // [SP] User wants to force aspect ratio; let them. @@ -1628,7 +1651,7 @@ int CheckRatio (int width, int height, int *trueratio) else if (fakeratio == 5) { fakeratio = 3; - } + } } if (vid_nowidescreen) { @@ -1638,53 +1661,13 @@ int CheckRatio (int width, int height, int *trueratio) } else { - fakeratio = (height * 5/4 == width) ? 4 : 0; + fakeratio = (height * 5 / 4 == width) ? 4 : 0; } } - // If the size is approximately 16:9, consider it so. - if (abs (height * 16/9 - width) < 10) - { - ratio = 1; - } - // Consider 17:10 as well. - else if (abs (height * 17/10 - width) < 10) - { - ratio = 3; - } - // 16:10 has more variance in the pixel dimensions. Grr. - else if (abs (height * 16/10 - width) < 60) - { - // 320x200 and 640x400 are always 4:3, not 16:10 - if ((width == 320 && height == 200) || (width == 640 && height == 400)) - { - ratio = 0; - } - else - { - ratio = 2; - } - } - // Unless vid_tft is set, 1280x1024 is 4:3, not 5:4. - else if (height * 5/4 == width && vid_tft) - { - ratio = 4; - } - // test for 21:9 (actually 64:27, 21:9 is a semi-accurate ratio used in marketing) - else if (abs (height * 64/27 - width) < 30) - { - ratio = 6; - } - // Assume anything else is 4:3. (Which is probably wrong these days...) - else - { - ratio = 0; - } - if (trueratio != NULL) - { + if (trueratio) *trueratio = ratio; - } - return (fakeratio >= 0) ? fakeratio : ratio; + return fakeratio; } // First column: Base width From 5720634045b0812bc838eb4671a4039917582a94 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 13:59:01 +0200 Subject: [PATCH 05/22] Add ActiveRatio to be used where CheckRatio is used today --- src/v_video.cpp | 81 ++++++++++++++++++++++++++++++++++--------------- src/v_video.h | 2 ++ 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index 78995f3002..dcc5789eee 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1603,6 +1603,59 @@ CUSTOM_CVAR (Int, vid_aspect, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) } } +// Helper for ActiveRatio and CheckRatio. Returns the forced ratio type, or -1 if none. +int ActiveFakeRatio(int width, int height) +{ + int fakeratio = -1; + if ((vid_aspect >= 1) && (vid_aspect <= 6)) + { + // [SP] User wants to force aspect ratio; let them. + fakeratio = int(vid_aspect); + if (fakeratio == 3) + { + fakeratio = 0; + } + else if (fakeratio == 5) + { + fakeratio = 3; + } + } + if (vid_nowidescreen) + { + if (!vid_tft) + { + fakeratio = 0; + } + else + { + fakeratio = (height * 5 / 4 == width) ? 4 : 0; + } + } + return fakeratio; +} + +// Active screen ratio based on cvars and size +float ActiveRatio(int width, int height, float *trueratio) +{ + static float forcedRatioTypes[] = + { + 4 / 3.0f, + 16 / 9.0f, + 16 / 10.0f, + 17 / 10.0f, + 5 / 4.0f, + 17 / 10.0f, + 21 / 9.0f + }; + + float ratio = width / (float)height; + int fakeratio = ActiveFakeRatio(width, height); + + if (trueratio) + *trueratio = ratio; + return (fakeratio != -1) ? forcedRatioTypes[fakeratio] : ratio; +} + // Tries to guess the physical dimensions of the screen based on the // screen's pixel dimensions. Can return: // 0: 4:3 @@ -1639,31 +1692,9 @@ int CheckRatio (int width, int height, int *trueratio) } } - int fakeratio = ratio; - if ((vid_aspect >= 1) && (vid_aspect <= 6)) - { - // [SP] User wants to force aspect ratio; let them. - fakeratio = int(vid_aspect); - if (fakeratio == 3) - { - fakeratio = 0; - } - else if (fakeratio == 5) - { - fakeratio = 3; - } - } - if (vid_nowidescreen) - { - if (!vid_tft) - { - fakeratio = 0; - } - else - { - fakeratio = (height * 5 / 4 == width) ? 4 : 0; - } - } + int fakeratio = ActiveFakeRatio(width, height); + if (fakeratio == -1) + fakeratio = ratio; if (trueratio) *trueratio = ratio; diff --git a/src/v_video.h b/src/v_video.h index 11a10c8d82..6b46fa2781 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -516,6 +516,8 @@ extern "C" void ASM_PatchPitch (void); int CheckRatio (int width, int height, int *trueratio=NULL); static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); } +float ActiveRatio (int width, int height, float *trueratio = NULL); +static inline double ActiveRatio (double width, double height) { return ActiveRatio(int(width), int(height)); } extern const int BaseRatioSizes[7][4]; inline bool IsRatioWidescreen(int ratio) { From 6d4e4dad25ffa3978f5bf54d0fc60dd59b29d119 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 14:37:10 +0200 Subject: [PATCH 06/22] BaseRatioSizes replacement functions --- src/v_video.cpp | 20 ++++++++++++++++++++ src/v_video.h | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/src/v_video.cpp b/src/v_video.cpp index dcc5789eee..acd34f37f8 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1721,6 +1721,26 @@ const int BaseRatioSizes[7][4] = { 1707, 338, 0, 48*9/16 } // 21:9 568.8889, 337.5, multiplied by three }; +int AspectBaseWidth(float aspect) +{ + return (int)round(240.0f * aspect * 3.0f); +} + +int AspectBaseHeight(float aspect) +{ + return (int)round(200.0f * (320.0f / (240.0f * aspect)) * 3.0f); +} + +int AspectPspriteOffset(float aspect) +{ + return aspect < 1.3f ? (int)(6.5*FRACUNIT) : 0; +} + +int AspectMultiplier(float aspect) +{ + return (int)round(320.0f / (240.0f * aspect) * 48.0f); +} + void IVideo::DumpAdapters () { Printf("Multi-monitor support unavailable.\n"); diff --git a/src/v_video.h b/src/v_video.h index 6b46fa2781..2dc3bbddc3 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -518,6 +518,11 @@ int CheckRatio (int width, int height, int *trueratio=NULL); static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); } float ActiveRatio (int width, int height, float *trueratio = NULL); static inline double ActiveRatio (double width, double height) { return ActiveRatio(int(width), int(height)); } + +int AspectBaseWidth(float aspect); +int AspectBaseHeight(float aspect); +int AspectPspriteOffset(float aspect); +int AspectMultiplier(float aspect); extern const int BaseRatioSizes[7][4]; inline bool IsRatioWidescreen(int ratio) { From 5b438d220f918e4d5b604e970f0f45f96963e8d1 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 15:51:50 +0200 Subject: [PATCH 07/22] Switch from ratio enum to float --- src/g_shared/shared_hud.cpp | 6 +++--- src/g_shared/shared_sbar.cpp | 17 +++++++++-------- src/r_main.cpp | 16 ++++++++-------- src/r_renderer.h | 2 +- src/r_swrenderer.cpp | 4 ++-- src/r_swrenderer.h | 2 +- src/r_things.cpp | 2 +- src/r_utility.cpp | 11 +++++------ src/r_utility.h | 2 +- src/v_draw.cpp | 34 +++++++++++++++++----------------- src/v_video.cpp | 30 +++++------------------------- src/v_video.h | 11 ++--------- 12 files changed, 55 insertions(+), 82 deletions(-) diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 25a88cb352..e40233defd 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -1108,13 +1108,13 @@ void DrawHUD() } else { - if (WidescreenRatio == 4) + if (CheckRatio(SCREENWIDTH, SCREENHEIGHT) == 4) { - hudheight = hudwidth * 30 / BaseRatioSizes[WidescreenRatio][3]; // BaseRatioSizes is inverted for this mode + hudheight = hudwidth * 30 / AspectMultiplier(WidescreenRatio); // BaseRatioSizes is inverted for this mode } else { - hudheight = hudwidth * 30 / (48*48/BaseRatioSizes[WidescreenRatio][3]); + hudheight = hudwidth * 30 / (48*48/AspectMultiplier(WidescreenRatio)); } } } diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 4631a99aa6..3c41d18ca6 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -299,14 +299,15 @@ void DBaseStatusBar::SetScaled (bool scale, bool force) { ST_X = 0; ST_Y = VirticalResolution - RelTop; - if (CheckRatio(SCREENWIDTH, SCREENHEIGHT) != 4) + float aspect = ActiveRatio(SCREENWIDTH, SCREENHEIGHT); + if (aspect >= 1.3f) { // Normal resolution ::ST_Y = Scale (ST_Y, SCREENHEIGHT, VirticalResolution); } else { // 5:4 resolution - ::ST_Y = Scale(ST_Y - VirticalResolution/2, SCREENHEIGHT*3, Scale(VirticalResolution, BaseRatioSizes[4][1], 200)) + SCREENHEIGHT/2 - + (SCREENHEIGHT - SCREENHEIGHT * BaseRatioSizes[4][3] / 48) / 2; + ::ST_Y = Scale(ST_Y - VirticalResolution/2, SCREENHEIGHT*3, Scale(VirticalResolution, AspectBaseHeight(aspect), 200)) + SCREENHEIGHT/2 + + (SCREENHEIGHT - SCREENHEIGHT * AspectMultiplier(aspect) / 48) / 2; } Displacement = 0; } @@ -1035,10 +1036,10 @@ void DBaseStatusBar::DrSmallNumberOuter (int val, int x, int y, bool center) con void DBaseStatusBar::RefreshBackground () const { - int x, x2, y, ratio; + int x, x2, y; - ratio = CheckRatio (SCREENWIDTH, SCREENHEIGHT); - x = (!IsRatioWidescreen(ratio) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2); + float ratio = ActiveRatio (SCREENWIDTH, SCREENHEIGHT); + x = (ratio < 1.5f || !Scaled) ? ST_X : SCREENWIDTH*(48-AspectMultiplier(ratio))/(48*2); y = x == ST_X && x > 0 ? ST_Y : ::ST_Y; if(!CompleteBorder) @@ -1058,8 +1059,8 @@ void DBaseStatusBar::RefreshBackground () const { if(!CompleteBorder) { - x2 = !IsRatioWidescreen(ratio) || !Scaled ? ST_X+HorizontalResolution : - SCREENWIDTH - (SCREENWIDTH*(48-BaseRatioSizes[ratio][3])+48*2-1)/(48*2); + x2 = ratio < 1.5f || !Scaled ? ST_X+HorizontalResolution : + SCREENWIDTH - (SCREENWIDTH*(48-AspectMultiplier(ratio))+48*2-1)/(48*2); } else { diff --git a/src/r_main.cpp b/src/r_main.cpp index ecbd4cb347..d84698b7cf 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -232,7 +232,7 @@ void R_SetVisibility(double vis) else r_WallVisibility = r_BaseVisibility; - r_WallVisibility = (InvZtoScale * SCREENWIDTH*BaseRatioSizes[WidescreenRatio][1] / + r_WallVisibility = (InvZtoScale * SCREENWIDTH*AspectBaseHeight(WidescreenRatio) / (viewwidth*SCREENHEIGHT*3)) * (r_WallVisibility * FocalTangent); // Prevent overflow on floors/ceilings. Note that the calculation of @@ -295,7 +295,7 @@ CCMD (r_visibility) // //========================================================================== -void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio) +void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio) { int virtheight, virtwidth, virtwidth2, virtheight2; @@ -318,22 +318,22 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, virtwidth = virtwidth2 = fullWidth; virtheight = virtheight2 = fullHeight; - if (Is54Aspect(trueratio)) + if (trueratio < 1.3f) { - virtheight2 = virtheight2 * BaseRatioSizes[trueratio][3] / 48; + virtheight2 = virtheight2 * AspectMultiplier(trueratio) / 48; } else { - virtwidth2 = virtwidth2 * BaseRatioSizes[trueratio][3] / 48; + virtwidth2 = virtwidth2 * AspectMultiplier(trueratio) / 48; } - if (Is54Aspect(WidescreenRatio)) + if (WidescreenRatio < 1.3f) { - virtheight = virtheight * BaseRatioSizes[WidescreenRatio][3] / 48; + virtheight = virtheight * AspectMultiplier(WidescreenRatio) / 48; } else { - virtwidth = virtwidth * BaseRatioSizes[WidescreenRatio][3] / 48; + virtwidth = virtwidth * AspectMultiplier(WidescreenRatio) / 48; } BaseYaspectMul = 320.0 * virtheight2 / (r_Yaspect * virtwidth2); diff --git a/src/r_renderer.h b/src/r_renderer.h index 6c65fc12fd..a39520b49a 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -55,7 +55,7 @@ struct FRenderer virtual void ErrorCleanup () {} virtual void ClearBuffer(int color) = 0; virtual void Init() = 0; - virtual void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio) {} + virtual void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio) {} virtual void SetupFrame(player_t *player) {} virtual void CopyStackedViewParameters() {} virtual void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) = 0; diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index 07edf25e97..4d1fd03718 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -45,7 +45,7 @@ class FArchive; -void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio); +void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio); void R_SetupColormap(player_t *); void R_SetupFreelook(); void R_InitRenderer(); @@ -275,7 +275,7 @@ void FSoftwareRenderer::ClearBuffer(int color) // //=========================================================================== -void FSoftwareRenderer::SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio) +void FSoftwareRenderer::SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio) { R_SWRSetWindow(windowSize, fullWidth, fullHeight, stHeight, trueratio); } diff --git a/src/r_swrenderer.h b/src/r_swrenderer.h index 3e5fed9bca..2856d9586a 100644 --- a/src/r_swrenderer.h +++ b/src/r_swrenderer.h @@ -30,7 +30,7 @@ struct FSoftwareRenderer : public FRenderer void ErrorCleanup (); void ClearBuffer(int color); void Init(); - void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio); + void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio); void SetupFrame(player_t *player); void CopyStackedViewParameters(); void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov); diff --git a/src/r_things.cpp b/src/r_things.cpp index 28b52129b2..a62525d085 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1393,7 +1393,7 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double } if (pspr->GetID() < PSP_TARGETCENTER) { // Move the weapon down for 1280x1024. - vis->texturemid -= BaseRatioSizes[WidescreenRatio][2]; + vis->texturemid -= AspectPspriteOffset(WidescreenRatio); } vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth : x2; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 00ac91c971..8e4284b7e3 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -138,7 +138,7 @@ angle_t LocalViewAngle; int LocalViewPitch; bool LocalKeyboardTurner; -int WidescreenRatio; +float WidescreenRatio; int setblocks; int extralight; bool setsizeneeded; @@ -200,7 +200,7 @@ void R_SetViewSize (int blocks) void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) { - int trueratio; + float trueratio; if (windowSize >= 11) { @@ -220,8 +220,7 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) freelookviewheight = ((setblocks*fullHeight)/10)&~7; } - // If the screen is approximately 16:9 or 16:10, consider it widescreen. - WidescreenRatio = CheckRatio (fullWidth, fullHeight, &trueratio); + WidescreenRatio = ActiveRatio (fullWidth, fullHeight, &trueratio); DrawFSHUD = (windowSize == 11); @@ -230,13 +229,13 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) centery = viewheight/2; centerx = viewwidth/2; - if (Is54Aspect(WidescreenRatio)) + if (WidescreenRatio < 1.3f) { centerxwide = centerx; } else { - centerxwide = centerx * BaseRatioSizes[WidescreenRatio][3] / 48; + centerxwide = centerx * AspectMultiplier(WidescreenRatio) / 48; } diff --git a/src/r_utility.h b/src/r_utility.h index 8cabfa6002..e9fd436e50 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -33,7 +33,7 @@ extern int validcount; extern angle_t LocalViewAngle; // [RH] Added to consoleplayer's angle extern int LocalViewPitch; // [RH] Used directly instead of consoleplayer's pitch extern bool LocalKeyboardTurner; // [RH] The local player used the keyboard to turn, so interpolate -extern int WidescreenRatio; +extern float WidescreenRatio; extern double r_TicFracF; extern DWORD r_FrameTime; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index dada0cd57c..a33fd618bc 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -863,37 +863,37 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom, bool handleaspect) const { - int myratio = handleaspect ? CheckRatio (Width, Height) : 0; + float myratio = handleaspect ? ActiveRatio (Width, Height) : (4.0f / 3.0f); // if 21:9 AR, map to 16:9 for all callers. // this allows for black bars and stops the stretching of fullscreen images - if (myratio == 6) { - myratio = 2; + if (myratio > 1.7f) { + myratio = 16.0f / 9.0f; } double right = x + w; double bottom = y + h; - if (myratio != 0 && myratio != 4) + if (myratio > 1.4f) { // The target surface is either 16:9 or 16:10, so expand the // specified virtual size to avoid undesired stretching of the // image. Does not handle non-4:3 virtual sizes. I'll worry about // those if somebody expresses a desire to use them. - x = (x - vwidth * 0.5) * Width * 960 / (vwidth * BaseRatioSizes[myratio][0]) + Width * 0.5; - w = (right - vwidth * 0.5) * Width * 960 / (vwidth * BaseRatioSizes[myratio][0]) + Width * 0.5 - x; + x = (x - vwidth * 0.5) * Width * 960 / (vwidth * AspectBaseWidth(myratio)) + Width * 0.5; + w = (right - vwidth * 0.5) * Width * 960 / (vwidth * AspectBaseWidth(myratio)) + Width * 0.5 - x; } else { x = x * Width / vwidth; w = right * Width / vwidth - x; } - if (myratio == 4) + if (myratio < 1.3f) { // The target surface is 5:4 - y = (y - vheight * 0.5) * Height * 600 / (vheight * BaseRatioSizes[myratio][1]) + Height * 0.5; - h = (bottom - vheight * 0.5) * Height * 600 / (vheight * BaseRatioSizes[myratio][1]) + Height * 0.5 - y; + y = (y - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5; + h = (bottom - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5 - y; if (vbottom) { - y += (Height - Height * BaseRatioSizes[myratio][3] / 48.0) * 0.5; + y += (Height - Height * AspectMultiplier(myratio) / 48.0) * 0.5; } } else @@ -937,30 +937,30 @@ void DCanvas::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, void DCanvas::FillBorder (FTexture *img) { - int myratio = CheckRatio (Width, Height); + float myratio = ActiveRatio (Width, Height); // if 21:9 AR, fill borders akin to 16:9, since all fullscreen // images are being drawn to that scale. - if (myratio == 6) { - myratio = 2; + if (myratio > 1.7f) { + myratio = 16 / 9.0f; } - if (myratio == 0) + if (myratio >= 1.3f && myratio <= 1.4f) { // This is a 4:3 display, so no border to show return; } int bordtop, bordbottom, bordleft, bordright, bord; - if (Is54Aspect(myratio)) + if (myratio < 1.3f) { // Screen is taller than it is wide bordleft = bordright = 0; - bord = Height - Height * BaseRatioSizes[myratio][3] / 48; + bord = Height - Height * AspectMultiplier(myratio) / 48; bordtop = bord / 2; bordbottom = bord - bordtop; } else { // Screen is wider than it is tall bordtop = bordbottom = 0; - bord = Width - Width * BaseRatioSizes[myratio][3] / 48; + bord = Width - Width * AspectMultiplier(myratio) / 48; bordleft = bord / 2; bordright = bord - bordleft; } diff --git a/src/v_video.cpp b/src/v_video.cpp index acd34f37f8..43458dc637 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1356,20 +1356,20 @@ void V_OutputResized (int width, int height) void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2) { - int ratio; + float ratio; int cwidth; int cheight; int cx1, cy1, cx2, cy2; - ratio = CheckRatio(realwidth, realheight); - if (Is54Aspect(ratio)) + ratio = ActiveRatio(realwidth, realheight); + if (ratio < 1.3f) { cwidth = realwidth; - cheight = realheight * BaseRatioSizes[ratio][3] / 48; + cheight = realheight * AspectMultiplier(ratio) / 48; } else { - cwidth = realwidth * BaseRatioSizes[ratio][3] / 48; + cwidth = realwidth * AspectMultiplier(ratio) / 48; cheight = realheight; } // Use whichever pair of cwidth/cheight or width/height that produces less difference @@ -1701,26 +1701,6 @@ int CheckRatio (int width, int height, int *trueratio) return fakeratio; } -// First column: Base width -// Second column: Base height (used for wall visibility multiplier) -// Third column: Psprite offset (needed for "tallscreen" modes) -// Fourth column: Width or height multiplier - -// For widescreen aspect ratio x:y ... -// base_width = 240 * x / y -// multiplier = 320 / base_width -// base_height = 200 * multiplier -const int BaseRatioSizes[7][4] = -{ - { 960, 600, 0, 48 }, // 4:3 320, 200, multiplied by three - { 1280, 450, 0, 48*3/4 }, // 16:9 426.6667, 150, multiplied by three - { 1152, 500, 0, 48*5/6 }, // 16:10 386, 166.6667, multiplied by three - { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three - { 960, 640, (int)(6.5*FRACUNIT), 48*15/16 }, // 5:4 320, 213.3333, multiplied by three - { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three (REDUNDANT) - { 1707, 338, 0, 48*9/16 } // 21:9 568.8889, 337.5, multiplied by three -}; - int AspectBaseWidth(float aspect) { return (int)round(240.0f * aspect * 3.0f); diff --git a/src/v_video.h b/src/v_video.h index 2dc3bbddc3..8d785e43ff 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -516,6 +516,8 @@ extern "C" void ASM_PatchPitch (void); int CheckRatio (int width, int height, int *trueratio=NULL); static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); } +inline bool IsRatioWidescreen(int ratio) { return (ratio & 3) != 0; } + float ActiveRatio (int width, int height, float *trueratio = NULL); static inline double ActiveRatio (double width, double height) { return ActiveRatio(int(width), int(height)); } @@ -523,15 +525,6 @@ int AspectBaseWidth(float aspect); int AspectBaseHeight(float aspect); int AspectPspriteOffset(float aspect); int AspectMultiplier(float aspect); -extern const int BaseRatioSizes[7][4]; - -inline bool IsRatioWidescreen(int ratio) { - return (ratio & 3)!=0; -} - -inline bool Is54Aspect(int ratio) { - return ratio == 4; -} EXTERN_CVAR(Int, uiscale); From 4e58e6626cf0372a3fbca5649a66aa7e2441554c Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 16:05:42 +0200 Subject: [PATCH 08/22] Fix buffer overrun in CommandAspectRatio for 21:9 aspect ratio --- src/g_shared/sbarinfo_commands.cpp | 33 +++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index a9fac2ee10..47785076e2 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -1914,7 +1914,7 @@ class CommandAspectRatio : public SBarInfoCommandFlowControl { SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); - SetTruth(ratioMap[CheckRatio(screen->GetWidth(), screen->GetHeight())] == ratio, block, statusBar); + SetTruth(ratioMap[FindRatio()] == ratio, block, statusBar); } protected: enum Ratio @@ -1931,6 +1931,37 @@ class CommandAspectRatio : public SBarInfoCommandFlowControl static Ratio ratioMap[5]; Ratio ratio; + + private: + int FindRatio() + { + float aspect = ActiveRatio(screen->GetWidth(), screen->GetHeight()); + + static std::pair ratioTypes[] = + { + { 21 / 9.0f , ASPECTRATIO_16_9 }, + { 16 / 9.0f , ASPECTRATIO_16_9 }, + { 17 / 10.0f , ASPECTRATIO_17_10 }, + { 16 / 10.0f , ASPECTRATIO_16_10 }, + { 4 / 3.0f , ASPECTRATIO_4_3 }, + { 5 / 4.0f , ASPECTRATIO_5_4 }, + { 0.0f, 0 } + }; + + int ratio = ratioTypes[0].second; + float distance = abs(ratioTypes[0].first - aspect); + for (int i = 1; ratioTypes[i].first != 0.0f; i++) + { + float d = abs(ratioTypes[i].first - aspect); + if (d < distance) + { + ratio = ratioTypes[i].second; + distance = d; + } + } + + return ratio; + } }; CommandAspectRatio::Ratio CommandAspectRatio::ratioMap[5] = {ASPECTRATIO_4_3,ASPECTRATIO_16_9,ASPECTRATIO_16_10,ASPECTRATIO_16_10,ASPECTRATIO_5_4}; From 01b1efe9eec9877a409d14f749b9934a10224a58 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 12 Sep 2016 18:44:04 +0200 Subject: [PATCH 09/22] Switch from abs to fabs --- src/g_shared/sbarinfo_commands.cpp | 4 ++-- src/v_video.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 47785076e2..b7827f6bd8 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -1949,10 +1949,10 @@ class CommandAspectRatio : public SBarInfoCommandFlowControl }; int ratio = ratioTypes[0].second; - float distance = abs(ratioTypes[0].first - aspect); + float distance = fabs(ratioTypes[0].first - aspect); for (int i = 1; ratioTypes[i].first != 0.0f; i++) { - float d = abs(ratioTypes[i].first - aspect); + float d = fabs(ratioTypes[i].first - aspect); if (d < distance) { ratio = ratioTypes[i].second; diff --git a/src/v_video.cpp b/src/v_video.cpp index 43458dc637..20e1f526c5 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1681,10 +1681,10 @@ int CheckRatio (int width, int height, int *trueratio) }; int ratio = ratioTypes[0].second; - float distance = abs(ratioTypes[0].first - aspect); + float distance = fabs(ratioTypes[0].first - aspect); for (int i = 1; ratioTypes[i].first != 0.0f; i++) { - float d = abs(ratioTypes[i].first - aspect); + float d = fabs(ratioTypes[i].first - aspect); if (d < distance) { ratio = ratioTypes[i].second; From a2a1d2a36d0b8e7c921f5310ca478f16ccf9034c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 6 Sep 2016 11:55:29 +0300 Subject: [PATCH 10/22] Fixed significant distortion of sound effects with FMOD Studio API --- src/sound/fmodsound.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 2db5a98a10..81bbfb8c1f 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -2758,6 +2758,16 @@ std::pair FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int l exinfo.defaultfrequency = frequency; switch (bits) { +#if FMOD_STUDIO + case -8: + // Need to convert sample data from signed to unsigned. + for (int i = 0; i < length; i++) + { + sfxdata[i] ^= 0x80; + } + + case 8: +#else // !FMOD_STUDIO case 8: // Need to convert sample data from unsigned to signed. for (int i = 0; i < length; ++i) @@ -2766,6 +2776,7 @@ std::pair FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int l } case -8: +#endif // FMOD_STUDIO exinfo.format = FMOD_SOUND_FORMAT_PCM8; numsamples = length; break; From 764705a8e065889c2b896076642091b21e3ce46b Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 6 Sep 2016 11:34:15 +0300 Subject: [PATCH 11/22] Fixed 'Could not set resampler method. Defaults will be used. (Error 31)' message with FMOD Studio API --- src/sound/fmodsound.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 81bbfb8c1f..e45385210d 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -971,6 +971,7 @@ bool FMODSoundRenderer::Init() #if FMOD_STUDIO FMOD_ADVANCEDSETTINGS advSettings = {}; + advSettings.cbSize = sizeof advSettings; advSettings.resamplerMethod = resampler; result = Sys->setAdvancedSettings(&advSettings); if (result != FMOD_OK) From c88eec3d7361f2fd83a445cfcf08c18effe2a53d Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 6 Sep 2016 10:23:12 +0300 Subject: [PATCH 12/22] Fixed 'unreferenced local variable' warnings when building with FMOD Studio API --- src/sound/fmodsound.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index e45385210d..c130b7e6ae 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -1371,11 +1371,8 @@ void FMODSoundRenderer::PrintStatus() { FMOD_OUTPUTTYPE output; FMOD_SPEAKERMODE speakermode; - FMOD_SOUND_FORMAT format; - FMOD_DSP_RESAMPLER resampler; int driver; int samplerate; - int numoutputchannels; unsigned int bufferlength; int numbuffers; @@ -1414,6 +1411,9 @@ void FMODSoundRenderer::PrintStatus() #endif } #if !FMOD_STUDIO + FMOD_SOUND_FORMAT format; + FMOD_DSP_RESAMPLER resampler; + int numoutputchannels; if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &format, &numoutputchannels, NULL, &resampler, NULL)) { Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: " TEXTCOLOR_GREEN "%d\n", samplerate); From 7e61a1ce2b8108375e7089f26548e70ce4c7cc0b Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 6 Sep 2016 12:35:22 +0300 Subject: [PATCH 13/22] Added simple detection for FMOD Studio API in CMake --- src/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 190a9560a3..025d651c39 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -272,6 +272,10 @@ if( NOT NO_FMOD ) if( FMOD_INCLUDE_DIR ) message( STATUS "FMOD include files found at ${FMOD_INCLUDE_DIR}" ) include_directories( "${FMOD_INCLUDE_DIR}" ) + + if( EXISTS "${FMOD_INCLUDE_DIR}/fmod_common.h" ) + set( FMOD_STUDIO YES ) + endif() else() message( STATUS "Could not find FMOD include files" ) set( NO_FMOD ON ) From 9c91686e0fa2fc1af18c06e05ac9f6e33e0dc068 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 6 Sep 2016 12:36:30 +0300 Subject: [PATCH 14/22] Set delay loading for proper .dll depending on FMOD version (Studio vs. Ex) --- src/CMakeLists.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 025d651c39..841c06a6f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1343,7 +1343,16 @@ endif() if( MSVC ) option( ZDOOM_GENERATE_MAPFILE "Generate .map file for debugging." OFF ) - set( LINKERSTUFF "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\"" ) + set( LINKERSTUFF "/MANIFEST:NO" ) + + if( NOT NO_FMOD ) + if( FMOD_STUDIO ) + set( LINKERSTUFF "${LINKERSTUFF} /DELAYLOAD:\"fmod${X64}.dll\"" ) + else() + set( LINKERSTUFF "${LINKERSTUFF} /DELAYLOAD:\"fmodex${X64}.dll\"" ) + endif() + endif() + if( ZDOOM_GENERATE_MAPFILE ) set( LINKERSTUFF "${LINKERSTUFF} /MAP" ) endif() From b308a7df52dc9d6a223ddb53365a1852f0205d54 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 6 Sep 2016 12:43:57 +0300 Subject: [PATCH 15/22] Proper name of FMOD .dylib in loading path adjustment for macOS --- src/CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 841c06a6f3..bb5f213088 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1392,17 +1392,23 @@ if( APPLE ) MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/zdoom-info.plist" ) if( NOT NO_FMOD ) + if( FMOD_STUDIO ) + set( FMOD_DYLIB libfmod.dylib ) + else() + set( FMOD_DYLIB libfmodex.dylib ) + endif() + # Fix fmod link so that it can be found in the app bundle. find_program( OTOOL otool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" ) find_program( INSTALL_NAME_TOOL install_name_tool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" ) execute_process( COMMAND "${OTOOL}" -L "${FMOD_LIBRARY}" - COMMAND grep "libfmodex.dylib (compat" + COMMAND grep "${FMOD_DYLIB} (compat" COMMAND head -n1 COMMAND awk "{print $1}" OUTPUT_VARIABLE FMOD_LINK OUTPUT_STRIP_TRAILING_WHITESPACE ) add_custom_command( TARGET zdoom POST_BUILD - COMMAND "${INSTALL_NAME_TOOL}" -change "${FMOD_LINK}" @executable_path/../Frameworks/libfmodex.dylib "$" + COMMAND "${INSTALL_NAME_TOOL}" -change "${FMOD_LINK}" @executable_path/../Frameworks/${FMOD_DYLIB} "$" COMMENT "Relinking FMOD Ex" ) endif() endif() From 823f75e59239093a0947667ead7fbefa484cb851 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 Sep 2016 21:32:17 +0200 Subject: [PATCH 16/22] - fixed: UDMF user value lists need to be sorted for binary search to work but weren't. --- src/p_udmf.cpp | 5 +++++ src/r_defs.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 0b054247eb..c09debc512 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -309,6 +309,11 @@ void FUDMFKeys::Sort() FUDMFKey *FUDMFKeys::Find(FName key) { + if (!mSorted) + { + mSorted = true; + Sort(); + } int min = 0, max = Size()-1; while (min <= max) diff --git a/src/r_defs.h b/src/r_defs.h index f27ac27168..59b1fe0d37 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -220,6 +220,7 @@ struct FUDMFKey class FUDMFKeys : public TArray { + bool mSorted = false; public: void Sort(); FUDMFKey *Find(FName key); From e10abcad067b7786cabec0e723c7c61def64b6a1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 Sep 2016 10:43:53 +0200 Subject: [PATCH 17/22] - fixed: The TabCommands array needs to be cleared before the NameManager is destroyed. TabCommands use an FName to store the command's name so once the NameManager is destroyed its data will become invalid. This is a problem because C_RemoveTabCommand is being called from FBaseCVar's destructor and most CVARs are global variables. --- src/name.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/name.cpp b/src/name.cpp index 8140829c68..ecedcf0f31 100644 --- a/src/name.cpp +++ b/src/name.cpp @@ -35,6 +35,7 @@ #include #include "name.h" #include "c_dispatch.h" +#include "c_console.h" // MACROS ------------------------------------------------------------------ @@ -268,6 +269,8 @@ FName::NameManager::~NameManager() { NameBlock *block, *next; + C_ClearTabCommands(); + for (block = Blocks; block != NULL; block = next) { next = block->NextBlock; From ba68cfd61153ed260ae1cf3c8dc7e4986ee4fa69 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 Sep 2016 21:01:50 +0200 Subject: [PATCH 18/22] - do not even allow creation of names in C_RemoveTabCommands if there are no tab commands, so that FindName cannot be called after the NameManager has been destroyed. --- src/c_console.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/c_console.cpp b/src/c_console.cpp index 0868612292..2d164c4787 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1747,6 +1747,14 @@ void C_AddTabCommand (const char *name) void C_RemoveTabCommand (const char *name) { + if (TabCommands.Size() == 0) + { + // There are no tab commands that can be removed. + // This is important to skip construction of aname + // in case the NameManager has already been destroyed. + return; + } + FName aname(name, true); if (aname == NAME_None) From 172f58c1655848df85d35676a4a5aeb094d05b2c Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 13 Sep 2016 11:46:05 +0200 Subject: [PATCH 19/22] Fix 5:4 aspect ratio gun and status bar --- src/g_shared/shared_sbar.cpp | 2 +- src/r_main.cpp | 4 ++-- src/r_utility.cpp | 2 +- src/v_draw.cpp | 4 ++-- src/v_video.cpp | 19 +++++++++++++------ src/v_video.h | 3 ++- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 3c41d18ca6..22171a4bbe 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -300,7 +300,7 @@ void DBaseStatusBar::SetScaled (bool scale, bool force) ST_X = 0; ST_Y = VirticalResolution - RelTop; float aspect = ActiveRatio(SCREENWIDTH, SCREENHEIGHT); - if (aspect >= 1.3f) + if (!Is54Aspect(aspect)) { // Normal resolution ::ST_Y = Scale (ST_Y, SCREENHEIGHT, VirticalResolution); } diff --git a/src/r_main.cpp b/src/r_main.cpp index d84698b7cf..6094f70def 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -318,7 +318,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, virtwidth = virtwidth2 = fullWidth; virtheight = virtheight2 = fullHeight; - if (trueratio < 1.3f) + if (Is54Aspect(trueratio)) { virtheight2 = virtheight2 * AspectMultiplier(trueratio) / 48; } @@ -327,7 +327,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, virtwidth2 = virtwidth2 * AspectMultiplier(trueratio) / 48; } - if (WidescreenRatio < 1.3f) + if (Is54Aspect(WidescreenRatio)) { virtheight = virtheight * AspectMultiplier(WidescreenRatio) / 48; } diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 8e4284b7e3..76cf05e9b5 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -229,7 +229,7 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) centery = viewheight/2; centerx = viewwidth/2; - if (WidescreenRatio < 1.3f) + if (Is54Aspect(WidescreenRatio)) { centerxwide = centerx; } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index a33fd618bc..3075cd92d8 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -887,7 +887,7 @@ void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, x = x * Width / vwidth; w = right * Width / vwidth - x; } - if (myratio < 1.3f) + if (Is54Aspect(myratio)) { // The target surface is 5:4 y = (y - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5; h = (bottom - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5 - y; @@ -950,7 +950,7 @@ void DCanvas::FillBorder (FTexture *img) return; } int bordtop, bordbottom, bordleft, bordright, bord; - if (myratio < 1.3f) + if (Is54Aspect(myratio)) { // Screen is taller than it is wide bordleft = bordright = 0; bord = Height - Height * AspectMultiplier(myratio) / 48; diff --git a/src/v_video.cpp b/src/v_video.cpp index 20e1f526c5..710d8b1cf2 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1362,7 +1362,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real int cx1, cy1, cx2, cy2; ratio = ActiveRatio(realwidth, realheight); - if (ratio < 1.3f) + if (Is54Aspect(ratio)) { cwidth = realwidth; cheight = realheight * AspectMultiplier(ratio) / 48; @@ -1703,22 +1703,29 @@ int CheckRatio (int width, int height, int *trueratio) int AspectBaseWidth(float aspect) { - return (int)round(240.0f * aspect * 3.0f); + return !Is54Aspect(aspect) ? (int)round(240.0f * aspect * 3.0f) : 960; } int AspectBaseHeight(float aspect) { - return (int)round(200.0f * (320.0f / (240.0f * aspect)) * 3.0f); + return !Is54Aspect(aspect) ? (int)round(200.0f * (320.0f / (240.0f * aspect)) * 3.0f) : 640; } -int AspectPspriteOffset(float aspect) +double AspectPspriteOffset(float aspect) { - return aspect < 1.3f ? (int)(6.5*FRACUNIT) : 0; + return !Is54Aspect(aspect) ? 0.0 : 6.5; } int AspectMultiplier(float aspect) { - return (int)round(320.0f / (240.0f * aspect) * 48.0f); + return !Is54Aspect(aspect) ? (int)round(320.0f / (240.0f * aspect) * 48.0f) : 48 * 15 / 16; +} + +bool Is54Aspect(float aspect) +{ + // The 5:4 aspect ratio redefined all the values to mean something else.. + // Limit the range this is active to try prevent square cam textures inheriting this madness. + return aspect > 1.1f && aspect < 1.3f; } void IVideo::DumpAdapters () diff --git a/src/v_video.h b/src/v_video.h index 8d785e43ff..26d45d9a01 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -523,8 +523,9 @@ static inline double ActiveRatio (double width, double height) { return ActiveRa int AspectBaseWidth(float aspect); int AspectBaseHeight(float aspect); -int AspectPspriteOffset(float aspect); +double AspectPspriteOffset(float aspect); int AspectMultiplier(float aspect); +bool Is54Aspect(float aspect); EXTERN_CVAR(Int, uiscale); From 017d1cee29adf2b2b479cc26dbb8ac5f461f5f0a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 13 Sep 2016 23:26:30 +0200 Subject: [PATCH 20/22] Change canvas rendering to use the aspect ratio of the canvas and generalize 5:4 rendering as AspectTallerThanWide --- src/g_shared/shared_sbar.cpp | 2 +- src/r_main.cpp | 6 +++--- src/r_utility.cpp | 14 +++++++++++--- src/r_utility.h | 2 +- src/v_draw.cpp | 6 +++--- src/v_video.cpp | 25 ++++++++++++++++--------- src/v_video.h | 2 +- 7 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 22171a4bbe..f66ec187da 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -300,7 +300,7 @@ void DBaseStatusBar::SetScaled (bool scale, bool force) ST_X = 0; ST_Y = VirticalResolution - RelTop; float aspect = ActiveRatio(SCREENWIDTH, SCREENHEIGHT); - if (!Is54Aspect(aspect)) + if (!AspectTallerThanWide(aspect)) { // Normal resolution ::ST_Y = Scale (ST_Y, SCREENHEIGHT, VirticalResolution); } diff --git a/src/r_main.cpp b/src/r_main.cpp index 6094f70def..040b57b716 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -318,7 +318,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, virtwidth = virtwidth2 = fullWidth; virtheight = virtheight2 = fullHeight; - if (Is54Aspect(trueratio)) + if (AspectTallerThanWide(trueratio)) { virtheight2 = virtheight2 * AspectMultiplier(trueratio) / 48; } @@ -327,7 +327,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, virtwidth2 = virtwidth2 * AspectMultiplier(trueratio) / 48; } - if (Is54Aspect(WidescreenRatio)) + if (AspectTallerThanWide(WidescreenRatio)) { virtheight = virtheight * AspectMultiplier(WidescreenRatio) / 48; } @@ -948,7 +948,7 @@ void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, RenderTarget = canvas; bRenderingToCanvas = true; - R_SetWindow (12, width, height, height); + R_SetWindow (12, width, height, height, true); viewwindowx = x; viewwindowy = y; viewactive = true; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 76cf05e9b5..ebe36dc9d7 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -198,7 +198,7 @@ void R_SetViewSize (int blocks) // //========================================================================== -void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) +void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas) { float trueratio; @@ -220,7 +220,15 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) freelookviewheight = ((setblocks*fullHeight)/10)&~7; } - WidescreenRatio = ActiveRatio (fullWidth, fullHeight, &trueratio); + if (renderingToCanvas) + { + WidescreenRatio = fullWidth / (float)fullHeight; + trueratio = WidescreenRatio; + } + else + { + WidescreenRatio = ActiveRatio(fullWidth, fullHeight, &trueratio); + } DrawFSHUD = (windowSize == 11); @@ -229,7 +237,7 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) centery = viewheight/2; centerx = viewwidth/2; - if (Is54Aspect(WidescreenRatio)) + if (AspectTallerThanWide(WidescreenRatio)) { centerxwide = centerx; } diff --git a/src/r_utility.h b/src/r_utility.h index e9fd436e50..09a8b56678 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -95,7 +95,7 @@ void R_ExecuteSetViewSize (void); // Called by M_Responder. void R_SetViewSize (int blocks); -void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight); +void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas = false); extern void R_FreePastViewers (); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 3075cd92d8..4677c4b087 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -874,7 +874,7 @@ void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, double right = x + w; double bottom = y + h; - if (myratio > 1.4f) + if (myratio > 1.334f) { // The target surface is either 16:9 or 16:10, so expand the // specified virtual size to avoid undesired stretching of the // image. Does not handle non-4:3 virtual sizes. I'll worry about @@ -887,7 +887,7 @@ void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, x = x * Width / vwidth; w = right * Width / vwidth - x; } - if (Is54Aspect(myratio)) + if (AspectTallerThanWide(myratio)) { // The target surface is 5:4 y = (y - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5; h = (bottom - vheight * 0.5) * Height * 600 / (vheight * AspectBaseHeight(myratio)) + Height * 0.5 - y; @@ -950,7 +950,7 @@ void DCanvas::FillBorder (FTexture *img) return; } int bordtop, bordbottom, bordleft, bordright, bord; - if (Is54Aspect(myratio)) + if (AspectTallerThanWide(myratio)) { // Screen is taller than it is wide bordleft = bordright = 0; bord = Height - Height * AspectMultiplier(myratio) / 48; diff --git a/src/v_video.cpp b/src/v_video.cpp index 710d8b1cf2..af190d3724 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1362,7 +1362,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real int cx1, cy1, cx2, cy2; ratio = ActiveRatio(realwidth, realheight); - if (Is54Aspect(ratio)) + if (AspectTallerThanWide(ratio)) { cwidth = realwidth; cheight = realheight * AspectMultiplier(ratio) / 48; @@ -1703,29 +1703,36 @@ int CheckRatio (int width, int height, int *trueratio) int AspectBaseWidth(float aspect) { - return !Is54Aspect(aspect) ? (int)round(240.0f * aspect * 3.0f) : 960; + return (int)round(240.0f * aspect * 3.0f); } int AspectBaseHeight(float aspect) { - return !Is54Aspect(aspect) ? (int)round(200.0f * (320.0f / (240.0f * aspect)) * 3.0f) : 640; + if (!AspectTallerThanWide(aspect)) + return (int)round(200.0f * (320.0f / (AspectBaseWidth(aspect) / 3.0f)) * 3.0f); + else + return (int)round((200.0f * (4.0f / 3.0f)) / aspect * 3.0f); } double AspectPspriteOffset(float aspect) { - return !Is54Aspect(aspect) ? 0.0 : 6.5; + if (!AspectTallerThanWide(aspect)) + return 0.0; + else + return ((4.0 / 3.0) / aspect - 1.0) * 97.5; } int AspectMultiplier(float aspect) { - return !Is54Aspect(aspect) ? (int)round(320.0f / (240.0f * aspect) * 48.0f) : 48 * 15 / 16; + if (!AspectTallerThanWide(aspect)) + return (int)round(320.0f / (AspectBaseWidth(aspect) / 3.0f) * 48.0f); + else + return (int)round(200.0f / (AspectBaseHeight(aspect) / 3.0f) * 48.0f); } -bool Is54Aspect(float aspect) +bool AspectTallerThanWide(float aspect) { - // The 5:4 aspect ratio redefined all the values to mean something else.. - // Limit the range this is active to try prevent square cam textures inheriting this madness. - return aspect > 1.1f && aspect < 1.3f; + return aspect < 1.333f; } void IVideo::DumpAdapters () diff --git a/src/v_video.h b/src/v_video.h index 26d45d9a01..7317c9d1a3 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -525,7 +525,7 @@ int AspectBaseWidth(float aspect); int AspectBaseHeight(float aspect); double AspectPspriteOffset(float aspect); int AspectMultiplier(float aspect); -bool Is54Aspect(float aspect); +bool AspectTallerThanWide(float aspect); EXTERN_CVAR(Int, uiscale); From f1bca9d20e7d36b3057cc9faee7da213d9cbedd0 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 13 Sep 2016 20:10:06 -0400 Subject: [PATCH 21/22] The old DirectX setup is required to utilize v140_xp. Revert "- removed DirectX setup from CMakeLists for Visual Studio" This reverts commit 954ac8ce5e607e7811a91717e0e1cfe5126d820a. --- src/CMakeLists.txt | 86 ++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 48 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bb5f213088..7f1554f444 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -114,59 +114,49 @@ if( WIN32 ) set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib ) set( NASM_NAMES nasmw nasm ) - if( NOT MSVC ) - find_path( D3D_INCLUDE_DIR d3d9.h - PATHS ENV DXSDK_DIR - PATH_SUFFIXES Include ) - if( NOT D3D_INCLUDE_DIR ) - message( SEND_ERROR "Could not find DirectX 9 header files" ) - else() - include_directories( ${D3D_INCLUDE_DIR} ) - endif() - - find_path( XINPUT_INCLUDE_DIR xinput.h - PATHS ENV DXSDK_DIR - PATH_SUFFIXES Include ) - if( NOT XINPUT_INCLUDE_DIR ) - message( WARNING "Could not find xinput.h. XInput will be disabled." ) - add_definitions( -DNO_XINPUT ) - else() - include_directories( ${XINPUT_INCLUDE_DIR} ) - endif() - - find_library( DX_dxguid_LIBRARY dxguid - PATHS ENV DXSDK_DIR - PATH_SUFFIXES Lib Lib/${XBITS} ) - find_library( DX_dinput8_LIBRARY dinput8 - PATHS ENV DXSDK_DIR - PATH_SUFFIXES Lib Lib/${XBITS} ) - - set( DX_LIBS_FOUND YES ) - if( NOT DX_dxguid_LIBRARY ) - set( DX_LIBS_FOUND NO ) - endif() - if( NOT DX_dinput8_LIBRARY ) - set( DX_LIBS_FOUND NO ) - endif() - - if( NOT DX_LIBS_FOUND ) - message( FATAL_ERROR "Could not find DirectX 9 libraries" ) - endif() - - set( DX_LIBS - "${DX_dxguid_LIBRARY}" - "${DX_dinput8_LIBRARY}" - ) + find_path( D3D_INCLUDE_DIR d3d9.h + PATHS ENV DXSDK_DIR + PATH_SUFFIXES Include ) + if( NOT D3D_INCLUDE_DIR ) + message( SEND_ERROR "Could not find DirectX 9 header files" ) else() - set( DX_LIBS - dxguid - dinput8 - ) + include_directories( ${D3D_INCLUDE_DIR} ) + endif() + + find_path( XINPUT_INCLUDE_DIR xinput.h + PATHS ENV DXSDK_DIR + PATH_SUFFIXES Include ) + if( NOT XINPUT_INCLUDE_DIR ) + message( WARNING "Could not find xinput.h. XInput will be disabled." ) + add_definitions( -DNO_XINPUT ) + else() + include_directories( ${XINPUT_INCLUDE_DIR} ) endif() - set( ZDOOM_LIBS ${DX_LIBS} + find_library( DX_dxguid_LIBRARY dxguid + PATHS ENV DXSDK_DIR + PATH_SUFFIXES Lib Lib/${XBITS} ) + find_library( DX_dinput8_LIBRARY dinput8 + PATHS ENV DXSDK_DIR + PATH_SUFFIXES Lib Lib/${XBITS} ) + + set( DX_LIBS_FOUND YES ) + if( NOT DX_dxguid_LIBRARY ) + set( DX_LIBS_FOUND NO ) + endif() + if( NOT DX_dinput8_LIBRARY ) + set( DX_LIBS_FOUND NO ) + endif() + + if( NOT DX_LIBS_FOUND ) + message( FATAL_ERROR "Could not find DirectX 9 libraries" ) + endif() + + set( ZDOOM_LIBS wsock32 winmm + "${DX_dxguid_LIBRARY}" + "${DX_dinput8_LIBRARY}" ole32 user32 gdi32 From fd53aefbf27e4ffd2423d027d10f95b3be07dead Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 13 Sep 2016 20:54:06 -0400 Subject: [PATCH 22/22] Added warning if building on Visual Studio 2015 without v140_xp. --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f0bf8293c..9d7da1644d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,11 @@ list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ) include( CreateLaunchers ) include( FindPackageHandleStandardArgs ) +# Produce a warning if XP support will be missing. +if( MSVC14 AND NOT CMAKE_GENERATOR_TOOLSET STREQUAL "v140_xp" ) + message( WARNING "This project supports Windows XP (including XP x64), but you must set the optional toolset to v140_xp manually to have it in your build! Use -T \"v140_xp\" from the command prompt." ) +endif() + # Support cross compiling option( FORCE_CROSSCOMPILE "Turn on cross compiling." NO ) if( FORCE_CROSSCOMPILE )