int main(void) { PlatformState state; SDL_Event e; SDL_Window *window; SDL_Renderer *renderer; SDLInputContext sdlIC; SDLSoundRingBuffer srb; GameSoundOutput sb; GameMemory gameMemory; //controller input state InputContext inputStates[2]; //contains old and new state InputContext* newInputState = &inputStates[0]; InputContext* oldInputState = &inputStates[1]; real32_t secsSinceLastFrame = 0; sb.volume = 2500; gameMemory.permanentStorageSize = MB(64); gameMemory.transientStorageSize = MB(64); state.gameMemorySize = gameMemory.transientStorageSize + gameMemory.permanentStorageSize; state.memoryBlock = mmap(nullptr, state.gameMemorySize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE , -1, 0); gameMemory.permanentStorage = state.memoryBlock; gameMemory.transientStorage = (uint8_t*)(gameMemory.transientStorage) + gameMemory.transientStorageSize; initSDL(&window, &renderer, &gOsb, &sdlIC, &srb); GameCode gameCode = loadGameCode(); assert(gameCode.guarf); uint64_t startCount = SDL_GetPerformanceCounter(); real32_t targetFrameSeconds = 1./getRefreshRate(window); SDL_PauseAudio(0); while(state.running) { if(getCreateTimeOfFile(GAME_LIB_PATH) != gameCode.dateLastModified) { reloadGameCode(&gameCode); } //keyboard input ControllerInput* newKeyInput = getContoller(newInputState, 0); //TODO: figure out why this is special ControllerInput* oldKeyInput = getContoller(oldInputState, 0); *newKeyInput = {}; for(size_t i = 0; i < ARRAY_SIZE(oldKeyInput->buttons); i++) { newKeyInput->buttons[i] = oldKeyInput->buttons[i]; } while(SDL_PollEvent(&e)) { processEvent(&e, newInputState, &state); } //controller input for(int i = 0; i < MAX_SDL_CONTROLLERS; i++) { if(sdlIC.controllers[i] != nullptr && SDL_GameControllerGetAttached(sdlIC.controllers[i])) { ControllerInput* newCIState = getContoller(newInputState, i+1); ControllerInput* oldCIState = getContoller(oldInputState, i+1); int16_t xVal = SDL_GameControllerGetAxis(sdlIC.controllers[i], SDL_CONTROLLER_AXIS_LEFTX); int16_t yVal = SDL_GameControllerGetAxis(sdlIC.controllers[i], SDL_CONTROLLER_AXIS_LEFTY); newCIState->avgX = normalizeStickInput(xVal, LEFT_THUMB_DEADZONE); newCIState->avgY = normalizeStickInput(yVal, LEFT_THUMB_DEADZONE); if(newCIState->avgX != 0 || newCIState->avgY != 0) { newCIState->isAnalog = true; } processControllerButtonInput(&newCIState->actionDown, &oldCIState->actionDown, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_A); processControllerButtonInput(&newCIState->actionUp, &oldCIState->actionUp, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_Y); processControllerButtonInput(&newCIState->actionLeft, &oldCIState->actionLeft, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_X); processControllerButtonInput(&newCIState->actionRight, &oldCIState->actionRight, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_B); processControllerButtonInput(&newCIState->directionDown, &oldCIState->directionDown, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_DPAD_DOWN); processControllerButtonInput(&newCIState->directionUp, &oldCIState->directionUp, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_DPAD_UP); processControllerButtonInput(&newCIState->directionLeft, &oldCIState->directionLeft, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_DPAD_LEFT); processControllerButtonInput(&newCIState->directionRight, &oldCIState->directionRight, &newCIState->isAnalog, sdlIC.controllers[i], SDL_CONTROLLER_BUTTON_DPAD_RIGHT); oldCIState->isAnalog = newCIState->isAnalog; } else { //TODO: Logging } } //TODO: Do this instead of processing input, not after //process recording/playback assert(!(state.isRecording && state.isPlayingBack)); if(state.isRecording) { recordInput(newInputState, state.inputRecordFile); } if(state.isPlayingBack) { playInput(newInputState, state.inputRecordFile); } //calculate audio buffers' indicies and sizes SDL_LockAudioDevice(1); uint32_t startIndex = srb.runningIndex % ARRAY_SIZE(srb.samples); uint32_t endIndex = (srb.sampleToPlay + SOUND_LATENCY) % ARRAY_SIZE(srb.samples); uint32_t samplesToGetFromGame = (startIndex <= endIndex) ? endIndex - startIndex : (ARRAY_SIZE(srb.samples) - startIndex) + endIndex; sb.numSamples = samplesToGetFromGame; SDL_UnlockAudioDevice(1); gameCode.guarf(&gameMemory, &gOsb, &sb, newInputState, secsSinceLastFrame); updateSDLSoundBuffer(&srb, &sb, startIndex, endIndex); updateWindow(window, gTexture); InputContext* temp = newInputState; newInputState = oldInputState; oldInputState = temp; //benchmark stuff real32_t secsElapsed = secondsForCountRange(startCount, SDL_GetPerformanceCounter()); //sleep to lock frame rate if(secsElapsed < targetFrameSeconds) { //NOTE: .5 denotes the amount we will spin manually since // SDL_Delay is not 100% accurate real32_t timeToSleep = (targetFrameSeconds - secsElapsed)*1000 - .5; SDL_Delay(timeToSleep); secsElapsed = secondsForCountRange(startCount, SDL_GetPerformanceCounter()); //This assert will fire if the window is moved //assert(secondsForCountRange(startCount, SDL_GetPerformanceCounter()) < targetFrameSeconds); while(secondsForCountRange(startCount, SDL_GetPerformanceCounter()) < targetFrameSeconds) { //wait } secsElapsed = secondsForCountRange(startCount, SDL_GetPerformanceCounter()); } uint64_t endCount = SDL_GetPerformanceCounter(); real32_t fpsCount = ((1./secsElapsed)); real32_t mcPerFrame = (real32_t)(endCount-startCount) / (1000 * 1000 ); printf("TPF: %.2fms FPS: %.2f MCPF: %.2f\n", secsElapsed*1000, fpsCount, mcPerFrame); startCount = endCount; secsSinceLastFrame = secsElapsed; } cleanUp(&state, &gameCode); return 0; }
void pollGameController(SDL_GameController *gameController, GamepadBuffer& gamepad) { gamepad[gpLeft - gpRangeBegin] = SDL_GameControllerGetButton(gameController, SDL_CONTROLLER_BUTTON_DPAD_LEFT) || SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTX) < -DEAD_ZONE || SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTX) < -DEAD_ZONE; gamepad[gpRight - gpRangeBegin] = SDL_GameControllerGetButton(gameController, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) || SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTX) > +DEAD_ZONE || SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTX) > +DEAD_ZONE; gamepad[gpUp - gpRangeBegin] = SDL_GameControllerGetButton(gameController, SDL_CONTROLLER_BUTTON_DPAD_UP) || SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTY) < -DEAD_ZONE || SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTY) < -DEAD_ZONE; gamepad[gpDown - gpRangeBegin] = SDL_GameControllerGetButton(gameController, SDL_CONTROLLER_BUTTON_DPAD_DOWN) || SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTY) > +DEAD_ZONE || SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTY) > +DEAD_ZONE; for (int button = SDL_CONTROLLER_BUTTON_A; button < SDL_CONTROLLER_BUTTON_DPAD_UP; ++button) { gamepad[gpButton0 - gpRangeBegin + button - SDL_CONTROLLER_BUTTON_A] = SDL_GameControllerGetButton(gameController, (SDL_GameControllerButton)button); } }
/* * IN_GetThumbsticks */ void IN_GetThumbsticks( vec4_t sticks ) { SDL_GameController *controller = in_sdl_joyController; if( !controller || !in_sdl_joyActive ) { Vector4Set( sticks, 0.0f, 0.0f, 0.0f, 0.0f ); return; } sticks[0] = IN_SDL_JoyThumbstickValue( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_LEFTX ) ); sticks[1] = IN_SDL_JoyThumbstickValue( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_LEFTY ) ); sticks[2] = IN_SDL_JoyThumbstickValue( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_RIGHTX ) ); sticks[3] = IN_SDL_JoyThumbstickValue( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_RIGHTY ) ); }
int RawValuePointer(int axis) { switch(axis) { default: case JOY_AXIS_X: return SDL_GameControllerGetAxis(s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX); case JOY_AXIS_Y: return SDL_GameControllerGetAxis(s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY); case JOY_AXIS_Z: return SDL_GameControllerGetAxis(s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX); case JOY_AXIS_R: return SDL_GameControllerGetAxis(s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY); } }
int GameController::getRawRightYMove() { if (!isActive()) { return 0; } int y = SDL_GameControllerGetAxis(sdl_device, SDL_CONTROLLER_AXIS_RIGHTY); if (y < gamepad_deadzone && y > -gamepad_deadzone) { return 0; } if (y < -gamepad_deadzone) { y += gamepad_deadzone; } else { y -= gamepad_deadzone; } return (!gamepad_righty_invert) ? y : -y; }
int GameController::getRawLeftXMove() { if (!isActive()) { return 0; } int x = SDL_GameControllerGetAxis(sdl_device, SDL_CONTROLLER_AXIS_LEFTX); if (x < gamepad_deadzone && x > -gamepad_deadzone) { return 0; } if (x < -gamepad_deadzone) //TODO: Give each controller a deadzone setting? Or maybe on a player by player basis? And/or each analog stick its own deadzone setting? { x += gamepad_deadzone; } else { x -= gamepad_deadzone; } return (!gamepad_leftx_invert) ? x : -x; }
int GameController::getRawRightXMove() { if (!isActive()) { return 0; } int x = SDL_GameControllerGetAxis(sdl_device, SDL_CONTROLLER_AXIS_RIGHTX); if (x < gamepad_deadzone && x > -gamepad_deadzone) { return 0; } if (x < -gamepad_deadzone) { x += gamepad_deadzone; } else { x -= gamepad_deadzone; } return (!gamepad_rightx_invert) ? x : -x; }
static int16_t sdl_pad_get_axis(sdl_joypad_t *pad, unsigned axis) { #ifdef HAVE_SDL2 /* TODO: see if a rarch <-> sdl translation is needed. */ if (pad->controller) return SDL_GameControllerGetAxis(pad->controller, (SDL_GameControllerAxis)axis); #endif return SDL_JoystickGetAxis(pad->joypad, axis); }
static int getJoystickAxisState(const config::input::InputDevice *device, SDL_GameController *controller, vpad::Channel channel, vpad::CoreAxis axis) { decaf_check(device); decaf_check(controller); auto joystick = SDL_GameControllerGetJoystick(controller); decaf_check(joystick); auto index = -1; auto name = SDL_CONTROLLER_AXIS_INVALID; auto invert = false; switch (axis) { case vpad::CoreAxis::LeftStickX: index = device->joystick.left_stick_x; name = SDL_CONTROLLER_AXIS_LEFTX; invert = device->joystick.left_stick_x_invert; break; case vpad::CoreAxis::LeftStickY: index = device->joystick.left_stick_y; name = SDL_CONTROLLER_AXIS_LEFTY; invert = device->joystick.left_stick_y_invert; break; case vpad::CoreAxis::RightStickX: index = device->joystick.right_stick_x; name = SDL_CONTROLLER_AXIS_RIGHTX; invert = device->joystick.right_stick_x_invert; break; case vpad::CoreAxis::RightStickY: index = device->joystick.right_stick_y; name = SDL_CONTROLLER_AXIS_RIGHTY; invert = device->joystick.right_stick_y_invert; break; } auto value = 0; if (index >= 0) { value = SDL_JoystickGetAxis(joystick, index); } else if (index == -2) { if (name != SDL_CONTROLLER_AXIS_INVALID) { value = SDL_GameControllerGetAxis(controller, name); } } if (invert) { value = -value; } return value; }
void SDLController::Tick() { float x[3]; float y[3]; // we'll accept input from left stick, right stick or dpad... // X axis x[0] = ApplyDeadZone(SDL_GameControllerGetAxis(m_Ctrl, SDL_CONTROLLER_AXIS_LEFTX)); x[1] = ApplyDeadZone(SDL_GameControllerGetAxis(m_Ctrl, SDL_CONTROLLER_AXIS_RIGHTX)); if (SDL_GameControllerGetButton(m_Ctrl, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) x[2] = -1.0f; else if (SDL_GameControllerGetButton(m_Ctrl, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) x[2] = 1.0f; else x[2] = 0.0f; m_X = AvgNonZero(x); // Y axis y[0] = ApplyDeadZone(SDL_GameControllerGetAxis(m_Ctrl, SDL_CONTROLLER_AXIS_LEFTY)); y[1] = ApplyDeadZone(SDL_GameControllerGetAxis(m_Ctrl, SDL_CONTROLLER_AXIS_RIGHTY)); if (SDL_GameControllerGetButton(m_Ctrl, SDL_CONTROLLER_BUTTON_DPAD_UP)) y[2] = -1.0f; else if (SDL_GameControllerGetButton(m_Ctrl, SDL_CONTROLLER_BUTTON_DPAD_DOWN)) y[2] = 1.0f; else y[2] = 0.0f; m_Y = AvgNonZero(y); // buttons int buttons = 0; if (SDL_GameControllerGetButton(m_Ctrl,SDL_CONTROLLER_BUTTON_A)==1) buttons |= CTRL_BTN_FIRE; if (SDL_GameControllerGetButton(m_Ctrl,SDL_CONTROLLER_BUTTON_START)==1) buttons |= CTRL_BTN_START; m_PrevBtnState = m_BtnState; m_BtnState = buttons; }
float Joystick::getAxisValue(int8_t axis) const { if (axis < 0 || !isConnected()) { return 0; } if (!isController()) { return convertRange(SDL_JoystickGetAxis(m_joystickHandle, axis)); } SDL_GameControllerAxis sdlAxis = static_cast<SDL_GameControllerAxis>(axis); return convertRange(SDL_GameControllerGetAxis(m_controllerHandle, sdlAxis)); }
float Joystick::getGamepadAxis(love::joystick::Joystick::GamepadAxis axis) const { if (!isConnected() || !isGamepad()) return 0.f; SDL_GameControllerAxis sdlaxis; if (!getConstant(axis, sdlaxis)) return 0.f; Sint16 value = SDL_GameControllerGetAxis(controller, sdlaxis); return clampval((float) value / 32768.0f); }
void GameEngine::CheckJoystick(){ SDL_GameController *controller = this->GetController(); int jsJoystickState = JOY_NONE; Sint16 axis = 0; // Check horizontal movement axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); if(axis){ if(axis < m_rcJoystickTrip.x) jsJoystickState |= JOY_LEFT; else if(axis > m_rcJoystickTrip.w){ jsJoystickState |= JOY_RIGHT; } } // Check vertical movement axis = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); if(axis){ if(axis < m_rcJoystickTrip.h) jsJoystickState |= JOY_UP; else if(axis > m_rcJoystickTrip.y){ jsJoystickState |= JOY_DOWN; } } //check joystick buttons Uint8 is_pressed_a = SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A); Uint8 is_pressed_b = SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_B); if(is_pressed_a) jsJoystickState |= JOY_FIRE1; if(is_pressed_b) jsJoystickState |= JOY_FIRE2; // Allow the game to handle the joystick m_game->HandleJoystick((JOYSTATE)jsJoystickState); }
/* ================ IN_Commands Emit key events for game controller buttons, including emulated buttons for analog sticks/triggers ================ */ void IN_Commands (void) { joyaxisstate_t newaxisstate; int i; const float stickthreshold = 0.9; const float triggerthreshold = joy_deadzone_trigger.value; if (!joy_enable.value) return; if (!joy_active_controller) return; // emit key events for controller buttons for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) { qboolean newstate = SDL_GameControllerGetButton(joy_active_controller, (SDL_GameControllerButton)i); qboolean oldstate = joy_buttonstate.buttondown[i]; joy_buttonstate.buttondown[i] = newstate; // NOTE: This can cause a reentrant call of IN_Commands, via SCR_ModalMessage when confirming a new game. IN_JoyKeyEvent(oldstate, newstate, IN_KeyForControllerButton((SDL_GameControllerButton)i), &joy_buttontimer[i]); } for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++) { newaxisstate.axisvalue[i] = SDL_GameControllerGetAxis(joy_active_controller, (SDL_GameControllerAxis)i) / 32768.0f; } // emit emulated arrow keys so the analog sticks can be used in the menu if (key_dest != key_game) { IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] < -stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] < -stickthreshold, K_LEFTARROW, &joy_emulatedkeytimer[0]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] > stickthreshold, K_RIGHTARROW, &joy_emulatedkeytimer[1]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] < -stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] < -stickthreshold, K_UPARROW, &joy_emulatedkeytimer[2]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] > stickthreshold, K_DOWNARROW, &joy_emulatedkeytimer[3]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] < -stickthreshold,newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] < -stickthreshold, K_LEFTARROW, &joy_emulatedkeytimer[4]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] > stickthreshold, K_RIGHTARROW, &joy_emulatedkeytimer[5]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] < -stickthreshold,newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] < -stickthreshold, K_UPARROW, &joy_emulatedkeytimer[6]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] > stickthreshold, K_DOWNARROW, &joy_emulatedkeytimer[7]); } // emit emulated keys for the analog triggers IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERLEFT] > triggerthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERLEFT] > triggerthreshold, K_LTRIGGER, &joy_emulatedkeytimer[8]); IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] > triggerthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] > triggerthreshold, K_RTRIGGER, &joy_emulatedkeytimer[9]); joy_axisstate = newaxisstate; }
f32 getControllerAxis(u32 controllerIndex, ControllerAxis axis) { SDL_GameController* gc = g_controllerHandles[controllerIndex]; if (gc && SDL_GameControllerGetAttached(gc)) { s16 value = SDL_GameControllerGetAxis(gc, (SDL_GameControllerAxis)axis); if (axis == ControllerAxis::LeftY) value = -value; if (value >= 0) return (f32)value / 32767.0f; return (f32)value / 32768.0f; } return 0.0f; }
int GameController::getRawRightTrigger() { if (!isActive()) { return 0; } int n = SDL_GameControllerGetAxis(sdl_device, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); if (n < gamepad_trigger_deadzone) { return 0; } n -= gamepad_trigger_deadzone; return n; }
void DoInputSingle(photon_input_state &state, photon_input &input){ state.last_state = state.current_state; switch(state.type){ case photon_input_state::keyboard:{ const Uint8* keyboard = SDL_GetKeyboardState(nullptr); SDL_Keymod modifiers = SDL_GetModState(); state.current_state = keyboard[state.key] && (modifiers == state.modifiers || modifiers & state.modifiers); break; } case photon_input_state::joystick_axis:{ if(state.joystick_input_index > -1){ state.current_state = SDL_JoystickGetAxis(input.joystick, state.joystick_input_index) / 32768.0f; if(state.axis_input_negate){ state.current_state = -state.current_state; } } if(state.current_state < input.deadzone){ state.current_state = 0.0f; } break; } case photon_input_state::joystick_button:{ state.current_state = SDL_JoystickGetButton(input.joystick, state.joystick_input_index); break; } case photon_input_state::gamecontroller_axis:{ state.current_state = SDL_GameControllerGetAxis(input.controller, state.controller_axis) / 32768.0f; if(state.axis_input_negate){ state.current_state = -state.current_state; } if(state.current_state < input.deadzone){ state.current_state = 0.0f; } break; } case photon_input_state::gamecontroller_button:{ state.current_state = SDL_GameControllerGetButton(input.controller, state.controller_button); break; } case photon_input_state::none: break; } }
int GetKeyValue(PIN_GameControllerEntry* ctrl,PIN_GameControllerKeyInfo key) { if(key.KeyType == PIN_GKT_BUTTON) { return SDL_GameControllerGetButton(ctrl->Controller,key.Button); } else if(key.KeyType == PIN_GKT_AXIS) { if(key.Axis == SDL_CONTROLLER_AXIS_INVALID) { printf("Should NOT come this far!\n"); } else { Sint16 v = SDL_GameControllerGetAxis(ctrl->Controller,key.Axis); return v; } } return 0; }
int GameController::getAxis(State & state, SDL_GameController * gamecontroller){ Stack * stack = state.stack; stack->push<int>(SDL_GameControllerGetAxis(gamecontroller, static_cast<SDL_GameControllerAxis>(stack->to<int>(1)))); return 1; }
/* * IN_SDL_JoyCommands * * SDL game controller code called in IN_Commands. */ void IN_SDL_JoyCommands( void ) { int i, buttons = 0, buttonsDiff; static int buttonsOld; const int keys[] = { K_A_BUTTON, K_B_BUTTON, K_X_BUTTON, K_Y_BUTTON, K_ESCAPE, 0, 0, K_LSTICK, K_RSTICK, K_LSHOULDER, K_RSHOULDER, K_DPAD_UP, K_DPAD_DOWN, K_DPAD_LEFT, K_DPAD_RIGHT, K_LTRIGGER, K_RTRIGGER }; if( in_sdl_joyInitialized ) { SDL_GameControllerUpdate(); if( in_sdl_joyController && !SDL_GameControllerGetAttached( in_sdl_joyController ) ) { SDL_GameControllerClose( in_sdl_joyController ); in_sdl_joyController = NULL; } if( !in_sdl_joyController ) { int num = SDL_NumJoysticks(); for( i = 0; i < num; i++ ) { in_sdl_joyController = SDL_GameControllerOpen( i ); if( in_sdl_joyController ) break; } } } if( in_sdl_joyActive ) { SDL_GameController *controller = in_sdl_joyController; if( controller ) { for( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) { if( keys[i] && SDL_GameControllerGetButton( controller, i ) ) buttons |= 1 << i; } if( SDL_GameControllerGetButton( controller, SDL_CONTROLLER_BUTTON_START ) ) buttons |= 1 << SDL_CONTROLLER_BUTTON_BACK; if( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT ) > ( 30 * 128 ) ) buttons |= 1 << SDL_CONTROLLER_BUTTON_MAX; if( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT ) > ( 30 * 128 ) ) buttons |= 1 << ( SDL_CONTROLLER_BUTTON_MAX + 1 ); } } buttonsDiff = buttons ^ buttonsOld; if( buttonsDiff ) { unsigned int time = Sys_Milliseconds(); for( i = 0; i < ( sizeof( keys ) / sizeof( keys[0] ) ); i++ ) { if( buttonsDiff & ( 1 << i ) ) Key_Event( keys[i], ( buttons & ( 1 << i ) ) ? true : false, time ); } buttonsOld = buttons; } }
int16_t axis_state(axis a) const noexcept { return SDL_GameControllerGetAxis(ptr.get(), static_cast<SDL_GameControllerAxis>(a)); }
static bool getJoystickButtonState(const config::input::InputDevice *device, SDL_GameController *controller, vpad::Channel channel, vpad::Core button) { decaf_check(device); decaf_check(controller); auto joystick = SDL_GameControllerGetJoystick(controller); decaf_check(joystick); auto index = -1; auto name = SDL_CONTROLLER_BUTTON_INVALID; // SDL has no concept of ZR/ZL "buttons" (only axes) so we have to // kludge around... auto axisName = SDL_CONTROLLER_AXIS_INVALID; switch (button) { case vpad::Core::Up: index = device->button_up; name = SDL_CONTROLLER_BUTTON_DPAD_UP; break; case vpad::Core::Down: index = device->button_down; name = SDL_CONTROLLER_BUTTON_DPAD_DOWN; break; case vpad::Core::Left: index = device->button_left; name = SDL_CONTROLLER_BUTTON_DPAD_LEFT; break; case vpad::Core::Right: index = device->button_right; name = SDL_CONTROLLER_BUTTON_DPAD_RIGHT; break; case vpad::Core::A: index = device->button_a; name = SDL_CONTROLLER_BUTTON_B; // SDL uses stupid Microsoft mapping :P break; case vpad::Core::B: index = device->button_b; name = SDL_CONTROLLER_BUTTON_A; break; case vpad::Core::X: index = device->button_x; name = SDL_CONTROLLER_BUTTON_Y; break; case vpad::Core::Y: index = device->button_y; name = SDL_CONTROLLER_BUTTON_X; break; case vpad::Core::TriggerR: index = device->button_trigger_r; name = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; break; case vpad::Core::TriggerL: index = device->button_trigger_l; name = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; break; case vpad::Core::TriggerZR: index = device->button_trigger_zr; axisName = SDL_CONTROLLER_AXIS_TRIGGERRIGHT; break; case vpad::Core::TriggerZL: index = device->button_trigger_zl; axisName = SDL_CONTROLLER_AXIS_TRIGGERLEFT; break; case vpad::Core::LeftStick: index = device->button_stick_l; name = SDL_CONTROLLER_BUTTON_LEFTSTICK; break; case vpad::Core::RightStick: index = device->button_stick_r; name = SDL_CONTROLLER_BUTTON_RIGHTSTICK; break; case vpad::Core::Plus: index = device->button_plus; name = SDL_CONTROLLER_BUTTON_START; break; case vpad::Core::Minus: index = device->button_minus; name = SDL_CONTROLLER_BUTTON_BACK; break; case vpad::Core::Home: index = device->button_home; name = SDL_CONTROLLER_BUTTON_GUIDE; break; case vpad::Core::Sync: index = device->button_sync; break; } if (index >= 0) { return !!SDL_JoystickGetButton(joystick, index); } else if (index == -2) { if (name != SDL_CONTROLLER_BUTTON_INVALID) { return !!SDL_GameControllerGetButton(controller, name); } else if (axisName != SDL_CONTROLLER_AXIS_INVALID) { // ZL/ZR kludge int value = SDL_GameControllerGetAxis(controller, axisName); return value >= 16384; } } return false; }
CIControllerState SDL2EventHandler::getControllerState(uint16 index) { if(!getSDL2Context()) return {}; SDL_GameController* gc = getSDL2Context()->controllers[index]; if(!gc) return {}; CIControllerState state; state.axes.e.l_x = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTX); state.axes.e.l_y = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTY); state.axes.e.r_x = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_RIGHTX); state.axes.e.r_y = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_RIGHTY); state.axes.e.t_l = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_TRIGGERLEFT); state.axes.e.t_r = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); state.buttons.e.a = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_A); state.buttons.e.b = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_B); state.buttons.e.x = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_X); state.buttons.e.y = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_Y); state.buttons.e.back = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_BACK); state.buttons.e.guide = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_GUIDE); state.buttons.e.start = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_START); state.buttons.e.s_l = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_LEFTSTICK); state.buttons.e.s_r = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_RIGHTSTICK); state.buttons.e.b_l = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); state.buttons.e.b_r = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); state.buttons.e.p_up = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_DPAD_UP); state.buttons.e.p_down = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_DPAD_DOWN); state.buttons.e.p_left = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_DPAD_LEFT); state.buttons.e.p_right = SDL_GameControllerGetButton(gc, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); return state; }
SDL_bool WatchGameController(SDL_GameController * gamecontroller) { /* This is indexed by SDL_GameControllerButton. */ static const struct { int x; int y; } button_positions[] = { {387, 167}, /* A */ {431, 132}, /* B */ {342, 132}, /* X */ {389, 101}, /* Y */ {174, 132}, /* BACK */ {233, 132}, /* GUIDE */ {289, 132}, /* START */ {75, 154}, /* LEFTSTICK */ {305, 230}, /* RIGHTSTICK */ {77, 40}, /* LEFTSHOULDER */ {396, 36}, /* RIGHTSHOULDER */ {154, 188}, /* DPAD_UP */ {154, 249}, /* DPAD_DOWN */ {116, 217}, /* DPAD_LEFT */ {186, 217}, /* DPAD_RIGHT */ }; /* This is indexed by SDL_GameControllerAxis. */ static const struct { int x; int y; double angle; } axis_positions[] = { {75, 154, 0.0}, /* LEFTX */ {75, 154, 90.0}, /* LEFTY */ {305, 230, 0.0}, /* RIGHTX */ {305, 230, 90.0}, /* RIGHTY */ {91, 0, 90.0}, /* TRIGGERLEFT */ {375, 0, 90.0}, /* TRIGGERRIGHT */ }; const char *name = SDL_GameControllerName(gamecontroller); const char *basetitle = "Game Controller Test: "; const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1; char *title = (char *)SDL_malloc(titlelen); SDL_Texture *background, *button, *axis; SDL_Window *window = NULL; SDL_Renderer *screen = NULL; SDL_bool retval = SDL_FALSE; SDL_bool done = SDL_FALSE; SDL_Event event; int i; if (title) { SDL_snprintf(title, titlelen, "%s%s", basetitle, name); } /* Create a window to display controller state */ window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, 0); if (window == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError()); return SDL_FALSE; } screen = SDL_CreateRenderer(window, -1, 0); if (screen == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); SDL_DestroyWindow(window); return SDL_FALSE; } SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE); SDL_RenderClear(screen); SDL_RenderPresent(screen); SDL_RaiseWindow(window); /* scale for platforms that don't give you the window size you asked for. */ SDL_RenderSetLogicalSize(screen, SCREEN_WIDTH, SCREEN_HEIGHT); background = LoadTexture(screen, "controllermap.bmp", SDL_FALSE); button = LoadTexture(screen, "button.bmp", SDL_TRUE); axis = LoadTexture(screen, "axis.bmp", SDL_TRUE); if (!background || !button || !axis) { SDL_DestroyRenderer(screen); SDL_DestroyWindow(window); return SDL_FALSE; } SDL_SetTextureColorMod(button, 10, 255, 21); SDL_SetTextureColorMod(axis, 10, 255, 21); /* !!! FIXME: */ /*SDL_RenderSetLogicalSize(screen, background->w, background->h);*/ /* Print info about the controller we are watching */ SDL_Log("Watching controller %s\n", name ? name : "Unknown Controller"); /* Loop, getting controller events! */ while (!done) { /* blank screen, set up for drawing this frame. */ SDL_SetRenderDrawColor(screen, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE); SDL_RenderClear(screen); SDL_RenderCopy(screen, background, NULL, NULL); while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym != SDLK_ESCAPE) { break; } /* Fall through to signal quit */ case SDL_QUIT: done = SDL_TRUE; break; default: break; } } /* Update visual controller state */ for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) { if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) { const SDL_Rect dst = { button_positions[i].x, button_positions[i].y, 50, 50 }; SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, 0); } } for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; ++i) { const Sint16 deadzone = 8000; /* !!! FIXME: real deadzone */ const Sint16 value = SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i)); if (value < -deadzone) { const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 }; const double angle = axis_positions[i].angle; SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0); } else if (value > deadzone) { const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 }; const double angle = axis_positions[i].angle + 180.0; SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0); } } SDL_RenderPresent(screen); if (!SDL_GameControllerGetAttached(gamecontroller)) { done = SDL_TRUE; retval = SDL_TRUE; /* keep going, wait for reattach. */ } } SDL_DestroyRenderer(screen); SDL_DestroyWindow(window); return retval; }
void loop(void *arg) { SDL_Event event; int i; SDL_GameController *gamecontroller = (SDL_GameController *)arg; /* blank screen, set up for drawing this frame. */ SDL_SetRenderDrawColor(screen, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE); SDL_RenderClear(screen); SDL_RenderCopy(screen, background, NULL, NULL); while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym != SDLK_ESCAPE) { break; } /* Fall through to signal quit */ case SDL_QUIT: done = SDL_TRUE; break; default: break; } } /* Update visual controller state */ for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) { if (SDL_GameControllerGetButton( gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) { const SDL_Rect dst = {button_positions[i].x, button_positions[i].y, 50, 50}; SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, 0); } } for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; ++i) { const Sint16 deadzone = 8000; /* !!! FIXME: real deadzone */ const Sint16 value = SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i)); if (value < -deadzone) { const SDL_Rect dst = {axis_positions[i].x, axis_positions[i].y, 50, 50}; const double angle = axis_positions[i].angle; SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0); } else if (value > deadzone) { const SDL_Rect dst = {axis_positions[i].x, axis_positions[i].y, 50, 50}; const double angle = axis_positions[i].angle + 180.0; SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0); } } SDL_RenderPresent(screen); if (!SDL_GameControllerGetAttached(gamecontroller)) { done = SDL_TRUE; retval = SDL_TRUE; /* keep going, wait for reattach. */ } #ifdef __EMSCRIPTEN__ if (done) { emscripten_cancel_main_loop(); } #endif }
inline void SDLHandleUserInput(SDL_Event *Event, game_code *GameCode, game_memory *GameMemory, keyboard_input *KeyboardInput, gamepad_input *GamePadInput) { int KeyCode = Event->key.keysym.sym; uint8 GamePadButton = Event->cbutton.button; const uint8 *KeyState = SDL_GetKeyboardState(NULL); switch(Event->type) { case SDL_KEYDOWN: if(KeyCode == SDLK_ESCAPE) { HandleButtonPress(&KeyboardInput->Escape); GlobalRunning = false; } if(KeyCode == SDLK_a) { HandleButtonPress(&KeyboardInput->A); UnloadGameCode(GameCode); *GameCode = LoadGameCode(); GameMemory->IsInitialized = false; } if(KeyState[SDL_SCANCODE_LALT] && KeyState[SDL_SCANCODE_RETURN] ) { if(!Fullscreen){ SDL_SetWindowFullscreen(SDL_GetWindowFromID(Event->window.windowID), SDL_WINDOW_FULLSCREEN); SDL_SetRelativeMouseMode((SDL_bool)SDL_ENABLE); Fullscreen = true; } else { SDL_SetWindowFullscreen(SDL_GetWindowFromID(Event->window.windowID), 0); SDL_SetRelativeMouseMode((SDL_bool)SDL_DISABLE); Fullscreen = false; } } if(KeyCode == SDLK_b) { HandleButtonPress(&KeyboardInput->B); } if(KeyCode == SDLK_f) { HandleButtonPress(&KeyboardInput->F); } if(KeyCode == SDLK_UP) { HandleButtonPress(&KeyboardInput->Up); } if(KeyCode == SDLK_DOWN) { HandleButtonPress(&KeyboardInput->Down); } if(KeyCode == SDLK_LEFT) { HandleButtonPress(&KeyboardInput->Left); } if(KeyCode == SDLK_RIGHT) { HandleButtonPress(&KeyboardInput->Right); } break; case SDL_KEYUP: if(KeyCode == SDLK_ESCAPE) { HandleButtonRelease(&KeyboardInput->Escape); } if(KeyCode == SDLK_b) { HandleButtonRelease(&KeyboardInput->B); } if(KeyCode == SDLK_f) { HandleButtonRelease(&KeyboardInput->F); } if(KeyCode == SDLK_a) { HandleButtonRelease(&KeyboardInput->A); } if(KeyCode == SDLK_UP) { HandleButtonRelease(&KeyboardInput->Up); } if(KeyCode == SDLK_DOWN) { HandleButtonRelease(&KeyboardInput->Down); } if(KeyCode == SDLK_LEFT) { HandleButtonRelease(&KeyboardInput->Left); } if(KeyCode == SDLK_RIGHT) { HandleButtonRelease(&KeyboardInput->Right); } break; case SDL_CONTROLLERBUTTONDOWN: if(GamePadButton == SDL_CONTROLLER_BUTTON_A) { HandleButtonPress(&GamePadInput->AButton); } if(GamePadButton == SDL_CONTROLLER_BUTTON_B) { HandleButtonPress(&GamePadInput->BButton); } if(GamePadButton == SDL_CONTROLLER_BUTTON_X) { HandleButtonPress(&GamePadInput->XButton); } if(GamePadButton == SDL_CONTROLLER_BUTTON_Y) { HandleButtonPress(&GamePadInput->YButton); } break; case SDL_CONTROLLERBUTTONUP: if(GamePadButton == SDL_CONTROLLER_BUTTON_A) { HandleButtonRelease(&GamePadInput->AButton); } if(GamePadButton == SDL_CONTROLLER_BUTTON_B) { HandleButtonRelease(&GamePadInput->BButton); GlobalRunning = false; } if(GamePadButton == SDL_CONTROLLER_BUTTON_X) { HandleButtonRelease(&GamePadInput->XButton); } if(GamePadButton == SDL_CONTROLLER_BUTTON_Y) { HandleButtonRelease(&GamePadInput->YButton); } break; } // NOTE(Redab): Get values from gamepad joysticks and normalize. real32 LSX = (real32)SDL_GameControllerGetAxis(GamePadHandle, SDL_CONTROLLER_AXIS_LEFTX); if(LSX < 0) { GamePadInput->LeftStick.X = LSX / 32768.0f; } else { GamePadInput->LeftStick.X = LSX / 32767.0f; } real32 LSY = (real32)SDL_GameControllerGetAxis(GamePadHandle, SDL_CONTROLLER_AXIS_LEFTY); if(LSY < 0) { GamePadInput->LeftStick.Y = LSY / 32768.0f; } else { GamePadInput->LeftStick.Y = LSY / 32767.0f; } real32 RSX = (real32)SDL_GameControllerGetAxis(GamePadHandle, SDL_CONTROLLER_AXIS_RIGHTX); if(RSX < 0) { GamePadInput->RightStick.X = RSX / 32768.0f; } else { GamePadInput->RightStick.X = RSX / 32767.0f; } real32 RSY = (real32)SDL_GameControllerGetAxis(GamePadHandle, SDL_CONTROLLER_AXIS_RIGHTY); if(RSY < 0) { GamePadInput->RightStick.Y = RSY / 32768.0f; } else { GamePadInput->RightStick.Y = RSY / 32767.0f; } }
static int handle_event(void * data) { struct event_callback_t * cb = (struct event_callback_t *)(data); SDL_GameController * gc = NULL; SDL_Event e; int x, y, v; unsigned int button; while(1) { if(SDL_WaitEvent(&e)) { switch(e.type) { case SDL_KEYDOWN: if(cb->key.down) cb->key.down(cb->key.device, keycode_map(e.key.keysym.sym)); break; case SDL_KEYUP: if(cb->key.up) cb->key.up(cb->key.device, keycode_map(e.key.keysym.sym)); break; case SDL_MOUSEBUTTONDOWN: switch(e.button.button) { case SDL_BUTTON_LEFT: button = 0x01; break; case SDL_BUTTON_MIDDLE: button = 0x02; break; case SDL_BUTTON_RIGHT: button = 0x03; break; case SDL_BUTTON_X1: button = 0x04; break; case SDL_BUTTON_X2: button = 0x05; break; default: button = 0x00; break; } if(cb->mouse.down && (button != 0x00)) cb->mouse.down(cb->mouse.device, e.button.x, e.button.y, button); break; case SDL_MOUSEMOTION: if(cb->mouse.move) cb->mouse.move(cb->mouse.device, e.motion.x, e.motion.y); break; case SDL_MOUSEBUTTONUP: switch(e.button.button) { case SDL_BUTTON_LEFT: button = 0x01; break; case SDL_BUTTON_MIDDLE: button = 0x02; break; case SDL_BUTTON_RIGHT: button = 0x03; break; case SDL_BUTTON_X1: button = 0x04; break; case SDL_BUTTON_X2: button = 0x05; break; default: button = 0x00; break; } if(cb->mouse.up && (button != 0x00)) cb->mouse.up(cb->mouse.device, e.button.x, e.button.y, button); break; case SDL_MOUSEWHEEL: if(cb->mouse.wheel) cb->mouse.wheel(cb->mouse.device, e.wheel.x, e.wheel.y); break; /* case SDL_FINGERDOWN: if(cb->touch.begin) cb->touch.begin(cb->touch.device, (int)(e.tfinger.x * sandbox_sdl_fb_get_width()), (int)(e.tfinger.y * sandbox_sdl_fb_get_height()), (unsigned int)e.tfinger.fingerId); break; case SDL_FINGERMOTION: if(cb->touch.move) cb->touch.move(cb->touch.device, (int)(e.tfinger.x * sandbox_sdl_fb_get_width()), (int)(e.tfinger.y * sandbox_sdl_fb_get_height()), (unsigned int)e.tfinger.fingerId); break; case SDL_FINGERUP: if(cb->touch.end) cb->touch.end(cb->touch.device, (int)(e.tfinger.x * sandbox_sdl_fb_get_width()), (int)(e.tfinger.y * sandbox_sdl_fb_get_height()), (unsigned int)e.tfinger.fingerId); break; */ case SDL_CONTROLLERDEVICEADDED: if(!gc) gc = SDL_GameControllerOpen(e.cdevice.which); break; case SDL_CONTROLLERDEVICEREMOVED: if(gc) { SDL_GameControllerClose(gc); gc = NULL; } break; case SDL_CONTROLLERAXISMOTION: switch(e.caxis.axis) { case SDL_CONTROLLER_AXIS_LEFTX: case SDL_CONTROLLER_AXIS_LEFTY: x = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTX); y = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTY); if(cb->joystick.left_stick) cb->joystick.left_stick(cb->joystick.device, x, y); break; case SDL_CONTROLLER_AXIS_RIGHTX: case SDL_CONTROLLER_AXIS_RIGHTY: x = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_RIGHTX); y = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_RIGHTY); if(cb->joystick.right_stick) cb->joystick.right_stick(cb->joystick.device, x, y); break; case SDL_CONTROLLER_AXIS_TRIGGERLEFT: v = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_TRIGGERLEFT); if(cb->joystick.left_trigger) cb->joystick.left_trigger(cb->joystick.device, v); break; case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: v = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); if(cb->joystick.right_trigger) cb->joystick.right_trigger(cb->joystick.device, v); break; default: break; } break; case SDL_CONTROLLERBUTTONDOWN: switch(e.cbutton.button) { case SDL_CONTROLLER_BUTTON_A: button = 0x05; break; case SDL_CONTROLLER_BUTTON_B: button = 0x06; break; case SDL_CONTROLLER_BUTTON_X: button = 0x07; break; case SDL_CONTROLLER_BUTTON_Y: button = 0x08; break; case SDL_CONTROLLER_BUTTON_BACK: button = 0x09; break; case SDL_CONTROLLER_BUTTON_GUIDE: button = 0x0b; break; case SDL_CONTROLLER_BUTTON_START: button = 0x0a; break; case SDL_CONTROLLER_BUTTON_LEFTSTICK: button = 0x0e; break; case SDL_CONTROLLER_BUTTON_RIGHTSTICK: button = 0x0f; break; case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = 0x0c; break; case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = 0x0d; break; case SDL_CONTROLLER_BUTTON_DPAD_UP: button = 0x01; break; case SDL_CONTROLLER_BUTTON_DPAD_DOWN: button = 0x02; break; case SDL_CONTROLLER_BUTTON_DPAD_LEFT: button = 0x03; break; case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: button = 0x04; break; default: button = 0x00; break; } if(cb->joystick.button_down && (button != 0x00)) cb->joystick.button_down(cb->joystick.device, button); break; case SDL_CONTROLLERBUTTONUP: switch(e.cbutton.button) { case SDL_CONTROLLER_BUTTON_A: button = 0x05; break; case SDL_CONTROLLER_BUTTON_B: button = 0x06; break; case SDL_CONTROLLER_BUTTON_X: button = 0x07; break; case SDL_CONTROLLER_BUTTON_Y: button = 0x08; break; case SDL_CONTROLLER_BUTTON_BACK: button = 0x09; break; case SDL_CONTROLLER_BUTTON_GUIDE: button = 0x0b; break; case SDL_CONTROLLER_BUTTON_START: button = 0x0a; break; case SDL_CONTROLLER_BUTTON_LEFTSTICK: button = 0x0e; break; case SDL_CONTROLLER_BUTTON_RIGHTSTICK: button = 0x0f; break; case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = 0x0c; break; case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = 0x0d; break; case SDL_CONTROLLER_BUTTON_DPAD_UP: button = 0x01; break; case SDL_CONTROLLER_BUTTON_DPAD_DOWN: button = 0x02; break; case SDL_CONTROLLER_BUTTON_DPAD_LEFT: button = 0x03; break; case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: button = 0x04; break; default: button = 0x00; break; } if(cb->joystick.button_up && (button != 0x00)) cb->joystick.button_up(cb->joystick.device, button); break; case SDL_QUIT: sandbox_exit(); break; default: break; } } } return 0; }
void WatchGameController(SDL_GameController * gamecontroller) { SDL_Window *window = NULL; SDL_Renderer *screen = NULL; const char *name = NULL; int done = 0; SDL_Event event; int i; /* Create a window to display controller axis position */ window = SDL_CreateWindow("Game Controller Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (window == NULL) { fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError()); return; } screen = SDL_CreateRenderer(window, -1, 0); if (screen == NULL) { fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError()); SDL_DestroyWindow(window); return; } SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE); SDL_RenderClear(screen); SDL_RenderPresent(screen); SDL_RaiseWindow(window); /* Print info about the controller we are watching */ name = SDL_GameControllerName(gamecontroller); printf("Watching controller %s\n", name ? name : "Unknown Controller"); /* Loop, getting controller events! */ while (!done) { /* blank screen, set up for drawing this frame. */ SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE); SDL_RenderClear(screen); while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_CONTROLLERAXISMOTION: printf("Controller %d axis %d value: %d\n", event.caxis.which, event.caxis.axis, event.caxis.value); break; case SDL_CONTROLLERBUTTONDOWN: printf("Controller %d button %d down\n", event.cbutton.which, event.cbutton.button); break; case SDL_CONTROLLERBUTTONUP: printf("Controller %d button %d up\n", event.cbutton.which, event.cbutton.button); break; case SDL_KEYDOWN: if (event.key.keysym.sym != SDLK_ESCAPE) { break; } /* Fall through to signal quit */ case SDL_QUIT: done = 1; s_ForceQuit = SDL_TRUE; break; default: break; } } /* Update visual controller state */ SDL_SetRenderDrawColor(screen, 0x00, 0xFF, 0x00, SDL_ALPHA_OPAQUE); for (i = 0; i <SDL_CONTROLLER_BUTTON_MAX; ++i) { if (SDL_GameControllerGetButton(gamecontroller, i) == SDL_PRESSED) { DrawRect(screen, i * 34, SCREEN_HEIGHT - 34, 32, 32); } } SDL_SetRenderDrawColor(screen, 0xFF, 0x00, 0x00, SDL_ALPHA_OPAQUE); for (i = 0; i < SDL_CONTROLLER_AXIS_MAX / 2; ++i) { /* Draw the X/Y axis */ int x, y; x = (((int) SDL_GameControllerGetAxis(gamecontroller, i * 2 + 0)) + 32768); x *= SCREEN_WIDTH; x /= 65535; if (x < 0) { x = 0; } else if (x > (SCREEN_WIDTH - 16)) { x = SCREEN_WIDTH - 16; } y = (((int) SDL_GameControllerGetAxis(gamecontroller, i * 2 + 1)) + 32768); y *= SCREEN_HEIGHT; y /= 65535; if (y < 0) { y = 0; } else if (y > (SCREEN_HEIGHT - 16)) { y = SCREEN_HEIGHT - 16; } DrawRect(screen, x, y, 16, 16); } SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0xFF, SDL_ALPHA_OPAQUE); SDL_RenderPresent(screen); if ( !done ) done = SDL_GameControllerGetAttached( gamecontroller ) == 0; } SDL_DestroyRenderer(screen); SDL_DestroyWindow(window); }
s32 proc() { #if _WIN32 SetProcessDPIAware(); #endif #if defined(__APPLE__) SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1"); #endif // Initialize SDL if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC | SDL_INIT_TIMER | SDL_INIT_JOYSTICK ) < 0) { fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError()); return -1; } Loader::data_directory = SDL_GetPrefPath("HelveticaScenario", "Yearning"); SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt"); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); { SDL_DisplayMode display; SDL_GetDesktopDisplayMode(0, &display); Loader::settings_load(display.w, display.h); } if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) { fprintf(stderr, "Failed to set relative mouse mode: %s\n", SDL_GetError()); return -1; } window = SDL_CreateWindow ( "The Yearning", 0, 0, Settings::width, Settings::height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_MOUSE_CAPTURE | SDL_WINDOW_ALLOW_HIGHDPI | (Settings::fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_BORDERLESS) ); #if defined(__APPLE__) SDL_SetWindowGrab(window, SDL_TRUE); #endif // Open a window and create its OpenGL context if (!window) { fprintf(stderr, "Failed to open SDL window. Most likely your GPU is out of date! %s\n", SDL_GetError()); SDL_Quit(); return -1; } SDL_GLContext context = SDL_GL_CreateContext(window); if (!context) { fprintf(stderr, "Failed to create GL context: %s\n", SDL_GetError()); return -1; } if (SDL_GL_SetSwapInterval(Settings::vsync ? 1 : 0) != 0) { fprintf(stderr, "Failed to set OpenGL swap interval: %s\n", SDL_GetError()); return -1; } { glewExperimental = true; // Needed for core profile GLenum glew_result = glewInit(); if (glew_result != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW: %s\n", glewGetErrorString(glew_result)); return -1; } } glGetError(); // Clear initial error caused by GLEW render_init(); // Launch threads Sync<LoopSync> render_sync; LoopSwapper swapper_render_update = render_sync.swapper(0); LoopSwapper swapper_render = render_sync.swapper(1); Sync<PhysicsSync, 1> physics_sync; PhysicsSwapper swapper_physics = physics_sync.swapper(); PhysicsSwapper swapper_physics_update = physics_sync.swapper(); std::thread thread_physics(Physics::loop, &swapper_physics); std::thread thread_update(Loop::loop, &swapper_render_update, &swapper_physics_update); std::thread thread_ai(AI::loop); LoopSync* sync = swapper_render.get(); r64 last_time = SDL_GetTicks() / 1000.0; b8 has_focus = true; SDL_PumpEvents(); const u8* sdl_keys = SDL_GetKeyboardState(0); refresh_controllers(); while (true) { render(sync); // Swap buffers SDL_GL_SwapWindow(window); SDL_PumpEvents(); memcpy(sync->input.keys, sdl_keys, sizeof(sync->input.keys)); sync->input.keys[(s32)KeyCode::MouseWheelDown] = false; sync->input.keys[(s32)KeyCode::MouseWheelUp] = false; SDL_Event sdl_event; while (SDL_PollEvent(&sdl_event)) { if (sdl_event.type == SDL_QUIT) sync->quit = true; else if (sdl_event.type == SDL_MOUSEWHEEL) { b8 up = sdl_event.wheel.y > 0; if (sdl_event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) up = !up; if (up) sync->input.keys[(s32)KeyCode::MouseWheelUp] = true; else sync->input.keys[(s32)KeyCode::MouseWheelDown] = true; } else if (sdl_event.type == SDL_JOYDEVICEADDED || sdl_event.type == SDL_JOYDEVICEREMOVED) refresh_controllers(); else if (sdl_event.type == SDL_WINDOWEVENT) { if (sdl_event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) has_focus = true; else if (sdl_event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) has_focus = false; } } sync->input.focus = has_focus; s32 mouse_buttons = SDL_GetRelativeMouseState(&sync->input.cursor_x, &sync->input.cursor_y); sync->input.keys[(s32)KeyCode::MouseLeft] = mouse_buttons & (1 << 0); sync->input.keys[(s32)KeyCode::MouseMiddle] = mouse_buttons & (1 << 1); sync->input.keys[(s32)KeyCode::MouseRight] = mouse_buttons & (1 << 2); s32 active_gamepads = 0; for (s32 i = 0; i < MAX_GAMEPADS; i++) { SDL_GameController* controller = controllers[i]; Gamepad* gamepad = &sync->input.gamepads[i]; gamepad->active = controller != 0; gamepad->btns = 0; if (gamepad->active) { gamepad->left_x = (r32)SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX) / 32767.0f; gamepad->left_y = (r32)SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY) / 32767.0f; gamepad->right_x = (r32)SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX) / 32767.0f; gamepad->right_y = (r32)SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY) / 32767.0f; gamepad->left_trigger = (r32)SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) / 32767.0f; gamepad->right_trigger = (r32)SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) / 32767.0f; if (gamepad->left_trigger > 0.5f) gamepad->btns |= Gamepad::Btn::LeftTrigger; if (gamepad->right_trigger > 0.5f) gamepad->btns |= Gamepad::Btn::RightTrigger; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) gamepad->btns |= Gamepad::Btn::LeftShoulder; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) gamepad->btns |= Gamepad::Btn::RightShoulder; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSTICK)) gamepad->btns |= Gamepad::Btn::LeftClick; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_RIGHTSTICK)) gamepad->btns |= Gamepad::Btn::RightClick; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A)) gamepad->btns |= Gamepad::Btn::A; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_B)) gamepad->btns |= Gamepad::Btn::B; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X)) gamepad->btns |= Gamepad::Btn::X; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_Y)) gamepad->btns |= Gamepad::Btn::Y; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_BACK)) gamepad->btns |= Gamepad::Btn::Back; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_START)) gamepad->btns |= Gamepad::Btn::Start; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP)) gamepad->btns |= Gamepad::Btn::DUp; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN)) gamepad->btns |= Gamepad::Btn::DDown; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT)) gamepad->btns |= Gamepad::Btn::DLeft; if (SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) gamepad->btns |= Gamepad::Btn::DRight; if (gamepad->rumble > 0.0f) SDL_HapticRumblePlay(haptics[i], gamepad->rumble, 33); gamepad->rumble = 0.0f; active_gamepads++; } else { gamepad->left_x = 0.0f; gamepad->left_y = 0.0f; gamepad->right_x = 0.0f; gamepad->right_y = 0.0f; gamepad->left_trigger = 0.0f; gamepad->right_trigger = 0.0f; gamepad->rumble = 0.0f; } } SDL_GetWindowSize(window, &sync->input.width, &sync->input.height); r64 time = (SDL_GetTicks() / 1000.0); sync->time.total = (r32)time; sync->time.delta = vi_min((r32)(time - last_time), 0.25f); last_time = time; b8 quit = sync->quit; sync = swapper_render.swap<SwapType_Read>(); if (quit || sync->quit) break; } AI::quit(); thread_update.join(); thread_physics.join(); thread_ai.join(); SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); // SDL sucks for (s32 i = 0; i < MAX_GAMEPADS; i++) { if (haptics[i]) SDL_HapticClose(haptics[i]); } SDL_Quit(); return 0; }
/** * @brief Renderer::process_keys called each frame to process key inputs * @param keystate */ void Renderer::process_keys(const Uint8 *keystate){ if(keystate[SDL_SCANCODE_A]){ camera_position = camera_position - 0.05f*glm::vec3(glm::row(world_to_camera_matrix, 0)); } if(keystate[SDL_SCANCODE_D]){ camera_position = camera_position + 0.05f*glm::vec3(glm::row(world_to_camera_matrix, 0)); } if(keystate[SDL_SCANCODE_W]){ camera_position = camera_position - 0.05f*glm::vec3(glm::row(world_to_camera_matrix, 2)); } if(keystate[SDL_SCANCODE_S]){ camera_position = camera_position + 0.05f*glm::vec3(glm::row(world_to_camera_matrix, 2)); } if(keystate[SDL_SCANCODE_LSHIFT]){ camera_position[1] -= 0.05; } if(keystate[SDL_SCANCODE_SPACE]){ camera_position[1] += 0.05; } if(keystate[SDL_SCANCODE_Q]){ quit_flag = true; } if(gamepad != NULL){ float left_axis_x = SDL_GameControllerGetAxis(gamepad, (SDL_GameControllerAxis)0)/32768.0; float left_axis_y = SDL_GameControllerGetAxis(gamepad, (SDL_GameControllerAxis)1)/32768.0; float right_axis_x = SDL_GameControllerGetAxis(gamepad, (SDL_GameControllerAxis)2)/32768.0; float right_axis_y = SDL_GameControllerGetAxis(gamepad, (SDL_GameControllerAxis)3)/32768.0; // xbox360 controllers need a surprisingly large deadzone. These values are // lifted from microsofts xinput.h. float XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE = 7849.0/32768.0; float XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE = 8689.0/32768.0; if(fabs(left_axis_x) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE){ left_axis_x = 0.0f; } else { left_axis_x -= sgn(left_axis_x)*XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE; } if(fabs(left_axis_y) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE){ left_axis_y = 0.0f; } else { left_axis_y -= sgn(left_axis_y)*XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE; } if(fabs(right_axis_x) < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE){ right_axis_x = 0.0f; } else { right_axis_x -= sgn(right_axis_x)*XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE; } if(fabs(right_axis_y) < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE){ right_axis_y = 0.0f; } else { right_axis_y -= sgn(right_axis_y)*XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE; } camera_horizontal -= 0.06*right_axis_x; camera_vertical -= 0.06*right_axis_y; if(camera_vertical < -M_PI/2.0) camera_vertical = -M_PI/2.0; if(camera_vertical > M_PI/2.0) camera_vertical = M_PI/2.0; camera_position = camera_position + left_axis_y*0.07f*glm::vec3(glm::row(world_to_camera_matrix, 2)); camera_position = camera_position + left_axis_x*0.07f*glm::vec3(glm::row(world_to_camera_matrix, 0)); Uint8 left_shoulder_button = SDL_GameControllerGetButton(gamepad, (SDL_GameControllerButton)9); // left shoulder button Uint8 right_shoulder_button = SDL_GameControllerGetButton(gamepad, (SDL_GameControllerButton)10); // right shoulder button Uint8 start_button = SDL_GameControllerGetButton(gamepad, (SDL_GameControllerButton)6); // start button if(left_shoulder_button == 1){ camera_position[1] -= 0.04; } if(right_shoulder_button == 1){ camera_position[1] += 0.04; } if(start_button == 1){ quit_flag = true; } } }