Saturday, August 4, 2018

Dreamcast Tutorial: Gamepad Input

Since DCEmulation won't let me contribute to their site (I will never stop being salty about that. If there's a new wiki to go to, let me know), I'll be posting my quick and dirty way of getting controller input.

This blog is going to be focused on programming in C/C++ (C++ primarily).

You'll notice I do a lot of explaining. I really hate tutorials which just leave the reader to figure things out on their own. I don't just want to explain how to do something, but why it's done (to the best of my ability, at least!)

I'll try and get better about being more concise in the future, so bear with me for now!



The Code


I'll try and briefly give a run-down of what functions and macros do, but if you're confused you might want to look them up in the KOS documentation listed in the references at the end of this post.


There's not actually a ton here, so I'll break it down step by step.

maple_device_t is a reference to a controller. For some reason, KOS/Dreamcast refers to its input as "maple," so anything "maple" related will likely have to do with input.

We can get our controllers by using the maple_enum_type function which will give us the controller number we pass in (in this case, 0), and a type of controller to get the input for (in our case, a MAPLE_FUNC_CONTROLLER)




cont_state_t is a reference to what sort of state our controller is in. The struct contains information such as what buttons we've pressed, trigger values, and joystick values. We can get this by using maple_dev_status, passing it our controller, and casting it to a cont_state_t.




Next, we do a bitwise operation to check if we're hitting the button we want. We do an AND operation so that we can see if the A-button bit is set. If it's not set, then we'll get a 0 and the if-statement will move on.



And that's about it for basic input! Two other cool functions you might want to look into would be MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END which essentially loop through all of the input devices, allowing you to get the input from multiple devices.

An example of this can be seen in kos/examples/dreamcast/png/example.c 


How Console Input Works

Bit Manipulation


If you already know how about boolean algebra, bit shifting, and bitwise operators, then skip down to "Why is This Important?"

Last year, I took two courses: Computer Organization and the other dubbed "Video Game Programming 3." Both of these courses taught me the lower level workings of computers. The key take-away was bit manipulation (bit shifting and bitwise operators), and how useful it is in programming.

Bit Shifting

Bit shifting is the process of moving bits into different positions. C/C++ have operators for this, "<<" and ">>". For example, the number "1" is represented in binary as:
00000001
If we were to shift the bits over to the left three spaces using the "<<" operator,
1 << 3
the result would be
00001000

Bitwise Operators

Bitwise operators AND ( & ), OR ( | ) and XOR ( ^ ) are used to combine, test, and add strings of bits. I won't go extremely in depth, since this is something you've probably already learned in school (if not, it might be worth your time to do some quick research into boolean algebra), but I'll give a brief run-down:

AND ( & )
This operator is typically used as a comparison. AND only returns a "1" if both values are "1".
Example:
001001001
101000101 &
---------------
001000001

OR ( | )
This operator is typically used to combine two strings of bits. OR only returns a "0" if both values are "0"
Example:

001001001
101000101 |
---------------
101001101

XOR ( ^ )
This operator, on a very low level, is used to add bits (not to be confused with OR which just combines the bits). XOR returns "1" if both values are opposite, and "0" if both values are the same.
Example:
001001001
101000101 ^
---------------
100001100

Why is this important? 

Bit manipulation is the basis for console input.

During my time taking those aforementioned classes, I decided to try my hand at making a little demo on the Gameboy. To my surprise, input was all done using bit manipulation! Why is that?

Consoles typically read input by viewing the bits of a specific spot in memory. A bit in the 1's place might indicate that the user has hit the "A" button, while a bit in the 32's place might indicate the user has hit the "START" button.

The Dreamcast is no different.

KOS provides us with macros for input. You can read up on them here. These macros provide us with the bit string we need to get input for a specific button press.

References

Here are a couple of references that really helped me out while figuring this out! Hopefully they help you, as well! 
Don't underestimate the KOS documentation! It's full of extremely useful information.

No comments:

Post a Comment