WWDC2001 Session 135

Transcript

Kind: captions
Language: en
this is session 135 input for games and
I'm Jeff Stahl games in graphics DTS
engineer the good news is this year is
we're talking about head manager we're
talking about real input for 10 we're
talking about devices that you can
really get into you into your
applications use them and make some
great games and any other application
that you may be interested in that uses
input we're going to go through a number
of things today what I'm going to
basically start talking about is the
hidden manager and how it attaches to
the system where it sits and then how to
really use the hidden manager and show a
lot of examples we're gonna walk through
some of the i/o registry and look at how
the devices are actually laid out so you
get an understanding of how the device
is actually interface to the system
first thing we're talk about his system
services for input we're gonna talk a
little bit about carbon and about what's
there and why you may also want to use
carbon and why you need to use carbon
right now for some of the few devices
then we're gonna talk about the hid
manager and the meat of the discussion
will be about the hid manager will be
about how the hid manager works and will
be about how to use it and how you can
use in your application lastly will use
the hidden manager for getting user
input first thing we'll do is use device
discovery how do you go through the
system
use the services there to actually
discover what devices are on the system
we've done a lot of the work for you and
we have some sample code that'll be out
either later today or this weekend you
can look peruse over that will be the
basis for the code that's in this
discussion and you can use that directly
in your applications for device
discovery and for getting input then
we're gonna be talking about retrieving
input as far as retrieving input goes
you're gonna have to decide exactly what
how you want your input where it's
coming from what's an access whether
it's a button and know how to get that
into your application and lastly we'll
talk about input configuration one of
the big things people playing games or
any other use of the input devices if
you have your your jog shuttle you may
be using with your image editing
application your photo editing or your
you know Final Cut Pro premiere film
editing application one thing you may
want to do is your him the way you
design it and the way the user wants to
use it may not be exactly the same
so you want to have a way to configure
that you want to have the way for the
user to use any buttons for anything
they want whether they're navigating the
web or whether they're editing the next
great movie you want them to be able to
configure it however they want so let's
talk about what system services exist on
Mac OS 10 for hid manager
I'm sorry for input hidden manager is
built on top of i/o kit is a fairly thin
layer on top of i/o kit that actually
handles device communication and allows
you to get input from devices it's
fairly robust and the fact that it's not
an API that limits you and how you want
to use it you can use it at a high level
with an aqua interface or you can use it
in an immersive game with your own
interface it doesn't limit you as we've
seen in the past that you may be limited
to only one way of configuration or only
one way of dealing with devices this
allows you to deal with them however you
would like you can use joysticks jog
shuttles universal power supplies
gamepad anything that is a USB device or
hid compliant device actually that is a
heat compliant device will work with hid
manager it's some USB devices if you
look in the i/o register you'll see
they're not they don't have a hid
they're not supported through hid those
devices would have to have a special
driver to work through the hidden
manager but most devices that you'll
normally see in consumers your gamepads
your joysticks your jog shuttles will
automatically support plug-and-play
HID recognition carbon handles mouse and
keyboard for right now Mac OS 10
currently for carbonate you to get mouse
and keyboard that includes Mouse deltas
multiple mouse buttons Mouse wheels all
that can work through carbon events and
can be integrated with the hid manager
very simply we're looking to the future
to bring that all through into hid
manager and so you can get all all
inputs through the hid manager at
one-stop-shopping
let's talk a little about Carbon events
carpet events allows access to multiple
buttons up to 32 buttons and Mouse
deltas which is key if you if you're
doing the game or you want something
other than tracking the mouse on the
screen get keys and get Mouse also work
currently so if you have an application
that you just want to quickly code up or
you want to do some bait some basic
input you can still get the mouse
position with get Mouse realize that it
is pinned to the screen chord and store
through the
whole world coordinates whatever you're
supported by your screens and thus you
may not be usable without some hackery
to get the to continue keep the mouse in
the center of the screen or on the
screen there's a better way to do it and
I'll show you how to do that today
get mouse also get button works
that's only never return you the main
button so get button is more of a
signaling thing for your application and
you may want to use it for a quick
update but probably not is for her bus
stripping applications want to use those
two api's so how do you use carbon
events there's been a number of
discussions already this week about
carbon events I'm not going to go into
exactly how to use carbon events there's
a great book on carbon and how to use
carbon events there's some great sample
code in the carbon SDK
please look there look through it it's
it'll bring you up to speed on the basic
use of carbon events but what events are
you very interested in to get forgetting
the mouse we're talking about key event
mouse down key event mouse up to
determine whether your mouse is down or
Mouse off you can track those and see
whether the user has a mouse down or
Mouse up when you do that one thing you
want you want to look at is you want to
look at the actual what button there is
a button per a mole go into a little
later that tells you what button isn't
down is going down for the mouse down or
Mouse up so just the mouse down and
mouse up event says any some button went
down if the user has a multi button mice
it could be two different mouse buttons
to go down or up and different different
events their mouse wheel moved Mouse
dragged mouse moved the last two are the
key things determining for the mouse
moved events you're not gonna find a
mouse Delta event what you see is you
get a mouse moved event and then you
look at the mouse Delta and there so
you're actually when every time the
mouse moves you're gonna get a mouse
moved event and then you look at the
mouse Delta parameter to find the Delta
from the last time you got the mouse
moved realize that this updates on a per
event basis so you don't want to
accumulate you want to skip events you
want to get accumulate that Delta every
single time you add a carbon event so
that's kind of key one thing to note is
if you're in Cocoa you can use the core
graphics to get the mouse Delta's again
those need to be synchronized and the
fact that you can't wait half an hour
get a mouse Delta and expect it to be
accumulation of your lasts all the last
meltdown Mouse Delta's
or you if you pull very very quickly and
get the mouse Delta you're not going to
blank that last Mouse Delta it's gonna
be though you can make it the same one
over and over again so realize there is
a synchronization issue here when you're
doing this this is so seeing the pointer
see if you disassociate mouse and mouse
cursor position allows you to
disassociate the pointer from the app
from the actual cursor position so to
allow you through core graphics to not
have the pointer move you can hide the
pointer call that routine and the
pointers ought to be moving underneath
your application keyboard handler walkie
down hit handle rocky repeat our key K
event we're all repeat very simple if
you want to just get keys like you would
a user would be doing typing you'll
handle those two events key down you get
a key key repeat you get the same key
and you continue to handle those or you
may want to do a keydown keyup events
you want to when the wall the key is
down these ER holds the key key down you
have thrust going to your to your rocket
ship or you have your laser beam coming
out or whatever your game has in it you
can win the keys down you can activate
when the keys back up you release
instead of doing a polling on the key
down and key downs and key repeats and
one other thing to look at is key
modifying modifiers change that allow
you to get the modifiers figure out what
what modifiers are down on the keyboard
so let's moving the hid manager hid
manager basically handles input output
from devices the device discoveries
actually handled through the i/o kit
services it allows access to device
elements the key here is that you get a
device you get a joystick and there's
that joystick is built out of elements
it's built out of an X and a y-axis it
may be built out of a hat switch it may
be built out of a slider and some
buttons all those put together describe
your joystick so what you're gonna see
when you look at it you're actually
gonna see something that tells you it's
a joystick below that there's gonna be a
list or a collection of all the input
pieces of that joystick and that's how
you need to think about it when you're
thinking about your your game and
mapping this to actions so when you have
this what you'll do is you'll say I want
this device my joystick I want to get
the X axes and that'll be the x axis for
my game and I'll assign that to some
action in the game and that action in my
game will be turn left turn right
if someone then comes in with a gamepad
the gamepad will awesome
collection of elements they may also
have an X and y-axis healing then can
assign that the x-axis and the gamepad
also to turn left turn right hit manage
will provide polling and queuing
services you can either do a kind of a
poll that you can get current values of
any of any device in any element out
there on the system or you can queues
the queue events on a per element basis
which may differ from some other api's
out there as far as how you actually
pull and queue events and I think why do
we take a little sidebar here and talk
about hid manager as compared to direct
input as compared to inputs Brocket just
give them a little to have a cage
everyone's gyros as far as exactly how
they compare compare and contrast those
two so if you're familiar with one of
those other api's this will kind of
bring up to speed and where hid manager
stands in relation to that then we'll
jump into actually working with hid
manager so first device discovery hit
manager uses I okay but as we've talked
about for device discovery direct input
kind of similar it has its own its own
discovery services but very similar as
far as you create a direct input object
and you're gonna numerate devices
similar thing to what you're gonna do
and i/o kit as far as you create an
object neil numerator on the other
devices so very similar methodologies
their input sprocket you can use isp
devices extracting a little list through
the devices there which is the same
methodology or the high level new put
sprocket you can just use on isp in it
which will wash lea go out and grab the
devices for you element handling build
the hit device interface and then we
look we look for a cookie so we
basically have an interface and a cookie
and we go through IO kit to actually
find the LM find the device and then get
the element off the device once we have
an interface to the device so what
you're going to look at is you'll have a
device interface and then you just give
it a cookie and that will out that's the
exactly what you need to get information
about about that element so there's a
two pieces of information you need again
you need the device you need to be that
cookie that points to that input on that
device direct input you're going to
numerate objects and you can use git
capabilities to identify the
capabilities of that device direct input
is very device centric
when you get things out of direct input
you'll get a device at a time you don't
get an a element at a time
hidden manager on the other hand is it
is element centric you can you can say
IQ on a Q this one element so I'm only
only I'm interested in one element I'm
not interested in the entire device I'm
interested in one piece of that device
input sprocket you can use input
sprocket get element list to retrieve
input of elements and you can get to get
the reference to this elements through
that list and then use that to get the
information about that element use the
configuration use a configuration for
i/o kit from sorry for hit manager's
handle through the application however
you want to do it there's no built-in
services currently for high level
configuration dialogues but as you'll
see in some of the examples of giving
you some tools that will be real easy
for you to build your configuration
dialogues and or if you want to do a
fully immersive API build them into a
fully immersive API direct input again
handled by application you know the
application needs to handle the
configuration in some way in some some
some cases there is utilities provided
by the device vendors the handle handle
some some mapping of those devices but
again that's an application or device
specific thing there's no system
services specifically for input
configuration input sprocket we have an
IP configure that we you can could use
on nine one of the big things we have
feedback from the developers was that
works great for a limited subset of
cases if you have a fully immersive app
all we give you is the dialog box your
full screen we give you a dialog box
there's a lot of problems with some of
these things so really didn't work
completely well for all developers
because what happens is that when you
want to stay immerse if you don't want
to bring up the Mac dialog and there was
no real way of getting the information
out well he manager we have a full
services to give that information out so
you can build whatever kind of kind of a
dialogue or immersive API or immersive
UI that you would like to so for input
retrieval very simply you can get we're
gonna use a good element value for
polling and we're gonna use a cue for
querying and we're gonna get the next
event pretty simple we give it the
device give it the cookie for the IMP
for the element and we get the element
value or a QT or we put that same
information into the queue to QA then we
get the next event
direct input we're gonna get a device
state so basically direct input again is
just is very device centric and you're
gonna the entire state of the entire
device and you can sort through and
figure out exactly what you want input
sprocket you can use ISP get simple
state or get next event very similar in
this case the head manager when you're
working at the event level okay let's
talk about how to do things with head
manager device discovery first we're
going to setup an i/o matching
dictionary
then we're get device iterator then
we're gonna iterate for devices then
here's a key we have to recursively
inter iterate underneath that through CF
dictionaries and CF arrays for the
Frenette for the elements will capture
the cookies for the element
identification that seems pretty
complicated so what we're gonna break
this down I'm going to talk about how to
do this the first thing I want to do
though is I want to go through the i/o
registry and show you exactly what the
devices look like real good thing when
you're working with your your
applications is you can get right in
there and see everything it's on a
device you can see if your application
is correctly seeing the device see if
you see what ashley as the device is
reporting back to the system so you can
really easily make sure that you have
the correct information on device and
you understand what kind of information
you're working with so let's bring up
when we bring up demo machine number two
and this is the where you start with the
IO registry I are registry explore some
developer tools applications start at
the root and this is my you know I'm not
an IO registry guy so as far as do you
need to be an expert in this no you
don't not at all I'm not an expert by
any means on how exactly how the IO
registry works but I was able to very
easily put together the the hid samples
and I think you will be able to easily
easily use this so we're gonna we're
going to walk through the ir registry my
secret path here which is power Mac 3
for Mac risk and then the PC I here and
if you notice you have the you have USB
18 19 you look on here and where is it
there you go
if you notice down here you have a Mac
on a USB joystick you have a gamepad Pro
you have a Mac Holly I shocked and you
have a jogging shuttle
those are your hid devices and when you
when you look at the i/o USB interface
you'll notice it has a hid driver you
notice this one has a hid driver up in
this area you know this one has a hid
driver so they're all hid devices so
let's look at just pick the Mac on a USB
joystick look at the hid driver
so I'm looking the elements well if you
what you notice is I talked about the
vise being the package of elements you
notice as elements is an array and of
that there's five dictionaries and then
if you keep looking at elements you can
go down and look at the types of
elements there are and what you'll
notice is let's drill down to one of
these here's an element for example has
it is relative value has a a null state
type preferred state nonlinear wrapping
sized element cookie right there is
exactly the piece you need to save is
that that element cookie per device is
specific so this element will only be
referred to by that by that by that
cookie the no other element will have
that cookie has a min and Max in this
case based on the minimum axis is a
button the other thing we look at is the
usage
usage page well this may seem low-level
it's real simple and this is what USB
spec and hid spec is built on the usage
and usage page it's really important to
understand that that defines what you're
looking at anything from a joystick to a
button to a to a dial to a hat switch is
defined by usage and usage page and
we'll look at that in a second to show
exactly how that how that looks but when
you notice about this structure is it is
an array of CF dictionaries and we you
work down the dictionaries here's
another here's another example of
something and this in this case this is
a a slider or a axes because you see the
min value is zero and Max value is 55
usage is 54 so how do we figure out what
the heck this thing is you bring up demo
machine number three what you'll see is
trying to left-handed Mouse so we'll see
how this works what you'll see is this
is the hid USB parser dot H in the IO IO
kit framework this is a very long list
of everything you ever could want to
know about what's on a device the main
pages is what you have right here usage
pages is an undefined generic desktop
simulation VR etc etc you notice some
things that are interesting or there's a
button page and there's also a consumer
page almost everything you you want to
work on isn't a generic desktop page so
we move down to the generic desktop page
again as I said get back to the top
as I said with the generic desktop page
everything from the actual description
of the device down to the elements of
the devices on this page so a joystick
would be a generic desktop type 4 which
is a joystick while a gamepad will be
type 5 on that gamepad you might have
GDX generic desktop x-axis or exit our
y-axis on that same device so there's
not like this is the list of devices and
this is the list of stuff on the devices
everything's in the same kind of list
and this is your list this is your
dictionary so to speak how to convert
from the numerix of it to actually what
things are so you see there's a dial
wheel slide our hats which you also have
things like philosophy X velocity Y some
strange things system control system
sleep so if you have more advanced
devices may have that kind of stuff and
what's interesting if you go down this
is kind of fun to look at this is setup
for doing things like the Disney rides
and they'll use the hid speculoos tank
simulation device or magic carpet
simulation device I don't think I've
seen that in the store recently when you
go down flare release flight
communications trigger weapons armed
wing flaps rear brake front brake and
the bars oh here's a rowing simulation
here you have or you have a slope array
to stick speed oh and then you have for
golf if you need your 5-iron
or your loft wedge and oh they're bleep
over playing pinball here bump secondary
flipper flipper so it it's if this list
is very generic for everything that uses
hid type of devices some things we want
to look at is keyboard first for
keyboard support you will this keyboard
page will be the mapping in this section
you're seeing right here does map to the
ASCII value so the standard numbers will
map the ASCII values when you get those
back out as far as what element what
elements of the keyboard are pressed and
then you can have additional things like
your f keys your page up page down your
left arrow right arrow moving out of
that you have some LEDs and there's some
great LEDs in here also you have a night
mode paper jam so just in case your game
wants to show that you have a paper jam
buttons buttons once you get to the
button page buttons are very simply
enumerated down the page so the button
page number 12 is button 12 you can see
that they just move lists a few of them
because it's pretty obvious and you know
there's a also users telephone is listed
on here and the consumer page is
interesting also piz for example I have
this this jog and shuttle which list
itself as a consumer control device so
it just listed a consumer page and it
says I'm I'm device number one there so
that's something else and you notice the
consumer devices a lot of times our our
VCR kind of things or media control kind
of things play record fast-forward but
you can you can you could see that
someone could use a jog shuttle and put
them in sumer device page input play
play fast-forward rewind all those kind
of things and you could definitely
application to take advantage of it for
example would be great to have your
little jog shuttle with iTunes so I'm
gonna go to the next track let me back
up a little bit let me skip around those
kind of things or if you're doing
something like Final Cut Pro you could
control your movies directly and you
could take one and plug it in you think
you're this kind this jog shot don't
plug it right in or you could take some
other jog shot on plug it right in and
it would all work the same that's the
idea become behind hit so we've seen
where the i/o registry is and I I think
you everyone just look at the i/o
registry and see the hitted devices and
see how their lists and see the
information that's on there because the
information that we're talking about
here and I'll show you is basically the
information
the i/o registry and it's really pretty
simple to use into your application so
let's bring it back to the slides and
we'll talk about how to get information
out of these things first first the
caveat to all this
I have sample code that will be going up
either today or this weekend that will
do all this for you so you don't have to
well I'm going to tell you all about it
and we're going to talk about it this
will go through and build a list of
devices this will discover all the
devices for you this will get all this
information out of there you can look at
how it's done if you don't like it if
you think it's not done properly you can
change it I would love some feedback and
we'll keep this sample code up to date
I'm working very hard with engineering
to make sure that what this is done the
correct way and will reflect any changes
that we make an API so or an i/o kit or
something changes in the in the OS that
I may found that our mistakes I'm a I'm
a make so let's talk about the wonderful
setting up the i/o mashing Dictionary
because everyone know how to set up an
i/o matching dictionary the i/o matching
matching dictionary is what it's going
to do is is basically to say I'm going
to go into the i/o registry and I'm
gonna find everything under the type you
want and that type is gonna be joysticks
game pads jog shuttles whatever so in
this case first we're going to say we
want to match hid devices so well our
key is we want to say hid devices only I
don't want to find the USB hard drive
I just want hid devices then we're gonna
say we're gonna do the CF number create
which is some standards CF for creating
numbers and we're gonna set values and
then we see a ref you see patron rep
usage that's exactly what we just talked
about what you do for the page would be
generic desktop and for the usage might
be would be in this case would be dink
gamepad and it would find you're looking
for the game pads in this case so now we
want to get once we have a match and
want to get an iterator to iterate over
all the list of devices this is pretty
simple all it is is a list of devices
you get and you want to iterate from one
to the from first one to last one into
the i/o master port and you're gonna get
the access to the to the i/o registry
you're gonna use set up matching
dictionary and also and that was we just
saw a minute ago to get the matching
dictionary once you get the matching
dictionary you're gonna get io service
get get matching services and what
that's gonna do is take some matching
dictionary takes the master port puts
them together and gives you an iterator
for your objects so that gives you
something you can iterate across all the
device
list and pull your devices out so this
is going to show you how to use that
iterator first thing we do is we're
going to get an i/o device by looking at
continuously looping through the next
iterator we then what we need to do is
get to dictionary for the hid properties
as you saw that all the properties for
that device was stored in a dictionary
so we want to get that dictionary right
there we get the mutable different
dictionary ref IO registry creates CF
properties and we use that with the i/o
device we found I have my variable
called hid property that we're gonna
fill with the property list and then
what we're gonna do is we're going to go
a cloth go across and the top level will
be the info about the device so the top
level of that dictionary I will show you
about the device what kind of device it
is what the vendor is but who the
product is mean is serial number what
else will show your location ID which is
very important location ID is a is a
long that's kind of a mangled long that
has been encoded where in the whole tree
of USB LAN that thing plugs in so if I
have two gamepads
and you guys are playing with playing
with one gamepad you guys are playing
with the other I don't want in the
middle of the game have that swap and
not be able to figure out which gamepad
switch so the location ID make sure that
you can identify a device specifically
location if they're exactly the same
device is plugged into your system so
that's in the device info and then below
that we have a collection of the element
information and in that collection of
element information is we all the
information of all the elements and
we're gonna step through that and once
we're done with it we're gonna release
the properties I'm gonna try and go
through this and explain exactly in kind
of what this does but if you want more
more detail and I say you look at the
code the code is barely well commented
and you can step through it and see how
it works
the key here is that you have over you
have to recursively step through kind of
a dictionary array pairs so every time
you get an array you're going to step
through and you should get a dictionary
below the array and in the in the
dictionary you should have another array
so you come back and do the same thing
again so this is what this starts out
doing and we have kind of one level two
handles arrays and one levels Hill
handles the dictionaries you pass a
dictionary
into this level and this is gonna say
it's gonna get to get the value of the
properties and get the type ID if it's
an array type which is what we're
expecting we're gonna say you have a
dictionary at the top level of the
device with the elements and you may
have an array of 50 elements below that
so you're gonna get the array and then
you're gonna look at see if apply our
array apply function for the entire
range of that device and my or get my
array array elements which is the next
function I'll show you and so we're
gonna and you're gonna swap that off
back and forth so once a once you get
the array what you'll then do is call
the array applier for each value in the
array and in this case what you'll
notice that if it's a gishy if it's a
collection type under in this array will
go back to the dictionary and looking
for more arrays so for example a device
may be organized as a joystick you may
have X and y-axis grouped together you
may have some controls on the top of the
of the joystick grouped you may have
controls on the base of the joystick
group together so you may may not be a
flat file so there is some intrinsic
there as far as how the device is
actually built is built into this
information so what then in that case
you have a device you Inara may be an
array of two elements below that one
element will be the stick one element
will actually be the base inside the
array the array of the stick you may
have five elements inside of that next
and y axis which is grouped together
which is a group and then you may have
buttons that are that are outside of
that so if you know it so this is makes
a little more complicated as far as how
you extract things from devices you know
there's not a specific order to expect
things where it's not flat this code is
what what does that and what it does the
key here is where the switch if it finds
miscellaneous a button or an access type
it says hey I'm interested in that
that's that's an element that I'm
interested it's gonna give me input so
I'm gonna go get info about that element
if it's not again if it's the collection
type it says that's another array that's
another F to the stick that's the base
that's the X and Y axis grouped together
I'm gonna go back and get the dictionary
for that one well worth addition air for
that one and get another array and press
down into the hierarchy so get my own
element info is pretty simple this is
just a little piece of it basically the
what you want to do is see if dictionary
get value
with the with the hid the IO hid element
cookie keen where do you find the IO hid
element cookie key you find that in the
AIA the IO hid Lib dot H and it has a
list of all the all the keys that are in
the IO registry for all the hid devices
everything you want to know about a hid
device is listed in there you pass the
key in it's based out of value to you
might be a string might be a number
there's a couple bullying's and there
also and that's real simple and then you
go get get value for that and that's how
I got the cookie for all the elements of
every device and you just loop through
the entire device for doing this and you
pull out all the information there the
other stuff we talked about in the i/o
registry is what is in what makes up a
device it's a type an element that was
what we talked about before with it be a
button a an axis a miscellaneous type
this is a usage page which may be
generic desktop probably there's a usage
which would be button access slider X
exportation Y one other word what are
you can see rotation Z you may have
something just as numerically called a
slider can't think of anything else I've
seen recently the button the usage
actually four buttons will enumerate all
the buttons in order so you're not the
count them and when you look at a button
it will specifically identify the usages
button one or button five the min/max
will tell it what its gonna report them
in max one thing to look at and I'll
show you in a minute is that while
devices try and tell you what their
report they lie a lot may save report 0
to 55 and report 0 to 127 so there's not
much you can do about that because
that's the hardware it's gonna do that
for you also the other thing about mid
max is that's what the theoretical
design of and their test units probably
do 0 to 255 the one you got at home
probably does 7 to 252 so something else
to realize and I'll show you in some of
the code I have I have in sample code I
haven't already a calibration function
in there which you can either use or
expand on there's there's some ways to
make it better but it basically some
basic calibration takes the min max that
is reporting from the device and expands
and out to what device is actually
telling you it should report so it fixes
both the case where the device only
reports half its range or the case where
it doesn't quite make it to the end of
its range because it's about the
manufacturing tolerance tolerances
didn't allow Skillman scaled max I
haven't seen that used very much but
that would give you a scale minimax
if the devices can do some scaling on it
whether it's relative so whether it's
relative to to its previous position
like maybe a jog shuttle they the
forward backward rotation is not a with
maybe report relative movement and vice
reporting exactly by spice reporting
direct movement a mouse pointer for
example might be a relative movement and
vice reporting is a direct position of
them whether it wraps you'll see I'll
show you the jog shuttle the jog show
has a wrapping element that wraps around
non linear if it's non linear scale
preferred state buttons do have a
preferred state joysticks have a
preferred state and use in most cases
sliders may not have a preferred state
there's no way I mean since wherever
it's it there's no center state to it
what the null state is what the units
are what the units units exponent is
again normally not used but but it might
be used and the last thing the name of
the name of the element which for
element wise I have not seen one name
filled out so I've never seen a device
report itself hey this is button six or
this is the Hat switch or this is the
trigger I've always seen button one so
that's something that you may have
synthesized yourself for my code since
the sizes for you based on the usage and
usage page okay so let's talk about
device discovery and see what we've
already done for you demo to machine
we'll bring that back up and we don't
need to look at the registry again and
this is a piece of sample code that'll
be ready and it is done so it'll be
either up today or this weekend and
complete and it has the complete code to
do a device discovery get a list of
devices and tell you every piece of
information there is about the device we
can find in this case I have a key span
USB hub here and I have four devices
plugged in first my mat in my mac
allying USB joystick gamepad pro USB so
the standard gamepad Pro the Mac Ally I
shock right there and lastly what's
called the jog and shuttle which is this
jog shuttle device the no additional
code was done for this part those all
all those names came directly from the
device so I just looked up to the device
and said was the name and device what
the code that I have a sample code does
it goes and makes a list of every device
and
on the device pulls all the information
out so you have a flat structure to
access it so you can just go device
pointed pointed to device name and
that's the string that represents the
name of that device if you notice this
is a joystick it has two acts these four
buttons one hat one slider so the hats
up here sliders on the base axes and
four buttons vendor ID and Product ID
why do you care
vendor ID and Product ID are very
important that vendor ID combined with
that product ID identifies that specific
device the next version of that device
will have a different Product ID of
another vendors joystick will have a
different vendor ID even the product IDs
match so those two devices identify the
Mac I'll a USB joystick specifically so
if I find one of these on any one system
it's gonna be this device so it's if I
have a configuration that someone has
put together for this device and I find
one it'll work on that device you
guarantee this the same kind of device
if you combine that with this big long
location ID down here what that gives
you is that this device plugged into
that specific port on the hub plugged
into the specific port on the machine
which is actually on the keyboard which
is then plugged in from the machine the
reason you have that is when you run the
game or application again on that one
system you can say that's the exact same
joystick I had before someone didn't
plug in an additional one in it's not
two joysticks plugged in is the same
joystick probably sitting in the same
place on the person's desk that you had
before so it's really easy to do
configuration one thing you'll notice
here is that serial numbers blank I
haven't seen a serial number on any any
any devices but if device device vendors
start using serial numbers a serial
number would be a way to identify this
particular joystick what else we see
there product obviously mchale a USB
joystick manufacturers mac alley usage
is a joystick it's a generic zero one we
saw was generic desktop page and for the
joystick so it says this device is a
joystick here's a list of all the stuff
it has let's look at the x-axis but that
might be most interesting it's a
miscellaneous input type it's an X AXI
again all we did was look up in the
generic desktop page you see CH 13 was a
it was an x-axis it's cookie a 7 if you
notice if we go to any other any of
these other
inputs the cookies is not seven so you
can identify specifically that X access
without cookie so anytime you're
referring to that cookie that's the
exact same element range it says is 0 to
127 no skilled range size is 8 bit so
it's returning a turning a single byte
and you can see that it has a preferred
state and none of these are checked no
vendor specific information it doesn't
have a units or a name so if you look at
the bottom of that the raw value I'm
getting out you can see the raw value is
the bit that you're seeing is about 121
to 1 so it's not bad that gives me a lot
a lot of value my centering is not quite
right and I can obviously adjust the
centering through the joystick which if
you notice is not that accurate or that
linear once you start looking at the
devices you realize how how not
wonderful they are one thing that I did
was calibrated and we'll go to the
y-axis to do this easier I still go to
the slider up is easier doing a slider
slider hasn't moved yet so I have no
calibrated value my calibration is
pretty simple all it does is look at the
maximum in range that has had that it's
gotten and calibrates out to what it's
supposed to be so in this case if I move
it just a little bit it tries to map
that little bit of movement to the
entire max range the reason it does that
is it says if your slider in this case
goes to seven and goes up to 126 huh huh
922 yes there you go
255 126 that's the sliders all the way
throwing the one one exam one extreme if
you had this device and you were
expecting 255 you only got to get 126
but the but the calibrated value which
is in the sample code maps that 0 to 255
so you can get way you expect out of it
and then the bottom is just a scaled
value that says hey if you want to scale
your y-axis 0 to 55 it's gonna scale
your y-axis 0 to 55 again why is it an
example - it goes to 12 and that's full
throw and on the other side goes to 125
instead of 127 so you can see that these
devices don't always go to the extremes
and you can expect that let's look at
some other devices here a gamepad Pro we
can figure out what button that is that
that's that button right there we also
have look at the x-axis they're listed
and you can see the x-axis
1 to 255 0
twenty-seven from the middle in this
case so different ideas of how they want
to set up axes they're not always set up
the same in this case the the scaled
value again scales everything to the
same values that's why their only thing
exciting there what do we have on the I
shocked the I shock has three axes
twenty buttons in one slider if you
notice the I shock is set up with what
looks like an axis here and looks like
an axis here an x and y axis this is x
vertical Z Z is I think vertical on this
side and horizontal is a slider this is
rotation Z it's listed as so if you look
down here we have a zero tation and
that's that should be a side to side is
your Z rotation and if you notice also
that's the full throw again hundred
nineteen and the slider is the vertical
which goes from 118 to 13 so again be
careful with that when you're working
with the device is that you're not
expecting full full range or you don't
have to have full range or your mapping
at least a full range so that's
something there the last thing we'll
look at in this case is a jog and
shuttle the interesting thing about the
jog and shuttle it's a consumer device
has 13 buttons one dial and one wheel if
we look at the wheel which is
interesting it's the no welcome to
Ashley wanna look at the dial you know
it's a dials a wrapping element the dial
wraps around so it's kind of kind of
need a little little device there you
can see how the indication from the
element tells you exactly what how the
element how it's going to behave so will
we will we will quit out of this and go
back to the slide machine slides
okay luckily the code here is definitely
not the density of the code in the first
section so we're talking about setting
up the interface polling event queues
and Carbon events well maybe I lied
so this actually is not that that hard
of code it's just that once you get an
i/o kit everything's really long every
constants really long every functions
really long so really and I didn't help
I made really long variables all you're
going to do is create plug-in interface
for service and then you're going to
query the interface that's the only two
functions in there everything else is
cruft that surrounds those functions but
basically you're going to do is you're
gonna query the interface that's gonna
give you a hit interface then you're
going to release the plug-in interface
here that you have an intermediate
interface so basically you're gonna say
you're gonna say okay I need something
to point me to the hit interface I
create the plug-in interface I get the
hit interface from it and then I release
the plug-in interface but I don't need
it anymore and then you're gonna open it
open is key here once you open the
interface you want to make sure your
closing interface because you're holding
on to that device and you may if you
don't close interface you may have to
actually replug and unplug the device
into a different port so the so the i/o
kit thinks it's a different device and
you can then require it if you if you
crash or you're in debugger and you quit
out your application early polling okay
now we're now we're pretty easy this is
pretty simple all we do is get element
value on them with the interface we
achieved with the cookie we talked about
the element cookie you have a list of
cookies you just call get element value
pretty simple that now once you've gone
through all the setup this is really
easy to do easy to do have a queues
how're we gonna do queues keys are also
pretty easy we allocate a queue we tell
we create the queue when we create the
queue we need to tell them what size of
the queue is and when Brent comes up for
questions like he can actually answer
this so I'm off the top of my head I
don't know but the update rate for USBs
for like axes is pretty quick I think
it's a hundred Hertz but I'm not but I'm
not actually sure that and will give you
the actual answer later but realize that
your queue if you queue an acci you're
gonna be receiving data and a
significant rate and so in this case I
think by example
I have K device size Q but in fact
that's ten you got to be retrieving data
every tenth of a second to even keep up
with the input from an acci so realize
you may want to pull axes q buttons or
if you do Q axes you want to retrieve
data with a fairly large Q at a fairly
good rate also this the Q is actually
locked down in kernel memory so it's
held in in RAM so large Q is if you
create this obnoxiously large Q is the
new memory that you're committing to
holding down in RAM that will not be
released until you release the Q you add
element to the Q and then you start the
Q when you need to start the cube you
also can flush SKUs when you need to to
flush the events out of there
so get next event real simple you have a
Q you get that you get the event out of
it it gives you a time in the event it's
pretty easy it gives you the the element
the device in the cookie so it's real
easy to find out exactly what caused the
event let's talk about carbon events a
little bit and then we'll go back to
some examples in how this all works in
carbon events what we want to talk about
is Mouse drag Mouse moved I talked about
those earlier what you want to do is get
event parameter the mouse location and
it gives you a mouse point real simple
so this is this is how you would get the
mouse point of the actual amount of
mousemove event or Mouse dragged event
if you want the Delta K event per am
Mouse Delta this is not in the very top
level events in the carbon events dot H
file it's down on the bottom but it just
works just the same if you asked for
that parameter you'll get the mouse
Delta for any mouse moved event Mouse
down event things you can get out of it
you can get the mouse location so you
can get where they press the mouse down
so if you're tracking controls or doing
that kind of thing you also get the
modifier keys so if you want to see what
modifier keys were held down command
click shift click those kind of things
you can do that and lastly you can get
the mouse button so you can get one more
than one button they're enumerated in
order so if you want to get primary
secondary tertiary buttons you can do
that so support multi button mice very
easy to do with it with carbon events
lastly Carbon events for keyboard data
rocky down rocky repeat if you're just
trying to get keyboard data you get the
Mac character codes and you get the
modifiers and go with those really
simple
just get the kids there are character
codes out of there or you can get the
virtual key if you want to get the
virtual key instead okay so what I'm
going to do next we'll do the rocket
demo some of you may have seen this
before
and what I'll do
we're just going to open up the it's
gonna run the rocket demo and I think I
have it set up for the I shock yes so I
have the eye shock set up for the rocket
demo and you can see it's very simple
using the using the joystick for the
input using the button for the thrust
I have zoom in and zoom out on this one
call very very simple
quit out of there and one more quick
demo on this and then we'll talk about
saving and restoring configurations and
I think this is set up for a different
device I can't remember why when I set
this up for I have to look for the
joystick so this is just a little little
test demo that's really easy to see you
can see that is as a joystick set up
thrust in fire on the joystick easy to
easy to retrieve and what this is this
stuff is set up using some of the sample
code and basically all you're doing is
getting I have a wraparound good element
value and you pass it a pointer to the
element a pointer to the device you have
and it'll find the up find the value for
it or you can cue it and get the next
event out of the cue so this is again
one call to get the element value out of
it
you call build device list you're gonna
build a device list you find a device
you're interested in you have one call
to get the element value so you don't
have to do all all that code I showed
you it's not real it's already been done
for you and hopefully you can use that
so we'll go back to the slide then we'll
talk about getting in saving
configuration I'll show you now I'll do
a little more demo at the end so one of
the things we talked we need to talk
about is how you configure I mean yeah
you can get lots of I can get the first
button on a device but is that what the
user wants to use for fire I don't know
maybe that joystick is set up for as a
trigger but some of the other ones the I
shop for example the buttons one through
four set up on the on the Hat over here
I'm not sure if you're using this this
joystick as a you know as your control
here I probably want to use something on
this side of the of the gamepad so in
that case you want a new configuration
you want to let the user decide what
they want to configure you want to make
it as easy as possible so first thing
we're the kind of the methodology behind
is we have a set of actions and in the
application you may want to turn left
turn right
thrust fire zoom in zoom out kind of
thing those are the kind of actions you
want to map those two elements so we're
gonna have a UI you present whatever you
want whether it's immersive or whether
it's just aqua it took about 50 lines of
code to put a UI together that I'll show
you in a minute so it's not a real big
deal and then you call a function that
basically goes out and pulls all the
devices wrote a function that basically
the current current device values it
then pulls all the devices to find out
what changed and if it's beyond a
threshold it said it reports you back
that that device if it times out returns
time out with note with or that device
an element timeout returns without
anything returns null so you know that
the user either kind of canceled out or
waited for the thing to cancel itself
out when the user selects something to
assign we do exactly what I said we did
build those queues pull across the
queues and return what's associated we
just cookie and the device interface to
pull for the input order or build the
queue for the input so it's real simple
once you get that's the information back
out you can find the cookie you find the
device interface and you got it you got
the input right there you associated
that with your action and you're done
saving configurations when we talk about
saving configurations we need to bring
up my little slide here which tells me
exactly what we're gonna save and the
reason I want to do this is because how
do you identify a device across multiple
systems of disparity users that you may
have you know a gamepad here that's
close to your the gamepad but it's not
quite the other gamepad so what do you
want to do first thing you want to do is
for the element you want to save the
cookie so if you find that same device
you have the cookie to it you know
exactly where it is it on the same
device you pull the cookie out you also
want to say the usage and usage page
what's a what's an x-axis any but you
can't find that the the I shock device
we do find the USB gamepad pro if you if
you know you're looking for an x-axis he
doesn't matter what the button the
cookie was because the cookie won't
apply to a different device of a
different product vendor ID but you can
look for an axe axe he's an assign it to
the x-axis very simple to do as far as
devices you want to say the device
serial number most devices don't have it
but if you do have it it's really a easy
way to determine with a product vendor
ID exactly the same device you can track
that device exactly wherever the person
plugs it in whatever system it's on but
they have ten of those devices input in
their system you'll find that exact
device so they want to use their purple
painted joystick they can use the purple
painted joystick every time because
you'll be all find it vendor ID product
ID in location those three together
basically specify a certain device
that's plugged into a certain place in
the system so we're assuming that
someone doesn't get lots of devices lots
of
and change him around all time that'll
probably find the same joystick gamepad
whatever the person's been using they
will continue to use it
and lastly usage page and usage you
can't match anything else better to find
the gamepad that's close or joystick
disclosed to a gamepad and try and match
that than to find the jog shuttle to let
them trying to play they're there you
know shoot him up or quake with the with
their jog shuttle so again I think we
just went through these top to bottom a
vendor product ideas serial number and
cookie
he got all those that identifies a
specific element on a specific device
you're in there you're golden if you
can't give the serial number you can
substitute in the location in the USB
chain that says if the things plugged
into the same place it's great vendor ID
product ID and cookie
so this says I don't know if it's the
same device but I know it's the same
type of device plugged into the system
and when I say type I mean exactly the
same make and model spec from the same
manufacturer
so I know that that that is unless they
have two of them it's probably the same
device then usage in usage page if you
find a usage in usage page match to
match for your device you want to make
sure you realize that the cookie is no
longer valid actually the cookies no
longer valid I'm sorry that's correct
once you get off the vendor and product
you need your cookie will no longer be
valid so you then have to use the usage
and usage page for the element search
down and try and find the x-axis or the
first button or the fifth button and
then any device if you can't match any
of those so you haven't found the you
know you have a gamepad you didn't find
any game paths P have a joystick again
search by usage and usage page and that
should find that should find exactly
what you're looking for the closest
match and I think will bring up a demo
machine again and it just happens that I
have an example of this so here's my
configuration window pretty simple Mac
I'll a USB joystick which what we're
seeing here real simple carbon events by
the way to run both at the same time so
I can reconfigure this on the fly I want
to I want to switch to this device Ramar
plugged into the same computer is do
x-axis I shock x-axis so I scanned all
of them no problem found that one
user wants to use the I shock instead
for thrust I want to use that button and
fire I want to use the the jog and
shuttle button 5 for fire so no problem
to mix devices really easily and now if
you notice its reconfigured
automatically in that great no problems
wall wall everything's working I didn't
have to rebuild a list or do anything
like that bringing for your thrusters
over here and no hand no hands on this
thing no hands and the fires down here
on the on your jog and shuttle so that
works great another thing you can do
though is let's um let's go to something
more normal and so we have button 5 & 6
actually yeah I'll leave it at that
so we have x axis y axis on this device
button 5 & 6 I'm gonna hit OK there I'm
going to save that configuration I save
it to a flat file
I saved the exactly information I showed
you to a flat file I'm gonna quit this
bring reopen it it loads the the
configuration so we look at the
configuration and again it's the same
configuration we had before and I'll to
prove it that if we actually actually
changing things something I'll actually
make that button sing I don't want to do
that you can do that it's not a problem
there's no reason you can't map it that
way we'll make it button 7 so you're
okay again we'll save the configuration
and we'll quit and now we should have
button 6 & 7 here the configuration for
the input button 6 & 7 so that's that's
the input we want from this thing so
we're playing our game we're having a
great time doing we're doing great
things haven't in having a group having
a blast this is very exciting
oh here's two here's something
interesting I thought I will some
interesting okay I am moving this is the
Hat this is the little joystick add on
this device just see say it goes all the
way to that corner this is even with
calibrated input this is with
recalibrating to the full range because
all the way up there now I'm going to
the top left and bring it across I'm
still bringing it across still bringing
it across and if you notice it doesn't
have the full range and that that's the
full that's the full motion from that
hat switch so understand when you're
designing games and users may have
devices that don't quite respond to
every single corner of the input and
that that may be something that you
don't want to have to have the user turn
at a certain rate to get to you know to
make a corner and their device doesn't
be real frustrating if the device can't
make that corner so but we'll quit this
again and I'm gonna go over to to Bob's
house and Bob didn't spend the extra
money and he only ended up with the
gamepad pro so I want to play the game
anyway
so we're gonna launch and or actually
Bob brought his game prep pro for Bob
borrowed mine so I have to use this is I
don't have it anymore
oh well that's pretty nice it found this
as a gamepad pro and said I can I know
how to configure that I'll configure x
and y-axes button 6 and 7 and so play a
little game
obviously thrust and fire we happen to
be somewhere here in here not the best
buttons but but it did configure it
found that it found the device and
actually map it correctly so this is we
save the configuration
it'll keep this this as a safe
configuration mapping whatever it can
until I actually save a different
configuration at that point it would
save a different configuration one thing
to look at also which will quit that
again and I'll remove the gamepad probe
cuz now all I have is the joystick and
if I bring up the configuration for the
joystick one thing we can see is that it
mapped the X and y-axis but this only
has four buttons so it doesn't know how
to map those extra buttons you could
easily expand on the code and say hey if
it's not ever passed the
the buttons also I'll pick the first
buttons whatever you wanted to do this
the idea here is to give the user
something that's pretty close to work
with so they're not actually you know
suffering from a problem with them
I'm not having their you know having a
reconfigure entire device so we can
figure a lot of inputs for your for your
application every time they play they
change devices so what else do I got to
show you so it's all hit config save we
saw the different devices the there's no
except for location ID which identify as
a computer there's no specific thing in
your list of savings of things you save
that identify that you have to go bring
back to the slides please you actually
have to go to know you have to be on
that one computer so you can bring an
input file configuration file on your
computer with your development machine
and what you're going to find is you're
never going to find that location ID for
your development machine but what you're
in you will find is the vendor ID in the
product ID and so you'll be I'll
identify if you put a configuration in
for a certain type of joystick or you
put a gamepad configuration in you
definitely identify that there is that
type of thing on the system so roadmap
136 sound the networking for games is
two o'clock in the same room I'd like to
see all there and this afternoon or this
evening
basically at 5:00 last chance to vent
your venn your interest what we did good
what we did bad about games and Mac OS
so we'd like to see you there also to
hear about anything that you think that
we should be adding to the OS or how we
should be improving it that's my
information please do you have
information if you have questions you
feel free to contact me the sample code
again will be up so I think it will
handle almost everything for you the
code that you're actually to do the
interface to do the polling it's one
call to configure inputs it's one call
to build a device list one call a
release it it's not it's not real
complicated then you can look at the
code and you can learn from that
exactly how to how to implement it stuff
you