diff options
Diffstat (limited to 'tracker-wii')
-rw-r--r-- | tracker-wii/CMakeLists.txt | 13 | ||||
-rw-r--r-- | tracker-wii/lang/nl_NL.ts | 7 | ||||
-rw-r--r-- | tracker-wii/lang/ru_RU.ts | 7 | ||||
-rw-r--r-- | tracker-wii/lang/stub.ts | 7 | ||||
-rw-r--r-- | tracker-wii/lang/zh_CN.ts | 9 | ||||
-rw-r--r-- | tracker-wii/wii_camera.cpp | 122 | ||||
-rw-r--r-- | tracker-wii/wii_camera.h | 48 | ||||
-rw-r--r-- | tracker-wii/wii_frame.cpp | 19 | ||||
-rw-r--r-- | tracker-wii/wii_frame.hpp | 9 | ||||
-rw-r--r-- | tracker-wii/wii_module.cpp | 7 | ||||
-rw-r--r-- | tracker-wii/wii_module.hpp | 11 | ||||
-rw-r--r-- | tracker-wii/wii_point_extractor.cpp | 90 | ||||
-rw-r--r-- | tracker-wii/wii_point_extractor.h | 17 | ||||
-rw-r--r-- | tracker-wii/wiiyourself/CMakeLists.txt | 3 | ||||
-rw-r--r-- | tracker-wii/wiiyourself/lang/zh_CN.ts | 2 | ||||
-rw-r--r-- | tracker-wii/wiiyourself/wiimote.cpp | 191 | ||||
-rw-r--r-- | tracker-wii/wiiyourself/wiimote.h | 7 |
17 files changed, 283 insertions, 286 deletions
diff --git a/tracker-wii/CMakeLists.txt b/tracker-wii/CMakeLists.txt index 76a43a77..fb840385 100644 --- a/tracker-wii/CMakeLists.txt +++ b/tracker-wii/CMakeLists.txt @@ -1,9 +1,16 @@ if(WIN32) - find_package(OpenCV 3.0 QUIET) + include(opentrack-opencv) + find_package(OpenCV QUIET) if(OpenCV_FOUND) + foreach(k core imgproc) + otr_install_lib("opencv_${k}" "${opentrack-libexec}") + endforeach() add_subdirectory(wiiyourself) otr_module(tracker-wii) - target_link_libraries(opentrack-tracker-wii opentrack-tracker-pt-base opentrack-wiiyourself bthprops) - target_include_directories(opentrack-tracker-wii PRIVATE "${CMAKE_SOURCE_DIR}/tracker-pt") + target_link_libraries(${self} opencv_imgproc opentrack-tracker-pt-base opentrack-wiiyourself bthprops) + if(MINGW32) + target_link_libraries(${self} hid) + endif() + target_include_directories(${self} PRIVATE "${CMAKE_SOURCE_DIR}/tracker-pt") endif() endif() diff --git a/tracker-wii/lang/nl_NL.ts b/tracker-wii/lang/nl_NL.ts index 9e739505..4c21a820 100644 --- a/tracker-wii/lang/nl_NL.ts +++ b/tracker-wii/lang/nl_NL.ts @@ -1,4 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> <TS version="2.1" language="nl_NL"> +<context> + <name>wii_metadata_pt</name> + <message> + <source>WiiPointTracker 1.1</source> + <translation type="unfinished"></translation> + </message> +</context> </TS> diff --git a/tracker-wii/lang/ru_RU.ts b/tracker-wii/lang/ru_RU.ts index f62cf2e1..ff0e7092 100644 --- a/tracker-wii/lang/ru_RU.ts +++ b/tracker-wii/lang/ru_RU.ts @@ -1,4 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> <TS version="2.1" language="ru_RU"> +<context> + <name>wii_metadata_pt</name> + <message> + <source>WiiPointTracker 1.1</source> + <translation type="unfinished"></translation> + </message> +</context> </TS> diff --git a/tracker-wii/lang/stub.ts b/tracker-wii/lang/stub.ts index 6401616d..d67c57ad 100644 --- a/tracker-wii/lang/stub.ts +++ b/tracker-wii/lang/stub.ts @@ -1,4 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> <TS version="2.1"> +<context> + <name>wii_metadata_pt</name> + <message> + <source>WiiPointTracker 1.1</source> + <translation type="unfinished"></translation> + </message> +</context> </TS> diff --git a/tracker-wii/lang/zh_CN.ts b/tracker-wii/lang/zh_CN.ts index 6401616d..6959d95b 100644 --- a/tracker-wii/lang/zh_CN.ts +++ b/tracker-wii/lang/zh_CN.ts @@ -1,4 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1"> +<TS version="2.1" language="zh_CN"> +<context> + <name>wii_metadata_pt</name> + <message> + <source>WiiPointTracker 1.1</source> + <translation type="unfinished"></translation> + </message> +</context> </TS> diff --git a/tracker-wii/wii_camera.cpp b/tracker-wii/wii_camera.cpp index af9a2d1f..bec47651 100644 --- a/tracker-wii/wii_camera.cpp +++ b/tracker-wii/wii_camera.cpp @@ -15,14 +15,9 @@ #include "wii_camera.h" #include "wii_frame.hpp" -#include "compat/sleep.hpp" -#include "compat/camera-names.hpp" #include "compat/math-imports.hpp" #include <opencv2/imgproc.hpp> - -#include "cv/video-property-page.hpp" - #include <bluetoothapis.h> using namespace pt_module; @@ -33,93 +28,111 @@ WIICamera::WIICamera(const QString& module_name) : s { module_name } cam_info.res_x = 1024; cam_info.res_y = 768; cam_info.fov = 42.0f; - cam_info.idx = 0; + cam_info.name = "Wii"; } WIICamera::~WIICamera() { - //stop(); + stop(); } QString WIICamera::get_desired_name() const { - return desired_name; + return QStringLiteral("Wii"); } QString WIICamera::get_active_name() const { - return active_name; + return get_desired_name(); } void WIICamera::show_camera_settings() { - } WIICamera::result WIICamera::get_info() const { - if (cam_info.res_x == 0 || cam_info.res_y == 0) - return result(false, pt_camera_info()); - return result(true, cam_info); + if (cam_info.res_x == 0 || cam_info.res_y == 0) + return result(false, pt_camera_info()); + return result(true, cam_info); } WIICamera::result WIICamera::get_frame(pt_frame& frame_) { - cv::Mat& frame = frame_.as<WIIFrame>()->mat; + cv::Mat& frame = frame_.as<WIIFrame>()->mat; struct wii_info& wii = frame_.as<WIIFrame>()->wii; + const wii_camera_status new_frame = get_frame(frame); - const wii_camera_status new_frame = _get_frame(frame); //create a fake blank frame - frame = cv::Mat(cam_info.res_x, cam_info.res_y, CV_8UC3, cv::Scalar(0, 0, 0)); + frame.create(cam_info.res_x, cam_info.res_y, CV_8UC3); + frame.setTo({0}); wii.status = new_frame; - switch (new_frame) - { + switch (new_frame) + { case wii_cam_data_change: - _get_status(wii); - _get_points(wii); + get_status(wii); + get_points(wii); break; case wii_cam_data_no_change: return result(false, cam_info); + default: + break; } return result(true, cam_info); } -bool WIICamera::start(int idx, int fps, int res_x, int res_y) +bool WIICamera::start(const pt_settings&) { + if (m_pDev) + return true; m_pDev = std::make_unique<wiimote>(); m_pDev->ChangedCallback = on_state_change; m_pDev->CallbackTriggerFlags = (state_change_flags)(CONNECTED | EXTENSION_CHANGED | MOTIONPLUS_CHANGED); - return true; + return true; } void WIICamera::stop() { - onExit = true; - m_pDev->ChangedCallback = NULL; - m_pDev->Disconnect(); - Beep(1000, 200); - if (m_pDev) { - m_pDev=nullptr; - m_pDev = NULL; - } + if (!m_pDev) + return; - desired_name = QString(); - active_name = QString(); - cam_info = pt_camera_info(); - cam_desired = pt_camera_info(); + cam_info = {}; + cam_desired = {}; + pitch_ = 0; roll_ = 0; + + m_pDev->ChangedCallback = nullptr; + m_pDev->Disconnect(); + m_pDev = nullptr; } +#ifdef __MINGW32__ +extern "C" + DWORD WINAPI BluetoothAuthenticateDevice( + HWND hwndParent, + HANDLE hRadio, + BLUETOOTH_DEVICE_INFO *pbtbi, + PWSTR pszPasskey, + ULONG ulPasskeyLength + ); + +#ifndef BLUETOOTH_SERVICE_ENABLE +# define BLUETOOTH_SERVICE_DISABLE 0x00 +# define BLUETOOTH_SERVICE_ENABLE 0x01 +#endif + +#endif -wii_camera_status WIICamera::_pair() +wii_camera_status WIICamera::pair() { wii_camera_status ret = wii_cam_wait_for_sync; HBLUETOOTH_RADIO_FIND hbt; BLUETOOTH_FIND_RADIO_PARAMS bt_param; - HANDLE hbtlist[10]; + constexpr int max_devices = 64; + HANDLE hbtlist[max_devices]; int ibtidx = 0; bool wiifound = false; @@ -127,12 +140,10 @@ wii_camera_status WIICamera::_pair() hbt = BluetoothFindFirstRadio(&bt_param, hbtlist + ibtidx); if (!hbt) { ret = wii_cam_wait_for_dongle; return ret; } do - { ibtidx++; - } while (BluetoothFindNextRadio(&bt_param, hbtlist + ibtidx)); + while (ibtidx < max_devices && BluetoothFindNextRadio(&bt_param, hbtlist + ibtidx)); BluetoothFindRadioClose(hbt); - int i; bool error = false; for (i = 0; i < ibtidx; i++) @@ -143,11 +154,12 @@ wii_camera_status WIICamera::_pair() if (ERROR_SUCCESS != BluetoothGetRadioInfo(hbtlist[i], &btinfo)) {break;} HBLUETOOTH_DEVICE_FIND hbtdevfd; - BLUETOOTH_DEVICE_SEARCH_PARAMS btdevparam; + BLUETOOTH_DEVICE_SEARCH_PARAMS btdevparam {}; BLUETOOTH_DEVICE_INFO btdevinfo; btdevinfo.dwSize = sizeof(btdevinfo); btdevparam.dwSize = sizeof(btdevparam); + btdevparam.fReturnUnknown = TRUE; btdevparam.fReturnAuthenticated = TRUE; btdevparam.fReturnConnected = TRUE; btdevparam.fReturnRemembered = TRUE; @@ -162,7 +174,8 @@ wii_camera_status WIICamera::_pair() } do { - if (wcscmp(btdevinfo.szName, L"Nintendo RVL-CNT-01-TR") && wcscmp(btdevinfo.szName, L"Nintendo RVL-CNT-01")) + if (!!wcscmp(btdevinfo.szName, L"Nintendo RVL-CNT-01-TR") && + !!wcscmp(btdevinfo.szName, L"Nintendo RVL-CNT-01")) { continue; } @@ -183,11 +196,11 @@ wii_camera_status WIICamera::_pair() pwd[4] = btinfo.address.rgBytes[4]; pwd[5] = btinfo.address.rgBytes[5]; - if (ERROR_SUCCESS != BluetoothAuthenticateDevice(NULL, hbtlist[i], &btdevinfo, pwd, 6)) { error = true; continue; } + if (ERROR_SUCCESS != BluetoothAuthenticateDevice(nullptr, hbtlist[i], &btdevinfo, pwd, 6)) { error = true; continue; } DWORD servicecount = 32; GUID guids[32]; if (ERROR_SUCCESS != BluetoothEnumerateInstalledServices(hbtlist[i], &btdevinfo, &servicecount, guids)) { error = true; continue; } - if (ERROR_SUCCESS != BluetoothSetServiceState(hbtlist[i], &btdevinfo, &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE)) { error = true; continue; } + if (ERROR_SUCCESS != BluetoothSetServiceState(hbtlist[i], &btdevinfo, (GUID*)&HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE)) { error = true; continue; } break; } while (BluetoothFindNextDevice(hbtdevfd, &btdevinfo)); BluetoothFindDeviceClose(hbtdevfd); @@ -201,19 +214,22 @@ wii_camera_status WIICamera::_pair() return ret; } -wii_camera_status WIICamera::_get_frame(cv::Mat& frame) +wii_camera_status WIICamera::get_frame(cv::Mat&) { wii_camera_status ret = wii_cam_wait_for_connect; if (!m_pDev->IsConnected()) { qDebug() << "wii wait"; - ret = _pair(); - switch(ret){ + ret = pair(); + switch(ret) + { case wii_cam_wait_for_sync: m_pDev->Disconnect(); goto goodbye; case wii_cam_wait_for_connect: break; + default: + break; } if (!m_pDev->Connect(wiimote::FIRST_AVAILABLE)) { Beep(500, 30); Sleep(1000); @@ -238,7 +254,7 @@ goodbye: return ret; } -bool WIICamera::_get_points(struct wii_info& wii) +bool WIICamera::get_points(struct wii_info& wii) { bool dot_sizes = (m_pDev->IR.Mode == wiimote_state::ir::EXTENDED); bool ret = false; @@ -269,23 +285,21 @@ bool WIICamera::_get_points(struct wii_info& wii) return ret; } -void WIICamera::_get_status(struct wii_info& wii) +void WIICamera::get_status(struct wii_info& wii) { //draw battery status wii.BatteryPercent = m_pDev->BatteryPercent; wii.bBatteryDrained = m_pDev->bBatteryDrained; //draw horizon - static int p = 0; - static int r = 0; if (m_pDev->Nunchuk.Acceleration.Orientation.UpdateAge < 10) { - p = m_pDev->Acceleration.Orientation.Pitch; - r = m_pDev->Acceleration.Orientation.Roll; + pitch_ = (int)m_pDev->Acceleration.Orientation.Pitch; + roll_ = (int)m_pDev->Acceleration.Orientation.Roll; } - wii.Pitch = p; - wii.Roll = r; + wii.Pitch = pitch_; + wii.Roll = roll_; } void WIICamera::on_state_change(wiimote &remote, diff --git a/tracker-wii/wii_camera.h b/tracker-wii/wii_camera.h index 55def206..3a7993aa 100644 --- a/tracker-wii/wii_camera.h +++ b/tracker-wii/wii_camera.h @@ -17,7 +17,6 @@ #include <tuple> #include <opencv2/core.hpp> -#include <opencv2/videoio.hpp> #include <QString> @@ -28,46 +27,39 @@ namespace pt_module { struct WIICamera final : pt_camera { - WIICamera(const QString& module_name); - ~WIICamera() override; + WIICamera(const QString& module_name); + ~WIICamera() override; - bool start(int idx, int fps, int res_x, int res_y) override; - void stop() override; + bool start(const pt_settings&) override; + void stop() override; - result get_frame(pt_frame& Frame) override; - result get_info() const override; + result get_frame(pt_frame& Frame) override; + result get_info() const override; - pt_camera_info get_desired() const override { return cam_desired; } - QString get_desired_name() const override; - QString get_active_name() const override; + pt_camera_info get_desired() const override { return cam_desired; } + QString get_desired_name() const override; + QString get_active_name() const override; - void set_fov(double value) override {} - void show_camera_settings() override; + void set_fov(f x) override { (void) x; } + void show_camera_settings() override; private: std::unique_ptr<wiimote> m_pDev; static void on_state_change(wiimote &remote, state_change_flags changed, const wiimote_state &new_state); - bool onExit = false; - pt_frame internalframe; - - wii_camera_status _pair(); - wii_camera_status _get_frame(cv::Mat& Frame); - bool _get_points(struct wii_info&); - void _get_status(struct wii_info&); - double dt_mean = 0; + wii_camera_status pair(); + wii_camera_status get_frame(cv::Mat& Frame); + bool get_points(struct wii_info& wii); + void get_status(struct wii_info& wii); - Timer t; + pt_camera_info cam_info; + pt_camera_info cam_desired; + int pitch_ = 0, roll_ = 0; + pt_settings s; - pt_camera_info cam_info; - pt_camera_info cam_desired; - QString desired_name, active_name; - - pt_settings s; - - static constexpr inline double dt_eps = 1./384; + static constexpr inline double dt_eps = 1./384; }; } // ns pt_module diff --git a/tracker-wii/wii_frame.cpp b/tracker-wii/wii_frame.cpp index 9332a704..fcde5235 100644 --- a/tracker-wii/wii_frame.cpp +++ b/tracker-wii/wii_frame.cpp @@ -17,34 +17,29 @@ using namespace pt_module; -WIIPreview& WIIPreview::operator=(const pt_frame& frame_) +void WIIPreview::set_last_frame(const pt_frame& frame_) { const struct wii_info& wii = frame_.as_const<WIIFrame>()->wii; const cv::Mat& frame = frame_.as_const<const WIIFrame>()->mat; - ensure_size(frame_copy, frame_out.cols, frame_out.rows, CV_8UC3); status = wii.status; if (frame.channels() != 3) - { - once_only(qDebug() << "tracker/pt: camera frame depth: 3 !=" << frame.channels()); - return *this; - } + eval_once(qDebug() << "tracker/pt: camera frame depth: 3 !=" << frame.channels()); const bool need_resize = frame.cols != frame_out.cols || frame.rows != frame_out.rows; if (need_resize) cv::resize(frame, frame_copy, cv::Size(frame_out.cols, frame_out.rows), 0, 0, cv::INTER_NEAREST); else frame.copyTo(frame_copy); - - return *this; } WIIPreview::WIIPreview(int w, int h) { ensure_size(frame_out, w, h, CV_8UC4); + ensure_size(frame_copy, w, h, CV_8UC3); - frame_out.setTo(cv::Scalar(0, 0, 0, 0)); + frame_copy.setTo(cv::Scalar(0, 0, 0)); } QImage WIIPreview::get_bitmap() @@ -61,7 +56,7 @@ QImage WIIPreview::get_bitmap() if (stride < 64 || stride < frame_out.cols * 4) { - once_only(qDebug() << "bad stride" << stride + eval_once(qDebug() << "bad stride" << stride << "for bitmap size" << frame_copy.cols << frame_copy.rows); return QImage(); } @@ -74,7 +69,7 @@ QImage WIIPreview::get_bitmap() QImage::Format_ARGB32); } -void WIIPreview::draw_head_center(double x, double y) +void WIIPreview::draw_head_center(f x, f y) { double px_, py_; @@ -97,6 +92,6 @@ void WIIPreview::draw_head_center(double x, double y) void WIIPreview::ensure_size(cv::Mat& frame, int w, int h, int type) { - if (frame.cols != w || frame.rows != h) + if (frame.cols != w || frame.rows != h || frame.type() != type) frame = cv::Mat(h, w, type); } diff --git a/tracker-wii/wii_frame.hpp b/tracker-wii/wii_frame.hpp index 31967d10..bbb0c469 100644 --- a/tracker-wii/wii_frame.hpp +++ b/tracker-wii/wii_frame.hpp @@ -47,9 +47,9 @@ struct WIIPreview final : pt_preview { WIIPreview(int w, int h); - WIIPreview& operator=(const pt_frame& frame) override; + void set_last_frame(const pt_frame& frame) override; QImage get_bitmap() override; - void draw_head_center(double x, double y) override; + void draw_head_center(f x, f y) override; operator cv::Mat&() { return frame_copy; } operator cv::Mat const&() const { return frame_copy; } @@ -57,9 +57,8 @@ struct WIIPreview final : pt_preview private: static void ensure_size(cv::Mat& frame, int w, int h, int type); - bool fresh = true; - cv::Mat frame_copy, frame_color, frame_resize, frame_out; - wii_camera_status status; + cv::Mat frame_copy, frame_out; + wii_camera_status status = wii_cam_wait_for_connect; }; } // ns pt_module diff --git a/tracker-wii/wii_module.cpp b/tracker-wii/wii_module.cpp index 5ef75f57..0358004f 100644 --- a/tracker-wii/wii_module.cpp +++ b/tracker-wii/wii_module.cpp @@ -62,9 +62,9 @@ struct wii_dialog_pt : TrackerDialog_PT wii_dialog_pt(); }; -class wii_metadata_pt : public Metadata +struct wii_metadata_pt : Metadata { - QString name() { return _("WiiPointTracker 1.1"); } + QString name() { return tr("WiiPointTracker 1.1"); } QIcon icon() { return QIcon(":/Resources/wii.png"); } }; @@ -76,7 +76,8 @@ using namespace pt_module; wii_dialog_pt::wii_dialog_pt() : TrackerDialog_PT(module_name) { - ui.tabWidget->removeTab(0); + ui.camera_settings_groupbox->hide(); + ui.groupBox_2->hide(); } OPENTRACK_DECLARE_TRACKER(wii_tracker_pt, wii_dialog_pt, wii_metadata_pt) diff --git a/tracker-wii/wii_module.hpp b/tracker-wii/wii_module.hpp new file mode 100644 index 00000000..b167e150 --- /dev/null +++ b/tracker-wii/wii_module.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "api/plugin-api.hpp" + +class wii_metadata_pt : public Metadata +{ + Q_OBJECT + + QString name() override; + QIcon icon() override; +}; diff --git a/tracker-wii/wii_point_extractor.cpp b/tracker-wii/wii_point_extractor.cpp index 215d50b8..4f1f92b9 100644 --- a/tracker-wii/wii_point_extractor.cpp +++ b/tracker-wii/wii_point_extractor.cpp @@ -14,15 +14,6 @@ #include "cv/numeric.hpp" #include "compat/math.hpp" -#include <opencv2/videoio.hpp> - -#undef PREVIEW -//#define PREVIEW - -#if defined PREVIEW -# include <opencv2/highgui.hpp> -#endif - #include <cmath> #include <algorithm> #include <cinttypes> @@ -30,45 +21,41 @@ #include <QDebug> -using namespace types; +using namespace numeric_types; using namespace pt_module; WIIPointExtractor::WIIPointExtractor(const QString& module_name) : s(module_name) { - } //define a temp draw function -void WIIPointExtractor::_draw_point(cv::Mat& preview_frame, const vec2& p, const cv::Scalar& color, int thinkness) +void WIIPointExtractor::draw_point(cv::Mat& preview_frame, const vec2& p, const cv::Scalar& color, int thickness) { static constexpr int len = 9; - cv::Point p2(iround(p[0] * preview_frame.cols + preview_frame.cols / 2), - iround(-p[1] * preview_frame.cols + preview_frame.rows / 2)); + cv::Point p2(iround(p[0] * preview_frame.cols + preview_frame.cols / 2.f), + iround(-p[1] * preview_frame.cols + preview_frame.rows / 2.f)); cv::line(preview_frame, cv::Point(p2.x - len, p2.y), cv::Point(p2.x + len, p2.y), color, - thinkness); + thickness); cv::line(preview_frame, cv::Point(p2.x, p2.y - len), cv::Point(p2.x, p2.y + len), color, - thinkness); -}; + thickness); +} -bool WIIPointExtractor::_draw_points(cv::Mat& preview_frame, const struct wii_info &wii, std::vector<vec2>& points) +void WIIPointExtractor::draw_points(cv::Mat& preview_frame, const struct wii_info& wii) { - const float W = 1024.0f; - const float H = 768.0f; - points.reserve(4); - points.clear(); + constexpr int W = 1024; + constexpr int H = 768; - for (unsigned index = 0; index < 4; index++) + for (const wii_info_points& dot : wii.Points) { - const struct wii_info_points &dot = wii.Points[index]; if (dot.bvis) { //qDebug() << "wii:" << dot.RawX << "+" << dot.RawY; //anti-clockwise rotate the 2D point @@ -79,17 +66,12 @@ bool WIIPointExtractor::_draw_points(cv::Mat& preview_frame, const struct wii_in //vec2 dt((2.0f*RX - W) / W, -(2.0f*RY - H ) / W); vec2 dt; std::tie(dt[0], dt[1]) = to_screen_pos(RX, RY, W, H); - - points.push_back(dt); - _draw_point(preview_frame, dt, cv::Scalar(0, 255, 0), dot.isize); + draw_point(preview_frame, dt, cv::Scalar(0, 255, 0), std::clamp(dot.isize, 1, 32)); } } - const bool success = points.size() >= PointModel::N_POINTS; - - return success; } -void WIIPointExtractor::_draw_bg(cv::Mat& preview_frame, const struct wii_info &wii) +void WIIPointExtractor::draw_bg(cv::Mat& preview_frame, const struct wii_info& wii) { //draw battery status cv::line(preview_frame, @@ -99,8 +81,8 @@ void WIIPointExtractor::_draw_bg(cv::Mat& preview_frame, const struct wii_info & 2); //draw horizon - int pdelta = iround((preview_frame.rows / 4) * tan((wii.Pitch)* M_PI / 180.0f)); - int rdelta = iround((preview_frame.cols / 4) * tan((wii.Roll)* M_PI / 180.0f)); + int pdelta = iround(preview_frame.rows / 4.f * tan(wii.Pitch * pi / 180.f)); + int rdelta = iround(preview_frame.cols / 4.f * tan(wii.Roll* pi / 180.f)); cv::line(preview_frame, cv::Point(0, preview_frame.rows / 2 + rdelta - pdelta), @@ -109,16 +91,46 @@ void WIIPointExtractor::_draw_bg(cv::Mat& preview_frame, const struct wii_info & 1); } -void WIIPointExtractor::extract_points(const pt_frame& frame_, pt_preview& preview_frame_, std::vector<vec2>& points) +void WIIPointExtractor::extract_points(const pt_frame& frame_, + pt_preview& preview_frame_, + bool preview_visible, + std::vector<vec2>& points) { const struct wii_info& wii = frame_.as_const<WIIFrame>()->wii; cv::Mat& preview_frame = *preview_frame_.as<WIIPreview>(); - switch (wii.status) { - case wii_cam_data_change: - _draw_bg(preview_frame, wii); - _draw_points(preview_frame, wii, points); - break; + map_points(wii, points); + if (preview_visible && wii.status == wii_cam_data_change) + { + draw_bg(preview_frame, wii); + draw_points(preview_frame, wii); } } +bool WIIPointExtractor::map_points(const struct wii_info& wii, std::vector<vec2>& points) +{ + constexpr int W = 1024; + constexpr int H = 768; + points.reserve(4); + points.clear(); + + for (unsigned index = 0; index < 4; index++) // NOLINT(modernize-loop-convert) + { + const struct wii_info_points &dot = wii.Points[index]; + if (dot.bvis) { + //qDebug() << "wii:" << dot.RawX << "+" << dot.RawY; + //anti-clockwise rotate the 2D point + const float RX = W - dot.ux; + const float RY = H - dot.uy; + //vec2 dt((dot.RawX - W / 2.0f) / W, -(dot.RawY - H / 2.0f) / W); + //vec2 dt((RX - W / 2.0f) / W, -(RY - H / 2.0f) / W); + //vec2 dt((2.0f*RX - W) / W, -(2.0f*RY - H ) / W); + vec2 dt; + std::tie(dt[0], dt[1]) = to_screen_pos(RX, RY, W, H); + + points.push_back(dt); + } + } + + return points.size() >= PointModel::N_POINTS; +} diff --git a/tracker-wii/wii_point_extractor.h b/tracker-wii/wii_point_extractor.h index be0e5f45..b8b25b1a 100644 --- a/tracker-wii/wii_point_extractor.h +++ b/tracker-wii/wii_point_extractor.h @@ -16,22 +16,25 @@ namespace pt_module { -using namespace types; +using namespace numeric_types; class WIIPointExtractor final : public pt_point_extractor { public: // extracts points from frame and draws some processing info into frame, if draw_output is set // dt: time since last call in seconds - void extract_points(const pt_frame& frame, pt_preview& preview_frame, std::vector<vec2>& points) override; + void extract_points(const pt_frame& frame, + pt_preview& preview_frame, + bool preview_visible, + std::vector<vec2>& points) override; WIIPointExtractor(const QString& module_name); -private: - static constexpr int max_blobs = 16; +private: pt_settings s; - void _draw_point(cv::Mat& preview_frame, const vec2& p, const cv::Scalar& color, int thinkness = 1); - bool _draw_points(cv::Mat& preview_frame, const struct wii_info &wii, std::vector<vec2>& points); - void _draw_bg(cv::Mat& preview_frame, const struct wii_info &wii); + static void draw_point(cv::Mat& preview_frame, const vec2& p, const cv::Scalar& color, int thickness = 1); + static void draw_points(cv::Mat& preview_frame, const struct wii_info& wii); + static void draw_bg(cv::Mat& preview_frame, const struct wii_info& wii); + static bool map_points(const struct wii_info& wii, std::vector<vec2>& points); }; } // ns impl diff --git a/tracker-wii/wiiyourself/CMakeLists.txt b/tracker-wii/wiiyourself/CMakeLists.txt index 6a32fde4..d32c6eb6 100644 --- a/tracker-wii/wiiyourself/CMakeLists.txt +++ b/tracker-wii/wiiyourself/CMakeLists.txt @@ -1 +1,2 @@ -otr_module(wiiyourself STATIC) +otr_module(wiiyourself STATIC NO-QT NO-COMPAT) +target_link_libraries(${self} PUBLIC setupapi hid winmm) diff --git a/tracker-wii/wiiyourself/lang/zh_CN.ts b/tracker-wii/wiiyourself/lang/zh_CN.ts index 6401616d..e5ca8aa9 100644 --- a/tracker-wii/wiiyourself/lang/zh_CN.ts +++ b/tracker-wii/wiiyourself/lang/zh_CN.ts @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1"> +<TS version="2.1" language="zh_CN"> </TS> diff --git a/tracker-wii/wiiyourself/wiimote.cpp b/tracker-wii/wiiyourself/wiimote.cpp index e1e49101..01c80f37 100644 --- a/tracker-wii/wiiyourself/wiimote.cpp +++ b/tracker-wii/wiiyourself/wiimote.cpp @@ -8,106 +8,70 @@ // // wiimote.cpp (tab = 4 spaces) -// VC-specifics: -#ifdef _MSC_VER - // disable warning "C++ exception handler used, but unwind semantics are not enabled." - // in <xstring> (I don't use it - or just enable C++ exceptions) -# pragma warning(disable: 4530) -// auto-link with the necessary libs -# pragma comment(lib, "setupapi.lib") -# pragma comment(lib, "hid.lib") // for HID API (from DDK) -# pragma comment(lib, "winmm.lib") // for timeGetTime() -#endif // _MSC_VER - #include "wiimote.h" +#include <cmath> +#include <algorithm> // std::min +#include <iterator> // std::size +#include <tchar.h> #include <setupapi.h> extern "C" { -# ifdef __MINGW32__ -# include <ddk/hidsdi.h>// from WinDDK -# else -# include <hidsdi.h> -# endif +#include <hidsdi.h> } #include <sys/types.h> // for _stat #include <sys/stat.h> // " #include <process.h> // for _beginthreadex() -#ifdef __BORLANDC__ -# include <cmath.h> // for orientation -#else -# include <math.h> // " -#endif #include <mmreg.h> // for WAVEFORMATEXTENSIBLE #include <mmsystem.h> // for timeGetTime() -// apparently not defined in some compilers: -#ifndef min -# define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif // ------------------------------------------------------------------------------------ // helpers // ------------------------------------------------------------------------------------ template<class T> inline T sign (const T& val) { return (val<0)? T(-1) : T(1); } template<class T> inline T square(const T& val) { return val*val; } -#define ARRAY_ENTRIES(array) (sizeof(array)/sizeof(array[0])) // ------------------------------------------------------------------------------------ // Tracing & Debugging // ------------------------------------------------------------------------------------ -#define PREFIX _T("WiiYourself! : ") - -// comment these to auto-strip their code from the library: -// (they currently use OutputDebugString() via _TRACE() - change to suit) -#if (_MSC_VER >= 1400) // VC 2005+ (earlier versions don't support variable args) -# define TRACE(fmt, ...) _TRACE(PREFIX fmt _T("\n"), __VA_ARGS__) -# define WARN(fmt, ...) _TRACE(PREFIX _T("* ") fmt _T(" *") _T("\n"), __VA_ARGS__) -#elif defined(__MINGW32__) -# define TRACE(fmt, ...) _TRACE(PREFIX fmt _T("\n") , ##__VA_ARGS__) -# define WARN(fmt, ...) _TRACE(PREFIX _T("* ") fmt _T(" *") _T("\n") , ##__VA_ARGS__) -#endif -// uncomment any of these for deeper debugging: -//#define DEEP_TRACE(fmt, ...) _TRACE(PREFIX _T("|") fmt _T("\n"), __VA_ARGS__) // VC 2005+ -//#define DEEP_TRACE(fmt, ...) _TRACE(PREFIX _T("|") fmt _T("\n") , ##__VA_ARGS__) // mingw -//#define BEEP_DEBUG_READS -//#define BEEP_DEBUG_WRITES -//#define BEEP_ON_ORIENTATION_ESTIMATE -//#define BEEP_ON_PERIODIC_STATUSREFRESH -// internals: auto-strip code from the macros if they weren't defined +static_assert(sizeof(TCHAR) == sizeof(char)); + +template<typename... xs> +[[maybe_unused]] +static void trace_ (const char* fmt, const xs&... args) +{ + fprintf(stderr, fmt, args...); + fprintf(stderr, "\n"); + fflush(stderr); +} + +template<typename... xs> +[[maybe_unused]] +static inline void disabled_trace_(const char*, const xs&...) {} + +#define TRACE trace_ +#define WARN trace_ + #ifndef TRACE -# define TRACE +# define TRACE disabled_trace_ #endif #ifndef DEEP_TRACE -# define DEEP_TRACE +# define DEEP_TRACE disabled_trace_ #endif #ifndef WARN -# define WARN -#endif -// ------------------------------------------------------------------------------------ -static void _cdecl _TRACE (const TCHAR* fmt, ...) - { - static TCHAR buffer[256]; - if (!fmt) return; - - va_list argptr; - va_start (argptr, fmt); -#if (_MSC_VER >= 1400) // VC 2005+ - _vsntprintf_s(buffer, ARRAY_ENTRIES(buffer), _TRUNCATE, fmt, argptr); -#else - _vsntprintf (buffer, ARRAY_ENTRIES(buffer), fmt, argptr); +# define WARN disabled_trace_ #endif - va_end (argptr); - OutputDebugString(buffer); - } +// uncomment any of these for deeper debugging: +//#define BEEP_DEBUG_READS +//#define BEEP_DEBUG_WRITES +//#define BEEP_ON_ORIENTATION_ESTIMATE +//#define BEEP_ON_PERIODIC_STATUSREFRESH // ------------------------------------------------------------------------------------ // wiimote // ------------------------------------------------------------------------------------ // class statics -HMODULE wiimote::HidDLL = NULL; -unsigned wiimote::_TotalCreated = 0; unsigned wiimote::_TotalConnected = 0; -hidwrite_ptr wiimote::_HidD_SetOutputReport = NULL; // (keep in sync with 'speaker_freq'): const unsigned wiimote::FreqLookup [TOTAL_FREQUENCIES] = @@ -156,23 +120,6 @@ wiimote::wiimote () #endif { _ASSERT(DataRead != INVALID_HANDLE_VALUE); - - // if this is the first wiimote object, detect & enable HID write support - if(++_TotalCreated == 1) - { - HidDLL = LoadLibrary(_T("hid.dll")); - _ASSERT(HidDLL); - if(!HidDLL) - WARN(_T("Couldn't load hid.dll - shouldn't happen!")); - else{ - _HidD_SetOutputReport = (hidwrite_ptr) - GetProcAddress(HidDLL, "HidD_SetOutputReport"); - if(_HidD_SetOutputReport) - TRACE(_T("OS supports HID writes.")); - else - TRACE(_T("OS doesn't support HID writes.")); - } - } // clear our public and private state data completely (including deadzones) Clear (true); @@ -197,7 +144,7 @@ wiimote::wiimote () } // ------------------------------------------------------------------------------------ wiimote::~wiimote () - { +{ Disconnect(); // events & critical sections are kept open for the lifetime of the object, @@ -209,16 +156,8 @@ wiimote::~wiimote () DeleteCriticalSection(&StateLock); // tidy up timer accuracy request - timeEndPeriod(1); - - // release HID DLL (for dynamic HID write method) - if((--_TotalCreated == 0) && HidDLL) - { - FreeLibrary(HidDLL); - HidDLL = NULL; - _HidD_SetOutputReport = NULL; - } - } + timeEndPeriod(1); +} // ------------------------------------------------------------------------------------ bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites) @@ -255,7 +194,9 @@ bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites) { // get the buffer size for this device detail instance DWORD req_size = 0; - SetupDiGetDeviceInterfaceDetail(dev_info, &didata, NULL, 0, &req_size, NULL); + (void)SetupDiGetDeviceInterfaceDetail(dev_info, &didata, NULL, 0, &req_size, NULL); + if (req_size < sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)) + WARN(_T("couldn't get device size for %u"), index); // (bizarre way of doing it) create a buffer large enough to hold the // fixed-size detail struct components, and the variable string size @@ -341,10 +282,6 @@ bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites) // autodetect which write method the Bluetooth stack supports, // by requesting the wiimote status report: - if(force_hidwrites && !_HidD_SetOutputReport) { - TRACE(_T(".. can't force HID writes (not supported)")); - force_hidwrites = false; - } if(force_hidwrites) TRACE(_T(".. (HID writes forced)")); @@ -362,7 +299,7 @@ bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites) } // try HID write method (if supported) - if(!bStatusReceived && _HidD_SetOutputReport) + if(!bStatusReceived) { bUseHIDwrite = true; RequestStatusReport(); @@ -749,7 +686,7 @@ void wiimote::SetReportType (input_report type, bool continuous) TYPE2NAME(IN_BUTTONS_ACCEL_EXT) : TYPE2NAME(IN_BUTTONS_ACCEL_IR_EXT) : TYPE2NAME(IN_BUTTONS_BALANCE_BOARD) : - _T("(unknown??)"); + _T("(unknown?)"); TRACE(_T("ReportType: %s (%s)"), name, (continuous? _T("continuous") : _T("non-continuous"))); #endif @@ -1773,50 +1710,53 @@ int wiimote::ParseReadAddress (BYTE* buff) break; } - #define IF_TYPE(id) if(type == id) { \ - /* sometimes it comes in more than once */ \ - if(Internal.ExtensionType == wiimote_state::id)\ - break; \ - Internal.ExtensionType = wiimote_state::id; + #define IF_TYPE(id, ...) /* sometimes it comes in more than once */ \ + if(type == id) \ + { \ + if(Internal.ExtensionType == wiimote_state::id) \ + break; \ + Internal.ExtensionType = wiimote_state::id; \ + __VA_ARGS__; \ + } // MotionPlus: once it's activated & mapped to the standard ext. port - IF_TYPE(MOTION_PLUS) + IF_TYPE(MOTION_PLUS, TRACE(_T(".. Motion Plus!")); // and start a query for the calibration data ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); bMotionPlusDetected = true; - } - else IF_TYPE(NUNCHUK) + ) + else IF_TYPE(NUNCHUK, TRACE(_T(".. Nunchuk!")); bMotionPlusEnabled = false; // and start a query for the calibration data ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); - } - else IF_TYPE(CLASSIC) + ) + else IF_TYPE(CLASSIC, TRACE(_T(".. Classic Controller!")); bMotionPlusEnabled = false; // and start a query for the calibration data ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); - } - else IF_TYPE(GH3_GHWT_GUITAR) + ) + else IF_TYPE(GH3_GHWT_GUITAR, // sometimes it comes in more than once? TRACE(_T(".. GH3/GHWT Guitar Controller!")); bMotionPlusEnabled = false; // and start a query for the calibration data ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); - } - else IF_TYPE(GHWT_DRUMS) + ) + else IF_TYPE(GHWT_DRUMS, TRACE(_T(".. GHWT Drums!")); bMotionPlusEnabled = false; // and start a query for the calibration data ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); - } - else IF_TYPE(BALANCE_BOARD) + ) + else IF_TYPE(BALANCE_BOARD, TRACE(_T(".. Balance Board!")); bMotionPlusEnabled = false; // and start a query for the calibration data ReadAddress(REGISTER_BALANCE_CALIBRATION, 24); - } + ) else if(type == PARTIALLY_INSERTED) { // sometimes it comes in more than once? if(Internal.ExtensionType == wiimote_state::PARTIALLY_INSERTED) @@ -1829,13 +1769,12 @@ int wiimote::ParseReadAddress (BYTE* buff) // status report (this usually fixes it) Internal.bExtension = false; RequestStatusReport(); - } - else{ + } + else TRACE(_T("unknown extension controller found (0x%I64x)"), type); - } } break; - + case (REGISTER_EXTENSION_CALIBRATION & 0xffff): case (REGISTER_BALANCE_CALIBRATION & 0xffff): { @@ -2040,7 +1979,7 @@ unsigned __stdcall wiimote::HIDwriteThreadfunc (void* param) #endif LeaveCriticalSection(&remote.HIDwriteQueueLock); - if(!_HidD_SetOutputReport(remote.Handle, buff, REPORT_LENGTH)) + if(!HidD_SetOutputReport(remote.Handle, buff, REPORT_LENGTH)) { DWORD err = GetLastError(); if(err==ERROR_BUSY) @@ -2306,7 +2245,7 @@ unsigned __stdcall wiimote::SampleStreamThreadfunc (void* param) { // (remember that samples are 4bit, ie. 2 per byte) unsigned samples_left = (current_sample->length - sample_index); - unsigned report_samples = min(samples_left, (unsigned)40); + unsigned report_samples = std::min(samples_left, (unsigned)40); // round the entries up to the nearest multiple of 2 unsigned report_entries = (report_samples+1) >> 1; @@ -2468,7 +2407,7 @@ bool wiimote::Load16bitMonoSampleWAV (const TCHAR* filepath, wiimote_sample &out unsigned sample_freq = wf.x.nSamplesPerSec; const unsigned epsilon = 100; // for now - for(unsigned index=1; index<ARRAY_ENTRIES(FreqLookup); index++) + for(unsigned index=1; index<std::size(FreqLookup); index++) { if((sample_freq+epsilon) >= FreqLookup[index] && (sample_freq-epsilon) <= FreqLookup[index]) { diff --git a/tracker-wii/wiiyourself/wiimote.h b/tracker-wii/wiiyourself/wiimote.h index 3588b7c7..4b5ab42a 100644 --- a/tracker-wii/wiiyourself/wiimote.h +++ b/tracker-wii/wiiyourself/wiimote.h @@ -10,6 +10,7 @@ #pragma once +#undef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <tchar.h> // auto Unicode/Ansi support @@ -390,11 +391,6 @@ class wiimote : public wiimote_state EVENT DataRead; // signals overlapped read complete bool bUseHIDwrite; // alternative write method (less efficient // but required for some BT stacks (eg. MS') - // HidD_SetOutputReport is only supported from XP onwards, so detect & - // load it dynamically: - static HMODULE HidDLL; - static hidwrite_ptr _HidD_SetOutputReport; - volatile bool bStatusReceived; // for output method detection volatile bool bConnectInProgress; // don't handle extensions until complete volatile bool bInitInProgress; // stop regular requests until complete @@ -405,7 +401,6 @@ volatile int MotionPlusDetectCount; // waiting for the result volatile bool bMotionPlusEnabled; volatile bool bMotionPlusExtension;// detected one plugged into MotionPlus volatile bool bCalibrateAtRest; // as soon as the first sensor values // come in after a Connect() call. - static unsigned _TotalCreated; static unsigned _TotalConnected; input_report ReportType; // type of data the wiimote delivers // read buffer |