Home | History | Annotate | Download | only in WiiMote
      1 #include "OISConfig.h"
      2 #ifdef OIS_WIN32_WIIMOTE_SUPPORT
      3 /*
      4 The zlib/libpng License
      5 
      6 Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
      7 
      8 This software is provided 'as-is', without any express or implied warranty. In no event will
      9 the authors be held liable for any damages arising from the use of this software.
     10 
     11 Permission is granted to anyone to use this software for any purpose, including commercial
     12 applications, and to alter it and redistribute it freely, subject to the following
     13 restrictions:
     14 
     15     1. The origin of this software must not be misrepresented; you must not claim that
     16 		you wrote the original software. If you use this software in a product,
     17 		an acknowledgment in the product documentation would be appreciated but is
     18 		not required.
     19 
     20     2. Altered source versions must be plainly marked as such, and must not be
     21 		misrepresented as being the original software.
     22 
     23     3. This notice may not be removed or altered from any source distribution.
     24 
     25  # ------------------------#
     26  # Original License follows:
     27  # ------------------------#
     28 
     29  * PortAudio Portable Real-Time Audio Library
     30  * Latest version at: http://www.audiomulch.com/portaudio/
     31  * <platform> Implementation
     32  * Copyright (c) 1999-2000 <author(s)>
     33  *
     34  * Permission is hereby granted, free of charge, to any person obtaining
     35  * a copy of this software and associated documentation files
     36  * (the "Software"), to deal in the Software without restriction,
     37  * including without limitation the rights to use, copy, modify, merge,
     38  * publish, distribute, sublicense, and/or sell copies of the Software,
     39  * and to permit persons to whom the Software is furnished to do so,
     40  * subject to the following conditions:
     41  *
     42  * The above copyright notice and this permission notice shall be
     43  * included in all copies or substantial portions of the Software.
     44  *
     45  * Any person wishing to distribute modifications to the Software is
     46  * requested to send the modifications to the original developer so that
     47  * they can be incorporated into the canonical version.
     48  *
     49  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     50  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     51  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     52  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
     53  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
     54  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     55  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     56  */
     57 #ifndef OIS_WiiMoteRingBuffer_H
     58 #define OIS_WiiMoteRingBuffer_H
     59 
     60 #include "OISPrereqs.h"
     61 
     62 namespace OIS
     63 {
     64 	struct WiiMoteEvent
     65 	{
     66 		//! (7 buttons) If a button was just pressed, the bit will be set
     67 		unsigned int pushedButtons;
     68 
     69 		//! (7 buttons) If a button was just released, the bit will be set
     70 		unsigned int releasedButtons;
     71 
     72 		//! Will be true if POV changed this event
     73 		bool povChanged;
     74 
     75 		//! Will be valid if povChanged = true
     76 		unsigned int povDirection;
     77 
     78 		//! Will be valid if a movement just occurred on main motion sensing
     79 		bool movement;
     80 
     81 		//Values of main orientation vector
     82 		float x, y, z;
     83 
     84 		//! Will be valid if a movement just occurred on main motion sensing
     85 		bool movementChuck;
     86 
     87 		//Values of main orientation vector
     88 		float nunChuckx, nunChucky, nunChuckz;
     89 
     90 		//Used to flag when a Nunchuck axis moved
     91 		bool nunChuckXAxisMoved, nunChuckYAxisMoved;
     92 
     93 		//Values of NunChuck JoyStick
     94 		int nunChuckXAxis, nunChuckYAxis;
     95 
     96 		//! clear initial state
     97 		void clear()
     98 		{
     99 			pushedButtons = releasedButtons = 0;
    100 			povChanged = false;
    101 			povDirection = 0;
    102 
    103 			movement = false;
    104 			x = y = z = 0.0f;
    105 
    106 			nunChuckx = nunChucky = nunChuckz = 0;
    107 			movementChuck = false;
    108 
    109 			nunChuckXAxisMoved = nunChuckYAxisMoved = false;
    110 			nunChuckXAxis = nunChuckYAxis = 0;
    111 		}
    112 	};
    113 
    114 	/// <summary>
    115 	/// Ring Buffer (fifo) used to store 16bit pcm data
    116 	/// </summary>
    117 	class WiiMoteRingBuffer
    118 	{
    119 	private:
    120 		//! Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init
    121 		int bufferSize;
    122 		//! Used for wrapping indices with extra bit to distinguish full/empty.
    123 		int bigMask;
    124 		// Used for fitting indices to buffer.
    125 		int smallMask;
    126 
    127 		// Buffer holding the actual event buffers
    128 		WiiMoteEvent *buffer;
    129 
    130 		//! Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex.
    131 		volatile int writeIndex;
    132 
    133 		//! Index of next readable byte. Set by RingBuffer_AdvanceReadIndex.
    134 		volatile int readIndex;
    135 
    136 	public:
    137 		WiiMoteRingBuffer( unsigned int numEntries )
    138 		{
    139 			numEntries = RoundUpToNextPowerOf2( numEntries );
    140 
    141 			//2 bytes per short
    142 			bufferSize = (int)numEntries;
    143 			buffer = new WiiMoteEvent[numEntries];
    144 
    145 			Flush();
    146 
    147 			bigMask = (int)(numEntries*2)-1;
    148 			smallMask = (int)(numEntries)-1;
    149 		}
    150 
    151 		~WiiMoteRingBuffer()
    152 		{
    153 			delete buffer;
    154 		}
    155 
    156 		unsigned int RoundUpToNextPowerOf2( unsigned int n )
    157 		{
    158 			int numBits = 0;
    159 			if( ((n-1) & n) == 0)
    160 			return n; //Already Power of two.
    161 
    162 			while( n > 0 )
    163 			{
    164 				n= n>>1;
    165 				numBits++;
    166 			}
    167 			return (unsigned int)(1<<numBits);
    168 		}
    169 
    170 
    171 		int GetReadAvailable( )
    172 		{
    173 			return ( (writeIndex - readIndex) & bigMask );
    174 		}
    175 
    176 
    177 		int GetWriteAvailable( )
    178 		{
    179 			return ( bufferSize - GetReadAvailable());
    180 		}
    181 
    182 
    183 		int Write( WiiMoteEvent *data, int numEntries )
    184 		{
    185 			int size1 = 0, size2 = 0, numWritten;
    186 			int data1Ptr = 0, data2Ptr = 0;
    187 
    188 			numWritten = GetWriteRegions( numEntries, data1Ptr, size1, data2Ptr, size2 );
    189 
    190 			if( size2 > 0 )
    191 			{
    192 				//copy to two parts
    193 				memcpy( &buffer[data1Ptr], data, sizeof(WiiMoteEvent) * size1 );
    194 				//Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 );
    195 				memcpy( &buffer[data2Ptr], &data[size1], sizeof(WiiMoteEvent) * size2 );
    196 				//Array.Copy( data, offsetPtr + size1, buffer, data2Ptr, size2 );
    197 			}
    198 			else
    199 			{	//Copy all continous
    200 				memcpy( &buffer[data1Ptr], data, sizeof(WiiMoteEvent) * size1 );
    201 				//Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 );
    202 			}
    203 			AdvanceWriteIndex( numWritten );
    204 			return numWritten;
    205 		}
    206 
    207 
    208 		/// <summary>
    209 		/// Reads requested number of entries into sent array.
    210 		/// Returns number written
    211 		/// </summary>
    212 		int Read( WiiMoteEvent *data, int numEntries )
    213 		{
    214 			int size1 = 0, size2 = 0, numRead, data1Ptr = 0, data2Ptr = 0;
    215 
    216 			numRead = GetReadRegions( numEntries, data1Ptr, size1, data2Ptr, size2 );
    217 
    218 			if( size2 > 0 )
    219 			{
    220 				memcpy( data, &buffer[data1Ptr], sizeof(WiiMoteEvent) * size1 );
    221 				//Array.Copy( buffer, data1Ptr, data, 0, size1 );
    222 				memcpy( &data[size1], &buffer[data2Ptr], sizeof(WiiMoteEvent) * size2 );
    223 				//Array.Copy( buffer, data2Ptr, data, size1, size2 );
    224 			}
    225 			else
    226 				memcpy( data, &buffer[data1Ptr], sizeof(WiiMoteEvent) * size1 );
    227 				//Array.Copy( buffer, data1Ptr, data, 0, size1 );
    228 
    229 			AdvanceReadIndex( numRead );
    230 			return numRead;
    231 		}
    232 
    233 	private:
    234 
    235 		int GetWriteRegions( int numEntries, int &dataPtr1, int &sizePtr1,
    236 							 int &dataPtr2, int &sizePtr2 )
    237 		{
    238 			int   index;
    239 			int   available = GetWriteAvailable();
    240 			if( numEntries > available )
    241 				numEntries = available;
    242 
    243 			//Check to see if write is not contiguous.
    244 			index = writeIndex & smallMask;
    245 			if( (index + numEntries) > bufferSize )
    246 			{
    247 				//Write data in two blocks that wrap the buffer.
    248 				int   firstHalf = bufferSize - index;
    249 				dataPtr1 = index;//&buffer[index];
    250 				sizePtr1 = firstHalf;
    251 				dataPtr2 = 0;//&buffer[0];
    252 				sizePtr2 = numEntries - firstHalf;
    253 			}
    254 			else
    255 			{
    256 				dataPtr1 = index;//&buffer[index];
    257 				sizePtr1 = numEntries;
    258 				dataPtr2 = 0;
    259 				sizePtr2 = 0;
    260 			}
    261 			return numEntries;
    262 		}
    263 
    264 
    265 		int GetReadRegions( int numEntries, int &dataPtr1, int &sizePtr1, int &dataPtr2, int &sizePtr2 )
    266 		{
    267 			int   index;
    268 			int   available = GetReadAvailable( );
    269 			if( numEntries > available )
    270 				numEntries = available;
    271 
    272 			// Check to see if read is not contiguous
    273 			index = readIndex & smallMask;
    274 			if( (index + numEntries) > bufferSize )
    275 			{
    276 				// Write data in two blocks that wrap the buffer
    277 				int firstHalf = bufferSize - index;
    278 				dataPtr1 = index;//&buffer[index];
    279 				sizePtr1 = firstHalf;
    280 				dataPtr2 = 0;//&buffer[0];
    281 				sizePtr2 = numEntries - firstHalf;
    282 			}
    283 			else
    284 			{
    285 				dataPtr1 = index;//&buffer[index];
    286 				sizePtr1 = numEntries;
    287 				dataPtr2 = 0;
    288 				sizePtr2 = 0;
    289 			}
    290 			return numEntries;
    291 		}
    292 
    293 
    294 		int AdvanceWriteIndex( int numEntries )
    295 		{
    296 			 return writeIndex = (writeIndex + numEntries) & bigMask;
    297 		}
    298 
    299 
    300 		int AdvanceReadIndex( int numEntries )
    301 		{
    302 			return readIndex = (readIndex + numEntries) & bigMask;
    303 		}
    304 
    305 
    306 		void Flush( )
    307 		{
    308 			writeIndex = readIndex = 0;
    309 		}
    310 	};
    311 }
    312 #endif //#define OIS_WiiMoteRingBuffer_H
    313 #endif
    314