All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.flixel.plugin.GamepadManager Maven / Gradle / Ivy

The newest version!
package org.flixel.plugin;

import com.badlogic.gdx.controllers.Controller;
import com.badlogic.gdx.controllers.ControllerListener;
import com.badlogic.gdx.controllers.Controllers;
import com.badlogic.gdx.controllers.PovDirection;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import org.flixel.FlxBasic;
import org.flixel.FlxG;
import org.flixel.system.input.Gamepad;
import org.flixel.system.input.GamepadMapping;

/**
 * Manages the controllers and listen to input events.
 * 
 * @author Ka Wing Chin
 */
public class GamepadManager extends FlxBasic implements ControllerListener
{
	/**
	 * A self reference of the listener.
	 */
	public static GamepadManager listener;
	/**
	 * A map that keeps the controller and gamepad together.
	 */
	public static ObjectMap controllers;
	/**
	 * The button mappings that will be used with GamePad.
	 */
	private static Array mappings;
	/**
	 * An array that contains Gamepads for quick access.
	 */
	private static Array pads;

	/**
	 * Creates a new GamepadManager object.
	 * Needs to be added to the plugin, FlxG.addPlugin().
	 */
	public GamepadManager()
	{
		// TODO: error gdx-controllers-android can't be found.
		// SharedLibraryLoader loader = new SharedLibraryLoader();
		// if(FlxG.mobile)
		// { /*loader.load("gdx-controllers-android");*/}
		// else if(Gdx.app.getType() == ApplicationType.WebGL)
		// { /*loader.load("gdx-controllers-gwt");*/}
		// else
		// loader.load("gdx-controllers-desktop");

		listener = this;
		controllers = new ObjectMap();
		mappings = new Array();
		addMapping(new GamepadMapping("generic"));
		pads = new Array();
	}

	@Override
	public void destroy()
	{
		for(Controller c : Controllers.getControllers())
		{
			c.removeListener(listener);
		}
		listener = null;
		controllers.clear();
		controllers = null;
		for(int i = 0; i < mappings.size; i++)
			mappings.get(i).destroy();
		mappings.clear();
		mappings = null;
		for(int i = 0; i < pads.size; i++)
			pads.get(i).destroy();
		pads.clear();
		pads = null;
	}

	@Override
	public void update()
	{
		for(Gamepad pad : pads)
		{
			if(pad.connected)
				pad.update();
		}
	}

	/**
	 * Add new mapping.
	 * 
	 * @param	Mapping		The mapping that will be added.
	 */
	public static void addMapping(GamepadMapping Mapping)
	{
		//Don't bother adding a mapping twice.
		for(int i = 0; i < mappings.size; i++)
		{
			if(Mapping == mappings.get(i))
				return;
		}
		mappings.add(Mapping);
	}

	/**
	 * Add a new gamepad.
	 * 
	 * @param	Gamepad		The gamepad that will be added.
	 */
	public static void addGamepad(Gamepad Gamepad)
	{
		//Don't bother adding a gamepad twice.
		for(int i = 0; i < pads.size; i++)
		{
			if(Gamepad == pads.get(i))
				return;
		}
		pads.add(Gamepad);

		//Check if there is enough controllers available to hook a gamepad to it.
		if(pads.size > Controllers.getControllers().size)
		{
			FlxG.log("Gamepad > Available controllers: " + Controllers.getControllers().size);
			Gamepad.setMapping(mappings.get(0));
		}
		else
		{
			Controller c = Controllers.getControllers().get(pads.size - 1);
			c.addListener(listener);
			controllers.put(c, Gamepad);
			String controllerName = c.getName().toLowerCase();
			String mappingName;
			boolean mappingFound = false;
			for(int i = 0; i < mappings.size; i++)
			{
				if(mappings.get(i).ID != null)
				{
					if(controllerName.equals(mappings.get(i).ID.toLowerCase()))
					{
						Gamepad.setMapping(mappings.get(i));
						Gamepad.connected = true;
						mappingFound = true;
						break;
					}
				}
				if(mappings.get(i).IDs != null)
				{
					GamepadMapping mapping = mappings.get(i);
					for(int ii = 0; ii < mapping.IDs.length; ii++)
					{
						mappingName = mapping.IDs[ii].toLowerCase();
						if(controllerName.equals(mappingName))
						{
							Gamepad.setMapping(mapping);
							Gamepad.connected = true;
							mappingFound = true;
							break;
						}
					}
				}
			}
			if(!mappingFound)
			{
				FlxG.log("No mapping found for controller: " + c.getName() + "\nUse default mapping.");
				Gamepad.setMapping(mappings.get(0));
			}
		}
	}

