Przeglądaj źródła

Merged OIS directly into my project because I needed to make modifications to it

Marko Pintera 12 lat temu
rodzic
commit
9a1c4b6c9b
100 zmienionych plików z 16108 dodań i 16 usunięć
  1. 7 0
      BansheeEngine/Source/BsGUIInputBox.cpp
  2. 8 1
      CamelotCore/Include/CmInputHandler.h
  3. 45 12
      CamelotOISInput/CamelotOISInput.vcxproj
  4. 111 0
      CamelotOISInput/CamelotOISInput.vcxproj.filters
  5. 15 0
      CamelotOISInput/Include/OIS/Makefile.am
  6. 41 0
      CamelotOISInput/Include/OIS/OIS.h
  7. 75 0
      CamelotOISInput/Include/OIS/OISConfig.h
  8. 278 0
      CamelotOISInput/Include/OIS/OISEffect.h
  9. 43 0
      CamelotOISInput/Include/OIS/OISEvents.h
  10. 78 0
      CamelotOISInput/Include/OIS/OISException.h
  11. 81 0
      CamelotOISInput/Include/OIS/OISFactoryCreator.h
  12. 120 0
      CamelotOISInput/Include/OIS/OISForceFeedback.h
  13. 205 0
      CamelotOISInput/Include/OIS/OISInputManager.h
  14. 47 0
      CamelotOISInput/Include/OIS/OISInterface.h
  15. 228 0
      CamelotOISInput/Include/OIS/OISJoyStick.h
  16. 312 0
      CamelotOISInput/Include/OIS/OISKeyboard.h
  17. 138 0
      CamelotOISInput/Include/OIS/OISMouse.h
  18. 169 0
      CamelotOISInput/Include/OIS/OISMultiTouch.h
  19. 95 0
      CamelotOISInput/Include/OIS/OISObject.h
  20. 226 0
      CamelotOISInput/Include/OIS/OISPrereqs.h
  21. 73 0
      CamelotOISInput/Include/OIS/SDL/SDLInputManager.h
  22. 0 0
      CamelotOISInput/Include/OIS/SDL/SDLJoyStick.h
  23. 79 0
      CamelotOISInput/Include/OIS/SDL/SDLKeyboard.h
  24. 59 0
      CamelotOISInput/Include/OIS/SDL/SDLMouse.h
  25. 38 0
      CamelotOISInput/Include/OIS/SDL/SDLPrereqs.h
  26. 50 0
      CamelotOISInput/Include/OIS/iphone/iPhoneAccelerometer.h
  27. 56 0
      CamelotOISInput/Include/OIS/iphone/iPhoneHelpers.h
  28. 110 0
      CamelotOISInput/Include/OIS/iphone/iPhoneInputManager.h
  29. 64 0
      CamelotOISInput/Include/OIS/iphone/iPhoneMultiTouch.h
  30. 56 0
      CamelotOISInput/Include/OIS/iphone/iPhonePrereqs.h
  31. 49 0
      CamelotOISInput/Include/OIS/linux/EventHelpers.h
  32. 85 0
      CamelotOISInput/Include/OIS/linux/LinuxForceFeedback.h
  33. 105 0
      CamelotOISInput/Include/OIS/linux/LinuxInputManager.h
  34. 72 0
      CamelotOISInput/Include/OIS/linux/LinuxJoyStickEvents.h
  35. 98 0
      CamelotOISInput/Include/OIS/linux/LinuxKeyboard.h
  36. 75 0
      CamelotOISInput/Include/OIS/linux/LinuxMouse.h
  37. 82 0
      CamelotOISInput/Include/OIS/linux/LinuxPrereqs.h
  38. 103 0
      CamelotOISInput/Include/OIS/mac/MacHIDManager.h
  39. 94 0
      CamelotOISInput/Include/OIS/mac/MacHelpers.h
  40. 101 0
      CamelotOISInput/Include/OIS/mac/MacInputManager.h
  41. 76 0
      CamelotOISInput/Include/OIS/mac/MacJoyStick.h
  42. 102 0
      CamelotOISInput/Include/OIS/mac/MacKeyboard.h
  43. 51 0
      CamelotOISInput/Include/OIS/mac/MacMouse.h
  44. 57 0
      CamelotOISInput/Include/OIS/mac/MacPrereqs.h
  45. 108 0
      CamelotOISInput/Include/OIS/win32/Win32ForceFeedback.h
  46. 113 0
      CamelotOISInput/Include/OIS/win32/Win32InputManager.h
  47. 86 0
      CamelotOISInput/Include/OIS/win32/Win32JoyStick.h
  48. 87 0
      CamelotOISInput/Include/OIS/win32/Win32KeyBoard.h
  49. 59 0
      CamelotOISInput/Include/OIS/win32/Win32Mouse.h
  50. 70 0
      CamelotOISInput/Include/OIS/win32/Win32Prereqs.h
  51. 11 3
      CamelotOISInput/Source/CmInputHandlerOIS.cpp
  52. 128 0
      CamelotOISInput/Source/OIS/OISEffect.cpp
  53. 32 0
      CamelotOISInput/Source/OIS/OISException.cpp
  54. 74 0
      CamelotOISInput/Source/OIS/OISForceFeedback.cpp
  55. 290 0
      CamelotOISInput/Source/OIS/OISInputManager.cpp
  56. 73 0
      CamelotOISInput/Source/OIS/OISJoyStick.cpp
  57. 45 0
      CamelotOISInput/Source/OIS/OISKeyboard.cpp
  58. 23 0
      CamelotOISInput/Source/OIS/OISObject.cpp
  59. 114 0
      CamelotOISInput/Source/OIS/SDL/SDLInputManager.cpp
  60. 0 0
      CamelotOISInput/Source/OIS/SDL/SDLJoyStick.cpp
  61. 377 0
      CamelotOISInput/Source/OIS/SDL/SDLKeyboard.cpp
  62. 174 0
      CamelotOISInput/Source/OIS/SDL/SDLMouse.cpp
  63. 107 0
      CamelotOISInput/Source/OIS/extras/LIRC/OISLIRC.cpp
  64. 88 0
      CamelotOISInput/Source/OIS/extras/LIRC/OISLIRC.h
  65. 405 0
      CamelotOISInput/Source/OIS/extras/LIRC/OISLIRCFactoryCreator.cpp
  66. 98 0
      CamelotOISInput/Source/OIS/extras/LIRC/OISLIRCFactoryCreator.h
  67. 269 0
      CamelotOISInput/Source/OIS/extras/LIRC/OISLIRCRingBuffer.h
  68. 80 0
      CamelotOISInput/Source/OIS/iphone/iPhoneAccelerometer.mm
  69. 224 0
      CamelotOISInput/Source/OIS/iphone/iPhoneInputManager.mm
  70. 177 0
      CamelotOISInput/Source/OIS/iphone/iPhoneMultiTouch.mm
  71. 377 0
      CamelotOISInput/Source/OIS/linux/EventHelpers.cpp
  72. 559 0
      CamelotOISInput/Source/OIS/linux/LinuxForceFeedback.cpp
  73. 212 0
      CamelotOISInput/Source/OIS/linux/LinuxInputManager.cpp
  74. 305 0
      CamelotOISInput/Source/OIS/linux/LinuxJoyStickEvents.cpp
  75. 429 0
      CamelotOISInput/Source/OIS/linux/LinuxKeyboard.cpp
  76. 272 0
      CamelotOISInput/Source/OIS/linux/LinuxMouse.cpp
  77. 432 0
      CamelotOISInput/Source/OIS/mac/MacHIDManager.cpp
  78. 158 0
      CamelotOISInput/Source/OIS/mac/MacHelpers.cpp
  79. 206 0
      CamelotOISInput/Source/OIS/mac/MacInputManager.cpp
  80. 325 0
      CamelotOISInput/Source/OIS/mac/MacJoyStick.cpp
  81. 467 0
      CamelotOISInput/Source/OIS/mac/MacKeyboard.cpp
  82. 346 0
      CamelotOISInput/Source/OIS/mac/MacMouse.cpp
  83. 543 0
      CamelotOISInput/Source/OIS/win32/Win32ForceFeedback.cpp
  84. 273 0
      CamelotOISInput/Source/OIS/win32/Win32InputManager.cpp
  85. 683 0
      CamelotOISInput/Source/OIS/win32/Win32JoyStick.cpp
  86. 333 0
      CamelotOISInput/Source/OIS/win32/Win32KeyBoard.cpp
  87. 216 0
      CamelotOISInput/Source/OIS/win32/Win32Mouse.cpp
  88. 373 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMote.cpp
  89. 89 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMote.h
  90. 206 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteFactoryCreator.cpp
  91. 103 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteFactoryCreator.h
  92. 76 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteForceFeedback.cpp
  93. 67 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteForceFeedback.h
  94. 0 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteRingBuffer.cpp
  95. 313 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteRingBuffer.h
  96. 205 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/hiddevice.cpp
  97. 41 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/hiddevice.h
  98. 45 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/main.cpp
  99. 794 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/wiimote.cpp
  100. 291 0
      CamelotOISInput/Source/OIS/win32/extras/WiiMote/wiimote.h

+ 7 - 0
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -237,6 +237,13 @@ namespace BansheeEngine
 		{
 			// TODO - How are backspace, caps and enter handled?
 			mText += ev.getInputString();
+
+			if(mText != "")
+			{
+
+				int a = 5;
+			}
+
 			markAsDirty();
 
 			return true;

+ 8 - 1
CamelotCore/Include/CmInputHandler.h

@@ -6,6 +6,10 @@
 
 namespace CamelotFramework
 {
+	// Note: These KeyCodes are only keyboard scan codes. This means that exact scan code identifier might 
+	// not correspond to that exact character on users keyboard, depending on users input locale. 
+	// Only for US locale will these scan code names will match the actual keyboard input. Think of the US key
+	// code names as only a convenience for more easily identifying which location on the keyboard a scan code represents.
 	enum KeyCode
 	{
 		KC_UNASSIGNED  = 0x00,
@@ -159,7 +163,10 @@ namespace CamelotFramework
 	enum MouseButton
 	{
 		MB_Left = 0, MB_Right, MB_Middle,
-		MB_Button3, MB_Button4,	MB_Button5, MB_Button6,	MB_Button7, MB_Count
+		MB_Button3, MB_Button4,	MB_Button5, MB_Button6,	MB_Button7, 
+		MB_Button8, MB_Button9, MB_Button10, MB_Button11, MB_Button12, 
+		MB_Button13, MB_Button14, MB_Button15, MB_Button16, MB_Button17,
+		MB_Button18, MB_Button19, MB_Button20, MB_Count
 	};
 
 	struct MouseEvent

+ 45 - 12
CamelotOISInput/CamelotOISInput.vcxproj

@@ -85,14 +85,14 @@
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>../CamelotCore/Include;../CamelotUtility/Include;./Include;../Dependencies/Include;./Dependencies/Include</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../CamelotCore/Include;../CamelotUtility/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>CM_OIS_EXPORTS;_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>../lib/$(Configuration);../Dependencies/lib/Debug;./Dependencies/lib/Debug</AdditionalLibraryDirectories>
-      <AdditionalDependencies>CamelotCore.lib;CamelotUtility.lib;OIS.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/$(Configuration);../Dependencies/lib/Debug</AdditionalLibraryDirectories>
+      <AdditionalDependencies>CamelotCore.lib;CamelotUtility.lib;dxguid.lib;dinput8.lib;xinput.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImportLibrary>..\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
   </ItemDefinitionGroup>
@@ -100,14 +100,14 @@
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>../CamelotCore/Include;../CamelotUtility/Include;./Include;../Dependencies/Include;./Dependencies/Include</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../CamelotCore/Include;../CamelotUtility/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>CM_OIS_EXPORTS;_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Debug;./Dependencies/lib/x64/Debug</AdditionalLibraryDirectories>
-      <AdditionalDependencies>CamelotCore.lib;CamelotUtility.lib;OIS.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Debug</AdditionalLibraryDirectories>
+      <AdditionalDependencies>CamelotCore.lib;CamelotUtility.lib;dxguid.lib;dinput8.lib;xinput.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
   </ItemDefinitionGroup>
@@ -117,7 +117,7 @@
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../CamelotCore/Include;../CamelotUtility/Include;./Include;../Dependencies/Include;./Dependencies/Include</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../CamelotCore/Include;../CamelotUtility/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>CM_OIS_EXPORTS;_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
@@ -125,8 +125,8 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>../lib/$(Configuration);../Dependencies/lib/Release;./Dependencies/lib/Release</AdditionalLibraryDirectories>
-      <AdditionalDependencies>CamelotCore.lib;CamelotUtility.lib;OIS.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/$(Configuration);../Dependencies/lib/Release</AdditionalLibraryDirectories>
+      <AdditionalDependencies>CamelotCore.lib;CamelotUtility.lib;dxguid.lib;dinput8.lib;xinput.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImportLibrary>..\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
   </ItemDefinitionGroup>
@@ -136,7 +136,7 @@
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../CamelotCore/Include;../CamelotUtility/Include;./Include;../Dependencies/Include;./Dependencies/Include</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../CamelotCore/Include;../CamelotUtility/Include;./Include;../Dependencies/Include</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>CM_OIS_EXPORTS;_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
@@ -144,15 +144,48 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Release;./Dependencies/lib/x64/Release</AdditionalLibraryDirectories>
-      <AdditionalDependencies>CamelotCore.lib;CamelotUtility.lib;OIS.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Release</AdditionalLibraryDirectories>
+      <AdditionalDependencies>CamelotCore.lib;CamelotUtility.lib;dxguid.lib;dinput8.lib;xinput.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="Include\CmOISPrerequisites.h" />
+    <ClInclude Include="Include\OIS\OIS.h" />
+    <ClInclude Include="Include\OIS\OISConfig.h" />
+    <ClInclude Include="Include\OIS\OISEffect.h" />
+    <ClInclude Include="Include\OIS\OISEvents.h" />
+    <ClInclude Include="Include\OIS\OISException.h" />
+    <ClInclude Include="Include\OIS\OISFactoryCreator.h" />
+    <ClInclude Include="Include\OIS\OISForceFeedback.h" />
+    <ClInclude Include="Include\OIS\OISInputManager.h" />
+    <ClInclude Include="Include\OIS\OISInterface.h" />
+    <ClInclude Include="Include\OIS\OISJoyStick.h" />
+    <ClInclude Include="Include\OIS\OISKeyboard.h" />
+    <ClInclude Include="Include\OIS\OISMouse.h" />
+    <ClInclude Include="Include\OIS\OISMultiTouch.h" />
+    <ClInclude Include="Include\OIS\OISObject.h" />
+    <ClInclude Include="Include\OIS\OISPrereqs.h" />
+    <ClInclude Include="Include\OIS\win32\Win32ForceFeedback.h" />
+    <ClInclude Include="Include\OIS\win32\Win32InputManager.h" />
+    <ClInclude Include="Include\OIS\win32\Win32JoyStick.h" />
+    <ClInclude Include="Include\OIS\win32\Win32KeyBoard.h" />
+    <ClInclude Include="Include\OIS\win32\Win32Mouse.h" />
+    <ClInclude Include="Include\OIS\win32\Win32Prereqs.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="Source\OIS\OISEffect.cpp" />
+    <ClCompile Include="Source\OIS\OISException.cpp" />
+    <ClCompile Include="Source\OIS\OISForceFeedback.cpp" />
+    <ClCompile Include="Source\OIS\OISInputManager.cpp" />
+    <ClCompile Include="Source\OIS\OISJoyStick.cpp" />
+    <ClCompile Include="Source\OIS\OISKeyboard.cpp" />
+    <ClCompile Include="Source\OIS\OISObject.cpp" />
+    <ClCompile Include="Source\OIS\win32\Win32ForceFeedback.cpp" />
+    <ClCompile Include="Source\OIS\win32\Win32InputManager.cpp" />
+    <ClCompile Include="Source\OIS\win32\Win32JoyStick.cpp" />
+    <ClCompile Include="Source\OIS\win32\Win32KeyBoard.cpp" />
+    <ClCompile Include="Source\OIS\win32\Win32Mouse.cpp" />
     <ClInclude Include="Include\CmInputHandlerOIS.h">
       <FileType>CppCode</FileType>
     </ClInclude>

+ 111 - 0
CamelotOISInput/CamelotOISInput.vcxproj.filters

@@ -13,6 +13,18 @@
       <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
       <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
     </Filter>
+    <Filter Include="Header Files\OIS">
+      <UniqueIdentifier>{89daf073-a050-4791-9a01-35931b430cea}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\OIS">
+      <UniqueIdentifier>{e66fae83-5f33-4f75-a3b1-2e469a8195a3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\OIS\Win32">
+      <UniqueIdentifier>{15e5416a-b64b-44a5-9967-982d23d30f78}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\OIS\Win32">
+      <UniqueIdentifier>{e042ada7-f08f-4a4e-8315-042f7cd3d9a7}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Include\CmOISPrerequisites.h">
@@ -21,6 +33,69 @@
     <ClInclude Include="Include\CmInputHandlerOIS.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\OIS\OIS.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISConfig.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISEffect.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISEvents.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISException.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISFactoryCreator.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISForceFeedback.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISInputManager.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISInterface.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISJoyStick.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISKeyboard.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISMouse.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISMultiTouch.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISObject.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\OISPrereqs.h">
+      <Filter>Header Files\OIS</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\win32\Win32ForceFeedback.h">
+      <Filter>Header Files\OIS\Win32</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\win32\Win32InputManager.h">
+      <Filter>Header Files\OIS\Win32</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\win32\Win32JoyStick.h">
+      <Filter>Header Files\OIS\Win32</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\win32\Win32KeyBoard.h">
+      <Filter>Header Files\OIS\Win32</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\win32\Win32Mouse.h">
+      <Filter>Header Files\OIS\Win32</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\OIS\win32\Win32Prereqs.h">
+      <Filter>Header Files\OIS\Win32</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmOISPlugin.cpp">
@@ -29,5 +104,41 @@
     <ClCompile Include="Source\CmInputHandlerOIS.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\OIS\OISEffect.cpp">
+      <Filter>Source Files\OIS</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\OISException.cpp">
+      <Filter>Source Files\OIS</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\OISForceFeedback.cpp">
+      <Filter>Source Files\OIS</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\OISInputManager.cpp">
+      <Filter>Source Files\OIS</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\OISJoyStick.cpp">
+      <Filter>Source Files\OIS</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\OISKeyboard.cpp">
+      <Filter>Source Files\OIS</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\OISObject.cpp">
+      <Filter>Source Files\OIS</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\win32\Win32ForceFeedback.cpp">
+      <Filter>Source Files\OIS\Win32</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\win32\Win32InputManager.cpp">
+      <Filter>Source Files\OIS\Win32</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\win32\Win32JoyStick.cpp">
+      <Filter>Source Files\OIS\Win32</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\win32\Win32KeyBoard.cpp">
+      <Filter>Source Files\OIS\Win32</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\OIS\win32\Win32Mouse.cpp">
+      <Filter>Source Files\OIS\Win32</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 15 - 0
CamelotOISInput/Include/OIS/Makefile.am

@@ -0,0 +1,15 @@
+pkginclude_HEADERS = OISConfig.h \
+                     OISEffect.h \
+                     OISEvents.h \
+                     OISException.h \
+                     OISForceFeedback.h \
+                     OISInputManager.h \
+                     OISInterface.h \
+                     OISJoyStick.h \
+                     OISKeyboard.h \
+                     OISMouse.h \
+                     OISObject.h \
+                     OISPrereqs.h \
+                     OISFactoryCreator.h \
+                     OISMultiTouch.h \
+                     OIS.h

+ 41 - 0
CamelotOISInput/Include/OIS/OIS.h

@@ -0,0 +1,41 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_OISALL_H
+#define OIS_OISALL_H
+
+#include "OIS/OISPrereqs.h"
+#include "OIS/OISObject.h"
+#include "OIS/OISMouse.h"
+#include "OIS/OISKeyboard.h"
+#include "OIS/OISJoyStick.h"
+#include "OIS/OISMultiTouch.h"
+#include "OIS/OISInputManager.h"
+#include "OIS/OISFactoryCreator.h"
+#include "OIS/OISException.h"
+#include "OIS/OISEvents.h"
+
+#include "OIS/OISEffect.h"
+#include "OIS/OISInterface.h"
+#include "OIS/OISForceFeedback.h"
+
+#endif

+ 75 - 0
CamelotOISInput/Include/OIS/OISConfig.h

@@ -0,0 +1,75 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_CONFIG_HEADER
+#define OIS_CONFIG_HEADER
+
+//----------------------------------------------------------------------------//
+//* This file contains defines for building certain parts of this Lib
+//*	This file is not meant for External inclusion. However, you can edit this 
+//* file before a build to effect what features are used internally
+//----------------------------------------------------------------------------//
+
+/** 
+@remarks
+	These lines have no bearing on internal build of OIS. This is here for
+	external build settings. Meaning, changing this does not require a
+	rebuild of OIS. This just affects VC dll import settings, as the DLL
+	build already defines this during its build for setting dll exports.
+	The undefine here is here just incase you decide to only use
+	DLL, and want to set it permently and recompile OIS too.. Avoid redefinition
+	from DLL build of OIS.
+
+	So, if wanting to link against DLL version, just uncomment these lines.
+*/
+//#ifdef OIS_DYNAMIC_LIB
+//#  undef OIS_DYNAMIC_LIB
+//#endif
+//#define OIS_DYNAMIC_LIB
+
+/**
+@remarks
+	Build in support for LIRC / WinLIRC - remote control support.
+	Requires Boost::asio
+@notes
+	Experimental - Supports connecting and enumerating. Control does not
+	yet return state or events
+*/
+//#define OIS_LIRC_SUPPORT
+
+/**
+@remarks
+	Build in support for PC Nintendo WiiMote Win32 HID interface.
+	Requires Boost::threads
+@notes
+	Useable, but not quite finished - supports rumble, all buttons, & main orientation axis.
+	Still needs Nunchuck, IR, and LED/Battery support.
+*/
+//#define OIS_WIN32_WIIMOTE_SUPPORT
+
+/**
+@remarks
+	Build in support for Win32 XInput (Xbox 360 Controller)
+*/
+//#define OIS_WIN32_XINPUT_SUPPORT
+
+#endif

+ 278 - 0
CamelotOISInput/Include/OIS/OISEffect.h

@@ -0,0 +1,278 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Effect_H
+#define OIS_Effect_H
+
+#include "OIS/OISPrereqs.h"
+
+namespace OIS
+{
+	//Predeclare some Effect Property structs
+	class ForceEffect;
+	class ConstantEffect;
+	class RampEffect;
+	class PeriodicEffect;
+	class ConditionalEffect;
+
+	/**
+		Force Feedback is a relatively complex set of properties to upload to a device.
+		The best place for information on the different properties, effects, etc is in
+		the DX Documentation and MSDN - there are even pretty graphs ther =)
+		As this class is modeled on the the DX interface you can apply that same
+		knowledge to creating effects via this class on any OS supported by OIS.
+
+		In anycase, this is the main class you will be using. There is *absolutely* no
+		need to instance any of the supporting ForceEffect classes yourself.
+	*/
+	class _OISExport Effect
+	{
+		/**
+			hidden so this class cannot be instanced with default constructor
+		*/
+		Effect();
+	public:
+		//! Type of force
+		enum EForce
+		{
+			UnknownForce = 0,
+			ConstantForce,
+			RampForce,
+			PeriodicForce,
+			ConditionalForce,
+			CustomForce,
+			_ForcesNumber // Always keep in last position.
+		};
+
+		static const char* getForceTypeName(EForce eValue);
+
+		//! Type of effect
+		enum EType
+		{
+			//Type ----- Pairs with force:
+			Unknown = 0, //UnknownForce
+			Constant,    //ConstantForce
+			Ramp,        //RampForce
+			Square,      //PeriodicForce
+			Triangle,    //PeriodicForce
+            Sine,        //PeriodicForce
+			SawToothUp,  //PeriodicForce
+			SawToothDown,//PeriodicForce
+			Friction,    //ConditionalForce
+			Damper,      //ConditionalForce
+			Inertia,     //ConditionalForce
+			Spring,      //ConditionalForce
+			Custom,      //CustomForce
+			_TypesNumber // Always keep in last position.
+		};
+
+		static const char* getEffectTypeName(EType eValue);
+
+		//! Direction of the Force
+		enum EDirection
+		{
+			NorthWest,
+			North,
+			NorthEast,
+			East,
+			SouthEast,
+			South,
+			SouthWest,
+			West,
+			_DirectionsNumber // Always keep in last position.
+		};
+
+		static const char* getDirectionName(EDirection eValue);
+
+		/**
+			This constructor allows you to set the force type and effect.
+		*/
+		Effect(EForce ef, EType et);
+		virtual ~Effect();
+
+		const EForce force;
+		const EType type;
+
+		//Infinite Time
+		static const unsigned int OIS_INFINITE = 0xFFFFFFFF;
+
+		//-------------------------------------------------------------------//
+		//--- Set these variables before uploading or modifying an effect ---//
+
+		//Direction to apply to the force - affects two axes+ effects
+		EDirection direction;
+
+		//Number of button triggering an effect (-1 means no trigger)
+		short trigger_button;
+
+		//Time to wait before an effect can be re-triggered (microseconds)
+		unsigned int trigger_interval;
+
+		//Duration of an effect (microseconds)
+		unsigned int replay_length;
+
+		//Time to wait before to start playing an effect (microseconds)
+		unsigned int replay_delay;
+
+		//Get the specific Force Effect. This should be cast depending on the EForce
+		ForceEffect* getForceEffect() const;
+
+		/**
+		@remarks
+			Set the number of Axes to use before the initial creation of the effect.
+			Can only be done prior to creation! Use the FF interface to determine
+			how many axes can be used (are availiable)
+		*/
+		void setNumAxes(short nAxes);
+
+		/**
+		@remarks
+			Returns the number of axes used in this effect
+		*/
+		short getNumAxes() const;
+
+		//------------- Library Internal -------------------------------------//
+		/**
+			set internally.. do not change or you will not be able to upload/stop
+			this effect any more. It will become lost. It is mutable so even
+			with const reference it can/will be changed by this lib
+		*/
+		mutable int _handle;
+	protected:
+		ForceEffect* effect; //Properties depend on EForce
+		short axes;          //Number of axes to use in effect
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Base class of all effect property classes
+	*/
+	class _OISExport ForceEffect
+	{
+	public:
+		virtual ~ForceEffect() {}
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		An optional envelope to be applied to the start/end of an effect. If any of
+		these values are nonzero, then the envelope will be used in setting up the
+		effect.
+	*/
+	class _OISExport Envelope : public ForceEffect
+	{
+	public:
+		Envelope() : attackLength(0), attackLevel(0), fadeLength(0), fadeLevel(0) {}
+#if defined(OIS_MSVC_COMPILER)
+  #pragma warning (push)
+  #pragma warning (disable : 4800)
+#endif
+		bool isUsed() const { return attackLength | attackLevel | fadeLength | fadeLevel; }
+#if defined(OIS_MSVC_COMPILER)
+  #pragma warning (pop)
+#endif
+
+		// Duration of the attack (microseconds)
+		unsigned int attackLength;
+
+		// Absolute level at the beginning of the attack (0 to 10K)
+		// (automatically signed when necessary by FF core according to effect level sign)
+		unsigned short attackLevel;
+
+		// Duration of fade (microseconds)
+		unsigned int fadeLength;
+
+		// Absolute level at the end of fade (0 to 10K)
+		// (automatically signed when necessary by FF core according to effect level sign)
+		unsigned short fadeLevel;
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Use this class when dealing with Force type of Constant
+	*/
+	class _OISExport ConstantEffect : public ForceEffect
+	{
+	public:
+		ConstantEffect() : level(5000) {}
+
+		class Envelope envelope; //Optional envolope
+		signed short level;       //-10K to +10k
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Use this class when dealing with Force type of Ramp
+	*/
+	class _OISExport RampEffect : public ForceEffect
+	{
+	public:
+		RampEffect() : startLevel(0), endLevel(0) {}
+
+        class Envelope envelope; //Optional envelope
+		signed short startLevel;  //-10K to +10k
+		signed short endLevel;    //-10K to +10k
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Use this class when dealing with Force type of Periodic
+	*/
+	class _OISExport PeriodicEffect : public ForceEffect
+	{
+	public:
+		PeriodicEffect() : magnitude(0), offset(0), phase(0), period(0) {}
+
+		class Envelope envelope;  //Optional Envelope
+
+		unsigned short magnitude;  //0 to 10,0000
+		signed short   offset;
+		unsigned short phase;      //Position at which playback begins 0 to 35,999
+		unsigned int   period;     //Period of effect (microseconds)
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Use this class when dealing with Force type of Condional
+	*/
+	class _OISExport ConditionalEffect : public ForceEffect
+	{
+	public:
+		ConditionalEffect() :
+            rightCoeff(0), leftCoeff(0), rightSaturation(0), leftSaturation(0),
+			deadband(0), center(0) {}
+
+		signed short   rightCoeff;      //-10k to +10k (Positive Coeff)
+		signed short   leftCoeff;       //-10k to +10k (Negative Coeff)
+
+		unsigned short rightSaturation; //0 to 10k (Pos Saturation)
+		unsigned short leftSaturation;  //0 to 10k (Neg Saturation)
+
+		//Region around center in which the condition is not active, in the range
+		//from 0 through 10,000
+		unsigned short deadband;
+
+		//(Offset in DX) -10k and 10k
+		signed short center;
+	};
+}
+#endif //OIS_Effect_H

+ 43 - 0
CamelotOISInput/Include/OIS/OISEvents.h

@@ -0,0 +1,43 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _OIS_EVENTHEADERS_
+#define _OIS_EVENTHEADERS_
+#include "OIS/OISPrereqs.h"
+
+namespace OIS
+{
+	/**
+		Base class of all events
+	*/
+	class _OISExport EventArg
+	{
+	public:
+		EventArg( Object* obj ) : device(obj) {}
+		virtual ~EventArg() {}
+
+		//! Pointer to the Input Device
+		const Object* device;
+	};
+}
+
+#endif //_OIS_EVENTHEADERS_

+ 78 - 0
CamelotOISInput/Include/OIS/OISException.h

@@ -0,0 +1,78 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _OIS_EXCEPTION_HEADER_
+#define _OIS_EXCEPTION_HEADER_
+#include "OIS/OISPrereqs.h"
+#include <exception>
+
+namespace OIS
+{
+	//! Simple enum's for dealing with exceptions
+    enum OIS_ERROR
+	{
+		E_InputDisconnected,
+		E_InputDeviceNonExistant,
+		E_InputDeviceNotSupported,
+		E_DeviceFull,
+		E_NotSupported,
+		E_NotImplemented,
+		E_Duplicate,
+		E_InvalidParam,
+		E_General
+	};
+
+	/**
+	@remarks
+		Class for handling OIS exceptions. Much cleaner than checking every method for reurn value.
+		Inherits from std::exception so you can simply log those messages if you want to be generic.
+		Also note that this has a source file now since OSX was not finding the OIS::Exception symbol
+		which would cause program abortion with now correponding exception type.
+	*/
+	class _OISExport Exception : public std::exception
+	{
+		//! Hidden default
+		Exception() : eType(E_General), eLine(0), eFile(0) {}
+	public:
+		//! Creates exception object
+		Exception( OIS_ERROR err, const char* str, int line, const char *file )
+			: eType(err), eLine(line), eFile(file), eText(str) {}
+
+		~Exception() throw() {}
+
+		virtual const char* what() const throw();
+
+		//! The type of exception raised
+		const OIS_ERROR eType;
+		//! The line number it occurred on
+		const int eLine;
+		//! The source file
+		const char* eFile;
+		//! A message passed along when the exception was raised
+		const char* eText;
+	};
+}
+
+//! Use this macro to handle exceptions easily
+#define OIS_EXCEPT( err, str ) throw( OIS::Exception(err, str, __LINE__, __FILE__) )
+
+#endif //_OIS_EXCEPTION_HEADER_

+ 81 - 0
CamelotOISInput/Include/OIS/OISFactoryCreator.h

@@ -0,0 +1,81 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_FactoryCreator_H
+#define OIS_FactoryCreator_H
+
+#include "OIS/OISPrereqs.h"
+
+namespace OIS
+{
+	/**
+		Interface for creating devices - all devices ultimately get enumerated/created via a factory.
+		A factory can create multiple types of objects.
+	*/
+	class _OISExport FactoryCreator
+	{
+	public:
+		/**
+			@remarks Virtual Destructor
+		*/
+		virtual ~FactoryCreator() {};
+
+		/**
+			@remarks Return a list of all unused devices the factory maintains
+		*/
+		virtual DeviceList freeDeviceList() = 0;
+
+		/**
+			@remarks Number of total devices of requested type
+			@param iType Type of devices to check
+		*/
+		virtual int totalDevices(Type iType) = 0;
+
+		/**
+			@remarks Number of free devices of requested type
+			@param iType Type of devices to check
+		*/
+		virtual int freeDevices(Type iType) = 0;
+
+		/**
+			@remarks Does a Type exist with the given vendor name
+			@param iType Type to check
+			@param vendor Vendor name to test
+		*/
+		virtual bool vendorExist(Type iType, const std::string & vendor) = 0;
+
+		/**
+			@remarks Creates the object
+			@param iType Type to create
+			@param bufferMode True to setup for buffered events
+			@param vendor Create a device with the vendor name, "" means vendor name is unimportant
+		*/
+		virtual Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "") = 0;
+
+		/**
+			@remarks Destroys object
+			@param obj Object to destroy
+		*/
+		virtual void destroyObject(Object* obj) = 0;
+	};
+}
+#endif //OIS_FactoryCreator_H

+ 120 - 0
CamelotOISInput/Include/OIS/OISForceFeedback.h

@@ -0,0 +1,120 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_ForceFeedBack_H
+#define OIS_ForceFeedBack_H
+
+#include "OIS/OISPrereqs.h"
+#include "OIS/OISInterface.h"
+#include "OIS/OISEffect.h"
+
+namespace OIS
+{
+	/**
+		Interface class for dealing with Force Feedback devices
+	*/
+	class _OISExport ForceFeedback : public Interface
+	{
+	public:
+		ForceFeedback();
+		virtual ~ForceFeedback() {}
+
+		/**
+		@remarks
+			This is like setting the master volume of an audio device.
+			Individual effects have gain levels; however, this affects all
+			effects at once.
+			Note: If the device does not support master gain setting, nothing is done
+		@param level
+			A value between 0.0 and 1.0 represent the percentage of gain. 1.0
+			being the highest possible force level (means no scaling).
+		*/
+		virtual void setMasterGain( float level ) = 0;
+		
+		/**
+		@remarks
+			If using Force Feedback effects, this should be turned off
+			before uploading any effects. Auto centering is the motor moving
+			the joystick back to center. DirectInput only has an on/off setting,
+			whereas linux has levels.. Though, we go with DI's on/off mode only
+			Note: If the device does not support auto-centering, nothing is done
+		@param auto_on
+			true to turn auto centering on, false to turn off.
+		*/
+		virtual void setAutoCenterMode( bool auto_on ) = 0;
+
+		/**
+		@remarks
+			Creates and Plays the effect immediately. If the device is full
+			of effects, it will fail to be uploaded. You will know this by
+			an invalid Effect Handle
+		*/
+		virtual void upload( const Effect* effect ) = 0;
+
+		/**
+		@remarks
+			Modifies an effect that is currently playing
+		*/
+		virtual void modify( const Effect* effect ) = 0;
+
+		/**
+		@remarks
+			Remove the effect from the device
+		*/
+		virtual void remove( const Effect* effect ) = 0;
+
+		/**
+		@remarks
+			Get the number of supported Axes for FF usage
+		*/
+        virtual short getFFAxesNumber() = 0;
+
+		/**
+		@remarks
+			Get the current load (%, in [0, 100] of the FF device memory 
+		*/
+		virtual unsigned short getFFMemoryLoad() = 0;
+
+		typedef std::multimap<Effect::EForce, Effect::EType> SupportedEffectList;
+		/**
+		@remarks
+			Get a list of all supported effects
+		*/
+		const SupportedEffectList& getSupportedEffects() const;
+
+		/**
+		@remarks
+			Tell if a given force / effect type pair is supported
+		*/
+		bool supportsEffect(Effect::EForce force, Effect::EType type) const;
+
+		void _addEffectTypes( Effect::EForce force, Effect::EType type );
+		void _setGainSupport( bool on );
+		void _setAutoCenterSupport( bool on );
+
+	protected:
+		SupportedEffectList mSupportedEffects;
+		bool mSetGainSupport;
+		bool mSetAutoCenterSupport;
+	};
+}
+#endif //OIS_ForceFeedBack_H

+ 205 - 0
CamelotOISInput/Include/OIS/OISInputManager.h

@@ -0,0 +1,205 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_InputManager_H
+#define OIS_InputManager_H
+
+#include "OIS/OISPrereqs.h"
+
+namespace OIS
+{
+	//Forward declare a couple of classes we might use later
+	class LIRCFactoryCreator;
+	class WiiMoteFactoryCreator;
+
+	/**
+		Base Manager class. No longer a Singleton; so feel free to create as many InputManager's as you have
+		windows.
+	*/
+	class _OISExport InputManager
+	{
+	public:
+		/**
+		@remarks
+			Returns version number (useful in DLL/SO libs)
+		@returns
+			Bits: 1-8 Patch number, 9-16 Minor version, 17-32 Major version
+		*/
+		static unsigned int getVersionNumber();
+
+		/**
+		@remarks
+			Returns version string (useful in DLL/SO libs)
+		@returns
+			Version name
+		*/
+		const std::string &getVersionName();
+
+		/**
+		@remarks
+			Creates appropriate input system dependent on platform. 
+		@param winHandle
+			Contains OS specific window handle (such as HWND or X11 Window)
+		@returns
+			A pointer to the created manager, or raises Exception
+		*/
+		static InputManager* createInputSystem( std::size_t winHandle );
+
+		/**
+		@remarks
+			Creates appropriate input system dependent on platform. 
+		@param paramList
+			ParamList contains OS specific info (such as HWND and HINSTANCE for window apps),
+			and access mode.
+		@returns
+			A pointer to the created manager, or raises Exception
+		*/
+		static InputManager* createInputSystem( ParamList &paramList );
+
+		/**
+		@remarks
+			Destroys the InputManager
+		@param manager
+			Manager to destroy
+		*/
+		static void destroyInputSystem(InputManager* manager);
+
+		/**
+		@remarks Gets the name of the current platform input system
+		*/
+		const std::string& inputSystemName();
+
+		/**
+		@remarks
+			Returns the number of the specified OIS::Type devices discovered by OIS
+		@param iType
+			Type that you are interested in
+		*/
+		int getNumberOfDevices( Type iType );
+
+		/**
+		@remarks
+			Lists all unused devices
+		@returns
+			DeviceList which contains Type and vendor of device
+		*/
+		DeviceList listFreeDevices();
+
+		/**
+		@remarks
+			Tries to create an object with the specified vendor. If you have no
+			preference of vendor, leave vender as default (""). Raises exception on failure
+		*/
+		Object* createInputObject( Type iType, bool bufferMode, const std::string &vendor = "");
+
+		/**
+		@remarks Destroys Input Object
+		*/
+		void destroyInputObject( Object* obj );
+
+		/**
+		@remarks
+			Add a custom object factory to allow for user controls.
+		@param factory
+			Factory instance to add
+		@notes
+			Make sure you do not delete the factory before devices created from
+			the factory are destroyed (either by calling RemoveFactoryCreator, or shutting down
+			the input system). Order should be something like the following:
+				* Create Input System
+				* Create Factory Instance
+				* AddFactoryCreator(factory)
+				* Create a device from the InputManager (device created by factory)
+				* One of the follwoing:
+					* removeFactoryCreator(factory)
+					* inputManager->destroyInputObject(obj)
+				* destroyInputSystem(inputManager)
+				* destroy Factory Instance
+			You can safely delete the factory instance once you have removed it or shut down the
+			input manager.
+		*/
+		void addFactoryCreator( FactoryCreator* factory );
+
+		/**
+		@remarks
+			Remove a previously added object factory
+		@param factory
+			Factory object to remove.
+		@notes
+			Removing a factory will automatically destroy any Objects created from the factory
+		*/
+		void removeFactoryCreator( FactoryCreator* factory );
+
+		//! All generic devices OIS supports internally (if they are compiled in)
+		enum AddOnFactories
+		{
+			AddOn_All = 0,		//All Devices
+			AddOn_LIRC = 1,		//PC Linux Infrared Remote Control
+			AddOn_WiiMote = 2	//PC WiiMote Support
+		};
+
+		/**
+		@remarks
+			Enable an addon FactoryCreator extension. By default, none are activated.
+			If the desired support was not compiled in, this has no effect. Calling
+			multiple times has no effect. Once activated, there is no way to deactivate -
+			simply destroy and recreate input manager.
+		*/
+		void enableAddOnFactory(AddOnFactories factory);
+
+	protected:
+		/**
+		@remarks
+			Called from createInputSystem, gives derived input class a chance to setup after it is created
+		*/
+		virtual void _initialize(ParamList &paramList) = 0;
+
+		/**
+		@remarks
+			Derived classes must provide input system name
+		*/
+		InputManager(const std::string& name);
+
+		/**
+		@remarks
+			Virtual Destructor - this base class will clean up all devices still opened in mFactoryObjects list
+		*/
+		virtual ~InputManager();
+
+		//! OIS Version name
+		const std::string m_VersionName;
+
+		//! FactoryCreator list	
+		FactoryList mFactories;
+
+		//! Factory created objects - useful so we can find creator to send destruction request to
+		FactoryCreatedObject mFactoryObjects;
+
+		//! Name of the input system
+		const std::string mInputSystemName;
+
+		//! Extra factory (not enabled by default)
+		LIRCFactoryCreator *m_lircSupport;
+		WiiMoteFactoryCreator *m_wiiMoteSupport;
+	};
+}
+#endif

+ 47 - 0
CamelotOISInput/Include/OIS/OISInterface.h

@@ -0,0 +1,47 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Interface_H
+#define OIS_Interface_H
+
+#include "OIS/OISPrereqs.h"
+
+namespace OIS
+{
+	/**
+		An Object's interface is a way to gain write access to devices which support
+		it. For example, force feedack.
+	*/
+	class _OISExport Interface
+	{
+	public:
+		virtual ~Interface() {};
+
+		//! Type of Interface
+		enum IType
+		{
+			ForceFeedback,
+			Reserved
+		};
+	};
+}
+#endif //OIS_Interface_H

+ 228 - 0
CamelotOISInput/Include/OIS/OISJoyStick.h

@@ -0,0 +1,228 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Joystick_H
+#define OIS_Joystick_H
+#include "OIS/OISObject.h"
+#include "OIS/OISEvents.h"
+
+namespace OIS
+{
+	/** @remarks default sensitivity for vector3 component of joystick */
+	#define OIS_JOYSTICK_VECTOR3_DEFAULT 2.28f
+
+	//! POV / HAT Joystick component
+	class _OISExport Pov : public Component
+	{
+	public:
+		Pov() : Component(OIS_POV), direction(0) {}
+
+		static const int Centered  = 0x00000000;
+		static const int North     = 0x00000001;
+		static const int South     = 0x00000010;
+		static const int East      = 0x00000100;
+		static const int West      = 0x00001000;
+		static const int NorthEast = 0x00000101;
+		static const int SouthEast = 0x00000110;
+		static const int NorthWest = 0x00001001;
+		static const int SouthWest = 0x00001010;
+
+		int direction;
+	};
+
+	//! A sliding axis - only used in Win32 Right Now
+	class _OISExport Slider : public Component
+	{
+	public:
+		Slider() : Component(OIS_Slider), abX(0), abY(0) {};
+		//! true if pushed, false otherwise
+		int abX, abY;
+	};
+
+	/**
+		Represents the state of the joystick
+		All members are valid for both buffered and non buffered mode
+		Sticks with zero values are not present on the device
+	*/
+	class _OISExport JoyStickState
+	{
+	public:
+		//! Constructor
+		JoyStickState() { clear(); }
+
+		//! Represents all the buttons (uses a bitset)
+		std::vector<bool> mButtons;
+
+		//! Represents all the single axes on the device
+		std::vector<Axis> mAxes;
+
+		//! Represents the value of a POV. Maximum of 4
+		Pov mPOV[4];
+
+		//! Represent the max sliders
+		Slider mSliders[4];
+
+		//! Represents all Vector type controls the device exports
+		std::vector<Vector3> mVectors;
+
+		//! internal method to reset all variables to initial values
+		void clear()
+		{
+			for( std::vector<bool>::iterator i = mButtons.begin(), e = mButtons.end(); i != e; ++i )
+			{
+				(*i) = false;
+			}
+
+			for( std::vector<Axis>::iterator i = mAxes.begin(), e = mAxes.end(); i != e; ++i )
+			{
+				i->absOnly = true; //Currently, joysticks only report Absolute values
+				i->clear();
+			}
+
+			for( std::vector<Vector3>::iterator i = mVectors.begin(), e = mVectors.end(); i != e; ++i )
+			{
+				i->clear();
+			}
+
+			for( int i = 0; i < 4; ++i )
+			{
+				mPOV[i].direction = Pov::Centered;
+				mSliders[i].abX = mSliders[i].abY = 0;
+			}
+		}
+	};
+
+	/** Specialised for joystick events */
+	class _OISExport JoyStickEvent : public EventArg
+	{
+	public:
+		JoyStickEvent( Object* obj, const JoyStickState &st ) : EventArg(obj), state(st) {}
+		virtual ~JoyStickEvent() {}
+
+		const JoyStickState &state;
+	};
+
+	/**
+		To recieve buffered joystick input, derive a class from this, and implement the
+		methods here. Then set the call back to your JoyStick instance with JoyStick::setEventCallback
+		Each JoyStick instance can use the same callback class, as a devID number will be provided
+		to differentiate between connected joysticks. Of course, each can have a seperate
+		callback instead.
+	*/
+	class _OISExport JoyStickListener
+	{
+	public:
+		virtual ~JoyStickListener() {}
+		/** @remarks Joystick button down event */
+		virtual bool buttonPressed( const JoyStickEvent &arg, int button ) = 0;
+		
+		/** @remarks Joystick button up event */
+		virtual bool buttonReleased( const JoyStickEvent &arg, int button ) = 0;
+
+		/** @remarks Joystick axis moved event */
+		virtual bool axisMoved( const JoyStickEvent &arg, int axis ) = 0;
+
+		//-- Not so common control events, so are not required --//
+		//! Joystick Event, and sliderID
+		virtual bool sliderMoved( const JoyStickEvent &, int index) {return true;}
+		
+		//! Joystick Event, and povID
+		virtual bool povMoved( const JoyStickEvent &arg, int index) {return true;}
+
+		//! Joystick Event, and Vector3ID
+		virtual bool vector3Moved( const JoyStickEvent &arg, int index) {return true;}
+	};
+
+	/**
+		Joystick base class. To be implemented by specific system (ie. DirectX joystick)
+		This class is useful as you remain OS independent using this common interface.
+	*/
+	class _OISExport JoyStick : public Object
+	{
+	public:
+		virtual ~JoyStick() {}
+
+		/**
+		@remarks
+			Returns the number of requested components
+		@param cType
+			The ComponentType you are interested in knowing about
+		*/
+		int getNumberOfComponents(ComponentType cType) const;
+
+		/**
+		@remarks
+			Sets a cutoff limit for changes in the Vector3 component for movement to 
+			be ignored. Helps reduce much event traffic for frequent small/sensitive
+			changes
+		@param degrees
+			The degree under which Vector3 events should be discarded
+		*/
+		void setVector3Sensitivity(float degrees = OIS_JOYSTICK_VECTOR3_DEFAULT);
+
+		/**
+		@remarks
+			Returns the sensitivity cutoff for Vector3 Component
+		*/
+		float getVector3Sensitivity() const;
+
+		/**
+		@remarks
+			Register/unregister a JoyStick Listener - Only one allowed for simplicity. If broadcasting
+			is neccessary, just broadcast from the callback you registered.
+		@param joyListener
+			Send a pointer to a class derived from JoyStickListener or 0 to clear the callback
+		*/
+		virtual void setEventCallback( JoyStickListener *joyListener );
+
+		/** @remarks Returns currently set callback.. or null */
+		JoyStickListener* getEventCallback() const;
+
+		/** @remarks Returns the state of the joystick - is valid for both buffered and non buffered mode */
+		const JoyStickState& getJoyStickState() const { return mState; }
+
+		//! The minimal axis value
+		static const int MIN_AXIS = -32768;
+
+		//! The maximum axis value
+		static const int MAX_AXIS = 32767;
+
+	protected:
+		JoyStick(const std::string &vendor, bool buffered, int devID, InputManager* creator);
+
+		//! Number of sliders
+		int mSliders;
+
+		//! Number of POVs
+		int mPOVs;
+
+		//! The JoyStickState structure (contains all component values)
+		JoyStickState mState;
+
+		//! The callback listener
+		JoyStickListener *mListener;
+
+		//! Adjustment factor for orientation vector accuracy
+		float mVector3Sensitivity;
+	};
+}
+#endif

+ 312 - 0
CamelotOISInput/Include/OIS/OISKeyboard.h

@@ -0,0 +1,312 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Keyboard_H
+#define OIS_Keyboard_H
+#include "OIS/OISObject.h"
+#include "OIS/OISEvents.h"
+
+namespace OIS
+{
+	//! Keyboard scan codes
+	enum KeyCode
+	{
+		KC_UNASSIGNED  = 0x00,
+		KC_ESCAPE      = 0x01,
+		KC_1           = 0x02,
+		KC_2           = 0x03,
+		KC_3           = 0x04,
+		KC_4           = 0x05,
+		KC_5           = 0x06,
+		KC_6           = 0x07,
+		KC_7           = 0x08,
+		KC_8           = 0x09,
+		KC_9           = 0x0A,
+		KC_0           = 0x0B,
+		KC_MINUS       = 0x0C,    // - on main keyboard
+		KC_EQUALS      = 0x0D,
+		KC_BACK        = 0x0E,    // backspace
+		KC_TAB         = 0x0F,
+		KC_Q           = 0x10,
+		KC_W           = 0x11,
+		KC_E           = 0x12,
+		KC_R           = 0x13,
+		KC_T           = 0x14,
+		KC_Y           = 0x15,
+		KC_U           = 0x16,
+		KC_I           = 0x17,
+		KC_O           = 0x18,
+		KC_P           = 0x19,
+		KC_LBRACKET    = 0x1A,
+		KC_RBRACKET    = 0x1B,
+		KC_RETURN      = 0x1C,    // Enter on main keyboard
+		KC_LCONTROL    = 0x1D,
+		KC_A           = 0x1E,
+		KC_S           = 0x1F,
+		KC_D           = 0x20,
+		KC_F           = 0x21,
+		KC_G           = 0x22,
+		KC_H           = 0x23,
+		KC_J           = 0x24,
+		KC_K           = 0x25,
+		KC_L           = 0x26,
+		KC_SEMICOLON   = 0x27,
+		KC_APOSTROPHE  = 0x28,
+		KC_GRAVE       = 0x29,    // accent
+		KC_LSHIFT      = 0x2A,
+		KC_BACKSLASH   = 0x2B,
+		KC_Z           = 0x2C,
+		KC_X           = 0x2D,
+		KC_C           = 0x2E,
+		KC_V           = 0x2F,
+		KC_B           = 0x30,
+		KC_N           = 0x31,
+		KC_M           = 0x32,
+		KC_COMMA       = 0x33,
+		KC_PERIOD      = 0x34,    // . on main keyboard
+		KC_SLASH       = 0x35,    // / on main keyboard
+		KC_RSHIFT      = 0x36,
+		KC_MULTIPLY    = 0x37,    // * on numeric keypad
+		KC_LMENU       = 0x38,    // left Alt
+		KC_SPACE       = 0x39,
+		KC_CAPITAL     = 0x3A,
+		KC_F1          = 0x3B,
+		KC_F2          = 0x3C,
+		KC_F3          = 0x3D,
+		KC_F4          = 0x3E,
+		KC_F5          = 0x3F,
+		KC_F6          = 0x40,
+		KC_F7          = 0x41,
+		KC_F8          = 0x42,
+		KC_F9          = 0x43,
+		KC_F10         = 0x44,
+		KC_NUMLOCK     = 0x45,
+		KC_SCROLL      = 0x46,    // Scroll Lock
+		KC_NUMPAD7     = 0x47,
+		KC_NUMPAD8     = 0x48,
+		KC_NUMPAD9     = 0x49,
+		KC_SUBTRACT    = 0x4A,    // - on numeric keypad
+		KC_NUMPAD4     = 0x4B,
+		KC_NUMPAD5     = 0x4C,
+		KC_NUMPAD6     = 0x4D,
+		KC_ADD         = 0x4E,    // + on numeric keypad
+		KC_NUMPAD1     = 0x4F,
+		KC_NUMPAD2     = 0x50,
+		KC_NUMPAD3     = 0x51,
+		KC_NUMPAD0     = 0x52,
+		KC_DECIMAL     = 0x53,    // . on numeric keypad
+		KC_OEM_102     = 0x56,    // < > | on UK/Germany keyboards
+		KC_F11         = 0x57,
+		KC_F12         = 0x58,
+		KC_F13         = 0x64,    //                     (NEC PC98)
+		KC_F14         = 0x65,    //                     (NEC PC98)
+		KC_F15         = 0x66,    //                     (NEC PC98)
+		KC_KANA        = 0x70,    // (Japanese keyboard)
+		KC_ABNT_C1     = 0x73,    // / ? on Portugese (Brazilian) keyboards
+		KC_CONVERT     = 0x79,    // (Japanese keyboard)
+		KC_NOCONVERT   = 0x7B,    // (Japanese keyboard)
+		KC_YEN         = 0x7D,    // (Japanese keyboard)
+		KC_ABNT_C2     = 0x7E,    // Numpad . on Portugese (Brazilian) keyboards
+		KC_NUMPADEQUALS= 0x8D,    // = on numeric keypad (NEC PC98)
+		KC_PREVTRACK   = 0x90,    // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
+		KC_AT          = 0x91,    //                     (NEC PC98)
+		KC_COLON       = 0x92,    //                     (NEC PC98)
+		KC_UNDERLINE   = 0x93,    //                     (NEC PC98)
+		KC_KANJI       = 0x94,    // (Japanese keyboard)
+		KC_STOP        = 0x95,    //                     (NEC PC98)
+		KC_AX          = 0x96,    //                     (Japan AX)
+		KC_UNLABELED   = 0x97,    //                        (J3100)
+		KC_NEXTTRACK   = 0x99,    // Next Track
+		KC_NUMPADENTER = 0x9C,    // Enter on numeric keypad
+		KC_RCONTROL    = 0x9D,
+		KC_MUTE        = 0xA0,    // Mute
+		KC_CALCULATOR  = 0xA1,    // Calculator
+		KC_PLAYPAUSE   = 0xA2,    // Play / Pause
+		KC_MEDIASTOP   = 0xA4,    // Media Stop
+		KC_VOLUMEDOWN  = 0xAE,    // Volume -
+		KC_VOLUMEUP    = 0xB0,    // Volume +
+		KC_WEBHOME     = 0xB2,    // Web home
+		KC_NUMPADCOMMA = 0xB3,    // , on numeric keypad (NEC PC98)
+		KC_DIVIDE      = 0xB5,    // / on numeric keypad
+		KC_SYSRQ       = 0xB7,
+		KC_RMENU       = 0xB8,    // right Alt
+		KC_PAUSE       = 0xC5,    // Pause
+		KC_HOME        = 0xC7,    // Home on arrow keypad
+		KC_UP          = 0xC8,    // UpArrow on arrow keypad
+		KC_PGUP        = 0xC9,    // PgUp on arrow keypad
+		KC_LEFT        = 0xCB,    // LeftArrow on arrow keypad
+		KC_RIGHT       = 0xCD,    // RightArrow on arrow keypad
+		KC_END         = 0xCF,    // End on arrow keypad
+		KC_DOWN        = 0xD0,    // DownArrow on arrow keypad
+		KC_PGDOWN      = 0xD1,    // PgDn on arrow keypad
+		KC_INSERT      = 0xD2,    // Insert on arrow keypad
+		KC_DELETE      = 0xD3,    // Delete on arrow keypad
+		KC_LWIN        = 0xDB,    // Left Windows key
+		KC_RWIN        = 0xDC,    // Right Windows key
+		KC_APPS        = 0xDD,    // AppMenu key
+		KC_POWER       = 0xDE,    // System Power
+		KC_SLEEP       = 0xDF,    // System Sleep
+		KC_WAKE        = 0xE3,    // System Wake
+		KC_WEBSEARCH   = 0xE5,    // Web Search
+		KC_WEBFAVORITES= 0xE6,    // Web Favorites
+		KC_WEBREFRESH  = 0xE7,    // Web Refresh
+		KC_WEBSTOP     = 0xE8,    // Web Stop
+		KC_WEBFORWARD  = 0xE9,    // Web Forward
+		KC_WEBBACK     = 0xEA,    // Web Back
+		KC_MYCOMPUTER  = 0xEB,    // My Computer
+		KC_MAIL        = 0xEC,    // Mail
+		KC_MEDIASELECT = 0xED     // Media Select
+	};
+
+	/**
+		Specialised for key events
+	*/
+	class _OISExport KeyEvent : public EventArg
+	{
+	public:
+		KeyEvent(Object* obj, KeyCode kc, unsigned int txt) : EventArg(obj), key(kc), text(txt) {}
+		virtual ~KeyEvent() {}
+
+		//! KeyCode of event
+		const KeyCode key;
+		//! Text character, depends on current TextTranslationMode
+		unsigned int text;
+	};
+
+	/**
+		To recieve buffered keyboard input, derive a class from this, and implement the
+		methods here. Then set the call back to your Keyboard instance with Keyboard::setEventCallback
+	*/
+	class _OISExport KeyListener
+	{
+	public:
+		virtual ~KeyListener() {}
+		virtual bool keyPressed(const KeyEvent &arg) = 0;
+		virtual bool keyReleased(const KeyEvent &arg) = 0;		
+	};
+
+	/**
+		Keyboard base class. To be implemented by specific system (ie. DirectX Keyboard)
+		This class is useful as you remain OS independent using this common interface.
+	*/
+	class _OISExport Keyboard : public Object
+	{
+	public:
+		virtual ~Keyboard() {};
+		
+		/**
+		@remarks
+			Returns true if key is donwn
+		@param key
+			A KeyCode to check
+		*/
+		virtual bool isKeyDown(KeyCode key) const = 0;
+
+		/**
+		@remarks
+			Register/unregister a Keyboard Listener - Only one allowed for simplicity. If broadcasting
+			is neccessary, just broadcast from the callback you registered.
+		@param keyListener
+			Send a pointer to a class derived from KeyListener or 0 to clear the callback
+		*/
+		virtual void setEventCallback(KeyListener *keyListener) { mListener = keyListener;}
+
+		/**
+		@remarks
+			Returns currently set callback.. or 0
+		*/
+		KeyListener* getEventCallback() const {return mListener;}
+
+		//! TextTranslation Mode
+		enum TextTranslationMode
+		{
+			Off,
+			Unicode,
+			Ascii
+		};
+
+		/**
+		@remarks
+			Enable extra processing to translate KC_*** to an
+			actual text character based off of locale. Different 
+			managers may implement none or all. Check the 
+			translation mode after setting to be sure
+		@param mode
+			Off, Unicode, Ascii
+		*/
+		virtual void setTextTranslation(TextTranslationMode mode);
+
+		/**
+		@remarks
+			Returns current translation mode
+		*/
+		TextTranslationMode getTextTranslation() const {return mTextMode;}
+		
+		/**
+		@remarks
+			Translates KeyCode to string representation.
+			For example, KC_ENTER will be "Enter" - Locale
+			specific of course.
+		@param kc
+			KeyCode to convert
+		@returns
+			The string as determined from the current locale
+		*/
+		virtual const std::string& getAsString(KeyCode kc) = 0;
+
+		//! Enum of bit position of modifer
+		enum Modifier
+		{
+			Shift = 0x0000001,
+			Ctrl  = 0x0000010,
+			Alt   = 0x0000100
+		};
+
+		/**
+		@remarks
+			Check modifier status
+		*/
+		bool isModifierDown(Modifier mod) const;
+
+		/**
+		@remarks
+			Copies the state of the keys into the sent buffer
+			(in the form of 1 is down and 0 is up)
+		*/
+		virtual void copyKeyStates(char keys[256]) const = 0;
+		
+	protected:
+		Keyboard(const std::string &vendor, bool buffered, int devID, InputManager* creator)
+			: Object(vendor, OISKeyboard, buffered, devID, creator),
+			mModifiers(0), mListener(0), mTextMode(Unicode) {}
+
+		//! Bit field that holds status of Alt, Ctrl, Shift
+		unsigned int mModifiers;
+
+		//! Used for buffered/actionmapping callback
+		KeyListener *mListener;
+
+		//! The current translation mode
+		TextTranslationMode mTextMode;
+	};
+}
+#endif

+ 138 - 0
CamelotOISInput/Include/OIS/OISMouse.h

@@ -0,0 +1,138 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Mouse_H
+#define OIS_Mouse_H
+#include "OIS/OISObject.h"
+#include "OIS/OISEvents.h"
+
+namespace OIS
+{
+	//! Button ID for mouse devices
+	enum MouseButtonID
+	{
+		MB_Left = 0, MB_Right, MB_Middle,
+		MB_Button3, MB_Button4,	MB_Button5, MB_Button6,	MB_Button7
+	};
+
+	/**
+		Represents the state of the mouse
+		All members are valid for both buffered and non buffered mode
+	*/
+	class _OISExport MouseState
+	{
+	public:
+		MouseState() : width(50), height(50), buttons(0) {};
+
+		/** Represents the height/width of your display area.. used if mouse clipping
+		or mouse grabbed in case of X11 - defaults to 50.. Make sure to set this
+		and change when your size changes.. */
+		mutable int width, height;
+
+		//! X Axis component
+		Axis X;
+
+		//! Y Axis Component
+		Axis Y;
+
+		//! Z Axis Component
+		Axis Z;
+
+		//! represents all buttons - bit position indicates button down
+		int buttons;
+
+		//! Button down test
+		inline bool buttonDown( MouseButtonID button ) const
+		{
+			return ((buttons & ( 1L << button )) == 0) ? false : true;
+		}
+
+		//! Clear all the values
+		void clear()
+		{
+			X.clear();
+			Y.clear();
+			Z.clear();
+			buttons = 0;
+		}
+	};
+
+	/** Specialised for mouse events */
+	class _OISExport MouseEvent : public EventArg
+	{
+	public:
+		MouseEvent( Object *obj, const MouseState &ms )	: EventArg(obj), state(ms) {}
+		virtual ~MouseEvent() {}
+
+		//! The state of the mouse - including buttons and axes
+		const MouseState &state;
+	};
+
+	/**
+		To recieve buffered mouse input, derive a class from this, and implement the
+		methods here. Then set the call back to your Mouse instance with Mouse::setEventCallback
+	*/
+	class _OISExport MouseListener
+	{
+	public:
+		virtual ~MouseListener() {}
+		virtual bool mouseMoved( const MouseEvent &arg ) = 0;
+		virtual bool mousePressed( const MouseEvent &arg, MouseButtonID id ) = 0;
+		virtual bool mouseReleased( const MouseEvent &arg, MouseButtonID id ) = 0;
+	};
+
+	/**
+		Mouse base class. To be implemented by specific system (ie. DirectX Mouse)
+		This class is useful as you remain OS independent using this common interface.
+	*/
+	class _OISExport Mouse : public Object
+	{
+	public:
+		virtual ~Mouse() {}
+
+		/**
+		@remarks
+			Register/unregister a Mouse Listener - Only one allowed for simplicity. If broadcasting
+			is neccessary, just broadcast from the callback you registered.
+		@param mouseListener
+			Send a pointer to a class derived from MouseListener or 0 to clear the callback
+		*/
+		virtual void setEventCallback( MouseListener *mouseListener ) {mListener = mouseListener;}
+
+		/** @remarks Returns currently set callback.. or 0 */
+		MouseListener* getEventCallback() const {return mListener;}
+
+		/** @remarks Returns the state of the mouse - is valid for both buffered and non buffered mode */
+		const MouseState& getMouseState() const { return mState; }
+
+	protected:
+		Mouse(const std::string &vendor, bool buffered, int devID, InputManager* creator)
+			: Object(vendor, OISMouse, buffered, devID, creator), mListener(0) {}
+
+		//! The state of the mouse
+		MouseState mState;
+
+		//! Used for buffered/actionmapping callback
+		MouseListener *mListener;
+	};
+}
+#endif

+ 169 - 0
CamelotOISInput/Include/OIS/OISMultiTouch.h

@@ -0,0 +1,169 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_MultiTouch_H
+#define OIS_MultiTouch_H
+#include "OIS/OISObject.h"
+#include "OIS/OISEvents.h"
+
+#include <set>
+#include <vector>
+
+#define OIS_MAX_NUM_TOUCHES 4   // 4 finger touches are probably the highest we'll ever get
+
+namespace OIS
+{
+	/**
+		Represents the state of the multi-touch device
+		All members are valid for both buffered and non buffered mode
+	*/
+    
+	//! Touch Event type
+	enum MultiTypeEventTypeID
+	{
+		MT_None = 0, MT_Pressed, MT_Released, MT_Moved, MT_Cancelled
+	};
+
+	class _OISExport MultiTouchState
+	{
+	public:
+		MultiTouchState() : width(50), height(50), touchType(MT_None) {};
+
+		/** Represents the height/width of your display area.. used if touch clipping
+		or touch grabbed in case of X11 - defaults to 50.. Make sure to set this
+		and change when your size changes.. */
+		mutable int width, height;
+
+		//! X Axis component
+		Axis X;
+
+		//! Y Axis Component
+		Axis Y;
+
+		//! Z Axis Component
+		Axis Z;
+
+        int touchType;
+
+        inline bool touchIsType( MultiTypeEventTypeID touch ) const
+		{
+			return ((touchType & ( 1L << touch )) == 0) ? false : true;
+		}
+        
+		//! Clear all the values
+		void clear()
+		{
+			X.clear();
+			Y.clear();
+			Z.clear();
+            touchType = MT_None;
+		}
+	};
+
+	/** Specialised for multi-touch events */
+	class _OISExport MultiTouchEvent : public EventArg
+	{
+	public:
+		MultiTouchEvent( Object *obj, const MultiTouchState &ms ) : EventArg(obj), state(ms) {}
+		virtual ~MultiTouchEvent() {}
+
+		//! The state of the touch - including axes
+		const MultiTouchState &state;
+	};
+
+	/**
+		To receive buffered touch input, derive a class from this, and implement the
+		methods here. Then set the call back to your MultiTouch instance with MultiTouch::setEventCallback
+	*/
+	class _OISExport MultiTouchListener
+	{
+	public:
+		virtual ~MultiTouchListener() {}
+		virtual bool touchMoved( const MultiTouchEvent &arg ) = 0;
+		virtual bool touchPressed( const MultiTouchEvent &arg ) = 0;
+		virtual bool touchReleased( const MultiTouchEvent &arg ) = 0;
+		virtual bool touchCancelled( const MultiTouchEvent &arg ) = 0;
+	};
+
+	/**
+		MultiTouch base class. To be implemented by specific system (ie. iPhone UITouch)
+		This class is useful as you remain OS independent using this common interface.
+	*/
+	class _OISExport MultiTouch : public Object
+	{
+	public:
+		virtual ~MultiTouch() {}
+
+		/**
+		@remarks
+			Register/unregister a MultiTouch Listener - Only one allowed for simplicity. If broadcasting
+			is necessary, just broadcast from the callback you registered.
+		@param touchListener
+			Send a pointer to a class derived from MultiTouchListener or 0 to clear the callback
+		*/
+		virtual void setEventCallback( MultiTouchListener *touchListener ) {mListener = touchListener;}
+
+		/** @remarks Returns currently set callback.. or 0 */
+		MultiTouchListener* getEventCallback() {return mListener;}
+
+		/** @remarks Clear out the set of input states.  Should be called after input has been processed by the application */
+        void clearStates(void) { mStates.clear(); }
+
+		/** @remarks Returns the state of the touch - is valid for both buffered and non buffered mode */
+		std::vector<MultiTouchState> getMultiTouchStates() const { return mStates; }
+        
+        /** @remarks Returns the first n touch states.  Useful if you know your app only needs to 
+                process n touches.  The return value is a vector to allow random access */
+        const std::vector<MultiTouchState> getFirstNTouchStates(int n) {
+            std::vector<MultiTouchState> states;
+            for( unsigned int i = 0; i < mStates.size(); i++ ) {
+                if(!(mStates[i].touchIsType(MT_None))) {
+                    states.push_back(mStates[i]);
+                }
+            }
+            return states;
+        }
+
+        /** @remarks Returns the first n touch states.  Useful if you know your app only needs to 
+         process n touches.  The return value is a vector to allow random access */
+        const std::vector<MultiTouchState> getMultiTouchStatesOfType(MultiTypeEventTypeID type) {
+            std::vector<MultiTouchState> states;
+            for( unsigned int i = 0; i < mStates.size(); i++ ) {
+                if(mStates[i].touchIsType(type)) {
+                    states.push_back(mStates[i]);
+                }
+            }
+            return states;
+        }
+        
+	protected:
+		MultiTouch(const std::string &vendor, bool buffered, int devID, InputManager* creator)
+			: Object(vendor, OISMultiTouch, buffered, devID, creator), mListener(0) {}
+
+		//! The state of the touch device, implemented in a vector to store the state from each finger touch
+        std::vector<MultiTouchState> mStates;
+
+		//! Used for buffered/actionmapping callback
+		MultiTouchListener *mListener;
+	};
+}
+#endif

+ 95 - 0
CamelotOISInput/Include/OIS/OISObject.h

@@ -0,0 +1,95 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Object_H
+#define OIS_Object_H
+
+#include "OIS/OISPrereqs.h"
+#include "OIS/OISInterface.h"
+
+namespace OIS
+{
+	/**	The base class of all input types. */
+	class _OISExport Object
+	{
+	public:
+		virtual ~Object() {}
+
+		/**	@remarks Get the type of device	*/
+		Type type() const { return mType; }
+
+		/**	@remarks Get the vender string name	*/
+		const std::string& vendor() const { return mVendor; }
+
+		/**	@remarks Get buffered mode - true is buffered, false otherwise */
+		virtual bool buffered() const { return mBuffered; }
+
+		/** @remarks Returns this input object's creator */
+		InputManager* getCreator() const { return mCreator; }
+
+		/** @remarks Sets buffered mode	*/
+		virtual void setBuffered(bool buffered) = 0;
+
+		/**	@remarks Used for updating call once per frame before checking state or to update events */
+		virtual void capture() = 0;
+
+		/**	@remarks This may/may not) differentiate the different controllers based on (for instance) a port number (useful for console InputManagers) */
+		virtual int getID() const {return mDevID;}
+
+		/**
+		@remarks
+			If available, get an interface to write to some devices.
+			Examples include, turning on and off LEDs, ForceFeedback, etc
+		@param type
+			The type of interface you are looking for
+		*/
+		virtual Interface* queryInterface(Interface::IType type) = 0;
+
+		/**	@remarks Internal... Do not call this directly. */
+		virtual void _initialize() = 0;
+
+	protected:
+		Object(const std::string &vendor, Type iType, bool buffered,
+			   int devID, InputManager* creator) :
+					mVendor(vendor),
+					mType(iType),
+					mBuffered(buffered),
+					mDevID(devID),
+					mCreator(creator) {}
+
+		//! Vendor name if applicable/known
+		std::string mVendor;
+
+		//! Type of controller object
+		Type mType;
+
+		//! Buffered flag
+		bool mBuffered;
+
+		//! Not fully implemented yet
+		int mDevID;
+
+		//! The creator who created this object
+		InputManager* mCreator;
+	};
+}
+#endif

+ 226 - 0
CamelotOISInput/Include/OIS/OISPrereqs.h

@@ -0,0 +1,226 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Prereqs_H
+#define OIS_Prereqs_H
+//----------------------------------------------------------------------------//
+// This Header File contains: forward declared classes
+//  * Forward Declarations of all public API classes
+//  * Several typedef's used around the library
+//  * Base class component types
+//  * Preprocessor definitons
+//----------------------------------------------------------------------------//
+
+//-------------- Common STL Containers ---------------------------------------//
+#include <vector>
+#include <string>
+#include <map>
+#include "OIS/OISConfig.h"
+
+// Default is blank for most OS's
+#define _OISExport
+
+//-------------- Determine Compiler ---------------------------------
+#if defined( _MSC_VER )
+#	define OIS_MSVC_COMPILER
+#elif defined( __GNUC__ )
+#	if defined( __WIN32__ ) || defined( _WIN32 )
+#		define OIS_MINGW_COMPILER
+#	else
+#		define OIS_GCC_COMPILER
+#	endif
+#elif defined( __BORLANDC__ )
+#	define OIS_BORLAND_COMPILER
+#else
+#	error No Recognized Compiler!
+#endif
+
+// --------------- Determine Operating System Platform ---------------
+#if defined( __WIN32__ ) || defined( _WIN32 ) // Windows 2000, XP, ETC
+#	if defined ( _XBOX )
+#		define OIS_XBOX_PLATFORM
+#	else
+#		define OIS_WIN32_PLATFORM
+#		if defined( OIS_DYNAMIC_LIB )
+#			undef _OISExport
+			//Ignorable Dll interface warning...
+#           if !defined(OIS_MINGW_COMPILER)
+#			    pragma warning (disable : 4251)
+#           endif
+#			if defined( OIS_NONCLIENT_BUILD )
+#				define _OISExport __declspec( dllexport )
+#			else
+#               if defined(OIS_MINGW_COMPILER)
+#                   define _OISExport
+#               else
+#				    define _OISExport __declspec( dllimport )
+#               endif
+#			endif
+#		endif
+#	endif
+#elif defined( __APPLE_CC__ ) // Apple OS X
+    // Device                                       Simulator
+#   if __IPHONE_OS_VERSION_MIN_REQUIRED >= 20201 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000
+//#   if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000
+#       define OIS_IPHONE_PLATFORM
+#   else
+#       define OIS_APPLE_PLATFORM
+#   endif
+#   undef _OISExport
+#   define _OISExport __attribute__((visibility("default")))
+#else //Probably Linux
+#	define OIS_LINUX_PLATFORM
+#endif
+
+//Is Processor 32 or 64 bits...
+#if defined(__x86_64__)
+#	define OIS_ARCH_64
+#else
+#	define OIS_ARCH_32
+#endif
+
+//-------------- Common Classes, Enums, and Typdef's -------------------------//
+#define OIS_VERSION_MAJOR 1
+#define OIS_VERSION_MINOR 3
+#define OIS_VERSION_PATCH 0
+#define OIS_VERSION_NAME "1.3.0"
+
+#define OIS_VERSION ((OIS_VERSION_MAJOR << 16) | (OIS_VERSION_MINOR << 8) | OIS_VERSION_PATCH)
+
+namespace OIS
+{
+	//Forward Declarations
+	class InputManager;
+	class FactoryCreator;
+	class Object;
+	class Keyboard;
+	class Mouse;
+	class JoyStick;
+    class MultiTouch;
+	class KeyListener;
+	class MouseListener;
+    class MultiTouchListener;
+	class JoyStickListener;
+	class Interface;
+	class ForceFeedback;
+	class Effect;
+	class Exception;
+
+	//! Way to send OS nuetral parameters.. ie OS Window handles, modes, flags
+	typedef std::multimap<std::string, std::string> ParamList;
+
+	//! List of FactoryCreator's
+	typedef std::vector<FactoryCreator*> FactoryList;
+
+	//! Map of FactoryCreator created Objects
+	typedef std::map<Object*, FactoryCreator*> FactoryCreatedObject;
+
+	//! Each Input class has a General Type variable, a form of RTTI
+    enum Type
+	{
+		OISUnknown       = 0,
+		OISKeyboard      = 1,
+		OISMouse         = 2,
+		OISJoyStick      = 3,
+		OISTablet        = 4,
+		OISMultiTouch    = 5
+	};
+
+	//! Map of device objects connected and their respective vendors
+	typedef std::multimap<Type, std::string> DeviceList;
+
+	//--------     Shared common components    ------------------------//
+
+	//! Base type for all device components (button, axis, etc)
+    enum ComponentType
+	{
+		OIS_Unknown = 0,
+		OIS_Button  = 1, //ie. Key, mouse button, joy button, etc
+		OIS_Axis    = 2, //ie. A joystick or mouse axis
+		OIS_Slider  = 3, //
+		OIS_POV     = 4, //ie. Arrow direction keys
+		OIS_Vector3 = 5  //ie. WiiMote orientation
+	};
+
+	//! Base of all device components (button, axis, etc)
+	class _OISExport Component
+	{
+	public:
+		Component() : cType(OIS_Unknown) {};
+		Component(ComponentType type) : cType(type) {};
+		//! Indicates what type of coponent this is
+		ComponentType cType;
+	};
+
+	//! Button can be a keyboard key, mouse button, etc
+	class _OISExport Button : public Component
+	{
+	public:
+		Button() : Component(OIS_Button), pushed(false) {}
+		Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {}
+		//! true if pushed, false otherwise
+		bool pushed;
+	};
+
+	//! Axis component
+	class _OISExport Axis : public Component
+	{
+	public:
+		Axis() : Component(OIS_Axis), abs(0), rel(0), absOnly(false) {};
+
+		//! Absoulte and Relative value components
+		int abs, rel;
+
+		//! Indicates if this Axis only supports Absoulte (ie JoyStick)
+		bool absOnly;
+
+		//! Used internally by OIS
+		void clear()
+		{
+			abs = rel = 0;
+		}
+	};
+
+	//! A 3D Vector component (perhaps an orientation, as in the WiiMote)
+	class _OISExport Vector3 : public Component
+	{
+	public:
+		Vector3() {}
+		Vector3(float _x, float _y, float _z) : Component(OIS_Vector3), x(_x), y(_y), z(_z) {};
+		
+		//! X component of vector
+		float x;
+		
+		//! Y component of vector
+		float y;
+
+		//! Z component of vector
+		float z;
+
+		void clear()
+		{
+			x = y = z = 0.0f;
+		}
+	};
+}
+
+#endif //end if prereq header defined

+ 73 - 0
CamelotOISInput/Include/OIS/SDL/SDLInputManager.h

@@ -0,0 +1,73 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_SDLInputManager_H
+#define OIS_SDLInputManager_H
+
+#include "OISInputManager.h"
+#include "SDL/SDLPrereqs.h"
+
+namespace OIS
+{
+	/**
+		SDL Input Manager wrapper
+	*/
+	class SDLInputManager : public InputManager
+	{
+	public:
+		SDLInputManager();
+		virtual ~SDLInputManager();
+
+		/** @copydoc InputManager::inputSystemName */
+		virtual const std::string& inputSystemName() { return iName; }
+		
+		/** @copydoc InputManager::numJoysticks */
+		virtual int numJoySticks();
+		/** @copydoc InputManager::numMice */
+		virtual int numMice();
+		/** @copydoc InputManager::numKeyBoards */
+		virtual int numKeyboards();
+		
+		/** @copydoc InputManager::createInputObject */
+		Object* createInputObject( Type iType, bool bufferMode );
+		/** @copydoc InputManager::destroyInputObject */
+		void destroyInputObject( Object* obj );
+
+		/** @copydoc InputManager::_initialize */
+		void _initialize( ParamList &paramList );
+
+		//Utility methods to coordinate between mouse and keyboard grabbing
+		bool _getGrabMode() {return mGrabbed;};
+		void _setGrabMode(bool grabbed) {mGrabbed = grabbed;}
+
+	protected:
+		//! internal class method for dealing with param list
+		void _parseConfigSettings( ParamList &paramList );
+		//! internal class method for finding attached devices
+		void _enumerateDevices();
+
+		static const std::string iName;
+
+		bool mGrabbed;
+	};
+}
+#endif

+ 0 - 0
CamelotOISInput/Include/OIS/SDL/SDLJoyStick.h


+ 79 - 0
CamelotOISInput/Include/OIS/SDL/SDLKeyboard.h

@@ -0,0 +1,79 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _OIS_SDLKEYBOARD_H
+#define _OIS_SDLKEYBOARD_H
+
+#include "OISKeyboard.h"
+#include "SDL/SDLPrereqs.h"
+
+namespace OIS
+{
+	class SDLKeyboard : public Keyboard
+	{
+	public:
+		/**
+		@remarks
+			Constructor
+		@param buffered
+			True for buffered input mode
+		*/
+		SDLKeyboard( bool buffered );
+		virtual ~SDLKeyboard();
+
+		/** @copydoc Keyboard::isKeyDown */
+		virtual bool isKeyDown( KeyCode key );
+
+		/** @copydoc Keyboard::getAsString */
+		virtual const std::string& getAsString( KeyCode kc );
+
+		/** @copydoc Keyboard::copyKeyStates */
+		virtual void copyKeyStates( char keys[256] );
+
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+		/** @copydoc Object::setTextTranslation */
+		virtual void setTextTranslation( TextTranslationMode mode );
+
+	protected:
+		SDLKeyboard() {}
+
+		typedef std::map<SDLKey, KeyCode> KeyMap;
+        KeyMap mKeyMap;
+
+		unsigned char KeyBuffer[256];
+		Uint8* mSDLBuff;
+
+		std::string mGetString;
+	};
+}
+#endif

+ 59 - 0
CamelotOISInput/Include/OIS/SDL/SDLMouse.h

@@ -0,0 +1,59 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+	1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+	2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+	3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _OIS_SDLMOUSE_H
+#define _OIS_SDLMOUSE_H
+
+#include "OISMouse.h"
+#include "SDL/SDLPrereqs.h"
+
+namespace OIS
+{
+	class SDLMouse : public Mouse
+	{
+	public:
+		SDLMouse( bool buffered );
+		virtual ~SDLMouse();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+		void _setGrab(bool grabbed);
+		void _setVisible(bool visible);
+
+	protected:
+		SDLMouse() {}
+
+		bool mGrabbed;
+		bool mRegainFocus;
+	};
+}
+#endif

+ 38 - 0
CamelotOISInput/Include/OIS/SDL/SDLPrereqs.h

@@ -0,0 +1,38 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_SDLPrereqs_H
+#define OIS_SDLPrereqs_H
+
+#include "OISPrereqs.h"
+
+#ifdef OIS_APPLE_PLATFORM
+#  include <SDL/SDL.h>
+#else
+#  include <SDL.h>
+#endif
+
+#define OIS_SDL_KEY_BUFF   16
+#define OIS_SDL_MOUSE_BUFF 50
+#define OIS_SDL_JOY_BUFF   80
+
+#endif

+ 50 - 0
CamelotOISInput/Include/OIS/iphone/iPhoneAccelerometer.h

@@ -0,0 +1,50 @@
+#ifndef OIS_iPhoneAccelerometer_H
+#define OIS_iPhoneAccelerometer_H
+
+#include "OISJoystick.h"
+#include "iphone/iPhonePrereqs.h"
+
+#import <UIKit/UIKit.h>
+@class iPhoneAccelerometerDelegate;
+
+class JoyStickState;
+
+namespace OIS
+{
+	class iPhoneAccelerometer : public JoyStick
+    {
+	public:
+		iPhoneAccelerometer(InputManager* creator, bool buffered);
+		virtual ~iPhoneAccelerometer();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+        void setUpdateInterval(float interval) { 
+            mUpdateInterval = interval;
+            [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0f / mUpdateInterval)];
+        }
+        
+        Vector3 getAccelerometerVector3(void) { return mState.mVectors[0]; }
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+        void didAccelerate(UIAcceleration *acceleration);
+
+    protected:
+        iPhoneAccelerometerDelegate *accelerometerDelegate;
+
+        /** The update frequency of the accelerometer.  Represented in times per second. */
+        float mUpdateInterval;
+        Vector3 mTempState;
+	};
+}
+
+
+#endif // OIS_iPhoneAccelerometer_H

+ 56 - 0
CamelotOISInput/Include/OIS/iphone/iPhoneHelpers.h

@@ -0,0 +1,56 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_iPhoneHelpers_H
+#define OIS_iPhoneHelpers_H
+
+#include "iphone/iPhonePrereqs.h"
+#include "OISMultiTouch.h"
+
+// This is needed for keeping an event stack for keyboard and mouse
+namespace OIS
+{
+    // used in the eventStack to store the type
+    enum iPhone_EventType { iPhone_KEYUP = 0,
+                         iPhone_KEYDOWN = 1,
+                         iPhone_KEYREPEAT,
+                         iPhone_MOUSEDOWN,
+                         iPhone_MOUSEUP,
+                         iPhone_MOUSEMOVED,
+                         iPhone_MOUSESCROLL};
+    typedef enum iPhone_EventType iPhoneEventType;
+
+    // only used by iPhoneMultiTouch
+    typedef class iPhoneMultiTouchStackEvent
+    {
+        friend class iPhoneMultiTouch;
+        
+    private:
+        iPhoneMultiTouchStackEvent( MultiTouchEvent event, iPhoneEventType type) : Event(event), Type(type) {}
+        
+        iPhoneEventType Type;
+        MultiTouchEvent Event;
+        
+    } iPhoneMultiTouchStackEvent;
+}
+
+#endif

+ 110 - 0
CamelotOISInput/Include/OIS/iphone/iPhoneInputManager.h

@@ -0,0 +1,110 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_iPhoneInputManager_H
+#define OIS_iPhoneInputManager_H
+
+#include "OISInputManager.h"
+#include "OISFactoryCreator.h"
+#include "iphone/iPhonePrereqs.h"
+
+#import <UIKit/UIKit.h>
+namespace OIS {
+    class iPhoneAccelerometer;
+    class iPhoneMultiTouch;
+}
+
+@interface InputDelegate : UIView <UIAccelerometerDelegate> {
+    OIS::iPhoneAccelerometer    *accelerometerObject;
+    OIS::iPhoneMultiTouch       *touchObject;
+}
+
+@property (assign) OIS::iPhoneAccelerometer     *accelerometerObject;
+@property (assign) OIS::iPhoneMultiTouch        *touchObject;
+
+@end
+
+namespace OIS
+{
+
+    class iPhoneInputManager : public InputManager, public FactoryCreator
+    {
+    public:
+        iPhoneInputManager();
+        virtual ~iPhoneInputManager();
+        
+		//InputManager Overrides
+		/** @copydoc InputManager::_initialize */
+		void _initialize( ParamList &paramList );
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+		//Internal Items
+
+		//! Internal method, used for flagging multi-touch as available/unavailable for creation
+		void _setMultiTouchUsed(bool used) { bMultiTouchUsed = used; }
+
+        //! Internal method, used for flagging accelerometer as available/unavailable for creation
+		void _setAccelerometerUsed(bool used) { bAccelerometerUsed = used; }
+
+        //! methodfor getting the delegate
+        InputDelegate * _getDelegate() { return mDelegate; }
+
+        //! method for getting window
+        UIWindow * _getWindow() { return mWindow; }
+
+    protected:        
+        void _parseConfigSettings( ParamList& paramList );
+
+        // iPhone stuff
+		UIWindow *mWindow;
+        InputDelegate *mDelegate;
+
+        // settings
+        bool mHideMouse;
+
+		//! Used to know if we used up multi-touch device
+		bool bMultiTouchUsed;
+
+        //! Used to know if we used up accelerometer
+		bool bAccelerometerUsed;
+    };
+}
+
+#endif

+ 64 - 0
CamelotOISInput/Include/OIS/iphone/iPhoneMultiTouch.h

@@ -0,0 +1,64 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that
+ you wrote the original software. If you use this software in a product,
+ an acknowledgment in the product documentation would be appreciated but is
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+#ifndef OIS_iPhoneMultiTouch_H
+#define OIS_iPhoneMultiTouch_H
+
+#include "OISMultiTouch.h"
+#include "iphone/iPhonePrereqs.h"
+
+#import <UIKit/UIKit.h>
+
+struct CGPoint;
+
+namespace OIS
+{
+	class iPhoneMultiTouch : public MultiTouch
+    {
+	public:
+		iPhoneMultiTouch( InputManager* creator, bool buffered );
+		virtual ~iPhoneMultiTouch();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+        void _touchBegan(UITouch *touch);
+        void _touchEnded(UITouch *touch);
+        void _touchMoved(UITouch *touch);
+        void _touchCancelled(UITouch *touch);
+        
+	protected:
+		MultiTouchState mTempState;
+	};
+}
+
+
+#endif // OIS_iPhoneTouch_H

+ 56 - 0
CamelotOISInput/Include/OIS/iphone/iPhonePrereqs.h

@@ -0,0 +1,56 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_iPhonePrereqs_H
+#define OIS_iPhonePrereqs_H
+
+#include <string>
+#include <list>
+#include <CoreFoundation/CoreFoundation.h>
+
+namespace OIS
+{
+    class iPhoneInputManager;
+    class iPhoneAccelerometer;
+	class iPhoneMouse;
+
+	/** 
+		Simple wrapper class for CFString which will create a valid CFString and retain ownership until class instance is outof scope
+		To Access the CFStringRef instance, simply cast to void*, pass into a function expecting a void* CFStringRef object, or access via cf_str() method
+	*/
+	class OIS_CFString
+	{
+	public:
+		OIS_CFString() { m_StringRef = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8); }
+		OIS_CFString(const char* c_str) { m_StringRef = CFStringCreateWithCString(NULL, c_str, kCFStringEncodingUTF8); }
+		OIS_CFString(const std::string &s_str) { m_StringRef = CFStringCreateWithCString(NULL, s_str.c_str(), kCFStringEncodingUTF8); }
+		~OIS_CFString() { CFRelease(m_StringRef); }
+
+		//Allow this class to be autoconverted to base class of StringRef (void*)
+		operator void*() { return (void*)m_StringRef; }
+		CFStringRef cf_str() { return m_StringRef; }
+	
+	private:
+		CFStringRef m_StringRef;
+	};
+}
+#endif

+ 49 - 0
CamelotOISInput/Include/OIS/linux/EventHelpers.h

@@ -0,0 +1,49 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _LINUX_OISEVENT_HEADER_
+#define _LINUX_OISEVENT_HEADER_
+
+#include "linux/LinuxPrereqs.h"
+
+#define OIS_MAX_DEVICES 32
+#define OIS_DEVICE_NAME 128
+
+namespace OIS
+{
+	class EventUtils
+	{
+	public:
+		static bool isJoyStick( int deviceID, JoyStickInfo &js );
+		static bool isMouse( int ) {return false;}
+		static bool isKeyboard( int ) {return false;}
+
+		//Double pointer is so that we can set the value of the sent pointer
+		static void enumerateForceFeedback( int deviceID, LinuxForceFeedback** ff );
+		static void removeForceFeedback( LinuxForceFeedback** ff );
+
+		static std::string getName( int deviceID );
+		static std::string getUniqueId( int deviceID );
+		static std::string getPhysicalLocation( int deviceID );
+	};
+}
+#endif

+ 85 - 0
CamelotOISInput/Include/OIS/linux/LinuxForceFeedback.h

@@ -0,0 +1,85 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_LinuxForceFeedBack_H
+#define OIS_LinuxForceFeedBack_H
+
+#include "linux/LinuxPrereqs.h"
+#include "OISForceFeedback.h"
+#include <linux/input.h>
+
+namespace OIS
+{
+	class LinuxForceFeedback : public ForceFeedback
+	{
+	public:
+		LinuxForceFeedback(int deviceID);
+		~LinuxForceFeedback();
+
+		/** @copydoc ForceFeedback::setMasterGain */
+		void setMasterGain(float);
+		
+		/** @copydoc ForceFeedback::setAutoCenterMode */
+		void setAutoCenterMode(bool);
+
+		/** @copydoc ForceFeedback::upload */
+		void upload( const Effect* effect );
+
+		/** @copydoc ForceFeedback::modify */
+		void modify( const Effect* effect );
+
+		/** @copydoc ForceFeedback::remove */
+		void remove( const Effect* effect );
+
+		/** FF is not yet implemented fully on Linux.. just return -1 for now. todo, xxx */
+		short int getFFAxesNumber() { return -1; }
+
+		/** @copydoc ForceFeedback::getFFMemoryLoad */
+		unsigned short getFFMemoryLoad();
+
+	protected:
+
+		//Sets the common properties to all effects
+		void _setCommonProperties(struct ff_effect *event, struct ff_envelope *ffenvelope, 
+								  const Effect* effect, const Envelope *envelope );
+
+		//Specific Effect Settings
+		void _updateConstantEffect( const Effect* effect );
+		void _updateRampEffect( const Effect* effect );
+		void _updatePeriodicEffect( const Effect* effect );
+		void _updateConditionalEffect( const Effect* effect );
+		//void _updateCustomEffect( const Effect* effect );
+
+		void _upload( struct ff_effect* ffeffect, const Effect* effect);
+		void _stop( int handle);
+		void _start( int handle);
+		void _unload( int handle);
+
+		// Map of currently uploaded effects (handle => effect)
+		typedef std::map<int, struct ff_effect *> EffectList;
+		EffectList mEffectList;
+
+		// Joystick device (file) descriptor.
+		int mJoyStick;
+	};
+}
+#endif //OIS_LinuxForceFeedBack_H

+ 105 - 0
CamelotOISInput/Include/OIS/linux/LinuxInputManager.h

@@ -0,0 +1,105 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_LinuxInputManager_H
+#define OIS_LinuxInputManager_H
+
+#include "linux/LinuxPrereqs.h"
+#include "OISFactoryCreator.h"
+#include "OISInputManager.h"
+#include <X11/Xlib.h>
+
+namespace OIS
+{
+	/**
+		Linux X11 InputManager specialization - Using lowlevel joys
+	*/
+	class LinuxInputManager : public InputManager, public FactoryCreator
+	{
+	public:
+		LinuxInputManager();
+		virtual ~LinuxInputManager();
+
+		//InputManager Overrides
+		/** @copydoc InputManager::_initialize */
+		void _initialize( ParamList &paramList );
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager *creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+		//Internal Items
+		//! Method for retrieving the XWindow Handle
+		Window _getWindow() {return window;}
+
+		//! Internal method for checking if regrabbing is needed
+		void _setGrabState(bool grab) {mGrabs = grab;}
+		bool _getGrabState() {return mGrabs;}
+
+		//! Internal method, used for flaggin keyboard as available/unavailable for creation
+		void _setKeyboardUsed(bool used) {keyboardUsed = used; }
+
+		//! Internal method, used for flaggin mouse as available/unavailable for creation
+		void _setMouseUsed(bool used) { mouseUsed = used; }
+		
+	protected:
+		//! internal class method for dealing with param list
+		void _parseConfigSettings( ParamList &paramList );
+		//! internal class method for finding attached devices
+		void _enumerateDevices();
+
+		//! List of unused joysticks ready to be used
+		JoyStickInfoList unusedJoyStickList;
+		//! Number of joysticks found
+		char joySticks;
+
+		//! Used to know if we used up keyboard
+		bool keyboardUsed;
+
+		//! Used to know if we used up mouse
+		bool mouseUsed;
+
+		//! X11 Stuff
+		Window window;
+		
+		/// Keyboard, Mouse Settings
+		bool grabMouse, grabKeyboard;
+		bool mGrabs;
+		bool hideMouse;
+	};
+}
+#endif

+ 72 - 0
CamelotOISInput/Include/OIS/linux/LinuxJoyStickEvents.h

@@ -0,0 +1,72 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _LINUX_JOYSTICK_H_EADER_
+#define _LINUX_JOYSTICK_H_EADER_
+
+#include "linux/LinuxPrereqs.h"
+#include "OISJoyStick.h"
+
+namespace OIS
+{
+	/**
+		Linux specialization of JoyStick class.. This version is favored over the other.. and has the
+		*possibility* of Force Feedback.. notice I say possibility, i make no gaurantees under linux,
+		as FF support is sketchy at best AFAIK.
+	*/
+	class LinuxJoyStick : public JoyStick
+	{
+	public:
+		LinuxJoyStick(InputManager* creator, bool buffered, const JoyStickInfo& js);
+		virtual ~LinuxJoyStick();
+
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type);
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+		/**
+		@remarks
+			For internal use only... Returns a structure to the manager, to make the device
+			availiable for use again
+		*/
+		JoyStickInfo _getJoyInfo();
+
+		static JoyStickInfoList _scanJoys();
+		static void _clearJoys(JoyStickInfoList &joys);
+	protected:
+
+		int mJoyStick;
+		LinuxForceFeedback* ff_effect;
+		std::map <int, int> mButtonMap;
+		std::map <int, int> mAxisMap;
+		std::map <int, Range> mRanges;
+	};
+}
+#endif //_LINUX_JOYSTICK_H_EADER_

+ 98 - 0
CamelotOISInput/Include/OIS/linux/LinuxKeyboard.h

@@ -0,0 +1,98 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _LINUX_KEYBOARD_H_EADER_
+#define _LINUX_KEYBOARD_H_EADER_
+
+#include "linux/LinuxPrereqs.h"
+#include "OISKeyboard.h"
+#include <X11/Xlib.h>
+
+namespace OIS
+{
+	/** Linux implementation of Keyboard object - uses x11 */
+	class LinuxKeyboard : public Keyboard
+	{
+	public:
+		LinuxKeyboard(InputManager* creator, bool buffered, bool grab);
+		virtual ~LinuxKeyboard();
+
+		/** @copydoc Keyboard::isKeyDown */
+		virtual bool isKeyDown( KeyCode key ) const;
+
+		/** @copydoc Keyboard::getAsString */
+		virtual const std::string& getAsString( KeyCode kc );
+
+		/** @copydoc Keyboard::copyKeyStates */
+		virtual void copyKeyStates( char keys[256] ) const;
+
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+	protected:
+		inline bool _isKeyRepeat(XEvent &event)
+		{
+			//When a key is repeated, there will be two events: released, followed by another immediate pressed. So check to see if another pressed is present	
+			if(!XPending(display))
+				return false;
+
+			XEvent e;
+			XPeekEvent(display, &e);
+			if(e.type == KeyPress && e.xkey.keycode == event.xkey.keycode && (e.xkey.time - event.xkey.time) < 2)
+			{
+				XNextEvent(display, &e);
+				return true;
+			}
+
+			return false;
+		}
+
+		bool _injectKeyDown( KeySym key, int text );
+		bool _injectKeyUp( KeySym key );
+
+		//! 1:1 Conversion Map between X Key Events and OIS KeyCodes
+		typedef std::map<KeySym, KeyCode> XtoOIS_KeyMap;
+		XtoOIS_KeyMap keyConversion;
+
+		//! Depressed Key List
+		char KeyBuffer[256];
+
+		//! X11 Stuff
+		Window window;
+		Display *display;
+		bool grabKeyboard;
+		bool keyFocusLost;
+
+		std::string mGetString;
+	};
+}
+
+#endif //_LINUX_KEYBOARD_H_EADER_

+ 75 - 0
CamelotOISInput/Include/OIS/linux/LinuxMouse.h

@@ -0,0 +1,75 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _LINUX_MOUSE_H_EADER_
+#define _LINUX_MOUSE_H_EADER_
+
+#include "linux/LinuxPrereqs.h"
+#include "OISMouse.h"
+#include <X11/Xlib.h>
+
+namespace OIS
+{
+	class LinuxMouse : public Mouse
+	{
+	public:
+		LinuxMouse(InputManager* creator, bool buffered, bool grab, bool hide);
+		virtual ~LinuxMouse();
+
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/**
+		@remarks
+			Note: Calling this will also update the keyboard (X11 updates in a single
+			event queue). Updates State and/or raises event for buffered mode..
+		*/
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+		void grab(bool grab);
+		void hide(bool hide);
+
+	protected:
+		void _processXEvents();
+
+		bool mMoved, mWarped;
+
+		//Since X11 provides us with absolute values, we need to keep track of relative values
+		long oldXMouseX, oldXMouseY, oldXMouseZ;
+
+		Window window;		//The X Window
+		Display *display;	//The X display
+		Cursor cursor;		//A blank cursor
+
+		bool grabMouse;		//Are we grabbing the mouse to the window?
+		bool hideMouse;		//Are we hiding OS mouse?
+		bool mouseFocusLost;//Has the mouse just lost focus?
+	};
+}
+
+#endif //_LINUX_MOUSE_H_EADER_

+ 82 - 0
CamelotOISInput/Include/OIS/linux/LinuxPrereqs.h

@@ -0,0 +1,82 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _LINUX_INPUTSYSTEM_PREREQS_H
+#define _LINUX_INPUTSYSTEM_PREREQS_H
+
+//Bring in any auto generated config files
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "OISPrereqs.h"
+
+//! Max number of elements to collect from buffered input
+#define JOY_BUFFERSIZE 64
+
+namespace OIS
+{
+	class LinuxInputManager;
+	class LinuxKeyboard;
+	class LinuxJoyStick;
+	class LinuxMouse;
+	
+	class LinuxForceFeedback;
+
+	class Range
+	{
+	public:
+		Range() {};
+		Range(int _min, int _max) : min(_min), max(_max) {};
+		int min, max;
+	};
+
+	class JoyStickInfo
+	{
+	public:
+		JoyStickInfo(): devId(-1),joyFileD(-1),version(0),axes(0),buttons(0),hats(0) {}
+		//! Device number (/dev/input/j#) or /dev/input/event#
+		int devId;
+		//! File descriptor
+		int joyFileD;
+		//! Driver version
+		int version;
+		//! Joy vendor
+		std::string vendor;
+		//! Number of axes
+		unsigned char axes;
+		//! Number of buttons
+		unsigned char buttons;
+		//! Number of hats
+		unsigned char hats;
+		//! Maps Linux button values to OIS buttons values
+		std::map<int, int> button_map;
+		//! Maps Linux axis values to OIS axis
+		std::map<int, int> axis_map;
+		//! Maps OIS axis values to it's range
+		std::map<int, Range> axis_range;
+	};
+
+	typedef std::vector< JoyStickInfo > JoyStickInfoList;
+}
+
+#endif //_LINUX_INPUTSYSTEM_PREREQS_H

+ 103 - 0
CamelotOISInput/Include/OIS/mac/MacHIDManager.h

@@ -0,0 +1,103 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2007 Phillip
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_MacHIDManager_Header
+#define OIS_MacHIDManager_Header
+
+#include "OISPrereqs.h"
+#include "mac/MacPrereqs.h"
+#include "OISFactoryCreator.h"
+
+#import <CoreFoundation/CFString.h>
+#import <IOKit/IOKitLib.h>
+#import <IOKit/IOCFPlugIn.h>
+#import <IOKit/hid/IOHIDLib.h>
+#import <IOKit/hid/IOHIDKeys.h>
+#import <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
+
+namespace OIS
+{
+	//Information needed to create Mac HID Devices
+	class HidInfo
+	{
+	public:
+		HidInfo() : type(OISUnknown), numButtons(0), numHats(0), numAxes(0), inUse(false), interface(0)
+		{
+		}
+
+		//Useful tracking information
+		Type type;
+		std::string vendor;
+		std::string productKey;
+		std::string combinedKey;
+
+		//Retain some count information for recreating devices without having to reparse
+		int numButtons;
+		int numHats;
+		int numAxes;
+		bool inUse;
+
+		//Used for opening a read/write/tracking interface to device
+		IOHIDDeviceInterface **interface;
+	};
+
+	typedef std::vector<HidInfo*> HidInfoList;
+		
+	class MacHIDManager : public FactoryCreator
+	{
+	public:
+		MacHIDManager();
+		~MacHIDManager();
+
+		void initialize();
+		
+		void iterateAndOpenDevices(io_iterator_t iterator);
+		io_iterator_t lookUpDevices(int usage, int page);
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+	private:
+		HidInfo* enumerateDeviceProperties(CFMutableDictionaryRef propertyMap);
+		void parseDeviceProperties(CFDictionaryRef properties);
+		void parseDevicePropertiesGroup(CFDictionaryRef properties);
+
+		HidInfoList mDeviceList;		
+	};
+}
+#endif

+ 94 - 0
CamelotOISInput/Include/OIS/mac/MacHelpers.h

@@ -0,0 +1,94 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_MacHelpers_H
+#define OIS_MacHelpers_H
+
+#include "mac/MacPrereqs.h"
+#include "OISEvents.h"
+#include "OISKeyboard.h"
+#include "OISMouse.h"
+
+#include <Carbon/Carbon.h>
+
+// This is a hack needed to get the event handler working. 
+// The carbon lib expects a "OSStatus (*)(EventHandlerCallRef, EventRef, void*)",
+// so I cannot give it a class member function (unless it is static which is pointless)
+// Instead, I just pass the class* through the last paramter that gets passed to the
+// callback every time an event occurs. Then I dereference it and call the member function.
+OSStatus KeyDownWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass );
+
+OSStatus KeyUpWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass );
+
+OSStatus KeyModWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass );
+
+OSStatus MouseWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass );
+
+
+// This is needed for keeping an event stack for keyboard and mouse
+namespace OIS
+{
+    
+    // used in the eventStack to store the type
+    enum Mac_EventType { MAC_KEYUP = 0,
+                         MAC_KEYDOWN = 1,
+                         MAC_KEYREPEAT,
+                         MAC_MOUSEDOWN,
+                         MAC_MOUSEUP,
+                         MAC_MOUSEMOVED,
+                         MAC_MOUSESCROLL};
+    typedef enum Mac_EventType MacEventType;
+    
+    
+    // only used by MacKeyboard
+    typedef class Mac_KeyStackEvent
+    {
+        friend class MacKeyboard;
+        
+        
+    private:
+        Mac_KeyStackEvent( KeyEvent event, MacEventType type ) : Event(event), Type(type) {}
+        
+        MacEventType Type;
+        KeyEvent Event;
+    } MacKeyStackEvent;
+ 
+    
+
+    // only used by MacMouse
+    typedef class Mac_MouseStackEvent
+    {
+        friend class MacMouse;
+        
+    private:
+        Mac_MouseStackEvent( MouseEvent event, MacEventType type,  MouseButtonID button) : Event(event), Type(type), Button(button) {}
+        
+        MacEventType Type;
+        MouseEvent Event;
+		MouseButtonID Button;
+        
+    } MacMouseStackEvent;
+        
+}
+
+
+#endif

+ 101 - 0
CamelotOISInput/Include/OIS/mac/MacInputManager.h

@@ -0,0 +1,101 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_MacInputManager_H
+#define OIS_MacInputManager_H
+
+#include "OISInputManager.h"
+#include "OISFactoryCreator.h"
+#include "mac/MacPrereqs.h"
+#include <Carbon/Carbon.h>
+
+namespace OIS
+{
+    
+    class MacInputManager : public InputManager, public FactoryCreator
+    {
+    public:
+        MacInputManager();
+        virtual ~MacInputManager();
+        
+		//InputManager Overrides
+		/** @copydoc InputManager::_initialize */
+		void _initialize( ParamList &paramList );
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+		//Internal Items
+		//! Internal method, used for flaggin keyboard as available/unavailable for creation
+		void _setKeyboardUsed(bool used) {keyboardUsed = used; }
+
+		//! Internal method, used for flaggin mouse as available/unavailable for creation
+		void _setMouseUsed(bool used) { mouseUsed = used; }
+        
+        //! methodfor getting the event target
+        EventTargetRef _getEventTarget() {return mEventTargetRef;}
+        
+        //! method for getting window
+        WindowRef _getWindow() {return mWindow;}
+        
+    protected:        
+        void _parseConfigSettings( ParamList& paramList );
+        
+        void _enumerateDevices();
+        
+        static const std::string iName;
+        
+        // Mac stuff
+		EventTargetRef mEventTargetRef;
+		WindowRef mWindow;
+        
+        // settings
+        bool mHideMouse;
+        bool mUseRepeat;
+
+		//! Used to know if we used up keyboard
+		bool keyboardUsed;
+
+		//! Used to know if we used up mouse
+		bool mouseUsed;
+		
+		//! HID Manager class handling devices other than keyboard/mouse
+		MacHIDManager *mHIDManager;
+    };
+}
+#endif

+ 76 - 0
CamelotOISInput/Include/OIS/mac/MacJoyStick.h

@@ -0,0 +1,76 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that
+ you wrote the original software. If you use this software in a product,
+ an acknowledgment in the product documentation would be appreciated but is
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+#ifndef MAC_Joystick_H
+#define MAC_Joystick_H
+#include "OISJoyStick.h"
+#include "mac/MacPrereqs.h"
+#include "mac/MacHIDManager.h"
+
+namespace OIS
+{
+	struct AxisInfo
+	{
+		int min;
+		int max;
+		
+		AxisInfo(int min, int max)
+			: min(min), max(max) {}
+	};
+	
+	typedef struct cookie_struct 
+	{ 
+		std::map<IOHIDElementCookie, AxisInfo> axisCookies; 			
+		std::vector<IOHIDElementCookie> buttonCookies; 
+	} cookie_struct_t; 
+	
+	//class HidDeviceInfo
+	
+	class MacJoyStick : public JoyStick
+	{
+	public:
+		MacJoyStick(const std::string& vendor, bool buffered, HidInfo* info, InputManager* creator, int devID);
+		
+		virtual ~MacJoyStick();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+		
+		/** @copydoc Object::capture */
+		virtual void capture();
+		
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type);
+		
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+		
+		void _enumerateCookies();
+		
+		IOHIDQueueInterface** _createQueue(unsigned int depth = 8);
+	protected:
+		HidInfo* mInfo;
+		cookie_struct_t mCookies;
+		IOHIDQueueInterface** mQueue;
+	};
+}
+#endif

+ 102 - 0
CamelotOISInput/Include/OIS/mac/MacKeyboard.h

@@ -0,0 +1,102 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_MacKeyboard_H
+#define OIS_MacKeyboard_H
+
+#include "OISKeyboard.h"
+#include "mac/MacHelpers.h"
+#include "mac/MacPrereqs.h"
+
+#include <Carbon/Carbon.h>
+
+namespace OIS
+{
+    
+    class MacKeyboard : public Keyboard
+    {
+    public:
+        MacKeyboard( InputManager* creator, bool buffered, bool repeat );
+        virtual ~MacKeyboard();
+        
+        // Sets buffered mode
+        virtual void setBuffered( bool buffered );
+        
+        // unbuffered keydown check
+        virtual bool isKeyDown( KeyCode key ) const;
+        
+        // This will send listener events if buffered is on.
+        // Note that in the mac implementation, unbuffered input is
+        // automatically updated without calling this.
+        virtual void capture();
+        
+        // Copies the current key buffer
+        virtual void copyKeyStates( char keys[256] ) const;
+        
+        // Returns a description of the given key
+        virtual std::string& getAsString( KeyCode key );
+        
+        virtual Interface* queryInterface( Interface::IType type ) { return 0; }
+        
+        
+        // Public but reserved for internal use:
+        virtual void _initialize();
+        void _keyDownCallback( EventRef theEvent );
+        void _keyUpCallback( EventRef theEvent );
+        void _modChangeCallback( EventRef theEvent );
+        
+
+    protected:
+        // just to get this out of the way
+        void populateKeyConversion();
+        
+        // updates the keybuffer and optionally the eventStack
+        void injectEvent(KeyCode kc, unsigned int time, MacEventType type, unsigned int txt = 0 );
+                
+        typedef std::map<UInt32, KeyCode> VirtualtoOIS_KeyMap;
+        VirtualtoOIS_KeyMap keyConversion;
+        
+        std::string getString;
+        
+        char KeyBuffer[256];
+        UInt32 prevModMask;
+        
+        
+        // "universal procedure pointers" - required reference for callbacks
+        EventHandlerUPP keyDownUPP;
+        EventHandlerUPP keyUpUPP;
+        EventHandlerUPP keyModUPP;
+        
+        // so we can delete the handlers on destruction
+        EventHandlerRef keyDownEventRef;
+        EventHandlerRef keyUpEventRef;
+        EventHandlerRef keyModEventRef;
+        
+        // buffered events, fifo stack
+        typedef std::list<MacKeyStackEvent> eventStack;
+        eventStack pendingEvents;
+        
+        bool useRepeat;
+        
+    };
+}
+#endif

+ 51 - 0
CamelotOISInput/Include/OIS/mac/MacMouse.h

@@ -0,0 +1,51 @@
+#ifndef OIS_MacMouse_H
+#define OIS_MacMouse_H
+
+#include "OISMouse.h"
+#include "mac/MacHelpers.h"
+#include "mac/MacPrereqs.h"
+
+#include <Carbon/Carbon.h>
+
+namespace OIS
+{
+	class MacMouse : public Mouse
+    {
+	public:
+		MacMouse( InputManager* creator, bool buffered );
+		virtual ~MacMouse();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+        
+	public:
+        void _mouseCallback( EventRef theEvent );
+
+	protected:
+		static OSStatus WindowFocusChanged(EventHandlerCallRef nextHandler, EventRef event, void* macMouse);
+        
+        // "universal procedure pointers" - required reference for callbacks
+		EventHandlerUPP mouseUPP;
+		EventHandlerRef mouseEventRef;
+		
+		EventHandlerUPP mWindowFocusListener;
+		EventHandlerRef mWindowFocusHandler;
+		
+		bool mNeedsToRegainFocus;
+		bool mMouseWarped;
+		
+		MouseState mTempState;
+	};
+}
+
+
+#endif // OIS_MacMouse_H

+ 57 - 0
CamelotOISInput/Include/OIS/mac/MacPrereqs.h

@@ -0,0 +1,57 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_MacPrereqs_H
+#define OIS_MacPrereqs_H
+
+#include <string>
+#include <list>
+#include <CoreFoundation/CoreFoundation.h>
+
+namespace OIS
+{
+    class MacInputManager;
+	class MacHIDManager;
+	class MacMouse;
+    class MacKeyboard;
+
+	/** 
+		Simple wrapper class for CFString which will create a valid CFString and retain ownership until class instance is outof scope
+		To Access the CFStringRef instance, simply cast to void*, pass into a function expecting a void* CFStringRef object, or access via cf_str() method
+	*/
+	class OIS_CFString
+	{
+	public:
+		OIS_CFString() { m_StringRef = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8); }
+		OIS_CFString(const char* c_str) { m_StringRef = CFStringCreateWithCString(NULL, c_str, kCFStringEncodingUTF8); }
+		OIS_CFString(const std::string &s_str) { m_StringRef = CFStringCreateWithCString(NULL, s_str.c_str(), kCFStringEncodingUTF8); }
+		~OIS_CFString() { CFRelease(m_StringRef); }
+
+		//Allow this class to be autoconverted to base class of StringRef (void*)
+		operator void*() { return (void*)m_StringRef; }
+		CFStringRef cf_str() { return m_StringRef; }
+	
+	private:
+		CFStringRef m_StringRef;
+	};
+}
+#endif

+ 108 - 0
CamelotOISInput/Include/OIS/win32/Win32ForceFeedback.h

@@ -0,0 +1,108 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Win32ForceFeedBack_H
+#define OIS_Win32ForceFeedBack_H
+
+#include "OIS/OISPrereqs.h"
+#include "OIS/OISForceFeedback.h"
+#include "OIS/win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	class Win32ForceFeedback : public ForceFeedback
+	{
+		Win32ForceFeedback() {}
+	public:
+		Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps);
+		~Win32ForceFeedback();
+
+		/** @copydoc ForceFeedback::upload */
+		void upload( const Effect* effect );
+
+		/** @copydoc ForceFeedback::modify */
+		void modify( const Effect* effect );
+
+		/** @copydoc ForceFeedback::remove */
+		void remove( const Effect* effect );
+
+		/** @copydoc ForceFeedback::setMasterGain */
+		void setMasterGain( float level );
+		
+		/** @copydoc ForceFeedback::setAutoCenterMode */
+		void setAutoCenterMode( bool auto_on );
+
+		/** @copydoc ForceFeedback::getFFAxesNumber */
+		short getFFAxesNumber();
+
+		/** @copydoc ForceFeedback::getFFMemoryLoad */
+		unsigned short getFFMemoryLoad();
+
+		/**
+			@remarks
+			Internal use.. Used during enumeration to build a list of a devices
+			support effects.
+		*/
+		void _addEffectSupport( LPCDIEFFECTINFO pdei );
+
+		/**
+			@remarks
+			Internal use.. Used during axis enumeration to get number of FF axes
+			support effects.
+		*/
+		void _addFFAxis();
+
+	protected:
+
+		//Specific Effect Settings
+		void _updateConstantEffect( const Effect* effect );
+		void _updateRampEffect( const Effect* effect );
+		void _updatePeriodicEffect( const Effect* effect );
+		void _updateConditionalEffect( const Effect* effect );
+		void _updateCustomEffect( const Effect* effect );
+
+		//Sets the common properties to all effects
+		void _setCommonProperties( DIEFFECT* diEffect, DWORD* rgdwAxes,
+									LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size, 
+									LPVOID struct_type, const Effect* effect, const Envelope* envelope );
+		//Actually do the upload
+		void _upload( GUID, DIEFFECT*, const Effect* );
+
+		// Map of currently uploaded effects (handle => effect)
+		typedef std::map<int,LPDIRECTINPUTEFFECT> EffectList;
+		EffectList mEffectList;
+
+		//Simple unique handle creation - allows for upto 2+ billion effects
+		//during the lifetime of application. Hopefully, that is enough.
+		int mHandles;
+
+		// Joystick device descriptor.
+		IDirectInputDevice8* mJoyStick;
+		
+		// Joystick capabilities.
+		const DIDEVCAPS* mpDIJoyCaps;
+
+		// Number of axis supporting FF.
+		short mFFAxes;
+	};
+}
+#endif //OIS_Win32ForceFeedBack_H

+ 113 - 0
CamelotOISInput/Include/OIS/win32/Win32InputManager.h

@@ -0,0 +1,113 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_Win32InputManager_H
+#define OIS_Win32InputManager_H
+
+#include "OIS/OISInputManager.h"
+#include "OIS/OISFactoryCreator.h"
+#include "OIS/win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	/**	Win32InputManager specialization - Using DirectInput8 */
+	class Win32InputManager : public InputManager, public FactoryCreator
+	{
+	public:
+		Win32InputManager();
+		virtual ~Win32InputManager();
+
+		//InputManager Overrides
+		/** @copydoc InputManager::_initialize */
+		void _initialize( ParamList &paramList );
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+		//Internal Items
+		//! Internal method, used for flaggin keyboard as available/unavailable for creation
+		void _setKeyboardUsed(bool used) {keyboardUsed = used; }
+
+		//! Internal method, used for flaggin mouse as available/unavailable for creation
+		void _setMouseUsed(bool used) { mouseUsed = used; }
+		
+		//! Internal method, return unused joystick to queue
+		void _returnJoyStick(const JoyStickInfo& joystick);
+
+		//! Returns HWND needed by DirectInput Device Object
+		HWND getWindowHandle() { return hWnd; }
+
+	protected:
+		//! internal class method for dealing with param list
+		void _parseConfigSettings( ParamList &paramList );
+		
+		//! internal class method for finding attached devices
+		void _enumerateDevices();
+
+		//! Used during device enumeration
+		static BOOL CALLBACK _DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
+
+		//! Keep a list of all joysticks enumerated, but not in use
+		JoyStickInfoList unusedJoyStickList;
+
+		//! The window handle we are using
+		HWND hWnd;
+
+		//! Direct Input Interface
+		IDirectInput8* mDirectInput;
+
+		//! Used for keyboard device settings
+		DWORD kbSettings;
+
+		//! Used for mouse device settings
+		DWORD mouseSettings;
+
+		//! Used for joystick device settings
+		DWORD joySettings;
+
+		//! Number of total joysticks (inuse or not)
+		char joySticks;
+
+		//! Used to know if we used up keyboard
+		bool keyboardUsed;
+
+		//! Used to know if we used up mouse
+		bool mouseUsed;
+	};
+}
+#endif

+ 86 - 0
CamelotOISInput/Include/OIS/win32/Win32JoyStick.h

@@ -0,0 +1,86 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _WIN32_JOYSTICK_H_EADER_
+#define _WIN32_JOYSTICK_H_EADER_
+
+#include "OIS/OISJoyStick.h"
+#include "OIS/win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	class Win32JoyStick : public JoyStick
+	{
+	public:
+		Win32JoyStick( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings, const JoyStickInfo &info );
+		virtual ~Win32JoyStick();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+		
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		//! hanlde xinput
+		void captureXInput();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type);
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+		/**
+		@remarks
+			Enum each PNP device using WMI and check each device ID to see if it contains 
+			"IG_" (ex. "VID_045E&PID_028E&IG_00").  If it does, then it's an XInput device
+			Unfortunately this information can not be found by just using DirectInput 
+		*/
+		static void CheckXInputDevices(JoyStickInfoList &joys);
+
+	protected:
+		//! Enumerates all things
+		void _enumerate();
+		//! Enumerate axis callback
+		static BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef);
+		//! Enumerate Force Feedback callback
+		static BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef);
+
+		bool _doButtonClick( int button, DIDEVICEOBJECTDATA& di );
+		bool _changePOV( int pov, DIDEVICEOBJECTDATA& di );
+
+		IDirectInput8* mDirectInput;
+		IDirectInputDevice8* mJoyStick;
+		DIDEVCAPS mDIJoyCaps;
+		DWORD coopSetting;
+
+        JoyStickInfo mJoyInfo;
+
+		//! A force feedback device
+		Win32ForceFeedback* mFfDevice;
+
+		//! Mapping
+		int _AxisNumber;
+	};
+}
+
+#endif //_WIN32_JOYSTICK_H_EADER_

+ 87 - 0
CamelotOISInput/Include/OIS/win32/Win32KeyBoard.h

@@ -0,0 +1,87 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _WIN32_KEYBOARD_H_EADER_
+#define _WIN32_KEYBOARD_H_EADER_
+
+#include "OIS/OISKeyboard.h"
+#include "OIS/win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	class Win32Keyboard : public Keyboard
+	{
+	public:
+		/**
+		@remarks
+			Constructor
+		@param pDI
+			Valid DirectInput8 Interface
+		@param buffered
+			True for buffered input mode
+		@param coopSettings
+			A combination of DI Flags (see DX Help for info on input device settings)
+		*/
+		Win32Keyboard(InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings);
+		virtual ~Win32Keyboard();
+
+		/** @copydoc Keyboard::isKeyDown */
+		virtual bool isKeyDown(KeyCode key) const;
+		
+		/** @copydoc Keyboard::getAsString */
+		virtual const std::string& getAsString(KeyCode kc);
+
+		/** @copydoc Keyboard::copyKeyStates */
+		virtual void copyKeyStates(char keys[256]) const;
+
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+		
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+		
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+	protected:
+		void _readBuffered();
+		void _read();
+
+		IDirectInput8* mDirectInput;
+		IDirectInputDevice8* mKeyboard;
+		DWORD coopSetting;
+
+		unsigned char KeyBuffer[256];
+		
+		//! Internal method for translating KeyCodes to Text
+		int _translateText( KeyCode kc );
+
+		//! Stored dead key from last translation
+		WCHAR deadKey;
+
+		//! used for getAsString
+		std::string mGetString;
+	};
+}
+#endif //_WIN32_KEYBOARD_H_EADER_

+ 59 - 0
CamelotOISInput/Include/OIS/win32/Win32Mouse.h

@@ -0,0 +1,59 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+	1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+	2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+	3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _WIN32_MOUSE_H_EADER_
+#define _WIN32_MOUSE_H_EADER_
+
+#include "OIS/OISMouse.h"
+#include "OIS/win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	class Win32Mouse : public Mouse
+	{
+	public:
+		Win32Mouse( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings );
+		virtual ~Win32Mouse();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+	protected:
+		bool _doMouseClick( int mouseButton, DIDEVICEOBJECTDATA& di );
+
+		IDirectInput8* mDirectInput;
+		IDirectInputDevice8* mMouse;
+		DWORD coopSetting;
+		HWND mHwnd;
+	};
+}
+
+#endif //_WIN32_MOUSE_H_EADER_

+ 70 - 0
CamelotOISInput/Include/OIS/win32/Win32Prereqs.h

@@ -0,0 +1,70 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef _WIN32_INPUTSYSTEM_PREREQS_H
+#define _WIN32_INPUTSYSTEM_PREREQS_H
+
+#define WIN32_LEAN_AND_MEAN
+#define DIRECTINPUT_VERSION 0x0800
+#include <windows.h>
+#include <dinput.h>
+
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+#	include <XInput.h>
+#endif
+
+//Max number of elements to collect from buffered DirectInput
+#define KEYBOARD_DX_BUFFERSIZE 17
+#define MOUSE_DX_BUFFERSIZE 128
+#define JOYSTICK_DX_BUFFERSIZE 129
+
+//MinGW defines
+#if defined(OIS_MINGW_COMPILER)
+#	undef FIELD_OFFSET
+#	define FIELD_OFFSET offsetof
+#endif
+
+namespace OIS
+{
+	//Local Forward declarations
+	class Win32InputManager;
+	class Win32Keyboard;
+	class Win32JoyStick;
+	class Win32Mouse;
+	class Win32ForceFeedback;
+
+	//Information needed to create DirectInput joysticks
+	class JoyStickInfo
+	{
+	public:
+		int devId;
+		GUID deviceID;
+		GUID productGuid;
+		std::string vendor;
+        bool isXInput;
+		int xInputDev;
+	};
+
+	typedef std::vector<JoyStickInfo> JoyStickInfoList;
+}
+
+#endif //_WIN32_INPUTSYSTEM_PREREQS_H

+ 11 - 3
CamelotOISInput/Source/CmInputHandlerOIS.cpp

@@ -56,15 +56,23 @@ namespace CamelotFramework
 
 	void InputHandlerOIS::update()
 	{
+		mInputString = "";
+
 		mMouse->capture();
 		mKeyboard->capture();
-
-		mInputString = "";
 	}
 
 	bool InputHandlerOIS::keyPressed(const OIS::KeyEvent &arg)
 	{
-		mInputString += arg.text;
+		if(arg.text != 0)
+		{
+			mInputString += arg.text;
+			if(mInputString != "")
+			{
+				int a = 5;
+			}
+		}
+
 		onKeyDown((KeyCode)(int)arg.key);
 
 		return true;

+ 128 - 0
CamelotOISInput/Source/OIS/OISEffect.cpp

@@ -0,0 +1,128 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/OISEffect.h"
+#include "OIS/OISException.h"
+
+using namespace OIS;
+
+//VC7.1 had a problem with these not getting included.. 
+//Perhaps a case of a crazy extreme optimizer :/ (moved to header)
+//const unsigned int Effect::OIS_INFINITE = 0xFFFFFFFF;
+
+//------------------------------------------------------------------------------//
+static const char* pszEForceString[] = 
+  { "UnknownForce",
+    "ConstantForce", 
+    "RampForce", 
+    "PeriodicForce", 
+    "ConditionalForce", 
+    "CustomForce" };
+
+const char* Effect::getForceTypeName(Effect::EForce eValue)
+{
+  return (eValue >= 0 && eValue < _ForcesNumber) ? pszEForceString[eValue] : "<Bad force type>";
+}
+
+static const char* pszETypeString[] = 
+  { "Unknown",
+    "Constant",
+    "Ramp",
+    "Square", "Triangle", "Sine", "SawToothUp", "SawToothDown",
+    "Friction", "Damper", "Inertia", "Spring",
+    "Custom" };
+
+const char* Effect::getEffectTypeName(Effect::EType eValue)
+{
+  return (eValue >= 0 && eValue < _TypesNumber) ? pszETypeString[eValue] : "<Bad effect type>";
+}
+
+static const char* pszEDirectionString[] = 
+  { "NorthWest", "North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West"};
+
+const char* Effect::getDirectionName(Effect::EDirection eValue)
+{
+  return (eValue >= 0 && eValue < _DirectionsNumber) ? pszEDirectionString[eValue] : "<Bad direction>";
+}
+
+//------------------------------------------------------------------------------//
+Effect::Effect() : 
+	force(UnknownForce), 
+	type(Unknown),
+	effect(0),
+	axes(1)
+{
+}
+
+//------------------------------------------------------------------------------//
+Effect::Effect(EForce ef, EType et) : 
+	force(ef), 
+	type(et),
+	direction(North), 
+	trigger_button(-1),
+	trigger_interval(0),
+	replay_length(Effect::OIS_INFINITE),
+	replay_delay(0),
+	_handle(-1),
+	axes(1)
+{
+	effect = 0;
+
+	switch( ef )
+	{
+	case ConstantForce:    effect = new ConstantEffect(); break;
+	case RampForce:	       effect = new RampEffect(); break;
+	case PeriodicForce:    effect = new PeriodicEffect(); break;
+	case ConditionalForce: effect = new ConditionalEffect(); break;
+	default: break;
+	}
+}
+
+//------------------------------------------------------------------------------//
+Effect::~Effect()
+{
+	delete effect;
+}
+
+//------------------------------------------------------------------------------//
+ForceEffect* Effect::getForceEffect() const
+{
+	//If no effect was created in constructor, then we raise an error here
+	if( effect == 0 )
+		OIS_EXCEPT( E_NotSupported, "Requested ForceEffect is null!" );
+
+	return effect;
+}
+
+//------------------------------------------------------------------------------//
+void Effect::setNumAxes(short nAxes)
+{
+	//Can only be set before a handle was assigned (effect created)
+	if( _handle != -1 )
+        axes = nAxes;
+}
+
+//------------------------------------------------------------------------------//
+short Effect::getNumAxes() const
+{
+	return axes;
+}

+ 32 - 0
CamelotOISInput/Source/OIS/OISException.cpp

@@ -0,0 +1,32 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/OISException.h"
+
+using namespace OIS;
+
+//----------------------------------------------------------------------------//
+const char* Exception::what() const throw()
+{
+	return eText;
+}
+

+ 74 - 0
CamelotOISInput/Source/OIS/OISForceFeedback.cpp

@@ -0,0 +1,74 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/OISForceFeedback.h"
+#include "OIS/OISException.h"
+
+using namespace OIS;
+
+//-------------------------------------------------------------//
+ForceFeedback::ForceFeedback() : mSetGainSupport(false), mSetAutoCenterSupport(false)
+{
+}
+
+//-------------------------------------------------------------//
+void ForceFeedback::_addEffectTypes( Effect::EForce force, Effect::EType type )
+{
+	if( force <= Effect::UnknownForce || force >= Effect::_ForcesNumber
+		|| type <= Effect::Unknown || type >= Effect::_TypesNumber )
+		OIS_EXCEPT( E_General, "Can't add unknown effect Force/Type to the supported list" );
+
+	mSupportedEffects.insert(std::pair<Effect::EForce, Effect::EType>(force, type));
+}
+
+//-------------------------------------------------------------//
+void ForceFeedback::_setGainSupport( bool on )
+{
+	mSetGainSupport = on;
+}
+
+//-------------------------------------------------------------//
+void ForceFeedback::_setAutoCenterSupport( bool on )
+{
+	mSetAutoCenterSupport = on;
+}
+
+//-------------------------------------------------------------//
+const ForceFeedback::SupportedEffectList& ForceFeedback::getSupportedEffects() const
+{
+	return mSupportedEffects;
+}
+
+//-------------------------------------------------------------//
+bool ForceFeedback::supportsEffect(Effect::EForce force, Effect::EType type) const
+{
+    const std::pair<SupportedEffectList::const_iterator, SupportedEffectList::const_iterator> 
+	    iterRange = mSupportedEffects.equal_range(force);
+	SupportedEffectList::const_iterator iter;
+	for (iter = iterRange.first; iter != iterRange.second; iter++)
+	{
+	  if ((*iter).second == type)
+		return true;
+	}
+
+	return false;
+}

+ 290 - 0
CamelotOISInput/Source/OIS/OISInputManager.cpp

@@ -0,0 +1,290 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/OISInputManager.h"
+#include "OIS/OISException.h"
+#include "OIS/OISFactoryCreator.h"
+#include "OIS/OISObject.h"
+#include <sstream>
+#include <algorithm>
+
+//Bring in correct Header / InputManager for current build platform
+#if defined OIS_SDL_PLATFORM
+#  include "OIS/SDL/SDLInputManager.h"
+#elif defined OIS_WIN32_PLATFORM
+#  include "OIS/win32/Win32InputManager.h"
+#elif defined OIS_LINUX_PLATFORM
+#  include "OIS/linux/LinuxInputManager.h"
+#elif defined OIS_APPLE_PLATFORM
+#  include "OIS/mac/MacInputManager.h"
+#elif defined OIS_IPHONE_PLATFORM
+#  include "OIS/iphone/iPhoneInputManager.h"
+#elif defined OIS_XBOX_PLATFORM
+#  include "OIS/xbox/XBoxInputManager.h"
+#endif
+
+//Bring in extra controls
+#if defined OIS_LIRC_SUPPORT
+#  include "OIS/extras/LIRC/OISLIRCFactoryCreator.h"
+#endif
+#if defined OIS_WIN32_WIIMOTE_SUPPORT
+#  include "OIS/win32/extras/WiiMote/OISWiiMoteFactoryCreator.h"
+#endif
+
+
+using namespace OIS;
+
+//----------------------------------------------------------------------------//
+InputManager::InputManager(const std::string& name) :
+	m_VersionName(OIS_VERSION_NAME),
+	mInputSystemName(name),
+	m_lircSupport(0),
+	m_wiiMoteSupport(0)
+{
+    mFactories.clear();
+    mFactoryObjects.clear();
+}
+
+//----------------------------------------------------------------------------//
+InputManager::~InputManager()
+{
+#if defined OIS_LIRC_SUPPORT
+	delete m_lircSupport;
+#endif
+
+#if defined OIS_WIN32_WIIMOTE_SUPPORT
+	delete m_wiiMoteSupport;
+#endif
+}
+
+//----------------------------------------------------------------------------//
+unsigned int InputManager::getVersionNumber()
+{
+	return OIS_VERSION;
+}
+
+//----------------------------------------------------------------------------//
+const std::string &InputManager::getVersionName()
+{
+	return m_VersionName;
+}
+
+//----------------------------------------------------------------------------//
+InputManager* InputManager::createInputSystem( std::size_t windowhandle )
+{
+	ParamList pl;
+	std::ostringstream wnd;
+	wnd << windowhandle;
+	pl.insert(std::make_pair( std::string("WINDOW"), wnd.str() ));
+
+	return createInputSystem( pl );
+}
+
+//----------------------------------------------------------------------------//
+InputManager* InputManager::createInputSystem( ParamList &paramList )
+{
+	InputManager* im = 0;
+
+#if defined OIS_SDL_PLATFORM
+	im = new SDLInputManager();
+#elif defined OIS_WIN32_PLATFORM
+	im = new Win32InputManager();
+#elif defined OIS_XBOX_PLATFORM
+	im = new XBoxInputManager();
+#elif defined OIS_LINUX_PLATFORM
+	im = new LinuxInputManager();
+#elif defined OIS_APPLE_PLATFORM
+	im = new MacInputManager();
+#elif defined OIS_IPHONE_PLATFORM
+	im = new iPhoneInputManager();
+#else
+	OIS_EXCEPT(E_General, "No platform library.. check build platform defines!");
+#endif 
+
+	try
+	{
+		im->_initialize(paramList);
+	}
+	catch(...)
+	{
+		delete im;
+		throw; //rethrow
+	}
+
+	return im;
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::destroyInputSystem(InputManager* manager)
+{
+	if( manager == 0 )
+		return;
+
+	//Cleanup before deleting...
+	for( FactoryCreatedObject::iterator i = manager->mFactoryObjects.begin(); 
+		i != manager->mFactoryObjects.end(); ++i )
+	{
+		i->second->destroyObject( i->first );
+	}
+
+	manager->mFactoryObjects.clear();
+	delete manager;
+}
+
+//--------------------------------------------------------------------------------//
+const std::string& InputManager::inputSystemName()
+{
+	return mInputSystemName;
+}
+
+//--------------------------------------------------------------------------------//
+int InputManager::getNumberOfDevices( Type iType )
+{
+	//Count up all the factories devices
+	int factoyObjects = 0;
+	FactoryList::iterator i = mFactories.begin(), e = mFactories.end();
+	for( ; i != e; ++i )
+		factoyObjects += (*i)->totalDevices(iType);
+
+	return factoyObjects;
+}
+
+//----------------------------------------------------------------------------//
+DeviceList InputManager::listFreeDevices()
+{
+	DeviceList list;
+	FactoryList::iterator i = mFactories.begin(), e = mFactories.end();
+	for( ; i != e; ++i )
+	{
+		DeviceList temp = (*i)->freeDeviceList();
+		list.insert(temp.begin(), temp.end());
+	}
+
+	return list;
+}
+
+//----------------------------------------------------------------------------//
+Object* InputManager::createInputObject( Type iType, bool bufferMode, const std::string &vendor )
+{
+	Object* obj = 0;
+	FactoryList::iterator i = mFactories.begin(), e = mFactories.end();
+	for( ; i != e; ++i)
+	{
+		if( (*i)->freeDevices(iType) > 0 )
+		{
+			if( vendor == "" || (*i)->vendorExist(iType, vendor) )
+			{
+				obj = (*i)->createObject(this, iType, bufferMode, vendor);
+				mFactoryObjects[obj] = (*i);
+				break;
+			}
+		}
+	}
+
+	if(!obj)
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	try
+	{	//Intialize device
+		obj->_initialize();
+	}
+	catch(...)
+	{	//Somekind of error, cleanup and rethrow
+		destroyInputObject(obj);
+		throw;
+	}
+
+	return obj;
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::destroyInputObject( Object* obj )
+{
+	if( obj == 0 )
+		return;
+
+	FactoryCreatedObject::iterator i = mFactoryObjects.find(obj);
+	if( i != mFactoryObjects.end() )
+	{
+		i->second->destroyObject(obj);
+		mFactoryObjects.erase(i);
+	}
+	else
+	{
+		OIS_EXCEPT(E_General, "Object creator not known.");
+	}
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::addFactoryCreator( FactoryCreator* factory )
+{
+	if(factory != 0)
+		mFactories.push_back(factory);
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::removeFactoryCreator( FactoryCreator* factory )
+{
+	if(factory != 0)
+	{
+		//First, destroy all devices created with the factory
+		for( FactoryCreatedObject::iterator i = mFactoryObjects.begin(); i != mFactoryObjects.end(); ++i )
+		{
+			if( i->second == factory )
+			{
+				i->second->destroyObject(i->first);
+				mFactoryObjects.erase(i++);
+			}
+		}
+
+		//Now, remove the factory itself
+		FactoryList::iterator fact = std::find(mFactories.begin(), mFactories.end(), factory);
+		if( fact != mFactories.end() )
+			mFactories.erase(fact);
+	}
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::enableAddOnFactory(AddOnFactories factory)
+{
+#if defined OIS_LIRC_SUPPORT
+	if( factory == AddOn_LIRC || factory == AddOn_All )
+	{
+		if( m_lircSupport == 0 )
+		{
+			m_lircSupport = new LIRCFactoryCreator();
+			addFactoryCreator(m_lircSupport);
+		}
+	}
+#endif
+
+#if defined OIS_WIN32_WIIMOTE_SUPPORT
+	if( factory == AddOn_WiiMote || factory == AddOn_All )
+	{
+		if( m_wiiMoteSupport == 0 )
+		{
+			m_wiiMoteSupport = new WiiMoteFactoryCreator();
+			addFactoryCreator(m_wiiMoteSupport);
+		}
+	}
+#endif
+}

+ 73 - 0
CamelotOISInput/Source/OIS/OISJoyStick.cpp

@@ -0,0 +1,73 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/OISJoyStick.h"
+
+using namespace OIS;
+
+//----------------------------------------------------------------------------//
+JoyStick::JoyStick(const std::string &vendor, bool buffered, int devID, InputManager* creator) :
+	Object(vendor, OISJoyStick, buffered, devID, creator),
+	mSliders(0),
+	mPOVs(0),
+	mListener(0),
+	mVector3Sensitivity(OIS_JOYSTICK_VECTOR3_DEFAULT)
+{
+}
+
+//----------------------------------------------------------------------------//
+int JoyStick::getNumberOfComponents(ComponentType cType) const
+{
+	switch( cType )
+	{
+	case OIS_Button:	return (int)mState.mButtons.size();
+	case OIS_Axis:		return (int)mState.mAxes.size();
+	case OIS_Slider:	return mSliders;
+	case OIS_POV:		return mPOVs;
+	case OIS_Vector3:	return (int)mState.mVectors.size();
+	default:			return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+void JoyStick::setVector3Sensitivity(float degrees)
+{
+	mVector3Sensitivity = degrees;
+}
+
+//----------------------------------------------------------------------------//
+float JoyStick::getVector3Sensitivity() const
+{
+	return mVector3Sensitivity;
+}
+
+//----------------------------------------------------------------------------//
+void JoyStick::setEventCallback( JoyStickListener *joyListener )
+{
+	mListener = joyListener;
+}
+
+//----------------------------------------------------------------------------//
+JoyStickListener* JoyStick::getEventCallback() const
+{
+	return mListener;
+}

+ 45 - 0
CamelotOISInput/Source/OIS/OISKeyboard.cpp

@@ -0,0 +1,45 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/OISKeyboard.h"
+#include "OIS/OISException.h"
+
+using namespace OIS;
+
+//----------------------------------------------------------------------//
+void Keyboard::setTextTranslation( TextTranslationMode mode )
+{
+	mTextMode = mode;
+}
+
+//----------------------------------------------------------------------//
+bool Keyboard::isModifierDown( Modifier mod ) const
+{
+#if defined(OIS_MSVC_COMPILER)
+  #pragma warning (push)
+  #pragma warning (disable : 4800)
+#endif
+	return (mModifiers & mod);
+#if defined(OIS_MSVC_COMPILER)
+  #pragma warning (pop)
+#endif
+}

+ 23 - 0
CamelotOISInput/Source/OIS/OISObject.cpp

@@ -0,0 +1,23 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+//#include "OIS/OISObject.h"

+ 114 - 0
CamelotOISInput/Source/OIS/SDL/SDLInputManager.cpp

@@ -0,0 +1,114 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL/SDLInputManager.h"
+#include "SDL/SDLKeyboard.h"
+#include "SDL/SDLMouse.h"
+#include "SDL/SDLJoyStick.h"
+#include "OISException.h"
+#include "OISObject.h"
+
+using namespace OIS;
+
+const std::string SDLInputManager::iName = "SDL Input Wrapper";
+
+//--------------------------------------------------------------------------------//
+SDLInputManager::SDLInputManager() : mGrabbed(false)
+{
+}
+
+//--------------------------------------------------------------------------------//
+SDLInputManager::~SDLInputManager()
+{
+}
+
+//--------------------------------------------------------------------------------//
+void SDLInputManager::_initialize( ParamList &paramList )
+{
+	Uint32 flags = SDL_WasInit(0);
+	if( flags == 0 )
+		OIS_EXCEPT( E_General, "SDLInputManager::SDLInputManager >> SDL Not Initialized already!");
+
+	//Ok, now we have DirectInput, parse whatever extra settings were sent to us
+	_parseConfigSettings( paramList );
+	_enumerateDevices();
+}
+
+//--------------------------------------------------------------------------------//
+void SDLInputManager::_parseConfigSettings( ParamList &paramList )
+{
+}
+
+//--------------------------------------------------------------------------------//
+void SDLInputManager::_enumerateDevices()
+{
+}
+
+//--------------------------------------------------------------------------------//
+int SDLInputManager::numJoySticks()
+{
+	return 0;
+}
+
+//--------------------------------------------------------------------------------//
+int SDLInputManager::numMice()
+{
+	return 1;
+}
+
+//--------------------------------------------------------------------------------//
+int SDLInputManager::numKeyboards()
+{
+	return 1;
+}
+
+//----------------------------------------------------------------------------//
+Object* SDLInputManager::createInputObject( Type iType, bool bufferMode )
+{
+	Object* obj = 0;
+	
+	switch( iType )
+	{
+		case OISKeyboard: obj = new SDLKeyboard( bufferMode ); break;
+		case OISMouse: obj = new SDLMouse( bufferMode ); break;
+		case OISJoyStick: 
+		default: OIS_EXCEPT( E_InputDeviceNotSupported, "Type not implemented");
+	}
+
+	try	{
+		obj->_initialize();
+	}
+	catch(...) {
+		delete obj;
+		throw; //rethrow
+	}
+
+	return obj;
+}
+
+//----------------------------------------------------------------------------//
+void SDLInputManager::destroyInputObject( Object* obj )
+{
+	if( obj == 0 ) return;
+
+	delete obj;
+}

+ 0 - 0
CamelotOISInput/Source/OIS/SDL/SDLJoyStick.cpp


+ 377 - 0
CamelotOISInput/Source/OIS/SDL/SDLKeyboard.cpp

@@ -0,0 +1,377 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL/SDLKeyboard.h"
+#include "SDL/SDLInputManager.h"
+#include "OISException.h"
+#include "OISEvents.h"
+#include <sstream>
+
+using namespace OIS;
+
+//-------------------------------------------------------------------//
+SDLKeyboard::SDLKeyboard( bool buffered )
+{
+	mBuffered = buffered;
+	mType = OISKeyboard;
+	listener = 0;
+
+	//Clear our keyboard state buffer
+	memset( &KeyBuffer, 0, 256 );
+}
+
+//-------------------------------------------------------------------//
+void SDLKeyboard::_initialize()
+{
+	mModifiers = 0;
+	mSDLBuff = 0;
+
+	mKeyMap.insert( KeyMap::value_type(SDLK_ESCAPE,KC_ESCAPE) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_1, KC_1) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_2, KC_2) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_3, KC_3) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_4, KC_4) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_5, KC_5) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_6, KC_6) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_7, KC_7) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_8, KC_8) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_9, KC_9) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_0, KC_0) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_MINUS, KC_MINUS) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_EQUALS, KC_EQUALS) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_BACKSPACE, KC_BACK) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_TAB, KC_TAB) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_q, KC_Q) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_w, KC_W) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_e, KC_E) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_r, KC_R) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_t, KC_T) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_y, KC_Y) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_u, KC_U) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_i, KC_I) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_o, KC_O) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_p, KC_P) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_RETURN, KC_RETURN) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_LCTRL, KC_LCONTROL));
+	mKeyMap.insert( KeyMap::value_type(SDLK_a, KC_A) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_s, KC_S) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_d, KC_D) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_f, KC_F) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_g, KC_G) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_h, KC_H) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_j, KC_J) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_k, KC_K) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_l, KC_L) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_SEMICOLON, KC_SEMICOLON) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_COLON, KC_COLON) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_QUOTE, KC_APOSTROPHE) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_BACKQUOTE, KC_GRAVE)  );
+	mKeyMap.insert( KeyMap::value_type(SDLK_LSHIFT, KC_LSHIFT) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_BACKSLASH, KC_BACKSLASH) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_SLASH, KC_SLASH) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_z, KC_Z) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_x, KC_X) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_c, KC_C) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_v, KC_V) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_b, KC_B) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_n, KC_N) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_m, KC_M) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_COMMA, KC_COMMA)  );
+	mKeyMap.insert( KeyMap::value_type(SDLK_PERIOD, KC_PERIOD));
+	mKeyMap.insert( KeyMap::value_type(SDLK_RSHIFT, KC_RSHIFT));
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP_MULTIPLY, KC_MULTIPLY) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_LALT, KC_LMENU) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_SPACE, KC_SPACE));
+	mKeyMap.insert( KeyMap::value_type(SDLK_CAPSLOCK, KC_CAPITAL) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F1, KC_F1) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F2, KC_F2) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F3, KC_F3) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F4, KC_F4) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F5, KC_F5) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F6, KC_F6) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F7, KC_F7) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F8, KC_F8) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F9, KC_F9) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F10, KC_F10) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_NUMLOCK, KC_NUMLOCK) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_SCROLLOCK, KC_SCROLL));
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP7, KC_NUMPAD7) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP8, KC_NUMPAD8) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP9, KC_NUMPAD9) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP_MINUS, KC_SUBTRACT) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP4, KC_NUMPAD4) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP5, KC_NUMPAD5) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP6, KC_NUMPAD6) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP_PLUS, KC_ADD) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP1, KC_NUMPAD1) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP2, KC_NUMPAD2) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP3, KC_NUMPAD3) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP0, KC_NUMPAD0) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP_PERIOD, KC_DECIMAL) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F11, KC_F11) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F12, KC_F12) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F13, KC_F13) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F14, KC_F14) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_F15, KC_F15) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP_EQUALS, KC_NUMPADEQUALS) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_KP_DIVIDE, KC_DIVIDE) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_SYSREQ, KC_SYSRQ) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_RALT, KC_RMENU) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_HOME, KC_HOME) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_UP, KC_UP) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_PAGEUP, KC_PGUP) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_LEFT, KC_LEFT) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_RIGHT, KC_RIGHT) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_END, KC_END) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_DOWN, KC_DOWN) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_PAGEDOWN, KC_PGDOWN) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_INSERT, KC_INSERT) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_DELETE, KC_DELETE) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_LSUPER, KC_LWIN) );
+	mKeyMap.insert( KeyMap::value_type(SDLK_RSUPER, KC_RWIN) );
+
+	SDL_EnableUNICODE(1);
+}
+
+//-------------------------------------------------------------------//
+SDLKeyboard::~SDLKeyboard()
+{
+}
+
+//-------------------------------------------------------------------//
+void SDLKeyboard::capture()
+{
+	SDL_Event events[OIS_SDL_KEY_BUFF];
+	int count = SDL_PeepEvents(events, OIS_SDL_KEY_BUFF, SDL_GETEVENT, 
+		SDL_EVENTMASK(SDL_KEYDOWN) | SDL_EVENTMASK(SDL_KEYUP));
+
+	for( int i = 0; i < count; ++i )
+	{
+		KeyCode kc = mKeyMap[events[i].key.keysym.sym];
+		KeyBuffer[kc] = events[i].key.state;
+
+		if( mBuffered && listener )
+		{
+			if( events[i].key.state == SDL_PRESSED )
+			{
+				if( listener->keyPressed(KeyEvent(this, 0, kc, events[i].key.keysym.unicode)) == false )
+					break;
+			}
+			else
+			{
+				if( listener->keyReleased(KeyEvent(this, 0, kc, events[i].key.keysym.unicode)) == false )
+					break;
+			}
+		}
+	}
+
+	//Release Grab mode on Alt-Tab combinations (for non-window systems)
+	if( KeyBuffer[KC_RMENU] || KeyBuffer[KC_LMENU])
+	{
+		if( KeyBuffer[KC_TAB] )
+			static_cast<SDLInputManager*>(InputManager::getSingletonPtr())->_setGrabMode(false);
+	}
+}
+
+//-------------------------------------------------------------------//
+bool SDLKeyboard::isKeyDown( KeyCode key )
+{
+	return KeyBuffer[key] == 1 ? true : false;
+}
+
+//-------------------------------------------------------------------//
+const std::string& SDLKeyboard::getAsString( KeyCode kc )
+{
+    switch(kc)
+    {
+    case KC_ESCAPE: mGetString = SDL_GetKeyName(SDLK_ESCAPE); break;
+    case KC_1: mGetString = SDL_GetKeyName(SDLK_1); break;
+    case KC_2: mGetString = SDL_GetKeyName(SDLK_2); break;
+    case KC_3: mGetString = SDL_GetKeyName(SDLK_3); break;
+    case KC_4: mGetString = SDL_GetKeyName(SDLK_4); break;
+    case KC_5: mGetString = SDL_GetKeyName(SDLK_5); break;
+    case KC_6: mGetString = SDL_GetKeyName(SDLK_6); break;
+    case KC_7: mGetString = SDL_GetKeyName(SDLK_7); break;
+    case KC_8: mGetString = SDL_GetKeyName(SDLK_8); break;
+    case KC_9: mGetString = SDL_GetKeyName(SDLK_9); break;
+    case KC_0: mGetString = SDL_GetKeyName(SDLK_0); break;
+    case KC_MINUS: mGetString = SDL_GetKeyName(SDLK_MINUS); break;
+    case KC_EQUALS: mGetString = SDL_GetKeyName(SDLK_EQUALS); break;
+    case KC_BACK: mGetString = SDL_GetKeyName(SDLK_BACKSPACE); break;
+    case KC_TAB: mGetString = SDL_GetKeyName(SDLK_TAB); break;
+    case KC_Q: mGetString = SDL_GetKeyName(SDLK_q); break;
+    case KC_W: mGetString = SDL_GetKeyName(SDLK_w); break;
+    case KC_E: mGetString = SDL_GetKeyName(SDLK_e); break;
+    case KC_R: mGetString = SDL_GetKeyName(SDLK_r); break;
+    case KC_T: mGetString = SDL_GetKeyName(SDLK_t); break;
+    case KC_Y: mGetString = SDL_GetKeyName(SDLK_y); break;
+    case KC_U: mGetString = SDL_GetKeyName(SDLK_u); break;
+    case KC_I: mGetString = SDL_GetKeyName(SDLK_i); break;
+    case KC_O: mGetString = SDL_GetKeyName(SDLK_o); break;
+    case KC_P: mGetString = SDL_GetKeyName(SDLK_p); break;
+    case KC_LBRACKET: mGetString = "["; break;
+    case KC_RBRACKET: mGetString = "]"; break;
+    case KC_RETURN: mGetString = SDL_GetKeyName(SDLK_RETURN); break;
+    case KC_LCONTROL: mGetString = SDL_GetKeyName(SDLK_LCTRL); break;
+    case KC_A: mGetString = SDL_GetKeyName(SDLK_a); break;
+    case KC_S: mGetString = SDL_GetKeyName(SDLK_s); break;
+    case KC_D: mGetString = SDL_GetKeyName(SDLK_d); break;
+    case KC_F: mGetString = SDL_GetKeyName(SDLK_f); break;
+    case KC_G: mGetString = SDL_GetKeyName(SDLK_g); break;
+    case KC_H: mGetString = SDL_GetKeyName(SDLK_h); break;
+    case KC_J: mGetString = SDL_GetKeyName(SDLK_j); break;
+    case KC_K: mGetString = SDL_GetKeyName(SDLK_k); break;
+    case KC_L: mGetString = SDL_GetKeyName(SDLK_l); break;
+    case KC_SEMICOLON: mGetString = SDL_GetKeyName(SDLK_SEMICOLON); break;
+    case KC_APOSTROPHE: mGetString = SDL_GetKeyName(SDLK_QUOTE); break;
+    case KC_GRAVE: mGetString = SDL_GetKeyName(SDLK_BACKQUOTE); break;
+    case KC_LSHIFT: mGetString = SDL_GetKeyName(SDLK_LSHIFT); break;
+    case KC_BACKSLASH: mGetString = SDL_GetKeyName(SDLK_BACKSLASH); break;
+    case KC_Z: mGetString = SDL_GetKeyName(SDLK_z); break;
+    case KC_X: mGetString = SDL_GetKeyName(SDLK_x); break;
+    case KC_C: mGetString = SDL_GetKeyName(SDLK_c); break;
+    case KC_V: mGetString = SDL_GetKeyName(SDLK_v); break;
+    case KC_B: mGetString = SDL_GetKeyName(SDLK_b); break;
+    case KC_N: mGetString = SDL_GetKeyName(SDLK_n); break;
+    case KC_M: mGetString = SDL_GetKeyName(SDLK_m); break;
+    case KC_COMMA: mGetString = SDL_GetKeyName(SDLK_COMMA); break;
+    case KC_PERIOD: mGetString = SDL_GetKeyName(SDLK_PERIOD); break;
+    case KC_SLASH: mGetString = SDL_GetKeyName(SDLK_SLASH); break;
+    case KC_RSHIFT: mGetString = SDL_GetKeyName(SDLK_RSHIFT); break;
+    case KC_MULTIPLY: mGetString = SDL_GetKeyName(SDLK_KP_MULTIPLY); break;
+    case KC_LMENU: mGetString = SDL_GetKeyName(SDLK_LALT); break;
+    case KC_SPACE: mGetString = SDL_GetKeyName(SDLK_SPACE); break;
+    case KC_CAPITAL: mGetString = SDL_GetKeyName(SDLK_CAPSLOCK); break;
+    case KC_F1: mGetString = SDL_GetKeyName(SDLK_F1); break;
+    case KC_F2: mGetString = SDL_GetKeyName(SDLK_F2); break;
+    case KC_F3: mGetString = SDL_GetKeyName(SDLK_F3); break;
+    case KC_F4: mGetString = SDL_GetKeyName(SDLK_F4); break;
+    case KC_F5: mGetString = SDL_GetKeyName(SDLK_F5); break;
+    case KC_F6: mGetString = SDL_GetKeyName(SDLK_F6); break;
+    case KC_F7: mGetString = SDL_GetKeyName(SDLK_F7); break;
+    case KC_F8: mGetString = SDL_GetKeyName(SDLK_F8); break;
+    case KC_F9: mGetString = SDL_GetKeyName(SDLK_F9); break;
+    case KC_F10: mGetString = SDL_GetKeyName(SDLK_F10); break;
+    case KC_NUMLOCK: mGetString = SDL_GetKeyName(SDLK_NUMLOCK); break;
+    case KC_SCROLL: mGetString = SDL_GetKeyName(SDLK_SCROLLOCK); break;
+    case KC_NUMPAD7: mGetString = SDL_GetKeyName(SDLK_KP7); break;
+    case KC_NUMPAD8: mGetString = SDL_GetKeyName(SDLK_KP8); break;
+    case KC_NUMPAD9: mGetString = SDL_GetKeyName(SDLK_KP9); break;
+    case KC_SUBTRACT: mGetString = SDL_GetKeyName(SDLK_KP_MINUS); break;
+    case KC_NUMPAD4: mGetString = SDL_GetKeyName(SDLK_KP4); break;
+    case KC_NUMPAD5: mGetString = SDL_GetKeyName(SDLK_KP5); break;
+    case KC_NUMPAD6: mGetString = SDL_GetKeyName(SDLK_KP6); break;
+    case KC_ADD: mGetString = SDL_GetKeyName(SDLK_KP_PLUS); break;
+    case KC_NUMPAD1: mGetString = SDL_GetKeyName(SDLK_KP1); break;
+    case KC_NUMPAD2: mGetString = SDL_GetKeyName(SDLK_KP2); break;
+    case KC_NUMPAD3: mGetString = SDL_GetKeyName(SDLK_KP3); break;
+    case KC_NUMPAD0: mGetString = SDL_GetKeyName(SDLK_KP0); break;
+    case KC_DECIMAL: mGetString = SDL_GetKeyName(SDLK_KP_PERIOD); break;
+    case KC_OEM_102: mGetString = "OEM_102"; break;
+    case KC_F11: mGetString = SDL_GetKeyName(SDLK_F11); break;
+    case KC_F12: mGetString = SDL_GetKeyName(SDLK_F12); break;
+    case KC_F13: mGetString = SDL_GetKeyName(SDLK_F13); break;
+    case KC_F14: mGetString = SDL_GetKeyName(SDLK_F14); break;
+    case KC_F15: mGetString = SDL_GetKeyName(SDLK_F15); break;
+    case KC_KANA: mGetString = "Kana"; break;
+    case KC_ABNT_C1: mGetString = "ABNT_C1"; break;
+    case KC_CONVERT: mGetString = "CONVERT"; break;
+    case KC_NOCONVERT: mGetString = "NOCONVERT"; break;
+    case KC_YEN: mGetString = "YEN"; break;
+    case KC_ABNT_C2: mGetString = "ABNT_C2"; break;
+    case KC_NUMPADEQUALS: mGetString = SDL_GetKeyName(SDLK_KP_EQUALS); break;
+    case KC_PREVTRACK: mGetString = "KC_PREVTRACK"; break;
+    case KC_AT: mGetString = "KC_AT"; break;
+    case KC_COLON: mGetString = SDL_GetKeyName(SDLK_COLON); break;
+    case KC_UNDERLINE: mGetString = "KC_UNDERLINE"; break;
+    case KC_KANJI: mGetString = "KC_KANJI"; break;
+    case KC_STOP: mGetString = "KC_STOP"; break;
+    case KC_AX: mGetString = "KC_AX"; break;
+    case KC_UNLABELED: mGetString = "KC_UNLABELED"; break;
+    case KC_NEXTTRACK: mGetString = "KC_NEXTTRACK"; break;
+    case KC_NUMPADENTER: mGetString = "KC_NUMPADENTER"; break;
+    case KC_RCONTROL: mGetString = "KC_RCONTROL"; break;
+    case KC_MUTE: mGetString = "KC_MUTE"; break;
+    case KC_CALCULATOR: mGetString = "KC_CALCULATOR"; break;
+    case KC_PLAYPAUSE: mGetString = "KC_PLAYPAUSE"; break;
+    case KC_MEDIASTOP: mGetString = "KC_MEDIASTOP"; break;
+    case KC_VOLUMEDOWN: mGetString = "KC_VOLUMEDOWN"; break;
+    case KC_VOLUMEUP: mGetString = "KC_VOLUMEUP"; break;
+    case KC_WEBHOME: mGetString = "KC_WEBHOME"; break;
+    case KC_NUMPADCOMMA: mGetString = "KC_NUMPADCOMMA"; break;
+    case KC_DIVIDE: mGetString = SDL_GetKeyName(SDLK_KP_DIVIDE); break;
+    case KC_SYSRQ: mGetString = SDL_GetKeyName(SDLK_SYSREQ); break;
+    case KC_RMENU: mGetString = SDL_GetKeyName(SDLK_RALT); break;
+    case KC_PAUSE: mGetString = "Pause"; break;
+    case KC_HOME: mGetString = SDL_GetKeyName(SDLK_HOME); break;
+    case KC_UP: mGetString = SDL_GetKeyName(SDLK_UP); break;
+    case KC_PGUP: mGetString = SDL_GetKeyName(SDLK_PAGEUP); break;
+    case KC_LEFT: mGetString = SDL_GetKeyName(SDLK_LEFT); break;
+    case KC_RIGHT: mGetString = SDL_GetKeyName(SDLK_RIGHT); break;
+    case KC_END:  mGetString = SDL_GetKeyName(SDLK_END); break;
+    case KC_DOWN: mGetString = SDL_GetKeyName(SDLK_DOWN); break;
+    case KC_PGDOWN: mGetString = SDL_GetKeyName(SDLK_PAGEDOWN); break;
+    case KC_INSERT: mGetString = SDL_GetKeyName(SDLK_INSERT); break;
+    case KC_DELETE: mGetString = SDL_GetKeyName(SDLK_DELETE); break;
+    case KC_LWIN: mGetString = SDL_GetKeyName(SDLK_LSUPER); break;
+    case KC_RWIN: mGetString = SDL_GetKeyName(SDLK_RSUPER); break;
+    case KC_APPS: mGetString = "KC_APPS"; break;
+    case KC_POWER: mGetString = "KC_POWER"; break;
+    case KC_SLEEP: mGetString = "KC_SLEEP"; break;
+    case KC_WAKE: mGetString = "KC_WAKE"; break;
+    case KC_WEBSEARCH: mGetString = "KC_WEBSEARCH"; break;
+    case KC_WEBFAVORITES: mGetString = "KC_WEBFAVORITES"; break;
+    case KC_WEBREFRESH: mGetString = "KC_WEBREFRESH"; break;
+    case KC_WEBSTOP: mGetString = "KC_WEBSTOP"; break;
+    case KC_WEBFORWARD: mGetString = "KC_WEBFORWARD"; break;
+    case KC_WEBBACK: mGetString = "KC_WEBBACK"; break;
+    case KC_MYCOMPUTER: mGetString = "KC_MYCOMPUTER"; break;
+    case KC_MAIL: mGetString = "KC_MAIL"; break;
+    case KC_MEDIASELECT: mGetString = "KC_MEDIASELECT"; break;
+    default: mGetString = "Unknown"; break;
+    };
+
+	return mGetString;
+}
+
+//-------------------------------------------------------------------//
+void SDLKeyboard::copyKeyStates( char keys[256] )
+{
+	for(int i = 0; i < 256; ++i)
+		keys[i] = KeyBuffer[i];
+}
+
+//-------------------------------------------------------------------//
+void SDLKeyboard::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//-------------------------------------------------------------------//
+void SDLKeyboard::setTextTranslation( TextTranslationMode mode )
+{
+	mTextMode = mode;
+	if( mode == Off || mode == Ascii )
+		SDL_EnableUNICODE(0);
+	else if( mode == Unicode )
+		SDL_EnableUNICODE(1);
+}

+ 174 - 0
CamelotOISInput/Source/OIS/SDL/SDLMouse.cpp

@@ -0,0 +1,174 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL/SDLMouse.h"
+#include "SDL/SDLInputManager.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+using namespace OIS;
+
+//-------------------------------------------------------------------//
+SDLMouse::SDLMouse( bool buffered ) : mGrabbed(false), mRegainFocus(false)
+{
+	mBuffered = buffered;
+	mType = OISMouse;
+	listener = 0;
+}
+
+//-------------------------------------------------------------------//
+void SDLMouse::_initialize()
+{
+	//Clear old state
+	mState.clear();
+	mRegainFocus = false;
+
+	_setGrab(true);
+	_setVisible(false);
+	static_cast<SDLInputManager*>(InputManager::getSingletonPtr())->_setGrabMode(true);
+}
+
+//-------------------------------------------------------------------//
+SDLMouse::~SDLMouse()
+{
+	_setGrab(true);
+	_setVisible(true);
+
+	static_cast<SDLInputManager*>(InputManager::getSingletonPtr())->_setGrabMode(false);
+}
+
+//-------------------------------------------------------------------//
+void SDLMouse::capture()
+{
+	//Used for going from SDL Button to OIS button
+	static const MouseButtonID ButtonMask[4] = {MB_Left, MB_Left, MB_Middle, MB_Right};
+
+	//Clear old relative values
+	mState.relX = mState.relY = mState.relZ = 0;
+
+	SDL_Event events[OIS_SDL_MOUSE_BUFF];
+	int count = SDL_PeepEvents(events, OIS_SDL_MOUSE_BUFF, SDL_GETEVENT, SDL_MOUSEEVENTMASK);
+
+	bool mouseXYMoved = false;
+	bool mouseZMoved = false;
+	for( int i = 0; i < count; ++i )
+	{
+		switch( events[i].type )
+		{
+			case SDL_MOUSEMOTION: mouseXYMoved = true; break;				
+			case SDL_MOUSEBUTTONDOWN:
+			{
+				mRegainFocus = true;
+				int sdlButton = events[i].button.button;
+				if( sdlButton <= SDL_BUTTON_RIGHT )
+				{	//Left, Right, or Middle
+					mState.buttons |= (1 << ButtonMask[sdlButton]);
+					if( mBuffered && listener )
+						if( listener->mousePressed(MouseEvent(this,0,mState), ButtonMask[sdlButton]) == false )
+							return;
+				}
+				else
+				{	//mouse Wheel
+					mouseZMoved = true;
+					if( sdlButton == SDL_BUTTON_WHEELUP )
+						mState.relZ += 120;
+					else if( sdlButton == SDL_BUTTON_WHEELDOWN )
+						mState.relZ -= 120;
+				}
+				break;
+			}
+			case SDL_MOUSEBUTTONUP:
+			{
+				int sdlButton = events[i].button.button;
+				if( sdlButton <= SDL_BUTTON_RIGHT )
+				{	//Left, Right, or Middle
+					mState.buttons &= ~(1 << ButtonMask[sdlButton]);
+					if( mBuffered && listener )
+						if( listener->mouseReleased(MouseEvent(this,0,mState), ButtonMask[sdlButton]) == false )
+							return;
+				}
+				break;
+			}
+		}
+	}
+
+	//Handle X/Y axis move
+	if( mouseXYMoved )
+	{
+		SDL_GetMouseState( &mState.abX, &mState.abY );
+		SDL_GetRelativeMouseState( &mState.relX, &mState.relY );
+
+		if( mBuffered && listener )
+			listener->mouseMoved(MouseEvent(this, 0, mState));
+	}
+	//Handle Z Motion
+	if( mouseZMoved )
+	{
+		mState.abZ += mState.relZ;
+		if( mBuffered && listener )
+			listener->mouseMoved(MouseEvent(this, 0, mState));
+	}
+
+	//Handle Alt-Tabbing
+	SDLInputManager* man = static_cast<SDLInputManager*>(InputManager::getSingletonPtr());
+	if( man->_getGrabMode() == false )
+	{
+		if( mRegainFocus == false && mGrabbed == true )
+		{	//We had focus, but must release it now
+			_setGrab(false);
+			_setVisible(true);
+		}
+		else if( mRegainFocus == true && mGrabbed == false )
+		{	//We are gaining focus back (mouse clicked in window)
+			_setGrab(true);
+			_setVisible(false);
+			man->_setGrabMode(true);	//Notify manager
+		}
+	}
+}
+
+//-------------------------------------------------------------------//
+void SDLMouse::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//-------------------------------------------------------------------//
+void SDLMouse::_setGrab(bool grabbed)
+{
+	if( grabbed )
+		SDL_WM_GrabInput(SDL_GRAB_ON);
+	else
+		SDL_WM_GrabInput(SDL_GRAB_OFF);
+
+	mGrabbed = grabbed;
+}
+
+//-------------------------------------------------------------------//
+void SDLMouse::_setVisible(bool visible)
+{
+
+	if( visible )
+		SDL_ShowCursor(SDL_ENABLE);
+	else
+		SDL_ShowCursor(SDL_DISABLE);
+}

+ 107 - 0
CamelotOISInput/Source/OIS/extras/LIRC/OISLIRC.cpp

@@ -0,0 +1,107 @@
+#include "OISConfig.h"
+#ifdef OIS_LIRC_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OISLIRC.h"
+#include "OISLIRCFactoryCreator.h"
+#include "OISException.h"
+
+using namespace OIS;
+
+//-----------------------------------------------------------------------------------//
+LIRCControl::LIRCControl(InputManager* creator, int id, bool buffered, LIRCFactoryCreator* local_creator, RemoteInfo &info) :
+	JoyStick("Generic LIRC", buffered, id, creator),
+	mLIRCCreator(local_creator),
+	mRingBuffer(OIS_LIRC_EVENT_BUFFER),
+	mInfo(info)
+{
+	//Fill in joystick information
+	mState.mButtons.resize(mInfo.buttons);
+}
+
+//-----------------------------------------------------------------------------------//
+LIRCControl::~LIRCControl()
+{
+}
+
+//-----------------------------------------------------------------------------------//
+void LIRCControl::_initialize()
+{
+	mState.clear();
+}
+
+//-----------------------------------------------------------------------------------//
+void LIRCControl::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//-----------------------------------------------------------------------------------//
+void LIRCControl::capture()
+{
+	//Anything to read?
+	int entries = mRingBuffer.GetReadAvailable();
+	if( entries <= 0 )
+		return;
+
+	LIRCEvent events[OIS_LIRC_EVENT_BUFFER];
+	if( entries > OIS_LIRC_EVENT_BUFFER )
+		entries = OIS_LIRC_EVENT_BUFFER;
+	
+	mRingBuffer.Read(events, entries);
+
+	//Loop through each event
+	for( int i = 0; i < entries; ++i )
+	{
+		if( mBuffered && mListener )
+		{
+			//Quickly send off button events (there is no real stored state)
+			//As, even a held down button will kep generating button presses
+			mState.mButtons[events[i].button] = true;
+			if( !mListener->buttonPressed(JoyStickEvent(this, mState), events[i].button) )
+				return;
+
+			mState.mButtons[events[i].button] = false;
+			if( !mListener->buttonReleased(JoyStickEvent(this, mState), events[i].button) )
+				return;
+		}
+	}
+}
+
+//-----------------------------------------------------------------------------------//
+void LIRCControl::queueButtonPressed(const std::string &id)
+{
+	if( mRingBuffer.GetWriteAvailable() > 0 )
+	{
+		LIRCEvent evt;
+		evt.button = mInfo.buttonMap[id];
+		mRingBuffer.Write(&evt, 1);
+	}
+}
+
+//-----------------------------------------------------------------------------------//
+Interface* LIRCControl::queryInterface(Interface::IType type)
+{
+	return 0;
+}
+#endif

+ 88 - 0
CamelotOISInput/Source/OIS/extras/LIRC/OISLIRC.h

@@ -0,0 +1,88 @@
+#include "OISConfig.h"
+#ifdef OIS_LIRC_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_LIRC_H
+#define OIS_LIRC_H
+#include "OISJoyStick.h"
+#include "OISLIRCRingBuffer.h"
+
+namespace OIS
+{
+	class LIRCFactoryCreator;
+
+	struct RemoteInfo
+	{
+		RemoteInfo() : buttons(0) {}
+
+		RemoteInfo( const RemoteInfo &other )
+		{
+			buttons = other.buttons;
+			buttonMap = other.buttonMap;
+		}
+
+		int buttons;
+		std::map<std::string, int> buttonMap;
+	};
+
+	//Number of ring buffer events. should be nice sized (the structure is not very big)
+	//Will be rounded up to power of two automatically
+	#define OIS_LIRC_EVENT_BUFFER 16
+
+	/**	Specialty joystick - Linux Infrared Remote Support */
+	class _OISExport LIRCControl : public JoyStick
+	{
+		friend class LIRCFactoryCreator;
+	public:
+		LIRCControl(InputManager* creator, int id, bool buffered, LIRCFactoryCreator* local_creator, RemoteInfo &info);
+		~LIRCControl();
+
+		//Overrides of Object
+		/** copydoc Object::setBuffered */
+		void setBuffered(bool buffered);
+
+		/** copydoc Object::capture */
+		void capture();
+
+		/** copydoc Object::queryInterface */
+		Interface* queryInterface(Interface::IType type);
+
+		/** copydoc Object::_intialize */
+		void _initialize();
+
+	protected:
+		//! Internal method used to add a button press to the queue (called from thread)
+		void queueButtonPressed(const std::string &id);
+
+		//! The creator who created us
+		LIRCFactoryCreator *mLIRCCreator;
+
+		//! Ringbuffer is used to store events from thread and be read from capture
+		LIRCRingBuffer mRingBuffer;
+
+		//! Information about remote
+		RemoteInfo mInfo;
+	};
+}
+#endif //OIS_LIRC_H
+#endif

+ 405 - 0
CamelotOISInput/Source/OIS/extras/LIRC/OISLIRCFactoryCreator.cpp

@@ -0,0 +1,405 @@
+#include "OISConfig.h"
+#ifdef OIS_LIRC_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OISLIRCFactoryCreator.h"
+#include "OISException.h"
+#include <assert.h>
+#include <stdlib.h>
+
+#ifdef OIS_WIN32_PLATFORM
+#  pragma warning (disable : 4996)
+#  pragma warning (disable : 4267)
+#  pragma warning (disable : 4554)
+#  pragma warning (disable : 4996)
+#  define _WIN32_WINNT 0x0500
+#endif
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread.hpp>
+
+#include <istream>
+#include <sstream>
+
+using namespace OIS;
+
+//---------------------------------------------------------------------------------//
+class LIRCFactoryCreator::BoostWrapper
+{
+public:
+	LIRCFactoryCreator::BoostWrapper() : mSocket(mIOService), mThreadHandler(0)
+	{
+	}
+
+	//TCP stuff
+	boost::asio::io_service mIOService;
+	boost::asio::ip::tcp::socket mSocket;
+
+	//Thread Stuff
+	//! Boost thread execution object (only alive when at least 1 lirc is alive)
+	boost::thread *mThreadHandler;
+		
+	//! Gaurds access to the active lirc list
+	boost::mutex mLircListMutex;
+
+};
+
+//---------------------------------------------------------------------------------//
+LIRCFactoryCreator::LIRCFactoryCreator() :
+	mConnected(false),
+	mThreadRunning(false),
+	mCount(0),
+	mWrapped(0)
+{
+	mWrapped = new BoostWrapper();
+
+	mIP   = (getenv("OIS_LIRC_IP") != 0) ? getenv("OIS_LIRC_IP") : "127.0.0.1";
+	mPort = (getenv("OIS_LIRC_PORT") != 0) ? getenv("OIS_LIRC_PORT") : "8765";
+
+	try
+	{
+		enableConnection(true);
+		discoverRemotes();
+	}
+	catch(...)
+	{
+		mCount = 0;
+	}
+
+	//Regardless of if there is remotes or not, we will close the conenction now.
+	enableConnection(false);
+}
+
+//---------------------------------------------------------------------------------//
+LIRCFactoryCreator::~LIRCFactoryCreator()
+{
+	enableConnectionThread(false);
+	enableConnection(false);
+
+	delete mWrapped;
+}
+
+//---------------------------------------------------------------------------------//
+void LIRCFactoryCreator::discoverRemotes()
+{
+	//http://www.lirc.org/html/technical.html#applications
+	mCount = 0;
+
+	mWrapped->mSocket.write_some(boost::asio::buffer("LIST\n"));
+
+	boost::asio::streambuf buffer;
+
+	//Read all remotes
+	bool start = false;
+	bool data = false;
+	for(;;)
+	{
+		boost::asio::read_until(mWrapped->mSocket, buffer, '\n');
+
+		std::istream str(&buffer);
+		std::string res;
+		str >> res;
+
+		if( res == "" )				//If nothing left, we are done
+			break;
+		else if( res == "ERROR" )	//If any errors, we leave immediately
+			return;
+		else if( res == "END" )		//We have reached the end block
+			start = false;
+		else if( res == "DATA" )	//After Data will be a list of remote names
+		{
+			start = true;
+			data = true;
+			continue;
+		}
+
+		//Have we  gotten the DATA word yet?
+		if( start == false )
+			continue;
+
+		if( data ) //How many?
+			mCount = atoi(res.c_str());
+		else //What follows should now be a list of remote names
+			mUnusedRemotes.push_back(res);
+
+		data = false;
+	}
+
+	//Read information about each remote
+	boost::asio::streambuf buffer2;
+	for( int i = 0; i < mCount; ++i )
+	{
+		std::ostringstream istr;
+		istr << "LIST " << mUnusedRemotes[i] << "\n";
+		
+		mWrapped->mSocket.write_some(boost::asio::buffer(istr.str()));
+		RemoteInfo information;
+		int buttonCount = 0;
+
+		start = data = false;
+		
+		for(;;)
+		{
+			boost::asio::read_until(mWrapped->mSocket, buffer, '\n');
+
+			std::istream str(&buffer);
+			std::string res;
+			str >> res;
+
+			if( res == "" )				//If nothing left, we are done
+				break;
+			else if( res == "ERROR" )	//If error, bail out
+				return;
+			else if( res == "END" )		//We have reached the end block
+				start = false;
+			else if( res == "DATA" )	//After Data will be button count
+			{
+				start = true;
+				data = true;
+				continue;
+			}
+
+			//Have we  gotten the DATA word yet?
+			if( start == false )
+				continue;
+
+			if( data ) //After button count, there will be a list of button names
+				information.buttons = atoi(res.c_str());
+			else
+				information.buttonMap[res] = buttonCount++;
+
+			data = false;
+		}
+
+		mJoyStickInformation[mUnusedRemotes[i]] = information;
+	}
+}
+
+//---------------------------------------------------------------------------------//
+void LIRCFactoryCreator::enableConnection(bool enable, bool blocking)
+{
+	if( enable == true && mConnected == false )
+	{
+		boost::asio::ip::tcp::resolver resolver(mWrapped->mIOService);
+		boost::asio::ip::tcp::resolver::query query(mIP, mPort);
+		boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
+		boost::asio::ip::tcp::resolver::iterator end;
+
+		//Connect (trying all found connections - ip4/ip6)
+		boost::asio::error result = boost::asio::error::host_not_found;
+		while (result && endpoint_iterator != end)
+		{
+			mWrapped->mSocket.close();
+			mWrapped->mSocket.connect(*endpoint_iterator++, boost::asio::assign_error(result));
+		}
+
+		if (result != boost::asio::error::success)
+			throw (result);
+
+		if( blocking == false )
+		{
+			mWrapped->mSocket.io_control(boost::asio::socket_base::non_blocking_io(true));
+		}
+
+		mConnected = true;
+	}
+	else if( enable == false )
+	{
+		mWrapped->mSocket.close();
+		mConnected = false;
+	}
+}
+
+//---------------------------------------------------------------------------------//
+void LIRCFactoryCreator::enableConnectionThread(bool enable)
+{
+	if( enable == true && mThreadRunning == false )
+	{
+		mThreadRunning = true;
+		mWrapped->mThreadHandler = new boost::thread(boost::bind(&LIRCFactoryCreator::threadUpdate, this));
+	}
+	else if( enable == false && mThreadRunning == true )
+	{
+		mThreadRunning = false;
+		mWrapped->mThreadHandler->join();
+		delete mWrapped->mThreadHandler;
+		mWrapped->mThreadHandler = 0;
+	}
+}
+
+//---------------------------------------------------------------------------------//
+void LIRCFactoryCreator::threadUpdate()
+{
+	boost::xtime timer;
+	boost::asio::streambuf buffer;
+	std::istream stream(&buffer);
+	std::string code, repeat, button, remote;
+
+
+	while( mThreadRunning )
+	{
+		try
+		{
+			while(  mWrapped->mSocket.in_avail() > 0 )
+			{
+				boost::asio::read_until(mWrapped->mSocket, buffer, '\n');
+				
+				stream >> code;   //64 bit value, ignorable
+				stream >> repeat; //Repeat rate starting at zero (we ignore, for now)
+				stream >> button; //Button name
+				stream >> remote; //Remote name
+
+				{	//Lock object, find out which remote sent event
+					boost::mutex::scoped_lock arrayLock(mWrapped->mLircListMutex);
+					std::map<std::string, LIRCControl*>::iterator i = mUpdateRemotes.find(remote);
+					if( i != mUpdateRemotes.end() )
+					{
+						i->second->queueButtonPressed(button);
+					}
+				}
+			}
+		}
+		catch(...)
+		{	//Hmm, what should we do if we get a socket error here.. Ignore it I suppose,
+		}	//and wait till the used remote objects get shutdown. We could try to 
+			//reconnect, but how do we know if we will even get the same remotes.
+
+		boost::xtime_get(&timer, boost::TIME_UTC);
+		timer.nsec += 300000000; // 100 000 000 ~= .3 sec
+		boost::thread::sleep(timer);
+	}
+}
+
+//---------------------------------------------------------------------------------//
+DeviceList LIRCFactoryCreator::freeDeviceList()
+{
+	DeviceList list;
+	for( std::vector<std::string>::iterator i = mUnusedRemotes.begin(); i != mUnusedRemotes.end(); ++i )
+		list.insert(std::make_pair(OISJoyStick, *i));
+
+	return list;
+}
+
+//---------------------------------------------------------------------------------//
+int LIRCFactoryCreator::totalDevices(Type iType)
+{
+	if( iType == OISJoyStick )
+		return mCount;
+	else
+		return 0;
+}
+
+//---------------------------------------------------------------------------------//
+int LIRCFactoryCreator::freeDevices(Type iType)
+{
+	if( iType == OISJoyStick )
+		return (int)mUnusedRemotes.size();
+	else
+		return 0;
+}
+
+//---------------------------------------------------------------------------------//
+bool LIRCFactoryCreator::vendorExist(Type iType, const std::string & vendor)
+{
+	if( iType == OISJoyStick && std::find(mUnusedRemotes.begin(), mUnusedRemotes.end(), vendor) != mUnusedRemotes.end() )
+		return true;
+	else
+		return false;
+}
+
+//---------------------------------------------------------------------------------//
+Object* LIRCFactoryCreator::createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor)
+{
+	if( mUnusedRemotes.size() > 0 )
+	{
+		std::vector<std::string>::iterator remote = mUnusedRemotes.end();
+		if( vendor == "" )
+			remote = mUnusedRemotes.begin();
+		else
+			remote = std::find(mUnusedRemotes.begin(), mUnusedRemotes.end(), vendor);
+
+		if( remote != mUnusedRemotes.end() )
+		{
+			//Make sure connection is established
+			enableConnection(true, false);
+
+			//Make sure connection thread is alive
+			enableConnectionThread(true);
+
+			//Create device
+			LIRCControl *obj = new LIRCControl(creator, 0, bufferMode, this, mJoyStickInformation[*remote]);
+
+			//Add to used list, and then remove from unused list
+			{
+				boost::mutex::scoped_lock arrayLock(mWrapped->mLircListMutex);
+				mUpdateRemotes[*remote] = obj;
+			}
+			mUnusedRemotes.erase(remote);
+
+			return obj;
+		}
+	}
+	
+	OIS_EXCEPT(E_InputDeviceNonExistant, "No Device found which matches description!");
+}
+
+//---------------------------------------------------------------------------------//
+void LIRCFactoryCreator::destroyObject(Object* obj)
+{
+	if( obj == 0 )
+		return;
+
+	int remotes_alive = 0;
+
+	{	//Scope lock
+		boost::mutex::scoped_lock arrayLock(mWrapped->mLircListMutex);
+
+		//Find object
+		std::map<std::string, LIRCControl*>::iterator i = mUpdateRemotes.begin(), e = mUpdateRemotes.end();
+		bool found = false;
+		for(; i != e; ++i)
+		{
+			if( i->second == obj )
+			{
+				found = true;
+				break;
+			}
+		}
+
+		if( found == false )
+			OIS_EXCEPT(E_General, "Device not found in LIRC remote collection!");
+
+		//Move from used to unused list
+		mUnusedRemotes.push_back(i->first);
+		mUpdateRemotes.erase(i);
+		
+		delete obj;
+
+		remotes_alive = (int)mUpdateRemotes.size();
+	}
+
+	//Destroy thread if no longer in use (we do this after unlocking mutex!)
+	if( remotes_alive == 0 )
+		enableConnectionThread(false);
+}
+#endif

+ 98 - 0
CamelotOISInput/Source/OIS/extras/LIRC/OISLIRCFactoryCreator.h

@@ -0,0 +1,98 @@
+#include "OISConfig.h"
+#ifdef OIS_LIRC_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_LIRCFactoryCreator_H
+#define OIS_LIRCFactoryCreator_H
+
+#include "OISPrereqs.h"
+#include "OISFactoryCreator.h"
+#include "OISLIRC.h"
+
+namespace OIS
+{
+	//Forward declare local classes
+	class LIRCControl;
+
+	/** LIRC Factory Creator Class */
+	class _OISExport LIRCFactoryCreator : public FactoryCreator
+	{
+	public:
+		LIRCFactoryCreator();
+		~LIRCFactoryCreator();
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+	protected:
+		//! Gets a list of all remotes available
+		void discoverRemotes();
+
+		//! Connects to LIRC server
+		void enableConnection(bool enable, bool blocking = true);
+
+		//! Creates/destroys threaded read
+		void enableConnectionThread(bool enable);
+
+		void threadUpdate();
+
+		std::string mIP;
+		std::string mPort;
+		bool mConnected;
+		volatile bool mThreadRunning;
+		std::map<std::string, LIRCControl*> mUpdateRemotes;
+
+		//! List of vendor named remotes that are not used yet
+		std::vector<std::string> mUnusedRemotes;
+		
+		//! Information about enumerated remotes
+		std::map<std::string, RemoteInfo> mJoyStickInformation;
+
+		//! Number of total found remotes
+		int mCount;
+
+		//! Get the slow boost header includes from this header by using a proxy wrapper
+		class BoostWrapper;
+
+		//! Wrapped objects
+		BoostWrapper *mWrapped;
+	};
+}
+#endif //OIS_LIRCFactoryCreator_H
+#endif

+ 269 - 0
CamelotOISInput/Source/OIS/extras/LIRC/OISLIRCRingBuffer.h

@@ -0,0 +1,269 @@
+#include "OISConfig.h"
+#ifdef OIS_LIRC_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+
+ # ------------------------#
+ # Original License follows:
+ # ------------------------#
+
+ * PortAudio Portable Real-Time Audio Library
+ * Latest version at: http://www.audiomulch.com/portaudio/
+ * <platform> Implementation
+ * Copyright (c) 1999-2000 <author(s)>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef OIS_LIRCRingBuffer_H
+#define OIS_LIRCRingBuffer_H
+
+#include "OISPrereqs.h"
+
+namespace OIS
+{
+	struct LIRCEvent
+	{
+		//! high bit (0x80000000) will be on if button pushed, else it was released
+		unsigned int button;
+	};
+
+	/// <summary>
+	/// Ring Buffer (fifo) used to store 16bit pcm data
+	/// </summary>
+	class LIRCRingBuffer
+	{
+	private:
+		//! Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init
+		int bufferSize;
+		//! Used for wrapping indices with extra bit to distinguish full/empty.
+		int bigMask;
+		// Used for fitting indices to buffer.
+		int smallMask;
+
+		// Buffer holding the actual event buffers
+		LIRCEvent *buffer;
+
+		//! Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex.
+		volatile int writeIndex; 
+		
+		//! Index of next readable byte. Set by RingBuffer_AdvanceReadIndex.
+		volatile int readIndex;	
+
+	public:
+		LIRCRingBuffer( unsigned int numEntries )
+		{
+			numEntries = RoundUpToNextPowerOf2( numEntries );
+
+			//2 bytes per short
+			bufferSize = (int)numEntries;
+			buffer = new LIRCEvent[numEntries];
+
+			Flush();
+
+			bigMask = (int)(numEntries*2)-1;
+			smallMask = (int)(numEntries)-1;
+		}
+
+		~LIRCRingBuffer()
+		{
+			delete buffer;
+		}
+
+		unsigned int RoundUpToNextPowerOf2( unsigned int n )
+		{
+			int numBits = 0;
+			if( ((n-1) & n) == 0) 
+			return n; //Already Power of two.
+
+			while( n > 0 )
+			{
+				n= n>>1;
+				numBits++;
+			}
+			return (unsigned int)(1<<numBits);
+		}
+
+
+		int GetReadAvailable( )
+		{
+			return ( (writeIndex - readIndex) & bigMask );
+		}
+
+
+		int GetWriteAvailable( )
+		{
+			return ( bufferSize - GetReadAvailable());
+		}
+
+
+		int Write( LIRCEvent *data, int numEntries )
+		{
+			int size1 = 0, size2 = 0, numWritten;
+			int data1Ptr = 0, data2Ptr = 0;
+			
+			numWritten = GetWriteRegions( numEntries, data1Ptr, size1, data2Ptr, size2 );
+
+			if( size2 > 0 )
+			{
+				//copy to two parts
+				memcpy( &buffer[data1Ptr], data, sizeof(LIRCEvent) * size1 );
+				//Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 );
+				memcpy( &buffer[data2Ptr], &data[size1], sizeof(LIRCEvent) * size2 );
+				//Array.Copy( data, offsetPtr + size1, buffer, data2Ptr, size2 );
+			}
+			else
+			{	//Copy all continous
+				memcpy( &buffer[data1Ptr], data, sizeof(LIRCEvent) * size1 );
+				//Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 );
+			}
+			AdvanceWriteIndex( numWritten );
+			return numWritten;
+		}
+
+
+		/// <summary>
+		/// Reads requested number of entries into sent array.
+		/// Returns number written
+		/// </summary>
+		int Read( LIRCEvent *data, int numEntries )
+		{
+			int size1 = 0, size2 = 0, numRead, data1Ptr = 0, data2Ptr = 0;
+			
+			numRead = GetReadRegions( numEntries, data1Ptr, size1, data2Ptr, size2 );
+			
+			if( size2 > 0 )
+			{
+				memcpy( data, &buffer[data1Ptr], sizeof(LIRCEvent) * size1 );
+				//Array.Copy( buffer, data1Ptr, data, 0, size1 );
+				memcpy( &data[size1], &buffer[data2Ptr], sizeof(LIRCEvent) * size2 );
+				//Array.Copy( buffer, data2Ptr, data, size1, size2 );
+			}
+			else
+				memcpy( data, &buffer[data1Ptr], sizeof(LIRCEvent) * size1 );
+				//Array.Copy( buffer, data1Ptr, data, 0, size1 );
+
+			AdvanceReadIndex( numRead );
+			return numRead;
+		}
+
+	private:
+
+		int GetWriteRegions( int numEntries, int &dataPtr1, int &sizePtr1,
+							 int &dataPtr2, int &sizePtr2 )
+		{
+			int   index;
+			int   available = GetWriteAvailable();
+			if( numEntries > available ) 
+				numEntries = available;
+		
+			//Check to see if write is not contiguous.
+			index = writeIndex & smallMask;
+			if( (index + numEntries) > bufferSize )
+			{
+				//Write data in two blocks that wrap the buffer.
+				int   firstHalf = bufferSize - index;
+				dataPtr1 = index;//&buffer[index];
+				sizePtr1 = firstHalf;
+				dataPtr2 = 0;//&buffer[0];
+				sizePtr2 = numEntries - firstHalf;
+			}
+			else
+			{
+				dataPtr1 = index;//&buffer[index];
+				sizePtr1 = numEntries;
+				dataPtr2 = 0;
+				sizePtr2 = 0;
+			}
+			return numEntries;
+		}
+	
+
+		int GetReadRegions( int numEntries, int &dataPtr1, int &sizePtr1, int &dataPtr2, int &sizePtr2 )
+		{
+			int   index;
+			int   available = GetReadAvailable( );
+			if( numEntries > available ) 
+				numEntries = available;
+			
+			// Check to see if read is not contiguous
+			index = readIndex & smallMask;
+			if( (index + numEntries) > bufferSize )
+			{
+				// Write data in two blocks that wrap the buffer
+				int firstHalf = bufferSize - index;
+				dataPtr1 = index;//&buffer[index];
+				sizePtr1 = firstHalf;
+				dataPtr2 = 0;//&buffer[0];
+				sizePtr2 = numEntries - firstHalf;
+			}
+			else
+			{
+				dataPtr1 = index;//&buffer[index];
+				sizePtr1 = numEntries;
+				dataPtr2 = 0;
+				sizePtr2 = 0;
+			}
+			return numEntries;
+		}
+
+
+		int AdvanceWriteIndex( int numEntries )
+		{
+			 return writeIndex = (writeIndex + numEntries) & bigMask;
+		}
+
+
+		int AdvanceReadIndex( int numEntries )
+		{
+			return readIndex = (readIndex + numEntries) & bigMask;
+		}
+
+
+		void Flush( )
+		{
+			writeIndex = readIndex = 0;
+		}
+	};
+}
+#endif //#define OIS_LIRCRingBuffer_H
+#endif

+ 80 - 0
CamelotOISInput/Source/OIS/iphone/iPhoneAccelerometer.mm

@@ -0,0 +1,80 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+#include "iphone/iPhoneAccelerometer.h"
+#include "iphone/iPhoneInputManager.h"
+
+using namespace OIS;
+
+//-------------------------------------------------------------------//
+iPhoneAccelerometer::iPhoneAccelerometer( InputManager* creator, bool buffered )
+	: JoyStick(creator->inputSystemName(), buffered, 0, creator)
+{
+    iPhoneInputManager *man = static_cast<iPhoneInputManager*>(mCreator);
+    
+    man->_setAccelerometerUsed(true);
+    [man->_getDelegate() setAccelerometerObject:this];
+    [[UIAccelerometer sharedAccelerometer] setDelegate:man->_getDelegate()];
+    mUpdateInterval = 60.0f;
+}
+
+iPhoneAccelerometer::~iPhoneAccelerometer()
+{
+    iPhoneInputManager *man = static_cast<iPhoneInputManager*>(mCreator);
+    
+    man->_setAccelerometerUsed(false);
+    [man->_getDelegate() setAccelerometerObject:nil];
+}
+
+void iPhoneAccelerometer::_initialize()
+{
+	// Clear old joy state
+    mState.mVectors.resize(1);
+	mState.clear();
+	mTempState.clear();
+
+    // Set the update interval
+    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / mUpdateInterval)];
+}
+
+void iPhoneAccelerometer::setBuffered( bool buffered )
+{
+	mBuffered = buffered;
+}
+
+void iPhoneAccelerometer::didAccelerate(UIAcceleration *acceleration)
+{
+    mTempState.clear();
+    
+    mTempState.x = acceleration.x;
+    mTempState.y = acceleration.y;
+    mTempState.z = acceleration.z;
+}
+
+void iPhoneAccelerometer::capture()
+{
+    mState.clear();
+    mState.mVectors[0] = mTempState;
+
+    if(mListener && mBuffered)
+        mListener->axisMoved(JoyStickEvent(this, mState), 0);
+}

+ 224 - 0
CamelotOISInput/Source/OIS/iphone/iPhoneInputManager.mm

@@ -0,0 +1,224 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "iphone/iPhoneInputManager.h"
+#include "iphone/iPhoneHelpers.h"
+#include "iphone/iPhoneAccelerometer.h"
+#include "iphone/iPhoneMultiTouch.h"
+#include "OISException.h"
+
+using namespace std;
+using namespace OIS;
+
+@implementation InputDelegate
+
+@synthesize touchObject;
+@synthesize accelerometerObject;
+
+- (id)init {
+    if((self = [super init])) {
+        touchObject = nil;
+        accelerometerObject = nil;
+    }
+    return self;
+}
+
+- (void)dealloc {
+    delete touchObject; touchObject = NULL;
+    delete accelerometerObject; accelerometerObject = NULL;
+
+    [super dealloc];
+}
+
+- (BOOL)canBecomeFirstResponder
+{
+    return YES;
+}
+
+#pragma mark Accelerator Event Handling
+- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
+    accelerometerObject->didAccelerate(acceleration);
+}
+
+#pragma mark Touch Event Handling
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+    for(UITouch *touch in touches) {
+        touchObject->_touchEnded(touch);
+    }
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
+    for(UITouch *touch in touches) {
+        touchObject->_touchMoved(touch);
+    }
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
+    for(UITouch *touch in touches) {
+        touchObject->_touchCancelled(touch);
+    }
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+    for(UITouch *touch in touches) {
+        touchObject->_touchBegan(touch);
+    }
+}
+
+@end
+
+//--------------------------------------------------------------------------------//
+iPhoneInputManager::iPhoneInputManager() : InputManager("iPhone Input Manager")
+{
+    mHideMouse = true;
+	bAccelerometerUsed = bMultiTouchUsed = false;
+
+	// Setup our internal factories
+	mFactories.push_back(this);
+}
+
+//--------------------------------------------------------------------------------//
+iPhoneInputManager::~iPhoneInputManager()
+{
+    [mDelegate release]; mDelegate = nil;
+    [mWindow release]; mWindow = nil;
+}
+
+//--------------------------------------------------------------------------------//
+void iPhoneInputManager::_initialize( ParamList &paramList )
+{
+	_parseConfigSettings( paramList );
+    
+    mDelegate = [[InputDelegate alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+    
+    // Set flags that we want to accept multiple finger touches and be the only one to receive touch events
+    [mDelegate setMultipleTouchEnabled:YES];
+    [mDelegate setExclusiveTouch:YES];
+    [mDelegate becomeFirstResponder];
+
+    [mWindow addSubview:mDelegate];
+}
+
+//--------------------------------------------------------------------------------//
+void iPhoneInputManager::_parseConfigSettings( ParamList &paramList )
+{
+    // Some carbon apps are running in a window, however full screen apps
+	// do not have a window, so we need to account for that too.
+	ParamList::iterator i = paramList.find("WINDOW");
+	if(i != paramList.end())
+	{
+		mWindow = (UIWindow *)strtoul(i->second.c_str(), 0, 10);
+		if(mWindow == 0)
+			mWindow = nil;
+    }
+	else
+	{
+		// else get the main active window.. user might not have access to it through some
+		// graphics libraries, if that fails then try at the application level.
+        mWindow = [[UIApplication sharedApplication] keyWindow];
+	}
+	
+	if(mWindow == nil)
+		OIS_EXCEPT( E_General, "iPhoneInputManager::_parseConfigSettings >> Unable to find a window or event target" );
+}
+
+//--------------------------------------------------------------------------------//
+DeviceList iPhoneInputManager::freeDeviceList()
+{
+	DeviceList ret;
+
+	if( bAccelerometerUsed == false )
+		ret.insert(std::make_pair(OISJoyStick, mInputSystemName));
+
+	if( bMultiTouchUsed == false )
+		ret.insert(std::make_pair(OISMultiTouch, mInputSystemName));
+
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+int iPhoneInputManager::totalDevices(Type iType)
+{
+	switch(iType)
+	{
+        case OISJoyStick: return 1;
+        case OISMultiTouch: return 1;
+        default: return 0;
+	}
+}
+
+//--------------------------------------------------------------------------------//
+int iPhoneInputManager::freeDevices(Type iType)
+{
+	switch(iType)
+	{
+        case OISJoyStick: return bAccelerometerUsed ? 0 : 1;
+        case OISMultiTouch: return bMultiTouchUsed ? 0 : 1;
+        default: return 0;
+	}
+}
+
+//--------------------------------------------------------------------------------//
+bool iPhoneInputManager::vendorExist(Type iType, const std::string & vendor)
+{
+	if( ( iType == OISMultiTouch || iType == OISJoyStick ) && vendor == mInputSystemName )
+		return true;
+
+	return false;
+}
+
+//--------------------------------------------------------------------------------//
+Object* iPhoneInputManager::createObject(InputManager* creator, Type iType, bool bufferMode, 
+									  const std::string & vendor)
+{
+	Object *obj = 0;
+
+	switch(iType)
+	{
+        case OISJoyStick:
+        {
+            if( bAccelerometerUsed == false )
+                obj = new iPhoneAccelerometer(this, bufferMode);
+            break;
+        }
+        case OISMultiTouch:
+        {
+            if( bMultiTouchUsed == false )
+                obj = new iPhoneMultiTouch(this, bufferMode);
+            break;
+        }
+        default:
+            break;
+	}
+
+	if( obj == 0 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	return obj;
+}
+
+//--------------------------------------------------------------------------------//
+void iPhoneInputManager::destroyObject(Object* obj)
+{
+	delete obj;
+}

+ 177 - 0
CamelotOISInput/Source/OIS/iphone/iPhoneMultiTouch.mm

@@ -0,0 +1,177 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+#include "iphone/iPhoneMultiTouch.h"
+#include "iphone/iPhoneInputManager.h"
+
+using namespace OIS;
+
+//-------------------------------------------------------------------//
+iPhoneMultiTouch::iPhoneMultiTouch( InputManager* creator, bool buffered )
+	: MultiTouch(creator->inputSystemName(), buffered, 0, creator)
+{
+	iPhoneInputManager *man = static_cast<iPhoneInputManager*>(mCreator);
+
+    man->_setMultiTouchUsed(true);
+    [man->_getDelegate() setTouchObject:this];
+}
+
+iPhoneMultiTouch::~iPhoneMultiTouch()
+{
+	iPhoneInputManager *man = static_cast<iPhoneInputManager*>(mCreator);
+    
+    man->_setMultiTouchUsed(false);
+    [man->_getDelegate() setTouchObject:nil];
+}
+
+void iPhoneMultiTouch::_initialize()
+{
+//    mTempState.clear();
+}
+
+void iPhoneMultiTouch::setBuffered( bool buffered )
+{
+	mBuffered = buffered;
+}
+
+void iPhoneMultiTouch::capture()
+{
+#if 0
+    for( std::multiset<MultiTouchState *>::iterator i = mStates.begin(), e = mStates.end(); i != e; ++i )
+    {
+        // Clear the state first
+        dynamic_cast<MultiTouchState *>(*i)->clear();
+
+        if(mTempState.X.rel || mTempState.Y.rel || mTempState.Z.rel)
+        {
+            MultiTouchState *iState = dynamic_cast<MultiTouchState *>(*i);
+    //		NSLog(@"%i %i %i", mTempState.X.rel, mTempState.Y.rel, mTempState.Z.rel);
+
+            // Set new relative motion values
+            iState->X.rel = mTempState.X.rel;
+            iState->Y.rel = mTempState.Y.rel;
+            iState->Z.rel = mTempState.Z.rel;
+            
+            // Update absolute position
+            iState->X.abs += mTempState.X.rel;
+            iState->Y.abs += mTempState.Y.rel;
+            
+            if(iState->X.abs > iState->width)
+                iState->X.abs = iState->width;
+            else if(iState->X.abs < 0)
+                iState->X.abs = 0;
+
+            if(iState->Y.abs > iState->height)
+                iState->Y.abs = iState->height;
+            else if(iState->Y.abs < 0)
+                iState->Y.abs = 0;
+                
+            iState->Z.abs += mTempState.Z.rel;
+            
+            //Fire off event
+            if(mListener && mBuffered)
+                mListener->touchMoved(MultiTouchEvent(this, *iState));
+        }
+    }
+
+	mTempState.clear();
+#endif
+}
+
+void iPhoneMultiTouch::_touchBegan(UITouch *touch)
+{
+    CGPoint location = [touch locationInView:static_cast<iPhoneInputManager*>(mCreator)->_getDelegate()];
+
+    MultiTouchState newState;
+    newState.X.abs = location.x;
+    newState.Y.abs = location.y;
+    newState.touchType |= 1 << MT_Pressed;
+
+    if( mListener && mBuffered )
+    {
+        mListener->touchPressed(MultiTouchEvent(this, newState));
+    }
+    else
+    {
+        mStates.push_back(newState);
+    }
+}
+
+void iPhoneMultiTouch::_touchEnded(UITouch *touch)
+{
+    CGPoint location = [touch locationInView:static_cast<iPhoneInputManager*>(mCreator)->_getDelegate()];
+
+    MultiTouchState newState;
+    newState.X.abs = location.x;
+    newState.Y.abs = location.y;
+    newState.touchType |= 1 << MT_Released;
+
+    if( mListener && mBuffered )
+    {
+        mListener->touchReleased(MultiTouchEvent(this, newState));
+    }
+    else
+    {
+        mStates.push_back(newState);
+    }
+}
+
+void iPhoneMultiTouch::_touchMoved(UITouch *touch)
+{
+    CGPoint location = [touch locationInView:static_cast<iPhoneInputManager*>(mCreator)->_getDelegate()];
+    CGPoint previousLocation = [touch previousLocationInView:static_cast<iPhoneInputManager*>(mCreator)->_getDelegate()];
+
+    MultiTouchState newState;
+    newState.X.rel = (location.x - previousLocation.x);
+    newState.Y.rel = (location.y - previousLocation.y);
+    newState.X.abs = location.x;
+    newState.Y.abs = location.y;
+    newState.touchType |= 1 << MT_Moved;
+
+    if( mListener && mBuffered )
+    {
+        mListener->touchMoved(MultiTouchEvent(this, newState));
+    }
+    else
+    {
+        mStates.push_back(newState);
+    }
+}
+
+void iPhoneMultiTouch::_touchCancelled(UITouch *touch)
+{
+    CGPoint location = [touch locationInView:static_cast<iPhoneInputManager*>(mCreator)->_getDelegate()];
+
+    MultiTouchState newState;
+    newState.X.abs = location.x;
+    newState.Y.abs = location.y;
+    newState.touchType |= 1 << MT_Cancelled;
+
+    if( mListener && mBuffered )
+    {
+        mListener->touchCancelled(MultiTouchEvent(this, newState));
+    }
+    else
+    {
+        mStates.push_back(newState);
+    }
+}

+ 377 - 0
CamelotOISInput/Source/OIS/linux/EventHelpers.cpp

@@ -0,0 +1,377 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "linux/EventHelpers.h"
+#include "linux/LinuxPrereqs.h"
+#include "linux/LinuxForceFeedback.h"
+#include "OISException.h"
+#include "OISJoyStick.h"
+
+#include <linux/input.h>
+#include <cstring>
+
+//#define OIS_LINUX_JOY_DEBUG
+
+#ifdef OIS_LINUX_JOY_DEBUG
+# include <iostream>
+#endif
+
+using namespace std;
+using namespace OIS;
+
+class DeviceComponentInfo
+{
+public:
+	vector<int> buttons, relAxes, absAxes, hats;
+};
+
+bool inline isBitSet(unsigned char bits[], unsigned int bit)
+{
+  return (bits[(bit)/(sizeof(unsigned char)*8)] >> ((bit)%(sizeof(unsigned char)*8))) & 1;
+}
+
+//-----------------------------------------------------------------------------//
+DeviceComponentInfo getComponentInfo( int deviceID )
+{
+	unsigned char ev_bits[1 + EV_MAX/8/sizeof(unsigned char)];
+	memset( ev_bits, 0, sizeof(ev_bits) );
+
+	//Read "all" (hence 0) components of the device
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getComponentInfo(" << deviceID 
+		 << ") : Reading device events features" << endl;
+#endif
+	if (ioctl(deviceID, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1)
+		OIS_EXCEPT( E_General, "Could not read device events features");
+
+	DeviceComponentInfo components;
+
+	for (int i = 0; i < EV_MAX; i++)
+	{
+		if( isBitSet(ev_bits, i) )
+		{
+		    // Absolute axis.
+		    if(i == EV_ABS)
+			{
+			    unsigned char abs_bits[1 + ABS_MAX/8/sizeof(unsigned char)];
+			    memset( abs_bits, 0, sizeof(abs_bits) );
+
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device absolute axis features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(abs_bits)), abs_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device absolute axis features");
+
+				for (int j = 0; j < ABS_MAX; j++)
+				{
+				    if( isBitSet(abs_bits, j) )
+					{
+						//input_absinfo abInfo;
+						//ioctl( fd, EVIOCGABS(j), abInfo );
+						if( j >= ABS_HAT0X && j <= ABS_HAT3Y )
+						{
+							components.hats.push_back(j);
+						}
+						else
+						{
+							components.absAxes.push_back(j);
+							//input_absinfo absinfo;
+							//ioctl(deviceID, EVIOCGABS(j), &absinfo);
+							//We cannot actually change these values :|
+							//absinfo.minimum = JoyStick::MIN_AXIS;
+							//absinfo.maximum = JoyStick::MAX_AXIS;
+							//ioctl(deviceID, EVIOCSABS(j), &absinfo);
+						}
+					}
+				}
+			}
+			else if(i == EV_REL)
+			{
+			    unsigned char rel_bits[1 + REL_MAX/8/sizeof(unsigned char)];
+				memset( rel_bits, 0, sizeof(rel_bits) );
+				
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device relative axis features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(rel_bits)), rel_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device relative axis features");
+				
+				for (int j = 0; j < REL_MAX; j++)
+				{
+				    if( isBitSet(rel_bits, j) )
+					{
+					    components.relAxes.push_back(j);
+					}
+				}
+			}
+			else if(i == EV_KEY)
+			{
+			    unsigned char key_bits[1 + KEY_MAX/8/sizeof(unsigned char)];
+				memset( key_bits, 0, sizeof(key_bits) );
+				
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device buttons features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(key_bits)), key_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device buttons features");
+				
+				for (int j = 0; j < KEY_MAX; j++)
+				{
+				    if( isBitSet(key_bits, j) )
+					{
+					    components.buttons.push_back(j);
+					}
+				}
+			}
+		}
+	}
+
+	return components;
+}
+
+//-----------------------------------------------------------------------------//
+bool EventUtils::isJoyStick( int deviceID, JoyStickInfo &js )
+{
+	if( deviceID == -1 ) 
+		OIS_EXCEPT( E_General, "Error with File Descriptor" );
+
+	DeviceComponentInfo info = getComponentInfo( deviceID );
+
+	int buttons = 0;
+	bool joyButtonFound = false;
+	js.button_map.clear();
+
+	#ifdef OIS_LINUX_JOY_DEBUG
+	cout << endl << "Displaying ButtonMapping Status:" << endl;
+	#endif
+	for(vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i )
+	{
+		//Check to ensure we find at least one joy only button
+		if( (*i >= BTN_JOYSTICK && *i < BTN_GAMEPAD)  
+			|| (*i >= BTN_GAMEPAD && *i < BTN_DIGI)
+			|| (*i >= BTN_WHEEL && *i < KEY_OK) )
+			joyButtonFound = true;
+
+		js.button_map[*i] = buttons++;
+
+		#ifdef OIS_LINUX_JOY_DEBUG
+		  cout << "Button Mapping ID (hex): " << hex << *i 
+			   << " OIS Button Num: " << dec << buttons-1 << endl;
+		#endif
+	}
+	#ifdef OIS_LINUX_JOY_DEBUG
+	cout << endl;
+	#endif
+
+	//Joy Buttons found, so it must be a joystick or pad
+	if( joyButtonFound )
+	{
+		js.joyFileD = deviceID;
+		js.vendor = getName(deviceID);
+		js.buttons = buttons;
+		js.axes = info.relAxes.size() + info.absAxes.size();
+		js.hats = info.hats.size();
+		#ifdef OIS_LINUX_JOY_DEBUG
+		  cout << endl << "Device name:" << js.vendor << endl;
+		  cout << "Device unique Id:" << getUniqueId(deviceID) << endl;
+		  cout << "Device physical location:" << getPhysicalLocation(deviceID) << endl;
+		#endif
+
+		//Map the Axes
+		#ifdef OIS_LINUX_JOY_DEBUG
+		  cout << endl << "Displaying AxisMapping Status:" << endl;
+		#endif
+		int axes = 0;
+		for(vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i )
+		{
+			js.axis_map[*i] = axes;
+
+#ifdef OIS_LINUX_JOY_DEBUG
+			cout << "EventUtils::isJoyStick(" << deviceID 
+					  << ") : Reading device absolute axis #" << *i << " features" << endl;
+#endif
+
+			input_absinfo absinfo;
+			if (ioctl(deviceID, EVIOCGABS(*i), &absinfo) == -1)
+				OIS_EXCEPT( E_General, "Could not read device absolute axis features");
+			js.axis_range[axes] = Range(absinfo.minimum, absinfo.maximum);
+
+			#ifdef OIS_LINUX_JOY_DEBUG
+			  cout << "Axis Mapping ID (hex): " << hex << *i 
+				   << " OIS Axis Num: " << dec << axes << endl;
+			#endif
+
+			++axes;
+		}
+	}
+
+	return joyButtonFound;
+}
+
+//-----------------------------------------------------------------------------//
+string EventUtils::getName( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getName(" << deviceID 
+		 << ") : Reading device name" << endl;
+#endif
+
+	char name[OIS_DEVICE_NAME];
+	if (ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name) == -1)
+		OIS_EXCEPT( E_General, "Could not read device name");
+	return string(name);
+}
+
+//-----------------------------------------------------------------------------//
+string EventUtils::getUniqueId( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getUniqueId(" << deviceID 
+		 << ") : Reading device unique Id" << endl;
+#endif
+
+#define OIS_DEVICE_UNIQUE_ID 128
+	char uId[OIS_DEVICE_UNIQUE_ID];
+	if (ioctl(deviceID, EVIOCGUNIQ(OIS_DEVICE_UNIQUE_ID), uId) == -1)
+		OIS_EXCEPT( E_General, "Could not read device unique Id");
+	return string(uId);
+}
+
+//-----------------------------------------------------------------------------//
+string EventUtils::getPhysicalLocation( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getPhysicalLocation(" << deviceID 
+		 << ") : Reading device physical location" << endl;
+#endif
+
+#define OIS_DEVICE_PHYSICAL_LOCATION 128
+	char physLoc[OIS_DEVICE_PHYSICAL_LOCATION];
+	if (ioctl(deviceID, EVIOCGPHYS(OIS_DEVICE_PHYSICAL_LOCATION), physLoc) == -1)
+		OIS_EXCEPT( E_General, "Could not read device physical location");
+	return string(physLoc);
+}
+
+//-----------------------------------------------------------------------------//
+void EventUtils::enumerateForceFeedback( int deviceID, LinuxForceFeedback** ff )
+{
+	//Linux Event to OIS Event Mappings
+	map<int, Effect::EType> typeMap;
+	typeMap[FF_CONSTANT] = Effect::Constant;
+	typeMap[FF_RAMP]     = Effect::Ramp;
+	typeMap[FF_SPRING]   = Effect::Spring;
+	typeMap[FF_FRICTION] = Effect::Friction;
+	typeMap[FF_SQUARE]   = Effect::Square;
+	typeMap[FF_TRIANGLE] = Effect::Triangle;
+	typeMap[FF_SINE]     = Effect::Sine;
+	typeMap[FF_SAW_UP]   = Effect::SawToothUp;
+	typeMap[FF_SAW_DOWN] = Effect::SawToothDown;
+	typeMap[FF_DAMPER]   = Effect::Damper;
+	typeMap[FF_INERTIA]  = Effect::Inertia;
+	typeMap[FF_CUSTOM]   = Effect::Custom;
+
+	map<int, Effect::EForce> forceMap;
+	forceMap[FF_CONSTANT] = Effect::ConstantForce;
+	forceMap[FF_RAMP]     = Effect::RampForce;
+	forceMap[FF_SPRING]   = Effect::ConditionalForce;
+	forceMap[FF_FRICTION] = Effect::ConditionalForce;
+	forceMap[FF_SQUARE]   = Effect::PeriodicForce;
+	forceMap[FF_TRIANGLE] = Effect::PeriodicForce;
+	forceMap[FF_SINE]     = Effect::PeriodicForce;
+	forceMap[FF_SAW_UP]   = Effect::PeriodicForce;
+	forceMap[FF_SAW_DOWN] = Effect::PeriodicForce;
+	forceMap[FF_DAMPER]   = Effect::ConditionalForce;
+	forceMap[FF_INERTIA]  = Effect::ConditionalForce;
+	forceMap[FF_CUSTOM]   = Effect::CustomForce;
+
+	//Remove any previously existing memory and create fresh
+	removeForceFeedback( ff );
+	*ff = new LinuxForceFeedback(deviceID);
+
+	//Read overall force feedback features
+	unsigned char ff_bits[1 + FF_MAX/8/sizeof(unsigned char)];
+	memset(ff_bits, 0, sizeof(ff_bits));
+
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::enumerateForceFeedback(" << deviceID 
+		 << ") : Reading device force feedback features" << endl;
+#endif
+
+	if (ioctl(deviceID, EVIOCGBIT(EV_FF, sizeof(ff_bits)), ff_bits) == -1)
+		OIS_EXCEPT( E_General, "Could not read device force feedback features");
+
+
+    #ifdef OIS_LINUX_JOY_DEBUG
+	cout << "FF bits: " << hex;
+	for (int i = 0; i < sizeof(ff_bits); i++)
+		cout << (int)ff_bits[i];
+	cout << endl << dec;
+    #endif
+
+	//FF Axes
+	//if( isBitSet(ff_bits, ABS_X) ) //X Axis
+	//if( isBitSet(ff_bits, ABS_Y) ) //Y Axis
+	//if( isBitSet(ff_bits, ABS_WHEEL) ) //Wheel
+
+	//FF Effects
+	for( int effect = FF_EFFECT_MIN; effect <= FF_WAVEFORM_MAX; effect++ )
+	{
+		// The RUMBLE force type is ignored, as periodic force one is more powerfull.
+		// The PERIODIC force type is processed later, for each associated periodic effect type.
+		if (effect == FF_RUMBLE || effect == FF_PERIODIC)
+			continue;
+
+		if(isBitSet(ff_bits, effect))
+		{
+			#ifdef OIS_LINUX_JOY_DEBUG
+		    cout << "  Effect Type: " << Effect::getEffectTypeName(typeMap[effect]) << endl;
+			#endif
+
+			(*ff)->_addEffectTypes( forceMap[effect], typeMap[effect] );
+		}
+	}
+
+	//FF device properties
+	if (isBitSet(ff_bits, FF_GAIN))
+		(*ff)->_setGainSupport(true);
+		
+	if (isBitSet(ff_bits, FF_AUTOCENTER))
+		(*ff)->_setAutoCenterSupport(true);
+
+	//Check to see if any effects were added, else destroy the pointer
+	const ForceFeedback::SupportedEffectList &list = (*ff)->getSupportedEffects();
+	if( list.size() == 0 )
+		removeForceFeedback( ff );
+}
+
+//-----------------------------------------------------------------------------//
+void EventUtils::removeForceFeedback( LinuxForceFeedback** ff )
+{
+	delete *ff;
+	*ff = 0;
+}

+ 559 - 0
CamelotOISInput/Source/OIS/linux/LinuxForceFeedback.cpp

@@ -0,0 +1,559 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "linux/LinuxForceFeedback.h"
+#include "OISException.h"
+
+#include <cstdlib>
+#include <errno.h>
+#include <memory.h>
+
+using namespace OIS;
+
+// 0 = No trace; 1 = Important traces; 2 = Debug traces
+#define OIS_LINUX_JOYFF_DEBUG 1
+
+#ifdef OIS_LINUX_JOYFF_DEBUG
+# include <iostream>
+  using namespace std;
+#endif
+
+//--------------------------------------------------------------//
+LinuxForceFeedback::LinuxForceFeedback(int deviceID) :
+	ForceFeedback(), mJoyStick(deviceID)
+{
+}
+
+//--------------------------------------------------------------//
+LinuxForceFeedback::~LinuxForceFeedback()
+{
+	// Unload all effects.
+	for(EffectList::iterator i = mEffectList.begin(); i != mEffectList.end(); ++i )
+	{
+		struct ff_effect *linEffect = i->second;
+		if( linEffect )
+			_unload(linEffect->id);
+	}
+
+	mEffectList.clear();
+}
+
+//--------------------------------------------------------------//
+unsigned short LinuxForceFeedback::getFFMemoryLoad()
+{
+	int nEffects = -1;
+	if (ioctl(mJoyStick, EVIOCGEFFECTS, &nEffects) == -1)
+		OIS_EXCEPT(E_General, "Unknown error reading max number of uploaded effects.");
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "LinuxForceFeedback("<< mJoyStick  
+		 << ") : Read device max number of uploaded effects : " << nEffects << endl;
+#endif
+
+	return (unsigned short int)(nEffects > 0 ? 100.0*mEffectList.size()/nEffects : 100);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::setMasterGain(float value)
+{
+	if (!mSetGainSupport)
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+		cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting master gain " 
+			 << "is not supported by the device" << endl;
+#endif
+		return;
+	}
+
+	struct input_event event;
+
+	memset(&event, 0, sizeof(event));
+	event.type = EV_FF;
+	event.code = FF_GAIN;
+	if (value < 0.0)
+		value = 0.0;
+	else if (value > 1.0)
+		value = 1.0;
+	event.value = (__s32)(value * 0xFFFFUL);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+	cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting master gain to " 
+		 << value << " => " << event.value << endl;
+#endif
+
+	if (write(mJoyStick, &event, sizeof(event)) != sizeof(event)) {
+		OIS_EXCEPT(E_General, "Unknown error changing master gain.");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::setAutoCenterMode(bool enabled)
+{
+	if (!mSetAutoCenterSupport)
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+		cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting auto-center mode " 
+			 << "is not supported by the device" << endl;
+#endif
+		return;
+	}
+
+	struct input_event event;
+
+	memset(&event, 0, sizeof(event));
+	event.type = EV_FF;
+	event.code = FF_AUTOCENTER;
+	event.value = (__s32)(enabled*0xFFFFFFFFUL);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+	cout << "LinuxForceFeedback("<< mJoyStick << ") : Toggling auto-center to " 
+		 << enabled << " => 0x" << hex << event.value << dec << endl;
+#endif
+
+	if (write(mJoyStick, &event, sizeof(event)) != sizeof(event)) {
+		OIS_EXCEPT(E_General, "Unknown error toggling auto-center.");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::upload( const Effect* effect )
+{
+	switch( effect->force )
+	{
+		case OIS::Effect::ConstantForce: 
+			_updateConstantEffect(effect);	
+			break;
+		case OIS::Effect::ConditionalForce: 
+			_updateConditionalEffect(effect);
+			break;
+		case OIS::Effect::PeriodicForce: 
+			_updatePeriodicEffect(effect);
+			break;
+		case OIS::Effect::RampForce: 
+			_updateRampEffect(effect);	
+			break;
+		case OIS::Effect::CustomForce: 
+			//_updateCustomEffect(effect);
+			//break;
+		default: 
+			OIS_EXCEPT(E_NotImplemented, "Requested force not implemented yet, sorry!"); 
+			break;
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::modify( const Effect* effect )
+{
+	upload(effect);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::remove( const Effect* effect )
+{
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(effect->_handle);
+	if( i != mEffectList.end() )
+	{
+		struct ff_effect *linEffect = i->second;
+		if( linEffect )
+		{
+			_stop(effect->_handle);
+
+			_unload(effect->_handle);
+
+			free(linEffect);
+
+			mEffectList.erase(i);
+		}
+		else
+			mEffectList.erase(i);
+	}
+}
+
+//--------------------------------------------------------------//
+// To Signed16/Unsigned15 safe conversions
+#define MaxUnsigned15Value 0x7FFF
+#define toUnsigned15(value) \
+	(__u16)((value) < 0 ? 0 : ((value) > MaxUnsigned15Value ? MaxUnsigned15Value : (value)))
+
+#define MaxSigned16Value  0x7FFF
+#define MinSigned16Value -0x7FFF
+#define toSigned16(value) \
+  (__s16)((value) < MinSigned16Value ? MinSigned16Value : ((value) > MaxSigned16Value ? MaxSigned16Value : (value)))
+
+// OIS to Linux duration
+#define LinuxInfiniteDuration 0xFFFF
+#define OISDurationUnitMS 1000 // OIS duration unit (microseconds), expressed in milliseconds (theLinux duration unit)
+
+// linux/input.h : All duration values are expressed in ms. Values above 32767 ms (0x7fff)
+//                 should not be used and have unspecified results.
+#define LinuxDuration(oisDuration) ((oisDuration) == Effect::OIS_INFINITE ? LinuxInfiniteDuration \
+									: toUnsigned15((oisDuration)/OISDurationUnitMS))
+
+
+// OIS to Linux levels
+#define OISMaxLevel 10000
+#define LinuxMaxLevel 0x7FFF
+
+// linux/input.h : Valid range for the attack and fade levels is 0x0000 - 0x7fff
+#define LinuxPositiveLevel(oisLevel) toUnsigned15(LinuxMaxLevel*(long)(oisLevel)/OISMaxLevel)
+
+#define LinuxSignedLevel(oisLevel) toSigned16(LinuxMaxLevel*(long)(oisLevel)/OISMaxLevel)
+
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_setCommonProperties(struct ff_effect *event, 
+											  struct ff_envelope *ffenvelope, 
+											  const Effect* effect, const Envelope *envelope )
+{
+	memset(event, 0, sizeof(struct ff_effect));
+
+	if (envelope && ffenvelope && envelope->isUsed()) {
+		ffenvelope->attack_length = LinuxDuration(envelope->attackLength);
+		ffenvelope->attack_level = LinuxPositiveLevel(envelope->attackLevel);
+		ffenvelope->fade_length = LinuxDuration(envelope->fadeLength);
+		ffenvelope->fade_level = LinuxPositiveLevel(envelope->fadeLevel);
+	}
+	
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl;
+	if (envelope && ffenvelope)
+	{
+		cout << "  Enveloppe :" << endl
+			 << "    AttackLen : " << envelope->attackLength
+			 << " => " << ffenvelope->attack_length << endl 
+			 << "    AttackLvl : " << envelope->attackLevel
+			 << " => " << ffenvelope->attack_level << endl 
+			 << "    FadeLen   : " << envelope->fadeLength
+			 << " => " << ffenvelope->fade_length << endl
+			 << "    FadeLvl   : " << envelope->fadeLevel
+			 << " => " << ffenvelope->fade_level << endl;
+	}
+#endif
+	
+	event->direction = (__u16)(1 + (effect->direction*45.0+135.0)*0xFFFFUL/360.0);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Direction : " << Effect::getDirectionName(effect->direction)
+		 << " => 0x" << hex << event->direction << dec << endl;
+#endif
+
+	// TODO trigger_button 0 vs. -1
+	event->trigger.button = effect->trigger_button; // < 0 ? 0 : effect->trigger_button;
+	event->trigger.interval = LinuxDuration(effect->trigger_interval);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Trigger :" << endl
+		 << "    Button   : " << effect->trigger_button 
+		 << " => " << event->trigger.button << endl
+		 << "    Interval : " << effect->trigger_interval 
+		 << " => " << event->trigger.interval << endl;
+#endif
+
+	event->replay.length = LinuxDuration(effect->replay_length);
+	event->replay.delay = LinuxDuration(effect->replay_delay);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Replay :" << endl
+		 << "    Length : " << effect->replay_length 
+		 << " => " << event->replay.length << endl
+		 << "    Delay  : " << effect->replay_delay 
+		 << " => " << event->replay.delay << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateConstantEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	ConstantEffect *effect = static_cast<ConstantEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.constant.envelope, eff, &effect->envelope);
+
+	event.type = FF_CONSTANT;
+	event.id = -1;
+
+	event.u.constant.level = LinuxSignedLevel(effect->level);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Level : " << effect->level
+		 << " => " << event.u.constant.level << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateRampEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	RampEffect *effect = static_cast<RampEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.constant.envelope, eff, &effect->envelope);
+
+	event.type = FF_RAMP;
+	event.id = -1;
+
+	event.u.ramp.start_level = LinuxSignedLevel(effect->startLevel);
+	event.u.ramp.end_level = LinuxSignedLevel(effect->endLevel);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  StartLevel : " << effect->startLevel
+		 << " => " << event.u.ramp.start_level << endl
+		 << "  EndLevel   : " << effect->endLevel
+		 << " => " << event.u.ramp.end_level << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updatePeriodicEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	PeriodicEffect *effect = static_cast<PeriodicEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.periodic.envelope, eff, &effect->envelope);
+
+	event.type = FF_PERIODIC;
+	event.id = -1;
+
+	switch( eff->type )
+	{
+		case OIS::Effect::Square:
+			event.u.periodic.waveform = FF_SQUARE;
+			break;
+		case OIS::Effect::Triangle:
+			event.u.periodic.waveform = FF_TRIANGLE;
+			break;
+		case OIS::Effect::Sine:
+			event.u.periodic.waveform = FF_SINE;
+			break;
+		case OIS::Effect::SawToothUp:
+			event.u.periodic.waveform = FF_SAW_UP;
+			break;
+		case OIS::Effect::SawToothDown:
+			event.u.periodic.waveform = FF_SAW_DOWN;
+			break;
+		// Note: No support for Custom periodic force effect for the moment
+		//case OIS::Effect::Custom:
+			//event.u.periodic.waveform = FF_CUSTOM;
+			//break;
+		default:
+			OIS_EXCEPT(E_General, "No such available effect for Periodic force!"); 
+			break;
+	}
+
+	event.u.periodic.period    = LinuxDuration(effect->period);
+	event.u.periodic.magnitude = LinuxPositiveLevel(effect->magnitude);
+	event.u.periodic.offset    = LinuxPositiveLevel(effect->offset);
+	event.u.periodic.phase     = (__u16)(effect->phase*event.u.periodic.period/36000.0); // ?????
+
+	// Note: No support for Custom periodic force effect for the moment
+	event.u.periodic.custom_len = 0;
+	event.u.periodic.custom_data = 0;
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Magnitude : " << effect->magnitude
+		 << " => " << event.u.periodic.magnitude << endl
+		 << "  Period    : " << effect->period
+		 << " => " << event.u.periodic.period  << endl
+		 << "  Offset    : " << effect->offset
+		 << " => " << event.u.periodic.offset << endl
+		 << "  Phase     : " << effect->phase
+		 << " => " << event.u.periodic.phase << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateConditionalEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	ConditionalEffect *effect = static_cast<ConditionalEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, NULL, eff, NULL);
+
+	switch( eff->type )
+	{
+		case OIS::Effect::Friction:
+			event.type = FF_FRICTION; 
+			break;
+		case OIS::Effect::Damper:
+			event.type = FF_DAMPER; 
+			break;
+		case OIS::Effect::Inertia:
+			event.type = FF_INERTIA; 
+			break;
+		case OIS::Effect::Spring:
+			event.type = FF_SPRING;
+			break;
+		default:
+			OIS_EXCEPT(E_General, "No such available effect for Conditional force!"); 
+			break;
+	}
+
+	event.id = -1;
+
+	event.u.condition[0].right_saturation = LinuxSignedLevel(effect->rightSaturation);
+	event.u.condition[0].left_saturation  = LinuxSignedLevel(effect->leftSaturation);
+	event.u.condition[0].right_coeff      = LinuxSignedLevel(effect->rightCoeff);
+	event.u.condition[0].left_coeff       = LinuxSignedLevel(effect->leftCoeff);
+	event.u.condition[0].deadband         = LinuxPositiveLevel(effect->deadband);// Unit ?? 
+	event.u.condition[0].center           = LinuxSignedLevel(effect->center); // Unit ?? TODO ?
+
+	// TODO support for second condition
+	event.u.condition[1] = event.u.condition[0];
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Condition[0] : " << endl
+		 << "    RightSaturation  : " << effect->rightSaturation
+		 << " => " << event.u.condition[0].right_saturation << endl
+		 << "    LeftSaturation   : " << effect->leftSaturation
+		 << " => " << event.u.condition[0]. left_saturation << endl
+		 << "    RightCoefficient : " << effect->rightCoeff
+		 << " => " << event.u.condition[0].right_coeff << endl
+		 << "    LeftCoefficient : " << effect->leftCoeff
+		 << " => " << event.u.condition[0].left_coeff << endl
+		 << "    DeadBand        : " << effect->deadband
+		 << " => " << event.u.condition[0].deadband  << endl
+		 << "    Center          : " << effect->center
+		 << " => " << event.u.condition[0].center << endl;
+	cout << "  Condition[1] : Not implemented" << endl;
+#endif
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_upload( struct ff_effect* ffeffect, const Effect* effect)
+{
+	struct ff_effect *linEffect = 0;
+
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(effect->_handle);
+	//It has been created already
+	if( i != mEffectList.end() )
+		linEffect = i->second;
+
+	if( linEffect == 0 )
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+		cout << endl << "LinuxForceFeedback("<< mJoyStick << ") : Adding new effect : " 
+			 << Effect::getEffectTypeName(effect->type) << endl;
+#endif
+
+		//This effect has not yet been created, so create it in the device
+		if (ioctl(mJoyStick, EVIOCSFF, ffeffect) == -1) {
+			// TODO device full check
+			// OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!");
+			OIS_EXCEPT(E_General, "Unknown error creating effect (may be the device is full)->..");
+		}
+
+		// Save returned effect handle
+		effect->_handle = ffeffect->id;
+
+		// Save a copy of the uploaded effect for later simple modifications
+		linEffect = (struct ff_effect *)calloc(1, sizeof(struct ff_effect));
+		memcpy(linEffect, ffeffect, sizeof(struct ff_effect));
+
+		mEffectList[effect->_handle] = linEffect;
+
+		// Start playing the effect.
+		_start(effect->_handle);
+	}
+	else
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+		cout << endl << "LinuxForceFeedback("<< mJoyStick << ") : Replacing effect : " 
+			 << Effect::getEffectTypeName(effect->type) << endl;
+#endif
+
+		// Keep same id/handle, as this is just an update in the device.
+		ffeffect->id = effect->_handle;
+
+		// Update effect in the device.
+		if (ioctl(mJoyStick, EVIOCSFF, ffeffect) == -1) {
+			OIS_EXCEPT(E_General, "Unknown error updating an effect->..");
+		}
+
+		// Update local linEffect for next time.
+		memcpy(linEffect, ffeffect, sizeof(struct ff_effect));
+	}
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Effect handle : " << effect->_handle << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_stop( int handle) {
+	struct input_event stop;
+
+	stop.type = EV_FF;
+	stop.code = handle;
+	stop.value = 0;
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Stopping effect with handle " << handle << endl;
+#endif
+
+	if (write(mJoyStick, &stop, sizeof(stop)) != sizeof(stop)) {
+		OIS_EXCEPT(E_General, "Unknown error stopping effect->..");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_start( int handle) {
+	struct input_event play;
+
+	play.type = EV_FF;
+	play.code = handle;
+	play.value = 1; // Play once.
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Starting effect with handle " << handle << endl;
+#endif
+
+	if (write(mJoyStick, &play, sizeof(play)) != sizeof(play)) {
+		OIS_EXCEPT(E_General, "Unknown error playing effect->..");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_unload( int handle)
+{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Removing effect with handle " << handle << endl;
+#endif
+
+	if (ioctl(mJoyStick, EVIOCRMFF, handle) == -1) {
+		OIS_EXCEPT(E_General, "Unknown error removing effect->..");
+	}
+}

+ 212 - 0
CamelotOISInput/Source/OIS/linux/LinuxInputManager.cpp

@@ -0,0 +1,212 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "linux/LinuxInputManager.h"
+#include "linux/LinuxKeyboard.h"
+#include "linux/LinuxJoyStickEvents.h"
+#include "linux/LinuxMouse.h"
+#include "OISException.h"
+#include <cstdlib>
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------//
+LinuxInputManager::LinuxInputManager() : InputManager("X11InputManager")
+{
+	window = 0;
+
+	//Default settings
+	grabMouse = true;
+	grabKeyboard = true;
+	hideMouse = true;
+	mGrabs = true;
+	keyboardUsed = mouseUsed = false;
+
+	//Setup our internal factories
+	mFactories.push_back(this);
+}
+
+//--------------------------------------------------------------------------------//
+LinuxInputManager::~LinuxInputManager()
+{
+	//Close all joysticks
+	LinuxJoyStick::_clearJoys(unusedJoyStickList);
+}
+
+//--------------------------------------------------------------------------------//
+void LinuxInputManager::_initialize( ParamList &paramList )
+{
+	_parseConfigSettings( paramList );
+
+	//Enumerate all devices attached
+	_enumerateDevices();
+}
+
+//--------------------------------------------------------------------------------//
+void LinuxInputManager::_parseConfigSettings( ParamList &paramList )
+{
+	ParamList::iterator i = paramList.find("WINDOW");
+	if( i == paramList.end() ) 
+		OIS_EXCEPT( E_InvalidParam, "LinuxInputManager >> No WINDOW!" );
+
+	//TODO 64 bit proof this little conversion xxx wip
+	window  = strtoul(i->second.c_str(), 0, 10);
+
+	//--------- Keyboard Settings ------------//
+	i = paramList.find("x11_keyboard_grab");
+	if( i != paramList.end() )
+		if( i->second == "false" )
+			grabKeyboard = false;
+
+	//--------- Mouse Settings ------------//
+	i = paramList.find("x11_mouse_grab");
+	if( i != paramList.end() )
+		if( i->second == "false" )
+			grabMouse = false;
+
+	i = paramList.find("x11_mouse_hide");
+	if( i != paramList.end() )
+		if( i->second == "false" )
+			hideMouse = false;
+}
+
+//--------------------------------------------------------------------------------//
+void LinuxInputManager::_enumerateDevices()
+{
+	//Enumerate all attached devices
+	unusedJoyStickList = LinuxJoyStick::_scanJoys();
+	joySticks = unusedJoyStickList.size();
+}
+
+//----------------------------------------------------------------------------//
+DeviceList LinuxInputManager::freeDeviceList()
+{
+	DeviceList ret;
+
+	if( keyboardUsed == false )
+		ret.insert(std::make_pair(OISKeyboard, mInputSystemName));
+
+	if( mouseUsed == false )
+		ret.insert(std::make_pair(OISMouse, mInputSystemName));
+
+	for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+		ret.insert(std::make_pair(OISJoyStick, i->vendor));
+
+	return ret;
+}
+
+//----------------------------------------------------------------------------//
+int LinuxInputManager::totalDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return 1;
+	case OISMouse: return 1;
+	case OISJoyStick: return joySticks;
+	default: return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+int LinuxInputManager::freeDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return keyboardUsed ? 0 : 1;
+	case OISMouse: return mouseUsed ? 0 : 1;
+	case OISJoyStick: return (int)unusedJoyStickList.size();
+	default: return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+bool LinuxInputManager::vendorExist(Type iType, const std::string & vendor)
+{
+	if( (iType == OISKeyboard || iType == OISMouse) && vendor == mInputSystemName )
+	{
+		return true;
+	}
+	else if( iType == OISJoyStick )
+	{
+		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+			if(i->vendor == vendor)
+				return true;
+	}
+
+	return false;
+}
+
+//----------------------------------------------------------------------------//
+Object* LinuxInputManager::createObject(InputManager *creator, Type iType, bool bufferMode, const std::string & vendor)
+{
+	Object *obj = 0;
+
+	switch(iType)
+	{
+	case OISKeyboard:
+	{
+		if( keyboardUsed == false )
+			obj = new LinuxKeyboard(this, bufferMode, grabKeyboard);
+		break;
+	}
+	case OISMouse:
+	{
+		if( mouseUsed == false )
+			obj = new LinuxMouse(this, bufferMode, grabMouse, hideMouse);
+		break;
+	}
+	case OISJoyStick:
+	{
+		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+		{
+			if(vendor == "" || i->vendor == vendor)
+			{
+				obj = new LinuxJoyStick(this, bufferMode, *i);
+				unusedJoyStickList.erase(i);
+				break;
+			}
+		}
+		break;
+	}
+	default:
+		break;
+	}
+
+	if( obj == 0 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	return obj;
+}
+
+//----------------------------------------------------------------------------//
+void LinuxInputManager::destroyObject( Object* obj )
+{
+	if( obj )
+	{
+		if( obj->type() == OISJoyStick )
+		{
+			unusedJoyStickList.push_back( ((LinuxJoyStick*)obj)->_getJoyInfo() );
+		}
+
+		delete obj;
+	}
+}

+ 305 - 0
CamelotOISInput/Source/OIS/linux/LinuxJoyStickEvents.cpp

@@ -0,0 +1,305 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OISConfig.h"
+
+#include "linux/LinuxJoyStickEvents.h"
+#include "linux/LinuxInputManager.h"
+#include "linux/LinuxForceFeedback.h"
+#include "linux/EventHelpers.h"
+
+#include "OISEvents.h"
+#include "OISException.h"
+
+#include <fcntl.h>        //Needed to Open a file descriptor
+#include <cassert>	
+#include <linux/input.h>
+
+
+#include <sstream>
+# include <iostream>
+using namespace std;
+
+using namespace OIS;
+
+//#define OIS_LINUX_JOY_DEBUG
+
+//-------------------------------------------------------------------//
+LinuxJoyStick::LinuxJoyStick(InputManager* creator, bool buffered, const JoyStickInfo& js)
+	: JoyStick(js.vendor, buffered, js.devId, creator)
+{
+	mJoyStick = js.joyFileD;
+
+	mState.mAxes.clear();
+	mState.mAxes.resize(js.axes);
+	mState.mButtons.clear();
+	mState.mButtons.resize(js.buttons);
+
+	mPOVs = js.hats;
+
+	mButtonMap = js.button_map;
+	mAxisMap = js.axis_map;
+	mRanges = js.axis_range;
+
+	ff_effect = 0;
+}
+
+//-------------------------------------------------------------------//
+LinuxJoyStick::~LinuxJoyStick()
+{
+	EventUtils::removeForceFeedback( &ff_effect );
+}
+
+//-------------------------------------------------------------------//
+void LinuxJoyStick::_initialize()
+{
+	//Clear old joy state
+	mState.mAxes.resize(mAxisMap.size());
+	mState.clear();
+
+	//This will create and new us a force feedback structure if it exists
+	EventUtils::enumerateForceFeedback( mJoyStick, &ff_effect );
+
+	if( mJoyStick == -1 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "LinuxJoyStick::_initialize() >> JoyStick Not Found!");
+}
+
+//-------------------------------------------------------------------//
+void LinuxJoyStick::capture()
+{
+	static const short POV_MASK[8] = {0,0,1,1,2,2,3,3};
+
+	//Used to determine if an axis has been changed and needs an event
+	bool axisMoved[32] = {false, false, false, false, false, false, false, false, false, false, false, false, false,
+						  false, false, false, false, false, false, false, false, false, false, false, false, false,
+						  false, false, false, false, false, false};
+
+	//We are in non blocking mode - we just read once, and try to fill up buffer
+	input_event js[JOY_BUFFERSIZE];
+	while(true)
+	{
+		int ret = read(mJoyStick, &js, sizeof(struct input_event) * JOY_BUFFERSIZE);
+        if( ret < 0 )
+			break;
+
+		//Determine how many whole events re read up
+		ret /= sizeof(struct input_event);
+		for(int i = 0; i < ret; ++i)
+		{
+			switch(js[i].type)
+			{
+			case EV_KEY:  //Button
+			{
+				int button = mButtonMap[js[i].code];
+
+				#ifdef OIS_LINUX_JOY_DEBUG
+				  cout << "\nButton Code: " << js[i].code << ", OIS Value: " << button << endl;
+				#endif
+
+				//Check to see whether push or released event...
+				if(js[i].value)
+				{
+					mState.mButtons[button] = true;
+					if( mBuffered && mListener )
+						if(!mListener->buttonPressed(JoyStickEvent(this,mState), button)) return;
+				}
+				else
+				{
+					mState.mButtons[button] = false;
+					if( mBuffered && mListener )
+						if(!mListener->buttonReleased(JoyStickEvent(this,mState), button)) return;
+				}
+				break;
+			}
+
+			case EV_ABS:  //Absolute Axis
+			{
+				//A Stick (BrakeDefine is the highest possible Axis)
+				if( js[i].code <= ABS_BRAKE )
+				{
+					int axis = mAxisMap[js[i].code];
+					assert( axis < 32 && "Too many axes (Max supported is 32). Report this to OIS forums!" );
+
+					axisMoved[axis] = true;
+
+					//check for rescaling:
+					if( mRanges[axis].min == JoyStick::MIN_AXIS && mRanges[axis].max != JoyStick::MAX_AXIS )
+					{	//Scale is perfect
+						mState.mAxes[axis].abs = js[i].value;
+					}
+					else
+					{	//Rescale
+						float proportion = (float)(js[i].value-mRanges[axis].max)/(float)(mRanges[axis].min-mRanges[axis].max);
+						mState.mAxes[axis].abs = (int)(32767.0f - (65535.0f * proportion));
+					}
+				}
+				else if( js[i].code <= ABS_HAT3Y ) //A POV - Max four POVs allowed
+				{
+					//Normalise the POV to between 0-7
+					//Even is X Axis, Odd is Y Axis
+					unsigned char LinuxPovNumber = js[i].code - 16;
+					short OIS_POVIndex = POV_MASK[LinuxPovNumber];
+
+					//Handle X Axis first (Even) (left right)
+					if((LinuxPovNumber & 0x0001) == 0)
+					{
+						//Why do this? Because, we use a bit field, and when this axis is east,
+						//it can't possibly be west too. So clear out the two X axes, then refil
+						//it in with the new direction bit.
+						//Clear the East/West Bit Flags first
+						mState.mPOV[OIS_POVIndex].direction &= 0x11110011;
+						if( js[i].value == -1 )	//Left
+							mState.mPOV[OIS_POVIndex].direction |= Pov::West;
+						else if( js[i].value == 1 ) //Right
+							mState.mPOV[OIS_POVIndex].direction |= Pov::East;
+					}
+					//Handle Y Axis (Odd) (up down)
+					else
+					{
+						//Clear the North/South Bit Flags first
+						mState.mPOV[OIS_POVIndex].direction &= 0x11111100;
+						if( js[i].value == -1 )	//Up
+							mState.mPOV[OIS_POVIndex].direction |= Pov::North;
+						else if( js[i].value == 1 ) //Down
+							mState.mPOV[OIS_POVIndex].direction |= Pov::South;
+					}
+
+					if( mBuffered && mListener )
+						if( mListener->povMoved( JoyStickEvent(this,mState), OIS_POVIndex) == false )
+							return;
+				}
+				break;
+			}
+
+			
+			case EV_REL: //Relative Axes (Do any joystick actually have a relative axis?)
+	#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "\nWarning: Relatives axes not supported yet" << endl;
+	#endif
+				break;
+			default: break;
+			}
+		}
+	}
+
+	//All axes and POVs are combined into one movement per pair per captured frame
+	if( mBuffered && mListener )
+	{
+		for( int i = 0; i < 32; ++i )
+			if( axisMoved[i] )
+				if( mListener->axisMoved( JoyStickEvent(this,mState), i) == false )
+					return;
+	}
+}
+
+//-------------------------------------------------------------------//
+void LinuxJoyStick::setBuffered(bool buffered)
+{
+	if( buffered != mBuffered )
+	{
+		mBuffered = buffered;
+		_initialize();
+	}
+}
+
+//-------------------------------------------------------------------//
+JoyStickInfo LinuxJoyStick::_getJoyInfo()
+{
+	JoyStickInfo js;
+
+	js.devId = mDevID;
+	js.joyFileD = mJoyStick;
+	js.vendor = mVendor;
+	js.axes = (int)mState.mAxes.size();
+	js.buttons = (int)mState.mButtons.size();
+	js.hats = mPOVs;
+	js.button_map = mButtonMap;
+	js.axis_map = mAxisMap;
+	js.axis_range = mRanges;
+
+	return js;
+}
+
+//-------------------------------------------------------------------//
+JoyStickInfoList LinuxJoyStick::_scanJoys()
+{
+	JoyStickInfoList joys;
+
+	//Search through all of the event devices.. and identify which ones are joysticks
+	//xxx move this to InputManager, as it can also scan all other events
+	for(int i = 0; i < 64; ++i )
+	{
+		stringstream s;
+		s << "/dev/input/event" << i;
+		int fd = open( s.str().c_str(), O_RDWR |O_NONBLOCK );
+		if(fd == -1)
+			continue;
+
+        #ifdef OIS_LINUX_JOY_DEBUG
+		  cout << "Opening " << s.str() << "..." << endl;
+        #endif
+		try
+		{
+			JoyStickInfo js;
+			if( EventUtils::isJoyStick(fd, js) )
+			{
+				joys.push_back(js);
+                #ifdef OIS_LINUX_JOY_DEBUG
+                  cout << "=> Joystick added to list." << endl;
+                #endif
+			}
+			else
+			{
+                #ifdef OIS_LINUX_JOY_DEBUG
+                  cout << "=> Not a joystick." << endl;
+                #endif
+				close(fd);
+			}
+		}
+		catch(...)
+		{
+            #ifdef OIS_LINUX_JOY_DEBUG
+              cout << "Exception caught!!" << endl;
+            #endif
+			close(fd);
+		}
+	}
+
+	return joys;
+}
+
+//-------------------------------------------------------------------//
+void LinuxJoyStick::_clearJoys(JoyStickInfoList &joys)
+{
+	for(JoyStickInfoList::iterator i = joys.begin(); i != joys.end(); ++i)
+		close(i->joyFileD);
+	joys.clear();
+}
+
+//-------------------------------------------------------------------//
+Interface* LinuxJoyStick::queryInterface(Interface::IType type)
+{
+	if( ff_effect && type == Interface::ForceFeedback )
+		return ff_effect;
+
+	return 0;
+}

+ 429 - 0
CamelotOISInput/Source/OIS/linux/LinuxKeyboard.cpp

@@ -0,0 +1,429 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "linux/LinuxInputManager.h"
+#include "linux/LinuxKeyboard.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+#include <X11/keysym.h>
+#include <X11/Xutil.h>
+#include <cstring>
+
+using namespace OIS;
+#include <iostream>
+//-------------------------------------------------------------------//
+LinuxKeyboard::LinuxKeyboard(InputManager* creator, bool buffered, bool grab)
+	: Keyboard(creator->inputSystemName(), buffered, 0, creator)
+{
+	setlocale(LC_CTYPE, ""); //Set the locale to (hopefully) the users LANG UTF-8 Env var
+
+	display = 0;
+	window = 0;
+
+	grabKeyboard = grab;
+	keyFocusLost = false;
+
+	//X Key Map to KeyCode
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_1, KC_1));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_2, KC_2));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_3, KC_3));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_4, KC_4));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_5, KC_5));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_6, KC_6));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_7, KC_7));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_8, KC_8));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_9, KC_9));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_0, KC_0));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_BackSpace, KC_BACK));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_minus, KC_MINUS));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_equal, KC_EQUALS));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_space, KC_SPACE));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_comma, KC_COMMA));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_period, KC_PERIOD));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_backslash, KC_BACKSLASH));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_slash, KC_SLASH));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_bracketleft, KC_LBRACKET));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_bracketright, KC_RBRACKET));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Escape,KC_ESCAPE));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Caps_Lock, KC_CAPITAL));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Tab, KC_TAB));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Return, KC_RETURN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Control_L, KC_LCONTROL));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Control_R, KC_RCONTROL));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_colon, KC_COLON));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_semicolon, KC_SEMICOLON));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_apostrophe, KC_APOSTROPHE));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_grave, KC_GRAVE));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_b, KC_B));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_a, KC_A));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_c, KC_C));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_d, KC_D));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_e, KC_E));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_f, KC_F));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_g, KC_G));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_h, KC_H));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_i, KC_I));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_j, KC_J));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_k, KC_K));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_l, KC_L));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_m, KC_M));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_n, KC_N));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_o, KC_O));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_p, KC_P));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_q, KC_Q));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_r, KC_R));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_s, KC_S));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_t, KC_T));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_u, KC_U));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_v, KC_V));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_w, KC_W));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_x, KC_X));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_y, KC_Y));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_z, KC_Z));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F1, KC_F1));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F2, KC_F2));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F3, KC_F3));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F4, KC_F4));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F5, KC_F5));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F6, KC_F6));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F7, KC_F7));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F8, KC_F8));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F9, KC_F9));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F10, KC_F10));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F11, KC_F11));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F12, KC_F12));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F13, KC_F13));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F14, KC_F14));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F15, KC_F15));
+
+	//Keypad
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_0, KC_NUMPAD0));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_1, KC_NUMPAD1));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_2, KC_NUMPAD2));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_3, KC_NUMPAD3));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_4, KC_NUMPAD4));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_5, KC_NUMPAD5));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_6, KC_NUMPAD6));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_7, KC_NUMPAD7));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_8, KC_NUMPAD8));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_9, KC_NUMPAD9));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Add, KC_ADD));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Subtract, KC_SUBTRACT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Decimal, KC_DECIMAL));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Equal, KC_NUMPADEQUALS));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Divide, KC_DIVIDE));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Multiply, KC_MULTIPLY));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Enter, KC_NUMPADENTER));
+
+	//Keypad with numlock off
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Home, KC_NUMPAD7));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Up, KC_NUMPAD8));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Page_Up, KC_NUMPAD9));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Left, KC_NUMPAD4));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Begin, KC_NUMPAD5));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Right, KC_NUMPAD6));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_End, KC_NUMPAD1));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Down, KC_NUMPAD2));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Page_Down, KC_NUMPAD3));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Insert, KC_NUMPAD0));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Delete, KC_DECIMAL));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Up, KC_UP));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Down, KC_DOWN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Left, KC_LEFT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Right, KC_RIGHT));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Page_Up, KC_PGUP));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Page_Down, KC_PGDOWN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Home, KC_HOME));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_End, KC_END));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Num_Lock, KC_NUMLOCK));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Print, KC_SYSRQ));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Scroll_Lock, KC_SCROLL));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Pause, KC_PAUSE));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Shift_R, KC_RSHIFT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Shift_L, KC_LSHIFT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Alt_R, KC_RMENU));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Alt_L, KC_LMENU));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Insert, KC_INSERT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Delete, KC_DELETE));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Super_L, KC_LWIN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Super_R, KC_RWIN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Menu, KC_APPS));
+
+	static_cast<LinuxInputManager*>(mCreator)->_setKeyboardUsed(true);
+}
+
+//-------------------------------------------------------------------//
+void LinuxKeyboard::_initialize()
+{
+	//Clear our keyboard state buffer
+	memset( &KeyBuffer, 0, 256 );
+	mModifiers = 0;
+
+	if( display ) XCloseDisplay(display);
+	display = 0;
+	window = static_cast<LinuxInputManager*>(mCreator)->_getWindow();
+
+	//Create our local X mListener connection
+	if( !(display = XOpenDisplay(0)) )
+		OIS_EXCEPT(E_General, "LinuxKeyboard::_initialize >> Error opening X!");
+
+	//Set it to recieve Input events
+	if( XSelectInput(display, window, KeyPressMask | KeyReleaseMask) == BadWindow )
+		OIS_EXCEPT(E_General, "LinuxKeyboard::_initialize: X error!");
+
+	if( grabKeyboard )
+		XGrabKeyboard(display,window,True,GrabModeAsync,GrabModeAsync,CurrentTime);
+
+	keyFocusLost = false;
+}
+
+//-------------------------------------------------------------------//
+LinuxKeyboard::~LinuxKeyboard()
+{
+	if( display )
+	{
+		if( grabKeyboard )
+			XUngrabKeyboard(display, CurrentTime);
+
+		XCloseDisplay(display);
+	}
+
+	static_cast<LinuxInputManager*>(mCreator)->_setKeyboardUsed(true);
+}
+
+//-------------------------------------------------------------------//
+unsigned int UTF8ToUTF32(unsigned char* buf)
+{
+	unsigned char &FirstChar = buf[0];
+
+	if(FirstChar < 128)
+		return FirstChar;
+
+	unsigned int val = 0;
+	unsigned int len = 0;
+
+	if((FirstChar & 0xE0) == 0xC0) //2 Chars
+	{
+		len = 2;
+		val = FirstChar & 0x1F;
+	}
+	else if((FirstChar & 0xF0) == 0xE0) //3 Chars
+	{
+		len = 3;
+		val = FirstChar & 0x0F;
+	}
+	else if((FirstChar & 0xF8) == 0xF0) //4 Chars
+	{
+		len = 4;
+		val = FirstChar & 0x07;
+	}
+	else if((FirstChar & 0xFC) == 0xF8) //5 Chars
+	{
+		len = 5;
+		val = FirstChar & 0x03;
+	}
+	else // if((FirstChar & 0xFE) == 0xFC) //6 Chars
+	{
+		len = 6;
+		val = FirstChar & 0x01;
+	}
+
+	for(int i = 1; i < len; i++)
+		val = (val << 6) | (buf[i] & 0x3F);
+
+	return val;
+}
+
+//-------------------------------------------------------------------//
+bool LinuxKeyboard::isKeyDown( KeyCode key ) const
+{
+	return (KeyBuffer[key]);
+}
+
+//-------------------------------------------------------------------//
+void LinuxKeyboard::capture()
+{
+	KeySym key;
+	XEvent event;
+	LinuxInputManager* linMan = static_cast<LinuxInputManager*>(mCreator);
+
+	while( XPending(display) > 0 )
+	{
+		XNextEvent(display, &event);

+		if(KeyPress == event.type)
+		{
+			unsigned int character = 0;
+
+			if(mTextMode != Off)
+			{
+				unsigned char buffer[6] = {0,0,0,0,0,0};
+				XLookupString(&event.xkey, (char*)buffer, 6, &key, 0);
+
+				if( mTextMode == Unicode )
+					character = UTF8ToUTF32(buffer);
+				else if( mTextMode == Ascii)
+					character = buffer[0];
+			}
+
+			//Mask out the modifier states X11 sets and read again
+			event.xkey.state &= ~ShiftMask;
+			event.xkey.state &= ~LockMask;
+			XLookupString(&event.xkey, 0, 0,&key, 0);
+
+			_injectKeyDown(key, character);
+
+			//Just printing out some debugging info.. to verify all chars are mapped
+			//std::cout << "KEY PRESSED X=" << event.xkey.keycode;
+			//std::cout << "\n KeySym=" << key << std::endl;
+
+			//Check for Alt-Tab
+			if( event.xkey.state & Mod1Mask && key == XK_Tab )
+				linMan->_setGrabState(false);
+		}
+		else if(KeyRelease == event.type)
+		{
+			if(!_isKeyRepeat(event))
+			{
+				//Mask out the modifier states X sets.. or we will get improper values
+				event.xkey.state &= ~ShiftMask;
+				event.xkey.state &= ~LockMask;
+
+				XLookupString(&event.xkey,NULL,0,&key,NULL);
+				_injectKeyUp(key);
			}
+		}
+	}
+
+	//If grabbing mode is on.. Handle focus lost/gained via Alt-Tab and mouse clicks
+	if( grabKeyboard )
+	{
+		if( linMan->_getGrabState() == false )
+		{
+			// are no longer grabbing
+			if( keyFocusLost == false )
+			{
+				//UnGrab KeyBoard
+				XUngrabKeyboard(display, CurrentTime);
+				keyFocusLost = true;
+			}
+		}
+		else
+		{
+			//We are grabbing - and regained focus
+			if( keyFocusLost == true )
+			{
+				//ReGrab KeyBoard
+				XGrabKeyboard(display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
+				keyFocusLost = false;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------//
+void LinuxKeyboard::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//-------------------------------------------------------------------//
+bool LinuxKeyboard::_injectKeyDown( KeySym key, int text )
+{
+	KeyCode kc = keyConversion[key];
+	KeyBuffer[kc] = 1;
+
+	//Turn on modifier flags
+	if( kc == KC_LCONTROL || kc == KC_RCONTROL)
+		mModifiers |= Ctrl;
+	else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
+		mModifiers |= Shift;
+	else if( kc == KC_LMENU || kc == KC_RMENU )
+		mModifiers |= Alt;
+
+	if( mBuffered && mListener )
+		return mListener->keyPressed(KeyEvent(this,kc,text));
+
+	return true;
+}
+
+//-------------------------------------------------------------------//
+bool LinuxKeyboard::_injectKeyUp( KeySym key )
+{
+	KeyCode kc = keyConversion[key];
+	KeyBuffer[kc] = 0;
+
+	//Turn off modifier flags
+	if( kc == KC_LCONTROL || kc == KC_RCONTROL)
+		mModifiers &= ~Ctrl;
+	else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
+		mModifiers &= ~Shift;
+	else if( kc == KC_LMENU || kc == KC_RMENU )
+		mModifiers &= ~Alt;
+
+	if( mBuffered && mListener )
+		return mListener->keyReleased(KeyEvent(this, kc, 0));
+
+	return true;
+}
+
+//-------------------------------------------------------------------//
+const std::string& LinuxKeyboard::getAsString( KeyCode kc )
+{
+	mGetString = "Unknown";
+	char *temp = 0;
+
+	XtoOIS_KeyMap::iterator i = keyConversion.begin(),
+				e = keyConversion.end();
+
+	for( ; i != e; ++i )
+	{
+		if( i->second == kc )
+		{
+			temp = XKeysymToString(i->first);
+			if( temp )
+				mGetString = temp;
+			break;
+		}
+	}
+
+	return mGetString;
+}
+
+//-------------------------------------------------------------------//
+void LinuxKeyboard::copyKeyStates( char keys[256] ) const
+{
+	memcpy( keys, KeyBuffer, 256 );
+}

+ 272 - 0
CamelotOISInput/Source/OIS/linux/LinuxMouse.cpp

@@ -0,0 +1,272 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered friosom any source distribution.
+*/
+#include "linux/LinuxMouse.h"
+#include "linux/LinuxInputManager.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+using namespace OIS;
+
+//-------------------------------------------------------------------//
+LinuxMouse::LinuxMouse(InputManager* creator, bool buffered, bool grab, bool hide)
+	: Mouse(creator->inputSystemName(), buffered, 0, creator)
+{
+	display = 0;
+	window = 0;
+	cursor = 0;
+
+	grabMouse = grab;
+	hideMouse = hide;
+
+	static_cast<LinuxInputManager*>(mCreator)->_setMouseUsed(true);
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::_initialize()
+{
+	//Clear old state
+	mState.clear();
+	mMoved  = false;
+	mWarped = false;
+
+	//6 is just some random value... hardly ever would anyone have a window smaller than 6
+	oldXMouseX = oldXMouseY = 6;
+	oldXMouseZ = 0;
+
+	if( display ) XCloseDisplay(display);
+	display = 0;
+	window = static_cast<LinuxInputManager*>(mCreator)->_getWindow();
+
+	//Create our local X mListener connection
+	if( !(display = XOpenDisplay(0)) )
+		OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> Error opening X!");
+
+	//Set it to recieve Mouse Input events
+	if( XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask) == BadWindow )
+		OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> X error!");
+
+	//Warp mouse inside window
+	XWarpPointer(display,None,window,0,0,0,0, 6,6);
+
+	//Create a blank cursor:
+	Pixmap bm_no;
+	XColor black, dummy;
+	Colormap colormap;
+	static char no_data[] = { 0,0,0,0,0,0,0,0 };
+
+	colormap = DefaultColormap( display, DefaultScreen(display) );
+	XAllocNamedColor( display, colormap, "black", &black, &dummy );
+	bm_no = XCreateBitmapFromData( display, window, no_data, 8, 8 );
+	cursor = XCreatePixmapCursor( display, bm_no, bm_no, &black, &black, 0, 0 );
+
+	grab( grabMouse );
+	hide( hideMouse );
+
+	mouseFocusLost = false;
+}
+
+//-------------------------------------------------------------------//
+LinuxMouse::~LinuxMouse()
+{
+	if( display )
+	{
+		grab(false);
+		hide(false);
+		XFreeCursor(display, cursor);
+		XCloseDisplay(display);
+	}
+
+	static_cast<LinuxInputManager*>(mCreator)->_setMouseUsed(false);
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::capture()
+{
+	//Clear out last frames values
+	mState.X.rel = 0;
+	mState.Y.rel = 0;
+	mState.Z.rel = 0;
+
+	_processXEvents();
+
+	mWarped = false;
+
+	if( mMoved == true )
+	{
+		if( mBuffered && mListener )
+			mListener->mouseMoved( MouseEvent( this, mState ) );
+
+		mMoved = false;
+	}
+
+	//Check for losing/gaining mouse grab focus (alt-tab, etc)
+	if( grabMouse )
+	{
+		if( static_cast<LinuxInputManager*>(mCreator)->_getGrabState() )
+		{
+			if( mouseFocusLost )	//We just regained mouse grab focus
+			{
+				grab( true );
+				hide( hideMouse );
+				mouseFocusLost = false;
+			}
+		}
+		else
+		{
+			if( mouseFocusLost == false )	//We just lost mouse grab focus
+			{
+				grab( false );
+				hide( false );
+				mouseFocusLost = true;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::_processXEvents()
+{
+	//X11 Button Events: 1=left 2=middle 3=right; Our Bit Postion: 1=Left 2=Right 3=Middle
+	char mask[4] = {0,1,4,2};
+	XEvent event;
+
+	//Poll x11 for events mouse events
+	while( XPending(display) > 0 ) 
+	{
+		XNextEvent(display, &event);
+
+		if( event.type == MotionNotify )
+		{	//Mouse moved
+			//Ignore out of bounds mouse if we just warped
+			if( mWarped )
+			{
+				if(event.xmotion.x < 5 || event.xmotion.x > mState.width - 5 ||
+				   event.xmotion.y < 5 || event.xmotion.y > mState.height - 5)
+					continue;
+			}
+
+			//Compute this frames Relative X & Y motion
+			int dx = event.xmotion.x - oldXMouseX;
+			int dy = event.xmotion.y - oldXMouseY;
+		
+			//Store old values for next time to compute relative motion
+			oldXMouseX = event.xmotion.x;
+			oldXMouseY = event.xmotion.y;
+
+			mState.X.abs += dx;
+			mState.Y.abs += dy;
+			mState.X.rel += dx;
+			mState.Y.rel += dy;
+
+			//Check to see if we are grabbing the mouse to the window (requires clipping and warping)
+			if( grabMouse )
+			{
+				if( mState.X.abs < 0 )
+					mState.X.abs = 0;
+				else if( mState.X.abs > mState.width )
+					mState.X.abs = mState.width;
+
+				if( mState.Y.abs < 0 )
+					mState.Y.abs = 0;
+				else if( mState.Y.abs > mState.height )
+					mState.Y.abs = mState.height;
+
+				if( mouseFocusLost == false )
+				{
+					//Keep mouse in window (fudge factor)
+					if(event.xmotion.x < 5 || event.xmotion.x > mState.width - 5 ||
+					   event.xmotion.y < 5 || event.xmotion.y > mState.height - 5 )
+					{
+						oldXMouseX = mState.width >> 1;  //center x
+						oldXMouseY = mState.height >> 1; //center y
+						XWarpPointer(display, None, window, 0, 0, 0, 0, oldXMouseX, oldXMouseY);
+						mWarped = true;
+					}
+				}
+			}
+			mMoved = true;
+		}
+		else if( event.type == ButtonPress )
+		{	//Button down
+			static_cast<LinuxInputManager*>(mCreator)->_setGrabState(true);
+
+			if( event.xbutton.button < 4 )
+			{
+				mState.buttons |= mask[event.xbutton.button];
+				if( mBuffered && mListener )
+					if( mListener->mousePressed( MouseEvent( this, mState ),
+						(MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
+						return;
+			}
+		}
+		else if( event.type == ButtonRelease )
+		{	//Button up
+			if( event.xbutton.button < 4 )
+			{
+				mState.buttons &= ~mask[event.xbutton.button];
+				if( mBuffered && mListener )
+					if( mListener->mouseReleased( MouseEvent( this, mState ),
+						(MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
+						return;
+			}
+			//The Z axis gets pushed/released pair message (this is up)
+			else if( event.xbutton.button == 4 )
+			{
+				mState.Z.rel += 120;
+				mState.Z.abs += 120;
+				mMoved = true;
+			}
+			//The Z axis gets pushed/released pair message (this is down)
+			else if( event.xbutton.button == 5 )
+			{
+				mState.Z.rel -= 120;
+				mState.Z.abs -= 120;
+				mMoved = true;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::grab(bool grab)
+{
+	if( grab )
+		XGrabPointer(display, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
+	else
+		XUngrabPointer(display, CurrentTime);
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::hide(bool hide)
+{
+	if( hide )
+		XDefineCursor(display, window, cursor);
+	else
+		XUndefineCursor(display, window);
+}

+ 432 - 0
CamelotOISInput/Source/OIS/mac/MacHIDManager.cpp

@@ -0,0 +1,432 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Phillip Castaneda
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+#include "mac/MacHIDManager.h"
+#include "mac/MacJoyStick.h"
+#include "OISException.h"
+#include "OISObject.h"
+
+#include <iostream>
+using namespace std;
+
+using namespace OIS;
+
+//------------------------------------------------------------------------------------------------------//
+//------------------------------------------------------------------------------------------------------//
+template<typename T>
+T getDictionaryItemAsRef(CFDictionaryRef dict, const char* keyName)
+{
+	return CFDictionaryGetValue(dict, OIS_CFString(keyName));
+}
+
+template<>
+CFArrayRef getDictionaryItemAsRef(CFDictionaryRef dict, const char* keyName)
+{
+	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
+	
+	if(temp && CFGetTypeID(temp) == CFArrayGetTypeID())
+		return (CFArrayRef)temp;
+	else
+		return 0;
+}
+
+template<>
+CFStringRef getDictionaryItemAsRef(CFDictionaryRef dict, const char* keyName)
+{
+	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
+	
+	if(temp && CFGetTypeID(temp) == CFStringGetTypeID())
+		return (CFStringRef)temp;
+	else
+		return 0;
+}
+
+template<>
+CFNumberRef getDictionaryItemAsRef(CFDictionaryRef dict, const char* keyName)
+{
+	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
+	
+	if(temp && CFGetTypeID(temp) == CFNumberGetTypeID())
+		return (CFNumberRef)temp;
+	else
+		return 0;
+}
+
+//------------------------------------------------------------------------------------------------------//
+//------------------------------------------------------------------------------------------------------//
+template<typename T>
+T getArrayItemAsRef(CFArrayRef array, CFIndex idx)
+{
+	return CFArrayGetValueAtIndex(array, idx);
+}
+
+template<>
+CFDictionaryRef getArrayItemAsRef(CFArrayRef array, CFIndex idx)
+{
+	CFTypeRef temp = CFArrayGetValueAtIndex(array, idx);
+	
+	if(temp && CFGetTypeID(temp) == CFDictionaryGetTypeID())
+		return (CFDictionaryRef)temp;
+	else
+		return 0;
+}
+
+//------------------------------------------------------------------------------------------------------//
+int getInt32(CFNumberRef ref)
+{
+	int r = 0;
+	if (r) 
+		CFNumberGetValue(ref, kCFNumberIntType, &r);
+	return r;
+}
+
+//--------------------------------------------------------------------------------//
+MacHIDManager::MacHIDManager()
+{
+}
+
+//--------------------------------------------------------------------------------//
+MacHIDManager::~MacHIDManager()
+{
+}
+
+//------------------------------------------------------------------------------------------------------//
+void MacHIDManager::initialize()
+{
+	//Make the search more specific by adding usage flags
+	int usage = kHIDUsage_GD_Joystick;
+	int page = kHIDPage_GenericDesktop;
+	
+	io_iterator_t iterator = lookUpDevices(usage, page);
+	
+	if(iterator)
+		iterateAndOpenDevices(iterator);
+	
+	//Doesn't support multiple usage flags, iterate twice
+	usage = kHIDUsage_GD_GamePad;
+	iterator = lookUpDevices(usage, page);
+	
+	if(iterator)
+		iterateAndOpenDevices(iterator);
+}
+
+//------------------------------------------------------------------------------------------------------//
+io_iterator_t MacHIDManager::lookUpDevices(int usage, int page)
+{
+	CFMutableDictionaryRef deviceLookupMap = IOServiceMatching(kIOHIDDeviceKey);
+	if(!deviceLookupMap)
+		OIS_EXCEPT(E_General, "Could not setup HID device search parameters");
+	
+	CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
+	CFNumberRef pageRef  = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
+	
+	CFDictionarySetValue(deviceLookupMap, CFSTR(kIOHIDPrimaryUsageKey), usageRef);
+	CFDictionarySetValue(deviceLookupMap, CFSTR(kIOHIDPrimaryUsagePageKey), pageRef);
+	
+	//IOServiceGetMatchingServices consumes the map so we do not have to release it ourself
+	io_iterator_t iterator = 0;
+	IOReturn result = IOServiceGetMatchingServices(kIOMasterPortDefault, deviceLookupMap, &iterator);
+	
+	CFRelease(usageRef);
+	CFRelease(pageRef);
+	
+	if(result == kIOReturnSuccess)
+	{
+		return iterator;
+	}
+	//TODO: Throw exception instead?
+	else
+	{
+		return 0;
+	}
+}
+
+//------------------------------------------------------------------------------------------------------//
+void MacHIDManager::iterateAndOpenDevices(io_iterator_t iterator)
+{
+	io_object_t hidDevice = 0;
+	while ((hidDevice = IOIteratorNext(iterator)) !=0)
+	{
+		//Get the current registry items property map
+		CFMutableDictionaryRef propertyMap = 0;
+		if (IORegistryEntryCreateCFProperties(hidDevice, &propertyMap, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS && propertyMap)
+		{
+			//Go through device to find all needed info
+			HidInfo* hid = enumerateDeviceProperties(propertyMap);
+			
+			if(hid)
+			{
+				//todo - we need to hold an open interface so we do not have to enumerate again later
+				//should be able to watch for device removals also
+				
+				// Testing opening / closing interface
+				IOCFPlugInInterface **pluginInterface = NULL;
+				SInt32 score = 0;
+				if (IOCreatePlugInInterfaceForService(hidDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &pluginInterface, &score) == kIOReturnSuccess)
+				{
+					IOHIDDeviceInterface **interface;
+					
+					HRESULT pluginResult = (*pluginInterface)->QueryInterface(pluginInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void **)&(interface));
+					
+					if(pluginResult != S_OK)
+						OIS_EXCEPT(E_General, "Not able to create plugin interface");
+					
+					IODestroyPlugInInterface(pluginInterface);
+					
+					hid->interface = interface;
+					
+					//Check for duplicates - some devices have multiple usage
+					if(std::find(mDeviceList.begin(), mDeviceList.end(), hid) == mDeviceList.end())
+						mDeviceList.push_back(hid);
+				}
+			}
+		}
+	}
+	
+	IOObjectRelease(iterator);
+}
+
+//------------------------------------------------------------------------------------------------------//
+HidInfo* MacHIDManager::enumerateDeviceProperties(CFMutableDictionaryRef propertyMap)
+{
+	HidInfo* info = new HidInfo();
+	
+	info->type = OISJoyStick;
+	
+	CFStringRef str = getDictionaryItemAsRef<CFStringRef>(propertyMap, kIOHIDManufacturerKey);
+	if (str)
+		info->vendor = CFStringGetCStringPtr(str, CFStringGetSystemEncoding());
+	
+	str = getDictionaryItemAsRef<CFStringRef>(propertyMap, kIOHIDProductKey);
+	if (str)
+		info->productKey = CFStringGetCStringPtr(str, CFStringGetSystemEncoding());
+	
+	info->combinedKey = info->vendor + " " + info->productKey;
+	
+	//Go through all items in this device (i.e. buttons, hats, sticks, axes, etc)
+	CFArrayRef array = getDictionaryItemAsRef<CFArrayRef>(propertyMap, kIOHIDElementKey);
+	if (array)
+		for (int i = 0; i < CFArrayGetCount(array); i++)
+			parseDeviceProperties(getArrayItemAsRef<CFDictionaryRef>(array, i));
+	
+	return info;
+}
+
+//------------------------------------------------------------------------------------------------------//
+void MacHIDManager::parseDeviceProperties(CFDictionaryRef properties)
+{
+	if(!properties)
+		return;
+	
+	CFArrayRef array = getDictionaryItemAsRef<CFArrayRef>(properties, kIOHIDElementKey);
+	if (array)
+	{
+		for (int i = 0; i < CFArrayGetCount(array); i++)
+		{
+			CFDictionaryRef element = getArrayItemAsRef<CFDictionaryRef>(array, i);
+			if (element)
+			{
+				if(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementTypeKey)) == kIOHIDElementTypeCollection) 
+				{	//Check if we need to recurse further intoi another collection
+					if(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsagePageKey)) == kHIDPage_GenericDesktop)
+						parseDeviceProperties(element);
+				}
+				else
+				{
+					switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsagePageKey)))
+					{
+						case kHIDPage_GenericDesktop:
+							switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsageKey)))
+						{
+							case kHIDUsage_GD_Pointer:
+								cout << "\tkHIDUsage_GD_Pointer\n";
+								parseDevicePropertiesGroup(element);
+								break;
+							case kHIDUsage_GD_X:
+							case kHIDUsage_GD_Y:
+							case kHIDUsage_GD_Z:
+							case kHIDUsage_GD_Rx:
+							case kHIDUsage_GD_Ry:
+							case kHIDUsage_GD_Rz:
+								cout << "\tAxis\n";
+								break;
+							case kHIDUsage_GD_Slider:
+							case kHIDUsage_GD_Dial:
+							case kHIDUsage_GD_Wheel:
+								cout << "\tUnsupported kHIDUsage_GD_Wheel\n";
+								break;
+							case kHIDUsage_GD_Hatswitch:
+								cout << "\tUnsupported - kHIDUsage_GD_Hatswitch\n";
+								break;
+						}
+							break;
+						case kHIDPage_Button:
+							cout << "\tkHIDPage_Button\n";
+							break;
+					}
+				}
+			}
+		}
+	}
+}
+
+//------------------------------------------------------------------------------------------------------//
+void MacHIDManager::parseDevicePropertiesGroup(CFDictionaryRef properties)
+{
+	if(!properties)
+		return;
+	
+	CFArrayRef array = getDictionaryItemAsRef<CFArrayRef>(properties, kIOHIDElementKey);
+	if(array)
+	{
+		for (int i = 0; i < CFArrayGetCount(array); i++)
+		{
+			CFDictionaryRef element = getArrayItemAsRef<CFDictionaryRef>(array, i);
+			if (element)
+			{
+				switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsagePageKey)))
+				{
+					case kHIDPage_GenericDesktop:
+						switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsageKey)))
+					{
+						case kHIDUsage_GD_X:
+						case kHIDUsage_GD_Y:
+						case kHIDUsage_GD_Z:
+						case kHIDUsage_GD_Rx:
+						case kHIDUsage_GD_Ry:
+						case kHIDUsage_GD_Rz:
+							cout << "\t\tAxis\n";
+							break;
+						case kHIDUsage_GD_Slider:
+						case kHIDUsage_GD_Dial:
+						case kHIDUsage_GD_Wheel:
+							cout << "\tUnsupported - kHIDUsage_GD_Wheel\n";
+							break;
+						case kHIDUsage_GD_Hatswitch:
+							cout << "\tUnsupported - kHIDUsage_GD_Hatswitch\n";
+							break;
+					}
+						break;
+					case kHIDPage_Button:
+						break;
+				}
+			}
+		}
+	}
+}
+
+//--------------------------------------------------------------------------------//
+DeviceList MacHIDManager::freeDeviceList()
+{
+	DeviceList ret;
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+	for(; it != end; ++it)
+	{
+		if((*it)->inUse == false)
+			ret.insert(std::make_pair((*it)->type, (*it)->combinedKey));
+	}
+	
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+int MacHIDManager::totalDevices(Type iType)
+{
+	int ret = 0;
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+	
+	for(; it != end; ++it)
+	{
+		if((*it)->type == iType)
+			ret++;
+	}
+	
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+int MacHIDManager::freeDevices(Type iType)
+{
+	int ret = 0;
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+	
+	for(; it != end; ++it)
+	{
+		if((*it)->inUse == false && (*it)->type == iType)
+			ret++;
+	}
+	
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+bool MacHIDManager::vendorExist(Type iType, const std::string & vendor)
+{
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+	
+	for(; it != end; ++it)
+	{
+		if((*it)->type == iType && (*it)->combinedKey == vendor)
+			return true;
+	}
+	
+	return false;
+}
+
+//--------------------------------------------------------------------------------//
+Object* MacHIDManager::createObject(InputManager* creator, Type iType, bool bufferMode, 
+									const std::string & vendor)
+{
+	Object *obj = 0;
+	
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+	for(; it != end; ++it)
+	{
+		if((*it)->inUse == false && (*it)->type == iType && (vendor == "" || (*it)->combinedKey == vendor))
+		{
+			switch(iType)
+			{
+				case OISJoyStick:
+					int totalDevs = totalDevices(iType);
+					int freeDevs = freeDevices(iType);
+					int devID = totalDevs - freeDevs;
+					
+					obj = new MacJoyStick((*it)->combinedKey, bufferMode, *it, creator, devID);
+					(*it)->inUse = true;
+					return obj;
+				case OISTablet:
+					//Create MacTablet
+					break;
+				default:
+					break;
+			}
+		}
+	}
+	
+	return obj;
+}
+
+//--------------------------------------------------------------------------------//
+void MacHIDManager::destroyObject(Object* obj)
+{
+	delete obj;
+}

+ 158 - 0
CamelotOISInput/Source/OIS/mac/MacHelpers.cpp

@@ -0,0 +1,158 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "mac/MacHelpers.h"
+#include "mac/MacKeyboard.h"
+#include "mac/MacMouse.h"
+#include "OISException.h"
+
+#include <Carbon/Carbon.h>
+
+using namespace OIS;
+    
+//-------------------------------------------------------------------//
+OSStatus KeyDownWrapper( EventHandlerCallRef nextHandler,
+                        EventRef               theEvent,
+                        void*                  callClass )
+{
+    // TODO find a better way. This cast isn't very safe
+    if (callClass != NULL) {
+        ((MacKeyboard*)callClass)->_keyDownCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+    }
+    else {
+        OIS_EXCEPT(E_General, "KeyDownWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+
+//-------------------------------------------------------------------//
+OSStatus KeyUpWrapper( EventHandlerCallRef nextHandler,
+                       EventRef               theEvent,
+                       void*                  callClass )
+{
+    if (callClass != NULL) {
+        ((MacKeyboard*)callClass)->_keyUpCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+    }
+    else {
+        OIS_EXCEPT(E_General, "KeyUpWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+
+//-------------------------------------------------------------------//
+OSStatus KeyModWrapper( EventHandlerCallRef nextHandler,
+                        EventRef               theEvent,
+                        void*                  callClass )
+{
+    if (callClass != NULL) {
+        ((MacKeyboard*)callClass)->_modChangeCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+        
+    }
+    else {
+        OIS_EXCEPT(E_General, "KeyModWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+/*
+//-------------------------------------------------------------------//
+OSStatus MouseMoveWrapper( EventHandlerCallRef nextHandler,
+                           EventRef            theEvent,
+                           void*               callClass )
+{
+    if (callClass != NULL) {
+        ((MacMouse*)callClass)->_mouseMoveCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+        
+    }
+    else {
+        OIS_EXCEPT(E_General, "MouseMoveWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+
+//-------------------------------------------------------------------//
+OSStatus MouseScrollWrapper( EventHandlerCallRef nextHandler,
+                             EventRef            theEvent,
+                             void*               callClass )
+{
+    if (callClass != NULL) {
+        ((MacMouse*)callClass)->_mouseScrollCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+        
+    }
+    else {
+        OIS_EXCEPT(E_General, "MouseScrollWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+
+//-------------------------------------------------------------------//
+OSStatus MouseButtonWrapper( EventHandlerCallRef nextHandler,
+                             EventRef            theEvent,
+                             void*               callClass )
+{
+    if (callClass != NULL) {
+        ((MacMouse*)callClass)->_mouseButtonCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+        
+    }
+    else {
+        OIS_EXCEPT(E_General, "MouseButtonWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+*/
+
+//-------------------------------------------------------------------//
+OSStatus MouseWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass )
+{
+    if (callClass != NULL)
+	{
+        ((MacMouse*)callClass)->_mouseCallback( theEvent );
+
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );        
+    }
+    else
+        OIS_EXCEPT(E_General, "MouseWrapper >> Being called by something other than our event handler!");
+}

+ 206 - 0
CamelotOISInput/Source/OIS/mac/MacInputManager.cpp

@@ -0,0 +1,206 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "mac/MacInputManager.h"
+#include "mac/MacKeyboard.h"
+#include "mac/MacMouse.h"
+#include "mac/MacHIDManager.h"
+#include "OISException.h"
+
+#include <Carbon/Carbon.h>
+
+#include <iostream>
+using namespace std;
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------//
+MacInputManager::MacInputManager() : InputManager("Mac OSX Input Manager")
+{
+    mHideMouse = true;
+    mUseRepeat = false;
+    mEventTargetRef = NULL;
+	mWindow = NULL;
+
+	keyboardUsed = mouseUsed = false;
+
+	//Setup our internal factories
+	mFactories.push_back(this);
+
+	mHIDManager = new MacHIDManager();
+	mFactories.push_back(mHIDManager);
+}
+
+//--------------------------------------------------------------------------------//
+MacInputManager::~MacInputManager()
+{
+	delete mHIDManager;
+}
+
+//--------------------------------------------------------------------------------//
+void MacInputManager::_initialize( ParamList &paramList )
+{
+	_parseConfigSettings( paramList );
+    
+	//Enumerate all devices attached
+	_enumerateDevices();
+	
+	mHIDManager->initialize();
+}
+
+//--------------------------------------------------------------------------------//
+void MacInputManager::_parseConfigSettings( ParamList &paramList )
+{
+    // Some carbon apps are running in a window, however full screen apps
+	// do not have a window, so we need to account for that too.
+	ParamList::iterator i = paramList.find("WINDOW");
+	if(i != paramList.end())
+	{
+		mWindow = (WindowRef)strtoul(i->second.c_str(), 0, 10);
+		if(mWindow == 0)
+		{
+			mWindow = NULL;
+			mEventTargetRef = GetApplicationEventTarget();
+		}
+		else
+		{
+			//mEventTargetRef = GetWindowEventTarget(mWindow);
+			mEventTargetRef = GetApplicationEventTarget();
+		}
+    }
+	else
+	{
+		// else get the main active window.. user might not have access to it through some
+		// graphics libraries, if that fails then try at the application level.
+		mWindow = ActiveNonFloatingWindow();
+		if(mWindow == NULL)
+		{
+			mEventTargetRef = GetApplicationEventTarget();
+		}
+		else
+		{
+			//mEventTargetRef = GetWindowEventTarget(mWindow);
+			mEventTargetRef = GetApplicationEventTarget();
+		}
+	}
+	
+	if(mEventTargetRef == NULL)
+		OIS_EXCEPT( E_General, "MacInputManager::_parseConfigSettings >> Unable to find a window or event target" );
+    
+    // Keyboard
+    if(paramList.find("MacAutoRepeatOn") != paramList.end())
+	{
+        if(paramList.find("MacAutoRepeatOn")->second == "true")
+		{
+            mUseRepeat = true;
+        }
+    }
+}
+
+//--------------------------------------------------------------------------------//
+void MacInputManager::_enumerateDevices()
+{
+}
+
+//--------------------------------------------------------------------------------//
+DeviceList MacInputManager::freeDeviceList()
+{
+	DeviceList ret;
+
+	if( keyboardUsed == false )
+		ret.insert(std::make_pair(OISKeyboard, mInputSystemName));
+
+	if( mouseUsed == false )
+		ret.insert(std::make_pair(OISMouse, mInputSystemName));
+
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+int MacInputManager::totalDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return 1;
+	case OISMouse: return 1;
+	default: return 0;
+	}
+}
+
+//--------------------------------------------------------------------------------//
+int MacInputManager::freeDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return keyboardUsed ? 0 : 1;
+	case OISMouse: return mouseUsed ? 0 : 1;
+	default: return 0;
+	}
+}
+
+//--------------------------------------------------------------------------------//
+bool MacInputManager::vendorExist(Type iType, const std::string & vendor)
+{
+	if( (iType == OISKeyboard || iType == OISMouse) && vendor == mInputSystemName )
+		return true;
+
+	return false;
+}
+
+//--------------------------------------------------------------------------------//
+Object* MacInputManager::createObject(InputManager* creator, Type iType, bool bufferMode, 
+									  const std::string & vendor)
+{
+	Object *obj = 0;
+
+	switch(iType)
+	{
+	case OISKeyboard: 
+	{
+		if( keyboardUsed == false )
+			obj = new MacKeyboard(this, bufferMode, mUseRepeat);
+		break;
+	}
+	case OISMouse:
+	{
+		if( mouseUsed == false )
+			obj = new MacMouse(this, bufferMode);
+		break;
+	}
+	default:
+	{
+		obj = mHIDManager->createObject(creator, iType, bufferMode, vendor);
+		break;
+	}
+	}
+
+	if( obj == 0 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	return obj;
+}
+
+//--------------------------------------------------------------------------------//
+void MacInputManager::destroyObject(Object* obj)
+{
+	delete obj;
+}

+ 325 - 0
CamelotOISInput/Source/OIS/mac/MacJoyStick.cpp

@@ -0,0 +1,325 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that
+ you wrote the original software. If you use this software in a product,
+ an acknowledgment in the product documentation would be appreciated but is
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "mac/MacJoyStick.h"
+#include "mac/MacHIDManager.h"
+#include "mac/MacInputManager.h"
+#include "OISEvents.h"
+#include "OISException.h"
+
+#include <cassert>
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------------------------//
+MacJoyStick::MacJoyStick(const std::string &vendor, bool buffered, HidInfo* info, InputManager* creator, int devID) : 
+JoyStick(vendor, buffered, devID, creator), mInfo(info)
+{
+	
+}
+
+//--------------------------------------------------------------------------------------------------//
+MacJoyStick::~MacJoyStick()
+{
+	//TODO: check if the queue has been started first?
+	//(*mQueue)->stop(mQueue); 
+	(*mQueue)->dispose(mQueue); 
+	(*mQueue)->Release(mQueue); 
+	
+	
+	//TODO: check if the interface has been opened first?
+	(*mInfo->interface)->close(mInfo->interface);
+	(*mInfo->interface)->Release(mInfo->interface); 
+}
+
+//--------------------------------------------------------------------------------------------------//
+void MacJoyStick::_initialize()
+{
+	assert(mInfo && "Given HidInfo invalid");
+	assert(mInfo->interface && "Joystick interface invalid");
+	
+	//TODO: Is this necessary?
+	//Clear old state
+	mState.mAxes.clear();
+	
+	if ((*mInfo->interface)->open(mInfo->interface, 0) != KERN_SUCCESS)
+		OIS_EXCEPT(E_General, "MacJoyStick::_initialize() >> Could not initialize joy device!");
+	
+	mState.clear();
+	
+	_enumerateCookies();
+	
+	mState.mButtons.resize(mInfo->numButtons);
+	mState.mAxes.resize(mInfo->numAxes);
+	
+	mQueue = _createQueue();
+}
+
+class FindAxisCookie : public std::unary_function<std::pair<IOHIDElementCookie, AxisInfo>&, bool>
+{
+public:
+	FindAxisCookie(IOHIDElementCookie cookie) : m_Cookie(cookie) {}
+	bool operator()(const std::pair<IOHIDElementCookie, AxisInfo>& pair) const
+	{
+		return pair.first == m_Cookie;
+	}
+private:
+	IOHIDElementCookie m_Cookie;
+};
+
+//--------------------------------------------------------------------------------------------------//
+void MacJoyStick::capture()
+{
+	assert(mQueue && "Queue must be initialized before calling MacJoyStick::capture()");
+	
+	AbsoluteTime zeroTime = {0,0}; 
+	
+	IOHIDEventStruct event; 
+	IOReturn result = (*mQueue)->getNextEvent(mQueue, &event, zeroTime, 0); 
+	while(result == kIOReturnSuccess)
+	{
+		switch(event.type)
+		{
+			case kIOHIDElementTypeInput_Button:
+			{
+				std::vector<IOHIDElementCookie>::iterator buttonIt = std::find(mCookies.buttonCookies.begin(), mCookies.buttonCookies.end(), event.elementCookie);
+				int button = std::distance(mCookies.buttonCookies.begin(), buttonIt);
+				mState.mButtons[button] = (event.value == 1);
+				
+				if(mBuffered && mListener)
+				{
+					if(event.value == 0)
+						mListener->buttonPressed(JoyStickEvent(this, mState), button);
+					else if(event.value == 1)
+						mListener->buttonReleased(JoyStickEvent(this, mState), button);
+				}
+				break;
+			}
+			case kIOHIDElementTypeInput_Misc:
+				//TODO: It's an axis! - kind of - for gamepads - or should this be a pov?
+			case kIOHIDElementTypeInput_Axis:
+				std::map<IOHIDElementCookie, AxisInfo>::iterator axisIt = std::find_if(mCookies.axisCookies.begin(), mCookies.axisCookies.end(), FindAxisCookie(event.elementCookie));
+				int axis = std::distance(mCookies.axisCookies.begin(), axisIt);
+				
+				//Copied from LinuxJoyStickEvents.cpp, line 149
+				const AxisInfo& axisInfo = axisIt->second;
+				float proportion = (float) (event.value - axisInfo.max) / (float) (axisInfo.min - axisInfo.max);
+				mState.mAxes[axis].abs = -JoyStick::MIN_AXIS - (JoyStick::MAX_AXIS * 2 * proportion);
+				
+				if(mBuffered && mListener) mListener->axisMoved(JoyStickEvent(this, mState), axis);
+				break;
+		}
+		
+		result = (*mQueue)->getNextEvent(mQueue, &event, zeroTime, 0);
+	}
+}
+
+//--------------------------------------------------------------------------------------------------//
+void MacJoyStick::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//--------------------------------------------------------------------------------------------------//
+Interface* MacJoyStick::queryInterface(Interface::IType type)
+{
+	//Thought about using covariant return type here.. however,
+	//some devices may allow LED light changing, or other interface stuff
+	
+	//f( ff_device && type == Interface::ForceFeedback )
+	//return ff_device;
+	//else
+	return 0;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void MacJoyStick::_enumerateCookies()
+{
+	assert(mInfo && "Given HidInfo invalid");
+	assert(mInfo->interface && "Joystick interface invalid");
+	
+	CFTypeRef                               object; 
+	long                                    number; 
+	IOHIDElementCookie                      cookie; 
+	long                                    usage; 
+	long                                    usagePage;
+	int										min;
+	int										max;
+
+	CFDictionaryRef                         element; 
+	
+	// Copy all elements, since we're grabbing most of the elements 
+	// for this device anyway, and thus, it's faster to iterate them 
+	// ourselves. When grabbing only one or two elements, a matching 
+	// dictionary should be passed in here instead of NULL. 
+	CFArrayRef elements; 
+	IOReturn success = reinterpret_cast<IOHIDDeviceInterface122*>(*mInfo->interface)->copyMatchingElements(mInfo->interface, NULL, &elements); 
+	
+	if (success == kIOReturnSuccess)
+	{ 
+		const CFIndex numOfElements = CFArrayGetCount(elements);
+		for (CFIndex i = 0; i < numOfElements; ++i) 
+		{ 
+			element = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(elements, i));
+			
+			//Get cookie 
+			object = (CFDictionaryGetValue(element, 
+										   CFSTR(kIOHIDElementCookieKey))); 
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) 
+				continue; 
+			if(!CFNumberGetValue((CFNumberRef) object, kCFNumberLongType, 
+								 &number)) 
+				continue; 
+			cookie = (IOHIDElementCookie) number; 
+			
+			//Get usage 
+			object = CFDictionaryGetValue(element, 
+										  CFSTR(kIOHIDElementUsageKey)); 
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) 
+				continue; 
+			if (!CFNumberGetValue((CFNumberRef) object, kCFNumberLongType, 
+								  &number)) 
+				continue; 
+			usage = number; 
+			
+			//Get min
+			object = CFDictionaryGetValue(element,
+										  CFSTR(kIOHIDElementMinKey)); // kIOHIDElementMinKey or kIOHIDElementScaledMinKey?, no idea ...
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID())
+				continue;
+			if (!CFNumberGetValue((CFNumberRef) object, kCFNumberIntType,
+								  &number))
+				continue;
+			min = number;
+			
+			//Get max
+			object = CFDictionaryGetValue(element,
+										  CFSTR(kIOHIDElementMaxKey)); // kIOHIDElementMaxKey or kIOHIDElementScaledMaxKey?, no idea ...
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID())
+				continue;
+			if (!CFNumberGetValue((CFNumberRef) object, kCFNumberIntType,
+								  &number))
+				continue;
+			max = number;			
+			
+			//Get usage page 
+			object = CFDictionaryGetValue(element, 
+										  CFSTR(kIOHIDElementUsagePageKey)); 
+			
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) 
+				continue; 
+			
+			if (!CFNumberGetValue((CFNumberRef) object, kCFNumberLongType, 
+								  &number)) 
+				continue; 
+			
+			usagePage = number;
+			switch(usagePage)
+			{
+				case kHIDPage_GenericDesktop:
+					switch(usage)
+				{
+					case kHIDUsage_GD_Pointer:
+						break;
+					case kHIDUsage_GD_X:
+					case kHIDUsage_GD_Y:
+					case kHIDUsage_GD_Z:
+					case kHIDUsage_GD_Rx:
+					case kHIDUsage_GD_Ry:
+					case kHIDUsage_GD_Rz:
+						mCookies.axisCookies.insert(std::make_pair(cookie, AxisInfo(min, max)));
+						break;
+					case kHIDUsage_GD_Slider:
+					case kHIDUsage_GD_Dial:
+					case kHIDUsage_GD_Wheel:
+						break;
+					case kHIDUsage_GD_Hatswitch:
+						break;
+				}
+					break;
+				case kHIDPage_Button:
+					mCookies.buttonCookies.push_back(cookie);
+					break;
+			}		
+		}
+		
+		mInfo->numButtons = mCookies.buttonCookies.size();
+		mInfo->numAxes = mCookies.axisCookies.size();
+
+	} 
+	else 
+	{ 
+		OIS_EXCEPT(E_General, "JoyStick elements could not be copied: copyMatchingElements failed with error: " + success); 
+	}
+	
+}
+
+//--------------------------------------------------------------------------------------------------//
+IOHIDQueueInterface** MacJoyStick::_createQueue(unsigned int depth)
+{	
+	assert(mInfo && "Given HidInfo invalid");
+	assert(mInfo->interface && "Joystick interface invalid");
+	
+	IOHIDQueueInterface** queue = (*mInfo->interface)->allocQueue(mInfo->interface); 
+	
+	if (queue) 
+	{		
+		//create the queue 
+		IOReturn result = (*queue)->create(queue, 0, depth); 
+		
+		if(result == kIOReturnSuccess)
+		{		
+			//add elements to the queue
+			std::map<IOHIDElementCookie, AxisInfo>::iterator axisIt = mCookies.axisCookies.begin();
+			for(; axisIt != mCookies.axisCookies.end(); ++axisIt)
+			{
+				result = (*queue)->addElement(queue, axisIt->first, 0);
+			}
+			
+			std::vector<IOHIDElementCookie>::iterator buttonIt = mCookies.buttonCookies.begin();
+			for(; buttonIt != mCookies.buttonCookies.end(); ++buttonIt)
+			{
+				result = (*queue)->addElement(queue, (*buttonIt), 0);
+			}
+
+			//start data delivery to queue 
+			result = (*queue)->start(queue); 
+			if(result == kIOReturnSuccess)
+			{
+				return queue;
+			}
+			else
+			{
+				OIS_EXCEPT(E_General, "Queue could not be started.");
+			}
+		}
+		else
+		{
+			OIS_EXCEPT(E_General, "Queue could not be created.");
+		}
+	}
+	else
+	{
+		OIS_EXCEPT(E_General, "Queue allocation failed.");
+	}
+}

+ 467 - 0
CamelotOISInput/Source/OIS/mac/MacKeyboard.cpp

@@ -0,0 +1,467 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ This software is provided 'as-is', without any express or implied warranty. In no event will
+ the authors be held liable for any damages arising from the use of this software.
+ 
+ Permission is granted to anyone to use this software for any purpose, including commercial 
+ applications, and to alter it and redistribute it freely, subject to the following
+ restrictions:
+ 
+ 1. The origin of this software must not be misrepresented; you must not claim that 
+ you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+ 
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+ 
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "mac/MacKeyboard.h"
+#include "mac/MacInputManager.h"
+#include "mac/MacHelpers.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+#include <Carbon/Carbon.h>
+
+#include <list>
+#include <string>
+
+const EventTypeSpec DownSpec[] = {{kEventClassKeyboard, kEventRawKeyDown},	//non - repeats
+							{kEventClassKeyboard, kEventRawKeyRepeat}}; //repeats
+const EventTypeSpec UpSpec = {kEventClassKeyboard, kEventRawKeyUp},
+			  ModSpec = {kEventClassKeyboard, kEventRawKeyModifiersChanged};
+
+const EventTypeSpec AllSpecs[] = {{kEventClassKeyboard, kEventRawKeyDown},
+						  {kEventClassKeyboard, kEventRawKeyRepeat},
+						  {kEventClassKeyboard, kEventRawKeyUp},
+						  {kEventClassKeyboard, kEventRawKeyModifiersChanged}};
+
+using namespace OIS;
+
+//-------------------------------------------------------------------//
+MacKeyboard::MacKeyboard( InputManager* creator, bool buffered, bool repeat )
+	: Keyboard(creator->inputSystemName(), buffered, 0, creator)
+{
+	keyDownEventRef = NULL;
+	keyUpEventRef = NULL;
+	keyModEventRef = NULL;
+	
+	useRepeat = repeat;
+
+	// Get a so-called "Univeral procedure pointer" for our callback
+	keyDownUPP = NewEventHandlerUPP( KeyDownWrapper );
+	keyUpUPP   = NewEventHandlerUPP( KeyUpWrapper );
+	keyModUPP  = NewEventHandlerUPP( KeyModWrapper );
+	
+	// populate the conversion map
+	populateKeyConversion();
+
+	static_cast<MacInputManager*>(mCreator)->_setKeyboardUsed(true);
+}
+
+//-------------------------------------------------------------------//
+MacKeyboard::~MacKeyboard()
+{
+	// Remove our handlers so that this instance doesn't get called
+	// after it is deleted
+	if (keyDownEventRef != NULL)
+		RemoveEventHandler(keyDownEventRef);
+		
+	if (keyUpEventRef != NULL)
+		RemoveEventHandler(keyUpEventRef);
+	
+	if (keyModEventRef != NULL)
+		RemoveEventHandler(keyModEventRef);
+	
+	// dispose of our UPPs
+	DisposeEventHandlerUPP(keyDownUPP);
+	DisposeEventHandlerUPP(keyUpUPP);
+	DisposeEventHandlerUPP(keyModUPP);
+
+	//Free the input managers keyboard
+	static_cast<MacInputManager*>(mCreator)->_setKeyboardUsed(false);
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::_initialize()
+{
+	EventTargetRef event = ((MacInputManager*)mCreator)->_getEventTarget();
+
+	memset( &KeyBuffer, 0, 256 );
+	mModifiers = 0;
+	prevModMask = 0;
+	
+	// just in case this gets called after the first time.. better safe
+	if (keyDownEventRef != NULL)
+		RemoveEventHandler(keyDownEventRef);
+		
+	if (keyUpEventRef != NULL)
+		RemoveEventHandler(keyUpEventRef);
+		
+	if (keyModEventRef != NULL)
+		RemoveEventHandler(keyModEventRef);
+   
+	keyDownEventRef = NULL;
+	keyUpEventRef = NULL;
+	keyModEventRef = NULL;
+
+	OSStatus status;
+	// send both elements of downspec array... second index is for repeat events
+	if ( useRepeat )
+		status = InstallEventHandler( event, keyDownUPP, 2, DownSpec, this, &keyDownEventRef );
+	else
+		status = InstallEventHandler( event, keyDownUPP, 1, DownSpec, this, &keyDownEventRef );
+		
+	if (status != noErr)
+		OIS_EXCEPT( E_General, "MacKeyboard::_initialize >> Error loading KeyDown event handler" );
+
+	if (InstallEventHandler( event, keyUpUPP, 1, &UpSpec, this, &keyUpEventRef ) != noErr)
+		OIS_EXCEPT( E_General, "MacKeyboard::_initialize >> Error loading KeyUp event handler" );
+
+	if (InstallEventHandler( event, keyModUPP, 1, &ModSpec, this, &keyModEventRef ) != noErr )
+		OIS_EXCEPT( E_General, "MacKeyboard::_initialize >> Error loading Keymods event handler" );
+}
+
+//-------------------------------------------------------------------//
+bool MacKeyboard::isKeyDown( KeyCode key ) const
+{
+	return (bool)KeyBuffer[key];
+}
+
+
+//-------------------------------------------------------------------//
+void MacKeyboard::capture()
+{
+	// if not buffered just return, we update the unbuffered automatically
+	if ( !mBuffered || !mListener )
+		return;
+	
+	//If the mListener returns false, that means that we are probably deleted...
+	//send no more events and just leave as the this pointer is invalid now...
+	bool ret = true;
+	
+	// run through our event stack
+	eventStack::iterator cur_it;
+	
+	for (cur_it = pendingEvents.begin(); cur_it != pendingEvents.end(); cur_it++)
+	{
+		
+		if ( (*cur_it).Type == MAC_KEYDOWN || (*cur_it).Type == MAC_KEYREPEAT)
+			mListener->keyPressed( (*cur_it).Event );
+		else if ( (*cur_it).Type == MAC_KEYUP )
+			mListener->keyReleased( (*cur_it).Event );
+	}
+	
+	pendingEvents.clear();
+}
+
+
+//-------------------------------------------------------------------//
+std::string& MacKeyboard::getAsString( KeyCode key )
+{
+	getString = "";
+	
+	return getString;
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::setBuffered( bool buffered )
+{
+	mBuffered = buffered;
+}
+
+#include <iostream>
+//-------------------------------------------------------------------//
+void MacKeyboard::_keyDownCallback( EventRef theEvent )
+{
+	
+	UInt32 virtualKey;
+	OSStatus status;
+	
+	unsigned int time = (unsigned int)GetEventTime(theEvent);
+	
+	status = GetEventParameter(theEvent,
+					'kcod',			// get it in virtual keycode
+					typeUInt32, NULL,	// desired return type
+					sizeof(UInt32), NULL, 	// bufsize
+					&virtualKey );
+	
+	KeyCode kc = keyConversion[virtualKey];
+
+	// record what kind of text we should pass the KeyEvent
+	UniChar text[10];
+	char macChar;
+	
+	// TODO clean this up
+	if (mTextMode == Unicode)
+	{
+		//get string size
+		UInt32 stringsize;
+		//status = GetEventParameter( theEvent, 'kuni', typeUnicodeText, NULL, 0, &stringsize, NULL);
+		//status = GetEventParameter( theEvent, 'kuni', typeUnicodeText, NULL, sizeof(UniChar)*10, NULL, &text );
+		status = GetEventParameter( theEvent, 'kuni', typeUnicodeText, NULL, sizeof(UniChar) * 10, &stringsize, &text );
+		std::cout << "String length: " << stringsize << std::endl;
+		
+		//wstring unitext;
+		//for (int i=0;i<10;i++) unitext += (wchar_t)text[i];
+		//wcout << "Unicode out: " << unitext << endl;
+		
+		if(stringsize > 0)
+		{
+			// for each unicode char, send an event
+			stringsize--; // no termination char
+			for ( int i = 0; i < stringsize; i++ )
+			{
+				injectEvent( kc, time, MAC_KEYDOWN, (unsigned int)text[i] );
+			}
+		}
+	} 
+	else if (mTextMode == Ascii)
+	{
+		 
+		status = GetEventParameter( theEvent, 'kchr', typeChar, NULL, sizeof(char), NULL, &macChar );
+		injectEvent( kc, time, MAC_KEYDOWN, (unsigned int)macChar );
+	}
+	else
+	{
+		injectEvent( kc, time, MAC_KEYDOWN );
+	}
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::_keyUpCallback( EventRef theEvent )
+{
+	UInt32 virtualKey;
+	
+	OSStatus status;
+	status = GetEventParameter( theEvent, kEventParamKeyCode, typeUInt32,
+								NULL, sizeof(UInt32), NULL, &virtualKey );
+	
+	KeyCode kc = keyConversion[virtualKey];
+	injectEvent( kc, (int)GetEventTime(theEvent), MAC_KEYUP );
+	
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::_modChangeCallback( EventRef theEvent )
+{
+	UInt32 mods;
+	
+	OSStatus status;
+	status = GetEventParameter( theEvent, kEventParamKeyModifiers,
+								typeUInt32, NULL, sizeof(UInt32), NULL, &mods );
+	
+	// find the changed bit
+	UInt32 change = prevModMask ^ mods;
+	MacEventType newstate = ((change & prevModMask) > 0) ? MAC_KEYUP : MAC_KEYDOWN;
+	unsigned int time = (int)GetEventTime( theEvent );
+	
+	//cout << "preMask: " << hex << prevModMask << endl;
+	//cout << "ModMask: " << hex << mods << endl;
+	//cout << "Change:  " << hex << (change & prevModMask) << endl << endl;
+	
+	// TODO test modifiers on a full keyboard to check if different mask for left/right
+	switch (change)
+	{
+		case (shiftKey): // shift
+			mModifiers &= (newstate == MAC_KEYDOWN) ? Shift : ~Shift;
+			injectEvent( KC_LSHIFT, time, newstate );
+			//injectEvent( KC_RSHIFT, time, newstate );
+			break;
+			
+		case (optionKey): // option (alt)
+			mModifiers &= (newstate == MAC_KEYDOWN) ? Alt : -Alt;
+			//injectEvent( KC_RMENU, time, newstate );
+			injectEvent( KC_LMENU, time, newstate );
+			break;
+			
+		case (controlKey): // Ctrl
+			mModifiers += (newstate == MAC_KEYDOWN) ? Ctrl : -Ctrl;
+			//injectEvent( KC_RCONTROL, time, newstate );
+			injectEvent( KC_LCONTROL, time, newstate );
+			break;
+	
+		case (cmdKey): // apple
+			//injectEvent( KC_RWIN, time, newstate );
+			injectEvent( KC_LWIN, time, newstate );
+			break;
+	
+		case (kEventKeyModifierFnMask): // fn key
+			injectEvent( KC_APPS, time, newstate );
+			break;
+			
+		case (kEventKeyModifierNumLockMask): // numlock
+			injectEvent( KC_NUMLOCK, time, newstate );
+			break;
+			
+		case (alphaLock): // caps lock
+			injectEvent( KC_CAPITAL, time, newstate );
+			break;
+	}
+	
+	prevModMask = mods;
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::injectEvent( KeyCode kc, unsigned int time, MacEventType type, unsigned int txt )
+{
+	// set to 1 if this is either a keydown or repeat
+	KeyBuffer[kc] = ( type == MAC_KEYUP ) ? 0 : 1;
+	
+	if ( mBuffered && mListener )
+		pendingEvents.push_back( MacKeyStackEvent( KeyEvent(this, kc, txt), type) );
+}
+
+
+//-------------------------------------------------------------------//
+void MacKeyboard::copyKeyStates( char keys[256] ) const
+{
+	memcpy( keys, KeyBuffer, 256 );
+}
+
+
+
+//-------------------------------------------------------------------//
+void MacKeyboard::populateKeyConversion()
+{
+	// TODO finish the key mapping
+	
+	// Virtual Key Map to KeyCode
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x12, KC_1));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x13, KC_2));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x14, KC_3));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x15, KC_4));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x17, KC_5));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x16, KC_6));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1A, KC_7));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1C, KC_8));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x19, KC_9));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1D, KC_0));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x33, KC_BACK));  // might be wrong
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1B, KC_MINUS));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x18, KC_EQUALS));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x31, KC_SPACE));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2B, KC_COMMA));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2F, KC_PERIOD));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2A, KC_BACKSLASH));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2C, KC_SLASH));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x21, KC_LBRACKET));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1E, KC_RBRACKET));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x35, KC_ESCAPE));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x39, KC_CAPITAL));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x30, KC_TAB));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x24, KC_RETURN));  // double check return/enter
+	
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_colon, KC_COLON));	 // no colon?
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x29, KC_SEMICOLON));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x27, KC_APOSTROPHE));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x32, KC_GRAVE));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0B, KC_B));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x00, KC_A));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x08, KC_C));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x02, KC_D));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0E, KC_E));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x03, KC_F));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x05, KC_G));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x04, KC_H));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x22, KC_I));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x26, KC_J));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x28, KC_K));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x25, KC_L));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2E, KC_M));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2D, KC_N));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1F, KC_O));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x23, KC_P));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0C, KC_Q));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0F, KC_R));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x01, KC_S));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x11, KC_T));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x20, KC_U));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x09, KC_V));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0D, KC_W));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x07, KC_X));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x10, KC_Y));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x06, KC_Z));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7A, KC_F1));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x78, KC_F2));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x63, KC_F3));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x76, KC_F4));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x60, KC_F5));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x61, KC_F6));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x62, KC_F7));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x64, KC_F8));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x65, KC_F9));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x6D, KC_F10));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x67, KC_F11));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x6F, KC_F12));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x69, KC_F13));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x6B, KC_F14));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x71, KC_F15));
+	
+	//Keypad
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x52, KC_NUMPAD0));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x53, KC_NUMPAD1));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x54, KC_NUMPAD2));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x55, KC_NUMPAD3));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x56, KC_NUMPAD4));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x57, KC_NUMPAD5));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x58, KC_NUMPAD6));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x59, KC_NUMPAD7));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x5B, KC_NUMPAD8));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x5C, KC_NUMPAD9));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x45, KC_ADD));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x4E, KC_SUBTRACT));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x41, KC_DECIMAL));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x51, KC_NUMPADEQUALS));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x4B, KC_DIVIDE));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x43, KC_MULTIPLY));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x4C, KC_NUMPADENTER));
+	
+	//Keypad with numlock off
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x73, KC_NUMPAD7));  // not sure of these
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Up, KC_NUMPAD8)); // check on a non-laptop
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Page_Up, KC_NUMPAD9));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Left, KC_NUMPAD4));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Begin, KC_NUMPAD5));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Right, KC_NUMPAD6));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_End, KC_NUMPAD1));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Down, KC_NUMPAD2));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Page_Down, KC_NUMPAD3));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Insert, KC_NUMPAD0));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Delete, KC_DECIMAL));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7E, KC_UP));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7D, KC_DOWN));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7B, KC_LEFT));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7C, KC_RIGHT));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x74, KC_PGUP));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x79, KC_PGDOWN));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x73, KC_HOME));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x77, KC_END));
+	
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_Print, KC_SYSRQ));		// ??
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_Scroll_Lock, KC_SCROLL)); // ??
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_Pause, KC_PAUSE));		// ??
+	
+	
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_Insert, KC_INSERT));	  // ??
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x75, KC_DELETE)); // del under help key?
+}
+
+
+
+

+ 346 - 0
CamelotOISInput/Source/OIS/mac/MacMouse.cpp

@@ -0,0 +1,346 @@
+#include "mac/MacMouse.h"
+#include "mac/MacInputManager.h"
+#include "mac/MacHelpers.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+#include <Carbon/Carbon.h>
+
+#include <list>
+
+#include <iostream>
+
+using namespace OIS;
+
+//Events we subscribe to and remove from queue
+const EventTypeSpec mouseEvents[] = {
+	{ kEventClassMouse, kEventMouseDown },
+	{ kEventClassMouse, kEventMouseUp },
+	{ kEventClassMouse, kEventMouseMoved },
+	{ kEventClassMouse, kEventMouseDragged },
+	{ kEventClassMouse, kEventMouseWheelMoved }		
+};
+
+const EventTypeSpec WinFocusAcquired [] = {{kEventClassApplication, kEventAppDeactivated}};
+
+//-------------------------------------------------------------------//
+MacMouse::MacMouse( InputManager* creator, bool buffered )
+	: Mouse(creator->inputSystemName(), buffered, 0, creator), mNeedsToRegainFocus( false )
+{
+    mouseEventRef = NULL;
+	mWindowFocusHandler = NULL;
+
+    // Get a "Univeral procedure pointer" for our callback
+    mouseUPP = NewEventHandlerUPP(MouseWrapper);
+	mWindowFocusListener = NewEventHandlerUPP(WindowFocusChanged);
+
+	static_cast<MacInputManager*>(mCreator)->_setMouseUsed(true);
+}
+
+MacMouse::~MacMouse()
+{
+    if(mouseEventRef != NULL)
+		RemoveEventHandler(mouseEventRef);
+
+	if(mWindowFocusHandler != NULL)
+		RemoveEventHandler(mWindowFocusHandler);
+	
+	DisposeEventHandlerUPP(mouseUPP);
+	DisposeEventHandlerUPP(mWindowFocusListener);
+	
+	// Restore Mouse
+	CGAssociateMouseAndMouseCursorPosition(TRUE);
+	CGDisplayShowCursor(kCGDirectMainDisplay);
+
+	static_cast<MacInputManager*>(mCreator)->_setMouseUsed(false);
+}
+
+void MacMouse::_initialize()
+{
+	mState.clear();
+	mTempState.clear();
+	mMouseWarped = false;
+	
+	// Hide OS Mouse
+ 	CGDisplayHideCursor(kCGDirectMainDisplay);
+
+	MacInputManager* im = static_cast<MacInputManager*>(mCreator);
+	WindowRef win = im->_getWindow();
+	
+	if(win)
+	{
+		Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
+		GetWindowBounds(win, kWindowContentRgn, &clipRect);
+		
+		CGPoint warpPoint;
+		warpPoint.x = ((clipRect.right - clipRect.left) / 2) + clipRect.left;
+		warpPoint.y = ((clipRect.bottom - clipRect.top) / 2) + clipRect.top;
+		CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, warpPoint); //Place at display origin
+		
+		mMouseWarped = true;
+	}
+
+	//Now that mouse is warped, start listening for events
+	EventTargetRef event = ((MacInputManager*)mCreator)->_getEventTarget();
+    
+	if(mouseEventRef != NULL)
+		RemoveEventHandler(mouseEventRef);
+		
+	if(mWindowFocusHandler != NULL)
+		RemoveEventHandler(mWindowFocusHandler);
+
+	mouseEventRef = mWindowFocusHandler = NULL;
+
+	if(InstallEventHandler(event, mouseUPP, GetEventTypeCount(mouseEvents), mouseEvents, this, &mouseEventRef) != noErr)
+		OIS_EXCEPT( E_General, "MacMouse::_initialize >> Error loading Mouse event handler" );
+
+	if(InstallEventHandler(event, mWindowFocusListener, GetEventTypeCount(WinFocusAcquired), WinFocusAcquired, this, &mWindowFocusHandler) != noErr)
+		OIS_EXCEPT( E_General, "MacMouse::_initialize >> Error loading Mouse event handler" );		
+
+	//Lock OS Mouse movement
+	mNeedsToRegainFocus = false;
+	CGAssociateMouseAndMouseCursorPosition(FALSE);
+}
+
+OSStatus MacMouse::WindowFocusChanged(EventHandlerCallRef nextHandler, EventRef event, void* macMouse)
+{
+	//std::cout << "Window Focus Changed\n";
+
+	MacMouse* _this = static_cast<MacMouse*>(macMouse);
+    if (_this)
+	{
+		_this->mNeedsToRegainFocus = true;
+		CGAssociateMouseAndMouseCursorPosition(TRUE);
+
+        // propagate the event down the chain
+        return CallNextEventHandler(nextHandler, event);
+    }
+    else
+        OIS_EXCEPT(E_General, "MouseWrapper >> Being called by something other than our event handler!");
+}
+
+void MacMouse::setBuffered( bool buffered )
+{
+	mBuffered = buffered;
+}
+
+void MacMouse::capture()
+{
+	mState.X.rel = 0;
+	mState.Y.rel = 0;
+	mState.Z.rel = 0;
+	    
+	if(mTempState.X.rel || mTempState.Y.rel || mTempState.Z.rel)
+	{
+		//printf("%i %i %i\n\n", mTempState.X.rel, mTempState.Y.rel, mTempState.Z.rel);
+
+		//Set new relative motion values
+		mState.X.rel = mTempState.X.rel;
+		mState.Y.rel = mTempState.Y.rel;
+		mState.Z.rel = mTempState.Z.rel;
+		
+		//Update absolute position
+		mState.X.abs += mTempState.X.rel;
+		mState.Y.abs += mTempState.Y.rel;
+		
+		if(mState.X.abs > mState.width)
+			mState.X.abs = mState.width;
+		else if(mState.X.abs < 0)
+			mState.X.abs = 0;
+
+		if(mState.Y.abs > mState.height)
+			mState.Y.abs = mState.height;
+		else if(mState.Y.abs < 0)
+			mState.Y.abs = 0;
+			
+		mState.Z.abs += mTempState.Z.rel;
+		
+		//Fire off event
+		if(mListener && mBuffered)
+			mListener->mouseMoved(MouseEvent(this, mState));
+	}
+
+	mTempState.clear();
+}
+
+void MacMouse::_mouseCallback( EventRef theEvent )
+{
+	OSStatus result = eventNotHandledErr;
+    UInt32 kind = GetEventKind (theEvent);
+
+	switch(kind)
+	{
+		case kEventMouseDragged:
+		case kEventMouseMoved:
+		{
+			//HIPoint location = {0.0f, 0.0f};
+			HIPoint delta = {0.0f, 0.0f};
+			//Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
+			
+			if(mNeedsToRegainFocus)
+				break;
+
+			// Capture the parameters
+			// TODO: Look into HIViewNewTrackingArea
+			//GetEventParameter(theEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &location);
+			GetEventParameter(theEvent, kEventParamMouseDelta, typeHIPoint, NULL, sizeof(HIPoint), NULL, &delta);
+			
+			// Mouse X and Y are the position on the screen, 
+			// startng from top-left at 0,0 caps at full monitor resolution
+			
+			// If we have a window we need to return adjusted coordinates
+			// If not, just use raw coordinates - only do this if showing OS mouse
+			//MacInputManager* im = static_cast<MacInputManager*>(mCreator);
+			//WindowRef win = im->_getWindow();
+			
+			//if(win != NULL)
+			//{
+			//	GetWindowBounds(win, kWindowContentRgn, &clipRect);
+			//}
+            //else
+            //{
+            //    clipRect.right = mState.width;
+            //    clipRect.bottom = mState.height;
+            //}
+                
+            // clip the mouse, absolute positioning
+            //if (location.x <= clipRect.left)
+			//	mState.X.abs = 0;
+			//else if(location.x >= clipRect.right)
+			//	mState.X.abs = clipRect.right - clipRect.left;
+			//else
+			//	mState.X.abs = location.x - clipRect.left;
+			
+			//if (location.y <= clipRect.top)
+			//	mState.Y.abs = 0;
+			//else if(location.y >= clipRect.bottom)
+			//	mState.Y.abs = clipRect.bottom - clipRect.top;
+			//else
+			//	mState.Y.abs = location.y - clipRect.top;
+			
+			// relative positioning
+			if(!mMouseWarped)
+			{
+				mTempState.X.rel += delta.x;
+				mTempState.Y.rel += delta.y;
+			}
+			
+			mMouseWarped = false;
+
+			break;
+		}
+		case kEventMouseDown:
+		{
+			EventMouseButton button = 0;
+			int mouseButton = 3;
+			UInt32 modifiers = 0;
+			
+			if(mNeedsToRegainFocus)
+				break;
+
+			// Capture parameters
+			GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &button);
+			GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+			
+			if((button == kEventMouseButtonTertiary) || ((button == kEventMouseButtonPrimary) && (modifiers & optionKey)))
+			{
+				mouseButton = 2;
+				mState.buttons |= 1 << mouseButton;
+			}
+            else if((button == kEventMouseButtonSecondary) || ((button == kEventMouseButtonPrimary) && (modifiers & controlKey)))
+            {	
+                mouseButton = 1;
+                mState.buttons |= 1 << mouseButton;
+            }
+            else if(button == kEventMouseButtonPrimary)
+            {
+                mouseButton = 0;
+                mState.buttons |= 1 << mouseButton;
+            }
+
+            if( mListener && mBuffered )
+                mListener->mousePressed( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
+
+            break;
+		}
+		case kEventMouseUp:
+		{
+			EventMouseButton button = 0;
+			int mouseButton = 3;
+			UInt32 modifiers = 0;
+			
+			if(mNeedsToRegainFocus)
+			{
+				mNeedsToRegainFocus = false;
+				CGAssociateMouseAndMouseCursorPosition(false);
+				
+				MacInputManager* im = static_cast<MacInputManager*>(mCreator);
+				WindowRef win = im->_getWindow();
+				
+				if(win)
+				{
+					Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
+					GetWindowBounds(win, kWindowContentRgn, &clipRect);
+					
+					CGPoint warpPoint;
+					warpPoint.x = ((clipRect.right - clipRect.left) / 2) + clipRect.left;
+					warpPoint.y = ((clipRect.bottom - clipRect.top) / 2) + clipRect.top;
+					CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, warpPoint); //Place at display origin
+					
+					CGDisplayHideCursor(kCGDirectMainDisplay);
+					
+					mMouseWarped = true;
+				}
+				
+				//Once we regain focus, we do not really know what state all the buttons are in - for now, set to not pressed. todo, check current status
+				//compare against old status, and send off any needed events
+				mState.buttons = 0;
+				
+				break;
+			}
+			
+			// Capture parameters
+			GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &button);
+			GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+			
+			if ((button == kEventMouseButtonTertiary) || ((button == kEventMouseButtonPrimary) && (modifiers & optionKey)))
+			{
+				mouseButton = 2;
+				mState.buttons &= ~(1 << mouseButton);
+			}
+            else if ((button == kEventMouseButtonSecondary) || ((button == kEventMouseButtonPrimary) && (modifiers & controlKey)))
+            {	
+                mouseButton = 1;
+                mState.buttons &= ~(1 << mouseButton);
+            }
+            else if (button == kEventMouseButtonPrimary)
+            {
+                mouseButton = 0;
+                mState.buttons &= ~(1 << mouseButton);
+            }
+
+            if( mListener && mBuffered )
+                mListener->mouseReleased( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
+
+            break;
+		}
+		case kEventMouseWheelMoved:
+		{
+			SInt32 wheelDelta = 0;
+			EventMouseWheelAxis	wheelAxis = 0; 
+
+			// Capture parameters
+			GetEventParameter(theEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &wheelAxis);
+			GetEventParameter(theEvent, kEventParamMouseWheelDelta, typeSInt32, NULL, sizeof(SInt32), NULL, &wheelDelta);
+			
+			// If the Y axis of the wheel changed, then update the Z
+			// Does OIS care about the X wheel axis?
+			if(wheelAxis == kEventMouseWheelAxisY)
+				mTempState.Z.rel += (wheelDelta * 60);
+
+            break;
+		}
+		default:
+			break;
+	}    
+}

+ 543 - 0
CamelotOISInput/Source/OIS/win32/Win32ForceFeedback.cpp

@@ -0,0 +1,543 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/win32/Win32ForceFeedback.h"
+#include "OIS/OISException.h"
+#include <math.h>
+
+// 0 = No trace; 1 = Important traces; 2 = Debug traces
+#define OIS_WIN32_JOYFF_DEBUG 1
+
+#if (defined (_DEBUG) || defined(OIS_WIN32_JOYFF_DEBUG))
+  #include <iostream>
+  #include <sstream>
+  using namespace std;
+#endif
+
+using namespace OIS;
+
+//--------------------------------------------------------------//
+Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps) :
+  mHandles(0), mJoyStick(pDIJoy), mFFAxes(0), mpDIJoyCaps(pDIJoyCaps)
+{
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+  cout << "FFSamplePeriod      : " << mpDIJoyCaps->dwFFSamplePeriod << " mu-s, "
+	   << "FFMinTimeResolution : " << mpDIJoyCaps->dwFFMinTimeResolution << " mu-s,"
+	   << "" << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+Win32ForceFeedback::~Win32ForceFeedback()
+{
+	//Get the effect - if it exists
+	for(EffectList::iterator i = mEffectList.begin(); i != mEffectList.end(); ++i )
+	{
+		LPDIRECTINPUTEFFECT dxEffect = i->second;
+		if( dxEffect )
+		{
+			dxEffect->Unload();
+			dxEffect->Release();
+		}
+	}
+
+	mEffectList.clear();
+}
+
+//--------------------------------------------------------------//
+short Win32ForceFeedback::getFFAxesNumber()
+{
+	return mFFAxes;
+}
+
+//--------------------------------------------------------------//
+unsigned short Win32ForceFeedback::getFFMemoryLoad()
+{
+    DIPROPDWORD dipdw;  // DIPROPDWORD contains a DIPROPHEADER structure. 
+	dipdw.diph.dwSize       = sizeof(DIPROPDWORD); 
+	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
+	dipdw.diph.dwObj        = 0; // device property 
+	dipdw.diph.dwHow        = DIPH_DEVICE;
+	dipdw.dwData            = 0; // In case of any error.
+
+	const HRESULT hr = mJoyStick->GetProperty(DIPROP_FFLOAD, &dipdw.diph);
+	if(FAILED(hr))
+	{
+	    if (hr == DIERR_NOTEXCLUSIVEACQUIRED)
+		    OIS_EXCEPT(E_General, "Can't query FF memory load as device was not acquired in exclusive mode");
+		else
+		    OIS_EXCEPT(E_General, "Unknown error querying FF memory load ->..");
+	}
+
+	return (unsigned short)dipdw.dwData;
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::upload( const Effect* effect )
+{
+	switch( effect->force )
+	{
+		case OIS::Effect::ConstantForce: _updateConstantEffect(effect);	break;
+		case OIS::Effect::RampForce: _updateRampEffect(effect);	break;
+		case OIS::Effect::PeriodicForce: _updatePeriodicEffect(effect);	break;
+		case OIS::Effect::ConditionalForce:	_updateConditionalEffect(effect); break;
+		//case OIS::Effect::CustomForce: _updateCustomEffect(effect); break;
+		default: OIS_EXCEPT(E_NotImplemented, "Requested Force not Implemented yet, sorry!"); break;
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::modify( const Effect* eff )
+{
+	//Modifying is essentially the same as an upload, so, just reuse that function
+	upload(eff);
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::remove( const Effect* eff )
+{
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(eff->_handle);
+	if( i != mEffectList.end() )
+	{
+		LPDIRECTINPUTEFFECT dxEffect = i->second;
+		if( dxEffect )
+		{
+			dxEffect->Stop();
+			//We care about the return value - as the effect might not
+			//have been unlaoded
+			if( SUCCEEDED(dxEffect->Unload()) )
+			{
+			    dxEffect->Release();
+				mEffectList.erase(i);
+			}
+		}
+		else
+			mEffectList.erase(i);
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::setMasterGain( float level )
+{
+	//Between 0 - 10,000
+	int gain_level = (int)(10000.0f * level);
+
+	if( gain_level > 10000 )
+		gain_level = 10000;
+	else if( gain_level < 0 )
+		gain_level = 0;
+
+	DIPROPDWORD DIPropGain;
+	DIPropGain.diph.dwSize       = sizeof(DIPropGain);
+	DIPropGain.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	DIPropGain.diph.dwObj        = 0;
+	DIPropGain.diph.dwHow        = DIPH_DEVICE;
+	DIPropGain.dwData            = gain_level;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+	cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting master gain to " 
+		 << level << " => " << DIPropGain.dwData << endl;
+#endif
+
+	const HRESULT hr = mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph);
+
+#if defined (_DEBUG)
+	if(FAILED(hr))
+	    cout << "Failed to change master gain" << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::setAutoCenterMode( bool auto_on )
+{
+	DIPROPDWORD DIPropAutoCenter;
+	DIPropAutoCenter.diph.dwSize       = sizeof(DIPropAutoCenter);
+	DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	DIPropAutoCenter.diph.dwObj        = 0;
+	DIPropAutoCenter.diph.dwHow        = DIPH_DEVICE;
+	DIPropAutoCenter.dwData            = (auto_on ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF);
+
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+	cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting auto-center mode to " 
+		 << auto_on << " => " << DIPropAutoCenter.dwData << endl;
+#endif
+
+	const HRESULT hr = mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
+
+#if defined (_DEBUG)
+	if(FAILED(hr))
+	    cout << "Failed to change auto-center mode" << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updateConstantEffect( const Effect* effect )
+{
+	ConstantEffect *eff = static_cast<ConstantEffect*>(effect->getForceEffect());
+
+	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
+	DICONSTANTFORCE cf;
+	DIEFFECT        diEffect;
+
+	//Currently only support 1 axis
+	//if( effect->getNumAxes() == 1 )
+	cf.lMagnitude = eff->level;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Level : " << eff->level
+		 << " => " << cf.lMagnitude << endl;
+#endif
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONSTANTFORCE), &cf, effect, &eff->envelope);
+	_upload(GUID_ConstantForce, &diEffect, effect);
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updateRampEffect( const Effect* effect )
+{
+	RampEffect *eff = static_cast<RampEffect*>(effect->getForceEffect());
+
+	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
+	DIRAMPFORCE     rf;
+	DIEFFECT        diEffect;
+
+	//Currently only support 1 axis
+	rf.lStart = eff->startLevel;
+	rf.lEnd = eff->endLevel;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIRAMPFORCE), &rf, effect, &eff->envelope );
+	_upload(GUID_RampForce, &diEffect, effect);
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updatePeriodicEffect( const Effect* effect )
+{
+	PeriodicEffect *eff = static_cast<PeriodicEffect*>(effect->getForceEffect());
+
+	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
+	DIPERIODIC      pf;
+	DIEFFECT        diEffect;
+
+	//Currently only support 1 axis
+	pf.dwMagnitude = eff->magnitude;
+	pf.lOffset = eff->offset;
+	pf.dwPhase = eff->phase;
+	pf.dwPeriod = eff->period;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIPERIODIC), &pf, effect, &eff->envelope );
+
+	switch( effect->type )
+	{
+	case OIS::Effect::Square: _upload(GUID_Square, &diEffect, effect); break;
+	case OIS::Effect::Triangle: _upload(GUID_Triangle, &diEffect, effect); break;
+	case OIS::Effect::Sine: _upload(GUID_Sine, &diEffect, effect); break;
+	case OIS::Effect::SawToothUp: _upload(GUID_SawtoothUp, &diEffect, effect); break;
+	case OIS::Effect::SawToothDown:	_upload(GUID_SawtoothDown, &diEffect, effect); break;
+	default: break;
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updateConditionalEffect( const Effect* effect )
+{
+	ConditionalEffect *eff = static_cast<ConditionalEffect*>(effect->getForceEffect());
+
+	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
+	DICONDITION     cf;
+	DIEFFECT        diEffect;
+
+	cf.lOffset = eff->deadband;
+	cf.lPositiveCoefficient = eff->rightCoeff;
+	cf.lNegativeCoefficient = eff->leftCoeff;
+	cf.dwPositiveSaturation = eff->rightSaturation;
+	cf.dwNegativeSaturation = eff->leftSaturation;
+	cf.lDeadBand = eff->deadband;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONDITION), &cf, effect, 0 );
+
+	switch( effect->type )
+	{
+	case OIS::Effect::Friction:	_upload(GUID_Friction, &diEffect, effect); break;
+	case OIS::Effect::Damper: _upload(GUID_Damper, &diEffect, effect); break;
+	case OIS::Effect::Inertia: _upload(GUID_Inertia, &diEffect, effect); break;
+	case OIS::Effect::Spring: _upload(GUID_Spring, &diEffect, effect); break;
+	default: break;
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updateCustomEffect( const Effect* /*effect*/ )
+{
+    //CustomEffect *eff = static_cast<CustomEffect*>(effect->getForceEffect());
+    //
+	//DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	//LONG            rglDirection[2] = { 0, 0 };
+	//DIENVELOPE      diEnvelope;
+	//DICUSTOMFORCE cf;
+	//DIEFFECT        diEffect;
+	//cf.cChannels = 0;
+	//cf.dwSamplePeriod = 0;
+	//cf.cSamples = 0;
+	//cf.rglForceData = 0;
+	//_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICUSTOMFORCE), &cf, effect, &eff->envelope);
+	//_upload(GUID_CustomForce, &diEffect, effect);
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_setCommonProperties(
+		DIEFFECT* diEffect, DWORD* rgdwAxes,
+		LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size,
+		LPVOID struct_type, const Effect* effect, const Envelope* envelope )
+{
+	ZeroMemory(diEffect, sizeof(DIEFFECT));
+
+	diEffect->dwSize                  = sizeof(DIEFFECT);
+	diEffect->dwFlags                 = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
+	diEffect->dwGain                  = DI_FFNOMINALMAX;
+
+	diEffect->dwTriggerButton         = DIEB_NOTRIGGER; // effect->trigger_button; // TODO: Conversion
+	diEffect->dwTriggerRepeatInterval = effect->trigger_interval;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Trigger :" << endl
+		 << "    Button   : " << effect->trigger_button 
+		 << " => " << diEffect->dwTriggerButton << endl
+		 << "    Interval : " << effect->trigger_interval 
+		 << " => " << diEffect->dwTriggerRepeatInterval << endl;
+#endif
+
+	diEffect->cAxes                   = 1; // effect->getNumAxes();
+	diEffect->rgdwAxes                = rgdwAxes;
+
+	diEffect->rglDirection            = rglDirection; // TODO: conversion from effect->direction
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Direction : " << Effect::getDirectionName(effect->direction)
+		 << " => {";
+	for (int iDir=0; iDir < (int)diEffect->cAxes; iDir++)
+	  cout << " " << diEffect->rglDirection[iDir];
+	cout << "}" << endl;
+#endif
+
+	if (diEnvelope && envelope && envelope->isUsed())
+	{
+	    diEnvelope->dwSize = sizeof(DIENVELOPE);
+	    diEnvelope->dwAttackLevel = envelope->attackLevel;
+	    diEnvelope->dwAttackTime  = envelope->attackLength;
+	    diEnvelope->dwFadeLevel   = envelope->fadeLevel;
+	    diEnvelope->dwFadeTime    = envelope->fadeLength;
+	    diEffect->lpEnvelope = diEnvelope;
+	}
+	else
+	    diEffect->lpEnvelope = 0;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	if (diEnvelope && envelope && envelope->isUsed())
+	{
+		cout << "  Enveloppe :" << endl
+			 << "    AttackLen : " << envelope->attackLength
+			 << " => " << diEnvelope->dwAttackTime << endl 
+			 << "    AttackLvl : " << envelope->attackLevel
+			 << " => " << diEnvelope->dwAttackLevel << endl 
+			 << "    FadeLen   : " << envelope->fadeLength
+			 << " => " << diEnvelope->dwFadeTime << endl
+			 << "    FadeLvl   : " << envelope->fadeLevel
+			 << " => " << diEnvelope->dwFadeLevel << endl;
+	}
+#endif
+
+	diEffect->dwSamplePeriod          = 0;
+	diEffect->dwDuration              = effect->replay_length;
+	diEffect->dwStartDelay            = effect->replay_delay;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Replay :" << endl
+		 << "    Length : " << effect->replay_length 
+		 << " => " << diEffect->dwDuration << endl
+		 << "    Delay  : " << effect->replay_delay 
+		 << " => " << diEffect->dwStartDelay << endl;
+#endif
+
+	diEffect->cbTypeSpecificParams    = struct_size;
+	diEffect->lpvTypeSpecificParams   = struct_type;
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_upload( GUID guid, DIEFFECT* diEffect, const Effect* effect)
+{
+	LPDIRECTINPUTEFFECT dxEffect = 0;
+
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(effect->_handle);
+	//It has been created already
+	if( i != mEffectList.end() )
+		dxEffect = i->second;
+	else //This effect has not yet been created - generate a handle
+		effect->_handle = mHandles++;
+
+	if( dxEffect == 0 )
+	{
+		//This effect has not yet been created, so create it
+		HRESULT hr = mJoyStick->CreateEffect(guid, diEffect, &dxEffect, NULL);
+		if(SUCCEEDED(hr))
+		{
+			mEffectList[effect->_handle] = dxEffect;
+			dxEffect->Start(INFINITE,0);
+		}
+		else if( hr == DIERR_DEVICEFULL )
+			OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!");
+		else
+			OIS_EXCEPT(E_General, "Unknown error creating effect->..");
+	}
+	else
+	{
+		//ToDo -- Update the Effect
+		HRESULT hr = dxEffect->SetParameters( diEffect, DIEP_DIRECTION |
+			DIEP_DURATION | DIEP_ENVELOPE | DIEP_STARTDELAY | DIEP_TRIGGERBUTTON |
+			DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS | DIEP_START );
+
+		if(FAILED(hr)) OIS_EXCEPT(E_InvalidParam, "Error updating device!");
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_addEffectSupport( LPCDIEFFECTINFO pdei )
+{
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+    // Dump some usefull information about the effect type.
+    cout << "Adding support for '" << pdei->tszName << "' effect type" << endl;
+	cout << "  Supported static params: ";
+	if (pdei->dwStaticParams & DIEP_AXES) cout << " Axes";
+	if (pdei->dwStaticParams & DIEP_DIRECTION) cout << " Direction";
+	if (pdei->dwStaticParams & DIEP_DURATION) cout << " Duration";
+	if (pdei->dwStaticParams & DIEP_ENVELOPE) cout << " Envelope";
+	if (pdei->dwStaticParams & DIEP_GAIN) cout << " Gain";
+	if (pdei->dwStaticParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod";
+	if (pdei->dwStaticParams & DIEP_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwStaticParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton";
+	if (pdei->dwStaticParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval";
+	if (pdei->dwStaticParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams";
+	cout << endl;
+	cout << "  Supported dynamic params: ";
+	if (pdei->dwDynamicParams & DIEP_AXES) cout << " Axes";
+	if (pdei->dwDynamicParams & DIEP_DIRECTION) cout << " Direction";
+	if (pdei->dwDynamicParams & DIEP_DURATION) cout << " Duration";
+	if (pdei->dwDynamicParams & DIEP_ENVELOPE) cout << " Envelope";
+	if (pdei->dwDynamicParams & DIEP_GAIN) cout << " Gain";
+	if (pdei->dwDynamicParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod";
+	if (pdei->dwDynamicParams & DIEP_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwDynamicParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton";
+	if (pdei->dwDynamicParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval";
+	if (pdei->dwDynamicParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams";
+	cout << endl;
+	cout << "  More details about supported parameters support: ";
+	if (pdei->dwEffType & DIEFT_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwEffType & DIEFT_FFATTACK) cout << " Attack";
+	if (pdei->dwEffType & DIEFT_FFFADE) cout << " Fade";
+	if (pdei->dwEffType & DIEFT_DEADBAND) cout << " DeadBand";
+	if (pdei->dwEffType & DIEFT_SATURATION) cout << " Saturation";
+	if (pdei->dwEffType & DIEFT_POSNEGSATURATION) cout << " PosNegaturation";
+	if (pdei->dwEffType & DIEFT_POSNEGCOEFFICIENTS) cout << " PosNegCoefficients";
+	if (pdei->dwEffType & DIEFT_HARDWARE) cout << " HardwareSpecific";
+	cout << endl;
+#endif
+
+    Effect::EForce eForce;
+	switch (DIEFT_GETTYPE(pdei->dwEffType))
+	{
+	    case DIEFT_CONSTANTFORCE:
+		    eForce = Effect::ConstantForce;
+			break;
+	    case DIEFT_RAMPFORCE:
+		    eForce = Effect::RampForce;
+			break;
+	    case DIEFT_PERIODIC:
+		    eForce = Effect::PeriodicForce;
+			break;
+	    case DIEFT_CONDITION:
+		    eForce = Effect::ConditionalForce;
+			break;
+	    case DIEFT_CUSTOMFORCE:
+		    eForce = Effect::CustomForce;
+			break;
+	    default:
+		    eForce = Effect::UnknownForce;
+#if defined (_DEBUG)
+			cout << "Win32ForceFeedback: DirectInput8 Effect type support not implemented: " 
+				 << "DIEFT_GETTYPE="<< (int)DIEFT_GETTYPE(pdei->dwEffType) << endl;
+#endif
+			return;
+	}
+
+	//Determine what the effect type is and how it corresponds to our OIS's Enums
+	//We could save the GUIDs too, however, we will just use the predefined ones later
+	if( pdei->guid == GUID_ConstantForce )
+		_addEffectTypes(eForce, Effect::Constant );
+	else if( pdei->guid == GUID_Triangle )
+		_addEffectTypes(eForce, Effect::Triangle );
+	else if( pdei->guid == GUID_Spring )
+		_addEffectTypes(eForce, Effect::Spring );
+	else if( pdei->guid == GUID_Friction )
+		_addEffectTypes(eForce, Effect::Friction );
+	else if( pdei->guid == GUID_Square )
+		_addEffectTypes(eForce, Effect::Square );
+	else if( pdei->guid == GUID_Sine )
+		_addEffectTypes(eForce, Effect::Sine );
+	else if( pdei->guid == GUID_SawtoothUp )
+		_addEffectTypes(eForce, Effect::SawToothUp );
+	else if( pdei->guid == GUID_SawtoothDown )
+		_addEffectTypes(eForce, Effect::SawToothDown );
+	else if( pdei->guid == GUID_Damper )
+		_addEffectTypes(eForce, Effect::Damper );
+	else if( pdei->guid == GUID_Inertia )
+		_addEffectTypes(eForce, Effect::Inertia );
+	else if( pdei->guid == GUID_CustomForce )
+		_addEffectTypes(eForce, Effect::Custom );
+	else if( pdei->guid == GUID_RampForce )
+		_addEffectTypes(eForce, Effect::Ramp );
+
+#if defined (_DEBUG)
+	//Only care about this for Debugging Purposes
+	//else
+	//{
+	//	std::ostringstream ss;
+	//	ss << "Win32ForceFeedback, DirectInput8 Effect not found. Reported as: "
+	//	   << pdei->tszName;
+	//	OIS_EXCEPT( E_General, ss.str().c_str());
+	//}
+#endif
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_addFFAxis()
+{
+	mFFAxes++;
+}

+ 273 - 0
CamelotOISInput/Source/OIS/win32/Win32InputManager.cpp

@@ -0,0 +1,273 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/win32/Win32InputManager.h"
+#include "OIS/win32/Win32KeyBoard.h"
+#include "OIS/win32/Win32Mouse.h"
+#include "OIS/win32/Win32JoyStick.h"
+#include "OIS/OISException.h"
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------//
+Win32InputManager::Win32InputManager() : InputManager("Win32InputManager")
+{
+	hWnd = 0;
+	mDirectInput = 0;
+
+	kbSettings    = 0;
+	mouseSettings = 0;
+	joySettings   = 0;
+
+	joySticks = 0;
+	keyboardUsed = mouseUsed = false;
+
+	//Setup our internal factories
+	mFactories.push_back(this);
+}
+
+//--------------------------------------------------------------------------------//
+Win32InputManager::~Win32InputManager()
+{
+	if( mDirectInput )
+	{
+		mDirectInput->Release();
+		mDirectInput = 0;
+	}
+}
+
+//--------------------------------------------------------------------------------//
+void Win32InputManager::_initialize( ParamList &paramList )
+{
+	HINSTANCE hInst = 0;
+	HRESULT hr;
+
+	//TODO 64 bit proof this little conversion xxx wip
+	//First of all, get the Windows Handle and Instance
+	ParamList::iterator i = paramList.find("WINDOW");
+	if( i == paramList.end() ) 
+		OIS_EXCEPT( E_InvalidParam, "Win32InputManager::Win32InputManager >> No HWND found!" );
+
+	hWnd  = (HWND)strtoul(i->second.c_str(), 0, 10);
+
+	if( IsWindow(hWnd) == 0 )
+		OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> The sent HWND is not valid!");
+
+	hInst = GetModuleHandle(0);
+
+	//Create the device
+	hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
+    if (FAILED(hr))	
+		OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> Not able to init DirectX8 Input!");
+
+	//Ok, now we have DirectInput, parse whatever extra settings were sent to us
+	_parseConfigSettings( paramList );
+
+	// Enumerate devices ...
+	_enumerateDevices();
+}
+
+//--------------------------------------------------------------------------------//
+void Win32InputManager::_parseConfigSettings( ParamList &paramList )
+{
+	//Here we pick up settings such as a device's cooperation mode
+	std::map<std::string, DWORD> temp;
+	temp["DISCL_BACKGROUND"]	= DISCL_BACKGROUND;
+	temp["DISCL_EXCLUSIVE"]		= DISCL_EXCLUSIVE;
+	temp["DISCL_FOREGROUND"]	= DISCL_FOREGROUND;
+	temp["DISCL_NONEXCLUSIVE"]	= DISCL_NONEXCLUSIVE;
+	temp["DISCL_NOWINKEY"]		= DISCL_NOWINKEY;
+
+	//Check for pairs: ie. ("w32_keyboard","DISCL_NOWINKEY")("w32_keyboard","DISCL_FOREGROUND")
+	ParamList::iterator i = paramList.begin(), e = paramList.end();
+	for( ; i != e; ++i ) 
+	{
+		if( i->first == "w32_keyboard" )
+				kbSettings |= temp[i->second];
+		else if( i->first == "w32_mouse" )
+				mouseSettings |= temp[i->second];
+		else if( i->first == "w32_joystick" )
+				joySettings |= temp[i->second];
+	}
+	if( kbSettings == 0 ) kbSettings = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY;
+	if( mouseSettings == 0 ) mouseSettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE;
+	if( joySettings == 0 ) joySettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE;
+}
+
+//--------------------------------------------------------------------------------//
+void Win32InputManager::_enumerateDevices()
+{
+	//Enumerate all attached devices
+	mDirectInput->EnumDevices(NULL, _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY);
+
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+	//let's check how many possible XInput devices we may have (max 4)... 
+	for(int i = 0; i < 3; ++i)
+	{
+		XINPUT_STATE state;
+		if(XInputGetState(i, &state) != ERROR_DEVICE_NOT_CONNECTED)
+		{	//Once we found 1, just check our whole list against devices
+			Win32JoyStick::CheckXInputDevices(unusedJoyStickList);
+			break;
+		}
+	}
+#endif
+}
+
+//--------------------------------------------------------------------------------//
+BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
+{
+	Win32InputManager *_this_ = static_cast<Win32InputManager*>(pvRef);
+
+	// Register only game devices (keyboard and mouse are managed differently).
+	if( GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK ||
+		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD ||
+		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_1STPERSON ||
+		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DRIVING ||
+		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_FLIGHT)
+	{
+		JoyStickInfo jsInfo;
+		jsInfo.isXInput = false;
+		jsInfo.productGuid = lpddi->guidProduct;
+		jsInfo.deviceID = lpddi->guidInstance;
+		jsInfo.vendor = lpddi->tszInstanceName;
+		jsInfo.devId = _this_->joySticks;
+
+		_this_->joySticks++;
+		
+		_this_->unusedJoyStickList.push_back( jsInfo );
+	}
+
+	return DIENUM_CONTINUE;
+}
+
+//----------------------------------------------------------------------------//
+void Win32InputManager::_returnJoyStick(const JoyStickInfo& joystick)
+{
+	unusedJoyStickList.push_back(joystick);
+}
+
+//----------------------------------------------------------------------------//
+DeviceList Win32InputManager::freeDeviceList()
+{
+	DeviceList ret;
+
+	if( keyboardUsed == false )
+		ret.insert(std::make_pair(OISKeyboard, mInputSystemName));
+
+	if( mouseUsed == false )
+		ret.insert(std::make_pair(OISMouse, mInputSystemName));
+
+	for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+		ret.insert(std::make_pair(OISJoyStick, i->vendor));
+
+	return ret;
+}
+
+//----------------------------------------------------------------------------//
+int Win32InputManager::totalDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return 1;
+	case OISMouse: return 1;
+	case OISJoyStick: return joySticks;
+	default: return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+int Win32InputManager::freeDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return keyboardUsed ? 0 : 1;
+	case OISMouse: return mouseUsed ? 0 : 1;
+	case OISJoyStick: return (int)unusedJoyStickList.size();
+	default: return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+bool Win32InputManager::vendorExist(Type iType, const std::string & vendor)
+{
+	if( (iType == OISKeyboard || iType == OISMouse) && vendor == mInputSystemName )
+	{
+		return true;
+	}
+	else if( iType == OISJoyStick )
+	{
+		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+			if(i->vendor == vendor)
+				return true;
+	}
+
+	return false;
+}
+
+//----------------------------------------------------------------------------//
+Object* Win32InputManager::createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor)
+{
+	Object *obj = 0;
+
+	switch(iType)
+	{
+	case OISKeyboard: 
+	{
+		if( keyboardUsed == false )
+			obj = new Win32Keyboard(this, mDirectInput, bufferMode, kbSettings);
+		break;
+	}
+	case OISMouse:
+	{
+		if( mouseUsed == false )
+			obj = new Win32Mouse(this, mDirectInput, bufferMode, mouseSettings);
+		break;
+	}
+	case OISJoyStick:
+	{
+		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+		{
+			if(vendor == "" || i->vendor == vendor)
+			{
+				obj = new Win32JoyStick(this, mDirectInput, bufferMode, joySettings, *i);
+				unusedJoyStickList.erase(i);
+				break;
+			}
+		}
+		break;
+	}
+	default:
+		break;
+	}
+
+	if( obj == 0 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	return obj;
+}
+
+//----------------------------------------------------------------------------//
+void Win32InputManager::destroyObject(Object* obj)
+{
+	delete obj;
+}

+ 683 - 0
CamelotOISInput/Source/OIS/win32/Win32JoyStick.cpp

@@ -0,0 +1,683 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/win32/Win32JoyStick.h"
+#include "OIS/win32/Win32InputManager.h"
+#include "OIS/win32/Win32ForceFeedback.h"
+#include "OIS/OISEvents.h"
+#include "OIS/OISException.h"
+
+#include <cassert>
+#include <wbemidl.h>
+#include <oleauto.h>
+//#include <wmsstd.h>
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) \
+   if(x != NULL)        \
+   {                    \
+      x->Release();     \
+      x = NULL;         \
+   }
+#endif
+
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+#	pragma comment(lib, "xinput.lib")
+#endif
+
+//DX Only defines macros for the JOYSTICK not JOYSTICK2, so fix it
+#undef DIJOFS_BUTTON
+#undef DIJOFS_POV
+
+#define DIJOFS_BUTTON(n)  (FIELD_OFFSET(DIJOYSTATE2, rgbButtons) + (n))
+#define DIJOFS_POV(n)     (FIELD_OFFSET(DIJOYSTATE2, rgdwPOV)+(n)*sizeof(DWORD))
+#define DIJOFS_SLIDER0(n) (FIELD_OFFSET(DIJOYSTATE2, rglSlider)+(n) * sizeof(LONG))
+#define DIJOFS_SLIDER1(n) (FIELD_OFFSET(DIJOYSTATE2, rglVSlider)+(n) * sizeof(LONG))
+#define DIJOFS_SLIDER2(n) (FIELD_OFFSET(DIJOYSTATE2, rglASlider)+(n) * sizeof(LONG))
+#define DIJOFS_SLIDER3(n) (FIELD_OFFSET(DIJOYSTATE2, rglFSlider)+(n) * sizeof(LONG))
+
+#define XINPUT_TRANSLATED_BUTTON_COUNT 12
+#define XINPUT_TRANSLATED_AXIS_COUNT 6
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------------------------//
+Win32JoyStick::Win32JoyStick( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings, const JoyStickInfo &info ) :
+	JoyStick(info.vendor, buffered, info.devId, creator),
+	mDirectInput(pDI),
+	coopSetting(coopSettings),
+	mJoyStick(0),
+	mJoyInfo(info),
+	mFfDevice(0)
+{
+}
+
+//--------------------------------------------------------------------------------------------------//
+Win32JoyStick::~Win32JoyStick()
+{
+	delete mFfDevice;
+
+	if(mJoyStick)
+	{
+		mJoyStick->Unacquire();
+		mJoyStick->Release();
+		mJoyStick = 0;
+	}
+
+	//Return joystick to pool
+	static_cast<Win32InputManager*>(mCreator)->_returnJoyStick(mJoyInfo);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::_initialize()
+{
+    if (mJoyInfo.isXInput)
+    {
+        _enumerate();
+    }
+    else
+    {
+	    //Clear old state
+	    mState.mAxes.clear();
+
+	    delete mFfDevice;
+	    mFfDevice = 0;
+
+	    DIPROPDWORD dipdw;
+
+	    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
+	    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	    dipdw.diph.dwObj        = 0;
+	    dipdw.diph.dwHow        = DIPH_DEVICE;
+	    dipdw.dwData            = JOYSTICK_DX_BUFFERSIZE;
+
+	    if(FAILED(mDirectInput->CreateDevice(mJoyInfo.deviceID, &mJoyStick, NULL)))
+		    OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!");
+
+	    if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2)))
+		    OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!");
+
+	    HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
+
+	    if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting)))
+		    OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!");
+
+	    if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) )
+		    OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set buffer size property" );
+
+	    //Enumerate all axes/buttons/sliders/etc before aquiring
+	    _enumerate();
+
+	    mState.clear();
+
+	    capture();
+    }
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::_enumerate()
+{
+    if (mJoyInfo.isXInput)
+    {
+        mPOVs = 1;
+
+        mState.mButtons.resize(XINPUT_TRANSLATED_BUTTON_COUNT);
+	    mState.mAxes.resize(XINPUT_TRANSLATED_AXIS_COUNT);
+    }
+    else
+    {
+		// Get joystick capabilities.
+		mDIJoyCaps.dwSize = sizeof(DIDEVCAPS);
+		if( FAILED(mJoyStick->GetCapabilities(&mDIJoyCaps)) )
+			OIS_EXCEPT( E_General, "Win32JoyStick::_enumerate >> Failed to get capabilities" );
+
+	    mPOVs = (short)mDIJoyCaps.dwPOVs;
+
+	    mState.mButtons.resize(mDIJoyCaps.dwButtons);
+	    mState.mAxes.resize(mDIJoyCaps.dwAxes);
+
+	    //Reset the axis mapping enumeration value
+	    _AxisNumber = 0;
+
+	    //Enumerate Force Feedback (if any)
+	    mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL);
+
+	    //Enumerate and set axis constraints (and check FF Axes)
+	    mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS);
+    }
+}
+
+//--------------------------------------------------------------------------------------------------//
+BOOL CALLBACK Win32JoyStick::DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
+{
+	Win32JoyStick* _this = (Win32JoyStick*)pvRef;
+
+	//Setup mappings
+	DIPROPPOINTER diptr;
+	diptr.diph.dwSize       = sizeof(DIPROPPOINTER);
+	diptr.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	diptr.diph.dwHow        = DIPH_BYID;
+	diptr.diph.dwObj        = lpddoi->dwType;
+	//Add a magic number to recognise we set seomthing
+	diptr.uData             = 0x13130000 | _this->_AxisNumber;
+
+	//Check if axis is slider, if so, do not treat as regular axis
+	if(GUID_Slider == lpddoi->guidType)
+	{
+		++_this->mSliders;
+
+		//Decrease Axes, since this slider shows up in a different place
+		_this->mState.mAxes.pop_back();
+	}
+	else if (FAILED(_this->mJoyStick->SetProperty(DIPROP_APPDATA, &diptr.diph)))
+	{	//If for some reason we could not set needed user data, just ignore this axis
+		return DIENUM_CONTINUE;
+	}
+
+	//Increase for next time through
+	if(GUID_Slider != lpddoi->guidType)
+		_this->_AxisNumber += 1;
+
+	//Set range
+	DIPROPRANGE diprg;
+	diprg.diph.dwSize       = sizeof(DIPROPRANGE);
+	diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	diprg.diph.dwHow        = DIPH_BYID;
+	diprg.diph.dwObj        = lpddoi->dwType;
+	diprg.lMin              = MIN_AXIS;
+	diprg.lMax              = MAX_AXIS;
+
+	if (FAILED(_this->mJoyStick->SetProperty(DIPROP_RANGE, &diprg.diph)))
+		OIS_EXCEPT( E_General, "Win32JoyStick::_DIEnumDeviceObjectsCallback >> Failed to set min/max range property" );
+
+	//Check if FF Axes, and if so, increment counter
+	if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 )
+	{
+		if( _this->mFfDevice )
+		{
+			_this->mFfDevice->_addFFAxis();
+		}
+	}
+
+	//Force the flags for gain and auto-center support to true,
+	//as DInput has no API to query the device for these capabilities
+	//(the only way to know is to try them ...)
+	if( _this->mFfDevice )
+	{
+	    _this->mFfDevice->_setGainSupport(true);
+	    _this->mFfDevice->_setAutoCenterSupport(true);
+	}
+
+	return DIENUM_CONTINUE;
+}
+
+//--------------------------------------------------------------------------------------------------//
+BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef)
+{
+	Win32JoyStick* _this = (Win32JoyStick*)pvRef;
+
+	//Create the FF instance only after we know there is at least one effect type
+	if( _this->mFfDevice == 0 )
+		_this->mFfDevice = new Win32ForceFeedback(_this->mJoyStick, &_this->mDIJoyCaps);
+
+	_this->mFfDevice->_addEffectSupport(pdei);
+
+	return DIENUM_CONTINUE;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::capture()
+{
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+	//handle xbox controller differently
+    if (mJoyInfo.isXInput)
+	{
+		captureXInput();
+		return;
+	}
+#endif
+
+	//handle directinput based devices
+	DIDEVICEOBJECTDATA diBuff[JOYSTICK_DX_BUFFERSIZE];
+	DWORD entries = JOYSTICK_DX_BUFFERSIZE;
+
+	// Poll the device to read the current state
+	HRESULT hr = mJoyStick->Poll();
+	if( hr == DI_OK )
+		hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+
+	if( hr != DI_OK )
+	{
+		hr = mJoyStick->Acquire();
+		while( hr == DIERR_INPUTLOST )
+			hr = mJoyStick->Acquire();
+
+		// Poll the device to read the current state
+		mJoyStick->Poll();
+		hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+		//Perhaps the user just tabbed away
+		if( FAILED(hr) )
+			return;
+	}
+
+	bool axisMoved[24] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,
+						  false,false,false,false,false,false,false,false};
+	bool sliderMoved[4] = {false,false,false,false};
+
+	//Loop through all the events
+	for(unsigned int i = 0; i < entries; ++i)
+	{
+		//This may seem outof order, but is in order of the way these variables
+		//are declared in the JoyStick State 2 structure.
+		switch(diBuff[i].dwOfs)
+		{
+		//------ slider -//
+		case DIJOFS_SLIDER0(0):
+			sliderMoved[0] = true;
+			mState.mSliders[0].abX = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER0(1):
+			sliderMoved[0] = true;
+			mState.mSliders[0].abY = diBuff[i].dwData;
+			break;
+		//----- Max 4 POVs Next ---------------//
+		case DIJOFS_POV(0):
+			if(!_changePOV(0,diBuff[i]))
+				return;
+			break;
+		case DIJOFS_POV(1):
+			if(!_changePOV(1,diBuff[i]))
+				return;
+			break;
+		case DIJOFS_POV(2):
+			if(!_changePOV(2,diBuff[i]))
+				return;
+			break;
+		case DIJOFS_POV(3):
+			if(!_changePOV(3,diBuff[i]))
+				return;
+			break;
+		case DIJOFS_SLIDER1(0):
+			sliderMoved[1] = true;
+			mState.mSliders[1].abX = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER1(1):
+			sliderMoved[1] = true;
+			mState.mSliders[1].abY = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER2(0):
+			sliderMoved[2] = true;
+			mState.mSliders[2].abX = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER2(1):
+			sliderMoved[2] = true;
+			mState.mSliders[2].abY = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER3(0):
+			sliderMoved[3] = true;
+			mState.mSliders[3].abX = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER3(1):
+			sliderMoved[3] = true;
+			mState.mSliders[3].abY = diBuff[i].dwData;
+			break;
+		//-----------------------------------------//
+		default:
+			//Handle Button Events Easily using the DX Offset Macros
+			if( diBuff[i].dwOfs >= DIJOFS_BUTTON(0) && diBuff[i].dwOfs < DIJOFS_BUTTON(128) )
+			{
+				if(!_doButtonClick((diBuff[i].dwOfs - DIJOFS_BUTTON(0)), diBuff[i]))
+					return;
+			}
+			else if((short)(diBuff[i].uAppData >> 16) == 0x1313)
+			{	//If it was nothing else, might be axis enumerated earlier (determined by magic number)
+				int axis = (int)(0x0000FFFF & diBuff[i].uAppData); //Mask out the high bit
+				assert( axis >= 0 && axis < (int)mState.mAxes.size() && "Axis out of range!");
+
+				if(axis >= 0 && axis < (int)mState.mAxes.size())
+				{
+					mState.mAxes[axis].abs = diBuff[i].dwData;
+					axisMoved[axis] = true;
+				}
+			}
+
+			break;
+		} //end case
+	} //end for
+
+	//Check to see if any of the axes values have changed.. if so send events
+	if( mBuffered && mListener && entries > 0 )
+	{
+		JoyStickEvent temp(this, mState);
+
+		//Update axes
+		for( int i = 0; i < 24; ++i )
+			if( axisMoved[i] )
+				if( mListener->axisMoved( temp, i ) == false )
+					return;
+
+		//Now update sliders
+		for( int i = 0; i < 4; ++i )
+			if( sliderMoved[i] )
+				if( mListener->sliderMoved( temp, i ) == false )
+					return;
+	}
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::captureXInput()
+{
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+    XINPUT_STATE inputState;
+	if (XInputGetState((DWORD)mJoyInfo.xInputDev, &inputState) != ERROR_SUCCESS)
+        memset(&inputState, 0, sizeof(inputState));
+
+    //Sticks and triggers
+	int value;
+    bool axisMoved[XINPUT_TRANSLATED_AXIS_COUNT] = {false,false,false,false,false,false};
+
+	//LeftY
+	value = -(int)inputState.Gamepad.sThumbLY;
+	mState.mAxes[0].rel = value - mState.mAxes[0].abs;
+	mState.mAxes[0].abs = value;
+	if(mState.mAxes[0].rel != 0)
+        axisMoved[0] = true;
+
+	//LeftX
+    mState.mAxes[1].rel = inputState.Gamepad.sThumbLX - mState.mAxes[1].abs;
+    mState.mAxes[1].abs = inputState.Gamepad.sThumbLX;
+
+	if(mState.mAxes[1].rel != 0)
+        axisMoved[1] = true;
+
+	//RightY
+	value = -(int)inputState.Gamepad.sThumbRY;           
+    mState.mAxes[2].rel = value - mState.mAxes[2].abs;
+    mState.mAxes[2].abs = value;
+	if(mState.mAxes[2].rel != 0)
+        axisMoved[2] = true;
+
+	//RightX
+    mState.mAxes[3].rel = inputState.Gamepad.sThumbRX - mState.mAxes[3].abs;
+    mState.mAxes[3].abs = inputState.Gamepad.sThumbRX;
+	if(mState.mAxes[3].rel != 0)
+		axisMoved[3] = true;
+
+	//Left trigger
+    value = inputState.Gamepad.bLeftTrigger * 129;
+	if(value > JoyStick::MAX_AXIS)
+		value = JoyStick::MAX_AXIS;
+
+    mState.mAxes[4].rel = value - mState.mAxes[4].abs;
+    mState.mAxes[4].abs = value;
+	if(mState.mAxes[4].rel != 0)
+		axisMoved[4] = true;
+
+	//Right trigger
+    value = (int)inputState.Gamepad.bRightTrigger * 129;
+	if(value > JoyStick::MAX_AXIS)
+		value = JoyStick::MAX_AXIS;
+
+	mState.mAxes[5].rel = value - mState.mAxes[5].abs;
+    mState.mAxes[5].abs = value;
+	if(mState.mAxes[5].rel != 0)
+		axisMoved[5] = true;
+    
+    //POV
+    int previousPov = mState.mPOV[0].direction;        
+    int& pov = mState.mPOV[0].direction;
+    pov = Pov::Centered;        
+    if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
+        pov |= Pov::North;
+    else if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
+        pov |= Pov::South;
+    if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
+        pov |= Pov::West;
+    else if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
+        pov |= Pov::East;
+    
+    //Buttons - The first 4 buttons don't need to be checked since they represent the dpad
+    bool previousButtons[XINPUT_TRANSLATED_BUTTON_COUNT];
+    std::copy(mState.mButtons.begin(), mState.mButtons.end(), previousButtons);
+    for (size_t i = 0; i < XINPUT_TRANSLATED_BUTTON_COUNT; i++)
+        mState.mButtons[i] = (inputState.Gamepad.wButtons & (1 << (i + 4))) != 0;
+
+    //Send events
+    if (mBuffered && mListener)
+    {
+	    JoyStickEvent joystickEvent(this, mState);
+
+	    //Axes
+	    for (int i = 0; i < XINPUT_TRANSLATED_AXIS_COUNT; i++)
+        {
+		    if (axisMoved[i] && !mListener->axisMoved(joystickEvent, i))
+			    return;
+        }
+
+        //POV
+        if (previousPov != pov && !mListener->povMoved(joystickEvent, 0))
+            return;
+
+        //Buttons
+        for (int i = 0; i < XINPUT_TRANSLATED_BUTTON_COUNT; i++)
+        {
+            if (!previousButtons[i] && mState.mButtons[i])
+            {
+                if (!mListener->buttonPressed(joystickEvent, i))
+                    return;
+            }
+            else if (previousButtons[i] && !mState.mButtons[i])
+            {
+                if (!mListener->buttonReleased(joystickEvent, i))
+                    return;
+            }
+        }
+    }
+#endif
+}
+
+//--------------------------------------------------------------------------------------------------//
+bool Win32JoyStick::_doButtonClick( int button, DIDEVICEOBJECTDATA& di )
+{
+	if( di.dwData & 0x80 )
+	{
+		mState.mButtons[button] = true;
+		if( mBuffered && mListener )
+			return mListener->buttonPressed( JoyStickEvent( this, mState ), button );
+	}
+	else
+	{
+		mState.mButtons[button] = false;
+		if( mBuffered && mListener )
+			return mListener->buttonReleased( JoyStickEvent( this, mState ), button );
+	}
+
+	return true;
+}
+
+//--------------------------------------------------------------------------------------------------//
+bool Win32JoyStick::_changePOV( int pov, DIDEVICEOBJECTDATA& di )
+{
+	//Some drivers report a value of 65,535, instead of —1,
+	//for the center position
+	if(LOWORD(di.dwData) == 0xFFFF)
+	{
+		mState.mPOV[pov].direction = Pov::Centered;
+	}
+	else
+	{
+		switch(di.dwData)
+		{
+			case 0: mState.mPOV[pov].direction = Pov::North; break;
+			case 4500: mState.mPOV[pov].direction = Pov::NorthEast; break;
+			case 9000: mState.mPOV[pov].direction = Pov::East; break;
+			case 13500: mState.mPOV[pov].direction = Pov::SouthEast; break;
+			case 18000: mState.mPOV[pov].direction = Pov::South; break;
+			case 22500: mState.mPOV[pov].direction = Pov::SouthWest; break;
+			case 27000: mState.mPOV[pov].direction = Pov::West; break;
+			case 31500: mState.mPOV[pov].direction = Pov::NorthWest; break;
+		}
+	}
+
+	if( mBuffered && mListener )
+		return mListener->povMoved( JoyStickEvent( this, mState ), pov );
+
+	return true;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//--------------------------------------------------------------------------------------------------//
+Interface* Win32JoyStick::queryInterface(Interface::IType type)
+{
+	if( mFfDevice && type == Interface::ForceFeedback )
+		return mFfDevice;
+	else
+		return 0;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::CheckXInputDevices(JoyStickInfoList &joys)
+{
+    IWbemLocator*           pIWbemLocator  = NULL;
+    IEnumWbemClassObject*   pEnumDevices   = NULL;
+    IWbemClassObject*       pDevices[20]   = {0};
+    IWbemServices*          pIWbemServices = NULL;
+    BSTR                    bstrNamespace  = NULL;
+    BSTR                    bstrDeviceID   = NULL;
+    BSTR                    bstrClassName  = NULL;
+    DWORD                   uReturned      = 0;
+    bool                    bIsXinputDevice= false;
+	DWORD                   iDevice        = 0;
+	int                     xDevice        = 0;
+    VARIANT                 var;
+    HRESULT                 hr;
+
+	if(joys.size() == 0)
+		return;
+
+    // CoInit if needed
+    hr = CoInitialize(NULL);
+    bool bCleanupCOM = SUCCEEDED(hr);
+
+    // Create WMI
+    hr = CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator);
+    if( FAILED(hr) || pIWbemLocator == NULL )
+        goto LCleanup;
+
+    bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );
+	if( bstrNamespace == NULL )
+		goto LCleanup;
+
+    bstrClassName = SysAllocString( L"Win32_PNPEntity" );
+	if( bstrClassName == NULL )
+		goto LCleanup;
+
+    bstrDeviceID  = SysAllocString( L"DeviceID" );
+	if( bstrDeviceID == NULL )
+		goto LCleanup;
+    
+    // Connect to WMI 
+    hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices );
+    if( FAILED(hr) || pIWbemServices == NULL )
+        goto LCleanup;
+
+    // Switch security level to IMPERSONATE. 
+    CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );                    
+
+    hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, NULL, &pEnumDevices ); 
+    if( FAILED(hr) || pEnumDevices == NULL )
+        goto LCleanup;
+
+    // Loop over all devices
+    for( ;; )
+    {
+        // Get 20 at a time
+        hr = pEnumDevices->Next(5000, 20, pDevices, &uReturned);
+        if( FAILED(hr) )
+            goto LCleanup;
+
+        if( uReturned == 0 )
+            break;
+
+        for(iDevice = 0; iDevice < uReturned; iDevice++)
+        {
+            // For each device, get its device ID
+            hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL);
+            if(SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL)
+            {
+                // Check if the device ID contains "IG_".  If it does, then it's an XInput device - This information can not be found from DirectInput 
+                if(wcsstr(var.bstrVal, L"IG_"))
+                {
+                    // If it does, then get the VID/PID from var.bstrVal
+                    DWORD dwPid = 0, dwVid = 0;
+                    WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" );
+                    if(strVid && swscanf_s( strVid, L"VID_%4X", &dwVid ) != 1)
+						dwVid = 0;
+
+                    WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" );
+                    if(strPid && swscanf_s( strPid, L"PID_%4X", &dwPid ) != 1)
+                        dwPid = 0;
+
+                    // Compare the VID/PID to the DInput device
+                    DWORD dwVidPid = MAKELONG(dwVid, dwPid);
+					for(JoyStickInfoList::iterator i = joys.begin(); i != joys.end(); ++i)
+					{
+						if(dwVidPid == i->productGuid.Data1)
+						{
+							i->isXInput = true;
+							i->xInputDev = xDevice;
+						}
+					}
+
+					if(joys.size() == 0)
+						goto LCleanup;
+                }
+            }
+
+            SAFE_RELEASE(pDevices[iDevice]);
+        }
+    }
+
+LCleanup:
+    if(bstrNamespace)
+        SysFreeString(bstrNamespace);
+
+    if(bstrDeviceID)
+        SysFreeString(bstrDeviceID);
+
+    if(bstrClassName)
+        SysFreeString(bstrClassName);
+
+    for(iDevice=0; iDevice < 20; iDevice++)
+        SAFE_RELEASE(pDevices[iDevice]);
+
+    SAFE_RELEASE(pEnumDevices);
+    SAFE_RELEASE(pIWbemLocator);
+    SAFE_RELEASE(pIWbemServices);
+
+    if(bCleanupCOM)
+        CoUninitialize();
+}

+ 333 - 0
CamelotOISInput/Source/OIS/win32/Win32KeyBoard.cpp

@@ -0,0 +1,333 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/win32/Win32InputManager.h"
+#include "OIS/win32/Win32KeyBoard.h"
+#include "OIS/OISException.h"
+#include "OIS/OISEvents.h"
+#include <sstream>
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------------------------//
+Win32Keyboard::Win32Keyboard( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings )
+	: Keyboard(creator->inputSystemName(), buffered, 0, creator)
+{
+	mKeyboard = 0;
+	mDirectInput = pDI;
+	coopSetting = coopSettings;
+
+	//Clear our keyboard state buffer
+	memset( &KeyBuffer, 0, 256 );
+	deadKey = '\0';
+	static_cast<Win32InputManager*>(mCreator)->_setKeyboardUsed(true);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::_initialize()
+{
+	mModifiers = 0;
+	deadKey = '\0';
+
+	if(FAILED(mDirectInput->CreateDevice(GUID_SysKeyboard, &mKeyboard, NULL)))
+		OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> Could not init device!");
+
+	if(FAILED(mKeyboard->SetDataFormat(&c_dfDIKeyboard)))
+		OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> format error!");
+
+	HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
+
+	if(FAILED(mKeyboard->SetCooperativeLevel( hwin, coopSetting)))
+		OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> coop error!");
+
+	if( mBuffered )
+	{
+		DIPROPDWORD dipdw;
+		dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
+		dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+		dipdw.diph.dwObj        = 0;
+		dipdw.diph.dwHow        = DIPH_DEVICE;
+		dipdw.dwData            = KEYBOARD_DX_BUFFERSIZE;
+
+		if (FAILED(mKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph )))
+			OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> buffer error!");
+	}
+
+	HRESULT hr = mKeyboard->Acquire();
+	if(FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO)
+		OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> aquire error!");
+}
+
+//--------------------------------------------------------------------------------------------------//
+Win32Keyboard::~Win32Keyboard()
+{
+	if(mKeyboard)
+	{
+		mKeyboard->Unacquire();
+		mKeyboard->Release();
+		mKeyboard = 0;
+	}
+	static_cast<Win32InputManager*>(mCreator)->_setKeyboardUsed(false);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::capture()
+{
+	if( mBuffered )
+		_readBuffered();
+	else
+		_read();
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::_readBuffered()
+{
+	DIDEVICEOBJECTDATA diBuff[KEYBOARD_DX_BUFFERSIZE];
+	DWORD entries = KEYBOARD_DX_BUFFERSIZE;
+	HRESULT hr;
+	//Only one keyboard allowed per app, so static is ok
+	static bool verifyAfterAltTab = false;
+
+	hr = mKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+	if( hr != DI_OK )
+	{
+		hr = mKeyboard->Acquire();
+		if (hr == E_ACCESSDENIED)
+			verifyAfterAltTab = true;
+
+		while( hr == DIERR_INPUTLOST )
+			hr = mKeyboard->Acquire();
+
+		return;
+	}
+
+	if( FAILED(hr) )
+		OIS_EXCEPT( E_General, "Win32Keyboard::_readBuffered() >> Problem with Device!" );
+
+	//Update keyboard and modifier states.. And, if mListener, fire events
+	for(unsigned int i = 0; i < entries; ++i )
+	{
+		//If the listener returns false, that means that we are probably deleted...
+		//send no more events and just leave as the this pointer is invalid now...
+		bool ret = true;
+		KeyCode kc = (KeyCode)diBuff[ i ].dwOfs;
+			
+		//Store result in our keyBuffer too
+		KeyBuffer[kc] = static_cast<unsigned char>(diBuff[ i ].dwData);
+			
+		if( diBuff[ i ].dwData & 0x80 )
+		{
+			//Turn on modifier
+			if( kc == KC_LCONTROL || kc == KC_RCONTROL )
+				mModifiers |= Ctrl;
+			else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
+				mModifiers |= Shift;
+			else if( kc == KC_LMENU || kc == KC_RMENU )
+				mModifiers |= Alt;
+
+			if( mListener )
+				ret = mListener->keyPressed( KeyEvent( this, kc, _translateText(kc) ) );
+		}
+		else
+		{
+			//Turn off modifier
+			if( kc == KC_LCONTROL || kc == KC_RCONTROL )
+				mModifiers &= ~Ctrl;
+			else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
+				mModifiers &= ~Shift;
+			else if( kc == KC_LMENU || kc == KC_RMENU )
+				mModifiers &= ~Alt;
+
+			//Fire off event
+			if( mListener )
+				ret = mListener->keyReleased( KeyEvent( this, kc, 0 ) );
+		}
+
+		if(ret == false)
+			break;
+	}
+
+	// If a lost device/access denied was detected, recover gracefully with new events
+	if(verifyAfterAltTab)
+	{
+		bool ret = true;
+		
+		//Copy old buffer to temp location to compare against
+		unsigned char keyBufferCopy[256];
+		memcpy(keyBufferCopy, KeyBuffer, 256);
+
+		//Update new state
+		_read();
+
+		for (unsigned i = 0; i < 256; i++)
+		{
+			if (keyBufferCopy[i] != KeyBuffer[i])
+			{
+				if (mListener)
+				{
+					if (KeyBuffer[i])
+						ret = mListener->keyPressed( KeyEvent( this, (KeyCode)i, _translateText((KeyCode)i) ) );
+					else
+						ret = mListener->keyReleased( KeyEvent( this, (KeyCode)i, 0 ) );
+				}
+			}
+
+			//If user returned false from callback, return immediately
+			if(ret == false)
+				return;
+		}
+
+		verifyAfterAltTab = false;
+	}
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::_read()
+{
+    HRESULT  hr = mKeyboard->GetDeviceState( sizeof(KeyBuffer), &KeyBuffer );
+
+	if( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED )
+	{
+		hr = mKeyboard->Acquire();
+		if (hr != DIERR_OTHERAPPHASPRIO)
+			mKeyboard->GetDeviceState(sizeof(KeyBuffer), &KeyBuffer);
+	}
+
+	//Set Shift, Ctrl, Alt
+	mModifiers = 0;
+	if( isKeyDown(KC_LCONTROL) || isKeyDown(KC_RCONTROL) )
+		mModifiers |= Ctrl;
+	if( isKeyDown(KC_LSHIFT) || isKeyDown(KC_RSHIFT) )
+		mModifiers |= Shift;
+	if( isKeyDown(KC_LMENU) || isKeyDown(KC_RMENU) )
+		mModifiers |= Alt;
+}
+
+//--------------------------------------------------------------------------------------------------//
+int Win32Keyboard::_translateText( KeyCode kc )
+{
+	if( mTextMode == Off )
+		return 0;
+
+	BYTE keyState[256];
+	HKL  layout = GetKeyboardLayout(0);
+	if( GetKeyboardState(keyState) == 0 )
+		return 0;
+
+	unsigned int vk = MapVirtualKeyEx(kc, 3, layout);
+	if( vk == 0 )
+		return 0;
+
+	WCHAR buff[3] = {0};
+	int ascii = ToUnicodeEx(vk, kc, keyState, buff, 3, 0, layout);
+
+	if(ascii == 1 && deadKey != '\0' )
+	{
+		// A dead key is stored and we have just converted a character key
+		// Combine the two into a single character
+		WCHAR wcBuff[3] = {buff[0], deadKey, '\0'};
+		WCHAR out[3];
+		
+		deadKey = '\0';
+		if(FoldStringW(MAP_PRECOMPOSED, (LPWSTR)wcBuff, 3, (LPWSTR)out, 3))
+			return out[0];
+	}
+	else if (ascii == 1)
+	{	// We have a single character
+		deadKey = '\0';
+		return buff[0];
+	}
+	else if(ascii == 2)
+	{	// Convert a non-combining diacritical mark into a combining diacritical mark
+		// Combining versions range from 0x300 to 0x36F; only 5 (for French) have been mapped below
+		// http://www.fileformat.info/info/unicode/block/combining_diacritical_marks/images.htm
+		switch(buff[0])	{
+		case 0x5E: // Circumflex accent: â
+			deadKey = 0x302; break;
+		case 0x60: // Grave accent: à
+			deadKey = 0x300; break;
+		case 0xA8: // Diaeresis: ü
+			deadKey = 0x308; break;
+		case 0xB4: // Acute accent: é
+			deadKey = 0x301; break;
+		case 0xB8: // Cedilla: ç
+			deadKey = 0x327; break;
+		default:
+			deadKey = buff[0]; break;
+		}
+	}
+
+	return 0;
+}
+
+//--------------------------------------------------------------------------------------------------//
+bool Win32Keyboard::isKeyDown( KeyCode key ) const
+{
+	return (KeyBuffer[key] & 0x80) != 0;
+}
+
+//--------------------------------------------------------------------------------------------------//
+const std::string& Win32Keyboard::getAsString(KeyCode kc)
+{
+	char temp[256];
+
+	DIPROPSTRING prop;
+	prop.diph.dwSize = sizeof(DIPROPSTRING);
+	prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	prop.diph.dwObj = static_cast<DWORD>(kc);
+	prop.diph.dwHow = DIPH_BYOFFSET;
+
+	if (SUCCEEDED(mKeyboard->GetProperty(DIPROP_KEYNAME, &prop.diph)))
+	{
+		// convert the WCHAR in "wsz" to multibyte
+		if (WideCharToMultiByte(CP_ACP, 0, prop.wsz, -1, temp, sizeof(temp), NULL, NULL))
+			return mGetString.assign(temp);
+	}
+
+	std::stringstream ss;
+	ss << "Key_" << (int)kc;
+	return mGetString.assign(ss.str());
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::copyKeyStates( char keys[256] ) const
+{
+	for(int i = 0; i < 256; ++i)
+		keys[i] = KeyBuffer[i] > 0; //Normalise the DX values (0x80)
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::setBuffered(bool buffered)
+{
+	if( buffered != mBuffered )
+	{
+		if(mKeyboard)
+		{
+			mKeyboard->Unacquire();
+			mKeyboard->Release();
+			mKeyboard = 0;
+		}
+		
+		mBuffered = buffered;
+		_initialize();
+	}
+}

+ 216 - 0
CamelotOISInput/Source/OIS/win32/Win32Mouse.cpp

@@ -0,0 +1,216 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OIS/win32/Win32Mouse.h"
+#include "OIS/win32/Win32InputManager.h"
+#include "OIS/OISException.h"
+#include "OIS/OISEvents.h"
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------------------------//
+Win32Mouse::Win32Mouse( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings )
+	: Mouse(creator->inputSystemName(), buffered, 0, creator)
+{
+	mMouse = 0;
+	mDirectInput = pDI;
+	coopSetting = coopSettings;
+	mHwnd = 0;
+
+	static_cast<Win32InputManager*>(mCreator)->_setMouseUsed(true);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Mouse::_initialize()
+{
+	DIPROPDWORD dipdw;
+
+	//Clear old state
+	mState.clear();
+
+    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
+    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+    dipdw.diph.dwObj        = 0;
+    dipdw.diph.dwHow        = DIPH_DEVICE;
+	dipdw.dwData            = MOUSE_DX_BUFFERSIZE;
+	
+	if( FAILED(mDirectInput->CreateDevice(GUID_SysMouse, &mMouse, NULL)) )
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to create device" );
+
+	if( FAILED(mMouse->SetDataFormat(&c_dfDIMouse2)) )
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set format" );
+	
+	mHwnd = ((Win32InputManager*)mCreator)->getWindowHandle();
+
+	if( FAILED(mMouse->SetCooperativeLevel(mHwnd, coopSetting)) )
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set coop level" );
+	
+	if( FAILED(mMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph )) )
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set property" );
+
+	HRESULT hr = mMouse->Acquire();
+	if (FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO)
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to aquire mouse!" );
+}
+
+//--------------------------------------------------------------------------------------------------//
+Win32Mouse::~Win32Mouse()
+{
+	if (mMouse)
+	{
+		mMouse->Unacquire();
+		mMouse->Release();
+		mMouse = 0;
+	}
+
+	static_cast<Win32InputManager*>(mCreator)->_setMouseUsed(false);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Mouse::capture()
+{
+	//Clear old relative values
+	mState.X.rel = mState.Y.rel = mState.Z.rel = 0;
+
+	DIDEVICEOBJECTDATA diBuff[MOUSE_DX_BUFFERSIZE];
+	DWORD entries = MOUSE_DX_BUFFERSIZE;
+
+	HRESULT hr = mMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+	if( hr != DI_OK )
+	{
+		hr = mMouse->Acquire();
+		while( hr == DIERR_INPUTLOST ) 
+			hr = mMouse->Acquire();
+
+		hr = mMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+		
+		//Perhaps the user just tabbed away, and coop settings
+		//are nonexclusive..so just ignore
+		if( FAILED(hr) )
+			return;
+	}
+
+	bool axesMoved = false;
+	//Accumulate all axis movements for one axesMove message..
+	//Buttons are fired off as they are found
+	for(unsigned int i = 0; i < entries; ++i )
+	{
+		switch( diBuff[i].dwOfs )
+		{
+			case DIMOFS_BUTTON0:
+				if(!_doMouseClick(0, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON1:
+				if(!_doMouseClick(1, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON2:
+				if(!_doMouseClick(2, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON3:
+				if(!_doMouseClick(3, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON4:
+				if(!_doMouseClick(4, diBuff[i])) return;
+				break;	
+			case DIMOFS_BUTTON5:
+				if(!_doMouseClick(5, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON6:
+				if(!_doMouseClick(6, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON7:
+				if(!_doMouseClick(7, diBuff[i])) return;
+				break;
+			case DIMOFS_X:
+				mState.X.rel += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			case DIMOFS_Y:
+				mState.Y.rel += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			case DIMOFS_Z:
+				mState.Z.rel += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			default: break;
+		} //end switch
+	}//end for
+
+	if( axesMoved )
+	{
+		if( coopSetting & DISCL_NONEXCLUSIVE )
+		{
+			//DirectInput provides us with meaningless values, so correct that
+			POINT point;
+			GetCursorPos(&point);
+			ScreenToClient(mHwnd, &point);
+			mState.X.abs = point.x;
+			mState.Y.abs = point.y;
+		}
+		else
+		{
+			mState.X.abs +=  mState.X.rel;
+			mState.Y.abs +=  mState.Y.rel;
+		}
+		mState.Z.abs +=  mState.Z.rel;
+
+		//Clip values to window
+		if( mState.X.abs < 0 )
+			mState.X.abs = 0;
+		else if( mState.X.abs > mState.width )
+			mState.X.abs = mState.width;
+		if( mState.Y.abs < 0 )
+			mState.Y.abs = 0;
+		else if( mState.Y.abs > mState.height )
+			mState.Y.abs = mState.height;
+
+		//Do the move
+		if( mListener && mBuffered )
+			mListener->mouseMoved( MouseEvent( this, mState ) );
+	}
+}
+
+//--------------------------------------------------------------------------------------------------//
+bool Win32Mouse::_doMouseClick( int mouseButton, DIDEVICEOBJECTDATA& di )
+{
+	if( di.dwData & 0x80 )
+	{
+		mState.buttons |= 1 << mouseButton; //turn the bit flag on
+		if( mListener && mBuffered )
+			return mListener->mousePressed( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
+	}
+	else
+	{
+		mState.buttons &= ~(1 << mouseButton); //turn the bit flag off
+		if( mListener && mBuffered )
+			return mListener->mouseReleased( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
+	}
+
+	return true;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Mouse::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}

+ 373 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMote.cpp

@@ -0,0 +1,373 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OISWiiMote.h"
+#include "OISWiiMoteFactoryCreator.h"
+#include "OISException.h"
+#include "OISWiiMoteForceFeedback.h"
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <limits.h>
+
+using namespace OIS;
+
+//-----------------------------------------------------------------------------------//
+WiiMote::WiiMote(InputManager* creator, int id, bool buffered, WiiMoteFactoryCreator* local_creator) :
+	JoyStick("cWiiMote", buffered, id, creator),
+	mWiiCreator(local_creator),
+	mtInitialized(false),
+	mRingBuffer(OIS_WII_EVENT_BUFFER),
+	mtLastButtonStates(0),
+	mtLastPOVState(0),
+	mtLastX(0.0f),
+	mtLastY(1.0f),
+	mtLastZ(0.0f),
+	mtLastNunChuckX(0.0f),
+	mtLastNunChuckY(1.0f),
+	mtLastNunChuckZ(0.0f),
+	mLastNunChuckXAxis(0),
+	mLastNunChuckYAxis(0),
+	_mWiiMoteMotionDelay(5),
+	mRumble(0)
+{
+	mRumble = new WiiMoteForceFeedback(mWiiMote);
+}
+
+//-----------------------------------------------------------------------------------//
+WiiMote::~WiiMote()
+{
+	delete mRumble;
+
+	if( mWiiMote.IsConnected() )
+	{
+		mWiiMote.StopDataStream();
+		mWiiMote.Disconnect();
+	}
+	mWiiCreator->_returnWiiMote(mDevID);
+}
+
+//-----------------------------------------------------------------------------------//
+void WiiMote::_initialize()
+{
+	if( mWiiMote.ConnectToDevice(mDevID) == false )
+		OIS_EXCEPT(E_InputDisconnected, "Error connecting to WiiMote!");
+
+	if( mWiiMote.StartDataStream() == false )
+		OIS_EXCEPT(E_InputDisconnected, "Error starting WiiMote data stream!");
+
+	//Fill in joystick information
+	mState.mVectors.clear();
+	mState.mButtons.clear();
+	mState.mAxes.clear();
+
+	if( mWiiMote.IsNunChuckAttached() )
+	{	//Setup for WiiMote + nunChuck
+		mState.mVectors.resize(2);
+		mState.mButtons.resize(9);
+		mState.mAxes.resize(2);
+		mState.mAxes[0].absOnly = true;
+		mState.mAxes[1].absOnly = true;
+	}
+	else
+	{	//Setup for WiiMote
+		mState.mVectors.resize(1);
+		mState.mButtons.resize(7);
+	}
+
+	mPOVs = 1;
+	mState.clear();
+	mtInitialized = true;
+}
+
+//-----------------------------------------------------------------------------------//
+void WiiMote::_threadUpdate()
+{
+	//Leave early if nothing is setup yet
+	if( mtInitialized == false )
+		return;
+
+	//Oops, no room left in ring buffer.. have to wait for client app to call Capture()
+	if( mRingBuffer.GetWriteAvailable() == 0 )
+		return;
+
+	WiiMoteEvent newEvent;
+	newEvent.clear();
+
+	//Update read
+	mWiiMote.HeartBeat();
+
+	//Get & check current button states
+	const cWiiMote::tButtonStatus &bState = mWiiMote.GetLastButtonStatus();
+	_doButtonCheck(bState.m1, 0, newEvent.pushedButtons, newEvent.releasedButtons);	//1
+	_doButtonCheck(bState.m2, 1, newEvent.pushedButtons, newEvent.releasedButtons);	//2
+	_doButtonCheck(bState.mA, 2, newEvent.pushedButtons, newEvent.releasedButtons);	//A
+	_doButtonCheck(bState.mB, 3, newEvent.pushedButtons, newEvent.releasedButtons);	//B
+	_doButtonCheck(bState.mPlus, 4, newEvent.pushedButtons, newEvent.releasedButtons);//+
+	_doButtonCheck(bState.mMinus, 5, newEvent.pushedButtons, newEvent.releasedButtons);//-
+	_doButtonCheck(bState.mHome, 6, newEvent.pushedButtons, newEvent.releasedButtons);//Home
+
+	//Check POV
+	newEvent.povChanged = _doPOVCheck(bState, newEvent.povDirection);
+
+	//Do motion check on main orientation - accounting for sensitivity factor
+	mWiiMote.GetCalibratedAcceleration(newEvent.x, newEvent.y, newEvent.z);
+	//Normalize new vector (old vector is already normalized)
+	float len = sqrt((newEvent.x*newEvent.x) + (newEvent.y*newEvent.y) + (newEvent.z*newEvent.z));
+	newEvent.x /= len;
+	newEvent.y /= len;
+	newEvent.z /= len;
+	
+	//Get new angle
+	float angle = acos((newEvent.x * mtLastX) + (newEvent.y * mtLastY) + (newEvent.z * mtLastZ));
+	if( angle > (mVector3Sensitivity * (M_PI / 180.0)) )
+	{	//Store for next check
+		mtLastX = newEvent.x;
+		mtLastY = newEvent.y;
+		mtLastZ = newEvent.z;
+
+		if( _mWiiMoteMotionDelay <= 0 )
+			newEvent.movement = true; //Set flag as moved
+		else
+			--_mWiiMoteMotionDelay;
+	}
+
+	//Act on NunChuck Data
+	if( mWiiMote.IsNunChuckAttached() )
+	{
+		const cWiiMote::tChuckReport &bState = mWiiMote.GetLastChuckReport();
+		_doButtonCheck(bState.mButtonC, 7, newEvent.pushedButtons, newEvent.releasedButtons); //C
+		_doButtonCheck(bState.mButtonZ, 8, newEvent.pushedButtons, newEvent.releasedButtons); //Z
+
+		mWiiMote.GetCalibratedChuckAcceleration(newEvent.nunChuckx, newEvent.nunChucky, newEvent.nunChuckz);
+		//Normalize new vector (old vector is already normalized)
+		float len = sqrt((newEvent.nunChuckx*newEvent.nunChuckx) + 
+			             (newEvent.nunChucky*newEvent.nunChucky) +
+						 (newEvent.nunChuckz*newEvent.nunChuckz));
+
+		newEvent.nunChuckx /= len;
+		newEvent.nunChucky /= len;
+		newEvent.nunChuckz /= len;
+
+		float angle = acos((newEvent.nunChuckx * mtLastNunChuckX) + 
+			               (newEvent.nunChucky * mtLastNunChuckY) +
+						   (newEvent.nunChuckz * mtLastNunChuckZ));
+
+		if( angle > (mVector3Sensitivity * (M_PI / 180.0)) )
+		{	//Store for next check
+			mtLastNunChuckX = newEvent.nunChuckx;
+			mtLastNunChuckY = newEvent.nunChucky;
+			mtLastNunChuckZ = newEvent.nunChuckz;
+
+			if( _mWiiMoteMotionDelay <= 0 )
+				newEvent.movementChuck = true;
+		}
+
+		//Ok, Now check both NunChuck Joystick axes for movement
+		float tempX = 0.0f, tempY = 0.0f;
+		mWiiMote.GetCalibratedChuckStick(tempX, tempY);
+		
+		//Convert to int and clip
+		newEvent.nunChuckXAxis = (int)(tempX * JoyStick::MAX_AXIS);
+		if( newEvent.nunChuckXAxis > JoyStick::MAX_AXIS )
+			newEvent.nunChuckXAxis = JoyStick::MAX_AXIS;
+		else if( newEvent.nunChuckXAxis < JoyStick::MIN_AXIS )
+			newEvent.nunChuckXAxis = JoyStick::MIN_AXIS;
+
+		newEvent.nunChuckYAxis = (int)(tempY * JoyStick::MAX_AXIS);
+		if( newEvent.nunChuckYAxis > JoyStick::MAX_AXIS )
+			newEvent.nunChuckYAxis = JoyStick::MAX_AXIS;
+		else if( newEvent.nunChuckYAxis < JoyStick::MIN_AXIS )
+			newEvent.nunChuckYAxis = JoyStick::MIN_AXIS;
+
+		//Apply a little dead-zone dampner
+		int xDiff = newEvent.nunChuckXAxis - mLastNunChuckXAxis;
+		if( xDiff > 1500 || xDiff < -1500 )
+		{
+			mLastNunChuckXAxis = newEvent.nunChuckXAxis;
+			newEvent.nunChuckXAxisMoved = true;
+		}
+
+		int yDiff = newEvent.nunChuckYAxis - mLastNunChuckYAxis;
+		if( yDiff > 1500 || yDiff < -1500 )
+		{
+			mLastNunChuckYAxis = newEvent.nunChuckYAxis;
+			newEvent.nunChuckYAxisMoved = true;
+		}
+	}
+
+	//Ok, put entry in ringbuffer if something changed
+	if(newEvent.pushedButtons || newEvent.releasedButtons || newEvent.povChanged || newEvent.movement ||
+	   newEvent.movementChuck || newEvent.nunChuckXAxisMoved || newEvent.nunChuckYAxisMoved)
+	{
+		mRingBuffer.Write(&newEvent, 1);
+	}
+
+	//mWiiMote.PrintStatus();
+}
+
+//-----------------------------------------------------------------------------------//
+void WiiMote::_doButtonCheck(bool new_state, int ois_button, unsigned int &pushed, unsigned int &released)
+{
+	const bool old_state = ((mtLastButtonStates & ( 1L << ois_button )) == 0) ? false : true;
+	
+	//Check to see if new state and old state are the same, and hence, need no change
+	if( new_state == old_state )
+		return;
+
+	//Ok, so it changed... but how?
+	if( new_state )
+	{	//Ok, new state is pushed, old state was not pushed.. so send button press
+		mtLastButtonStates |= 1 << ois_button; //turn the bit flag on
+		pushed |= 1 << ois_button;
+	}
+	else
+	{	//Ok, so new state is not pushed, and old state was pushed.. So, send release
+		mtLastButtonStates &= ~(1 << ois_button); //turn the bit flag off
+		released |= 1 << ois_button;
+	}
+}
+
+//-----------------------------------------------------------------------------------//
+bool WiiMote::_doPOVCheck(const cWiiMote::tButtonStatus &bState, unsigned int &newPosition)
+{
+	newPosition = Pov::Centered;
+
+	if( bState.mUp )
+		newPosition |= Pov::North;
+	else if( bState.mDown )
+		newPosition |= Pov::South;
+
+	if( bState.mLeft )
+		newPosition |= Pov::West;
+	else if( bState.mRight )
+		newPosition |= Pov::East;
+
+	//Was there a change?
+	if( mtLastPOVState != newPosition )
+	{
+		mtLastPOVState = newPosition;
+		return true;
+	}
+
+	return false;
+}
+
+//-----------------------------------------------------------------------------------//
+void WiiMote::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//-----------------------------------------------------------------------------------//
+void WiiMote::capture()
+{
+	//Anything to read?
+	int entries = mRingBuffer.GetReadAvailable();
+	if( entries <= 0 )
+		return;
+
+	WiiMoteEvent events[OIS_WII_EVENT_BUFFER];
+	if( entries > OIS_WII_EVENT_BUFFER )
+		entries = OIS_WII_EVENT_BUFFER;
+	
+	mRingBuffer.Read(events, entries);
+
+	//Loop through each event
+	for( int i = 0; i < entries; ++i )
+	{
+		//Any movement changes in the main accellerometers?
+		if( events[i].movement )
+		{
+			mState.mVectors[0].x = events[i].x;
+			mState.mVectors[0].y = events[i].y;
+			mState.mVectors[0].z = events[i].z;
+			if( mBuffered && mListener )
+				if( !mListener->vector3Moved( JoyStickEvent( this, mState ), 0 ) ) return;
+		}
+
+		//Check NunChuck movements
+		if( events[i].movementChuck )
+		{
+			mState.mVectors[1].x = events[i].nunChuckx;
+			mState.mVectors[1].y = events[i].nunChucky;
+			mState.mVectors[1].z = events[i].nunChuckz;
+			if( mBuffered && mListener )
+				if( !mListener->vector3Moved( JoyStickEvent( this, mState ), 1 ) ) return;
+		}
+
+		if( events[i].nunChuckXAxisMoved )
+		{
+			mState.mAxes[0].abs = events[i].nunChuckXAxis;
+
+			if( mBuffered && mListener )
+				if( !mListener->axisMoved( JoyStickEvent( this, mState ), 0 ) ) return;
+		}
+
+		if( events[i].nunChuckYAxisMoved )
+		{
+			mState.mAxes[1].abs = events[i].nunChuckYAxis;
+
+			if( mBuffered && mListener )
+				if( !mListener->axisMoved( JoyStickEvent( this, mState ), 1 ) ) return;
+		}
+
+		//Has the hat swtich changed?
+		if( events[i].povChanged )
+		{
+			mState.mPOV[0].direction = events[i].povDirection;
+			if( mBuffered && mListener )
+				if( !mListener->povMoved( JoyStickEvent( this, mState ), 0 ) ) return;
+		}
+
+		//Check for any pushed/released events for each button bit
+		int buttons = (int)mState.mButtons.size();
+		for( int b = 0; b < buttons; ++b )
+		{
+			unsigned bit_flag = 1 << b;
+			if( (events[i].pushedButtons & bit_flag) != 0 )
+			{	//send event
+				mState.mButtons[b] = true;
+				if( mBuffered && mListener )
+					if( !mListener->buttonPressed( JoyStickEvent( this, mState ), b ) ) return;
+			}
+
+			if( (events[i].releasedButtons & bit_flag) != 0 )
+			{	//send event
+				mState.mButtons[b] = false;
+				if( mBuffered && mListener )
+					if( !mListener->buttonReleased( JoyStickEvent( this, mState ), b ) ) return;
+			}
+		}
+	}
+}
+
+//-----------------------------------------------------------------------------------//
+Interface* WiiMote::queryInterface(Interface::IType type)
+{
+	if( type == Interface::ForceFeedback && mtInitialized )
+		return mRumble;
+
+	return 0;
+}
+#endif

+ 89 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMote.h

@@ -0,0 +1,89 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that
+		you wrote the original software. If you use this software in a product,
+		an acknowledgment in the product documentation would be appreciated but is
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_WiiMote_H
+#define OIS_WiiMote_H
+#include "OISJoyStick.h"
+#include "OISWiiMoteRingBuffer.h"
+#include "wiimote.h"
+
+namespace OIS
+{
+	class WiiMoteFactoryCreator;
+	class WiiMoteForceFeedback;
+
+	//Number of ring buffer events. should be nice sized (the structure is not very big)
+	//Will be rounded up to power of two automatically
+	#define OIS_WII_EVENT_BUFFER 32
+
+	/**	Specialty joystick - WiiMote controller */
+	class _OISExport WiiMote : public JoyStick
+	{
+	public:
+		WiiMote(InputManager* creator, int id, bool buffered, WiiMoteFactoryCreator* local_creator);
+		~WiiMote();
+
+		//Overrides of Object
+		void setBuffered(bool buffered);
+
+		void capture();
+
+		Interface* queryInterface(Interface::IType type);
+
+		void _initialize();
+
+		void _threadUpdate();
+
+	protected:
+		void _doButtonCheck(bool new_state, int ois_button, unsigned int &pushed, unsigned int &released);
+		bool _doPOVCheck(const cWiiMote::tButtonStatus &bState, unsigned int &newPosition);
+
+		//! The creator who created us
+		WiiMoteFactoryCreator *mWiiCreator;
+
+		//! Actual WiiMote HID device
+		cWiiMote mWiiMote;
+
+		//! Used to signal thread that remote is ready
+		volatile bool mtInitialized;
+
+		//! Ringbuffer is used to store events from thread and be read from capture
+		WiiMoteRingBuffer mRingBuffer;
+
+		//Following variables are used entirely within threaded context
+		int mtLastButtonStates;
+		unsigned int mtLastPOVState;
+		float mtLastX, mtLastY, mtLastZ;
+		float mtLastNunChuckX, mtLastNunChuckY, mtLastNunChuckZ;
+		int mLastNunChuckXAxis, mLastNunChuckYAxis;
+
+		//Small workaround for slow calibration of wiimote data
+		int _mWiiMoteMotionDelay;
+
+		//Simple rumble force
+		WiiMoteForceFeedback *mRumble;
+	};
+}
+#endif //OIS_WiiMote_H
+#endif

+ 206 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteFactoryCreator.cpp

@@ -0,0 +1,206 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OISWiiMoteFactoryCreator.h"
+#include "OISException.h"
+#include "OISWiiMote.h"
+#include <assert.h>
+#include <boost/thread.hpp>   //include here, keep compilation times down
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+
+using namespace OIS;
+
+//---------------------------------------------------------------------------------//
+WiiMoteFactoryCreator::WiiMoteFactoryCreator() :
+	mVendorName("cWiiMote"),
+	mCount(0),
+	mtThreadHandler(0),
+	mtWiiMoteListMutex(0),
+	mtThreadRunning(0)
+{
+	//Discover how many Wii's there are
+	for( ; mCount < OIS_cWiiMote_MAX_WIIS; ++mCount )
+	{
+		cWiiMote wii;
+		if( wii.ConnectToDevice(mCount) == false )
+			break;
+	}
+
+	//Store how many WiiMotes there were in the form of integer handles
+	for(int i = 0; i < mCount; ++i)
+		mFreeWiis.push_back(i);
+
+	//The mutex lasts the whole life of this class. The thread does not.
+	mtWiiMoteListMutex = new boost::mutex();
+}
+
+//---------------------------------------------------------------------------------//
+WiiMoteFactoryCreator::~WiiMoteFactoryCreator()
+{
+	//Thread (once all objects destroyed) should be killed off already
+	assert( (mtThreadRunning == false && mtThreadHandler == 0) && 
+		"~WiiMoteFactoryCreator(): invalid state.. Some objects left dangling!");
+
+	delete mtWiiMoteListMutex;
+}
+
+//---------------------------------------------------------------------------------//
+DeviceList WiiMoteFactoryCreator::freeDeviceList()
+{
+	DeviceList list;
+	for( std::deque<int>::iterator i = mFreeWiis.begin(); i != mFreeWiis.end(); ++i )
+	{
+		list.insert(std::make_pair(OISJoyStick, mVendorName));
+	}
+	return list;
+}
+
+//---------------------------------------------------------------------------------//
+int WiiMoteFactoryCreator::totalDevices(Type iType)
+{
+	if( iType == OISJoyStick )
+		return mCount;
+	else
+		return 0;
+}
+
+//---------------------------------------------------------------------------------//
+int WiiMoteFactoryCreator::freeDevices(Type iType)
+{
+	if( iType == OISJoyStick )
+		return (int)mFreeWiis.size();
+	else
+		return 0;
+}
+
+//---------------------------------------------------------------------------------//
+bool WiiMoteFactoryCreator::vendorExist(Type iType, const std::string & vendor)
+{
+	if( iType == OISJoyStick && mVendorName == vendor )
+		return true;
+	else
+		return false;
+}
+
+//---------------------------------------------------------------------------------//
+Object* WiiMoteFactoryCreator::createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor)
+{
+	if( mFreeWiis.size() > 0 && (vendor == "" || vendor == mVendorName ) )
+	{
+		int id = mFreeWiis.front();
+		mFreeWiis.pop_front();
+		WiiMote *wii = new WiiMote(creator, id, bufferMode, this);
+
+		if( mtThreadRunning == false )
+		{	//Create common thread manager (this is the first wiimote created)
+			mtThreadRunning = true;
+			mtThreadHandler = new boost::thread(boost::bind(&WiiMoteFactoryCreator::_updateWiiMotesThread, this));
+		}
+		
+		//Now, add new WiiMote to thread manager for polling
+		{	//Get an auto lock on the list of active wiimotes
+			boost::mutex::scoped_lock arrayLock(*mtWiiMoteListMutex);
+			mtInUseWiiMotes.push_back(wii);
+		}
+
+		return wii;
+	}
+	else
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No Device found which matches description!");
+}
+
+//---------------------------------------------------------------------------------//
+void WiiMoteFactoryCreator::destroyObject(Object* obj)
+{
+	if( obj == 0 )
+		return;
+
+	int wiis_alive = 0;
+
+	{	//Get an auto lock on the list of active wiimotes
+		boost::mutex::scoped_lock arrayLock(*mtWiiMoteListMutex);
+
+		//Find object
+		std::vector<WiiMote*>::iterator i = std::find(mtInUseWiiMotes.begin(), mtInUseWiiMotes.end(), obj);
+		if( i == mtInUseWiiMotes.end() )
+			OIS_EXCEPT(E_General, "Device not found in wimote collection!");
+
+		//Erase opject
+		mtInUseWiiMotes.erase(i);
+
+		//Delete object
+		delete obj;
+
+		wiis_alive = (int)mtInUseWiiMotes.size();
+	}
+
+	//Destroy thread if no longer in use (we do this after unlocking mutex!)
+	if( wiis_alive == 0 && mtThreadRunning )
+	{
+		mtThreadRunning = false;
+		mtThreadHandler->join();
+		delete mtThreadHandler;
+		mtThreadHandler = 0;
+	}
+
+}
+
+//---------------------------------------------------------------------------------//
+void WiiMoteFactoryCreator::_returnWiiMote(int id)
+{	//Restore ID to controller pool
+	mFreeWiis.push_front(id);
+}
+
+//---------------------------------------------------------------------------------//
+bool WiiMoteFactoryCreator::_updateWiiMotesThread()
+{
+	boost::xtime timer;
+
+	while(mtThreadRunning)
+	{
+		int numMotes = 0;
+		{	//Get an auto lock on the list of active wiimotes
+			boost::mutex::scoped_lock arrayLock(*mtWiiMoteListMutex);
+			numMotes = (int)mtInUseWiiMotes.size();
+			for( std::vector<WiiMote*>::iterator i = mtInUseWiiMotes.begin(), e = mtInUseWiiMotes.end(); i != e; ++i )
+			{	//Update it
+				(*i)->_threadUpdate();
+			}
+		}
+
+		//ok, we have updated all wiimotes, let us rest a bit
+		//sleep time = 30 / 1000 
+		//boost::thread::sleep(xtime) todo xxx wip use sleep instead??
+		//boost::thread::yield();
+		boost::xtime_get(&timer, boost::TIME_UTC);
+		timer.nsec += 20000000; //20 000 000 ~= 1/50 sec
+		boost::thread::sleep(timer);
+	}
+
+	return true;
+}
+
+#endif

+ 103 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteFactoryCreator.h

@@ -0,0 +1,103 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_WiiMoteFactoryCreator_H
+#define OIS_WiiMoteFactoryCreator_H
+
+#include "OISPrereqs.h"
+#include "OISFactoryCreator.h"
+#include <deque>
+
+//Forward declare boost classes used
+namespace boost
+{
+	class thread;
+	class mutex;
+}
+
+namespace OIS
+{
+	//Forward declare local classes
+	class WiiMote;
+
+	//! Max amount of Wiis we will attempt to find
+	#define OIS_cWiiMote_MAX_WIIS 4
+
+	/** WiiMote Factory Creator Class */
+	class _OISExport WiiMoteFactoryCreator : public FactoryCreator
+	{
+	public:
+		WiiMoteFactoryCreator();
+		~WiiMoteFactoryCreator();
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+		//! Local method used to return controller to pool
+		void _returnWiiMote(int id);
+
+	protected:
+		//! Internal - threaded method
+		bool _updateWiiMotesThread();
+
+		//! String name of this vendor
+		std::string mVendorName;
+
+		//! queue of open wiimotes (int represents index into hid device)
+		std::deque<int> mFreeWiis;
+
+		//! Number of total wiimotes
+		int mCount;
+
+		//! Boost thread execution object (only alive when at least 1 wiimote is alive)
+		boost::thread *mtThreadHandler;
+		
+		//! Gaurds access to the Active WiiMote List
+		boost::mutex *mtWiiMoteListMutex;
+
+		//! List of created (active) WiiMotes
+		std::vector<WiiMote*> mtInUseWiiMotes;
+
+		//! Used to signal thread running or not
+		volatile bool mtThreadRunning;
+	};
+}
+#endif //OIS_WiiMoteFactoryCreator_H
+#endif

+ 76 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteForceFeedback.cpp

@@ -0,0 +1,76 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#include "OISWiiMoteForceFeedback.h"
+#include "OISEffect.h"
+
+using namespace OIS;
+
+//-----------------------------------------------------------------------------------//
+WiiMoteForceFeedback::WiiMoteForceFeedback(cWiiMote &wiiMote) : mWiiMote(wiiMote), mHandle(-1)
+{
+	//One and only supported effect
+	_addEffectTypes( OIS::Effect::ConstantForce, OIS::Effect::Constant );
+}
+
+//-----------------------------------------------------------------------------------//
+WiiMoteForceFeedback::~WiiMoteForceFeedback()
+{
+	mWiiMote.SetVibration(false);
+}
+
+//-----------------------------------------------------------------------------------//
+void WiiMoteForceFeedback::upload( const Effect* effect )
+{
+	if( effect )
+	{
+		//Multiple effects are useless, just return
+		if( mHandle != -1 || effect->_handle != -1) return;
+		
+		//Ok, so we are uploading a fresh effect
+		effect->_handle = mHandle = 1;
+
+		mWiiMote.SetVibration(true);
+	}
+}
+
+//-----------------------------------------------------------------------------------//
+void WiiMoteForceFeedback::modify( const Effect* effect )
+{
+	//Nothing to modify
+}
+
+//-----------------------------------------------------------------------------------//
+void WiiMoteForceFeedback::remove( const Effect* effect )
+{
+	//We have no effects uploaded, so just return
+	if( mHandle == -1 || effect == 0) return;
+
+	if( mHandle == effect->_handle )
+	{
+		mWiiMote.SetVibration(false);
+		mHandle = effect->_handle = -1;
+	}
+}
+#endif

+ 67 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteForceFeedback.h

@@ -0,0 +1,67 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef OIS_WiiMoteForceFeedBack_H
+#define OIS_WiiMoteForceFeedBack_H
+
+#include "OISPrereqs.h"
+#include "OISForceFeedback.h"
+#include "wiimote.h"
+
+namespace OIS
+{
+	class WiiMoteForceFeedback : public ForceFeedback
+	{
+	public:
+		WiiMoteForceFeedback(cWiiMote &wiiMote);
+		~WiiMoteForceFeedback();
+
+		/** @copydoc ForceFeedback::upload */
+		void upload( const Effect* effect );
+
+		/** @copydoc ForceFeedback::modify */
+		void modify( const Effect* effect );
+
+		/** @copydoc ForceFeedback::remove */
+		void remove( const Effect* effect );
+
+		/** @copydoc ForceFeedback::setMasterGain */
+		void setMasterGain( float level ) {}
+		
+		/** @copydoc ForceFeedback::setAutoCenterMode */
+		void setAutoCenterMode( bool auto_on ) {}
+
+		/** @copydoc ForceFeedback::getFFAxesNumber */
+		short getFFAxesNumber() { return 1; }
+
+	protected:
+		//! The WiiMote associated with this effect interface
+		cWiiMote &mWiiMote;
+
+		//! The handle of the one and only allowed effect
+		int mHandle;
+	};
+}
+#endif //OIS_WiiMoteForceFeedBack_H
+#endif

+ 0 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteRingBuffer.cpp


+ 313 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/OISWiiMoteRingBuffer.h

@@ -0,0 +1,313 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+This software is provided 'as-is', without any express or implied warranty. In no event will
+the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial 
+applications, and to alter it and redistribute it freely, subject to the following
+restrictions:
+
+    1. The origin of this software must not be misrepresented; you must not claim that 
+		you wrote the original software. If you use this software in a product, 
+		an acknowledgment in the product documentation would be appreciated but is 
+		not required.
+
+    2. Altered source versions must be plainly marked as such, and must not be 
+		misrepresented as being the original software.
+
+    3. This notice may not be removed or altered from any source distribution.
+
+ # ------------------------#
+ # Original License follows:
+ # ------------------------#
+
+ * PortAudio Portable Real-Time Audio Library
+ * Latest version at: http://www.audiomulch.com/portaudio/
+ * <platform> Implementation
+ * Copyright (c) 1999-2000 <author(s)>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef OIS_WiiMoteRingBuffer_H
+#define OIS_WiiMoteRingBuffer_H
+
+#include "OISPrereqs.h"
+
+namespace OIS
+{
+	struct WiiMoteEvent
+	{
+		//! (7 buttons) If a button was just pressed, the bit will be set
+		unsigned int pushedButtons;
+
+		//! (7 buttons) If a button was just released, the bit will be set
+		unsigned int releasedButtons;
+
+		//! Will be true if POV changed this event
+		bool povChanged;
+
+		//! Will be valid if povChanged = true
+		unsigned int povDirection;
+
+		//! Will be valid if a movement just occurred on main motion sensing
+		bool movement;
+
+		//Values of main orientation vector
+		float x, y, z;
+
+		//! Will be valid if a movement just occurred on main motion sensing
+		bool movementChuck;
+
+		//Values of main orientation vector
+		float nunChuckx, nunChucky, nunChuckz;
+
+		//Used to flag when a Nunchuck axis moved
+		bool nunChuckXAxisMoved, nunChuckYAxisMoved;
+
+		//Values of NunChuck JoyStick
+		int nunChuckXAxis, nunChuckYAxis;
+
+		//! clear initial state
+		void clear()
+		{
+			pushedButtons = releasedButtons = 0;
+			povChanged = false;
+			povDirection = 0;
+
+			movement = false;
+			x = y = z = 0.0f;
+
+			nunChuckx = nunChucky = nunChuckz = 0;
+			movementChuck = false;
+
+			nunChuckXAxisMoved = nunChuckYAxisMoved = false;
+			nunChuckXAxis = nunChuckYAxis = 0;
+		}
+	};
+
+	/// <summary>
+	/// Ring Buffer (fifo) used to store 16bit pcm data
+	/// </summary>
+	class WiiMoteRingBuffer
+	{
+	private:
+		//! Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init
+		int bufferSize;
+		//! Used for wrapping indices with extra bit to distinguish full/empty.
+		int bigMask;
+		// Used for fitting indices to buffer.
+		int smallMask;
+
+		// Buffer holding the actual event buffers
+		WiiMoteEvent *buffer;
+
+		//! Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex.
+		volatile int writeIndex; 
+		
+		//! Index of next readable byte. Set by RingBuffer_AdvanceReadIndex.
+		volatile int readIndex;	
+
+	public:
+		WiiMoteRingBuffer( unsigned int numEntries )
+		{
+			numEntries = RoundUpToNextPowerOf2( numEntries );
+
+			//2 bytes per short
+			bufferSize = (int)numEntries;
+			buffer = new WiiMoteEvent[numEntries];
+		
+			Flush();
+		
+			bigMask = (int)(numEntries*2)-1;
+			smallMask = (int)(numEntries)-1;
+		}
+
+		~WiiMoteRingBuffer()
+		{
+			delete buffer;
+		}
+
+		unsigned int RoundUpToNextPowerOf2( unsigned int n )
+		{
+			int numBits = 0;
+			if( ((n-1) & n) == 0) 
+			return n; //Already Power of two.
+
+			while( n > 0 )
+			{
+				n= n>>1;
+				numBits++;
+			}
+			return (unsigned int)(1<<numBits);
+		}
+
+
+		int GetReadAvailable( )
+		{
+			return ( (writeIndex - readIndex) & bigMask );
+		}
+
+
+		int GetWriteAvailable( )
+		{
+			return ( bufferSize - GetReadAvailable());
+		}
+
+
+		int Write( WiiMoteEvent *data, int numEntries )
+		{
+			int size1 = 0, size2 = 0, numWritten;
+			int data1Ptr = 0, data2Ptr = 0;
+			
+			numWritten = GetWriteRegions( numEntries, data1Ptr, size1, data2Ptr, size2 );
+
+			if( size2 > 0 )
+			{
+				//copy to two parts
+				memcpy( &buffer[data1Ptr], data, sizeof(WiiMoteEvent) * size1 );
+				//Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 );
+				memcpy( &buffer[data2Ptr], &data[size1], sizeof(WiiMoteEvent) * size2 );
+				//Array.Copy( data, offsetPtr + size1, buffer, data2Ptr, size2 );
+			}
+			else
+			{	//Copy all continous
+				memcpy( &buffer[data1Ptr], data, sizeof(WiiMoteEvent) * size1 );
+				//Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 );
+			}
+			AdvanceWriteIndex( numWritten );
+			return numWritten;
+		}
+
+
+		/// <summary>
+		/// Reads requested number of entries into sent array.
+		/// Returns number written
+		/// </summary>
+		int Read( WiiMoteEvent *data, int numEntries )
+		{
+			int size1 = 0, size2 = 0, numRead, data1Ptr = 0, data2Ptr = 0;
+			
+			numRead = GetReadRegions( numEntries, data1Ptr, size1, data2Ptr, size2 );
+			
+			if( size2 > 0 )
+			{
+				memcpy( data, &buffer[data1Ptr], sizeof(WiiMoteEvent) * size1 );
+				//Array.Copy( buffer, data1Ptr, data, 0, size1 );
+				memcpy( &data[size1], &buffer[data2Ptr], sizeof(WiiMoteEvent) * size2 );
+				//Array.Copy( buffer, data2Ptr, data, size1, size2 );
+			}
+			else
+				memcpy( data, &buffer[data1Ptr], sizeof(WiiMoteEvent) * size1 );
+				//Array.Copy( buffer, data1Ptr, data, 0, size1 );
+
+			AdvanceReadIndex( numRead );
+			return numRead;
+		}
+
+	private:
+
+		int GetWriteRegions( int numEntries, int &dataPtr1, int &sizePtr1,
+							 int &dataPtr2, int &sizePtr2 )
+		{
+			int   index;
+			int   available = GetWriteAvailable();
+			if( numEntries > available ) 
+				numEntries = available;
+		
+			//Check to see if write is not contiguous.
+			index = writeIndex & smallMask;
+			if( (index + numEntries) > bufferSize )
+			{
+				//Write data in two blocks that wrap the buffer.
+				int   firstHalf = bufferSize - index;
+				dataPtr1 = index;//&buffer[index];
+				sizePtr1 = firstHalf;
+				dataPtr2 = 0;//&buffer[0];
+				sizePtr2 = numEntries - firstHalf;
+			}
+			else
+			{
+				dataPtr1 = index;//&buffer[index];
+				sizePtr1 = numEntries;
+				dataPtr2 = 0;
+				sizePtr2 = 0;
+			}
+			return numEntries;
+		}
+	
+
+		int GetReadRegions( int numEntries, int &dataPtr1, int &sizePtr1, int &dataPtr2, int &sizePtr2 )
+		{
+			int   index;
+			int   available = GetReadAvailable( );
+			if( numEntries > available ) 
+				numEntries = available;
+			
+			// Check to see if read is not contiguous
+			index = readIndex & smallMask;
+			if( (index + numEntries) > bufferSize )
+			{
+				// Write data in two blocks that wrap the buffer
+				int firstHalf = bufferSize - index;
+				dataPtr1 = index;//&buffer[index];
+				sizePtr1 = firstHalf;
+				dataPtr2 = 0;//&buffer[0];
+				sizePtr2 = numEntries - firstHalf;
+			}
+			else
+			{
+				dataPtr1 = index;//&buffer[index];
+				sizePtr1 = numEntries;
+				dataPtr2 = 0;
+				sizePtr2 = 0;
+			}
+			return numEntries;
+		}
+
+
+		int AdvanceWriteIndex( int numEntries )
+		{
+			 return writeIndex = (writeIndex + numEntries) & bigMask;
+		}
+
+
+		int AdvanceReadIndex( int numEntries )
+		{
+			return readIndex = (readIndex + numEntries) & bigMask;
+		}
+
+
+		void Flush( )
+		{
+			writeIndex = readIndex = 0;
+		}
+	};
+}
+#endif //#define OIS_WiiMoteRingBuffer_H
+#endif

+ 205 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/hiddevice.cpp

@@ -0,0 +1,205 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+//cWiimote 0.2 by Kevin Forbes (http://simulatedcomicproduct.com)
+//This code is public domain, and comes with no warranty. The user takes full responsibility for anything that happens as a result from using this code.
+//This was based in part on Alan Macek <www.alanmacek.com>'s USB interface library
+
+//Edited for Toshiba Stack support (hopefully also all others) by 
+//Sean Stellingwerff (http://sean.stellingwerff.com) using information
+//gathered from http://www.lvr.com/hidpage.htm (Thanks a million! :D) 
+
+//#include "stdafx.h"
+#include "hiddevice.h"
+
+extern "C" 
+{
+	#include "hidsdi.h"
+	#include <Setupapi.h>
+}
+#pragma comment(lib, "setupapi.lib")
+#pragma comment(lib, "hid.lib")
+
+HIDP_CAPS							Capabilities;
+PSP_DEVICE_INTERFACE_DETAIL_DATA	detailData;
+
+cHIDDevice::cHIDDevice() : mConnected(false), mHandle(NULL), mEvent(NULL)
+{
+}
+
+
+cHIDDevice::~cHIDDevice()
+{
+	if (mConnected)
+	{
+		Disconnect();
+	}
+}
+
+bool cHIDDevice::Disconnect()
+{
+	bool retval = false;
+	if (mConnected)
+	{
+		retval = (CloseHandle(mHandle) == TRUE && CloseHandle(mEvent) == TRUE);
+	
+		mConnected = false;
+	}
+
+	return retval;
+}
+
+bool cHIDDevice::Connect(unsigned short device_id, unsigned short vendor_id, int index)
+{
+	if (mConnected)
+	{
+		if (!Disconnect())
+		{
+			return false;
+		}
+	}
+
+	// Find the wiimote(s)
+	//for (int i = 0; i <= index; i++)
+	OpenDevice( device_id, vendor_id, index );
+
+	return mConnected;
+}
+
+bool cHIDDevice::OpenDevice(unsigned short device_id, unsigned short vendor_id, int index)
+{
+	//Use a series of API calls to find a HID with a specified Vendor IF and Product ID.
+	HIDD_ATTRIBUTES						Attributes;
+	SP_DEVICE_INTERFACE_DATA			devInfoData;
+	bool								LastDevice = FALSE;
+	bool								MyDeviceDetected = FALSE; 
+	int									MemberIndex = 0;
+	int									MembersFound = 0;
+	GUID								HidGuid;
+	ULONG								Length;
+	LONG								Result;
+	HANDLE								hDevInfo;
+	ULONG								Required;
+
+	Length = 0;
+	detailData = NULL;
+	mHandle=NULL;
+
+	HidD_GetHidGuid(&HidGuid);	
+	hDevInfo=SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
+		
+	devInfoData.cbSize = sizeof(devInfoData);
+
+	MemberIndex = 0;
+	MembersFound = 0;
+	LastDevice = FALSE;
+
+	do
+	{
+		Result=SetupDiEnumDeviceInterfaces(hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData);
+		if (Result != 0)
+		{
+			Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL);
+
+			detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
+			detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+			Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length, &Required, NULL);
+
+			mHandle=CreateFile(detailData->DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL);
+			Attributes.Size = sizeof(Attributes);
+
+			Result = HidD_GetAttributes(mHandle, &Attributes);
+			//Is it the desired device?
+
+			MyDeviceDetected = FALSE;
+
+			if (Attributes.VendorID == vendor_id)
+			{
+				if (Attributes.ProductID == device_id)
+				{
+					if (MembersFound == index)
+					{
+						//Both the Vendor ID and Product ID match.
+						//printf("Wiimote found!\n");
+						mConnected = true;
+						GetCapabilities();
+
+						WriteHandle=CreateFile(detailData->DevicePath, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL);
+						MyDeviceDetected = TRUE;
+
+						PrepareForOverlappedTransfer();
+
+						mEvent = CreateEvent(NULL, TRUE, TRUE, "");
+						mOverlapped.Offset = 0;
+						mOverlapped.OffsetHigh = 0;
+						mOverlapped.hEvent = mEvent;
+					
+					} else { 
+						//The Product ID doesn't match.
+						CloseHandle(mHandle);
+					}
+
+					MembersFound++;
+				}
+			} else {
+				CloseHandle(mHandle);
+			}
+			free(detailData);
+		} else {
+			LastDevice=TRUE;
+		}
+		MemberIndex = MemberIndex + 1;
+	} while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
+
+	SetupDiDestroyDeviceInfoList(hDevInfo);
+	return MyDeviceDetected;
+}
+
+bool cHIDDevice::WriteToDevice(unsigned const char * OutputReport, int num_bytes)
+{
+	bool retval = false;
+	if (mConnected)
+	{
+		DWORD bytes_written;
+		retval = (WriteFile( WriteHandle, OutputReport, num_bytes, &bytes_written, &mOverlapped) == TRUE); 
+		retval = retval && bytes_written == num_bytes;
+	}
+	return retval;
+}
+
+void cHIDDevice::PrepareForOverlappedTransfer()
+{
+	//Get a handle to the device for the overlapped ReadFiles.
+	ReadHandle=CreateFile(detailData->DevicePath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+}
+
+void cHIDDevice::GetCapabilities()
+{
+	//Get the Capabilities structure for the device.
+	PHIDP_PREPARSED_DATA PreparsedData;
+	HidD_GetPreparsedData(mHandle, &PreparsedData);
+	HidP_GetCaps(PreparsedData, &Capabilities);
+
+	//No need for PreparsedData any more, so free the memory it's using.
+	HidD_FreePreparsedData(PreparsedData);
+}
+
+bool cHIDDevice::ReadFromDevice(unsigned const char * buffer, int max_bytes, int & bytes_read, int timeout)
+{
+	bool retval = false;
+	if (mConnected)
+	{
+		ReadFile( ReadHandle, (LPVOID)buffer,max_bytes,(LPDWORD)&bytes_read,(LPOVERLAPPED) &mOverlapped); 
+		DWORD Result = WaitForSingleObject(mEvent, timeout);
+		if (Result == WAIT_OBJECT_0) 
+		{		
+			retval = true;
+		}
+		else 
+		{
+			CancelIo(mHandle);			
+		}
+		ResetEvent(mEvent);
+	}
+	return retval;
+}
+#endif

+ 41 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/hiddevice.h

@@ -0,0 +1,41 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+//cWiimote 0.2 by Kevin Forbes (http://simulatedcomicproduct.com)
+//This code is public domain, and comes with no warranty. The user takes full responsibility for anything that happens as a result from using this code.
+
+#ifndef HIDDEVICE_H
+#define HIDDEVICE_H
+
+#include <windows.h>
+
+class cHIDDevice
+{
+public:
+	cHIDDevice();
+	~cHIDDevice();
+	bool Disconnect();
+	bool Connect(unsigned short device_id, unsigned short vendor_id, int index=0);
+	bool IsConnected() const {return mConnected;}
+
+	bool WriteToDevice(unsigned const char * OutputReport, int num_bytes);
+	bool ReadFromDevice(unsigned const char * buffer, int max_bytes, int & bytes_read, int timeout=50);
+private:
+
+	//bool OpenDevice(int index, unsigned short device_id, unsigned short vendor_id);
+	bool OpenDevice(unsigned short device_id, unsigned short vendor_id, int index);
+	//bool FindWiimote();
+	void GetCapabilities();
+	void PrepareForOverlappedTransfer();
+	
+	HANDLE mHandle;
+	HANDLE mEvent;
+	HANDLE WriteHandle;
+	HANDLE ReadHandle;
+	OVERLAPPED mOverlapped;
+	OVERLAPPED HIDOverlapped;
+//	HIDP_CAPS Capabilities;
+	bool mConnected;
+
+};
+#endif
+#endif

+ 45 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/main.cpp

@@ -0,0 +1,45 @@
+//cWiimote 0.2 by Kevin Forbes (http://simulatedcomicproduct.com)
+//This code is public domain, and comes with no warranty. The user takes full responsibility for anything that happens as a result from using this code.
+
+//#include "wiimote.h"
+//#include <stdio.h>
+
+//Features:
+// Read Accelerometer, button values from the wiimote
+// Read Accelerometer, stick, and button values from the nunchuck
+// Preliminary IR support
+
+//Known issues:
+// The IR support is spotty at best. It tends to kick out if you plug your 'chuck in and out too many times
+// Reading 'chuck calibration data doesn't seem to work, so the code just uses defaults
+// Multiple Wiimote support not yet tested
+// May only work with Bluesoleil stack?
+
+//Instructions:
+// See below for how to connect to a device and start the data stream.
+// It is up to the user to call heartbeat fast enough - if you're too slow, you will loose data. Ideally, this would be done in a separate thread
+// There are several public functions for getting the values from the wiimote. Look in cWiiMote::PrintStatus for examples.
+
+//Version History:
+//0.1 Preliminary Release
+//0.2 Added nunchuck, IR support
+
+/*
+int main(int nargs, const char * cargs)
+{
+	cWiiMote wiimote;
+	
+	if (wiimote.ConnectToDevice() &&
+		wiimote.StartDataStream())
+	{
+		for (;;)
+		{
+			wiimote.HeartBeat();
+			wiimote.PrintStatus();
+		}
+	}
+	return 0;
+}
+*/
+
+//#eof "$Id: main.cpp,v 1.1.2.1 2008/02/14 03:33:36 pjcast Exp $"

+ 794 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/wiimote.cpp

@@ -0,0 +1,794 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+//cWiimote 0.2 by Kevin Forbes (http://simulatedcomicproduct.com)
+//This code is public domain, and comes with no warranty. The user takes full responsibility for anything that happens as a result from using this code.
+
+//Edited for Toshiba Stack support (hopefully also all others) by 
+//Sean Stellingwerff (http://sean.stellingwerff.com) using information
+//gathered from http://www.lvr.com/hidpage.htm (Thanks a million! :D) 
+
+//#include "stdafx.h"
+#include "wiimote.h"
+#include <stdio.h>
+
+//output channels
+const unsigned char OUTPUT_CHANNEL_FORCE_FEEDBACK = 0x13;
+const unsigned char OUTPUT_CHANNEL_LED = 0x11;
+const unsigned char OUTPUT_CHANNEL_REPORT = 0x12;
+const unsigned char OUTPUT_READ_MEMORY = 0x17;
+const unsigned char OUTPUT_WRITE_MEMORY = 0x16;
+
+const unsigned char OUTPUT_ENABLE_IR = 0x13;
+const unsigned char OUTPUT_ENABLE_IR2 = 0x1a;
+
+//report request types
+const unsigned char REQUEST_CONTINUOUS_REPORTS = 0x4;
+const unsigned char REQUEST_SINGLE_REPORTS = 0x0;
+
+//input channels
+const unsigned char INPUT_CHANNEL_BUTTONS_ONLY = 0x30;
+const unsigned char INPUT_CHANNEL_BUTTONS_MOTION = 0x31;
+const unsigned char INPUT_CHANNEL_WRITE_CONFIRM = 0x22;
+const unsigned char INPUT_CHANNEL_EXPANSION_PORT = 0x20;
+
+const unsigned char INPUT_CHANNEL_MOTION_IR = 0x33;
+const unsigned char INPUT_CHANNEL_MOTION_CHUCK_IR = 0x37;
+const unsigned char INPUT_CHANNEL_MOTION_CHUCK = 0x35;
+
+//the ID values for a wiimote
+const unsigned short mVendorID = 0x057E;
+const unsigned short mDeviceID = 0x0306;
+
+//how to find the calibration data for the wiimote
+const unsigned short CALIBRATION_ADDRESS = 0x16;
+const unsigned short CALIBRATION_DATA_LENGTH = 7;
+
+//nunchuck constants
+const unsigned long NUNCHUCK_STATUS_ADDRESS = 0x04A40000;
+const unsigned long NUNCHUCK_CALIBRATION_ADDRESS = 0x04A40020;
+const unsigned long NUNCHUCK_CALIBRATION_ADDRESS_2 = 0x04A40030;
+const unsigned long NUNCHUCK_INIT_ADDRESS= 0x04A40040;
+const unsigned long NUNCHUK_ID_ADDRESS = 0x04a400f0;
+const unsigned char NUNCHUCK_INIT_VAL= 0x0;
+
+//IR constants
+const unsigned long IR_REG_1 = 0x04b00030;
+const unsigned long IR_REG_2 = 0x04b00033;
+const unsigned long IR_SENS_ADDR_1 = 0x04b00000;
+const unsigned long IR_SENS_ADDR_2 = 0x04b0001a;
+
+const unsigned char IR_SENS_MIDRANGE_PART1[] = {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0xaa, 0x00, 0x64};
+const unsigned char IR_SENS_MIDRANGE_PART2[] = {0x63, 0x03};
+
+const unsigned char IR_MODE_OFF = 0;
+const unsigned char IR_MODE_STD = 1;
+const unsigned char IR_MODE_EXP = 3;
+const unsigned char IR_MODE_FULL = 5;
+
+cWiiMote::cWiiMote()
+{
+	Init();
+}
+
+cWiiMote::~cWiiMote()
+{
+	Disconnect();
+}
+
+void cWiiMote::Init()
+{
+	mReportMode = REPORT_MODE_EVENT_BUTTONS;
+	mLastButtonStatus.Init();
+	mLastExpansionReport.Init();
+	mLastMotionReport.Init();
+	mOutputControls.Init();
+	mReadInfo.Init();
+	mAccelCalibrationData.Init();
+	mNunchuckAccelCalibrationData.Init();
+	mNunchuckStickCalibrationData.Init();
+	mLastIRReport.Init();
+	mNunchuckAttached = false;
+	mIRRunning = false;
+	mDataStreamRunning = false;
+}
+
+bool cWiiMote::SetReportMode(eReportMode mode)
+{
+	mReportMode = mode;
+	return SendReportMode();
+}
+
+bool cWiiMote::SendReportMode()
+{
+	bool continuous = true;
+	unsigned char channel = INPUT_CHANNEL_BUTTONS_ONLY;
+	bool check_chuck = false;
+	
+	switch (mReportMode)
+	{
+	case REPORT_MODE_MOTION_IR:
+		channel = INPUT_CHANNEL_MOTION_IR;
+		break;
+	case REPORT_MODE_MOTION_CHUCK_IR:
+		channel = INPUT_CHANNEL_MOTION_CHUCK_IR;
+		check_chuck = true;
+		break;
+	case REPORT_MODE_MOTION_CHUCK:
+		channel = INPUT_CHANNEL_MOTION_CHUCK;
+		check_chuck = true;
+		break;
+	case REPORT_MODE_MOTION:
+		channel = INPUT_CHANNEL_BUTTONS_MOTION;
+		break;
+	case REPORT_MODE_EVENT_BUTTONS:
+		channel = INPUT_CHANNEL_BUTTONS_ONLY;
+		continuous = false;
+		break;
+	default:
+		break;
+	}
+
+	//check to make sure that there is a chuck attached
+//	if (check_chuck && !mNunchuckAttached)
+//	{
+//		printf("Supposed to check for nunchuck, but couldn't find one!");
+//		return false;
+//	}
+
+	bool retval = SelectInputChannel(continuous,channel);
+	return retval;
+}
+
+bool cWiiMote::ConnectToDevice(int index)
+{
+	Init();
+	const bool retval = mHIDDevice.Connect(mDeviceID,mVendorID,index) && 
+						SetReportMode(REPORT_MODE_MOTION_CHUCK_IR) && 
+						UpdateOutput() &&
+						ReadCalibrationData();
+
+	if (retval)
+	{
+		InitNunchuck();
+	}
+	return retval;
+}
+
+bool cWiiMote::Disconnect()
+{
+	bool retval = false;
+	StopDataStream();
+	
+	if (mHIDDevice.IsConnected())
+	{
+		retval = mHIDDevice.Disconnect();
+	}
+
+	return retval;
+}
+
+bool cWiiMote::SetVibration(bool vib_on)
+{
+	bool retval = true;
+	if (mOutputControls.mVibration != vib_on)
+	{
+		mOutputControls.mVibration = vib_on;
+		retval = UpdateOutput();
+	}
+	return retval;
+}
+
+void cWiiMote::ClearBuffer()
+{
+	memset(mOutputBuffer,0, mOutputBufferSize);
+}
+
+bool cWiiMote::SetLEDs(bool led1, bool led2, bool led3, bool led4)
+{
+	const bool no_change = mOutputControls.mLED1 == led1 &&
+							mOutputControls.mLED2 == led2 &&
+							mOutputControls.mLED3 == led3 &&
+							mOutputControls.mLED4 == led4;
+
+	if (no_change)
+	{
+		return true;
+	}
+
+	mOutputControls.mLED1 = led1;
+	mOutputControls.mLED2 = led2;	
+	mOutputControls.mLED3 = led3;
+	mOutputControls.mLED4 = led4;
+	return UpdateOutput();
+}
+
+bool cWiiMote::UpdateOutput()
+{
+	ClearBuffer();
+	mOutputBuffer[0] = OUTPUT_CHANNEL_LED;
+	mOutputBuffer[1] =  (mOutputControls.mVibration ? 0x1 : 0x0) |
+						(mOutputControls.mLED1 ? 0x1 : 0x0) << 4 | 
+						(mOutputControls.mLED2 ? 0x1 : 0x0) << 5 | 
+						(mOutputControls.mLED3 ? 0x1 : 0x0) << 6 | 
+						(mOutputControls.mLED4 ? 0x1 : 0x0) << 7; 
+	return mHIDDevice.WriteToDevice(mOutputBuffer,mOutputBufferSize);
+}
+
+bool cWiiMote::HeartBeat(int timeout)
+{
+	bool retval = true;
+	int bytes_read = 0;
+	
+
+	//most of these reports aren't implemented yet. I don't have a sensor bar or a nunchuck :)
+	if (mHIDDevice.ReadFromDevice(mInputBuffer,mInputBufferSize,bytes_read) && (bytes_read > 0,timeout))
+	{
+		const int channel = mInputBuffer[0];
+		switch (channel)
+		{
+			case INPUT_CHANNEL_EXPANSION_PORT:// 	 6 	Expansion Port change
+				{
+					ParseButtonReport(&mInputBuffer[1]);
+					ParseExpansionReport(&mInputBuffer[2]);
+					bool restart = mDataStreamRunning;
+					StopDataStream();
+					InitNunchuck();
+					
+					if (restart)
+					{
+						retval = StartDataStream();
+					}
+				}
+			break;
+
+			case INPUT_CHANNEL_BUTTONS_ONLY:// 	2 	Buttons only
+				ParseButtonReport(&mInputBuffer[1]);
+			break;
+
+			case 0x21:// 	21 	Read data
+				ParseButtonReport(&mInputBuffer[1]);
+				ParseReadData(&mInputBuffer[3]);
+				break;
+
+			case INPUT_CHANNEL_WRITE_CONFIRM:// 	4 	Write data
+			break;
+
+			case 0x31:// 	5 	Buttons | Motion Sensing Report
+				ParseButtonReport(&mInputBuffer[1]);
+				ParseMotionReport(&mInputBuffer[3]);
+			break;
+
+			case 0x32:// 	16 	Buttons | Expansion Port | IR??
+				ParseButtonReport(&mInputBuffer[1]);
+			break;
+
+			case INPUT_CHANNEL_MOTION_IR:
+				ParseButtonReport(&mInputBuffer[1]);
+				ParseMotionReport(&mInputBuffer[3]);
+				ParseIRReport(&mInputBuffer[6]);
+			break;
+
+			case INPUT_CHANNEL_MOTION_CHUCK_IR:
+				ParseButtonReport(&mInputBuffer[1]);
+				ParseMotionReport(&mInputBuffer[3]);
+				ParseIRReport(&mInputBuffer[6]);
+				ParseChuckReport(&mInputBuffer[16]);
+			break;
+
+			case INPUT_CHANNEL_MOTION_CHUCK:
+				ParseButtonReport(&mInputBuffer[1]);
+				ParseMotionReport(&mInputBuffer[3]);
+				ParseChuckReport(&mInputBuffer[6]);
+
+			break;
+
+			case 0x34:// 	21 	Buttons | Expansion Port | IR??
+			case 0x3d:// 	21 	Buttons | Expansion Port | IR??
+				ParseButtonReport(&mInputBuffer[1]);
+			break;
+
+			case 0x3e:// 	21 	Buttons | Motion Sensing Report | IR??
+			case 0x3f:// 	21 	Buttons | Motion Sensing Report | IR??
+				ParseButtonReport(&mInputBuffer[1]);
+			break;
+			default:
+				retval = false;
+				//unknown report
+			break;
+		}		
+	}
+	return retval;
+}
+
+void cWiiMote::ParseExpansionReport(const unsigned char *data)
+{
+	//four bytes long
+	mLastExpansionReport.mAttachmentPluggedIn = (data[0] & 0x02) != 0;
+	mLastExpansionReport.mIREnabled = (data[0] & 0x08) != 0;
+	mLastExpansionReport.mSpeakerEnabled = (data[0] & 0x04) != 0;
+	mLastExpansionReport.mLED1On = (data[0] & 0x10) != 0;
+	mLastExpansionReport.mLED2On = (data[0] & 0x20) != 0;
+	mLastExpansionReport.mLED3On = (data[0] & 0x40) != 0;
+	mLastExpansionReport.mLED4On = (data[0] & 0x80) != 0;
+	
+	//two unknown bytes
+	mLastExpansionReport.mBatteryLevel = data[3];
+}
+
+void cWiiMote::ParseButtonReport(const unsigned char * data)
+{
+	//two bytes long
+	mLastButtonStatus.mA = (data[1] & 0x08) != 0;
+ 	mLastButtonStatus.mB = (data[1] & 0x04) != 0;
+ 	mLastButtonStatus.m1 = (data[1] & 0x02) != 0;
+ 	mLastButtonStatus.m2 = (data[1] & 0x01) != 0;
+ 	mLastButtonStatus.mPlus = (data[0] & 0x10) != 0;
+ 	mLastButtonStatus.mMinus = (data[1] & 0x10) != 0;
+ 	mLastButtonStatus.mHome = (data[1] & 0x80) != 0;
+ 	mLastButtonStatus.mUp = (data[0] & 0x08) != 0;
+ 	mLastButtonStatus.mDown = (data[0] & 0x04) != 0;
+ 	mLastButtonStatus.mLeft = (data[0] & 0x01) != 0;
+ 	mLastButtonStatus.mRight = (data[0] & 0x02) != 0;
+}
+
+void cWiiMote::ParseMotionReport(const unsigned char * data)
+{
+	//three bytes long
+	mLastMotionReport.mX = data[0];
+	mLastMotionReport.mY = data[1];
+	mLastMotionReport.mZ = data[2];
+}
+
+void cWiiMote::PrintStatus() const
+{
+	float wX,wY,wZ;
+	float cX,cY,cZ;
+	float sX,sY;
+	float irX,irY;
+	
+	wX =wY=wZ=cX=cY=cZ=sX=sY=irX=irY=0.f;
+
+	GetCalibratedAcceleration(wX,wY,wZ);
+	printf("W:[%+1.2f %+1.2f %+1.2f] ",wX,wY,wZ);
+
+	if (mNunchuckAttached)
+	{
+		GetCalibratedChuckAcceleration(cX,cY,cZ);
+		printf("N:[%+1.2f %+1.2f %+1.2f] ",cX,cY,cZ);
+
+		GetCalibratedChuckStick(sX,sY);
+		printf("S:[%+1.2f %+1.2f] ",sX,sY);
+	}
+
+	if (mIRRunning)
+	{
+		if (GetIRP1(irX,irY))
+		{
+			printf("P1:[%+1.2f %+1.2f]",irX,irY);
+		}
+		if (GetIRP2(irX,irY))
+		{
+			printf("P2:[%+1.2f %+1.2f]",irX,irY);
+		}
+	}
+
+
+	//print the button status
+	if (mLastButtonStatus.m1)
+		printf("1");
+	if (mLastButtonStatus.m2)
+		printf("2");
+	if (mLastButtonStatus.mA)
+		printf("A");
+	if (mLastButtonStatus.mB)
+		printf("B");
+	if (mLastButtonStatus.mPlus)
+		printf("+");
+	if (mLastButtonStatus.mMinus)
+		printf("-");
+	if (mLastButtonStatus.mUp)
+		printf("U");
+	if (mLastButtonStatus.mDown)
+		printf("D");
+	if (mLastButtonStatus.mLeft)
+		printf("L");
+	if (mLastButtonStatus.mRight)
+		printf("R");
+	if (mLastButtonStatus.mHome)
+		printf("H");
+
+	if (mNunchuckAttached)
+	{
+		if (mLastChuckReport.mButtonZ)
+			printf("Z");
+		if (mLastChuckReport.mButtonC)
+			printf("C");
+	}
+
+	printf("\n");
+
+}
+
+
+bool cWiiMote::SelectInputChannel(bool continuous, unsigned char channel)
+{
+	ClearBuffer();
+	mOutputBuffer[0] = OUTPUT_CHANNEL_REPORT;
+	mOutputBuffer[1] = (continuous ? REQUEST_CONTINUOUS_REPORTS : REQUEST_SINGLE_REPORTS) | (mOutputControls.mVibration ? 0x1 : 0x0);
+	mOutputBuffer[2] = channel;
+	return mHIDDevice.WriteToDevice(mOutputBuffer,mOutputBufferSize);
+}
+
+
+//this may or may not work to read buffers greater than 16 bytes. . . .
+bool cWiiMote::IssueReadRequest(unsigned int address, unsigned short size, unsigned char * buffer)
+{
+	bool retval = false;
+	if (mReadInfo.mReadStatus != tMemReadInfo::READ_PENDING)
+	{
+		ClearBuffer();
+		mOutputBuffer[0] = OUTPUT_READ_MEMORY;
+		mOutputBuffer[1] = (((address & 0xff000000) >> 24) & 0xFE) | (mOutputControls.mVibration ? 0x1 : 0x0);
+		mOutputBuffer[2] = (address & 0x00ff0000) >> 16;
+		mOutputBuffer[3] = (address & 0x0000ff00) >> 8;
+		mOutputBuffer[4] = (address & 0xff);
+		
+		mOutputBuffer[5] = (size & 0xff00) >> 8;
+		mOutputBuffer[6] = (size & 0xff);
+		
+		if (mHIDDevice.WriteToDevice(mOutputBuffer,mOutputBufferSize))
+		{
+			mReadInfo.mReadStatus = tMemReadInfo::READ_PENDING;
+			mReadInfo.mReadBuffer = buffer;
+			mReadInfo.mTotalBytesToRead = size;
+			mReadInfo.mBytesRead =0;
+			mReadInfo.mBaseAddress = (unsigned short)(address & 0xFFFF);
+			retval = true;
+		}
+	}
+
+	return retval;
+}
+
+void cWiiMote::ParseReadData(const unsigned char * data)
+{
+	if(mReadInfo.mReadStatus == tMemReadInfo::READ_PENDING)
+	{
+		const bool error = (data[0] & 0x0F) != 0;
+		if (error)
+		{
+			mReadInfo.mReadStatus = tMemReadInfo::READ_ERROR;
+		}
+		else
+		{
+			unsigned char bytes = (data[0] >> 4)+1;
+			unsigned short offset = ((unsigned short)data[1] << 8) + data[2];
+			unsigned int space_left_in_buffer = mReadInfo.mTotalBytesToRead -  mReadInfo.mBytesRead;
+			if (offset == mReadInfo.mBytesRead + mReadInfo.mBaseAddress &&
+				space_left_in_buffer >= bytes)
+			{
+				memcpy(&mReadInfo.mReadBuffer[mReadInfo.mBytesRead],&data[3],bytes);
+				
+				mReadInfo.mBytesRead+= bytes;
+				if (mReadInfo.mBytesRead >= mReadInfo.mTotalBytesToRead)
+				{
+					mReadInfo.mReadStatus = tMemReadInfo::READ_COMPLETE;
+				}
+			}
+		}
+	}
+
+}
+
+bool cWiiMote::ReadData(unsigned int address, unsigned short size, unsigned char * buffer)
+{
+	if (IssueReadRequest(address, size,buffer))
+	{
+		while (mReadInfo.mReadStatus == tMemReadInfo::READ_PENDING)
+		{
+			if (!HeartBeat(1000))
+			{
+				break;
+			}
+		}
+	}
+	return mReadInfo.mReadStatus == tMemReadInfo::READ_COMPLETE;
+}
+
+bool cWiiMote::ReadCalibrationData()
+{
+	bool retval = false;
+	unsigned char buffer[CALIBRATION_DATA_LENGTH];
+	if (ReadData(CALIBRATION_ADDRESS, CALIBRATION_DATA_LENGTH,buffer))
+	{
+		mAccelCalibrationData.mXZero = buffer[0];
+		mAccelCalibrationData.mYZero = buffer[1];
+		mAccelCalibrationData.mZZero = buffer[2];
+		mAccelCalibrationData.mXG = buffer[4];
+		mAccelCalibrationData.mYG = buffer[5];
+		mAccelCalibrationData.mZG = buffer[6];
+		retval = true;
+	}
+	
+	return retval;
+}
+
+void cWiiMote::GetCalibratedAcceleration(float & x, float & y, float &z) const
+{
+ 	x = (mLastMotionReport.mX - mAccelCalibrationData.mXZero) / (float)(mAccelCalibrationData.mXG- mAccelCalibrationData.mXZero);
+	y = (mLastMotionReport.mY - mAccelCalibrationData.mYZero) / (float)(mAccelCalibrationData.mYG- mAccelCalibrationData.mYZero);
+	z = (mLastMotionReport.mZ - mAccelCalibrationData.mZZero) / (float)(mAccelCalibrationData.mZG- mAccelCalibrationData.mZZero);
+}
+
+void cWiiMote::GetCalibratedChuckAcceleration(float & x, float & y, float &z) const
+{
+	if (!mNunchuckAttached)
+	{
+		x = y = z = 0.f;
+		return;
+	}
+
+	x = (mLastChuckReport.mAccelX - mNunchuckAccelCalibrationData.mXZero) / (float)(mNunchuckAccelCalibrationData.mXG- mNunchuckAccelCalibrationData.mXZero);
+	y = (mLastChuckReport.mAccelY - mNunchuckAccelCalibrationData.mYZero) / (float)(mNunchuckAccelCalibrationData.mYG- mNunchuckAccelCalibrationData.mYZero);
+	z = (mLastChuckReport.mAccelZ - mNunchuckAccelCalibrationData.mZZero) / (float)(mNunchuckAccelCalibrationData.mZG- mNunchuckAccelCalibrationData.mZZero);
+}
+void cWiiMote::GetCalibratedChuckStick(float & x, float & y) const
+{
+	if (!mNunchuckAttached)
+	{
+		x = y = 0.f;
+		return;
+	}
+
+	if (mLastChuckReport.mStickX < mNunchuckStickCalibrationData.mXmid)
+	{
+		x = ((mLastChuckReport.mStickX - mNunchuckStickCalibrationData.mXmin) / (float)(mNunchuckStickCalibrationData.mXmid - mNunchuckStickCalibrationData.mXmin)) -  1.f;
+	}
+	else
+	{
+		x = ((mLastChuckReport.mStickX - mNunchuckStickCalibrationData.mXmid) / (float)(mNunchuckStickCalibrationData.mXmax - mNunchuckStickCalibrationData.mXmid));
+	}
+
+	if (mLastChuckReport.mStickY < mNunchuckStickCalibrationData.mYmid)
+	{
+		y = ((mLastChuckReport.mStickY - mNunchuckStickCalibrationData.mYmin) / (float)(mNunchuckStickCalibrationData.mYmid - mNunchuckStickCalibrationData.mYmin)) -  1.f;
+	}
+	else
+	{
+		y = ((mLastChuckReport.mStickY - mNunchuckStickCalibrationData.mYmid) / (float)(mNunchuckStickCalibrationData.mYmax - mNunchuckStickCalibrationData.mYmid));
+	}
+}
+
+
+bool cWiiMote::WriteMemory(unsigned int address, unsigned char size, const unsigned char * buffer)
+{
+	bool retval = false;
+	if (size <= 16)
+	{
+		ClearBuffer();
+		mOutputBuffer[0] = OUTPUT_WRITE_MEMORY;
+		mOutputBuffer[1] = (address & 0xff000000) >> 24 | (mOutputControls.mVibration ? 0x1 : 0x0);
+		mOutputBuffer[2] = (address & 0x00ff0000) >> 16;
+		mOutputBuffer[3] = (address & 0x0000ff00) >> 8;
+		mOutputBuffer[4] = (address & 0xff);
+		mOutputBuffer[5] = size;
+		memcpy(&mOutputBuffer[6],buffer,size);
+		retval = mHIDDevice.WriteToDevice(mOutputBuffer,mOutputBufferSize);
+	}
+
+	return retval;
+}
+
+bool cWiiMote::InitNunchuck()
+{
+
+	bool retval = false;
+	
+	//first init the nunchuck, if it is present
+	if (WriteMemory(NUNCHUCK_INIT_ADDRESS,1,&NUNCHUCK_INIT_VAL))
+	{
+	
+		unsigned char buffer[16];
+		//now try to read the nunchuck's calibration data
+		if (ReadData(NUNCHUCK_CALIBRATION_ADDRESS,16,buffer))
+		{
+			
+			//note that this hasn't worked properly for me yet (I get all 0xff). 
+			/*mNunchuckAccelCalibrationData.mXZero = NunChuckByte(buffer[0]);
+			mNunchuckAccelCalibrationData.mYZero = NunChuckByte(buffer[1]);
+			mNunchuckAccelCalibrationData.mZZero = NunChuckByte(buffer[2]);
+
+			mNunchuckAccelCalibrationData.mXG = NunChuckByte(buffer[4]);
+			mNunchuckAccelCalibrationData.mYG = NunChuckByte(buffer[5]);
+			mNunchuckAccelCalibrationData.mZG = NunChuckByte(buffer[6]);
+
+			mNunchuckStickCalibrationData.mXmax = NunChuckByte(buffer[8]);
+			mNunchuckStickCalibrationData.mXmin = NunChuckByte(buffer[9]);
+			mNunchuckStickCalibrationData.mXmid = NunChuckByte(buffer[10]);
+			mNunchuckStickCalibrationData.mYmax = NunChuckByte(buffer[11]);
+			mNunchuckStickCalibrationData.mYmin = NunChuckByte(buffer[12]);
+			mNunchuckStickCalibrationData.mYmid = NunChuckByte(buffer[13]);*/
+
+			//these are default values from the wiili wiki
+			mNunchuckAccelCalibrationData.mXZero = 0x7E;
+			mNunchuckAccelCalibrationData.mYZero = 0x7A;
+			mNunchuckAccelCalibrationData.mZZero = 0x7D;
+			mNunchuckAccelCalibrationData.mXG = 0xB0;
+			mNunchuckAccelCalibrationData.mYG = 0xAF;
+			mNunchuckAccelCalibrationData.mZG = 0xB1;
+			mNunchuckStickCalibrationData.mXmax = 0xe5;
+			mNunchuckStickCalibrationData.mXmin = 0x21;
+			mNunchuckStickCalibrationData.mXmid =  0x7c;
+			mNunchuckStickCalibrationData.mYmax = 0xe7;
+			mNunchuckStickCalibrationData.mYmin =  0x23;
+			mNunchuckStickCalibrationData.mYmid = 0x7a;
+			retval = true;
+
+		}
+	}
+	mNunchuckAttached = retval;
+	return retval;
+}
+
+void cWiiMote::ParseChuckReport(const unsigned char * data)
+{
+	mLastChuckReport.mStickX = NunChuckByte(data[0]);
+	mLastChuckReport.mStickY = NunChuckByte(data[1]);
+	mLastChuckReport.mAccelX = NunChuckByte(data[2]);
+	mLastChuckReport.mAccelY = NunChuckByte(data[3]);
+	mLastChuckReport.mAccelZ = NunChuckByte(data[4]);
+	mLastChuckReport.mButtonC = (NunChuckByte(data[5]) & 0x2) == 0;
+	mLastChuckReport.mButtonZ = (NunChuckByte(data[5]) & 0x1) == 0;
+}
+
+bool cWiiMote::EnableIR()
+{
+	bool retval = false;
+	
+	DisableIR();
+
+	if (!mIRRunning)
+	{
+		ClearBuffer();
+		mOutputBuffer[0] = OUTPUT_ENABLE_IR;
+		mOutputBuffer[1] = 0x4 | (mOutputControls.mVibration ? 0x1 : 0x0);
+		retval = mHIDDevice.WriteToDevice(mOutputBuffer,mOutputBufferSize);
+		
+		if (retval)
+		{
+			mOutputBuffer[0] = OUTPUT_ENABLE_IR2;
+			mOutputBuffer[1] = 0x4 | (mOutputControls.mVibration ? 0x1 : 0x0);
+			retval = mHIDDevice.WriteToDevice(mOutputBuffer,mOutputBufferSize);
+		}
+
+		if (retval)
+		{
+			unsigned char val = 0x1;
+			retval = WriteMemory(IR_REG_1,1,&val);
+		}
+		
+		if (retval)
+		{
+			retval = WriteMemory(IR_SENS_ADDR_1,9,IR_SENS_MIDRANGE_PART1);
+		}
+
+		if (retval)
+		{
+			retval = WriteMemory(IR_SENS_ADDR_2,2,IR_SENS_MIDRANGE_PART2);
+		}
+
+
+		if (retval)
+		{
+			retval = WriteMemory(IR_REG_2,1,&IR_MODE_EXP);
+		}
+		
+		if (retval)
+		{
+			unsigned char val = 0x8;
+			retval = WriteMemory(IR_REG_1,1,&val);
+		}
+
+
+		mIRRunning = retval;
+	}
+	return retval;
+
+}
+
+bool cWiiMote::DisableIR()
+{
+	bool retval = false;
+
+	if (mIRRunning)
+	{
+		ClearBuffer();
+		mOutputBuffer[0] = OUTPUT_ENABLE_IR;
+		mOutputBuffer[1] = (mOutputControls.mVibration ? 0x1 : 0x0);
+		retval = mHIDDevice.WriteToDevice(mOutputBuffer,mOutputBufferSize);
+		
+		if (retval)
+		{
+			mOutputBuffer[0] = OUTPUT_ENABLE_IR2;
+			mOutputBuffer[1] = (mOutputControls.mVibration ? 0x1 : 0x0);
+			retval = mHIDDevice.WriteToDevice(mOutputBuffer,mOutputBufferSize);
+		}
+
+		mIRRunning = false;
+	}
+	return retval;
+
+}
+
+void cWiiMote::ParseIRReport(const unsigned char * data)
+{
+	mLastIRReport.mP1X = data[0] << 2 | (data[2] & 0x30) >>4;
+	mLastIRReport.mP1Y = data[1] << 2 | (data[2] & 0xc0) >>6;
+	mLastIRReport.mP1Size = data[2] & 0xf;
+
+	mLastIRReport.mP2X = data[3] << 2 | (data[5] & 0x30) >>4;
+	mLastIRReport.mP2Y = data[4] << 2 | (data[5] & 0xc0) >>6;
+	mLastIRReport.mP2Size = data[5] & 0xf;
+
+	mLastIRReport.mP1Found =  !(data[0] == 0xff && data[1] == 0xff && data[2] == 0xff);
+	mLastIRReport.mP2Found =  !(data[3] == 0xff && data[4] == 0xff && data[5] == 0xff);
+}
+
+bool cWiiMote::GetIRP1(float &x, float &y) const
+{
+	bool retval = false;
+	if (mIRRunning && mLastIRReport.mP1Found)
+	{
+		x = mLastIRReport.mP1X / 1024.f;
+		y = mLastIRReport.mP1Y / 1024.f;
+		retval = true;
+	}
+	return retval;
+}
+
+
+bool cWiiMote::GetIRP2(float &x, float &y) const
+{
+	bool retval = false;
+	if (mIRRunning && mLastIRReport.mP2Found)
+	{
+		x = mLastIRReport.mP2X / 1024.f;
+		y = mLastIRReport.mP2Y / 1024.f;
+		retval = true;
+	}
+	return retval;
+
+}
+
+bool cWiiMote::StartDataStream()
+{
+	bool retval = false;
+	
+	StopDataStream();
+
+	if (mNunchuckAttached)
+	{
+		retval =SetReportMode(REPORT_MODE_MOTION_CHUCK_IR);
+	}
+	else
+	{
+		retval = SetReportMode(REPORT_MODE_MOTION_IR);
+	}
+	EnableIR();
+
+	mDataStreamRunning = retval;
+	return retval;
+}
+
+
+bool cWiiMote::StopDataStream()
+{
+	if (mDataStreamRunning)
+	{
+		mDataStreamRunning = false;
+		DisableIR();
+		SetReportMode(REPORT_MODE_EVENT_BUTTONS);
+	}
+	return true;;
+}
+#endif

+ 291 - 0
CamelotOISInput/Source/OIS/win32/extras/WiiMote/wiimote.h

@@ -0,0 +1,291 @@
+#include "OISConfig.h"
+#ifdef OIS_WIN32_WIIMOTE_SUPPORT
+//cWiimote 0.2 by Kevin Forbes (http://simulatedcomicproduct.com)
+//This code is public domain, and comes with no warranty. The user takes full responsibility for anything that happens as a result from using this code.
+
+#ifndef WIIMOTE_H
+#define WIIMOTE_H
+
+#include "hiddevice.h"
+
+
+
+class cWiiMote
+{
+public:
+	cWiiMote();
+	~cWiiMote();
+	
+	//connection management
+	bool ConnectToDevice(int index = 0);
+	bool Disconnect();	
+	bool IsConnected() const {return mHIDDevice.IsConnected();}
+	
+	
+	bool StartDataStream();
+	bool StopDataStream();
+
+	bool IsNunChuckAttached() { return mNunchuckAttached; }
+
+
+	//this is the wiimote message pump. It should probably be called in loop from a thread
+	bool HeartBeat(int timeout = 1);
+	bool SetVibration(bool vib_on);
+	bool SetLEDs(bool led1, bool led2, bool led3, bool led4);
+
+
+
+	//Querying functions and structures:
+	void GetCalibratedAcceleration(float & x, float & y, float &z) const;
+	void GetCalibratedChuckAcceleration(float & x, float & y, float &z) const;
+	void GetCalibratedChuckStick(float & x, float & y) const;
+	bool GetIRP1(float &x, float &y) const;
+	bool GetIRP2(float &x, float &y) const;
+
+
+	struct tExpansionReport
+	{
+		bool mAttachmentPluggedIn;
+		bool mIREnabled;
+		bool mSpeakerEnabled;
+		bool mLED1On;
+		bool mLED2On;
+		bool mLED3On;
+		bool mLED4On;
+		unsigned char mBatteryLevel;
+
+		void Init()
+		{
+			mAttachmentPluggedIn = false;
+			mIREnabled = false;
+			mSpeakerEnabled = false;
+			mLED1On = false;
+			mLED2On = false;
+			mLED3On = false;
+			mLED4On = false;
+			mBatteryLevel = 0;
+		}
+	};
+	struct tButtonStatus
+	{
+		bool mA;
+		bool mB;
+		bool m1;
+		bool m2;
+		bool mPlus;
+		bool mMinus;
+		bool mHome;
+		bool mUp;
+		bool mDown;
+		bool mLeft;
+		bool mRight;
+	
+		void Init()
+		{
+			mA = mB = m1 = m2 = mPlus = mMinus = mHome = mUp = mDown = mLeft = mRight = false;
+		}
+	};
+	struct tMotionReport
+	{
+		unsigned char mX;
+		unsigned char mY;
+		unsigned char mZ;
+		
+		void Init()
+		{
+			mX = mY = mZ = 0;
+		}
+	};
+
+	struct tChuckReport
+	{
+		unsigned char mStickX;
+		unsigned char mStickY;
+		unsigned char mAccelX;
+		unsigned char mAccelY;
+		unsigned char mAccelZ;
+		bool	mButtonC;
+		bool	mButtonZ;
+		void Init()
+		{
+			mStickX=mStickY=mAccelX=mAccelY=mAccelZ=0;
+			mButtonC = mButtonZ = false;
+		};
+	};
+
+	struct tIRReport
+	{
+		unsigned short mP1X;
+		unsigned short mP1Y;
+		
+		unsigned short mP2X;
+		unsigned short mP2Y;
+
+		unsigned char mP1Size;
+		unsigned char mP2Size;
+
+		bool mP1Found;
+		bool mP2Found;
+
+		void Init()
+		{
+			mP1X = mP1Y = mP2X = mP2Y = mP1Size = mP2Size = 0;
+			mP1Found = mP2Found = false;
+		}
+
+
+	};
+	const tButtonStatus & GetLastButtonStatus() const {return mLastButtonStatus;}
+	const tChuckReport & GetLastChuckReport() const {return mLastChuckReport;}
+	const tMotionReport & GetLastMotionReport() const { return mLastMotionReport;}
+	const tExpansionReport & GetLastExpansionReport() const { return mLastExpansionReport;}
+	const tIRReport & GetLastIRReport() const { return mLastIRReport;}
+	
+	
+	//debugging functions:
+	void PrintStatus() const;
+
+private:
+	
+	//parsing functions for input reports
+	void ParseExpansionReport(const unsigned char * data);
+	void ParseButtonReport(const unsigned char * data);
+	void ParseMotionReport(const unsigned char * data);
+	void ParseReadData(const unsigned char * data);
+	void ParseChuckReport(const unsigned char * data);
+	void ParseIRReport(const unsigned char * data);
+
+
+	//tell the wiimote how to send data
+	enum eReportMode
+	{
+		REPORT_MODE_EVENT_BUTTONS,
+		REPORT_MODE_MOTION, 
+		REPORT_MODE_MOTION_CHUCK,
+		REPORT_MODE_MOTION_IR,
+		REPORT_MODE_MOTION_CHUCK_IR
+	};
+	bool SetReportMode(eReportMode mode);
+
+
+	//housekeeping functions
+	void Init();
+	void ClearBuffer();
+
+	//low level tasks
+	bool SelectInputChannel(bool continuous, unsigned char channel);
+	bool UpdateOutput();
+	bool ReadMemory(unsigned int address, unsigned short size, unsigned char * buffer) const;	
+	bool WriteMemory(unsigned int address, unsigned char size, const unsigned char * buffer);
+
+	bool ReadData(unsigned int address, unsigned short size, unsigned char * buffer);
+	bool IssueReadRequest(unsigned int address, unsigned short size, unsigned char * buffer);
+	bool ReadCalibrationData();
+	bool SendReportMode();
+
+	bool InitNunchuck();
+	bool EnableIR();
+	bool DisableIR();
+
+	static inline unsigned char NunChuckByte(unsigned char in) {return (in ^ 0x17)+0x17;}
+	//flash reading vars
+	struct tMemReadInfo
+	{
+		enum eReadStatus
+		{
+			READ_PENDING,
+			READ_NONE,
+			READ_COMPLETE,
+			READ_ERROR
+		} mReadStatus;
+
+		unsigned char * mReadBuffer;
+		unsigned short mTotalBytesToRead;
+		unsigned short mBytesRead;
+		unsigned short mBaseAddress;
+		void Init()
+		{
+			mReadStatus = READ_NONE;
+			mReadBuffer = NULL;
+			mTotalBytesToRead = 0;
+			mBytesRead = 0;
+			mBaseAddress = 0;
+		}
+	} mReadInfo;
+
+	//calibration data for the wiimote
+	struct tAccelCalibrationData
+	{
+		unsigned char mXZero;
+		unsigned char mYZero;
+		unsigned char mZZero;
+		unsigned char mXG;
+		unsigned char mYG;
+		unsigned char mZG;
+		void Init()
+		{
+			mXZero = mYZero = mZZero = mXG = mYG = mZG= 0;
+		}
+	} ;
+
+	struct tStickCalibrationData
+	{
+		unsigned char mXmin;
+		unsigned char mXmid;
+		unsigned char mXmax;
+		unsigned char mYmin;
+		unsigned char mYmid;
+		unsigned char mYmax;
+
+		void Init()
+		{
+			mXmax = mYmax = mXmin = mYmin = mXmid = mYmid =0;
+		}
+	};
+	
+	tAccelCalibrationData mAccelCalibrationData;
+	tAccelCalibrationData mNunchuckAccelCalibrationData;
+	tStickCalibrationData mNunchuckStickCalibrationData;
+
+	//output requests
+	struct tOutputControls
+	{
+		bool mVibration;
+		bool mLED1;
+		bool mLED2;
+		bool mLED3;
+		bool mLED4;
+
+		void Init()
+		{
+			mVibration = mLED1 = mLED2= mLED3= mLED4 = false;
+		}
+	};
+	
+	
+	//input states
+	tExpansionReport mLastExpansionReport;
+	tButtonStatus mLastButtonStatus;
+	tMotionReport mLastMotionReport;
+	tChuckReport mLastChuckReport;
+	tIRReport mLastIRReport;
+
+	//output states
+	tOutputControls mOutputControls;
+	eReportMode	mReportMode;
+
+	//our communications device
+	cHIDDevice mHIDDevice;
+	
+	bool mNunchuckAttached;
+	bool mIRRunning;
+	bool mDataStreamRunning;
+
+	//buffers for input/output
+	static const int mOutputBufferSize = 22;
+	unsigned char mOutputBuffer[mOutputBufferSize];
+	static const int mInputBufferSize = 22;
+	unsigned char mInputBuffer[mInputBufferSize];
+};
+#endif
+#endif

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików