Browse Source

Added GameController.

Mark Sibly 7 years ago
parent
commit
e664f13d17

+ 2 - 1
modules/mojo/app/app.monkey2

@@ -89,11 +89,12 @@ Class AppInstance
 	
 	
 		_config=config
 		_config=config
 		
 		
-		SDL_Init( SDL_INIT_VIDEO|SDL_INIT_JOYSTICK )
+		SDL_Init( SDL_INIT_VIDEO|SDL_INIT_JOYSTICK|SDL_INIT_GAMECONTROLLER )
 		
 		
 		SDL_SetHint( "SDL_MOUSE_FOCUS_CLICKTHROUGH","1" )
 		SDL_SetHint( "SDL_MOUSE_FOCUS_CLICKTHROUGH","1" )
 
 
 		SDL_FlushEvents( SDL_JOYDEVICEADDED,SDL_JOYDEVICEADDED )
 		SDL_FlushEvents( SDL_JOYDEVICEADDED,SDL_JOYDEVICEADDED )
+		SDL_FlushEvents( SDL_CONTROLLERDEVICEADDED,SDL_CONTROLLERDEVICEADDED )
 		
 		
 		'possible fix for linux crashing at exit (can't reproduce myself).
 		'possible fix for linux crashing at exit (can't reproduce myself).
 		'		
 		'		

+ 222 - 0
modules/mojo/input/gamecontroller.monkey2

