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.16k stars 83 forks source link

Mouse cursor position in Pharaoh and Zeus #86

Closed maxigaz closed 3 years ago

maxigaz commented 3 years ago

Yesterday I reported in an issue for cnc-ddraw that I also tried DxWrapper with Pharaoh and Wine and it fixed the problem with the position of the mouse cursor being incorrect. After some further playtesting, I realised that while the game is certainly playable this way, the mouse cursor is still somewhat off.

When I launch the game, as I hover the mouse over and off the main menu items, it can be seen right away that it’s as if the whole screen content has been shifted slightly downward and even more to the right.

I can reproduce this with DxWrapper v1.0.6387.21, with multiple Lutris versions of Wine (namely the packages lutris-fshack-5.5-2 and lutris-fshack-5.6-5), both with and without a widescreen hack, and with DdrawUseNativeResolution set to either 0 or 1.

I’ve also installed Zeus to take a glimpe at how DxWrapper performs with it and I have the exact same results so far as with Pharaoh.

elishacloud commented 3 years ago

Ok, try this update. I put a full fix in for this. You no longer need to enable DdrawUseNativeResolution. I basically simulate what DirectDraw does. This should work with only Dd7to9 enabled.

dxwrapper.zip

maxigaz commented 3 years ago

With this update, the mouse cursor position is now correct in both games. Thank you very much!

maxigaz commented 3 years ago

Actually, now if I leave DdrawUseNativeResolution disabled, scrolling no longer works if the mouse cursor touches the right or lower edge of the screen. If I enable DdrawUseNativeResolution, scrolling works but the cursor position is wrong again.

Shall I create a separate issue for this?

elishacloud commented 3 years ago

Scrolling works for me. I tried all three games (Caesar, Pharaoh and Zeus) with multiple resolutions. Scrolling works with both the keyboard and the mouse. Moving the mouse to any of the four sides of the screen scrolls the game in that direction.

I am testing on Windows 10 64bit with the GOG version of the games. No patches, just native game play.

Here is the build I am using, should work the same as the one I gave you: dxwrapper.zip

maxigaz commented 3 years ago

It’s still the same here on Wine and Proton’s fullscreen hack, which upscales the internal resolution (e.g. 1280x720) to the screen resolution (1920x1080). If the internal resolution is also 1920x1080, mouse scroll works, but the visuals look too small for comfortable playing.

(As a sidenote, the author of cnc-ddraw pushed a commit and a test build today that fixed both the issue with the mouse position and scrolling, even with fshack. I don’t know how it works, but I guess you might be able to use it as a reference.)

elishacloud commented 3 years ago

It’s still the same here on Wine and Proton’s fullscreen hack

This could be a bug with the Proton fullscreen hack. I tried with WineD3D and scrolling seemed fine for me. I did, however, create an update to see if it helps.

Here is the update: dxwrapper.zip

If that updated does not work you may also want to try setting the FullscreenWindowMode option to see if that helps.

As a sidenote, the author of cnc-ddraw pushed a commit and a test build today that fixed both the issue with the mouse position and scrolling

Yeah, I saw his update. He adds a custom option into the config file for this and does some custom hacks (here and here) that may not work with other games. I am trying to build a generic solution that works with all games. It is a bit harder to implement, but makes it easier for the user and should be more compatible in the long run.

FunkyFr3sh commented 3 years ago

It's gonna be impossible to mimic the original DirectDraw in this case because we have custom features like windowed mode and windowed fullscreen (which both, the original DirectDraw isn't doing) so there will never be a WM_DISPLAYCHANGE message in our case and a hack is unavoidable. You could try to just change the resolution to something random and then change it to the final resolution to trigger the WM_DISPLAYCHANGE instead of using PostMessageA. But in the end it's also a hack :D

If you just want to have it working in fullscreen without any additional features then yeah, you can create a generic solution. (It will not work with fshack though)

elishacloud commented 3 years ago

