![]() |
|
Incosnsistency in al_get_mouse_state_axis and al_mouse_button_down |
Dennis
Member #1,090
July 2003
![]() |
I think there is a minor inconsistency in how the data sources on the mouse device are handled. The available axes start counting at 0. The code below is a snippet from "mousenu.c" 1/* Function: al_get_mouse_state_axis
2 */
3int al_get_mouse_state_axis(ALLEGRO_MOUSE_STATE *ret_state, int axis)
4{
5 ASSERT(ret_state);
6 ASSERT(axis >= 0);
7 ASSERT(axis < (4 + ALLEGRO_MOUSE_MAX_EXTRA_AXES));
8
9 switch (axis) {
10 case 0:
11 return ret_state->x;
12 case 1:
13 return ret_state->y;
14 case 2:
15 return ret_state->z;
16 case 3:
17 return ret_state->w;
18 default:
19 return ret_state->more_axes[axis - 4];
20 }
21}
22
23/* Function: al_mouse_button_down
24 */
25bool al_mouse_button_down(ALLEGRO_MOUSE_STATE *state, int button)
26{
27 ASSERT(state);
28 ASSERT(button > 0);
29
30 return (state->buttons & (1 << (button-1)));
31}
and the documentation said: Now, as I see that, there are two options now. option 2) add a remark to the documentation to those two functions, which says something like "first axis is 0" / "first (left) button is 1" Option 2 has the benefit of not destroying any existing code which uses Allegro5 (less intrusive). I would personally prefer option 1, so that "the first" of whatever collection of thing is always 0. --- 0xDB | @dennisbusch_de --- |
Mark Oates
Member #1,146
March 2001
![]() |
Dennis said: Option 2 has the benefit of not destroying any existing code which uses Allegro5 (less intrusive). Though I'm not one to know about the purpose of the standard, I vote that we "do it right", regardless of what that does to the existing API. -- |
Elias
Member #358
May 2000
|
I'd agree, "mouse_state.buttons & (button - 1)" or "event.button - 1" make no sense. The only thing the currently required -1 is likely to do is cause someone to get their mouse button code wrong at first. On the other hand it's a fairly minor issue and breaks existing mouse button code in a somewhat bad manner (e.g. the A5 examples themselves would crash if 0 can now be returned in "buttons[event.mouse.button-1]"). In any case, we need to add information about what the button field does to the ALLEGRO_EVENT and ALLEGRO_MOUSE_STATE documentation. Like for example say that 1 or 0 (depending on if we change it) is the left button. -- |
Evert
Member #794
November 2000
![]() |
Mark Oates said: I vote that we "do it right", regardless of what that does to the existing API.
Yes. Elias said: On the other hand it's a fairly minor issue and breaks existing mouse button code in a somewhat bad manner This is a valid point. It also doesn't break it in a way that is immediately obvious. You hope things will crash immediately when you do a bad memory access, but we all know that sometimes that doesn't happen - and that's the optimal case where it would be something obvious like that. Anyway, before deciding on whether to change it or not, maybe it's a good idea to think about whether there is a reason for the difference? I can't imagine that someone arbitrarily decided to use 0 or 1 in one case or the other. Quote: In any case, we need to add information about what the button field does to the ALLEGRO_EVENT and ALLEGRO_MOUSE_STATE documentation. Agreed. |
Matthew Leverton
Supreme Loser
January 1999
![]() |
I think all index related functions should start at 0, so I would vote to change it. It doesn't return a bitfield, not in that instance. It shouldn't matter that the underlying structure is a bitfield. ALLEGRO_MOUSE_STATE.buttons is a bitfield, so the buttons are 1, 2, 4, ... So either way there will be differences: state | func (curr) | func (new) --------------------------------- 1 1 0 2 2 1 4 3 2
|
Slartibartfast
Member #8,789
June 2007
![]() |
Why not dump the numbers and go with something like ALLEGRO_MOUSE_BUTTON_LEFT; You know, magic numbers and whatnot. ---- |
Dennis
Member #1,090
July 2003
![]() |
Evert said: It also doesn't break it in a way that is immediately obvious. You hope things will crash immediately when you do a bad memory access, but we all know that sometimes that doesn't happen - and that's the optimal case where it would be something obvious like that. Concerning the necessary refactoring of the library itself (and any other code included with Allegro5 inside the SVN), a safe way to catch all the code using the "al_mouse_button_down" function is to rename it temporarily. The compiler will then complain about being unable to find the function wherever it is used. The function can then be changed (to start with 0 for the left button). Each code file/line (identified by compiler) which uses the function can then be adjusted for the changed way of numbering the buttons (without renaming the call to the function though). Then after all the calls to it have been changed, the function can be renamed to its current name. This does not fix any usercode (not included with Allegro5) of course, but if the release notes for the next version include a well visible hint that that has been changed, users can adjust their code accordingly. Quote: Anyway, before deciding on whether to change it or not, maybe it's a good idea to think about whether there is a reason for the difference? I can't imagine that someone arbitrarily decided to use 0 or 1 in one case or the other. I think the current behavior might be a relic from the old Allegro (pre 5) api, where "mouse_b" was a bitfield (same that is now button in the state structure). In the old Allegro, there was no function to test for any specific mouse button (it had to be done by manually comparing the bits). In the current code, there are two different ways to test for a button state (which I like, because the user isn't forced to use either the event code or the manual state get/check). In the event handling code, the user would still have to compare the "button" bitfield to 1, 2, 4 to get which button was pressed, whereas with "al_mouse_button_down", currently 1,2,3 must be passed for the button parameter. "0" for "no button held down" does not make sense with the event handling code, because there are only the events "ALLEGRO_EVENT_MOUSE_AXES", "ALLEGRO_EVENT_MOUSE_BUTTON_DOWN" and "ALLEGRO_EVENT_MOUSE_BUTTON_UP". --- 0xDB | @dennisbusch_de --- |
Matthew Leverton
Supreme Loser
January 1999
![]() |
Slartibartfast said: Why not dump the numbers and go with something like ALLEGRO_MOUSE_BUTTON_LEFT; You know, magic numbers and whatnot. The first button is not necessarily the left button. So you'd have _FIRST, _SECOND, ... or _PRIMARY, _SECONDARY, ..., which to me is more verbose than it needs to be. |
Evert
Member #794
November 2000
![]() |
Matthew Leverton said: I think all index related functions should start at 0, so I would vote to change it. It doesn't return a bitfield, not in that instance.
Obviously, since C arrays start at 0, any index returned should be 0-based. Dennis said: Concerning the necessary refactoring of the library itself (and any other code included with Allegro5 inside the SVN), a safe way to catch all the code using the "al_mouse_button_down" function is to rename it temporarily. I'm not actually too worried about introducing bugs due to that in Allegro itself, which mostly records the information and passes it on to the user. I don't think any part of Allegro's internals poll the state-query functions. Quote: "0" for "no button held down" does not make sense with the event handling code, because there are only the events "ALLEGRO_EVENT_MOUSE_AXES", "ALLEGRO_EVENT_MOUSE_BUTTON_DOWN" and "ALLEGRO_EVENT_MOUSE_BUTTON_UP". You can get an ALLEGRO_EVENT_MOUSE_AXES with the buttons in either state, depending on whether the mouse was moved or dragged. I know, you can keep track of this yourself easily as a user. I would personally prefer a bitfield to tell me which buttons are held down, but again, not a big deal. |
Peter Wang
Member #23
April 2000
|
Evert said: Anyway, before deciding on whether to change it or not, maybe it's a good idea to think about whether there is a reason for the difference? I can't imagine that someone arbitrarily decided to use 0 or 1 in one case or the other. For some reason, I always number mouse buttons from 1 in my mind. Probably 1==primary, or as Dennis said, influence from mouse_b: in A4 you write, (mouse_b & 1) or (mouse_b & 2), which happens to work for the first two mouse buttons. I'm not opposed to changing it, which seems to be the consensus. The only worry is breaking user code at this stage. Matthew Leverton said: So you'd have _FIRST, _SECOND, ... or _PRIMARY, _SECONDARY, ..., which to me is more verbose than it needs to be. We can provide them as synonyms. Evert said: I would personally prefer a bitfield to tell me which buttons are held down, but again, not a big deal.
|
Matthew Leverton
Supreme Loser
January 1999
![]() |
Evert said: In this case, I would opt to make the return field a bitfield But you already have that: ALLEGRO_MOUSE_STATE m; al_get_mouse_state(&m); if (m.buttons & 1) { // first button is pressed } if (m.buttons & 4) { // third button is pressed } The function works like: ALLEGRO_MOUSE_STATE m; al_get_mouse_state(&m); if (al_mouse_button_down(&m, 1)) { // first button is pressed } if (al_mouse_button_down(&m, 3)) { // third button is pressed } The joystick buttons go from 0 to n-1, don't they? PS: Should the function be named al_is_mouse_button_down? I don't know how we are handling similar function names elsewhere. |
Evert
Member #794
November 2000
![]() |
Matthew Leverton said: But you already have that:
In the event structure, I mean. But if that's already a bitfield too, then that's fine. |
Matthew Leverton
Supreme Loser
January 1999
![]() |
ALLEGRO_EVENT_MOUSE_BUTTON_DOWN - a mouse button was pressed.
Fields:
mouse.x,
mouse.y,
mouse.z,
mouse.button,
mouse.display
I don't remember what it is without looking at it, but I'd assume it was only the individual mouse button pressed. For example, if I did this:
I'd assume there would be four events triggered, each with an indexed button (given that the field name is singular.) If only three events are triggered, then they'd obviously need to be a bitfield. Personally, I don't care which way the event system works, as long as it is documented correctly... |
Evert
Member #794
November 2000
![]() |
Matthew Leverton said: I don't remember what it is without looking at it, but I'd assume it was only the individual mouse button pressed. So did I, but Peter's comment seemed to indicate that it's actually a bitfield. He seems to have corrected that. Quote: Personally, I don't care which way the event system works, as long as it is documented correctly...
Quite. |
Dennis
Member #1,090
July 2003
![]() |
Evert said: You can get an ALLEGRO_EVENT_MOUSE_AXES with the buttons in either state The button is not a part of the ALLEGRO_EVENT_MOUSE_AXES event fields. Evert said: So did I, but Peter's comment seemed to indicate that it's actually a bitfield. He seems to have corrected that. So in the event field "button" is not a bitfield? (see strikethrough in his last post) If that's so, that's good, as long as it starts counting at 0. Then all that has to be done is have al_mouse_button_down start at 0 as well. (The buttons in the state can still stay a bitfield internally.) Matthew Leverton said: Personally, I don't care which way the event system works, as long as it is documented correctly Same here but it would be nice if things were consistent across different functions with similar names and purposes. edit,append: Changing that to 0 in both would result in a lot more changes necessary than I first thought, because each platform code would have to change the function that fills the event structure as well. The more I think about it, the more I lean towards voting to just adjust the documentation for event.button and al_mouse_button_down. But then that's inconsistent with the joystick button numbers and the axis numbers.. --- 0xDB | @dennisbusch_de --- |
Evert
Member #794
November 2000
![]() |
Dennis said: The button is not a part of the ALLEGRO_EVENT_MOUSE_AXES event fields.
'course it is. Quote: So in the event field "button" is not a bitfield? (see strikethrough in his last post) Seems so. Quote: Changing that to 0 in both would result in a lot more changes necessary than I first thought, because each platform code would have to change the function that fills the event structure as well. Shouldn't be too bad. At least on OS X, the function that records the current state is the same function that fires off the events. I assume it's similar on the other platforms. Quote: The more I think about it, the more I lean towards voting to just adjust the documentation for event.button and al_mouse_button_down.
That is certainly the easiest thing to do. |
Peter Wang
Member #23
April 2000
|
Dennis said: So in the event field "button" is not a bitfield? (see strikethrough in his last post)
Yes, I made the mistake of posting too early in the morning. Ah, that gives me a half-decent reason to number mouse buttons from 1: as the "button" field is undefined in axis events, we should fill it with a nonce value that the user can't accidentally use, such as zero. That doesn't explain why joystick buttons are numbered from 0, but anyway...
|
Matthew Leverton
Supreme Loser
January 1999
![]() |
Peter Wang said: we should fill it with a nonce value that the user can't accidentally use, such as zero Or -1. |
Elias
Member #358
May 2000
|
Maybe we can rename the button field and also add the additional bit-field. That way we fix the issue with existing code (instead of .button there's two new fields). And it would allow to do things in a consistent way now. -- |
Dennis
Member #1,090
July 2003
![]() |
Sounds good to me. What should the new field names (in the ALLEGRO_MOUSE_STATE) be? And in al_mouse_button_down, rename the "button" parameter to "button_index"? (let that start from 0 too) The fields in the ALLEGRO_MOUSE_EVENT structure should probably have the same names as the fields in tha ALLEGRO_MOUSE_STATE? --- 0xDB | @dennisbusch_de --- |
|