Input and games.

Todd Showalter todd at electronjump.com
Mon Apr 29 07:17:31 PDT 2013


On Mon, Apr 29, 2013 at 4:15 AM, Pekka Paalanen <ppaalanen at gmail.com> wrote:

> a problem here is that to receive a wl_gamepad::connect event, you
> first have to create a wl_gamepad protocol object, which is a bit
> counterintuitive.
>
> A wl_gamepad protocol object should correspond to a single physical
> device. So, we would have a wl_gamepad object per each contoller, and
> you do not need the pad_index argument in any of the events. This
> should be easier on the game programmer, too, since you can attach
> user data to each protocol object in libwayland-client, and use that in
> the callbacks without any global data.

    That's not necessarily how games are designed, though; I know that
with our engine, input is represented internally as an array of
gamepads.  It lets us do things like feed a pad with a stack of pad
values to do things like demos and "replays".

> That leaves the question, where do we put the connect and disconnect
> event equivalents. Below you mention also keyboards, so instead of
> playing ad-hoc, let's use wl_seats the way they are designed.
>
> A wl_seat would need to grow a capability bit for wl_gamepad, and a
> request to create a wl_gamepad object. When you use that request to
> create a wl_gamepad, the first thing it does is send its description:
> name and cookie in your proposal, as an extra event type.
>
> That limits us to one wl_gamepad device per wl_seat, so a server needs
> to create more wl_seats for more controllers. That shouldn't be any
> problem, these seats would only have the gamepad capability by default.

    This is I think where there's a potential problem.  Gamepads live
in a somewhat more chaotic world than mice and keyboards; wireless
ones have much shorter battery lives, and players are used to being
able to unplug and plug them while playing.  It's not uncommon for
someone to (say) play for a bit with a gamepad they don't like (maybe
it was on sale), unplug it, and plug in one they like better.  Or drop
the gamepad that ran out of batteries in the charger and pull out
another.

    Players also expect to be able to add a gamepad part way through a
game, at least for some games.

    So, gamepads can appear and disappear during the game's runtime,
and the game needs to know that is happening.  There also need to be
some heuristics about which gamepad is what player (or seat).

> If your gamepad actually had a keyboard, or maybe even a touchpad (if
> that is supposed to be used as a pointer device), it would simply be
> advertised as a standard wl_keyboard or wl_pointer on the wl_seat. Each
> player would have their own wl_seat, and it is obvious which keyboard
> belongs with which gamepad.

    That does solve that problem nicely.  It's somewhat of a corner
case, though, so I wouldn't move mountains to solve it.

> Oh, and the disconnect event. The standard wl_seat way for that seems
> to be a new capabilities event, with the gamepad bit unset.

    Ok.

> All this still leaves some details unsolved, like which Wayland client
> should receive the gamepad events on a wl_seat? The one having the
> keyboard focus? Probably. But what if a wl_seat has no wl_keyboard or
> wl_pointer? Just the first client that creates a wl_gamepad? What if
> you have two games running, and you want to switch between them? Should
> a wl_gamepad have its own focused surface attribute? How do you assign
> that focus? If you have other input devices in addition to a gamepad on
> a wl_seat, how do you get all their foci to the game, when the user
> wants it? How does the user indicate he wants it?

    I think all gamepad input should be routed to whatever has focus
or whatever has grabbed input.  I don't see a scenario where it makes
sense to route different gamepads separately unless you're doing
multiuser multihead (which I assume is the point of the wl_seat
abstraction).

>> Arguments:
>>     time -- uint -- standard event timestamp
>>     pad_index -- uint -- which gamepad this is
>>     stick_index -- uint -- 0 for left stick, 1 for right stick, 2 for
>> dpad x -- int -- the x axis of the stick mapped to [-2^15 .. 2^15 - 1]
>>     y -- int -- the y axis of the stick mapped to [-2^15 .. 2^15 - 1]
>
> All int and uint are 32-bit in the protocol, btw, should be enough
> precision for intervals like [0, 1] and [-1, 1], I think.
>
> I agree that the fixed type is not really suitable here. It was
> designed to hold pixel coordinates foremost.

    I figured; it looked like a suitable encoding for subpixel
precision rather than for components of normalized vectors.  For input
axis values float remains the ideal, but fixed point with 16 bits
below the decimal should cover most things adequately.  There will
probably be roundoff error for things like quaternions, but those
would probably be better served by a 2.30 fixed format anyways.

>> ----------------------------------------------------------------
>> wl_gamepad::sysbutton -- gamepad system button event
>>     A sysbutton event occurs when the system button (the ps button on
>> a ps3 controller, the glowy x button on the xbox 360 controller, the
>> home button on the wii controller) is pressed.  While this information
>> might be passed on to the application, it is somewhat expected that
>> his event will be trapped and acted upon by the window manager.
>>
>> Arguments:
>>     time -- uint -- standard event timestamp
>>     pad_index -- uint -- which gamepad this is
>
> I don't think we need a separate event for this, just the normal button
> event is enough. If the display server wants to eat the event, it can
> do so in any case. Or was there some other reason for this?

    Mostly to logically separate the home button from the others.
It's not available on all gamepads.  The gamepads that do have it are
gamepads for hardware platforms (wii, ps3, xbox 360), and the button's
purpose is "interrupt the game and bring up the OS".  Pressing it gets
you access to meta things like system settings, gamepad settings, and
GUI buttons to do things like quit the game, which is useful in
single-screen environments where the game is running full-screen.

    Splitting it off isn't essential.

> I agree with Jason here, the interface can be extended later as needed,
> so no need for a generic catch-all event.

    I wasn't sure about the idea to begin with, so let's drop that part.

                                           Todd.

--
 Todd Showalter, President,
 Electron Jump Games, Inc.


More information about the wayland-devel mailing list