Explorar el Código

WIP: Linux port
- OIS removed as a dependency, and all input is now handled internally, due to issues on Linux

BearishSun hace 8 años
padre
commit
89a714a82a
Se han modificado 32 ficheros con 1472 adiciones y 681 borrados
  1. 0 6
      Documentation/GitHub/dependencies.md
  2. 0 2
      Source/BansheeCore/BsCoreApplication.cpp
  3. 1 1
      Source/BansheeCore/CMakeLists.txt
  4. 9 0
      Source/BansheeCore/CMakeSources.cmake
  5. 42 0
      Source/BansheeCore/Input/BsGamepad.h
  6. 14 18
      Source/BansheeCore/Input/BsInput.cpp
  7. 0 5
      Source/BansheeCore/Input/BsInput.h
  8. 73 69
      Source/BansheeCore/Input/BsInputFwd.h
  9. 35 0
      Source/BansheeCore/Input/BsKeyboard.h
  10. 35 0
      Source/BansheeCore/Input/BsMouse.h
  11. 187 0
      Source/BansheeCore/Input/BsRawInputHandler.cpp
  12. 64 12
      Source/BansheeCore/Input/BsRawInputHandler.h
  13. 417 0
      Source/BansheeCore/Win32/BsWin32Gamepad.cpp
  14. 205 0
      Source/BansheeCore/Win32/BsWin32Input.cpp
  15. 47 0
      Source/BansheeCore/Win32/BsWin32Input.h
  16. 166 0
      Source/BansheeCore/Win32/BsWin32Keyboard.cpp
  17. 172 0
      Source/BansheeCore/Win32/BsWin32Mouse.cpp
  18. 0 1
      Source/BansheeEditor/BsEditorApplication.cpp
  19. 4 2
      Source/BansheeEditorExec/BsEditorExec.cpp
  20. 0 1
      Source/BansheeEngine/BsApplication.cpp
  21. 0 337
      Source/BansheeOISInput/BsInputHandlerOIS.cpp
  22. 0 123
      Source/BansheeOISInput/BsInputHandlerOIS.h
  23. 0 33
      Source/BansheeOISInput/BsOISPlugin.cpp
  24. 0 15
      Source/BansheeOISInput/BsOISPrerequisites.h
  25. 0 29
      Source/BansheeOISInput/CMakeLists.txt
  26. 0 17
      Source/BansheeOISInput/CMakeSources.cmake
  27. 0 1
      Source/CMake/BsEngineConfig.h.in
  28. 1 1
      Source/CMake/Common.cmake
  29. 0 5
      Source/CMakeLists.txt
  30. 0 1
      Source/Examples/ExampleGettingStarted/Main.cpp
  31. 0 1
      Source/Examples/ExamplePhysicallyBasedShading/Main.cpp
  32. 0 1
      Source/Game/Main.cpp

+ 0 - 6
Documentation/GitHub/dependencies.md

@@ -66,12 +66,6 @@ Additionally, if the dependency structure still isn't clear, download one of the
 - Required by BansheeFreeImgImporter
 - Compile as a static library
    
-**OIS**
-- OIS 1.3
-- https://github.com/BearishSun/OIS
-- Required by BansheeOISInput
-- Compile as a dynamic library
-   
 **mono**
 - Mono 4.4.0
 - http://www.mono-project.com/

+ 0 - 2
Source/BansheeCore/BsCoreApplication.cpp

@@ -174,8 +174,6 @@ namespace bs
 
 		for (auto& importerName : mStartUpDesc.importers)
 			loadPlugin(importerName);
-
-		loadPlugin(mStartUpDesc.input, nullptr, mPrimaryWindow.get());
 	}
 
 	void CoreApplication::runMainLoop()

+ 1 - 1
Source/BansheeCore/CMakeLists.txt

@@ -30,7 +30,7 @@ target_link_libraries(BansheeCore PUBLIC BansheeUtility)
 	
 ## OS libs
 if(WIN32)
-target_link_libraries(BansheeCore PRIVATE Winmm)
+	target_link_libraries(BansheeCore PRIVATE Winmm dinput8 xinput9_1_0 dxguid.lib)
 else()
 	# TODO_OTHER_PLATFORMS_GO_HERE
 endif()

+ 9 - 0
Source/BansheeCore/CMakeSources.cmake

@@ -87,6 +87,9 @@ set(BS_BANSHEECORE_INC_INPUT
 	"Input/BsOSInputHandler.h"
 	"Input/BsInputFwd.h"
 	"Input/BsInput.h"
+	"Input/BsMouse.h"
+	"Input/BsKeyboard.h"
+	"Input/BsGamepad.h"
 )
 
 set(BS_BANSHEECORE_INC_RENDERER
@@ -432,6 +435,7 @@ set(BS_BANSHEECORE_SRC_MATERIAL
 set(BS_BANSHEECORE_SRC_INPUT
 	"Input/BsInput.cpp"
 	"Input/BsOSInputHandler.cpp"
+	"Input/BsRawInputHandler.cpp"
 )
 
 set(BS_BANSHEECORE_INC_LOCALIZATION
@@ -587,12 +591,17 @@ set(BS_BANSHEECORE_SRC_PLATFORM
 set(BS_BANSHEECORE_INC_PLATFORM_WIN32
 	"Win32/BsWin32DropTarget.h"
 	"Win32/BsWin32Platform.h"
+	"Win32/BsWin32Input.h"
 )
 
 set(BS_BANSHEECORE_SRC_PLATFORM_WIN32
 	"Win32/BsWin32FolderMonitor.cpp"
 	"Win32/BsWin32Platform.cpp"
 	"Win32/BsWin32DropTarget.cpp"
+	"Win32/BsWin32Input.cpp"
+	"Win32/BsWin32Mouse.cpp"
+	"Win32/BsWin32Keyboard.cpp"
+	"Win32/BsWin32Gamepad.cpp"
 )
 
 set(BS_BANSHEECORE_INC_PLATFORM_UNIX

+ 42 - 0
Source/BansheeCore/Input/BsGamepad.h

@@ -0,0 +1,42 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace bs
+{
+	struct GamepadInfo;
+
+	/** Represents a single hardware gamepad. Used by the RawInputHandler to report gamepad input events. */
+	class BS_CORE_EXPORT Gamepad
+	{
+	public:
+		struct Pimpl;
+
+		Gamepad(const String& name, const GamepadInfo& gamepadInfo, RawInputHandler* owner);
+		~Gamepad();
+
+		/** Returns the name of the device. */
+		String getName() const { return mName; }
+
+		/** Captures the input since the last call and triggers the events on the parent RawInputHandler. */
+		void capture();
+
+		/** Minimum allowed value as reported by the axis movement events. */
+		static constexpr int MIN_AXIS = -32768;
+
+		/** Maximum allowed value as reported by the axis movement events. */
+		static constexpr int MAX_AXIS = 32767;
+	private:
+		friend class RawInputHandler;
+
+		/** Changes the capture context. Should be called when focus is moved to a new window. */
+		void changeCaptureContext(UINT64 windowHandle);
+
+		String mName;
+		RawInputHandler* mOwner;
+
+		Pimpl* m;
+	};
+}

+ 14 - 18
Source/BansheeCore/Input/BsInput.cpp

@@ -6,6 +6,7 @@
 #include "Math/BsRect2I.h"
 #include "Debug/BsDebug.h"
 #include "Managers/BsRenderWindowManager.h"
+#include "BsCoreApplication.h"
 
 using namespace std::placeholders;
 
@@ -21,9 +22,15 @@ namespace bs
 	}
 
 	Input::Input()
-		:mPointerDoubleClicked(false), mLastPositionSet(false)
-	{ 
+		: mPointerDoubleClicked(false), mLastPositionSet(false)
+	{
+		SPtr<RenderWindow> primaryWindow = gCoreApplication().getPrimaryWindow();
+
+		UINT64 windowId = 0;
+		primaryWindow->getCustomAttribute("WINDOW", &windowId);
+
 		mOSInputHandler = bs_shared_ptr_new<OSInputHandler>();
+		mRawInputHandler = bs_shared_ptr_new<RawInputHandler>(windowId);
 
 		mOSInputHandler->onCharInput.connect(std::bind(&Input::charInput, this, _1));
 		mOSInputHandler->onCursorMoved.connect(std::bind(&Input::cursorMoved, this, _1));
@@ -32,6 +39,11 @@ namespace bs
 		mOSInputHandler->onDoubleClick.connect(std::bind(&Input::cursorDoubleClick, this, _1));
 		mOSInputHandler->onInputCommand.connect(std::bind(&Input::inputCommandEntered, this, _1));
 
+		mRawInputHandler->onButtonDown.connect(std::bind(&Input::buttonDown, this, _1, _2, _3));
+		mRawInputHandler->onButtonUp.connect(std::bind(&Input::buttonUp, this, _1, _2, _3));
+
+		mRawInputHandler->onAxisMoved.connect(std::bind(&Input::axisMoved, this, _1, _2, _3));
+
 		RenderWindowManager::instance().onFocusGained.connect(std::bind(&Input::inputWindowChanged, this, _1));
 
 		for (int i = 0; i < 3; i++)
@@ -41,22 +53,6 @@ namespace bs
 	Input::~Input()
 	{ }
 
-	void Input::_registerRawInputHandler(SPtr<RawInputHandler> inputHandler)
-	{
-		if(mRawInputHandler != inputHandler)
-		{
-			mRawInputHandler = inputHandler;
-
-			if(mRawInputHandler != nullptr)
-			{
-				mRawInputHandler->onButtonDown.connect(std::bind(&Input::buttonDown, this, _1, _2, _3));
-				mRawInputHandler->onButtonUp.connect(std::bind(&Input::buttonUp, this, _1, _2, _3));
-
-				mRawInputHandler->onAxisMoved.connect(std::bind(&Input::axisMoved, this, _1, _2, _3));
-			}
-		}
-	}
-
 	void Input::_update()
 	{
 		// Toggle states only remain active for a single frame before they are transitioned

+ 0 - 5
Source/BansheeCore/Input/BsInput.h

@@ -17,8 +17,6 @@ namespace bs
 	/**
 	 * Primary module used for dealing with input. Allows you to receieve and query raw or OS input for 
 	 * mouse/keyboard/gamepad.
-	 *
-	 * All inputs are received through an input handler, which can be overriden to provide custom input functionality.
 	 */
 	class BS_CORE_EXPORT Input : public Module<Input>
 	{
@@ -158,9 +156,6 @@ namespace bs
 		 *  @{
 		 */
 
-		/** Registers a new input handler. Replaces any previous input handler. */
-		void _registerRawInputHandler(SPtr<RawInputHandler> inputHandler);
-
 		/**
 		 * Called every frame. Detects button state changes and prepares callback events to trigger via a call to 
 		 * _triggerCallbacks().

+ 73 - 69
Source/BansheeCore/Input/BsInputFwd.h

@@ -172,77 +172,81 @@ namespace bs
 		BC_WEBBACK     = 0xEA,    // Web Back
 		BC_MYCOMPUTER  = 0xEB,    // My Computer
 		BC_MAIL        = 0xEC,    // Mail
-		BC_MEDIASELECT = 0xED,     // Media Select
+		BC_MEDIASELECT = 0xED,    // Media Select
 		BC_MOUSE_LEFT = 0x800000EE, // Mouse buttons - Most important bit signifies this key is a mouse button
-		BC_MOUSE_RIGHT = 0x800000EF,
-		BC_MOUSE_MIDDLE = 0x800000F0,
-		BC_MOUSE_BTN4 = 0x800000F1,
-		BC_MOUSE_BTN5 = 0x800000F2,
-		BC_MOUSE_BTN6 = 0x800000F3,
-		BC_MOUSE_BTN7 = 0x800000F4,
-		BC_MOUSE_BTN8 = 0x800000F5,
-		BC_MOUSE_BTN9 = 0x800000F6,
-		BC_MOUSE_BTN10 = 0x800000F7,
-		BC_MOUSE_BTN11 = 0x800000F8,
-		BC_MOUSE_BTN12 = 0x800000F9,
-		BC_MOUSE_BTN13 = 0x800000FA,
-		BC_MOUSE_BTN14 = 0x800000FB,
-		BC_MOUSE_BTN15 = 0x800000FC,
-		BC_MOUSE_BTN16 = 0x800000FD,
-		BC_MOUSE_BTN17 = 0x800000FE,
-		BC_MOUSE_BTN18 = 0x800000FF,
-		BC_MOUSE_BTN19 = 0x80000101,
-		BC_MOUSE_BTN20 = 0x80000102,
-		BC_MOUSE_BTN21 = 0x80000103,
-		BC_MOUSE_BTN22 = 0x80000104,
-		BC_MOUSE_BTN23 = 0x80000105,
-		BC_MOUSE_BTN24 = 0x80000106,
-		BC_MOUSE_BTN25 = 0x80000107,
-		BC_MOUSE_BTN26 = 0x80000108,
-		BC_MOUSE_BTN27 = 0x80000109,
-		BC_MOUSE_BTN28 = 0x8000010A,
-		BC_MOUSE_BTN29 = 0x8000010B,
-		BC_MOUSE_BTN30 = 0x8000010C,
-		BC_MOUSE_BTN31 = 0x8000010D,
-		BC_MOUSE_BTN32 = 0x8000010E,
+		BC_MOUSE_RIGHT,
+		BC_MOUSE_MIDDLE,
+		BC_MOUSE_BTN4,
+		BC_MOUSE_BTN5,
+		BC_MOUSE_BTN6,
+		BC_MOUSE_BTN7,
+		BC_MOUSE_BTN8,
+		BC_MOUSE_BTN9,
+		BC_MOUSE_BTN10,
+		BC_MOUSE_BTN11,
+		BC_MOUSE_BTN12,
+		BC_MOUSE_BTN13,
+		BC_MOUSE_BTN14,
+		BC_MOUSE_BTN15,
+		BC_MOUSE_BTN16,
+		BC_MOUSE_BTN17,
+		BC_MOUSE_BTN18,
+		BC_MOUSE_BTN19,
+		BC_MOUSE_BTN20,
+		BC_MOUSE_BTN21,
+		BC_MOUSE_BTN22,
+		BC_MOUSE_BTN23,
+		BC_MOUSE_BTN24,
+		BC_MOUSE_BTN25,
+		BC_MOUSE_BTN26,
+		BC_MOUSE_BTN27,
+		BC_MOUSE_BTN28,
+		BC_MOUSE_BTN29,
+		BC_MOUSE_BTN30,
+		BC_MOUSE_BTN31,
+		BC_MOUSE_BTN32,
 		BC_GAMEPAD_A = 0x4000010F, // Joystick/Gamepad buttons- Second most important bit signifies key is a gamepad button
-		BC_GAMEPAD_B = 0x40000110, // Similar to keyboard names, these are for convenience named after Xbox controller buttons
-		BC_GAMEPAD_X = 0x40000111, // but if some other controller is connected you will need to learn yourself which of these
-		BC_GAMEPAD_Y = 0x40000112, // corresponds to which actual button on the controller.
-		BC_GAMEPAD_LB = 0x40000113,
-		BC_GAMEPAD_RB = 0x40000114,
-		BC_GAMEPAD_LS = 0x40000115,
-		BC_GAMEPAD_RS = 0x40000116,
-		BC_GAMEPAD_BACK = 0x40000117,
-		BC_GAMEPAD_START = 0x40000118,
-		BC_GAMEPAD_DPAD_LEFT = 0x40000119,
-		BC_GAMEPAD_DPAD_RIGHT = 0x4000011A,
-		BC_GAMEPAD_DPAD_UP = 0x4000011B,
-		BC_GAMEPAD_DPAD_DOWN = 0x4000011C,
-		BC_GAMEPAD_BTN1 = 0x4000011D,
-		BC_GAMEPAD_BTN2 = 0x4000011E,
-		BC_GAMEPAD_BTN3 = 0x4000011F,
-		BC_GAMEPAD_BTN4 = 0x40000120,
-		BC_GAMEPAD_BTN5 = 0x40000121,
-		BC_GAMEPAD_BTN6 = 0x40000122,
-		BC_GAMEPAD_BTN7 = 0x40000123,
-		BC_GAMEPAD_BTN8 = 0x40000124,
-		BC_GAMEPAD_BTN9 = 0x40000125,
-		BC_GAMEPAD_BTN10 = 0x40000126,
-		BC_GAMEPAD_BTN11 = 0x40000127,
-		BC_GAMEPAD_BTN12 = 0x40000128,
-		BC_GAMEPAD_BTN13 = 0x40000129,
-		BC_GAMEPAD_BTN14 = 0x4000012A,
-		BC_GAMEPAD_BTN15 = 0x4000012B,
-		BC_GAMEPAD_BTN16 = 0x4000012C,
-		BC_GAMEPAD_BTN17 = 0x4000012D,
-		BC_GAMEPAD_BTN18 = 0x4000012E,
-		BC_GAMEPAD_BTN19 = 0x4000012F,
-		BC_GAMEPAD_BTN20 = 0x40000130,
-		BC_Count = 304,
-		BC_NumKeys = 238, // IMPORTANT: Make sure to update these if you modify the values above
-		BC_NumMouse = 32,
-		BC_NumGamepad = 34,
+		BC_GAMEPAD_B,              // Similar to keyboard names, these are for convenience named after Xbox controller buttons
+		BC_GAMEPAD_X,              // but if some other controller is connected you will need to learn yourself which of these
+		BC_GAMEPAD_Y,              // corresponds to which actual button on the controller.
+		BC_GAMEPAD_LB,
+		BC_GAMEPAD_RB,
+		BC_GAMEPAD_LS,
+		BC_GAMEPAD_RS,
+		BC_GAMEPAD_BACK,
+		BC_GAMEPAD_START,
+		BC_GAMEPAD_DPAD_LEFT,
+		BC_GAMEPAD_DPAD_RIGHT,
+		BC_GAMEPAD_DPAD_UP,
+		BC_GAMEPAD_DPAD_DOWN,
+		BC_GAMEPAD_BTN1,
+		BC_GAMEPAD_BTN2,
+		BC_GAMEPAD_BTN3,
+		BC_GAMEPAD_BTN4,
+		BC_GAMEPAD_BTN5,
+		BC_GAMEPAD_BTN6,
+		BC_GAMEPAD_BTN7,
+		BC_GAMEPAD_BTN8,
+		BC_GAMEPAD_BTN9,
+		BC_GAMEPAD_BTN10,
+		BC_GAMEPAD_BTN11,
+		BC_GAMEPAD_BTN12,
+		BC_GAMEPAD_BTN13,
+		BC_GAMEPAD_BTN14,
+		BC_GAMEPAD_BTN15,
+		BC_GAMEPAD_BTN16,
+		BC_GAMEPAD_BTN17,
+		BC_GAMEPAD_BTN18,
+		BC_GAMEPAD_BTN19,
+		BC_GAMEPAD_BTN20,
+		BC_GAMEPAD_DPAD_UPLEFT,
+		BC_GAMEPAD_DPAD_UPRIGHT,
+		BC_GAMEPAD_DPAD_DOWNLEFT,
+		BC_GAMEPAD_DPAD_DOWNRIGHT,
+		BC_NumKeys = BC_MEDIASELECT - BC_UNASSIGNED + 1, // IMPORTANT: Make sure to update these if you modify the values above
+		BC_NumMouse = BC_MOUSE_BTN32 - BC_MOUSE_LEFT + 1,
+		BC_NumGamepad = BC_GAMEPAD_DPAD_DOWNRIGHT - BC_GAMEPAD_A + 1,
+		BC_Count = BC_NumKeys + BC_NumMouse + BC_NumGamepad,
 	};
 
 	/**	Contains data about a button input event. */

+ 35 - 0
Source/BansheeCore/Input/BsKeyboard.h

@@ -0,0 +1,35 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace bs
+{
+	/** Represents a single hardware keyboard. Used by the RawInputHandler to report raw keyboard input events. */
+	class BS_CORE_EXPORT Keyboard
+	{
+	public:
+		struct Pimpl;
+
+		Keyboard(const String& name, RawInputHandler* owner);
+		~Keyboard();
+
+		/** Returns the name of the device. */
+		String getName() const { return mName; }
+
+		/** Captures the input since the last call and triggers the events on the parent RawInputHandler. */
+		void capture();
+
+	private:
+		friend class RawInputHandler;
+
+		/** Changes the capture context. Should be called when focus is moved to a new window. */
+		void changeCaptureContext(UINT64 windowHandle);
+
+		String mName;
+		RawInputHandler* mOwner;
+
+		Pimpl* m;
+	};
+}

+ 35 - 0
Source/BansheeCore/Input/BsMouse.h

@@ -0,0 +1,35 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace bs
+{
+	/** Represents a single hardware mouse. Used by the RawInputHandler to report raw mouse input events. */
+	class BS_CORE_EXPORT Mouse
+	{
+	public:
+		struct Pimpl;
+
+		Mouse(const String& name, RawInputHandler* owner);
+		~Mouse();
+
+		/** Returns the name of the device. */
+		String getName() const { return mName; }
+
+		/** Captures the input since the last call and triggers the events on the parent RawInputHandler. */
+		void capture();
+
+	private:
+		friend class RawInputHandler;
+
+		/** Changes the capture context. Should be called when focus is moved to a new window. */
+		void changeCaptureContext(UINT64 windowHandle);
+
+		String mName;
+		RawInputHandler* mOwner;
+
+		Pimpl* m;
+	};
+}

+ 187 - 0
Source/BansheeCore/Input/BsRawInputHandler.cpp

@@ -0,0 +1,187 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "Input/BsRawInputHandler.h"
+#include "Input/BsMouse.h"
+#include "Input/BsKeyboard.h"
+#include "Input/BsGamepad.h"
+#include "Utility/BsTime.h"
+#include "RenderAPI/BsRenderWindow.h"
+#include "Math/BsMath.h"
+
+namespace bs
+{
+	RawInputHandler::RawInputHandler(UINT64 windowHandle)
+		: mMouseSmoothingEnabled(false), mWindowHandle(windowHandle), mMouse(nullptr), mKeyboard(nullptr)
+	{
+		mMouseSampleAccumulator[0] = 0;
+		mMouseSampleAccumulator[1] = 0;
+		mTotalMouseSamplingTime[0] = 1.0f / 125.0f; // Use 125Hz as initial pooling rate for mice
+		mTotalMouseSamplingTime[1] = 1.0f / 125.0f;
+		mTotalMouseNumSamples[0] = 1;
+		mTotalMouseNumSamples[1] = 1;
+		mMouseSmoothedAxis[0] = 0.0f;
+		mMouseSmoothedAxis[1] = 0.0f;
+		mMouseZeroTime[0] = 0.0f;
+		mMouseZeroTime[1] = 0.0f;
+
+		initialize();
+
+		mTimestampClockOffset = gTime().getStartTimeMs();
+	}
+
+	RawInputHandler::~RawInputHandler()
+	{
+		if (mMouse != nullptr)
+			bs_delete(mMouse);
+
+		if (mKeyboard != nullptr)
+			bs_delete(mKeyboard);
+
+		for (auto& gamepad : mGamepads)
+			bs_delete(gamepad);
+
+		cleanUp();
+	}
+
+	void RawInputHandler::_update()
+	{
+		if (mMouse != nullptr)
+			mMouse->capture();
+
+		if (mKeyboard != nullptr)
+			mKeyboard->capture();
+
+		for (auto& gamepad : mGamepads)
+			gamepad->capture();
+
+		float rawXValue = 0.0f;
+		float rawYValue = 0.0f;
+
+		// Smooth mouse axes if needed
+		if (mMouseSmoothingEnabled)
+		{
+			rawXValue = smoothMouse((float)mMouseSampleAccumulator[0], 0);
+			rawYValue = smoothMouse((float)mMouseSampleAccumulator[1], 1);
+		}
+		else
+		{
+			rawXValue = (float)mMouseSampleAccumulator[0];
+			rawYValue = (float)mMouseSampleAccumulator[1];
+		}
+
+		rawXValue *= 0.1f;
+		rawYValue *= 0.1f;
+
+		mMouseSampleAccumulator[0] = 0;
+		mMouseSampleAccumulator[1] = 0;
+
+		RawAxisState xState;
+		xState.rel = -rawXValue;
+		onAxisMoved(0, xState, (UINT32)InputAxis::MouseX);
+
+		RawAxisState yState;
+		yState.rel = -rawYValue;
+		
+		onAxisMoved(0, yState, (UINT32)InputAxis::MouseY);
+	}
+
+	void RawInputHandler::_inputWindowChanged(const RenderWindow& win)
+	{
+		UINT64 hWnd = 0;
+		win.getCustomAttribute("WINDOW", &hWnd);
+
+		mKeyboard->changeCaptureContext(hWnd);
+		mMouse->changeCaptureContext(hWnd);
+
+		for (auto& gamepad : mGamepads)
+			gamepad->changeCaptureContext(hWnd);
+	}
+
+	void RawInputHandler::_notifyMouseMoved(INT32 relX, INT32 relY, INT32 relZ)
+	{
+		mMouseSampleAccumulator[0] += relX;
+		mMouseSampleAccumulator[1] += relY;
+
+		mTotalMouseNumSamples[0] += Math::roundToInt(Math::abs((float)relX));
+		mTotalMouseNumSamples[1] += Math::roundToInt(Math::abs((float)relY));
+
+		// Update sample times used for determining sampling rate. But only if something was
+		// actually sampled, and only if this isn't the first non-zero sample.
+		if (mLastMouseUpdateFrame != gTime().getFrameIdx())
+		{
+			if (relX != 0 && !Math::approxEquals(mMouseSmoothedAxis[0], 0.0f))
+				mTotalMouseSamplingTime[0] += gTime().getFrameDelta();
+
+			if (relY != 0 && !Math::approxEquals(mMouseSmoothedAxis[1], 0.0f))
+				mTotalMouseSamplingTime[1] += gTime().getFrameDelta();
+
+			mLastMouseUpdateFrame = gTime().getFrameIdx();
+		}
+
+		RawAxisState zState;
+		zState.rel = (float)relZ;
+
+		onAxisMoved(0, zState, (UINT32)InputAxis::MouseZ);
+	}
+
+	void RawInputHandler::_notifyAxisMoved(UINT32 gamepadIdx, UINT32 axisIdx, INT32 value)
+	{
+		// Move axis values into [-1.0f, 1.0f] range
+		float axisRange = Math::abs((float)Gamepad::MAX_AXIS) + Math::abs((float)Gamepad::MIN_AXIS);
+
+		RawAxisState axisState;
+		axisState.rel = ((value + Math::abs((float)Gamepad::MIN_AXIS)) / axisRange) * 2.0f - 1.0f;
+
+		onAxisMoved(gamepadIdx, axisState, axisIdx);
+	}
+
+	void RawInputHandler::_notifyButtonPressed(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp)
+	{
+		onButtonDown(deviceIdx, code, timestamp - mTimestampClockOffset);
+	}
+
+	void RawInputHandler::_notifyButtonReleased(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp)
+	{
+		onButtonUp(deviceIdx, code, timestamp - mTimestampClockOffset);
+	}
+
+	float RawInputHandler::smoothMouse(float value, UINT32 idx)
+	{
+		UINT32 sampleCount = 1;
+
+		float deltaTime = gTime().getFrameDelta();
+		if (deltaTime < 0.25f)
+		{
+			float secondsPerSample = mTotalMouseSamplingTime[idx] / mTotalMouseNumSamples[idx];
+
+			if (value == 0.0f)
+			{
+				mMouseZeroTime[idx] += deltaTime;
+				if (mMouseZeroTime[idx] < secondsPerSample)
+					value = mMouseSmoothedAxis[idx] * deltaTime / secondsPerSample;
+				else
+					mMouseSmoothedAxis[idx] = 0;
+			}
+			else
+			{
+				mMouseZeroTime[idx] = 0;
+				if (mMouseSmoothedAxis[idx] != 0)
+				{
+					if (deltaTime < secondsPerSample * (sampleCount + 1))
+						value = value * deltaTime / (secondsPerSample * sampleCount);
+					else
+						sampleCount = Math::roundToInt(deltaTime / secondsPerSample);
+				}
+
+				mMouseSmoothedAxis[idx] = value / sampleCount;
+			}
+		}
+		else
+		{
+			mMouseSmoothedAxis[idx] = 0.0f;
+			mMouseZeroTime[idx] = 0.0f;
+		}
+
+		return value;
+	}
+}

+ 64 - 12
Source/BansheeCore/Input/BsRawInputHandler.h

@@ -8,22 +8,25 @@
 
 namespace bs
 {
+	class Mouse;
+	class Keyboard;
+	class Gamepad;
+	struct InputPrivateData;
+
 	/** @addtogroup Input-Internal
 	 *  @{
 	 */
 
 	/**
-	 * Contains relative and absolute position of an input axis. Relative state represents the difference between current 
-	 * and last state.
+	 * Contains relative position of an input axis. Relative state represents the difference between current and last state.
 	 */
 	struct RawAxisState
 	{
 		RawAxisState()
-		 :rel(0.0f), abs(0.0f)
+		 :rel(0.0f)
 		{ }
 
 		float rel;
-		float abs;
 	};
 
 	/**
@@ -34,11 +37,14 @@ namespace bs
 	class BS_CORE_EXPORT RawInputHandler
 	{
 	public:
-		RawInputHandler()
-			:mMouseSmoothingEnabled(false) 
-		{}
+		RawInputHandler(UINT64 windowHandle);
+		virtual ~RawInputHandler();
 
-		virtual ~RawInputHandler() {}
+		/** Enables or disables mouse smoothing. Smoothing makes the changes to mouse axes more gradual. */
+		void setMouseSmoothing(bool enabled) { mMouseSmoothingEnabled = enabled; }
+
+		/** Returns the number of detected devices of the specified type. */
+		UINT32 getDeviceCount(InputDevice device) const;
 
 		/**
 		 * Triggered when user presses a button. Parameters include device index, button code of the pressed button, 
@@ -59,20 +65,66 @@ namespace bs
 		Event<void(UINT32, const RawAxisState&, UINT32)> onAxisMoved;
 
 		/** Called once per frame. Capture input here if needed. */
-		virtual void _update() {}
+		void _update();
 
 		/**
 		 * Called whenever the active window changes.
 		 *
 		 * @param[in]	win	Newly active window.
 		 */
-		virtual void _inputWindowChanged(const RenderWindow& win) {}
+		void _inputWindowChanged(const RenderWindow& win);
 
-		/** Enables or disables mouse smoothing. Smoothing makes the changes to mouse axes more gradual. */
-		void setMouseSmoothing(bool enabled) { mMouseSmoothingEnabled = enabled; }
+		/** Returns internal, platform specific privata data. */
+		InputPrivateData* _getPrivateData() const { return mPlatformData; }
+
+		/** Returns a handle to the window that is currently receiving input. */
+		UINT64 _getWindowHandle() const { return mWindowHandle; }
+
+		/** Called by Mouse when mouse movement is detected. */
+		void _notifyMouseMoved(INT32 relX, INT32 relY, INT32 relZ);
+
+		/** Called by any of the devices when analog axis movement is detected. */
+		void _notifyAxisMoved(UINT32 gamepadIdx, UINT32 axisIdx, INT32 value);
+
+		/** Called by any of the devices when a button is pressed. */
+		void _notifyButtonPressed(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
 
+		/** Called by any of the devices when a button is released. */
+		void _notifyButtonReleased(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
 	protected:
+		/** Performs platform specific input system initialization. */
+		void initialize();
+
+		/** Performs platform specific input system cleanup. */
+		void cleanUp();
+
+		/**
+		 * Smooths the input mouse axis value. Smoothing makes the changes to the axis more gradual depending on previous
+		 * values.
+		 *
+		 * @param[in]	value	Value to smooth.
+		 * @param[in]	idx		Index of the mouse axis to smooth, 0 - horizontal, 1 - vertical.
+		 * @return				Smoothed value.
+		 */
+		float smoothMouse(float value, UINT32 idx);
+
 		bool mMouseSmoothingEnabled;
+		UINT64 mWindowHandle;
+
+		Mouse* mMouse;
+		Keyboard* mKeyboard;
+		Vector<Gamepad*> mGamepads;
+
+		float mTotalMouseSamplingTime[2];
+		UINT32 mTotalMouseNumSamples[2];
+		float mMouseZeroTime[2];
+		INT32 mMouseSampleAccumulator[2];
+		float mMouseSmoothedAxis[2];
+		UINT64 mLastMouseUpdateFrame;
+
+		UINT64 mTimestampClockOffset;
+
+		InputPrivateData* mPlatformData;
 	};
 
 	/** @} */

+ 417 - 0
Source/BansheeCore/Win32/BsWin32Gamepad.cpp

@@ -0,0 +1,417 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "Input/BsGamepad.h"
+#include "Input/BsRawInputHandler.h"
+#include "Win32/BsWin32Input.h"
+#include "Error/BsException.h"
+
+#undef DIJOFS_BUTTON
+#define DIJOFS_BUTTON(n)  (FIELD_OFFSET(DIJOYSTATE2, rgbButtons) + (n))
+
+namespace bs
+{
+	/** Contains state of a POV (DPad). */
+	struct POVState
+	{
+		ButtonCode code;
+		bool pressed;
+	};
+
+	/** Contains private data for the Win32 Gamepad implementation. */
+	struct Gamepad::Pimpl
+	{
+		IDirectInput8* directInput;
+		IDirectInputDevice8* gamepad;
+		GamepadInfo info;
+		DWORD coopSettings;
+		HWND hWnd;
+
+		POVState povState[4];
+		INT32 axisState[6]; // Only for XInput
+		bool buttonState[16]; // Only for XInput
+	};
+
+	/** 
+	 * Initializes DirectInput gamepad device for a window with the specified handle. Only input from that window will be 
+	 * reported. 
+	 */
+	void initializeDirectInput(Gamepad::Pimpl* m, HWND hWnd)
+	{
+		DIPROPDWORD dipdw;
+		dipdw.diph.dwSize = sizeof(DIPROPDWORD);
+		dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+		dipdw.diph.dwObj = 0;
+		dipdw.diph.dwHow = DIPH_DEVICE;
+		dipdw.dwData = DI_BUFFER_SIZE_GAMEPAD;
+
+		if (FAILED(m->directInput->CreateDevice(m->info.guidInstance, &m->gamepad, nullptr)))
+			BS_EXCEPT(InternalErrorException, "DirectInput gamepad init: Failed to create device.");
+
+		if (FAILED(m->gamepad->SetDataFormat(&c_dfDIJoystick2)))
+			BS_EXCEPT(InternalErrorException, "DirectInput gamepad init: Failed to set format.");
+
+		if (FAILED(m->gamepad->SetCooperativeLevel(hWnd, m->coopSettings)))
+			BS_EXCEPT(InternalErrorException, "DirectInput gamepad init: Failed to set coop level.");
+
+		if (FAILED(m->gamepad->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
+			BS_EXCEPT(InternalErrorException, "DirectInput gamepad init: Failed to set property.");
+
+		HRESULT hr = m->gamepad->Acquire();
+		if (FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO)
+			BS_EXCEPT(InternalErrorException, "DirectInput gamepad init: Failed to acquire device.");
+
+		m->hWnd = hWnd;
+	}
+
+	/** Releases DirectInput resources for the provided device */
+	void releaseDirectInput(Gamepad::Pimpl* m)
+	{
+		if(m->gamepad)
+		{
+			m->gamepad->Unacquire();
+			m->gamepad->Release();
+			m->gamepad = nullptr;
+		}
+	}
+
+	/** Handles a DirectInput POV event. */
+	void handlePOV(RawInputHandler* owner, Gamepad::Pimpl* m, int pov, DIDEVICEOBJECTDATA& di)
+	{
+		if (LOWORD(di.dwData) == 0xFFFF)
+		{
+			// Centered, release any buttons
+			if (m->povState[pov].pressed)
+			{
+				owner->_notifyButtonReleased(m->info.id, m->povState[pov].code, di.dwTimeStamp);
+				m->povState[pov].pressed = false;
+			}
+		}
+		else
+		{
+			POVState newPOVState;
+			bs_zero_out(newPOVState);
+
+			switch (di.dwData)
+			{
+			case 0: 
+				newPOVState.code = BC_GAMEPAD_DPAD_UP;
+				newPOVState.pressed = true;
+				break;
+			case 4500:
+				newPOVState.code = BC_GAMEPAD_DPAD_UPRIGHT;
+				newPOVState.pressed = true;
+				break;
+			case 9000:
+				newPOVState.code = BC_GAMEPAD_DPAD_RIGHT;
+				newPOVState.pressed = true;
+				break;
+			case 13500:
+				newPOVState.code = BC_GAMEPAD_DPAD_DOWNRIGHT;
+				newPOVState.pressed = true;
+				break;
+			case 18000:
+				newPOVState.code = BC_GAMEPAD_DPAD_DOWN;
+				newPOVState.pressed = true;
+				break;
+			case 22500:
+				newPOVState.code = BC_GAMEPAD_DPAD_DOWNLEFT;
+				newPOVState.pressed = true;
+				break;
+			case 27000:
+				newPOVState.code = BC_GAMEPAD_DPAD_LEFT;
+				newPOVState.pressed = true;
+				break;
+			case 31500:
+				newPOVState.code = BC_GAMEPAD_DPAD_UPLEFT;
+				newPOVState.pressed = true;
+				break;
+			}
+
+			// Button was pressed
+			if (newPOVState.pressed)
+			{
+				// Another button was previously pressed
+				if (m->povState[pov].pressed)
+				{
+					// If its a different button, release the old one and press the new one
+					if (m->povState[pov].code != newPOVState.code)
+					{
+						owner->_notifyButtonReleased(m->info.id, m->povState[pov].code, di.dwTimeStamp);
+						owner->_notifyButtonPressed(m->info.id, newPOVState.code, di.dwTimeStamp);
+
+						m->povState[pov].code = newPOVState.code;
+					}
+				}
+				else
+				{
+					owner->_notifyButtonPressed(m->info.id, newPOVState.code, di.dwTimeStamp);
+					m->povState[pov].code = newPOVState.code;
+					m->povState[pov].pressed = true;
+				}
+			}
+		}
+	}
+
+	/** Converts a DirectInput or XInput button code to Banshee ButtonCode. */
+	ButtonCode gamepadButtonToButtonCode(INT32 code)
+	{
+		switch (code)
+		{
+		case 0:
+			return BC_GAMEPAD_DPAD_UP;
+		case 1:
+			return BC_GAMEPAD_DPAD_DOWN;
+		case 2:
+			return BC_GAMEPAD_DPAD_LEFT;
+		case 3:
+			return BC_GAMEPAD_DPAD_RIGHT;
+		case 4:
+			return BC_GAMEPAD_START;
+		case 5:
+			return BC_GAMEPAD_BACK;
+		case 6:
+			return BC_GAMEPAD_LS;
+		case 7:
+			return BC_GAMEPAD_RS;
+		case 8:
+			return BC_GAMEPAD_LB;
+		case 9:
+			return BC_GAMEPAD_RB;
+		case 10:
+			return BC_GAMEPAD_BTN1;
+		case 11:
+			return BC_GAMEPAD_LS;
+		case 12:
+			return BC_GAMEPAD_A;
+		case 13:
+			return BC_GAMEPAD_B;
+		case 14:
+			return BC_GAMEPAD_X;
+		case 15:
+			return BC_GAMEPAD_Y;
+		}
+
+		return (ButtonCode)(BC_GAMEPAD_BTN1 + (code - 15));
+	}
+
+	Gamepad::Gamepad(const String& name, const GamepadInfo& gamepadInfo, RawInputHandler* owner)
+		: mName(name), mOwner(owner)
+	{
+		InputPrivateData* pvtData = owner->_getPrivateData();
+
+		m = bs_new<Pimpl>();
+		m->directInput = pvtData->directInput;
+		m->coopSettings = pvtData->mouseSettings;
+		m->info = gamepadInfo;
+		m->gamepad = nullptr;
+		m->hWnd = (HWND)owner->_getWindowHandle();
+		bs_zero_out(m->povState);
+		bs_zero_out(m->axisState);
+		bs_zero_out(m->buttonState);
+
+		if(!m->info.isXInput)
+			initializeDirectInput(m, m->hWnd);
+	}
+
+	Gamepad::~Gamepad()
+	{
+		releaseDirectInput(m);
+
+		bs_delete(m);
+	}
+
+	void Gamepad::capture()
+	{
+		if(m->info.isXInput)
+		{
+			XINPUT_STATE inputState;
+			if (XInputGetState((DWORD)m->info.xInputDev, &inputState) != ERROR_SUCCESS)
+				memset(&inputState, 0, sizeof(inputState));
+
+			// Sticks and triggers
+			struct AxisState
+			{
+				bool moved;
+				INT32 value;
+			};
+
+			AxisState axisState[6];
+			bs_zero_out(axisState);
+
+			// Left stick
+			axisState[0].value = -(int)inputState.Gamepad.sThumbLY;
+			axisState[1].value = (int)inputState.Gamepad.sThumbLX;
+
+			// Right stick 
+			axisState[2].value = -(int)inputState.Gamepad.sThumbRY;
+			axisState[3].value = (int)inputState.Gamepad.sThumbRX;
+
+			// Left trigger
+			axisState[4].value = std::min((int)inputState.Gamepad.bLeftTrigger * 129, MAX_AXIS);
+
+			// Right trigger
+			axisState[5].value = std::min((int)inputState.Gamepad.bRightTrigger * 129, MAX_AXIS);
+
+			for (UINT32 i = 0; i < 6; i++)
+			{
+				axisState[i].moved = axisState[i].value != m->axisState[i];
+				m->axisState[i] = axisState[i].value;
+			}
+
+			// DPAD (POV)
+			ButtonCode dpadButton = BC_UNASSIGNED;
+			if ((inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0)
+				dpadButton = BC_GAMEPAD_DPAD_UP;
+			else if ((inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0)
+				dpadButton = BC_GAMEPAD_DPAD_DOWN;
+			if ((inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0 )
+				dpadButton = BC_GAMEPAD_DPAD_LEFT;
+			else if ((inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0)
+				dpadButton = BC_GAMEPAD_DPAD_RIGHT;
+
+			if(dpadButton != BC_UNASSIGNED) // Pressed
+			{
+				// Another button was previously pressed
+				if (m->povState[0].pressed)
+				{
+					// If its a different button, release the old one and press the new one
+					if (m->povState[0].code != dpadButton)
+					{
+						mOwner->_notifyButtonReleased(m->info.id, m->povState[0].code, GetTickCount64());
+						mOwner->_notifyButtonPressed(m->info.id, dpadButton, GetTickCount64());
+
+						m->povState[0].code = dpadButton;
+					}
+				}
+				else
+				{
+					mOwner->_notifyButtonPressed(m->info.id, dpadButton, GetTickCount64());
+					m->povState[0].code = dpadButton;
+					m->povState[0].pressed = true;
+				}
+			}
+			else
+			{
+				if (m->povState[0].pressed)
+				{
+					mOwner->_notifyButtonReleased(m->info.id, m->povState[0].code, GetTickCount64());
+					m->povState[0].pressed = false;
+				}
+			}
+
+			// Buttons
+			for (UINT32 i = 0; i < 16; i++)
+			{
+				bool buttonState = (inputState.Gamepad.wButtons & (1 << i)) != 0;
+
+				if(buttonState != m->buttonState[i])
+				{
+					if (buttonState)
+						mOwner->_notifyButtonPressed(m->info.id, gamepadButtonToButtonCode(i), GetTickCount64());
+					else
+						mOwner->_notifyButtonReleased(m->info.id, gamepadButtonToButtonCode(i), GetTickCount64());
+
+					m->buttonState[i] = buttonState;
+				}
+			}
+		}
+		else // DirectInput
+		{
+			DIDEVICEOBJECTDATA diBuff[DI_BUFFER_SIZE_GAMEPAD];
+			DWORD numEntries = DI_BUFFER_SIZE_GAMEPAD;
+
+			HRESULT hr = m->gamepad->Poll();
+			if (hr == DI_OK)
+				hr = m->gamepad->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diBuff, &numEntries, 0);
+
+			if (hr != DI_OK)
+			{
+				hr = m->gamepad->Acquire();
+				while (hr == DIERR_INPUTLOST)
+					hr = m->gamepad->Acquire();
+
+				m->gamepad->Poll();
+				hr = m->gamepad->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diBuff, &numEntries, 0);
+
+				if (FAILED(hr))
+					return;
+			}
+
+			struct AxisState
+			{
+				bool moved;
+				INT32 value;
+			};
+
+			AxisState axisState[24];
+			bs_zero_out(axisState);
+
+			// Note: Not reporting slider or POV events
+			for (UINT32 i = 0; i < numEntries; ++i)
+			{
+				switch (diBuff[i].dwOfs)
+				{
+				case DIJOFS_POV(0):
+					handlePOV(mOwner, m, 0, diBuff[i]);
+					break;
+				case DIJOFS_POV(1):
+					handlePOV(mOwner, m, 1, diBuff[i]);
+					break;
+				case DIJOFS_POV(2):
+					handlePOV(mOwner, m, 2, diBuff[i]);
+					break;
+				case DIJOFS_POV(3):
+					handlePOV(mOwner, m, 3, diBuff[i]);
+					break;
+				default:
+					// Button event
+					if (diBuff[i].dwOfs >= DIJOFS_BUTTON(0) && diBuff[i].dwOfs < DIJOFS_BUTTON(128))
+					{
+						int button = diBuff[i].dwOfs - DIJOFS_BUTTON(0);
+
+						if ((diBuff[i].dwData & 0x80) != 0)
+							mOwner->_notifyButtonPressed(m->info.id, gamepadButtonToButtonCode(button), diBuff[i].dwTimeStamp);
+						else
+							mOwner->_notifyButtonReleased(m->info.id, gamepadButtonToButtonCode(button), diBuff[i].dwTimeStamp);
+
+					}
+					else if ((short)(diBuff[i].uAppData >> 16) == 0x1313) // Axis event
+					{
+						int axis = (int)(0x0000FFFF & diBuff[i].uAppData);
+						if (axis < 24)
+						{
+							axisState[axis].moved = true;
+							axisState[axis].value = diBuff[i].dwData;
+						}
+					}
+				}
+			}
+
+			if (numEntries > 0)
+			{
+				for (int i = 0; i < 24; ++i)
+				{
+					if (!axisState[i].moved)
+						continue;
+					
+					mOwner->_notifyAxisMoved(m->info.id, i + (int)InputAxis::MouseZ, axisState[i].value);
+				}
+			}
+		}
+	}
+
+	void Gamepad::changeCaptureContext(UINT64 windowHandle)
+	{
+		HWND newhWnd = (HWND)windowHandle;
+
+		if(m->hWnd != newhWnd)
+		{
+			releaseDirectInput(m);
+
+			if (!m->info.isXInput)
+				initializeDirectInput(m, newhWnd);
+			else
+				m->hWnd = newhWnd;
+		}
+	}
+}

+ 205 - 0
Source/BansheeCore/Win32/BsWin32Input.cpp

@@ -0,0 +1,205 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "Input/BsRawInputHandler.h"
+#include "Error/BsException.h"
+#include "Win32/BsWin32Input.h"
+#include "Input/BsMouse.h"
+#include "Input/BsKeyboard.h"
+#include "Input/BsGamepad.h"
+
+namespace bs
+{
+	BOOL CALLBACK _DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
+	{
+		InputPrivateData* data = (InputPrivateData*)(pvRef);
+
+		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)
+		{
+			GamepadInfo gamepadInfo;
+			gamepadInfo.name = lpddi->tszInstanceName;
+			gamepadInfo.guidInstance = lpddi->guidInstance;
+			gamepadInfo.guidProduct = lpddi->guidProduct;
+			gamepadInfo.id = (UINT32)data->gamepadInfos.size();
+			gamepadInfo.isXInput = false;
+			gamepadInfo.xInputDev = 0;
+
+			data->gamepadInfos.push_back(gamepadInfo);
+		}
+
+		return DIENUM_CONTINUE;
+	}
+	
+	void CheckXInputDevices(Vector<GamepadInfo>& infos)
+	{
+		if (infos.size() == 0)
+			return;
+
+		HRESULT hr = CoInitialize(nullptr);
+		bool cleanupCOM = SUCCEEDED(hr);
+
+		// Create WMI
+		IWbemLocator* IWbemLocator = nullptr;
+		hr = CoCreateInstance(__uuidof(WbemLocator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&IWbemLocator);
+		if (FAILED(hr) || IWbemLocator == nullptr)
+			goto cleanup;
+
+		BSTR classNameSpace = SysAllocString(L"\\\\.\\root\\cimv2");
+		if (classNameSpace == nullptr)
+			goto cleanup;
+
+		BSTR className = SysAllocString(L"Win32_PNPEntity");
+		if (className == nullptr)
+			goto cleanup;
+
+		BSTR deviceID = SysAllocString(L"DeviceID");
+		if (deviceID == nullptr)
+			goto cleanup;
+
+		// Connect to WMI
+		IWbemServices* IWbemServices = nullptr;
+		hr = IWbemLocator->ConnectServer(classNameSpace, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &IWbemServices);
+		if (FAILED(hr) || IWbemServices == nullptr)
+			goto cleanup;
+
+		// Switch security level to IMPERSONATE
+		CoSetProxyBlanket(IWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
+
+		IEnumWbemClassObject* enumDevices = nullptr;
+		hr = IWbemServices->CreateInstanceEnum(className, 0, nullptr, &enumDevices);
+		if (FAILED(hr) || enumDevices == nullptr)
+			goto cleanup;
+
+		// Loop over all devices
+		IWbemClassObject* devices[20] = { 0 };
+		for (;; )
+		{
+			DWORD numDevices = 0;
+			hr = enumDevices->Next(5000, 20, devices, &numDevices);
+			if (FAILED(hr))
+				goto cleanup;
+
+			if (numDevices == 0)
+				break;
+
+			for (DWORD i = 0; i < numDevices; i++)
+			{
+				// For each device, get its device ID
+				VARIANT var;
+				hr = devices[i]->Get(deviceID, 0L, &var, nullptr, nullptr);
+				if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != nullptr)
+				{
+					// Check if the device ID contains "IG_".  If it does, then it's an XInput device
+					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 (auto entry : infos)
+						{
+							if (dwVidPid == entry.guidProduct.Data1)
+							{
+								entry.isXInput = true;
+								entry.xInputDev = (int)entry.id; // Note: These might not match and I might need to get the XInput id differently
+							}
+						}
+					}
+				}
+
+				devices[i]->Release();
+			}
+		}
+
+	cleanup:
+		if (classNameSpace)
+			SysFreeString(classNameSpace);
+
+		if (deviceID)
+			SysFreeString(deviceID);
+
+		if (className)
+			SysFreeString(className);
+
+		for (DWORD i = 0; i < 20; i++)
+			devices[i]->Release();
+
+		enumDevices->Release();
+		IWbemLocator->Release();
+		IWbemServices->Release();
+
+		if (cleanupCOM)
+			CoUninitialize();
+	}
+
+	void RawInputHandler::initialize()
+	{
+		mPlatformData = bs_new<InputPrivateData>();
+		
+		if (IsWindow((HWND)mWindowHandle) == 0)
+			BS_EXCEPT(InvalidStateException, "RawInputManager failed to initialized. Invalid HWND provided.")
+
+		HINSTANCE hInst = GetModuleHandle(0);
+
+		HRESULT hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mPlatformData->directInput, nullptr);
+		if (FAILED(hr))
+			BS_EXCEPT(InternalErrorException, "Unable to initialize DirectInput.");
+
+		mPlatformData->kbSettings = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE;
+		mPlatformData->mouseSettings = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE;
+		
+		// Enumerate all attached devices
+		// Note: Only enumerating gamepads, assuming there is 1 keyboard and 1 mouse
+		mPlatformData->directInput->EnumDevices(NULL, _DIEnumDevCallback, mPlatformData, DIEDFL_ATTACHEDONLY);
+
+		for (UINT32 i = 0; i < 4; ++i)
+		{
+			XINPUT_STATE state;
+			if (XInputGetState(i, &state) != ERROR_DEVICE_NOT_CONNECTED)
+			{
+				CheckXInputDevices(mPlatformData->gamepadInfos);
+				break;
+			}
+		}
+
+		if (getDeviceCount(InputDevice::Keyboard) > 0)
+			mKeyboard = bs_new<Keyboard>("Keyboard", this);
+
+		if (getDeviceCount(InputDevice::Mouse) > 0)
+			mMouse = bs_new<Mouse>("Mouse", this);
+
+		UINT32 numGamepads = getDeviceCount(InputDevice::Gamepad);
+		for (UINT32 i = 0; i < numGamepads; i++)
+			mGamepads.push_back(bs_new<Gamepad>(mPlatformData->gamepadInfos[i].name, mPlatformData->gamepadInfos[i], this));
+	}
+
+	void RawInputHandler::cleanUp()
+	{
+		mPlatformData->directInput->Release();
+
+		bs_delete(mPlatformData);
+	}
+
+	UINT32 RawInputHandler::getDeviceCount(InputDevice device) const
+	{
+		switch(device)
+		{
+		case InputDevice::Keyboard: return 1;
+		case InputDevice::Mouse: return 1;
+		case InputDevice::Gamepad: return (UINT32)mPlatformData->gamepadInfos.size();
+		default:
+		case InputDevice::Count: return 0;
+		}
+	}
+}

+ 47 - 0
Source/BansheeCore/Win32/BsWin32Input.h

@@ -0,0 +1,47 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+#define WIN32_LEAN_AND_MEAN
+#define DIRECTINPUT_VERSION 0x0800
+#include <windows.h>
+#include <dinput.h>
+#include <Xinput.h>
+
+#include <wbemidl.h>
+#include <oleauto.h>
+
+namespace bs
+{
+	/** Information about a gamepad from DirectInput. */
+	struct GamepadInfo
+	{
+		UINT32 id;
+		GUID guidInstance;
+		GUID guidProduct;
+		String name;
+
+		bool isXInput;
+		int xInputDev;
+	};
+
+	/**
+	 * Data specific to Win32 implementation of the input system. Can be passed to platform specific implementations of
+	 * the individual device types.
+	 */
+	struct InputPrivateData
+	{
+		IDirectInput8* directInput;
+		Vector<GamepadInfo> gamepadInfos;
+
+		DWORD kbSettings;
+		DWORD mouseSettings;
+	};
+
+	// Max number of elements to collect from buffered DirectInput
+	#define DI_BUFFER_SIZE_KEYBOARD 17
+	#define DI_BUFFER_SIZE_MOUSE 128
+	#define DI_BUFFER_SIZE_GAMEPAD 129
+}

+ 166 - 0
Source/BansheeCore/Win32/BsWin32Keyboard.cpp

@@ -0,0 +1,166 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "Input/BsKeyboard.h"
+#include "Input/BsRawInputHandler.h"
+#include "Win32/BsWin32Input.h"
+#include "Error/BsException.h"
+
+namespace bs
+{
+	/** Contains private data for the Win32 Keyboard implementation. */
+	struct Keyboard::Pimpl
+	{
+		IDirectInput8* directInput;
+		IDirectInputDevice8* keyboard;
+		DWORD coopSettings;
+		HWND hWnd;
+
+		UINT8 keyBuffer[256];
+	};
+
+	/** 
+	 * Initializes DirectInput keyboard device for a window with the specified handle. Only input from that window will be 
+	 * reported. 
+	 */
+	void initializeDirectInput(Keyboard::Pimpl* m, HWND hWnd)
+	{
+		DIPROPDWORD dipdw;
+		dipdw.diph.dwSize = sizeof(DIPROPDWORD);
+		dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+		dipdw.diph.dwObj = 0;
+		dipdw.diph.dwHow = DIPH_DEVICE;
+		dipdw.dwData = DI_BUFFER_SIZE_KEYBOARD;
+
+		if (FAILED(m->directInput->CreateDevice(GUID_SysKeyboard, &m->keyboard, nullptr)))
+			BS_EXCEPT(InternalErrorException, "DirectInput keyboard init: Failed to create device.");
+
+		if (FAILED(m->keyboard->SetDataFormat(&c_dfDIKeyboard)))
+			BS_EXCEPT(InternalErrorException, "DirectInput keyboard init: Failed to set format.");
+
+		if (FAILED(m->keyboard->SetCooperativeLevel(hWnd, m->coopSettings)))
+			BS_EXCEPT(InternalErrorException, "DirectInput keyboard init: Failed to set coop level.");
+
+		if (FAILED(m->keyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
+			BS_EXCEPT(InternalErrorException, "DirectInput keyboard init: Failed to set property.");
+
+		HRESULT hr = m->keyboard->Acquire();
+		if (FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO)
+			BS_EXCEPT(InternalErrorException, "DirectInput keyboard init: Failed to acquire device.");
+
+		m->hWnd = hWnd;
+	}
+
+	/** Releases DirectInput resources for the provided device */
+	void releaseDirectInput(Keyboard::Pimpl* m)
+	{
+		if(m->keyboard)
+		{
+			m->keyboard->Unacquire();
+			m->keyboard->Release();
+			m->keyboard = nullptr;
+		}
+	}
+
+	Keyboard::Keyboard(const String& name, RawInputHandler* owner)
+		: mName(name), mOwner(owner)
+	{
+		InputPrivateData* pvtData = owner->_getPrivateData();
+
+		m = bs_new<Pimpl>();
+		m->directInput = pvtData->directInput;
+		m->coopSettings = pvtData->kbSettings;
+		m->keyboard = nullptr;
+		bs_zero_out(m->keyBuffer);
+
+		initializeDirectInput(m, (HWND)owner->_getWindowHandle());
+	}
+
+	Keyboard::~Keyboard()
+	{
+		releaseDirectInput(m);
+
+		bs_delete(m);
+	}
+
+	void Keyboard::capture()
+	{
+		DIDEVICEOBJECTDATA diBuff[DI_BUFFER_SIZE_KEYBOARD];
+		DWORD numEntries = DI_BUFFER_SIZE_KEYBOARD;
+
+		// Note: Only one keyboard per app due to this static (which is fine)
+		static bool verifyAfterAltTab = false;
+
+		HRESULT hr = m->keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diBuff, &numEntries, 0);
+		if (hr != DI_OK)
+		{
+			hr = m->keyboard->Acquire();
+			if (hr == E_ACCESSDENIED)
+				verifyAfterAltTab = true;
+
+			while (hr == DIERR_INPUTLOST)
+				hr = m->keyboard->Acquire();
+
+			return;
+		}
+
+		if (FAILED(hr))
+		{
+			LOGERR("Failed to read keyboard input. Internal error. ");
+			return;
+		}
+
+		for (UINT32 i = 0; i < numEntries; ++i)
+		{
+			ButtonCode buttonCode = (ButtonCode)diBuff[i].dwOfs;
+
+			m->keyBuffer[buttonCode] = (UINT8)(diBuff[i].dwData);
+
+			if (diBuff[i].dwData & 0x80)
+				mOwner->_notifyButtonPressed(0, buttonCode, diBuff[i].dwTimeStamp);
+			else
+				mOwner->_notifyButtonReleased(0, buttonCode, diBuff[i].dwTimeStamp);
+		}
+
+		// If a lost device/access denied was detected, recover
+		if (verifyAfterAltTab)
+		{
+			// Store old buffer
+			UINT8 keyBufferCopy[256];
+			memcpy(keyBufferCopy, m->keyBuffer, 256);
+
+			// Read immediate state
+			hr = m->keyboard->GetDeviceState(sizeof(m->keyBuffer), &m->keyBuffer);
+
+			if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)
+			{
+				hr = m->keyboard->Acquire();
+				if (hr != DIERR_OTHERAPPHASPRIO)
+					m->keyboard->GetDeviceState(sizeof(m->keyBuffer), &m->keyBuffer);
+			}
+
+			for (UINT32 i = 0; i < 256; i++)
+			{
+				if (keyBufferCopy[i] != m->keyBuffer[i])
+				{
+					if (m->keyBuffer[i])
+						mOwner->_notifyButtonPressed(0, (ButtonCode)i, GetTickCount64());
+					else
+						mOwner->_notifyButtonReleased(0, (ButtonCode)i, GetTickCount64());
+				}
+			}
+
+			verifyAfterAltTab = false;
+		}
+	}
+
+	void Keyboard::changeCaptureContext(UINT64 windowHandle)
+	{
+		HWND newhWnd = (HWND)windowHandle;
+
+		if(m->hWnd != newhWnd)
+		{
+			releaseDirectInput(m);
+			initializeDirectInput(m, newhWnd);
+		}
+	}
+}

+ 172 - 0
Source/BansheeCore/Win32/BsWin32Mouse.cpp

@@ -0,0 +1,172 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "Input/BsMouse.h"
+#include "Input/BsRawInputHandler.h"
+#include "Win32/BsWin32Input.h"
+#include "Error/BsException.h"
+
+namespace bs
+{
+	/** Contains private data for the Win32 Mouse implementation. */
+	struct Mouse::Pimpl
+	{
+		IDirectInput8* directInput;
+		IDirectInputDevice8* mouse;
+		DWORD coopSettings;
+		HWND hWnd;
+	};
+
+	/** 
+	 * Initializes DirectInput mouse device for a window with the specified handle. Only input from that window will be 
+	 * reported. 
+	 */
+	void initializeDirectInput(Mouse::Pimpl* m, HWND hWnd)
+	{
+		DIPROPDWORD dipdw;
+		dipdw.diph.dwSize = sizeof(DIPROPDWORD);
+		dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+		dipdw.diph.dwObj = 0;
+		dipdw.diph.dwHow = DIPH_DEVICE;
+		dipdw.dwData = DI_BUFFER_SIZE_MOUSE;
+
+		if (FAILED(m->directInput->CreateDevice(GUID_SysMouse, &m->mouse, nullptr)))
+			BS_EXCEPT(InternalErrorException, "DirectInput mouse init: Failed to create device.");
+
+		if (FAILED(m->mouse->SetDataFormat(&c_dfDIMouse2)))
+			BS_EXCEPT(InternalErrorException, "DirectInput mouse init: Failed to set format.");
+
+		if (FAILED(m->mouse->SetCooperativeLevel(hWnd, m->coopSettings)))
+			BS_EXCEPT(InternalErrorException, "DirectInput mouse init: Failed to set coop level.");
+
+		if (FAILED(m->mouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
+			BS_EXCEPT(InternalErrorException, "DirectInput mouse init: Failed to set property.");
+
+		HRESULT hr = m->mouse->Acquire();
+		if (FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO)
+			BS_EXCEPT(InternalErrorException, "DirectInput mouse init: Failed to acquire device.");
+
+		m->hWnd = hWnd;
+	}
+
+	/** Releases DirectInput resources for the provided device */
+	void releaseDirectInput(Mouse::Pimpl* m)
+	{
+		if(m->mouse)
+		{
+			m->mouse->Unacquire();
+			m->mouse->Release();
+			m->mouse = nullptr;
+		}
+	}
+
+	/** Notifies the input handler that a mouse press or release occurred. Triggers an event in the input handler. */
+	void doMouseClick(RawInputHandler* owner, ButtonCode mouseButton, const DIDEVICEOBJECTDATA& data)
+	{
+		if (data.dwData & 0x80)
+			owner->_notifyButtonPressed(0, mouseButton, data.dwTimeStamp);
+		else
+			owner->_notifyButtonReleased(0, mouseButton, data.dwTimeStamp);
+	}
+
+	Mouse::Mouse(const String& name, RawInputHandler* owner)
+		: mName(name), mOwner(owner)
+	{
+		InputPrivateData* pvtData = owner->_getPrivateData();
+
+		m = bs_new<Pimpl>();
+		m->directInput = pvtData->directInput;
+		m->coopSettings = pvtData->mouseSettings;
+		m->mouse = nullptr;
+
+		initializeDirectInput(m, (HWND)owner->_getWindowHandle());
+	}
+
+	Mouse::~Mouse()
+	{
+		releaseDirectInput(m);
+
+		bs_delete(m);
+	}
+
+	void Mouse::capture()
+	{
+		DIDEVICEOBJECTDATA diBuff[DI_BUFFER_SIZE_MOUSE];
+		DWORD numEntries = DI_BUFFER_SIZE_MOUSE;
+
+		HRESULT hr = m->mouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diBuff, &numEntries, 0);
+		if (hr != DI_OK)
+		{
+			hr = m->mouse->Acquire();
+			while (hr == DIERR_INPUTLOST)
+				hr = m->mouse->Acquire();
+
+			hr = m->mouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), diBuff, &numEntries, 0);
+
+			if (FAILED(hr))
+				return;
+		}
+
+		INT32 relX, relY, relZ;
+		relX = relY = relZ = 0;
+
+		bool axesMoved = false;
+		for (UINT32 i = 0; i < numEntries; ++i)
+		{
+			switch (diBuff[i].dwOfs)
+			{
+			case DIMOFS_BUTTON0:
+				doMouseClick(mOwner, BC_MOUSE_LEFT, diBuff[i]);
+				break;
+			case DIMOFS_BUTTON1:
+				doMouseClick(mOwner, BC_MOUSE_RIGHT, diBuff[i]);
+				break;
+			case DIMOFS_BUTTON2:
+				doMouseClick(mOwner, BC_MOUSE_MIDDLE, diBuff[i]);
+				break;
+			case DIMOFS_BUTTON3:
+				doMouseClick(mOwner, BC_MOUSE_BTN4, diBuff[i]);
+				break;
+			case DIMOFS_BUTTON4:
+				doMouseClick(mOwner, BC_MOUSE_BTN5, diBuff[i]);
+				break;
+			case DIMOFS_BUTTON5:
+				doMouseClick(mOwner, BC_MOUSE_BTN6, diBuff[i]);
+				break;
+			case DIMOFS_BUTTON6:
+				doMouseClick(mOwner, BC_MOUSE_BTN7, diBuff[i]);
+				break;
+			case DIMOFS_BUTTON7:
+				doMouseClick(mOwner, BC_MOUSE_BTN8, diBuff[i]);
+				break;
+			case DIMOFS_X:
+				relX += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			case DIMOFS_Y:
+				relY += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			case DIMOFS_Z:
+				relZ += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			default: break;
+			}
+		}
+
+		if (axesMoved)
+			mOwner->_notifyMouseMoved(relX, relY, relZ);
+
+	}
+
+	void Mouse::changeCaptureContext(UINT64 windowHandle)
+	{
+		HWND newhWnd = (HWND)windowHandle;
+
+		if(m->hWnd != newhWnd)
+		{
+			releaseDirectInput(m);
+			initializeDirectInput(m, newhWnd);
+		}
+	}
+}

+ 0 - 1
Source/BansheeEditor/BsEditorApplication.cpp

@@ -44,7 +44,6 @@ namespace bs
 		startUpDesc.renderer = BS_RENDERER_MODULE;
 		startUpDesc.audio = BS_AUDIO_MODULE;
 		startUpDesc.physics = BS_PHYSICS_MODULE;
-		startUpDesc.input = BS_INPUT_MODULE;
 		startUpDesc.scripting = true;
 
 		startUpDesc.primaryWindowDesc.videoMode = VideoMode(1920, 1080);

+ 4 - 2
Source/BansheeEditorExec/BsEditorExec.cpp

@@ -5,11 +5,11 @@
 #include "BsEditorApplication.h"
 #include "Error/BsCrashHandler.h"
 
-using namespace bs;
-
 #if BS_PLATFORM == BS_PLATFORM_WIN32
 #include <windows.h>
 
+using namespace bs;
+
 int CALLBACK WinMain(
 	_In_  HINSTANCE hInstance,
 	_In_  HINSTANCE hPrevInstance,
@@ -35,6 +35,8 @@ int CALLBACK WinMain(
 	return 0;
 }
 #else
+using namespace bs;
+
 int main()
 {
 	EditorApplication::startUp();

+ 0 - 1
Source/BansheeEngine/BsApplication.cpp

@@ -140,7 +140,6 @@ namespace bs
 		desc.renderer = BS_RENDERER_MODULE;
 		desc.audio = BS_AUDIO_MODULE;
 		desc.physics = BS_PHYSICS_MODULE;
-		desc.input = BS_INPUT_MODULE;
 		desc.scripting = false;
 
 		desc.importers.push_back("BansheeFreeImgImporter");

+ 0 - 337
Source/BansheeOISInput/BsInputHandlerOIS.cpp

@@ -1,337 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsInputHandlerOIS.h"
-#include "Math/BsVector2I.h"
-#include "OIS/OISException.h"
-#include "RenderAPI/BsRenderWindow.h"
-#include "Utility/BsTime.h"
-#include "Math/BsMath.h"
-#include "Debug/BsDebug.h"
-
-namespace bs
-{
-	GamepadEventListener::GamepadEventListener(InputHandlerOIS* parentHandler, UINT32 joystickIdx)
-		:mGamepadIdx(joystickIdx), mParentHandler(parentHandler)
-	{ }
-
-	bool GamepadEventListener::buttonPressed(const OIS::JoyStickEvent& arg, int button)
-	{
-		ButtonCode bc = InputHandlerOIS::gamepadButtonToButtonCode(button);
-
-		// Note: No timestamps for gamepad buttons, but they shouldn't be used for anything anyway
-		mParentHandler->onButtonDown(mGamepadIdx, bc, 0);
-		return true;
-	}
-
-	bool GamepadEventListener::buttonReleased(const OIS::JoyStickEvent& arg, int button)
-	{
-		ButtonCode bc = InputHandlerOIS::gamepadButtonToButtonCode(button);
-
-		// Note: No timestamps for gamepad buttons, but they shouldn't be used for anything anyway
-		mParentHandler->onButtonUp(mGamepadIdx, bc, 0);
-		return true;
-	}
-
-	bool GamepadEventListener::axisMoved(const OIS::JoyStickEvent& arg, int axis)
-	{
-		// Move axis values into [-1.0f, 1.0f] range
-		float axisRange = Math::abs((float)OIS::JoyStick::MAX_AXIS) + Math::abs((float)OIS::JoyStick::MIN_AXIS);
-
-		INT32 axisRel = arg.state.mAxes[axis].rel;
-		INT32 axisAbs = arg.state.mAxes[axis].abs;
-
-		RawAxisState axisState;
-		axisState.rel = ((axisRel + Math::abs((float)OIS::JoyStick::MIN_AXIS)) / axisRange) * 2.0f - 1.0f;
-		axisState.abs = ((axisAbs + Math::abs((float)OIS::JoyStick::MIN_AXIS)) / axisRange) * 2.0f - 1.0f;
-
-		mParentHandler->onAxisMoved(mGamepadIdx, axisState, (UINT32)axis);
-
-		return true;
-	}
-
-	InputHandlerOIS::InputHandlerOIS(UINT64 hWnd)
-		:mInputManager(nullptr), mMouse(nullptr), mKeyboard(nullptr), mLastMouseUpdateFrame(0), mTimestampClockOffset(0)
-	{
-		mMouseSampleAccumulator[0] = 0;
-		mMouseSampleAccumulator[1] = 0;
-		mTotalMouseSamplingTime[0] = 1.0f / 125.0f; // Use 125Hz as initial pooling rate for mice
-		mTotalMouseSamplingTime[1] = 1.0f / 125.0f;
-		mTotalMouseNumSamples[0] = 1;
-		mTotalMouseNumSamples[1] = 1;
-		mMouseSmoothedAxis[0] = 0.0f;
-		mMouseSmoothedAxis[1] = 0.0f;
-		mMouseZeroTime[0] = 0.0f;
-		mMouseZeroTime[1] = 0.0f;
-
-		OIS::ParamList pl;
-		std::ostringstream windowHndStr;
-		windowHndStr << hWnd;
-		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
-
-#if BS_PLATFORM == BS_PLATFORM_WIN32
-		pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
-		pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
-		pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
-		pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
-#elif BS_PLATFORM == BS_PLATFORM_LINUX || BS_PLATFORM == BS_PLATFORM_OSX
-		pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
-		pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
-		pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
-		pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
-#endif
-
-		mInputManager = OIS::InputManager::createInputSystem(pl);
-
-		if (mInputManager->getNumberOfDevices(OIS::OISKeyboard) > 0)
-		{
-			mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject(OIS::OISKeyboard, true));
-			mKeyboard->setEventCallback(this);
-		}
-
-		if (mInputManager->getNumberOfDevices(OIS::OISMouse) > 0)
-		{
-			mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject(OIS::OISMouse, true));
-			mMouse->setEventCallback(this);
-		}
-
-		UINT32 numGamepads = mInputManager->getNumberOfDevices(OIS::OISJoyStick);
-		for (UINT32 i = 0; i < numGamepads; i++)
-		{
-			mGamepads.push_back(GamepadData());
-			GamepadData& gamepadData = mGamepads.back();
-
-			gamepadData.gamepad = static_cast<OIS::JoyStick*>(mInputManager->createInputObject(OIS::OISJoyStick, true));
-			gamepadData.listener = bs_new<GamepadEventListener>(this, i);
-
-			gamepadData.gamepad->setEventCallback(gamepadData.listener);
-		}
-
-		// OIS reports times since system start but we use time since program start
-		mTimestampClockOffset = gTime().getStartTimeMs();
-	}
-
-	InputHandlerOIS::~InputHandlerOIS()
-	{
-		if(mInputManager)
-		{		
-			if(mMouse != nullptr)
-				mInputManager->destroyInputObject(mMouse);
-
-			if(mKeyboard != nullptr)
-				mInputManager->destroyInputObject(mKeyboard);
-
-			for (auto& gamepadData : mGamepads)
-			{
-				mInputManager->destroyInputObject(gamepadData.gamepad);
-				bs_delete(gamepadData.listener);
-			}
-
-			OIS::InputManager::destroyInputSystem(mInputManager);
-			mInputManager = nullptr;
-		}
-	}
-
-	float InputHandlerOIS::smoothMouse(float value, UINT32 idx)
-	{
-		UINT32 sampleCount = 1;
-
-		float deltaTime = gTime().getFrameDelta();
-		if (deltaTime < 0.25f)
-		{
-			float secondsPerSample = mTotalMouseSamplingTime[idx] / mTotalMouseNumSamples[idx];
-
-			if (value == 0.0f)
-			{
-				mMouseZeroTime[idx] += deltaTime;
-				if (mMouseZeroTime[idx] < secondsPerSample)
-					value = mMouseSmoothedAxis[idx] * deltaTime / secondsPerSample;
-				else
-					mMouseSmoothedAxis[idx] = 0;
-			}
-			else
-			{
-				mMouseZeroTime[idx] = 0;
-				if (mMouseSmoothedAxis[idx] != 0)
-				{
-					if (deltaTime < secondsPerSample * (sampleCount + 1))
-						value = value * deltaTime / (secondsPerSample * sampleCount);
-					else
-						sampleCount = Math::roundToInt(deltaTime / secondsPerSample);
-				}
-
-				mMouseSmoothedAxis[idx] = value / sampleCount;
-			}
-		}
-		else
-		{
-			mMouseSmoothedAxis[idx] = 0.0f;
-			mMouseZeroTime[idx] = 0.0f;
-		}
-
-		return value;
-	}
-
-	void InputHandlerOIS::_update()
-	{
-		if (mMouse != nullptr)
-			mMouse->capture();
-
-		if (mKeyboard != nullptr)
-			mKeyboard->capture();
-
-		for (auto& gamepadData : mGamepads)
-		{
-			gamepadData.gamepad->capture();
-		}
-
-		float rawXValue = 0.0f;
-		float rawYValue = 0.0f;
-
-		// Smooth mouse axes if needed
-		if (mMouseSmoothingEnabled)
-		{
-			rawXValue = smoothMouse((float)mMouseSampleAccumulator[0], 0);
-			rawYValue = smoothMouse((float)mMouseSampleAccumulator[1], 1);
-		}
-		else
-		{
-			rawXValue = (float)mMouseSampleAccumulator[0];
-			rawYValue = (float)mMouseSampleAccumulator[1];
-		}
-
-		rawXValue *= 0.1f;
-		rawYValue *= 0.1f;
-
-		mMouseSampleAccumulator[0] = 0;
-		mMouseSampleAccumulator[1] = 0;
-
-		RawAxisState xState;
-		xState.rel = -rawXValue;
-		xState.abs = xState.rel; // Abs value irrelevant for mouse
-
-		onAxisMoved(0, xState, (UINT32)InputAxis::MouseX);
-
-		RawAxisState yState;
-		yState.rel = -rawYValue;
-		yState.abs = yState.rel; // Abs value irrelevant for mouse
-		
-		onAxisMoved(0, yState, (UINT32)InputAxis::MouseY);
-	}
-
-	void InputHandlerOIS::_inputWindowChanged(const RenderWindow& win)
-	{
-		UINT64 hWnd = 0;
-		win.getCustomAttribute("WINDOW", &hWnd);
-
-		std::string normalString = toString(hWnd).c_str();
-		mKeyboard->setCaptureContext(normalString);
-		mMouse->setCaptureContext(normalString);
-	}
-
-	bool InputHandlerOIS::keyPressed(const OIS::KeyEvent &arg)
-	{
-		onButtonDown(0, keyCodeToButtonCode(arg.key), arg.timestamp - mTimestampClockOffset);
-		return true;
-	}
-
-	bool InputHandlerOIS::keyReleased(const OIS::KeyEvent& arg)
-	{
-		onButtonUp(0, keyCodeToButtonCode(arg.key), arg.timestamp - mTimestampClockOffset);
-		return true;
-	}
-
-	bool InputHandlerOIS::mouseMoved(const OIS::MouseEvent& arg)
-	{
-		mMouseSampleAccumulator[0] += arg.state.X.rel;
-		mMouseSampleAccumulator[1] += arg.state.Y.rel;
-
-		mTotalMouseNumSamples[0] += Math::roundToInt(Math::abs((float)arg.state.X.rel));
-		mTotalMouseNumSamples[1] += Math::roundToInt(Math::abs((float)arg.state.Y.rel));
-
-		// Update sample times used for determining sampling rate. But only if something was
-		// actually sampled, and only if this isn't the first non-zero sample.
-		if (mLastMouseUpdateFrame != gTime().getFrameIdx())
-		{
-			if (arg.state.X.rel != 0 && !Math::approxEquals(mMouseSmoothedAxis[0], 0.0f))
-				mTotalMouseSamplingTime[0] += gTime().getFrameDelta();
-
-			if (arg.state.Y.rel != 0 && !Math::approxEquals(mMouseSmoothedAxis[1], 0.0f))
-				mTotalMouseSamplingTime[1] += gTime().getFrameDelta();
-
-			mLastMouseUpdateFrame = gTime().getFrameIdx();
-		}
-
-		RawAxisState zState;
-		zState.abs = (float)arg.state.Z.abs;
-		zState.rel = (float)arg.state.Z.rel;
-
-		onAxisMoved(0, zState, (UINT32)InputAxis::MouseZ);
-
-		return true;
-	}
-
-	bool InputHandlerOIS::mousePressed(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
-	{
-		onButtonDown(0, mouseButtonToButtonCode(id), arg.timestamp - mTimestampClockOffset);
-
-		return true;
-	}
-
-	bool InputHandlerOIS::mouseReleased(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
-	{
-		onButtonUp(0, mouseButtonToButtonCode(id), arg.timestamp - mTimestampClockOffset);
-
-		return true;
-	}
-
-	ButtonCode InputHandlerOIS::keyCodeToButtonCode(OIS::KeyCode keyCode)
-	{
-		return (ButtonCode)keyCode;
-	}
-
-	ButtonCode InputHandlerOIS::mouseButtonToButtonCode(OIS::MouseButtonID mouseBtn)
-	{
-		return (ButtonCode)(((int)mouseBtn + BC_NumKeys) | 0x80000000);
-	}
-
-	ButtonCode InputHandlerOIS::gamepadButtonToButtonCode(INT32 joystickCode)
-	{
-		switch (joystickCode)
-		{
-		case 0:
-			return BC_GAMEPAD_DPAD_UP;
-		case 1:
-			return BC_GAMEPAD_DPAD_DOWN;
-		case 2:
-			return BC_GAMEPAD_DPAD_LEFT;
-		case 3:
-			return BC_GAMEPAD_DPAD_RIGHT;
-		case 4:
-			return BC_GAMEPAD_START;
-		case 5:
-			return BC_GAMEPAD_BACK;
-		case 6:
-			return BC_GAMEPAD_LS;
-		case 7:
-			return BC_GAMEPAD_RS;
-		case 8:
-			return BC_GAMEPAD_LB;
-		case 9:
-			return BC_GAMEPAD_RB;
-		case 10:
-			return BC_GAMEPAD_BTN1;
-		case 11:
-			return BC_GAMEPAD_LS;
-		case 12:
-			return BC_GAMEPAD_A;
-		case 13:
-			return BC_GAMEPAD_B;
-		case 14:
-			return BC_GAMEPAD_X;
-		case 15:
-			return BC_GAMEPAD_Y;
-		}
-
-		return (ButtonCode)(BC_GAMEPAD_BTN1 + (joystickCode - 15));
-	}
-}

+ 0 - 123
Source/BansheeOISInput/BsInputHandlerOIS.h

@@ -1,123 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsOISPrerequisites.h"
-#include "Input/BsRawInputHandler.h"
-
-#include <OIS/OISEvents.h>
-#include <OIS/OISInputManager.h>
-#include <OIS/OISKeyboard.h>
-#include <OIS/OISMouse.h>
-#include <OIS/OISJoyStick.h>
-
-namespace bs
-{
-	/** @addtogroup OISInput
-	 *  @{
-	 */
-
-	class InputHandlerOIS;
-
-	/**	Listens for events from a specific OIS joystick device. */
-	class GamepadEventListener : public OIS::JoyStickListener
-	{
-	public:
-		GamepadEventListener(InputHandlerOIS* parentHandler, UINT32 joystickIdx);
-
-		/**	Called by OIS whenever a gamepad/joystick button is pressed. */
-		bool buttonPressed(const OIS::JoyStickEvent& arg, int button) override;
-
-		/**	Called by OIS whenever a gamepad/joystick button is released. */
-		bool buttonReleased(const OIS::JoyStickEvent& arg, int button) override;
-
-		/**	Called by OIS whenever a gamepad/joystick axis is moved. */
-		bool axisMoved(const OIS::JoyStickEvent& arg, int axis) override;
-
-	private:
-		UINT32 mGamepadIdx;
-		InputHandlerOIS* mParentHandler;
-	};
-
-	/**	Raw input handler using OIS library for acquiring input. */
-	class InputHandlerOIS : public RawInputHandler, public OIS::KeyListener, 
-		public OIS::MouseListener
-	{
-		/**	Holding data about an active gamepad object. */
-		struct GamepadData
-		{
-			OIS::JoyStick* gamepad;
-			GamepadEventListener* listener;
-		};
-
-	public:
-		InputHandlerOIS(UINT64 hWnd);
-		virtual ~InputHandlerOIS();
-
-	private:
-		/**	Called by OIS whenever a keyboard button is pressed. */
-		bool keyPressed(const OIS::KeyEvent& arg) override;
-
-		/**	Called by OIS whenever a keyboard button is released. */
-		bool keyReleased(const OIS::KeyEvent& arg) override;
-
-		/**	Called by OIS whenever mouse is moved. */
-		bool mouseMoved(const OIS::MouseEvent& arg) override;
-
-		/**	Called by OIS whenever is a mouse button pressed. */
-		bool mousePressed(const OIS::MouseEvent& arg, OIS::MouseButtonID id) override;
-
-		/**	Called by OIS whenever is a mouse button released. */
-		bool mouseReleased(const OIS::MouseEvent& arg, OIS::MouseButtonID id) override;
-
-		/**	Converts an OIS key code into engine button code. */
-		static ButtonCode keyCodeToButtonCode(OIS::KeyCode keyCode);
-
-		/**	Converts an OIS mouse button code into engine button code. */
-		static ButtonCode mouseButtonToButtonCode(OIS::MouseButtonID mouseBtn);
-
-		/**	Converts an OIS gamepad button code into engine button code. */
-		static ButtonCode gamepadButtonToButtonCode(INT32 joystickCode);
-
-		/** @name Internal 
-		 *  @{
-		 */
-
-		/** Called once per frame. */
-		void _update() override;
-
-		/** Called whenever the currently focused window changes. */
-		void _inputWindowChanged(const RenderWindow& win) override;
-
-		/** @} */
-
-	private:
-		friend class GamepadEventListener;
-
-		/**
-		 * Smooths the input mouse axis value. Smoothing makes the changes to the axis more gradual depending on previous
-		 * values.
-		 *
-		 * @param[in]	value	Value to smooth.
-		 * @param[in]	idx		Index of the mouse axis to smooth, 0 - horizontal, 1 - vertical.
-		 * @return				Smoothed value.
-		 */
-		float smoothMouse(float value, UINT32 idx);
-
-		OIS::InputManager* mInputManager;
-		OIS::Mouse*	mMouse;
-		OIS::Keyboard* mKeyboard;
-		Vector<GamepadData> mGamepads;
-
-		float mTotalMouseSamplingTime[2];
-		UINT32 mTotalMouseNumSamples[2];
-		float mMouseZeroTime[2];
-		INT32 mMouseSampleAccumulator[2];
-		float mMouseSmoothedAxis[2];
-		UINT64 mLastMouseUpdateFrame;
-
-		UINT64 mTimestampClockOffset;
-	};
-
-	/** @} */
-}

+ 0 - 33
Source/BansheeOISInput/BsOISPlugin.cpp

@@ -1,33 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsOISPrerequisites.h"
-#include "BsInputHandlerOIS.h"
-#include "RenderAPI/BsRenderWindow.h"
-#include "Input/BsInput.h"
-
-namespace bs
-{
-	/**	Returns a name of the plugin. */
-	extern "C" BS_PLUGIN_EXPORT const char* getPluginName()
-	{
-		static const char* pluginName = "OISInput";
-		return pluginName;
-	}
-
-	/**	Entry point to the plugin. Called by the engine when the plugin is loaded. */
-	extern "C" BS_PLUGIN_EXPORT void* loadPlugin(void* primaryWindowPtr)
-	{
-		RenderWindow* primaryWindow = (RenderWindow*)primaryWindowPtr;
-
-		if (primaryWindow == nullptr)
-			assert(false && "Unable to get window handle. No active window exists!");
-
-		UINT64 windowId = 0;
-		primaryWindow->getCustomAttribute("WINDOW", &windowId);
-
-		SPtr<RawInputHandler> inputHandler = bs_shared_ptr_new<InputHandlerOIS>(windowId);
-		gInput()._registerRawInputHandler(inputHandler);
-
-		return nullptr;
-	}
-}

+ 0 - 15
Source/BansheeOISInput/BsOISPrerequisites.h

@@ -1,15 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-/** @addtogroup Plugins
- *  @{
- */
-
-/** @defgroup OISInput BansheeOISInput
- *	OIS implementation for raw keyboard/mouse/gamepad input.
- */
-
-/** @} */

+ 0 - 29
Source/BansheeOISInput/CMakeLists.txt

@@ -1,29 +0,0 @@
-# Source files and their filters
-include(CMakeSources.cmake)
-
-# Find packages
-find_package(OIS)
-
-# Includes
-set(BansheeOISInput_INC 
-	"./"
-	"../BansheeUtility" 
-	"../BansheeCore")
-
-include_directories(${BansheeOISInput_INC})	
-	
-# Target
-add_library(BansheeOISInput SHARED ${BS_BANSHEEOISINPUT_SRC})
-
-# Defines
-target_compile_definitions(BansheeOISInput PRIVATE -DBS_OIS_EXPORTS -DOIS_DYNAMIC_LIB -DOIS_NONCLIENT_BUILD)
-
-# Libraries
-## External lib: OIS
-target_link_libraries(BansheeOISInput PRIVATE ${OIS_LIBRARIES})
-
-## Local libs
-target_link_libraries(BansheeOISInput PRIVATE BansheeUtility BansheeCore)
-
-# IDE specific
-set_property(TARGET BansheeOISInput PROPERTY FOLDER Plugins)

+ 0 - 17
Source/BansheeOISInput/CMakeSources.cmake

@@ -1,17 +0,0 @@
-set(BS_BANSHEEOISINPUT_INC_NOFILTER
-	"BsInputHandlerOIS.h"
-	"BsOISPrerequisites.h"
-)
-
-set(BS_BANSHEEOISINPUT_SRC_NOFILTER
-	"BsInputHandlerOIS.cpp"
-	"BsOISPlugin.cpp"
-)
-
-source_group("Header Files" FILES ${BS_BANSHEEOISINPUT_INC_NOFILTER})
-source_group("Source Files" FILES ${BS_BANSHEEOISINPUT_SRC_NOFILTER})
-
-set(BS_BANSHEEOISINPUT_SRC
-	${BS_BANSHEEOISINPUT_INC_NOFILTER}
-	${BS_BANSHEEOISINPUT_SRC_NOFILTER}
-)

+ 0 - 1
Source/CMake/BsEngineConfig.h.in

@@ -2,7 +2,6 @@
 #define BS_RENDER_API_MODULE "@RENDER_API_MODULE_LIB@"
 #define BS_AUDIO_MODULE "@AUDIO_MODULE_LIB@"
 #define BS_PHYSICS_MODULE "@PHYSICS_MODULE_LIB@"
-#define BS_INPUT_MODULE "@INPUT_MODULE_LIB@"
 
 /** Path to the application root when files haven't been packaged yet (e.g. running from debugger). */
 static constexpr const char* RAW_APP_ROOT = "@PROJECT_SOURCE_DIR@/../"; 

+ 1 - 1
Source/CMake/Common.cmake

@@ -13,7 +13,7 @@ function(add_engine_dependencies target_name)
 		add_dependencies(${target_name} BansheeOpenAudio)
 	endif()
 	
-	add_dependencies(${target_name} BansheeMono BansheeSL BansheeOISInput BansheePhysX RenderBeast SBansheeEngine)
+	add_dependencies(${target_name} BansheeMono BansheeSL BansheePhysX RenderBeast SBansheeEngine)
 endfunction()
 
 function(add_subdirectory_optional subdir_name)

+ 0 - 5
Source/CMakeLists.txt

@@ -37,9 +37,6 @@ set_property(CACHE AUDIO_MODULE PROPERTY STRINGS OpenAudio FMOD)
 set(PHYSICS_MODULE "PhysX" CACHE STRING "Physics backend to use.")
 set_property(CACHE PHYSICS_MODULE PROPERTY STRINGS PhysX)
 
-set(INPUT_MODULE "OIS" CACHE STRING "Input backend to use.")
-set_property(CACHE INPUT_MODULE PROPERTY STRINGS OIS)
-
 if(WIN32)
 set(RENDER_API_MODULE "DirectX 11" CACHE STRING "Render API to use.")
 set_property(CACHE RENDER_API_MODULE PROPERTY STRINGS "DirectX 11" "OpenGL" "Vulkan")
@@ -244,7 +241,6 @@ else() # Default to OpenAudio
 endif()
 
 set(RENDERER_MODULE_LIB RenderBeast)
-set(INPUT_MODULE_LIB BansheeOISInput)
 set(PHYSICS_MODULE_LIB BansheePhysX)
 
 if(BUILD_EDITOR)
@@ -295,7 +291,6 @@ else() # Otherwise include only chosen ones
 endif()
 
 add_subdirectory(RenderBeast)
-add_subdirectory(BansheeOISInput)
 add_subdirectory(BansheePhysX)
 add_subdirectory(BansheeFBXImporter)
 add_subdirectory(BansheeFontImporter)

+ 0 - 1
Source/Examples/ExampleGettingStarted/Main.cpp

@@ -92,7 +92,6 @@ int main()
 	startUpDesc.renderer = BS_RENDERER_MODULE;
 	startUpDesc.audio = BS_AUDIO_MODULE;
 	startUpDesc.physics = BS_PHYSICS_MODULE;
-	startUpDesc.input = BS_INPUT_MODULE;
 
 	// Descriptor used for initializing the primary application window.
 	startUpDesc.primaryWindowDesc.videoMode = VideoMode(windowResWidth, windowResHeight);

+ 0 - 1
Source/Examples/ExamplePhysicallyBasedShading/Main.cpp

@@ -93,7 +93,6 @@ int main()
 	startUpDesc.renderer = BS_RENDERER_MODULE;
 	startUpDesc.audio = BS_AUDIO_MODULE;
 	startUpDesc.physics = BS_PHYSICS_MODULE;
-	startUpDesc.input = BS_INPUT_MODULE;
 
 	// Descriptor used for initializing the primary application window.
 	startUpDesc.primaryWindowDesc.videoMode = VideoMode(windowResWidth, windowResHeight);

+ 0 - 1
Source/Game/Main.cpp

@@ -78,7 +78,6 @@ void runApplication()
 	startUpDesc.renderer = BS_RENDERER_MODULE;
 	startUpDesc.audio = BS_AUDIO_MODULE;
 	startUpDesc.physics = BS_PHYSICS_MODULE;
-	startUpDesc.input = BS_INPUT_MODULE;
 	startUpDesc.scripting = true;
 
 	startUpDesc.primaryWindowDesc.videoMode = VideoMode(resolutionWidth, resolutionHeight);