src/joystick/windows/SDL_mmjoystick.c
author Sam Lantinga
Tue, 03 Jan 2017 23:39:28 -0800
changeset 10745 7461fcef6ae2
parent 10737 3406a0f8b041
child 10818 7e06b0e4dbe0
permissions -rw-r--r--
Fixed binding the D-pad on some Super NES style controllers
Fixed a case where partial trigger pull could be bound to another button

There is a fundamental problem not resolved by this commit:

Some controllers have axes (triggers, pedals, etc.) that don't start at zero, but we're guaranteed that if we get a value that it's correct. For these controllers, the current code works, where we take the first value we get and use that as the zero point and generate axis motion starting from that point on.

Other controllers have digital axes (D-pad) that assume a zero starting point, and the first value we get is the min or max axis value when the D-pad is moved. For these controllers, the current code thinks that the zero point is the axis value after the D-pad motion and this doesn't work.

My hypothesis is that the first class of devices is more common and that we should solve for that, and add an exception to SDL_JoystickAxesCenteredAtZero() as needed for the second class of devices.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@0
    22
slouken@1635
    23
#ifdef SDL_JOYSTICK_WINMM
slouken@1635
    24
slouken@0
    25
/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */
slouken@0
    26
slouken@5090
    27
#include "../../core/windows/SDL_windows.h"
slouken@1358
    28
#include <mmsystem.h>
slouken@1358
    29
#include <regstr.h>
slouken@1358
    30
slouken@1330
    31
#include "SDL_events.h"
slouken@0
    32
#include "SDL_joystick.h"
slouken@1361
    33
#include "../SDL_sysjoystick.h"
slouken@1361
    34
#include "../SDL_joystick_c.h"
slouken@0
    35
slouken@7828
    36
#ifdef REGSTR_VAL_JOYOEMNAME 
slouken@7828
    37
#undef REGSTR_VAL_JOYOEMNAME 
slouken@7828
    38
#endif
slouken@7828
    39
#define REGSTR_VAL_JOYOEMNAME "OEMName"
slouken@7828
    40
slouken@7191
    41
#define MAX_JOYSTICKS   16
slouken@7191
    42
#define MAX_AXES    6       /* each joystick can have up to 6 axes */
slouken@7191
    43
#define MAX_BUTTONS 32      /* and 32 buttons                      */
slouken@7191
    44
#define JOY_BUTTON_FLAG(n)  (1<<n)
slouken@0
    45
slouken@0
    46
slouken@0
    47
/* array to hold joystick ID values */
slouken@1895
    48
static UINT SYS_JoystickID[MAX_JOYSTICKS];
slouken@7828
    49
static JOYCAPSA SYS_Joystick[MAX_JOYSTICKS];
slouken@1895
    50
static char *SYS_JoystickName[MAX_JOYSTICKS];
slouken@0
    51
slouken@0
    52
/* The private structure used to keep track of a joystick */
slouken@0
    53
struct joystick_hwdata
slouken@0
    54
{
slouken@1895
    55
    /* joystick ID */
slouken@1895
    56
    UINT id;
slouken@0
    57
slouken@1895
    58
    /* values used to translate device-specific coordinates into
slouken@1895
    59
       SDL-standard ranges */
slouken@1895
    60
    struct _transaxis
slouken@1895
    61
    {
slouken@1895
    62
        int offset;
slouken@1895
    63
        float scale;
slouken@1895
    64
    } transaxis[6];
slouken@0
    65
};
slouken@0
    66
slouken@5062
    67
/* Convert a Windows Multimedia API return code to a text message */
slouken@0
    68
static void SetMMerror(char *function, int code);
slouken@0
    69
slouken@0
    70
slouken@1895
    71
static char *
slouken@1895
    72
GetJoystickName(int index, const char *szRegKey)
slouken@937
    73
{
slouken@1895
    74
    /* added 7/24/2004 by Eckhard Stolberg */
slouken@1895
    75
    /*
slouken@1895
    76
       see if there is a joystick for the current
slouken@1895
    77
       index (1-16) listed in the registry
slouken@1895
    78
     */
slouken@1895
    79
    char *name = NULL;
slouken@2176
    80
    HKEY hTopKey;
slouken@1895
    81
    HKEY hKey;
slouken@1895
    82
    DWORD regsize;
slouken@1895
    83
    LONG regresult;
slouken@2176
    84
    char regkey[256];
slouken@2176
    85
    char regvalue[256];
slouken@2176
    86
    char regname[256];
slouken@2176
    87
slouken@2176
    88
    SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s\\%s",
slouken@2176
    89
                 REGSTR_PATH_JOYCONFIG, szRegKey, REGSTR_KEY_JOYCURR);
slouken@2176
    90
    hTopKey = HKEY_LOCAL_MACHINE;
slouken@2176
    91
    regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
slouken@2176
    92
    if (regresult != ERROR_SUCCESS) {
slouken@2176
    93
        hTopKey = HKEY_CURRENT_USER;
slouken@2176
    94
        regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
slouken@2176
    95
    }
slouken@2176
    96
    if (regresult != ERROR_SUCCESS) {
slouken@2176
    97
        return NULL;
slouken@2176
    98
    }
slouken@937
    99
slouken@2176
   100
    /* find the registry key name for the joystick's properties */
slouken@2176
   101
    regsize = sizeof(regname);
slouken@2176
   102
    SDL_snprintf(regvalue, SDL_arraysize(regvalue), "Joystick%d%s", index + 1,
slouken@2176
   103
                 REGSTR_VAL_JOYOEMNAME);
slouken@2176
   104
    regresult =
slouken@2176
   105
        RegQueryValueExA(hKey, regvalue, 0, 0, (LPBYTE) regname, &regsize);
slouken@2176
   106
    RegCloseKey(hKey);
slouken@2176
   107
slouken@2176
   108
    if (regresult != ERROR_SUCCESS) {
slouken@2176
   109
        return NULL;
slouken@2176
   110
    }
slouken@2176
   111
slouken@2176
   112
    /* open that registry key */
slouken@2176
   113
    SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s", REGSTR_PATH_JOYOEM,
slouken@2176
   114
                 regname);
slouken@2176
   115
    regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
slouken@2176
   116
    if (regresult != ERROR_SUCCESS) {
slouken@2176
   117
        return NULL;
slouken@2176
   118
    }
slouken@2176
   119
slouken@2176
   120
    /* find the size for the OEM name text */
slouken@2176
   121
    regsize = sizeof(regvalue);
slouken@2176
   122
    regresult =
slouken@2176
   123
        RegQueryValueExA(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, NULL, &regsize);
slouken@1895
   124
    if (regresult == ERROR_SUCCESS) {
slouken@2176
   125
        /* allocate enough memory for the OEM name text ... */
slouken@2176
   126
        name = (char *) SDL_malloc(regsize);
slouken@2176
   127
        if (name) {
slouken@2176
   128
            /* ... and read it from the registry */
slouken@2176
   129
            regresult = RegQueryValueExA(hKey,
slouken@1895
   130
                                         REGSTR_VAL_JOYOEMNAME, 0, 0,
slouken@2176
   131
                                         (LPBYTE) name, &regsize);
slouken@1895
   132
        }
slouken@1895
   133
    }
slouken@2176
   134
    RegCloseKey(hKey);
slouken@2176
   135
slouken@1895
   136
    return (name);
slouken@937
   137
}
slouken@937
   138
slouken@6698
   139
static int SDL_SYS_numjoysticks = 0;
slouken@6698
   140
slouken@0
   141
/* Function to scan the system for joysticks.
philipp@9311
   142
 * Joystick 0 should be the system default joystick.
slouken@0
   143
 * It should return 0, or -1 on an unrecoverable fatal error.
slouken@0
   144
 */
slouken@1895
   145
int
slouken@1895
   146
SDL_SYS_JoystickInit(void)
slouken@0
   147
{
slouken@1895
   148
    int i;
slouken@1895
   149
    int maxdevs;
slouken@1895
   150
    JOYINFOEX joyinfo;
slouken@7828
   151
    JOYCAPSA joycaps;
slouken@1895
   152
    MMRESULT result;
slouken@0
   153
slouken@1895
   154
    /* Reset the joystick ID & name mapping tables */
slouken@1895
   155
    for (i = 0; i < MAX_JOYSTICKS; ++i) {
slouken@1895
   156
        SYS_JoystickID[i] = 0;
slouken@1895
   157
        SYS_JoystickName[i] = NULL;
slouken@1895
   158
    }
slouken@531
   159
slouken@1895
   160
    /* Loop over all potential joystick devices */
slouken@6698
   161
    SDL_SYS_numjoysticks = 0;
slouken@1895
   162
    maxdevs = joyGetNumDevs();
slouken@6698
   163
    for (i = JOYSTICKID1; i < maxdevs && SDL_SYS_numjoysticks < MAX_JOYSTICKS; ++i) {
slouken@1895
   164
slouken@1895
   165
        joyinfo.dwSize = sizeof(joyinfo);
slouken@1895
   166
        joyinfo.dwFlags = JOY_RETURNALL;
icculus@2061
   167
        result = joyGetPosEx(i, &joyinfo);
slouken@1895
   168
        if (result == JOYERR_NOERROR) {
slouken@7828
   169
            result = joyGetDevCapsA(i, &joycaps, sizeof(joycaps));
slouken@1895
   170
            if (result == JOYERR_NOERROR) {
slouken@6698
   171
                SYS_JoystickID[SDL_SYS_numjoysticks] = i;
slouken@6698
   172
                SYS_Joystick[SDL_SYS_numjoysticks] = joycaps;
slouken@6698
   173
                SYS_JoystickName[SDL_SYS_numjoysticks] =
slouken@1895
   174
                    GetJoystickName(i, joycaps.szRegKey);
slouken@6698
   175
                SDL_SYS_numjoysticks++;
slouken@1895
   176
            }
slouken@1895
   177
        }
slouken@1895
   178
    }
slouken@6698
   179
    return (SDL_SYS_numjoysticks);
slouken@0
   180
}
slouken@0
   181
philipp@10617
   182
int
philipp@10617
   183
SDL_SYS_NumJoysticks(void)
slouken@6707
   184
{
slouken@6707
   185
    return SDL_SYS_numjoysticks;
slouken@6707
   186
}
slouken@6707
   187
philipp@10617
   188
void
philipp@10617
   189
SDL_SYS_JoystickDetect(void)
slouken@6707
   190
{
slouken@6707
   191
}
slouken@6707
   192
slouken@0
   193
/* Function to get the device-dependent name of a joystick */
slouken@1895
   194
const char *
slouken@6707
   195
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
slouken@0
   196
{
slouken@6707
   197
    if (SYS_JoystickName[device_index] != NULL) {
slouken@6707
   198
        return (SYS_JoystickName[device_index]);
slouken@1895
   199
    } else {
slouken@6707
   200
        return (SYS_Joystick[device_index].szPname);
slouken@1895
   201
    }
slouken@0
   202
}
slouken@0
   203
slouken@6707
   204
/* Function to perform the mapping from device index to the instance id for this index */
slouken@6707
   205
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
slouken@6707
   206
{
slouken@6707
   207
    return device_index;
slouken@6707
   208
}
slouken@6707
   209
slouken@0
   210
/* Function to open a joystick for use.
philipp@9380
   211
   The joystick to open is specified by the device index.
slouken@0
   212
   This should fill the nbuttons and naxes fields of the joystick structure.
slouken@0
   213
   It returns 0, or -1 if there is an error.
slouken@0
   214
 */
slouken@1895
   215