@@ -0,0 +1,222 @@
+Namespace mojo.input
+
+#rem monkeydoc @hidden
+#end
+Enum GameControllerAxis		'uses SDL values
+	LeftX=0
+	LeftY=1
+	RightX=2
+	RightY=3
+	LeftTrigger=4
+	RightTrigger=5
+End
+
+#rem monkeydoc @hidden
+#end
+Enum GameControllerButton	'uses SDL values
+	A=0
+	B=1
+	X=2
+	Y=3
+	Back=4
+	Guide=5
+	Start=6
+	LeftStick=7
+	RightStick=8
+	LeftShoulder=9
+	RightShoulder=10
+	DpadUp=11
+	DpadDown=12
+	DpadLeft=13
+	DpadRight=14
+End
+
+#rem monkeydoc @hidden
+#end
+Class GameController
+	
+	#rem monkeydoc True if game controller is attached.
+	#end
+	Property Attached:Bool()
+		
+		If _discarded Return False
+		
+		If SDL_GameControllerGetAttached( _sdlcontroller ) Return True
+		
+		Discard()
+		
+		Return False
+	End
+	
+	#rem monkeydoc Name of game controller
+	#end
+	Property Name:String()
+		
+		If _discarded Return ""
+		
+		Return SDL_GameControllerName( _sdlcontroller )
+	End
+
+	#rem monkeydoc Gets game controller axis value in the range -1 to 1.
+	#end	
+	Method GetAxis:Float( axis:GameControllerAxis )
+		
+		If _discarded Return 0
+		
+		Return (Float(SDL_GameControllerGetAxis( _sdlcontroller,Cast<SDL_GameControllerAxis>( Int(axis) ) ) )+32768)/32767.5-1
+	End
+	
+	#rem monkeydoc Get game controll button state.
+	#end
+	Method GetButton:Bool( button:GameControllerButton )
+		
+		If _discarded Return False
+		
+		Return SDL_GameControllerGetButton( _sdlcontroller,Cast<SDL_GameControllerButton>( Int(button) ) )
+	End
+	
+	#rem monkeydoc Check up/down state of a game controller button.
+	#end
+	Method ButtonDown:Bool( button:GameControllerButton )
+		
+		If _discarded Return False
+		
+		Return SDL_GameControllerGetButton( _sdlcontroller,Cast<SDL_GameControllerButton>( Int(button) ) )
+	End
+	
+	#rem monkeydoc Gets joystick mapping.
+	#end
+	Method GetMapping:String()
+		
+		If _discarded Return ""
+		
+		Local mapping:=SDL_GameControllerMapping( _sdlcontroller )
+		
+		Local r:=String.FromCString( mapping )
+		
+		SDL_free( mapping )
+		
+		Return r
+	End
+	
+	#rem monkeydoc Closes a game controller.
+	#end
+	Method Close()
+		
+		If _discarded Return
+		
+		_refs-=1
+		If Not _refs Discard()
+	End
+	
+	#rem  monkeydoc Adds a GameController mapping.
+	
+	Returns 1 if mapping added, 0 if mapping updated, -1 if error.
+	
+	https://wiki.libsdl.org/SDL_GameControllerAddMapping
+	
+	#end
+	Function AddMapping:Int( mapping:String )
+		
+		Return SDL_GameControllerAddMapping( mapping )
+	End
+
+	#rem monkeydoc Loads game controller mappings from a file.
+	
+	Returns the number of mappings added.
+
+	#end
+	Function AddMappingsFromFile:Int( path:String )
+		
+		Local n:=0
+		
+		For Local mapping:=Eachin LoadString( "asset::gamecontrollerdb.txt",True ).Split( "~n" )
+			
+			n+=AddMapping( mapping )>0 ? 1 Else 0
+		Next
+		
+		Return n
+	End
+
+#rem	
+	Function GetAxisName:String( axis:GameControllerAxis )
+
+		Return SDL_GameControllerGetStringForAxis( Cast<SDL_GameControllerAxis>( Int(axis) ) )
+	End
+	
+	Function GetButtonName:String( button:GameControllerButton )
+		
+		Return SDL_GameControllerGetStringForButton( Cast<SDL_GameControllerButton>( int(button) ) )
+	End
+#end
+
+	Function Open:GameController( index:Int )
+		
+		If index<0 Or index>=MaxControllers Return Null
+		
+		Local controller:=_controllers[index]
+		If controller?.Attached
+			controller._refs+=1
+			Return controller
+		End
+		
+		For Local devid:=0 Until JoystickDevice.NumJoysticks()
+			
+			If Not SDL_IsGameController( devid ) Continue
+			
+			Local sdlcontroller:=SDL_GameControllerOpen( devid )
+			If Not sdlcontroller Continue
+			
+			Local inst:=SDL_JoystickInstanceID( SDL_GameControllerGetJoystick( sdlcontroller ) )
+			If _opened[inst]
+				SDL_GameControllerClose( sdlcontroller )
+				Continue
+			Endif
+
+			Local controller:=New GameController( index,sdlcontroller,inst )
+			
+			Return controller
+		Next
+		
+		Return Null
+	End
+	
+	Private
+	
+	Const MaxControllers:=8
+	
+	Global _opened:=New IntMap<GameController>
+	
+	Global _controllers:=New GameController[MaxControllers]
+	
+	Field _refs:=1
+	Field _discarded:=False
+	
+	Field _index:Int
+	Field _sdlcontroller:SDL_GameController Ptr
+	Field _inst:Int
+	
+	Method New( index:Int,sdlcontroller:SDL_GameController Ptr,inst:Int )
+		
+		_index=index
+		_sdlcontroller=sdlcontroller
+		_inst=inst
+		
+		_controllers[_index]=Self
+		_opened[_inst]=Self
+	End
+	
+	Method Discard()
+		
+		if _discarded Return
+		
+		SDL_GameControllerClose( _sdlcontroller )
+		
+		_controllers[_index]=Null
+		
+		_opened.Remove( _inst )
+		
+		_discarded=True
+	End
+	
+End

+ 44 - 41
modules/mojo/input/joystick.monkey2

@@ -62,42 +62,58 @@ Class Joystick
 	#end	
 	#end	
 	Property Name:String()
 	Property Name:String()
 		
 		
-		Return _name
+		If _discarded Return ""
+		
+		Return SDL_JoystickName( _sdljoystick )
 	End
 	End
 	
 	
-	#rem monkeydoc Joystick globally unique identifier.
-	#end	
+	#rem monkeydoc Joystick GUID.
+	#end
 	Property GUID:String()
 	Property GUID:String()
 		
 		
