sfall-team / sfall

sfall - Engine modifications for Fallout 2
https://sfall-team.github.io/sfall/
GNU General Public License v3.0
342 stars 40 forks source link

Add an option to chainload cnc-ddraw. #504

Closed eierfrucht closed 7 months ago

eierfrucht commented 7 months ago

sFall can profit greatly if augmented by cnc-ddraw (e.g. much better non-integer picture scaling with jinc2 GLSL shader)

So far chainloading cnc-ddraw after sFall requires the user to patch the fake ddraw.dll so that it redirects the calls to wardd.dll instead of \SysWOW64\ddraw.dll.

I would like to suggest adding an automated check: if there’s a wardd.dll present in the game directory, all ddraw calls that pass through the fake ddraw.dll are redirected there; otherwise they go to \SysWOW64\ddraw.dll as normal.

See: https://www.nuclear-city.com/topic/1566-fo2-%D0%BA%D0%B0%D0%BA-%D0%BF%D0%BE%D0%B4%D1%80%D1%83%D0%B6%D0%B8%D1%82%D1%8C-cnc-ddraw-%D0%B8-sfall-%D0%B2%D1%80%D0%B0%D0%BF%D0%BF%D0%B5%D1%80-%D0%B8-%D1%88%D0%B5%D0%B9%D0%B4%D0%B5%D1%80%D1%8B/?do=findComment&comment=127105

eierfrucht commented 7 months ago

Current (dirty) solution in a nutshell:

  1. HEX edit sfall's ddraw.dll so that the first two ddraw.dll references (in plain ASCII text) stay intact and the remaining three are changed to wardd.dll

https://i.postimg.cc/j2ZH4BFp/ddraw.png https://i.postimg.cc/Y035fqkt/ddraw3.png https://i.postimg.cc/Bv9mbf9p/wardd.png https://i.postimg.cc/7Y59NZqX/wardd2.png https://i.postimg.cc/3NdX9tQW/wardd3.png

  1. Get cnc-ddraw and rename its .dll, .ini and config tool to "wardd.dll", "wardd.ini" and "wardd.exe", respectively.

  2. HEX edit wardd.dll to replace the two references to "ddraw.ini" with "wardd.ini"

https://i.postimg.cc/YSNw8w1D/wardd-ni.png

  1. HEX edit wardd.exe to replace the two references to "ddraw.ini" with "wardd.ini"

https://i.postimg.cc/2S6w2dhs/wardd33.png https://i.postimg.cc/MGB1F9TF/warddddd.png

  1. Dump the three files next to Fallout2.exe

  2. Configure sFall to just use Mode 1 (ddraw) and turn off every feature that tampers with fullscreen/windowed mode, Vsync, FPS, anything that might be affected by cnc-ddraw. Make sFall behave as ddraw-compliant as possible, as if it were 1998.

  3. Configure cnc-ddraw to your liking either by manually editing wardd.ini or by running wardd.exe. You may select the OpenGL backend and activate any GLSL shader you place in .\Shaders, e.g. Jinc2-modified: https://forums.libretro.com/t/jinc-2-fixes/21146

  4. ...or you may alternatively select Nearest Neighbor and set sFall to exactly half your screen resolution to replicate the crisp pixel look of SCALE_X2=1

  5. Run the game and enjoy the new rendering pipeline: .\Fallout2.exe ➤ .\ddraw.dll (sFall) ➤ .\wardd.dll (cnc-ddraw) ➤ .\SysWOW64\opengl32.dll

Some screenshots:

sFall + cnc-ddraw (jinc2-modified shader) @ 1066x600 upscaled to 1920x1080:

https://i.postimg.cc/mT7WGyCT/Sonora1.png https://i.postimg.cc/D2dtDfs6/Sonora2.png https://i.postimg.cc/bpDjmhvD/Sonora3.png

sFall + cnc-ddraw (jinc2-modified shader) @ 1280x720 upscaled to 1920x1080:

https://i.postimg.cc/mRsd2Vzm/attal.jpg

sFall + cnc-ddraw (jinc2-modified shader) @ 1366x768 upscaled to 1920x1080:

https://i.postimg.cc/xY6KDPKJ/screen00002.png

sFall + cnc-ddraw (jinc2-modified shader) vs sFall DirectX9 SCALE_X2 @ 960x540 upscaled to 1920x1080:

https://i.postimg.cc/ys9YX1Y1/screen00001.png https://i.postimg.cc/dFpmf36G/comparison.png

sFall + cnc-ddraw (Nearest Neighbor via OpenGL) @ 960x540 upscaled to 1920x1080:

https://i.postimg.cc/YkCzR0WN/png.png

However a much more important aspect of cnc-ddraw is its superior control over Vsync, FPS, windowed/fullscreen modes, input fixes, etc. etc. and all of them work as long as sFall is in Mode 1 and all of its renderer tampering features are turned off.

