{"id":1073,"date":"2020-11-29T22:07:02","date_gmt":"2020-11-29T21:07:02","guid":{"rendered":"https:\/\/next-hack.com\/?p=1073"},"modified":"2020-11-30T19:04:45","modified_gmt":"2020-11-30T18:04:45","slug":"usvc-tutorial-4-usb-input","status":"publish","type":"post","link":"https:\/\/next-hack.com\/index.php\/2020\/11\/29\/usvc-tutorial-4-usb-input\/","title":{"rendered":"uSVC Tutorial 4: USB input"},"content":{"rendered":"\n<p>Hi there! Let\u2019s continue with our tutorial series. This time we will explore another important part (maybe the most important in videogames?), i.e. the input.<\/p>\n\n\n\n<p>uSVC uses USB gamepads or keyboards as inputs. The USB stack we implemented is hot swap and plug and play, i.e. the USB peripherals can be inserted anytime, and they will be \u201cinstalled\u201d right away, provided that there is a driver available for that peripheral. Luckily, we already created drivers for standard keyboard and gamepads, so pretty most of keyboards and gamepad will work, without any effort.<\/p>\n\n\n\n<p>For this tutorial we are going to use the keyboard (and later the gamepad) to navigate (i.e. scroll) around our map. Therefore you need to copy (and rename) last project we made for the <a href=\"https:\/\/next-hack.com\/index.php\/2020\/11\/22\/usvc-tutorial-3-smooth-scrolling\/\" target=\"_blank\" rel=\"noreferrer noopener\">smooth scrolling tutorial<\/a>.<\/p>\n\n\n\n<p>Before including the USB code, we need to disable the routine that scrolled automatically the screen with a rectangular pattern. To do this, comment the highlighted section below:<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"643\" height=\"442\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/11\/fourh-comment-autoscroll.png\" alt=\"\" class=\"wp-image-1075\"\/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>Now, let\u2019s add USB support. Let\u2019s first add the following snippet that allows to poll data from the keyboard or gamepad. The snippet should be added at the end of the main <code>while(1)<\/code> loop, as shown below:<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"643\" height=\"284\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/11\/fourth-usb-readout.png\" alt=\"\" class=\"wp-image-1076\"\/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>Let\u2019s analyze it.<\/p>\n\n\n\n<p>In order for the USB host stack to work, the <code>usbHostTask()<\/code> should be called at least once per frame. It is not a problem if this function is called more than once, and actually, to speed up enumeration (i.e. device recognition and driver installation), we call <code>usbHostTask()<\/code> as many times as we can, depending on how much time is left for the USB. For this reason we use a <code>do...while()<\/code> loop.<\/p>\n\n\n\n<p>In this loop we also poll several times the keyboard or the gamepad (if they are installed) to get the data. Note that calling the poll function does not actually initiates any I\/O transaction. The poll function will simply reserve an I\/O transaction (if not already reserved), which will be performed when the<code> usbHostTask()<\/code> will be called. Calling the poll function more than once is not an issue, and actually it might be useful, if, for any reason, the packet is corrupted or the USB device was not ready, when we polled it previously. When a poll transaction is successfully executed by the <code>usbHostTask()<\/code> function, the current device state (e.g. pressed keys, gamepad axis state, etc) will be updated.<\/p>\n\n\n\n<p>The loop runs until the currentScanLine number is smaller than 523 (i.e. 524-th line). &nbsp;<\/p>\n\n\n\n<p>Why we do not include the lines 523 and 524?<\/p>\n\n\n\n<p>Because the USB host task might be quite time consuming, and we do not want the currentScanLine to wrap to 0 in the loop: this would results in several issues such as glitches, frame drop and, in the worst case, even deadlock (the do\u2026while loop would never exit).<\/p>\n\n\n\n<p>After we poll for data, we need to process what we got from the driver.<\/p>\n\n\n\n<p>A keyboard and a gamepad of course are different: a USB keyboard has about 100 keys, while the gamepad have some buttons, the d-pad and possibly some analog joysticks. The included gamepad driver returns the axes status (up to 4 axes) and the button status (up to 32 buttons), while the keyboard driver offers different possibilities: reading the keypresses already in the ASCII format (using a the standard US keyboard layout), or reading the raw keyboard codes. It is up to the game developer to decide how to get and interpret the input data, and how to unify the two input methods. In our games, for sake of simplicity we decided to convert the gamepad inputs to an equivalent keypress on the keyboard, so the game only has to check which keyboard keys were pressed.<\/p>\n\n\n\n<p>Furthermore in the game examples, we did not use raw keyboard status, but the key already decoded in the ASCII<a href=\"#_ftn1\">[1]<\/a> format.<\/p>\n\n\n\n<p>This latter choice has the following limitation: key modifiers (Ctrl, Shift and alt) are not considered as separate keys, but they are used to create, together with the other keys, an equivalent ASCII character. However, not all the ctrl and shift combinations are actually decoded. Furthermore, alt is not even considered. In other words, Ctrl, Shift and alt are not well supported by this method. A better one is to get the raw keyboard status using this snippet (only the keyboard section is shown):<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1164\" height=\"179\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/11\/fourth-readkeyboard.png\" alt=\"\" class=\"wp-image-1079\"\/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>The snippet above should be placed after the previous <code>do\u2026while()<\/code> loop.<\/p>\n\n\n\n<p>In this tutorial we will proceed using the raw key codes. For now, we use only the keyboard, getting the gamepad data later.<\/p>\n\n\n\n<p>We use the keys \u201cwasd\u201d to move (i.e. scroll) the screen. To do this, we simply act on cameraX and cameraY variables based on which keys have been pressed. Note that up to 6 keys might be pressed at once, therefore an additional <code>for<\/code>-loop is required to scan all of them. The whole USB-related handling should be like as follows:<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1158\" height=\"709\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/11\/fourth-act-on-keyboard.png\" alt=\"\" class=\"wp-image-1080\"\/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>Let\u2019s compile and upload the code to uSVC in debug mode (see guide on the previous article).<\/p>\n\n\n\n<p>Connect to the uSVC a micro usb to USB-A adapter, and then connect the USB keyboard to the adapter. You should see the keyboard LEDs turning on for 1 second, indicating that the keyboard driver has been installed and it is ready to return data. This is handled by the usbHostTask() function, which also handles the poll requests. Now, with the keyboard you should be able to move around the screen.<\/p>\n\n\n\n<p>Noticeably, you should see something strange: initially you should see only the sprites, but, later, if you press any of the WASD key, you should see the background appear again. This is due to the drawMap() function, which initially does not redraw the map, because it thinks that it was already drawn (see previous post). To avoid this glitch, just write <br><code>drawMap(0, 0, 1);<\/code> (i.e. with non zero <code>forceRedraw <\/code>parameter) before the <code>while(1);<\/code> as shown below:<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"435\" height=\"110\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/11\/fourth-force-redraw.png\" alt=\"\" class=\"wp-image-1081\"\/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>Let\u2019s add gamepad support now:<\/p>\n\n\n\n<p>We will still use the same strategy we used on our example games: gamepad actions are converted to keys, using a small code snippet shown below.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1138\" height=\"523\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/11\/fourth-handle-gamepad.png\" alt=\"\" class=\"wp-image-1082\"\/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>As you can see, we just convert the gamepad axes status to the keypresses, so no other modification is required.<\/p>\n\n\n\n<p>Let\u2019s connect uSVC again to the PC, and build and upload the program. Now you should be able to move around in the map, with the gamepad too!<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/11\/Fourth-scrolled.png\" alt=\"\" class=\"wp-image-1083\"\/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>As a homework, we leave you a small task: instead of scrolling the screen, try to move the sprites!<\/p>\n\n\n\n<p>This is all for this week, however, think about this: now you already know all the basics to create your first game: you can draw tiles and sprites, you know how to produce smooth scrolling effects and how to get the keyboard\/gamepad input\u2026 &nbsp;<\/p>\n\n\n\n<p>Well, yes, but we are still missing sound\u2026 This will be covered in the next tutorial!<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p id=\"_ftn1\"><a href=\"#_ftnref1\">[1]<\/a> And if no ASCII code can be generated with a particular key, the key code is put in the MSB of the 16 bit integer.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi there! Let\u2019s continue with our tutorial series. This time we will explore another important part (maybe the most important in videogames?), i.e. the input. uSVC uses USB gamepads or keyboards as inputs. The USB stack we implemented is hot&#8230; <a class=\"read-more-button\" href=\"https:\/\/next-hack.com\/index.php\/2020\/11\/29\/usvc-tutorial-4-usb-input\/\">(READ MORE)<\/a><\/p>\n","protected":false},"author":2,"featured_media":836,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[32,27],"tags":[],"class_list":["post-1073","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-all-projects","category-usvc"],"_links":{"self":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/1073"}],"collection":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/comments?post=1073"}],"version-history":[{"count":4,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/1073\/revisions"}],"predecessor-version":[{"id":1085,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/1073\/revisions\/1085"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/media\/836"}],"wp:attachment":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/media?parent=1073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/categories?post=1073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/tags?post=1073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}