PageRenderTime 46ms CodeModel.GetById 19ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/ois/src/win32/extras/WiiMote/OISWiiMoteRingBuffer.h

https://bitbucket.org/cabalistic/ogredeps/
C++ Header | 313 lines | 172 code | 51 blank | 90 comment | 8 complexity | 3d3ea9c3f14084051e1589a4d19984b6 MD5 | raw file
  1#include "OISConfig.h"
  2#ifdef OIS_WIN32_WIIMOTE_SUPPORT
  3/*
  4The zlib/libpng License
  5
  6Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
  7
  8This software is provided 'as-is', without any express or implied warranty. In no event will
  9the authors be held liable for any damages arising from the use of this software.
 10
 11Permission is granted to anyone to use this software for any purpose, including commercial 
 12applications, and to alter it and redistribute it freely, subject to the following
 13restrictions:
 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
 62namespace 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