https://bugs.winehq.org/show_bug.cgi?id=56364
Bug ID: 56364 Summary: Crazy Factory: Hang when starting new game Product: Wine Version: 9.2 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: user32 Assignee: wine-bugs@winehq.org Reporter: winebugzilla@tasossah.com Distribution: ---
Created attachment 76101 --> https://bugs.winehq.org/attachment.cgi?id=76101 Minimal reproducible example: client
Crazy Factory (AppID 13494, also known as Gadget Tycoon) hangs when starting a new game (Main Menu -> Offline game -> Freeplay). This is not a regression, but has last been tested under wine-staging 9.2.
The game (client) spawns the server (CrazyFactoryServer.exe), waits for it to finish initialising by calling WaitForSingleObject() and WaitForInputIdle(), and then looks for its HWND so that it can communicate with it using window messages.
I have written a standalone test case which reproduces this issue in Wine without requiring access to the original software.
To reproduce: 1. Download client.c and server.c 2. Compile them as follows: - i686-w64-mingw32-gcc server.c -l ole32 -mwindows -o server.exe - i686-w64-mingw32-gcc client.c -o client.exe 3. Run client.exe
Under Windows XP: client.exe reports "HWND Found" and exits. Under Wine: client.exe hangs on WaitForInputIdle().
The only way in Wine to get WaitForInputIdle() to return is by running everything in a virtual desktop, clicking on the start menu (which makes the server show up in the taskbar), clicking on the server in the taskbar, and then clicking on the server's window decoration and moving it around.
Unfortunately, since the game itself runs in fullscreen, one can not click and drag the server window. Instead, to get the game working as-is, one can patch the binary (556b01b1afa97f39d361fe692bc3477a2577a25abf91f4a92e88a561bd5bd561 GadgetTycoon.exe) by setting the byte at offset 0x241ED from 0xFF to 0x01. This sets the dwMilliseconds parameter on WaitForInputIdle() to 0x01 (instead of INFINITE), which makes it time out, thus avoiding the hang and getting the game running.
https://bugs.winehq.org/show_bug.cgi?id=56364
--- Comment #1 from TasosSah winebugzilla@tasossah.com --- Created attachment 76102 --> https://bugs.winehq.org/attachment.cgi?id=76102 Minimal reproducible example: server
https://bugs.winehq.org/show_bug.cgi?id=56364
Fabian Maurer dark.shadow4@web.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Keywords| |download, testcase CC| |dark.shadow4@web.de
--- Comment #2 from Fabian Maurer dark.shadow4@web.de --- Confirming
https://bugs.winehq.org/show_bug.cgi?id=56364
--- Comment #3 from Fabian Maurer dark.shadow4@web.de --- When I replace your messageloop (the whole wile(1)) with the following code it works: ``` while (GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } ```
Your code is doing a busy wait, not sure if that is normal.
Fun fact: In vanilla wine this issue only occurs when I delete my WINEPREFIX and then run the command.
Will bisect staging tomorrow (or so).
https://bugs.winehq.org/show_bug.cgi?id=56364
--- Comment #4 from Fabian Maurer dark.shadow4@web.de --- Btw, are you sure the game uses the same messageloop, or how did you figure that out?
https://bugs.winehq.org/show_bug.cgi?id=56364
TasosSah winebugzilla@tasossah.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Version|9.2 |9.3
--- Comment #5 from TasosSah winebugzilla@tasossah.com ---
Your code is doing a busy wait, not sure if that is normal.
That is what CrazyFactoryServer.exe does. It causes equally high CPU load on my machine, just like server.exe.
Fun fact: In vanilla wine this issue only occurs when I delete my WINEPREFIX and then run the command. Will bisect staging tomorrow (or so).
I just tested it, and it does not work in vanilla wine no matter how many times I start it. Make sure to run it in a virtual desktop for consistency. It's possible your WM does something which causes a message to be sent, which might get the whole thing unstuck. Although under compiz nothing I do to the server window makes it work.
$ /opt/wine-devel/bin/wine --version wine-9.3
I did notice however that I can click and move the server window in vanilla wine (inside the virtual desktop). The game, however, seems to break when it loses focus.
Btw, are you sure the game uses the same messageloop, or how did you figure that out?
I am pretty confident it is the same loop. I disassembled it many years ago to create the test case, so the details are a bit fuzzy. Looking at it again, it is more like this (which has the same effect in this case):
``` BOOL run = TRUE; do { while(PeekMessageA(&Msg, 0, 0, 0, PM_REMOVE)) { if(Msg.message == WM_QUIT) { run = FALSE; break; } TranslateMessage(&Msg); DispatchMessageA(&Msg); } } while(DoServerWork() && run); ```