From 61fb4ee580bc62506876913ca9e49a82cc70aaf1 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Sat, 16 Dec 2023 17:24:06 -0500 Subject: [PATCH] Some fixes and cleanup to joystick input --- indra/newview/app_settings/settings.xml | 11 + indra/newview/llfloaterjoystick.cpp | 20 +- indra/newview/llfloaterjoystick.h | 2 + indra/newview/llviewerjoystick.cpp | 407 ++++++++++++------ indra/newview/llviewerjoystick.h | 33 +- .../skins/default/xui/en/floater_joystick.xml | 13 +- 6 files changed, 341 insertions(+), 145 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5b1444ac6bc..77284034140 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -18124,5 +18124,16 @@ <key>Value</key> <string>0</string> </map> + <key>JoystickInvertPitch</key> + <map> + <key>Comment</key> + <string>Invert pitch of joystick input</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> </map> </llsd> diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index a797661d62f..8326999b96e 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -113,10 +113,15 @@ void LLFloaterJoystick::draw() refreshListOfDevices(); } + if (gFrameIntervalSeconds.value() == 0.0f) + { + joystick->updateStatus(); + } + for (U32 i = 0; i < 6; i++) { F32 value = joystick->getJoystickAxis(i); - sample(*sJoystickAxes[i], value * gFrameIntervalSeconds.value()); + sample(*sJoystickAxes[i], value); if (mAxisStatsBar[i]) { F32 minbar, maxbar; @@ -135,7 +140,7 @@ void LLFloaterJoystick::draw() BOOL LLFloaterJoystick::postBuild() { center(); - F32 range = gSavedSettings.getBOOL("Cursor3D") ? 128.f : 2.f; + F32 range = gSavedSettings.getBOOL("Cursor3D") ? 128.f : 0.5f; for (U32 i = 0; i < 6; i++) { @@ -155,6 +160,7 @@ BOOL LLFloaterJoystick::postBuild() childSetCommitCallback("JoystickFlycamEnabled",onCommitJoystickEnabled,this); childSetAction("SpaceNavigatorDefaults", onClickRestoreSNDefaults, this); + childSetAction("XboxDefaults", onClickRestoreXboxDefaults, this); childSetAction("cancel_btn", onClickCancel, this); childSetAction("ok_btn", onClickOK, this); @@ -431,6 +437,11 @@ void LLFloaterJoystick::onClickRestoreSNDefaults(void *joy_panel) setSNDefaults(); } +void LLFloaterJoystick::onClickRestoreXboxDefaults(void* joy_panel) +{ + setXboxDefaults(); +} + void LLFloaterJoystick::onClickCancel(void *joy_panel) { if (joy_panel) @@ -469,6 +480,11 @@ void LLFloaterJoystick::setSNDefaults() LLViewerJoystick::getInstance()->setSNDefaults(); } +void LLFloaterJoystick::setXboxDefaults() +{ + LLViewerJoystick::getInstance()->setXboxDefaults(); +} + void LLFloaterJoystick::onClose(bool app_quitting) { if (app_quitting) diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index f2788b70b55..5f4a8d77ef8 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -45,6 +45,7 @@ class LLFloaterJoystick final : public LLFloater virtual void cancel(); // Cancel the changed values. virtual void draw(); static void setSNDefaults(); + static void setXboxDefaults(); void addDevice(std::string &name, LLSD& value); @@ -63,6 +64,7 @@ class LLFloaterJoystick final : public LLFloater static void onCommitJoystickEnabled(LLUICtrl*, void*); static void onClickRestoreSNDefaults(void*); + static void onClickRestoreXboxDefaults(void*); static void onClickCancel(void*); static void onClickOK(void*); diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index f45d1255126..6f038209a18 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -60,8 +60,8 @@ #define RY_I 5 #define RZ_I 3 -F32 LLViewerJoystick::sLastDelta[] = {0,0,0,0,0,0,0}; -F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0}; +std::array<F32, 7> LLViewerJoystick::sLastDelta = {0,0,0,0,0,0,0}; +std::array<F32, 7> LLViewerJoystick::sDelta = {0,0,0,0,0,0,0}; // These constants specify the maximum absolute value coming in from the device. // HACK ALERT! the value of MAX_JOYSTICK_INPUT_VALUE is not arbitrary as it @@ -253,7 +253,7 @@ void LLViewerJoystick::updateEnabled(bool autoenable) void LLViewerJoystick::setOverrideCamera(bool val) { - if (!gSavedSettings.getBOOL("JoystickEnabled")) + if (!mJoystickEnabled) { mOverrideCamera = FALSE; } @@ -323,6 +323,76 @@ LLViewerJoystick::LLViewerJoystick() mPerfScale = 4000.f / gSysCPU.getMHz(); // hmm. why? mLastDeviceUUID = LLSD::Integer(1); + + gSavedSettings.getControl("JoystickEnabled")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("JoystickAxis0")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("JoystickAxis1")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("JoystickAxis2")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("JoystickAxis3")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("JoystickAxis4")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("JoystickAxis5")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("JoystickAxis6")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("Cursor3D")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AutoLeveling")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("ZoomDirect")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("JoystickAvatarEnabled")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("JoystickBuildEnabled")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("JoystickFlycamEnabled")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("AvatarAxisScale0")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisScale1")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisScale2")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisScale3")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisScale4")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisScale5")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("BuildAxisScale0")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisScale1")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisScale2")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisScale3")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisScale4")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisScale5")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("FlycamAxisScale0")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisScale1")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisScale2")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisScale3")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisScale4")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisScale5")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisScale6")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("AvatarAxisDeadZone0")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisDeadZone1")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisDeadZone2")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisDeadZone3")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisDeadZone4")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("AvatarAxisDeadZone5")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("BuildAxisDeadZone0")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisDeadZone1")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisDeadZone2")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisDeadZone3")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisDeadZone4")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildAxisDeadZone5")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("FlycamAxisDeadZone0")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisDeadZone1")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisDeadZone2")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisDeadZone3")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisDeadZone4")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisDeadZone5")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamAxisDeadZone6")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("AvatarFeathering")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("BuildFeathering")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + gSavedSettings.getControl("FlycamFeathering")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + gSavedSettings.getControl("JoystickInvertPitch")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); }); + + refreshFromSettings(); } // ----------------------------------------------------------------------------- @@ -435,6 +505,77 @@ void LLViewerJoystick::init(bool autoenable) #endif } +void LLViewerJoystick::refreshFromSettings() +{ + mJoystickEnabled = gSavedSettings.getBOOL("JoystickEnabled"); + + mJoystickAxis[0] = gSavedSettings.getS32("JoystickAxis0"); + mJoystickAxis[1] = gSavedSettings.getS32("JoystickAxis1"); + mJoystickAxis[2] = gSavedSettings.getS32("JoystickAxis2"); + mJoystickAxis[3] = gSavedSettings.getS32("JoystickAxis3"); + mJoystickAxis[4] = gSavedSettings.getS32("JoystickAxis4"); + mJoystickAxis[5] = gSavedSettings.getS32("JoystickAxis5"); + mJoystickAxis[6] = gSavedSettings.getS32("JoystickAxis6"); + + m3DCursor = gSavedSettings.getBOOL("Cursor3D"); + mAutoLeveling = gSavedSettings.getBOOL("AutoLeveling"); + mZoomDirect = gSavedSettings.getBOOL("ZoomDirect"); + + mAvatarEnabled = gSavedSettings.getBOOL("JoystickAvatarEnabled"); + mBuildEnabled = gSavedSettings.getBOOL("JoystickBuildEnabled"); + mFlycamEnabled = gSavedSettings.getBOOL("JoystickFlycamEnabled"); + + mAvatarAxisScale[0] = gSavedSettings.getF32("AvatarAxisScale0"); + mAvatarAxisScale[1] = gSavedSettings.getF32("AvatarAxisScale1"); + mAvatarAxisScale[2] = gSavedSettings.getF32("AvatarAxisScale2"); + mAvatarAxisScale[3] = gSavedSettings.getF32("AvatarAxisScale3"); + mAvatarAxisScale[4] = gSavedSettings.getF32("AvatarAxisScale4"); + mAvatarAxisScale[5] = gSavedSettings.getF32("AvatarAxisScale5"); + + mBuildAxisScale[0] = gSavedSettings.getF32("BuildAxisScale0"); + mBuildAxisScale[1] = gSavedSettings.getF32("BuildAxisScale1"); + mBuildAxisScale[2] = gSavedSettings.getF32("BuildAxisScale2"); + mBuildAxisScale[3] = gSavedSettings.getF32("BuildAxisScale3"); + mBuildAxisScale[4] = gSavedSettings.getF32("BuildAxisScale4"); + mBuildAxisScale[5] = gSavedSettings.getF32("BuildAxisScale5"); + + mFlycamAxisScale[0] = gSavedSettings.getF32("FlycamAxisScale0"); + mFlycamAxisScale[1] = gSavedSettings.getF32("FlycamAxisScale1"); + mFlycamAxisScale[2] = gSavedSettings.getF32("FlycamAxisScale2"); + mFlycamAxisScale[3] = gSavedSettings.getF32("FlycamAxisScale3"); + mFlycamAxisScale[4] = gSavedSettings.getF32("FlycamAxisScale4"); + mFlycamAxisScale[5] = gSavedSettings.getF32("FlycamAxisScale5"); + mFlycamAxisScale[6] = gSavedSettings.getF32("FlycamAxisScale6"); + + mAvatarAxisDeadZone[0] = gSavedSettings.getF32("AvatarAxisDeadZone0"); + mAvatarAxisDeadZone[1] = gSavedSettings.getF32("AvatarAxisDeadZone1"); + mAvatarAxisDeadZone[2] = gSavedSettings.getF32("AvatarAxisDeadZone2"); + mAvatarAxisDeadZone[3] = gSavedSettings.getF32("AvatarAxisDeadZone3"); + mAvatarAxisDeadZone[4] = gSavedSettings.getF32("AvatarAxisDeadZone4"); + mAvatarAxisDeadZone[5] = gSavedSettings.getF32("AvatarAxisDeadZone5"); + + mBuildAxisDeadZone[0] = gSavedSettings.getF32("BuildAxisDeadZone0"); + mBuildAxisDeadZone[1] = gSavedSettings.getF32("BuildAxisDeadZone1"); + mBuildAxisDeadZone[2] = gSavedSettings.getF32("BuildAxisDeadZone2"); + mBuildAxisDeadZone[3] = gSavedSettings.getF32("BuildAxisDeadZone3"); + mBuildAxisDeadZone[4] = gSavedSettings.getF32("BuildAxisDeadZone4"); + mBuildAxisDeadZone[5] = gSavedSettings.getF32("BuildAxisDeadZone5"); + + mFlycamAxisDeadZone[0] = gSavedSettings.getF32("FlycamAxisDeadZone0"); + mFlycamAxisDeadZone[1] = gSavedSettings.getF32("FlycamAxisDeadZone1"); + mFlycamAxisDeadZone[2] = gSavedSettings.getF32("FlycamAxisDeadZone2"); + mFlycamAxisDeadZone[3] = gSavedSettings.getF32("FlycamAxisDeadZone3"); + mFlycamAxisDeadZone[4] = gSavedSettings.getF32("FlycamAxisDeadZone4"); + mFlycamAxisDeadZone[5] = gSavedSettings.getF32("FlycamAxisDeadZone5"); + mFlycamAxisDeadZone[6] = gSavedSettings.getF32("FlycamAxisDeadZone6"); + + mAvatarFeathering = gSavedSettings.getF32("AvatarFeathering"); // note: max feather is 32.0 + mBuildFeathering = gSavedSettings.getF32("BuildFeathering"); + mFlycamFeathering = gSavedSettings.getF32("FlycamFeathering"); + + mInvertPitch = gSavedSettings.getBOOL("JoystickInvertPitch"); +} + void LLViewerJoystick::initDevice(LLSD &guid) { #if LIB_NDOF @@ -476,7 +617,7 @@ void LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8 mLastDeviceUUID = guid; size_t dest_size = sizeof(mNdofDev->product); - strncpy(mNdofDev->product, name.c_str(), dest_size-1); + strncpy(mNdofDev->product, name.c_str(), dest_size); mNdofDev->product[dest_size-1] = '\0'; mNdofDev->manufacturer[0] = '\0'; @@ -537,6 +678,10 @@ void LLViewerJoystick::terminate() void LLViewerJoystick::updateStatus() { #if LIB_NDOF + if (!mNdofDev || !mNdofDev->private_data) + { + return; + } ndof_update(mNdofDev); @@ -579,7 +724,8 @@ void LLViewerJoystick::handleRun(F32 inc) // Decide whether to walk or run by applying a threshold, with slight // hysteresis to avoid oscillating between the two with input spikes. // Analog speed control would be better, but not likely any time soon. - if (inc > gSavedSettings.getF32("JoystickRunThreshold")) + static LLCachedControl<F32> joy_run_threshold(gSavedSettings, "JoystickRunThreshold"); + if (inc > joy_run_threshold) { if (1 == mJoystickRun) { @@ -685,7 +831,8 @@ void LLViewerJoystick::agentPitch(F32 pitch_inc) void LLViewerJoystick::agentYaw(F32 yaw_inc) { // Cannot steer some vehicles in mouselook if the script grabs the controls - if (gAgentCamera.cameraMouselook() && !gSavedSettings.getBOOL("JoystickMouselookYaw")) + static LLCachedControl<bool> joy_mouse_yaw(gSavedSettings, "JoystickMouselookYaw"); + if (gAgentCamera.cameraMouselook() && !joy_mouse_yaw) { gAgent.rotate(-yaw_inc, gAgent.getReferenceUpVector()); } @@ -723,47 +870,17 @@ void LLViewerJoystick::moveObjects(bool reset) static bool toggle_send_to_sim = false; if (!gFocusMgr.getAppHasFocus() || mDriverState != JDS_INITIALIZED - || !gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickBuildEnabled")) + || !mJoystickEnabled || !mBuildEnabled) { return; } - S32 axis[] = - { - gSavedSettings.getS32("JoystickAxis0"), - gSavedSettings.getS32("JoystickAxis1"), - gSavedSettings.getS32("JoystickAxis2"), - gSavedSettings.getS32("JoystickAxis3"), - gSavedSettings.getS32("JoystickAxis4"), - gSavedSettings.getS32("JoystickAxis5"), - }; - if (reset || mResetFlag) { - resetDeltas(axis); + resetDeltas(mJoystickAxis); return; } - F32 axis_scale[] = - { - gSavedSettings.getF32("BuildAxisScale0"), - gSavedSettings.getF32("BuildAxisScale1"), - gSavedSettings.getF32("BuildAxisScale2"), - gSavedSettings.getF32("BuildAxisScale3"), - gSavedSettings.getF32("BuildAxisScale4"), - gSavedSettings.getF32("BuildAxisScale5"), - }; - - F32 dead_zone[] = - { - gSavedSettings.getF32("BuildAxisDeadZone0"), - gSavedSettings.getF32("BuildAxisDeadZone1"), - gSavedSettings.getF32("BuildAxisDeadZone2"), - gSavedSettings.getF32("BuildAxisDeadZone3"), - gSavedSettings.getF32("BuildAxisDeadZone4"), - gSavedSettings.getF32("BuildAxisDeadZone5"), - }; - F32 cur_delta[6]; F32 time = gFrameIntervalSeconds.value(); @@ -774,12 +891,16 @@ void LLViewerJoystick::moveObjects(bool reset) } // max feather is 32 - F32 feather = gSavedSettings.getF32("BuildFeathering"); - bool is_zero = true, absolute = gSavedSettings.getBOOL("Cursor3D"); + F32 feather = mBuildFeathering; + bool is_zero = true, absolute = m3DCursor; for (U32 i = 0; i < 6; i++) { - cur_delta[i] = -mAxes[axis[i]]; + cur_delta[i] = -mAxes[mJoystickAxis[i]]; +// //BD - Invertable Pitch Controls + if (!mInvertPitch && i == 4) + cur_delta[i] = -cur_delta[i]; + F32 tmp = cur_delta[i]; if (absolute) { @@ -790,13 +911,13 @@ void LLViewerJoystick::moveObjects(bool reset) if (cur_delta[i] > 0) { - cur_delta[i] = llmax(cur_delta[i]-dead_zone[i], 0.f); + cur_delta[i] = llmax(cur_delta[i]- mBuildAxisDeadZone[i], 0.f); } else { - cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f); + cur_delta[i] = llmin(cur_delta[i]+ mBuildAxisDeadZone[i], 0.f); } - cur_delta[i] *= axis_scale[i]; + cur_delta[i] *= mBuildAxisScale[i]; if (!absolute) { @@ -845,26 +966,14 @@ void LLViewerJoystick::moveObjects(bool reset) void LLViewerJoystick::moveAvatar(bool reset) { if (!gFocusMgr.getAppHasFocus() || mDriverState != JDS_INITIALIZED - || !gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickAvatarEnabled")) + || !mJoystickEnabled || !mAvatarEnabled) { return; } - S32 axis[] = - { - // [1 0 2 4 3 5] - // [Z X Y RZ RX RY] - gSavedSettings.getS32("JoystickAxis0"), - gSavedSettings.getS32("JoystickAxis1"), - gSavedSettings.getS32("JoystickAxis2"), - gSavedSettings.getS32("JoystickAxis3"), - gSavedSettings.getS32("JoystickAxis4"), - gSavedSettings.getS32("JoystickAxis5") - }; - if (reset || mResetFlag) { - resetDeltas(axis); + resetDeltas(mJoystickAxis); if (reset) { // Note: moving the agent triggers agent camera mode; @@ -908,26 +1017,6 @@ void LLViewerJoystick::moveAvatar(bool reset) button_held = false; } - F32 axis_scale[] = - { - gSavedSettings.getF32("AvatarAxisScale0"), - gSavedSettings.getF32("AvatarAxisScale1"), - gSavedSettings.getF32("AvatarAxisScale2"), - gSavedSettings.getF32("AvatarAxisScale3"), - gSavedSettings.getF32("AvatarAxisScale4"), - gSavedSettings.getF32("AvatarAxisScale5") - }; - - F32 dead_zone[] = - { - gSavedSettings.getF32("AvatarAxisDeadZone0"), - gSavedSettings.getF32("AvatarAxisDeadZone1"), - gSavedSettings.getF32("AvatarAxisDeadZone2"), - gSavedSettings.getF32("AvatarAxisDeadZone3"), - gSavedSettings.getF32("AvatarAxisDeadZone4"), - gSavedSettings.getF32("AvatarAxisDeadZone5") - }; - // time interval in seconds between this frame and the previous F32 time = gFrameIntervalSeconds.value(); @@ -938,20 +1027,24 @@ void LLViewerJoystick::moveAvatar(bool reset) } // note: max feather is 32.0 - F32 feather = gSavedSettings.getF32("AvatarFeathering"); + F32 feather = mAvatarFeathering; F32 cur_delta[6]; F32 val, dom_mov = 0.f; U32 dom_axis = Z_I; #if LIB_NDOF - bool absolute = (gSavedSettings.getBOOL("Cursor3D") && mNdofDev->absolute); + bool absolute = (m3DCursor && mNdofDev->absolute); #else bool absolute = false; #endif // remove dead zones and determine biggest movement on the joystick for (U32 i = 0; i < 6; i++) { - cur_delta[i] = -mAxes[axis[i]]; + cur_delta[i] = -mAxes[mJoystickAxis[i]]; + + if (!mInvertPitch && i == 4) + cur_delta[i] = -cur_delta[i]; + if (absolute) { F32 tmp = cur_delta[i]; @@ -961,11 +1054,11 @@ void LLViewerJoystick::moveAvatar(bool reset) if (cur_delta[i] > 0) { - cur_delta[i] = llmax(cur_delta[i]-dead_zone[i], 0.f); + cur_delta[i] = llmax(cur_delta[i]- mAvatarAxisDeadZone[i], 0.f); } else { - cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f); + cur_delta[i] = llmin(cur_delta[i]+ mAvatarAxisDeadZone[i], 0.f); } // we don't care about Roll (RZ) and Z is calculated after the loop @@ -1005,11 +1098,11 @@ void LLViewerJoystick::moveAvatar(bool reset) dom_axis = Z_I; } - sDelta[X_I] = -cur_delta[X_I] * axis_scale[X_I]; - sDelta[Y_I] = -cur_delta[Y_I] * axis_scale[Y_I]; - sDelta[Z_I] = -cur_delta[Z_I] * axis_scale[Z_I]; - cur_delta[RX_I] *= -axis_scale[RX_I] * mPerfScale; - cur_delta[RY_I] *= -axis_scale[RY_I] * mPerfScale; + sDelta[X_I] = -cur_delta[X_I] * mAvatarAxisScale[X_I]; + sDelta[Y_I] = -cur_delta[Y_I] * mAvatarAxisScale[Y_I]; + sDelta[Z_I] = -cur_delta[Z_I] * mAvatarAxisScale[Z_I]; + cur_delta[RX_I] *= -mAvatarAxisScale[RX_I] * mPerfScale; + cur_delta[RY_I] *= -mAvatarAxisScale[RY_I] * mPerfScale; if (!absolute) { @@ -1038,8 +1131,8 @@ void LLViewerJoystick::moveAvatar(bool reset) // too many rotations during walking can be confusing, so apply // the deadzones one more time (quick & dirty), at 50%|30% power - F32 eff_rx = .3f * dead_zone[RX_I]; - F32 eff_ry = .3f * dead_zone[RY_I]; + F32 eff_rx = .3f * mAvatarAxisDeadZone[RX_I]; + F32 eff_ry = .3f * mAvatarAxisDeadZone[RY_I]; if (sDelta[RX_I] > 0) { @@ -1092,22 +1185,11 @@ void LLViewerJoystick::moveFlycam(bool reset) static F32 sFlycamZoom; if (!gFocusMgr.getAppHasFocus() || mDriverState != JDS_INITIALIZED - || !gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickFlycamEnabled")) + || !mJoystickEnabled || !mFlycamEnabled) { return; } - S32 axis[] = - { - gSavedSettings.getS32("JoystickAxis0"), - gSavedSettings.getS32("JoystickAxis1"), - gSavedSettings.getS32("JoystickAxis2"), - gSavedSettings.getS32("JoystickAxis3"), - gSavedSettings.getS32("JoystickAxis4"), - gSavedSettings.getS32("JoystickAxis5"), - gSavedSettings.getS32("JoystickAxis6") - }; - bool in_build_mode = LLToolMgr::getInstance()->inBuildMode(); if (reset || mResetFlag) { @@ -1115,33 +1197,11 @@ void LLViewerJoystick::moveFlycam(bool reset) sFlycamRotation = LLViewerCamera::getInstance()->getQuaternion(); sFlycamZoom = LLViewerCamera::getInstance()->getView(); - resetDeltas(axis); + resetDeltas(mJoystickAxis); return; } - F32 axis_scale[] = - { - gSavedSettings.getF32("FlycamAxisScale0"), - gSavedSettings.getF32("FlycamAxisScale1"), - gSavedSettings.getF32("FlycamAxisScale2"), - gSavedSettings.getF32("FlycamAxisScale3"), - gSavedSettings.getF32("FlycamAxisScale4"), - gSavedSettings.getF32("FlycamAxisScale5"), - gSavedSettings.getF32("FlycamAxisScale6") - }; - - F32 dead_zone[] = - { - gSavedSettings.getF32("FlycamAxisDeadZone0"), - gSavedSettings.getF32("FlycamAxisDeadZone1"), - gSavedSettings.getF32("FlycamAxisDeadZone2"), - gSavedSettings.getF32("FlycamAxisDeadZone3"), - gSavedSettings.getF32("FlycamAxisDeadZone4"), - gSavedSettings.getF32("FlycamAxisDeadZone5"), - gSavedSettings.getF32("FlycamAxisDeadZone6") - }; - F32 time = gFrameIntervalSeconds.value(); // avoid making ridiculously big movements if there's a big drop in fps @@ -1151,14 +1211,16 @@ void LLViewerJoystick::moveFlycam(bool reset) } F32 cur_delta[7]; - F32 feather = gSavedSettings.getF32("FlycamFeathering"); - bool absolute = gSavedSettings.getBOOL("Cursor3D"); + F32 feather = mFlycamFeathering; + bool absolute = m3DCursor; bool is_zero = true; for (U32 i = 0; i < 7; i++) { - cur_delta[i] = -getJoystickAxis(axis[i]); + cur_delta[i] = -getJoystickAxis(mJoystickAxis[i]); + if (!mInvertPitch && i == 4) + cur_delta[i] = -cur_delta[i]; F32 tmp = cur_delta[i]; if (absolute) @@ -1169,11 +1231,11 @@ void LLViewerJoystick::moveFlycam(bool reset) if (cur_delta[i] > 0) { - cur_delta[i] = llmax(cur_delta[i]-dead_zone[i], 0.f); + cur_delta[i] = llmax(cur_delta[i]- mFlycamAxisDeadZone[i], 0.f); } else { - cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f); + cur_delta[i] = llmin(cur_delta[i]+ mFlycamAxisDeadZone[i], 0.f); } // We may want to scale camera movements up or down in build mode. @@ -1188,7 +1250,7 @@ void LLViewerJoystick::moveFlycam(bool reset) } } - cur_delta[i] *= axis_scale[i]; + cur_delta[i] *= mFlycamAxisScale[i]; if (!absolute) { @@ -1207,12 +1269,12 @@ void LLViewerJoystick::moveFlycam(bool reset) gAgent.clearAFK(); } - sFlycamPosition += LLVector3(sDelta) * sFlycamRotation; + sFlycamPosition += LLVector3(sDelta.data()) * sFlycamRotation; LLMatrix3 rot_mat(sDelta[3], sDelta[4], sDelta[5]); sFlycamRotation = LLQuaternion(rot_mat)*sFlycamRotation; - if (gSavedSettings.getBOOL("AutoLeveling")) + if (mAutoLeveling) { LLMatrix3 level(sFlycamRotation); @@ -1230,13 +1292,15 @@ void LLViewerJoystick::moveFlycam(bool reset) sFlycamRotation = nlerp(llmin(feather*time,1.f), sFlycamRotation, quat); } - if (gSavedSettings.getBOOL("ZoomDirect")) + if (mZoomDirect) { - sFlycamZoom = sLastDelta[6]*axis_scale[6]+dead_zone[6]; + sFlycamZoom = sLastDelta[6]* mFlycamAxisScale[6]+ mFlycamAxisDeadZone[6]; } else { - sFlycamZoom += sDelta[6]; + //BD - We need to cap zoom otherwise it internally counts higher causing + // the zoom level to not react until that extra has been removed first. + sFlycamZoom = llclamp(sFlycamZoom + sDelta[6], LLViewerCamera::getInstance()->getMinView(), LLViewerCamera::getInstance()->getMaxView()); } LLMatrix3 mat(sFlycamRotation); @@ -1251,7 +1315,7 @@ void LLViewerJoystick::moveFlycam(bool reset) // ----------------------------------------------------------------------------- bool LLViewerJoystick::toggleFlycam() { - if (!gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickFlycamEnabled")) + if (!mJoystickEnabled || !mFlycamEnabled) { mOverrideCamera = false; return false; @@ -1285,7 +1349,7 @@ bool LLViewerJoystick::toggleFlycam() void LLViewerJoystick::scanJoystick() { - if (mDriverState != JDS_INITIALIZED || !gSavedSettings.getBOOL("JoystickEnabled")) + if (mDriverState != JDS_INITIALIZED || !mJoystickEnabled) { return; } @@ -1318,7 +1382,7 @@ void LLViewerJoystick::scanJoystick() toggle_flycam = 0; } - if (!mOverrideCamera && !(LLToolMgr::getInstance()->inBuildMode() && gSavedSettings.getBOOL("JoystickBuildEnabled"))) + if (!mOverrideCamera && !(LLToolMgr::getInstance()->inBuildMode() && mBuildEnabled)) { moveAvatar(); } @@ -1410,6 +1474,7 @@ bool LLViewerJoystick::isLikeSpaceNavigator() const #if LIB_NDOF return (isJoystickInitialized() && (strncmp(mNdofDev->product, "SpaceNavigator", 14) == 0 + || strncmp(mNdofDev->product, "3Dconnexion SpaceNavigator", 26) == 0 || strncmp(mNdofDev->product, "SpaceExplorer", 13) == 0 || strncmp(mNdofDev->product, "SpaceTraveler", 13) == 0 || strncmp(mNdofDev->product, "SpacePilot", 10) == 0)); @@ -1446,6 +1511,7 @@ void LLViewerJoystick::setSNDefaults() gSavedSettings.setBOOL("Cursor3D", is_3d_cursor); gSavedSettings.setBOOL("AutoLeveling", true); gSavedSettings.setBOOL("ZoomDirect", false); + gSavedSettings.setBOOL("JoystickInvertPitch", true); gSavedSettings.setF32("AvatarAxisScale0", 1.f * platformScaleAvXZ); gSavedSettings.setF32("AvatarAxisScale1", 1.f * platformScaleAvXZ); @@ -1491,3 +1557,66 @@ void LLViewerJoystick::setSNDefaults() gSavedSettings.setF32("BuildFeathering", 12.f); gSavedSettings.setF32("FlycamFeathering", 5.f); } + +//BD - Xbox360 Controller Support +void LLViewerJoystick::setXboxDefaults() +{ + LL_INFOS() << "restoring Xbox Controller defaults..." << LL_ENDL; + + gSavedSettings.setS32("JoystickAxis0", 1); // Z + gSavedSettings.setS32("JoystickAxis1", 0); // X + gSavedSettings.setS32("JoystickAxis2", -1); // Y + gSavedSettings.setS32("JoystickAxis3", 2); // Roll + gSavedSettings.setS32("JoystickAxis4", 4); // Pitch + gSavedSettings.setS32("JoystickAxis5", 3); // Yaw + gSavedSettings.setS32("JoystickAxis6", -1); // Zoom + + gSavedSettings.setBOOL("Cursor3D", false); // Xbox Gamepad, not 3D Mouse + gSavedSettings.setBOOL("AutoLeveling", false); + gSavedSettings.setBOOL("ZoomDirect", false); + gSavedSettings.setBOOL("JoystickInvertPitch", false); + + gSavedSettings.setF32("AvatarAxisScale0", 1.f); + gSavedSettings.setF32("AvatarAxisScale2", 1.f); + gSavedSettings.setF32("AvatarAxisScale1", 1.f); + gSavedSettings.setF32("AvatarAxisScale4", 1.f); + gSavedSettings.setF32("AvatarAxisScale5", 1.f); + gSavedSettings.setF32("AvatarAxisScale3", 1.f); + gSavedSettings.setF32("BuildAxisScale0", 1.25f); + gSavedSettings.setF32("BuildAxisScale2", 1.25f); + gSavedSettings.setF32("BuildAxisScale1", 1.25f); + gSavedSettings.setF32("BuildAxisScale4", 1.f); + gSavedSettings.setF32("BuildAxisScale5", 1.f); + gSavedSettings.setF32("BuildAxisScale3", 1.f); + gSavedSettings.setF32("FlycamAxisScale0", 5.0f); + gSavedSettings.setF32("FlycamAxisScale2", 5.0f); + gSavedSettings.setF32("FlycamAxisScale1", 5.0f); + gSavedSettings.setF32("FlycamAxisScale4", 2.0f); + gSavedSettings.setF32("FlycamAxisScale5", 2.5f); + gSavedSettings.setF32("FlycamAxisScale3", 2.0f); + gSavedSettings.setF32("FlycamAxisScale6", 1.0f); + + gSavedSettings.setF32("AvatarAxisDeadZone0", .6f); + gSavedSettings.setF32("AvatarAxisDeadZone2", .3f); + gSavedSettings.setF32("AvatarAxisDeadZone1", .6f); + gSavedSettings.setF32("AvatarAxisDeadZone3", .3f); + gSavedSettings.setF32("AvatarAxisDeadZone4", .3f); + gSavedSettings.setF32("AvatarAxisDeadZone5", .3f); + gSavedSettings.setF32("BuildAxisDeadZone0", .25f); + gSavedSettings.setF32("BuildAxisDeadZone2", .25f); + gSavedSettings.setF32("BuildAxisDeadZone1", .25f); + gSavedSettings.setF32("BuildAxisDeadZone3", .3f); + gSavedSettings.setF32("BuildAxisDeadZone4", .3f); + gSavedSettings.setF32("BuildAxisDeadZone5", .1f); + gSavedSettings.setF32("FlycamAxisDeadZone0", .25f); + gSavedSettings.setF32("FlycamAxisDeadZone2", .25f); + gSavedSettings.setF32("FlycamAxisDeadZone1", .25f); + gSavedSettings.setF32("FlycamAxisDeadZone3", .1f); + gSavedSettings.setF32("FlycamAxisDeadZone4", .3f); + gSavedSettings.setF32("FlycamAxisDeadZone5", .3f); + gSavedSettings.setF32("FlycamAxisDeadZone6", .1f); + + gSavedSettings.setF32("AvatarFeathering", 20.0f); + gSavedSettings.setF32("BuildFeathering", 3.f); + gSavedSettings.setF32("FlycamFeathering", 1.0f); +} \ No newline at end of file diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index bac96914b11..d2bf601718c 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -72,6 +72,7 @@ class LLViewerJoystick final : public LLSingleton<LLViewerJoystick> void setOverrideCamera(bool val); bool toggleFlycam(); void setSNDefaults(); + void setXboxDefaults(); bool isDeviceUUIDSet(); LLSD getDeviceUUID(); //unconverted, OS dependent value wrapped into LLSD, for comparison/search std::string getDeviceUUIDString(); // converted readable value for settings @@ -88,6 +89,7 @@ class LLViewerJoystick final : public LLSingleton<LLViewerJoystick> void agentJump(); void resetDeltas(S32 axis[]); void loadDeviceIdFromSettings(); + void refreshFromSettings(); #if LIB_NDOF static NDOF_HotPlugResult HotPlugAddCallback(NDOF_Device *dev); static void HotPlugRemovalCallback(NDOF_Device *dev); @@ -105,8 +107,35 @@ class LLViewerJoystick final : public LLSingleton<LLViewerJoystick> U32 mJoystickRun; LLSD mLastDeviceUUID; // _GUID as U8 binary map, integer 1 for no device/ndof's device - static F32 sLastDelta[7]; - static F32 sDelta[7]; + // SETTINGS + + // [1 0 2 4 3 5] + // [Z X Y RZ RX RY] + // Device prefs + bool mJoystickEnabled; + LLSD mJoystickId; + S32 mJoystickAxis[7]; + bool m3DCursor; + bool mAutoLeveling; + bool mZoomDirect; + bool mInvertPitch; + + // Modes prefs + bool mAvatarEnabled; + bool mBuildEnabled; + bool mFlycamEnabled; + F32 mAvatarAxisScale[6]; + F32 mBuildAxisScale[6]; + F32 mFlycamAxisScale[7]; + F32 mAvatarAxisDeadZone[6]; + F32 mBuildAxisDeadZone[6]; + F32 mFlycamAxisDeadZone[7]; + F32 mAvatarFeathering; + F32 mBuildFeathering; + F32 mFlycamFeathering; + + static std::array<F32, 7> sLastDelta; + static std::array<F32, 7> sDelta; }; #endif diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml index 7d2cea1fe50..2cd1435f7e5 100644 --- a/indra/newview/skins/default/xui/en/floater_joystick.xml +++ b/indra/newview/skins/default/xui/en/floater_joystick.xml @@ -899,7 +899,16 @@ layout="topleft" left="359" name="SpaceNavigatorDefaults" - top="437" + top="417" + width="200" /> + <button + follows="left|top" + height="22" + label="Xbox Defaults" + layout="topleft" + left="359" + name="XboxDefaults" + top="445" width="200" /> <button follows="right|bottom" @@ -909,7 +918,7 @@ layout="topleft" left_delta="0" name="ok_btn" - top_pad="9" + top_pad="7" width="98" /> <button follows="right|bottom" -- GitLab