/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"

/* This is the game controller API for Simple DirectMedia Layer */

#include "SDL_events.h"
#include "SDL_assert.h"
#include "SDL_hints.h"
#include "SDL_timer.h"
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "SDL_gamecontrollerdb.h"

#if !SDL_EVENTS_DISABLED
#include "../events/SDL_events_c.h"
#endif

#if defined(__ANDROID__)
#include "SDL_system.h"
#endif


/* Many controllers turn the center button into an instantaneous button press */
#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS   250

#define SDL_CONTROLLER_PLATFORM_FIELD "platform:"

/* a list of currently opened game controllers */
static SDL_GameController *SDL_gamecontrollers = NULL;

typedef struct
{
    SDL_GameControllerBindType inputType;
    union
    {
        int button;

        struct {
            int axis;
            int axis_min;
            int axis_max;
        } axis;

        struct {
            int hat;
            int hat_mask;
        } hat;

    } input;

    SDL_GameControllerBindType outputType;
    union
    {
        SDL_GameControllerButton button;

        struct {
            SDL_GameControllerAxis axis;
            int axis_min;
            int axis_max;
        } axis;

    } output;

} SDL_ExtendedGameControllerBind;

/* our hard coded list of mapping support */
typedef enum
{
    SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT,
    SDL_CONTROLLER_MAPPING_PRIORITY_API,
    SDL_CONTROLLER_MAPPING_PRIORITY_USER,
} SDL_ControllerMappingPriority;

typedef struct _ControllerMapping_t
{
    SDL_JoystickGUID guid;
    char *name;
    char *mapping;
    SDL_ControllerMappingPriority priority;
    struct _ControllerMapping_t *next;
} ControllerMapping_t;

static SDL_JoystickGUID s_zeroGUID;
static ControllerMapping_t *s_pSupportedControllers = NULL;
static ControllerMapping_t *s_pDefaultMapping = NULL;
static ControllerMapping_t *s_pHIDAPIMapping = NULL;
static ControllerMapping_t *s_pXInputMapping = NULL;

/* The SDL game controller structure */
struct _SDL_GameController
{
    SDL_Joystick *joystick; /* underlying joystick device */
    int ref_count;

    SDL_JoystickGUID guid;
    const char *name;
    int num_bindings;
    SDL_ExtendedGameControllerBind *bindings;
    SDL_ExtendedGameControllerBind **last_match_axis;
    Uint8 *last_hat_mask;
    Uint32 guide_button_down;

    struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
};


typedef struct
{
    int num_entries;
    int max_entries;
    Uint32 *entries;
} SDL_vidpid_list;

static SDL_vidpid_list SDL_allowed_controllers;
static SDL_vidpid_list SDL_ignored_controllers;

static void
SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list)
{
    Uint32 entry;
    char *spot;
    char *file = NULL;

    list->num_entries = 0;

    if (hint && *hint == '@') {
        spot = file = (char *)SDL_LoadFile(hint+1, NULL);
    } else {
        spot = (char *)hint;
    }

    if (!spot) {
        return;
    }

    while ((spot = SDL_strstr(spot, "0x")) != NULL) {
        entry = (Uint16)SDL_strtol(spot, &spot, 0);
        entry <<= 16;
        spot = SDL_strstr(spot, "0x");
        if (!spot) {
            break;
        }
        entry |= (Uint16)SDL_strtol(spot, &spot, 0);

        if (list->num_entries == list->max_entries) {
            int max_entries = list->max_entries + 16;
            Uint32 *entries = (Uint32 *)SDL_realloc(list->entries, max_entries*sizeof(*list->entries));
            if (entries == NULL) {
                /* Out of memory, go with what we have already */
                break;
            }
            list->entries = entries;
            list->max_entries = max_entries;
        }
        list->entries[list->num_entries++] = entry;
    }

    if (file) {
        SDL_free(file);
    }
}

static void SDLCALL
SDL_GameControllerIgnoreDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
    SDL_LoadVIDPIDListFromHint(hint, &SDL_ignored_controllers);
}

static void SDLCALL
SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
    SDL_LoadVIDPIDListFromHint(hint, &SDL_allowed_controllers);
}

static int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
static int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);

/*
 * If there is an existing add event in the queue, it needs to be modified
 * to have the right value for which, because the number of controllers in
 * the system is now one less.
 */
static void UpdateEventsForDeviceRemoval()
{
    int i, num_events;
    SDL_Event *events;

    num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
    if (num_events <= 0) {
        return;
    }

    events = SDL_stack_alloc(SDL_Event, num_events);
    if (!events) {
        return;
    }

    num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
    for (i = 0; i < num_events; ++i) {
        --events[i].cdevice.which;
    }
    SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);

    SDL_stack_free(events);
}

static SDL_bool HasSameOutput(SDL_ExtendedGameControllerBind *a, SDL_ExtendedGameControllerBind *b)
{
    if (a->outputType != b->outputType) {
        return SDL_FALSE;
    }

    if (a->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
        return (a->output.axis.axis == b->output.axis.axis);
    } else {
        return (a->output.button == b->output.button);
    }
}

static void ResetOutput(SDL_GameController *gamecontroller, SDL_ExtendedGameControllerBind *bind)
{
    if (bind->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
        SDL_PrivateGameControllerAxis(gamecontroller, bind->output.axis.axis, 0);
    } else {
        SDL_PrivateGameControllerButton(gamecontroller, bind->output.button, SDL_RELEASED);
    }
}

static void HandleJoystickAxis(SDL_GameController *gamecontroller, int axis, int value)
{
    int i;
    SDL_ExtendedGameControllerBind *last_match = gamecontroller->last_match_axis[axis];
    SDL_ExtendedGameControllerBind *match = NULL;

    for (i = 0; i < gamecontroller->num_bindings; ++i) {
        SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
        if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
            axis == binding->input.axis.axis) {
            if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
                if (value >= binding->input.axis.axis_min &&
                    value <= binding->input.axis.axis_max) {
                    match = binding;
                    break;
                }
            } else {
                if (value >= binding->input.axis.axis_max &&
                    value <= binding->input.axis.axis_min) {
                    match = binding;
                    break;
                }
            }
        }
    }

    if (last_match && (!match || !HasSameOutput(last_match, match))) {
        /* Clear the last input that this axis generated */
        ResetOutput(gamecontroller, last_match);
    }

    if (match) {
        if (match->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
            if (match->input.axis.axis_min != match->output.axis.axis_min || match->input.axis.axis_max != match->output.axis.axis_max) {
                float normalized_value = (float)(value - match->input.axis.axis_min) / (match->input.axis.axis_max - match->input.axis.axis_min);
                value = match->output.axis.axis_min + (int)(normalized_value * (match->output.axis.axis_max - match->output.axis.axis_min));
            }
            SDL_PrivateGameControllerAxis(gamecontroller, match->output.axis.axis, (Sint16)value);
        } else {
            Uint8 state;
            int threshold = match->input.axis.axis_min + (match->input.axis.axis_max - match->input.axis.axis_min) / 2;
            if (match->input.axis.axis_max < match->input.axis.axis_min) {
                state = (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
            } else {
                state = (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
            }
            SDL_PrivateGameControllerButton(gamecontroller, match->output.button, state);
        }
    }
    gamecontroller->last_match_axis[axis] = match;
}

static void HandleJoystickButton(SDL_GameController *gamecontroller, int button, Uint8 state)
{
    int i;

    for (i = 0; i < gamecontroller->num_bindings; ++i) {
        SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
        if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON &&
            button == binding->input.button) {
            if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
                int value = state ? binding->output.axis.axis_max : binding->output.axis.axis_min;
                SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)value);
            } else {
                SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, state);
            }
            break;
        }
    }
}

static void HandleJoystickHat(SDL_GameController *gamecontroller, int hat, Uint8 value)
{
    int i;
    Uint8 last_mask = gamecontroller->last_hat_mask[hat];
    Uint8 changed_mask = (last_mask ^ value);

    for (i = 0; i < gamecontroller->num_bindings; ++i) {
        SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
        if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT && hat == binding->input.hat.hat) {
            if ((changed_mask & binding->input.hat.hat_mask) != 0) {
                if (value & binding->input.hat.hat_mask) {
                    if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
                        SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)binding->output.axis.axis_max);
                    } else {
                        SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, SDL_PRESSED);
                    }
                } else {
                    ResetOutput(gamecontroller, binding);
                }
            }
        }
    }
    gamecontroller->last_hat_mask[hat] = value;
}

/*
 * Event filter to fire controller events from joystick ones
 */
static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
{
    switch(event->type) {
    case SDL_JOYAXISMOTION:
        {
            SDL_GameController *controllerlist = SDL_gamecontrollers;
            while (controllerlist) {
                if (controllerlist->joystick->instance_id == event->jaxis.which) {
                    HandleJoystickAxis(controllerlist, event->jaxis.axis, event->jaxis.value);
                    break;
                }
                controllerlist = controllerlist->next;
            }
        }
        break;
    case SDL_JOYBUTTONDOWN:
    case SDL_JOYBUTTONUP:
        {
            SDL_GameController *controllerlist = SDL_gamecontrollers;
            while (controllerlist) {
                if (controllerlist->joystick->instance_id == event->jbutton.which) {
                    HandleJoystickButton(controllerlist, event->jbutton.button, event->jbutton.state);
                    break;
                }
                controllerlist = controllerlist->next;
            }
        }
        break;
    case SDL_JOYHATMOTION:
        {
            SDL_GameController *controllerlist = SDL_gamecontrollers;
            while (controllerlist) {
                if (controllerlist->joystick->instance_id == event->jhat.which) {
                    HandleJoystickHat(controllerlist, event->jhat.hat, event->jhat.value);
                    break;
                }
                controllerlist = controllerlist->next;
            }
        }
        break;
    case SDL_JOYDEVICEADDED:
        {
            if (SDL_IsGameController(event->jdevice.which)) {
                SDL_Event deviceevent;
                deviceevent.type = SDL_CONTROLLERDEVICEADDED;
                deviceevent.cdevice.which = event->jdevice.which;
                SDL_PushEvent(&deviceevent);
            }
        }
        break;
    case SDL_JOYDEVICEREMOVED:
        {
            SDL_GameController *controllerlist = SDL_gamecontrollers;
            while (controllerlist) {
                if (controllerlist->joystick->instance_id == event->jdevice.which) {
                    SDL_Event deviceevent;

                    deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
                    deviceevent.cdevice.which = event->jdevice.which;
                    SDL_PushEvent(&deviceevent);

                    UpdateEventsForDeviceRemoval();
                    break;
                }
                controllerlist = controllerlist->next;
            }
        }
        break;
    default:
        break;
    }

    return 1;
}

/*
 * Helper function to scan the mappings database for a controller with the specified GUID
 */
static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
{
    ControllerMapping_t *pSupportedController = s_pSupportedControllers;
    while (pSupportedController) {
        if (SDL_memcmp(guid, &pSupportedController->guid, sizeof(*guid)) == 0) {
            return pSupportedController;
        }
        pSupportedController = pSupportedController->next;
    }
    if (guid->data[14] == 'h') {
        /* This is a HIDAPI device */
        return s_pHIDAPIMapping;
    }
#if SDL_JOYSTICK_XINPUT
    if (guid->data[14] == 'x') {
        /* This is an XInput device */
        return s_pXInputMapping;
    }
#endif
    return NULL;
}

static const char* map_StringForControllerAxis[] = {
    "leftx",
    "lefty",
    "rightx",
    "righty",
    "lefttrigger",
    "righttrigger",
    NULL
};

/*
 * convert a string to its enum equivalent
 */
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const char *pchString)
{
    int entry;

    if (pchString && (*pchString == '+' || *pchString == '-')) {
        ++pchString;
    }

    if (!pchString || !pchString[0]) {
        return SDL_CONTROLLER_AXIS_INVALID;
    }

    for (entry = 0; map_StringForControllerAxis[entry]; ++entry) {
        if (!SDL_strcasecmp(pchString, map_StringForControllerAxis[entry]))
            return (SDL_GameControllerAxis) entry;
    }
    return SDL_CONTROLLER_AXIS_INVALID;
}

/*
 * convert an enum to its string equivalent
 */
const char* SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis)
{
    if (axis > SDL_CONTROLLER_AXIS_INVALID && axis < SDL_CONTROLLER_AXIS_MAX) {
        return map_StringForControllerAxis[axis];
    }
    return NULL;
}

static const char* map_StringForControllerButton[] = {
    "a",
    "b",
    "x",
    "y",
    "back",
    "guide",
    "start",
    "leftstick",
    "rightstick",
    "leftshoulder",
    "rightshoulder",
    "dpup",
    "dpdown",
    "dpleft",
    "dpright",
    NULL
};

/*
 * convert a string to its enum equivalent
 */
SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const char *pchString)
{
    int entry;
    if (!pchString || !pchString[0])
        return SDL_CONTROLLER_BUTTON_INVALID;

    for (entry = 0; map_StringForControllerButton[entry]; ++entry) {
        if (SDL_strcasecmp(pchString, map_StringForControllerButton[entry]) == 0)
            return (SDL_GameControllerButton) entry;
    }
    return SDL_CONTROLLER_BUTTON_INVALID;
}

/*
 * convert an enum to its string equivalent
 */
const char* SDL_GameControllerGetStringForButton(SDL_GameControllerButton axis)
{
    if (axis > SDL_CONTROLLER_BUTTON_INVALID && axis < SDL_CONTROLLER_BUTTON_MAX) {
        return map_StringForControllerButton[axis];
    }
    return NULL;
}

/*
 * given a controller button name and a joystick name update our mapping structure with it
 */
static void SDL_PrivateGameControllerParseElement(SDL_GameController *gamecontroller, const char *szGameButton, const char *szJoystickButton)
{
    SDL_ExtendedGameControllerBind bind;
    SDL_GameControllerButton button;
    SDL_GameControllerAxis axis;
    SDL_bool invert_input = SDL_FALSE;
    char half_axis_input = 0;
    char half_axis_output = 0;

    if (*szGameButton == '+' || *szGameButton == '-') {
        half_axis_output = *szGameButton++;
    }

    axis = SDL_GameControllerGetAxisFromString(szGameButton);
    button = SDL_GameControllerGetButtonFromString(szGameButton);
    if (axis != SDL_CONTROLLER_AXIS_INVALID) {
        bind.outputType = SDL_CONTROLLER_BINDTYPE_AXIS;
        bind.output.axis.axis = axis;
        if (axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT || axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) {
            bind.output.axis.axis_min = 0;
            bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
        } else {
            if (half_axis_output == '+') {
                bind.output.axis.axis_min = 0;
                bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
            } else if (half_axis_output == '-') {
                bind.output.axis.axis_min = 0;
                bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
            } else {
                bind.output.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
                bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
            }
        }
    } else if (button != SDL_CONTROLLER_BUTTON_INVALID) {
        bind.outputType = SDL_CONTROLLER_BINDTYPE_BUTTON;
        bind.output.button = button;
    } else {
        SDL_SetError("Unexpected controller element %s", szGameButton);
        return;
    }

    if (*szJoystickButton == '+' || *szJoystickButton == '-') {
        half_axis_input = *szJoystickButton++;
    }
    if (szJoystickButton[SDL_strlen(szJoystickButton) - 1] == '~') {
        invert_input = SDL_TRUE;
    }

    if (szJoystickButton[0] == 'a' && SDL_isdigit(szJoystickButton[1])) {
        bind.inputType = SDL_CONTROLLER_BINDTYPE_AXIS;
        bind.input.axis.axis = SDL_atoi(&szJoystickButton[1]);
        if (half_axis_input == '+') {
            bind.input.axis.axis_min = 0;
            bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
        } else if (half_axis_input == '-') {
            bind.input.axis.axis_min = 0;
            bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
        } else {
            bind.input.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
            bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
        }
        if (invert_input) {
            int tmp = bind.input.axis.axis_min;
            bind.input.axis.axis_min = bind.input.axis.axis_max;
            bind.input.axis.axis_max = tmp;
        }
    } else if (szJoystickButton[0] == 'b' && SDL_isdigit(szJoystickButton[1])) {
        bind.inputType = SDL_CONTROLLER_BINDTYPE_BUTTON;
        bind.input.button = SDL_atoi(&szJoystickButton[1]);
    } else if (szJoystickButton[0] == 'h' && SDL_isdigit(szJoystickButton[1]) &&
               szJoystickButton[2] == '.' && SDL_isdigit(szJoystickButton[3])) {
        int hat = SDL_atoi(&szJoystickButton[1]);
        int mask = SDL_atoi(&szJoystickButton[3]);
        bind.inputType = SDL_CONTROLLER_BINDTYPE_HAT;
        bind.input.hat.hat = hat;
        bind.input.hat.hat_mask = mask;
    } else {
        SDL_SetError("Unexpected joystick element: %s", szJoystickButton);
        return;
    }

    ++gamecontroller->num_bindings;
    gamecontroller->bindings = (SDL_ExtendedGameControllerBind *)SDL_realloc(gamecontroller->bindings, gamecontroller->num_bindings * sizeof(*gamecontroller->bindings));
    if (!gamecontroller->bindings) {
        gamecontroller->num_bindings = 0;
        SDL_OutOfMemory();
        return;
    }
    gamecontroller->bindings[gamecontroller->num_bindings - 1] = bind;
}


/*
 * given a controller mapping string update our mapping object
 */
static void
SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecontroller, const char *pchString)
{
    char szGameButton[20];
    char szJoystickButton[20];
    SDL_bool bGameButton = SDL_TRUE;
    int i = 0;
    const char *pchPos = pchString;

    SDL_zero(szGameButton);
    SDL_zero(szJoystickButton);

    while (pchPos && *pchPos) {
        if (*pchPos == ':') {
            i = 0;
            bGameButton = SDL_FALSE;
        } else if (*pchPos == ' ') {

        } else if (*pchPos == ',') {
            i = 0;
            bGameButton = SDL_TRUE;
            SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
            SDL_zero(szGameButton);
            SDL_zero(szJoystickButton);

        } else if (bGameButton) {
            if (i >= sizeof(szGameButton)) {
                SDL_SetError("Button name too large: %s", szGameButton);
                return;
            }
            szGameButton[i] = *pchPos;
            i++;
        } else {
            if (i >= sizeof(szJoystickButton)) {
                SDL_SetError("Joystick button name too large: %s", szJoystickButton);
                return;
            }
            szJoystickButton[i] = *pchPos;
            i++;
        }
        pchPos++;
    }

    SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);

}

/*
 * Make a new button mapping struct
 */
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)
{
    int i;

    gamecontroller->guid = guid;
    gamecontroller->name = pchName;
    gamecontroller->num_bindings = 0;
    SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));

    SDL_PrivateGameControllerParseControllerConfigString(gamecontroller, pchMapping);

    /* Set the zero point for triggers */
    for (i = 0; i < gamecontroller->num_bindings; ++i) {
        SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
        if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
            binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
            (binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ||
             binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) {
            if (binding->input.axis.axis < gamecontroller->joystick->naxes) {
                gamecontroller->joystick->axes[binding->input.axis.axis].value =
                gamecontroller->joystick->axes[binding->input.axis.axis].zero = (Sint16)binding->input.axis.axis_min;
            }
        }
    }
}


/*
 * grab the guid string from a mapping string
 */
static char *SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping)
{
    const char *pFirstComma = SDL_strchr(pMapping, ',');
    if (pFirstComma) {
        char *pchGUID = SDL_malloc(pFirstComma - pMapping + 1);
        if (!pchGUID) {
            SDL_OutOfMemory();
            return NULL;
        }
        SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping);
        pchGUID[pFirstComma - pMapping] = '\0';

        /* Convert old style GUIDs to the new style in 2.0.5 */
#if __WIN32__
        if (SDL_strlen(pchGUID) == 32 &&
            SDL_memcmp(&pchGUID[20], "504944564944", 12) == 0) {
            SDL_memcpy(&pchGUID[20], "000000000000", 12);
            SDL_memcpy(&pchGUID[16], &pchGUID[4], 4);
            SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
            SDL_memcpy(&pchGUID[0], "03000000", 8);
        }
#elif __MACOSX__
        if (SDL_strlen(pchGUID) == 32 &&
            SDL_memcmp(&pchGUID[4], "000000000000", 12) == 0 &&
            SDL_memcmp(&pchGUID[20], "000000000000", 12) == 0) {
            SDL_memcpy(&pchGUID[20], "000000000000", 12);
            SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
            SDL_memcpy(&pchGUID[0], "03000000", 8);
        }
#endif
        return pchGUID;
    }
    return NULL;
}


/*
 * grab the name string from a mapping string
 */
static char *SDL_PrivateGetControllerNameFromMappingString(const char *pMapping)
{
    const char *pFirstComma, *pSecondComma;
    char *pchName;

    pFirstComma = SDL_strchr(pMapping, ',');
    if (!pFirstComma)
        return NULL;

    pSecondComma = SDL_strchr(pFirstComma + 1, ',');
    if (!pSecondComma)
        return NULL;

    pchName = SDL_malloc(pSecondComma - pFirstComma);
    if (!pchName) {
        SDL_OutOfMemory();
        return NULL;
    }
    SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma);
    pchName[pSecondComma - pFirstComma - 1] = 0;
    return pchName;
}


/*
 * grab the button mapping string from a mapping string
 */
static char *SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
{
    const char *pFirstComma, *pSecondComma;

    pFirstComma = SDL_strchr(pMapping, ',');
    if (!pFirstComma)
        return NULL;

    pSecondComma = SDL_strchr(pFirstComma + 1, ',');
    if (!pSecondComma)
        return NULL;

    return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
}

/*
 * Helper function to refresh a mapping
 */
static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
{
    SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
    while (gamecontrollerlist) {
        if (!SDL_memcmp(&gamecontrollerlist->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
            SDL_Event event;
            event.type = SDL_CONTROLLERDEVICEREMAPPED;
            event.cdevice.which = gamecontrollerlist->joystick->instance_id;
            SDL_PushEvent(&event);

            /* Not really threadsafe.  Should this lock access within SDL_GameControllerEventWatcher? */
            SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
        }

        gamecontrollerlist = gamecontrollerlist->next;
    }
}

/*
 * Helper function to add a mapping for a guid
 */
static ControllerMapping_t *
SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority)
{
    char *pchName;
    char *pchMapping;
    ControllerMapping_t *pControllerMapping;

    pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString);
    if (!pchName) {
        SDL_SetError("Couldn't parse name from %s", mappingString);
        return NULL;
    }

    pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString);
    if (!pchMapping) {
        SDL_free(pchName);
        SDL_SetError("Couldn't parse %s", mappingString);
        return NULL;
    }

    pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
    if (pControllerMapping) {
        /* Only overwrite the mapping if the priority is the same or higher. */
        if (pControllerMapping->priority <= priority) {
            /* Update existing mapping */
            SDL_free(pControllerMapping->name);
            pControllerMapping->name = pchName;
            SDL_free(pControllerMapping->mapping);
            pControllerMapping->mapping = pchMapping;
            pControllerMapping->priority = priority;
            /* refresh open controllers */
            SDL_PrivateGameControllerRefreshMapping(pControllerMapping);
        } else {
            SDL_free(pchName);
            SDL_free(pchMapping);
        }
        *existing = SDL_TRUE;
    } else {
        pControllerMapping = SDL_malloc(sizeof(*pControllerMapping));
        if (!pControllerMapping) {
            SDL_free(pchName);
            SDL_free(pchMapping);
            SDL_OutOfMemory();
            return NULL;
        }
        pControllerMapping->guid = jGUID;
        pControllerMapping->name = pchName;
        pControllerMapping->mapping = pchMapping;
        pControllerMapping->next = NULL;
        pControllerMapping->priority = priority;

        if (s_pSupportedControllers) {
            /* Add the mapping to the end of the list */
            ControllerMapping_t *pCurrMapping, *pPrevMapping;

            for ( pPrevMapping = s_pSupportedControllers, pCurrMapping = pPrevMapping->next;
                  pCurrMapping; 
                  pPrevMapping = pCurrMapping, pCurrMapping = pCurrMapping->next ) {
                continue;
            }
            pPrevMapping->next = pControllerMapping;
        } else {
            s_pSupportedControllers = pControllerMapping;
        }
        *existing = SDL_FALSE;
    }
    return pControllerMapping;
}

#ifdef __ANDROID__
/*
 * Helper function to guess at a mapping based on the elements reported for this controller
 */
static ControllerMapping_t *SDL_CreateMappingForAndroidController(const char *name, SDL_JoystickGUID guid)
{
    SDL_bool existing;
    char name_string[128];
    char mapping_string[1024];
    int button_mask;
    int axis_mask;

    button_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-4]));
    axis_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-2]));
    if (!button_mask && !axis_mask) {
        /* Accelerometer, shouldn't have a game controller mapping */
        return NULL;
    }

    /* Remove any commas in the name */
    SDL_strlcpy(name_string, name, sizeof(name_string));
    {
        char *spot;
        for (spot = name_string; *spot; ++spot) {
            if (*spot == ',') {
                *spot = ' ';
            }
        }
    }
    SDL_snprintf(mapping_string, sizeof(mapping_string), "none,%s,", name_string);
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_A)) {
        SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_B)) {
        SDL_strlcat(mapping_string, "b:b1,", sizeof(mapping_string));
    } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
        /* Use the back button as "B" for easy UI navigation with TV remotes */
        SDL_strlcat(mapping_string, "b:b4,", sizeof(mapping_string));
        button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_BACK);
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_X)) {
        SDL_strlcat(mapping_string, "x:b2,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_Y)) {
        SDL_strlcat(mapping_string, "y:b3,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
        SDL_strlcat(mapping_string, "back:b4,", sizeof(mapping_string));
    }
#if 0 /* The guide button generally isn't functional (or acts as a home button) on most Android controllers */
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) {
        SDL_strlcat(mapping_string, "guide:b5,", sizeof(mapping_string));
#if 0 /* Actually this will be done in Steam */
    } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
        /* The guide button doesn't exist, use the start button instead,
           so you can do Steam guide button chords and open the Steam overlay.
         */
        SDL_strlcat(mapping_string, "guide:b6,", sizeof(mapping_string));
        button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_START);
#endif
    }
#endif
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
        SDL_strlcat(mapping_string, "start:b6,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) {
        SDL_strlcat(mapping_string, "leftstick:b7,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) {
        SDL_strlcat(mapping_string, "rightstick:b8,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) {
        SDL_strlcat(mapping_string, "leftshoulder:b9,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) {
        SDL_strlcat(mapping_string, "rightshoulder:b10,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP)) {
        SDL_strlcat(mapping_string, "dpup:b11,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN)) {
        SDL_strlcat(mapping_string, "dpdown:b12,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT)) {
        SDL_strlcat(mapping_string, "dpleft:b13,", sizeof(mapping_string));
    }
    if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
        SDL_strlcat(mapping_string, "dpright:b14,", sizeof(mapping_string));
    }
    if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX)) {
        SDL_strlcat(mapping_string, "leftx:a0,", sizeof(mapping_string));
    }
    if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY)) {
        SDL_strlcat(mapping_string, "lefty:a1,", sizeof(mapping_string));
    }
    if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX)) {
        SDL_strlcat(mapping_string, "rightx:a2,", sizeof(mapping_string));
    }
    if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY)) {
        SDL_strlcat(mapping_string, "righty:a3,", sizeof(mapping_string));
    }
    if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT)) {
        SDL_strlcat(mapping_string, "lefttrigger:a4,", sizeof(mapping_string));
    }
    if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) {
        SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string));
    }
    return SDL_PrivateAddMappingForGUID(guid, mapping_string,
                      &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
#endif /* __ANDROID__ */


/*
 * Helper function to determine pre-calculated offset to certain joystick mappings
 */
static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const char *name, SDL_JoystickGUID guid)
{
    ControllerMapping_t *mapping;

    mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
#ifdef __LINUX__
    if (!mapping && name) {
        if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
            /* The Linux driver xpad.c maps the wireless dpad to buttons */
            SDL_bool existing;
            mapping = SDL_PrivateAddMappingForGUID(guid,
"none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
                          &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
        }
    }
#endif /* __LINUX__ */

    if (!mapping && name) {
        if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) {
            mapping = s_pXInputMapping;
        }
    }
#ifdef __ANDROID__
    if (!mapping) {
        mapping = SDL_CreateMappingForAndroidController(name, guid);
    }
#endif
    if (!mapping) {
        mapping = s_pDefaultMapping;
    }
    return mapping;
}

static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
{
    const char *name;
    SDL_JoystickGUID guid;
    ControllerMapping_t *mapping;

    SDL_LockJoysticks();

    if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
        SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
        SDL_UnlockJoysticks();
        return (NULL);
    }

    name = SDL_JoystickNameForIndex(device_index);
    guid = SDL_JoystickGetDeviceGUID(device_index);
    mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid);
    SDL_UnlockJoysticks();
    return mapping;
}

/*
 * Add or update an entry into the Mappings Database
 */
int
SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw)
{
    const char *platform = SDL_GetPlatform();
    int controllers = 0;
    char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
    size_t db_size, platform_len;
    
    if (rw == NULL) {
        return SDL_SetError("Invalid RWops");
    }
    db_size = (size_t)SDL_RWsize(rw);
    
    buf = (char *)SDL_malloc(db_size + 1);
    if (buf == NULL) {
        if (freerw) {
            SDL_RWclose(rw);
        }
        return SDL_SetError("Could not allocate space to read DB into memory");
    }
    
    if (SDL_RWread(rw, buf, db_size, 1) != 1) {
        if (freerw) {
            SDL_RWclose(rw);
        }
        SDL_free(buf);
        return SDL_SetError("Could not read DB");
    }
    
    if (freerw) {
        SDL_RWclose(rw);
    }
    
    buf[db_size] = '\0';
    line = buf;
    
    while (line < buf + db_size) {
        line_end = SDL_strchr(line, '\n');
        if (line_end != NULL) {
            *line_end = '\0';
        } else {
            line_end = buf + db_size;
        }
        
        /* Extract and verify the platform */
        tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD);
        if (tmp != NULL) {
            tmp += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD);
            comma = SDL_strchr(tmp, ',');
            if (comma != NULL) {
                platform_len = comma - tmp + 1;
                if (platform_len + 1 < SDL_arraysize(line_platform)) {
                    SDL_strlcpy(line_platform, tmp, platform_len);
                    if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 &&
                        SDL_GameControllerAddMapping(line) > 0) {
                        controllers++;
                    }
                }
            }
        }
        
        line = line_end + 1;
    }

    SDL_free(buf);
    return controllers;
}

/*
 * Add or update an entry into the Mappings Database with a priority
 */
static int
SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority)
{
    char *pchGUID;
    SDL_JoystickGUID jGUID;
    SDL_bool is_default_mapping = SDL_FALSE;
    SDL_bool is_hidapi_mapping = SDL_FALSE;
    SDL_bool is_xinput_mapping = SDL_FALSE;
    SDL_bool existing = SDL_FALSE;
    ControllerMapping_t *pControllerMapping;

    if (!mappingString) {
        return SDL_InvalidParamError("mappingString");
    }

    pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString);
    if (!pchGUID) {
        return SDL_SetError("Couldn't parse GUID from %s", mappingString);
    }
    if (!SDL_strcasecmp(pchGUID, "default")) {
        is_default_mapping = SDL_TRUE;
    } else if (!SDL_strcasecmp(pchGUID, "hidapi")) {
        is_hidapi_mapping = SDL_TRUE;
    } else if (!SDL_strcasecmp(pchGUID, "xinput")) {
        is_xinput_mapping = SDL_TRUE;
    }
    jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
    SDL_free(pchGUID);

    pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing, priority);
    if (!pControllerMapping) {
        return -1;
    }

    if (existing) {
        return 0;
    } else {
        if (is_default_mapping) {
            s_pDefaultMapping = pControllerMapping;
        } else if (is_hidapi_mapping) {
            s_pHIDAPIMapping = pControllerMapping;
        } else if (is_xinput_mapping) {
            s_pXInputMapping = pControllerMapping;
        }
        return 1;
    }
}

/*
 * Add or update an entry into the Mappings Database
 */
int
SDL_GameControllerAddMapping(const char *mappingString)
{
    return SDL_PrivateGameControllerAddMapping(mappingString, SDL_CONTROLLER_MAPPING_PRIORITY_API);
}

/*
 *  Get the number of mappings installed
 */
int
SDL_GameControllerNumMappings(void)
{
    int num_mappings = 0;
    ControllerMapping_t *mapping;

    for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) {
        if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
            continue;
        }
        ++num_mappings;
    }
    return num_mappings;
}

/*
 *  Get the mapping at a particular index.
 */
char *
SDL_GameControllerMappingForIndex(int mapping_index)
{
    ControllerMapping_t *mapping;

    for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) {
        if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
            continue;
        }
        if (mapping_index == 0) {
            char *pMappingString;
            char pchGUID[33];
            size_t needed;

            SDL_JoystickGetGUIDString(mapping->guid, pchGUID, sizeof(pchGUID));
            /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
            needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
            pMappingString = SDL_malloc(needed);
            if (!pMappingString) {
                SDL_OutOfMemory();
                return NULL;
            }
            SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
            return pMappingString;
        }
        --mapping_index;
    }
    return NULL;
}

/*
 * Get the mapping string for this GUID
 */
char *
SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)
{
    char *pMappingString = NULL;
    ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
    if (mapping) {
        char pchGUID[33];
        size_t needed;
        SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
        /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
        needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
        pMappingString = SDL_malloc(needed);
        if (!pMappingString) {
            SDL_OutOfMemory();
            return NULL;
        }
        SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
    }
    return pMappingString;
}

/*
 * Get the mapping string for this device
 */
char *
SDL_GameControllerMapping(SDL_GameController * gamecontroller)
{
    if (!gamecontroller) {
        return NULL;
    }

    return SDL_GameControllerMappingForGUID(gamecontroller->guid);
}

static void
SDL_GameControllerLoadHints()
{
    const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
    if (hint && hint[0]) {
        size_t nchHints = SDL_strlen(hint);
        char *pUserMappings = SDL_malloc(nchHints + 1);
        char *pTempMappings = pUserMappings;
        SDL_memcpy(pUserMappings, hint, nchHints);
        pUserMappings[nchHints] = '\0';
        while (pUserMappings) {
            char *pchNewLine = NULL;

            pchNewLine = SDL_strchr(pUserMappings, '\n');
            if (pchNewLine)
                *pchNewLine = '\0';

            SDL_PrivateGameControllerAddMapping(pUserMappings, SDL_CONTROLLER_MAPPING_PRIORITY_USER);

            if (pchNewLine) {
                pUserMappings = pchNewLine + 1;
            } else {
                pUserMappings = NULL;
            }
        }
        SDL_free(pTempMappings);
    }
}

/*
 * Fill the given buffer with the expected controller mapping filepath. 
 * Usually this will just be CONTROLLER_MAPPING_FILE, but for Android,
 * we want to get the internal storage path.
 */
static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size)
{
#ifdef CONTROLLER_MAPPING_FILE
#define STRING(X) SDL_STRINGIFY_ARG(X)
    return SDL_strlcpy(path, STRING(CONTROLLER_MAPPING_FILE), size) < size;
#elif defined(__ANDROID__)
    return SDL_snprintf(path, size, "%s/controller_map.txt", SDL_AndroidGetInternalStoragePath()) < size;
#else
    return SDL_FALSE;
#endif
}

/*
 * Initialize the game controller system, mostly load our DB of controller config mappings
 */
int
SDL_GameControllerInitMappings(void)
{
    char szControllerMapPath[1024];
    int i = 0;
    const char *pMappingString = NULL;
    pMappingString = s_ControllerMappings[i];
    while (pMappingString) {
        SDL_PrivateGameControllerAddMapping(pMappingString, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);

        i++;
        pMappingString = s_ControllerMappings[i];
    }

    if (SDL_GetControllerMappingFilePath(szControllerMapPath, sizeof(szControllerMapPath))) {
        SDL_GameControllerAddMappingsFromFile(szControllerMapPath);        
    }

    /* load in any user supplied config */
    SDL_GameControllerLoadHints();

    SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES,
                        SDL_GameControllerIgnoreDevicesChanged, NULL);
    SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT,
                        SDL_GameControllerIgnoreDevicesExceptChanged, NULL);

    return (0);
}

int
SDL_GameControllerInit(void)
{
    int i;

    /* watch for joy events and fire controller ones if needed */
    SDL_AddEventWatch(SDL_GameControllerEventWatcher, NULL);

    /* Send added events for controllers currently attached */
    for (i = 0; i < SDL_NumJoysticks(); ++i) {
        if (SDL_IsGameController(i)) {
            SDL_Event deviceevent;
            deviceevent.type = SDL_CONTROLLERDEVICEADDED;
            deviceevent.cdevice.which = i;
            SDL_PushEvent(&deviceevent);
        }
    }

    return (0);
}


/*
 * Get the implementation dependent name of a controller
 */
const char *
SDL_GameControllerNameForIndex(int device_index)
{
    ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
    if (pSupportedController) {
        if (SDL_strcmp(pSupportedController->name, "*") == 0) {
            return SDL_JoystickNameForIndex(device_index);
        } else {
            return pSupportedController->name;
        }
    }
    return NULL;
}


/**
 *  Get the mapping of a game controller.
 *  This can be called before any controllers are opened.
 *  If no mapping can be found, this function returns NULL.
 */
char *
SDL_GameControllerMappingForDeviceIndex(int joystick_index)
{
    char *pMappingString = NULL;
    ControllerMapping_t *mapping;

    SDL_LockJoysticks();
    mapping = SDL_PrivateGetControllerMapping(joystick_index);
    if (mapping) {
        SDL_JoystickGUID guid;
        char pchGUID[33];
        size_t needed;
        guid = SDL_JoystickGetDeviceGUID(joystick_index);
        SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
        /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
        needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
        pMappingString = SDL_malloc(needed);
        if (!pMappingString) {
            SDL_OutOfMemory();
            SDL_UnlockJoysticks();
            return NULL;
        }
        SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
    }
    SDL_UnlockJoysticks();
    return pMappingString;
}


/*
 * Return 1 if the joystick with this name and GUID is a supported controller
 */
SDL_bool
SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid)
{
    ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid);
    if (pSupportedController) {
        return SDL_TRUE;
    }
    return SDL_FALSE;
}

/*
 * Return 1 if the joystick at this device index is a supported controller
 */
SDL_bool
SDL_IsGameController(int device_index)
{
    ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
    if (pSupportedController) {
        return SDL_TRUE;
    }
    return SDL_FALSE;
}

/*
 * Return 1 if the game controller should be ignored by SDL
 */
SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
{
    int i;
    Uint16 vendor;
    Uint16 product;
    Uint32 vidpid;

    if (SDL_allowed_controllers.num_entries == 0 &&
        SDL_ignored_controllers.num_entries == 0) {
        return SDL_FALSE;
    }

    SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);

    if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
        /* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */
        SDL_bool bSteamVirtualGamepad = SDL_FALSE;
#if defined(__LINUX__)
        bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
#elif defined(__MACOSX__)
        bSteamVirtualGamepad = (SDL_strncmp(name, "GamePad-", 8) == 0);
#elif defined(__WIN32__)
        /* We can't tell on Windows, but Steam will block others in input hooks */
        bSteamVirtualGamepad = SDL_TRUE;
#endif
        if (bSteamVirtualGamepad) {
            return SDL_FALSE;
        }
    }

    vidpid = MAKE_VIDPID(vendor, product);

    if (SDL_allowed_controllers.num_entries > 0) {
        for (i = 0; i < SDL_allowed_controllers.num_entries; ++i) {
            if (vidpid == SDL_allowed_controllers.entries[i]) {
                return SDL_FALSE;
            }
        }
        return SDL_TRUE;
    } else {
        for (i = 0; i < SDL_ignored_controllers.num_entries; ++i) {
            if (vidpid == SDL_ignored_controllers.entries[i]) {
                return SDL_TRUE;
            }
        }
        return SDL_FALSE;
    }
}

/*
 * Open a controller for use - the index passed as an argument refers to
 * the N'th controller on the system.  This index is the value which will
 * identify this controller in future controller events.
 *
 * This function returns a controller identifier, or NULL if an error occurred.
 */
SDL_GameController *
SDL_GameControllerOpen(int device_index)
{
    SDL_JoystickID instance_id;
    SDL_GameController *gamecontroller;
    SDL_GameController *gamecontrollerlist;
    ControllerMapping_t *pSupportedController = NULL;

    SDL_LockJoysticks();

    gamecontrollerlist = SDL_gamecontrollers;
    /* If the controller is already open, return it */
    instance_id = SDL_JoystickGetDeviceInstanceID(device_index);
    while (gamecontrollerlist) {
        if (instance_id == gamecontrollerlist->joystick->instance_id) {
                gamecontroller = gamecontrollerlist;
                ++gamecontroller->ref_count;
                SDL_UnlockJoysticks();
                return (gamecontroller);
        }
        gamecontrollerlist = gamecontrollerlist->next;
    }

    /* Find a controller mapping */
    pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
    if (!pSupportedController) {
        SDL_SetError("Couldn't find mapping for device (%d)", device_index);
        SDL_UnlockJoysticks();
        return NULL;
    }

    /* Create and initialize the controller */
    gamecontroller = (SDL_GameController *) SDL_calloc(1, sizeof(*gamecontroller));
    if (gamecontroller == NULL) {
        SDL_OutOfMemory();
        SDL_UnlockJoysticks();
        return NULL;
    }

    gamecontroller->joystick = SDL_JoystickOpen(device_index);
    if (!gamecontroller->joystick) {
        SDL_free(gamecontroller);
        SDL_UnlockJoysticks();
        return NULL;
    }

    if (gamecontroller->joystick->naxes) {
        gamecontroller->last_match_axis = (SDL_ExtendedGameControllerBind **)SDL_calloc(gamecontroller->joystick->naxes, sizeof(*gamecontroller->last_match_axis));
        if (!gamecontroller->last_match_axis) {
            SDL_OutOfMemory();
            SDL_JoystickClose(gamecontroller->joystick);
            SDL_free(gamecontroller);
            SDL_UnlockJoysticks();
            return NULL;
        }
    }
    if (gamecontroller->joystick->nhats) {
        gamecontroller->last_hat_mask = (Uint8 *)SDL_calloc(gamecontroller->joystick->nhats, sizeof(*gamecontroller->last_hat_mask));
        if (!gamecontroller->last_hat_mask) {
            SDL_OutOfMemory();
            SDL_JoystickClose(gamecontroller->joystick);
            SDL_free(gamecontroller->last_match_axis);
            SDL_free(gamecontroller);
            SDL_UnlockJoysticks();
            return NULL;
        }
    }

    SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping);

    /* Add the controller to list */
    ++gamecontroller->ref_count;
    /* Link the controller in the list */
    gamecontroller->next = SDL_gamecontrollers;
    SDL_gamecontrollers = gamecontroller;

    SDL_UnlockJoysticks();

    return (gamecontroller);
}

/*
 * Manually pump for controller updates.
 */
void
SDL_GameControllerUpdate(void)
{
    /* Just for API completeness; the joystick API does all the work. */
    SDL_JoystickUpdate();
}

/*
 * Get the current state of an axis control on a controller
 */
Sint16
SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
{
    int i;

    if (!gamecontroller)
        return 0;

    for (i = 0; i < gamecontroller->num_bindings; ++i) {
        SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
        if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
            int value = 0;
            SDL_bool valid_input_range;
            SDL_bool valid_output_range;

            if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
                value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
                if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
                    valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
                } else {
                    valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
                }
                if (valid_input_range) {
                    if (binding->input.axis.axis_min != binding->output.axis.axis_min || binding->input.axis.axis_max != binding->output.axis.axis_max) {
                        float normalized_value = (float)(value - binding->input.axis.axis_min) / (binding->input.axis.axis_max - binding->input.axis.axis_min);
                        value = binding->output.axis.axis_min + (int)(normalized_value * (binding->output.axis.axis_max - binding->output.axis.axis_min));
                    }
                }
            } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
                value = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
                if (value == SDL_PRESSED) {
                    value = binding->output.axis.axis_max;
                }
            } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
                int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
                if (hat_mask & binding->input.hat.hat_mask) {
                    value = binding->output.axis.axis_max;
                }
            }

            if (binding->output.axis.axis_min < binding->output.axis.axis_max) {
                valid_output_range = (value >= binding->output.axis.axis_min && value <= binding->output.axis.axis_max);
            } else {
                valid_output_range = (value >= binding->output.axis.axis_max && value <= binding->output.axis.axis_min);
            }
            /* If the value is zero, there might be another binding that makes it non-zero */
            if (value != 0 && valid_output_range) {
                return (Sint16)value;
            }
        }
    }
    return 0;
}

/*
 * Get the current state of a button on a controller
 */
Uint8
SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
{
    int i;

    if (!gamecontroller)
        return 0;

    for (i = 0; i < gamecontroller->num_bindings; ++i) {
        SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
        if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
            if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
                SDL_bool valid_input_range;

                int value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
                int threshold = binding->input.axis.axis_min + (binding->input.axis.axis_max - binding->input.axis.axis_min) / 2;
                if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
                    valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
                    if (valid_input_range) {
                        return (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
                    }
                } else {
                    valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
                    if (valid_input_range) {
                        return (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
                    }
                }
            } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
                return SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
            } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
                int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
                return (hat_mask & binding->input.hat.hat_mask) ? SDL_PRESSED : SDL_RELEASED;
            }
        }
    }
    return SDL_RELEASED;
}

const char *
SDL_GameControllerName(SDL_GameController * gamecontroller)
{
    if (!gamecontroller)
        return NULL;

    if (SDL_strcmp(gamecontroller->name, "*") == 0) {
        return SDL_JoystickName(SDL_GameControllerGetJoystick(gamecontroller));
    } else {
        return gamecontroller->name;
    }
}

Uint16
SDL_GameControllerGetVendor(SDL_GameController * gamecontroller)
{
    return SDL_JoystickGetVendor(SDL_GameControllerGetJoystick(gamecontroller));
}

Uint16
SDL_GameControllerGetProduct(SDL_GameController * gamecontroller)
{
    return SDL_JoystickGetProduct(SDL_GameControllerGetJoystick(gamecontroller));
}

Uint16
SDL_GameControllerGetProductVersion(SDL_GameController * gamecontroller)
{
    return SDL_JoystickGetProductVersion(SDL_GameControllerGetJoystick(gamecontroller));
}

/*
 * Return if the controller in question is currently attached to the system,
 *  \return 0 if not plugged in, 1 if still present.
 */
SDL_bool
SDL_GameControllerGetAttached(SDL_GameController * gamecontroller)
{
    if (!gamecontroller)
        return SDL_FALSE;

    return SDL_JoystickGetAttached(gamecontroller->joystick);
}

/*
 * Get the joystick for this controller
 */
SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
{
    if (!gamecontroller)
        return NULL;

    return gamecontroller->joystick;
}


/*
 * Find the SDL_GameController that owns this instance id
 */
SDL_GameController *
SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
{
    SDL_GameController *gamecontroller;

    SDL_LockJoysticks();
    gamecontroller = SDL_gamecontrollers;
    while (gamecontroller) {
        if (gamecontroller->joystick->instance_id == joyid) {
            SDL_UnlockJoysticks();
            return gamecontroller;
        }
        gamecontroller = gamecontroller->next;
    }
    SDL_UnlockJoysticks();
    return NULL;
}


/*
 * Get the SDL joystick layer binding for this controller axis mapping
 */
SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
{
    int i;
    SDL_GameControllerButtonBind bind;
    SDL_zero(bind);

    if (!gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID)
        return bind;

    for (i = 0; i < gamecontroller->num_bindings; ++i) {
        SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
        if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
            bind.bindType = binding->inputType;
            if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
                /* FIXME: There might be multiple axes bound now that we have axis ranges... */
                bind.value.axis = binding->input.axis.axis;
            } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
                bind.value.button = binding->input.button;
            } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
                bind.value.hat.hat = binding->input.hat.hat;
                bind.value.hat.hat_mask = binding->input.hat.hat_mask;
            }
            break;
        }
    }
    return bind;
}


/*
 * Get the SDL joystick layer binding for this controller button mapping
 */
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
{
    int i;
    SDL_GameControllerButtonBind bind;
    SDL_zero(bind);

    if (!gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID)
        return bind;

    for (i = 0; i < gamecontroller->num_bindings; ++i) {
        SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
        if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
            bind.bindType = binding->inputType;
            if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
                bind.value.axis = binding->input.axis.axis;
            } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
                bind.value.button = binding->input.button;
            } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
                bind.value.hat.hat = binding->input.hat.hat;
                bind.value.hat.hat_mask = binding->input.hat.hat_mask;
            }
            break;
        }
    }
    return bind;
}


int
SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
    return SDL_JoystickRumble(SDL_GameControllerGetJoystick(gamecontroller), low_frequency_rumble, high_frequency_rumble, duration_ms);
}

void
SDL_GameControllerClose(SDL_GameController * gamecontroller)
{
    SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;

    if (!gamecontroller)
        return;

    SDL_LockJoysticks();

    /* First decrement ref count */
    if (--gamecontroller->ref_count > 0) {
        SDL_UnlockJoysticks();
        return;
    }

    SDL_JoystickClose(gamecontroller->joystick);

    gamecontrollerlist = SDL_gamecontrollers;
    gamecontrollerlistprev = NULL;
    while (gamecontrollerlist) {
        if (gamecontroller == gamecontrollerlist) {
            if (gamecontrollerlistprev) {
                /* unlink this entry */
                gamecontrollerlistprev->next = gamecontrollerlist->next;
            } else {
                SDL_gamecontrollers = gamecontroller->next;
            }
            break;
        }
        gamecontrollerlistprev = gamecontrollerlist;
        gamecontrollerlist = gamecontrollerlist->next;
    }

    SDL_free(gamecontroller->bindings);
    SDL_free(gamecontroller->last_match_axis);
    SDL_free(gamecontroller->last_hat_mask);
    SDL_free(gamecontroller);

    SDL_UnlockJoysticks();
}


/*
 * Quit the controller subsystem
 */
void
SDL_GameControllerQuit(void)
{
    SDL_LockJoysticks();
    while (SDL_gamecontrollers) {
        SDL_gamecontrollers->ref_count = 1;
        SDL_GameControllerClose(SDL_gamecontrollers);
    }
    SDL_UnlockJoysticks();
}

void
SDL_GameControllerQuitMappings(void)
{
    ControllerMapping_t *pControllerMap;

    while (s_pSupportedControllers) {
        pControllerMap = s_pSupportedControllers;
        s_pSupportedControllers = s_pSupportedControllers->next;
        SDL_free(pControllerMap->name);
        SDL_free(pControllerMap->mapping);
        SDL_free(pControllerMap);
    }

    SDL_DelEventWatch(SDL_GameControllerEventWatcher, NULL);

    SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES,
                        SDL_GameControllerIgnoreDevicesChanged, NULL);
    SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT,
                        SDL_GameControllerIgnoreDevicesExceptChanged, NULL);

    if (SDL_allowed_controllers.entries) {
        SDL_free(SDL_allowed_controllers.entries);
        SDL_zero(SDL_allowed_controllers);
    }
    if (SDL_ignored_controllers.entries) {
        SDL_free(SDL_ignored_controllers.entries);
        SDL_zero(SDL_ignored_controllers);
    }
}

/*
 * Event filter to transform joystick events into appropriate game controller ones
 */
static int
SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
{
    int posted;

    /* translate the event, if desired */
    posted = 0;
#if !SDL_EVENTS_DISABLED
    if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) {
        SDL_Event event;
        event.type = SDL_CONTROLLERAXISMOTION;
        event.caxis.which = gamecontroller->joystick->instance_id;
        event.caxis.axis = axis;
        event.caxis.value = value;
        posted = SDL_PushEvent(&event) == 1;
    }
#endif /* !SDL_EVENTS_DISABLED */
    return (posted);
}


/*
 * Event filter to transform joystick events into appropriate game controller ones
 */
static int
SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state)
{
    int posted;
#if !SDL_EVENTS_DISABLED
    SDL_Event event;

    if (button == SDL_CONTROLLER_BUTTON_INVALID)
        return (0);

    switch (state) {
    case SDL_PRESSED:
        event.type = SDL_CONTROLLERBUTTONDOWN;
        break;
    case SDL_RELEASED:
        event.type = SDL_CONTROLLERBUTTONUP;
        break;
    default:
        /* Invalid state -- bail */
        return (0);
    }
#endif /* !SDL_EVENTS_DISABLED */

    if (button == SDL_CONTROLLER_BUTTON_GUIDE) {
        Uint32 now = SDL_GetTicks();
        if (state == SDL_PRESSED) {
            gamecontroller->guide_button_down = now;

            if (gamecontroller->joystick->delayed_guide_button) {
                /* Skip duplicate press */
                return (0);
            }
        } else {
            if (!SDL_TICKS_PASSED(now, gamecontroller->guide_button_down+SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS) && !gamecontroller->joystick->force_recentering) {
                gamecontroller->joystick->delayed_guide_button = SDL_TRUE;
                return (0);
            }
            gamecontroller->joystick->delayed_guide_button = SDL_FALSE;
        }
    }

    /* translate the event, if desired */
    posted = 0;
#if !SDL_EVENTS_DISABLED
    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
        event.cbutton.which = gamecontroller->joystick->instance_id;
        event.cbutton.button = button;
        event.cbutton.state = state;
        posted = SDL_PushEvent(&event) == 1;
    }
#endif /* !SDL_EVENTS_DISABLED */
    return (posted);
}

/*
 * Turn off controller events
 */
int
SDL_GameControllerEventState(int state)
{
#if SDL_EVENTS_DISABLED
    return SDL_IGNORE;
#else
    const Uint32 event_list[] = {
        SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP,
        SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_CONTROLLERDEVICEREMAPPED,
    };
    unsigned int i;

    switch (state) {
    case SDL_QUERY:
        state = SDL_IGNORE;
        for (i = 0; i < SDL_arraysize(event_list); ++i) {
            state = SDL_EventState(event_list[i], SDL_QUERY);
            if (state == SDL_ENABLE) {
                break;
            }
        }
        break;
    default:
        for (i = 0; i < SDL_arraysize(event_list); ++i) {
            SDL_EventState(event_list[i], state);
        }
        break;
    }
    return (state);
#endif /* SDL_EVENTS_DISABLED */
}

void
SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick)
{
    SDL_GameController *controllerlist = SDL_gamecontrollers;
    while (controllerlist) {
        if (controllerlist->joystick == joystick) {
            SDL_PrivateGameControllerButton(controllerlist, SDL_CONTROLLER_BUTTON_GUIDE, SDL_RELEASED);
            break;
        }
        controllerlist = controllerlist->next;
    }
}

/* vi: set ts=4 sw=4 expandtab: */
