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

https://bitbucket.org/cabalistic/ogredeps/ · C Header · 313 lines · 172 code · 51 blank · 90 comment · 9 complexity · 3d3ea9c3f14084051e1589a4d19984b6 MD5 · raw file

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