Files
MidnightControls/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java
2020-01-01 01:54:14 +01:00

305 lines
12 KiB
Java

/*
* Copyright © 2020 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;
import com.mojang.blaze3d.platform.GlStateManager;
import me.lambdaurora.lambdacontrols.compat.LambdaControlsCompat;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.controller.Controller;
import me.lambdaurora.lambdacontrols.gui.LambdaControlsHud;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.client.util.InputUtil;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
/**
* Represents the LambdaControls mod.
*
* @author LambdAurora
* @version 1.1.0
* @since 1.0.0
*/
public class LambdaControls implements ClientModInitializer
{
private static LambdaControls INSTANCE;
public static final String MODID = "lambdacontrols";
public static final FabricKeyBinding BINDING_LOOK_UP = FabricKeyBinding.Builder.create(new Identifier(MODID, "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(MODID, "look_right"),
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_6, "key.categories.movement").build();
public static final FabricKeyBinding BINDING_LOOK_DOWN = FabricKeyBinding.Builder.create(new Identifier(MODID, "look_down"),
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_2, "key.categories.movement").build();
public static final FabricKeyBinding BINDING_LOOK_LEFT = FabricKeyBinding.Builder.create(new Identifier(MODID, "look_left"),
InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_KP_4, "key.categories.movement").build();
public static final Identifier CONTROLLER_BUTTONS = new Identifier(MODID, "textures/gui/controller_buttons.png");
public static final Identifier CONTROLLER_AXIS = new Identifier(MODID, "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 LambdaControlsHud hud;
private ControlsMode previous_controls_mode;
@Override
public void onInitializeClient()
{
INSTANCE = this;
this.log("Initializing LambdaControls...");
KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_UP);
KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_RIGHT);
KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_DOWN);
KeyBindingRegistry.INSTANCE.register(BINDING_LOOK_LEFT);
HudRenderCallback.EVENT.register(delta -> this.hud.render());
}
/**
* This method is called when Minecraft is initializing.
*/
public void on_mc_init(@NotNull MinecraftClient client)
{
ButtonBinding.init(client.options);
this.config.load();
Controller.update_mappings();
GLFW.glfwSetJoystickCallback((jid, event) -> {
if (event == GLFW.GLFW_CONNECTED) {
Controller controller = Controller.by_id(jid);
client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.connected", jid),
new LiteralText(controller.get_name())));
} else if (event == GLFW.GLFW_DISCONNECTED) {
client.getToastManager().add(new SystemToast(SystemToast.Type.TUTORIAL_HINT, new TranslatableText("lambdacontrols.controller.disconnected", jid),
null));
}
this.switch_controls_mode();
});
this.hud = new LambdaControlsHud(client, this);
LambdaControlsCompat.init();
}
/**
* This method is called every Minecraft tick.
*
* @param client The client instance.
*/
public void on_tick(@NotNull MinecraftClient client)
{
this.input.on_tick(client);
if (this.config.get_controls_mode() == ControlsMode.CONTROLLER)
this.input.on_controller_tick(client);
}
public void on_render(MinecraftClient client)
{
this.input.on_render(client);
}
/**
* Switches the controls mode if the auto switch is enabled.
*/
public void switch_controls_mode()
{
if (this.config.has_auto_switch_mode()) {
if (this.config.get_controller().is_gamepad()) {
this.previous_controls_mode = this.config.get_controls_mode();
this.config.set_controls_mode(ControlsMode.CONTROLLER);
} else {
if (this.previous_controls_mode == null) {
this.previous_controls_mode = ControlsMode.DEFAULT;
}
this.config.set_controls_mode(this.previous_controls_mode);
}
}
}
/**
* Prints a message to the terminal.
*
* @param info The message to print.
*/
public void log(String info)
{
this.logger.info("[LambdaControls] " + info);
}
/**
* Prints a warning to the terminal.
*
* @param warning The warning to print.
*/
public void warn(String warning)
{
this.logger.info("[LambdaControls] " + warning);
}
/**
* Gets the LambdaControls instance.
*
* @return The LambdaControls instance.
*/
public static LambdaControls get()
{
return INSTANCE;
}
public static Pair<Integer, Integer> draw_button(int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client)
{
return draw_button(x, y, button.get_button(), client);
}
public static Pair<Integer, Integer> draw_button(int x, int y, int[] buttons, @NotNull MinecraftClient client)
{
int height = 0;
int length = 0;
int current_x = x;
for (int i = 0; i < buttons.length; i++) {
int btn = buttons[i];
Pair<Integer, Integer> size = draw_button(current_x, y, btn, client);
if (size.get_key() > height)
height = size.get_value();
length += size.get_key();
if (i + 1 < buttons.length) {
length += 2;
current_x = x + length;
}
}
return Pair.of(length, height);
}
public static Pair<Integer, Integer> draw_button(int x, int y, int button, @NotNull MinecraftClient client)
{
boolean second = false;
if (button == -1)
return Pair.of(0, 0);
else if (button >= 500) {
button -= 1000;
second = true;
}
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, second ? 0.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 ? Pair.of(18, 18) : Pair.of(15, 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);
}
public static int draw_button_tip(int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client)
{
if (display) {
int button_width = draw_button(x, y, button, client).get_key();
String translated_action = I18n.translate(action);
int text_y = (15 - client.textRenderer.fontHeight) / 2;
client.textRenderer.drawWithShadow(translated_action, (float) (x + button_width + 5), (float) (y + text_y), 14737632);
return get_button_tip_width(translated_action, client.textRenderer);
}
return -10;
}
private static int get_button_tip_width(@NotNull String action, @NotNull TextRenderer text_renderer)
{
return 15 + 5 + text_renderer.getStringWidth(action);
}
}