I already notified the dev of cnc-ddraw that we need something better than brute HEX editing to automate the ddraw.ini ➤ wardd.ini renaming shtick: https://github.com/FunkyFr3sh/cnc-ddraw/issues/287

What we desperately need on sFall's end is either support for a CustomDllPath parameter pointing to a third party library for sFall to hand over all the drawcalls to or... a simple hardcoded fallback name like "wardd.dll": if that filename exists in the game directory, sFall switches to forwarding all the calls there, otherwise it proceeds to call \SysWOW64\ddraw.dll like originally intended.

eierfrucht commented 7 months ago
egornovivan commented 7 months ago

https://i.postimg.cc/542cwL5Z/fsr-vs-nearest.png

not bad Безымянный

NovaRain commented 7 months ago

I don't have time to test it, but you can try this test build with DLL loading option: sfall-dll-load-dev.zip In ddraw.ini:

[Main]
;Set a comma delimited list of custom DLL files
CustomDLLs=exter01.dll,exter02.dll
eierfrucht commented 7 months ago

So I made a clean install of GOG Fallout 2, installed the latest sfall 4.4.2, replaced ddraw.dll with the one you gave me...

It does load the custom dll: https://i.postimg.cc/Pqnyk2wV/custom-dll.jpg

But setting Mode to 0 does not make the game switch to legacy DX7 drawcalls. sFall itself keeps wrapping all the drawcalls into DirectX9 and off they go to d3d9.dll: https://i.postimg.cc/fRCc6DMy/DX9-1.jpg

(This happens even with cnc-ddraw fully missing from the installation, and cnc-ddraw itself is configured to use Opengl32.dll and glu32.dll -- apparently it is sFall 4.X that utilizes parts of DirectX 9 in all available modes)

This way cnc-ddraw becomes utterly useless because it expects vanilla DX7 calls, namely ones targeting the real ddraw.dll

The config file says: "Modes 1, 2 and 3 are no longer supported"

I first discovered the cnc chainloading trick whilst toying with Fallout: Sonora, which is built off a different sFall fork (namely sFall 5)

With it, setting Mode to 1 fully switches the game to DX7 calls which makes cnc-ddraw work in the first place...

Sadly sFall 4 seems fully DX9-ified so it's incompatible with cnc-ddraw =(

NovaRain commented 7 months ago

Try not using sfall's built-in HRP (you need to patch game exe to use Mash's HRP), or try your trick on sfall 3.8.x. TBH I don't have much interest in shader stuff, so the build was merely a simple attempt to load extra DLLs after sfall initialization.

eierfrucht commented 7 months ago

Just patched FO2 with Mash's patch 4.1.8

sFall coughed up the expected warning on launch...

Set in ddraw.ini:

HiResMode=0 Mode=0

The thing keeps running on DX9 and I have no idea why patching Fallout2.exe with Mash's stuff ought to have kept sFall from wrapping ddraw.dll calls into d3d9.dll calls before cnc-ddraw could ever get hold of them...

TBH I don't have much interest in shader stuff,

cnc-ddraw is not as much about shaders as it is about its extensive list of optional fixes and compatibility boosts... its control over FPS, Vsync, tic rate, input and many other things is superior. I myself have always been playing FO2 and its mods with nearest neighbor at half the resolution (i.e. SCALE_2X integer scaled) so I don't have a lot of interest in shader stuff either.

eierfrucht commented 7 months ago

Just double checked, with Mash's patch the game responds to every change that I make in f2_res_config.exe (like resolution or color bit depth) except when I set the graphics mode to DX7, it still loads DX9 libraries and does all the on-screen drawing through them...

NovaRain commented 7 months ago