int
slouken@6698
   216
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
slouken@0
   217
{
slouken@1895
   218
    int index, i;
slouken@1895
   219
    int caps_flags[MAX_AXES - 2] =
slouken@1895
   220
        { JOYCAPS_HASZ, JOYCAPS_HASR, JOYCAPS_HASU, JOYCAPS_HASV };
slouken@1895
   221
    int axis_min[MAX_AXES], axis_max[MAX_AXES];
slouken@0
   222
slouken@0
   223
slouken@1895
   224
    /* shortcut */
slouken@6698
   225
    index = device_index;
slouken@1895
   226
    axis_min[0] = SYS_Joystick[index].wXmin;
slouken@1895
   227
    axis_max[0] = SYS_Joystick[index].wXmax;
slouken@1895
   228
    axis_min[1] = SYS_Joystick[index].wYmin;
slouken@1895
   229
    axis_max[1] = SYS_Joystick[index].wYmax;
slouken@1895
   230
    axis_min[2] = SYS_Joystick[index].wZmin;
slouken@1895
   231
    axis_max[2] = SYS_Joystick[index].wZmax;
slouken@1895
   232
    axis_min[3] = SYS_Joystick[index].wRmin;
slouken@1895
   233
    axis_max[3] = SYS_Joystick[index].wRmax;
slouken@1895
   234
    axis_min[4] = SYS_Joystick[index].wUmin;
slouken@1895
   235
    axis_max[4] = SYS_Joystick[index].wUmax;
slouken@1895
   236
    axis_min[5] = SYS_Joystick[index].wVmin;
slouken@1895
   237
    axis_max[5] = SYS_Joystick[index].wVmax;
slouken@0
   238
slouken@1895
   239
    /* allocate memory for system specific hardware data */
slouken@6698
   240
    joystick->instance_id = device_index;
slouken@1895
   241
    joystick->hwdata =
slouken@1895
   242
        (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
slouken@1895
   243
    if (joystick->hwdata == NULL) {
icculus@7037
   244
        return SDL_OutOfMemory();
slouken@1895
   245
    }
slouken@1895
   246
    SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
slouken@0
   247
slouken@1895
   248
    /* set hardware data */
slouken@1895
   249
    joystick->hwdata->id = SYS_JoystickID[index];
slouken@1895
   250
    for (i = 0; i < MAX_AXES; ++i) {
slouken@1895
   251
        if ((i < 2) || (SYS_Joystick[index].wCaps & caps_flags[i - 2])) {
slouken@10724
   252
            joystick->hwdata->transaxis[i].offset = SDL_JOYSTICK_AXIS_MIN - axis_min[i];
slouken@1895
   253
            joystick->hwdata->transaxis[i].scale =
slouken@10724
   254
                (float) (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) / (axis_max[i] - axis_min[i]);
slouken@1895
   255
        } else {
slouken@1895
   256
            joystick->hwdata->transaxis[i].offset = 0;
slouken@1895
   257
            joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */
slouken@1895
   258
        }
slouken@1895
   259
    }
slouken@1895
   260
slouken@1895
   261
    /* fill nbuttons, naxes, and nhats fields */
slouken@1895
   262
    joystick->nbuttons = SYS_Joystick[index].wNumButtons;
slouken@1895
   263
    joystick->naxes = SYS_Joystick[index].wNumAxes;
slouken@1895
   264
    if (SYS_Joystick[index].wCaps & JOYCAPS_HASPOV) {
slouken@1895
   265
        joystick->nhats = 1;
slouken@1895
   266
    } else {
slouken@1895
   267
        joystick->nhats = 0;
slouken@1895
   268
    }
slouken@1895
   269
    return (0);
slouken@0
   270
}
slouken@0
   271
philipp@9561
   272
/* Function to determine if this joystick is attached to the system right now */
slouken@6707
   273
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
slouken@6707
   274
{
slouken@6707
   275
    return SDL_TRUE;
slouken@6707
   276
}
slouken@6707
   277
slouken@1895
   278
static Uint8
slouken@1895
   279
TranslatePOV(DWORD value)
slouken@0
   280
{
slouken@1895
   281
    Uint8 pos;
slouken@0
   282
slouken@1895
   283
    pos = SDL_HAT_CENTERED;
slouken@1895
   284
    if (value != JOY_POVCENTERED) {
slouken@1895
   285
        if ((value > JOY_POVLEFT) || (value < JOY_POVRIGHT)) {
slouken@1895
   286
            pos |= SDL_HAT_UP;
slouken@1895
   287
        }
slouken@1895
   288
        if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) {
slouken@1895
   289
            pos |= SDL_HAT_RIGHT;
slouken@1895
   290
        }
slouken@1895
   291
        if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) {
slouken@1895
   292
            pos |= SDL_HAT_DOWN;
slouken@1895
   293
        }
slouken@1895
   294
        if (value > JOY_POVBACKWARD) {
slouken@1895
   295
            pos |= SDL_HAT_LEFT;
slouken@1895
   296
        }
slouken@1895
   297
    }
