Skip to content

Crude gamepad input implementation#4

Open
kryksyh wants to merge 1 commit intomasterfrom
gamepad_controls
Open

Crude gamepad input implementation#4
kryksyh wants to merge 1 commit intomasterfrom
gamepad_controls

Conversation

@kryksyh
Copy link
Copy Markdown
Collaborator

@kryksyh kryksyh commented Mar 25, 2025

A simple note input with a gamepad, left-side buttons are mapped to note 0, and right-side buttons are mapped to note 60. Velocity is controlled with the left stick.

@kryksyh kryksyh requested a review from saintmatthieu March 25, 2025 19:00
@kryksyh kryksyh force-pushed the gamepad_controls branch 2 times, most recently from f590d34 to 31f2fbc Compare March 25, 2025 19:05
Copy link
Copy Markdown
Owner

@saintmatthieu saintmatthieu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks simple: if someone has a gamepad plugged, we take control of it and the user can start interacting.
Eventually, we'll want to show some indication that the gamepad is connected and available, but until then just LOGI() would be enough for us to get started.

About the interaction: ideally we need four easily accessible buttons, two for each hand, to be able to play legato or staccato, and two other controls for left-hand and right-hand velocities, if possible without interfering with the fingers that trigger the notes (except if the note-triggering buttons themselves can convey velocity). Maybe there's something to explore with the accelerometers.

It'd be great if it could be tuned to something pleasant to use and without expressiveness restriction wrt a MIDI keyboard, it could really make a difference in widening the audience. All these improvements can be done peu à peu. If it turns out good, then we should support multiple pads, to allow two persons (e.g. parent and kid, teacher and pupil) to play together.

public muse::async::Asyncable
{
muse::Inject<IOrchestrion> orchestrion = {this};
muse::Inject<IGamepad> gamepad = {this};
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect the gamepad to be owned exclusively be GamepadMidiController? Then I would just let it be a member, no need for it to be injected.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, thought about it again: I don't think there is a need for the IGamepadMidiController API, just having the module instantiate and own GamepadMidiController would be enough.

private:
void doConnect() {
if (SDL_Init(SDL_INIT_GAMECONTROLLER) < 0) {
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call succeeds even if there is not game controller connected? If not, then I'd log just at info leve.
BTW, you can use the framework's log.h

}
}

SDL_AddEventWatch([](void* userdata, SDL_Event* event) -> int {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably check that m_controller != nullptr before adding the watcher?

@saintmatthieu
Copy link
Copy Markdown
Owner

Of course, CI must be fixed before merging.

@saintmatthieu saintmatthieu force-pushed the master branch 2 times, most recently from 1cb98ff to c869682 Compare July 17, 2025 20:58
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

Successfully merging this pull request may close these issues.

2 participants