Add better button management, the controls screen and more.

This commit is contained in:
LambdAurora
2019-12-08 23:40:16 +01:00
parent 82f67e7af9
commit 6b78d32e6f
20 changed files with 1061 additions and 128 deletions

View File

@@ -10,16 +10,18 @@
package me.lambdaurora.lambdacontrols;
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.options.GameOptions;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.ScreenshotUtils;
import org.aperlambda.lambdacommon.utils.Nameable;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import java.util.stream.Stream;
/**
* Represents a button binding.
@@ -28,28 +30,59 @@ import java.util.Optional;
*/
public class ButtonBinding implements Nameable
{
private static final List<ButtonBinding> BINDINGS = new ArrayList<>();
public static final ButtonBinding ATTACK = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true), "attack");
public static final ButtonBinding BACK = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, false), "back");
public static final ButtonBinding DROP_ITEM = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_B, "drop_item");
public static final ButtonBinding FORWARD = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, true), "forward");
public static final ButtonBinding INVENTORY = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_Y, "inventory");
public static final ButtonBinding JUMP = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_A, "jump");
public static final ButtonBinding PAUSE_GAME = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_START, "pause_game");
public static final ButtonBinding SNEAK = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, "sneak");
public static final ButtonBinding SPRINT = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB, "sprint");
public static final ButtonBinding SWAP_HANDS = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_X, "swap_hands");
private static final List<ButtonBinding> BINDINGS = new ArrayList<>();
private static final Map<Pair<String, Integer>, List<ButtonBinding>> CATEGORIES = new HashMap<>();
public static final String MOVEMENT_CATEGORY = "key.categories.movement";
public static final String GAMEPLAY_CATEGORY = "key.categories.gameplay";
public static final String INVENTORY_CATEGORY = "key.categories.inventory";
public static final String MULTIPLAYER_CATEGORY = "key.categories.multiplayer";
public static final String MISC_CATEGORY = "key.categories.misc";
public static final ButtonBinding ATTACK = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true), "attack");
public static final ButtonBinding BACK = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, false), "back");
public static final ButtonBinding CHAT = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, "chat");
public static final ButtonBinding DROP_ITEM = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_B, "drop_item");
public static final ButtonBinding FORWARD = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, true), "forward");
public static final ButtonBinding INVENTORY = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_Y, "inventory");
public static final ButtonBinding JUMP = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_A, "jump");
public static final ButtonBinding LEFT = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, false), "left");
public static final ButtonBinding PAUSE_GAME = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_START, "pause_game");
public static final ButtonBinding PICK_BLOCK = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT, "pick_block");
public static final ButtonBinding PLAYER_LIST = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_BACK, "player_list");
public static final ButtonBinding RIGHT = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, true), "right");
public static final ButtonBinding SCREENSHOT = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN, "screenshot",
Collections.singletonList((client, action) -> {
ScreenshotUtils.method_1659(client.runDirectory, client.window.getFramebufferWidth(), client.window.getFramebufferHeight(), client.getFramebuffer(),
text -> client.execute(() -> client.inGameHud.getChatHud().addMessage(text)));
return true;
}));
public static final ButtonBinding SMOOTH_CAMERA = new ButtonBinding(-1, "toggle_smooth_camera");
public static final ButtonBinding SNEAK = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, "sneak");
public static final ButtonBinding SPRINT = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB, "sprint");
public static final ButtonBinding SWAP_HANDS = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_X, "swap_hands");
public static final ButtonBinding TOGGLE_PERSPECTIVE = new ButtonBinding(GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, "toggle_perspective");
public static final ButtonBinding USE = new ButtonBinding(axis_as_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true), "use");
private int button;
private String key;
private KeyBinding minecraft_key_binding = null;
private boolean pressed = false;
private int button;
private int default_button;
private String key;
private KeyBinding minecraft_key_binding = null;
private List<PressAction> actions = new ArrayList<>(Collections.singletonList((client, action) -> {
this.as_key_binding().ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(this.is_button_down()));
return true;
}));
private boolean pressed = false;
public ButtonBinding(int button, @NotNull String key, @NotNull List<PressAction> actions)
{
this.default_button = this.button = button;
this.key = key;
this.actions.addAll(actions);
BINDINGS.add(this);
}
public ButtonBinding(int button, @NotNull String key)
{
this.button = button;
this.key = key;
BINDINGS.add(this);
this(button, key, Collections.emptyList());
}
/**
@@ -62,6 +95,11 @@ public class ButtonBinding implements Nameable
return this.button;
}
/**
* Sets the bound button.
*
* @param button The bound button.
*/
public void set_button(int button)
{
this.button = button;
@@ -88,6 +126,36 @@ public class ButtonBinding implements Nameable
return this.pressed;
}
/**
* Returns whether this button binding is bound or not.
*
* @return True if this button binding is bound, else false.
*/
public boolean is_not_bound()
{
return this.button == -1;
}
/**
* Gets the default button assigned to this binding.
*
* @return The default button.
*/
public int get_default_button()
{
return this.default_button;
}
/**
* Returns whether the assigned button is the default button.
*
* @return True if the assigned button is the default button, else false.
*/
public boolean is_default()
{
return this.button == this.default_button;
}
@Override
public @NotNull String get_name()
{
@@ -139,13 +207,29 @@ public class ButtonBinding implements Nameable
public static void init(@NotNull GameOptions options)
{
ATTACK.minecraft_key_binding = options.keyAttack;
BACK.minecraft_key_binding = options.keyBack;
CHAT.minecraft_key_binding = options.keyChat;
DROP_ITEM.minecraft_key_binding = options.keyDrop;
FORWARD.minecraft_key_binding = options.keyForward;
INVENTORY.minecraft_key_binding = options.keyInventory;
JUMP.minecraft_key_binding = options.keyJump;
LEFT.minecraft_key_binding = options.keyLeft;
PICK_BLOCK.minecraft_key_binding = options.keyPickItem;
PLAYER_LIST.minecraft_key_binding = options.keyPlayerList;
RIGHT.minecraft_key_binding = options.keyRight;
SCREENSHOT.minecraft_key_binding = options.keyScreenshot;
SMOOTH_CAMERA.minecraft_key_binding = options.keySmoothCamera;
SNEAK.minecraft_key_binding = options.keySneak;
SPRINT.minecraft_key_binding = options.keySprint;
SWAP_HANDS.minecraft_key_binding = options.keySwapHands;
TOGGLE_PERSPECTIVE.minecraft_key_binding = options.keyTogglePerspective;
USE.minecraft_key_binding = options.keyUse;
}
public static void load_from_config(@NotNull LambdaControlsConfig config)
{
BINDINGS.forEach(config::load_button_binding);
}
public static void set_button_state(int button, boolean state)
@@ -154,10 +238,144 @@ public class ButtonBinding implements Nameable
.forEach(binding -> binding.pressed = state);
}
public static void handle_button(int button, boolean state)
public static void handle_button(@NotNull MinecraftClient client, int button, int action)
{
BINDINGS.parallelStream().filter(binding -> binding.button == button)
.map(ButtonBinding::as_key_binding)
.forEach(binding -> binding.ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(state)));
.forEach(binding -> {
for (int i = binding.actions.size() - 1; i >= 0; i--) {
if (binding.actions.get(i).press(client, action))
break;
}
});
}
/**
* Returns whether the button has duplicated bindings.
*
* @param button The button to check.
* @return True if the button has duplicated bindings, else false.
*/
public static boolean has_duplicates(int button)
{
return BINDINGS.parallelStream().filter(binding -> binding.button == button).count() > 1;
}
/**
* Returns the localized name of the specified button.
*
* @param button The button.
* @return The localized name of the button.
*/
public static @NotNull String get_localized_button_name(int button)
{
switch (button) {
case -1:
return I18n.translate("key.keyboard.unknown");
case GLFW.GLFW_GAMEPAD_BUTTON_A:
return I18n.translate("lambdacontrols.button.a");
case GLFW.GLFW_GAMEPAD_BUTTON_B:
return I18n.translate("lambdacontrols.button.b");
case GLFW.GLFW_GAMEPAD_BUTTON_X:
return I18n.translate("lambdacontrols.button.x");
case GLFW.GLFW_GAMEPAD_BUTTON_Y:
return I18n.translate("lambdacontrols.button.y");
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
return I18n.translate("lambdacontrols.button.left_bumper");
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
return I18n.translate("lambdacontrols.button.right_bumper");
case GLFW.GLFW_GAMEPAD_BUTTON_BACK:
return I18n.translate("lambdacontrols.button.back");
case GLFW.GLFW_GAMEPAD_BUTTON_START:
return I18n.translate("lambdacontrols.button.start");
case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE:
return I18n.translate("lambdacontrols.button.guide");
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
return I18n.translate("lambdacontrols.button.left_thumb");
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
return I18n.translate("lambdacontrols.button.right_thumb");
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP:
return I18n.translate("lambdacontrols.button.dpad_up");
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
return I18n.translate("lambdacontrols.button.dpad_right");
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
return I18n.translate("lambdacontrols.button.dpad_down");
case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
return I18n.translate("lambdacontrols.button.dpad_left");
case 100:
return I18n.translate("lambdacontrols.axis.left_x+");
case 101:
return I18n.translate("lambdacontrols.axis.left_y+");
case 102:
return I18n.translate("lambdacontrols.axis.right_x+");
case 103:
return I18n.translate("lambdacontrols.axis.right_y+");
case 104:
return I18n.translate("lambdacontrols.axis.left_trigger");
case 105:
return I18n.translate("lambdacontrols.axis.right_trigger");
case 200:
return I18n.translate("lambdacontrols.axis.left_x-");
case 201:
return I18n.translate("lambdacontrols.axis.left_y-");
case 202:
return I18n.translate("lambdacontrols.axis.right_x-");
case 203:
return I18n.translate("lambdacontrols.axis.right_y-");
default:
return I18n.translate("lambdacontrols.button.unknown", button);
}
}
public static @NotNull Stream<ButtonBinding> stream()
{
return BINDINGS.stream();
}
public static @NotNull Stream<Map.Entry<Pair<String, Integer>, List<ButtonBinding>>> stream_categories()
{
return CATEGORIES.entrySet().stream();
}
static {
CATEGORIES.put(Pair.of(MOVEMENT_CATEGORY, 0), Arrays.asList(
FORWARD,
BACK,
LEFT,
RIGHT,
JUMP,
SNEAK,
SPRINT
));
CATEGORIES.put(Pair.of(GAMEPLAY_CATEGORY, 1), Arrays.asList(
ATTACK,
PICK_BLOCK,
USE
));
CATEGORIES.put(Pair.of(INVENTORY_CATEGORY, 2), Arrays.asList(
DROP_ITEM,
INVENTORY,
SWAP_HANDS
));
CATEGORIES.put(Pair.of(MULTIPLAYER_CATEGORY, 2), Arrays.asList(
CHAT,
PLAYER_LIST
));
CATEGORIES.put(Pair.of(MISC_CATEGORY, 3), Arrays.asList(
SCREENSHOT,
//SMOOTH_CAMERA,
TOGGLE_PERSPECTIVE
));
}
@FunctionalInterface
public static interface PressAction
{
/**
* Handles when there is a press action on the button.
*
* @param client The client instance.
* @param action The action done.
*/
boolean press(@NotNull MinecraftClient client, int action);
}
}

