diff --git a/.gitignore b/.gitignore index cfe83db..1d48d5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # # LambdAurora's ignore file # -# v0.11 +# v0.12 # JetBrains .idea/ @@ -58,6 +58,7 @@ desktop.ini *.dylib *.lib lib*.a +*.png~ # Common bin/ diff --git a/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java b/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java index 4edf4a9..e8e9609 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java @@ -32,8 +32,8 @@ import org.lwjgl.glfw.GLFW; */ public class LambdaControls implements ClientModInitializer { - private static LambdaControls INSTANCE; - public static final FabricKeyBinding BINDING_LOOK_UP = FabricKeyBinding.Builder.create(new Identifier("lambdacontrols", "look_up"), + private static LambdaControls INSTANCE; + public static final FabricKeyBinding BINDING_LOOK_UP = FabricKeyBinding.Builder.create(new Identifier("lambdacontrols", "look_up"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_8, "key.categories.movement").build(); public static final FabricKeyBinding BINDING_LOOK_RIGHT = FabricKeyBinding.Builder.create(new Identifier("lambdacontrols", "look_right"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_6, "key.categories.movement").build(); @@ -42,10 +42,11 @@ public class LambdaControls implements ClientModInitializer public static final FabricKeyBinding BINDING_LOOK_LEFT = FabricKeyBinding.Builder.create(new Identifier("lambdacontrols", "look_left"), InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement").build(); public static final Identifier CONTROLLER_BUTTONS = new Identifier("lambdacontrols", "textures/gui/controller_buttons.png"); + public static final Identifier CONTROLLER_AXIS = new Identifier("lambdacontrols", "textures/gui/controller_axis.png"); public final Logger logger = LogManager.getLogger("LambdaControls"); - public final LambdaControlsConfig config = new LambdaControlsConfig(this); - public final LambdaInput input = new LambdaInput(this); - private ControlsMode previous_controls_mode; + public final LambdaControlsConfig config = new LambdaControlsConfig(this); + public final LambdaInput input = new LambdaInput(this); + private ControlsMode previous_controls_mode; @Override public void onInitializeClient() @@ -137,6 +138,93 @@ public class LambdaControls implements ClientModInitializer return INSTANCE; } + public static int draw_button(int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client) + { + return draw_button(x, y, button.get_button(), client); + } + + public static int draw_button(int x, int y, int button, @NotNull MinecraftClient client) + { + if (button == -1) + return 0; + + int controller_type = get().config.get_controller_type().get_id(); + boolean axis = false; + int button_offset = button * 15; + switch (button) { + case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: + button_offset = 7 * 15; + break; + case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: + button_offset = 8 * 15; + break; + case GLFW.GLFW_GAMEPAD_BUTTON_BACK: + button_offset = 4 * 15; + break; + case GLFW.GLFW_GAMEPAD_BUTTON_START: + button_offset = 6 * 15; + break; + case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE: + button_offset = 5 * 15; + break; + case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB: + button_offset = 15 * 15; + break; + case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: + button_offset = 16 * 15; + break; + case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100: + button_offset = 0; + axis = true; + break; + case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100: + button_offset = 18; + axis = true; + break; + case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100: + button_offset = 2 * 18; + axis = true; + break; + case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100: + button_offset = 3 * 18; + axis = true; + break; + case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200: + button_offset = 4 * 18; + axis = true; + break; + case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200: + button_offset = 5 * 18; + axis = true; + break; + case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200: + button_offset = 6 * 18; + axis = true; + break; + case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200: + button_offset = 7 * 18; + axis = true; + break; + case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100: + case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200: + button_offset = 9 * 15; + break; + case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100: + case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200: + button_offset = 10 * 15; + break; + } + + client.getTextureManager().bindTexture(axis ? LambdaControls.CONTROLLER_AXIS : LambdaControls.CONTROLLER_BUTTONS); + GlStateManager.disableDepthTest(); + + GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); + DrawableHelper.blit(x, y, (float) button_offset, (float) (controller_type * (axis ? 18 : 15)), axis ? 18 : 15, axis ? 18 : 15, 256, 256); + GlStateManager.enableDepthTest(); + + return axis ? 18 : 15; + } + public static int draw_button_tip(int x, int y, @NotNull ButtonBinding button, boolean display, @NotNull MinecraftClient client) { return draw_button_tip(x, y, button.get_button(), button.get_translation_key(), display, client); @@ -144,37 +232,13 @@ public class LambdaControls implements ClientModInitializer public static int draw_button_tip(int x, int y, int button, @NotNull String action, boolean display, @NotNull MinecraftClient client) { - int controller_type = get().config.get_controller_type().get_id(); String translated_action = I18n.translate(action); if (display) { - int button_offset = button * 15; - switch (button) { - case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB: - button_offset = 15 * 15; - break; - case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: - button_offset = 16 * 15; - break; - case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100: - case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200: - button_offset = 9 * 15; - break; - case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100: - case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200: - button_offset = 10 * 15; - break; - } - - client.getTextureManager().bindTexture(LambdaControls.CONTROLLER_BUTTONS); - GlStateManager.disableDepthTest(); - - GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); - DrawableHelper.blit(x, y, (float) button_offset, (float) (controller_type * 15), 15, 15, 256, 256); - GlStateManager.enableDepthTest(); + int button_width = draw_button(x, y, button, client); int text_y = (15 - client.textRenderer.fontHeight) / 2; - client.textRenderer.drawWithShadow(translated_action, (float) (x + 15 + 5), (float) (y + text_y), 14737632); + client.textRenderer.drawWithShadow(translated_action, (float) (x + button_width + 5), (float) (y + text_y), 14737632); } return display ? get_button_tip_width(translated_action, client.textRenderer) : -10; diff --git a/src/main/java/me/lambdaurora/lambdacontrols/gui/AbstractIconButtonWidget.java b/src/main/java/me/lambdaurora/lambdacontrols/gui/AbstractIconButtonWidget.java new file mode 100644 index 0000000..65c35cb --- /dev/null +++ b/src/main/java/me/lambdaurora/lambdacontrols/gui/AbstractIconButtonWidget.java @@ -0,0 +1,55 @@ +/* + * Copyright © 2019 LambdAurora + * + * This file is part of LambdaControls. + * + * Licensed under the MIT license. For more information, + * see the LICENSE file. + */ + +package me.lambdaurora.lambdacontrols.gui; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.util.math.MathHelper; +import org.jetbrains.annotations.NotNull; + +/** + * Represents a button with an icon instead of text. + */ +public abstract class AbstractIconButtonWidget extends ButtonWidget +{ + private int icon_size = 0; + + public AbstractIconButtonWidget(int x, int y, int width, int height, @NotNull String message, @NotNull PressAction on_press) + { + super(x, y, width, height, message, on_press); + } + + protected abstract int render_icon(int mouse_x, int mouse_y, float delta, int x, int y); + + @Override + public void renderButton(int mouse_x, int mouse_y, float delta) + { + MinecraftClient client = MinecraftClient.getInstance(); + client.getTextureManager().bindTexture(WIDGETS_LOCATION); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha); + int i = this.getYImage(this.isHovered()); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA); + this.blit(this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height); + this.blit(this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height); + this.renderBg(client, mouse_x, mouse_y); + + this.icon_size = this.render_icon(mouse_x, mouse_y, delta, this.x + 4, this.y + (this.height / 2 - this.icon_size / 2)); + + if (!this.getMessage().isEmpty()) { + int j = this.active ? 16777215 : 10526880; + this.drawCenteredString(client.textRenderer, this.getMessage(), this.x + 8 + this.icon_size + (this.width - 8 - this.icon_size - 6) / 2, + this.y + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24); + } + } +} diff --git a/src/main/java/me/lambdaurora/lambdacontrols/gui/ControllerButtonWidget.java b/src/main/java/me/lambdaurora/lambdacontrols/gui/ControllerButtonWidget.java new file mode 100644 index 0000000..206c5d2 --- /dev/null +++ b/src/main/java/me/lambdaurora/lambdacontrols/gui/ControllerButtonWidget.java @@ -0,0 +1,40 @@ +/* + * Copyright © 2019 LambdAurora + * + * 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.MinecraftClient; +import org.jetbrains.annotations.NotNull; + +/** + * Represents a controller button widget. + */ +public class ControllerButtonWidget extends AbstractIconButtonWidget +{ + private ButtonBinding binding; + + public ControllerButtonWidget(int x, int y, int width, @NotNull ButtonBinding button_binding, @NotNull PressAction on_press) + { + super(x, y, width, 20, ButtonBinding.get_localized_button_name(button_binding.get_button()), on_press); + this.binding = button_binding; + } + + public void update() + { + this.setMessage(ButtonBinding.get_localized_button_name(binding.get_button())); + } + + @Override + protected int render_icon(int mouse_x, int mouse_y, float delta, int x, int y) + { + return LambdaControls.draw_button(x, y, this.binding, MinecraftClient.getInstance()); + } +} diff --git a/src/main/java/me/lambdaurora/lambdacontrols/gui/ControlsListWidget.java b/src/main/java/me/lambdaurora/lambdacontrols/gui/ControlsListWidget.java index 309e28e..2ba5dc5 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/gui/ControlsListWidget.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/gui/ControlsListWidget.java @@ -36,7 +36,7 @@ public class ControlsListWidget extends ElementListWidget gui.focused_binding = binding) + this.edit_button = new ControllerButtonWidget(0, 0, 90, this.binding, btn -> gui.focused_binding = binding) { protected String getNarrationMessage() { @@ -107,16 +107,16 @@ public class ControlsListWidget extends ElementListWidget " + Formatting.YELLOW + this.edit_button.getMessage() + Formatting.WHITE + " <"); diff --git a/src/main/java/me/lambdaurora/lambdacontrols/mixin/SettingsScreenMixin.java b/src/main/java/me/lambdaurora/lambdacontrols/mixin/SettingsScreenMixin.java index c614eb5..1a7020e 100644 --- a/src/main/java/me/lambdaurora/lambdacontrols/mixin/SettingsScreenMixin.java +++ b/src/main/java/me/lambdaurora/lambdacontrols/mixin/SettingsScreenMixin.java @@ -12,6 +12,7 @@ package me.lambdaurora.lambdacontrols.mixin; import me.lambdaurora.lambdacontrols.gui.LambdaControlsSettingsScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.SettingsScreen; +import net.minecraft.client.gui.widget.AbstractButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.options.GameOptions; import net.minecraft.client.resource.language.I18n; @@ -21,6 +22,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** @@ -38,16 +40,10 @@ public class SettingsScreenMixin extends Screen super(title); } - @Inject(method = "init", at = @At("RETURN")) - private void on_init(CallbackInfo ci) + @Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/SettingsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 7)) + private AbstractButtonWidget on_init(SettingsScreen screen, AbstractButtonWidget btn) { - this.buttons.stream().filter(button -> button.getMessage().equals(I18n.translate("options.controls"))) - .findFirst() - .ifPresent(btn -> { - this.buttons.remove(btn); - this.children.remove(btn); - this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).get_height(), btn.getMessage(), - b -> this.minecraft.openScreen(new LambdaControlsSettingsScreen(this, this.settings)))); - }); + return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).get_height(), btn.getMessage(), + b -> this.minecraft.openScreen(new LambdaControlsSettingsScreen(this, this.settings)))); } } diff --git a/src/main/resources/assets/lambdacontrols/textures/gui/controller_axis.png b/src/main/resources/assets/lambdacontrols/textures/gui/controller_axis.png new file mode 100644 index 0000000..ccc6a59 Binary files /dev/null and b/src/main/resources/assets/lambdacontrols/textures/gui/controller_axis.png differ diff --git a/src/main/resources/assets/lambdacontrols/textures/gui/widgets.png b/src/main/resources/assets/lambdacontrols/textures/gui/widgets.png index f684d6a..b4e48ad 100644 Binary files a/src/main/resources/assets/lambdacontrols/textures/gui/widgets.png and b/src/main/resources/assets/lambdacontrols/textures/gui/widgets.png differ