diff --git a/SPD-classes/src/main/java/com/watabou/input/ControllerHandler.java b/SPD-classes/src/main/java/com/watabou/input/ControllerHandler.java index 71d70c66f..54a526d29 100644 --- a/SPD-classes/src/main/java/com/watabou/input/ControllerHandler.java +++ b/SPD-classes/src/main/java/com/watabou/input/ControllerHandler.java @@ -31,7 +31,7 @@ import com.watabou.utils.PointF; public class ControllerHandler implements ControllerListener { - public static enum ControllerType { + public enum ControllerType { XBOX, PLAYSTATION, NINTENDO, @@ -98,6 +98,7 @@ public class ControllerHandler implements ControllerListener { private float L2Trigger = 0f; private float R2Trigger = 0f; + //FIXME these axis mappings seem to be wrong on Android (and iOS?) in some cases @Override public boolean axisMoved(Controller controller, int axisCode, float value) { setControllerType(controller); @@ -130,6 +131,18 @@ public class ControllerHandler implements ControllerListener { return true; } + //we use a separate variable as Gdx.input.isCursorCatched only works on desktop + private static boolean controllerPointerActive = false; + + public static void setControllerPointer( boolean active ){ + Gdx.input.setCursorCatched(active); + controllerPointerActive = active; + } + + public static boolean controllerPointerActive(){ + return controllerPointerActive; + } + //converts controller button codes to keyEvent codes public static int buttonToKey(Controller controller, int btnCode){ ControllerMapping mapping = controller.getMapping(); diff --git a/SPD-classes/src/main/java/com/watabou/input/InputHandler.java b/SPD-classes/src/main/java/com/watabou/input/InputHandler.java index 765d8afe6..aeea0e5cc 100644 --- a/SPD-classes/src/main/java/com/watabou/input/InputHandler.java +++ b/SPD-classes/src/main/java/com/watabou/input/InputHandler.java @@ -108,6 +108,7 @@ public class InputHandler extends InputAdapter { @Override public boolean mouseMoved(int screenX, int screenY) { + ControllerHandler.setControllerPointer(false); PointerEvent.addPointerEvent(new PointerEvent(screenX, screenY, -1, PointerEvent.Type.HOVER)); return true; } diff --git a/SPD-classes/src/main/java/com/watabou/noosa/ui/Cursor.java b/SPD-classes/src/main/java/com/watabou/noosa/ui/Cursor.java index a9b2ffa53..ae5ac4b5f 100644 --- a/SPD-classes/src/main/java/com/watabou/noosa/ui/Cursor.java +++ b/SPD-classes/src/main/java/com/watabou/noosa/ui/Cursor.java @@ -33,9 +33,10 @@ public class Cursor { public enum Type { //TODO if we ever add more cursors, should cache their pixmaps rather than always remaking - DEFAULT("gdx/cursor.png"); + DEFAULT("gdx/cursor_mouse.png"), + CONTROLLER("gdx/cursor_controller.png"); - private String file; + public final String file; Type(String file){ this.file = file; diff --git a/core/src/main/assets/gdx/cursor_controller.png b/core/src/main/assets/gdx/cursor_controller.png new file mode 100644 index 000000000..f744b2b8c Binary files /dev/null and b/core/src/main/assets/gdx/cursor_controller.png differ diff --git a/core/src/main/assets/gdx/cursor.png b/core/src/main/assets/gdx/cursor_mouse.png similarity index 100% rename from core/src/main/assets/gdx/cursor.png rename to core/src/main/assets/gdx/cursor_mouse.png diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene.java index dd2649437..ea0898eb8 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/PixelScene.java @@ -21,7 +21,6 @@ package com.shatteredpixel.shatteredpixeldungeon.scenes; -import com.badlogic.gdx.Gdx; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Badges; import com.shatteredpixel.shatteredpixeldungeon.SPDSettings; @@ -41,6 +40,7 @@ import com.watabou.noosa.Camera; import com.watabou.noosa.ColorBlock; import com.watabou.noosa.Game; import com.watabou.noosa.Gizmo; +import com.watabou.noosa.Image; import com.watabou.noosa.Scene; import com.watabou.noosa.Visual; import com.watabou.noosa.ui.Component; @@ -159,7 +159,7 @@ public class PixelScene extends Scene { } - private PointF fractionalMovement = new PointF(); + private static PointF virtualCursorPos; @Override public void update() { @@ -167,18 +167,36 @@ public class PixelScene extends Scene { //15% deadzone if (Math.abs(ControllerHandler.rightStickPosition.x) >= 0.15f || Math.abs(ControllerHandler.rightStickPosition.y) >= 0.15f) { - PointF curMouse = PointerEvent.currentHoverPos(); + if (!ControllerHandler.controllerPointerActive()) { + ControllerHandler.setControllerPointer(true); + virtualCursorPos = PointerEvent.currentHoverPos(); + } //cursor moves 500 scaled pixels per second at full speed, 75 at minimum speed - fractionalMovement.x += defaultZoom * 500 * Game.elapsed * ControllerHandler.rightStickPosition.x; - fractionalMovement.y += defaultZoom * 500 * Game.elapsed * ControllerHandler.rightStickPosition.y; - curMouse.x += (int)fractionalMovement.x; - curMouse.y += (int)fractionalMovement.y; - Gdx.input.setCursorPosition((int) curMouse.x, (int) curMouse.y); - PointerEvent.addPointerEvent(new PointerEvent((int) curMouse.x, (int) curMouse.y, 10_000, PointerEvent.Type.HOVER, PointerEvent.NONE)); - fractionalMovement.x -= (int)fractionalMovement.x; - fractionalMovement.y -= (int)fractionalMovement.y; - } else { - fractionalMovement.set(0); + virtualCursorPos.x += defaultZoom * 500 * Game.elapsed * ControllerHandler.rightStickPosition.x; + virtualCursorPos.y += defaultZoom * 500 * Game.elapsed * ControllerHandler.rightStickPosition.y; + virtualCursorPos.x = GameMath.gate(0, virtualCursorPos.x, Game.width); + virtualCursorPos.y = GameMath.gate(0, virtualCursorPos.y, Game.height); + PointerEvent.addPointerEvent(new PointerEvent((int) virtualCursorPos.x, (int) virtualCursorPos.y, 10_000, PointerEvent.Type.HOVER, PointerEvent.NONE)); + } + } + + private Image cursor = null; + + @Override + public synchronized void draw() { + super.draw(); + + //cursor is separate from the rest of the scene, always appears above + if (ControllerHandler.controllerPointerActive()){ + if (cursor == null){ + cursor = new Image(Cursor.Type.CONTROLLER.file); + } + + cursor.x = (virtualCursorPos.x / defaultZoom) - cursor.width()/2f; + cursor.y = (virtualCursorPos.y / defaultZoom) - cursor.height()/2f; + cursor.camera = uiCamera; + align(cursor); + cursor.draw(); } } @@ -215,6 +233,9 @@ public class PixelScene extends Scene { public void destroy() { super.destroy(); PointerEvent.clearListeners(); + if (cursor != null){ + cursor.destroy(); + } } public static boolean landscape(){