View File

@@ -147,7 +147,6 @@ public class Controller implements Nameable
try (SeekableByteChannel fc = Files.newByteChannel(path)) {
buffer = createByteBuffer((int) fc.size() + 2);
while (fc.read(buffer) != -1) {
;
}
buffer.put((byte) 0);
}

View File

@@ -9,6 +9,8 @@
package me.lambdaurora.lambdacontrols;
import me.lambdaurora.lambdacontrols.gui.LambdaControlsControlsScreen;
import me.lambdaurora.lambdacontrols.mixin.EntryListWidgetAccessor;
import me.lambdaurora.lambdacontrols.util.AbstractContainerScreenAccessor;
import me.lambdaurora.lambdacontrols.util.CreativeInventoryScreenAccessor;
import me.lambdaurora.lambdacontrols.util.KeyBindingAccessor;
@@ -20,8 +22,11 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.advancement.AdvancementsScreen;
import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.gui.screen.world.WorldListWidget;
import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget;
import net.minecraft.client.gui.widget.SliderWidget;
import net.minecraft.container.Slot;
import net.minecraft.container.SlotActionType;
@@ -40,8 +45,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static me.lambdaurora.lambdacontrols.ButtonBinding.PAUSE_GAME;
import static me.lambdaurora.lambdacontrols.ButtonBinding.SNEAK;
import static me.lambdaurora.lambdacontrols.ButtonBinding.*;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
@@ -109,7 +113,7 @@ public class ControllerInput
public void on_pre_render_screen(@NotNull MinecraftClient client, @NotNull Screen screen)
{
if (!this.is_screen_interactive(screen)) {
if (!is_screen_interactive(screen)) {
if (this.prev_target_mouse_x != this.target_mouse_x || this.prev_target_mouse_y != this.target_mouse_y) {
double mouse_x = this.prev_target_mouse_x + (this.target_mouse_x - this.prev_target_mouse_x) * client.getTickDelta() + 0.5;
double mouse_y = this.prev_target_mouse_y + (this.target_mouse_y - this.prev_target_mouse_y) * client.getTickDelta() + 0.5;
@@ -172,6 +176,12 @@ public class ControllerInput
float value = buffer.get();
float abs_value = Math.abs(value);
if (i == GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y)
value *= -1.0F;
ButtonBinding.set_button_state(axis_as_button(i, true), value > 0.5F);
ButtonBinding.set_button_state(axis_as_button(i, false), value < -0.5F);
int state = value > this.config.get_dead_zone() ? 1 : (value < -this.config.get_dead_zone() ? 2 : 0);
this.handle_axe(client, i, value, abs_value, state);
}
@@ -179,12 +189,38 @@ public class ControllerInput
private void handle_button(@NotNull MinecraftClient client, int button, int action, boolean state)
{
if (client.currentScreen instanceof LambdaControlsControlsScreen && action == 0) {
LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen;
if (controls_screen.focused_binding != null) {
this.config.set_button_binding(controls_screen.focused_binding, button);
controls_screen.focused_binding = null;
return;
}
}
if (action == 0 || action == 2) {
// Handles RB and LB buttons.
if (button == GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER || button == GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER) {
this.handle_rb_lb(client, button == GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER);
return;
}
if (client.currentScreen != null && is_screen_interactive(client.currentScreen)
&& (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN
|| button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)) {
if (this.action_gui_cooldown == 0) {
if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP) {
this.change_focus(client.currentScreen, false);
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) {
this.change_focus(client.currentScreen, true);
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT) {
this.handle_left_right(client.currentScreen, false);
} else {
this.handle_left_right(client.currentScreen, true);
}
}
return;
}
}
if (action == 0) {
@@ -203,8 +239,8 @@ public class ControllerInput
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null) {
if (this.action_gui_cooldown == 0) {
Element focused = client.currentScreen.getFocused();
if (focused != null && this.is_screen_interactive(client.currentScreen)) {
if (this.handle_a_button(focused)) {
if (focused != null && is_screen_interactive(client.currentScreen)) {
if (this.handle_a_button(client.currentScreen, focused)) {
this.action_gui_cooldown = 5; // Prevent to press too quickly the focused element, so we have to skip 5 ticks.
return;
}
@@ -243,7 +279,7 @@ public class ControllerInput
}
}
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !this.is_screen_interactive(client.currentScreen) && this.action_gui_cooldown == 0 && this.ignore_next_a == 0) {
if (button == GLFW.GLFW_GAMEPAD_BUTTON_A && client.currentScreen != null && !is_screen_interactive(client.currentScreen) && this.action_gui_cooldown == 0 && this.ignore_next_a == 0) {
double mouse_x = client.mouse.getX() * (double) client.window.getScaledWidth() / (double) client.window.getWidth();
double mouse_y = client.mouse.getY() * (double) client.window.getScaledHeight() / (double) client.window.getHeight();
if (action == 0) {
@@ -256,24 +292,35 @@ public class ControllerInput
}
if (client.currentScreen == null && action != 2) {
ButtonBinding.handle_button(button, state);
ButtonBinding.handle_button(client, button, action);
}
}
private void handle_axe(@NotNull MinecraftClient client, int axis, float value, float abs_value, int state)
{
int as_button_state = value > 0.5F ? 1 : (value < -0.5F ? 2 : 0);
if (client.currentScreen instanceof LambdaControlsControlsScreen && as_button_state != 0
&& !(as_button_state == 2 && (axis == GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER))) {
LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen;
if (controls_screen.focused_binding != null) {
this.config.set_button_binding(controls_screen.focused_binding, axis_as_button(axis, as_button_state == 1));
controls_screen.focused_binding = null;
return;
}
}
double dead_zone = this.config.get_dead_zone();
if (client.currentScreen == null) {
{
int axis_minus = axis + 10;
int axis_minus = axis + 100;
boolean current_plus_state = as_button_state == 1;
boolean current_minus_state = as_button_state == 2;
boolean previous_plus_state = AXIS_STATES.getOrDefault(axis, false);
boolean previous_minus_state = AXIS_STATES.getOrDefault(axis_minus, false);
if (current_plus_state != previous_plus_state) {
this.config.get_keybind("axis_" + axis + "+").ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(current_plus_state));
ButtonBinding.handle_button(client, ButtonBinding.axis_as_button(axis, true), 0);
if (current_plus_state)
AXIS_COOLDOWNS.put(axis, 5);
} else if (current_plus_state) {
@@ -283,7 +330,7 @@ public class ControllerInput
}
if (current_minus_state != previous_minus_state) {
this.config.get_keybind("axis_" + axis + "-").ifPresent(key_binding -> ((KeyBindingAccessor) key_binding).handle_press_state(current_minus_state));
ButtonBinding.handle_button(client, ButtonBinding.axis_as_button(axis, false), 0);
if (current_minus_state)
AXIS_COOLDOWNS.put(axis_minus, 5);
} else if (current_minus_state) {
@@ -298,27 +345,28 @@ public class ControllerInput
// Handles the look direction.
if (client.player != null) {
double pow_value = Math.pow(abs_value, 2.0);
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
if (state == 2) {
this.target_pitch = client.player.pitch - this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * (abs_value + dead_zone) / (1.0 - dead_zone)) * 0.33D;
this.target_pitch = client.player.pitch - this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
this.target_pitch = MathHelper.clamp(this.target_pitch, -90.0D, 90.0D);
} else if (state == 1) {
this.target_pitch = client.player.pitch + this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * (abs_value - dead_zone) / (1.0 - dead_zone)) * 0.33D;
this.target_pitch = client.player.pitch + this.config.get_right_y_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
this.target_pitch = MathHelper.clamp(this.target_pitch, -90.0D, 90.0D);
}
}
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_X) {
if (state == 2) {
this.target_yaw = client.player.yaw - this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * (abs_value + dead_zone) / (1.0 - dead_zone)) * 0.33D;
this.target_yaw = client.player.yaw - this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
} else if (state == 1) {
this.target_yaw = client.player.yaw + this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * (abs_value + dead_zone) / (1.0 - dead_zone)) * 0.33D;
this.target_yaw = client.player.yaw + this.config.get_right_x_axis_sign() * (this.config.get_rotation_speed() * pow_value) * 0.33D;
}
}
}
} else {
boolean allow_mouse_control = true;
if (this.action_gui_cooldown == 0 && this.config.is_movement_axis(axis) && this.is_screen_interactive(client.currentScreen)) {
if (this.action_gui_cooldown == 0 && this.config.is_movement_axis(axis) && is_screen_interactive(client.currentScreen)) {
if (this.config.is_forward_button(axis, false, as_button_state)) {
allow_mouse_control = this.change_focus(client.currentScreen, false);
} else if (this.config.is_back_button(axis, false, as_button_state)) {
@@ -412,7 +460,7 @@ public class ControllerInput
}
}
private boolean handle_a_button(@NotNull Element focused)
private boolean handle_a_button(@NotNull Screen screen, @NotNull Element focused)
{
if (focused instanceof AbstractPressableButtonWidget) {
AbstractPressableButtonWidget button_widget = (AbstractPressableButtonWidget) focused;
@@ -423,10 +471,17 @@ public class ControllerInput
WorldListWidget list = (WorldListWidget) focused;
list.method_20159().ifPresent(WorldListWidget.LevelItem::play);
return true;
} else if (focused instanceof MultiplayerServerListWidget) {
MultiplayerServerListWidget list = (MultiplayerServerListWidget) focused;
MultiplayerServerListWidget.Entry entry = list.getSelected();
if (entry instanceof MultiplayerServerListWidget.LanServerListEntry || entry instanceof MultiplayerServerListWidget.ServerItem) {
((MultiplayerScreen) screen).selectEntry(entry);
((MultiplayerScreen) screen).connect();
}
} else if (focused instanceof ParentElement) {
Element child_focused = ((ParentElement) focused).getFocused();
if (child_focused != null)
return this.handle_a_button(child_focused);
return this.handle_a_button(screen, child_focused);
}
return false;
}
@@ -452,6 +507,9 @@ public class ControllerInput
slider.keyPressed(right ? 262 : 263, 0, 0);
this.action_gui_cooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks.
return false;
} else if (element instanceof AlwaysSelectedEntryListWidget) {
((EntryListWidgetAccessor) element).move_selection(right ? 1 : -1);
return false;
} else if (element instanceof ParentElement) {
ParentElement entry_list = (ParentElement) element;
Element focused = entry_list.getFocused();
@@ -486,7 +544,7 @@ public class ControllerInput
}
}
private boolean is_screen_interactive(@NotNull Screen screen)
static boolean is_screen_interactive(@NotNull Screen screen)
{
return !(screen instanceof AdvancementsScreen || screen instanceof AbstractContainerScreen);
}

View File

@@ -22,7 +22,7 @@ import java.util.Optional;
public enum ControllerType implements Nameable
{
DEFAULT(0),
PLAYSTATION(1),
DUALSHOCK(1),
SWITCH(2),
XBOX(3),
STEAM(4),

View File

@@ -50,7 +50,6 @@ public class LambdaControls implements ClientModInitializer
{
Controller.update_mappings();
ButtonBinding.init(client.options);
this.config.init_keybindings(client.options);
GLFW.glfwSetJoystickCallback((jid, event) -> {
if (event == GLFW.GLFW_CONNECTED) {
Controller controller = Controller.by_id(jid);

View File

@@ -10,7 +10,6 @@
package me.lambdaurora.lambdacontrols;
import com.electronwill.nightconfig.core.file.FileConfig;
import net.minecraft.client.options.GameOptions;
import net.minecraft.client.options.KeyBinding;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
@@ -19,8 +18,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static org.lwjgl.glfw.GLFW.*;
/**
* Represents LambdaControls configuration.
*/
@@ -38,11 +35,6 @@ public class LambdaControlsConfig
private double dead_zone;
private double rotation_speed;
private double mouse_speed;
// Controller controls
private String back_button;
private String forward_button;
private String left_button;
private String right_button;
public LambdaControlsConfig(@NotNull LambdaControls mod)
{
@@ -64,29 +56,7 @@ public class LambdaControlsConfig
this.rotation_speed = this.config.getOrElse("controller.rotation_speed", 40.0);
this.mouse_speed = this.config.getOrElse("controller.mouse_speed", 25.0);
// Controller controls.
this.back_button = this.config.getOrElse("controller.controls.back", "none").toLowerCase();
this.forward_button = this.config.getOrElse("controller.controls.forward", "none").toLowerCase();
this.left_button = this.config.getOrElse("controller.controls.left", "none").toLowerCase();
this.right_button = this.config.getOrElse("controller.controls.right", "none").toLowerCase();
}
public void init_keybindings(GameOptions options)
{
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + "+", options.keyAttack);
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + "+", options.keyUse);
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_X + "+", options.keyRight);
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_X + "-", options.keyLeft);
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_Y + "+", options.keyBack);
this.keybinding_mappings.put("axis_" + GLFW_GAMEPAD_AXIS_LEFT_Y + "-", options.keyForward);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_A, options.keyJump);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_B, options.keyDrop);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_X, options.keySwapHands);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_Y, options.keyInventory);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_BACK, options.keyPlayerList);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_GUIDE, options.keyScreenshot);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, options.keySneak);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_LEFT_THUMB, options.keySprint);
this.keybinding_mappings.put("button_" + GLFW_GAMEPAD_BUTTON_DPAD_UP, options.keyTogglePerspective);
ButtonBinding.load_from_config(this);
}
public void save()
@@ -343,52 +313,54 @@ public class LambdaControlsConfig
return Optional.ofNullable(this.keybinding_mappings.get(id));
}
public String get_back_button()
/**
* Loads the button binding from configuration.
*
* @param button The button binding.
*/
public void load_button_binding(@NotNull ButtonBinding button)
{
return this.back_button;
button.set_button(this.config.getOrElse("controller.controls." + button.get_name(), button.get_button()));
}
public String get_forward_button()
/**
* Sets the button binding in configuration.
*
* @param binding The button binding.
* @param button The button.
*/
public void set_button_binding(@NotNull ButtonBinding binding, int button)
{
return this.forward_button;
}
public String get_left_button()
{
return this.left_button;
}
public String get_right_button()
{
return this.right_button;
binding.set_button(button);
this.config.set("controller.controls." + binding.get_name(), button);
}
public boolean is_back_button(int btn, boolean is_btn, int state)
{
if (!is_btn && state == 0)
return false;
return this.get_back_button().equals((is_btn ? "button_" : "axe_") + btn + (is_btn ? "" : (state == 1 ? "+" : "-")));
return ButtonBinding.BACK.is_button(ButtonBinding.axis_as_button(btn, state == 1));
}
public boolean is_forward_button(int btn, boolean is_btn, int state)
{
if (!is_btn && state == 0)
return false;
return this.get_forward_button().equals((is_btn ? "button_" : "axe_") + btn + (is_btn ? "" : (state == 1 ? "+" : "-")));
return ButtonBinding.FORWARD.is_button(ButtonBinding.axis_as_button(btn, state == 1));
}
public boolean is_left_button(int btn, boolean is_btn, int state)
{
if (!is_btn && state == 0)
return false;
return this.get_left_button().equals((is_btn ? "button_" : "axe_") + btn + (is_btn ? "" : (state == 1 ? "+" : "-")));
return ButtonBinding.LEFT.is_button(ButtonBinding.axis_as_button(btn, state == 1));
}
public boolean is_right_button(int btn, boolean is_btn, int state)
{
if (!is_btn && state == 0)
return false;
return this.get_right_button().equals((is_btn ? "button_" : "axe_") + btn + (is_btn ? "" : (state == 1 ? "+" : "-")));
return ButtonBinding.RIGHT.is_button(ButtonBinding.axis_as_button(btn, state == 1));
}
/**
@@ -399,7 +371,9 @@ public class LambdaControlsConfig
*/
public boolean is_movement_axis(int i)
{
return this.get_forward_button().startsWith("axe_" + i) || this.get_back_button().startsWith("axe_" + i) || this.get_left_button().startsWith("axe_" + i)
|| this.get_right_button().startsWith("axe_" + i);
return ButtonBinding.FORWARD.is_button(ButtonBinding.axis_as_button(i, true)) || ButtonBinding.FORWARD.is_button(ButtonBinding.axis_as_button(i, false))
|| ButtonBinding.BACK.is_button(ButtonBinding.axis_as_button(i, true)) || ButtonBinding.BACK.is_button(ButtonBinding.axis_as_button(i, false))
|| ButtonBinding.LEFT.is_button(ButtonBinding.axis_as_button(i, true)) || ButtonBinding.LEFT.is_button(ButtonBinding.axis_as_button(i, false))
|| ButtonBinding.RIGHT.is_button(ButtonBinding.axis_as_button(i, true)) || ButtonBinding.RIGHT.is_button(ButtonBinding.axis_as_button(i, false));
}
}

