24
24
import android .content .*;
25
25
26
26
import java .lang .*;
27
+ import java .util .List ;
28
+ import java .util .ArrayList ;
27
29
28
30
29
31
/**
@@ -42,6 +44,11 @@ public class SDLActivity extends Activity {
42
44
43
45
// This is what SDL runs in. It invokes SDL_main(), eventually
44
46
private static Thread mSDLThread ;
47
+
48
+ // Joystick
49
+ private static List <Integer > mJoyIdList ;
50
+ // TODO: Have a (somewhat) more efficient way of storing these?
51
+ private static List <List <Integer >> mJoyAxesLists ;
45
52
46
53
// Audio
47
54
private static Thread mAudioThread ;
@@ -156,12 +163,15 @@ void sendCommand(int command, Object data) {
156
163
public static native void nativePause ();
157
164
public static native void nativeResume ();
158
165
public static native void onNativeResize (int x , int y , int format );
166
+ public static native void onNativePadDown (int padId , int keycode );
167
+ public static native void onNativePadUp (int padId , int keycode );
168
+ public static native void onNativeJoy (int joyId , int axisNum , float value );
159
169
public static native void onNativeKeyDown (int keycode );
160
170
public static native void onNativeKeyUp (int keycode );
161
171
public static native void onNativeTouch (int touchDevId , int pointerFingerId ,
162
172
int action , float x ,
163
173
float y , float p );
164
- public static native void onNativeAccel (float x , float y , float z );
174
+ // public static native void onNativeAccel(float x, float y, float z);
165
175
public static native void nativeRunAudioThread ();
166
176
167
177
@@ -180,6 +190,74 @@ public static void setActivityTitle(String title) {
180
190
mSingleton .sendCommand (COMMAND_CHANGE_TITLE , title );
181
191
}
182
192
193
+ // Call when initializing the joystick subsystem
194
+ public static void joystickInit () {
195
+ mJoyIdList = new ArrayList <Integer >();
196
+ mJoyAxesLists = new ArrayList <List <Integer >>();
197
+
198
+ int [] deviceIds = InputDevice .getDeviceIds ();
199
+ for (int i =0 ; i <deviceIds .length ; i ++) {
200
+ if ( (InputDevice .getDevice (deviceIds [i ]).getSources () & 0x00000010 /* API 12: InputDevice.SOURCE_CLASS_JOYSTICK*/ ) != 0 ) {
201
+ mJoyIdList .add (deviceIds [i ]);
202
+ List <Integer > axesList = new ArrayList <Integer >();
203
+ /* With API 12 and above we can get a list of all motion
204
+ * ranges, hence all axes. Some of them may be irrelevant
205
+ * (e.g. an embedded trackpad). We filter the desired axes.
206
+ */
207
+ if (Build .VERSION .SDK_INT >= 12 ) {
208
+ List <InputDevice .MotionRange > rangesList = InputDevice .getDevice (deviceIds [i ]).getMotionRanges ();
209
+ for (InputDevice .MotionRange range : rangesList ) {
210
+ // Skip any possibly unrelated axis
211
+ if ( (range .getSource () & InputDevice .SOURCE_CLASS_JOYSTICK ) != 0 ) {
212
+ axesList .add (range .getAxis ());
213
+ }
214
+ }
215
+ } else {
216
+ // In older versions, we can assume a sane X-Y default configuration
217
+ axesList .add (MotionEvent .AXIS_X );
218
+ axesList .add (MotionEvent .AXIS_Y );
219
+ }
220
+ mJoyAxesLists .add (axesList );
221
+ }
222
+ }
223
+ }
224
+
225
+ // Call when one clears joystick subsystem resources
226
+ public static void joystickQuit () {
227
+ mJoyIdList = null ;
228
+ mJoyAxesLists = null ;
229
+ }
230
+
231
+ public static int getNumJoysticks () {
232
+ if (mJoyIdList == null )
233
+ return -1 ;
234
+ return mJoyIdList .size ();
235
+ }
236
+
237
+ public static String getJoystickName (int joy ) {
238
+ if (mJoyIdList == null )
239
+ return null ;
240
+ return InputDevice .getDevice (mJoyIdList .get (joy )).getName ();
241
+ }
242
+
243
+ public static List <Integer > getJoystickAxesList (int joy ) {
244
+ if (mJoyIdList == null )
245
+ return null ;
246
+ return mJoyAxesLists .get (joy );
247
+ }
248
+
249
+ public static int getJoystickNumOfAxes (int joy ) {
250
+ if (mJoyIdList == null )
251
+ return -1 ;
252
+ return mJoyAxesLists .get (joy ).size ();
253
+ }
254
+
255
+ public static int getJoyId (int devId ) {
256
+ if (mJoyIdList == null )
257
+ return -1 ;
258
+ return mJoyIdList .indexOf (devId );
259
+ }
260
+
183
261
public static void sendMessage (int command , int param ) {
184
262
mSingleton .sendCommand (command , Integer .valueOf (param ));
185
263
}
@@ -478,7 +556,12 @@ public SDLSurface(Context context) {
478
556
setFocusableInTouchMode (true );
479
557
requestFocus ();
480
558
setOnKeyListener (this );
481
- setOnTouchListener (this );
559
+ setOnTouchListener (this );
560
+
561
+ // Listen to joystick motion events if supported
562
+ if (Build .VERSION .SDK_INT >= 12 ) {
563
+ setOnGenericMotionListener (new SDLOnGenericMotionListener ());
564
+ }
482
565
483
566
mSensorManager = (SensorManager )context .getSystemService ("sensor" );
484
567
@@ -568,18 +651,65 @@ public void onDraw(Canvas canvas) {}
568
651
569
652
570
653
654
+ // Listen to joystick motion events if supported (API >= 12)
655
+ private static class SDLOnGenericMotionListener implements View .OnGenericMotionListener {
656
+ @ Override
657
+ public boolean onGenericMotion (View view , MotionEvent event ) {
658
+ int actionPointerIndex = event .getActionIndex ();
659
+ int action = event .getActionMasked ();
660
+
661
+ if ( (event .getSource () & InputDevice .SOURCE_CLASS_JOYSTICK ) != 0 ) {
662
+ switch (action ) {
663
+ case MotionEvent .ACTION_MOVE :
664
+ int id = SDLActivity .getJoyId ( event .getDeviceId () );
665
+ // The joystick subsystem may be uninitialized, so ignore
666
+ if (id < 0 )
667
+ return true ;
668
+ // Update values for all joystick axes
669
+ List <Integer > axes = SDLActivity .getJoystickAxesList (id );
670
+ for (int axisIndex = 0 ; axisIndex < axes .size (); axisIndex ++) {
671
+ SDLActivity .onNativeJoy (id , axisIndex , event .getAxisValue (axes .get (axisIndex ), actionPointerIndex ));
672
+ }
673
+
674
+ return true ;
675
+ }
676
+ }
677
+ return false ;
678
+ }
679
+ }
680
+
571
681
// Key events
572
682
public boolean onKey (View v , int keyCode , KeyEvent event ) {
573
-
574
- if (event .getAction () == KeyEvent .ACTION_DOWN ) {
575
- //Log.v("SDL", "key down: " + keyCode);
576
- SDLActivity .onNativeKeyDown (keyCode );
577
- return true ;
578
- }
579
- else if (event .getAction () == KeyEvent .ACTION_UP ) {
580
- //Log.v("SDL", "key up: " + keyCode);
581
- SDLActivity .onNativeKeyUp (keyCode );
582
- return true ;
683
+ /* Dispatch the different events depending on where they come from:
684
+ * If the input device has some joystick source (probably differing
685
+ * from the source to which the given key belongs), assume it is a
686
+ * game controller button. Otherwise, assume a keyboard key.
687
+ * This should also take care of some kinds of manually toggled soft
688
+ * keyboards (i.e. not via the SDL text input API).
689
+ */
690
+ if ( (event .getDevice ().getSources () & 0x00000010 /* API 12: InputDevice.SOURCE_CLASS_JOYSTICK*/ ) != 0 ) {
691
+ int id = SDLActivity .getJoyId ( event .getDeviceId () );
692
+ // The joystick subsystem may be uninitialized, so ignore
693
+ if (id < 0 )
694
+ return true ;
695
+ if (event .getAction () == KeyEvent .ACTION_DOWN ) {
696
+ SDLActivity .onNativePadDown (id , keyCode );
697
+ return true ;
698
+ } else if (event .getAction () == KeyEvent .ACTION_UP ) {
699
+ SDLActivity .onNativePadUp (id , keyCode );
700
+ return true ;
701
+ }
702
+ } else {
703
+ if (event .getAction () == KeyEvent .ACTION_DOWN ) {
704
+ //Log.v("SDL", "key down: " + keyCode);
705
+ SDLActivity .onNativeKeyDown (keyCode );
706
+ return true ;
707
+ }
708
+ else if (event .getAction () == KeyEvent .ACTION_UP ) {
709
+ //Log.v("SDL", "key up: " + keyCode);
710
+ SDLActivity .onNativeKeyUp (keyCode );
711
+ return true ;
712
+ }
583
713
}
584
714
585
715
return false ;
@@ -614,7 +744,7 @@ public boolean onTouch(View v, MotionEvent event) {
614
744
}
615
745
}
616
746
return true ;
617
- }
747
+ }
618
748
619
749
// Sensor events
620
750
public void enableSensor (int sensortype , boolean enabled ) {
@@ -634,13 +764,14 @@ public void onAccuracyChanged(Sensor sensor, int accuracy) {
634
764
}
635
765
636
766
public void onSensorChanged (SensorEvent event ) {
767
+ /*
637
768
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
638
769
SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH,
639
770
event.values[1] / SensorManager.GRAVITY_EARTH,
640
771
event.values[2] / SensorManager.GRAVITY_EARTH);
641
772
}
773
+ */
642
774
}
643
-
644
775
}
645
776
646
777
/* This is a fake invisible editor view that receives the input and defines the
0 commit comments