src/joystick/psp/SDL_sysjoystick.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 20 Oct 2013 21:56:15 -0700
changeset 7860 2b0bcdea3a79
parent 7191 75360622e65f
child 8138 0fbc97d82043
permissions -rw-r--r--
Fixed bug 2129 - fix for bug 2121 breaks linking for mingw and throws multiple warnings

Andreas Ertelt

The problem in question is caused by changeset 7771 (http://hg.libsdl.org/SDL/rev/4434498bf4b9 / https://bugzilla.libsdl.org/show_bug.cgi?id=2121)

The redefinition of __inline__ (introduced by the addition of begin_code.h:128's "|| __STRICT_ANSI__") results in mingw's gcc throwing multiple

warning: always_inline function might not be inlinable [-Wattributes]

as well as a whole bunch of redefinitions of mingw internals which break linking of projects including the SDL2 headers.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     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 
    22 /* This is the system specific header for the SDL joystick API */
    23 #include <pspctrl.h>
    24 #include <pspkernel.h>
    25 
    26 #include <stdio.h>      /* For the definition of NULL */
    27 #include <stdlib.h>
    28 
    29 #include "../SDL_sysjoystick.h"
    30 #include "../SDL_joystick_c.h"
    31 
    32 #include "SDL_events.h"
    33 #include "SDL_error.h"
    34 #include "SDL_thread.h"
    35 #include "SDL_mutex.h"
    36 #include "SDL_timer.h"
    37 
    38 /* Current pad state */
    39 static SceCtrlData pad = { .Lx = 0, .Ly = 0, .Buttons = 0 };
    40 static SDL_sem *pad_sem = NULL;
    41 static SDL_Thread *thread = NULL;
    42 static int running = 0;
    43 static const enum PspCtrlButtons button_map[] = {
    44     PSP_CTRL_TRIANGLE, PSP_CTRL_CIRCLE, PSP_CTRL_CROSS, PSP_CTRL_SQUARE,
    45     PSP_CTRL_LTRIGGER, PSP_CTRL_RTRIGGER,
    46     PSP_CTRL_DOWN, PSP_CTRL_LEFT, PSP_CTRL_UP, PSP_CTRL_RIGHT,
    47     PSP_CTRL_SELECT, PSP_CTRL_START, PSP_CTRL_HOME, PSP_CTRL_HOLD };
    48 static int analog_map[256];  /* Map analog inputs to -32768 -> 32767 */
    49 
    50 typedef struct
    51 {
    52   int x;
    53   int y;
    54 } point;
    55 
    56 /* 4 points define the bezier-curve. */
    57 static point a = { 0, 0 };
    58 static point b = { 50, 0  };
    59 static point c = { 78, 32767 };
    60 static point d = { 128, 32767 };
    61 
    62 /* simple linear interpolation between two points */
    63 static SDL_INLINE void lerp (point *dest, point *a, point *b, float t)
    64 {
    65     dest->x = a->x + (b->x - a->x)*t;
    66     dest->y = a->y + (b->y - a->y)*t;
    67 }
    68 
    69 /* evaluate a point on a bezier-curve. t goes from 0 to 1.0 */
    70 static int calc_bezier_y(float t)
    71 {
    72     point ab, bc, cd, abbc, bccd, dest;
    73     lerp (&ab, &a, &b, t);           /* point between a and b */
    74     lerp (&bc, &b, &c, t);           /* point between b and c */
    75     lerp (&cd, &c, &d, t);           /* point between c and d */
    76     lerp (&abbc, &ab, &bc, t);       /* point between ab and bc */
    77     lerp (&bccd, &bc, &cd, t);       /* point between bc and cd */
    78     lerp (&dest, &abbc, &bccd, t);   /* point on the bezier-curve */
    79     return dest.y;
    80 }
    81 
    82 /*
    83  * Collect pad data about once per frame
    84  */
    85 int JoystickUpdate(void *data)
    86 {
    87     while (running) {
    88         SDL_SemWait(pad_sem);
    89         sceCtrlPeekBufferPositive(&pad, 1);
    90         SDL_SemPost(pad_sem);
    91         /* Delay 1/60th of a second */
    92         sceKernelDelayThread(1000000 / 60);
    93     }
    94     return 0;
    95 }
    96 
    97 
    98 
    99 /* Function to scan the system for joysticks.
   100  * This function should set SDL_numjoysticks to the number of available
   101  * joysticks.  Joystick 0 should be the system default joystick.
   102  * It should return number of joysticks, or -1 on an unrecoverable fatal error.
   103  */
   104 int SDL_SYS_JoystickInit(void)
   105 {
   106     int i;
   107 
   108 /*  SDL_numjoysticks = 1; */
   109 
   110     /* Setup input */
   111     sceCtrlSetSamplingCycle(0);
   112     sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
   113 
   114     /* Start thread to read data */
   115     if((pad_sem =  SDL_CreateSemaphore(1)) == NULL) {
   116         return SDL_SetError("Can't create input semaphore");
   117     }
   118     running = 1;
   119     if((thread = SDL_CreateThread(JoystickUpdate, "JoySitckThread",NULL)) == NULL) {
   120         return SDL_SetError("Can't create input thread");
   121     }
   122 
   123     /* Create an accurate map from analog inputs (0 to 255)
   124        to SDL joystick positions (-32768 to 32767) */
   125     for (i = 0; i < 128; i++)
   126     {
   127         float t = (float)i/127.0f;
   128         analog_map[i+128] = calc_bezier_y(t);
   129         analog_map[127-i] = -1 * analog_map[i+128];
   130     }
   131 
   132     return 1;
   133 }
   134 
   135 int SDL_SYS_NumJoysticks()
   136 {
   137     return 1;
   138 }
   139 
   140 void SDL_SYS_JoystickDetect()
   141 {
   142 }
   143 
   144 SDL_bool SDL_SYS_JoystickNeedsPolling()
   145 {
   146     return SDL_FALSE;
   147 }
   148 
   149 /* Function to get the device-dependent name of a joystick */
   150 const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index)
   151 {
   152     return "PSP builtin joypad";
   153 }
   154 
   155 /* Function to perform the mapping from device index to the instance id for this index */
   156 SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   157 {
   158     return device_index;
   159 }
   160 
   161 /* Function to get the device-dependent name of a joystick */
   162 const char *SDL_SYS_JoystickName(int index)
   163 {
   164     if (index == 0)
   165         return "PSP controller";
   166 
   167     SDL_SetError("No joystick available with that index");
   168     return(NULL);
   169 }
   170 
   171 /* Function to open a joystick for use.
   172    The joystick to open is specified by the index field of the joystick.
   173    This should fill the nbuttons and naxes fields of the joystick structure.
   174    It returns 0, or -1 if there is an error.
   175  */
   176 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
   177 {
   178     joystick->nbuttons = 14;
   179     joystick->naxes = 2;
   180     joystick->nhats = 0;
   181 
   182     return 0;
   183 }
   184 
   185 /* Function to determine is this joystick is attached to the system right now */
   186 SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
   187 {
   188     return SDL_TRUE;
   189 }
   190 /* Function to update the state of a joystick - called as a device poll.
   191  * This function shouldn't update the joystick structure directly,
   192  * but instead should call SDL_PrivateJoystick*() to deliver events
   193  * and update joystick device state.
   194  */
   195 
   196 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
   197 {
   198     int i;
   199     enum PspCtrlButtons buttons;
   200     enum PspCtrlButtons changed;
   201     unsigned char x, y;
   202     static enum PspCtrlButtons old_buttons = 0;
   203     static unsigned char old_x = 0, old_y = 0;
   204 
   205     SDL_SemWait(pad_sem);
   206     buttons = pad.Buttons;
   207     x = pad.Lx;
   208     y = pad.Ly;
   209     SDL_SemPost(pad_sem);
   210 
   211     /* Axes */
   212     if(old_x != x) {
   213         SDL_PrivateJoystickAxis(joystick, 0, analog_map[x]);
   214         old_x = x;
   215     }
   216     if(old_y != y) {
   217         SDL_PrivateJoystickAxis(joystick, 1, analog_map[y]);
   218         old_y = y;
   219     }
   220 
   221     /* Buttons */
   222     changed = old_buttons ^ buttons;
   223     old_buttons = buttons;
   224     if(changed) {
   225         for(i=0; i<sizeof(button_map)/sizeof(button_map[0]); i++) {
   226             if(changed & button_map[i]) {
   227                 SDL_PrivateJoystickButton(
   228                     joystick, i,
   229                     (buttons & button_map[i]) ?
   230                     SDL_PRESSED : SDL_RELEASED);
   231             }
   232         }
   233     }
   234 
   235     sceKernelDelayThread(0);
   236 }
   237 
   238 /* Function to close a joystick after use */
   239 void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
   240 {
   241     /* Do nothing. */
   242 }
   243 
   244 /* Function to perform any system-specific joystick related cleanup */
   245 void SDL_SYS_JoystickQuit(void)
   246 {
   247     /* Cleanup Threads and Semaphore. */
   248     running = 0;
   249     SDL_WaitThread(thread, NULL);
   250     SDL_DestroySemaphore(pad_sem);
   251 }
   252 
   253 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   254 {
   255     SDL_JoystickGUID guid;
   256     /* the GUID is just the first 16 chars of the name for now */
   257     const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
   258     SDL_zero( guid );
   259     SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   260     return guid;
   261 }
   262 
   263 SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
   264 {
   265     SDL_JoystickGUID guid;
   266     /* the GUID is just the first 16 chars of the name for now */
   267     const char *name = joystick->name;
   268     SDL_zero( guid );
   269     SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   270     return guid;
   271 }
   272 
   273 /* vim: ts=4 sw=4
   274  */