Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed off-by-one error in mouse button bit-masking #177

Merged
merged 1 commit into from
Apr 26, 2018

Conversation

Linearity
Copy link

@Linearity Linearity commented Apr 18, 2018

getMouseButtons detects the wrong buttons because its bit mask doesn't match SDL's convention. For example, it's impossible to detect the left mouse button being held.

getMouseState, like SDL_GetMouseState, produces a set of Boolean flags encoded as the bits of an integer. We test the nth flag by AND-ing that integer with a bit mask: the integer 1 bit-shifted by n places.

The state of the left mouse button resides in the lowest-order bit—0 places away from the lowest place. So, to test that button we have to bit-shift by 0 places.

SDL provides the macro definitions SDL_BUTTON(X) and SDL_BUTTON_LEFT to do that bit-shifting. It defines SDL_BUTTON_LEFT to be 1, not 0, and it defines SDL_BUTTON(X) to subtract 1 from its argument before using it to construct the bit mask (see lines 203-204 in SDL_mouse.h):

#define SDL_BUTTON(X)       (1 << ((X)-1))
#define SDL_BUTTON_LEFT     1

So, && SDL_BUTTON( SDL_BUTTON_LEFT ) = && (1 << (1 - 1)) = && (1 << 0), which is what we want.

However, the corresponding Haskell provisions don't match that convention. Raw.SDL_BUTTON_LEFT (and hence toNumber ButtonLeft) is defined to be 1, but getMouseButtons doesn't do the same subtraction as SDL_BUTTON(X):

getMouseButtons = liftIO $
  convert <$> Raw.getMouseState nullPtr nullPtr
  where
    convert w b = w `testBit` fromIntegral (toNumber b)

Here, (`testBit` fromIntegral (toNumber ButtonLeft)) = (`testBit` 1), but that doesn't test the left button. We want (`testBit` 0).

@chrisdone
Copy link
Member

Pity it's hard to make a test suite for this!

@chrisdone
Copy link
Member

Thanks!

@chrisdone chrisdone merged commit c24388c into haskell-game:master Apr 26, 2018
@Linearity
Copy link
Author

Thanks for pulling this. When will it be on Hackage? There is no workaround for detecting the left mouse button with the current version. I either have to distribute my own version or use a different, much less popular button.

@ocharles
Copy link
Member

I'll try and cut a release soon - I'll add a reminder.

@Linearity
Copy link
Author

What's the status of this?

@ocharles
Copy link
Member

ocharles commented Jul 5, 2018

Just to update others, this is released as 2.4.1.0.

@chrisdone
Copy link
Member

chrisdone commented Jul 5, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants