• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
clearWiiMoteEvent97 		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:
WiiMoteRingBuffer(unsigned int numEntries)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 
~WiiMoteRingBuffer()151 		~WiiMoteRingBuffer()
152 		{
153 			delete buffer;
154 		}
155 
RoundUpToNextPowerOf2(unsigned int n)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 
GetReadAvailable()171 		int GetReadAvailable( )
172 		{
173 			return ( (writeIndex - readIndex) & bigMask );
174 		}
175 
176 
GetWriteAvailable()177 		int GetWriteAvailable( )
178 		{
179 			return ( bufferSize - GetReadAvailable());
180 		}
181 
182 
Write(WiiMoteEvent * data,int numEntries)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>
Read(WiiMoteEvent * data,int numEntries)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 
GetWriteRegions(int numEntries,int & dataPtr1,int & sizePtr1,int & dataPtr2,int & sizePtr2)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 
GetReadRegions(int numEntries,int & dataPtr1,int & sizePtr1,int & dataPtr2,int & sizePtr2)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 
AdvanceWriteIndex(int numEntries)294 		int AdvanceWriteIndex( int numEntries )
295 		{
296 			 return writeIndex = (writeIndex + numEntries) & bigMask;
297 		}
298 
299 
AdvanceReadIndex(int numEntries)300 		int AdvanceReadIndex( int numEntries )
301 		{
302 			return readIndex = (readIndex + numEntries) & bigMask;
303 		}
304 
305 
Flush()306 		void Flush( )
307 		{
308 			writeIndex = readIndex = 0;
309 		}
310 	};
311 }
312 #endif //#define OIS_WiiMoteRingBuffer_H
313 #endif
314