diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2019-03-14 13:40:09 +0100 | 
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2019-03-14 13:44:32 +0100 | 
| commit | 599afab6c9991df3d87d538ef65fe54533d25a11 (patch) | |
| tree | 55bba99136ab4da1c71ee4a75eccb5006f1da0da /tracker-wii | |
| parent | c90f8fbd1a83ffeed6b0bb9d55e91f4a4a9b8641 (diff) | |
tracker/wii: revert to 2.3.10
Issue: #876
Diffstat (limited to 'tracker-wii')
| -rw-r--r-- | tracker-wii/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | tracker-wii/lang/nl_NL.ts | 7 | ||||
| -rw-r--r-- | tracker-wii/lang/ru_RU.ts | 7 | ||||
| -rw-r--r-- | tracker-wii/lang/stub.ts | 7 | ||||
| -rw-r--r-- | tracker-wii/lang/zh_CN.ts | 7 | ||||
| -rw-r--r-- | tracker-wii/wii_camera.cpp | 105 | ||||
| -rw-r--r-- | tracker-wii/wii_camera.h | 33 | ||||
| -rw-r--r-- | tracker-wii/wii_frame.cpp | 34 | ||||
| -rw-r--r-- | tracker-wii/wii_frame.hpp | 16 | ||||
| -rw-r--r-- | tracker-wii/wii_module.cpp | 33 | ||||
| -rw-r--r-- | tracker-wii/wii_point_extractor.cpp | 52 | ||||
| -rw-r--r-- | tracker-wii/wii_point_extractor.h | 14 | ||||
| -rw-r--r-- | tracker-wii/wiiyourself/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | tracker-wii/wiiyourself/warns-begin.hpp | 24 | ||||
| -rw-r--r-- | tracker-wii/wiiyourself/warns-end.hpp | 7 | ||||
| -rw-r--r-- | tracker-wii/wiiyourself/wiimote.cpp | 2925 | ||||
| -rw-r--r-- | tracker-wii/wiiyourself/wiimote.h | 15 | ||||
| -rw-r--r-- | tracker-wii/wiiyourself/wiimote_common.h | 2 | 
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  | 