View File

@@ -0,0 +1,183 @@
/*
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.gui;
import me.lambdaurora.lambdacontrols.ButtonBinding;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ElementListWidget;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.util.Formatting;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Represents a control list widget.
*/
public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Entry>
{
private final LambdaControlsControlsScreen gui;
private int field_2733;
public ControlsListWidget(@NotNull LambdaControlsControlsScreen gui, @NotNull MinecraftClient client)
{
super(client, gui.width + 45, gui.height, 43, gui.height - 32, 20);
this.gui = gui;
ButtonBinding.stream_categories()
.sorted(Comparator.comparingInt(e -> e.getKey().get_value()))
.map(category -> Pair.of(category.getKey().get_key(), category.getValue()))
.forEach(category -> {
this.addEntry(new CategoryEntry(category.get_key()));
category.get_value().forEach(binding -> {
int i = client.textRenderer.getStringWidth(I18n.translate(binding.get_translation_key()));
if (i > this.field_2733) {
this.field_2733 = i;
}
this.addEntry(new ControlsListWidget.ButtonBindingEntry(binding));
});
});
}
@Override
protected int getScrollbarPosition()
{
return super.getScrollbarPosition() + 15;
}
@Override
public int getRowWidth()
{
return super.getRowWidth() + 32;
}
public class ButtonBindingEntry extends Entry
{
private final ButtonBinding binding;
private final String binding_name;
private final ButtonWidget edit_button;
private final ButtonWidget reset_button;
ButtonBindingEntry(@NotNull ButtonBinding binding)
{
this.binding = binding;
this.binding_name = I18n.translate(this.binding.get_translation_key());
this.edit_button = new ButtonWidget(0, 0, 75, 20, this.binding_name, btn -> gui.focused_binding = binding)
{
protected String getNarrationMessage()
{
return binding.is_not_bound() ? I18n.translate("narrator.controls.unbound", binding_name) : I18n.translate("narrator.controls.bound", binding_name, super.getNarrationMessage());
}
};
this.reset_button = new ButtonWidget(0, 0, 50, 20, I18n.translate("controls.reset"),
btn -> gui.mod.config.set_button_binding(binding, binding.get_default_button()))
{
protected String getNarrationMessage()
{
return I18n.translate("narrator.controls.reset", binding_name);
}
};
}
@Override
public List<? extends Element> children()
{
return Collections.unmodifiableList(Arrays.asList(this.edit_button, this.reset_button));
}
@Override
public void render(int index, int y, int x, int width, int height, int mouse_x, int mouse_y, boolean hovering, float delta)
{
boolean focused = gui.focused_binding == this.binding;
TextRenderer text_renderer = ControlsListWidget.this.minecraft.textRenderer;
String binding_name = this.binding_name;
float var10002 = (float) (x + 90 - ControlsListWidget.this.field_2733);
int var10003 = y + height / 2;
text_renderer.draw(binding_name, var10002, (float) (var10003 - 9 / 2), 16777215);
this.reset_button.x = x + 190;
this.reset_button.y = y;
this.reset_button.active = !this.binding.is_default();
this.reset_button.render(mouse_x, mouse_y, delta);
this.edit_button.x = x + 105;
this.edit_button.y = y;
this.edit_button.setMessage(ButtonBinding.get_localized_button_name(binding.get_button()));
if (focused) {
this.edit_button.setMessage(Formatting.WHITE + "> " + Formatting.YELLOW + this.edit_button.getMessage() + Formatting.WHITE + " <");
} else if (!this.binding.is_not_bound() && ButtonBinding.has_duplicates(this.binding.get_button())) {
this.edit_button.setMessage(Formatting.RED + this.edit_button.getMessage());
} else if (this.binding.is_not_bound()) {
this.edit_button.setMessage(Formatting.GOLD + edit_button.getMessage());
}
this.edit_button.render(mouse_x, mouse_y, delta);
}
public boolean mouseClicked(double mouseX, double mouseY, int button)
{
if (this.edit_button.mouseClicked(mouseX, mouseY, button))
return true;
else
return this.reset_button.mouseClicked(mouseX, mouseY, button);
}
public boolean mouseReleased(double mouseX, double mouseY, int button)
{
return this.edit_button.mouseReleased(mouseX, mouseY, button) || this.reset_button.mouseReleased(mouseX, mouseY, button);
}
}
public class CategoryEntry extends Entry
{
private final String name;
private final int name_width;
public CategoryEntry(String string)
{
this.name = I18n.translate(string);
this.name_width = ControlsListWidget.this.minecraft.textRenderer.getStringWidth(this.name);
}
@Override
public void render(int index, int y, int x, int width, int height, int mouse_x, int mouse_y, boolean hovering, float delta)
{
ControlsListWidget.this.minecraft.textRenderer.draw(this.name, (float) (ControlsListWidget.this.minecraft.currentScreen.width / 2 - this.name_width / 2),
(float) ((y + height) - 9 - 1), 16777215);
}
@Override
public boolean changeFocus(boolean bl)
{
return false;
}
@Override
public List<? extends Element> children()
{
return Collections.emptyList();
}
}
@Environment(EnvType.CLIENT)
public abstract static class Entry extends ElementListWidget.Entry<Entry>
{
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.gui;
import me.lambdaurora.lambdacontrols.ButtonBinding;
import me.lambdaurora.lambdacontrols.LambdaControls;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.options.BooleanOption;
import net.minecraft.client.options.Option;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.TranslatableText;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.function.Predicate;
/**
* Represents the controls screen.
*/
public class LambdaControlsControlsScreen extends Screen
{
private final LambdaControlsSettingsScreen parent;
final LambdaControls mod;
private final Option inverts_right_x_axis;
private final Option inverts_right_y_axis;
private ControlsListWidget bindings_list_widget;
private ButtonWidget reset_button;
public ButtonBinding focused_binding;
protected LambdaControlsControlsScreen(@NotNull LambdaControlsSettingsScreen parent)
{
super(new TranslatableText("lambdacontrols.menu.title.controller_controls"));
this.parent = parent;
this.mod = parent.mod;
this.inverts_right_x_axis = new BooleanOption("lambdacontrols.menu.invert_right_x_axis", game_options -> this.mod.config.does_invert_right_x_axis(),
(game_options, new_value) -> {
synchronized (this.mod.config) {
this.mod.config.set_invert_right_x_axis(new_value);
}
});
this.inverts_right_y_axis = new BooleanOption("lambdacontrols.menu.invert_right_y_axis", game_options -> this.mod.config.does_invert_right_y_axis(),
(game_options, new_value) -> {
synchronized (this.mod.config) {
this.mod.config.set_invert_right_y_axis(new_value);
}
});
}
@Override
public void removed()
{
this.mod.config.save();
super.removed();
}
@Override
protected void init()
{
this.addButton(this.inverts_right_x_axis.createButton(this.minecraft.options, this.width / 2 - 155, 18, 150));
this.addButton(this.inverts_right_y_axis.createButton(this.minecraft.options, this.width / 2 - 155 + 160, 18, 150));
this.bindings_list_widget = new ControlsListWidget(this, this.minecraft);
this.children.add(this.bindings_list_widget);
this.reset_button = this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 150, 20, I18n.translate("controls.resetAll"),
btn -> ButtonBinding.stream().forEach(binding -> this.mod.config.set_button_binding(binding, binding.get_default_button()))));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, I18n.translate("gui.done"),
btn -> this.minecraft.openScreen(this.parent)));
}
// Replacement for Predicate#not as it is Java 11.
private <T> Predicate<T> not(Predicate<T> target)
{
Objects.requireNonNull(target);
return target.negate();
}
@Override
public void render(int mouse_x, int mouse_y, float delta)
{
this.renderBackground();
this.bindings_list_widget.render(mouse_x, mouse_y, delta);
this.drawCenteredString(this.font, this.title.asFormattedString(), this.width / 2, 8, 16777215);
this.reset_button.active = ButtonBinding.stream().anyMatch(this.not(ButtonBinding::is_default));
super.render(mouse_x, mouse_y, delta);
}
}

View File

@@ -19,6 +19,7 @@ import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.options.*;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
@@ -27,7 +28,7 @@ import org.lwjgl.glfw.GLFW;
*/
public class LambdaControlsSettingsScreen extends Screen
{
private final LambdaControls mod;
final LambdaControls mod;
private final Screen parent;
private final GameOptions options;
private final Option controller_option;
@@ -37,8 +38,6 @@ public class LambdaControlsSettingsScreen extends Screen
private final Option dead_zone_option;
private final Option rotation_speed_option;
private final Option mouse_speed_option;
private final Option inverts_right_x_axis;
private final Option inverts_right_y_axis;
private ButtonListWidget list;
public LambdaControlsSettingsScreen(Screen parent, @NotNull GameOptions options)
@@ -53,7 +52,13 @@ public class LambdaControlsSettingsScreen extends Screen
if (current_id > GLFW.GLFW_JOYSTICK_LAST)
current_id = GLFW.GLFW_JOYSTICK_1;
this.mod.config.set_controller(Controller.by_id(current_id));
}, (game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_controller().get_name());
}, (game_options, option) -> {
String controller_name = this.mod.config.get_controller().get_name();
if (controller_name.equals(String.valueOf(this.mod.config.get_controller().get_id())))
return option.getDisplayPrefix() + Formatting.RED + controller_name;
else
return option.getDisplayPrefix() + controller_name;
});
this.controller_type_option = new CyclingOption("lambdacontrols.menu.controller_type",
(game_options, amount) -> this.mod.config.set_controller_type(this.mod.config.get_controller_type().next()),
(game_options, option) -> option.getDisplayPrefix() + this.mod.config.get_controller_type().get_translated_name());
@@ -83,18 +88,6 @@ public class LambdaControlsSettingsScreen extends Screen
this.mod.config.set_mouse_speed(new_value);
}
}, (game_options, option) -> option.getDisplayPrefix() + option.get(options));
this.inverts_right_x_axis = new BooleanOption("lambdacontrols.menu.invert_right_x_axis", game_options -> this.mod.config.does_invert_right_x_axis(),
(game_options, new_value) -> {
synchronized (this.mod.config) {
this.mod.config.set_invert_right_x_axis(new_value);
}
});
this.inverts_right_y_axis = new BooleanOption("lambdacontrols.menu.invert_right_y_axis", game_options -> this.mod.config.does_invert_right_y_axis(),
(game_options, new_value) -> {
synchronized (this.mod.config) {
this.mod.config.set_invert_right_y_axis(new_value);
}
});
}
@Override
@@ -129,14 +122,18 @@ public class LambdaControlsSettingsScreen extends Screen
this.mod.config.save();
}));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, button_height, I18n.translate("options.controls"),
btn -> this.minecraft.openScreen(new ControlsOptionsScreen(this, this.options))));
btn -> {
if (this.mod.config.get_controls_mode() == ControlsMode.CONTROLLER)
this.minecraft.openScreen(new LambdaControlsControlsScreen(this));
else
this.minecraft.openScreen(new ControlsOptionsScreen(this, this.options));
}));
this.list = new ButtonListWidget(this.minecraft, this.width, this.height, 43, this.height - 29 - this.get_text_height(), 25);
this.list.addSingleOptionEntry(this.controller_option);
this.list.addOptionEntry(this.controller_type_option, this.dead_zone_option);
this.list.addOptionEntry(this.hud_enable_option, this.hud_side_option);
this.list.addOptionEntry(this.rotation_speed_option, this.mouse_speed_option);
this.list.addOptionEntry(this.inverts_right_x_axis, this.inverts_right_y_axis);
this.children.add(this.list);
this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 300, button_height, I18n.translate("gui.done"),
@@ -144,14 +141,14 @@ public class LambdaControlsSettingsScreen extends Screen
}
@Override
public void render(int mouseX, int mouseY, float delta)
public void render(int mouse_x, int mouse_y, float delta)
{
this.renderBackground();
this.list.render(mouseX, mouseY, delta);
super.render(mouseX, mouseY, delta);
this.list.render(mouse_x, mouse_y, delta);
super.render(mouse_x, mouse_y, delta);
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215);
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.1"), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 3, 10526880);
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.2"), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 2, 10526880);
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.3"), this.width / 2, this.height - 29 - (5 + this.font.fontHeight), 10526880);
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.1", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 3, 10526880);
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.2", Formatting.GOLD.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.font.fontHeight) * 2, 10526880);
this.drawCenteredString(this.font, I18n.translate("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.font.fontHeight), 10526880);
}
}

View File

@@ -139,6 +139,7 @@ public class TouchscreenOverlay extends Screen
this.update_jump_buttons();
}
@Override
protected void init()
{
super.init();

View File

@@ -0,0 +1,21 @@
/*
* Copyright © 2019 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.mixin;
import net.minecraft.client.gui.widget.EntryListWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(EntryListWidget.class)
public interface EntryListWidgetAccessor
{
@Invoker("moveSelection")
void move_selection(int amount);
}