	/**
	 * Remove a gamepad.
	 * 
	 * @param	Gamepad		The gamepad that will be moved.
	 */
	public static void removeGamepad(Gamepad Gamepad)
	{
		if(pads.removeValue(Gamepad, true))
		{
			Gamepad.connected = false;
			Controller c = controllers.findKey(Gamepad, true);
			if(c != null)
			{
				controllers.remove(c);
				c.removeListener(listener);
			}
		}
	}

	/**
	 * Get a gamepad by index.
	 * 
	 * @param	Index	The index.
	 * 
	 * @return	The gamepad.
	 */
	public static Gamepad get(int Index)
	{
		if(Index < pads.size)
			return controllers.get(Controllers.getControllers().get(Index));
		return null;
	}

	@Override
	public void connected(Controller Controller)
	{
		if(controllers.containsKey(Controller))
			controllers.get(Controller).connected = true;
		else
		{
			//add new controller
			for(int i = 0; i < pads.size; i++)
			{
				if(pads.get(i).ID == null)
					addGamepad(pads.get(i));
			}
		}
	}

	@Override
	public void disconnected(Controller Controller)
	{
		Gamepad gamepad = controllers.get(Controller);
		if(gamepad != null)
		{
			gamepad.connected = false;
			Controller c = controllers.findKey(gamepad, true);
			if(c != null)
			{
				controllers.remove(c);
				c.removeListener(listener);
			}
		}
	}

	@Override
	public boolean buttonDown(Controller Controller, int ButtonCode)
	{
		controllers.get(Controller).handleKeyDown(ButtonCode);
		return false;
	}

	@Override
	public boolean buttonUp(Controller Controller, int ButtonCode)
	{
		controllers.get(Controller).handleKeyUp(ButtonCode);
		return false;
	}

	@Override
	public boolean axisMoved(Controller Controller, int AxisCode, float Value)
	{
		controllers.get(Controller).axisData.put(AxisCode, Value);
		return false;
	}

	@Override
	public boolean povMoved(Controller Controller, int PovCode, PovDirection Value)
	{
		Gamepad pad = controllers.get(Controller);
		if(Value == PovDirection.center || pad.povDirection != Value)
		{
			pad.handleKeyUp(GamepadMapping.UP);
			pad.handleKeyUp(GamepadMapping.UP_RIGHT);
			pad.handleKeyUp(GamepadMapping.UP_LEFT);
			pad.handleKeyUp(GamepadMapping.RIGHT);
			pad.handleKeyUp(GamepadMapping.DOWN);
			pad.handleKeyUp(GamepadMapping.DOWN_RIGHT);
			pad.handleKeyUp(GamepadMapping.DOWN_LEFT);
			pad.handleKeyUp(GamepadMapping.LEFT);
		}
		switch(Value)
		{
			case north:
				pad.handleKeyDown(GamepadMapping.UP);
				break;
			case northEast:
				pad.handleKeyDown(GamepadMapping.UP_RIGHT);
				break;
			case northWest:
				pad.handleKeyDown(GamepadMapping.UP_LEFT);
				break;
			case east:
				pad.handleKeyDown(GamepadMapping.RIGHT);
				break;
			case south:
				pad.handleKeyDown(GamepadMapping.DOWN);
				break;
			case southEast:
				pad.handleKeyDown(GamepadMapping.DOWN_RIGHT);
				break;
			case southWest:
				pad.handleKeyDown(GamepadMapping.DOWN_LEFT);
				break;
			case west:
				pad.handleKeyDown(GamepadMapping.LEFT);
				break;
			default:
				break;
		}
		pad.povDirection = Value;
		return false;
	}

	@Override
	public boolean xSliderMoved(Controller Controller, int SliderCode, boolean Value)
	{
		// FlxG.log(sliderCode + " " + value);
		return false;
	}

	@Override
	public boolean ySliderMoved(Controller Controller, int SliderCode, boolean Value)
	{
		// FlxG.log(sliderCode + " " + value);
		return false;
	}

	@Override
	public boolean accelerometerMoved(Controller Controller, int AccelerometerCode, Vector3 Value)
	{
		controllers.get(Controller).x = Value.x;
		controllers.get(Controller).y = Value.y;
		controllers.get(Controller).z = Value.z;
		return false;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy