sirnuke / steambridge

A project to allow Steam applications running under WINE to communicate with a native Linux version of Steam.
Other
122 stars 7 forks source link

MacOS compatibility #2

Open Drakulix opened 10 years ago

Drakulix commented 10 years ago

Hey SirNuke, I have spend the last days to find a way to get this nice library to work on MacOS.

I have already come quite far and have difficulties sorting out some final errors.

  1. I am using the pre-compiled steam_api_proxy.dll you uploaded.
  2. I got the steam_api_bridge.dll.so to compile after linking explicitly against libstdc++. (MacOS defaults to libc++, which does not compile correctly with the bridge, but thats another bug).
  3. I installed the helper tools and got a working Wine 1.7.20 install up and running.
  4. I have checked that the steam_api.dll gets replaced correctly, and all environment variables for launching Wine are set correctly.
  5. I also replaced the linux libsteam_api.so with my mac libsteam_api.dylib (taken from Left 4 Dead 2 for Mac, I did not find a global one).
  6. I also adjusted all paths in the config.py and utility.py to match the MacOS equivalent paths. (7. You have a lot typo's in the python scripts like "app = app.Entry(...)", instead of "app = appdb.Entry(...)")

So at first I made a second steam account for testing and tried to get "Loadout" running. I know it is a multiplayer title (which is not supported), but it was the first free game, that came into my mind and I was only hoping to get into the main menu. I installed the game in another wine prefix via Windows Steam and manually moved the Manifest and the Game Files.

Upon starting the game process killed itself very quickly. I forget to install the windows Steam version to that prefix and instead tried to run Alien Swarm, as I though the game itself is probably just not working. Alien Swarm was giving me an error message instead (GetSteamInstallPath not implemented).

Then I just linked my new steam account with family sharing to my real account to get some more games to test. Next try was "South Park: The Stick Of Truth", I got the same bug like with Loadout and finally realized Steam was not installed into the prefix probably. So I did that and now starting SouthPark was just launching the windows steam version instead and starting the game that way...

To debug this issue I was running wine with WINEDEBUG=+loaddll and WINEDEBUG=+module and I found not a single line about the steam_api.dll (neither proxy or bridge), instead the game did load c:\program\ files\steam\steam.exe.

For further debugging I downloaded the dependency walker and did open the southpark.exe with it. The result is, that the steam_api.dll is loaded lazy and it's dependency steam_api_bridge.dll cannot be loaded. Which means that the steam_api_bridge.dll.so fails to load, am I correct?

I have no idea, what I may try to continue debugging this error, as I do not find any errors in the wine logs about loading the bridge. To you have an idea, how to fix this? If this issue might be game related, can you recommend a game (best free or with a demo version), that is known to work correctly on linux with steambridge?

sirnuke commented 10 years ago

Hello Drakulix,

At a high level, I don't think there's any technical reason why SteamBridge can't work on OS X. I've mostly followed this document for calling conventions, which doesn't suggest any relevant differences between GCC-Linux and GCC-OSX. Apple gets a thumbs up for actually detailing their ABI, but doesn't discuss how to handle C++ code. If there's a calling convention mismatch, the app should crash in a way that provides a stack trace/memory dump/etc.

My test application has primarily been the demo of Ethan Meteor Hunter. I would run with some combination of the following in WINEDEBUG: +steambridge, warn+all, trace+all if you continue to have trouble.

Drakulix commented 10 years ago

Thanks for that quick tips. I compiled using clang however and not with the GCC as I am using already OSX 10.10, which unfortunately currently has problems building a working GCC (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61407, wtf apple..).. Might that also be a problem? Anyways there is enough to work on, thanks.

I will probably make a pull request once I got something working on mac os and try to keep linux compatibility as far as I can test it. No rush, but it would be nice, if you could review my changes, when those are done, to make sure, I did not accidentally broke something.

sirnuke commented 10 years ago

My gut suspicion is that the Bridge needs to be compiled with the same compiler (and same libstdc++) that Valve uses for SteamWorks/libsteam_api.dylib. This is all a bit unfortunate, as there's very little C++ code in the Bridge, and it'd probably be a non-issue if it was 100% C.

Drakulix commented 10 years ago

I check how the libsteam_api.dylib is linked and it does link against the same libstdc++ library I am using.

Okay upon fixing all my mistakes SouthPark is still not working (wired stuff), but Ethan Meteor Hunter Demo seems to try to load. steam_api_bridge does get loaded correctly, but it crashes very quickly:

TRACE: bool cdecl SteamAPI_Init(void)() TRACE: bool __cdecl SteamAPI_InitReal(bool)(0) TRACE: void thiscall AppState::setSafeMode(bool)(0) wine: Unhandled page fault on read access to 0xffffffff at address 0x95328159 (thread 0009), starting debugger...

If you need any other informations or if you have an idea, how to fix, I am willing to help. But I am not very skilled when it comes to assembly and low-level c++ calls and this looks like something fundamentally broken...

sirnuke commented 10 years ago

So SteamAPI_InitReal records whether the client application was activated in safe mode (safe mode means the client specifies the API version they are using, otherwise defaults to the latest API version in the steam_api library), and then calls SteamAPIInitSafe (which is exported by the Winelib DLL, the extra underscore is to avoid symbol conflicts).

If you are running with at least "WINEDEBUG=+steambridge" and you aren't getting a trace message for SteamAPIInitSafe, then is something is pretty broken. It should be fully supported out of the box by Winelib, even if you are using clang.

One thing to try is to print the backtrace (wait for wingdb to load and run 'backtrace') and dump that here.

Drakulix commented 10 years ago
MacBook-Pro:~ Drakulix$ WINEDEBUG=+steambridge WINEDLLPATH=/usr/local/Cellar/steambridge/0.0.2/share/steambridge/ wine /Users/Drakulix/Library/Application\ Support/Steam/SteamApps/common/Ethan\ Meteor\ Hunter\ Demo/Ethan.exe 
TRACE: __thiscall AppState::AppState(void)(this=0x0037164C)
TRACE: int __stdcall DllMain(struct HINSTANCE__ *,unsigned long,void *)(0x00360000,1,0x00000001])
TRACE: bool __cdecl SteamAPI_RestartAppIfNecessary(unsigned int)(273280)
LOG: bool __cdecl SteamAPI_RestartAppIfNecessary(unsigned int)Overriding this function to return FALSE (no restart request) appid=273280
TRACE: bool __cdecl SteamAPI_Init(void)()
TRACE: bool __cdecl SteamAPI_InitReal(bool)(0)
TRACE: void __thiscall AppState::setSafeMode(bool)(0)
wine: Unhandled page fault on read access to 0xffffffff at address 0x95328159 (thread 0009), starting debugger...
WineDbg starting on pid 0008
Unhandled exception: page fault on read access to 0xffffffff in 32-bit code (0x95328159).
Register dump:
 CS:001b SS:0023 DS:0023 ES:0023 FS:1007 GS:000f
 EIP:95328159 ESP:0032faf8 EBP:0032fc70 EFLAGS:00010212(  R- --  I   -A- - )
 EAX:7bcb1b24 EBX:0032fd2c ECX:0032fba0 EDX:7bc7abe8
 ESI:a062c038 EDI:00000400
