Getting game with native opengl32.dll to work...

Questions about Wine on Linux
Post Reply
spike1
Level 1
Level 1
Posts: 6
Joined: Thu Apr 11, 2019 10:11 am

Getting game with native opengl32.dll to work...

Post by spike1 » Thu Apr 11, 2019 10:31 am

Hey there!

Hopefully this is the right place to ask for help on this, my apologies if not... I've been trying to get the game Cry of Fear functioning fully and I've been having some difficulties. From my understanding, the game uses a modified version of opengl32.dll to alter its render engine (kind of odd but I think this is due to it originally being a Half Life mod). As expected Wine by default links it instead to the builtin opengl32.dll rather than the custom one, which leads to a lack of any real-time lighting and some other graphical issues. Outside of that everything works really well :).

I've tried the only thing I can think of which is to add it as an native override, however when this is done the game complains about not being able to find another dll (hw.dll) which is still right next to the executable. So yeah I was wondering if anyone has any ideas on how to proceed :). Thanks!

Setup Details:
OS: Arch Linux
Wine Version: Same problem on both 4.3 and 4.5
GPU: Nvidia GTX 750ti with proprietary drivers

Installation: In a fresh 32bit wine setup (set to approximate Windows XP) I used winetricks to install Steam, then downloaded and installed the game. I then ran it from within Steam.

Game Link: https://store.steampowered.com/app/223710/Cry_of_Fear/ (Surprisingly it's free!)

spike1
Level 1
Level 1
Posts: 6
Joined: Thu Apr 11, 2019 10:11 am

Re: Getting game with native opengl32.dll to work...

Post by spike1 » Fri Apr 12, 2019 9:56 pm

I'm not really sure if this helps but I ran the game while monitoring for file accesses, and I found that it's trying to access hw.dll (which it finds) and hw.dll.dll (which it doesn't), and afterwards tries shared object versions, neither which exists (I'm guessing Wine must create these from the dlls to link them or something?). I've attached the full strace output, hope it's useful :)
Attachments
foo.trace.25835.7z
output of strace -ff -o foo.trace <ExePath>
Compressed cause it's 4mb
(63.86 KiB) Downloaded 17 times

spike1
Level 1
Level 1
Posts: 6
Joined: Thu Apr 11, 2019 10:11 am

Re: Getting game with native opengl32.dll to work...

Post by spike1 » Tue Apr 16, 2019 12:44 am

Ok I manage to get it to use the correct opengl dll, but unsurprisingly this causes problems. The problem was that hw.dll loads opengl32.dll (the modified one), while it also loads ddraw.dll, which then requires wined3d which then requires the Wine opengl32.dll - so it had to be able to load both the native and builtin versions. I just renamed the modified opengl32 to opengl33 and modified hw.dll to use that instead.

So this works...except now obviously it calls wglCreateContext and hangs immediately...I'm starting to think the only way to get this working is via decompiling and remapping the opengl calls, but if I'm totally off track and anyone else has any better ideas I'd love to hear them!

spike1
Level 1
Level 1
Posts: 6
Joined: Thu Apr 11, 2019 10:11 am

Re: Getting game with native opengl32.dll to work...

Post by spike1 » Tue Apr 16, 2019 11:29 am

From what I can gather, it seems like the modified opengl32 (hereby dubbed paranoiagl32) should act as a layer between the application and the real opengl32. It seems to be having trouble loading the real opengl functions though. Having a look at the Wine opengl32.dll.so with "nm -D '/usr/lib32/wine/opengl32.dll.so'" I see a few functions missing; most notably wglCreateContext...so I was wondering what .so that might be defined in if not opengl32? For reference I've attached the output of that command.

(Also disregard what I said about the wglCreateContext hang, I accidentally modified the dll to load itself and since the wglCreateContext just jumps to the loaded wglCreateContext (I think anyway) it would just infinite loop...I'm so out of my depth here XD)

spike1
Level 1
Level 1
Posts: 6
Joined: Thu Apr 11, 2019 10:11 am

Re: Getting game with native opengl32.dll to work...

Post by spike1 » Thu Apr 18, 2019 6:13 am

Ok once more disregard the wglCreateContext thing - still don't know why it doesn't show up in nm -D but meh it's in there. I can confirm paranoiagl32 can load from opengl32 just fine, however I was right in that it was trying to load some functions that definitely don't exist (such as wglGetDefaultProcAddress) which would cause it to throw an error. I've modified it to just ignore any functions it can't load, however I guess it must actually use one of the ones which aren't defined since it just loads to a black window now. I'll try and figure out which one it uses and find a work around...that said I'm not sure how to do that...like I said I'm a bit out of my depth XD. I'm hoping I'll just be able to set break points on each of the wgl functions and see which ones it hits.

spike1
Level 1
Level 1
Posts: 6
Joined: Thu Apr 11, 2019 10:11 am

Re: Getting game with native opengl32.dll to work...

Post by spike1 » Sat Apr 20, 2019 8:32 pm

It works!
It is possible to get the dynamic lighting working under Wine (doing better than recent versions of Windows here haha). I'll try and find a better way to do this that doesn't involve modifying the binaries later, but here are the kinda messy steps I did:
First thing was to get it using the modified opengl32. I'm not sure if there's a better way, but I ended up just renaming the dll to opengl33 and then correcting the references to it in /hw.dll and /cryoffear/cl_dlls/client.dll. That said, I've got a feeling the normal opengl32 'Native then Builtin' override may work just as well, I just misinterpreted an error I got when I tried that early on.
Next, there's a single function that Wine's opengl32 doesn't expose currently (wglGetDefaultProcAddress, ideally this should just be added as a stub or something so this step won't be necessary), and the dll will error if it can't load it. Luckily it's really easy to fix this, just make these changes in CoF's opengl32.dll(or 33 if you went with renaming) from jne(75) to jmp(EB):

Code: Select all

Address To From
000066DB EB 75
00006702 EB 75
00006728 EB 75
0000674F EB 75
00006776 EB 75
0000679C EB 75
000067EA EB 75
00006810 EB 75
00006837 EB 75
0000685E EB 75
000068AB EB 75
000068F8 EB 75
0000691F EB 75
00006943 EB 75
00006966 EB 75
0000698A EB 75
(These are way more changes than necessary but 'eh I forget which are important)

And that's it!

As a side note, if at any point you run the game and it throws a 'Can't set video mode' error or what have you, it'll start loading from sw.dll instead of hw.dll. You can set this back through the registry key "HKEY_CURRENT_USER\Software\Valve\Half-Life\Settings\ENGINEDLL".

Hopefully this is helpful to anyone else wanting to play it. It's still not exactly a bug free experience, I get a freeze every so often from:
010b:err:ntdll:RtlpWaitForCriticalSection section 0x7bcf3d40 "../../../wine/dlls/ntdll/loader.c: loader_section" wait timed out in thread 010b, blocked by 00f3,
and a bunch of the same bugs that occur on Windows, but overall it's definitely playable :P. If you have any issues feel free to ask here :)

(Also by any chance could a moderator change the title of the thread to "Getting Cry of Fear with modified opengl32 to work..." to increase visibility? I'm not sure if I can do it myself, thanks :))

Post Reply