elishacloud / dxwrapper

Fixes compatibility issues with older games running on Windows 10/11 by wrapping DirectX dlls. Also allows loading custom libraries with the file extension .asi into game processes.
zlib License
1.23k stars 89 forks source link

Command & Conquer: Generals – Zero Hour #286

Open archibald1337 opened 1 month ago

archibald1337 commented 1 month ago

First of all I want to thank you for your project. Using it I've managed to fix unlimited framerate of the game on Windows 11 which was a source of broken animations of some objects and too fast movement of scrolling the map.

Now I'm working on some other fixes of the game:

  1. Broken Alt+Tab. It happens on Windows 8 and later versions. My current fix is to launch the game as a fullscreen window and then removing the style WS_EX_TOPMOST which prevents the game window from switching between other windows. It boils down to the next code:

        SetWindowLongW(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & -WS_EX_TOPMOST);
        SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, resolution.width, resolution.height, **SWP_FRAMECHANGED);
  2. Remapping WASD keys to ↑←↓→ keys. This one is more trickier, I need to inject a DLL or run another program and set up a hook and change aforementioned keys at right time when game match is started. This one is in progress. There is also a way to do it via AutoHotKey but I want to gather these fixes in one program.

So, my overall questions are: is there any functionality in the dxwrapper allowing me to change the style of the window? And, is there any way to inject my own code?

elishacloud commented 1 month ago

I don't have the ability to test the game right now, but I put an update in for 1. Broken Alt+Tab. I already had code to remove the WS_EX_TOOLWINDOW exstyle but I only did that for games that used DirectDraw/Direct3D7 or older. Now I moved the code to the Direct3D9 wrapper, which will work with both dd7to9 and d3d8to9, and updated it to remove WS_EX_TOPMOST also.

You can check out the build here with this change: https://github.com/elishacloud/dxwrapper/actions/runs/10148674548

As far as 2. Remapping WASD keys to ↑←↓→ keys., I am trying to make dxwrapper a generic tool for all kinds of games. I could make an option that will always redirect WASD keys to ↑←↓→ keys but that may break other things, like typing your name, etc. One way this could work is to add a hotkey to toggle the option on and off.

As far as adding code for the keyboard remapping, I guess the best place to do that would be in the WndProc function handler. However, that code is currently only enabled for dd7to9 and I am not sure if that works for DirectInput games. I could enable the code in Direct3D9 so it would work for all the dd7to9 and d3d8to9 games. But additional code may be needed for DirectInput as well.

Given then issues with the key remapping, I don't plan to do this anytime soon. However, you are welcome to create a branch of the dxwrapper code and add it yourself or you can create your own dll that does this. Alternatively, you can load your dll from dxwrapper using the LoadCustomDllPath option.

BTW: let me know if the code I put in fixes the Alt+Tab issue or not.

archibald1337 commented 1 month ago

elishacloud, thanks for your fast reply! I've downloaded and launched the latest build. Unfortunately, calling SetWindowPos with SWP_NOZORDER flag prevents from removing class WS_EX_TOPMOST (link to the docs so this one doesn't work:

SetWindowPos(DeviceDetails.DeviceWindow, ((lExStyle & WS_EX_TOPMOST) ? HWND_NOTOPMOST : HWND_TOP), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

I've tested without SWP_NOZORDER and it worked as needed, removing the class:

SetWindowPos(DeviceDetails.DeviceWindow, ((lExStyle & WS_EX_TOPMOST) ? HWND_NOTOPMOST : HWND_TOP), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);

I'm not sure how it must be added to your library so not to break support of other games etc. Maybe it's a good idea to break removing WS_EX_TOOLWINDOW and WS_EX_TOPMOST classes into to separate calls of SetWindowLong+SetWindowPos?

Also, maybe it's should be enabled some option?

elishacloud commented 1 month ago

Good catch! I fixed it. I tested with a few games. I don't think it will cause an issue. But there could be other games that have the same issue as Command & Conquer: Generals Zero Hour so for now I'll just make it standard. I can always change it later if I find an issue with another game.

You can test it here: https://github.com/elishacloud/dxwrapper/actions/runs/10154381394

archibald1337 commented 1 month ago

Hooray, it works now like a charm! Yes now I can retire my utility program to modifying game window and switch to your amazing dxwrapper.

Since it works perfectly, I suggest you to add Command & Conquer: Generals – Zero Hour on the list of Compatible Games. I can make a pull request describing problems with launching the game on Windows 11 and configuration of dxwrapper to fix them.

elishacloud commented 1 month ago

Hooray, it works now like a charm!

Ok, great.

Since it works perfectly, I suggest you to add Command & Conquer: Generals – Zero Hour on the list of Compatible Games. I can make a pull request describing problems with launching the game on Windows 11 and configuration of dxwrapper to fix them.

Sure. Feel free to make a pull request. I am not that good at updating the documentation. Thanks!

archibald1337 commented 1 month ago

Okay I've got a little problem with cloning wiki repo on Windows haha

error: invalid path 'Conquest:-Frontier-Wars.md'
error: invalid path 'Creatures-2:-The-Albian-Years.md'
error: invalid path 'Final-Liberation:-Warhammer-Epic-40,000.md'
elishacloud commented 1 month ago

Those are readme pages for those games. I have never tried creating a PR for those items, so I am not sure what the issue is.

archibald1337 commented 1 month ago

git can't checkout a revision with files containing semicolons. Could you rename them?

elishacloud commented 1 month ago

Good catch. Ok, I removed the colons. Try again.