From 744574a36be2914c6d4641a9fa6e76359a4e218e Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 8 Aug 2016 16:12:18 +0200 Subject: proto/vjoystick: add new vjoystick protocol to replace vjoy --- 3rdparty-notices/VJOYSTICK-COPYING.txt | 10 +++ proto-vjoystick/CMakeLists.txt | 16 ++++ proto-vjoystick/images/vjoystick.png | Bin 0 -> 6327 bytes proto-vjoystick/vjoystick.cpp | 147 +++++++++++++++++++++++++++++++++ proto-vjoystick/vjoystick.h | 79 ++++++++++++++++++ proto-vjoystick/vjoystick.qrc | 5 ++ proto-vjoystick/vjoystick.ui | 56 +++++++++++++ proto-vjoystick/vjoystick_dialog.cpp | 8 ++ 8 files changed, 321 insertions(+) create mode 100644 3rdparty-notices/VJOYSTICK-COPYING.txt create mode 100644 proto-vjoystick/CMakeLists.txt create mode 100644 proto-vjoystick/images/vjoystick.png create mode 100644 proto-vjoystick/vjoystick.cpp create mode 100644 proto-vjoystick/vjoystick.h create mode 100644 proto-vjoystick/vjoystick.qrc create mode 100644 proto-vjoystick/vjoystick.ui create mode 100644 proto-vjoystick/vjoystick_dialog.cpp diff --git a/3rdparty-notices/VJOYSTICK-COPYING.txt b/3rdparty-notices/VJOYSTICK-COPYING.txt new file mode 100644 index 00000000..1bf14d0c --- /dev/null +++ b/3rdparty-notices/VJOYSTICK-COPYING.txt @@ -0,0 +1,10 @@ +The vjoystick software is used under fair use terms. + +Software copyright follows: + +Copyright (c) Shaul Eizikovich. All rights reserved. + + THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/proto-vjoystick/CMakeLists.txt b/proto-vjoystick/CMakeLists.txt new file mode 100644 index 00000000..d0cfe591 --- /dev/null +++ b/proto-vjoystick/CMakeLists.txt @@ -0,0 +1,16 @@ +if(WIN32) + set(SDK_VJOYSTICK "" CACHE PATH "vjoystick SDK path") + if(SDK_VJOYSTICK) + if(opentrack-64bit) + set(arch "amd64/") + else() + set(arch "") + endif() + set(lib "${SDK_VJOYSTICK}/lib/${arch}vJoyInterface.lib") + set(dll "${SDK_VJOYSTICK}/lib/${arch}vJoyInterface.dll") + opentrack_boilerplate(opentrack-proto-vjoy) + target_link_libraries(opentrack-proto-vjoy ${lib}) + target_include_directories(opentrack-proto-vjoy SYSTEM PUBLIC "${SDK_VJOYSTICK}/inc") + install(FILES "${dll}" DESTINATION ${opentrack-hier-pfx}) + endif() +endif() diff --git a/proto-vjoystick/images/vjoystick.png b/proto-vjoystick/images/vjoystick.png new file mode 100644 index 00000000..c3def49f Binary files /dev/null and b/proto-vjoystick/images/vjoystick.png differ diff --git a/proto-vjoystick/vjoystick.cpp b/proto-vjoystick/vjoystick.cpp new file mode 100644 index 00000000..46d45bfb --- /dev/null +++ b/proto-vjoystick/vjoystick.cpp @@ -0,0 +1,147 @@ +#include "vjoystick.h" +#include "opentrack/plugin-api.hpp" + +#include +#include + +#include +#include +#include +#include + +// required for api headers +#include + +#undef PPJOY_MODE +#include +#include + +#define OPENTRACK_VJOYSTICK_ID 1 + +template +static t clamp(t val, u min, v max) +{ + if (val < min) + return t(min); + if (val > max) + return t(max); + return val; +} + +const unsigned char handle::axis_ids[6] = +{ + HID_USAGE_X, + HID_USAGE_Y, + HID_USAGE_Z, + HID_USAGE_RX, + HID_USAGE_RY, + HID_USAGE_RZ, +// HID_USAGE_SL0, +// HID_USAGE_SL1, +// HID_USAGE_WHL, +}; + +constexpr double handle::val_minmax[6]; + +void handle::init() +{ + bool ret = true; + + for (unsigned i = 0; i < axis_count; i++) + { + ret &= GetVJDAxisExist(OPENTRACK_VJOYSTICK_ID, axis_ids[i]); + if (!ret) { qDebug() << "axis" << i << "doesn't exist"; break; } + ret &= GetVJDAxisMin(OPENTRACK_VJOYSTICK_ID, axis_ids[i], &axis_min[i]); + if (!ret) { qDebug() << "axis" << i << "can't get min value"; break; }; + ret &= GetVJDAxisMax(OPENTRACK_VJOYSTICK_ID, axis_ids[i], &axis_max[i]); + if (!ret) { qDebug() << "axis" << i << "can't get max value"; break; }; + } + + if (!ret) + { + (void) RelinquishVJD(OPENTRACK_VJOYSTICK_ID); + joy_state = state_fail; + } + else + (void) ResetVJD(OPENTRACK_VJOYSTICK_ID); +} + +handle::handle() +{ + const bool ret = AcquireVJD(OPENTRACK_VJOYSTICK_ID); + if (!ret) + { + if (!isVJDExists(OPENTRACK_VJOYSTICK_ID)) + joy_state = state_notent; + else + joy_state = state_fail; + } + else + { + joy_state = state_success; + init(); + } +} + +handle::~handle() +{ + if (joy_state == state_success) + { + (void) RelinquishVJD(OPENTRACK_VJOYSTICK_ID); + joy_state = state_fail; + } +} + +LONG handle::to_axis_value(unsigned axis_id, double val) +{ + const double minmax = val_minmax[axis_id]; + const double min = axis_min[axis_id]; + const double max = axis_max[axis_id]; + + return LONG(clamp((val+minmax) * max / (2*minmax) - min, min, max)); +} + +vjoystick_proto::vjoystick_proto() +{ + if (h.get_state() != state_success) + { + QMessageBox msgbox; + msgbox.setIcon(QMessageBox::Critical); + msgbox.setText("vjoystick driver missing"); + msgbox.setInformativeText("vjoystick won't work without the driver installed."); + + QPushButton* driver_button = msgbox.addButton("Download the driver", QMessageBox::ActionRole); + QPushButton* project_site_button = msgbox.addButton("Visit project site", QMessageBox::ActionRole); + msgbox.addButton(QMessageBox::Close); + + (void) msgbox.exec(); + + if (msgbox.clickedButton() == driver_button) + { + static const char* download_driver_url = "https://sourceforge.net/projects/vjoystick/files/latest/download"; + QDesktopServices::openUrl(QUrl(download_driver_url, QUrl::StrictMode)); + } + else if (msgbox.clickedButton() == project_site_button) + { + static const char* project_site_url = "http://vjoystick.sourceforge.net/site/"; + QDesktopServices::openUrl(QUrl(project_site_url, QUrl::StrictMode)); + } + } +} + +vjoystick_proto::~vjoystick_proto() +{ +} + +void vjoystick_proto::pose(const double *pose) +{ + if (h.get_state() != state_success) + return; + + for (unsigned i = 0; i < handle::axis_count; i++) + { + SetAxis(h.to_axis_value(i, pose[i]), OPENTRACK_VJOYSTICK_ID, handle::axis_ids[i]); + } +} + +OPENTRACK_DECLARE_PROTOCOL(vjoystick_proto, vjoystick_dialog, vjoystick_metadata) diff --git a/proto-vjoystick/vjoystick.h b/proto-vjoystick/vjoystick.h new file mode 100644 index 00000000..c4cb7e69 --- /dev/null +++ b/proto-vjoystick/vjoystick.h @@ -0,0 +1,79 @@ +/* Copyright (c) 2016, Stanislaw Halik + + * Permission to use, copy, modify, and/or distribute this + * software for any purpose with or without fee is hereby granted, + * provided that the above copyright notice and this permission + * notice appear in all copies. + */ +#pragma once +#include "ui_vjoystick.h" +#include "opentrack/plugin-api.hpp" + +#include + +enum state : signed char +{ + state_notent = -1, + state_fail = -2, + state_success = 1, +}; + +class handle final +{ +public: + static constexpr unsigned axis_count = 6; + static const unsigned char axis_ids[axis_count]; + +private: + state joy_state; + LONG axis_min[6]; + LONG axis_max[6]; + + static constexpr double val_minmax[6] = + { + 50, + 50, + 50, + 180, + 180, + 180 + }; + + void init(); +public: + handle(); + ~handle(); + state get_state() { return joy_state; } + LONG to_axis_value(unsigned axis_id, double val); +}; + +class vjoystick_proto : public IProtocol +{ + handle h; +public: + vjoystick_proto(); + ~vjoystick_proto() override; + bool correct() override { return h.get_state() == state_success; } + void pose( const double *headpose ) override; + QString game_name() override { return "Virtual joystick"; } +private: +}; + +class vjoystick_dialog final : public IProtocolDialog +{ + Q_OBJECT +public: + + vjoystick_dialog(); + void register_protocol(IProtocol *) override {} + void unregister_protocol() override {} +private: + Ui::vjoystick ui; +}; + +class vjoystick_metadata : public Metadata +{ +public: + QString name() { return QString("Joystick emulation -- vjoystick"); } + QIcon icon() { return QIcon(":/images/vjoystick.png"); } +}; diff --git a/proto-vjoystick/vjoystick.qrc b/proto-vjoystick/vjoystick.qrc new file mode 100644 index 00000000..9c73169f --- /dev/null +++ b/proto-vjoystick/vjoystick.qrc @@ -0,0 +1,5 @@ + + + images/vjoystick.png + + diff --git a/proto-vjoystick/vjoystick.ui b/proto-vjoystick/vjoystick.ui new file mode 100644 index 00000000..6e6a2b33 --- /dev/null +++ b/proto-vjoystick/vjoystick.ui @@ -0,0 +1,56 @@ + + + vjoystick + + + Qt::NonModal + + + + 0 + 0 + 283 + 66 + + + + VJoy + + + + :/images/vjoystick.png:/images/vjoystick.png + + + Qt::LeftToRight + + + false + + + + + + <html><head/><body><p>Go to the <a href="http://vjoystick.sourceforge.net/site/"><span style=" text-decoration: underline; color:#0000ff;">vjoystick</span></a> project site or <a href="https://sourceforge.net/projects/vjoystick/files/latest/download"><span style=" text-decoration: underline; color:#0000ff;">download directly</span></a></p></body></html> + + + Qt::AlignCenter + + + true + + + + + + + QDialogButtonBox::Ok + + + + + + + + + + diff --git a/proto-vjoystick/vjoystick_dialog.cpp b/proto-vjoystick/vjoystick_dialog.cpp new file mode 100644 index 00000000..136e898b --- /dev/null +++ b/proto-vjoystick/vjoystick_dialog.cpp @@ -0,0 +1,8 @@ +#include "vjoystick.h" +#include "opentrack/plugin-api.hpp" + +vjoystick_dialog::vjoystick_dialog() +{ + ui.setupUi(this); + connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &QWidget::close); +} -- cgit v1.2.3