Atlas - SDL_sysjoystick.c

Home / ext / SDL / src / joystick / n3ds Lines: 1 | Size: 8796 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23#ifdef SDL_JOYSTICK_N3DS 24 25// This is the N3DS implementation of the SDL joystick API 26 27#include <3ds.h> 28 29#include "../SDL_sysjoystick.h" 30 31#define NB_BUTTONS 23 32 33/* 34 N3DS sticks values are roughly within +/-160 35 which is too small to pass the jitter tolerance. 36 This correction is applied to axis values 37 so they fit better in SDL's value range. 38*/ 39static inline int Correct_Axis_X(int X) { 40 if (X > 160) { 41 return SDL_JOYSTICK_AXIS_MAX; 42 } 43 else if (X < -160) { 44 return -SDL_JOYSTICK_AXIS_MAX; 45 } 46 return (X * SDL_JOYSTICK_AXIS_MAX) / 160; 47} 48 49/* 50 The Y axis needs to be flipped because SDL's "up" 51 is reversed compared to libctru's "up" 52*/ 53static inline int Correct_Axis_Y(int Y) { 54 return Correct_Axis_X(-Y); 55} 56 57static void UpdateN3DSPressedButtons(Uint64 timestamp, SDL_Joystick *joystick); 58static void UpdateN3DSReleasedButtons(Uint64 timestamp, SDL_Joystick *joystick); 59static void UpdateN3DSCircle(Uint64 timestamp, SDL_Joystick *joystick); 60static void UpdateN3DSCStick(Uint64 timestamp, SDL_Joystick *joystick); 61 62static bool N3DS_JoystickInit(void) 63{ 64 hidInit(); 65 SDL_PrivateJoystickAdded(1); 66 return true; 67} 68 69static const char *N3DS_JoystickGetDeviceName(int device_index) 70{ 71 return "Nintendo 3DS"; 72} 73 74static int N3DS_JoystickGetCount(void) 75{ 76 return 1; 77} 78 79static SDL_GUID N3DS_JoystickGetDeviceGUID(int device_index) 80{ 81 SDL_GUID guid = SDL_CreateJoystickGUIDForName("Nintendo 3DS"); 82 return guid; 83} 84 85static SDL_JoystickID N3DS_JoystickGetDeviceInstanceID(int device_index) 86{ 87 return device_index + 1; 88} 89 90static bool N3DS_JoystickOpen(SDL_Joystick *joystick, int device_index) 91{ 92 joystick->nbuttons = NB_BUTTONS; 93 joystick->naxes = 4; 94 joystick->nhats = 0; 95 96 return true; 97} 98 99static bool N3DS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled) 100{ 101 return SDL_Unsupported(); 102} 103 104static void N3DS_JoystickUpdate(SDL_Joystick *joystick) 105{ 106 Uint64 timestamp = SDL_GetTicksNS(); 107 108 UpdateN3DSPressedButtons(timestamp, joystick); 109 UpdateN3DSReleasedButtons(timestamp, joystick); 110 UpdateN3DSCircle(timestamp, joystick); 111 UpdateN3DSCStick(timestamp, joystick); 112} 113 114static void UpdateN3DSPressedButtons(Uint64 timestamp, SDL_Joystick *joystick) 115{ 116 static u32 previous_state = 0; 117 u32 updated_down; 118 u32 current_state = hidKeysDown(); 119 updated_down = previous_state ^ current_state; 120 if (updated_down) { 121 for (Uint8 i = 0; i < joystick->nbuttons; i++) { 122 if (current_state & BIT(i) & updated_down) { 123 SDL_SendJoystickButton(timestamp, joystick, i, true); 124 } 125 } 126 } 127 previous_state = current_state; 128} 129 130static void UpdateN3DSReleasedButtons(Uint64 timestamp, SDL_Joystick *joystick) 131{ 132 static u32 previous_state = 0; 133 u32 updated_up; 134 u32 current_state = hidKeysUp(); 135 updated_up = previous_state ^ current_state; 136 if (updated_up) { 137 for (Uint8 i = 0; i < joystick->nbuttons; i++) { 138 if (current_state & BIT(i) & updated_up) { 139 SDL_SendJoystickButton(timestamp, joystick, i, false); 140 } 141 } 142 } 143 previous_state = current_state; 144} 145 146static void UpdateN3DSCircle(Uint64 timestamp, SDL_Joystick *joystick) 147{ 148 static circlePosition previous_state = { 0, 0 }; 149 circlePosition current_state; 150 hidCircleRead(&current_state); 151 if (previous_state.dx != current_state.dx) { 152 SDL_SendJoystickAxis(timestamp, joystick, 153 0, 154 Correct_Axis_X(current_state.dx)); 155 } 156 if (previous_state.dy != current_state.dy) { 157 SDL_SendJoystickAxis(timestamp, joystick, 158 1, 159 Correct_Axis_Y(current_state.dy)); 160 } 161 previous_state = current_state; 162} 163 164static void UpdateN3DSCStick(Uint64 timestamp, SDL_Joystick *joystick) 165{ 166 static circlePosition previous_state = { 0, 0 }; 167 circlePosition current_state; 168 hidCstickRead(&current_state); 169 if (previous_state.dx != current_state.dx) { 170 SDL_SendJoystickAxis(timestamp, joystick, 171 2, 172 Correct_Axis_X(current_state.dx)); 173 } 174 if (previous_state.dy != current_state.dy) { 175 SDL_SendJoystickAxis(timestamp, joystick, 176 3, 177 Correct_Axis_Y(current_state.dy)); 178 } 179 previous_state = current_state; 180} 181 182static void N3DS_JoystickClose(SDL_Joystick *joystick) 183{ 184} 185 186static void N3DS_JoystickQuit(void) 187{ 188 hidExit(); 189} 190 191static bool N3DS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) 192{ 193 // There is only one possible mapping. 194 *out = (SDL_GamepadMapping){ 195 .a = { EMappingKind_Button, 0 }, 196 .b = { EMappingKind_Button, 1 }, 197 .x = { EMappingKind_Button, 10 }, 198 .y = { EMappingKind_Button, 11 }, 199 .back = { EMappingKind_Button, 2 }, 200 .guide = { EMappingKind_None, 255 }, 201 .start = { EMappingKind_Button, 3 }, 202 .leftstick = { EMappingKind_None, 255 }, 203 .rightstick = { EMappingKind_None, 255 }, 204 .leftshoulder = { EMappingKind_Button, 9 }, 205 .rightshoulder = { EMappingKind_Button, 8 }, 206 .dpup = { EMappingKind_Button, 6 }, 207 .dpdown = { EMappingKind_Button, 7 }, 208 .dpleft = { EMappingKind_Button, 5 }, 209 .dpright = { EMappingKind_Button, 4 }, 210 .misc1 = { EMappingKind_None, 255 }, 211 .right_paddle1 = { EMappingKind_None, 255 }, 212 .left_paddle1 = { EMappingKind_None, 255 }, 213 .right_paddle2 = { EMappingKind_None, 255 }, 214 .left_paddle2 = { EMappingKind_None, 255 }, 215 .leftx = { EMappingKind_Axis, 0 }, 216 .lefty = { EMappingKind_Axis, 1 }, 217 .rightx = { EMappingKind_Axis, 2 }, 218 .righty = { EMappingKind_Axis, 3 }, 219 .lefttrigger = { EMappingKind_Button, 14 }, 220 .righttrigger = { EMappingKind_Button, 15 }, 221 }; 222 return true; 223} 224 225static void N3DS_JoystickDetect(void) 226{ 227} 228 229static bool N3DS_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) 230{ 231 // We don't override any other drivers 232 return false; 233} 234 235static const char *N3DS_JoystickGetDevicePath(int device_index) 236{ 237 return NULL; 238} 239 240static int N3DS_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) 241{ 242 return -1; 243} 244 245static int N3DS_JoystickGetDevicePlayerIndex(int device_index) 246{ 247 return -1; 248} 249 250static void N3DS_JoystickSetDevicePlayerIndex(int device_index, int player_index) 251{ 252} 253 254static bool N3DS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) 255{ 256 return SDL_Unsupported(); 257} 258 259static bool N3DS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) 260{ 261 return SDL_Unsupported(); 262} 263 264static bool N3DS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) 265{ 266 return SDL_Unsupported(); 267} 268 269static bool N3DS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) 270{ 271 return SDL_Unsupported(); 272} 273 274SDL_JoystickDriver SDL_N3DS_JoystickDriver = { 275 N3DS_JoystickInit, 276 N3DS_JoystickGetCount, 277 N3DS_JoystickDetect, 278 N3DS_JoystickIsDevicePresent, 279 N3DS_JoystickGetDeviceName, 280 N3DS_JoystickGetDevicePath, 281 N3DS_JoystickGetDeviceSteamVirtualGamepadSlot, 282 N3DS_JoystickGetDevicePlayerIndex, 283 N3DS_JoystickSetDevicePlayerIndex, 284 N3DS_JoystickGetDeviceGUID, 285 N3DS_JoystickGetDeviceInstanceID, 286 N3DS_JoystickOpen, 287 N3DS_JoystickRumble, 288 N3DS_JoystickRumbleTriggers, 289 N3DS_JoystickSetLED, 290 N3DS_JoystickSendEffect, 291 N3DS_JoystickSetSensorsEnabled, 292 N3DS_JoystickUpdate, 293 N3DS_JoystickClose, 294 N3DS_JoystickQuit, 295 N3DS_JoystickGetGamepadMapping 296}; 297 298#endif // SDL_JOYSTICK_N3DS 299
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.