mirror of
				https://github.com/MaddyThorson/StrawberryBF.git
				synced 2025-11-04 01:41:33 +08:00 
			
		
		
		
	Support for multiple gamepads
This commit is contained in:
		
							
								
								
									
										37
									
								
								src/Game.bf
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								src/Game.bf
									
									
									
									
									
								
							@ -30,10 +30,10 @@ namespace Strawberry
 | 
			
		||||
		private SDL.Window* window;
 | 
			
		||||
		private SDL.Surface* screen;
 | 
			
		||||
		private bool* keyboardState;
 | 
			
		||||
		private SDL.SDL_GameController* gamepad;
 | 
			
		||||
		private SDL.SDL_GameController*[] gamepads;
 | 
			
		||||
		private int32 updateCounter;
 | 
			
		||||
 | 
			
		||||
		public this(String windowTitle, int32 width, int32 height)
 | 
			
		||||
		public this(String windowTitle, int32 width, int32 height, int gamepadLimit = 1)
 | 
			
		||||
			: base()
 | 
			
		||||
		{
 | 
			
		||||
			Game = this;
 | 
			
		||||
@ -51,7 +51,10 @@ namespace Strawberry
 | 
			
		||||
			Path.GetDirectoryPath(exePath, exeDir);
 | 
			
		||||
			Directory.SetCurrentDirectory(exeDir);
 | 
			
		||||
 | 
			
		||||
			SDL.Init(.Video | .Events | .Audio | .GameController);
 | 
			
		||||
			SDL.InitFlag init = .Video | .Events | .Audio;
 | 
			
		||||
			if (gamepadLimit > 0)
 | 
			
		||||
				init |= .GameController;
 | 
			
		||||
			SDL.Init(init);
 | 
			
		||||
			SDL.EventState(.JoyAxisMotion, .Disable);
 | 
			
		||||
			SDL.EventState(.JoyBallMotion, .Disable);
 | 
			
		||||
			SDL.EventState(.JoyHatMotion, .Disable);
 | 
			
		||||
@ -68,7 +71,9 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
			SDLTTF.Init();
 | 
			
		||||
 | 
			
		||||
			gamepad = SDL.GameControllerOpen(0);
 | 
			
		||||
			this.gamepads = new SDL.SDL_GameController*[gamepadLimit];
 | 
			
		||||
			for (let i < this.gamepads.Count)
 | 
			
		||||
				this.gamepads[i] = SDL.GameControllerOpen((int32)i);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ~this()
 | 
			
		||||
@ -79,8 +84,16 @@ namespace Strawberry
 | 
			
		||||
			if (switchToScene != scene && switchToScene != null)
 | 
			
		||||
				delete switchToScene;
 | 
			
		||||
 | 
			
		||||
			delete VirtualInputs;
 | 
			
		||||
			{
 | 
			
		||||
				let list = scope List<VirtualInput>();
 | 
			
		||||
				for (var i in VirtualInputs)
 | 
			
		||||
					list.Add(i);
 | 
			
		||||
				for (var i in list)
 | 
			
		||||
					delete i;
 | 
			
		||||
				delete VirtualInputs;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			delete gamepads;
 | 
			
		||||
			Game = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -94,7 +107,9 @@ namespace Strawberry
 | 
			
		||||
			{
 | 
			
		||||
				SDL.Event event;
 | 
			
		||||
				if (SDL.PollEvent(out event) != 0 && event.type == .Quit)
 | 
			
		||||
				{
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Fixed 60 Hz update
 | 
			
		||||
				double msPerTick = 1000 / 60.0;
 | 
			
		||||
@ -189,19 +204,19 @@ namespace Strawberry
 | 
			
		||||
			return keyboardState[(int)key];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool GamepadButtonCheck(SDL.SDL_GameControllerButton button)
 | 
			
		||||
		public bool GamepadButtonCheck(int gamepadID, SDL.SDL_GameControllerButton button)
 | 
			
		||||
		{
 | 
			
		||||
			if (gamepad == null)
 | 
			
		||||
			if (gamepads == null)
 | 
			
		||||
				return false;
 | 
			
		||||
			return SDL.GameControllerGetButton(gamepad, button) == 1;
 | 
			
		||||
			return SDL.GameControllerGetButton(gamepads[gamepadID], button) == 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float GamepadAxisCheck(SDL.SDL_GameControllerAxis axis)
 | 
			
		||||
		public float GamepadAxisCheck(int gamepadID, SDL.SDL_GameControllerAxis axis)
 | 
			
		||||
		{
 | 
			
		||||
			if (gamepad == null)
 | 
			
		||||
			if (gamepads == null)
 | 
			
		||||
				return 0;
 | 
			
		||||
 | 
			
		||||
			let val = SDL.GameControllerGetAxis(gamepad, axis);
 | 
			
		||||
			let val = SDL.GameControllerGetAxis(gamepads[gamepadID], axis);
 | 
			
		||||
			if (val == 0)
 | 
			
		||||
				return 0;
 | 
			
		||||
			else if (val > 0)
 | 
			
		||||
 | 
			
		||||
@ -95,15 +95,15 @@ namespace Strawberry
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public VirtualAxis AddButtons(SDL.SDL_GameControllerButton negativeButton, SDL.SDL_GameControllerButton positiveButton, OverlapBehaviors overlapBehavior = .TakeNewer)
 | 
			
		||||
		public VirtualAxis AddButtons(int gamepadID, SDL.SDL_GameControllerButton negativeButton, SDL.SDL_GameControllerButton positiveButton, OverlapBehaviors overlapBehavior = .TakeNewer)
 | 
			
		||||
		{
 | 
			
		||||
			nodes.Add(new GamepadButtons(negativeButton, positiveButton, overlapBehavior));
 | 
			
		||||
			nodes.Add(new GamepadButtons(gamepadID, negativeButton, positiveButton, overlapBehavior));
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public VirtualAxis AddAxis(SDL.SDL_GameControllerAxis axis, float deadzone)
 | 
			
		||||
		public VirtualAxis AddAxis(int gamepadID, SDL.SDL_GameControllerAxis axis, float deadzone)
 | 
			
		||||
		{
 | 
			
		||||
			nodes.Add(new GamepadAxis(axis, deadzone));
 | 
			
		||||
			nodes.Add(new GamepadAxis(gamepadID, axis, deadzone));
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -204,6 +204,7 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		private class GamepadButtons : Node
 | 
			
		||||
		{
 | 
			
		||||
			public int GamepadID;
 | 
			
		||||
			public OverlapBehaviors OverlapBehavior;
 | 
			
		||||
			public SDL.SDL_GameControllerButton NegativeButton;
 | 
			
		||||
			public SDL.SDL_GameControllerButton PositiveButton;
 | 
			
		||||
@ -211,8 +212,9 @@ namespace Strawberry
 | 
			
		||||
			private float value;
 | 
			
		||||
			private bool turned;
 | 
			
		||||
 | 
			
		||||
			public this(SDL.SDL_GameControllerButton negativeButton, SDL.SDL_GameControllerButton positiveButton, OverlapBehaviors overlapBehavior = .TakeNewer)
 | 
			
		||||
			public this(int gamepadID, SDL.SDL_GameControllerButton negativeButton, SDL.SDL_GameControllerButton positiveButton, OverlapBehaviors overlapBehavior = .TakeNewer)
 | 
			
		||||
			{
 | 
			
		||||
				GamepadID = gamepadID;
 | 
			
		||||
				NegativeButton = negativeButton;
 | 
			
		||||
				PositiveButton = positiveButton;
 | 
			
		||||
				OverlapBehavior = overlapBehavior;
 | 
			
		||||
@ -220,9 +222,9 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
			public override void Update()
 | 
			
		||||
			{
 | 
			
		||||
				if (Game.GamepadButtonCheck(PositiveButton))
 | 
			
		||||
				if (Game.GamepadButtonCheck(GamepadID, PositiveButton))
 | 
			
		||||
				{
 | 
			
		||||
				    if (Game.GamepadButtonCheck(NegativeButton))
 | 
			
		||||
				    if (Game.GamepadButtonCheck(GamepadID, NegativeButton))
 | 
			
		||||
				    {
 | 
			
		||||
				        switch (OverlapBehavior)
 | 
			
		||||
				        {
 | 
			
		||||
@ -249,7 +251,7 @@ namespace Strawberry
 | 
			
		||||
				        value = 1;
 | 
			
		||||
				    }
 | 
			
		||||
				}
 | 
			
		||||
				else if (Game.GamepadButtonCheck(NegativeButton))
 | 
			
		||||
				else if (Game.GamepadButtonCheck(GamepadID, NegativeButton))
 | 
			
		||||
				{
 | 
			
		||||
				    turned = false;
 | 
			
		||||
				    value = -1;
 | 
			
		||||
@ -272,11 +274,13 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		private class GamepadAxis : Node
 | 
			
		||||
		{
 | 
			
		||||
			public int GamepadID;
 | 
			
		||||
			public SDL.SDL_GameControllerAxis Axis;
 | 
			
		||||
			public float Deadzone;
 | 
			
		||||
 | 
			
		||||
			public this(SDL.SDL_GameControllerAxis axis, float deadzone)
 | 
			
		||||
			public this(int gamepadID, SDL.SDL_GameControllerAxis axis, float deadzone)
 | 
			
		||||
			{
 | 
			
		||||
				GamepadID = gamepadID;
 | 
			
		||||
				Axis = axis;
 | 
			
		||||
				Deadzone = deadzone;
 | 
			
		||||
			}
 | 
			
		||||
@ -285,7 +289,7 @@ namespace Strawberry
 | 
			
		||||
			{
 | 
			
		||||
				get
 | 
			
		||||
				{
 | 
			
		||||
					let val = Game.GamepadAxisCheck(Axis);
 | 
			
		||||
					let val = Game.GamepadAxisCheck(GamepadID, Axis);
 | 
			
		||||
					if (Math.Abs(val) < Deadzone)
 | 
			
		||||
						return 0;
 | 
			
		||||
					else
 | 
			
		||||
 | 
			
		||||
@ -91,9 +91,15 @@ namespace Strawberry
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public VirtualButton AddButton(SDL.SDL_GameControllerButton button)
 | 
			
		||||
		public VirtualButton AddButton(int gamepadID, SDL.SDL_GameControllerButton button)
 | 
			
		||||
		{
 | 
			
		||||
			nodes.Add(new GamepadButton(button));
 | 
			
		||||
			nodes.Add(new GamepadButton(gamepadID, button));
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public VirtualButton AddAxis(int gamepadID, SDL.SDL_GameControllerAxis axis, float threshold, ThresholdConditions condition = .GreaterThan)
 | 
			
		||||
		{
 | 
			
		||||
			nodes.Add(new GamepadAxis(gamepadID, axis, threshold, condition));
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -143,10 +149,12 @@ namespace Strawberry
 | 
			
		||||
 | 
			
		||||
		private class GamepadButton : Node
 | 
			
		||||
		{
 | 
			
		||||
			public int GamepadID;
 | 
			
		||||
			public SDL.SDL_GameControllerButton Button;
 | 
			
		||||
 | 
			
		||||
			public this(SDL.SDL_GameControllerButton button)
 | 
			
		||||
			public this(int gamepadID, SDL.SDL_GameControllerButton button)
 | 
			
		||||
			{
 | 
			
		||||
				GamepadID = gamepadID;
 | 
			
		||||
				Button = button;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -154,19 +162,21 @@ namespace Strawberry
 | 
			
		||||
			{
 | 
			
		||||
				get
 | 
			
		||||
				{
 | 
			
		||||
					 return Game.GamepadButtonCheck(Button);
 | 
			
		||||
					 return Game.GamepadButtonCheck(GamepadID, Button);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private class GamepadAxis : Node
 | 
			
		||||
		{
 | 
			
		||||
			public int GamepadID;
 | 
			
		||||
			public SDL.SDL_GameControllerAxis Axis;
 | 
			
		||||
			public float Threshold;
 | 
			
		||||
			public ThresholdConditions Condition;
 | 
			
		||||
 | 
			
		||||
			public this(SDL.SDL_GameControllerAxis axis, float threshold, ThresholdConditions condition = .GreaterThan)
 | 
			
		||||
			public this(int gamepadID, SDL.SDL_GameControllerAxis axis, float threshold, ThresholdConditions condition = .GreaterThan)
 | 
			
		||||
			{
 | 
			
		||||
				GamepadID = gamepadID;
 | 
			
		||||
				Axis = axis;
 | 
			
		||||
				Threshold = threshold;
 | 
			
		||||
				Condition = condition;
 | 
			
		||||
@ -177,9 +187,9 @@ namespace Strawberry
 | 
			
		||||
				get
 | 
			
		||||
				{
 | 
			
		||||
					if (Condition == .GreaterThan)
 | 
			
		||||
					 	return Game.GamepadAxisCheck(Axis) >= Threshold;
 | 
			
		||||
					 	return Game.GamepadAxisCheck(GamepadID, Axis) >= Threshold;
 | 
			
		||||
					else
 | 
			
		||||
						return Game.GamepadAxisCheck(Axis) <= Threshold;
 | 
			
		||||
						return Game.GamepadAxisCheck(GamepadID, Axis) <= Threshold;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user