Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new API function to test which buttons are pressed #56

Open
ghost opened this issue Jan 9, 2023 · 9 comments
Open

Add new API function to test which buttons are pressed #56

ghost opened this issue Jan 9, 2023 · 9 comments

Comments

@ghost
Copy link

ghost commented Jan 9, 2023

@Xyvir
Copy link

Xyvir commented Jan 9, 2023

Example/clarification:

new function

thumby.button.pressed()
or similair

Returns a 1 byte int 'register' with packed bits meaning the following:

0000 0000
1234 5678

1 up pressed
2 left pressed
3 down pressed
4 right pressed
5 A pressed
6 B pressed
7 Any Direction Pressed
8 A or B Button Pressed

No buttons pressed
0000 0000

up and A pressed
1000 1011
aka
decimal 139

down pressed
0010 0010
aka
decimal 34

@dan5sch
Copy link

dan5sch commented Jan 9, 2023

If the API returns the bit mask directly like in the example above, then you can define justPressed() and update() that match the semantics of the per-button methods.

@Xyvir
Copy link

Xyvir commented Jan 9, 2023

If the API returns the bit mask directly like in the example above, then you can define justPressed() and update() that match the semantics of the per-button methods.

So like
thumby.justPressed()

instead of my suggested
thumby.button.pressed()
?

also I don't see an existing update() function relating to input.

@dan5sch
Copy link

dan5sch commented Jan 9, 2023

The update() method I'm referring to:

If your frames take a long time to run, you can call update() repeatedly over the course of the frame and then call justPressed() once to find out if a short button press occurred during the frame.

My point is that it's possible to replicate the three methods of ButtonClass's API for an all-buttons mask-based API..

@Xyvir
Copy link

Xyvir commented Jan 9, 2023

OH! Gotcha.

Yeah we're both saying the same thing, thanks for the explanation.

@Xyvir
Copy link

Xyvir commented Jan 9, 2023

@dan5sch

On further thought, maybe one of the extra bits (like 7) should represent 'newly pressed this frame' or 'newly pressed since last update()' or something to distinguish from buttons being held previously?

Then the final bit can just be 'Any button/direction pressed' instead of splitting those out?

Let me know your thoughts, I'd like to get this theory-crafted well before it hopefully it's up in the API proper.

@dan5sch
Copy link

dan5sch commented Jan 9, 2023

I'm not sure what value one bit of information about new presses would add. The mask returned by justPressed() would be nonzero if and only if any buttons were newly pressed this frame.

Having special bits for "any direction" and "any A/B button" brings complications -- what meaning should those bits have in a just-pressed mask, when between two calls to justPressed() one direction might be released and a different direction pressed? Also, you can test if any direction or any A/B button was pressed or just-pressed using bitwise ops:
bool(button_mask & MASK_BUTTONS_DIRECTION)

Personally, I'm not sure what value there is to putting this in the official API. More advanced users who want to operate on button presses as bit masks can implement this with their desired behavior in very little code. Here is the entire button mask logic in my WIP game:

import thumbyHardware as th
# BUTTON_* constants omitted

class Blah:
    # ...

    @micropython.native
    def _set_frame_button_masks(self):
        # Get new frame's pressed buttons mask
        mask_pressed_new = 0
        if th.swL.value() != 1:
            mask_pressed_new |= BUTTON_L
        if th.swR.value() != 1:
            mask_pressed_new |= BUTTON_R
        if th.swU.value() != 1:
            mask_pressed_new |= BUTTON_U
        if th.swD.value() != 1:
            mask_pressed_new |= BUTTON_D
        if th.swA.value() != 1:
            mask_pressed_new |= BUTTON_A
        if th.swB.value() != 1:
            mask_pressed_new |= BUTTON_B
        # Update just-pressed then replace pressed with new mask
        self.mask_just_pressed = \
            mask_pressed_new & (self.mask_pressed ^ BUTTON_ALL)
        self.mask_pressed = mask_pressed_new

@Xyvir
Copy link

Xyvir commented Jan 9, 2023

Good point

It just felt right to round the register up to a full byte instead of 6 bits but you are correct it doesn't actually really add anything

@masonova1
Copy link
Collaborator

I've composed a PR that implements Jason's suggestion from the CPP library in #64. Button masks are defined inside the button base, and look like buttonMask*.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants