/* * Open controllers and joysticks */ void S2D_OpenControllers() { char guid_str[33]; // Enumerate joysticks for (int device_index = 0; device_index < SDL_NumJoysticks(); ++device_index) { // Check if joystick supports SDL's game controller interface (a mapping is available) if (SDL_IsGameController(device_index)) { SDL_GameController *controller = SDL_GameControllerOpen(device_index); SDL_JoystickID intance_id = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller)); SDL_JoystickGetGUIDString( SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(controller)), guid_str, 33 ); if (intance_id > last_intance_id) { if (controller) { S2D_Log(S2D_INFO, "Controller #%i: %s\n GUID: %s", intance_id, SDL_GameControllerName(controller), guid_str); } else { S2D_Log(S2D_ERROR, "Could not open controller #%i: %s", intance_id, SDL_GetError()); } last_intance_id = intance_id; } // Controller interface not supported, try to open as joystick } else { SDL_Joystick *joy = SDL_JoystickOpen(device_index); SDL_JoystickID intance_id = SDL_JoystickInstanceID(joy); if (!joy) { S2D_Log(S2D_ERROR, "Could not open controller"); } else if(intance_id > last_intance_id) { SDL_JoystickGetGUIDString( SDL_JoystickGetGUID(joy), guid_str, 33 ); S2D_Log(S2D_INFO, "Controller #%i: %s\n GUID: %s\n Axes: %d\n Buttons: %d\n Balls: %d", intance_id, SDL_JoystickName(joy), guid_str, SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_JoystickNumBalls(joy) ); S2D_Log(S2D_WARN, "Controller #%i does not have a mapping available", intance_id); last_intance_id = intance_id; } } } }
void init() { u32 maxJoysticks = SDL_NumJoysticks(); u32 controllerIndex = 0; for (u32 joystickIndex = 0; joystickIndex < maxJoysticks; joystickIndex++) { if (!SDL_IsGameController(joystickIndex)) continue; if (controllerIndex >= MaximumControllers) break; g_controllerHandles[controllerIndex] = SDL_GameControllerOpen(joystickIndex); controllerIndex++; } }
void GameEngine::CaptureJoystick(int id){ if (SDL_IsGameController(id)){ m_gameController = SDL_GameControllerOpen(id); if(m_gameController){ #ifdef DEBUG const char *name = SDL_GameControllerName(m_gameController); std::cout << "Found a valid controller at index " << id << ", named: " << name << std::endl; delete name; #endif } else{ std::cout << "Error while capturing game controller " << SDL_GetError() << std::endl; } } }
void SDLFrontend::initJoystickAndHaptic () { if (_haptic != nullptr) { SDL_HapticClose(_haptic); _haptic = nullptr; } const int joysticks = SDL_NumJoysticks(); SDL_Haptic *haptic = nullptr; for (int i = 0; i < joysticks; i++) { const char *name; if (SDL_IsGameController(i)) { name = SDL_GameControllerNameForIndex(i); } else { name = SDL_JoystickNameForIndex(i); } SDL_Joystick *joystick = SDL_JoystickOpen(i); info(LOG_CLIENT, String::format("found joystick %s", name ? name : "Unknown Joystick")); info(LOG_CLIENT, String::format("joystick axes: %i", SDL_JoystickNumAxes(joystick))); info(LOG_CLIENT, String::format("joystick hats: %i", SDL_JoystickNumHats(joystick))); info(LOG_CLIENT, String::format("joystick balls: %i", SDL_JoystickNumBalls(joystick))); info(LOG_CLIENT, String::format("joystick buttons: %i", SDL_JoystickNumButtons(joystick))); if (haptic == nullptr) haptic = SDL_HapticOpenFromJoystick(joystick); } if (!joysticks) { info(LOG_CLIENT, "no joysticks found"); } info(LOG_CLIENT, String::format("found %i touch device(s)", SDL_GetNumTouchDevices())); info(LOG_CLIENT, String::format("%i haptic devices", SDL_NumHaptics())); if (haptic == nullptr && SDL_MouseIsHaptic()) { haptic = SDL_HapticOpenFromMouse(); } if (haptic != nullptr) { const bool rumbleSupported = SDL_HapticRumbleSupported(haptic) && SDL_HapticRumbleInit(haptic) == 0; if (rumbleSupported) { info(LOG_CLIENT, "rumble support"); _haptic = haptic; } } if (_haptic == nullptr) { info(LOG_CLIENT, "no rumble support"); } }
photon_input InitInput(){ PrintToLog("INFO: Initializing Input System."); photon_input input; SDL_GameControllerEventState(SDL_ENABLE); SDL_JoystickEventState(SDL_ENABLE); for(int i = 0; i < SDL_NumJoysticks(); i++){ if(SDL_IsGameController(i)){ input.open_controllers.push_back(SDL_GameControllerOpen(i)); }else{ input.open_joysticks.push_back(SDL_JoystickOpen(i)); } } PrintToLog("INFO: Listening for input, press a button on the device you want to use."); return input; }
static SDL_GameController* grab_controller(SDL_GameController* controller) { if (!controller || !SDL_GameControllerGetAttached(controller)) { int32_t i, joystick_count; controller = NULL; joystick_count = SDL_NumJoysticks(); for (i = 0; i < joystick_count; ++i) { if (SDL_IsGameController(i)) { controller = SDL_GameControllerOpen(i); break; } } } return (controller); }
void I_InitGamepad(void) { if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0) C_Warning("Gamepad support couldn't be initialized."); else { int numjoysticks = SDL_NumJoysticks(); for (int i = 0; i < numjoysticks; i++) if ((joystick = SDL_JoystickOpen(i))) if (SDL_IsGameController(i)) { gamecontroller = SDL_GameControllerOpen(i); break; } if (!gamecontroller) SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC); else { const char *name = SDL_GameControllerName(gamecontroller); if (*name) { if (M_StrCaseStr(name, "xinput")) C_Output("An <i><b>XInput</b></i> gamepad is connected."); else C_Output("A <i><b>DirectInput</b></i> gamepad called \"%s\" is connected.", name); } else C_Output("A gamepad is connected."); if (!(haptic = SDL_HapticOpenFromJoystick(joystick)) || SDL_HapticRumbleInit(haptic) < 0) C_Warning("This gamepad doesn't support vibration."); } } gamepadbuttons = 0; gamepadthumbLX = 0; gamepadthumbLY = 0; gamepadthumbRX = 0; gamepadthumbRY = 0; }
C4GamePadOpener::C4GamePadOpener(int iGamepad) { int n = iGamepad; for (int i = 0; i < SDL_NumJoysticks(); i++) if (SDL_IsGameController(i) && n-- == 0) { controller = SDL_GameControllerOpen(i); if (!controller) LogF("SDL: %s", SDL_GetError()); SDL_Joystick *joystick = SDL_GameControllerGetJoystick(controller); haptic = SDL_HapticOpenFromJoystick(joystick); if (haptic && SDL_HapticRumbleSupported(haptic)) SDL_HapticRumbleInit(haptic); else LogF("Gamepad #%d %s does not support rumbling.", SDL_JoystickInstanceID(joystick), SDL_JoystickName(joystick)); break; } if (!controller) LogF("Gamepad %d not available", iGamepad); }
bool Joystick::deviceAdded(const SDL_Event *event) { int which = event->type == SDL_CONTROLLERDEVICEADDED ? event->cdevice.which : event->jdevice.which; if (!m_mapping->matchJoystick(SDL_JoystickGetDeviceGUID(which))) return false; if (event->type == SDL_CONTROLLERDEVICEADDED) { attachGameController(which); } else { if (SDL_IsGameController(which)) { // joystick is a supported game controller // let's wait for the CONTROLLERADDED event to add it return false; } attachJoystick(which); } return true; }
bool Input::init(const std::string& inputDBFilename) { m_Keyboard = new Keyboard(); m_Mouse = new Mouse(); SDL_GameControllerAddMappingsFromFile(inputDBFilename.c_str()); int numOfJoypads = SDL_NumJoysticks(); for (int i = 0; i < numOfJoypads; i++) { //Is the joypad able to use the new controller interface if (SDL_IsGameController(i)) { SDL_GameController *controller = SDL_GameControllerOpen(i); Joypad * joypad = new Joypad(controller); m_AttachedJoypads.push_back(joypad); } } return true; }
/* =============== IN_StartupJoystick =============== */ void IN_StartupJoystick (void) { // abort startup if user requests no joystick if ( gEngfuncs.CheckParm ("-nojoy", NULL ) ) return; // assume no joystick joy_avail = 0; int nJoysticks = SDL_NumJoysticks(); if ( nJoysticks > 0 ) { for ( int i = 0; i < nJoysticks; i++ ) { if ( SDL_IsGameController( i ) ) { s_pJoystick = SDL_GameControllerOpen( i ); if ( s_pJoystick ) { //save the joystick's number of buttons and POV status joy_numbuttons = SDL_CONTROLLER_BUTTON_MAX; joy_haspov = 0; // old button and POV states default to no buttons pressed joy_oldbuttonstate = joy_oldpovstate = 0; // mark the joystick as available and advanced initialization not completed // this is needed as cvars are not available during initialization gEngfuncs.Con_Printf ("joystick found\n\n", SDL_GameControllerName(s_pJoystick)); joy_avail = 1; joy_advancedinit = 0; break; } } } } else { gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); } }
void initializeGamepads() { int numGamepads = std::min<int>(Gosu::numGamepads, SDL_NumJoysticks()); for (int i = 0; i < numGamepads; ++i) { // Prefer the SDL_GameController API... if (SDL_IsGameController(i)) { SDL_GameController *gameController = SDL_GameControllerOpen(i); if (gameController) { gameControllers.push_back(gameController); continue; } } // ...but fall back on the good, old SDL_Joystick API :) SDL_Joystick *joystick = SDL_JoystickOpen(i); if (joystick) { joysticks.push_back(joystick); } } }
//=========================================================================== // XJoystickInit // // Creates and initializes joysticks. // // Parameters: // // Returns: // //=========================================================================== bool XJoystickInit() { int i; SDL_InitSubSystem(SDL_INIT_JOYSTICK); SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); SDL_JoystickEventState(SDL_ENABLE); SDL_GameControllerEventState(SDL_ENABLE); if(!SDL_WasInit(SDL_INIT_JOYSTICK) && SDL_InitSubSystem(SDL_INIT_JOYSTICK)) { std::cout<<"Unable to initialize the joystick subsystem"<<std::endl; return false; } for(i = 0; i < SDL_NumJoysticks(); ++i) { if (SDL_IsGameController(i)) { printf("Index \'%i\' is a compatible controller, named \'%s\'\n", i, SDL_GameControllerNameForIndex(i)); ctrl = SDL_GameControllerOpen(i); joy = SDL_GameControllerGetJoystick(ctrl); break; } else { printf("Index \'%s\' is not a compatible controller.\n", SDL_JoystickNameForIndex(i)); } } if (ctrl) { JoystickAvailable = 1; return true; } for(i = 0; i < SDL_NumJoysticks(); ++i) { joy = SDL_JoystickOpen(i); if (joy) { printf("Index \'%i\' is a compatible joystick, named \'%s\'\n", i, SDL_JoystickNameForIndex(i)); break; } } if (joy) { JoystickAvailable = 1; return true; } else { return false; } }
void GameControllerManager::on_controller_added(int joystick_index) { if (!SDL_IsGameController(joystick_index)) { log_warning << "joystick is not a game controller, ignoring: " << joystick_index << std::endl; } else { SDL_GameController* game_controller = SDL_GameControllerOpen(joystick_index); if (!game_controller) { log_warning << "failed to open game_controller: " << joystick_index << ": " << SDL_GetError() << std::endl; } else { m_game_controllers.push_back(game_controller); } } }
void GeneralManager::init() { for (int i = 0; i < SDL_NumJoysticks(); i++) { if(SDL_IsGameController(i)); { std::cout << "Controller " << i << " assigned\n"; _players.emplace_back(i); } } _numPlayers = _players.size(); MenuController = -1; _levels.emplace_back("Level 1", "Textures/Levels/Level001.png", "Level001.xml"); _levels.emplace_back("Level 2", "Textures/Levels/Level002.png", "Level002.xml"); _levels.emplace_back("Level 3", "Textures/Levels/Level003.png", "Level003.xml"); _levels.emplace_back("Level 4", "Textures/Levels/Level004.png", "Level004.xml"); _levels.emplace_back("Level 5", "Textures/Levels/Level005.png", "Level005.xml"); currentLevel = 0; }
void C4GamePadControl::CheckGamePad(const SDL_Event& e) { switch (e.type) { case SDL_JOYDEVICEADDED: // Report that an unsupported joystick device has been detected, to help with controller issues. if (!SDL_IsGameController(e.jdevice.which)) LogF("Gamepad %s isn't supported.", SDL_JoystickNameForIndex(e.jdevice.which)); break; case SDL_CONTROLLERDEVICEADDED: { auto device = std::make_shared<C4GamePadOpener>(e.cdevice.which); Gamepads[device->GetID()] = device; LogF("Gamepad #%d connected: %s", device->GetID(), SDL_JoystickNameForIndex(e.cdevice.which)); break; } case SDL_CONTROLLERDEVICEREMOVED: LogF("Gamepad #%d disconnected.", e.cdevice.which); Gamepads.erase(e.cdevice.which); break; } }
void init_controllers_and_audio() { SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); SDL_SetHint(SDL_HINT_GAMECONTROLLERCONFIG, "1"); Uint32 SDL_INIT_FLAGS = SDL_INIT_GAMECONTROLLER; // custom mappings SDL_HINT_GAMECONTROLLERCONFIG; if(ENABLE_AUDIO) { SDL_INIT_FLAGS |= SDL_INIT_AUDIO; // this does not seem to work :S } if(SDL_Init(SDL_INIT_FLAGS) == 0) { if( ENABLE_AUDIO && Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 1024 ) < 0) { std::cout << "Unable to open audio device" << std::endl; std::cout << Mix_GetError() << std::endl; } //TODO: SDL_JOYDEVICEADDED or SDL_JOYDEVICEREMOVED //SDL_GameControllerEventState(int state); SDL_JoystickEventState(SDL_ENABLE); if(SDL_NumJoysticks() == 0) { std::cout << "No joysticks" << std::endl; } else { for (int i = 0; i < SDL_NumJoysticks(); ++i) { if (SDL_IsGameController(i)) { controller = SDL_GameControllerOpen(i); if (controller) { std::cout << "Controller: " << SDL_GameControllerName(controller) << std::endl; break; } else { std::cout << "Could not open gamecontroller " << i << ":" << SDL_GetError() << std::endl; } } else { std::cout << "Not controller" << std::endl; } } } } else { std::cout << "SDL Failed to initialize" << std::endl; std::cout << SDL_GetError() << std::endl; } }
bool SDLGamepad::Connect (int deviceID) { if (SDL_IsGameController (deviceID)) { SDL_GameController *gameController = SDL_GameControllerOpen (deviceID); if (gameController) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick (gameController); int id = SDL_JoystickInstanceID (joystick); gameControllers[id] = gameController; gameControllerIDs[deviceID] = id; return true; } } return false; }
GameController System::create_gamecontroller() { for (int i = 0; i < SDL_NumJoysticks(); ++i) { if (SDL_IsGameController(i)) { SDL_GameController* controller = SDL_GameControllerOpen(i); if (controller) { return GameController(controller); } else { std::ostringstream out; out << "Could not open gamecontroller: " << i << ": " << SDL_GetError(); throw std::runtime_error(out.str()); } } } return {}; }
internal void sdl_init_joysticks(struct sdl_event_context *ctx) { unsigned int player; int num_joy_sticks, jsi; SDL_GameController *controller; SDL_Joystick *joystick; SDL_Haptic *rumble; for (player = 0; player < MAX_CONTROLLERS; ++player) { ctx->players[player].controller = NULL; ctx->players[player].rumble = NULL; } num_joy_sticks = SDL_NumJoysticks(); debug(0, "SDL_NumJoysticks() == %d\n", num_joy_sticks); player = 0; for (jsi = 0; jsi < num_joy_sticks && player < MAX_CONTROLLERS; ++jsi) { if (!SDL_IsGameController(jsi)) { debug(0, "SDL_IsGameController(%d) == 0\n", jsi); continue; } controller = SDL_GameControllerOpen(jsi); ctx->players[player].controller = controller; debug(0, "ctx->players[%u].controller = %p\n", player, (void *)controller); joystick = SDL_GameControllerGetJoystick(controller); rumble = SDL_HapticOpenFromJoystick(joystick); if (SDL_HapticRumbleInit(rumble)) { ctx->players[player].rumble = rumble; } else { SDL_HapticClose(rumble); } ++player; } }
void initGameControllers() { SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt"); int c = 0; bool found = false; //TODO: Bugger this and implement multi-controller support. game_controller = new GameController(); for (c = 0; c < SDL_NumJoysticks() && !found; ++c) //TODO: Bugger this and implement multi-controller support on a player-by-player basis. { if (SDL_IsGameController(c) && game_controller->open(c)) { printlog("(Device %d successfully initialized as game controller.)\n", c); found = true; //TODO: Bugger this and implement multi-controller support. } else { printlog("Info: device %d is not a game controller! Joysticks are not supported.\n", c); } } if (!found) { printlog("Info: No game controller detected!"); } }
Joystick::Joystick(InputDeviceMapping *mapping) : InputDevice(mapping) { device_attached = false; joystick = nullptr; controller = nullptr; m_mapping = reinterpret_cast<Mapping *>(InputDevice::m_mapping); Q_ASSERT(m_mapping != nullptr); callback = std::bind(&Joystick::handleSDLEvent, this, std::placeholders::_1); sdl_events.registerCallback(&callback); for (int i = 0; i < SDL_NumJoysticks(); i++) { if (!m_mapping->matchJoystick(SDL_JoystickGetDeviceGUID(i))) continue; if (SDL_IsGameController(i)) { attachGameController(i); break; } else { attachJoystick(i); break; } } }
inline void SDLOpenGameControllers() { int MaxJoysticks = SDL_NumJoysticks(); for(int JoystickIndex = 0; JoystickIndex < MaxJoysticks; JoystickIndex++) { if (!SDL_IsGameController(JoystickIndex)) { continue; } else { GamePadHandle = SDL_GameControllerOpen(JoystickIndex); RumbleHandle = SDL_HapticOpen(JoystickIndex); // NOTE(Redab): SDL_HapticRumbleInit() returns 0 on // success, check for failure. if(RumbleHandle && SDL_HapticRumbleInit(RumbleHandle) != 0) { SDL_HapticClose(RumbleHandle); RumbleHandle = 0; } printf("Game controller added.\n"); break; } } }
bool SDLUtilityTool::InitInputHandler() { // create the game controller and give the InputHandler a copy g_assert(SDL_NumJoysticks() != 0); g_assert(SDL_IsGameController(0)); m_inputController = SDL_GameControllerOpen(0); LogSDLError(); g_assert(m_inputController != nullptr); m_inputHandler.m_gameController = m_inputController; g_assert(m_inputHandler.m_gameController != nullptr); // sets the flag that the input thread watches to true m_inputHandler.Activate(); // create the input thread m_inputThread = SDL_CreateThread(ProcessInputFunctionXboxController, "InputThread", &m_inputHandler); LogSDLError(); g_assert(m_inputThread != nullptr); // any failure here is critical return true; }
void InputDaemon::addInputDevice(int index) { SDL_Joystick *joystick = SDL_JoystickOpen(index); if (joystick) { SDL_JoystickID tempJoystickID = SDL_JoystickInstanceID(joystick); if (!joysticks->contains(tempJoystickID)) { settings->getLock()->lock(); settings->beginGroup("Mappings"); QString temp; SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(joystick); char guidString[65] = {'0'}; SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); temp = QString(guidString); bool disableGameController = settings->value(QString("%1Disable").arg(temp), false).toBool(); if (SDL_IsGameController(index) && !disableGameController) { // Make sure to decrement reference count SDL_JoystickClose(joystick); SDL_GameController *controller = SDL_GameControllerOpen(index); if (controller) { SDL_Joystick *sdlStick = SDL_GameControllerGetJoystick(controller); SDL_JoystickID tempJoystickID = SDL_JoystickInstanceID(sdlStick); if (!joysticks->contains(tempJoystickID)) { GameController *damncontroller = new GameController(controller, index, settings, this); connect(damncontroller, SIGNAL(requestWait()), eventWorker, SLOT(haltServices())); joysticks->insert(tempJoystickID, damncontroller); trackcontrollers.insert(tempJoystickID, damncontroller); settings->endGroup(); settings->getLock()->unlock(); emit deviceAdded(damncontroller); } } else { settings->endGroup(); settings->getLock()->unlock(); } } else { Joystick *curJoystick = new Joystick(joystick, index, settings, this); joysticks->insert(tempJoystickID, curJoystick); trackjoysticks.insert(tempJoystickID, curJoystick); settings->endGroup(); settings->getLock()->unlock(); emit deviceAdded(curJoystick); } } else { // Make sure to decrement reference count SDL_JoystickClose(joystick); } } }
void InputDaemon::refreshJoysticks() { QMapIterator<SDL_JoystickID, InputDevice*> iter(*joysticks); while (iter.hasNext()) { InputDevice *joystick = iter.next().value(); if (joystick) { delete joystick; joystick = 0; } } joysticks->clear(); #ifdef USE_SDL_2 trackjoysticks.clear(); trackcontrollers.clear(); #endif #ifdef USE_SDL_2 settings->getLock()->lock(); settings->beginGroup("Mappings"); #endif for (int i=0; i < SDL_NumJoysticks(); i++) { #ifdef USE_SDL_2 SDL_Joystick *joystick = SDL_JoystickOpen(i); QString temp; SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(joystick); char guidString[65] = {'0'}; SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); temp = QString(guidString); bool disableGameController = settings->value(QString("%1Disable").arg(temp), false).toBool(); if (SDL_IsGameController(i) && !disableGameController) { SDL_GameController *controller = SDL_GameControllerOpen(i); GameController *damncontroller = new GameController(controller, i, settings, this); connect(damncontroller, SIGNAL(requestWait()), eventWorker, SLOT(haltServices())); SDL_Joystick *sdlStick = SDL_GameControllerGetJoystick(controller); SDL_JoystickID joystickID = SDL_JoystickInstanceID(sdlStick); joysticks->insert(joystickID, damncontroller); trackcontrollers.insert(joystickID, damncontroller); } else { Joystick *curJoystick = new Joystick(joystick, i, settings, this); connect(curJoystick, SIGNAL(requestWait()), eventWorker, SLOT(haltServices())); SDL_JoystickID joystickID = SDL_JoystickInstanceID(joystick); joysticks->insert(joystickID, curJoystick); trackjoysticks.insert(joystickID, curJoystick); } #else SDL_Joystick *joystick = SDL_JoystickOpen(i); Joystick *curJoystick = new Joystick(joystick, i, settings, this); connect(curJoystick, SIGNAL(requestWait()), eventWorker, SLOT(haltServices())); joysticks->insert(i, curJoystick); #endif } #ifdef USE_SDL_2 settings->endGroup(); settings->getLock()->unlock(); #endif emit joysticksRefreshed(joysticks); }
/* * Event filter to fire controller events from joystick ones */ int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event) { switch( event->type ) { case SDL_JOYAXISMOTION: { SDL_GameController *controllerlist; if ( event->jaxis.axis >= k_nMaxReverseEntries ) break; controllerlist = SDL_gamecontrollers; while ( controllerlist ) { if ( controllerlist->joystick->instance_id == event->jaxis.which ) { if ( controllerlist->mapping.raxes[event->jaxis.axis] >= 0 ) /* simple axis to axis, send it through */ { SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis]; Sint16 value = event->jaxis.value; switch (axis) { case SDL_CONTROLLER_AXIS_TRIGGERLEFT: case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: /* Shift it to be 0 - 32767. */ value = value / 2 + 16384; default: break; } SDL_PrivateGameControllerAxis( controllerlist, axis, value ); } else if ( controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0 ) /* simulate an axis as a button */ { SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED ); } break; } controllerlist = controllerlist->next; } } break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: { SDL_GameController *controllerlist; if ( event->jbutton.button >= k_nMaxReverseEntries ) break; controllerlist = SDL_gamecontrollers; while ( controllerlist ) { if ( controllerlist->joystick->instance_id == event->jbutton.which ) { if ( controllerlist->mapping.rbuttons[event->jbutton.button] >= 0 ) /* simple button as button */ { SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state ); } else if ( controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0 ) /* an button pretending to be an axis */ { SDL_PrivateGameControllerAxis( controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0 ); } break; } controllerlist = controllerlist->next; } } break; case SDL_JOYHATMOTION: { SDL_GameController *controllerlist; if ( event->jhat.hat >= 4 ) break; controllerlist = SDL_gamecontrollers; while ( controllerlist ) { if ( controllerlist->joystick->instance_id == event->jhat.which ) { Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value; /* Get list of removed bits (button release) */ Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame; /* the hat idx in the high nibble */ int bHighHat = event->jhat.hat << 4; if ( bChanged & SDL_HAT_DOWN ) SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED ); if ( bChanged & SDL_HAT_UP ) SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED ); if ( bChanged & SDL_HAT_LEFT ) SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED ); if ( bChanged & SDL_HAT_RIGHT ) SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED ); /* Get list of added bits (button press) */ bChanged = event->jhat.value ^ bSame; if ( bChanged & SDL_HAT_DOWN ) SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED ); if ( bChanged & SDL_HAT_UP ) SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED ); if ( bChanged & SDL_HAT_LEFT ) SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED ); if ( bChanged & SDL_HAT_RIGHT ) SDL_PrivateGameControllerButton( controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED ); /* update our state cache */ controllerlist->hatState[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); break; } controllerlist = controllerlist->next; } } break; default: break; } return 1; }
/* * Initializes the backend */ void IN_Init(void) { Com_Printf("------- input initialization -------\n"); mouse_x = mouse_y = 0; #if SDL_VERSION_ATLEAST(2, 0, 0) joystick_yaw = joystick_pitch = joystick_forwardmove = joystick_sidemove = 0; #endif exponential_speedup = Cvar_Get("exponential_speedup", "0", CVAR_ARCHIVE); freelook = Cvar_Get("freelook", "1", 0); in_grab = Cvar_Get("in_grab", "2", CVAR_ARCHIVE); lookstrafe = Cvar_Get("lookstrafe", "0", 0); m_filter = Cvar_Get("m_filter", "0", CVAR_ARCHIVE); m_up = Cvar_Get("m_up", "1", 0); m_forward = Cvar_Get("m_forward", "1", 0); m_pitch = Cvar_Get("m_pitch", "0.022", 0); m_side = Cvar_Get("m_side", "0.8", 0); m_yaw = Cvar_Get("m_yaw", "0.022", 0); sensitivity = Cvar_Get("sensitivity", "3", 0); #if SDL_VERSION_ATLEAST(2, 0, 0) joy_haptic_magnitude = Cvar_Get("joy_haptic_magnitude", "0.0", CVAR_ARCHIVE); joy_yawsensitivity = Cvar_Get("joy_yawsensitivity", "1.0", CVAR_ARCHIVE); joy_pitchsensitivity = Cvar_Get("joy_pitchsensitivity", "1.0", CVAR_ARCHIVE); joy_forwardsensitivity = Cvar_Get("joy_forwardsensitivity", "1.0", CVAR_ARCHIVE); joy_sidesensitivity = Cvar_Get("joy_sidesensitivity", "1.0", CVAR_ARCHIVE); joy_upsensitivity = Cvar_Get("joy_upsensitivity", "1.0", CVAR_ARCHIVE); joy_axis_leftx = Cvar_Get("joy_axis_leftx", "sidemove", CVAR_ARCHIVE); joy_axis_lefty = Cvar_Get("joy_axis_lefty", "forwardmove", CVAR_ARCHIVE); joy_axis_rightx = Cvar_Get("joy_axis_rightx", "yaw", CVAR_ARCHIVE); joy_axis_righty = Cvar_Get("joy_axis_righty", "pitch", CVAR_ARCHIVE); joy_axis_triggerleft = Cvar_Get("joy_axis_triggerleft", "triggerleft", CVAR_ARCHIVE); joy_axis_triggerright = Cvar_Get("joy_axis_triggerright", "triggerright", CVAR_ARCHIVE); joy_axis_leftx_threshold = Cvar_Get("joy_axis_leftx_threshold", "0.15", CVAR_ARCHIVE); joy_axis_lefty_threshold = Cvar_Get("joy_axis_lefty_threshold", "0.15", CVAR_ARCHIVE); joy_axis_rightx_threshold = Cvar_Get("joy_axis_rightx_threshold", "0.15", CVAR_ARCHIVE); joy_axis_righty_threshold = Cvar_Get("joy_axis_righty_threshold", "0.15", CVAR_ARCHIVE); joy_axis_triggerleft_threshold = Cvar_Get("joy_axis_triggerleft_threshold", "0.15", CVAR_ARCHIVE); joy_axis_triggerright_threshold = Cvar_Get("joy_axis_triggerright_threshold", "0.15", CVAR_ARCHIVE); #endif vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE); windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE); Cmd_AddCommand("+mlook", IN_MLookDown); Cmd_AddCommand("-mlook", IN_MLookUp); #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_StartTextInput(); #else SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); #endif #if SDL_VERSION_ATLEAST(2, 0, 0) /* joystik init */ if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC)) { if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == -1) { Com_Printf ("Couldn't init SDL joystick: %s.\n", SDL_GetError ()); } else { Com_Printf ("%i joysticks were found.\n", SDL_NumJoysticks()); if (SDL_NumJoysticks() > 0) { int i; for (i=0; i<SDL_NumJoysticks(); i ++) { joystick = SDL_JoystickOpen(i); Com_Printf ("The name of the joystick is '%s'\n", SDL_JoystickName(joystick)); Com_Printf ("Number of Axes: %d\n", SDL_JoystickNumAxes(joystick)); Com_Printf ("Number of Buttons: %d\n", SDL_JoystickNumButtons(joystick)); Com_Printf ("Number of Balls: %d\n", SDL_JoystickNumBalls(joystick)); Com_Printf ("Number of Hats: %d\n", SDL_JoystickNumHats(joystick)); joystick_haptic = SDL_HapticOpenFromJoystick(joystick); if (joystick_haptic == NULL) Com_Printf ("Most likely joystick isn't haptic\n"); else IN_Haptic_Effects_Info(); if(SDL_IsGameController(i)) { SDL_GameControllerButtonBind backBind; controller = SDL_GameControllerOpen(i); Com_Printf ("Controller settings: %s\n", SDL_GameControllerMapping(controller)); Com_Printf ("Controller axis: \n"); Com_Printf (" * leftx = %s\n", joy_axis_leftx->string); Com_Printf (" * lefty = %s\n", joy_axis_lefty->string); Com_Printf (" * rightx = %s\n", joy_axis_rightx->string); Com_Printf (" * righty = %s\n", joy_axis_righty->string); Com_Printf (" * triggerleft = %s\n", joy_axis_triggerleft->string); Com_Printf (" * triggerright = %s\n", joy_axis_triggerright->string); Com_Printf ("Controller thresholds: \n"); Com_Printf (" * leftx = %f\n", joy_axis_leftx_threshold->value); Com_Printf (" * lefty = %f\n", joy_axis_lefty_threshold->value); Com_Printf (" * rightx = %f\n", joy_axis_rightx_threshold->value); Com_Printf (" * righty = %f\n", joy_axis_righty_threshold->value); Com_Printf (" * triggerleft = %f\n", joy_axis_triggerleft_threshold->value); Com_Printf (" * triggerright = %f\n", joy_axis_triggerright_threshold->value); backBind = SDL_GameControllerGetBindForButton(controller, SDL_CONTROLLER_BUTTON_BACK); if (backBind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) { back_button_id = backBind.value.button; Com_Printf ("\nBack button JOY%d will be unbindable.\n", back_button_id+1); } break; } else { char joystick_guid[256] = {0}; SDL_JoystickGUID guid; guid = SDL_JoystickGetDeviceGUID(i); SDL_JoystickGetGUIDString(guid, joystick_guid, 255); Com_Printf ("For use joystic as game contoller please set SDL_GAMECONTROLLERCONFIG:\n"); Com_Printf ("e.g.: SDL_GAMECONTROLLERCONFIG='%s,%s,leftx:a0,lefty:a1,rightx:a2,righty:a3,back:b1,...\n", joystick_guid, SDL_JoystickName(joystick)); } } } else { joystick_haptic = SDL_HapticOpenFromMouse(); if (joystick_haptic == NULL) Com_Printf ("Most likely mouse isn't haptic\n"); else IN_Haptic_Effects_Info(); } } } #endif Com_Printf("------------------------------------\n\n"); }
static bool gamepad_update_device_list(void) { int cnt = SDL_NumJoysticks(); log_info("Updating gamepad devices list"); if(gamepad.num_devices > 0) { assume(gamepad.devices != NULL); for(uint i = 0; i < gamepad.num_devices; ++i) { SDL_GameControllerClose(gamepad.devices[i].controller); } } gamepad.num_devices = 0; if(!cnt) { free(gamepad.devices); gamepad.devices = NULL; gamepad.num_devices_allocated = 0; log_info("No joysticks attached"); return false; } if(gamepad.num_devices_allocated != cnt) { free(gamepad.devices); gamepad.devices = calloc(cnt, sizeof(GamepadDevice)); gamepad.num_devices_allocated = cnt; } GamepadDevice *dev = gamepad.devices; for(int i = 0; i < cnt; ++i) { SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(i); char guid_str[33] = { 0 }; SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); if(!*guid_str) { log_warn("Failed to read GUID of joystick at index %i: %s", i, SDL_GetError()); continue; } if(!SDL_IsGameController(i)) { log_warn("Joystick at index %i (name: \"%s\"; guid: %s) is not recognized as a game controller by SDL. " "Most likely it just doesn't have a mapping. See https://git.io/vdvdV for solutions", i, SDL_JoystickNameForIndex(i), guid_str); continue; } dev->sdl_id = i; dev->controller = SDL_GameControllerOpen(i); if(dev->controller == NULL) { log_sdl_error(LOG_WARN, "SDL_GameControllerOpen"); continue; } dev->joy_instance = SDL_JoystickGetDeviceInstanceID(i); if(dev->joy_instance < 0) { log_sdl_error(LOG_WARN, "SDL_JoystickGetDeviceInstanceID"); continue; } log_info("Found device '%s' (#%i): %s", guid_str, DEVNUM(dev), gamepad_device_name_unmapped(i)); ++gamepad.num_devices; ++dev; } if(!gamepad.num_devices) { log_info("No usable devices"); return false; } return true; }
int main(int argc, char *argv[]) { int opt; struct sockaddr_can addr; struct canfd_frame frame; int running = 1; int enable_canfd = 1; int play_traffic = 1; struct stat st; SDL_Event event; while ((opt = getopt(argc, argv, "Xdl:s:t:h?")) != -1) { switch(opt) { case 'l': difficulty = atoi(optarg); break; case 's': seed = atoi(optarg); break; case 't': traffic_log = optarg; break; case 'd': debug = 1; break; case 'X': play_traffic = 0; break; case 'h': case '?': default: usage(NULL); break; } } if (optind >= argc) usage("You must specify at least one can device"); if(stat(traffic_log, &st) == -1) { char msg[256]; snprintf(msg, 255, "CAN Traffic file not found: %s\n", traffic_log); usage(msg); } /* open socket */ if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { perror("socket"); return 1; } addr.can_family = AF_CAN; strcpy(ifr.ifr_name, argv[optind]); if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { perror("SIOCGIFINDEX"); return 1; } addr.can_ifindex = ifr.ifr_ifindex; if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_canfd, sizeof(enable_canfd))){ printf("error when enabling CAN FD support\n"); return 1; } if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } door_id = DEFAULT_DOOR_ID; signal_id = DEFAULT_SIGNAL_ID; speed_id = DEFAULT_SPEED_ID; if (seed) { srand(seed); door_id = (rand() % 2046) + 1; signal_id = (rand() % 2046) + 1; speed_id = (rand() % 2046) + 1; door_pos = rand() % 9; signal_pos = rand() % 9; speed_pos = rand() % 8; printf("Seed: %d\n", seed); door_len = door_pos + 1; signal_len = signal_pos + 1; speed_len = speed_len + 2; } if(difficulty > 0) { if (door_len < 8) { door_len += rand() % (8 - door_len); } else { door_len = 0; } if (signal_len < 8) { signal_len += rand() % (8 - signal_len); } else { signal_len = 0; } if (speed_len < 8) { speed_len += rand() % (8 - speed_len); } else { speed_len = 0; } } if(play_traffic) { signal(SIGALRM,(void (*)(int))kill_child); play_id = fork(); if((int)play_id == -1) { printf("Error: Couldn't fork bg player\n"); exit(-1); } else if (play_id != 0) { play_can_traffic(); } } // GUI Setup SDL_Window *window = NULL; SDL_Surface *screenSurface = NULL; if(SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0 ) { printf("SDL Could not initializes\n"); exit(40); } if( SDL_NumJoysticks() < 1) { printf(" Warning: No joysticks connected\n"); } else { if(SDL_IsGameController(0)) { gGameController = SDL_GameControllerOpen(0); if(gGameController == NULL) { printf(" Warning: Unable to open game controller. %s\n", SDL_GetError() ); } else { gJoystick = SDL_GameControllerGetJoystick(gGameController); gHaptic = SDL_HapticOpenFromJoystick(gJoystick); print_joy_info(); } } else { gJoystick = SDL_JoystickOpen(0); if(gJoystick == NULL) { printf(" Warning: Could not open joystick\n"); } else { gHaptic = SDL_HapticOpenFromJoystick(gJoystick); if (gHaptic == NULL) printf("No Haptic support\n"); print_joy_info(); } } } window = SDL_CreateWindow("CANBus Control Panel", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); if(window == NULL) { printf("Window could not be shown\n"); } renderer = SDL_CreateRenderer(window, -1, 0); SDL_Surface *image = IMG_Load(get_data("joypad.png")); base_texture = SDL_CreateTextureFromSurface(renderer, image); SDL_RenderCopy(renderer, base_texture, NULL, NULL); SDL_RenderPresent(renderer); int button, axis; // Used for checking dynamic joystick mappings while(running) { while( SDL_PollEvent(&event) != 0 ) { switch(event.type) { case SDL_QUIT: running = 0; break; case SDL_WINDOWEVENT: switch(event.window.event) { case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_RESIZED: redraw_screen(); break; } case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_UP: throttle = 1; break; case SDLK_LEFT: turning = -1; break; case SDLK_RIGHT: turning = 1; break; case SDLK_LSHIFT: lock_enabled = 1; if(unlock_enabled) send_lock(CAN_DOOR1_LOCK | CAN_DOOR2_LOCK | CAN_DOOR3_LOCK | CAN_DOOR4_LOCK); break; case SDLK_RSHIFT: unlock_enabled = 1; if(lock_enabled) send_unlock(CAN_DOOR1_LOCK | CAN_DOOR2_LOCK | CAN_DOOR3_LOCK | CAN_DOOR4_LOCK); break; case SDLK_a: if(lock_enabled) { send_lock(CAN_DOOR1_LOCK); } else if(unlock_enabled) { send_unlock(CAN_DOOR1_LOCK); } break; case SDLK_b: if(lock_enabled) { send_lock(CAN_DOOR2_LOCK); } else if(unlock_enabled) { send_unlock(CAN_DOOR2_LOCK); } break; case SDLK_x: if(lock_enabled) { send_lock(CAN_DOOR3_LOCK); } else if(unlock_enabled) { send_unlock(CAN_DOOR3_LOCK); } break; case SDLK_y: if(lock_enabled) { send_lock(CAN_DOOR4_LOCK); } else if(unlock_enabled) { send_unlock(CAN_DOOR4_LOCK); } break; } kk_check(event.key.keysym.sym); break; case SDL_KEYUP: switch(event.key.keysym.sym) { case SDLK_UP: throttle = -1; break; case SDLK_LEFT: case SDLK_RIGHT: turning = 0; break; case SDLK_LSHIFT: lock_enabled = 0; break; case SDLK_RSHIFT: unlock_enabled = 0; break; } break; case SDL_JOYAXISMOTION: axis = event.jaxis.axis; if(axis == gAxisLeftH) { ud(event.jaxis.value); } else if(axis == gAxisLeftV) { turn(event.jaxis.value); } else if(axis == gAxisR2) { accelerate(event.jaxis.value); } else if(axis == gAxisRightH || axis == gAxisRightV || axis == gAxisL2 || axis == gJoyX || axis == gJoyY || axis == gJoyZ) { // Do nothing, the axis is known just not connected } else { if (debug) printf("Unkown axis: %d\n", event.jaxis.axis); } break; case SDL_JOYBUTTONDOWN: button = event.jbutton.button; if(button == gButtonLock) { lock_enabled = 1; if(unlock_enabled) send_lock(CAN_DOOR1_LOCK | CAN_DOOR2_LOCK | CAN_DOOR3_LOCK | CAN_DOOR4_LOCK); } else if(button == gButtonUnlock) { unlock_enabled = 1; if(lock_enabled) send_unlock(CAN_DOOR1_LOCK | CAN_DOOR2_LOCK | CAN_DOOR3_LOCK | CAN_DOOR4_LOCK); } else if(button == gButtonA) { if(lock_enabled) { send_lock(CAN_DOOR1_LOCK); } else if(unlock_enabled) { send_unlock(CAN_DOOR1_LOCK); } kk_check(SDLK_a); } else if (button == gButtonB) { if(lock_enabled) { send_lock(CAN_DOOR2_LOCK); } else if(unlock_enabled) { send_unlock(CAN_DOOR2_LOCK); } kk_check(SDLK_b); } else if (button == gButtonX) { if(lock_enabled) { send_lock(CAN_DOOR3_LOCK); } else if(unlock_enabled) { send_unlock(CAN_DOOR3_LOCK); } kk_check(SDLK_x); } else if (button == gButtonY) { if(lock_enabled) { send_lock(CAN_DOOR4_LOCK); } else if(unlock_enabled) { send_unlock(CAN_DOOR4_LOCK); } kk_check(SDLK_y); } else if (button == gButtonStart) { kk_check(SDLK_RETURN); } else { if(debug) printf("Unassigned button: %d\n", event.jbutton.button); } break; case SDL_JOYBUTTONUP: button = event.jbutton.button; if(button == gButtonLock) { lock_enabled = 0; } else if(button == gButtonUnlock) { unlock_enabled = 0; } else { //if(debug) printf("Unassigned button: %d\n", event.jbutton.button); } break; case SDL_JOYDEVICEADDED: // Only use the first controller if(event.cdevice.which == 0) { gJoystick = SDL_JoystickOpen(0); if(gJoystick) { gHaptic = SDL_HapticOpenFromJoystick(gJoystick); print_joy_info(); } } break; case SDL_JOYDEVICEREMOVED: if(event.cdevice.which == 0) { SDL_JoystickClose(gJoystick); gJoystick = NULL; } break; case SDL_CONTROLLERDEVICEADDED: // Only use the first controller if(gGameController == NULL) { gGameController = SDL_GameControllerOpen(0); gJoystick = SDL_GameControllerGetJoystick(gGameController); gHaptic = SDL_HapticOpenFromJoystick(gJoystick); print_joy_info(); } break; case SDL_CONTROLLERDEVICEREMOVED: if(event.cdevice.which == 0) { SDL_GameControllerClose(gGameController); gGameController = NULL; } break; } } currentTime = SDL_GetTicks(); checkAccel(); checkTurn(); SDL_Delay(5); } kill_child(SIGKILL); close(s); SDL_DestroyTexture(base_texture); SDL_FreeSurface(image); SDL_GameControllerClose(gGameController); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); }