connected_device_info_t

This commit is contained in:
angie 2024-06-06 18:04:29 -04:00
parent 123132c2a0
commit 0a55b67a7b
2 changed files with 80 additions and 10 deletions

View file

@ -5,24 +5,55 @@
namespace ultramodern {
namespace input {
enum class Device {
None,
Controller,
// Mouse,
// VRU,
};
enum class Pak {
None,
RumblePak,
// ControllerPak,
// TransferPak
};
struct connected_device_info_t {
Device connected_device;
Pak connected_pak;
};
struct callbacks_t {
using poll_input_t = void(void);
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);
using get_connected_device_info_t = connected_device_info_t(int controller_num);
poll_input_t* poll_input;
/**
* Requests the state of the pressed buttons and the analog stick for the given `controller_num`.
*
* `controller_num` is zero-indexed, meaning 0 corresponds to the first controller.
*
* 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.
*
* `controller_num` is zero-indexed, meaning 0 corresponds to the first controller.
*/
set_rumble_t* set_rumble;
/**
* Returns the connected device info for the given `controller_num` (as in, the controller port of the console).
*
* `controller_num` is zero-indexed, meaning 0 corresponds to the first controller.
*/
get_connected_device_info_t* get_connected_device_info;
};
void set_callbacks(const callbacks_t& callbacks);

View file

@ -24,23 +24,61 @@ void ultramodern::measure_input_latency() {
#define MAXCONTROLLERS 4
#define CONT_NO_RESPONSE_ERROR 0x8
#define CONT_TYPE_NORMAL 0x0005
#define CONT_TYPE_MOUSE 0x0002
#define CONT_TYPE_VOICE 0x0100
static int max_controllers = 0;
/* Plain controller */
static u16 get_controller_type(ultramodern::input::Device device_type) {
switch (device_type) {
case ultramodern::input::Device::None:
return 0;
case ultramodern::input::Device::Controller:
return CONT_TYPE_NORMAL;
#if 0
case ultramodern::input::Device::Mouse:
return CONT_TYPE_MOUSE;
case ultramodern::input::Device::VRU:
return CONT_TYPE_VOICE;
#endif
}
return 0;
}
static void __osContGetInitData(u8* pattern, OSContStatus *data) {
// Set bit 0 to indicate that controller 0 is present
*pattern = 0x01;
*pattern = 0x00;
// Mark controller 0 as present
data[0].type = 0x0005; // type: CONT_TYPE_NORMAL (from joybus)
data[0].status = 0x01; // status: 0x01 (from joybus, indicates that a pak is plugged into the controller)
data[0].err_no = 0x00; // errno: 0 (from libultra)
for (int controller = 0; controller < max_controllers; controller++) {
ultramodern::input::connected_device_info_t device_info{};
// Mark controllers 1-3 as not connected
for (int controller = 1; controller < max_controllers; controller++) {
// Libultra doesn't write status or type for absent controllers
data[controller].err_no = 0x80 >> 4; // errno: CONT_NO_RESPONSE_ERROR >> 4
if (input_callbacks.get_connected_device_info != nullptr) {
device_info = input_callbacks.get_connected_device_info(controller);
}
if (device_info.connected_device != ultramodern::input::Device::None) {
// Mark controller as present
data[controller].type = get_controller_type(device_info.connected_device);
data[controller].status = device_info.connected_pak != ultramodern::input::Pak::None;
data[controller].err_no = 0x00;
*pattern = 1 << controller;
}
else {
// Mark controller as not connected
// Libultra doesn't write status or type for absent controllers
data[controller].err_no = CONT_NO_RESPONSE_ERROR; // CHNL_ERR_NORESP >> 4
}
}
}
@ -136,6 +174,7 @@ s32 __osMotorAccess(RDRAM_ARG PTR(OSPfs) pfs_, s32 flag) {
OSPfs *pfs = TO_PTR(OSPfs, pfs_);
if (input_callbacks.set_rumble != nullptr) {
// TODO: Should we check if the Rumble Pak is connected? Or just rumble regardless of the connected Pak?
input_callbacks.set_rumble(pfs->channel, flag);
}