1/* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Sam Lantinga 20 slouken@libsdl.org 21*/ 22#include "SDL_config.h" 23 24#ifdef SDL_JOYSTICK_DC 25 26#include "SDL_events.h" 27#include "SDL_joystick.h" 28#include "../SDL_sysjoystick.h" 29#include "../SDL_joystick_c.h" 30 31#include <dc/maple.h> 32#include <dc/maple/controller.h> 33 34#define MAX_JOYSTICKS 8 /* only 2 are supported in the multimedia API */ 35#define MAX_AXES 6 /* each joystick can have up to 6 axes */ 36#define MAX_BUTTONS 8 /* and 8 buttons */ 37#define MAX_HATS 2 38 39#define JOYNAMELEN 8 40 41/* array to hold joystick ID values */ 42static uint8 SYS_Joystick_addr[MAX_JOYSTICKS]; 43 44/* The private structure used to keep track of a joystick */ 45struct joystick_hwdata 46{ 47 cont_cond_t prev_cond; 48 int prev_buttons; 49}; 50 51/* Function to scan the system for joysticks. 52 * This function should set SDL_numjoysticks to the number of available 53 * joysticks. Joystick 0 should be the system default joystick. 54 * It should return 0, or -1 on an unrecoverable fatal error. 55 */ 56int SDL_SYS_JoystickInit(void) 57{ 58 int numdevs; 59 60 int p,u; 61 62 numdevs = 0; 63 for(p=0;p<MAPLE_PORT_COUNT;p++) { 64 for(u=0;u<MAPLE_UNIT_COUNT;u++) { 65 if (maple_device_func(p,u)&MAPLE_FUNC_CONTROLLER) { 66 SYS_Joystick_addr[numdevs] = maple_addr(p,u); 67 numdevs++; 68 } 69 } 70 } 71 72 return(numdevs); 73} 74 75/* Function to get the device-dependent name of a joystick */ 76const char *SDL_SYS_JoystickName(int index) 77{ 78 maple_device_t *dev; 79 if (maple_compat_resolve(SYS_Joystick_addr[index],&dev,MAPLE_FUNC_CONTROLLER)!=0) return NULL; 80 return dev->info.product_name; 81} 82 83/* Function to open a joystick for use. 84 The joystick to open is specified by the index field of the joystick. 85 This should fill the nbuttons and naxes fields of the joystick structure. 86 It returns 0, or -1 if there is an error. 87 */ 88int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) 89{ 90 /* allocate memory for system specific hardware data */ 91 joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); 92 if (joystick->hwdata == NULL) 93 { 94 SDL_OutOfMemory(); 95 return(-1); 96 } 97 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); 98 99 /* fill nbuttons, naxes, and nhats fields */ 100 joystick->nbuttons = MAX_BUTTONS; 101 joystick->naxes = MAX_AXES; 102 joystick->nhats = MAX_HATS; 103 return(0); 104} 105 106 107/* Function to update the state of a joystick - called as a device poll. 108 * This function shouldn't update the joystick structure directly, 109 * but instead should call SDL_PrivateJoystick*() to deliver events 110 * and update joystick device state. 111 */ 112 113void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) 114{ 115const int sdl_buttons[] = { 116 CONT_C, 117 CONT_B, 118 CONT_A, 119 CONT_START, 120 CONT_Z, 121 CONT_Y, 122 CONT_X, 123 CONT_D 124}; 125 126 uint8 addr; 127 cont_cond_t cond,*prev_cond; 128 int buttons,prev_buttons,i,changed; 129 130 addr = SYS_Joystick_addr[joystick->index]; 131 if (cont_get_cond(addr,&cond)<0) return; 132 133 buttons = cond.buttons; 134 prev_buttons = joystick->hwdata->prev_buttons; 135 changed = buttons^prev_buttons; 136 137 if ((changed)&(CONT_DPAD_UP|CONT_DPAD_DOWN|CONT_DPAD_LEFT|CONT_DPAD_RIGHT)) { 138 int hat = SDL_HAT_CENTERED; 139 if (buttons&CONT_DPAD_UP) hat|=SDL_HAT_UP; 140 if (buttons&CONT_DPAD_DOWN) hat|=SDL_HAT_DOWN; 141 if (buttons&CONT_DPAD_LEFT) hat|=SDL_HAT_LEFT; 142 if (buttons&CONT_DPAD_RIGHT) hat|=SDL_HAT_RIGHT; 143 SDL_PrivateJoystickHat(joystick, 0, hat); 144 } 145 if ((changed)&(CONT_DPAD2_UP|CONT_DPAD2_DOWN|CONT_DPAD2_LEFT|CONT_DPAD2_RIGHT)) { 146 int hat = SDL_HAT_CENTERED; 147 if (buttons&CONT_DPAD2_UP) hat|=SDL_HAT_UP; 148 if (buttons&CONT_DPAD2_DOWN) hat|=SDL_HAT_DOWN; 149 if (buttons&CONT_DPAD2_LEFT) hat|=SDL_HAT_LEFT; 150 if (buttons&CONT_DPAD2_RIGHT) hat|=SDL_HAT_RIGHT; 151 SDL_PrivateJoystickHat(joystick, 1, hat); 152 } 153 154 for(i=0;i<sizeof(sdl_buttons)/sizeof(sdl_buttons[0]);i++) { 155 if (changed & sdl_buttons[i]) { 156 SDL_PrivateJoystickButton(joystick, i, (buttons & sdl_buttons[i])?SDL_PRESSED:SDL_RELEASED); 157 } 158 } 159 160 prev_cond = &joystick->hwdata->prev_cond; 161 if (cond.joyx!=prev_cond->joyx) 162 SDL_PrivateJoystickAxis(joystick, 0, cond.joyx-128); 163 if (cond.joyy!=prev_cond->joyy) 164 SDL_PrivateJoystickAxis(joystick, 1, cond.joyy-128); 165 if (cond.rtrig!=prev_cond->rtrig) 166 SDL_PrivateJoystickAxis(joystick, 2, cond.rtrig); 167 if (cond.ltrig!=prev_cond->ltrig) 168 SDL_PrivateJoystickAxis(joystick, 3, cond.ltrig); 169 if (cond.joy2x!=prev_cond->joy2x) 170 SDL_PrivateJoystickAxis(joystick, 4, cond.joy2x-128); 171 if (cond.joy2y!=prev_cond->joy2y) 172 SDL_PrivateJoystickAxis(joystick, 5, cond.joy2y-128); 173 174 joystick->hwdata->prev_buttons = buttons; 175 joystick->hwdata->prev_cond = cond; 176} 177 178/* Function to close a joystick after use */ 179void SDL_SYS_JoystickClose(SDL_Joystick *joystick) 180{ 181 if (joystick->hwdata != NULL) { 182 /* free system specific hardware data */ 183 SDL_free(joystick->hwdata); 184 } 185} 186 187/* Function to perform any system-specific joystick related cleanup */ 188void SDL_SYS_JoystickQuit(void) 189{ 190 return; 191} 192 193#endif /* SDL_JOYSTICK_DC */ 194