The only thing I can think of is to try even older HRP (3.0.6, ignoring sfall's extended AP bar and world map feature first), which shouldn't invoke DX9 in any way. Or simply don't use any HRP to check if cnc works.

eierfrucht commented 7 months ago

Cnc has always worked with vanilla Fallout 2. It’s literally on the supported games list. I’ve done that countless times. Cnc also works with every QoL extension provided by sfall 5 as long as you select Mode 1 that doesn't invoke any DX9 whilst preserving every feature uncompromised (save for the fact that DX7 itself works like shit in Win 10 and 11, and has issues in Win 7, unless wrapped into a different API, which is what cnc and Mode 4/5/6 both do, the former externally and the latter internally).

In sfall 5, Modes 4/5/6 also activate the built-in DX9 wrapper so the behavior becomes identical to that of sfall 4 (cnc is bypassed like expected). For some reason, sfall 4 is locked in DX9 wrapper mode even if you force an external HRP and toggle on DX7 (pure ddraw) mode in f2_res.ini. What happened to Modes 1/2/3? Even if they are no longer fully supported, can they be brought back—as broken as they appear to be—to see if they work with cnc-ddraw?

For instance, a lot of stuff that won’t work (reliably or at all) in DX7 on Win10 and later still works the moment ddraw calls get translated to, say, opengl or DX9.

NovaRain commented 7 months ago

Cnc has always worked with vanilla Fallout 2. It’s literally on the supported games list.

I mean using HRP 3.0.6 with sfall (w/ built-in HRP disabled, or try 3.8.x which doesn't have built-in HRP to make things a bit simpler).

What happened to Modes 1/2/3? Even if they are no longer fully supported, can they be brought back—as broken as they appear to be—to see if they work with cnc-ddraw?

Mode 1/2/3 were removed from v1.25 in 2008, long before sfall became open-source (pre-2.0) so I have no idea how they work. Here are their graphics settings from an ancient INI:

[Graphics]
;Set to 0 for 8 bit fullscreen
;Set to 1 for 8 bit windowed
;Set to 2 for 16 bit fullscreen
;Set to 3 for 16 bit windowed
;Set to 4 for dx9 fullscreen
;Set to 5 for dx9 windowed
;Mode 1 requires your desktop colour depth to be set to 32 bit
;Windowed modes incur a performance hit. (Modes 1 and 5 more so than mode 3)
;The 16 bit colour modes cause movies to display incorrect colours, and slows down fades
;dx9 modes cause some corruption of movies, but not as bad as 16 bit colour modes
;16 bit colour modes only work in fallout 2
;dx9 modes work with fallout 1, but results in movies being completely corrupted
;A dx9 mode is required for any graphics related script extender functions to work (i.e. fullscreen shaders)
Mode=0
eierfrucht commented 7 months ago

Setting Mode to 1 in sfall 5 makes the game go full DX7 which is why it is obligatory for cnc to work. Mode 1 is described as "DX7 fullscreen", you could take a look at sfall 5 and see for yourself.

Setting Mode to 1 in sfall 4 does nothing. The game retains its internal DX9 wrapping behavior.

Vanilla Fallout 2 is DX7/ddraw based all through, but this legacy renderer is for some reason not preserved in sfall 4 but stays functional as Mode 1/2/3 in sfall 5.

eierfrucht commented 7 months ago

I mean using HRP 3.0.6 with sfall (w/ built-in HRP disabled, or try 3.8.x which doesn't have built-in HRP to make things a bit simpler).

What about mods and TCs that require at least sfall 4 or 5?

That derelict stuff is derelict for a reason.

NovaRain commented 7 months ago

No point for me in checking Stalin's version, as I don't have skills to recreate what he wrote for graphics components from a disassembler. If the DLL loading test option doesn't work (obviously it doesn't work for cnc), wait till phobos2077 starts reviewing this issue.

eierfrucht commented 7 months ago

My point is that (at least to me) it looks like Mode 1 is the untampered legacy DX7 renderer, quite broken on modern OSes if left unwrapped into a different API via some helper tool, and simply carried over since the dawn of sfall—not an addition or rehash of an existing function by Stalin. Raw DX7 is so finicky or outright broken since Win 7, nobody would bother to reimplement it... Some projects may carry it on as a legacy mode for testing purposes at best.

For some reason, this legacy renderer can't be activated in sfall 4 by setting Mode = 1 which itself might be a bug.

eierfrucht commented 7 months ago

If the DLL loading test option doesn't work (obviously it doesn't work for cnc)

It absolutely does work, above I posted screenshots from process explorer with wardd.dll (renamed cnc) loaded.

Cnc just expects ddraw (DX7) calls, which sfall 4 receives from fallout2.exe but wraps them in DX9 before forwarding them to d3d9.dll. This way, there are zero ddraw.dll calls exiting sfall, and nothing for cnc to intercept and handle. I’ve been meaning this for like half of this thread.

eierfrucht commented 7 months ago

BTW there may be another misunderstanding. Regardless of the rest of the issues, for cnc to work, any ddraw call exiting sfall and destined for SysWOW64\ddraw.dll must instead be explicitly redirected to SysWOW64\ddraw.dll or whatever you have renamed the cnc .dll to.

Since there is no such file as SysWOW64\ddraw.dll the OS will look for it in the same directory as the parent executable that initiated the call chain, i.e. in the game directory. That's what the original binary patching trick does. Simply loading custom code from a .dll won’t affect anything.

By specifying "CustomDLLs=wardd.dll" I assume (probably mistakenly) that all and every call that sfall might issue to the real ddraw.dll, is instead redirected to a "wardd.dll".

My first post in the thread asks for the following feature: "if there’s a wardd.dll present in the game directory, all ddraw calls that pass through the fake ddraw.dll are redirected there; otherwise they go to \SysWOW64\ddraw.dll as normal"

NovaRain commented 7 months ago

If the DLL loading test option doesn't work (obviously it doesn't work for cnc)

