Fwd: Input and games.

Bengt Richter bokr at oz.net
Mon Apr 29 06:57:31 PDT 2013


On 04/27/2013 03:05 AM Todd Showalter wrote:
> I failed to reply-all before, so I'm forwarding this back to the list.
>
> On Fri, Apr 26, 2013 at 5:46 PM, Jason Ekstrand<jason at jlekstrand.net>  wrote:
>
>> My first general comment is about floating point.  I'm not 100% sure what
>> all went into the design decision to make wl_fixed have 8 bits of fractional
>> precision vs. 12 or 16.  I'm guessing that they wanted the increased integer
>> capability, but you'd have to ask Kristian about that.  My understanding is
>> that most game controllers work with ranges of [0,1] or [-1,1] which would
>> be wasteful to put into wl_fixed.  Looking below, it seems as if you're
>> fairly consistently picking a 16 bit fractional part.  That breaks out of
>> the norm of the wire format a bit, but I think it's justified in this case.
>> The big thing is to be consistent which it looks like you're doing anyway.
>
>      In my experience, most game controllers actually return byte
> values which you wind up interpreting either as signed or unsigned
> depending on what makes sense.  Certainly that's been the case
> historically.  In games we typically do something like:
>
> stick.x = ((float)raw_x) / (raw_x>= 0) ? 127.0f : 128.0f;
> stick.y = ((float)raw_y) / (raw_y>= 0) ? 127.0f : 128.0f;
>
I'm not an electronics or game equipment insider, but I wonder
why isn't the above

    stick.x = (((float)(raw_x+128)) / 127.5f) - 1.0f;
    stick.y = (((float)(raw_y+128)) / 127.5f) - 1.0f;

thus mapping [0,255] to [-1.0 to +1.0] symmetrically?

I think you might want to map a shaft encoder differently
though, since while a linear fence with 256 pickets make
a span of 255 spaces end to end, a circular fence of 256
pickets makes 256 spaces along the full circle.

I.e., if you wanted to map [-pi, +pi] to [-1.0, +1.0]
you'd just scale raw_angle times 1.0/128.0, given that
-128 represents -pi diametrically across from 0 and
coinciding with one step beyond 127 as +pi at +128.

>> Another concern is how to map [0, 255] onto [0, 2^15 - 1] cleanly.
>> Unfortunately, there is no good way to do this so that 0 ->  0 and 255 ->
>> 2^15 - 1.  Perhaps that doesn't matter much for games since you're sensing
>> human movements which will be slightly different for each controller anyway.
>
>      There is, actually:
>
> expanded = (base<<  7) | (base>>  1);
>
>      ie: repeat the bit pattern down into the lower bits.  Examples:
>
> 11111111 ->  (111111110000000) | (1111111) ->  111111111111111
> 0000000 ->  (0000000000000000) | (0000000) ->  000000000000000
> 1000000 ->  (1000000000000000) | (100000) ->  100000001000000
> 1011001 ->  (10110010000000) | (101100) ->  1011001101100
>
>      And so forth.  It's the same scheme you use when doing color
> channel expansion.  I haven't seen a rigorous mathematical proof that
> it's correct, but I'd be surprised if someone moreo inclined than I
> hasn't come up with one.

My take on an integer arithmetic interpretation in python, FWIW:

      >>> def expand(base): return ( base << 7 ) | ( base >> 1 )
      ...
      >>> def altexp(base): return base==255 and 32767 or base*2**15/255
      ...
      >>> set([expand(i)==altexp(i) for i in range(256)])     # show that all results are same
      set([True])

IOW, you could say expand is outputting the base/255 fraction of 2**15,
(not 2**15-1 BTW), evaluated by integer multiplying before unrounded integer
dividing, except where the fraction is 255/255.

If you do it in floating point and round up, you can map [0,255] to [0,2**15-1]
and not special case 255/255:

	>>> def altex2(base): return int((base*(2.0**15-1.0)/255.)+.5)
	...
	>>> set([expand(i)-altex2(i) for i in range(256)])
	set([0])

I guess that is closer to the real math explanation.

[...]

BTW, does input come in well behaved chunks, so that you get
a well aligned struct without having to assemble it yourself from a
stream of bytes as done somehow in showkey to group what comes
in a burst together from a function key press? Is it one record
at a time, or as many as are available and will fit in the
buffer you supply?

I.e., how hard would it be to write a showkey utility
for game inputs, with similar cooked and raw options ?

BTW2, does showkey itself work with wayland in all modes?

Regards,
Bengt Richter



More information about the wayland-devel mailing list