-		Return _guid
-	End
+		If _discarded Return ""
 
 
+		Local buf:=New Byte[64]
+		Local guid:=SDL_JoystickGetGUID( _sdljoystick )
+		SDL_JoystickGetGUIDString( guid,Cast<libc.char_t Ptr>( buf.Data ),buf.Length )
+		buf[buf.Length-1]=0
+		Return String.FromCString( buf.Data )
+	End
+	
 	#rem monkeydoc The number of axes supported by the joystick.
 	#rem monkeydoc The number of axes supported by the joystick.
 	#end	
 	#end	
 	Property NumAxes:Int()
 	Property NumAxes:Int()
 		
 		
-		Return _numAxes
+		If _discarded Return 0
+		
+		Return SDL_JoystickNumAxes( _sdljoystick )
 	End
 	End
 	
 	
 	#rem monkeydoc The number of balls upported by the joystick.
 	#rem monkeydoc The number of balls upported by the joystick.
 	#end	
 	#end	
 	Property NumBalls:Int()
 	Property NumBalls:Int()
 		
 		
-		Return _numBalls
+		If _discarded Return 0
+		
+		Return SDL_JoystickNumBalls( _sdljoystick )
 	End
 	End
 	
 	
 	#rem monkeydoc The number of buttons supported by the joystick.
 	#rem monkeydoc The number of buttons supported by the joystick.
 	#end	
 	#end	
 	Property NumButtons:Int()
 	Property NumButtons:Int()
 		
 		
-		Return _numButtons
+		If _discarded Return 0
+		
+		Return SDL_JoystickNumButtons( _sdljoystick )
 	End
 	End
 	
 	
 	#rem monkeydoc The number of hats supported by the joystick.
 	#rem monkeydoc The number of hats supported by the joystick.
 	#end	
 	#end	
 	Property NumHats:Int()
 	Property NumHats:Int()
 		
 		
-		Return _numHats
+		If _discarded Return 0
+		
+		Return SDL_JoystickNumHats( _sdljoystick )
 	End
 	End
 	
 	
 	#rem monkeydoc Gets joystick axis value in the range -1 to 1.
 	#rem monkeydoc Gets joystick axis value in the range -1 to 1.
@@ -129,7 +145,16 @@ Class Joystick
 		Return Cast<JoystickHat>( SDL_JoystickGetHat( _sdljoystick,hat ) )
 		Return Cast<JoystickHat>( SDL_JoystickGetHat( _sdljoystick,hat ) )
 	End
 	End
 
 
-	#rem monkeydoc Check up/down state of a button.
+	#rem monkeydoc Gets button state.
+	#end
+	Method GetButton:Bool( button:Int )
+		
+		If _discarded Return False
+		
+		Return SDL_JoystickGetButton( _sdljoystick,button )
+	End
+
+	#rem monkeydoc Checks up/down state of a button.
 	#end
 	#end
 	Method ButtonDown:Bool( button:Int )
 	Method ButtonDown:Bool( button:Int )
 		
 		
@@ -138,7 +163,7 @@ Class Joystick
 		Return SDL_JoystickGetButton( _sdljoystick,button )
 		Return SDL_JoystickGetButton( _sdljoystick,button )
 	End
 	End
 	
 	
-	#rem monkeydoc Checks is a button has been pressed.
+	#rem monkeydoc Checks if a button has been pressed.
 	#end
 	#end
 	Method ButtonPressed:Bool( button:Int )
 	Method ButtonPressed:Bool( button:Int )
 
 
@@ -180,7 +205,7 @@ Class Joystick
 		If index<0 Or index>=MaxJoysticks Return Null
 		If index<0 Or index>=MaxJoysticks Return Null
 		
 		
 		Local joystick:=_joysticks[index]
 		Local joystick:=_joysticks[index]
-		If joystick 
+		If joystick?.Attached
 			joystick._refs+=1
 			joystick._refs+=1
 			Return joystick
 			Return joystick
 		End
 		End
