Files
Cesarus85--ringfall-mjolnir-vr/tools/tests/GyroscopeAimTest.java
T
Milenko d90f84faa3 Add on-screen touch controls for the game on Android
An overlay over the game, from JoshRob297's halo-ce-touch, which ported
theLlamaNet's halo-ce-android: a stick, the controller's buttons with word
labels, swipe aiming, optional gyroscope aiming, the phone's vibration, and
an editor to move, resize, hide, copy, export and import the buttons. It
is player 1's controller, merged into port 0's state as the keyboard is.

Changes from the fork:

- The controls show only in a game. In the menus and during cinematics
  they hide and let the fingers through, so HiIAmMoot's menu touch
  (upstream #50) and its tap to skip work under them. The game tells the
  overlay through a new host import, host_touch_scene.
- They hide while a controller with a stick is connected, such as a
  handheld's built-in one, and never show without a touchscreen (a TV).
  The new setting input.touch_controls ("auto", "on", "off"; default
  "auto") overrides this. Hiding with a controller follows diegotorres00's
  upstream #58.
- Swipes that start in Android's edge-gesture zones do not turn the view,
  and a press shorter than a frame is held long enough for the game to see
  it, as HiIAmMoot suggested in the review of #58.
- The swipe is not the mouse's aiming, so it keeps the controller's aim
  assist.
- The phone vibrates from port 0's XInputSetState, so the game's own
  vibration setting applies and no game source changes. It vibrates only
  while the touch controls show.
- The fork's cheats menu and its built-in cheat buttons are left out.

Co-authored-by: JoshRob297 <99092299+JoshRob297@users.noreply.github.com>
Co-authored-by: theLlamaNet <107216990+theLlamaNet@users.noreply.github.com>
(cherry picked from commit 7bd7481bdede370558a3c93d286e37a9c24237bd)
(cherry picked from commit 5911e2312b6960de58dfa1cad2fefce1a17b97f7)
2026-10-10 00:59:59 +13:00

35 lines
2.1 KiB
Java

package com.halo.decomp;
public final class GyroscopeAimTest {
private static void check(boolean ok, String message) {
if (!ok) throw new AssertionError(message);
}
private static void near(float value, float expected, String message) {
check(Math.abs(value-expected) < 0.000001f, message);
}
public static void main(String[] args) {
GyroscopeAim aim = new GyroscopeAim(); float[] delta = new float[2];
check(!aim.sample(1000000000L, 1, 0, 1, delta), "First event must only anchor time");
check(aim.sample(1020000000L, 1, 0, 1, delta), "Landscape yaw must produce motion");
near(delta[0], 0.02f, "Yaw integrates angular velocity in radians");
near(delta[1], 0, "Pure yaw does not pitch");
check(!aim.sample(1040000000L, 1, 0, 3, delta), "Changing orientation must reset the sample");
aim.sample(1060000000L, 1, 0, 3, delta);
near(delta[0], -0.02f, "Reverse landscape must reverse device-axis mapping");
check(!aim.sample(2000000000L, 1, 0, 3, delta), "A resume gap must not jump the camera");
aim.reset();
check(!aim.sample(2100000000L, 0, 1, 1, delta), "Reset releases pending gyro motion");
aim.sample(2120000000L, 0, 1, 1, delta);
near(delta[1], -0.02f, "Landscape pitch must follow phone tilt rather than invert it");
aim.reset(); aim.sample(2200000000L, 0, 1, 3, delta);
aim.sample(2220000000L, 0, 1, 3, delta);
near(delta[1], 0.02f, "Reverse landscape pitch must follow the reversed display axis");
aim.reset(); aim.sample(3000000000L, 0.005f, -0.005f, 0, delta);
check(!aim.sample(3020000000L, 0.005f, -0.005f, 0, delta), "Small stationary noise must not drift");
check(!aim.sample(3040000000L, Float.NaN, 1, 0, delta), "Invalid sensor values are rejected");
aim.sample(4000000000L, 1, 1, 0, delta);
check(!aim.sample(3990000000L, 1, 1, 0, delta), "Out-of-order timestamps produce no motion");
System.out.println("Gyroscope integration, orientation and lifecycle checks passed");
}
}