diff options
| -rw-r--r-- | tracker-wii/wiiyourself/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tracker-wii/wiiyourself/wiimote.cpp | 187 | ||||
| -rw-r--r-- | tracker-wii/wiiyourself/wiimote.h | 6 | 
3 files changed, 62 insertions, 132 deletions
| diff --git a/tracker-wii/wiiyourself/CMakeLists.txt b/tracker-wii/wiiyourself/CMakeLists.txt index 1df52dbd..d32c6eb6 100644 --- a/tracker-wii/wiiyourself/CMakeLists.txt +++ b/tracker-wii/wiiyourself/CMakeLists.txt @@ -1 +1,2 @@  otr_module(wiiyourself STATIC NO-QT NO-COMPAT) +target_link_libraries(${self} PUBLIC setupapi hid winmm) diff --git a/tracker-wii/wiiyourself/wiimote.cpp b/tracker-wii/wiiyourself/wiimote.cpp index e7a8ca90..76bb26c4 100644 --- a/tracker-wii/wiiyourself/wiimote.cpp +++ b/tracker-wii/wiiyourself/wiimote.cpp @@ -8,106 +8,68 @@  //  //  wiimote.cpp  (tab = 4 spaces) -// VC-specifics: -#ifdef _MSC_VER  - // disable warning "C++ exception handler used, but unwind semantics are not enabled." - //				     in <xstring> (I don't use it - or just enable C++ exceptions) -# pragma warning(disable: 4530) -//  auto-link with the necessary libs -# pragma comment(lib, "setupapi.lib")	 -# pragma comment(lib, "hid.lib")		// for HID API (from DDK) -# pragma comment(lib, "winmm.lib")		// for timeGetTime() -#endif // _MSC_VER -  #include "wiimote.h" +#include <cmath> +#include <algorithm>    // std::min +#include <iterator>     // std::size +#include <tchar.h>  #include <setupapi.h> -extern "C" { -# ifdef __MINGW32__ -#  include <ddk/hidsdi.h>// from WinDDK -# else -#  include <hidsdi.h> -# endif -} +#include <hidsdi.h>  #include <sys/types.h>	// for _stat  #include <sys/stat.h>	// "  #include <process.h>	// for _beginthreadex() -#ifdef __BORLANDC__ -# include <cmath.h>		// for orientation -#else -# include <math.h>		// " -#endif  #include <mmreg.h>		// for WAVEFORMATEXTENSIBLE  #include <mmsystem.h>	// for timeGetTime() -// apparently not defined in some compilers: -#ifndef min -# define min(a,b)	(((a) < (b)) ? (a) : (b)) -#endif  // ------------------------------------------------------------------------------------  // helpers  // ------------------------------------------------------------------------------------  template<class T> inline T sign  (const T& val)  { return (val<0)? T(-1) : T(1); }  template<class T> inline T square(const T& val)  { return val*val; } -#define ARRAY_ENTRIES(array)	(sizeof(array)/sizeof(array[0]))  // ------------------------------------------------------------------------------------  //  Tracing & Debugging  // ------------------------------------------------------------------------------------ -#define PREFIX	_T("WiiYourself! : ") - -// comment these to auto-strip their code from the library: -//  (they currently use OutputDebugString() via _TRACE() - change to suit) -#if (_MSC_VER >= 1400) // VC 2005+ (earlier versions don't support variable args) -# define TRACE(fmt, ...) _TRACE(PREFIX          fmt          _T("\n"), __VA_ARGS__) -# define WARN(fmt, ...)  _TRACE(PREFIX _T("* ") fmt _T(" *") _T("\n"), __VA_ARGS__) -#elif defined(__MINGW32__) -# define TRACE(fmt, ...) _TRACE(PREFIX          fmt          _T("\n") , ##__VA_ARGS__) -# define WARN(fmt, ...)  _TRACE(PREFIX _T("* ") fmt _T(" *") _T("\n") , ##__VA_ARGS__) -#endif -// uncomment any of these for deeper debugging: -//#define DEEP_TRACE(fmt, ...) _TRACE(PREFIX _T("|") fmt _T("\n"), __VA_ARGS__)    // VC 2005+ -//#define DEEP_TRACE(fmt, ...) _TRACE(PREFIX _T("|") fmt _T("\n") , ##__VA_ARGS__) // mingw -//#define BEEP_DEBUG_READS -//#define BEEP_DEBUG_WRITES -//#define BEEP_ON_ORIENTATION_ESTIMATE -//#define BEEP_ON_PERIODIC_STATUSREFRESH -// internals: auto-strip code from the macros if they weren't defined +static_assert(sizeof(TCHAR) == sizeof(char)); + +template<typename... xs> +[[maybe_unused]] +static void trace_ (const char* fmt, const xs&... args) +{ +    fprintf(stderr, fmt, args...); +    fprintf(stderr, "\n"); +    fflush(stderr); +} + +template<typename... xs> +[[maybe_unused]] +static inline void disabled_trace_(const char*, const xs&...) {} + +#define TRACE trace_ +#define WARN  trace_ +  #ifndef TRACE -# define TRACE +# define TRACE disabled_trace_  #endif  #ifndef DEEP_TRACE -# define DEEP_TRACE +# define DEEP_TRACE disabled_trace_  #endif  #ifndef WARN -# define WARN +# define WARN disabled_trace_  #endif -// ------------------------------------------------------------------------------------ -static void _cdecl _TRACE (const TCHAR* fmt, ...) -	{ -	static TCHAR buffer[256]; -	if (!fmt) return; -	va_list	 argptr; -	va_start (argptr, fmt); -#if (_MSC_VER >= 1400) // VC 2005+ -	_vsntprintf_s(buffer, ARRAY_ENTRIES(buffer), _TRUNCATE, fmt, argptr); -#else -	_vsntprintf  (buffer, ARRAY_ENTRIES(buffer),			 fmt, argptr); -#endif -	va_end (argptr); - -	OutputDebugString(buffer); -	} +// uncomment any of these for deeper debugging: +//#define BEEP_DEBUG_READS +//#define BEEP_DEBUG_WRITES +//#define BEEP_ON_ORIENTATION_ESTIMATE +//#define BEEP_ON_PERIODIC_STATUSREFRESH  // ------------------------------------------------------------------------------------  //  wiimote  // ------------------------------------------------------------------------------------  // class statics -HMODULE		   wiimote::HidDLL				  = NULL; -unsigned	   wiimote::_TotalCreated		  = 0;  unsigned	   wiimote::_TotalConnected		  = 0; -hidwrite_ptr   wiimote::_HidD_SetOutputReport = NULL;  // (keep in sync with 'speaker_freq'):  const unsigned wiimote::FreqLookup [TOTAL_FREQUENCIES] =  @@ -156,23 +118,6 @@ wiimote::wiimote ()  #endif  	{  	_ASSERT(DataRead != INVALID_HANDLE_VALUE); -				 -	// if this is the first wiimote object, detect & enable HID write support -	if(++_TotalCreated == 1) -		{ -		HidDLL = LoadLibrary(_T("hid.dll")); -		_ASSERT(HidDLL); -		if(!HidDLL) -			WARN(_T("Couldn't load hid.dll - shouldn't happen!")); -		else{ -			_HidD_SetOutputReport = (hidwrite_ptr) -									GetProcAddress(HidDLL, "HidD_SetOutputReport"); -			if(_HidD_SetOutputReport) -				TRACE(_T("OS supports HID writes.")); -			else -				TRACE(_T("OS doesn't support HID writes.")); -			} -		}  	// clear our public and private state data completely (including deadzones)  	Clear		  (true); @@ -197,7 +142,7 @@ wiimote::wiimote ()  	}  // ------------------------------------------------------------------------------------  wiimote::~wiimote () -	{ +{  	Disconnect();  	// events & critical sections are kept open for the lifetime of the object, @@ -209,16 +154,8 @@ wiimote::~wiimote ()  	DeleteCriticalSection(&StateLock);  	// tidy up timer accuracy request -	timeEndPeriod(1);		 - -	// release HID DLL (for dynamic HID write method) -	if((--_TotalCreated == 0) && HidDLL) -		{ -		FreeLibrary(HidDLL); -		HidDLL				  = NULL; -		_HidD_SetOutputReport = NULL; -		} -	} +	timeEndPeriod(1); +}  // ------------------------------------------------------------------------------------  bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites) @@ -343,10 +280,6 @@ bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites)  			// autodetect which write method the Bluetooth stack supports,  			//  by requesting the wiimote status report: -			if(force_hidwrites && !_HidD_SetOutputReport) { -				TRACE(_T(".. can't force HID writes (not supported)")); -				force_hidwrites = false; -				}  			if(force_hidwrites)  				TRACE(_T(".. (HID writes forced)")); @@ -364,7 +297,7 @@ bool wiimote::Connect (unsigned wiimote_index, bool force_hidwrites)  				}  			// try HID write method (if supported) -			if(!bStatusReceived && _HidD_SetOutputReport) +			if(!bStatusReceived)  				{  				bUseHIDwrite = true;  				RequestStatusReport(); @@ -1775,50 +1708,53 @@ int wiimote::ParseReadAddress (BYTE* buff)  				break;  				} -			#define IF_TYPE(id)	if(type == id) { \ -									/* sometimes it comes in more than once */ \ -									if(Internal.ExtensionType == wiimote_state::id)\ -										break; \ -									Internal.ExtensionType = wiimote_state::id; +			#define IF_TYPE(id, ...) /* sometimes it comes in more than once */ \ +			    if(type == id)                                      \ +			    {                                                   \ +                    if(Internal.ExtensionType == wiimote_state::id) \ +                        break;                                      \ +                    Internal.ExtensionType = wiimote_state::id;     \ +                    __VA_ARGS__;                                    \ +                }  			// MotionPlus: once it's activated & mapped to the standard ext. port -			IF_TYPE(MOTION_PLUS) +			IF_TYPE(MOTION_PLUS,  				TRACE(_T(".. Motion Plus!"));  				// and start a query for the calibration data  				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16);  				bMotionPlusDetected = true; -				} -			else IF_TYPE(NUNCHUK) +            ) +			else IF_TYPE(NUNCHUK,  				TRACE(_T(".. Nunchuk!"));  				bMotionPlusEnabled = false;  				// and start a query for the calibration data  				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				} -			else IF_TYPE(CLASSIC) +            ) +			else IF_TYPE(CLASSIC,  				TRACE(_T(".. Classic Controller!"));  				bMotionPlusEnabled = false;  				// and start a query for the calibration data  				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				} -			else IF_TYPE(GH3_GHWT_GUITAR) +            ) +			else IF_TYPE(GH3_GHWT_GUITAR,  				// sometimes it comes in more than once?  				TRACE(_T(".. GH3/GHWT Guitar Controller!"));  				bMotionPlusEnabled = false;  				// and start a query for the calibration data  				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				} -			else IF_TYPE(GHWT_DRUMS) +            ) +			else IF_TYPE(GHWT_DRUMS,  				TRACE(_T(".. GHWT Drums!"));  				bMotionPlusEnabled = false;  				// and start a query for the calibration data  				ReadAddress(REGISTER_EXTENSION_CALIBRATION, 16); -				} -			else IF_TYPE(BALANCE_BOARD) +            ) +			else IF_TYPE(BALANCE_BOARD,  				TRACE(_T(".. Balance Board!"));  				bMotionPlusEnabled = false;  				// and start a query for the calibration data  				ReadAddress(REGISTER_BALANCE_CALIBRATION, 24); -				} +            )  			else if(type == PARTIALLY_INSERTED) {  				// sometimes it comes in more than once?  				if(Internal.ExtensionType == wiimote_state::PARTIALLY_INSERTED) @@ -1831,13 +1767,12 @@ int wiimote::ParseReadAddress (BYTE* buff)  				//  status report (this usually fixes it)  				Internal.bExtension = false;  				RequestStatusReport(); -				} -			else{ +			} +			else  				TRACE(_T("unknown extension controller found (0x%I64x)"), type); -				}  			}  			break; -		 +  		case (REGISTER_EXTENSION_CALIBRATION & 0xffff):  		case (REGISTER_BALANCE_CALIBRATION   & 0xffff):  			{ @@ -2042,7 +1977,7 @@ unsigned __stdcall wiimote::HIDwriteThreadfunc (void* param)  #endif  			LeaveCriticalSection(&remote.HIDwriteQueueLock); -			if(!_HidD_SetOutputReport(remote.Handle, buff, REPORT_LENGTH)) +			if(!HidD_SetOutputReport(remote.Handle, buff, REPORT_LENGTH))  				{  				DWORD err = GetLastError();  if(err==ERROR_BUSY) @@ -2308,7 +2243,7 @@ unsigned __stdcall wiimote::SampleStreamThreadfunc (void* param)  					{  					// (remember that samples are 4bit, ie. 2 per byte)  					unsigned samples_left   = (current_sample->length - sample_index); -					unsigned report_samples = min(samples_left, (unsigned)40); +					unsigned report_samples = std::min(samples_left, (unsigned)40);  					// round the entries up to the nearest multiple of 2  					unsigned report_entries = (report_samples+1) >> 1; @@ -2470,7 +2405,7 @@ bool wiimote::Load16bitMonoSampleWAV (const TCHAR* filepath, wiimote_sample &out  			unsigned	   sample_freq = wf.x.nSamplesPerSec;  			const unsigned epsilon	   = 100; // for now -			for(unsigned index=1; index<ARRAY_ENTRIES(FreqLookup); index++) +			for(unsigned index=1; index<std::size(FreqLookup); index++)  				{  				if((sample_freq+epsilon) >= FreqLookup[index] &&  				   (sample_freq-epsilon) <= FreqLookup[index]) { diff --git a/tracker-wii/wiiyourself/wiimote.h b/tracker-wii/wiiyourself/wiimote.h index 27551c76..4b5ab42a 100644 --- a/tracker-wii/wiiyourself/wiimote.h +++ b/tracker-wii/wiiyourself/wiimote.h @@ -391,11 +391,6 @@ class wiimote : public wiimote_state  		EVENT			 DataRead;		  // signals overlapped read complete  		bool			 bUseHIDwrite;	  // alternative write method (less efficient  										  //  but required for some BT stacks (eg. MS') -		// HidD_SetOutputReport is only supported from XP onwards, so detect & -		//  load it dynamically: -		static HMODULE	 HidDLL;	 -		static hidwrite_ptr _HidD_SetOutputReport; -		  		volatile bool	 bStatusReceived;	  // for output method detection  		volatile bool	 bConnectInProgress;  // don't handle extensions until complete  		volatile bool	 bInitInProgress;	  // stop regular requests until complete @@ -406,7 +401,6 @@ volatile int	 MotionPlusDetectCount;		  // waiting for the result  		volatile bool	 bMotionPlusEnabled;  		volatile bool	 bMotionPlusExtension;// detected one plugged into MotionPlus  		volatile bool	 bCalibrateAtRest;	  // as soon as the first sensor values 											  //  come in after a Connect() call. -		static unsigned	 _TotalCreated;  		static unsigned	 _TotalConnected;  		input_report	 ReportType;	      // type of data the wiimote delivers	  		// read buffer | 