@@ -190,13 +215,13 @@ Class Joystick
 			Local sdljoystick:=SDL_JoystickOpen( devid )
 			Local sdljoystick:=SDL_JoystickOpen( devid )
 			If Not sdljoystick Continue
 			If Not sdljoystick Continue
 			
 			
-			Local instid:=SDL_JoystickInstanceID( sdljoystick )
-			If _opened[instid]
+			Local inst:=SDL_JoystickInstanceID( sdljoystick )
+			If _opened[inst]
 				SDL_JoystickClose( sdljoystick )
 				SDL_JoystickClose( sdljoystick )
 				Continue
 				Continue
 			Endif
 			Endif
 			
 			
-			Local joystick:=New Joystick( index,sdljoystick )
+			Local joystick:=New Joystick( index,sdljoystick,inst )
 			
 			
 			Return joystick
 			Return joystick
 		Next
 		Next
@@ -249,56 +274,34 @@ Class Joystick
 	End
 	End
 	
 	
 	Field _refs:=1
 	Field _refs:=1
-	Field _index:Int
-	Field _sdljoystick:SDL_Joystick Ptr 
 	Field _discarded:Bool
 	Field _discarded:Bool
 	
 	
+	Field _index:Int
+	Field _sdljoystick:SDL_Joystick Ptr 
 	Field _inst:Int
 	Field _inst:Int
-	Field _name:String
-	Field _guid:String
-	
-	Field _numAxes:Int
-	Field _numBalls:Int
-	Field _numButtons:Int
-	Field _numHats:Int
 	
 	
 	Field _hits:=New Bool[32]
 	Field _hits:=New Bool[32]
 	
 	
-	Method New( index:Int,sdljoystick:SDL_Joystick Ptr )
+	Method New( index:Int,sdljoystick:SDL_Joystick Ptr,inst:Int )
 		
 		
 		_index=index
 		_index=index
 		_sdljoystick=sdljoystick
 		_sdljoystick=sdljoystick
-	
-		_inst=SDL_JoystickInstanceID( _sdljoystick )
-		_name=String.FromCString( SDL_JoystickName( _sdljoystick ) )
-		_guid=GetGUID( _sdljoystick )
-		
-		_numAxes=SDL_JoystickNumAxes( _sdljoystick )
-		_numBalls=SDL_JoystickNumBalls( _sdljoystick )
-		_numButtons=SDL_JoystickNumButtons( _sdljoystick )
-		_numHats=SDL_JoystickNumHats( _sdljoystick )
+		_inst=inst
 		
 		
 		_joysticks[_index]=Self
 		_joysticks[_index]=Self
 		
 		
 		_opened[_inst]=Self
 		_opened[_inst]=Self
-		
-		If DEBUG Print "Joystick Created, user id="+_index+", instance id="+_inst
 	End
 	End
 	
 	
 	Method Discard()
 	Method Discard()
 
 
 		If _discarded Return
 		If _discarded Return
 		
 		
-		If DEBUG Print "Discarding Joystick, user id="+_index+", instance id="+_inst
-		
 		SDL_JoystickClose( _sdljoystick )
 		SDL_JoystickClose( _sdljoystick )
-		_sdljoystick=Null
 		
 		
 		_joysticks[_index]=Null
 		_joysticks[_index]=Null
-		_index=-1
 		
 		
 		_opened.Remove( _inst )
 		_opened.Remove( _inst )
-		_inst=-1
 		
 		
 		_discarded=True
 		_discarded=True
 	End
 	End

+ 1 - 0
modules/mojo/mojo.monkey2

@@ -44,6 +44,7 @@ Namespace mojo
 #Import "input/mouse"
 #Import "input/mouse"
 #Import "input/touch"
 #Import "input/touch"
 #Import "input/joystick"
 #Import "input/joystick"
+#Import "input/gamecontroller"
 #Import "input/keycodes"
 #Import "input/keycodes"
 
 
 #Import "audio/audio"
 #Import "audio/audio"