It absolutely does work, above I posted screenshots from process explorer with wardd.dll (renamed cnc) loaded.

Cnc just expects ddraw (DX7) calls, which sfall 4 receives from fallout2.exe but wraps them in DX9 before forwarding them to d3d9.dll. This way, there are zero ddraw.dll calls exiting sfall, and nothing for cnc to intercept and handle. I’ve been meaning this for like half of this thread.

Well, I said "not working" because it doesn't really help the cnc case. And I do check NC regularly, I apologize if you think I gave out stupid advices. I just think if newer sfall 4 keeps wrapping ddraw calls to DX9 probably due to the built-in HRP code (which largely a reimplementation from Mash's HRP 4.1.8), trying something "older" that doesn't contain those code might work.

eierfrucht commented 7 months ago

I just think if newer sfall 4 keeps wrapping ddraw calls to DX9 probably due to the built-in HRP code (which largely a reimplementation from Mash's HRP 4.1.8),

And so does sfall 5. It has the same internal reimplementation of HRP code. HiResMode=1 is required to get cnc working, actually, along with Mode=1. All the external HRP stuff must be turned off to avoid clashing with cnc (graphics mode set to 0 in f2_res.ini)

Another possibility may be that DX9 libs getting loaded by sfall 4 is something automated and harmless (loaded doesn't mean actually used), and Mode 1 actually works, but simply putting wardd.dll on the experimental external DLL list does not warrant obligatory ddraw call forwarding to said external library, unlike what my original request is all about. sfall keeps forwarding the calls to SysWOW64\ddraw.dll instead of SysWOW64\wardd.dll.

phobos2077 commented 7 months ago

wait till phobos2077 starts reviewing this issue.

Tbh, I never messed with the graphics/DirectX stuff of sfall, except maybe some keyboard event stuff a long time ago. So I will have to do some research to understand what's going on here. It's the first time I hear about cnc-ddraw and I've been an enjoyer of old games for many years. I'm curious what real benefits it gives compared to the current built-in and HRP options. I would appreciate some TL;DR explanation.

Not sure how easy it will be to chainload another ddraw.dll via source code changes, need to do some research. Maybe you can take a look at the code yourself and give some pointers?

egornovivan commented 7 months ago

@NovaRain pls push commit


We play a guessing game without a code


I want to understand what’s going on there, how do you load several dlls?

CustomDLLs=exter01.dll,exter02.dll

https://github.com/sfall-team/sfall/blob/af2fdb5153b079e393ef98f0895582e6096ee968/sfall/main.cpp#L310-L359

eierfrucht commented 7 months ago

Not sure how easy it will be to chainload another ddraw.dll via source code changes, need to do some research. Maybe you can take a look at the code yourself and give some pointers?

I've managed to make sfall4 chainload cnc-ddraw with a few hex edits, really should have done this before starting this thread but my first attempt (using the same exact steps) failed for no reason so I was like "Let's ask the actual coder guy".

It looks like the legacy DX7 renderer is just as functional as it is in sFall 5. Here's what made me stumble: even in DX7 mode, sFall 4 still loads DirectX9 libraries for no apparent reason, which tricked me into making a lot of wrong assumptions. Maybe it does so "just in case". With sFall 4, when the game is running in DX7 mode, a bunch of DX9 dlls stay idly sitting in memory and don't do any actual on-screen drawing; sFall 5 only loads DirectX 9 libraries when it actually wraps DX7 calls into DX9 calls (Mode 4 and above).

I've never coded a single program myself and haven't ever worked on anything IT-related whatsoever. My understanding of any code is limited to my common sense and intuition, which probably amounts to a measly 5% on the Fallout skill scale.

There's a different legacy DirectX wrapper called dxwrapper that is open source and has this exact functionality: it lets you specify a custom library to forward all the drawcalls to. This feature serves the sole purpose of pumping the drawcalls through multiple chained wrappers like a scary DLL centipede before the calls finally land in some "real" graphics API library tucked into \System32\ or \SysWOW64\

Dxwrapper mainly targets DX6/7/8 games with hardware-accelerated 3D rendering. Its core features are of little use in 2D games like Fallout. Still, it could serve as a great reference for implementing chainloading: https://github.com/elishacloud/dxwrapper/wiki/Configuration

Namely this: https://i.postimg.cc/tRD1FGFN/Real-DLLPath.jpg

Some other popular wrappers (primarily targeting 3D games) just for reference:

OpenGL to DX12: https://apps.microsoft.com/detail/9NQPSL29BFFF

DirectX to Vulkan: https://www.makeuseof.com/dxvk-windows-guide

DgVodoo2: http://dege.freeweb.hu/dgVoodoo2/ReadmeGeneral (the swiss army knife of graphics API wrapping on Windows with such a vast feature set that sometimes it becomes an obstacle in itself; a must for old Glide-based games and a handful of titles that defy other measures; it can also emulate custom-property GPUs much like a virtual machine)

Why I think cnc-ddraw is relevant for Fallout? It easily eliminates issues like these:

https://github.com/sfall-team/sfall/issues/322#issue-649316819

Using sfall's (or high resolution's) dx9 mode results in extreme framerates (300 - 1000+) on modern systems. This leads to coil whine and heating-up of the gpu, especially when using additional post-processing shaders. Capping the framerate at screen refresh results in an unbearable slow game. Even a cap of 200 fps can be a sluggish experience. I know at least two ddraw-wrapper that don't have this problem: cnc-ddraw and dgvoodoo. Latter has implementend a solution to this, after I reported the same problem here

Seems like the way main loop is implemented in DX9 mode is wrong and needs some fixes. Probably different CPU idle settings needs to go (they seem like ugly half-working hacks) in favor of a proper frame pacing solution.

By offloading all the rendering / CPU / FPS / Vsync / Windowed mode handling tasks to cnc-ddraw, you will no longer have to care about any of that. In my suggested setup, sFall only peforms tasks related to enhancing the game engine: mod support, custom viewport resolutions, etc. The game defaults to the old-ass DX7 renderer and thinks it's running in full screen mode, while cnc-ddraw handles all the rendering / postprocessing / window compositing / input fixes in one of the modern graphics backends according to the user's choice: OpenGL, DirectX 9, DirectX 9-on-12, or GDI (the latter is a 100% software renderer so it works on vintage computers and virtual machines with no support for hardware accelerated rendering). sFall's built-in DX9 wrapper and CPU / FPS fixes lay at rest and everybody's happy.

Give me some time. I'll be back with a set of patched sFall 4 files, an explanation how to reproduce these steps, and maybe a better understanding of which libraries sFall 4 actually uses in which exact mode.

NovaRain commented 7 months ago

I want to understand what’s going on there, how do you load several dlls?

I simply took the code from #273.

egornovivan commented 7 months ago

I want to understand what’s going on there, how do you load several dlls?

I simply took the code from #273.

This is not a chainload. This is just a normal loading of the dll into the game process memory and it waits for calls.🤔But such functionality will also be useful.


You need to add a parameter to the ini file for this https://github.com/sfall-team/sfall/blob/af2fdb5153b079e393ef98f0895582e6096ee968/sfall/main.cpp#L315 if I understood everything correctly.

eierfrucht commented 7 months ago

Okay guys here's the deal...

Fixed files: https://www.mediafire.com/file/5xt892ljfq0g065/sFall4.4.2%252Bcnc-ddraw.zip/file

File list:

.\Shaders -- GLSL shaders for the OpenGL backend
ddraw.dll -- patched ddraw.dll from sFall 4.4.2
ddraw.ini -- tweaked ddraw.ini from sFall 4.4.2 (targeting vanilla Fallout 2)
f2_res.ini -- tweaked f2_res.ini that ships with GOG version of Fallout 2
wardd.ini -- renamed ddraw.ini from cnc-ddraw
wardd.dll -- renamed and patched ddraw.dll from cnc-ddraw
wardd.exe -- renamed and patched "cnc-ddraw config.exe" from cnc-ddraw

HEX edits applied: https://i.postimg.cc/1tTNVLgK/sfall4-ddraw-dll-hack.jpg

Basic cnc-ddraw configuration: https://i.postimg.cc/Mpvv2z9K/cnc-ddraw-config-for-sfall4.jpg

ddraw.ini edits explained:

HiResMode=1   ; This is mandatory for sFall's built-in HRP to kick in
Mode=1   ; This activates the legacy DirectX 7 renderer (full-screen mode) that cnc-ddraw intercepts
GraphicsWidth=960   ; Half of my actual screen width in pixels
GraphicsHeight=540   ; Half of my actual screen height in pixels
ProcessorIdle=-1    ; let this get handled by cnc-ddraw

f2_res.ini edits explained:

UAC_AWARE=0   ; probably we should stay on the safe side
GRAPHICS_MODE=0   ; to keep away Mash's wacky renderer modifications
SCALE_2X=0   ; this is now handled by the Nearest Neighbor shader in cnc-ddraw
SCR_WIDTH=   ; leave blank
SCR_HEIGHT=   ; leave blank
COLOUR_BITS=32  ; any value will do with cnc-ddraw
REFRESH_RATE=0  ; let this get handled by cnc-ddraw
WIN_DATA=0  ; let this get handled by cnc-ddraw

wardd.ini edits explained:

[ddraw]
width=0     ;  zero for auto scaling to screen size, edit ddraw.ini instead to change the in-game viewport width
height=0    ; zero for auto scaling to screen size, edit ddraw.ini instead to change the in-game viewport height
fullscreen=true ; scale the viewport to the size of the screen
windowed=true ; let the fullscreen actually be a window for fast alt tabbing
maintas=true ; maintain viewport aspect ratio regardless of the screen aspect ratio
boxing=false ; we don't need forced integer scaling on cnc's end, just set a correct viewport resolution in sFall's config instead and let the Nearest Neighbor shader do the rest
maxfps=-1 ; cap FPS at the current screen refresh rate; can be set to 30 or 60 for 120 Hz monitors / 36 or 72 for 144 Hz monitors
vsync=true  ; Vsync is so good
adjmouse=true  ; otherwise mouse input will fail to work on some setups
shader=Shaders\nearest-neighbor.glsl  ; this is basically your good old SCALE_2X when run at half the screen resolution
renderer=opengl   ; OpenGL backend supports GLSL shaders but other options are also available
border=false   ; let the window be a borderless one so it looks like plain fullscreen
resizable=false  ; protect our fake fullscreen from getting resized
toggle_borderless=true  ; required for borderless windows mode
toggle_upscaled=false   ; we don't need "Fullscreen: Upscaled" mode
noactivateapp=true   ; part of compatibility fixes
maxgameticks=-2   ; cap the game's tic rate at the current screen refresh rate; can be set to 30 or 60 for 120 Hz monitors / 36 or 72 for 144 Hz 
minfps=0   ; not needed at least for sFall
nonexclusive=true    ; part of compatibility fixes
singlecpu=true   ; the good old single CPU affinity fix, probably not needed

Installation:

  1. Make a clean install of Fallout 2 by GOG
  2. Do NOT run f2_res_patcher.exe, Mash's stuff should stay away
  3. Install https://sourceforge.net/projects/sfall/files/sfall/sfall_4.4.2.7z/download
  4. Overwrite the game folder with the fixed files
  5. Set a correct viewport resolution in ddraw.ini
  6. Run the game, it should work as intended with a [DD7] label in task manager: https://i.postimg.cc/T3ZsYSw-r/sfall4-dd7.jpg

If you don't dig Nearest Neighbor scaling, just edit ddraw.ini for a non-integer-scaled viewport (e.g. 1066x600, 1280x720, or 1366x768 for 16:9), run wardd.exe and switch the shader from nearest-neighbor.glsl to jinc2-modified.glsl or catmull-rom-bilinear.glsl or anything else you like; you can add custom GLSL shaders to .\Shaders\shader-name\shader-name.glsl

Switching from OpenGL to DirectX 9 will limit you to just the four built-in shaders but otherwise works like a charm.

Switching to GDI will work in environments with no support for hardware graphics acceleration like certain kinds of virtual machines or very old PCs. The only scaling algorithm available in GDI mode is Nearest Neighbor, so set your viewport size to strictly half (or quarter for 4K displays) of your actual screen resolution. GDI is very similar to the vanilla DX7-based software renderer except it works where DX7 fails.

egornovivan commented 7 months ago

Why is the dll name hardcoded here? https://github.com/sfall-team/sfall/blob/af2fdb5153b079e393ef98f0895582e6096ee968/sfall/Modules/Input.cpp#L33

eierfrucht commented 7 months ago

It would suffice to add a second name like "wardd.dll" that takes precedence over "ddraw.dll" and that'll be it.

egornovivan commented 7 months ago

It would suffice to add a second name

On the contrary, we are getting rid of the hardcode, and such a solution will add shit


NovaRain the parameter must support relative file path with subfolder https://github.com/sfall-team/sfall/issues/504#issuecomment-1942590888

eierfrucht commented 7 months ago

On the contrary, we are getting rid of the hardcode, and such a solution will add shit

A CustomDLLPath-like .ini parameter will either have to be left blank (unassisted mode) or be pointing to a valid third-party wrapper (drawcall forwarding mode). Specifying a non-existent filename will make the game crash. Pointing to a file that is not a valid wrapper will also make the game crash. People will flock here with questions.

Adding a second, higher-preference name is by design more foolproof albeit cryptic: if you are about to drop a file named precisely "wardd.dll" into the game directory, you probably have read the manual and fully realize what you are doing.


Uh-oh. I just reinstalled this whole thing following my own guide and guess what, Fallout 2 & sFall 4.4.2 run without invoking any DirectX 9 libraries in OpenGL mode. I apologize for making a fuss and truly am at a loss as to what was so stubbornly causing such behavior yesterday while I was reiterating these very steps over and over again.

The only additional libraries with cnc-ddraw running in OpenGL mode are: https://i.postimg.cc/CLXtFNFT/cnc-sfall-opengl.jpg

DInput8.dll instead of Dinput.dll improves mouse input compatibility on Windows 10 & 11 and is also provided by cnc-ddraw.


The below section of ddraw.ini

[Graphics]
;Set to 0 for 8 bit fullscreen
;Set to 4 for DX9 fullscreen
;Set to 5 for DX9 windowed
;Set to 6 for DX9 fullscreen windowed (the resolution in f2_res.ini should be set to the same aspect ratio as your desktop resolution)
;A DX9 mode is required for any graphics related script extender functions to work (i.e. fullscreen shaders)
;Modes 1, 2 and 3 are no longer supported
;If using the hi-res patch by Mash, this option will always be read from the main ddraw.ini file
Mode=

probably should be swapped for a clearer description:

[Graphics]
;Set to 0 for 8 bit fullscreen
;Set to 1 for DX7 fullscreen mode, required for cnc-ddraw
;Set to 2 for DX7 windowed mode, incompatible with cnc-ddraw and unstable from Windows 7 onwards
;Set to 3 for DX7 fullscreen windowed mode, incompatible with cnc-ddraw and unstable from Windows 7 onwards
;Set to 4 for DX9 fullscreen
;Set to 5 for DX9 windowed
;Set to 6 for DX9 fullscreen windowed (the resolution in f2_res.ini should be set to the same aspect ratio as your desktop resolution)
;A DX9 mode is required for sFall's built-in DirectX 9 wrapper and its extensions to work
;Mode 1 is mandatory for enabling cnc-ddraw but highly unstable if used without it
;Modes 2 and 3 aren't fully compatible with cnc-ddraw and are highly unstable from Windows 7 onwards
;If using the hi-res patch by Mash, this option will always be read from the main ddraw.ini file
Mode=
eierfrucht commented 7 months ago

parameter must support relative file path with subfolder

The stand-in library MUST reside in the same directory as the game executable.

However a more correct solution would be to target \System32\fake-library-name.dll

When invoked from a 32bit process, this will automatically map to \SysWOW64\fake-library-name.dll

If \SysWOW64\fake-library-name.dll isn't an existing path, Windows will attempt to make the game load "fake-library-name.dll" right from the executable's directory.

If both \SysWOW64\fake-library-name.dll and .\fake-library-name.dll exist, the latter will have the upper hand UNLESS the code is tailored to seek specifically in \System32\ -- this is actually how sFall's ddraw.dll, when running in DX7 mode, finds the real \SysWOW64\ddraw.dll instead of calling upon itself in loops.

For third party wrappers, we probably want the usual behavior provided by Windows: with two namesakes at hand, the one in the executable directory has the upper hand over the one in \SysWOW64\

It's then up to the third party wrapper to decide where to next forward the intercepted calls.

egornovivan commented 7 months ago

MUST

nope

Everything you wrote right now concerns only system dlls. For everything to work as correctly as possible, full and relative paths must be supported, as well as only the name of the file that will be loaded from the directory with exe

NovaRain commented 7 months ago

Why is the dll name hardcoded here?

https://github.com/sfall-team/sfall/blob/af2fdb5153b079e393ef98f0895582e6096ee968/sfall/Modules/Input.cpp#L33

It replaces dinput.dll string with ddraw.dll when the game initializes the input library. It can be replaced with getting the same "ddraw.dll" string from the game exe, so no hardcoded string from sfall itself.

egornovivan commented 7 months ago

Hmmm🤔 sfall4-ddraw-dll-hack


Somewhere in the .h files of Windows SDK there is still hardcode it seems

eierfrucht commented 7 months ago

Yet the real ddraw.dll is no longer invoked after the patch.

egornovivan commented 7 months ago

@NovaRain Probably worth adding WS_EX_APPWINDOW to all modes? This should fix a bug with the icon disappearing from the taskbar. https://github.com/FunkyFr3sh/cnc-ddraw/issues/287#issuecomment-1944836604

NovaRain commented 7 months ago

Try this test build: sfall-exstyle-test.zip I don't know if setting the style works as I don't have the icon disappearing bug on my current system.

egornovivan commented 7 months ago

I don't know if setting the style works as I don't have the icon disappearing bug on my current system.

On version sfall 4.4.2 the bug appears when the parameter is set HiResMode=0


I'll test it now exstyle


notwork exstyle

NovaRain commented 7 months ago

On version sfall 4.4.2 the bug appears when the parameter is set HiResMode=0

Oh, I only set the extended style for sfall's DD7 (requires HiResMode=1) and DX9 modes. Try this one for HiResMode=0: sfall-exstyle-test2.zip I added a small hack to game engine's GNW95_init_window_ function to add the extended style when the game calls CreateWindowExA.

egornovivan commented 7 months ago

I added a small hack to game engine's GNW95_init_window_ function to add the extended style when the game calls CreateWindowExA.

its working👍

eierfrucht commented 7 months ago

It works... not that I’m saying turning HiResMode off makes any practical sense in 2024.

/EDIT/ I was too hitting the missing taskbar entry bug on Windows but I mostly run the game in Wine.

brussell1 commented 7 months ago

It works... not that I’m saying turning HiResMode off makes any practical sense in 2024.

Well, I don't need it.

Nevertheless, thank you very much for your dll hack. I've also tried to chainload cncddraw, but failed unfortunately. Official support for chainloading would be highly appreciated.

Btw, I still prefer a "ProcessorIdle" setting of 1-5. It's barely noticable and saves you 5-10 watts on the cpu.

eierfrucht commented 7 months ago

Btw, I still prefer a "ProcessorIdle" setting of 1-5. It's barely noticable and saves you 5-10 watts on the cpu.

Same can be done by limiting both FPS and tic rate in cnc-ddraw.

FunkyFr3sh commented 7 months ago

https://github.com/sfall-team/sfall/blob/af2fdb5153b079e393ef98f0895582e6096ee968/sfall/main.cpp#L310-L359

Wouldn't it be as simple as this?


    ddraw.dll = LoadLibraryA("wrapper\\ddraw.dll");

    if (!ddraw.dll)
   {
      char path[MAX_PATH];
      CopyMemory(path + GetSystemDirectoryA(path , MAX_PATH - 10), "\\ddraw.dll", 11); // path to original dll
      ddraw.dll = LoadLibraryA(path);
   }
egornovivan commented 7 months ago

Well. We will need to load cnc from a subdirectory. https://github.com/FunkyFr3sh/cnc-ddraw/pull/289

FunkyFr3sh commented 7 months ago

Well. We will need to load cnc from a subdirectory. FunkyFr3sh/cnc-ddraw#289

Yeah, I edited my last post with a better example.

But anyways, I tried to change the code in sfall but it didn'T work (it was stull using DX9, even with Mode=0). Might need to do some more research

eierfrucht commented 7 months ago

it was stull using DX9, even with Mode=0

I'm consistently getting DX7 in Mode=1, HRP off, Mash's stuff off, here are the steps (skip the binary patching part): https://github.com/sfall-team/sfall/issues/504#issuecomment-1942844856

Namely:

ddraw.ini:

HiResMode=1   ; This is mandatory for sFall's built-in HRP to kick in
Mode=1   ; This activates the legacy DirectX 7 renderer (full-screen mode) that cnc-ddraw intercepts
GraphicsWidth=960   ; Half of my actual screen width in pixels
GraphicsHeight=540   ; Half of my actual screen height in pixels
ProcessorIdle=-1    ; let this get handled by cnc-ddraw

f2_res.ini:

UAC_AWARE=0   ; probably we should stay on the safe side
GRAPHICS_MODE=0   ; to keep away Mash's wacky renderer modifications
SCALE_2X=0   ; this is now handled by the Nearest Neighbor shader in cnc-ddraw
SCR_WIDTH=   ; leave blank
SCR_HEIGHT=   ; leave blank
COLOUR_BITS=32  ; any value will do with cnc-ddraw
REFRESH_RATE=0  ; let this get handled by cnc-ddraw
WIN_DATA=0  ; let this get handled by cnc-ddraw

I was too plagued for a time by some weird behavior on sFall's part where it was stubbornly using DX9 until I figured out those; some rogue parameter inadvertently activates sfall's built-in DX9 wrapper. Probably one of those features depends on DX9 so it auto kicks in.

pdishh commented 7 months ago

to get ddraw, you should set in f2_res.ini

UAC_AWARE=0
GRAPHICS_MODE=1

and in ddraw.ini

HiResMode=1
Mode=0

If it still doesn't work, check if Direct3DCreate9 was actually called.

FunkyFr3sh commented 7 months ago

I don't even have such .ini files, so I guess I'll wait for a patch. Just wanted to try it out for fun (not really an fallout/sfall expert anyways)

eierfrucht commented 7 months ago

GRAPHICS_MODE=1

as per the description, it's GRAPHICS_MODE=0 that fully hands over the handling of rendering to sFall from Mash's stuff

Set GRAPHICS_MODE=0 to enable Basic mode which supports resolution change only(required for sfalls Graphic modes).

eierfrucht commented 7 months ago

I don't even have such .ini files, so I guess I'll wait for a patch. Just wanted to try it out for fun (not really an fallout/sfall expert anyways)

Did you try it on FO2 from GOG?

Otherwise you'd need http://www.mediafire.com/view/7uaa8r5600r9n92/Fallout2_High_Resolution_Patch_4.1.8

sFall depends on f2_res.ini and f2_res.dat from that patch, don't run the bundled executable though (you wouldn't want to apply the actual patch, you just need some of its resources that sFall recycles)

GOG bundles Mash's patch with their installation.