diff options
Diffstat (limited to 'indra/newview/llfloaterjoystick.cpp')
-rw-r--r-- | indra/newview/llfloaterjoystick.cpp | 148 |
1 files changed, 136 insertions, 12 deletions
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index 2b672bc890..93a26f31cc 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -40,7 +40,17 @@ #include "llviewercontrol.h" #include "llappviewer.h" #include "llviewerjoystick.h" +#include "llviewerwindow.h" +#include "llwindow.h" #include "llcheckboxctrl.h" +#include "llcombobox.h" + +#if LL_WINDOWS && !LL_MESA_HEADLESS +// Require DirectInput version 8 +#define DIRECTINPUT_VERSION 0x0800 + +#include <dinput.h> +#endif static LLTrace::SampleStatHandle<> sJoystickAxis0("Joystick axis 0"), sJoystickAxis1("Joystick axis 1"), @@ -58,8 +68,33 @@ static LLTrace::SampleStatHandle<>* sJoystickAxes[6] = &sJoystickAxis5 }; + +#if LL_WINDOWS && !LL_MESA_HEADLESS + +BOOL CALLBACK di8_list_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef) +{ + // Note: If a single device can function as more than one DirectInput + // device type, it is enumerated as each device type that it supports. + // Capable of detecting devices like Oculus Rift + if (device_instance_ptr && pvRef) + { + std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName)); + S32 size = sizeof(GUID); + LLSD::Binary data; //just an std::vector + data.resize(size); + memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size); + + LLFloaterJoystick * floater = (LLFloaterJoystick*)pvRef; + LLSD value = data; + floater->addDevice(product_name, value); + } + return DIENUM_CONTINUE; +} +#endif + LLFloaterJoystick::LLFloaterJoystick(const LLSD& data) - : LLFloater(data) + : LLFloater(data), + mHasDeviceList(false) { if (!LLViewerJoystick::getInstance()->isJoystickInitialized()) { @@ -71,14 +106,13 @@ LLFloaterJoystick::LLFloaterJoystick(const LLSD& data) void LLFloaterJoystick::draw() { - bool joystick_inited = LLViewerJoystick::getInstance()->isJoystickInitialized(); - getChildView("enable_joystick")->setEnabled(joystick_inited); - getChildView("joystick_type")->setEnabled(joystick_inited); - std::string desc = LLViewerJoystick::getInstance()->getDescription(); - if (desc.empty()) desc = getString("NoDevice"); - getChild<LLUICtrl>("joystick_type")->setValue(desc); - - LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); + LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); + bool joystick_inited = joystick->isJoystickInitialized(); + if (joystick_inited != mHasDeviceList) + { + refreshListOfDevices(); + } + for (U32 i = 0; i < 6; i++) { F32 value = joystick->getJoystickAxis(i); @@ -115,8 +149,8 @@ BOOL LLFloaterJoystick::postBuild() } } - mCheckJoystickEnabled = getChild<LLCheckBoxCtrl>("enable_joystick"); - childSetCommitCallback("enable_joystick",onCommitJoystickEnabled,this); + mJoysticksCombo = getChild<LLComboBox>("joystick_combo"); + childSetCommitCallback("joystick_combo",onCommitJoystickEnabled,this); mCheckFlycamEnabled = getChild<LLCheckBoxCtrl>("JoystickFlycamEnabled"); childSetCommitCallback("JoystickFlycamEnabled",onCommitJoystickEnabled,this); @@ -125,6 +159,7 @@ BOOL LLFloaterJoystick::postBuild() childSetAction("ok_btn", onClickOK, this); refresh(); + refreshListOfDevices(); return TRUE; } @@ -141,6 +176,7 @@ void LLFloaterJoystick::apply() void LLFloaterJoystick::initFromSettings() { mJoystickEnabled = gSavedSettings.getBOOL("JoystickEnabled"); + mJoystickId = gSavedSettings.getLLSD("JoystickDeviceUUID"); mJoystickAxis[0] = gSavedSettings.getS32("JoystickAxis0"); mJoystickAxis[1] = gSavedSettings.getS32("JoystickAxis1"); @@ -210,12 +246,80 @@ void LLFloaterJoystick::initFromSettings() void LLFloaterJoystick::refresh() { LLFloater::refresh(); + initFromSettings(); } +void LLFloaterJoystick::addDevice(std::string &name, LLSD& value) +{ + mJoysticksCombo->add(name, value, ADD_BOTTOM, 1); +} + +void LLFloaterJoystick::refreshListOfDevices() +{ + mJoysticksCombo->removeall(); + std::string no_device = getString("JoystickDisabled"); + LLSD value = LLSD::Integer(0); + addDevice(no_device, value); + + mHasDeviceList = false; + + // di8_devices_callback callback is immediate and happens in scope of getInputDevices() +#if LL_WINDOWS && !LL_MESA_HEADLESS + // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib + U32 device_type = DI8DEVCLASS_GAMECTRL; + void* callback = &di8_list_devices_callback; +#else + // MAC doesn't support device search yet + // On MAC there is an ndof_idsearch and it is possible to specify product + // and manufacturer in NDOF_Device for ndof_init_first to pick specific one + U32 device_type = 0; + void* callback = NULL; +#endif + if (gViewerWindow->getWindow()->getInputDevices(device_type, callback, this)) + { + mHasDeviceList = true; + } + + bool is_device_id_set = LLViewerJoystick::getInstance()->isDeviceUUIDSet(); + + if (LLViewerJoystick::getInstance()->isJoystickInitialized() && + (!mHasDeviceList || !is_device_id_set)) + { +#if LL_WINDOWS && !LL_MESA_HEADLESS + LL_WARNS() << "NDOF connected to device without using SL provided handle" << LL_ENDL; +#endif + std::string desc = LLViewerJoystick::getInstance()->getDescription(); + if (!desc.empty()) + { + LLSD value = LLSD::Integer(0); + addDevice(desc, value); + mHasDeviceList = true; + } + } + + if (gSavedSettings.getBOOL("JoystickEnabled") && mHasDeviceList) + { + if (is_device_id_set) + { + LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID(); + mJoysticksCombo->selectByValue(guid); + } + else + { + mJoysticksCombo->selectByValue(LLSD::Integer(1)); + } + } + else + { + mJoysticksCombo->selectByValue(LLSD::Integer(0)); + } +} + void LLFloaterJoystick::cancel() { gSavedSettings.setBOOL("JoystickEnabled", mJoystickEnabled); + gSavedSettings.setLLSD("JoystickDeviceUUID", mJoystickId); gSavedSettings.setS32("JoystickAxis0", mJoystickAxis[0]); gSavedSettings.setS32("JoystickAxis1", mJoystickAxis[1]); @@ -285,7 +389,21 @@ void LLFloaterJoystick::cancel() void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel) { LLFloaterJoystick* self = (LLFloaterJoystick*)joy_panel; - BOOL joystick_enabled = self->mCheckJoystickEnabled->get(); + + LLSD value = self->mJoysticksCombo->getValue(); + bool joystick_enabled = true; + if (value.isInteger()) + { + // ndof already has a device selected, we are just setting it enabled or disabled + joystick_enabled = value.asInteger(); + } + else + { + LLViewerJoystick::getInstance()->initDevice(value); + // else joystick is enabled, because combobox holds id of device + joystick_enabled = true; + } + gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled); BOOL flycam_enabled = self->mCheckFlycamEnabled->get(); if (!joystick_enabled || !flycam_enabled) @@ -297,6 +415,12 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel) joystick->toggleFlycam(); } } + + std::string device_id = LLViewerJoystick::getInstance()->getDeviceUUIDString(); + gSavedSettings.setString("JoystickDeviceUUID", device_id); + LL_DEBUGS("Joystick") << "Selected " << device_id << " as joystick." << LL_ENDL; + + self->refreshListOfDevices(); } void LLFloaterJoystick::onClickRestoreSNDefaults(void *joy_panel) |