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