@FunkyFr3sh, thanks for your comments. I am trying to convert DirectDraw and Direct3D to Direct3D9, just like d3d8to9 does. I am trying to do as straight of a conversion as possible, so you can see for example, as I am working on the 3D functions I call the Direct3D9 equivalent directly.

we have custom features like windowed mode and windowed fullscreen (which both, the original DirectDraw isn't doing)

Yeah, those are just there for convenience. They don't work on all games.

For the case of these games, when the game calls SetDislpayMode() and DirectDraw is in exclusive mode I will change the resolution to the requested resolution. This seems to work for this game in all my tests.

If you just want to have it working in fullscreen without any additional features then yeah, you can create a generic solution. (It will not work with fshack though)

Why won't this work with the work with fshack? What does the fshack do that breaks this?

FunkyFr3sh commented 3 years ago

Oh I see, didn't know you treat these additional features as optional bonus. I always try hard to make windowed mode and upscaling work with all games :)

Why won't this work with the work with fshack? What does the fshack do that breaks this?

With fshack you can't call ChangeDisplaySettings, it was made to prevent that to ensure the display resolution will always stay the same and instead it will just upscale the game to the native resolution. That means there will never be a WM_DISPLAYCHANGE message.

elishacloud commented 3 years ago

I always try hard to make windowed mode and upscaling work with all games :)

Yeah, you do a good job also! That is what's so great about the Internet. We can have different projects with different focuses. :-)

With fshack you can't call ChangeDisplaySettings, it was made to prevent that to ensure the display resolution will always stay the same and instead it will just upscale the game to the native resolution. That means there will never be a WM_DISPLAYCHANGE message.

I see. Thanks for the information!

elishacloud commented 3 years ago

Ok, I found a fix for this. I just added the following code to the SetDisplayMode() function if exclusive mode is set.

DWORD bpp = displayModeBPP;
DWORD res = (WORD)displayWidth | ((WORD)displayHeight << 16);
SendMessage(HWND_BROADCAST, WM_DISPLAYCHANGE, (WPARAM)bpp, (LPARAM)res);

Here is the new update: dxwrapper.zip

mirh commented 3 years ago

With fshack you can't call ChangeDisplaySettings, it was made to prevent that to ensure the display resolution will always stay the same and instead it will just upscale the game to the native resolution

That sounds a hella lot like GPU scaling... Which does still allow all calls to succeed. I'm really skeptical wine's bugs should be covered here.

FunkyFr3sh commented 3 years ago

I posted a comment about it here too: https://github.com/ValveSoftware/Proton/issues/2858#issuecomment-698888259

Maybe they're going to fix it. But we need the patch on windows too if we want upscaling support (It's not just a problem on wine)

maxigaz commented 3 years ago

Here is the new update: dxwrapper.zip

When I try it with the internal resolution being 1280x720, the game crashes at launch. If both the internal and screen resolution are 1920x1080, the game works fine.

Here’s the message that appears in the terminal output:

X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  12 (X_ConfigureWindow)
  Value in failed request:  0x0
  Serial number of failed request:  145
  Current serial number in output stream:  149

In addition, here’s the generated log file that I found next to dxwrapper: dxwrapper-pharaoh.log

mirh commented 3 years ago

But we need the patch on windows too if we want upscaling support

Upscaling is a nice convenience feature, but you shouldn't start from the assumption a generic utility ought to support it.

Anyway.. the games are platinum since like a decade. What's the deal now? And why aren't you first testing vanilla stable wine?

elishacloud commented 3 years ago

@maxigaz, thanks for testing this for me. I can only test it on Windows. Can you try this one?

Here is the update: dxwrapper.zip

maxigaz commented 3 years ago

@maxigaz, thanks for testing this for me. I can only test it on Windows. Can you try this one?

Here is the update: dxwrapper.zip

I’ve just playtested it for an hour in Pharaoh and for a few minutes in Zeus. Scrolling works now in both. Thank you very much! I truly appreciate your work.