mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-14 10:46:51 -07:00
Add switch rumble and motion feedbacks
This commit is contained in:
parent
9ab84e6054
commit
acf15480f2
7 changed files with 255 additions and 100 deletions
|
@ -69,12 +69,6 @@ class PSRemotePlay : public brls::View
|
|||
// to send gamepad inputs
|
||||
Host *host;
|
||||
brls::Label *label;
|
||||
ChiakiControllerState state = {0};
|
||||
// FPS calculation
|
||||
// double base_time;
|
||||
// int frame_counter = 0;
|
||||
// int fps = 0;
|
||||
|
||||
public:
|
||||
PSRemotePlay(Host *host);
|
||||
~PSRemotePlay();
|
||||
|
|
|
@ -54,7 +54,9 @@ class Host
|
|||
std::function<void()> chiaki_regist_event_type_finished_success = nullptr;
|
||||
std::function<void()> chiaki_event_connected_cb = nullptr;
|
||||
std::function<void(bool)> chiaki_even_login_pin_request_cb = nullptr;
|
||||
std::function<void(uint8_t, uint8_t)> chiaki_event_rumble_cb = nullptr;
|
||||
std::function<void(ChiakiQuitEvent *)> chiaki_event_quit_cb = nullptr;
|
||||
std::function<void(ChiakiControllerState *)> io_read_controller_cb = nullptr;
|
||||
|
||||
// internal state
|
||||
bool discovered = false;
|
||||
|
@ -73,6 +75,7 @@ class Host
|
|||
std::string server_nickname;
|
||||
ChiakiTarget target = CHIAKI_TARGET_PS4_UNKNOWN;
|
||||
ChiakiDiscoveryHostState state = CHIAKI_DISCOVERY_HOST_STATE_UNKNOWN;
|
||||
ChiakiControllerState controller_state = {0};
|
||||
|
||||
// mac address = 48 bits
|
||||
uint8_t server_mac[6] = {0};
|
||||
|
@ -96,7 +99,7 @@ class Host
|
|||
int FiniSession();
|
||||
void StopSession();
|
||||
void StartSession();
|
||||
void SendFeedbackState(ChiakiControllerState *);
|
||||
void SendFeedbackState();
|
||||
void RegistCB(ChiakiRegistEvent *);
|
||||
void ConnectionEventCB(ChiakiEvent *);
|
||||
bool GetVideoResolution(int *ret_width, int *ret_height);
|
||||
|
@ -110,7 +113,9 @@ class Host
|
|||
void SetRegistEventTypeFinishedSuccess(std::function<void()> chiaki_regist_event_type_finished_success);
|
||||
void SetEventConnectedCallback(std::function<void()> chiaki_event_connected_cb);
|
||||
void SetEventLoginPinRequestCallback(std::function<void(bool)> chiaki_even_login_pin_request_cb);
|
||||
void SetEventRumbleCallback(std::function<void(uint8_t, uint8_t)> chiaki_event_rumble_cb);
|
||||
void SetEventQuitCallback(std::function<void(ChiakiQuitEvent *)> chiaki_event_quit_cb);
|
||||
void SetReadControllerCallback(std::function<void(ChiakiControllerState *)> io_read_controller_cb);
|
||||
bool IsRegistered();
|
||||
bool IsDiscovered();
|
||||
bool IsReady();
|
||||
|
|
|
@ -28,6 +28,12 @@ Omit khrplatform: False
|
|||
Reproducible: False
|
||||
*/
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#else
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include <mutex>
|
||||
extern "C"
|
||||
{
|
||||
|
@ -65,6 +71,11 @@ class IO
|
|||
SDL_AudioDeviceID sdl_audio_device_id = 0;
|
||||
SDL_Event sdl_event;
|
||||
SDL_Joystick *sdl_joystick_ptr[SDL_JOYSTICK_COUNT] = {0};
|
||||
#ifdef __SWITCH__
|
||||
PadState pad;
|
||||
HidSixAxisSensorHandle sixaxis_handles[4];
|
||||
HidVibrationDeviceHandle vibration_handles[2][2];
|
||||
#endif
|
||||
GLuint vao;
|
||||
GLuint vbo;
|
||||
GLuint tex[PLANES_COUNT];
|
||||
|
@ -86,7 +97,7 @@ class IO
|
|||
void SetOpenGlYUVPixels(AVFrame *frame);
|
||||
bool ReadGameKeys(SDL_Event *event, ChiakiControllerState *state);
|
||||
bool ReadGameTouchScreen(ChiakiControllerState *state);
|
||||
|
||||
bool ReadGameSixAxis(ChiakiControllerState *state);
|
||||
public:
|
||||
// singleton configuration
|
||||
IO(const IO&) = delete;
|
||||
|
@ -100,9 +111,11 @@ class IO
|
|||
void AudioCB(int16_t *buf, size_t samples_count);
|
||||
bool InitVideo(int video_width, int video_height, int screen_width, int screen_height);
|
||||
bool FreeVideo();
|
||||
bool InitJoystick();
|
||||
bool FreeJoystick();
|
||||
bool MainLoop(ChiakiControllerState *state);
|
||||
bool InitController();
|
||||
bool FreeController();
|
||||
bool MainLoop();
|
||||
void UpdateControllerState(ChiakiControllerState *state);
|
||||
void SetRumble(uint8_t left, uint8_t right);
|
||||
};
|
||||
|
||||
#endif //CHIAKI_IO_H
|
||||
|
|
|
@ -42,6 +42,9 @@ HostInterface::HostInterface(Host *host)
|
|||
// when the host is connected
|
||||
this->host->SetEventConnectedCallback(std::bind(&HostInterface::Stream, this));
|
||||
this->host->SetEventQuitCallback(std::bind(&HostInterface::CloseStream, this, std::placeholders::_1));
|
||||
// allow host to update controller state
|
||||
this->host->SetEventRumbleCallback(std::bind(&IO::SetRumble, this->io, std::placeholders::_1, std::placeholders::_2));
|
||||
this->host->SetReadControllerCallback(std::bind(&IO::UpdateControllerState, this->io, std::placeholders::_1));
|
||||
}
|
||||
|
||||
HostInterface::~HostInterface()
|
||||
|
@ -245,7 +248,7 @@ MainApplication::MainApplication(DiscoveryManager *discoverymanager)
|
|||
MainApplication::~MainApplication()
|
||||
{
|
||||
this->discoverymanager->SetService(false);
|
||||
//this->io->FreeJoystick();
|
||||
this->io->FreeController();
|
||||
this->io->FreeVideo();
|
||||
}
|
||||
|
||||
|
@ -264,16 +267,15 @@ bool MainApplication::Load()
|
|||
|
||||
// init chiaki gl after borealis
|
||||
// let borealis manage the main screen/window
|
||||
|
||||
if(!io->InitVideo(0, 0, SCREEN_W, SCREEN_H))
|
||||
{
|
||||
brls::Logger::error("Failed to initiate Video");
|
||||
}
|
||||
|
||||
brls::Logger::info("Load sdl joysticks");
|
||||
if(!io->InitJoystick())
|
||||
brls::Logger::info("Load sdl/hid controller");
|
||||
if(!io->InitController())
|
||||
{
|
||||
brls::Logger::error("Faled to initiate Joysticks");
|
||||
brls::Logger::error("Faled to initiate Controller");
|
||||
}
|
||||
|
||||
// Create a view
|
||||
|
@ -541,38 +543,12 @@ PSRemotePlay::PSRemotePlay(Host *host)
|
|||
: host(host)
|
||||
{
|
||||
this->io = IO::GetInstance();
|
||||
|
||||
// store joycon/touchpad keys
|
||||
for(int x = 0; x < CHIAKI_CONTROLLER_TOUCHES_MAX; x++)
|
||||
// start touchpad as "untouched"
|
||||
this->state.touches[x].id = -1;
|
||||
|
||||
// this->base_time=glfwGetTime();
|
||||
}
|
||||
|
||||
void PSRemotePlay::draw(NVGcontext *vg, int x, int y, unsigned width, unsigned height, brls::Style *style, brls::FrameContext *ctx)
|
||||
{
|
||||
this->io->MainLoop(&this->state);
|
||||
this->host->SendFeedbackState(&this->state);
|
||||
|
||||
// FPS calculation
|
||||
// this->frame_counter += 1;
|
||||
// double frame_time = glfwGetTime();
|
||||
// if((frame_time - base_time) >= 1.0)
|
||||
// {
|
||||
// base_time += 1;
|
||||
// //printf("FPS: %d\n", this->frame_counter);
|
||||
// this->fps = this->frame_counter;
|
||||
// this->frame_counter = 0;
|
||||
// }
|
||||
// nvgBeginPath(vg);
|
||||
// nvgFillColor(vg, nvgRGBA(255,192,0,255));
|
||||
// nvgFontFaceId(vg, ctx->fontStash->regular);
|
||||
// nvgFontSize(vg, style->Label.smallFontSize);
|
||||
// nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
|
||||
// char fps_str[9] = {0};
|
||||
// sprintf(fps_str, "FPS: %000d", this->fps);
|
||||
// nvgText(vg, 5,10, fps_str, NULL);
|
||||
this->io->MainLoop();
|
||||
this->host->SendFeedbackState();
|
||||
}
|
||||
|
||||
PSRemotePlay::~PSRemotePlay()
|
||||
|
|
|
@ -156,9 +156,17 @@ int Host::InitSession(IO *user)
|
|||
// audio setting_cb and frame_cb
|
||||
chiaki_opus_decoder_set_cb(&this->opus_decoder, InitAudioCB, AudioCB, user);
|
||||
chiaki_opus_decoder_get_sink(&this->opus_decoder, &audio_sink);
|
||||
chiaki_session_set_audio_sink(&(this->session), &audio_sink);
|
||||
chiaki_session_set_video_sample_cb(&(this->session), VideoCB, user);
|
||||
chiaki_session_set_event_cb(&(this->session), EventCB, this);
|
||||
chiaki_session_set_audio_sink(&this->session, &audio_sink);
|
||||
chiaki_session_set_video_sample_cb(&this->session, VideoCB, user);
|
||||
chiaki_session_set_event_cb(&this->session, EventCB, this);
|
||||
|
||||
// init controller states
|
||||
chiaki_controller_state_set_idle(&this->controller_state);
|
||||
|
||||
for(int x = 0; x < CHIAKI_CONTROLLER_TOUCHES_MAX; x++)
|
||||
// start touchpad as "untouched"
|
||||
this->controller_state.touches[x].id = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -189,10 +197,13 @@ void Host::StartSession()
|
|||
}
|
||||
}
|
||||
|
||||
void Host::SendFeedbackState(ChiakiControllerState *state)
|
||||
void Host::SendFeedbackState()
|
||||
{
|
||||
// send controller/joystick key
|
||||
chiaki_session_set_controller_state(&this->session, state);
|
||||
if(this->io_read_controller_cb != nullptr)
|
||||
this->io_read_controller_cb(&this->controller_state);
|
||||
|
||||
chiaki_session_set_controller_state(&this->session, &this->controller_state);
|
||||
}
|
||||
|
||||
void Host::ConnectionEventCB(ChiakiEvent *event)
|
||||
|
@ -209,6 +220,11 @@ void Host::ConnectionEventCB(ChiakiEvent *event)
|
|||
if(this->chiaki_even_login_pin_request_cb != nullptr)
|
||||
this->chiaki_even_login_pin_request_cb(event->login_pin_request.pin_incorrect);
|
||||
break;
|
||||
case CHIAKI_EVENT_RUMBLE:
|
||||
CHIAKI_LOGD(this->log, "EventCB CHIAKI_EVENT_RUMBLE");
|
||||
if(this->chiaki_event_rumble_cb != nullptr)
|
||||
this->chiaki_event_rumble_cb(event->rumble.left, event->rumble.right);
|
||||
break;
|
||||
case CHIAKI_EVENT_QUIT:
|
||||
CHIAKI_LOGI(this->log, "EventCB CHIAKI_EVENT_QUIT");
|
||||
if(this->chiaki_event_quit_cb != nullptr)
|
||||
|
@ -352,6 +368,16 @@ void Host::SetEventQuitCallback(std::function<void(ChiakiQuitEvent *)> chiaki_ev
|
|||
this->chiaki_event_quit_cb = chiaki_event_quit_cb;
|
||||
}
|
||||
|
||||
void Host::SetEventRumbleCallback(std::function<void(uint8_t, uint8_t)> chiaki_event_rumble_cb)
|
||||
{
|
||||
this->chiaki_event_rumble_cb = chiaki_event_rumble_cb;
|
||||
}
|
||||
|
||||
void Host::SetReadControllerCallback(std::function<void(ChiakiControllerState *)> io_read_controller_cb)
|
||||
{
|
||||
this->io_read_controller_cb = io_read_controller_cb;
|
||||
}
|
||||
|
||||
bool Host::IsRegistered()
|
||||
{
|
||||
return this->registered;
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
// SPDX-License-Identifier: LicenseRef-AGPL-3.0-only-OpenSSL
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#else
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include "io.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
@ -345,22 +339,23 @@ bool IO::FreeVideo()
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool IO::ReadGameTouchScreen(ChiakiControllerState *state)
|
||||
bool IO::ReadGameTouchScreen(ChiakiControllerState *chiaki_state)
|
||||
{
|
||||
#ifdef __SWITCH__
|
||||
hidScanInput();
|
||||
int touch_count = hidTouchCount();
|
||||
HidTouchScreenState sw_state = {0};
|
||||
|
||||
bool ret = false;
|
||||
if(!touch_count)
|
||||
if(!hidGetTouchScreenStates(&sw_state, 1) || sw_state.count == 0)
|
||||
{
|
||||
// flush state
|
||||
chiaki_state->buttons &= ~CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen release
|
||||
for(int i = 0; i < CHIAKI_CONTROLLER_TOUCHES_MAX; i++)
|
||||
{
|
||||
if(state->touches[i].id != -1)
|
||||
if(chiaki_state->touches[i].id != -1)
|
||||
{
|
||||
state->touches[i].x = 0;
|
||||
state->touches[i].y = 0;
|
||||
state->touches[i].id = -1;
|
||||
state->buttons &= ~CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen release
|
||||
chiaki_state->touches[i].x = 0;
|
||||
chiaki_state->touches[i].y = 0;
|
||||
chiaki_state->touches[i].id = -1;
|
||||
// the state changed
|
||||
ret = true;
|
||||
}
|
||||
|
@ -368,32 +363,25 @@ bool IO::ReadGameTouchScreen(ChiakiControllerState *state)
|
|||
return ret;
|
||||
}
|
||||
|
||||
touchPosition touch;
|
||||
for(int i = 0; i < touch_count && i < CHIAKI_CONTROLLER_TOUCHES_MAX; i++)
|
||||
// scale switch screen to the PS trackpad
|
||||
for(int i = 0; i < sw_state.count && i < CHIAKI_CONTROLLER_TOUCHES_MAX; i++)
|
||||
{
|
||||
hidTouchRead(&touch, i);
|
||||
|
||||
// 1280×720 px (16:9)
|
||||
// ps4 controller aspect ratio looks closer to 29:10
|
||||
uint16_t x = touch.px * (DS4_TRACKPAD_MAX_X / SWITCH_TOUCHSCREEN_MAX_X);
|
||||
uint16_t y = touch.py * (DS4_TRACKPAD_MAX_Y / SWITCH_TOUCHSCREEN_MAX_Y);
|
||||
uint16_t x = sw_state.touches[i].x * (DS4_TRACKPAD_MAX_X / SWITCH_TOUCHSCREEN_MAX_X);
|
||||
uint16_t y = sw_state.touches[i].y * (DS4_TRACKPAD_MAX_Y / SWITCH_TOUCHSCREEN_MAX_Y);
|
||||
|
||||
// use nintendo switch border's 5% to
|
||||
if(x <= (SWITCH_TOUCHSCREEN_MAX_X * 0.05) || x >= (SWITCH_TOUCHSCREEN_MAX_X * 0.95) || y <= (SWITCH_TOUCHSCREEN_MAX_Y * 0.05) || y >= (SWITCH_TOUCHSCREEN_MAX_Y * 0.95))
|
||||
{
|
||||
state->buttons |= CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen
|
||||
// printf("CHIAKI_CONTROLLER_BUTTON_TOUCHPAD\n");
|
||||
}
|
||||
chiaki_state->buttons |= CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen
|
||||
else
|
||||
{
|
||||
state->buttons &= ~CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen release
|
||||
}
|
||||
chiaki_state->buttons &= ~CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen release
|
||||
|
||||
state->touches[i].x = x;
|
||||
state->touches[i].y = y;
|
||||
state->touches[i].id = i;
|
||||
// printf("[point_id=%d] px=%03d, py=%03d, dx=%03d, dy=%03d, angle=%03d\n",
|
||||
// i, touch.px, touch.py, touch.dx, touch.dy, touch.angle);
|
||||
chiaki_state->touches[i].x = x;
|
||||
chiaki_state->touches[i].y = y;
|
||||
chiaki_state->touches[i].id = i;
|
||||
// printf("[point_id=%d] x=%03d, y=%03d\n", i, x, y);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
|
@ -402,14 +390,127 @@ bool IO::ReadGameTouchScreen(ChiakiControllerState *state)
|
|||
#endif
|
||||
}
|
||||
|
||||
void IO::SetRumble(uint8_t left, uint8_t right)
|
||||
{
|
||||
#ifdef __SWITCH__
|
||||
Result rc = 0;
|
||||
HidVibrationValue vibration_values[] = {
|
||||
{
|
||||
.amp_low = 0.0f,
|
||||
.freq_low = 160.0f,
|
||||
.amp_high = 0.0f,
|
||||
.freq_high = 320.0f,
|
||||
},
|
||||
{
|
||||
.amp_low = 0.0f,
|
||||
.freq_low = 160.0f,
|
||||
.amp_high = 0.0f,
|
||||
.freq_high = 320.0f,
|
||||
}};
|
||||
|
||||
int target_device = padIsHandheld(&pad) ? 0 : 1;
|
||||
if(left > 0)
|
||||
{
|
||||
// SDL_HapticRumblePlay(this->sdl_haptic_ptr[0], left / 100, 5000);
|
||||
vibration_values[0].amp_low = (float)left / (float)100;
|
||||
vibration_values[0].amp_high = (float)left / (float)100;
|
||||
vibration_values[0].freq_low *= (float)left / (float)100;
|
||||
vibration_values[0].freq_high *= (float)left / (float)100;
|
||||
}
|
||||
|
||||
if(right > 0)
|
||||
{
|
||||
// SDL_HapticRumblePlay(this->sdl_haptic_ptr[1], right / 100, 5000);
|
||||
vibration_values[1].amp_low = (float)right / (float)100;
|
||||
vibration_values[1].amp_high = (float)right / (float)100;
|
||||
vibration_values[1].freq_low *= (float)left / (float)100;
|
||||
vibration_values[1].freq_high *= (float)left / (float)100;
|
||||
}
|
||||
|
||||
// printf("left ptr %p amp_low %f amp_high %f freq_low %f freq_high %f\n",
|
||||
// &vibration_values[0],
|
||||
// vibration_values[0].amp_low,
|
||||
// vibration_values[0].amp_high,
|
||||
// vibration_values[0].freq_low,
|
||||
// vibration_values[0].freq_high);
|
||||
|
||||
// printf("right ptr %p amp_low %f amp_high %f freq_low %f freq_high %f\n",
|
||||
// &vibration_values[1],
|
||||
// vibration_values[1].amp_low,
|
||||
// vibration_values[1].amp_high,
|
||||
// vibration_values[1].freq_low,
|
||||
// vibration_values[1].freq_high);
|
||||
|
||||
rc = hidSendVibrationValues(this->vibration_handles[target_device], vibration_values, 2);
|
||||
if(R_FAILED(rc))
|
||||
CHIAKI_LOGE(this->log, "hidSendVibrationValues() returned: 0x%x", rc);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IO::ReadGameSixAxis(ChiakiControllerState *state)
|
||||
{
|
||||
#ifdef __SWITCH__
|
||||
// Read from the correct sixaxis handle depending on the current input style
|
||||
HidSixAxisSensorState sixaxis = {0};
|
||||
uint64_t style_set = padGetStyleSet(&pad);
|
||||
if(style_set & HidNpadStyleTag_NpadHandheld)
|
||||
hidGetSixAxisSensorStates(this->sixaxis_handles[0], &sixaxis, 1);
|
||||
else if(style_set & HidNpadStyleTag_NpadFullKey)
|
||||
hidGetSixAxisSensorStates(this->sixaxis_handles[1], &sixaxis, 1);
|
||||
else if(style_set & HidNpadStyleTag_NpadJoyDual)
|
||||
{
|
||||
// For JoyDual, read from either the Left or Right Joy-Con depending on which is/are connected
|
||||
u64 attrib = padGetAttributes(&pad);
|
||||
if(attrib & HidNpadAttribute_IsLeftConnected)
|
||||
hidGetSixAxisSensorStates(this->sixaxis_handles[2], &sixaxis, 1);
|
||||
else if(attrib & HidNpadAttribute_IsRightConnected)
|
||||
hidGetSixAxisSensorStates(this->sixaxis_handles[3], &sixaxis, 1);
|
||||
}
|
||||
|
||||
// printf("Acceleration: x=% .4f, y=% .4f, z=% .4f\n", sixaxis.acceleration.x, sixaxis.acceleration.y, sixaxis.acceleration.z);
|
||||
// printf("Angular velocity: x=% .4f, y=% .4f, z=% .4f\n", sixaxis.angular_velocity.x, sixaxis.angular_velocity.y, sixaxis.angular_velocity.z);
|
||||
// printf("Angle: x=% .4f, y=% .4f, z=% .4f\n", sixaxis.angle.x, sixaxis.angle.y, sixaxis.angle.z);
|
||||
// printf("Direction matrix:\n"
|
||||
// " [ % .4f, % .4f, % .4f ]\n"
|
||||
// " [ % .4f, % .4f, % .4f ]\n"
|
||||
// " [ % .4f, % .4f, % .4f ]\n",
|
||||
// sixaxis.direction.direction[0][0], sixaxis.direction.direction[1][0], sixaxis.direction.direction[2][0],
|
||||
// sixaxis.direction.direction[0][1], sixaxis.direction.direction[1][1], sixaxis.direction.direction[2][1],
|
||||
// sixaxis.direction.direction[0][2], sixaxis.direction.direction[1][2], sixaxis.direction.direction[2][2]);
|
||||
|
||||
state->gyro_x = sixaxis.angular_velocity.x;
|
||||
state->gyro_y = sixaxis.angular_velocity.y;
|
||||
state->gyro_z = sixaxis.angular_velocity.z;
|
||||
state->accel_x = sixaxis.acceleration.x;
|
||||
state->accel_y = sixaxis.acceleration.y;
|
||||
state->accel_z = sixaxis.acceleration.z;
|
||||
|
||||
// thank you @thestr4ng3r for the hint
|
||||
// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Euler_angles_to_quaternion_conversion
|
||||
double cy = cos(sixaxis.angle.z * 0.5);
|
||||
double sy = sin(sixaxis.angle.z * 0.5);
|
||||
double cp = cos(sixaxis.angle.y * 0.5);
|
||||
double sp = sin(sixaxis.angle.y * 0.5);
|
||||
double cr = cos(sixaxis.angle.x * 0.5);
|
||||
double sr = sin(sixaxis.angle.x * 0.5);
|
||||
|
||||
state->orient_x = sr * cp * cy - cr * sp * sy;
|
||||
state->orient_y = cr * sp * cy + sr * cp * sy;
|
||||
state->orient_z = cr * cp * sy - sr * sp * cy;
|
||||
state->orient_w = cr * cp * cy + sr * sp * sy;
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IO::ReadGameKeys(SDL_Event *event, ChiakiControllerState *state)
|
||||
{
|
||||
// return true if an event changed (gamepad input)
|
||||
|
||||
// TODO
|
||||
// share vs PS button
|
||||
// Gyro ?
|
||||
// rumble ?
|
||||
bool ret = true;
|
||||
switch(event->type)
|
||||
{
|
||||
|
@ -620,7 +721,7 @@ bool IO::InitOpenGlTextures()
|
|||
|
||||
D(glGenTextures(PLANES_COUNT, this->tex));
|
||||
D(glGenBuffers(PLANES_COUNT, this->pbo));
|
||||
uint8_t uv_default[] = { 0x7f, 0x7f };
|
||||
uint8_t uv_default[] = {0x7f, 0x7f};
|
||||
for(int i = 0; i < PLANES_COUNT; i++)
|
||||
{
|
||||
D(glBindTexture(GL_TEXTURE_2D, this->tex[i]));
|
||||
|
@ -633,7 +734,7 @@ bool IO::InitOpenGlTextures()
|
|||
|
||||
D(glUseProgram(this->prog));
|
||||
// bind only as many planes as we need
|
||||
const char *plane_names[] = { "plane1", "plane2", "plane3" };
|
||||
const char *plane_names[] = {"plane1", "plane2", "plane3"};
|
||||
for(int i = 0; i < PLANES_COUNT; i++)
|
||||
D(glUniform1i(glGetUniformLocation(this->prog, plane_names[i]), i));
|
||||
|
||||
|
@ -786,7 +887,7 @@ inline void IO::OpenGlDraw()
|
|||
D(glFinish());
|
||||
}
|
||||
|
||||
bool IO::InitJoystick()
|
||||
bool IO::InitController()
|
||||
{
|
||||
// https://github.com/switchbrew/switch-examples/blob/master/graphics/sdl2/sdl2-simple/source/main.cpp#L57
|
||||
// open CONTROLLER_PLAYER_1 and CONTROLLER_PLAYER_2
|
||||
|
@ -800,24 +901,64 @@ bool IO::InitJoystick()
|
|||
CHIAKI_LOGE(this->log, "SDL_JoystickOpen: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
// this->sdl_haptic_ptr[i] = SDL_HapticOpenFromJoystick(sdl_joystick_ptr[i]);
|
||||
// SDL_HapticRumbleInit(this->sdl_haptic_ptr[i]);
|
||||
// if(sdl_haptic_ptr[i] == nullptr)
|
||||
// {
|
||||
// CHIAKI_LOGE(this->log, "SDL_HapticRumbleInit: %s\n", SDL_GetError());
|
||||
// }
|
||||
}
|
||||
#ifdef __SWITCH__
|
||||
Result rc = 0;
|
||||
// Configure our supported input layout: a single player with standard controller styles
|
||||
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
|
||||
// Initialize the default gamepad (which reads handheld mode inputs as well as the first connected controller)
|
||||
padInitializeDefault(&this->pad);
|
||||
// touchpad
|
||||
hidInitializeTouchScreen();
|
||||
// It's necessary to initialize these separately as they all have different handle values
|
||||
hidGetSixAxisSensorHandles(&this->sixaxis_handles[0], 1, HidNpadIdType_Handheld, HidNpadStyleTag_NpadHandheld);
|
||||
hidGetSixAxisSensorHandles(&this->sixaxis_handles[1], 1, HidNpadIdType_No1, HidNpadStyleTag_NpadFullKey);
|
||||
hidGetSixAxisSensorHandles(&this->sixaxis_handles[2], 2, HidNpadIdType_No1, HidNpadStyleTag_NpadJoyDual);
|
||||
hidStartSixAxisSensor(this->sixaxis_handles[0]);
|
||||
hidStartSixAxisSensor(this->sixaxis_handles[1]);
|
||||
hidStartSixAxisSensor(this->sixaxis_handles[2]);
|
||||
hidStartSixAxisSensor(this->sixaxis_handles[3]);
|
||||
|
||||
rc = hidInitializeVibrationDevices(this->vibration_handles[0], 2, HidNpadIdType_Handheld, HidNpadStyleTag_NpadHandheld);
|
||||
if(R_FAILED(rc))
|
||||
CHIAKI_LOGE(this->log, "hidInitializeVibrationDevices() HidNpadIdType_Handheld returned: 0x%x", rc);
|
||||
|
||||
rc = hidInitializeVibrationDevices(this->vibration_handles[1], 2, HidNpadIdType_No1, HidNpadStyleTag_NpadJoyDual);
|
||||
if(R_FAILED(rc))
|
||||
CHIAKI_LOGE(this->log, "hidInitializeVibrationDevices() HidNpadIdType_No1 returned: 0x%x", rc);
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IO::FreeJoystick()
|
||||
bool IO::FreeController()
|
||||
{
|
||||
for(int i = 0; i < SDL_JOYSTICK_COUNT; i++)
|
||||
{
|
||||
if(SDL_JoystickGetAttached(sdl_joystick_ptr[i]))
|
||||
SDL_JoystickClose(sdl_joystick_ptr[i]);
|
||||
SDL_JoystickClose(this->sdl_joystick_ptr[i]);
|
||||
// SDL_HapticClose(this->sdl_haptic_ptr[i]);
|
||||
}
|
||||
#ifdef __SWITCH__
|
||||
hidStopSixAxisSensor(this->sixaxis_handles[0]);
|
||||
hidStopSixAxisSensor(this->sixaxis_handles[1]);
|
||||
hidStopSixAxisSensor(this->sixaxis_handles[2]);
|
||||
hidStopSixAxisSensor(this->sixaxis_handles[3]);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IO::MainLoop(ChiakiControllerState *state)
|
||||
void IO::UpdateControllerState(ChiakiControllerState *state)
|
||||
{
|
||||
D(glUseProgram(this->prog));
|
||||
|
||||
#ifdef __SWITCH__
|
||||
padUpdate(&this->pad);
|
||||
#endif
|
||||
// handle SDL events
|
||||
while(SDL_PollEvent(&this->sdl_event))
|
||||
{
|
||||
|
@ -825,11 +966,17 @@ bool IO::MainLoop(ChiakiControllerState *state)
|
|||
switch(this->sdl_event.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
return false;
|
||||
this->quit = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReadGameTouchScreen(state);
|
||||
ReadGameSixAxis(state);
|
||||
}
|
||||
|
||||
bool IO::MainLoop()
|
||||
{
|
||||
D(glUseProgram(this->prog));
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
|
|
@ -83,12 +83,6 @@ extern "C" void userAppInit()
|
|||
// load socket custom config
|
||||
socketInitialize(&g_chiakiSocketInitConfig);
|
||||
setsysInitialize();
|
||||
|
||||
// padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
// PadState pad;
|
||||
// padInitializeDefault(&pad);
|
||||
|
||||
//hidInitializeTouchScreen();
|
||||
}
|
||||
|
||||
extern "C" void userAppExit()
|
||||
|
@ -126,7 +120,7 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
CHIAKI_LOGI(log, "Loading SDL audio / joystick");
|
||||
CHIAKI_LOGI(log, "Loading SDL audio / joystick / haptic");
|
||||
if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK))
|
||||
{
|
||||
CHIAKI_LOGE(log, "SDL initialization failed: %s", SDL_GetError());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue