void EmuScreen::processAxis(const AxisInput &axis, int direction) { std::vector<int> results; KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, direction, &results); std::vector<int> resultsOpposite; KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, -direction, &resultsOpposite); for (size_t i = 0; i < results.size(); i++) { int result = results[i]; switch (result) { case VIRTKEY_AXIS_X_MIN: __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_X_MAX: __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MIN: __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MAX: __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_RIGHT_X_MIN: __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_X_MAX: __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MIN: __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MAX: __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_RIGHT); break; default: if (axis.value >= AXIS_BIND_THRESHOLD || axis.value <= -AXIS_BIND_THRESHOLD) { pspKey(result, KEY_DOWN); // Also unpress the other direction. std::vector<int> opposite; KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, axis.value >= 0 ? -1 : 1, &opposite); for (size_t i = 0; i < opposite.size(); i++) { pspKey(opposite[i], KEY_UP); } // Hm, why do we use a different way below? } else { // Release both directions, trying to deal with some erratic controllers that can cause it to stick. pspKey(result, KEY_UP); for (size_t i = 0; i < resultsOpposite.size(); i++) { pspKey(resultsOpposite[i], KEY_UP); } } } } }
void EmuScreen::onVKeyDown(int virtualKeyCode) { I18NCategory *s = GetI18NCategory("Screen"); switch (virtualKeyCode) { case VIRTKEY_SPEED_TOGGLE: if (PSP_CoreParameter().fpsLimit == 0) { PSP_CoreParameter().fpsLimit = 1; osm.Show(s->T("fixed", "Speed: fixed"), 1.0); } else if (PSP_CoreParameter().fpsLimit == 1) { PSP_CoreParameter().fpsLimit = 0; osm.Show(s->T("standard", "Speed: standard"), 1.0); } break; // On Android, this is take care of in update() using input.buttons & back // Should get rid of that but not now. #ifndef ANDROID case VIRTKEY_PAUSE: screenManager()->push(new PauseScreen()); break; #endif case VIRTKEY_AXIS_X_MIN: __CtrlSetAnalogX(-1.0f, CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_X_MAX: __CtrlSetAnalogX(1.0f, CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MIN: __CtrlSetAnalogY(-1.0f, CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MAX: __CtrlSetAnalogY(1.0f, CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_RIGHT_X_MIN: __CtrlSetAnalogX(-1.0f, CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_X_MAX: __CtrlSetAnalogX(1.0f, CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MIN: __CtrlSetAnalogY(-1.0f, CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MAX: __CtrlSetAnalogY(1.0f, CTRL_STICK_RIGHT); break; } }
void EmuScreen::processAxis(const AxisInput &axis, int direction) { int result = KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, direction); int resultOpposite = KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, -direction); if (result == KEYMAP_ERROR_UNKNOWN_KEY) return; switch (result) { case VIRTKEY_AXIS_X_MIN: __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_X_MAX: __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MIN: __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MAX: __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_RIGHT_X_MIN: __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_X_MAX: __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MIN: __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MAX: __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_RIGHT); break; default: if (axis.value >= AXIS_BIND_THRESHOLD || axis.value <= -AXIS_BIND_THRESHOLD) { pspKey(result, KEY_DOWN); // Also unpress the other direction. result = KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, axis.value >= 0 ? -1 : 1); if (result != KEYMAP_ERROR_UNKNOWN_KEY) pspKey(result, KEY_UP); } else { // Release both directions, trying to deal with some erratic controllers that can cause it to stick. pspKey(result, KEY_UP); pspKey(resultOpposite, KEY_UP); } } }
void EmuScreen::update(InputState &input) { if (!booted_) bootGame(gamePath_); UIScreen::update(input); // Simply forcibily update to the current screen size every frame. Doesn't cost much. PSP_CoreParameter().outputWidth = dp_xres; PSP_CoreParameter().outputHeight = dp_yres; PSP_CoreParameter().pixelWidth = pixel_xres; PSP_CoreParameter().pixelHeight = pixel_yres; UpdateUIState(UISTATE_INGAME); if (errorMessage_.size()) { I18NCategory *g = GetI18NCategory("Error"); std::string errLoadingFile = g->T("Error loading file"); errLoadingFile.append(" "); errLoadingFile.append(g->T(errorMessage_.c_str())); screenManager()->push(new PromptScreen( errLoadingFile, "OK", "")); errorMessage_ = ""; return; } if (invalid_) return; float leftstick_x = 0.0f; float leftstick_y = 0.0f; float rightstick_x = 0.0f; float rightstick_y = 0.0f; // Virtual keys. __CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]); // Apply tilt to left stick // TODO: Make into an axis #ifdef USING_GLES2 if (g_Config.bAccelerometerToAnalogHoriz) { // TODO: Deadzone, etc. leftstick_x += clamp1(curve1(input.acc.y) * 2.0f) * g_Config.iTiltSensitivity / 100; __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); } #endif // Make sure fpsLimit starts at 0 if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1) { PSP_CoreParameter().fpsLimit = 0; } // This is here to support the iOS on screen back button. if (pauseTrigger_) { pauseTrigger_ = false; screenManager()->push(new GamePauseScreen(gamePath_)); } }
void EmuScreen::axis(const AxisInput &axis) { int result = KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, axis.value >= 0 ? 1 : -1); if (result == KEYMAP_ERROR_UNKNOWN_KEY) return; switch (result) { case VIRTKEY_AXIS_X_MIN: __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_X_MAX: __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MIN: __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MAX: __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_RIGHT_X_MIN: __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_X_MAX: __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MIN: __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MAX: __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_RIGHT); break; default: if (axis.value >= AXIS_BIND_THRESHOLD || axis.value <= -AXIS_BIND_THRESHOLD) { pspKey(result, KEY_DOWN); // Also unpress the other direction. result = KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, axis.value >= 0 ? -1 : 1); if (result != KEYMAP_ERROR_UNKNOWN_KEY) pspKey(result, KEY_UP); } else { pspKey(result, KEY_UP); } } }
inline void EmuScreen::setVKeyAnalogX(int stick, int virtualKeyMin, int virtualKeyMax) { float axis = 0.0f; // The down events can repeat, so just trust the virtKeys array. if (virtKeys[virtualKeyMin - VIRTKEY_FIRST]) axis -= 1.0f; if (virtKeys[virtualKeyMax - VIRTKEY_FIRST]) axis += 1.0f; __CtrlSetAnalogX(axis, stick); }
inline void EmuScreen::setVKeyAnalogX(int stick, int virtualKeyMin, int virtualKeyMax) { const float value = virtKeys[VIRTKEY_ANALOG_LIGHTLY - VIRTKEY_FIRST] ? 0.5f : 1.0f; float axis = 0.0f; // The down events can repeat, so just trust the virtKeys array. if (virtKeys[virtualKeyMin - VIRTKEY_FIRST]) axis -= value; if (virtKeys[virtualKeyMax - VIRTKEY_FIRST]) axis += value; __CtrlSetAnalogX(axis, stick); }
void EmuScreen::update(InputState &input) { if (!booted_) bootGame(gamePath_); UIScreen::update(input); // Simply forcibily update to the current screen size every frame. Doesn't cost much. PSP_CoreParameter().outputWidth = dp_xres; PSP_CoreParameter().outputHeight = dp_yres; PSP_CoreParameter().pixelWidth = pixel_xres; PSP_CoreParameter().pixelHeight = pixel_yres; globalUIState = UISTATE_INGAME; if (errorMessage_.size()) { screenManager()->push(new PromptScreen( "Error loading file: " + errorMessage_, "OK", "")); errorMessage_ = ""; return; } if (invalid_) return; float leftstick_x = 0.0f; float leftstick_y = 0.0f; float rightstick_x = 0.0f; float rightstick_y = 0.0f; // Virtual keys. __CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]); // Apply tilt to left stick if (g_Config.bAccelerometerToAnalogHoriz) { // TODO: Deadzone, etc. leftstick_x += clamp1(curve1(input.acc.y) * 2.0f); __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); } // Make sure fpsLimit starts at 0 if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1) { PSP_CoreParameter().fpsLimit = 0; } // This is here to support the iOS on screen back button. if (pauseTrigger_) { pauseTrigger_ = false; if (g_Config.bNewUI) { screenManager()->push(new GamePauseScreen(gamePath_)); } else { screenManager()->push(new PauseScreen()); } } }
void EmuScreen::onVKeyUp(int virtualKeyCode) { switch (virtualKeyCode) { case VIRTKEY_AXIS_X_MIN: case VIRTKEY_AXIS_X_MAX: __CtrlSetAnalogX(0.0f, CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MIN: case VIRTKEY_AXIS_Y_MAX: __CtrlSetAnalogY(0.0f, CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_RIGHT_X_MIN: case VIRTKEY_AXIS_RIGHT_X_MAX: __CtrlSetAnalogX(0.0f, CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MIN: case VIRTKEY_AXIS_RIGHT_Y_MAX: __CtrlSetAnalogY(0.0f, CTRL_STICK_RIGHT); break; default: break; } }
void EmuScreen::update(InputState &input) { globalUIState = UISTATE_INGAME; if (errorMessage_.size()) { screenManager()->push(new ErrorScreen( "Error loading file", errorMessage_)); errorMessage_ = ""; return; } if (invalid_) return; float leftstick_x = 0.0f; float leftstick_y = 0.0f; float rightstick_x = 0.0f; float rightstick_y = 0.0f; // Virtual keys. __CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]); // First translate touches into native pad input. // Do this no matter the value of g_Config.bShowTouchControls, some people // like to use invisible controls... // Don't force on platforms that likely don't have a touchscreen, like Win32, OSX, and Linux... // TODO: What are good ifdefs for OSX and Linux, without breaking other mobile platforms? #ifdef _WIN32 if(g_Config.bShowTouchControls) { #endif // TODO: Make new better touch buttons so we don't have to do this crap. // Copy over the mouse data from the real inputstate. fakeInputState.mouse_valid = input.mouse_valid; fakeInputState.pad_last_buttons = fakeInputState.pad_buttons; fakeInputState.pad_buttons = input.pad_buttons; memcpy(fakeInputState.pointer_down, input.pointer_down, sizeof(input.pointer_down)); memcpy(fakeInputState.pointer_x, input.pointer_x, sizeof(input.pointer_x)); memcpy(fakeInputState.pointer_y, input.pointer_y, sizeof(input.pointer_y)); fakeInputState.pad_lstick_x = 0.0f; fakeInputState.pad_lstick_y = 0.0f; fakeInputState.pad_rstick_x = 0.0f; fakeInputState.pad_rstick_y = 0.0f; UpdateGamepad(fakeInputState); UpdateInputState(&fakeInputState); for (size_t i = 0; i < ARRAY_SIZE(legacy_touch_mapping); i++) { if (fakeInputState.pad_buttons_down & legacy_touch_mapping[i].from) __CtrlButtonDown(legacy_touch_mapping[i].to); if (fakeInputState.pad_buttons_up & legacy_touch_mapping[i].from) __CtrlButtonUp(legacy_touch_mapping[i].to); } leftstick_x += fakeInputState.pad_lstick_x; leftstick_y += fakeInputState.pad_lstick_y; rightstick_x += fakeInputState.pad_rstick_x; rightstick_y += fakeInputState.pad_rstick_y; if (g_Config.bShowAnalogStick) { __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); __CtrlSetAnalogY(clamp1(leftstick_y), CTRL_STICK_LEFT); } __CtrlSetAnalogX(clamp1(rightstick_x), CTRL_STICK_RIGHT); __CtrlSetAnalogY(clamp1(rightstick_y), CTRL_STICK_RIGHT); // Also send the special buttons to input, since that's where they're handled. input.pad_buttons_down |= fakeInputState.pad_buttons_down & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB | PAD_BUTTON_LEFT_THUMB); input.pad_buttons_up |= fakeInputState.pad_buttons_up & (PAD_BUTTON_MENU | PAD_BUTTON_BACK | PAD_BUTTON_RIGHT_THUMB | PAD_BUTTON_LEFT_THUMB); input.pad_buttons = fakeInputState.pad_buttons; #ifdef _WIN32 } #endif // Still checking input.pad_buttons here to support the onscreen throttle button. PSP_CoreParameter().unthrottle = virtKeys[VIRTKEY_UNTHROTTLE - VIRTKEY_FIRST] || (input.pad_buttons & PAD_BUTTON_UNTHROTTLE) != 0; // Apply tilt to left stick if (g_Config.bAccelerometerToAnalogHoriz) { // TODO: Deadzone, etc. leftstick_x += clamp1(curve1(input.acc.y) * 2.0f); __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); } // Make sure fpsLimit starts at 0 if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1) { PSP_CoreParameter().fpsLimit = 0; } // This is still here to support the iOS on screen back button. if (input.pad_buttons_down & (PAD_BUTTON_BACK)) { screenManager()->push(new PauseScreen()); } }
void EmuScreen::update(InputState &input) { if (!booted_) bootGame(gamePath_); UIScreen::update(input); // Simply forcibily update to the current screen size every frame. Doesn't cost much. PSP_CoreParameter().outputWidth = dp_xres; PSP_CoreParameter().outputHeight = dp_yres; PSP_CoreParameter().pixelWidth = pixel_xres; PSP_CoreParameter().pixelHeight = pixel_yres; UpdateUIState(UISTATE_INGAME); if (errorMessage_.size()) { // Special handling for ZIP files. It's not very robust to check an error message but meh, // at least it's pre-translation. if (errorMessage_.find("ZIP") != std::string::npos) { screenManager()->push(new InstallZipScreen(gamePath_)); errorMessage_ = ""; return; } I18NCategory *g = GetI18NCategory("Error"); std::string errLoadingFile = g->T("Error loading file", "Could not load game"); errLoadingFile.append(" "); errLoadingFile.append(g->T(errorMessage_.c_str())); screenManager()->push(new PromptScreen(errLoadingFile, "OK", "")); errorMessage_ = ""; return; } if (invalid_) return; float leftstick_x = 0.0f; float leftstick_y = 0.0f; float rightstick_x = 0.0f; float rightstick_y = 0.0f; // Virtual keys. __CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]); // Apply tilt to left stick // TODO: Make into an axis #ifdef USING_GLES2 if (g_Config.bAccelerometerToAnalogHoriz) { // Get the "base" coordinate system which is setup by the calibration system float base_x = g_Config.fTiltBaseX; float base_y = g_Config.fTiltBaseY; //convert the current input into base coordinates and normalize //TODO: check if all phones give values between [-50, 50]. I'm not sure how iOS works. float normalized_input_x = (input.acc.y - base_x) / 50.0 ; float normalized_input_y = (input.acc.x - base_y) / 50.0 ; //TODO: need a better name for computed x and y. float delta_x = tiltInputCurve(normalized_input_x * 2.0 * (g_Config.iTiltSensitivityX)) ; //if the invert is enabled, invert the motion if (g_Config.bInvertTiltX) { delta_x *= -1; } float delta_y = tiltInputCurve(normalized_input_y * 2.0 * (g_Config.iTiltSensitivityY)) ; if (g_Config.bInvertTiltY) { delta_y *= -1; } //clamp the delta between [-1, 1] leftstick_x += clamp1(delta_x); __CtrlSetAnalogX(clamp1(leftstick_x), CTRL_STICK_LEFT); leftstick_y += clamp1(delta_y); __CtrlSetAnalogY(clamp1(leftstick_y), CTRL_STICK_LEFT); } #endif // Make sure fpsLimit starts at 0 if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1) { PSP_CoreParameter().fpsLimit = 0; } // This is here to support the iOS on screen back button. if (pauseTrigger_) { pauseTrigger_ = false; screenManager()->push(new GamePauseScreen(gamePath_)); } }
void EmuScreen::processAxis(const AxisInput &axis, int direction) { // Sanity check if (axis.axisId < 0 || axis.axisId >= JOYSTICK_AXIS_MAX) { return; } std::vector<int> results; KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, direction, &results); for (size_t i = 0; i < results.size(); i++) { int result = results[i]; switch (result) { case VIRTKEY_AXIS_X_MIN: __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_X_MAX: __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MIN: __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_Y_MAX: __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_LEFT); break; case VIRTKEY_AXIS_RIGHT_X_MIN: __CtrlSetAnalogX(-fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_X_MAX: __CtrlSetAnalogX(fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MIN: __CtrlSetAnalogY(-fabs(axis.value), CTRL_STICK_RIGHT); break; case VIRTKEY_AXIS_RIGHT_Y_MAX: __CtrlSetAnalogY(fabs(axis.value), CTRL_STICK_RIGHT); break; } } std::vector<int> resultsOpposite; KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, -direction, &resultsOpposite); int axisState = 0; if ((direction == 1 && axis.value >= AXIS_BIND_THRESHOLD)) { axisState = 1; } else if (direction == -1 && axis.value <= -AXIS_BIND_THRESHOLD) { axisState = -1; } else { axisState = 0; } if (axisState != axisState_[axis.axisId]) { axisState_[axis.axisId] = axisState; if (axisState != 0) { for (size_t i = 0; i < results.size(); i++) { if (!IsAnalogStickKey(results[i])) pspKey(results[i], KEY_DOWN); } // Also unpress the other direction. for (size_t i = 0; i < resultsOpposite.size(); i++) { if (!IsAnalogStickKey(resultsOpposite[i])) pspKey(resultsOpposite[i], KEY_UP); } } else if (axisState == 0) { // Release both directions, trying to deal with some erratic controllers that can cause it to stick. for (size_t i = 0; i < results.size(); i++) { if (!IsAnalogStickKey(results[i])) pspKey(results[i], KEY_UP); } for (size_t i = 0; i < resultsOpposite.size(); i++) { if (!IsAnalogStickKey(resultsOpposite[i])) pspKey(resultsOpposite[i], KEY_UP); } } } }