• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////// OS Nuetral Headers ////////////////
2 #include "OISInputManager.h"
3 #include "OISException.h"
4 #include "OISKeyboard.h"
5 #include "OISMouse.h"
6 #include "OISJoyStick.h"
7 #include "OISEvents.h"
8 
9 //Advanced Usage
10 #include "OISForceFeedback.h"
11 
12 #include <iostream>
13 #include <vector>
14 #include <sstream>
15 
16 ////////////////////////////////////Needed Windows Headers////////////
17 #if defined OIS_WIN32_PLATFORM
18 #define WIN32_LEAN_AND_MEAN
19 #include "windows.h"
20 #ifdef min
21 #undef min
22 #endif
23 #include "resource.h"
24 LRESULT DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
25 //////////////////////////////////////////////////////////////////////
26 ////////////////////////////////////Needed Linux Headers//////////////
27 #elif defined OIS_LINUX_PLATFORM
28 #include <X11/Xlib.h>
29 #include <X11/Xatom.h>
30 void checkX11Events();
31 //////////////////////////////////////////////////////////////////////
32 ////////////////////////////////////Needed Mac Headers//////////////
33 #elif defined OIS_APPLE_PLATFORM
34 #include <Carbon/Carbon.h>
35 void checkMacEvents();
36 #endif
37 //////////////////////////////////////////////////////////////////////
38 using namespace OIS;
39 
40 //-- Some local prototypes --//
41 void doStartup();
42 void handleNonBufferedKeys();
43 void handleNonBufferedMouse();
44 void handleNonBufferedJoy( JoyStick* js );
45 
46 //-- Easy access globals --//
47 bool appRunning = true;				//Global Exit Flag
48 
49 const char *g_DeviceType[6] = {"OISUnknown", "OISKeyboard", "OISMouse", "OISJoyStick",
50 							 "OISTablet", "OISOther"};
51 
52 InputManager *g_InputManager = 0;	//Our Input System
53 Keyboard *g_kb  = 0;				//Keyboard Device
54 Mouse	 *g_m   = 0;				//Mouse Device
55 JoyStick* g_joys[4] = {0,0,0,0};	//This demo supports up to 4 controllers
56 
57 //-- OS Specific Globals --//
58 #if defined OIS_WIN32_PLATFORM
59   HWND hWnd = 0;
60 #elif defined OIS_LINUX_PLATFORM
61   Display *xDisp = 0;
62   Window xWin = 0;
63 #elif defined OIS_APPLE_PLATFORM
64   WindowRef mWin = 0;
65 #endif
66 
67 //////////// Common Event handler class ////////
68 class EventHandler : public KeyListener, public MouseListener, public JoyStickListener
69 {
70 public:
EventHandler()71 	EventHandler() {}
~EventHandler()72 	~EventHandler() {}
keyPressed(const KeyEvent & arg)73 	bool keyPressed( const KeyEvent &arg ) {
74 		std::cout << " KeyPressed {" << arg.key
75 			<< ", " << ((Keyboard*)(arg.device))->getAsString(arg.key)
76 			<< "} || Character (" << (char)arg.text << ")" << std::endl;
77 		return true;
78 	}
keyReleased(const KeyEvent & arg)79 	bool keyReleased( const KeyEvent &arg ) {
80 		if( arg.key == KC_ESCAPE || arg.key == KC_Q )
81 			appRunning = false;
82 		std::cout << "KeyReleased {" << ((Keyboard*)(arg.device))->getAsString(arg.key) << "}\n";
83 		return true;
84 	}
mouseMoved(const MouseEvent & arg)85 	bool mouseMoved( const MouseEvent &arg ) {
86 		const OIS::MouseState& s = arg.state;
87 		std::cout << "\nMouseMoved: Abs("
88 				  << s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
89 				  << s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
90 		return true;
91 	}
mousePressed(const MouseEvent & arg,MouseButtonID id)92 	bool mousePressed( const MouseEvent &arg, MouseButtonID id ) {
93 		const OIS::MouseState& s = arg.state;
94 		std::cout << "\nMouse button #" << id << " pressed. Abs("
95 				  << s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
96 				  << s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
97 		return true;
98 	}
mouseReleased(const MouseEvent & arg,MouseButtonID id)99 	bool mouseReleased( const MouseEvent &arg, MouseButtonID id ) {
100 		const OIS::MouseState& s = arg.state;
101 		std::cout << "\nMouse button #" << id << " released. Abs("
102 				  << s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
103 				  << s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")";
104 		return true;
105 	}
buttonPressed(const JoyStickEvent & arg,int button)106 	bool buttonPressed( const JoyStickEvent &arg, int button ) {
107 		std::cout << std::endl << arg.device->vendor() << ". Button Pressed # " << button;
108 		return true;
109 	}
buttonReleased(const JoyStickEvent & arg,int button)110 	bool buttonReleased( const JoyStickEvent &arg, int button ) {
111 		std::cout << std::endl << arg.device->vendor() << ". Button Released # " << button;
112 		return true;
113 	}
axisMoved(const JoyStickEvent & arg,int axis)114 	bool axisMoved( const JoyStickEvent &arg, int axis )
115 	{
116 		//Provide a little dead zone
117 		if( arg.state.mAxes[axis].abs > 2500 || arg.state.mAxes[axis].abs < -2500 )
118 			std::cout << std::endl << arg.device->vendor() << ". Axis # " << axis << " Value: " << arg.state.mAxes[axis].abs;
119 		return true;
120 	}
povMoved(const JoyStickEvent & arg,int pov)121 	bool povMoved( const JoyStickEvent &arg, int pov )
122 	{
123 		std::cout << std::endl << arg.device->vendor() << ". POV" << pov << " ";
124 
125 		if( arg.state.mPOV[pov].direction & Pov::North ) //Going up
126 			std::cout << "North";
127 		else if( arg.state.mPOV[pov].direction & Pov::South ) //Going down
128 			std::cout << "South";
129 
130 		if( arg.state.mPOV[pov].direction & Pov::East ) //Going right
131 			std::cout << "East";
132 		else if( arg.state.mPOV[pov].direction & Pov::West ) //Going left
133 			std::cout << "West";
134 
135 		if( arg.state.mPOV[pov].direction == Pov::Centered ) //stopped/centered out
136 			std::cout << "Centered";
137 		return true;
138 	}
139 
vector3Moved(const JoyStickEvent & arg,int index)140 	bool vector3Moved( const JoyStickEvent &arg, int index)
141 	{
142 		std::cout.precision(2);
143 		std::cout.flags(std::ios::fixed | std::ios::right);
144 		std::cout << std::endl << arg.device->vendor() << ". Orientation # " << index
145 			<< " X Value: " << arg.state.mVectors[index].x
146 			<< " Y Value: " << arg.state.mVectors[index].y
147 			<< " Z Value: " << arg.state.mVectors[index].z;
148 		std::cout.precision();
149 		std::cout.flags();
150 		return true;
151 	}
152 };
153 
154 //Create a global instance
155 EventHandler handler;
156 
main()157 int main()
158 {
159 	std::cout << "\n\n*** OIS Console Demo App is starting up... *** \n";
160 	try
161 	{
162 		doStartup();
163 		std::cout << "\nStartup done... Hit 'q' or ESC to exit.\n\n";
164 
165 		while(appRunning)
166 		{
167 			//Throttle down CPU usage
168 			#if defined OIS_WIN32_PLATFORM
169 			  Sleep(90);
170 			  MSG  msg;
171 			  while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
172 			  {
173 				TranslateMessage( &msg );
174 				DispatchMessage( &msg );
175 			  }
176 			#elif defined OIS_LINUX_PLATFORM
177 			  checkX11Events();
178 			  usleep( 500 );
179             #elif defined OIS_APPLE_PLATFORM
180 			  checkMacEvents();
181 			  usleep( 500 );
182 			#endif
183 
184 			if( g_kb )
185 			{
186 				g_kb->capture();
187 				if( !g_kb->buffered() )
188 					handleNonBufferedKeys();
189 			}
190 
191 			if( g_m )
192 			{
193 				g_m->capture();
194 				if( !g_m->buffered() )
195 					handleNonBufferedMouse();
196 			}
197 
198 			for( int i = 0; i < 4 ; ++i )
199 			{
200 				if( g_joys[i] )
201 				{
202 					g_joys[i]->capture();
203 					if( !g_joys[i]->buffered() )
204 						handleNonBufferedJoy( g_joys[i] );
205 				}
206 			}
207 		}
208 	}
209 	catch( const Exception &ex )
210 	{
211 		#if defined OIS_WIN32_PLATFORM
212 		  MessageBox( NULL, ex.eText, "An exception has occurred!", MB_OK |
213 				MB_ICONERROR | MB_TASKMODAL);
214 		#else
215 		  std::cout << "\nOIS Exception Caught!\n" << "\t" << ex.eText << "[Line "
216 			<< ex.eLine << " in " << ex.eFile << "]\nExiting App";
217 		#endif
218 	}
219 	catch(std::exception &ex)
220 	{
221 		std::cout << "Caught std::exception: what = " << ex.what() << std::endl;
222 	}
223 
224 	//Destroying the manager will cleanup unfreed devices
225 	std::cout << "Cleaning up...\n";
226 	if( g_InputManager )
227 		InputManager::destroyInputSystem(g_InputManager);
228 
229 #if defined OIS_LINUX_PLATFORM
230 	// Be nice to X and clean up the x window
231 	XDestroyWindow(xDisp, xWin);
232 	XCloseDisplay(xDisp);
233 #endif
234 
235 	std::cout << "\nGoodbye!\n";
236 	return 0;
237 }
238 
doStartup()239 void doStartup()
240 {
241 	ParamList pl;
242 
243 #if defined OIS_WIN32_PLATFORM
244 	//Create a capture window for Input Grabbing
245 	hWnd = CreateDialog( 0, MAKEINTRESOURCE(IDD_DIALOG1), 0,(DLGPROC)DlgProc);
246 	if( hWnd == NULL )
247 		OIS_EXCEPT(E_General, "Failed to create Win32 Window Dialog!");
248 
249 	ShowWindow(hWnd, SW_SHOW);
250 
251 	std::ostringstream wnd;
252 	wnd << (size_t)hWnd;
253 
254 	pl.insert(std::make_pair( std::string("WINDOW"), wnd.str() ));
255 
256 	//Default mode is foreground exclusive..but, we want to show mouse - so nonexclusive
257 //	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
258 //	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
259 #elif defined OIS_LINUX_PLATFORM
260 	//Connects to default X window
261 	if( !(xDisp = XOpenDisplay(0)) )
262 		OIS_EXCEPT(E_General, "Error opening X!");
263 	//Create a window
264 	xWin = XCreateSimpleWindow(xDisp, DefaultRootWindow(xDisp), 0, 0, 100, 100, 0, 0, 0);
265 	//bind our connection to that window
266 	XMapWindow(xDisp, xWin);
267 	// XInternAtom
268 	//Select what events we want to listen to locally
269 	XSelectInput(xDisp, xWin, StructureNotifyMask | SubstructureNotifyMask);
270 	Atom wmProto = XInternAtom(xDisp, "WM_PROTOCOLS", False);
271 	Atom wmDelete = XInternAtom(xDisp, "WM_DELETE_WINDOW", False);
272 	XChangeProperty(xDisp, xWin, wmProto, XA_ATOM, 32, 0, (const unsigned char*)&wmDelete, 1);
273 	XEvent evtent;
274 	do
275 	{
276 		XNextEvent(xDisp, &evtent);
277 	} while(evtent.type != MapNotify);
278 
279 	std::ostringstream wnd;
280 	wnd << xWin;
281 
282 	pl.insert(std::make_pair(std::string("WINDOW"), wnd.str()));
283 
284 	//For this demo, show mouse and do not grab (confine to window)
285 //	pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
286 //	pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
287 #elif defined OIS_APPLE_PLATFORM && !__LP64__
288     // create the window rect in global coords
289     ::Rect windowRect;
290     windowRect.left = 0;
291     windowRect.top = 0;
292     windowRect.right = 300;
293     windowRect.bottom = 300;
294 
295     // set the default attributes for the window
296     WindowAttributes windowAttrs = kWindowStandardDocumentAttributes
297         | kWindowStandardHandlerAttribute
298         | kWindowInWindowMenuAttribute
299         | kWindowHideOnFullScreenAttribute;
300 
301     // Create the window
302     CreateNewWindow(kDocumentWindowClass, windowAttrs, &windowRect, &mWin);
303 
304     // Color the window background black
305     SetThemeWindowBackground (mWin, kThemeBrushBlack, true);
306 
307     // Set the title of our window
308     CFStringRef titleRef = CFStringCreateWithCString( kCFAllocatorDefault, "OIS Input", kCFStringEncodingASCII );
309     SetWindowTitleWithCFString( mWin, titleRef );
310 
311     // Center our window on the screen
312     RepositionWindow( mWin, NULL, kWindowCenterOnMainScreen );
313 
314     // Install the event handler for the window
315     InstallStandardEventHandler(GetWindowEventTarget(mWin));
316 
317     // This will give our window focus, and not lock it to the terminal
318     ProcessSerialNumber psn = { 0, kCurrentProcess };
319     TransformProcessType( &psn, kProcessTransformToForegroundApplication );
320 	SetFrontProcess(&psn);
321 
322     // Display and select our window
323     ShowWindow(mWin);
324     SelectWindow(mWin);
325 
326     std::ostringstream wnd;
327 	wnd << (unsigned int)mWin; //cast to int so it gets encoded correctly (else it gets stored as a hex string)
328     std::cout << "WindowRef: " << mWin << " WindowRef as int: " << wnd.str() << "\n";
329 	pl.insert(std::make_pair(std::string("WINDOW"), wnd.str()));
330 #endif
331 
332 	//This never returns null.. it will raise an exception on errors
333 	g_InputManager = InputManager::createInputSystem(pl);
334 
335 	//Lets enable all addons that were compiled in:
336 	g_InputManager->enableAddOnFactory(InputManager::AddOn_All);
337 
338 	//Print debugging information
339 	unsigned int v = g_InputManager->getVersionNumber();
340 	std::cout << "OIS Version: " << (v>>16 ) << "." << ((v>>8) & 0x000000FF) << "." << (v & 0x000000FF)
341 		<< "\nRelease Name: " << g_InputManager->getVersionName()
342 		<< "\nManager: " << g_InputManager->inputSystemName()
343 		<< "\nTotal Keyboards: " << g_InputManager->getNumberOfDevices(OISKeyboard)
344 		<< "\nTotal Mice: " << g_InputManager->getNumberOfDevices(OISMouse)
345 		<< "\nTotal JoySticks: " << g_InputManager->getNumberOfDevices(OISJoyStick);
346 
347 	//List all devices
348 	DeviceList list = g_InputManager->listFreeDevices();
349 	for( DeviceList::iterator i = list.begin(); i != list.end(); ++i )
350 		std::cout << "\n\tDevice: " << g_DeviceType[i->first] << " Vendor: " << i->second;
351 
352 	g_kb = (Keyboard*)g_InputManager->createInputObject( OISKeyboard, true );
353 	g_kb->setEventCallback( &handler );
354 
355 	g_m = (Mouse*)g_InputManager->createInputObject( OISMouse, true );
356 	g_m->setEventCallback( &handler );
357 	const MouseState &ms = g_m->getMouseState();
358 	ms.width = 100;
359 	ms.height = 100;
360 
361 	try
362 	{
363 		//This demo uses at most 4 joysticks - use old way to create (i.e. disregard vendor)
364 		int numSticks = std::min(g_InputManager->getNumberOfDevices(OISJoyStick), 4);
365 		for( int i = 0; i < numSticks; ++i )
366 		{
367 			g_joys[i] = (JoyStick*)g_InputManager->createInputObject( OISJoyStick, true );
368 			g_joys[i]->setEventCallback( &handler );
369 			std::cout << "\n\nCreating Joystick " << (i + 1)
370 				<< "\n\tAxes: " << g_joys[i]->getNumberOfComponents(OIS_Axis)
371 				<< "\n\tSliders: " << g_joys[i]->getNumberOfComponents(OIS_Slider)
372 				<< "\n\tPOV/HATs: " << g_joys[i]->getNumberOfComponents(OIS_POV)
373 				<< "\n\tButtons: " << g_joys[i]->getNumberOfComponents(OIS_Button)
374 				<< "\n\tVector3: " << g_joys[i]->getNumberOfComponents(OIS_Vector3);
375 		}
376 	}
377 	catch(OIS::Exception &ex)
378 	{
379 		std::cout << "\nException raised on joystick creation: " << ex.eText << std::endl;
380 	}
381 }
382 
handleNonBufferedKeys()383 void handleNonBufferedKeys()
384 {
385 	if( g_kb->isKeyDown( KC_ESCAPE ) || g_kb->isKeyDown( KC_Q ) )
386 		appRunning = false;
387 
388 	if( g_kb->isModifierDown(Keyboard::Shift) )
389 		std::cout << "Shift is down..\n";
390 	if( g_kb->isModifierDown(Keyboard::Alt) )
391 		std::cout << "Alt is down..\n";
392 	if( g_kb->isModifierDown(Keyboard::Ctrl) )
393 		std::cout << "Ctrl is down..\n";
394 }
395 
handleNonBufferedMouse()396 void handleNonBufferedMouse()
397 {
398 	//Just dump the current mouse state
399 	const MouseState &ms = g_m->getMouseState();
400 	std::cout << "\nMouse: Abs(" << ms.X.abs << " " << ms.Y.abs << " " << ms.Z.abs
401 		<< ") B: " << ms.buttons << " Rel(" << ms.X.rel << " " << ms.Y.rel << " " << ms.Z.rel << ")";
402 }
403 
handleNonBufferedJoy(JoyStick * js)404 void handleNonBufferedJoy( JoyStick* js )
405 {
406 	//Just dump the current joy state
407 	const JoyStickState &joy = js->getJoyStickState();
408 	for( unsigned int i = 0; i < joy.mAxes.size(); ++i )
409 		std::cout << "\nAxis " << i << " X: " << joy.mAxes[i].abs;
410 }
411 
412 #if defined OIS_WIN32_PLATFORM
DlgProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)413 LRESULT DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
414 {
415 	return FALSE;
416 }
417 #endif
418 
419 #if defined OIS_LINUX_PLATFORM
420 //This is just here to show that you still recieve x11 events, as the lib only needs mouse/key events
checkX11Events()421 void checkX11Events()
422 {
423 	if(!appRunning)
424 		return;
425 
426 	XEvent event;
427 
428 	while(XPending(xDisp) > 0)
429 	{
430 		XNextEvent(xDisp, &event);
431 		//Handle Resize events
432 		if(event.type == ConfigureNotify)
433 		{
434 			if(g_m)
435 			{
436 				const MouseState &ms = g_m->getMouseState();
437 				ms.width = event.xconfigure.width;
438 				ms.height = event.xconfigure.height;
439 			}
440 		}
441 		else if(event.type == ClientMessage || event.type == DestroyNotify)
442 		{	// We only get DestroyNotify for child windows. However, we regeistered earlier to receive WM_DELETE_MESSAGEs
443 			std::cout << "Exiting...\n";
444 			appRunning = false;
445 			return;
446 		}
447 		else
448 		{
449 			std::cout << "\nUnknown X Event: " << event.type << std::endl;
450 		}
451 	}
452 }
453 #endif
454 
455 #if defined OIS_APPLE_PLATFORM
checkMacEvents()456 void checkMacEvents()
457 {
458 	//TODO - Check for window resize events, and then adjust the members of mousestate
459 	EventRef event = NULL;
460 	EventTargetRef targetWindow = GetEventDispatcherTarget();
461 
462 	if( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr )
463 	{
464 		SendEventToEventTarget(event, targetWindow);
465 		std::cout << "Event : " << GetEventKind(event) << "\n";
466 		ReleaseEvent(event);
467 	}
468 }
469 #endif
470