Menu

#110 Suggested fix for broken mouse behavior in latest Exult

None
closed-accepted
nobody
None
5
2020-04-20
2018-12-08
No

I tried out the latest version of Exult on github, and noticed that the mouse wasn't working as expected. I have made a fix (see the attached patch) that solves it for me.

It's a bit hard to explain the problem that is fixed by this patch, but I'll try:

To move around in Ultima 7, the player must keep the right mouse button pressed while moving the cursor towards the edge of the screen. Before my patch, the mouse cursor would appear to be restricted to the boundaries of the game window while keeping the right mouse button pressed. By "appear", I mean that the displayed mouse cursor was locked to the game window. However, it turned out that the actual mouse cursor position was not restricted. When dragging the cursor towards the edge of the window, it would keep moving beyond the edge of the game window (completely invisible). The effect of this was a mismatch between the displayed mouse cursor positon and the actual mouse cursor position. This made the mouse cursor seem completely unresponsive and made movement in the game extremely annoying.

I don't remember seeing this bug when I last played Ultima 7 on Exult (a few years ago), but so many things have changed since then that I didn't bother looking for regressions. I am using xorg-server 1.20.3, which also seems to be causing similar issues with dosbox (the mouse doesn't work at all when autolock=true ), so the regression might not even be caused by Exult. To find a solution, I googled around for a general SDL call that would allow me to lock the cursor to the game window. I found that SDL2 has SDL_SetWindowGrab() that does exactly this. My patch simply calls this function with grab=true on button down and grab=false on button up.

I don't know if this will have other, unintented, side effects but at least it's made the game playable for me, so I thought I'd share my solution here.

1 Attachments

Discussion

  • Dominik Reichardt

    While we are at it, you might need to do that for the Wizard's Eye spell movement in exult.cc, too.
    In void Wizard_eye

    To test: grab a spellbook, enter the archwizard cheat (alt+w), and use the wizard eye spell. The eye is moved same as the avatar in normal play.

     
  • Haakon Riiser

    Haakon Riiser - 2018-12-08

    Thanks for the tip regarding Wizard_eye. Don't remember ever using that spell, so I was not aware. :)

    Btw, the patch I attached when I created this ticket also patches MenuList::handle_events(), even though that's not a place where you would normally need this fix. The only reason I patched that method was to get a faster edit-compile-test loop (no need to launch the game and load a save, just test it immediately after starting Exult).

     
  • Haakon Riiser

    Haakon Riiser - 2018-12-08

    Untested fix for the wizard's eye spell:

    diff --git a/exult.cc b/exult.cc
    index 6977cd7a..37905113 100644
    --- a/exult.cc
    +++ b/exult.cc
    @@ -2053,6 +2053,7 @@ void Wizard_eye(
            uint32 last_repaint = 0;    // For insuring animation repaints.
            uint32 stop_time = SDL_GetTicks() + msecs;
            bool timeout = false;
    
    +       bool window_grab_enabled = false;
            while (!timeout) {
                    Delay();        // Wait a fraction of a second.
    
    @@ -2091,8 +2092,18 @@ void Wizard_eye(
                            int ms = SDL_GetMouseState(&x, &y);
                            int mx, my;
                            gwin->get_win()->screen_to_game(x, y, gwin->get_fastmouse(), mx, my);
    
    -                       if (SDL_BUTTON(3) & ms)
    +                       if (SDL_BUTTON(3) & ms) {
    +                               if (!window_grab_enabled) {
    +                                       SDL_SetWindowGrab(gwin->get_win()->get_screen_window(), SDL_TRUE);
    +                                       window_grab_enabled = true;
    +                               }
                                    Shift_wizards_eye(mx, my);
    +                       } else {
    +                               if (window_grab_enabled) {
    +                                       SDL_SetWindowGrab(gwin->get_win()->get_screen_window(), SDL_FALSE);
    +                                       window_grab_enabled = false;
    +                               }
    +                       }
                            gwin->set_all_dirty();
                            gwin->paint_dirty();
                            // Paint sprite over view.
    @@ -2123,6 +2134,11 @@ void Wizard_eye(
                            Mouse::mouse->blit_dirty();
            }
    
    
    +       // Make sure that the window is ungrabbed after the wizard's eye spell ends.
    +       if (window_grab_enabled) {
    +               SDL_SetWindowGrab(gwin->get_win()->get_screen_window(), SDL_FALSE);
    +       }
    +
            if (!os)
                    Mouse::mouse->hide();
            gwin->center_view(gwin->get_main_actor()->get_tile());
    
     

    Last edit: Haakon Riiser 2018-12-08
  • Jeff Freedman

    Jeff Freedman - 2018-12-08

    Thanks for finding this!
    I've been playing through the two games recently and have noticed this
    problem.

    On Fri, Dec 7, 2018, 5:38 PM Haakon Riiser <hakonrk@users.sourceforge.net
    wrote:


    Status: open
    Group: Unimplemented
    Created: Sat Dec 08, 2018 01:38 AM UTC by Haakon Riiser
    Last Updated: Sat Dec 08, 2018 01:38 AM UTC
    Owner: nobody
    Attachments:

    I tried out the latest version of Exult on github, and noticed that the
    mouse wasn't working as expected. I have made a fix (see the attached
    patch) that solves it for me.

    It's a bit hard to explain the problem that is fixed by this patch, but
    I'll try:

    To move around in Ultima 7, the player must keep the right mouse button
    pressed while moving the cursor towards the edge of the screen. Before my
    patch, the mouse cursor would appear to be restricted to the boundaries
    of the game window while keeping the right mouse button pressed. By
    "appear", I mean that the displayed mouse cursor was locked to the game
    window. However, it turned out that the actual mouse cursor position
    was not restricted. When dragging the cursor towards the edge of the
    window, it would keep moving beyond the edge of the game window (completely
    invisible). The effect of this was a mismatch between the displayed mouse
    cursor positon and the actual mouse cursor position. This made the mouse
    cursor seem completely unresponsive and made movement in the game extremely
    annoying.

    I don't remember seeing this bug when I last played Ultima 7 on Exult (a
    few years ago), but so many things have changed since then that I didn't
    bother looking for regressions. I am using xorg-server 1.20.3, which also
    seems to be causing similar issues with dosbox (the mouse doesn't work at
    all when autolock=true ), so the regression might not even be caused by
    Exult. To find a solution, I googled around for a general SDL call that
    would allow me to lock the cursor to the game window. I found that SDL2 has
    SDL_SetWindowGrab() that does exactly this. My patch simply calls this
    function with grab=true on button down and grab=false on button up.

    I don't know if this will have other, unintented, side effects but at
    least it's made the game playable for me, so I thought I'd share my
    solution here.


    Sent from sourceforge.net because you indicated interest in
    https://sourceforge.net/p/exult/bugs/2031/

    To unsubscribe from further messages, please visit
    https://sourceforge.net/auth/subscriptions/

     
  • Dominik Reichardt

    look at the workaround the DOSBOX team just implemented https://sourceforge.net/p/dosbox/code-0/4177 maybe that is something for Exult, too

     
  • Dominik Reichardt

    Ticket moved from /p/exult/bugs/2031/

     
  • Dominik Reichardt

    A bit late, but Haakon, did you experience any other issue? Otherwise I will take a look at implementing this.
    As Jeff mentioned it I thought he would add it and forgot about it :)

     
  • Dominik Reichardt

    Updated the patch for current master. The Wizard eye part is not working (doesn't grab the mouse) so I left this out.

     
  • Dominik Reichardt

    Accepted in 62324ce5 without the MenuList::handle_events() and Wizard Eyes part

     
  • Dominik Reichardt

    • status: open --> closed-accepted
    • Group: Unimplemented -->
     
  • Haakon Riiser

    Haakon Riiser - 2020-04-20

    Thanks for merging this fix. It's been a while, but I don't remember having any problems with the patch when I was testing it.