1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version.  The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * OpenSceneGraph Public License for more details.
12 */
13 
14 #include <osgViewer/Viewer>
15 
16 #include "SDLIntegration.h"
17 
18 #include <SDL.h>
19 #include <SDL_events.h>
20 #include <SDL_joystick.h>
21 
22 #include <iostream>
23 
SDLIntegration()24 SDLIntegration::SDLIntegration()
25 {
26     _verbose = false;
27 
28     // init SDL
29     if ( SDL_Init(SDL_INIT_JOYSTICK) < 0 )
30     {
31         fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
32         exit(1);
33     }
34     atexit(SDL_Quit);
35 
36     int numJoysticks =  SDL_NumJoysticks();
37 
38     if (_verbose)
39     {
40         std::cout<<"number of joysticks "<<numJoysticks<<std::endl;
41         for(int i=0; i<numJoysticks; ++i)
42         {
43             std::cout<<"Joystick name '"<<SDL_JoystickName(i)<<"'"<<std::endl;
44         }
45     }
46 
47     _joystick = numJoysticks>0 ? SDL_JoystickOpen(0) : 0;
48 
49     _numAxes = _joystick ? SDL_JoystickNumAxes(_joystick) : 0;
50     _numBalls = _joystick ? SDL_JoystickNumBalls(_joystick) : 0;
51     _numHats = _joystick ? SDL_JoystickNumHats(_joystick) : 0;
52     _numButtons = _joystick ? SDL_JoystickNumButtons(_joystick) : 0;
53 
54     if (_verbose)
55     {
56         std::cout<<"numAxes = "<<_numAxes<<std::endl;
57         std::cout<<"numBalls = "<<_numBalls<<std::endl;
58         std::cout<<"numHats = "<<_numHats<<std::endl;
59         std::cout<<"numButtons = "<<_numButtons<<std::endl;
60     }
61 
62     addMouseButtonMapping(4, 1); // left
63     addMouseButtonMapping(5, 3); // right
64     addMouseButtonMapping(6, 2); // middle
65 
66     addKeyMapping(10, ' '); // R2
67 
68     addKeyMapping(0, '1'); // 1
69     addKeyMapping(1, '2'); // 2
70     addKeyMapping(2, '3'); // 3
71     addKeyMapping(4, '4'); // 4
72 
73     addKeyMapping(7, ' '); // home
74 
75     addKeyMapping(8, osgGA::GUIEventAdapter::KEY_Page_Up); // Start
76     addKeyMapping(9, osgGA::GUIEventAdapter::KEY_Page_Down); // Start
77     addKeyMapping(10, osgGA::GUIEventAdapter::KEY_Home); // Start
78 
79 
80     capture(_axisValues, _buttonValues);
81 }
82 
~SDLIntegration()83 SDLIntegration::~SDLIntegration()
84 {
85 }
86 
capture(ValueList & axisValues,ValueList & buttonValues) const87 void SDLIntegration::capture(ValueList& axisValues, ValueList& buttonValues) const
88 {
89     if (_joystick)
90     {
91         SDL_JoystickUpdate();
92 
93         axisValues.resize(_numAxes);
94         for(int ai=0; ai<_numAxes; ++ai)
95         {
96             axisValues[ai] = SDL_JoystickGetAxis(_joystick, ai);
97         }
98 
99         buttonValues.resize(_numButtons);
100         for(int bi=0; bi<_numButtons; ++bi)
101         {
102             buttonValues[bi] = SDL_JoystickGetButton(_joystick, bi);
103         }
104     }
105 }
106 
update(osgViewer::Viewer & viewer)107 void SDLIntegration::update(osgViewer::Viewer& viewer)
108 {
109     if (_joystick)
110     {
111 
112         ValueList newAxisValues;
113         ValueList newButtonValues;
114 
115         capture(newAxisValues, newButtonValues);
116 
117         unsigned int mouseXaxis = 0;
118         unsigned int mouseYaxis = 1;
119 
120         float prev_mx = (float)_axisValues[mouseXaxis]/32767.0f;
121         float prev_my = -(float)_axisValues[mouseYaxis]/32767.0f;
122 
123         float mx = (float)newAxisValues[mouseXaxis]/32767.0f;
124         float my = -(float)newAxisValues[mouseYaxis]/32767.0f;
125 
126 
127         osgGA::EventQueue* eq = viewer.getEventQueue();
128         double time = eq ? eq->getTime() : 0.0;
129         osgGA::GUIEventAdapter* previous_event = eq->getCurrentEventState();
130         float projected_mx = previous_event->getXmin() + (mx+1.0)*0.5*(previous_event->getXmax()-previous_event->getXmin());
131         float projected_my = previous_event->getYmin() + (my+1.0)*0.5*(previous_event->getYmax()-previous_event->getYmin());
132 
133         if (mx!=prev_mx || my!=prev_my)
134         {
135             eq->mouseMotion(projected_mx, projected_my, time);
136         }
137 
138 
139         if (_verbose)
140         {
141             for(int ai=0; ai<_numAxes; ++ai)
142             {
143                 if (newAxisValues[ai]!=_axisValues[ai])
144                 {
145                     std::cout<<"axis "<<ai<<" moved to "<<newAxisValues[ai]<<std::endl;
146                 }
147             }
148         }
149 
150         for(int bi=0; bi<_numButtons; ++bi)
151         {
152             if (newButtonValues[bi]!=_buttonValues[bi])
153             {
154                 if (_verbose)
155                 {
156                     std::cout<<"button "<<bi<<" changed to "<<newButtonValues[bi]<<std::endl;
157                 }
158 
159                 int key =  getKeyMapping(bi);
160                 int mouseButton =  getMouseButtonMapping(bi);
161 
162                 if (mouseButton>0)
163                 {
164                     if (newButtonValues[bi]==0) eq->mouseButtonRelease(projected_mx,projected_my,mouseButton,time);
165                     else  eq->mouseButtonPress(projected_mx,projected_my,mouseButton,time);
166                 }
167                 else if (key>0)
168                 {
169 
170                     if (newButtonValues[bi]==0) eq->keyRelease(key,time);
171                     else eq->keyPress(key,time);
172                 }
173             }
174         }
175 
176         _axisValues.swap(newAxisValues);
177         _buttonValues.swap(newButtonValues);
178 
179     }
180 
181 }
182 
183