diff --git a/SADXModLoader/config.cpp b/SADXModLoader/config.cpp index a4d3d476..6df5fe45 100644 --- a/SADXModLoader/config.cpp +++ b/SADXModLoader/config.cpp @@ -71,6 +71,8 @@ void LoadModLoaderSettings(LoaderSettings* loaderSettings, std::wstring appPath) loaderSettings->VerticalResolution = json_graphics.value("VerticalResolution", 480); loaderSettings->ForceAspectRatio = json_graphics.value("Enable43ResolutionRatio", false); loaderSettings->EnableVsync = json_graphics.value("EnableVsync", true); + loaderSettings->Antialiasing = json_graphics.value("Antialiasing", 0); + loaderSettings->Anisotropic = json_graphics.value("Anisotropic", 0); loaderSettings->PauseWhenInactive = json_graphics.value("EnablePauseOnInactive", true); //loaderSettings->WindowedFullscreen = json_graphics.value("EnableBorderless", true); //loaderSettings->CustomWindowSize = json_graphics.value("EnableCustomWindow", false); diff --git a/SADXModLoader/direct3d.cpp b/SADXModLoader/direct3d.cpp index 678b6a94..3d6d94c5 100644 --- a/SADXModLoader/direct3d.cpp +++ b/SADXModLoader/direct3d.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" - #include "direct3d.h" - #include "include/d3d8types.h" #include "FixFOV.h" #include "uiscale.h" @@ -10,6 +8,8 @@ DataPointer(D3DVIEWPORT8, Direct3D_ViewPort, 0x3D12780); DataPointer(D3DCAPS8, Direct3D_DeviceCaps, 0x03D127C0); static bool vsync = false; +static D3DMULTISAMPLE_TYPE antialiasing = D3DMULTISAMPLE_NONE; +static int anisotropy = 0; // oh god static const D3DRENDERSTATETYPE D3DRENDERSTATE_TYPES[] = { @@ -224,8 +224,6 @@ inline void setup_vsync() if (vsync) { - //using D3DSWAPEFFECT_DISCARD here causes stuttering, consider adding a toggle if you really want it. - //p.SwapEffect = d3d9 ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_COPY_VSYNC; p.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC; p.FullScreen_PresentationInterval = (IsWindowed && !d3d9) ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_ONE; } @@ -236,6 +234,31 @@ inline void setup_vsync() } } +inline void setup_aa() +{ + if (!antialiasing) + return; + + auto& p = PresentParameters; + + D3DMULTISAMPLE_TYPE MSType = D3DMULTISAMPLE_NONE; + + if (antialiasing >= 16 && SUCCEEDED(Direct3D_Object->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, PresentParameters.BackBufferFormat, PresentParameters.Windowed, D3DMULTISAMPLE_16_SAMPLES))) + MSType = D3DMULTISAMPLE_16_SAMPLES; + else if (antialiasing >= 8 && SUCCEEDED(Direct3D_Object->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, PresentParameters.BackBufferFormat, PresentParameters.Windowed, D3DMULTISAMPLE_8_SAMPLES))) + MSType = D3DMULTISAMPLE_8_SAMPLES; + else if (antialiasing >= 4 && SUCCEEDED(Direct3D_Object->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, PresentParameters.BackBufferFormat, PresentParameters.Windowed, D3DMULTISAMPLE_4_SAMPLES))) + MSType = D3DMULTISAMPLE_4_SAMPLES; + else if (antialiasing >= 2 && SUCCEEDED(Direct3D_Object->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, PresentParameters.BackBufferFormat, PresentParameters.Windowed, D3DMULTISAMPLE_2_SAMPLES))) + MSType = D3DMULTISAMPLE_2_SAMPLES; + + if (MSType != D3DMULTISAMPLE_NONE) + { + p.SwapEffect = D3DSWAPEFFECT_DISCARD; + p.MultiSampleType = MSType; + } +} + void __fastcall CreateDirect3DDevice_r(void*, int behavior, D3DDEVTYPE type) { if (Direct3D_Device != nullptr) @@ -245,6 +268,8 @@ void __fastcall CreateDirect3DDevice_r(void*, int behavior, D3DDEVTYPE type) setup_vsync(); + setup_aa(); + auto result = Direct3D_Object->CreateDevice(DisplayAdapter, type, PresentParameters.hDeviceWindow, behavior, &PresentParameters, &Direct3D_Device); @@ -252,6 +277,13 @@ void __fastcall CreateDirect3DDevice_r(void*, int behavior, D3DDEVTYPE type) { Direct3D_Device = nullptr; } + else + { + if (antialiasing != D3DMULTISAMPLE_NONE) + Direct3D_Device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + if (anisotropy) + Direct3D_Device->SetTextureStageState(0, D3DTSS_MAXANISOTROPY, anisotropy); + } } void __cdecl Direct3D_EndScene_r(); @@ -298,6 +330,16 @@ void direct3d::set_vsync(bool value) vsync = value; } +void direct3d::set_aa(int value) +{ + antialiasing = (D3DMULTISAMPLE_TYPE)value; +} + +void direct3d::set_af(int value) +{ + anisotropy = value; +} + void direct3d::reset_device() { const auto retry_count = 5; @@ -306,6 +348,7 @@ void direct3d::reset_device() Uint32 tries = 0; setup_vsync(); + setup_aa(); auto level = D3DERR_DEVICENOTRESET; RaiseEvents(modRenderDeviceLost); diff --git a/SADXModLoader/direct3d.h b/SADXModLoader/direct3d.h index 0081ae1f..2246d3e8 100644 --- a/SADXModLoader/direct3d.h +++ b/SADXModLoader/direct3d.h @@ -89,6 +89,8 @@ namespace direct3d { void init(); void set_vsync(bool value); + void set_aa(int value); + void set_af(int value); void reset_device(); void change_resolution(uint32_t width, uint32_t height); void change_resolution(uint32_t width, uint32_t height, bool windowed); diff --git a/SADXModLoader/dllmain.cpp b/SADXModLoader/dllmain.cpp index 9d49f696..ef27dd60 100644 --- a/SADXModLoader/dllmain.cpp +++ b/SADXModLoader/dllmain.cpp @@ -384,6 +384,12 @@ void __cdecl Direct3D_TextureFilterPoint_ForceLinear() Direct3D_Device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); Direct3D_Device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); Direct3D_Device->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + // Maybe use D3DTEXF_ANISOTROPIC here instead? Not sure + /* + Direct3D_Device->SetTextureStageState(0, D3DTSS_MAGFILTER, loaderSettings.Anisotropic ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR); + Direct3D_Device->SetTextureStageState(0, D3DTSS_MINFILTER, loaderSettings.Anisotropic ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR); + Direct3D_Device->SetTextureStageState(0, D3DTSS_MIPFILTER, loaderSettings.Anisotropic ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR); + */ } void __cdecl SetPreferredFilterOption() @@ -909,13 +915,21 @@ static void __cdecl InitMods() PatchWindow(loaderSettings); // override window creation function - // Other various settings. + // Other various settings if (IsGamePatchEnabled("DisableCDCheck")) WriteJump((void*)0x402621, (void*)0x402664); if (loaderSettings.AutoMipmap) mipmap::enable_auto_mipmaps(); + if (loaderSettings.Anisotropic) + { + // gjRender2DReset: set MIN/MIP/MAG filter to anisotropic instead of linear + WriteData<1>((char*)0x0078B808, (char)D3DTEXF_ANISOTROPIC); + WriteData<1>((char*)0x0078B81C, (char)D3DTEXF_ANISOTROPIC); + WriteData<1>((char*)0x0078B830, (char)D3DTEXF_ANISOTROPIC); + } + // Hijack a ton of functions in SADX. *(void**)0x38A5DB8 = (void*)0x38A5D94; // depth buffer fix WriteData((short*)0x50473E, (short)0x00EB); // File select bullshit lol @@ -949,6 +963,8 @@ static void __cdecl InitMods() } direct3d::set_vsync(loaderSettings.EnableVsync); + direct3d::set_aa(loaderSettings.Antialiasing); + direct3d::set_af(loaderSettings.Anisotropic); if (loaderSettings.ScaleHud) { diff --git a/SADXModLoader/include/SADXModInfo.h b/SADXModLoader/include/SADXModInfo.h index 110a335d..5ff44c2b 100644 --- a/SADXModLoader/include/SADXModInfo.h +++ b/SADXModLoader/include/SADXModInfo.h @@ -12,7 +12,7 @@ #include "WeightInfo.h" // SADX Mod Loader API version. -static const int ModLoaderVer = 25; +static const int ModLoaderVer = 26; // Patch-type codes struct PatchInfo @@ -103,7 +103,9 @@ struct LoaderSettings // Graphics int ScreenMode; // Window Mode (Windowed, Fullscreen, Borderless Fullscren, or Custom Window); requires version 20+ bool ShowMouseInFullscreen; // Displays Cursor when in Fullscreen; requires version 20+ - bool DisableBorderImage; // Requires version >= 25. + bool DisableBorderImage; // Requires version >= 25 + int Antialiasing; // Requires version >= 26 + int Anisotropic; // Requires version >= 26 }; struct ModDependency