Skip to content
makapuf edited this page Jun 24, 2015 · 2 revisions

Gamepad

Standard macros and input

All inputs methods are defined in bitbox.h

Gamepad buttons are stored in a global uint16_t gamepad_buttons[2]. They are rewritten each frame with the current values.

You need to call this function in order to get a keyboard to emulate a gamepad (ie transform keyboard events to gamepad button status):

void game_frame(void)
{
   kbd_emulate_gamepad();
   // the rest of your code for each game frame
}

(If you don't use it, you will see individual keyboard events as well as the real gamepad state)

And with the following macro (already defined in bitbox.h), you can check whether the state of a certain key is depressed or not:

#define GAMEPAD_PRESSED(id, key) gamepad_buttons[id] & gamepad_##key

where id is the gamepad number (either 0 or 1 for now), and key is one of the following: start, A, B, X, Y, select, L, R, etc. You can use it like this:

if (GAMEPAD_PRESSED(0, start))
{
    message("player 0's start button is depressed.\n");
}

check out https://github.com/makapuf/bitbox-polar or https://github.com/makapuf/bitbox/tree/master/test_usb for a good example of how things all tie together (for the latter, mixing mouse, gamepad and keyboard).

Ignoring held buttons

Sometimes it is nice to remove button events from the controller once you have processed them. For example, when a player presses start, you want to remove that from the button information, and wait for the player to press start again. But to do this, you need a few extra variables, since gamepad_buttons is overwritten each game_frame. You can add my_gamepad_buttons to manage the buttons you want persistent or not, and prev_gamepad_buttons to keep information about the previous state of gamepad_buttons. This will help you know when a player presses a button for the first time, and when s/he is holding it down. Notice these are both arrays since we have player 0 and 1 to worry about:

uint16_t my_gamepad_buttons[2];
uint16_t prev_gamepad_buttons[2];

You can define some helper macros to press and unpress buttons you care about, as well as check if a button is pressed or not:

#define UNPRESS(id, key) my_gamepad_buttons[id] -= gamepad_##key
#define PRESSED(id, key) my_gamepad_buttons[id] & gamepad_##key
#define PRESS(id, key) my_gamepad_buttons[id] |= gamepad_##key

though notice: you shouldn't UNPRESS a button (UNPRESS(0, start)) unless that button is pressed! Then instead of using kbd_emulate_gamepad(), you can use an extra function that only registers new presses for your my_gamepad_buttons:

void read_presses()
{
    // get current state
    kbd_emulate_gamepad();

    // update my state using only new presses:
    for (uint8_t i=0; i<2; ++i)
    {
        // only allow button on if it's on:
        my_gamepad_buttons[i] &= gamepad_buttons[i];
        // but only add in _new_ presses to my gamepad buttons
        my_gamepad_buttons[i] |= gamepad_buttons[i] & (~prev_gamepad_buttons[i]);
    }

    // get previous state of buttons
    for (uint8_t i=0; i<2; i++)
        prev_gamepad_buttons[i] = gamepad_buttons[i];
}

check out https://github.com/lowagner/bitbox-mmat for a good example of how things all tie together.

Another possibility (used in bdash) :

uint16_t previous_gamepad[2];
#define PUSHED(id,key) (gamepad_buttons[id] & ~previous_gamepad[id] & gamepad_##key) 

void game_frame (void) {
    
    ... your game logic ...
    if (PUSHED(0,start)) ...        
    if (PUSHED(0,up)) ...
    ... your game logic ...


    for (int i=0;i<2;i++)
        previous_gamepad[i] = gamepad_buttons[i];
}

Mouse

A USB mouse can be used quite simply. Just check https://github.com/makapuf/bitbox/tree/master/test_usb

Mice are handled through the event system, with basically three events :

e.type = evt_mouse_move: use e.mov.x and e.mov.y (relative movement, signed)
e.type = evt_mouse_click: use e.button.id (0=left, 1=right, 2=middle)
e.type = evt_mouse_release: use e.button.id also

If you don't want to use events, you can also use data_mouse_x, data_mouse_y and data_mouse_buttons variables (see bitbox.h).

Keyboard

Also see https://github.com/makapuf/bitbox/tree/master/test_usb

Again, you can use events, with e.type = evt_keyboard_press: use e.kbd.key (key ) with e.kbd.mod (modifier bitmap, see bitbox.h) e.type = evt_keyboard_release

be careful that you will get key IDs, not ascii letters. By example, the A key will have a different id on azerty since it's not the same key.

You can use translation funciton kbd_map to convert keyboard type to ascii chars (see bitbox.h)