Stack dump:
0x0032faf8:  00000000 00000000 00000000 00000000
0x0032fb08:  00000000 00000000 00000000 00000000
0x0032fb18:  00000000 00000000 00000000 00000000
0x0032fb28:  00000000 00000000 00000000 00000000
0x0032fb38:  00000000 00000000 00000000 00000000
0x0032fb48:  00000000 00000000 0032fba0 00000000
0200: sel=1007 base=7ffc0000 limit=00000fff 32-bit rw-
Backtrace:
=>0 0x95328159 (0x0032fc70)
  1 0x95328537 (0x0032fca0)
  2 0x95362441 (0x0032fcc0)
  3 0x7bc2beaa (0x0032fd00)
  4 0x8205678a (0x0032fd20)
  5 0x7bc2c052 (0x0032fd50)
  6 0x8205685d (0x0032fd80)
  7 0x40e4c682 (0x0032fe10)
  8 0x0040152f in ethan (+0x152e) (0x0032fe40)
  9 0x0062091f in ethan (+0x22091e) (0x0032fed0)
  10 0x7b847edc in kernel32 (+0x37edb) (0x0032fee8)
  11 0x7b84a7b6 in kernel32 (+0x3a7b5) (0x0032ff28)
  12 0x7bc62dbc (0x0032ff38)
  13 0x7bc65076 (0x0032ffb8)
  14 0x7bc62d82 (0x0032ffd8)
  15 0x7bc412f0 (0x0032ffe8)
sirnuke commented 10 years ago

This supports my suspicion that the crash is happening when SteamAPIInitSafe() is called, but unfortunately, without access to an OSX setup I'm not sure if I can debug it further. One thing to try is to compile using GCC instead of Clang, once all that is sorted out.

Drakulix commented 10 years ago

I will report back, once I got a GCC running. If you want an OSX setup, you might be interested in the possibility of install Mac OS X into a VM. There are even some unofficial 2d graphic acceleration drivers for VMWare, just in case you are interested.