slouken@1895
   298
    return (pos);
slouken@0
   299
}
slouken@0
   300
slouken@0
   301
/* Function to update the state of a joystick - called as a device poll.
slouken@0
   302
 * This function shouldn't update the joystick structure directly,
slouken@0
   303
 * but instead should call SDL_PrivateJoystick*() to deliver events
slouken@0
   304
 * and update joystick device state.
slouken@0
   305
 */
slouken@1895
   306
void
slouken@1895
   307
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
slouken@0
   308
{
slouken@1895
   309
    MMRESULT result;
slouken@1895
   310
    int i;
slouken@1895
   311
    DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ,
slouken@1895
   312
        JOY_RETURNR, JOY_RETURNU, JOY_RETURNV
slouken@1895
   313
    };
slouken@1895
   314
    DWORD pos[MAX_AXES];
slouken@1895
   315
    struct _transaxis *transaxis;
slouken@1895
   316
    int value, change;
slouken@1895
   317
    JOYINFOEX joyinfo;
slouken@0
   318
slouken@1895
   319
    joyinfo.dwSize = sizeof(joyinfo);
slouken@1895
   320
    joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS;
slouken@1895
   321
    if (!joystick->hats) {
slouken@1895
   322
        joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS);
slouken@1895
   323
    }
slouken@1895
   324
    result = joyGetPosEx(joystick->hwdata->id, &joyinfo);
slouken@1895
   325
    if (result != JOYERR_NOERROR) {
slouken@1895
   326
        SetMMerror("joyGetPosEx", result);
slouken@1895
   327
        return;
slouken@1895
   328
    }
slouken@0
   329
slouken@1895
   330
    /* joystick motion events */
slouken@1895
   331
    pos[0] = joyinfo.dwXpos;
slouken@1895
   332
    pos[1] = joyinfo.dwYpos;
slouken@1895
   333
    pos[2] = joyinfo.dwZpos;
slouken@1895
   334
    pos[3] = joyinfo.dwRpos;
slouken@1895
   335
    pos[4] = joyinfo.dwUpos;
slouken@1895
   336
    pos[5] = joyinfo.dwVpos;
slouken@0
   337
slouken@1895
   338
    transaxis = joystick->hwdata->transaxis;
slouken@1895
   339
    for (i = 0; i < joystick->naxes; i++) {
slouken@1895
   340
        if (joyinfo.dwFlags & flags[i]) {
slouken@10745
   341
            value = (int) (((float) pos[i] + transaxis[i].offset) * transaxis[i].scale);
slouken@10745
   342
            SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value);
slouken@1895
   343
        }
slouken@1895
   344
    }
slouken@0
   345
slouken@1895
   346
    /* joystick button events */
slouken@1895
   347
    if (joyinfo.dwFlags & JOY_RETURNBUTTONS) {
slouken@1895
   348
        for (i = 0; i < joystick->nbuttons; ++i) {
slouken@1895
   349
            if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) {
slouken@10745
   350
                SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_PRESSED);
slouken@1895
   351
            } else {
slouken@10745
   352
                SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_RELEASED);
slouken@1895
   353
            }
slouken@1895
   354
        }
slouken@1895
   355
    }
slouken@0
   356
slouken@1895
   357
    /* joystick hat events */
slouken@1895
   358
    if (joyinfo.dwFlags & JOY_RETURNPOV) {
slouken@1895
   359
        Uint8 pos;
slouken@0
   360
slouken@1895
   361
        pos = TranslatePOV(joyinfo.dwPOV);
slouken@10745
   362
        SDL_PrivateJoystickHat(joystick, 0, pos);
slouken@1895
   363
    }
