summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--tracker-wii/CMakeLists.txt7
-rw-r--r--tracker-wii/lang/nl_NL.ts7
-rw-r--r--tracker-wii/lang/ru_RU.ts7
-rw-r--r--tracker-wii/lang/stub.ts7
-rw-r--r--tracker-wii/lang/zh_CN.ts7
-rw-r--r--tracker-wii/wii_camera.cpp105
-rw-r--r--tracker-wii/wii_camera.h33
-rw-r--r--tracker-wii/wii_frame.cpp34
-rw-r--r--tracker-wii/wii_frame.hpp16
-rw-r--r--tracker-wii/wii_module.cpp33
-rw-r--r--tracker-wii/wii_point_extractor.cpp52
-rw-r--r--tracker-wii/wii_point_extractor.h14
-rw-r--r--tracker-wii/wiiyourself/CMakeLists.txt8
-rw-r--r--tracker-wii/wiiyourself/warns-begin.hpp24
-rw-r--r--tracker-wii/wiiyourself/warns-end.hpp7
-rw-r--r--tracker-wii/wiiyourself/wiimote.cpp2925
-rw-r--r--tracker-wii/wiiyourself/wiimote.h15
-rw-r--r--tracker-wii/wiiyourself/wiimote_common.h2
18 files changed, 1607 insertions, 1696 deletions
diff --git a/tracker-wii/CMakeLists.txt b/tracker-wii/CMakeLists.txt
index f43dca55..76a43a77 100644
--- a/tracker-wii/CMakeLists.txt
+++ b/tracker-wii/CMakeLists.txt
@@ -1,10 +1,9 @@
if(WIN32)
- find_package(OpenCV QUIET)
+ find_package(OpenCV 3.0 QUIET)
if(OpenCV_FOUND)
add_subdirectory(wiiyourself)
otr_module(tracker-wii)
- target_link_libraries(${self} opentrack-tracker-pt-base opentrack-wiiyourself bthprops)
- target_include_directories(${self} PRIVATE SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/wiiyourself")
- target_include_directories(${self} PRIVATE "${CMAKE_SOURCE_DIR}/tracker-pt")
+ 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")
endif()
endif()
diff --git a/tracker-wii/lang/nl_NL.ts b/tracker-wii/lang/nl_NL.ts
index 4c21a820..9e739505 100644
--- a/tracker-wii/lang/nl_NL.ts
+++ b/tracker-wii/lang/nl_NL.ts
@@ -1,11 +1,4 @@
<?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 ff0e7092..f62cf2e1 100644
--- a/tracker-wii/lang/ru_RU.ts
+++ b/tracker-wii/lang/ru_RU.ts
@@ -1,11 +1,4 @@
<?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 d67c57ad..6401616d 100644
--- a/tracker-wii/lang/stub.ts
+++ b/tracker-wii/lang/stub.ts
@@ -1,11 +1,4 @@
<?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 d67c57ad..6401616d 100644
--- a/tracker-wii/lang/zh_CN.ts
+++ b/tracker-wii/lang/zh_CN.ts
@@ -1,11 +1,4 @@
<?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/wii_camera.cpp b/tracker-wii/wii_camera.cpp
index 25173bb7..af9a2d1f 100644
--- a/tracker-wii/wii_camera.cpp
+++ b/tracker-wii/wii_camera.cpp
@@ -7,19 +7,8 @@
*/
// silence #pragma deprecated in bluetoothapis.h
-
-#ifdef __clang__
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wreserved-id-macro"
-#endif
-
#undef _WIN32_WINNT
#define _WIN32_WINNT _WIN32_WINNT_VISTA
-
-#ifdef __clang__
-# pragma clang diagnostic pop
-#endif
-
#undef NTDDI_VERSION
#define NTDDI_VERSION NTDDI_VISTASP1
@@ -32,17 +21,18 @@
#include <opencv2/imgproc.hpp>
-#include <bthsdpdef.h>
+#include "cv/video-property-page.hpp"
+
#include <bluetoothapis.h>
-namespace pt_module {
+using namespace pt_module;
WIICamera::WIICamera(const QString& module_name) : s { module_name }
{
- cam_info.fps = 70;
- cam_info.res_x = 1024;
- cam_info.res_y = 768;
- cam_info.fov = 42;
+ cam_info.fps = 70;
+ cam_info.res_x = 1024;
+ cam_info.res_y = 768;
+ cam_info.fov = 42.0f;
cam_info.idx = 0;
}
@@ -53,12 +43,12 @@ WIICamera::~WIICamera()
QString WIICamera::get_desired_name() const
{
- return {};
+ return desired_name;
}
QString WIICamera::get_active_name() const
{
- return {};
+ return active_name;
}
void WIICamera::show_camera_settings()
@@ -69,8 +59,8 @@ void WIICamera::show_camera_settings()
WIICamera::result WIICamera::get_info() const
{
if (cam_info.res_x == 0 || cam_info.res_y == 0)
- return { false, {} };
- return { true, cam_info };
+ return result(false, pt_camera_info());
+ return result(true, cam_info);
}
WIICamera::result WIICamera::get_frame(pt_frame& frame_)
@@ -78,7 +68,7 @@ WIICamera::result WIICamera::get_frame(pt_frame& frame_)
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));
wii.status = new_frame;
@@ -86,43 +76,46 @@ WIICamera::result WIICamera::get_frame(pt_frame& 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 { false, cam_info };
- default:
- break;
+ return result(false, cam_info);
}
- return { true, cam_info };
+ return result(true, cam_info);
}
-bool WIICamera::start(int, int, int, int)
+bool WIICamera::start(int idx, int fps, int res_x, int res_y)
{
m_pDev = std::make_unique<wiimote>();
m_pDev->ChangedCallback = on_state_change;
- m_pDev->CallbackTriggerFlags = (state_change_flags)(CONNECTED|EXTENSION_CHANGED |MOTIONPLUS_CHANGED);
+ m_pDev->CallbackTriggerFlags = (state_change_flags)(CONNECTED |
+ EXTENSION_CHANGED |
+ MOTIONPLUS_CHANGED);
return true;
}
void WIICamera::stop()
{
- m_pDev->ChangedCallback = nullptr;
- m_pDev->Disconnect();
- Beep(1000, 200);
- m_pDev = nullptr;
+ onExit = true;
+ m_pDev->ChangedCallback = NULL;
+ m_pDev->Disconnect();
+ Beep(1000, 200);
+ if (m_pDev) {
+ m_pDev=nullptr;
+ m_pDev = NULL;
+ }
- cam_info = {};
- cam_desired = {};
+ desired_name = QString();
+ active_name = QString();
+ cam_info = pt_camera_info();
+ cam_desired = pt_camera_info();
}
-wii_camera_status WIICamera::pair()
+
+wii_camera_status WIICamera::_pair()
{
-#if defined __MINGW32__
- // missing prototypes and implib entries
- return wii_cam_wait_for_connect;
-#else
wii_camera_status ret = wii_cam_wait_for_sync;
HBLUETOOTH_RADIO_FIND hbt;
BLUETOOTH_FIND_RADIO_PARAMS bt_param;
@@ -150,7 +143,7 @@ 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);
@@ -190,7 +183,7 @@ wii_camera_status WIICamera::pair()
pwd[4] = btinfo.address.rgBytes[4];
pwd[5] = btinfo.address.rgBytes[5];
- if (ERROR_SUCCESS != BluetoothAuthenticateDevice(nullptr, hbtlist[i], &btdevinfo, pwd, 6)) { error = true; continue; }
+ if (ERROR_SUCCESS != BluetoothAuthenticateDevice(NULL, 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; }
@@ -206,25 +199,21 @@ wii_camera_status WIICamera::pair()
}
if (wiifound) { ret = wii_cam_wait_for_connect; }
return ret;
-#endif
}
-wii_camera_status WIICamera::get_frame_(cv::Mat& frame)
+wii_camera_status WIICamera::_get_frame(cv::Mat& frame)
{
- (void)frame;
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);
@@ -249,7 +238,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;
@@ -280,21 +269,23 @@ 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)
{
- horizon.p = m_pDev->Acceleration.Orientation.Pitch;
- horizon.r = m_pDev->Acceleration.Orientation.Roll;
+ p = m_pDev->Acceleration.Orientation.Pitch;
+ r = m_pDev->Acceleration.Orientation.Roll;
}
- wii.Pitch = horizon.p;
- wii.Roll = horizon.r;
+ wii.Pitch = p;
+ wii.Roll = r;
}
void WIICamera::on_state_change(wiimote &remote,
@@ -339,5 +330,3 @@ void WIICamera::on_state_change(wiimote &remote,
remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR);
}
}
-
-} // ns pt_module
diff --git a/tracker-wii/wii_camera.h b/tracker-wii/wii_camera.h
index e7d93b83..55def206 100644
--- a/tracker-wii/wii_camera.h
+++ b/tracker-wii/wii_camera.h
@@ -21,7 +21,7 @@
#include <QString>
-#include <wiimote.h>
+#include <wiiyourself/wiimote.h>
#include "wii_frame.hpp"
namespace pt_module {
@@ -41,26 +41,33 @@ struct WIICamera final : pt_camera
QString get_desired_name() const override;
QString get_active_name() const override;
- void set_fov(f value) override { (void)value; }
+ void set_fov(double value) override {}
void show_camera_settings() override;
private:
- static void on_state_change(wiimote &remote,
- state_change_flags changed,
- const wiimote_state &new_state);
- 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);
-
- std::unique_ptr<wiimote> m_pDev;
+ 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;
+
+ Timer t;
pt_camera_info cam_info;
pt_camera_info cam_desired;
-
- struct { float p = 0, r = 0; } horizon;
+ QString desired_name, active_name;
pt_settings s;
+
+ 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 4520fde4..9332a704 100644
--- a/tracker-wii/wii_frame.cpp
+++ b/tracker-wii/wii_frame.cpp
@@ -15,7 +15,7 @@
#include <opencv2/imgproc.hpp>
-namespace pt_module {
+using namespace pt_module;
WIIPreview& WIIPreview::operator=(const pt_frame& frame_)
{
@@ -27,7 +27,7 @@ WIIPreview& WIIPreview::operator=(const pt_frame& frame_)
if (frame.channels() != 3)
{
- eval_once(qDebug() << "tracker/pt: camera frame depth: 3 !=" << frame.channels());
+ once_only(qDebug() << "tracker/pt: camera frame depth: 3 !=" << frame.channels());
return *this;
}
@@ -49,23 +49,19 @@ WIIPreview::WIIPreview(int w, int h)
QImage WIIPreview::get_bitmap()
{
- switch (status) {
- case wii_cam_wait_for_dongle:
- return QImage(":/Resources/usb.png");
- case wii_cam_wait_for_sync:
- return QImage(":/Resources/sync.png");
- case wii_cam_wait_for_connect:
- return QImage(":/Resources/on.png");
- case wii_cam_data_change:
- case wii_cam_data_no_change:
- break;
- }
-
+ switch (status) {
+ case wii_cam_wait_for_dongle:
+ return QImage(":/Resources/usb.png");
+ case wii_cam_wait_for_sync:
+ return QImage(":/Resources/sync.png");
+ case wii_cam_wait_for_connect:
+ return QImage(":/Resources/on.png");
+ }
int stride = frame_out.step.p[0];
if (stride < 64 || stride < frame_out.cols * 4)
{
- eval_once(qDebug() << "bad stride" << stride
+ once_only(qDebug() << "bad stride" << stride
<< "for bitmap size" << frame_copy.cols << frame_copy.rows);
return QImage();
}
@@ -78,9 +74,11 @@ QImage WIIPreview::get_bitmap()
QImage::Format_ARGB32);
}
-void WIIPreview::draw_head_center(f x, f y)
+void WIIPreview::draw_head_center(double x, double y)
{
- auto [px_, py_] = to_pixel_pos(x, y, frame_copy.cols, frame_copy.rows);
+ double px_, py_;
+
+ std::tie(px_, py_) = to_pixel_pos(x, y, frame_copy.cols, frame_copy.rows);
int px = iround(px_), py = iround(py_);
@@ -102,5 +100,3 @@ void WIIPreview::ensure_size(cv::Mat& frame, int w, int h, int type)
if (frame.cols != w || frame.rows != h)
frame = cv::Mat(h, w, type);
}
-
-} // ns pt_module
diff --git a/tracker-wii/wii_frame.hpp b/tracker-wii/wii_frame.hpp
index 8c4508b2..31967d10 100644
--- a/tracker-wii/wii_frame.hpp
+++ b/tracker-wii/wii_frame.hpp
@@ -12,10 +12,7 @@
#include <opencv2/core.hpp>
#include <QImage>
-#ifdef __clang__
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wweak-vtables"
-#endif
+
namespace pt_module {
@@ -52,7 +49,7 @@ struct WIIPreview final : pt_preview
WIIPreview& operator=(const pt_frame& frame) override;
QImage get_bitmap() override;
- void draw_head_center(f x, f y) override;
+ void draw_head_center(double x, double y) override;
operator cv::Mat&() { return frame_copy; }
operator cv::Mat const&() const { return frame_copy; }
@@ -60,12 +57,9 @@ struct WIIPreview final : pt_preview
private:
static void ensure_size(cv::Mat& frame, int w, int h, int type);
- cv::Mat frame_copy, frame_out;
- wii_camera_status status = wii_cam_wait_for_dongle;
+ bool fresh = true;
+ cv::Mat frame_copy, frame_color, frame_resize, frame_out;
+ wii_camera_status status;
};
} // ns pt_module
-
-#ifdef __clang__
-# pragma clang diagnostic pop
-#endif
diff --git a/tracker-wii/wii_module.cpp b/tracker-wii/wii_module.cpp
index c4884f22..40131f69 100644
--- a/tracker-wii/wii_module.cpp
+++ b/tracker-wii/wii_module.cpp
@@ -6,12 +6,11 @@
* copyright notice and this permission notice appear in all copies.
*/
#include "ftnoir_tracker_pt.h"
+#include "api/plugin-api.hpp"
-#include "wii_module.hpp"
#include "wii_camera.h"
#include "wii_frame.hpp"
#include "wii_point_extractor.h"
-#include "wii_module.hpp"
#include "ftnoir_tracker_pt_dialog.h"
#include "pt-api.hpp"
@@ -20,12 +19,7 @@
static const QString module_name = "tracker-wii-pt";
-#ifdef __clang__
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wweak-vtables"
-#endif
-
-namespace pt_module {
+using namespace pt_module;
struct wii_pt_module_traits final : pt_runtime_traits
{
@@ -68,27 +62,22 @@ struct wii_dialog_pt : TrackerDialog_PT
wii_dialog_pt();
};
-} // ns pt_module
-
-#ifdef __clang__
-# pragma clang diagnostic pop
-#endif
-
-QString wii_metadata_pt::name()
+class wii_metadata_pt : public Metadata
{
- return tr("WiiPointTracker 1.1");
-}
+ QString name() { return _("WiiPointTracker 1.1"); }
+ QIcon icon() { return QIcon(":/Resources/wii.png"); }
+};
-QIcon wii_metadata_pt::icon()
-{
- return QIcon(":/Resources/wii.png");
-}
+// ns pt_module
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_point_extractor.cpp b/tracker-wii/wii_point_extractor.cpp
index a16cf233..215d50b8 100644
--- a/tracker-wii/wii_point_extractor.cpp
+++ b/tracker-wii/wii_point_extractor.cpp
@@ -30,9 +30,9 @@
#include <QDebug>
-using namespace numeric_types;
+using namespace types;
+using namespace pt_module;
-namespace pt_module {
WIIPointExtractor::WIIPointExtractor(const QString& module_name) : s(module_name)
{
@@ -40,40 +40,40 @@ 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 thickness)
+void WIIPointExtractor::_draw_point(cv::Mat& preview_frame, const vec2& p, const cv::Scalar& color, int thinkness)
{
static constexpr int len = 9;
- cv::Point p2(iround(p[0] * preview_frame.cols + preview_frame.cols / f{2}),
- iround(-p[1] * preview_frame.cols + preview_frame.rows / f{2}));
+ cv::Point p2(iround(p[0] * preview_frame.cols + preview_frame.cols / 2),
+ iround(-p[1] * preview_frame.cols + preview_frame.rows / 2));
cv::line(preview_frame,
cv::Point(p2.x - len, p2.y),
cv::Point(p2.x + len, p2.y),
color,
- thickness);
+ thinkness);
cv::line(preview_frame,
cv::Point(p2.x, p2.y - len),
cv::Point(p2.x, p2.y + len),
color,
- thickness);
-}
+ thinkness);
+};
-bool WIIPointExtractor::draw_points(cv::Mat& preview_frame, const struct wii_info& wii, std::vector<vec2>& points)
+bool WIIPointExtractor::_draw_points(cv::Mat& preview_frame, const struct wii_info &wii, std::vector<vec2>& points)
{
- constexpr int W = 1024;
- constexpr int H = 768;
+ const float W = 1024.0f;
+ const float H = 768.0f;
points.reserve(4);
points.clear();
- for (unsigned index = 0; index < 4; index++) // NOLINT(modernize-loop-convert)
+ for (unsigned index = 0; index < 4; index++)
{
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 f RX = W - dot.ux;
- const f RY = H - dot.uy;
+ 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);
@@ -81,7 +81,7 @@ bool WIIPointExtractor::draw_points(cv::Mat& preview_frame, const struct wii_inf
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), dot.isize);
}
}
const bool success = points.size() >= PointModel::N_POINTS;
@@ -89,7 +89,7 @@ bool WIIPointExtractor::draw_points(cv::Mat& preview_frame, const struct wii_inf
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 +99,8 @@ void WIIPointExtractor::draw_bg(cv::Mat& preview_frame, const struct wii_info& w
2);
//draw horizon
- int pdelta = iround((preview_frame.rows / f{4}) * tan(((double)wii.Pitch)* pi / f(180)));
- int rdelta = iround((preview_frame.cols / f{4}) * tan(((double)wii.Roll)* pi / f(180)));
+ 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));
cv::line(preview_frame,
cv::Point(0, preview_frame.rows / 2 + rdelta - pdelta),
@@ -114,15 +114,11 @@ void WIIPointExtractor::extract_points(const pt_frame& frame_, pt_preview& previ
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;
- default:
- break;
- }
+ switch (wii.status) {
+ case wii_cam_data_change:
+ _draw_bg(preview_frame, wii);
+ _draw_points(preview_frame, wii, points);
+ break;
+ }
}
-} // ns pt_module
diff --git a/tracker-wii/wii_point_extractor.h b/tracker-wii/wii_point_extractor.h
index 661ce35f..be0e5f45 100644
--- a/tracker-wii/wii_point_extractor.h
+++ b/tracker-wii/wii_point_extractor.h
@@ -16,19 +16,23 @@
namespace pt_module {
-using namespace numeric_types;
+using namespace 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;
WIIPointExtractor(const QString& module_name);
-
private:
+ static constexpr int max_blobs = 16;
+
pt_settings s;
- void draw_point(cv::Mat& preview_frame, const vec2& p, const cv::Scalar& color, int thickness = 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);
+ 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);
};
} // ns impl
+
diff --git a/tracker-wii/wiiyourself/CMakeLists.txt b/tracker-wii/wiiyourself/CMakeLists.txt
index 91fa245a..6a32fde4 100644
--- a/tracker-wii/wiiyourself/CMakeLists.txt
+++ b/tracker-wii/wiiyourself/CMakeLists.txt
@@ -1,7 +1 @@
-if(WIN32)
- otr_module(wiiyourself STATIC NO-COMPAT NO-QT)
- target_link_libraries(${self} setupapi hid winmm)
- if(CMAKE_COMPILER_IS_CLANGXX OR CMAKE_COMPILER_IS_GNUCXX)
- target_compile_options(${self} PRIVATE -Wno-error)
- endif()
-endif()
+otr_module(wiiyourself STATIC)
diff --git a/tracker-wii/wiiyourself/warns-begin.hpp b/tracker-wii/wiiyourself/warns-begin.hpp
deleted file mode 100644
index 0d0365a9..00000000
--- a/tracker-wii/wiiyourself/warns-begin.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifdef __GNUG__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wswitch"
-# pragma GCC diagnostic ignored "-Wreorder"
-# pragma GCC diagnostic ignored "-Wunused-variable"
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-# pragma GCC diagnostic ignored "-Wcast-align"
-# ifndef __clang__
-# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
-# pragma GCC diagnostic ignored "-Wcast-function-type"
-# endif
-#endif
-
-#ifdef __clang__
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
-# pragma clang diagnostic ignored "-Wextra-semi"
-# pragma clang diagnostic ignored "-Wshadow-field"
-# pragma clang diagnostic ignored "-Wreserved-id-macro"
-# pragma clang diagnostic ignored "-Wconversion"
-# pragma clang diagnostic ignored "-Wfloat-equal"
-# pragma clang diagnostic ignored "-Wunused-macros"
-# pragma clang diagnostic ignored "-Wcast-qual"
-#endif
diff --git a/tracker-wii/wiiyourself/warns-end.hpp b/tracker-wii/wiiyourself/warns-end.hpp
deleted file mode 100644
index 3de03ca5..00000000
--- a/tracker-wii/wiiyourself/warns-end.hpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifdef __GNUG__
-# pragma GCC diagnostic pop
-#endif
-
-#ifdef __clang__
-# pragma clang diagnostic pop
-#endif
diff --git a/tracker-wii/wiiyourself/wiimote.cpp b/tracker-wii/wiiyourself/wiimote.cpp
index f3fcd81f..e1e49101 100644
--- a/tracker-wii/wiiyourself/wiimote.cpp
+++ b/tracker-wii/wiiyourself/wiimote.cpp
@@ -8,22 +8,34 @@
//
// wiimote.cpp (tab = 4 spaces)
-#include "warns-begin.hpp"
-
-#include <cmath>
-#include <new>
-#include <cstring>
-#include <cstdio>
-#include <iterator>
+// 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 <setupapi.h>
-#include <hidsdi.h>// from WinDDK
-
+extern "C" {
+# ifdef __MINGW32__
+# include <ddk/hidsdi.h>// from WinDDK
+# else
+# include <hidsdi.h>
+# endif
+}
#include <sys/types.h> // for _stat
#include <sys/stat.h> // "
#include <process.h> // for _beginthreadex()
-#include <math.h> // for orientation
+#ifdef __BORLANDC__
+# include <cmath.h> // for orientation
+#else
+# include <math.h> // "
+#endif
#include <mmreg.h> // for WAVEFORMATEXTENSIBLE
#include <mmsystem.h> // for timeGetTime()
@@ -34,19 +46,24 @@
// ------------------------------------------------------------------------------------
// 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; }
+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 "WiiYourself: "
+#define PREFIX _T("WiiYourself! : ")
// comment these to auto-strip their code from the library:
// (they currently use OutputDebugString() via _TRACE() - change to suit)
-# define TRACE trace_
-# define WARN trace_
+#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
@@ -57,112 +74,108 @@ template<class T> inline T square(const T& val) { return val * val; }
// internals: auto-strip code from the macros if they weren't defined
#ifndef TRACE
-# define TRACE(...) (void)0
+# define TRACE
#endif
#ifndef DEEP_TRACE
-# define DEEP_TRACE(...) (void)0
+# define DEEP_TRACE
#endif
#ifndef WARN
-# define WARN(...) (void)0
+# define WARN
#endif
// ------------------------------------------------------------------------------------
-static void trace_(const char* fmt, ...)
-{
- char buffer[256];
-
- if (!fmt)
- return;
-
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(buffer, std::size(buffer), fmt, ap);
- va_end(ap);
-
- if (IsDebuggerPresent())
- OutputDebugString(buffer);
- else
- {
- fprintf(stderr, "%s\n", buffer);
- fflush(stderr);
- }
-}
+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);
+#endif
+ va_end (argptr);
+
+ OutputDebugString(buffer);
+ }
// ------------------------------------------------------------------------------------
// wiimote
// ------------------------------------------------------------------------------------
// class statics
-HMODULE wiimote::HidDLL = NULL;
-unsigned wiimote::_TotalCreated = 0;
-unsigned wiimote::_TotalConnected = 0;
+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] =
-{ 0, 4200, 3920, 3640, 3360,
- 3130, 2940, 2760, 2610, 2470 };
-
-const TCHAR* const wiimote::ButtonNameFromBit[TOTAL_BUTTON_BITS] =
-{ _T("Left") , _T("Right"), _T("Down"), _T("Up"),
- _T("Plus") , _T("??") , _T("??") , _T("??") ,
- _T("Two") , _T("One") , _T("B") , _T("A") ,
- _T("Minus"), _T("??") , _T("??") , _T("Home") };
-
-const TCHAR* const wiimote::ClassicButtonNameFromBit[TOTAL_BUTTON_BITS] =
-{ _T("??") , _T("TrigR") , _T("Plus") , _T("Home"),
- _T("Minus"), _T("TrigL") , _T("Down") , _T("Right") ,
- _T("Up") , _T("Left") , _T("ZR") , _T("X") ,
- _T("A") , _T("Y") , _T("B") , _T("ZL") };
+const unsigned wiimote::FreqLookup [TOTAL_FREQUENCIES] =
+ { 0, 4200, 3920, 3640, 3360,
+ 3130, 2940, 2760, 2610, 2470 };
+
+const TCHAR* const wiimote::ButtonNameFromBit [TOTAL_BUTTON_BITS] =
+ { _T("Left") , _T("Right"), _T("Down"), _T("Up"),
+ _T("Plus") , _T("??") , _T("??") , _T("??") ,
+ _T("Two") , _T("One") , _T("B") , _T("A") ,
+ _T("Minus"), _T("??") , _T("??") , _T("Home") };
+
+const TCHAR* const wiimote::ClassicButtonNameFromBit [TOTAL_BUTTON_BITS] =
+ { _T("??") , _T("TrigR") , _T("Plus") , _T("Home"),
+ _T("Minus"), _T("TrigL") , _T("Down") , _T("Right") ,
+ _T("Up") , _T("Left") , _T("ZR") , _T("X") ,
+ _T("A") , _T("Y") , _T("B") , _T("ZL") };
// ------------------------------------------------------------------------------------
-wiimote::wiimote()
+wiimote::wiimote ()
:
- DataRead(CreateEvent(NULL, FALSE, FALSE, NULL)),
- Handle(INVALID_HANDLE_VALUE),
- ReportType(IN_BUTTONS),
- bStatusReceived(false), // for output method detection
- bConnectInProgress(true),
- bInitInProgress(false),
- bEnablingMotionPlus(false),
- bConnectionLost(false), // set if write fails after connection
- bMotionPlusDetected(false),
- bMotionPlusEnabled(false),
- bMotionPlusExtension(false),
- bCalibrateAtRest(false),
- bUseHIDwrite(false), // if OS supports it
- ChangedCallback(NULL),
- CallbackTriggerFlags(CHANGED_ALL),
- InternalChanged(NO_CHANGE),
- CurrentSample(NULL),
- HIDwriteThread(NULL),
- ReadParseThread(NULL),
- SampleThread(NULL),
- AsyncRumbleThread(NULL),
- AsyncRumbleTimeout(0),
- UniqueID(0) // not _guaranteed_ unique, see comments in header
+ DataRead (CreateEvent(NULL, FALSE, FALSE, NULL)),
+ Handle (INVALID_HANDLE_VALUE),
+ ReportType (IN_BUTTONS),
+ bStatusReceived (false), // for output method detection
+ bConnectInProgress (true ),
+ bInitInProgress (false),
+ bEnablingMotionPlus (false),
+ bConnectionLost (false), // set if write fails after connection
+ bMotionPlusDetected (false),
+ bMotionPlusEnabled (false),
+ bMotionPlusExtension (false),
+ bCalibrateAtRest (false),
+ bUseHIDwrite (false), // if OS supports it
+ ChangedCallback (NULL),
+ CallbackTriggerFlags (CHANGED_ALL),
+ InternalChanged (NO_CHANGE),
+ CurrentSample (NULL),
+ HIDwriteThread (NULL),
+ ReadParseThread (NULL),
+ SampleThread (NULL),
+ AsyncRumbleThread (NULL),
+ AsyncRumbleTimeout (0),
+ UniqueID (0) // not _guaranteed_ unique, see comments in header
#ifdef ID2_FROM_DEVICEPATH // (see comments in header)
// UniqueID2 (0)
#endif
-{
+ {
_ASSERT(DataRead != INVALID_HANDLE_VALUE);
-
+
// if this is the first wiimote object, detect & enable HID write support
- if (++_TotalCreated == 1)
- {
+ if(++_TotalCreated == 1)
+ {
HidDLL = LoadLibrary(_T("hid.dll"));
_ASSERT(HidDLL);
- if (!HidDLL)
+ if(!HidDLL)
WARN(_T("Couldn't load hid.dll - shouldn't happen!"));
- else {
+ else{
_HidD_SetOutputReport = (hidwrite_ptr)
- GetProcAddress(HidDLL, "HidD_SetOutputReport");
- if (_HidD_SetOutputReport)
+ 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);
+ Clear (true);
Internal.Clear(true);
// and the state recording vars
@@ -170,9 +183,9 @@ wiimote::wiimote()
// for overlapped IO (Read/WriteFile)
memset(&Overlapped, 0, sizeof(Overlapped));
- Overlapped.hEvent = DataRead;
- Overlapped.Offset =
- Overlapped.OffsetHigh = 0;
+ Overlapped.hEvent = DataRead;
+ Overlapped.Offset =
+ Overlapped.OffsetHigh = 0;
// for async HID output method
InitializeCriticalSection(&HIDwriteQueueLock);
@@ -180,43 +193,43 @@ wiimote::wiimote()
InitializeCriticalSection(&StateLock);
// request millisecond timer accuracy
- timeBeginPeriod(1);
-}
+ timeBeginPeriod(1);
+ }
// ------------------------------------------------------------------------------------
-wiimote::~wiimote()
-{
+wiimote::~wiimote ()
+ {
Disconnect();
// events & critical sections are kept open for the lifetime of the object,
// so tidy them up here:
- if (DataRead != INVALID_HANDLE_VALUE)
+ if(DataRead != INVALID_HANDLE_VALUE)
CloseHandle(DataRead);
DeleteCriticalSection(&HIDwriteQueueLock);
DeleteCriticalSection(&StateLock);
// tidy up timer accuracy request
- timeEndPeriod(1);
+ timeEndPeriod(1);
// release HID DLL (for dynamic HID write method)
- if ((--_TotalCreated == 0) && HidDLL)
- {
+ if((--_TotalCreated == 0) && HidDLL)
+ {
FreeLibrary(HidDLL);
- HidDLL = NULL;
+ HidDLL = NULL;
_HidD_SetOutputReport = NULL;
+ }
}
-}
// ------------------------------------------------------------------------------------
-bool wiimote::Connect(unsigned wiimote_index, bool force_hidwrites)
-{
- if (wiimote_index == FIRST_AVAILABLE)
+bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites)
+ {
+ if(wiimote_index == FIRST_AVAILABLE)
TRACE(_T("Connecting first available Wiimote:"));
else
TRACE(_T("Connecting Wiimote %u:"), wiimote_index);
// auto-disconnect if user is being naughty
- if (IsConnected())
+ if(IsConnected())
Disconnect();
// get the GUID of the HID class
@@ -227,68 +240,65 @@ bool wiimote::Connect(unsigned wiimote_index, bool force_hidwrites)
// Brian: Fun fact: DIGCF_PRESENT worked on my machine just fine. I reinstalled
// Vista, and now it no longer finds the Wiimote with that parameter enabled...
HDEVINFO dev_info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE);// | DIGCF_PRESENT);
- if (!dev_info) {
+ if(!dev_info) {
WARN(_T("couldn't get device info"));
return false;
- }
+ }
// enumerate the devices
SP_DEVICE_INTERFACE_DATA didata;
didata.cbSize = sizeof(didata);
-
- unsigned index = 0;
+
+ unsigned index = 0;
unsigned wiimotes_found = 0;
- while (SetupDiEnumDeviceInterfaces(dev_info, NULL, &guid, index, &didata))
- {
+ while(SetupDiEnumDeviceInterfaces(dev_info, NULL, &guid, index, &didata))
+ {
// get the buffer size for this device detail instance
DWORD req_size = 0;
- if (!SetupDiGetDeviceInterfaceDetail(dev_info, &didata, NULL, 0, &req_size, NULL))
- {
- WARN(_T("couldn't get devinterface info for %u"), index);
- break;
- }
+ SetupDiGetDeviceInterfaceDetail(dev_info, &didata, NULL, 0, &req_size, NULL);
// (bizarre way of doing it) create a buffer large enough to hold the
// fixed-size detail struct components, and the variable string size
- using spdidd = SP_DEVICE_INTERFACE_DETAIL_DATA;
- spdidd *didetail = (spdidd*)operator new(req_size, (std::align_val_t)alignof(spdidd));
+ SP_DEVICE_INTERFACE_DETAIL_DATA *didetail =
+ (SP_DEVICE_INTERFACE_DETAIL_DATA*) new BYTE[req_size];
+ _ASSERT(didetail);
didetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
// now actually get the detail struct
- if (!SetupDiGetDeviceInterfaceDetail(dev_info, &didata, didetail,
- req_size, &req_size, NULL)) {
- WARN(_T("couldn't get devinterface info for %u #2"), index);
+ if(!SetupDiGetDeviceInterfaceDetail(dev_info, &didata, didetail,
+ req_size, &req_size, NULL)) {
+ WARN(_T("couldn't get devinterface info for %u"), index);
break;
- }
+ }
// open a shared handle to the device to query it (this will succeed even
// if the wiimote is already Connect()'ed)
DEEP_TRACE(_T(".. querying device %s"), didetail->DevicePath);
- Handle = CreateFile(didetail->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, 0, NULL);
- if (Handle == INVALID_HANDLE_VALUE) {
- DEEP_TRACE(_T(".... failed with err %x (probably harmless)."),
- GetLastError());
+ Handle = CreateFile(didetail->DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ if(Handle == INVALID_HANDLE_VALUE) {
+ DEEP_TRACE(_T(".... failed with err %x (probably harmless)."),
+ GetLastError());
goto skip;
- }
-
+ }
+
// get the device attributes
HIDD_ATTRIBUTES attrib;
attrib.Size = sizeof(attrib);
- if (HidD_GetAttributes(Handle, &attrib))
- {
+ if(HidD_GetAttributes(Handle, &attrib))
+ {
// is this a wiimote?
- if ((attrib.VendorID != VID) || (attrib.ProductID != PID))
+ if((attrib.VendorID != VID) || (attrib.ProductID != PID))
goto skip;
// yes, but is it the one we're interested in?
++wiimotes_found;
- if ((wiimote_index != FIRST_AVAILABLE) &&
- (wiimote_index != wiimotes_found))
+ if((wiimote_index != FIRST_AVAILABLE) &&
+ (wiimote_index != wiimotes_found))
goto skip;
// the wiimote is installed, but it may not be currently paired:
- if (wiimote_index == FIRST_AVAILABLE)
+ if(wiimote_index == FIRST_AVAILABLE)
TRACE(_T(".. opening Wiimote %u:"), wiimotes_found);
else
TRACE(_T(".. opening:"));
@@ -298,7 +308,7 @@ bool wiimote::Connect(unsigned wiimote_index, bool force_hidwrites)
// (that way subsequent calls can still _discover_ wiimotes above, but
// will correctly fail here if they're already connected)
CloseHandle(Handle);
-
+
// note this also means that if another application has already opened
// the device, the library can no longer connect it (this may happen
// with software that enumerates all joysticks in the system, because
@@ -309,21 +319,21 @@ bool wiimote::Connect(unsigned wiimote_index, bool force_hidwrites)
// call below to open the device in full shared mode - but then the
// library can no longer detect if you've already connected a device
// and will allow you to connect it twice! So be careful ...
- Handle = CreateFile(didetail->DevicePath, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED, NULL);
- if (Handle == INVALID_HANDLE_VALUE) {
+ Handle = CreateFile(didetail->DevicePath, GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ| FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED, NULL);
+ if(Handle == INVALID_HANDLE_VALUE) {
TRACE(_T(".... failed with err %x"), GetLastError());
goto skip;
- }
+ }
// clear the wiimote state & buffers
- Clear(false); // preserves existing deadzones
+ Clear (false); // preserves existing deadzones
Internal.Clear(false); // "
InternalChanged = NO_CHANGE;
- memset(ReadBuff, 0, sizeof(ReadBuff));
- bConnectionLost = false;
+ memset(ReadBuff , 0, sizeof(ReadBuff));
+ bConnectionLost = false;
bConnectInProgress = true; // don't parse extensions or request regular
// updates until complete
// enable async reading
@@ -331,49 +341,49 @@ 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) {
+ if(force_hidwrites && !_HidD_SetOutputReport) {
TRACE(_T(".. can't force HID writes (not supported)"));
force_hidwrites = false;
- }
+ }
- if (force_hidwrites)
+ if(force_hidwrites)
TRACE(_T(".. (HID writes forced)"));
- else {
+ else{
// - try WriteFile() first as it's the most efficient (it uses
// harware interrupts where possible and is async-capable):
bUseHIDwrite = false;
RequestStatusReport();
// and wait for the report to arrive:
DWORD last_time = timeGetTime();
- while (!bStatusReceived && ((timeGetTime() - last_time) < 500))
+ while(!bStatusReceived && ((timeGetTime()-last_time) < 500))
Sleep(10);
- TRACE(_T(".. WriteFile() %s."), bStatusReceived ? _T("succeeded") :
- _T("failed"));
- }
+ TRACE(_T(".. WriteFile() %s."), bStatusReceived? _T("succeeded") :
+ _T("failed"));
+ }
// try HID write method (if supported)
- if (!bStatusReceived && _HidD_SetOutputReport)
- {
+ if(!bStatusReceived && _HidD_SetOutputReport)
+ {
bUseHIDwrite = true;
RequestStatusReport();
// wait for the report to arrive:
DWORD last_time = timeGetTime();
- while (!bStatusReceived && ((timeGetTime() - last_time) < 500))
+ while(!bStatusReceived && ((timeGetTime()-last_time) < 500))
Sleep(10);
// did we get it?
- TRACE(_T(".. HID write %s."), bStatusReceived ? _T("succeeded") :
- _T("failed"));
- }
+ TRACE(_T(".. HID write %s."), bStatusReceived? _T("succeeded") :
+ _T("failed"));
+ }
// still failed?
- if (!bStatusReceived) {
+ if(!bStatusReceived) {
WARN(_T("output failed - wiimote is not connected (or confused)."));
Disconnect();
goto skip;
- }
+ }
- //Sleep(500);
- // reset it
+//Sleep(500);
+ // reset it
Reset();
// read the wiimote calibration info
@@ -406,113 +416,113 @@ bool wiimote::Connect(unsigned wiimote_index, bool force_hidwrites)
// create a 2nd alternative id by simply adding all the characters
// in the device path to create a single number
UniqueID2 = 0;
- for (unsigned index = 0; index < _tcslen(didetail->DevicePath); index++)
+ for(unsigned index=0; index<_tcslen(didetail->DevicePath); index++)
UniqueID2 += didetail->DevicePath[index];
#endif
// and show when we want to trigger the next periodic status request
// (for battery level and connection loss detection)
- NextStatusTime = timeGetTime() + REQUEST_STATUS_EVERY_MS;
+ NextStatusTime = timeGetTime() + REQUEST_STATUS_EVERY_MS;
NextMPlusDetectTime = timeGetTime() + DETECT_MPLUS_EVERY_MS;
- MPlusDetectCount = DETECT_MPLUS_COUNT;
+ MPlusDetectCount = DETECT_MPLUS_COUNT;
// tidy up
- delete[](BYTE*)didetail;
+ delete[] (BYTE*)didetail;
break;
- }
- skip:
+ }
+skip:
// tidy up
- delete[](BYTE*)didetail;
+ delete[] (BYTE*)didetail;
- if (Handle != INVALID_HANDLE_VALUE) {
+ if(Handle != INVALID_HANDLE_VALUE) {
CloseHandle(Handle);
Handle = INVALID_HANDLE_VALUE;
- }
+ }
// if this was the specified wiimote index, abort
- if ((wiimote_index != FIRST_AVAILABLE) &&
- (wiimote_index == (wiimotes_found - 1)))
- break;
+ if((wiimote_index != FIRST_AVAILABLE) &&
+ (wiimote_index == (wiimotes_found-1)))
+ break;
index++;
- }
+ }
// clean up our list
SetupDiDestroyDeviceInfoList(dev_info);
bConnectInProgress = false;
- if (IsConnected()) {
+ if(IsConnected()) {
TRACE(_T(".. connected!"));
// notify the callbacks (if requested to do so)
- if (CallbackTriggerFlags & CONNECTED)
- {
+ if(CallbackTriggerFlags & CONNECTED)
+ {
ChangedNotifier(CONNECTED, Internal);
- if (ChangedCallback)
+ if(ChangedCallback)
ChangedCallback(*this, CONNECTED, Internal);
- }
+ }
return true;
- }
+ }
TRACE(_T(".. connection failed."));
return false;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::CalibrateAtRest()
-{
+void wiimote::CalibrateAtRest ()
+ {
_ASSERT(IsConnected());
- if (!IsConnected())
+ if(!IsConnected())
return;
// the app calls this to remove 'at rest' offsets from the analogue sensor
// values (currently only works for the Balance Board):
- if (IsBalanceBoard()) {
+ if(IsBalanceBoard()) {
TRACE(_T(".. removing 'at rest' BBoard offsets."));
Internal.BalanceBoard.AtRestKg = Internal.BalanceBoard.Kg;
RefreshState();
+ }
}
-}
// ------------------------------------------------------------------------------------
-void wiimote::Disconnect()
-{
- if (Handle == INVALID_HANDLE_VALUE)
+void wiimote::Disconnect ()
+ {
+ if(Handle == INVALID_HANDLE_VALUE)
return;
TRACE(_T("Disconnect()."));
-
- if (IsConnected())
- {
+
+ if(IsConnected())
+ {
_ASSERT(_TotalConnected > 0); // sanity
_TotalConnected--;
-
- if (!bConnectionLost)
+
+ if(!bConnectionLost)
Reset();
- }
+ }
CloseHandle(Handle);
Handle = INVALID_HANDLE_VALUE;
- UniqueID = 0;
+ UniqueID = 0;
#ifdef ID2_FROM_DEVICEPATH // (see comments in header)
UniqueID2 = 0;
#endif
// close the read thread
- if (ReadParseThread) {
+ if(ReadParseThread) {
// unblock it so it can realise we're closing and exit straight away
SetEvent(DataRead);
WaitForSingleObject(ReadParseThread, 3000);
CloseHandle(ReadParseThread);
- ReadParseThread = NULL;
- }
+ ReadParseThread = NULL;
+ }
// close the rumble thread
- if (AsyncRumbleThread) {
+ if(AsyncRumbleThread) {
WaitForSingleObject(AsyncRumbleThread, 3000);
CloseHandle(AsyncRumbleThread);
- AsyncRumbleThread = NULL;
+ AsyncRumbleThread = NULL;
AsyncRumbleTimeout = 0;
- }
+ }
// and the sample streaming thread
- if (SampleThread) {
+ if(SampleThread) {
WaitForSingleObject(SampleThread, 3000);
CloseHandle(SampleThread);
SampleThread = NULL;
- }
+ }
#ifndef USE_DYNAMIC_HIDQUEUE
HID.Deallocate();
@@ -521,197 +531,197 @@ void wiimote::Disconnect()
bStatusReceived = false;
// and clear the state
- Clear(false); // (preserves deadzones)
+ Clear (false); // (preserves deadzones)
Internal.Clear(false); // "
InternalChanged = NO_CHANGE;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::Reset()
-{
+void wiimote::Reset ()
+ {
TRACE(_T("Resetting wiimote."));
-
- if (bMotionPlusEnabled)
+
+ if(bMotionPlusEnabled)
DisableMotionPlus();
// stop updates (by setting report type to non-continuous, buttons-only)
- if (IsBalanceBoard())
+ if(IsBalanceBoard())
SetReportType(IN_BUTTONS_BALANCE_BOARD, false);
else
SetReportType(IN_BUTTONS, false);
- SetRumble(false);
- SetLEDs(0x00);
- // MuteSpeaker (true);
+ SetRumble (false);
+ SetLEDs (0x00);
+// MuteSpeaker (true);
EnableSpeaker(false);
Sleep(150); // avoids loosing the extension calibration data on Connect()
-}
+ }
// ------------------------------------------------------------------------------------
-unsigned __stdcall wiimote::ReadParseThreadfunc(void* param)
-{
+unsigned __stdcall wiimote::ReadParseThreadfunc (void* param)
+ {
// this thread waits for the async ReadFile() to deliver data & parses it.
// it also requests periodic status updates, deals with connection loss
// and ends state recordings with a specific duration:
_ASSERT(param);
- wiimote &remote = *(wiimote*)param;
+ wiimote &remote = *(wiimote*)param;
OVERLAPPED &overlapped = remote.Overlapped;
- unsigned exit_code = 0; // (success)
+ unsigned exit_code = 0; // (success)
- while (1)
- {
+ while(1)
+ {
// wait until the overlapped read completes, or the timeout is reached:
DWORD wait = WaitForSingleObject(overlapped.hEvent, 500);
// before we deal with the result, let's do some housekeeping:
// if we were recently Disconect()ed, exit now
- if (remote.Handle == INVALID_HANDLE_VALUE) {
+ if(remote.Handle == INVALID_HANDLE_VALUE) {
DEEP_TRACE(_T("read thread: wiimote was disconnected"));
break;
- }
+ }
// ditto if the connection was lost (eg. through a failed write)
- if (remote.bConnectionLost)
- {
- connection_lost:
+ if(remote.bConnectionLost)
+ {
+connection_lost:
TRACE(_T("read thread: connection to wiimote was lost"));
remote.Disconnect();
remote.InternalChanged = (state_change_flags)
- (remote.InternalChanged | CONNECTION_LOST);
+ (remote.InternalChanged | CONNECTION_LOST);
// report via the callback (if any)
- if (remote.CallbackTriggerFlags & CONNECTION_LOST)
- {
+ if(remote.CallbackTriggerFlags & CONNECTION_LOST)
+ {
remote.ChangedNotifier(CONNECTION_LOST, remote.Internal);
- if (remote.ChangedCallback)
+ if(remote.ChangedCallback)
remote.ChangedCallback(remote, CONNECTION_LOST, remote.Internal);
- }
+ }
break;
- }
+ }
DWORD time = timeGetTime();
// periodic events (but not if we're streaming audio,
// we don't want to cause a glitch)
- if (remote.IsConnected() && !remote.bInitInProgress &&
- !remote.IsPlayingAudio())
- {
- // status request due?
- if (time > remote.NextStatusTime)
+ if(remote.IsConnected() && !remote.bInitInProgress &&
+ !remote.IsPlayingAudio())
{
+ // status request due?
+ if(time > remote.NextStatusTime)
+ {
#ifdef BEEP_ON_PERIODIC_STATUSREFRESH
- Beep(2000, 50);
+ Beep(2000,50);
#endif
remote.RequestStatusReport();
// and schedule the next one
remote.NextStatusTime = time + REQUEST_STATUS_EVERY_MS;
- }
+ }
// motion plus detection due?
- if (!remote.IsBalanceBoard() &&
- // !remote.bConnectInProgress &&
- !remote.bMotionPlusExtension &&
- (remote.Internal.ExtensionType != MOTION_PLUS) &&
- (remote.Internal.ExtensionType != PARTIALLY_INSERTED) &&
- (time > remote.NextMPlusDetectTime))
- {
+ if(!remote.IsBalanceBoard() &&
+// !remote.bConnectInProgress &&
+ !remote.bMotionPlusExtension &&
+ (remote.Internal.ExtensionType != MOTION_PLUS) &&
+ (remote.Internal.ExtensionType != PARTIALLY_INSERTED) &&
+ (time > remote.NextMPlusDetectTime))
+ {
remote.DetectMotionPlusExtensionAsync();
// we try several times in quick succession before the next
// delay:
- if (--remote.MPlusDetectCount == 0) {
+ if(--remote.MPlusDetectCount == 0) {
remote.NextMPlusDetectTime = time + DETECT_MPLUS_EVERY_MS;
- remote.MPlusDetectCount = DETECT_MPLUS_COUNT;
+ remote.MPlusDetectCount = DETECT_MPLUS_COUNT;
#ifdef _DEBUG
TRACE(_T("--"));
#endif
+ }
}
}
- }
// if we're state recording and have reached the specified duration, stop
- if (remote.Recording.bEnabled && (remote.Recording.EndTimeMS != UNTIL_STOP) &&
- (time >= remote.Recording.EndTimeMS))
- remote.Recording.bEnabled = false;
+ if(remote.Recording.bEnabled && (remote.Recording.EndTimeMS != UNTIL_STOP) &&
+ (time >= remote.Recording.EndTimeMS))
+ remote.Recording.bEnabled = false;
// now handle the wait result:
// did the wait time out?
- if (wait == WAIT_TIMEOUT) {
+ if(wait == WAIT_TIMEOUT) {
DEEP_TRACE(_T("read thread: timed out"));
continue; // wait again
- }
+ }
// did an error occurr?
- if (wait != WAIT_OBJECT_0) {
+ if(wait != WAIT_OBJECT_0) {
DEEP_TRACE(_T("read thread: error waiting!"));
remote.bConnectionLost = true;
// deal with it straight away to avoid a longer delay
goto connection_lost;
- }
-
+ }
+
// data was received:
#ifdef BEEP_DEBUG_READS
- Beep(500, 1);
+ Beep(500,1);
#endif
DWORD read = 0;
// get the data read result
GetOverlappedResult(remote.Handle, &overlapped, &read, TRUE);
// if we read data, parse it
- if (read) {
+ if(read) {
DEEP_TRACE(_T("read thread: parsing data"));
remote.OnReadData(read);
- }
+ }
else
DEEP_TRACE(_T("read thread: didn't get any data??"));
- }
+ }
TRACE(_T("(ending read thread)"));
#ifdef BEEP_DEBUG_READS
- if (exit_code != 0)
- Beep(200, 1000);
+ if(exit_code != 0)
+ Beep(200,1000);
#endif
return exit_code;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::BeginAsyncRead()
-{
+bool wiimote::BeginAsyncRead ()
+ {
// (this is also called before we're fully connected)
- if (Handle == INVALID_HANDLE_VALUE)
+ if(Handle == INVALID_HANDLE_VALUE)
return false;
DEEP_TRACE(_T(".. starting async read"));
#ifdef BEEP_DEBUG_READS
- Beep(1000, 1);
+ Beep(1000,1);
#endif
DWORD read;
if (!ReadFile(Handle, ReadBuff, REPORT_LENGTH, &read, &Overlapped)) {
DWORD err = GetLastError();
- if (err != ERROR_IO_PENDING) {
+ if(err != ERROR_IO_PENDING) {
DEEP_TRACE(_T(".... ** ReadFile() failed! **"));
return false;
+ }
}
- }
// launch the completion wait/callback thread
- if (!ReadParseThread) {
+ if(!ReadParseThread) {
ReadParseThread = (HANDLE)_beginthreadex(NULL, 0, ReadParseThreadfunc,
- this, 0, NULL);
+ this, 0, NULL);
DEEP_TRACE(_T(".... creating read thread"));
_ASSERT(ReadParseThread);
- if (!ReadParseThread)
+ if(!ReadParseThread)
return false;
SetThreadPriority(ReadParseThread, WORKER_THREAD_PRIORITY);
- }
+ }
// if ReadFile completed while we called, signal the thread to proceed
- if (read) {
+ if(read) {
DEEP_TRACE(_T(".... got data right away"));
SetEvent(DataRead);
- }
+ }
return true;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::OnReadData(DWORD bytes_read)
-{
+void wiimote::OnReadData (DWORD bytes_read)
+ {
_ASSERT(bytes_read == REPORT_LENGTH);
// copy our input buffer
- BYTE buff[REPORT_LENGTH];
+ BYTE buff [REPORT_LENGTH];
memcpy(buff, ReadBuff, bytes_read);
// start reading again
@@ -719,122 +729,122 @@ void wiimote::OnReadData(DWORD bytes_read)
// parse it
ParseInput(buff);
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::SetReportType(input_report type, bool continuous)
-{
+void wiimote::SetReportType (input_report type, bool continuous)
+ {
_ASSERT(IsConnected());
- if (!IsConnected())
+ if(!IsConnected())
return;
// the balance board only uses one type of report
_ASSERT(!IsBalanceBoard() || type == IN_BUTTONS_BALANCE_BOARD);
- if (IsBalanceBoard() && (type != IN_BUTTONS_BALANCE_BOARD))
+ if(IsBalanceBoard() && (type != IN_BUTTONS_BALANCE_BOARD))
return;
#ifdef TRACE
-#define TYPE2NAME(_type) (type==_type)? _T(#_type)
- const TCHAR* name = TYPE2NAME(IN_BUTTONS) :
- TYPE2NAME(IN_BUTTONS_ACCEL_IR) :
- TYPE2NAME(IN_BUTTONS_ACCEL_EXT) :
- TYPE2NAME(IN_BUTTONS_ACCEL_IR_EXT) :
- TYPE2NAME(IN_BUTTONS_BALANCE_BOARD) :
- _T("(unknown?)");
- TRACE(_T("ReportType: %s (%s)"), name, (continuous ? _T("continuous") :
- _T("non-continuous")));
+ #define TYPE2NAME(_type) (type==_type)? _T(#_type)
+ const TCHAR* name = TYPE2NAME(IN_BUTTONS) :
+ TYPE2NAME(IN_BUTTONS_ACCEL_IR) :
+ TYPE2NAME(IN_BUTTONS_ACCEL_EXT) :
+ TYPE2NAME(IN_BUTTONS_ACCEL_IR_EXT) :
+ TYPE2NAME(IN_BUTTONS_BALANCE_BOARD) :
+ _T("(unknown??)");
+ TRACE(_T("ReportType: %s (%s)"), name, (continuous? _T("continuous") :
+ _T("non-continuous")));
#endif
ReportType = type;
- switch (type)
- {
- case IN_BUTTONS_ACCEL_IR:
- EnableIR(wiimote_state::ir::EXTENDED);
- break;
- case IN_BUTTONS_ACCEL_IR_EXT:
- EnableIR(wiimote_state::ir::BASIC);
- break;
- default:
- DisableIR();
- break;
- }
+ switch(type)
+ {
+ case IN_BUTTONS_ACCEL_IR:
+ EnableIR(wiimote_state::ir::EXTENDED);
+ break;
+ case IN_BUTTONS_ACCEL_IR_EXT:
+ EnableIR(wiimote_state::ir::BASIC);
+ break;
+ default:
+ DisableIR();
+ break;
+ }
- BYTE buff[REPORT_LENGTH] = { 0 };
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_TYPE;
buff[1] = (continuous ? 0x04 : 0x00) | GetRumbleBit();
buff[2] = (BYTE)type;
WriteReport(buff);
- // Sleep(15);
-}
+// Sleep(15);
+ }
// ------------------------------------------------------------------------------------
-void wiimote::SetLEDs(BYTE led_bits)
-{
+void wiimote::SetLEDs (BYTE led_bits)
+ {
_ASSERT(IsConnected());
- if (!IsConnected() || bInitInProgress)
+ if(!IsConnected() || bInitInProgress)
return;
_ASSERT(led_bits <= 0x0f);
led_bits &= 0xf;
-
- BYTE buff[REPORT_LENGTH] = { 0 };
+
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_LEDs;
- buff[1] = (led_bits << 4) | GetRumbleBit();
+ buff[1] = (led_bits<<4) | GetRumbleBit();
WriteReport(buff);
Internal.LED.Bits = led_bits;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::SetRumble(bool on)
-{
+void wiimote::SetRumble (bool on)
+ {
_ASSERT(IsConnected());
- if (!IsConnected())
+ if(!IsConnected())
return;
- if (Internal.bRumble == on)
+ if(Internal.bRumble == on)
return;
Internal.bRumble = on;
// if we're streaming audio, we don't need to send a report (sending it makes
// the audio glitch, and the rumble bit is sent with every report anyway)
- if (IsPlayingAudio())
+ if(IsPlayingAudio())
return;
- BYTE buff[REPORT_LENGTH] = { 0 };
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_STATUS;
- buff[1] = on ? 0x01 : 0x00;
+ buff[1] = on? 0x01 : 0x00;
WriteReport(buff);
-}
+ }
// ------------------------------------------------------------------------------------
-unsigned __stdcall wiimote::AsyncRumbleThreadfunc(void* param)
-{
+unsigned __stdcall wiimote::AsyncRumbleThreadfunc (void* param)
+ {
// auto-disables rumble after x milliseconds:
_ASSERT(param);
wiimote &remote = *(wiimote*)param;
-
- while (remote.IsConnected())
- {
- if (remote.AsyncRumbleTimeout)
+
+ while(remote.IsConnected())
{
- DWORD current_time = timeGetTime();
- if (current_time >= remote.AsyncRumbleTimeout)
+ if(remote.AsyncRumbleTimeout)
{
- if (remote.Internal.bRumble)
+ DWORD current_time = timeGetTime();
+ if(current_time >= remote.AsyncRumbleTimeout)
+ {
+ if(remote.Internal.bRumble)
remote.SetRumble(false);
remote.AsyncRumbleTimeout = 0;
- }
+ }
Sleep(1);
- }
+ }
else
Sleep(4);
- }
+ }
return 0;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::RumbleForAsync(unsigned milliseconds)
-{
+void wiimote::RumbleForAsync (unsigned milliseconds)
+ {
// rumble for a fixed amount of time
_ASSERT(IsConnected());
- if (!IsConnected())
+ if(!IsConnected())
return;
SetRumble(true);
@@ -844,146 +854,146 @@ void wiimote::RumbleForAsync(unsigned milliseconds)
AsyncRumbleTimeout = timeGetTime() + milliseconds;
// create the thread?
- if (AsyncRumbleThread)
+ if(AsyncRumbleThread)
return;
AsyncRumbleThread = (HANDLE)_beginthreadex(NULL, 0, AsyncRumbleThreadfunc, this,
- 0, NULL);
+ 0, NULL);
_ASSERT(AsyncRumbleThread);
- if (!AsyncRumbleThread) {
+ if(!AsyncRumbleThread) {
WARN(_T("couldn't create rumble thread!"));
return;
- }
+ }
SetThreadPriority(AsyncRumbleThread, WORKER_THREAD_PRIORITY);
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::RequestStatusReport()
-{
+void wiimote::RequestStatusReport ()
+ {
// (this can be called before we're fully connected)
_ASSERT(Handle != INVALID_HANDLE_VALUE);
- if (Handle == INVALID_HANDLE_VALUE)
+ if(Handle == INVALID_HANDLE_VALUE)
return;
- BYTE buff[REPORT_LENGTH] = { 0 };
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_STATUS;
buff[1] = GetRumbleBit();
WriteReport(buff);
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::ReadAddress(int address, short size)
-{
+bool wiimote::ReadAddress (int address, short size)
+ {
// asynchronous
- BYTE buff[REPORT_LENGTH] = { 0 };
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_READMEMORY;
buff[1] = (BYTE)(((address & 0xff000000) >> 24) | GetRumbleBit());
- buff[2] = (BYTE)((address & 0x00ff0000) >> 16);
- buff[3] = (BYTE)((address & 0x0000ff00) >> 8);
- buff[4] = (BYTE)((address & 0x000000ff));
- buff[5] = (BYTE)((size & 0xff00) >> 8);
- buff[6] = (BYTE)((size & 0xff));
+ buff[2] = (BYTE)( (address & 0x00ff0000) >> 16);
+ buff[3] = (BYTE)( (address & 0x0000ff00) >> 8);
+ buff[4] = (BYTE)( (address & 0x000000ff));
+ buff[5] = (BYTE)( (size & 0xff00 ) >> 8);
+ buff[6] = (BYTE)( (size & 0xff));
return WriteReport(buff);
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::WriteData(int address, BYTE size, const BYTE* buff)
-{
+void wiimote::WriteData (int address, BYTE size, const BYTE* buff)
+ {
// asynchronous
- BYTE write[REPORT_LENGTH] = { 0 };
+ BYTE write [REPORT_LENGTH] = {0};
write[0] = OUT_WRITEMEMORY;
write[1] = (BYTE)(((address & 0xff000000) >> 24) | GetRumbleBit());
- write[2] = (BYTE)((address & 0x00ff0000) >> 16);
- write[3] = (BYTE)((address & 0x0000ff00) >> 8);
- write[4] = (BYTE)((address & 0x000000ff));
+ write[2] = (BYTE)( (address & 0x00ff0000) >> 16);
+ write[3] = (BYTE)( (address & 0x0000ff00) >> 8);
+ write[4] = (BYTE)( (address & 0x000000ff));
write[5] = size;
- memcpy(write + 6, buff, size);
+ memcpy(write+6, buff, size);
WriteReport(write);
-}
+ }
// ------------------------------------------------------------------------------------
-int wiimote::ParseInput(BYTE* buff)
-{
+int wiimote::ParseInput (BYTE* buff)
+ {
int changed = 0;
// lock our internal state (so RefreshState() is blocked until we're done
EnterCriticalSection(&StateLock);
- switch (buff[0])
- {
- case IN_BUTTONS:
- DEEP_TRACE(_T(".. parsing buttons."));
- changed |= ParseButtons(buff);
- break;
-
- case IN_BUTTONS_ACCEL:
- DEEP_TRACE(_T(".. parsing buttons/accel."));
- changed |= ParseButtons(buff);
- if (!IsBalanceBoard())
- changed |= ParseAccel(buff);
- break;
-
- case IN_BUTTONS_ACCEL_EXT:
- DEEP_TRACE(_T(".. parsing extenion/accel."));
- changed |= ParseButtons(buff);
- changed |= ParseExtension(buff, 6);
- if (!IsBalanceBoard())
- changed |= ParseAccel(buff);
- break;
-
- case IN_BUTTONS_ACCEL_IR:
- DEEP_TRACE(_T(".. parsing ir/accel."));
- changed |= ParseButtons(buff);
- if (!IsBalanceBoard()) {
- changed |= ParseAccel(buff);
- changed |= ParseIR(buff);
- }
- break;
-
- case IN_BUTTONS_ACCEL_IR_EXT:
- DEEP_TRACE(_T(".. parsing ir/extenion/accel."));
- changed |= ParseButtons(buff);
- changed |= ParseExtension(buff, 16);
- if (!IsBalanceBoard()) {
- changed |= ParseAccel(buff);
- changed |= ParseIR(buff);
+ switch(buff[0])
+ {
+ case IN_BUTTONS:
+ DEEP_TRACE(_T(".. parsing buttons."));
+ changed |= ParseButtons(buff);
+ break;
+
+ case IN_BUTTONS_ACCEL:
+ DEEP_TRACE(_T(".. parsing buttons/accel."));
+ changed |= ParseButtons(buff);
+ if(!IsBalanceBoard())
+ changed |= ParseAccel(buff);
+ break;
+
+ case IN_BUTTONS_ACCEL_EXT:
+ DEEP_TRACE(_T(".. parsing extenion/accel."));
+ changed |= ParseButtons(buff);
+ changed |= ParseExtension(buff, 6);
+ if(!IsBalanceBoard())
+ changed |= ParseAccel(buff);
+ break;
+
+ case IN_BUTTONS_ACCEL_IR:
+ DEEP_TRACE(_T(".. parsing ir/accel."));
+ changed |= ParseButtons(buff);
+ if(!IsBalanceBoard()) {
+ changed |= ParseAccel(buff);
+ changed |= ParseIR(buff);
+ }
+ break;
+
+ case IN_BUTTONS_ACCEL_IR_EXT:
+ DEEP_TRACE(_T(".. parsing ir/extenion/accel."));
+ changed |= ParseButtons(buff);
+ changed |= ParseExtension(buff, 16);
+ if(!IsBalanceBoard()) {
+ changed |= ParseAccel(buff);
+ changed |= ParseIR (buff);
+ }
+ break;
+
+ case IN_BUTTONS_BALANCE_BOARD:
+ DEEP_TRACE(_T(".. parsing buttson/balance."));
+ changed |= ParseButtons(buff);
+ changed |= ParseExtension(buff, 3);
+ break;
+
+ case IN_READADDRESS:
+ DEEP_TRACE(_T(".. parsing read address."));
+ changed |= ParseButtons (buff);
+ changed |= ParseReadAddress(buff);
+ break;
+
+ case IN_STATUS:
+ DEEP_TRACE(_T(".. parsing status."));
+ changed |= ParseStatus(buff);
+ // show that we received the status report (used for output method
+ // detection during Connect())
+ bStatusReceived = true;
+ break;
+
+ default:
+ DEEP_TRACE(_T(".. ** unknown input ** (happens)."));
+ ///_ASSERT(0);
+ //Debug.WriteLine("Unknown report type: " + type.ToString());
+ LeaveCriticalSection(&StateLock);
+ return false;
}
- break;
-
- case IN_BUTTONS_BALANCE_BOARD:
- DEEP_TRACE(_T(".. parsing buttson/balance."));
- changed |= ParseButtons(buff);
- changed |= ParseExtension(buff, 3);
- break;
-
- case IN_READADDRESS:
- DEEP_TRACE(_T(".. parsing read address."));
- changed |= ParseButtons(buff);
- changed |= ParseReadAddress(buff);
- break;
-
- case IN_STATUS:
- DEEP_TRACE(_T(".. parsing status."));
- changed |= ParseStatus(buff);
- // show that we received the status report (used for output method
- // detection during Connect())
- bStatusReceived = true;
- break;
-
- default:
- DEEP_TRACE(_T(".. ** unknown input ** (happens)."));
- ///_ASSERT(0);
- //Debug.WriteLine("Unknown report type: " + type.ToString());
- LeaveCriticalSection(&StateLock);
- return false;
- }
// if we're recording and some state we care about has changed, insert it into
// the state history
- if (Recording.bEnabled && (changed & Recording.TriggerFlags))
- {
+ if(Recording.bEnabled && (changed & Recording.TriggerFlags))
+ {
DEEP_TRACE(_T(".. adding state to history"));
state_event event;
event.time_ms = timeGetTime();
- event.state = *(wiimote_state*)this;
+ event.state = *(wiimote_state*)this;
Recording.StateHistory->push_back(event);
- }
+ }
// for polling: show which state has changed since the last RefreshState()
InternalChanged = (state_change_flags)(InternalChanged | changed);
@@ -991,53 +1001,53 @@ int wiimote::ParseInput(BYTE* buff)
LeaveCriticalSection(&StateLock);
// callbacks: call it (if set & state the app is interested in has changed)
- if (changed & CallbackTriggerFlags)
- {
+ if(changed & CallbackTriggerFlags)
+ {
DEEP_TRACE(_T(".. calling state change callback"));
ChangedNotifier((state_change_flags)changed, Internal);
- if (ChangedCallback)
+ if(ChangedCallback)
ChangedCallback(*this, (state_change_flags)changed, Internal);
- }
-
+ }
+
DEEP_TRACE(_T(".. parse complete."));
return true;
-}
+ }
// ------------------------------------------------------------------------------------
-state_change_flags wiimote::RefreshState()
-{
+state_change_flags wiimote::RefreshState ()
+ {
// nothing changed since the last call?
- if (InternalChanged == NO_CHANGE)
+ if(InternalChanged == NO_CHANGE)
return NO_CHANGE;
// copy the internal state to our public data members:
// synchronise the interal state with the read/parse thread (we don't want
// values changing during the copy)
EnterCriticalSection(&StateLock);
-
+
// remember which state changed since the last call
state_change_flags changed = InternalChanged;
-
+
// preserve the application-set deadzones (if any)
- joystick::deadzone nunchuk_deadzone = Nunchuk.Joystick.DeadZone;
+ joystick::deadzone nunchuk_deadzone = Nunchuk.Joystick.DeadZone;
joystick::deadzone classic_joyl_deadzone = ClassicController.JoystickL.DeadZone;
joystick::deadzone classic_joyr_deadzone = ClassicController.JoystickR.DeadZone;
-
- // copy the internal state to the public one
+
+ // copy the internal state to the public one
*(wiimote_state*)this = Internal;
- InternalChanged = NO_CHANGE;
-
- // restore the application-set deadzones
- Nunchuk.Joystick.DeadZone = nunchuk_deadzone;
+ InternalChanged = NO_CHANGE;
+
+ // restore the application-set deadzones
+ Nunchuk.Joystick.DeadZone = nunchuk_deadzone;
ClassicController.JoystickL.DeadZone = classic_joyl_deadzone;
ClassicController.JoystickR.DeadZone = classic_joyr_deadzone;
LeaveCriticalSection(&StateLock);
-
+
return changed;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::DetectMotionPlusExtensionAsync()
-{
+void wiimote::DetectMotionPlusExtensionAsync ()
+ {
#ifdef _DEBUG
TRACE(_T("(looking for motion plus)"));
#endif
@@ -1047,35 +1057,35 @@ void wiimote::DetectMotionPlusExtensionAsync()
// activated, when it maps itself into the usual extension registers), so
// try to detect it first:
ReadAddress(REGISTER_MOTIONPLUS_DETECT, 6);
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::EnableMotionPlus()
-{
+bool wiimote::EnableMotionPlus ()
+ {
_ASSERT(bMotionPlusDetected);
- if (!bMotionPlusDetected)
+ if(!bMotionPlusDetected)
return false;
- if (bMotionPlusEnabled)
+ if(bMotionPlusEnabled)
return true;
TRACE(_T("Enabling Motion Plus:"));
-
+
bMotionPlusExtension = false;
- bInitInProgress = true;
- bEnablingMotionPlus = true;
+ bInitInProgress = true;
+ bEnablingMotionPlus = true;
// Initialize it:
- WriteData(REGISTER_MOTIONPLUS_INIT, 0x55);
- // Sleep(50);
- // Enable it (this maps it to the standard extension port):
+ WriteData(REGISTER_MOTIONPLUS_INIT , 0x55);
+// Sleep(50);
+ // Enable it (this maps it to the standard extension port):
WriteData(REGISTER_MOTIONPLUS_ENABLE, 0x04);
- // Sleep(50);
- Sleep(500);
+// Sleep(50);
+Sleep(500);
return true;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::DisableMotionPlus()
-{
- if (!bMotionPlusDetected || !bMotionPlusEnabled)
+bool wiimote::DisableMotionPlus ()
+ {
+ if(!bMotionPlusDetected || !bMotionPlusEnabled)
return false;
TRACE(_T("Disabling Motion Plus:"));
@@ -1083,53 +1093,53 @@ bool wiimote::DisableMotionPlus()
// disable it (this makes standard extensions visible again)
WriteData(REGISTER_EXTENSION_INIT1, 0x55);
return true;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::InitializeExtension()
-{
+void wiimote::InitializeExtension ()
+ {
TRACE(_T("Initialising Extension."));
// wibrew.org: The new way to initialize the extension is by writing 0x55 to
// 0x(4)A400F0, then writing 0x00 to 0x(4)A400FB. It works on all extensions, and
// makes the extension type bytes unencrypted. This means that you no longer have
// to decrypt the extension bytes using the transform listed above.
bInitInProgress = true;
- _ASSERT(Internal.bExtension);
+_ASSERT(Internal.bExtension);
// only initialize if it's not a MotionPlus
- if (!bEnablingMotionPlus) {
- WriteData(REGISTER_EXTENSION_INIT1, 0x55);
- WriteData(REGISTER_EXTENSION_INIT2, 0x00);
- }
+ if(!bEnablingMotionPlus) {
+ WriteData (REGISTER_EXTENSION_INIT1, 0x55);
+ WriteData (REGISTER_EXTENSION_INIT2, 0x00);
+ }
else
bEnablingMotionPlus = false;
-
- ReadAddress(REGISTER_EXTENSION_TYPE, 6);
-}
+
+ ReadAddress(REGISTER_EXTENSION_TYPE , 6);
+ }
// ------------------------------------------------------------------------------------
-int wiimote::ParseStatus(BYTE* buff)
-{
+int wiimote::ParseStatus (BYTE* buff)
+ {
// parse the buttons
int changed = ParseButtons(buff);
-
+
// get the battery level
BYTE battery_raw = buff[6];
- if (Internal.BatteryRaw != battery_raw)
+ if(Internal.BatteryRaw != battery_raw)
changed |= BATTERY_CHANGED;
- Internal.BatteryRaw = battery_raw;
+ Internal.BatteryRaw = battery_raw;
// it is estimated that ~200 is the maximum battery level
Internal.BatteryPercent = battery_raw / 2;
// there is also a flag that shows if the battery is nearly empty
bool drained = buff[3] & 0x01;
- if (drained != bBatteryDrained)
- {
+ if(drained != bBatteryDrained)
+ {
bBatteryDrained = drained;
- if (drained)
+ if(drained)
changed |= BATTERY_DRAINED;
- }
+ }
// leds
BYTE leds = buff[3] >> 4;
- if (leds != Internal.LED.Bits)
+ if(leds != Internal.LED.Bits)
changed |= LEDS_CHANGED;
Internal.LED.Bits = leds;
@@ -1138,50 +1148,50 @@ int wiimote::ParseStatus(BYTE* buff)
// return changed;
bool extension = ((buff[3] & 0x02) != 0);
- // TRACE(_T("(extension = %s)"), (extension? _T("TRUE") : _T("false")));
+// TRACE(_T("(extension = %s)"), (extension? _T("TRUE") : _T("false")));
- if (extension != Internal.bExtension)
- {
- if (!Internal.bExtension)
+ if(extension != Internal.bExtension)
{
+ if(!Internal.bExtension)
+ {
TRACE(_T("Extension connected:"));
Internal.bExtension = true;
InitializeExtension();
- }
- else {
+ }
+ else{
TRACE(_T("Extension disconnected."));
- Internal.bExtension = false;
+ Internal.bExtension = false;
Internal.ExtensionType = wiimote_state::NONE;
- bMotionPlusEnabled = false;
- bMotionPlusExtension = false;
- bMotionPlusDetected = false;
- bInitInProgress = false;
- bEnablingMotionPlus = false;
- changed |= EXTENSION_DISCONNECTED;
+ bMotionPlusEnabled = false;
+ bMotionPlusExtension = false;
+ bMotionPlusDetected = false;
+ bInitInProgress = false;
+ bEnablingMotionPlus = false;
+ changed |= EXTENSION_DISCONNECTED;
// renable reports
// SetReportType(ReportType);
+ }
}
- }
-
+
return changed;
-}
+ }
// ------------------------------------------------------------------------------------
-int wiimote::ParseButtons(BYTE* buff)
-{
+int wiimote::ParseButtons (BYTE* buff)
+ {
int changed = 0;
+
+// WORD bits = *(WORD*)(buff+1);
+ WORD bits = *(WORD*)(buff+1) & Button.ALL;
- // WORD bits = *(WORD*)(buff+1);
- WORD bits = *(WORD*)(buff + 1) & Button.ALL;
-
- if (bits != Internal.Button.Bits)
+ if(bits != Internal.Button.Bits)
changed |= BUTTONS_CHANGED;
Internal.Button.Bits = bits;
-
+
return changed;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::EstimateOrientationFrom(wiimote_state::acceleration &accel)
-{
+bool wiimote::EstimateOrientationFrom (wiimote_state::acceleration &accel)
+ {
// Orientation estimate from acceleration data (shared between wiimote and nunchuk)
// return true if the orientation was updated
@@ -1191,17 +1201,17 @@ bool wiimote::EstimateOrientationFrom(wiimote_state::acceleration &accel)
// TODO: as I'm comparing _squared_ length, I really need different
// min/max epsilons...
-#define DOT(x1,y1,z1, x2,y2,z2) ((x1*x2) + (y1*y2) + (z1*z2))
+ #define DOT(x1,y1,z1, x2,y2,z2) ((x1*x2) + (y1*y2) + (z1*z2))
static const float epsilon = 0.2f;
- if ((length_sq >= (1.f - epsilon)) && (length_sq <= (1.f + epsilon)))
- {
- if (++WiimoteNearGUpdates < 2)
+ if((length_sq >= (1.f-epsilon)) && (length_sq <= (1.f+epsilon)))
+ {
+ if(++WiimoteNearGUpdates < 2)
return false;
-
+
// wiimote seems to be stationary: normalize the current acceleration
// (ie. the assumed gravity vector)
- float inv_len = 1.f / std::sqrt(length_sq);
+ float inv_len = 1.f / sqrt(length_sq);
float x = accel.X * inv_len;
float y = accel.Y * inv_len;
float z = accel.Z * inv_len;
@@ -1213,16 +1223,16 @@ bool wiimote::EstimateOrientationFrom(wiimote_state::acceleration &accel)
// and extract pitch & roll from them:
// (may not be optimal)
- float pitch = -std::asin(y) * 57.2957795f;
- // float roll = asin(x) * 57.2957795f;
- float roll = std::atan2(x, z) * 57.2957795f;
- if (z < 0) {
- pitch = (y < 0) ? 180 - pitch : -180 - pitch;
- roll = (x < 0) ? -180 - roll : 180 - roll;
- }
+ float pitch = -asin(y) * 57.2957795f;
+// float roll = asin(x) * 57.2957795f;
+ float roll = atan2(x,z) * 57.2957795f;
+ if(z < 0) {
+ pitch = (y < 0)? 180 - pitch : -180 - pitch;
+ roll = (x < 0)? -180 - roll : 180 - roll;
+ }
accel.Orientation.Pitch = pitch;
- accel.Orientation.Roll = roll;
+ accel.Orientation.Roll = roll;
// show that we just updated orientation
accel.Orientation.UpdateAge = 0;
@@ -1230,89 +1240,89 @@ bool wiimote::EstimateOrientationFrom(wiimote_state::acceleration &accel)
Beep(2000, 1);
#endif
return true; // updated
- }
+ }
// not updated this time:
- WiimoteNearGUpdates = 0;
+ WiimoteNearGUpdates = 0;
// age the last orientation update
accel.Orientation.UpdateAge++;
return false;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::ApplyJoystickDeadZones(wiimote_state::joystick &joy)
-{
- // apply the deadzones to each axis (if set)
- if ((joy.DeadZone.X > 0.f) && (joy.DeadZone.X <= 1.f))
+void wiimote::ApplyJoystickDeadZones (wiimote_state::joystick &joy)
{
- if (fabs(joy.X) <= joy.DeadZone.X)
+ // apply the deadzones to each axis (if set)
+ if((joy.DeadZone.X > 0.f) && (joy.DeadZone.X <= 1.f))
+ {
+ if(fabs(joy.X) <= joy.DeadZone.X)
joy.X = 0;
- else {
+ else{
joy.X -= joy.DeadZone.X * sign(joy.X);
joy.X /= 1.f - joy.DeadZone.X;
+ }
}
- }
- if ((joy.DeadZone.Y > 0.f) && (joy.DeadZone.Y <= 1.f))
- {
- if (fabs(joy.Y) <= joy.DeadZone.Y)
+ if((joy.DeadZone.Y > 0.f) && (joy.DeadZone.Y <= 1.f))
+ {
+ if(fabs(joy.Y) <= joy.DeadZone.Y)
joy.Y = 0;
- else {
+ else{
joy.Y -= joy.DeadZone.Y * sign(joy.Y);
joy.Y /= 1.f - joy.DeadZone.Y;
+ }
}
}
-}
// ------------------------------------------------------------------------------------
-int wiimote::ParseAccel(BYTE* buff)
-{
+int wiimote::ParseAccel (BYTE* buff)
+ {
int changed = 0;
-
+
BYTE raw_x = buff[3];
BYTE raw_y = buff[4];
BYTE raw_z = buff[5];
- if ((raw_x != Internal.Acceleration.RawX) ||
- (raw_y != Internal.Acceleration.RawY) ||
- (raw_z != Internal.Acceleration.RawZ))
- changed |= ACCEL_CHANGED;
-
+ if((raw_x != Internal.Acceleration.RawX) ||
+ (raw_y != Internal.Acceleration.RawY) ||
+ (raw_z != Internal.Acceleration.RawZ))
+ changed |= ACCEL_CHANGED;
+
Internal.Acceleration.RawX = raw_x;
Internal.Acceleration.RawY = raw_y;
Internal.Acceleration.RawZ = raw_z;
// avoid / 0.0 when calibration data hasn't arrived yet
- if (Internal.CalibrationInfo.X0)
- {
+ if(Internal.CalibrationInfo.X0)
+ {
Internal.Acceleration.X =
- ((float)Internal.Acceleration.RawX - Internal.CalibrationInfo.X0) /
- ((float)Internal.CalibrationInfo.XG - Internal.CalibrationInfo.X0);
+ ((float)Internal.Acceleration.RawX - Internal.CalibrationInfo.X0) /
+ ((float)Internal.CalibrationInfo.XG - Internal.CalibrationInfo.X0);
Internal.Acceleration.Y =
- ((float)Internal.Acceleration.RawY - Internal.CalibrationInfo.Y0) /
- ((float)Internal.CalibrationInfo.YG - Internal.CalibrationInfo.Y0);
+ ((float)Internal.Acceleration.RawY - Internal.CalibrationInfo.Y0) /
+ ((float)Internal.CalibrationInfo.YG - Internal.CalibrationInfo.Y0);
Internal.Acceleration.Z =
- ((float)Internal.Acceleration.RawZ - Internal.CalibrationInfo.Z0) /
- ((float)Internal.CalibrationInfo.ZG - Internal.CalibrationInfo.Z0);
- }
- else {
+ ((float)Internal.Acceleration.RawZ - Internal.CalibrationInfo.Z0) /
+ ((float)Internal.CalibrationInfo.ZG - Internal.CalibrationInfo.Z0);
+ }
+ else{
Internal.Acceleration.X =
- Internal.Acceleration.Y =
- Internal.Acceleration.Z = 0.f;
- }
+ Internal.Acceleration.Y =
+ Internal.Acceleration.Z = 0.f;
+ }
// see if we can estimate the orientation from the current values
- if (EstimateOrientationFrom(Internal.Acceleration))
+ if(EstimateOrientationFrom(Internal.Acceleration))
changed |= ORIENTATION_CHANGED;
-
+
return changed;
-}
+ }
// ------------------------------------------------------------------------------------
-int wiimote::ParseIR(BYTE* buff)
-{
- if (Internal.IR.Mode == wiimote_state::ir::OFF)
+int wiimote::ParseIR (BYTE* buff)
+ {
+ if(Internal.IR.Mode == wiimote_state::ir::OFF)
return NO_CHANGE;
// avoid garbage values when the MotionPlus is enabled, but the app is
// still using the extended IR report type
- if (bMotionPlusEnabled && (Internal.IR.Mode == wiimote_state::ir::EXTENDED))
+ if(bMotionPlusEnabled && (Internal.IR.Mode == wiimote_state::ir::EXTENDED))
return NO_CHANGE;
// take a copy of the existing IR state (so we can detect changes)
@@ -1320,100 +1330,100 @@ int wiimote::ParseIR(BYTE* buff)
// only updates the other values if the dots are visible (so that the last
// valid values stay unmodified)
- switch (Internal.IR.Mode)
- {
- case wiimote_state::ir::BASIC:
- // 2 dots are encoded in 5 bytes, so read 2 at a time
- for (unsigned step = 0; step < 2; step++)
+ switch(Internal.IR.Mode)
{
- ir::dot &dot0 = Internal.IR.Dot[step * 2];
- ir::dot &dot1 = Internal.IR.Dot[step * 2 + 1];
- const unsigned offs = 6 + (step * 5); // 5 bytes for 2 dots
-
- dot0.bVisible = !(buff[offs] == 0xff && buff[offs + 1] == 0xff);
- dot1.bVisible = !(buff[offs + 3] == 0xff && buff[offs + 4] == 0xff);
-
- if (dot0.bVisible) {
- dot0.RawX = buff[offs] | ((buff[offs + 2] >> 4) & 0x03) << 8;;
- dot0.RawY = buff[offs + 1] | ((buff[offs + 2] >> 6) & 0x03) << 8;;
- dot0.X = 1.f - (dot0.RawX / (float)wiimote_state::ir::MAX_RAW_X);
- dot0.Y = (dot0.RawY / (float)wiimote_state::ir::MAX_RAW_Y);
- }
- if (dot1.bVisible) {
- dot1.RawX = buff[offs + 3] | ((buff[offs + 2] >> 0) & 0x03) << 8;
- dot1.RawY = buff[offs + 4] | ((buff[offs + 2] >> 2) & 0x03) << 8;
- dot1.X = 1.f - (dot1.RawX / (float)wiimote_state::ir::MAX_RAW_X);
- dot1.Y = (dot1.RawY / (float)wiimote_state::ir::MAX_RAW_Y);
- }
- }
- break;
+ case wiimote_state::ir::BASIC:
+ // 2 dots are encoded in 5 bytes, so read 2 at a time
+ for(unsigned step=0; step<2; step++)
+ {
+ ir::dot &dot0 = Internal.IR.Dot[step*2 ];
+ ir::dot &dot1 = Internal.IR.Dot[step*2+1];
+ const unsigned offs = 6 + (step*5); // 5 bytes for 2 dots
+
+ dot0.bVisible = !(buff[offs ] == 0xff && buff[offs+1] == 0xff);
+ dot1.bVisible = !(buff[offs+3] == 0xff && buff[offs+4] == 0xff);
+
+ if(dot0.bVisible) {
+ dot0.RawX = buff[offs ] | ((buff[offs+2] >> 4) & 0x03) << 8;;
+ dot0.RawY = buff[offs+1] | ((buff[offs+2] >> 6) & 0x03) << 8;;
+ dot0.X = 1.f - (dot0.RawX / (float)wiimote_state::ir::MAX_RAW_X);
+ dot0.Y = (dot0.RawY / (float)wiimote_state::ir::MAX_RAW_Y);
+ }
+ if(dot1.bVisible) {
+ dot1.RawX = buff[offs+3] | ((buff[offs+2] >> 0) & 0x03) << 8;
+ dot1.RawY = buff[offs+4] | ((buff[offs+2] >> 2) & 0x03) << 8;
+ dot1.X = 1.f - (dot1.RawX / (float)wiimote_state::ir::MAX_RAW_X);
+ dot1.Y = (dot1.RawY / (float)wiimote_state::ir::MAX_RAW_Y);
+ }
+ }
+ break;
+
+ case wiimote_state::ir::EXTENDED:
+ // each dot is encoded into 3 bytes
+ for(unsigned index=0; index<4; index++)
+ {
+ ir::dot &dot = Internal.IR.Dot[index];
+ const unsigned offs = 6 + (index * 3);
+
+ dot.bVisible = !(buff[offs ]==0xff && buff[offs+1]==0xff &&
+ buff[offs+2]==0xff);
+ if(dot.bVisible) {
+ dot.RawX = buff[offs ] | ((buff[offs+2] >> 4) & 0x03) << 8;
+ dot.RawY = buff[offs+1] | ((buff[offs+2] >> 6) & 0x03) << 8;
+ dot.X = 1.f - (dot.RawX / (float)wiimote_state::ir::MAX_RAW_X);
+ dot.Y = (dot.RawY / (float)wiimote_state::ir::MAX_RAW_Y);
+ dot.Size = buff[offs+2] & 0x0f;
+ }
+ }
+ break;
- case wiimote_state::ir::EXTENDED:
- // each dot is encoded into 3 bytes
- for (unsigned index = 0; index < 4; index++)
- {
- ir::dot &dot = Internal.IR.Dot[index];
- const unsigned offs = 6 + (index * 3);
-
- dot.bVisible = !(buff[offs] == 0xff && buff[offs + 1] == 0xff &&
- buff[offs + 2] == 0xff);
- if (dot.bVisible) {
- dot.RawX = buff[offs] | ((buff[offs + 2] >> 4) & 0x03) << 8;
- dot.RawY = buff[offs + 1] | ((buff[offs + 2] >> 6) & 0x03) << 8;
- dot.X = 1.f - (dot.RawX / (float)wiimote_state::ir::MAX_RAW_X);
- dot.Y = (dot.RawY / (float)wiimote_state::ir::MAX_RAW_Y);
- dot.Size = buff[offs + 2] & 0x0f;
- }
+ case wiimote_state::ir::FULL:
+ _ASSERT(0); // not supported yet;
+ break;
}
- break;
- case wiimote_state::ir::FULL:
- _ASSERT(0); // not supported yet;
- break;
+ return memcmp(&prev_ir, &Internal.IR, sizeof(Internal.IR))? IR_CHANGED : 0;
}
-
- return memcmp(&prev_ir, &Internal.IR, sizeof(Internal.IR)) ? IR_CHANGED : 0;
-}
// ------------------------------------------------------------------------------------
-inline float wiimote::GetBalanceValue(short sensor, short min, short mid, short max)
-{
- if (max == mid || mid == min)
+inline float wiimote::GetBalanceValue (short sensor, short min, short mid, short max)
+ {
+ if(max == mid || mid == min)
return 0;
- float val = (sensor < mid) ?
- 68.0f * ((float)(sensor - min) / (mid - min)) :
- 68.0f * ((float)(sensor - mid) / (max - mid)) + 68.0f;
-
+ float val = (sensor < mid)?
+ 68.0f * ((float)(sensor - min) / (mid - min)) :
+ 68.0f * ((float)(sensor - mid) / (max - mid)) + 68.0f;
+
// divide by four (so that each sensor is correct)
return val * 0.25f;
-}
+ }
// ------------------------------------------------------------------------------------
-int wiimote::ParseExtension(BYTE *buff, unsigned offset)
-{
- int changed = 0;
-
- switch (Internal.ExtensionType)
+int wiimote::ParseExtension (BYTE *buff, unsigned offset)
{
- case wiimote_state::NUNCHUK:
- {
- // buttons
- bool c = (buff[offset + 5] & 0x02) == 0;
- bool z = (buff[offset + 5] & 0x01) == 0;
-
- if ((c != Internal.Nunchuk.C) || (z != Internal.Nunchuk.Z))
- changed |= NUNCHUK_BUTTONS_CHANGED;
-
- Internal.Nunchuk.C = c;
- Internal.Nunchuk.Z = z;
-
- // acceleration
+ int changed = 0;
+
+ switch(Internal.ExtensionType)
{
+ case wiimote_state::NUNCHUK:
+ {
+ // buttons
+ bool c = (buff[offset+5] & 0x02) == 0;
+ bool z = (buff[offset+5] & 0x01) == 0;
+
+ if((c != Internal.Nunchuk.C) || (z != Internal.Nunchuk.Z))
+ changed |= NUNCHUK_BUTTONS_CHANGED;
+
+ Internal.Nunchuk.C = c;
+ Internal.Nunchuk.Z = z;
+
+ // acceleration
+ {
wiimote_state::acceleration &accel = Internal.Nunchuk.Acceleration;
-
- BYTE raw_x = buff[offset + 2];
- BYTE raw_y = buff[offset + 3];
- BYTE raw_z = buff[offset + 4];
- if ((raw_x != accel.RawX) || (raw_y != accel.RawY) || (raw_z != accel.RawZ))
+
+ BYTE raw_x = buff[offset+2];
+ BYTE raw_y = buff[offset+3];
+ BYTE raw_z = buff[offset+4];
+ if((raw_x != accel.RawX) || (raw_y != accel.RawY) || (raw_z != accel.RawZ))
changed |= NUNCHUK_ACCEL_CHANGED;
accel.RawX = raw_x;
@@ -1421,23 +1431,23 @@ int wiimote::ParseExtension(BYTE *buff, unsigned offset)
accel.RawZ = raw_z;
wiimote_state::nunchuk::calibration_info &calib =
- Internal.Nunchuk.CalibrationInfo;
+ Internal.Nunchuk.CalibrationInfo;
accel.X = ((float)raw_x - calib.X0) / ((float)calib.XG - calib.X0);
accel.Y = ((float)raw_y - calib.Y0) / ((float)calib.YG - calib.Y0);
accel.Z = ((float)raw_z - calib.Z0) / ((float)calib.ZG - calib.Z0);
// try to extract orientation from the accel:
- if (EstimateOrientationFrom(accel))
+ if(EstimateOrientationFrom(accel))
changed |= NUNCHUK_ORIENTATION_CHANGED;
- }
- {
+ }
+ {
// joystick:
wiimote_state::joystick &joy = Internal.Nunchuk.Joystick;
- float raw_x = buff[offset + 0];
- float raw_y = buff[offset + 1];
-
- if (std::fabs(raw_x - joy.RawX) < 1e-6f || std::fabs(raw_y - joy.RawY) < 1e-6f)
+ float raw_x = buff[offset+0];
+ float raw_y = buff[offset+1];
+
+ if((raw_x != joy.RawX) || (raw_y != joy.RawY))
changed |= NUNCHUK_JOYSTICK_CHANGED;
joy.RawX = raw_x;
@@ -1445,10 +1455,10 @@ int wiimote::ParseExtension(BYTE *buff, unsigned offset)
// apply the calibration data
wiimote_state::nunchuk::calibration_info &calib =
- Internal.Nunchuk.CalibrationInfo;
- if (Internal.Nunchuk.CalibrationInfo.MaxX != 0x00)
+ Internal.Nunchuk.CalibrationInfo;
+ if(Internal.Nunchuk.CalibrationInfo.MaxX != 0x00)
joy.X = ((float)raw_x - calib.MidX) / ((float)calib.MaxX - calib.MinX);
- if (calib.MaxY != 0x00)
+ if(calib.MaxY != 0x00)
joy.Y = ((float)raw_y - calib.MidY) / ((float)calib.MaxY - calib.MinY);
// i prefer the outputs to range -1 - +1 (note this also affects the
@@ -1458,255 +1468,255 @@ int wiimote::ParseExtension(BYTE *buff, unsigned offset)
// apply the public deadzones to the internal state (if set)
joy.DeadZone = Nunchuk.Joystick.DeadZone;
ApplyJoystickDeadZones(joy);
- }
- }
- break;
+ }
+ }
+ break;
+
+ case wiimote_state::CLASSIC:
+ case wiimote_state::GH3_GHWT_GUITAR:
+ case wiimote_state::GHWT_DRUMS:
+ {
+ // buttons:
+ WORD bits = *(WORD*)(buff+offset+4);
+ bits = ~bits; // need to invert bits since 0 is down, and 1 is up
+
+ if(bits != Internal.ClassicController.Button.Bits)
+ changed |= CLASSIC_BUTTONS_CHANGED;
+
+ Internal.ClassicController.Button.Bits = bits;
+
+ // joysticks:
+ wiimote_state::joystick &joyL = Internal.ClassicController.JoystickL;
+ wiimote_state::joystick &joyR = Internal.ClassicController.JoystickR;
+
+ float l_raw_x = (float) (buff[offset+0] & 0x3f);
+ float l_raw_y = (float) (buff[offset+1] & 0x3f);
+ float r_raw_x = (float)((buff[offset+2] >> 7) |
+ ((buff[offset+1] & 0xc0) >> 5) |
+ ((buff[offset+0] & 0xc0) >> 3));
+ float r_raw_y = (float) (buff[offset+2] & 0x1f);
+
+ if((joyL.RawX != l_raw_x) || (joyL.RawY != l_raw_y))
+ changed |= CLASSIC_JOYSTICK_L_CHANGED;
+ if((joyR.RawX != r_raw_x) || (joyR.RawY != r_raw_y))
+ changed |= CLASSIC_JOYSTICK_R_CHANGED;
+
+ joyL.RawX = l_raw_x; joyL.RawY = l_raw_y;
+ joyR.RawX = r_raw_x; joyR.RawY = r_raw_y;
+
+ // apply calibration
+ wiimote_state::classic_controller::calibration_info &calib =
+ Internal.ClassicController.CalibrationInfo;
+ if(calib.MaxXL != 0x00)
+ joyL.X = (joyL.RawX - calib.MidXL) / ((float)calib.MaxXL - calib.MinXL);
+ if(calib.MaxYL != 0x00)
+ joyL.Y = (joyL.RawY - calib.MidYL) / ((float)calib.MaxYL - calib.MinYL);
+ if(calib.MaxXR != 0x00)
+ joyR.X = (joyR.RawX - calib.MidXR) / ((float)calib.MaxXR - calib.MinXR);
+ if(calib.MaxYR != 0x00)
+ joyR.Y = (joyR.RawY - calib.MidYR) / ((float)calib.MaxYR - calib.MinYR);
+
+ // i prefer the joystick outputs to range -1 - +1 (note this also affects
+ // the deadzone calculations)
+ joyL.X *= 2; joyL.Y *= 2; joyR.X *= 2; joyR.Y *= 2;
- case wiimote_state::CLASSIC:
- case wiimote_state::GH3_GHWT_GUITAR:
- case wiimote_state::GHWT_DRUMS:
- {
- // buttons:
- WORD bits = *(WORD*)(buff + offset + 4);
- bits = ~bits; // need to invert bits since 0 is down, and 1 is up
-
- if (bits != Internal.ClassicController.Button.Bits)
- changed |= CLASSIC_BUTTONS_CHANGED;
-
- Internal.ClassicController.Button.Bits = bits;
-
- // joysticks:
- wiimote_state::joystick &joyL = Internal.ClassicController.JoystickL;
- wiimote_state::joystick &joyR = Internal.ClassicController.JoystickR;
-
- float l_raw_x = (float)(buff[offset + 0] & 0x3f);
- float l_raw_y = (float)(buff[offset + 1] & 0x3f);
- float r_raw_x = (float)((buff[offset + 2] >> 7) |
- ((buff[offset + 1] & 0xc0) >> 5) |
- ((buff[offset + 0] & 0xc0) >> 3));
- float r_raw_y = (float)(buff[offset + 2] & 0x1f);
-
- if ((joyL.RawX != l_raw_x) || (joyL.RawY != l_raw_y))
- changed |= CLASSIC_JOYSTICK_L_CHANGED;
- if ((joyR.RawX != r_raw_x) || (joyR.RawY != r_raw_y))
- changed |= CLASSIC_JOYSTICK_R_CHANGED;
-
- joyL.RawX = l_raw_x; joyL.RawY = l_raw_y;
- joyR.RawX = r_raw_x; joyR.RawY = r_raw_y;
-
- // apply calibration
- wiimote_state::classic_controller::calibration_info &calib =
- Internal.ClassicController.CalibrationInfo;
- if (calib.MaxXL != 0x00)
- joyL.X = (joyL.RawX - calib.MidXL) / ((float)calib.MaxXL - calib.MinXL);
- if (calib.MaxYL != 0x00)
- joyL.Y = (joyL.RawY - calib.MidYL) / ((float)calib.MaxYL - calib.MinYL);
- if (calib.MaxXR != 0x00)
- joyR.X = (joyR.RawX - calib.MidXR) / ((float)calib.MaxXR - calib.MinXR);
- if (calib.MaxYR != 0x00)
- joyR.Y = (joyR.RawY - calib.MidYR) / ((float)calib.MaxYR - calib.MinYR);
-
- // i prefer the joystick outputs to range -1 - +1 (note this also affects
- // the deadzone calculations)
- joyL.X *= 2; joyL.Y *= 2; joyR.X *= 2; joyR.Y *= 2;
-
- // apply the public deadzones to the internal state (if set)
- joyL.DeadZone = ClassicController.JoystickL.DeadZone;
- joyR.DeadZone = ClassicController.JoystickR.DeadZone;
- ApplyJoystickDeadZones(joyL);
- ApplyJoystickDeadZones(joyR);
-
- // triggers
- BYTE raw_trigger_l = ((buff[offset + 2] & 0x60) >> 2) |
- (buff[offset + 3] >> 5);
- BYTE raw_trigger_r = buff[offset + 3] & 0x1f;
-
- if ((raw_trigger_l != Internal.ClassicController.RawTriggerL) ||
- (raw_trigger_r != Internal.ClassicController.RawTriggerR))
- changed |= CLASSIC_TRIGGERS_CHANGED;
-
- Internal.ClassicController.RawTriggerL = raw_trigger_l;
- Internal.ClassicController.RawTriggerR = raw_trigger_r;
-
- if (calib.MaxTriggerL != 0x00)
- Internal.ClassicController.TriggerL =
- (float)Internal.ClassicController.RawTriggerL /
- ((float)calib.MaxTriggerL - calib.MinTriggerL);
- if (calib.MaxTriggerR != 0x00)
- Internal.ClassicController.TriggerR =
- (float)Internal.ClassicController.RawTriggerR /
- ((float)calib.MaxTriggerR - calib.MinTriggerR);
- }
- break;
+ // apply the public deadzones to the internal state (if set)
+ joyL.DeadZone = ClassicController.JoystickL.DeadZone;
+ joyR.DeadZone = ClassicController.JoystickR.DeadZone;
+ ApplyJoystickDeadZones(joyL);
+ ApplyJoystickDeadZones(joyR);
+
+ // triggers
+ BYTE raw_trigger_l = ((buff[offset+2] & 0x60) >> 2) |
+ (buff[offset+3] >> 5);
+ BYTE raw_trigger_r = buff[offset+3] & 0x1f;
+
+ if((raw_trigger_l != Internal.ClassicController.RawTriggerL) ||
+ (raw_trigger_r != Internal.ClassicController.RawTriggerR))
+ changed |= CLASSIC_TRIGGERS_CHANGED;
+
+ Internal.ClassicController.RawTriggerL = raw_trigger_l;
+ Internal.ClassicController.RawTriggerR = raw_trigger_r;
+
+ if(calib.MaxTriggerL != 0x00)
+ Internal.ClassicController.TriggerL =
+ (float)Internal.ClassicController.RawTriggerL /
+ ((float)calib.MaxTriggerL - calib.MinTriggerL);
+ if(calib.MaxTriggerR != 0x00)
+ Internal.ClassicController.TriggerR =
+ (float)Internal.ClassicController.RawTriggerR /
+ ((float)calib.MaxTriggerR - calib.MinTriggerR);
+ }
+ break;
- case BALANCE_BOARD:
- {
- wiimote_state::balance_board::sensors_raw prev_raw =
- Internal.BalanceBoard.Raw;
- Internal.BalanceBoard.Raw.TopR =
- (short)((short)buff[offset + 0] << 8 | buff[offset + 1]);
- Internal.BalanceBoard.Raw.BottomR =
- (short)((short)buff[offset + 2] << 8 | buff[offset + 3]);
- Internal.BalanceBoard.Raw.TopL =
- (short)((short)buff[offset + 4] << 8 | buff[offset + 5]);
- Internal.BalanceBoard.Raw.BottomL =
- (short)((short)buff[offset + 6] << 8 | buff[offset + 7]);
-
- if ((Internal.BalanceBoard.Raw.TopL != prev_raw.TopL) ||
- (Internal.BalanceBoard.Raw.TopR != prev_raw.TopR) ||
- (Internal.BalanceBoard.Raw.BottomL != prev_raw.BottomL) ||
- (Internal.BalanceBoard.Raw.BottomR != prev_raw.BottomR))
- changed |= BALANCE_WEIGHT_CHANGED;
-
- Internal.BalanceBoard.Kg.TopL =
- GetBalanceValue(Internal.BalanceBoard.Raw.TopL,
- Internal.BalanceBoard.CalibrationInfo.Kg0.TopL,
- Internal.BalanceBoard.CalibrationInfo.Kg17.TopL,
- Internal.BalanceBoard.CalibrationInfo.Kg34.TopL);
- Internal.BalanceBoard.Kg.TopR =
- GetBalanceValue(Internal.BalanceBoard.Raw.TopR,
- Internal.BalanceBoard.CalibrationInfo.Kg0.TopR,
- Internal.BalanceBoard.CalibrationInfo.Kg17.TopR,
- Internal.BalanceBoard.CalibrationInfo.Kg34.TopR);
- Internal.BalanceBoard.Kg.BottomL =
- GetBalanceValue(Internal.BalanceBoard.Raw.BottomL,
- Internal.BalanceBoard.CalibrationInfo.Kg0.BottomL,
- Internal.BalanceBoard.CalibrationInfo.Kg17.BottomL,
- Internal.BalanceBoard.CalibrationInfo.Kg34.BottomL);
- Internal.BalanceBoard.Kg.BottomR =
- GetBalanceValue(Internal.BalanceBoard.Raw.BottomR,
- Internal.BalanceBoard.CalibrationInfo.Kg0.BottomR,
- Internal.BalanceBoard.CalibrationInfo.Kg17.BottomR,
- Internal.BalanceBoard.CalibrationInfo.Kg34.BottomR);
-
- // uses these as the 'at rest' offsets? (immediately after Connect(),
- // or if the app called CalibrateAtRest())
- if (bCalibrateAtRest) {
- bCalibrateAtRest = false;
- TRACE(_T(".. Auto-removing 'at rest' BBoard offsets."));
- Internal.BalanceBoard.AtRestKg = Internal.BalanceBoard.Kg;
- }
+ case BALANCE_BOARD:
+ {
+ wiimote_state::balance_board::sensors_raw prev_raw =
+ Internal.BalanceBoard.Raw;
+ Internal.BalanceBoard.Raw.TopR =
+ (short)((short)buff[offset+0] << 8 | buff[offset+1]);
+ Internal.BalanceBoard.Raw.BottomR =
+ (short)((short)buff[offset+2] << 8 | buff[offset+3]);
+ Internal.BalanceBoard.Raw.TopL =
+ (short)((short)buff[offset+4] << 8 | buff[offset+5]);
+ Internal.BalanceBoard.Raw.BottomL =
+ (short)((short)buff[offset+6] << 8 | buff[offset+7]);
+
+ if((Internal.BalanceBoard.Raw.TopL != prev_raw.TopL) ||
+ (Internal.BalanceBoard.Raw.TopR != prev_raw.TopR) ||
+ (Internal.BalanceBoard.Raw.BottomL != prev_raw.BottomL) ||
+ (Internal.BalanceBoard.Raw.BottomR != prev_raw.BottomR))
+ changed |= BALANCE_WEIGHT_CHANGED;
+
+ Internal.BalanceBoard.Kg.TopL =
+ GetBalanceValue(Internal.BalanceBoard.Raw.TopL,
+ Internal.BalanceBoard.CalibrationInfo.Kg0 .TopL,
+ Internal.BalanceBoard.CalibrationInfo.Kg17.TopL,
+ Internal.BalanceBoard.CalibrationInfo.Kg34.TopL);
+ Internal.BalanceBoard.Kg.TopR =
+ GetBalanceValue(Internal.BalanceBoard.Raw.TopR,
+ Internal.BalanceBoard.CalibrationInfo.Kg0 .TopR,
+ Internal.BalanceBoard.CalibrationInfo.Kg17.TopR,
+ Internal.BalanceBoard.CalibrationInfo.Kg34.TopR);
+ Internal.BalanceBoard.Kg.BottomL =
+ GetBalanceValue(Internal.BalanceBoard.Raw.BottomL,
+ Internal.BalanceBoard.CalibrationInfo.Kg0 .BottomL,
+ Internal.BalanceBoard.CalibrationInfo.Kg17.BottomL,
+ Internal.BalanceBoard.CalibrationInfo.Kg34.BottomL);
+ Internal.BalanceBoard.Kg.BottomR =
+ GetBalanceValue(Internal.BalanceBoard.Raw.BottomR,
+ Internal.BalanceBoard.CalibrationInfo.Kg0 .BottomR,
+ Internal.BalanceBoard.CalibrationInfo.Kg17.BottomR,
+ Internal.BalanceBoard.CalibrationInfo.Kg34.BottomR);
+
+ // uses these as the 'at rest' offsets? (immediately after Connect(),
+ // or if the app called CalibrateAtRest())
+ if(bCalibrateAtRest) {
+ bCalibrateAtRest = false;
+ TRACE(_T(".. Auto-removing 'at rest' BBoard offsets."));
+ Internal.BalanceBoard.AtRestKg = Internal.BalanceBoard.Kg;
+ }
- // remove the 'at rest' offsets
- Internal.BalanceBoard.Kg.TopL -= BalanceBoard.AtRestKg.TopL;
- Internal.BalanceBoard.Kg.TopR -= BalanceBoard.AtRestKg.TopR;
- Internal.BalanceBoard.Kg.BottomL -= BalanceBoard.AtRestKg.BottomL;
- Internal.BalanceBoard.Kg.BottomR -= BalanceBoard.AtRestKg.BottomR;
-
- // compute the average
- Internal.BalanceBoard.Kg.Total = Internal.BalanceBoard.Kg.TopL +
- Internal.BalanceBoard.Kg.TopR +
- Internal.BalanceBoard.Kg.BottomL +
- Internal.BalanceBoard.Kg.BottomR;
- // and convert to Lbs
- const float KG2LB = 2.20462262f;
- Internal.BalanceBoard.Lb = Internal.BalanceBoard.Kg;
- Internal.BalanceBoard.Lb.TopL *= KG2LB;
- Internal.BalanceBoard.Lb.TopR *= KG2LB;
- Internal.BalanceBoard.Lb.BottomL *= KG2LB;
- Internal.BalanceBoard.Lb.BottomR *= KG2LB;
- Internal.BalanceBoard.Lb.Total *= KG2LB;
- }
- break;
+ // remove the 'at rest' offsets
+ Internal.BalanceBoard.Kg.TopL -= BalanceBoard.AtRestKg.TopL;
+ Internal.BalanceBoard.Kg.TopR -= BalanceBoard.AtRestKg.TopR;
+ Internal.BalanceBoard.Kg.BottomL -= BalanceBoard.AtRestKg.BottomL;
+ Internal.BalanceBoard.Kg.BottomR -= BalanceBoard.AtRestKg.BottomR;
+
+ // compute the average
+ Internal.BalanceBoard.Kg.Total = Internal.BalanceBoard.Kg.TopL +
+ Internal.BalanceBoard.Kg.TopR +
+ Internal.BalanceBoard.Kg.BottomL +
+ Internal.BalanceBoard.Kg.BottomR;
+ // and convert to Lbs
+ const float KG2LB = 2.20462262f;
+ Internal.BalanceBoard.Lb = Internal.BalanceBoard.Kg;
+ Internal.BalanceBoard.Lb.TopL *= KG2LB;
+ Internal.BalanceBoard.Lb.TopR *= KG2LB;
+ Internal.BalanceBoard.Lb.BottomL *= KG2LB;
+ Internal.BalanceBoard.Lb.BottomR *= KG2LB;
+ Internal.BalanceBoard.Lb.Total *= KG2LB;
+ }
+ break;
- case MOTION_PLUS:
- {
- bMotionPlusDetected = true;
- bMotionPlusEnabled = true;
-
- short yaw = ((unsigned short)buff[offset + 3] & 0xFC) << 6 |
- (unsigned short)buff[offset + 0];
- short pitch = ((unsigned short)buff[offset + 5] & 0xFC) << 6 |
- (unsigned short)buff[offset + 2];
- short roll = ((unsigned short)buff[offset + 4] & 0xFC) << 6 |
- (unsigned short)buff[offset + 1];
-
- // we get one set of bogus values when the MotionPlus is disconnected,
- // so ignore them
- if ((yaw != 0x3fff) || (pitch != 0x3fff) || (roll != 0x3fff))
- {
- wiimote_state::motion_plus::sensors_raw &raw = Internal.MotionPlus.Raw;
-
- if ((raw.Yaw != yaw) || (raw.Pitch != pitch) || (raw.Roll != roll))
- changed |= MOTIONPLUS_SPEED_CHANGED;
-
- raw.Yaw = yaw;
- raw.Pitch = pitch;
- raw.Roll = roll;
-
- // convert to float values
- bool yaw_slow = (buff[offset + 3] & 0x2) == 0x2;
- bool pitch_slow = (buff[offset + 3] & 0x1) == 0x1;
- bool roll_slow = (buff[offset + 4] & 0x2) == 0x2;
- float y_scale = yaw_slow ? 0.05f : 0.25f;
- float p_scale = pitch_slow ? 0.05f : 0.25f;
- float r_scale = roll_slow ? 0.05f : 0.25f;
-
- Internal.MotionPlus.Speed.Yaw = -(raw.Yaw - 0x1F7F) * y_scale;
- Internal.MotionPlus.Speed.Pitch = -(raw.Pitch - 0x1F7F) * p_scale;
- Internal.MotionPlus.Speed.Roll = -(raw.Roll - 0x1F7F) * r_scale;
-
- // show if there's an extension plugged into the MotionPlus:
- bool extension = buff[offset + 4] & 1;
- if (extension != bMotionPlusExtension)
+ case MOTION_PLUS:
{
- if (extension) {
- TRACE(_T(".. MotionPlus extension found."));
- changed |= MOTIONPLUS_EXTENSION_CONNECTED;
- }
- else {
- TRACE(_T(".. MotionPlus' extension disconnected."));
- changed |= MOTIONPLUS_EXTENSION_DISCONNECTED;
+ bMotionPlusDetected = true;
+ bMotionPlusEnabled = true;
+
+ short yaw = ((unsigned short)buff[offset+3] & 0xFC)<<6 |
+ (unsigned short)buff[offset+0];
+ short pitch = ((unsigned short)buff[offset+5] & 0xFC)<<6 |
+ (unsigned short)buff[offset+2];
+ short roll = ((unsigned short)buff[offset+4] & 0xFC)<<6 |
+ (unsigned short)buff[offset+1];
+
+ // we get one set of bogus values when the MotionPlus is disconnected,
+ // so ignore them
+ if((yaw != 0x3fff) || (pitch != 0x3fff) || (roll != 0x3fff))
+ {
+ wiimote_state::motion_plus::sensors_raw &raw = Internal.MotionPlus.Raw;
+
+ if((raw.Yaw != yaw) || (raw.Pitch != pitch) || (raw.Roll != roll))
+ changed |= MOTIONPLUS_SPEED_CHANGED;
+
+ raw.Yaw = yaw;
+ raw.Pitch = pitch;
+ raw.Roll = roll;
+
+ // convert to float values
+ bool yaw_slow = (buff[offset+3] & 0x2) == 0x2;
+ bool pitch_slow = (buff[offset+3] & 0x1) == 0x1;
+ bool roll_slow = (buff[offset+4] & 0x2) == 0x2;
+ float y_scale = yaw_slow? 0.05f : 0.25f;
+ float p_scale = pitch_slow? 0.05f : 0.25f;
+ float r_scale = roll_slow? 0.05f : 0.25f;
+
+ Internal.MotionPlus.Speed.Yaw = -(raw.Yaw - 0x1F7F) * y_scale;
+ Internal.MotionPlus.Speed.Pitch = -(raw.Pitch - 0x1F7F) * p_scale;
+ Internal.MotionPlus.Speed.Roll = -(raw.Roll - 0x1F7F) * r_scale;
+
+ // show if there's an extension plugged into the MotionPlus:
+ bool extension = buff[offset+4] & 1;
+ if(extension != bMotionPlusExtension)
+ {
+ if(extension) {
+ TRACE(_T(".. MotionPlus extension found."));
+ changed |= MOTIONPLUS_EXTENSION_CONNECTED;
+ }
+ else{
+ TRACE(_T(".. MotionPlus' extension disconnected."));
+ changed |= MOTIONPLUS_EXTENSION_DISCONNECTED;
+ }
+ }
+ bMotionPlusExtension = extension;
}
+ // while we're getting data, the plus is obviously detected/enabled
+// bMotionPlusDetected = bMotionPlusEnabled = true;
}
- bMotionPlusExtension = extension;
+ break;
}
- // while we're getting data, the plus is obviously detected/enabled
-// bMotionPlusDetected = bMotionPlusEnabled = true;
- }
- break;
- }
-
+
return changed;
-}
+ }
// ------------------------------------------------------------------------------------
-int wiimote::ParseReadAddress(BYTE* buff)
-{
+int wiimote::ParseReadAddress (BYTE* buff)
+ {
// decode the address that was queried:
- int address = buff[4] << 8 | buff[5];
- int size = buff[3] >> 4;
- (void)size;
- int changed = 0;
+ int address = buff[4]<<8 | buff[5];
+ int size = buff[3] >> 4;
+ (void)size;
+ int changed = 0;
- if ((buff[3] & 0x08) != 0) {
+ if((buff[3] & 0x08) != 0) {
WARN(_T("error: read address not valid."));
_ASSERT(0);
return NO_CHANGE;
- }
+ }
// address read failed (write-only)?
- else if ((buff[3] & 0x07) != 0)
- {
- // this also happens when attempting to detect a non-existant MotionPlus
- if (MotionPlusDetectCount)
+ else if((buff[3] & 0x07) != 0)
{
- --MotionPlusDetectCount;
- if (Internal.ExtensionType == MOTION_PLUS)
+ // this also happens when attempting to detect a non-existant MotionPlus
+ if(MotionPlusDetectCount)
{
- if (bMotionPlusDetected)
+ --MotionPlusDetectCount;
+ if(Internal.ExtensionType == MOTION_PLUS)
+ {
+ if(bMotionPlusDetected)
TRACE(_T(".. MotionPlus removed."));
- bMotionPlusDetected = false;
- bMotionPlusEnabled = false;
+ bMotionPlusDetected = false;
+ bMotionPlusEnabled = false;
// the MotionPlus can sometimes get confused - initializing
// extenions fixes it:
// if(address == 0xfa)
// InitializeExtension();
+ }
}
- }
else
WARN(_T("error: attempt to read from write-only register 0x%X."), buff[3]);
return NO_CHANGE;
- }
+ }
// *NOTE*: this is a major (but convenient) hack! The returned data only
// contains the lower two bytes of the address that was queried.
@@ -1716,264 +1726,258 @@ int wiimote::ParseReadAddress(BYTE* buff)
// skip the header
buff += 6;
- switch (address)
- {
- case (REGISTER_CALIBRATION & 0xffff):
- {
- _ASSERT(size == 6);
- TRACE(_T(".. got wiimote calibration."));
- Internal.CalibrationInfo.X0 = buff[0];
- Internal.CalibrationInfo.Y0 = buff[1];
- Internal.CalibrationInfo.Z0 = buff[2];
- Internal.CalibrationInfo.XG = buff[4];
- Internal.CalibrationInfo.YG = buff[5];
- Internal.CalibrationInfo.ZG = buff[6];
- //changed |= CALIBRATION_CHANGED;
- }
- break;
-
- // note: this covers both the normal extension and motion plus extension
- // addresses (0x4a400fa / 0x4a600fa)
- case (REGISTER_EXTENSION_TYPE & 0xffff):
- {
- _ASSERT(size == 5);
- QWORD type = *(QWORD*)buff;
-
- // TRACE(_T("(found extension 0x%I64x)"), type);
-
- static const QWORD NUNCHUK = 0x000020A40000ULL;
- static const QWORD CLASSIC = 0x010120A40000ULL;
- static const QWORD GH3_GHWT_GUITAR = 0x030120A40000ULL;
- static const QWORD GHWT_DRUMS = 0x030120A40001ULL;
- static const QWORD BALANCE_BOARD = 0x020420A40000ULL;
- static const QWORD MOTION_PLUS = 0x050420A40000ULL;
- static const QWORD MOTION_PLUS_DETECT = 0x050020a60000ULL;
- static const QWORD MOTION_PLUS_DETECT2 = 0x050420a60000ULL;
- static const QWORD PARTIALLY_INSERTED = 0xffffffffffffULL;
-
- // MotionPlus: _before_ it's been activated
- if ((type == MOTION_PLUS_DETECT) || (type == MOTION_PLUS_DETECT2))
+ switch(address)
{
- if (!bMotionPlusDetected) {
- TRACE(_T("Motion Plus detected!"));
- changed |= MOTIONPLUS_DETECTED;
+ case (REGISTER_CALIBRATION & 0xffff):
+ {
+ _ASSERT(size == 6);
+ TRACE(_T(".. got wiimote calibration."));
+ Internal.CalibrationInfo.X0 = buff[0];
+ Internal.CalibrationInfo.Y0 = buff[1];
+ Internal.CalibrationInfo.Z0 = buff[2];
+ Internal.CalibrationInfo.XG = buff[4];
+ Internal.CalibrationInfo.YG = buff[5];
+ Internal.CalibrationInfo.ZG = buff[6];
+ //changed |= CALIBRATION_CHANGED;
}
- bMotionPlusDetected = true;
- --MotionPlusDetectCount;
break;
- }
+
+ // note: this covers both the normal extension and motion plus extension
+ // addresses (0x4a400fa / 0x4a600fa)
+ case (REGISTER_EXTENSION_TYPE & 0xffff):
+ {
+ _ASSERT(size == 5);
+ QWORD type = *(QWORD*)buff;
+
+// TRACE(_T("(found extension 0x%I64x)"), type);
+
+ static const QWORD NUNCHUK = 0x000020A40000ULL;
+ static const QWORD CLASSIC = 0x010120A40000ULL;
+ static const QWORD GH3_GHWT_GUITAR = 0x030120A40000ULL;
+ static const QWORD GHWT_DRUMS = 0x030120A40001ULL;
+ static const QWORD BALANCE_BOARD = 0x020420A40000ULL;
+ static const QWORD MOTION_PLUS = 0x050420A40000ULL;
+ static const QWORD MOTION_PLUS_DETECT = 0x050020a60000ULL;
+ static const QWORD MOTION_PLUS_DETECT2 = 0x050420a60000ULL;
+ static const QWORD PARTIALLY_INSERTED = 0xffffffffffffULL;
+
+ // MotionPlus: _before_ it's been activated
+ if((type == MOTION_PLUS_DETECT) || (type == MOTION_PLUS_DETECT2))
+ {
+ if(!bMotionPlusDetected) {
+ TRACE(_T("Motion Plus detected!"));
+ changed |= MOTIONPLUS_DETECTED;
+ }
+ bMotionPlusDetected = true;
+ --MotionPlusDetectCount;
+ break;
+ }
- // sometimes we get idempotent ExtensionType events
-#define IF_TYPE(id, ...) \
- if(type == id) \
- { \
- if(Internal.ExtensionType == wiimote_state::id) \
- break; \
- Internal.ExtensionType = wiimote_state::id; \
- { __VA_ARGS__ } \
- }
+ #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;
// MotionPlus: once it's activated & mapped to the standard ext. port
- 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,
- TRACE(_T(".. Nunchuk!"));
- bMotionPlusEnabled = false;
- // and start a query for the calibration data
- ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16);
- )
- 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,
- // 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,
- TRACE(_T(".. GHWT Drums!"));
- bMotionPlusEnabled = false;
- // and start a query for the calibration data
- ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16);
- )
- 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)
- Sleep(50);
- TRACE(_T(".. partially inserted!"));
- bMotionPlusEnabled = false;
- Internal.ExtensionType = wiimote_state::PARTIALLY_INSERTED;
- changed |= EXTENSION_PARTIALLY_INSERTED;
- // try initializing the extension again by requesting another
- // status report (this usually fixes it)
- Internal.bExtension = false;
- RequestStatusReport();
- }
- else {
+ 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)
+ TRACE(_T(".. Nunchuk!"));
+ bMotionPlusEnabled = false;
+ // and start a query for the calibration data
+ ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16);
+ }
+ 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)
+ // 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)
+ TRACE(_T(".. GHWT Drums!"));
+ bMotionPlusEnabled = false;
+ // and start a query for the calibration data
+ ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16);
+ }
+ 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)
+ Sleep(50);
+ TRACE(_T(".. partially inserted!"));
+ bMotionPlusEnabled = false;
+ Internal.ExtensionType = wiimote_state::PARTIALLY_INSERTED;
+ changed |= EXTENSION_PARTIALLY_INSERTED;
+ // try initializing the extension again by requesting another
+ // status report (this usually fixes it)
+ Internal.bExtension = false;
+ RequestStatusReport();
+ }
+ else{
TRACE(_T("unknown extension controller found (0x%I64x)"), type);
+ }
}
- }
- break;
-
- case (REGISTER_EXTENSION_CALIBRATION & 0xffff):
- case (REGISTER_BALANCE_CALIBRATION & 0xffff):
- {
- // _ASSERT(((Internal.ExtensionType == BALANCE_BOARD) && (size == 31)) ||
- // ((Internal.ExtensionType != BALANCE_BOARD) && (size == 15)));
+ break;
+
+ case (REGISTER_EXTENSION_CALIBRATION & 0xffff):
+ case (REGISTER_BALANCE_CALIBRATION & 0xffff):
+ {
+// _ASSERT(((Internal.ExtensionType == BALANCE_BOARD) && (size == 31)) ||
+// ((Internal.ExtensionType != BALANCE_BOARD) && (size == 15)));
- switch (Internal.ExtensionType)
- {
- case wiimote_state::NUNCHUK:
- {
- wiimote_state::nunchuk::calibration_info
- &calib = Internal.Nunchuk.CalibrationInfo;
-
- calib.X0 = buff[0];
- calib.Y0 = buff[1];
- calib.Z0 = buff[2];
- calib.XG = buff[4];
- calib.YG = buff[5];
- calib.ZG = buff[6];
- calib.MaxX = buff[8];
- calib.MinX = buff[9];
- calib.MidX = buff[10];
- calib.MaxY = buff[11];
- calib.MinY = buff[12];
- calib.MidY = buff[13];
-
- changed |= NUNCHUK_CONNECTED;//|NUNCHUK_CALIBRATION_CHANGED;
- // reenable reports
+ switch(Internal.ExtensionType)
+ {
+ case wiimote_state::NUNCHUK:
+ {
+ wiimote_state::nunchuk::calibration_info
+ &calib = Internal.Nunchuk.CalibrationInfo;
+
+ calib.X0 = buff[ 0];
+ calib.Y0 = buff[ 1];
+ calib.Z0 = buff[ 2];
+ calib.XG = buff[ 4];
+ calib.YG = buff[ 5];
+ calib.ZG = buff[ 6];
+ calib.MaxX = buff[ 8];
+ calib.MinX = buff[ 9];
+ calib.MidX = buff[10];
+ calib.MaxY = buff[11];
+ calib.MinY = buff[12];
+ calib.MidY = buff[13];
+
+ changed |= NUNCHUK_CONNECTED;//|NUNCHUK_CALIBRATION_CHANGED;
+ // reenable reports
// SetReportType(ReportType);
- }
- break;
-
- case wiimote_state::CLASSIC:
- case wiimote_state::GH3_GHWT_GUITAR:
- case wiimote_state::GHWT_DRUMS:
- {
- wiimote_state::classic_controller::calibration_info
- &calib = Internal.ClassicController.CalibrationInfo;
-
- calib.MaxXL = buff[0] >> 2;
- calib.MinXL = buff[1] >> 2;
- calib.MidXL = buff[2] >> 2;
- calib.MaxYL = buff[3] >> 2;
- calib.MinYL = buff[4] >> 2;
- calib.MidYL = buff[5] >> 2;
- calib.MaxXR = buff[6] >> 3;
- calib.MinXR = buff[7] >> 3;
- calib.MidXR = buff[8] >> 3;
- calib.MaxYR = buff[9] >> 3;
- calib.MinYR = buff[10] >> 3;
- calib.MidYR = buff[11] >> 3;
- // this doesn't seem right...
- // calib.MinTriggerL = buff[12] >> 3;
- // calib.MaxTriggerL = buff[14] >> 3;
- // calib.MinTriggerR = buff[13] >> 3;
- // calib.MaxTriggerR = buff[15] >> 3;
- calib.MinTriggerL = 0;
- calib.MaxTriggerL = 31;
- calib.MinTriggerR = 0;
- calib.MaxTriggerR = 31;
-
- changed |= CLASSIC_CONNECTED;//|CLASSIC_CALIBRATION_CHANGED;
- // reenable reports
+ }
+ break;
+
+ case wiimote_state::CLASSIC:
+ case wiimote_state::GH3_GHWT_GUITAR:
+ case wiimote_state::GHWT_DRUMS:
+ {
+ wiimote_state::classic_controller::calibration_info
+ &calib = Internal.ClassicController.CalibrationInfo;
+
+ calib.MaxXL = buff[ 0] >> 2;
+ calib.MinXL = buff[ 1] >> 2;
+ calib.MidXL = buff[ 2] >> 2;
+ calib.MaxYL = buff[ 3] >> 2;
+ calib.MinYL = buff[ 4] >> 2;
+ calib.MidYL = buff[ 5] >> 2;
+ calib.MaxXR = buff[ 6] >> 3;
+ calib.MinXR = buff[ 7] >> 3;
+ calib.MidXR = buff[ 8] >> 3;
+ calib.MaxYR = buff[ 9] >> 3;
+ calib.MinYR = buff[10] >> 3;
+ calib.MidYR = buff[11] >> 3;
+ // this doesn't seem right...
+ // calib.MinTriggerL = buff[12] >> 3;
+ // calib.MaxTriggerL = buff[14] >> 3;
+ // calib.MinTriggerR = buff[13] >> 3;
+ // calib.MaxTriggerR = buff[15] >> 3;
+ calib.MinTriggerL = 0;
+ calib.MaxTriggerL = 31;
+ calib.MinTriggerR = 0;
+ calib.MaxTriggerR = 31;
+
+ changed |= CLASSIC_CONNECTED;//|CLASSIC_CALIBRATION_CHANGED;
+ // reenable reports
// SetReportType(ReportType);
- }
- break;
+ }
+ break;
- case BALANCE_BOARD:
- {
- // first part, 0 & 17kg calibration values
- wiimote_state::balance_board::calibration_info
- &calib = Internal.BalanceBoard.CalibrationInfo;
+ case BALANCE_BOARD:
+ {
+ // first part, 0 & 17kg calibration values
+ wiimote_state::balance_board::calibration_info
+ &calib = Internal.BalanceBoard.CalibrationInfo;
- calib.Kg0.TopR = (short)((short)buff[0] << 8 | buff[1]);
- calib.Kg0.BottomR = (short)((short)buff[2] << 8 | buff[3]);
- calib.Kg0.TopL = (short)((short)buff[4] << 8 | buff[5]);
- calib.Kg0.BottomL = (short)((short)buff[6] << 8 | buff[7]);
+ calib.Kg0 .TopR = (short)((short)buff[0] << 8 | buff[1]);
+ calib.Kg0 .BottomR = (short)((short)buff[2] << 8 | buff[3]);
+ calib.Kg0 .TopL = (short)((short)buff[4] << 8 | buff[5]);
+ calib.Kg0 .BottomL = (short)((short)buff[6] << 8 | buff[7]);
- calib.Kg17.TopR = (short)((short)buff[8] << 8 | buff[9]);
- calib.Kg17.BottomR = (short)((short)buff[10] << 8 | buff[11]);
- calib.Kg17.TopL = (short)((short)buff[12] << 8 | buff[13]);
- calib.Kg17.BottomL = (short)((short)buff[14] << 8 | buff[15]);
+ calib.Kg17.TopR = (short)((short)buff[8] << 8 | buff[9]);
+ calib.Kg17.BottomR = (short)((short)buff[10] << 8 | buff[11]);
+ calib.Kg17.TopL = (short)((short)buff[12] << 8 | buff[13]);
+ calib.Kg17.BottomL = (short)((short)buff[14] << 8 | buff[15]);
- // 2nd part is scanned above
- }
- break;
+ // 2nd part is scanned above
+ }
+ break;
- case MOTION_PLUS:
- {
- // TODO: not known how the calibration values work
- changed |= MOTIONPLUS_ENABLED;
- bMotionPlusEnabled = true;
- bInitInProgress = false;
- // reenable reports
+ case MOTION_PLUS:
+ {
+ // TODO: not known how the calibration values work
+ changed |= MOTIONPLUS_ENABLED;
+ bMotionPlusEnabled = true;
+ bInitInProgress = false;
+ // reenable reports
// SetReportType(ReportType);
- }
- break;
- }
- break;
- // XXX missing break here? -sh
- case 0x34:
- {
- if (Internal.ExtensionType == BALANCE_BOARD)
- {
- wiimote_state::balance_board::calibration_info
- &calib = Internal.BalanceBoard.CalibrationInfo;
-
- // 2nd part of the balance board calibration,
- // 34kg calibration values
- calib.Kg34.TopR = (short)((short)buff[0] << 8 | buff[1]);
- calib.Kg34.BottomR = (short)((short)buff[2] << 8 | buff[3]);
- calib.Kg34.TopL = (short)((short)buff[4] << 8 | buff[5]);
- calib.Kg34.BottomL = (short)((short)buff[6] << 8 | buff[7]);
-
- changed |= BALANCE_CONNECTED;
- // reenable reports
- SetReportType(IN_BUTTONS_BALANCE_BOARD);
- }
- // else unknown what these are for
- }
- bInitInProgress = false;
- }
- break;
-
- default:
- // _ASSERT(0); // shouldn't happen
- break;
- }
+ }
+ break;
+ }
+ case 0x34:
+ {
+ if(Internal.ExtensionType == BALANCE_BOARD)
+ {
+ wiimote_state::balance_board::calibration_info
+ &calib = Internal.BalanceBoard.CalibrationInfo;
+
+ // 2nd part of the balance board calibration,
+ // 34kg calibration values
+ calib.Kg34.TopR = (short)((short)buff[0] << 8 | buff[1]);
+ calib.Kg34.BottomR = (short)((short)buff[2] << 8 | buff[3]);
+ calib.Kg34.TopL = (short)((short)buff[4] << 8 | buff[5]);
+ calib.Kg34.BottomL = (short)((short)buff[6] << 8 | buff[7]);
+
+ changed |= BALANCE_CONNECTED;
+ // reenable reports
+ SetReportType(IN_BUTTONS_BALANCE_BOARD);
+ }
+ // else unknown what these are for
+ }
+ bInitInProgress = false;
+ }
+ break;
+ default:
+// _ASSERT(0); // shouldn't happen
+ break;
+ }
+
return changed;
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::ReadCalibration()
-{
+void wiimote::ReadCalibration ()
+ {
TRACE(_T("Requestion wiimote calibration:"));
// this appears to change the report type to 0x31
ReadAddress(REGISTER_CALIBRATION, 7);
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::EnableIR(wiimote_state::ir::mode mode)
-{
+void wiimote::EnableIR (wiimote_state::ir::mode mode)
+ {
Internal.IR.Mode = mode;
- BYTE buff[REPORT_LENGTH] = { 0 };
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_IR;
buff[1] = 0x04 | GetRumbleBit();
WriteReport(buff);
@@ -1983,22 +1987,22 @@ void wiimote::EnableIR(wiimote_state::ir::mode mode)
buff[1] = 0x04 | GetRumbleBit();
WriteReport(buff);
- static const BYTE ir_sens1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00,
- 0xc0 };
- static const BYTE ir_sens2[] = { 0x40, 0x00 };
+ static const BYTE ir_sens1[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00,
+ 0xc0};
+ static const BYTE ir_sens2[] = {0x40, 0x00};
WriteData(REGISTER_IR, 0x08);
Sleep(25); // wait a little to make IR more reliable (for some)
WriteData(REGISTER_IR_SENSITIVITY_1, sizeof(ir_sens1), ir_sens1);
WriteData(REGISTER_IR_SENSITIVITY_2, sizeof(ir_sens2), ir_sens2);
WriteData(REGISTER_IR_MODE, (BYTE)mode);
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::DisableIR()
-{
+void wiimote::DisableIR ()
+ {
Internal.IR.Mode = wiimote_state::ir::OFF;
- BYTE buff[REPORT_LENGTH] = { 0 };
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_IR;
buff[1] = GetRumbleBit();
WriteReport(buff);
@@ -2007,91 +2011,91 @@ void wiimote::DisableIR()
buff[0] = OUT_IR2;
buff[1] = GetRumbleBit();
WriteReport(buff);
-}
+ }
// ------------------------------------------------------------------------------------
-unsigned __stdcall wiimote::HIDwriteThreadfunc(void* param)
-{
+unsigned __stdcall wiimote::HIDwriteThreadfunc (void* param)
+ {
_ASSERT(param);
TRACE(_T("(starting HID write thread)"));
wiimote &remote = *(wiimote*)param;
- while (remote.Handle != INVALID_HANDLE_VALUE)
- {
+ while(remote.Handle != INVALID_HANDLE_VALUE)
+ {
// try to write the oldest entry in the queue
#ifdef USE_DYNAMIC_HIDQUEUE
- if (!remote.HIDwriteQueue.empty())
+ if(!remote.HIDwriteQueue.empty())
#else
- if (!remote.HID.IsEmpty())
+ if(!remote.HID.IsEmpty())
#endif
- {
+ {
#ifdef BEEP_DEBUG_WRITES
- Beep(1500, 1);
+ Beep(1500,1);
#endif
EnterCriticalSection(&remote.HIDwriteQueueLock);
#ifdef USE_DYNAMIC_HIDQUEUE
- BYTE *buff = remote.HIDwriteQueue.front();
- _ASSERT(buff);
+ BYTE *buff = remote.HIDwriteQueue.front();
+ _ASSERT(buff);
#else
- BYTE *buff = remote.HID.Queue[remote.HID.ReadIndex].Report;
+ BYTE *buff = remote.HID.Queue[remote.HID.ReadIndex].Report;
#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)
- TRACE(_T("**** HID WRITE: BUSY ****"));
- else if (err == ERROR_NOT_READY)
- TRACE(_T("**** HID WRITE: NOT READY ****"));
+if(err==ERROR_BUSY)
+TRACE(_T("**** HID WRITE: BUSY ****"));
+else if(err == ERROR_NOT_READY)
+TRACE(_T("**** HID WRITE: NOT READY ****"));
- if ((err != ERROR_BUSY) && // "the requested resource is in use"
- (err != ERROR_NOT_READY)) // "the device is not ready"
- {
- if (err == ERROR_NOT_SUPPORTED) {
+ if((err != ERROR_BUSY) && // "the requested resource is in use"
+ (err != ERROR_NOT_READY)) // "the device is not ready"
+ {
+ if(err == ERROR_NOT_SUPPORTED) {
WARN(_T("BT Stack doesn't suport HID writes!"));
goto remove_entry;
- }
- else {
+ }
+ else{
DEEP_TRACE(_T("HID write failed (err %u)! - "), err);
// if this worked previously, the connection was probably lost
- if (remote.IsConnected())
+ if(remote.IsConnected())
remote.bConnectionLost = true;
- }
+ }
//_T("aborting write thread"), err);
//return 911;
+ }
}
- }
- else {
- remove_entry:
+ else{
+remove_entry:
EnterCriticalSection(&remote.HIDwriteQueueLock);
#ifdef USE_DYNAMIC_HIDQUEUE
- remote.HIDwriteQueue.pop();
- delete[] buff;
+ remote.HIDwriteQueue.pop();
+ delete[] buff;
#else
- remote.HID.ReadIndex++;
- remote.HID.ReadIndex &= (hid::MAX_QUEUE_ENTRIES - 1);
+ remote.HID.ReadIndex++;
+ remote.HID.ReadIndex &= (hid::MAX_QUEUE_ENTRIES-1);
#endif
LeaveCriticalSection(&remote.HIDwriteQueueLock);
+ }
}
- }
Sleep(1);
- }
+ }
TRACE(_T("ending HID write thread"));
return 0;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::WriteReport(BYTE *buff)
-{
+bool wiimote::WriteReport (BYTE *buff)
+ {
#ifdef BEEP_DEBUG_WRITES
- Beep(2000, 1);
+ Beep(2000,1);
#endif
#ifdef _DEBUG
-#define DEEP_TRACE_TYPE(type) case OUT_##type: DEEP_TRACE(_T("WriteReport: ")\
+ #define DEEP_TRACE_TYPE(type) case OUT_##type: DEEP_TRACE(_T("WriteReport: ")\
_T(#type)); break
- switch (buff[0])
- {
+ switch(buff[0])
+ {
DEEP_TRACE_TYPE(NONE);
DEEP_TRACE_TYPE(LEDs);
DEEP_TRACE_TYPE(TYPE);
@@ -2103,13 +2107,13 @@ bool wiimote::WriteReport(BYTE *buff)
DEEP_TRACE_TYPE(SPEAKER_DATA);
DEEP_TRACE_TYPE(SPEAKER_MUTE);
DEEP_TRACE_TYPE(IR2);
- default:
- TRACE(_T("WriteReport: type [%02x][%02x]"), buff[1], buff[2]);
- }
+ default:
+ TRACE(_T("WriteReport: type [%02x][%02x]"), buff[1], buff[2]);
+ }
#endif
- if (bUseHIDwrite)
- {
+ if(bUseHIDwrite)
+ {
/* no where to release handle, I have to do it myself */
if (HIDwriteThread)
{
@@ -2120,231 +2124,231 @@ bool wiimote::WriteReport(BYTE *buff)
}
// HidD_SetOutputReport: +: works on MS Bluetooth stacks (WriteFile doesn't).
// -: is synchronous, so make it async
- if (!HIDwriteThread)
- {
+ if(!HIDwriteThread)
+ {
HIDwriteThread = (HANDLE)_beginthreadex(NULL, 0, HIDwriteThreadfunc,
- this, 0, NULL);
+ this, 0, NULL);
_ASSERT(HIDwriteThread);
- if (!HIDwriteThread) {
+ if(!HIDwriteThread) {
WARN(_T("couldn't create HID write thread!"));
return false;
- }
+ }
SetThreadPriority(HIDwriteThread, WORKER_THREAD_PRIORITY);
- }
+ }
// insert the write request into the thread's queue
#ifdef USE_DYNAMIC_HIDQUEUE
EnterCriticalSection(&HIDwriteQueueLock);
- BYTE *buff_copy = new BYTE[REPORT_LENGTH];
+ BYTE *buff_copy = new BYTE[REPORT_LENGTH];
#else
// allocate the HID write queue once
- if (!HID.Queue && !HID.Allocate())
+ if(!HID.Queue && !HID.Allocate())
return false;
EnterCriticalSection(&HIDwriteQueueLock);
- BYTE *buff_copy = HID.Queue[HID.WriteIndex].Report;
+ BYTE *buff_copy = HID.Queue[HID.WriteIndex].Report;
#endif
- memcpy(buff_copy, buff, REPORT_LENGTH);
+ memcpy(buff_copy, buff, REPORT_LENGTH);
#ifdef USE_DYNAMIC_HIDQUEUE
- HIDwriteQueue.push(buff_copy);
+ HIDwriteQueue.push(buff_copy);
#else
- HID.WriteIndex++;
- HID.WriteIndex &= (HID.MAX_QUEUE_ENTRIES - 1);
-
- // check if the fixed report queue has overflown:
- // if this ASSERT triggers, the HID write queue (that stores reports
- // for asynchronous output by HIDwriteThreadfunc) has overflown.
- // this can happen if the connection with the wiimote has been lost
- // and in that case is harmless.
- //
- // if it happens during normal operation though you need to increase
- // hid::MAX_QUEUE_ENTRIES to the next power-of-2 (see comments)
- // _and_ email me the working setting so I can update the next release
- _ASSERT(HID.WriteIndex != HID.ReadIndex);
+ HID.WriteIndex++;
+ HID.WriteIndex &= (HID.MAX_QUEUE_ENTRIES-1);
+
+ // check if the fixed report queue has overflown:
+ // if this ASSERT triggers, the HID write queue (that stores reports
+ // for asynchronous output by HIDwriteThreadfunc) has overflown.
+ // this can happen if the connection with the wiimote has been lost
+ // and in that case is harmless.
+ //
+ // if it happens during normal operation though you need to increase
+ // hid::MAX_QUEUE_ENTRIES to the next power-of-2 (see comments)
+ // _and_ email me the working setting so I can update the next release
+ _ASSERT(HID.WriteIndex != HID.ReadIndex);
#endif
LeaveCriticalSection(&HIDwriteQueueLock);
return true;
- }
+ }
// WriteFile:
DWORD written;
- if (!WriteFile(Handle, buff, REPORT_LENGTH, &written, &Overlapped))
- {
+ if(!WriteFile(Handle, buff, REPORT_LENGTH, &written, &Overlapped))
+ {
DWORD error = GetLastError();
- if (error != ERROR_IO_PENDING) {
+ if(error != ERROR_IO_PENDING) {
TRACE(_T("WriteFile failed, err: %u!"), error);
// if it worked previously, assume we lost the connection
- if (IsConnected())
+ if(IsConnected())
bConnectionLost = true;
#ifndef USE_DYNAMIC_HIDQUEUE
HID.Deallocate();
#endif
return false;
+ }
}
- }
return true;
-}
+ }
// ------------------------------------------------------------------------------------
// experimental speaker support:
// ------------------------------------------------------------------------------------
-bool wiimote::MuteSpeaker(bool on)
-{
+bool wiimote::MuteSpeaker (bool on)
+ {
_ASSERT(IsConnected());
- if (!IsConnected())
+ if(!IsConnected())
return false;
- if (Internal.Speaker.bMuted == on)
+ if(Internal.Speaker.bMuted == on)
return true;
- if (on) TRACE(_T("muting speaker."));
+ if(on) TRACE(_T("muting speaker." ));
else TRACE(_T("unmuting speaker."));
- BYTE buff[REPORT_LENGTH] = { 0 };
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_SPEAKER_MUTE;
- buff[1] = (on ? 0x04 : 0x00) | GetRumbleBit();
- if (!WriteReport(buff))
+ buff[1] = (on? 0x04 : 0x00) | GetRumbleBit();
+ if(!WriteReport(buff))
return false;
Sleep(1);
Internal.Speaker.bMuted = on;
return true;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::EnableSpeaker(bool on)
-{
+bool wiimote::EnableSpeaker (bool on)
+ {
_ASSERT(IsConnected());
- if (!IsConnected())
+ if(!IsConnected())
return false;
- if (Internal.Speaker.bEnabled == on)
+ if(Internal.Speaker.bEnabled == on)
return true;
- if (on) TRACE(_T("enabling speaker.")); else TRACE(_T("disabling speaker."));
+ if(on) TRACE(_T("enabling speaker.")); else TRACE(_T("disabling speaker."));
- BYTE buff[REPORT_LENGTH] = { 0 };
+ BYTE buff [REPORT_LENGTH] = {0};
buff[0] = OUT_SPEAKER_ENABLE;
- buff[1] = (on ? 0x04 : 0x00) | GetRumbleBit();
- if (!WriteReport(buff))
+ buff[1] = (on? 0x04 : 0x00) | GetRumbleBit();
+ if(!WriteReport(buff))
return false;
- if (!on) {
- Internal.Speaker.Freq = FREQ_NONE;
+ if(!on) {
+ Internal.Speaker.Freq = FREQ_NONE;
Internal.Speaker.Volume = 0;
MuteSpeaker(true);
- }
+ }
Internal.Speaker.bEnabled = on;
return true;
-}
+ }
// ------------------------------------------------------------------------------------
#ifdef TR4 // TEMP, ignore
-extern int hzinc;
+ extern int hzinc;
#endif
// ------------------------------------------------------------------------------------
-unsigned __stdcall wiimote::SampleStreamThreadfunc(void* param)
-{
+unsigned __stdcall wiimote::SampleStreamThreadfunc (void* param)
+ {
TRACE(_T("(starting sample thread)"));
// sends a simple square wave sample stream
wiimote &remote = *(wiimote*)param;
-
+
static BYTE squarewave_report[REPORT_LENGTH] =
- { OUT_SPEAKER_DATA, 20 << 3, 0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
- 0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3, };
- static BYTE sample_report[REPORT_LENGTH] =
- { OUT_SPEAKER_DATA, 0 };
-
- bool last_playing = false;
- DWORD frame = 0;
- DWORD frame_start = 0;
- unsigned total_samples = 0;
- unsigned sample_index = 0;
+ { OUT_SPEAKER_DATA, 20<<3, 0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,
+ 0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3, };
+ static BYTE sample_report [REPORT_LENGTH] =
+ { OUT_SPEAKER_DATA, 0 };
+
+ bool last_playing = false;
+ DWORD frame = 0;
+ DWORD frame_start = 0;
+ unsigned total_samples = 0;
+ unsigned sample_index = 0;
wiimote_sample *current_sample = NULL;
-
+
// TODO: duration!!
- while (remote.IsConnected())
- {
+ while(remote.IsConnected())
+ {
bool playing = remote.IsPlayingAudio();
-
- if (!playing)
+
+ if(!playing)
Sleep(1);
- else {
- const unsigned freq_hz = FreqLookup[remote.Internal.Speaker.Freq];
+ else{
+ const unsigned freq_hz = FreqLookup[remote.Internal.Speaker.Freq];
#ifdef TR4
- const float frame_ms = 1000 / ((freq_hz + hzinc) / 40.f); // 20bytes = 40 samples per write
+ const float frame_ms = 1000 / ((freq_hz+hzinc) / 40.f); // 20bytes = 40 samples per write
#else
- const float frame_ms = 1000 / (freq_hz / 40.f); // 20bytes = 40 samples per write
+ const float frame_ms = 1000 / (freq_hz / 40.f); // 20bytes = 40 samples per write
#endif
// has the sample just changed?
bool sample_changed = (current_sample != remote.CurrentSample);
- current_sample = (wiimote_sample*)remote.CurrentSample;
+ current_sample = (wiimote_sample*)remote.CurrentSample;
- // (attempts to minimise glitches, doesn't seem to help though)
- //#define FIRSTFRAME_IS_SILENT // send all-zero for first frame
+// (attempts to minimise glitches, doesn't seem to help though)
+//#define FIRSTFRAME_IS_SILENT // send all-zero for first frame
#ifdef FIRSTFRAME_IS_SILENT
bool silent_frame = false;
#endif
- if (!last_playing || sample_changed) {
- frame = 0;
- frame_start = timeGetTime();
- total_samples = current_sample ? current_sample->length : 0;
- sample_index = 0;
+ if(!last_playing || sample_changed) {
+ frame = 0;
+ frame_start = timeGetTime();
+ total_samples = current_sample? current_sample->length : 0;
+ sample_index = 0;
#ifdef FIRSTFRAME_IS_SILENT
- silent_frame = true;
+ silent_frame = true;
#endif
- }
+ }
// are we streaming a sample?
- if (current_sample)
- {
- if (sample_index < current_sample->length)
+ if(current_sample)
{
+ if(sample_index < current_sample->length)
+ {
// (remember that samples are 4bit, ie. 2 per byte)
- unsigned samples_left = (current_sample->length - sample_index);
+ unsigned samples_left = (current_sample->length - sample_index);
unsigned report_samples = min(samples_left, (unsigned)40);
// round the entries up to the nearest multiple of 2
- unsigned report_entries = (report_samples + 1) >> 1;
-
- sample_report[1] = (BYTE)((report_entries << 3) |
- remote.GetRumbleBit());
+ unsigned report_entries = (report_samples+1) >> 1;
+
+ sample_report[1] = (BYTE)((report_entries<<3) |
+ remote.GetRumbleBit());
#ifdef FIRSTFRAME_IS_SILENT
- if (silent_frame) {
+ if(silent_frame) {
// send all-zeroes
- for (unsigned index = 0; index < report_entries; index++)
- sample_report[2 + index] = 0;
+ for(unsigned index=0; index<report_entries; index++)
+ sample_report[2+index] = 0;
remote.WriteReport(sample_report);
- }
+ }
else
#endif
{
- for (unsigned index = 0; index < report_entries; index++)
- sample_report[2 + index] =
- current_sample->samples[(sample_index >> 1) + index];
+ for(unsigned index=0; index<report_entries; index++)
+ sample_report[2+index] =
+ current_sample->samples[(sample_index>>1)+index];
remote.WriteReport(sample_report);
sample_index += report_samples;
+ }
}
- }
- else {
+ else{
// we reached the sample end
- remote.CurrentSample = NULL;
- current_sample = NULL;
- remote.Internal.Speaker.Freq = FREQ_NONE;
+ remote.CurrentSample = NULL;
+ current_sample = NULL;
+ remote.Internal.Speaker.Freq = FREQ_NONE;
remote.Internal.Speaker.Volume = 0;
+ }
}
- }
// no, a squarewave
- else {
- squarewave_report[1] = (20 << 3) | remote.GetRumbleBit();
+ else{
+ squarewave_report[1] = (20<<3) | remote.GetRumbleBit();
remote.WriteReport(squarewave_report);
#if 0
// verify that we're sending at the correct rate (we are)
- DWORD elapsed = (timeGetTime() - frame_start);
+ DWORD elapsed = (timeGetTime()-frame_start);
unsigned total_samples = frame * 40;
- float elapsed_secs = elapsed / 1000.f;
- float sent_persec = total_samples / elapsed_secs;
+ float elapsed_secs = elapsed / 1000.f;
+ float sent_persec = total_samples / elapsed_secs;
#endif
- }
+ }
frame++;
@@ -2352,60 +2356,64 @@ unsigned __stdcall wiimote::SampleStreamThreadfunc(void* param)
// startup glitches by assuming we're filling a small sample
// (or general input) buffer on the wiimote) - doesn't seem to help
// if(frame > 2) {
- while ((timeGetTime() - frame_start) < (unsigned)(frame*frame_ms))
- Sleep(1);
- // }
- }
+ while((timeGetTime()-frame_start) < (unsigned)(frame*frame_ms))
+ Sleep(1);
+// }
+ }
last_playing = playing;
- }
-
+ }
+
TRACE(_T("(ending sample thread)"));
return 0;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::Load16bitMonoSampleWAV(const TCHAR* filepath, wiimote_sample &out)
-{
- out = {};
+bool wiimote::Load16bitMonoSampleWAV (const TCHAR* filepath, wiimote_sample &out)
+ {
// converts unsigned 16bit mono .wav audio data to the 4bit ADPCM variant
// used by the Wiimote (at least the closest match so far), and returns
// the data in a BYTE array (caller must delete[] it when no longer needed):
+ memset(&out, 0, sizeof(out));
TRACE(_T("Loading '%s'"), filepath);
FILE *file;
+#if (_MSC_VER >= 1400) // VC 2005+
_tfopen_s(&file, filepath, _T("rb"));
+#else
+ file = _tfopen(filepath, _T("rb"));
+#endif
_ASSERT(file);
- if (!file) {
+ if(!file) {
WARN(_T("Couldn't open '%s"), filepath);
return false;
- }
+ }
// parse the .wav file
struct riff_chunkheader {
- char ckID[4];
+ char ckID [4];
DWORD ckSize;
- char formType[4];
- };
+ char formType [4];
+ };
struct chunk_header {
- char ckID[4];
+ char ckID [4];
DWORD ckSize;
- };
+ };
union {
WAVEFORMATEX x;
WAVEFORMATEXTENSIBLE xe;
- } wf = {};
+ } wf = {0};
riff_chunkheader riff_chunkheader;
chunk_header chunk_header;
speaker_freq freq = FREQ_NONE;
-#define READ(data) if(fread(&data, sizeof(data), 1, file) != 1) { \
+ #define READ(data) if(fread(&data, sizeof(data), 1, file) != 1) { \
TRACE(_T(".wav file corrupt")); \
fclose(file); \
return false; \
}
-#define READ_SIZE(ptr,size) if(fread(ptr, size, 1, file) != 1) { \
+ #define READ_SIZE(ptr,size) if(fread(ptr, size, 1, file) != 1) { \
TRACE(_T(".wav file corrupt")); \
fclose(file); \
return false; \
@@ -2415,107 +2423,107 @@ bool wiimote::Load16bitMonoSampleWAV(const TCHAR* filepath, wiimote_sample &out)
// valid RIFF file?
_ASSERT(!strncmp(riff_chunkheader.ckID, "RIFF", 4));
- if (strncmp(riff_chunkheader.ckID, "RIFF", 4))
+ if(strncmp(riff_chunkheader.ckID, "RIFF", 4))
goto unsupported; // nope
// valid WAV variant?
_ASSERT(!strncmp(riff_chunkheader.formType, "WAVE", 4));
- if (strncmp(riff_chunkheader.formType, "WAVE", 4))
+ if(strncmp(riff_chunkheader.formType, "WAVE", 4))
goto unsupported; // nope
// find the format & data chunks
- while (1)
- {
- READ(chunk_header);
-
- if (!strncmp(chunk_header.ckID, "fmt ", 4))
+ while(1)
{
+ READ(chunk_header);
+
+ if(!strncmp(chunk_header.ckID, "fmt ", 4))
+ {
// not a valid .wav file?
- if (chunk_header.ckSize < 16 ||
- chunk_header.ckSize > sizeof(WAVEFORMATEXTENSIBLE))
+ if(chunk_header.ckSize < 16 ||
+ chunk_header.ckSize > sizeof(WAVEFORMATEXTENSIBLE))
goto unsupported;
READ_SIZE((BYTE*)&wf.x, chunk_header.ckSize);
// now we know it's true wav file
bool extensible = (wf.x.wFormatTag == WAVE_FORMAT_EXTENSIBLE);
- int format = extensible ? wf.xe.SubFormat.Data1 :
- wf.x.wFormatTag;
+ int format = extensible? wf.xe.SubFormat.Data1 :
+ wf.x .wFormatTag;
// must be uncompressed PCM (the format comparisons also work on
// the 'extensible' header, even though they're named differently)
- if (format != WAVE_FORMAT_PCM) {
+ if(format != WAVE_FORMAT_PCM) {
TRACE(_T(".. not uncompressed PCM"));
goto unsupported;
- }
+ }
// must be mono, 16bit
- if ((wf.x.nChannels != 1) || (wf.x.wBitsPerSample != 16)) {
+ if((wf.x.nChannels != 1) || (wf.x.wBitsPerSample != 16)) {
TRACE(_T(".. %d bit, %d channel%s"), wf.x.wBitsPerSample,
- wf.x.nChannels,
- (wf.x.nChannels > 1 ? _T("s") : _T("")));
+ wf.x.nChannels,
+ (wf.x.nChannels>1? _T("s"):_T("")));
goto unsupported;
- }
+ }
// must be _near_ a supported speaker frequency range (but allow some
// tolerance, especially as the speaker freq values aren't final yet):
unsigned sample_freq = wf.x.nSamplesPerSec;
- const unsigned epsilon = 100; // for now
-
- for (unsigned index = 1; index < ARRAY_ENTRIES(FreqLookup); index++)
- {
- if ((sample_freq + epsilon) >= FreqLookup[index] &&
- (sample_freq - epsilon) <= FreqLookup[index]) {
+ const unsigned epsilon = 100; // for now
+
+ for(unsigned index=1; index<ARRAY_ENTRIES(FreqLookup); index++)
+ {
+ if((sample_freq+epsilon) >= FreqLookup[index] &&
+ (sample_freq-epsilon) <= FreqLookup[index]) {
freq = (speaker_freq)index;
TRACE(_T(".. using speaker freq %u"), FreqLookup[index]);
break;
+ }
}
- }
- if (freq == FREQ_NONE) {
+ if(freq == FREQ_NONE) {
WARN(_T("Couldn't (loosely) match .wav samplerate %u Hz to speaker"),
- sample_freq);
+ sample_freq);
goto unsupported;
+ }
}
- }
- else if (!strncmp(chunk_header.ckID, "data", 4))
- {
+ else if(!strncmp(chunk_header.ckID, "data", 4))
+ {
// make sure we got a valid fmt chunk first
- if (!wf.x.nBlockAlign)
+ if(!wf.x.nBlockAlign)
goto corrupt_file;
// grab the data
unsigned total_samples = chunk_header.ckSize / wf.x.nBlockAlign;
- if (total_samples == 0)
+ if(total_samples == 0)
goto corrupt_file;
-
+
short *samples = new short[total_samples];
size_t read = fread(samples, 2, total_samples, file);
fclose(file);
- if (read != total_samples)
- {
- if (read == 0) {
+ if(read != total_samples)
+ {
+ if(read == 0) {
delete[] samples;
goto corrupt_file;
- }
+ }
// got a different number, but use them anyway
WARN(_T("found %s .wav audio data than expected (%u/%u samples)"),
- ((read < total_samples) ? _T("less") : _T("more")),
+ ((read < total_samples)? _T("less") : _T("more")),
read, total_samples);
total_samples = read;
- }
+ }
// and convert them
bool res = Convert16bitMonoSamples(samples, true, total_samples, freq,
- out);
+ out);
delete[] samples;
return res;
- }
- else {
+ }
+ else{
// unknown chunk, skip its data
DWORD chunk_bytes = (chunk_header.ckSize + 1) & ~1L;
- if (fseek(file, chunk_bytes, SEEK_CUR))
+ if(fseek(file, chunk_bytes, SEEK_CUR))
goto corrupt_file;
+ }
}
- }
corrupt_file:
WARN(_T(".wav file is corrupt"));
@@ -2526,56 +2534,61 @@ unsupported:
WARN(_T(".wav file format not supported (must be mono 16bit PCM)"));
fclose(file);
return false;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::Load16BitMonoSampleRAW(const TCHAR* filepath,
- bool _signed,
- speaker_freq freq,
- wiimote_sample &out)
-{
- out = {};
+bool wiimote::Load16BitMonoSampleRAW (const TCHAR* filepath,
+ bool _signed,
+ speaker_freq freq,
+ wiimote_sample &out)
+ {
// converts (.wav style) unsigned 16bit mono raw data to the 4bit ADPCM variant
// used by the Wiimote, and returns the data in a BYTE array (caller must
// delete[] it when no longer needed):
+ memset(&out, 0, sizeof(out));
// get the length of the file
struct _stat file_info;
- if (_tstat(filepath, &file_info)) {
+ if(_tstat(filepath, &file_info)) {
WARN(_T("couldn't get filesize for '%s'"), filepath);
return false;
- }
-
+ }
+
DWORD len = file_info.st_size;
_ASSERT(len);
- if (!len) {
+ if(!len) {
WARN(_T("zero-size sample file '%s'"), filepath);
return false;
- }
+ }
- unsigned total_samples = (len + 1) / 2; // round up just in case file is corrupt
+ unsigned total_samples = (len+1) / 2; // round up just in case file is corrupt
// allocate a buffer to hold the samples to convert
- if (!total_samples) {
+ short *samples = new short[total_samples];
+ _ASSERT(samples);
+ if(!samples) {
TRACE(_T("Couldn't open '%s"), filepath);
return false;
- }
- short *samples = new short[total_samples];
+ }
// load them
FILE *file;
bool res;
+#if (_MSC_VER >= 1400) // VC 2005+
_tfopen_s(&file, filepath, _T("rb"));
+#else
+ file = _tfopen(filepath, _T("rb"));
+#endif
_ASSERT(file);
- if (!file) {
+ if(!file) {
TRACE(_T("Couldn't open '%s"), filepath);
- goto error;
- }
+ goto error;
+ }
res = (fread(samples, 1, len, file) == len);
fclose(file);
- if (!res) {
+ if(!res) {
WARN(_T("Couldn't load file '%s'"), filepath);
goto error;
- }
+ }
// and convert them
res = Convert16bitMonoSamples(samples, _signed, total_samples, freq, out);
@@ -2585,100 +2598,99 @@ bool wiimote::Load16BitMonoSampleRAW(const TCHAR* filepath,
error:
delete[] samples;
return false;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::Convert16bitMonoSamples(const short* samples,
- bool _signed,
- DWORD length,
- speaker_freq freq,
- wiimote_sample &out)
-{
- out = {};
-
+bool wiimote::Convert16bitMonoSamples (const short* samples,
+ bool _signed,
+ DWORD length,
+ speaker_freq freq,
+ wiimote_sample &out)
+ {
// converts 16bit mono sample data to the native 4bit format used by the Wiimote,
// and returns the data in a BYTE array (caller must delete[] when no
// longer needed):
+ memset(&out, 0, sizeof(0));
_ASSERT(samples && length);
- if (!samples || !length)
+ if(!samples || !length)
return false;
// allocate the output buffer
out.samples = new BYTE[length];
_ASSERT(out.samples);
- if (!out.samples)
+ if(!out.samples)
return false;
// clear it
memset(out.samples, 0, length);
out.length = length;
- out.freq = freq;
+ out.freq = freq;
// ADPCM code, adapted from
// http://www.wiindows.org/index.php/Talk:Wiimote#Input.2FOutput_Reports
- static const int index_table[16] = { -1, -1, -1, -1, 2, 4, 6, 8,
+ static const int index_table[16] = { -1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8 };
- static const int diff_table[16] = { 1, 3, 5, 7, 9, 11, 13, 15,
+ static const int diff_table [16] = { 1, 3, 5, 7, 9, 11, 13, 15,
-1, -3, -5, -7, -9, -11, -13, 15 };
- static const int step_scale[16] = { 230, 230, 230, 230, 307, 409, 512, 614,
+ static const int step_scale [16] = { 230, 230, 230, 230, 307, 409, 512, 614,
230, 230, 230, 230, 307, 409, 512, 614 };
// Encode to ADPCM, on initialization set adpcm_prev_value to 0 and adpcm_step
// to 127 (these variables must be preserved across reports)
int adpcm_prev_value = 0;
- int adpcm_step = 127;
+ int adpcm_step = 127;
- for (size_t i = 0; i < length; i++)
- {
+ for(size_t i=0; i<length; i++)
+ {
// convert to 16bit signed
int value = samples[i];// (8bit) << 8);// | samples[i]; // dither it?
- if (!_signed)
+ if(!_signed)
value -= 32768;
// encode:
int diff = value - adpcm_prev_value;
BYTE encoded_val = 0;
- if (diff < 0) {
+ if(diff < 0) {
encoded_val |= 8;
diff = -diff;
- }
+ }
diff = (diff << 2) / adpcm_step;
if (diff > 7)
diff = 7;
encoded_val |= diff;
adpcm_prev_value += ((adpcm_step * diff_table[encoded_val]) / 8);
- if (adpcm_prev_value > 0x7fff)
- adpcm_prev_value = 0x7fff;
- if (adpcm_prev_value < -0x8000)
+ if(adpcm_prev_value > 0x7fff)
+ adpcm_prev_value = 0x7fff;
+ if(adpcm_prev_value < -0x8000)
adpcm_prev_value = -0x8000;
adpcm_step = (adpcm_step * step_scale[encoded_val]) >> 8;
- if (adpcm_step < 127)
+ if(adpcm_step < 127)
adpcm_step = 127;
- if (adpcm_step > 24567)
+ if(adpcm_step > 24567)
adpcm_step = 24567;
- if (i & 1)
- out.samples[i >> 1] |= encoded_val;
+ if(i & 1)
+ out.samples[i>>1] |= encoded_val;
else
- out.samples[i >> 1] |= encoded_val << 4;
- }
+ out.samples[i>>1] |= encoded_val << 4;
+ }
return true;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::PlaySample(const wiimote_sample &sample, BYTE volume,
- speaker_freq freq_override)
-{
+bool wiimote::PlaySample (const wiimote_sample &sample, BYTE volume,
+ speaker_freq freq_override)
+ {
_ASSERT(IsConnected());
- if (!IsConnected())
+ if(!IsConnected())
return false;
- speaker_freq freq = freq_override ? freq_override : sample.freq;
+ speaker_freq freq = freq_override? freq_override : sample.freq;
TRACE(_T("playing sample."));
EnableSpeaker(true);
- MuteSpeaker(true);
+ MuteSpeaker (true);
#if 0
// combine everything into one write - faster, seems to work?
- BYTE bytes[9] = { 0x00, 0x00, 0x00, 10 + freq, vol, 0x00, 0x00, 0x01, 0x01 };
+ BYTE bytes[9] = { 0x00, 0x00, 0x00, 10+freq, vol, 0x00, 0x00, 0x01, 0x01 };
WriteData(0x04a20001, sizeof(bytes), bytes);
#else
// Write 0x01 to register 0x04a20009
@@ -2692,45 +2704,45 @@ bool wiimote::PlaySample(const wiimote_sample &sample, BYTE volume,
WriteData(0x04a20008, 0x01);
#endif
- Internal.Speaker.Freq = freq;
+ Internal.Speaker.Freq = freq;
Internal.Speaker.Volume = volume;
- CurrentSample = &sample;
+ CurrentSample = &sample;
MuteSpeaker(false);
return StartSampleThread();
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::StartSampleThread()
-{
- if (SampleThread)
+bool wiimote::StartSampleThread ()
+ {
+ if(SampleThread)
return true;
SampleThread = (HANDLE)_beginthreadex(NULL, 0, SampleStreamThreadfunc,
- this, 0, NULL);
+ this, 0, NULL);
_ASSERT(SampleThread);
- if (!SampleThread) {
+ if(!SampleThread) {
WARN(_T("couldn't create sample thread!"));
- MuteSpeaker(true);
- EnableSpeaker(false);
+ MuteSpeaker (true);
+ EnableSpeaker(false);
return false;
- }
+ }
SetThreadPriority(SampleThread, WORKER_THREAD_PRIORITY);
return true;
-}
+ }
// ------------------------------------------------------------------------------------
-bool wiimote::PlaySquareWave(speaker_freq freq, BYTE volume)
-{
+bool wiimote::PlaySquareWave (speaker_freq freq, BYTE volume)
+ {
_ASSERT(IsConnected());
- if (!IsConnected())
+ if(!IsConnected())
return false;
// if we're already playing a sample, stop it first
- if (IsPlayingSample())
+ if(IsPlayingSample())
CurrentSample = NULL;
// if we're already playing a square wave at this freq and volume, return
- else if (IsPlayingAudio() && (Internal.Speaker.Freq == freq) &&
- (Internal.Speaker.Volume == volume))
+ else if(IsPlayingAudio() && (Internal.Speaker.Freq == freq) &&
+ (Internal.Speaker.Volume == volume))
return true;
TRACE(_T("playing square wave."));
@@ -2738,7 +2750,7 @@ bool wiimote::PlaySquareWave(speaker_freq freq, BYTE volume)
CurrentSample = 0;
EnableSpeaker(true);
- MuteSpeaker(true);
+ MuteSpeaker (true);
#if 0
// combined everything into one write - much faster, seems to work?
@@ -2751,56 +2763,53 @@ bool wiimote::PlaySquareWave(speaker_freq freq, BYTE volume)
WriteData(0x04a20001, 0x08);
// write default sound mode (4bit ADPCM, we assume) 7-byte configuration
// to registers 0xa20001-0xa20008
- BYTE bytes[7] = { '\0', '\0', '\0', BYTE(10 + freq), volume, '\0', '\0' };
+ BYTE bytes[7] = { '\0', '\0', '\0', BYTE(10+freq), volume, '\0', '\0' };
WriteData(0x04a20001, sizeof(bytes), bytes);
// write 0x01 to register 0xa20008
WriteData(0x04a20008, 0x01);
#endif
- Internal.Speaker.Freq = freq;
+ Internal.Speaker.Freq = freq;
Internal.Speaker.Volume = volume;
MuteSpeaker(false);
return StartSampleThread();
-}
+ }
// ------------------------------------------------------------------------------------
-void wiimote::RecordState(state_history &events_out,
- unsigned max_time_ms,
- state_change_flags change_trigger)
-{
+void wiimote::RecordState (state_history &events_out,
+ unsigned max_time_ms,
+ state_change_flags change_trigger)
+ {
// user being naughty?
- if (Recording.bEnabled)
+ if(Recording.bEnabled)
StopRecording();
// clear the list
- if (!events_out.empty())
+ if(!events_out.empty())
events_out.clear();
// start recording
Recording.StateHistory = &events_out;
- Recording.StartTimeMS = timeGetTime();
- Recording.EndTimeMS = Recording.StartTimeMS + max_time_ms;
+ Recording.StartTimeMS = timeGetTime();
+ Recording.EndTimeMS = Recording.StartTimeMS + max_time_ms;
Recording.TriggerFlags = change_trigger;
// as this call happens outside the read/parse thread, set the boolean
// which will enable reocrding last, so that all params are in place.
// TODO: * stricly speaking this only works on VC2005+ or better, as it
// automatically places a memory barrier on volatile variables - earlier/
// other compilers may reorder the assignments!). *
- Recording.bEnabled = true;
-}
+ Recording.bEnabled = true;
+ }
// ------------------------------------------------------------------------------------
-void wiimote::StopRecording()
-{
- if (!Recording.bEnabled)
+void wiimote::StopRecording ()
+ {
+ if(!Recording.bEnabled)
return;
Recording.bEnabled = false;
// make sure the read/parse thread has time to notice the change (else it might
// still write one more state to the list)
Sleep(10); // too much?
-}
+ }
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
-
-#include "warns-end.hpp"
-
diff --git a/tracker-wii/wiiyourself/wiimote.h b/tracker-wii/wiiyourself/wiimote.h
index 73212e05..3588b7c7 100644
--- a/tracker-wii/wiiyourself/wiimote.h
+++ b/tracker-wii/wiiyourself/wiimote.h
@@ -10,18 +10,15 @@
#pragma once
-#undef NDEBUG
-
-#include "warns-begin.hpp"
-
-#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h> // auto Unicode/Ansi support
#include <queue> // for HID write method
#include <list> // for state recording
-typedef unsigned __int64 QWORD;
+#ifndef QWORD
+ typedef unsigned __int64 QWORD;
+#endif
#ifdef _MSC_VER // VC-specific: _DEBUG build only _ASSERT() sanity checks
# include <crtdbg.h>
@@ -184,7 +181,7 @@ class wiimote : public wiimote_state
// get the frequency from speaker_freq enum
static const unsigned FreqLookup [TOTAL_FREQUENCIES];
- static unsigned GetFreqLookup(unsigned index)
+ static const unsigned GetFreqLookup (unsigned index)
{
_ASSERT(index < TOTAL_FREQUENCIES);
if(index >= TOTAL_FREQUENCIES)
@@ -474,7 +471,7 @@ volatile int MotionPlusDetectCount; // waiting for the result
volatile DWORD AsyncRumbleTimeout;
// orientation estimation
unsigned WiimoteNearGUpdates;
- //unsigned NunchukNearGUpdates;
+ unsigned NunchukNearGUpdates;
// audio
HANDLE SampleThread;
const wiimote_sample* volatile CurrentSample; // otherwise playing square wave
@@ -489,5 +486,3 @@ volatile int MotionPlusDetectCount; // waiting for the result
unsigned ExtTriggerFlags;// extension changes "
} Recording;
};
-
-#include "warns-end.hpp"
diff --git a/tracker-wii/wiiyourself/wiimote_common.h b/tracker-wii/wiiyourself/wiimote_common.h
index 9934d6ec..c0fd01e1 100644
--- a/tracker-wii/wiiyourself/wiimote_common.h
+++ b/tracker-wii/wiiyourself/wiimote_common.h
@@ -1,5 +1,3 @@
-#pragma once
-
// _______________________________________________________________________________
//
// - WiiYourself! - native C++ Wiimote library v1.15 RC