diff --git a/ultramodern/include/ultramodern/input.hpp b/ultramodern/include/ultramodern/input.hpp index efbe5e8..6973dfa 100644 --- a/ultramodern/include/ultramodern/input.hpp +++ b/ultramodern/include/ultramodern/input.hpp @@ -7,11 +7,21 @@ namespace ultramodern { namespace input { struct callbacks_t { using poll_input_t = void(void); - using get_input_t = void(uint16_t*, float*, float*); - using set_rumble_t = void(bool); + using get_input_t = bool(int controller_num, uint16_t* buttons, float* x, float* y); + using set_rumble_t = void(int controller_num, bool rumble); poll_input_t* poll_input; + + /** + * Requests the state of the pressed buttons and the analog stick for the given `controller_num`. + * + * Returns `true` if was able to fetch the specified data, `false` otherwise and the parameter arguments are left untouched. + */ get_input_t* get_input; + + /** + * Turns on or off rumbling for the specified controller. + */ set_rumble_t* set_rumble; }; diff --git a/ultramodern/src/input.cpp b/ultramodern/src/input.cpp index 5a6010f..811abdc 100644 --- a/ultramodern/src/input.cpp +++ b/ultramodern/src/input.cpp @@ -92,23 +92,25 @@ extern "C" void osContGetQuery(RDRAM_ARG PTR(OSContStatus) data_) { extern "C" void osContGetReadData(RDRAM_ARG PTR(OSContPad) data_) { OSContPad *data = TO_PTR(OSContPad, data_); - uint16_t buttons = 0; - float x = 0.0f; - float y = 0.0f; - if (input_callbacks.get_input != nullptr) { - input_callbacks.get_input(&buttons, &x, &y); - } + for (int controller = 0; controller < max_controllers; controller++) { + uint16_t buttons = 0; + float x = 0.0f; + float y = 0.0f; + bool got_response = false; - if (max_controllers > 0) { - // button - data[0].button = buttons; - data[0].stick_x = (int8_t)(127 * x); - data[0].stick_y = (int8_t)(127 * y); - data[0].err_no = 0; - } - for (int controller = 1; controller < max_controllers; controller++) { - data[controller].err_no = 0x80 >> 4; // errno: CONT_NO_RESPONSE_ERROR >> 4 + if (input_callbacks.get_input != nullptr) { + got_response = input_callbacks.get_input(controller, &buttons, &x, &y); + } + + if (got_response) { + data[0].button = buttons; + data[0].stick_x = (int8_t)(127 * x); + data[0].stick_y = (int8_t)(127 * y); + data[0].err_no = 0; + } else { + data[controller].err_no = 0x80 >> 4; // errno: CONT_NO_RESPONSE_ERROR >> 4 + } } } @@ -133,11 +135,8 @@ s32 osMotorStart(RDRAM_ARG PTR(OSPfs) pfs) { s32 __osMotorAccess(RDRAM_ARG PTR(OSPfs) pfs_, s32 flag) { OSPfs *pfs = TO_PTR(OSPfs, pfs_); - // Only respect accesses to controller 0. - if (pfs->channel == 0) { - if (input_callbacks.set_rumble != nullptr) { - input_callbacks.set_rumble(flag); - } + if (input_callbacks.set_rumble != nullptr) { + input_callbacks.set_rumble(pfs->channel, flag); } return 0;