slouken@0
   364
}
slouken@0
   365
slouken@0
   366
/* Function to close a joystick after use */
slouken@1895
   367
void
slouken@1895
   368
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
slouken@0
   369
{
slouken@7719
   370
    SDL_free(joystick->hwdata);
slouken@0
   371
}
slouken@0
   372
slouken@0
   373
/* Function to perform any system-specific joystick related cleanup */
slouken@1895
   374
void
slouken@1895
   375
SDL_SYS_JoystickQuit(void)
slouken@0
   376
{
slouken@1895
   377
    int i;
slouken@1895
   378
    for (i = 0; i < MAX_JOYSTICKS; i++) {
slouken@7719
   379
        SDL_free(SYS_JoystickName[i]);
slouken@7719
   380
        SYS_JoystickName[i] = NULL;
slouken@1895
   381
    }
slouken@0
   382
}
slouken@0
   383
slouken@6738
   384
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
slouken@6698
   385
{
slouken@6738
   386
    SDL_JoystickGUID guid;
slouken@7191
   387
    /* the GUID is just the first 16 chars of the name for now */
slouken@6707
   388
    const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
slouken@6698
   389
    SDL_zero( guid );
slouken@6698
   390
    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
slouken@6698
   391
    return guid;
slouken@6698
   392
}
slouken@6698
   393
slouken@6738
   394
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
slouken@6698
   395
{
slouken@6738
   396
    SDL_JoystickGUID guid;
slouken@7191
   397
    /* the GUID is just the first 16 chars of the name for now */
slouken@6698
   398
    const char *name = joystick->name;
slouken@6698
   399
    SDL_zero( guid );
slouken@6698
   400
    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
slouken@6698
   401
    return guid;
slouken@6698
   402
}
slouken@6698
   403
slouken@0
   404
slouken@0
   405
/* implementation functions */
slouken@1895
   406
void
slouken@1895
   407
SetMMerror(char *function, int code)
slouken@0
   408
{
slouken@1895
   409
    static char *error;
slouken@1895
   410
    static char errbuf[1024];
slouken@0
   411
slouken@1895
   412
    errbuf[0] = 0;
slouken@1895
   413
    switch (code) {
slouken@1895
   414
    case MMSYSERR_NODRIVER:
slouken@1895
   415
        error = "Joystick driver not present";
slouken@1895
   416
        break;
slouken@1895
   417
slouken@1895
   418
    case MMSYSERR_INVALPARAM:
slouken@1895
   419
    case JOYERR_PARMS:
slouken@1895
   420
        error = "Invalid parameter(s)";
slouken@1895
   421
        break;
slouken@1895
   422
slouken@1895
   423
    case MMSYSERR_BADDEVICEID:
slouken@1895
   424
        error = "Bad device ID";
slouken@1895
   425
        break;
slouken@0
   426
slouken@1895
   427
    case JOYERR_UNPLUGGED:
slouken@1895
   428
        error = "Joystick not attached";
slouken@1895
   429
        break;
slouken@0
   430
slouken@1895
   431
    case JOYERR_NOCANDO:
slouken@1895
   432
        error = "Can't capture joystick input";
slouken@1895
   433
        break;
slouken@0
   434
slouken@1895
   435
    default:
slouken@1895
   436
        SDL_snprintf(errbuf, SDL_arraysize(errbuf),
slouken@1895
   437
                     "%s: Unknown Multimedia system error: 0x%x",
slouken@1895
   438
                     function, code);
slouken@1895
   439
        break;
slouken@1895
   440
    }
slouken@0
   441
slouken@1895
   442
    if (!errbuf[0]) {
slouken@1895
   443
        SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
slouken@1895
   444
                     error);
slouken@1895
   445
    }
slouken@1895
   446
    SDL_SetError("%s", errbuf);
slouken@0
   447
}
slouken@1635
   448
slouken@1635
   449
#endif /* SDL_JOYSTICK_WINMM */
slouken@6707
   450
slouken@1895
   451
/* vi: set ts=4 sw=4 expandtab: */