Menu

RollerCoaster Tycoon 1 freeze (user32.cpp)

2023-04-11
2023-04-11
  • dippy dipper

    dippy dipper - 2023-04-11
    • First of all this affects only a configuration where "Run in Window" flag is disabled.
    • Secondly this became an issue starting with v2_05_85.

    Some background info:
    RCT1 has issues when set to fullscreen mode so it is usually better to leave it to run in its own windowed mode. So why use Dxwnd at all then? Well the game has one nasty bug/feature where if you enter the actual gameplay and use the right mouse button after closing the game your mouse buttons will be reversed in Windows. This corrects itself after clicking the mouse buttons a couple of times but its annoying. So Dxwnd can help with its "Hook dinput" flag which removes this annoyance.

    Now to the point:
    So my configuration for RCT1 in Dxwnd is to disable "Run in Window" and set the "Hook dinput" flag. However I then noticed that if I leave the game alone for about 3 minutes it freezes. This is noticeable if you start the game and leave the rolling demo to run by itself. Investigation showed that this issue started with v2_05_85 and I was able to trace the change back to user32.cpp.

    The "fix" was to comment out the old code which set the "ret" value and instead force an immediate return as it was done in v2_05_84.

    user32.cpp changes:

    static HDC WINAPI sGetDC(HWND hwnd, ApiArg)
    {
        // to do: add parameter and reference to pGDIGetDCEx to merge properly GetDC and GetDCEx
        HDC ret;
        HWND lochwnd;
    
        if(!dxw.IsFullScreen()) return(*pGDIGetDC)(hwnd); /* RCT1 fix - revert to 2_05_84 logic*/
        /*
        if(!dxw.IsFullScreen()) {
            ret = (*pGDIGetDC)(hwnd);
            OutTraceDW("%s: hdc=%#x\n", ApiRef, ret);
        }
        */
    
        lochwnd=hwnd;
    

    I am not sure if this is the proper way to fix it but it seemed to work with RCT1 and it no longer freezes in the rolling demo after ~3 minutes when "Run in Window" flag is disabled. I also don't know if this is something that would help other games that are run with "Run in Window" flag disabled or if it would be harmful. I just do not have the proper knowledge on this subject.

    Also I know that ideally you would set the game to run in fullscreen and not disable the "Run in Window" flag. I almost never disable the "Run in Window" flag. However RCT1 is a tricky exception as trying to handle its fullscreen mode with Dxwnd has proven problematic in my testing.

     
  • gho

    gho - 2023-04-11

    I see ... my big mistake. I suppose I made the change to get a trace of the DC handle, but I forgot to interrupt the operation in case on non-windowed mode. In effect, the code that follows can be dangerous, and probably causes a handle leakage.
    I would propose a slightly different fix to repair the logic but have a valid trace in any case. I would fix this way, con you test it and confirm it is as good as yours?

        if(!dxw.IsFullScreen()) {
            ret = (*pGDIGetDC)(hwnd);
            OutTraceDW("%s: hdc=%#x\n", ApiRef, ret);
            return ret; // <-- my fix, return after the trace message
        }
    
     
    • dippy dipper

      dippy dipper - 2023-04-11

      Yes, that works fine also.

       

Log in to post a comment.

MongoDB Logo MongoDB