1/*
2The zlib/libpng License
3
4Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
5
6This software is provided 'as-is', without any express or implied warranty. In no event will
7the authors be held liable for any damages arising from the use of this software.
8
9Permission is granted to anyone to use this software for any purpose, including commercial
10applications, and to alter it and redistribute it freely, subject to the following
11restrictions:
12
13    1. The origin of this software must not be misrepresented; you must not claim that
14		you wrote the original software. If you use this software in a product,
15		an acknowledgment in the product documentation would be appreciated but is
16		not required.
17
18    2. Altered source versions must be plainly marked as such, and must not be
19		misrepresented as being the original software.
20
21    3. This notice may not be removed or altered from any source distribution.
22*/
23#ifndef OIS_Joystick_H
24#define OIS_Joystick_H
25#include "OISObject.h"
26#include "OISEvents.h"
27
28namespace OIS
29{
30	/** @remarks default sensitivity for vector3 component of joystick */
31	#define OIS_JOYSTICK_VECTOR3_DEFAULT 2.28f
32
33	//! POV / HAT Joystick component
34	class _OISExport Pov : public Component
35	{
36	public:
37		Pov() : Component(OIS_POV), direction(0) {}
38
39		static const int Centered  = 0x00000000;
40		static const int North     = 0x00000001;
41		static const int South     = 0x00000010;
42		static const int East      = 0x00000100;
43		static const int West      = 0x00001000;
44		static const int NorthEast = 0x00000101;
45		static const int SouthEast = 0x00000110;
46		static const int NorthWest = 0x00001001;
47		static const int SouthWest = 0x00001010;
48
49		int direction;
50	};
51
52	//! A sliding axis - only used in Win32 Right Now
53	class _OISExport Slider : public Component
54	{
55	public:
56		Slider() : Component(OIS_Slider), abX(0), abY(0) {};
57		//! true if pushed, false otherwise
58		int abX, abY;
59	};
60
61	/**
62		Represents the state of the joystick
63		All members are valid for both buffered and non buffered mode
64		Sticks with zero values are not present on the device
65	*/
66	class _OISExport JoyStickState
67	{
68	public:
69		//! Constructor
70		JoyStickState() { clear(); }
71
72		//! Represents all the buttons (uses a bitset)
73		std::vector<bool> mButtons;
74
75		//! Represents all the single axes on the device
76		std::vector<Axis> mAxes;
77
78		//! Represents the value of a POV. Maximum of 4
79		Pov mPOV[4];
80
81		//! Represent the max sliders
82		Slider mSliders[4];
83
84		//! Represents all Vector type controls the device exports
85		std::vector<Vector3> mVectors;
86
87		//! internal method to reset all variables to initial values
88		void clear()
89		{
90			for( std::vector<bool>::iterator i = mButtons.begin(), e = mButtons.end(); i != e; ++i )
91			{
92				(*i) = false;
93			}
94
95			for( std::vector<Axis>::iterator i = mAxes.begin(), e = mAxes.end(); i != e; ++i )
96			{
97				i->absOnly = true; //Currently, joysticks only report Absolute values
98				i->clear();
99			}
100
101			for( std::vector<Vector3>::iterator i = mVectors.begin(), e = mVectors.end(); i != e; ++i )
102			{
103				i->clear();
104			}
105
106			for( int i = 0; i < 4; ++i )
107			{
108				mPOV[i].direction = Pov::Centered;
109				mSliders[i].abX = mSliders[i].abY = 0;
110			}
111		}
112	};
113
114	/** Specialised for joystick events */
115	class _OISExport JoyStickEvent : public EventArg
116	{
117	public:
118		JoyStickEvent( Object* obj, const JoyStickState &st ) : EventArg(obj), state(st) {}
119		virtual ~JoyStickEvent() {}
120
121		const JoyStickState &state;
122	};
123
124	/**
125		To recieve buffered joystick input, derive a class from this, and implement the
126		methods here. Then set the call back to your JoyStick instance with JoyStick::setEventCallback
127		Each JoyStick instance can use the same callback class, as a devID number will be provided
128		to differentiate between connected joysticks. Of course, each can have a seperate
129		callback instead.
130	*/
131	class _OISExport JoyStickListener
132	{
133	public:
134		virtual ~JoyStickListener() {}
135		/** @remarks Joystick button down event */
136		virtual bool buttonPressed( const JoyStickEvent &arg, int button ) = 0;
137
138		/** @remarks Joystick button up event */
139		virtual bool buttonReleased( const JoyStickEvent &arg, int button ) = 0;
140
141		/** @remarks Joystick axis moved event */
142		virtual bool axisMoved( const JoyStickEvent &arg, int axis ) = 0;
143
144		//-- Not so common control events, so are not required --//
145		//! Joystick Event, and sliderID
146		virtual bool sliderMoved( const JoyStickEvent &, int index) {return true;}
147
148		//! Joystick Event, and povID
149		virtual bool povMoved( const JoyStickEvent &arg, int index) {return true;}
150
151		//! Joystick Event, and Vector3ID
152		virtual bool vector3Moved( const JoyStickEvent &arg, int index) {return true;}
153	};
154
155	/**
156		Joystick base class. To be implemented by specific system (ie. DirectX joystick)
157		This class is useful as you remain OS independent using this common interface.
158	*/
159	class _OISExport JoyStick : public Object
160	{
161	public:
162		virtual ~JoyStick() {}
163
164		/**
165		@remarks
166			Returns the number of requested components
167		@param cType
168			The ComponentType you are interested in knowing about
169		*/
170		int getNumberOfComponents(ComponentType cType) const;
171
172		/**
173		@remarks
174			Sets a cutoff limit for changes in the Vector3 component for movement to
175			be ignored. Helps reduce much event traffic for frequent small/sensitive
176			changes
177		@param degrees
178			The degree under which Vector3 events should be discarded
179		*/
180		void setVector3Sensitivity(float degrees = OIS_JOYSTICK_VECTOR3_DEFAULT);
181
182		/**
183		@remarks
184			Returns the sensitivity cutoff for Vector3 Component
185		*/
186		float getVector3Sensitivity() const;
187
188		/**
189		@remarks
190			Register/unregister a JoyStick Listener - Only one allowed for simplicity. If broadcasting
191			is neccessary, just broadcast from the callback you registered.
192		@param joyListener
193			Send a pointer to a class derived from JoyStickListener or 0 to clear the callback
194		*/
195		virtual void setEventCallback( JoyStickListener *joyListener );
196
197		/** @remarks Returns currently set callback.. or null */
198		JoyStickListener* getEventCallback() const;
199
200		/** @remarks Returns the state of the joystick - is valid for both buffered and non buffered mode */
201		const JoyStickState& getJoyStickState() const { return mState; }
202
203		//! The minimal axis value
204		static const int MIN_AXIS = -32768;
205
206		//! The maximum axis value
207		static const int MAX_AXIS = 32767;
208
209	protected:
210		JoyStick(const std::string &vendor, bool buffered, int devID, InputManager* creator);
211
212		//! Number of sliders
213		int mSliders;
214
215		//! Number of POVs
216		int mPOVs;
217
218		//! The JoyStickState structure (contains all component values)
219		JoyStickState mState;
220
221		//! The callback listener
222		JoyStickListener *mListener;
223
224		//! Adjustment factor for orientation vector accuracy
225		float mVector3Sensitivity;
226	};
227}
228#endif
229