mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-28 23:13:02 +00:00
move rumble functions to controller API
This commit is contained in:
parent
a3ee774ba2
commit
bd68d6cb67
5 changed files with 68 additions and 45 deletions
|
@ -16,18 +16,24 @@
|
||||||
#include <ultra64.h>
|
#include <ultra64.h>
|
||||||
|
|
||||||
struct ControllerAPI {
|
struct ControllerAPI {
|
||||||
const u32 vkbase; // base number in the virtual keyspace (e.g. keyboard is 0x0000-0x1000)
|
const u32 vkbase; // base number in the virtual keyspace (e.g. keyboard is 0x0000-0x1000)
|
||||||
void (*init)(void); // call once, also calls reconfig()
|
void (*init)(void); // call once, also calls reconfig()
|
||||||
void (*read)(OSContPad *pad); // read controller and update N64 pad values
|
void (*read)(OSContPad *pad); // read controller and update N64 pad values
|
||||||
u32 (*rawkey)(void); // returns last pressed virtual key or VK_INVALID if none
|
u32 (*rawkey)(void); // returns last pressed virtual key or VK_INVALID if none
|
||||||
void (*reconfig)(void); // (optional) call when bindings have changed
|
void (*rumble_play)(float str, float time); // (optional) rumble with intensity `str` (0 - 1) for `time` seconds
|
||||||
void (*shutdown)(void); // (optional) call in osContReset
|
void (*rumble_stop)(void); // (optional) stop any ongoing haptic feedback
|
||||||
|
void (*reconfig)(void); // (optional) call when bindings have changed
|
||||||
|
void (*shutdown)(void); // (optional) call in osContReset
|
||||||
};
|
};
|
||||||
|
|
||||||
// used for binding keys
|
// used for binding keys
|
||||||
u32 controller_get_raw_key(void);
|
u32 controller_get_raw_key(void);
|
||||||
void controller_reconfigure(void);
|
void controller_reconfigure(void);
|
||||||
|
|
||||||
|
// rumbles all controllers with rumble support
|
||||||
|
void controller_rumble_play(float str, float time);
|
||||||
|
void controller_rumble_stop(void);
|
||||||
|
|
||||||
// calls the shutdown() function of all controller subsystems
|
// calls the shutdown() function of all controller subsystems
|
||||||
void controller_shutdown(void);
|
void controller_shutdown(void);
|
||||||
|
|
||||||
|
|
|
@ -31,15 +31,18 @@ s32 osContInit(OSMesgQueue *mq, u8 *controllerBits, OSContStatus *status) {
|
||||||
|
|
||||||
s32 osMotorStart(void *pfs) {
|
s32 osMotorStart(void *pfs) {
|
||||||
// Since rumble stops by osMotorStop, its duration is not nessecary.
|
// Since rumble stops by osMotorStop, its duration is not nessecary.
|
||||||
return controller_rumble_play(configRumbleStrength / 100.0, 50);
|
// Set it to 5 seconds and hope osMotorStop() is called in time.
|
||||||
|
controller_rumble_play(configRumbleStrength / 100.0f, 5.0f);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 osMotorStop(void *pfs) {
|
s32 osMotorStop(void *pfs) {
|
||||||
return controller_rumble_stop();
|
controller_rumble_stop();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 osMotorInit(OSMesgQueue *mq, void *pfs, s32 port) {
|
u32 osMotorInit(OSMesgQueue *mq, void *pfs, s32 port) {
|
||||||
return controller_rumble_init();
|
return 0; // rumble is initialized in the specific backend's init function
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 osContStartReadData(OSMesgQueue *mesg) {
|
s32 osContStartReadData(OSMesgQueue *mesg) {
|
||||||
|
@ -93,3 +96,17 @@ void controller_reconfigure(void) {
|
||||||
controller_implementations[i]->reconfig();
|
controller_implementations[i]->reconfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void controller_rumble_play(float str, float time) {
|
||||||
|
for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) {
|
||||||
|
if (controller_implementations[i]->rumble_play)
|
||||||
|
controller_implementations[i]->rumble_play(str, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void controller_rumble_stop(void) {
|
||||||
|
for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) {
|
||||||
|
if (controller_implementations[i]->rumble_stop)
|
||||||
|
controller_implementations[i]->rumble_stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ struct ControllerAPI controller_recorded_tas = {
|
||||||
tas_init,
|
tas_init,
|
||||||
tas_read,
|
tas_read,
|
||||||
tas_rawkey,
|
tas_rawkey,
|
||||||
|
NULL, // no rumble_play
|
||||||
|
NULL, // no rumble_stop
|
||||||
NULL, // no rebinding
|
NULL, // no rebinding
|
||||||
tas_shutdown
|
tas_shutdown
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,6 +113,24 @@ static void controller_sdl_init(void) {
|
||||||
init_ok = true;
|
init_ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDL_Haptic *controller_sdl_init_haptics(const int joy) {
|
||||||
|
SDL_Haptic *hap = SDL_HapticOpen(joy);
|
||||||
|
if (!hap) return NULL;
|
||||||
|
|
||||||
|
if (SDL_HapticRumbleSupported(hap) != SDL_TRUE) {
|
||||||
|
SDL_HapticClose(hap);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_HapticRumbleInit(hap) != 0) {
|
||||||
|
SDL_HapticClose(hap);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("controller %s has haptics support, rumble enabled\n", SDL_JoystickNameForIndex(joy));
|
||||||
|
return hap;
|
||||||
|
}
|
||||||
|
|
||||||
static void controller_sdl_read(OSContPad *pad) {
|
static void controller_sdl_read(OSContPad *pad) {
|
||||||
if (!init_ok) {
|
if (!init_ok) {
|
||||||
return;
|
return;
|
||||||
|
@ -138,15 +156,18 @@ static void controller_sdl_read(OSContPad *pad) {
|
||||||
SDL_GameControllerUpdate();
|
SDL_GameControllerUpdate();
|
||||||
|
|
||||||
if (sdl_cntrl != NULL && !SDL_GameControllerGetAttached(sdl_cntrl)) {
|
if (sdl_cntrl != NULL && !SDL_GameControllerGetAttached(sdl_cntrl)) {
|
||||||
|
SDL_HapticClose(sdl_haptic);
|
||||||
SDL_GameControllerClose(sdl_cntrl);
|
SDL_GameControllerClose(sdl_cntrl);
|
||||||
sdl_cntrl = NULL;
|
sdl_cntrl = NULL;
|
||||||
|
sdl_haptic = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdl_cntrl == NULL) {
|
if (sdl_cntrl == NULL) {
|
||||||
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
||||||
if (SDL_IsGameController(i)) {
|
if (SDL_IsGameController(i)) {
|
||||||
sdl_cntrl = SDL_GameControllerOpen(i);
|
sdl_cntrl = SDL_GameControllerOpen(i);
|
||||||
sdl_haptic = SDL_HapticOpen(i);
|
|
||||||
if (sdl_cntrl != NULL) {
|
if (sdl_cntrl != NULL) {
|
||||||
|
sdl_haptic = controller_sdl_init_haptics(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,6 +241,16 @@ static void controller_sdl_read(OSContPad *pad) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void controller_sdl_rumble_play(f32 strength, u32 length) {
|
||||||
|
if (sdl_haptic)
|
||||||
|
SDL_HapticRumblePlay(sdl_haptic, strength, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void controller_sdl_rumble_stop(void) {
|
||||||
|
if (sdl_haptic)
|
||||||
|
SDL_HapticRumbleStop(sdl_haptic);
|
||||||
|
}
|
||||||
|
|
||||||
static u32 controller_sdl_rawkey(void) {
|
static u32 controller_sdl_rawkey(void) {
|
||||||
if (last_joybutton != VK_INVALID) {
|
if (last_joybutton != VK_INVALID) {
|
||||||
const u32 ret = last_joybutton;
|
const u32 ret = last_joybutton;
|
||||||
|
@ -252,42 +283,13 @@ static void controller_sdl_shutdown(void) {
|
||||||
init_ok = false;
|
init_ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 controller_rumble_init(void) {
|
|
||||||
if (SDL_HapticRumbleSupported(sdl_haptic) != SDL_TRUE) {
|
|
||||||
// printf("Controller does not support haptics! %s\n", SDL_GetError());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (SDL_HapticRumbleInit(sdl_haptic) != 0) {
|
|
||||||
printf("Unable to initialize rumble! %s\n", SDL_GetError());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
s32 controller_rumble_play(f32 strength, u32 length) {
|
|
||||||
if (SDL_HapticRumblePlay(sdl_haptic, strength, length) != 0) {
|
|
||||||
printf("Unable to start rumble! %s\n", SDL_GetError());
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 controller_rumble_stop(void) {
|
|
||||||
if (SDL_HapticRumbleStop(sdl_haptic) != 0) {
|
|
||||||
printf("Unable to stop rumble! %s\n", SDL_GetError());
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ControllerAPI controller_sdl = {
|
struct ControllerAPI controller_sdl = {
|
||||||
VK_BASE_SDL_GAMEPAD,
|
VK_BASE_SDL_GAMEPAD,
|
||||||
controller_sdl_init,
|
controller_sdl_init,
|
||||||
controller_sdl_read,
|
controller_sdl_read,
|
||||||
controller_sdl_rawkey,
|
controller_sdl_rawkey,
|
||||||
|
controller_sdl_rumble_play,
|
||||||
|
controller_sdl_rumble_stop,
|
||||||
controller_sdl_bind,
|
controller_sdl_bind,
|
||||||
controller_sdl_shutdown
|
controller_sdl_shutdown
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,8 +7,4 @@
|
||||||
|
|
||||||
extern struct ControllerAPI controller_sdl;
|
extern struct ControllerAPI controller_sdl;
|
||||||
|
|
||||||
u32 controller_rumble_init(void);
|
|
||||||
s32 controller_rumble_play(f32 strength, u32 length);
|
|
||||||
s32 controller_rumble_stop(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue