Revision 1 API
the preceding API for gamepads on rev1 was very simple : in fact it was only a halfword (!), representing the bits of each button on the SNES gamepad. This was simple, convenient and closest to the hardware.Now with the different class of devices that can be used and the fact the USB HID is used, I think we will need to have a different API.
rev2 API goals
My
main design goals for this API are : keep it simple and just act as a
layer between the devices and the software (no policy, that's what
engines are for), but still provide something for the simpler games.
The first thing to decide, by device, is what needs to be handled as an event queue (i.e. an array of ints - we will keep it simple) or as state variables.
It is trivial to transform a state API to an event like API, but it is dumb to transform a natively event hardware model to a state API back to an event-based game. So It'll be useful to state what is practically used in games, noting that maybe event to status is simpler than the other transformation.
Device classes
The first three classes of devices I'd like to be able to handle are gamepads, mice and keyboards.Keyboards
I think the best representation is events (having a 256bit table of the
press of each key is somewhat not useful). Actually, the USB Boot
protocol for keyboards is made of an event : control keys status (8 bits
for left/right control, alt, windows ..) + up to 6 1byte keycodes
buffer. I think we can keep as close to it as possible, while separating
the different keystrokes as independent events. Translating with kb
maps (including ctrl/alt modifiers), handling stroke repeat, making some
keypresses have more priority than others (Ctrl-C) shall be done
outside of this event handling API.
Mice
there are buttons and cursor.
- buttons are somewhat like events (press/releases), however sometimes button status can be useful. I think event-based might win here. Handling dbl clicks or right/left handed shall be outside the scope of this API.
- mouse moves shall also be seen as events but 99% of the time what is needed is absolute x/y positioning, so it's not as clear-cut.
However, translating relative x/y move events to absolute x/y has a lot of policy : shall there be clipping (restricting the mouse movement), mouse speed can be adjusted, some acceleration can be needed. I think mousemove/clicks events are closest to the reality + simple x/y keeping as cut n paste examples. only 3 buttons need to be handled - wheel will need to move away from boot protocol, we won't do that now.
- buttons are somewhat like events (press/releases), however sometimes button status can be useful. I think event-based might win here. Handling dbl clicks or right/left handed shall be outside the scope of this API.
- mouse moves shall also be seen as events but 99% of the time what is needed is absolute x/y positioning, so it's not as clear-cut.
However, translating relative x/y move events to absolute x/y has a lot of policy : shall there be clipping (restricting the mouse movement), mouse speed can be adjusted, some acceleration can be needed. I think mousemove/clicks events are closest to the reality + simple x/y keeping as cut n paste examples. only 3 buttons need to be handled - wheel will need to move away from boot protocol, we won't do that now.
Gamepads and joysticks
Button
press are fundamentally events, because even if by example you want to
have autofire, you want the first fire to happen exactly as the button
is first pressed. For simplicity, sometimes only state is kept, so that
can be useful as well. Gamepads can be very various but we need to keep
the standard ones simple to use. I propose to stick (haha) to a known
set of buttons,
mapped by default. the name of the buttons can be snes ones (AB XY LR
start select)
I think dpad, hats & joysticks are different than mice as the pad status is much more useful than pad changes (except when you see one press to the right as one movement, but it is less frequent). For the directional pad/stick, I propose to only handle one per gamepad now, represented by X/Y position of +/-127 for d pads or hats, or int8 for analog sticks. if both are actioned, the last moved one wins.
I think dpad, hats & joysticks are different than mice as the pad status is much more useful than pad changes (except when you see one press to the right as one movement, but it is less frequent). For the directional pad/stick, I propose to only handle one per gamepad now, represented by X/Y position of +/-127 for d pads or hats, or int8 for analog sticks. if both are actioned, the last moved one wins.
other : device plugged/unplugged can be other events.
Proposal
the proposal is to have an array of 2 struct values (one per USB port):
{
- uint16 device type (none, mice, keyboard, gamepad ...).
- buttons : mice or joystick buttons current status
- int16 x/y : either absolute mice or current joypad position
}
+ one global event queue Extensions
since we have an event queue , other events can be provided by extra libraries :
- timers (why not? as a library)
- SD card async IO ready, sd card inserted, removed
- user button pressed/released
- user events for event-based programming
- sprite collisions
- UEXT related events
No comments:
Post a Comment