├── gradlew ├── src └── main │ ├── resources │ ├── pack.png │ ├── pack.mcmeta │ ├── assets │ │ └── controllermod │ │ │ ├── textures │ │ │ └── gui │ │ │ │ ├── toasts.png │ │ │ │ ├── pointer.png │ │ │ │ ├── controller_icon.png │ │ │ │ ├── controller_icon2.png │ │ │ │ ├── controller_button.png │ │ │ │ └── controllers │ │ │ │ ├── xbox_dpad.png │ │ │ │ ├── ps4_dpad_up.png │ │ │ │ ├── ps4_touchpad.png │ │ │ │ ├── xbox_dpad_up.png │ │ │ │ ├── ps3_stick_left.png │ │ │ │ ├── ps4_dpad_down.png │ │ │ │ ├── ps4_dpad_left.png │ │ │ │ ├── ps4_dpad_right.png │ │ │ │ ├── ps4_stick_left.png │ │ │ │ ├── switch_dpad_up.png │ │ │ │ ├── wii_u_pro_dpad.png │ │ │ │ ├── xbox_dpad_down.png │ │ │ │ ├── xbox_dpad_left.png │ │ │ │ ├── ps3_stick_right.png │ │ │ │ ├── ps4_bumper_left.png │ │ │ │ ├── ps4_bumper_right.png │ │ │ │ ├── ps4_left_trigger.png │ │ │ │ ├── ps4_right_trigger.png │ │ │ │ ├── ps4_select_button.png │ │ │ │ ├── ps4_start_button.png │ │ │ │ ├── ps4_stick_left_up.png │ │ │ │ ├── ps4_stick_right.png │ │ │ │ ├── switch_dpad_down.png │ │ │ │ ├── switch_dpad_left.png │ │ │ │ ├── switch_dpad_right.png │ │ │ │ ├── switch_sl_button.png │ │ │ │ ├── switch_sr_button.png │ │ │ │ ├── switch_stick_left.png │ │ │ │ ├── wii_u_pro_dpad_up.png │ │ │ │ ├── xbox_bumper_left.png │ │ │ │ ├── xbox_bumper_right.png │ │ │ │ ├── xbox_dpad_right.png │ │ │ │ ├── xbox_left_trigger.png │ │ │ │ ├── xbox_start_button.png │ │ │ │ ├── xbox_stick_left.png │ │ │ │ ├── xbox_stick_right.png │ │ │ │ ├── ps4_face_button_up.png │ │ │ │ ├── ps4_stick_left_down.png │ │ │ │ ├── ps4_stick_left_left.png │ │ │ │ ├── ps4_stick_right_up.png │ │ │ │ ├── switch_bumper_left.png │ │ │ │ ├── switch_bumper_right.png │ │ │ │ ├── switch_home_button.png │ │ │ │ ├── switch_left_trigger.png │ │ │ │ ├── switch_start_button.png │ │ │ │ ├── switch_stick_right.png │ │ │ │ ├── wii_u_pro_dpad_down.png │ │ │ │ ├── wii_u_pro_dpad_left.png │ │ │ │ ├── xbox_face_button_up.png │ │ │ │ ├── xbox_right_trigger.png │ │ │ │ ├── xbox_select_button.png │ │ │ │ ├── ps4_face_button_down.png │ │ │ │ ├── ps4_face_button_left.png │ │ │ │ ├── ps4_face_button_right.png │ │ │ │ ├── ps4_stick_left_right.png │ │ │ │ ├── ps4_stick_right_down.png │ │ │ │ ├── ps4_stick_right_left.png │ │ │ │ ├── ps4_stick_right_right.png │ │ │ │ ├── switch_circle_button.png │ │ │ │ ├── switch_face_button_up.png │ │ │ │ ├── switch_right_trigger.png │ │ │ │ ├── switch_select_button.png │ │ │ │ ├── switch_stick_left_down.png │ │ │ │ ├── switch_stick_left_left.png │ │ │ │ ├── switch_stick_left_up.png │ │ │ │ ├── switch_stick_right_up.png │ │ │ │ ├── wii_u_pro_dpad_right.png │ │ │ │ ├── wii_u_pro_guide_button.png │ │ │ │ ├── xbox_face_button_down.png │ │ │ │ ├── xbox_face_button_left.png │ │ │ │ ├── xbox_face_button_right.png │ │ │ │ ├── ps4_share_options_button.png │ │ │ │ ├── ps4_stick_left_vertical.png │ │ │ │ ├── ps4_stick_right_vertical.png │ │ │ │ ├── switch_face_button_down.png │ │ │ │ ├── switch_face_button_left.png │ │ │ │ ├── switch_face_button_right.png │ │ │ │ ├── switch_stick_left_right.png │ │ │ │ ├── switch_stick_right_down.png │ │ │ │ ├── switch_stick_right_left.png │ │ │ │ ├── switch_stick_right_right.png │ │ │ │ ├── ps4_stick_left_horizontal.png │ │ │ │ ├── ps4_stick_right_horizontal.png │ │ │ │ ├── switch_stick_left_vertical.png │ │ │ │ ├── switch_stick_right_vertical.png │ │ │ │ ├── switch_stick_left_horizontal.png │ │ │ │ └── switch_stick_right_horizontal.png │ │ │ ├── controllermodels │ │ │ ├── ps4_linux.json │ │ │ └── nintendo_wii_u_pro.json │ │ │ └── lang │ │ │ └── en_us.json │ ├── controllermod.mixins.json │ └── META-INF │ │ ├── mods.toml │ │ └── accesstransformer.cfg │ └── java │ └── com │ └── stereowalker │ └── controllermod │ ├── client │ ├── controller │ │ ├── UseCase.java │ │ ├── ControllerBindings.java │ │ ├── ControllerMap.java │ │ └── Controller.java │ ├── gui │ │ ├── screen │ │ │ ├── TriggerSetupScreen.java │ │ │ ├── PaperDollOptionsScreen.java │ │ │ ├── ControllerSettingsScreen.java │ │ │ └── ControllerInputOptionsScreen.java │ │ ├── toasts │ │ │ └── ControllerStatusToast.java │ │ └── widget │ │ │ └── list │ │ │ ├── TriggerAxesList.java │ │ │ └── ControllerBindingList.java │ ├── ControllerHandler.java │ ├── OnScreenKeyboard.java │ ├── PaperDollOptions.java │ └── VirtualMouseHelper.java │ ├── mixin │ ├── TitleScreenMixin.java │ ├── AbstractContainerScreenMixin.java │ ├── KeyboardInputMixin.java │ ├── GameRendererMixin.java │ ├── ControlsScreenMixin.java │ ├── ScreenMixin.java │ ├── GuiMixin.java │ └── MinecraftMixin.java │ ├── config │ └── Config.java │ ├── resources │ └── ControllerModelManager.java │ └── ControllerMod.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .factorypath ├── .gitignore ├── gradle.properties ├── changelog.md ├── .github └── workflows │ └── gradle.yml ├── gradlew.bat └── LICENSE.txt /gradlew: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/gradlew -------------------------------------------------------------------------------- /src/main/resources/pack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/pack.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "pack_format": 4, 4 | "description": "Controller Mod resources" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/toasts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/toasts.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/pointer.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controller_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controller_icon.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controller_icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controller_icon2.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controller_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controller_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad.png -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/controller/UseCase.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.controller; 2 | 3 | public enum UseCase { 4 | CONTAINER, ANY_SCREEN, INGAME, KEYBOARD, ANYWHERE; 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_dpad_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_dpad_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_touchpad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_touchpad.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps3_stick_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps3_stick_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_dpad_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_dpad_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_dpad_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_dpad_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_dpad_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_dpad_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_dpad_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_dpad_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps3_stick_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps3_stick_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_bumper_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_bumper_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_bumper_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_bumper_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_left_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_left_trigger.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_right_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_right_trigger.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_select_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_select_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_start_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_start_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_dpad_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_dpad_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_dpad_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_dpad_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_dpad_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_dpad_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_sl_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_sl_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_sr_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_sr_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_bumper_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_bumper_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_bumper_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_bumper_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_dpad_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_left_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_left_trigger.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_start_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_start_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_stick_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_stick_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_stick_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_stick_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_face_button_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_face_button_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_bumper_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_bumper_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_bumper_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_bumper_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_home_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_home_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_left_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_left_trigger.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_start_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_start_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_face_button_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_face_button_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_right_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_right_trigger.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_select_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_select_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_face_button_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_face_button_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_face_button_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_face_button_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_face_button_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_face_button_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_circle_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_circle_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_face_button_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_face_button_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_right_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_right_trigger.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_select_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_select_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_up.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_dpad_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_guide_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/wii_u_pro_guide_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_face_button_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_face_button_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_face_button_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_face_button_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/xbox_face_button_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/xbox_face_button_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_share_options_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_share_options_button.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_vertical.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_vertical.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_face_button_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_face_button_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_face_button_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_face_button_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_face_button_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_face_button_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_right.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_down.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_left.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_right.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_left_horizontal.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/ps4_stick_right_horizontal.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_vertical.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_vertical.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_left_horizontal.png -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/HEAD/src/main/resources/assets/controllermod/textures/gui/controllers/switch_stick_right_horizontal.png -------------------------------------------------------------------------------- /.factorypath: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.war 15 | *.nar 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | .classpath 24 | .gradle/ 25 | .metadata/ 26 | .project 27 | .settings/ 28 | bin/ 29 | build/ 30 | CREDITS.txt 31 | run/ 32 | *.launch 33 | /Java Projects/ 34 | -------------------------------------------------------------------------------- /src/main/resources/controllermod.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "com.stereowalker.controllermod.mixin", 4 | "compatibilityLevel": "JAVA_17", 5 | "refmap": "controllermod.refmap.json", 6 | "mixins": [ 7 | ], 8 | "client": [ 9 | "TitleScreenMixin", 10 | "AbstractContainerScreenMixin", 11 | "GuiMixin", 12 | "MinecraftMixin", 13 | "ScreenMixin", 14 | "ControlsScreenMixin", 15 | "KeyboardInputMixin", 16 | "GameRendererMixin" 17 | ], 18 | "injectors": { 19 | "defaultRequire": 1 20 | } 21 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | org.gradle.daemon=false 5 | 6 | modLoader = Forge 7 | modMinecraftVersion = 1.18.2 8 | modLoaderVersion = 40.1.52 9 | mappingsChannel = parchment 10 | mappingsVersion = 2022.03.13-1.18.2 11 | modMixinVersion = 0.8.5 12 | unionLibVersion = 7.2.3 13 | 14 | modVersion = 7.1.0 15 | modId = controllermod 16 | modGroup = com.stereowalker.controllermod 17 | modFilename = Controller Support 18 | modCurseId = 358633 -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | [7.1.0] 2 | - Fix config values not using sliders 3 | - Xbox 360 and PS4 Linux controllers can now bring up the keyboard with the select button by default 4 | - Fix crash when looking up any recipe with REI 5 | - Allowed combo buttons to be bound to a controller mapping of which the maximum is 2 6 | - Added support for Xbox 360 controllers on linux with help from @StormyIceLeopard 7 | - Added support for the Nintendo Wii U Pro Controller on linux 8 | 9 | [7.0.1] 10 | - Fix a crash caused when running alongside a lot of mods 11 | 12 | [7.0.0] 13 | - Changed the default bindings to match the defaults on the bedrock version of the game 14 | - Fix buttons that open other screen requiring double presses to open 15 | - Added a Controller Binding allowing the player to split item stacks 16 | - Moved the Controller Options button to the Controls screen 17 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: Java CI with Gradle 5 | 6 | on: ["push", "pull_request"] 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Set up JDK 16 16 | uses: actions/setup-java@v2 17 | with: 18 | java-version: '16' 19 | distribution: 'adopt' 20 | cache: gradle 21 | - name: Grant execute permission for gradlew 22 | run: chmod +x gradlew 23 | - name: Build with Gradle 24 | run: ./gradlew build 25 | - name: Upload artifacts 26 | uses: actions/upload-artifact@v2 27 | with: 28 | path: build/libs 29 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/mixin/TitleScreenMixin.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 9 | import com.stereowalker.controllermod.client.controller.ControllerUtil.ListeningMode; 10 | 11 | import net.minecraft.client.gui.screens.Screen; 12 | import net.minecraft.client.gui.screens.TitleScreen; 13 | import net.minecraft.network.chat.Component; 14 | 15 | @Mixin(TitleScreen.class) 16 | public abstract class TitleScreenMixin extends Screen { 17 | 18 | protected TitleScreenMixin(Component pTitle) { 19 | super(pTitle); 20 | } 21 | 22 | @Inject(method = "init", at = @At("TAIL")) 23 | public void init_inject(CallbackInfo ci) { 24 | ControllerUtil.listeningMode = ListeningMode.LISTEN_TO_MAPPINGS; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | 2 | modLoader="javafml" 3 | loaderVersion="[39,)" 4 | license="All Rights Reserved" 5 | issueTrackerURL="https://github.com/Stereowalker/Controller-Support-Mod/issues" 6 | logoFile="pack.png" 7 | [[mods]] 8 | modId="controllermod" 9 | version="${file.jarVersion}" 10 | displayName="Controller Support" 11 | updateJSONURL="https://raw.githubusercontent.com/Stereowalker/Controller-Support-Mod/master/update.json" 12 | displayURL="https://www.curseforge.com/minecraft/mc-mods/controller-mod" 13 | credits="I'd like to thank all my supporters on Patreon for giving me a reason to continue modding, and you for downloading and playing with this mod" 14 | authors="Stereowalker" 15 | description=''' 16 | Grants the ablility to play Minecraft with controllers and gives opportunity to those who want to play split-screen. 17 | ''' 18 | # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. 19 | [[dependencies.controllermod]] #optional 20 | modId="forge" #mandatory 21 | mandatory=true #mandatory 22 | versionRange="[39,)" #mandatory 23 | ordering="NONE" 24 | side="CLIENT" 25 | # Here's another dependency 26 | [[dependencies.controllermod]] 27 | modId="minecraft" 28 | mandatory=true 29 | versionRange="[1.18.1,1.19)" 30 | ordering="NONE" 31 | side="CLIENT" 32 | [[dependencies.controllermod]] 33 | modId="unionlib" 34 | mandatory=true 35 | versionRange="[7.2.3,7.3)" 36 | ordering="NONE" 37 | side="BOTH" -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/mixin/AbstractContainerScreenMixin.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Redirect; 6 | 7 | import com.stereowalker.controllermod.ControllerMod; 8 | 9 | import net.minecraft.client.gui.screens.Screen; 10 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 11 | import net.minecraft.client.gui.screens.inventory.MenuAccess; 12 | import net.minecraft.network.chat.Component; 13 | import net.minecraft.world.entity.player.Inventory; 14 | import net.minecraft.world.inventory.AbstractContainerMenu; 15 | import net.minecraftforge.api.distmarker.Dist; 16 | import net.minecraftforge.api.distmarker.OnlyIn; 17 | 18 | @Mixin(AbstractContainerScreen.class) 19 | @OnlyIn(Dist.CLIENT) 20 | public abstract class AbstractContainerScreenMixin extends Screen implements MenuAccess { 21 | 22 | public AbstractContainerScreenMixin(T pMenu, Inventory pPlayerInventory, Component pTitle) { 23 | super(pTitle); 24 | } 25 | 26 | @Redirect(method = {"mouseReleased", "mouseClicked"}, at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/InputConstants;isKeyDown(JI)Z")) 27 | public boolean shiftClick(long l, int i) { 28 | return Screen.hasShiftDown() || ControllerMod.getInstance().controllerOptions.controllerBindQuickMove.isDown(ControllerMod.getInstance().controllerOptions.controllerModel); 29 | } 30 | 31 | @Redirect(method = "mouseReleased", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;hasShiftDown()Z")) 32 | public boolean shiftClick() { 33 | return Screen.hasShiftDown() || ControllerMod.getInstance().controllerOptions.controllerBindQuickMove.isDown(ControllerMod.getInstance().controllerOptions.controllerModel); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/gui/screen/TriggerSetupScreen.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.gui.screen; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import com.stereowalker.controllermod.ControllerMod; 5 | import com.stereowalker.controllermod.client.gui.widget.list.TriggerAxesList; 6 | 7 | import net.minecraft.client.gui.GuiComponent; 8 | import net.minecraft.client.gui.components.Button; 9 | import net.minecraft.client.gui.screens.Screen; 10 | import net.minecraft.network.chat.CommonComponents; 11 | import net.minecraft.network.chat.TranslatableComponent; 12 | import net.minecraftforge.api.distmarker.Dist; 13 | import net.minecraftforge.api.distmarker.OnlyIn; 14 | 15 | @OnlyIn(Dist.CLIENT) 16 | public class TriggerSetupScreen extends Screen { 17 | private final Screen previousScreen; 18 | private TriggerAxesList triggerAxesList; 19 | private ControllerMod mod; 20 | 21 | public TriggerSetupScreen(Screen previousScreen) { 22 | super(new TranslatableComponent("trigger_setup.title")); 23 | this.previousScreen = previousScreen; 24 | this.mod = ControllerMod.getInstance(); 25 | } 26 | 27 | @Override 28 | public void init() { 29 | this.triggerAxesList = new TriggerAxesList(this, this.minecraft, ControllerMod.getInstance()); 30 | this.addWidget(this.triggerAxesList); 31 | this.addRenderableWidget(new Button(this.width / 2 - 155 + 210, this.height - 29, 100, 20, CommonComponents.GUI_DONE, (p_213124_1_) -> { 32 | this.minecraft.setScreen(this.previousScreen); 33 | })); 34 | } 35 | 36 | @Override 37 | public void removed() { 38 | mod.controllerOptions.saveOptions(); 39 | } 40 | 41 | @Override 42 | public void render(PoseStack matrixStack, int mouseX, int mouseY, float partialTicks) { 43 | this.renderBackground(matrixStack); 44 | this.triggerAxesList.render(matrixStack, mouseX, mouseY, partialTicks); 45 | GuiComponent.drawCenteredString(matrixStack, this.font, this.title, this.width / 2, 15, 16777215); 46 | super.render(matrixStack, mouseX, mouseY, partialTicks); 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/mixin/KeyboardInputMixin.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import com.stereowalker.controllermod.ControllerMod; 9 | import com.stereowalker.controllermod.client.ControllerOptions; 10 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 11 | 12 | import net.minecraft.client.player.Input; 13 | import net.minecraft.client.player.KeyboardInput; 14 | 15 | @Mixin(KeyboardInput.class) 16 | public abstract class KeyboardInputMixin extends Input { 17 | 18 | @Inject(method = "tick", at = @At("TAIL")) 19 | public void tick_inject(boolean p_108582_, CallbackInfo ci) { 20 | if (ControllerMod.CONFIG.usePreciseMovement && ControllerUtil.isControllerAvailable(ControllerMod.getInstance().controllerOptions.controllerNumber) && ControllerMod.getInstance().controllerOptions.enableController) { 21 | ControllerOptions settings = ControllerMod.getInstance().controllerOptions; 22 | float moveXAxis = p_108582_ ? settings.controllerBindMoveHorizontal.getAxis() * 0.3F : settings.controllerBindMoveHorizontal.getAxis(); 23 | float moveYAxis = p_108582_ ? settings.controllerBindMoveVertical.getAxis() * 0.3F : settings.controllerBindMoveVertical.getAxis(); 24 | if (moveXAxis >= -1.0F && moveXAxis < -ControllerMod.CONFIG.deadzone) { 25 | this.leftImpulse = -moveXAxis; 26 | this.left = true; 27 | } 28 | if (moveXAxis <= 1.0F && moveXAxis > ControllerMod.CONFIG.deadzone) { 29 | this.leftImpulse = -moveXAxis; 30 | this.right = true; 31 | } 32 | if (moveYAxis >= -1.0F && moveYAxis < -ControllerMod.CONFIG.deadzone) { 33 | this.forwardImpulse = -moveYAxis; 34 | this.up = true; 35 | } 36 | if (moveYAxis <= 1.0F && moveYAxis > ControllerMod.CONFIG.deadzone) { 37 | this.forwardImpulse = -moveYAxis; 38 | this.down = true; 39 | } 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/mixin/GameRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Final; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.At.Shift; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | import com.mojang.blaze3d.vertex.PoseStack; 12 | import com.stereowalker.controllermod.ControllerMod; 13 | import com.stereowalker.controllermod.client.ControllerOptions; 14 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 15 | 16 | import net.minecraft.client.Minecraft; 17 | import net.minecraft.client.renderer.GameRenderer; 18 | import net.minecraft.server.packs.resources.ResourceManagerReloadListener; 19 | 20 | @Mixin(GameRenderer.class) 21 | public abstract class GameRendererMixin implements ResourceManagerReloadListener, AutoCloseable { 22 | @Shadow @Final private Minecraft minecraft; 23 | @Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = Shift.AFTER, target = "Lnet/minecraft/client/Camera;setup(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/world/entity/Entity;ZZF)V")) 24 | public void renderLevel_inject(float pPartialTicks, long pFinishTimeNano, PoseStack pMatrixStack, CallbackInfo ci) { 25 | if(ControllerUtil.isControllerAvailable(ControllerMod.getInstance().controllerOptions.controllerNumber) && ControllerMod.getInstance().controllerOptions.enableController && minecraft.screen == null) { 26 | ControllerOptions settings = ControllerMod.getInstance().controllerOptions; 27 | float cameraXAxis = settings.controllerBindCameraHorizontal.getAxis(); 28 | float cameraYAxis = settings.controllerBindCameraVertical.getAxis(); 29 | 30 | double moveModifier = 10.0D; 31 | 32 | float newPitch = (cameraYAxis >= -1.0F && cameraYAxis < -0.1D) || (cameraYAxis <= 1.0F && cameraYAxis > 0.1D) ? (float) ((cameraYAxis * ControllerMod.CONFIG.ingame_sensitivity * moveModifier) + minecraft.player.getViewXRot((float) pPartialTicks)) : minecraft.player.getViewXRot((float) pPartialTicks); 33 | float newYaw = (cameraXAxis >= -1.0F && cameraXAxis < -0.1D) || (cameraXAxis <= 1.0F && cameraXAxis > 0.1D) ? (float) ((cameraXAxis * ControllerMod.CONFIG.ingame_sensitivity * moveModifier) + minecraft.player.getViewYRot((float) pPartialTicks)) : minecraft.player.getViewYRot((float) pPartialTicks); 34 | 35 | minecraft.player.xRot = newPitch; 36 | minecraft.player.yRot = newYaw; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/mixin/ControlsScreenMixin.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.At.Shift; 6 | import org.spongepowered.asm.mixin.injection.Inject; 7 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 10 | 11 | import com.stereowalker.controllermod.client.gui.screen.ControllerInputOptionsScreen; 12 | import com.stereowalker.controllermod.client.gui.screen.ControllerSettingsScreen; 13 | 14 | import net.minecraft.client.Options; 15 | import net.minecraft.client.gui.components.Button; 16 | import net.minecraft.client.gui.screens.OptionsSubScreen; 17 | import net.minecraft.client.gui.screens.Screen; 18 | import net.minecraft.client.gui.screens.controls.ControlsScreen; 19 | import net.minecraft.network.chat.Component; 20 | import net.minecraft.network.chat.TranslatableComponent; 21 | import net.minecraftforge.api.distmarker.Dist; 22 | import net.minecraftforge.api.distmarker.OnlyIn; 23 | 24 | @Mixin(ControlsScreen.class) 25 | @OnlyIn(Dist.CLIENT) 26 | public abstract class ControlsScreenMixin extends OptionsSubScreen { 27 | 28 | public ControlsScreenMixin(Screen pLastScreen, Options pOptions, Component pTitle) { 29 | super(pLastScreen, pOptions, pTitle); 30 | } 31 | 32 | @ModifyVariable(method = "init", ordinal = 2, at = @At(value = "INVOKE", shift = Shift.AFTER, ordinal = 4, target = "Lnet/minecraft/client/gui/screens/controls/ControlsScreen;addRenderableWidget(Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener;")) 33 | public int init_inject(int k){ 34 | return k+24; 35 | } 36 | 37 | @Inject(method = "init", at = @At(value = "INVOKE", shift = Shift.AFTER, ordinal = 4, target = "Lnet/minecraft/client/gui/screens/controls/ControlsScreen;addRenderableWidget(Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener;"), locals = LocalCapture.CAPTURE_FAILHARD) 38 | public void init_inject(CallbackInfo ci, int i, int j, int k){ 39 | this.addRenderableWidget(new Button(j, k-24, 150, 20, new TranslatableComponent("options.controller_settings"), (p_213088_1_) -> { 40 | this.minecraft.setScreen(new ControllerSettingsScreen(this)); 41 | })); 42 | this.addRenderableWidget(new Button(i, k, 150, 20, new TranslatableComponent("controls.controllerbinds"), (p_212984_1_) -> { 43 | this.minecraft.setScreen(new ControllerInputOptionsScreen(this, null, new int[] {0})); 44 | })); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/config/Config.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.config; 2 | 3 | import com.stereowalker.unionlib.config.ConfigObject; 4 | import com.stereowalker.unionlib.config.UnionConfig; 5 | 6 | @UnionConfig(name = "controllermod", autoReload = true, translatableName = "gui.controller_mod") 7 | public class Config implements ConfigObject { 8 | 9 | @UnionConfig.Entry(group = "General", name = "Debug Mode") 10 | public boolean debug = false; 11 | 12 | @UnionConfig.Entry(group = "Controller", name = "Ingame Sensitivity") 13 | @UnionConfig.Comment(comment = "The sensitivity of the controller ingame") 14 | @UnionConfig.Range(max = 1.0, min = 0.0, useSlider = true) 15 | public float ingame_sensitivity = 0.5f; 16 | 17 | @UnionConfig.Entry(group = "Controller", name = "Menu Sensitivity") 18 | @UnionConfig.Comment(comment = "The sensitivity of the controller in the menu") 19 | @UnionConfig.Range(max = 1.0, min = 0.0, useSlider = true) 20 | public float menu_sensitivity = 0.2f; 21 | 22 | @UnionConfig.Entry(group = "Controller", name = "Deadzone") 23 | @UnionConfig.Comment(comment = "The deadzone of the controller") 24 | @UnionConfig.Range(max = 1.0, min = 0.0, useSlider = true) 25 | public float deadzone = 0.2f; 26 | 27 | @UnionConfig.Entry(group = "Controller", name = "Use Precise Movement") 28 | @UnionConfig.Comment(comment = {"Allows you to use mose fine movements using your thumbstick"}) 29 | public boolean usePreciseMovement = true; 30 | 31 | @UnionConfig.Entry(group = "Gameplay", name = "Show Ingame Player Names") 32 | @UnionConfig.Comment(comment = {"Shows your name on the to right of the screen when in multiplayer","Useful in split-screen to identify whose instance is whose"}) 33 | public boolean ingame_player_names = true; 34 | 35 | @UnionConfig.Entry(group = "Gameplay", name = "Show Coordinates") 36 | @UnionConfig.Comment(comment = {"Shows your current coordinates on the screen if you are allowed to see them","I hope you weren't planning to use this feature to bypass the reduced debug info rule"}) 37 | public boolean show_coordinates = false; 38 | 39 | @UnionConfig.Entry(group = "Gameplay", name = "Safe Area") 40 | @UnionConfig.Comment(comment = {"Allows you to determine the safe area of your screen","This only works ingame. Any elements in any other menus will not be moved"}) 41 | @UnionConfig.Range(max = 100.0, min = 0.0, useSlider = true) 42 | public float safe_area = 100.0f; 43 | 44 | @UnionConfig.Entry(group = "Gameplay", name = "Show Button Hints") 45 | @UnionConfig.Comment(comment = {"SHows button hints at the bottom right and left of your screen"}) 46 | public boolean show_button_hints = false; 47 | 48 | @UnionConfig.Entry(group = "Gameplay", name = "Show Paper Doll") 49 | @UnionConfig.Comment(comment = {"Shows the mini you at the top left corner of the screen","Adorable right?"}) 50 | public boolean show_paper_doll = true; 51 | } 52 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/gui/screen/PaperDollOptionsScreen.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.gui.screen; 2 | 3 | import java.util.function.Consumer; 4 | 5 | import com.mojang.blaze3d.vertex.PoseStack; 6 | import com.stereowalker.controllermod.ControllerMod; 7 | import com.stereowalker.controllermod.client.ControllerOptions; 8 | import com.stereowalker.controllermod.client.PaperDollOptions.DollType; 9 | 10 | import net.minecraft.client.gui.GuiComponent; 11 | import net.minecraft.client.gui.components.Button; 12 | import net.minecraft.client.gui.screens.Screen; 13 | import net.minecraft.network.chat.CommonComponents; 14 | import net.minecraft.network.chat.MutableComponent; 15 | import net.minecraft.network.chat.TranslatableComponent; 16 | import net.minecraftforge.api.distmarker.Dist; 17 | import net.minecraftforge.api.distmarker.OnlyIn; 18 | 19 | @OnlyIn(Dist.CLIENT) 20 | public class PaperDollOptionsScreen extends Screen { 21 | private final Screen previousScreen; 22 | private ControllerOptions settings; 23 | 24 | public PaperDollOptionsScreen(Screen p_i51123_1_) { 25 | super(new TranslatableComponent("options.paper_doll.title")); 26 | this.previousScreen = p_i51123_1_; 27 | this.settings = ControllerMod.getInstance().controllerOptions; 28 | } 29 | 30 | @Override 31 | public void init() { 32 | int i = 0; 33 | for (DollType dollType : DollType.values()) { 34 | if (dollType.showInMenu()) { 35 | addOption(i, dollType); 36 | i++; 37 | } 38 | } 39 | this.addRenderableWidget(new Button(this.width / 2 - 100, this.height / 6 + 168, 200, 20, new TranslatableComponent("gui.done"), (p_212984_1_) -> { 40 | this.minecraft.setScreen(this.previousScreen); 41 | })); 42 | } 43 | 44 | public void addOption(int index, DollType getter) { 45 | boolean left = index%2 == 0; 46 | int position = index / 2; 47 | this.addRenderableWidget(new Button(this.width / 2 +(left?-155:5), this.height / 6 + (24*position), 150, 20, getter.getDisplayText().append(" : ").append(CommonComponents.optionStatus(settings.paperDoll.show.get(getter))), (p_212984_1_) -> { 48 | settings.paperDoll.show.put(getter, !settings.paperDoll.show.get(getter)); 49 | this.minecraft.setScreen(new PaperDollOptionsScreen(previousScreen)); 50 | })); 51 | } 52 | 53 | public void addOption(int index, boolean getter, Consumer setter, MutableComponent text) { 54 | boolean left = index%2 == 0; 55 | int position = index / 2; 56 | this.addRenderableWidget(new Button(this.width / 2 +(left?-155:5), this.height / 6 + (24*position), 150, 20, text.append(" : ").append(CommonComponents.optionStatus(getter)), (p_212984_1_) -> { 57 | setter.accept(!getter); 58 | this.minecraft.setScreen(new PaperDollOptionsScreen(previousScreen)); 59 | })); 60 | } 61 | 62 | @Override 63 | public void render(PoseStack matrixStack, int mouseX, int mouseY, float partialTicks) { 64 | this.renderBackground(matrixStack); 65 | GuiComponent.drawCenteredString(matrixStack, this.font, this.title, this.width / 2, 15, 16777215); 66 | super.render(matrixStack, mouseX, mouseY, partialTicks); 67 | } 68 | 69 | @Override 70 | public void removed() { 71 | settings.saveOptions(); 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/mixin/ScreenMixin.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Shadow; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | import org.spongepowered.asm.mixin.injection.Inject; 7 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 8 | 9 | import com.mojang.blaze3d.systems.RenderSystem; 10 | import com.mojang.blaze3d.vertex.BufferBuilder; 11 | import com.mojang.blaze3d.vertex.DefaultVertexFormat; 12 | import com.mojang.blaze3d.vertex.PoseStack; 13 | import com.mojang.blaze3d.vertex.Tesselator; 14 | import com.mojang.blaze3d.vertex.VertexFormat; 15 | import com.stereowalker.controllermod.ControllerMod; 16 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 17 | import com.stereowalker.controllermod.client.controller.ControllerUtil.ListeningMode; 18 | 19 | import net.minecraft.client.Minecraft; 20 | import net.minecraft.client.gui.Font; 21 | import net.minecraft.client.gui.components.Widget; 22 | import net.minecraft.client.gui.components.events.AbstractContainerEventHandler; 23 | import net.minecraft.client.gui.screens.LevelLoadingScreen; 24 | import net.minecraft.client.gui.screens.Screen; 25 | import net.minecraft.client.renderer.GameRenderer; 26 | 27 | @Mixin(Screen.class) 28 | public abstract class ScreenMixin extends AbstractContainerEventHandler implements Widget { 29 | @Shadow protected Font font; 30 | 31 | @Inject(method = "render", at = @At("TAIL")) 32 | public void render(PoseStack pPoseStack, int pMouseX, int pMouseY, float pPartialTick, CallbackInfo ci) { 33 | if (!((Object)this instanceof LevelLoadingScreen)) { 34 | int x = (int)(ControllerUtil.virtualmouse.xpos() * (double)Minecraft.getInstance().getWindow().getGuiScaledWidth() / (double)Minecraft.getInstance().getWindow().getWidth()); 35 | int y = (int)(ControllerUtil.virtualmouse.ypos() * (double)Minecraft.getInstance().getWindow().getGuiScaledHeight() / (double)Minecraft.getInstance().getWindow().getHeight()); 36 | if(ControllerUtil.isControllerAvailable(ControllerMod.getInstance().controllerOptions.controllerNumber) && ControllerMod.getInstance().controllerOptions.enableController) { 37 | if (ControllerUtil.listeningMode == ListeningMode.KEYBOARD) { 38 | ControllerMod.getInstance().onScreenKeyboard.drawKeyboard(pPoseStack, font, x, y); 39 | } else { 40 | renderPonter(x, y, 8.0D); 41 | } 42 | } 43 | } 44 | } 45 | 46 | private static void renderPonter(int x, int y, double size) { 47 | RenderSystem.enableBlend(); 48 | RenderSystem.enableDepthTest(); 49 | RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); 50 | RenderSystem.defaultBlendFunc(); 51 | 52 | RenderSystem.disableDepthTest(); 53 | RenderSystem.depthMask(false); 54 | RenderSystem.defaultBlendFunc(); 55 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 56 | RenderSystem.setShaderTexture(0, ControllerMod.Locations.CURSOR); 57 | Tesselator tessellator = Tesselator.getInstance(); 58 | BufferBuilder bufferbuilder = tessellator.getBuilder(); 59 | bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); 60 | bufferbuilder.vertex(-size+x, size+y, -90.0F).uv(0.0F, 1.0F).endVertex(); 61 | bufferbuilder.vertex(size+x, size+y, -90.0F).uv(1.0F, 1.0F).endVertex(); 62 | bufferbuilder.vertex(size+x, -size+y, -90.0F).uv(1.0F, 0.0F).endVertex(); 63 | bufferbuilder.vertex(-size+x, -size+y, -90.0F).uv(0.0F, 0.0F).endVertex(); 64 | tessellator.end(); 65 | RenderSystem.depthMask(true); 66 | RenderSystem.enableDepthTest(); 67 | RenderSystem.defaultBlendFunc(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/controller/ControllerBindings.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.lang3.ArrayUtils; 6 | import org.lwjgl.glfw.GLFW; 7 | 8 | import com.google.common.collect.Lists; 9 | import com.mojang.blaze3d.platform.InputConstants.Type; 10 | import com.stereowalker.controllermod.ControllerMod; 11 | import com.stereowalker.controllermod.client.controller.ControllerUtil.InputType; 12 | 13 | import net.minecraft.client.KeyMapping; 14 | import net.minecraft.client.Minecraft; 15 | import net.minecraft.resources.ResourceLocation; 16 | import net.minecraftforge.client.settings.KeyConflictContext; 17 | 18 | public class ControllerBindings { 19 | 20 | public static final String NEW = "new"; 21 | public static final ControllerMapping SELECT_INPUT = new ControllerMapping(NEW, "select", Type.MOUSE.getOrCreate(GLFW.GLFW_MOUSE_BUTTON_LEFT), (builder) -> { 22 | builder.put(ControllerModel.XBOX_360_WINDOWS.defaultName, Lists.newArrayList("#face_button_down")); 23 | builder.put(ControllerModel.XBOX_360_LINUX.defaultName, Lists.newArrayList("#face_button_down")); 24 | builder.put(ControllerModel.PS4_WINDOWS.defaultName, Lists.newArrayList("#face_button_down")); 25 | builder.put(new ResourceLocation("controllermod:ps4_linux"), Lists.newArrayList("#face_button_down")); 26 | builder.put(new ResourceLocation("controllermod:nintendo_wii_u_pro"), Lists.newArrayList("#face_button_down")); 27 | }, InputType.PRESS, UseCase.ANY_SCREEN); 28 | 29 | // public static final ControllerBinding CLOSE_INVENTORY_INPUT = new ControllerBinding("close_invenetory", "button3", InputType.PRESS, ControllerConflictContext.CONTAINER); 30 | public static final List excludedKeybinds = Lists.newArrayList(); 31 | 32 | @SuppressWarnings("resource") 33 | public static void registerAll() { 34 | excludeKeybind(Minecraft.getInstance().options.keyInventory); 35 | excludeKeybind(Minecraft.getInstance().options.keyJump); 36 | excludeKeybind(Minecraft.getInstance().options.keyAttack); 37 | excludeKeybind(Minecraft.getInstance().options.keyUse); 38 | excludeKeybind(Minecraft.getInstance().options.keyShift); 39 | excludeKeybind(Minecraft.getInstance().options.keyTogglePerspective); 40 | excludeKeybind(Minecraft.getInstance().options.keyDrop); 41 | excludeKeybind(Minecraft.getInstance().options.keyLeft); 42 | excludeKeybind(Minecraft.getInstance().options.keyRight); 43 | excludeKeybind(Minecraft.getInstance().options.keyUp); 44 | excludeKeybind(Minecraft.getInstance().options.keyDown); 45 | excludeKeybind(Minecraft.getInstance().options.keySprint); 46 | excludeKeybind(Minecraft.getInstance().options.keyChat); 47 | 48 | registerControllerBinding(SELECT_INPUT); 49 | for (KeyMapping key : Minecraft.getInstance().options.keyMappings) { 50 | if (!excludedKeybinds.contains(key)) registerControllerBinding(new ControllerMapping(key, key.getKeyConflictContext() == KeyConflictContext.IN_GAME ? UseCase.INGAME : key.getKeyConflictContext() == KeyConflictContext.GUI ? UseCase.ANY_SCREEN : UseCase.ANYWHERE)); 51 | } 52 | } 53 | 54 | /** 55 | * Registers a KeyMapping. 56 | * Call this during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent}. 57 | * This method is safe to call during parallel mod loading. 58 | */ 59 | public static synchronized void registerControllerBinding(ControllerMapping key) 60 | { 61 | ControllerMod.getInstance().controllerOptions.controllerBindings = ArrayUtils.add(ControllerMod.getInstance().controllerOptions.controllerBindings, key); 62 | } 63 | 64 | public static synchronized void excludeKeybind(KeyMapping binding) { 65 | if (!excludedKeybinds.contains(binding)) { 66 | excludedKeybinds.add(binding); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/accesstransformer.cfg: -------------------------------------------------------------------------------- 1 | public net.minecraft.client.KeyboardHandler m_90889_(JII)V # charTyped 2 | public net.minecraft.client.KeyMapping f_90816_ # key 3 | public net.minecraft.client.MouseHandler f_91503_ # minecraft 4 | public net.minecraft.client.MouseHandler f_91504_ # isLeftPressed 5 | public net.minecraft.client.MouseHandler f_91505_ # isMiddlePressed 6 | public net.minecraft.client.MouseHandler f_91506_ # isRightPressed 7 | public net.minecraft.client.MouseHandler f_91507_ # xpos 8 | public net.minecraft.client.MouseHandler f_91508_ # ypos 9 | public net.minecraft.client.MouseHandler f_91509_ # fakeRightMouse 10 | public net.minecraft.client.MouseHandler f_91510_ # activeButton 11 | public net.minecraft.client.MouseHandler f_91511_ # ignoreFirstMove 12 | public net.minecraft.client.MouseHandler f_91512_ # clickDepth 13 | public net.minecraft.client.MouseHandler f_91513_ # mousePressedTime 14 | public net.minecraft.client.MouseHandler f_91514_ # smoothTurnX 15 | public net.minecraft.client.MouseHandler f_91515_ # smoothTurnY 16 | public net.minecraft.client.MouseHandler f_91516_ # accumulatedDX 17 | public net.minecraft.client.MouseHandler f_91517_ # accumulatedDY 18 | public net.minecraft.client.MouseHandler f_91518_ # accumulatedScroll 19 | public net.minecraft.client.MouseHandler f_91519_ # lastMouseEventTime 20 | public net.minecraft.client.MouseHandler f_91520_ # mouseGrabbed 21 | public net.minecraft.client.MouseHandler m_91526_(JDD)V # onScroll 22 | public net.minecraft.client.MouseHandler m_91530_(JIII)V # onPress 23 | public net.minecraft.client.MouseHandler m_91539_(JLjava/util/List;)V # onDrop 24 | public net.minecraft.client.MouseHandler m_91561_(JDD)V # onMove 25 | 26 | public net.minecraft.client.gui.GuiComponent m_93123_(Lcom/mojang/math/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIIIII)V # fillGradient 27 | public net.minecraft.client.gui.Gui f_92977_ # screenWidth 28 | public net.minecraft.client.gui.Gui f_92978_ # screenHeight 29 | 30 | public net.minecraft.client.gui.screens.Screen f_96542_ # itemRenderer 31 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97706_ # clickedSlot 32 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97709_ # lastClickSlot 33 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97710_ # isSplittingStack 34 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97711_ # draggingItem 35 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97712_ # snapbackStartX 36 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97713_ # snapbackStartY 37 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97715_ # snapbackItem 38 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97717_ # quickCraftingType 39 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97718_ # quickCraftingButton 40 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97719_ # skipNextRelease 41 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97721_ # lastClickTime 42 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97722_ # lastClickButton 43 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97723_ # doubleclick 44 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97724_ # lastQuickMoved 45 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97737_ # quickCraftSlots 46 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97738_ # isQuickCrafting 47 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97744_(DD)Lnet/minecraft/world/inventory/Slot; # findSlot 48 | public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97762_(I)V # checkHotbarMouseClicked 49 | 50 | public net.minecraft.world.entity.Entity f_19858_ # xRot 51 | public net.minecraft.world.entity.Entity f_19857_ # yRot -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/controller/ControllerMap.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.controller; 2 | 3 | import java.util.Objects; 4 | 5 | import com.google.common.collect.Lists; 6 | 7 | import net.minecraftforge.api.distmarker.Dist; 8 | import net.minecraftforge.api.distmarker.OnlyIn; 9 | import net.minecraft.client.resources.language.I18n; 10 | import net.minecraft.resources.ResourceLocation; 11 | 12 | public class ControllerMap { 13 | public static String map(String input, ControllerModel model) { 14 | String lAr = "\u2190"; 15 | String uAr = "\u2191"; 16 | String rAr = "\u2192"; 17 | String dAr = "\u2193"; 18 | if (input.equals("empty") || input.equals(" ")) return " "; 19 | if (model == ControllerModel.XBOX_360_WINDOWS) 20 | if (input.equals("button7")) return "START"; 21 | else if (input.equals("button8")) return "LS"; 22 | else if (input.equals("button9")) return "RS"; 23 | else if (input.equals("button10")) return "UP"; 24 | else if (input.equals("button11")) return "RIGHT"; 25 | else if (input.equals("button12")) return "DOWN"; 26 | else if (input.equals("button13")) return "LEFT"; 27 | else if (input.equals("axis_pos0")) return "LS "+rAr; 28 | else if (input.equals("axis_neg0")) return "LS "+lAr; 29 | else if (input.equals("axis_pos1")) return "LS "+dAr; 30 | else if (input.equals("axis_neg1")) return "LS "+uAr; 31 | else if (input.equals("axis_pos2")) return "RS "+rAr; 32 | else if (input.equals("axis_neg2")) return "RS "+lAr; 33 | else if (input.equals("axis_pos3")) return "RS "+dAr; 34 | else if (input.equals("axis_neg3")) return "RS "+uAr; 35 | else if (input.equals("axis_pos4")) return "LT"; 36 | else if (input.equals("axis_pos5")) return "RT"; 37 | else if (input.equals("axis0")) return "LS "+lAr+rAr; 38 | else if (input.equals("axis1")) return "LS "+uAr+dAr; 39 | else if (input.equals("axis2")) return "RS "+lAr+rAr; 40 | else if (input.equals("axis3")) return "RS "+uAr+dAr; 41 | if (model == ControllerModel.PS4_WINDOWS) 42 | if (input.equals("button12")) return "PS BUTTON"; 43 | else if (input.equals("axis_pos0")) return "LS "+rAr; 44 | else if (input.equals("axis_neg0")) return "LS "+lAr; 45 | else if (input.equals("axis_pos1")) return "LS "+dAr; 46 | else if (input.equals("axis_neg1")) return "LS "+uAr; 47 | else if (input.equals("axis_pos2")) return "RS "+rAr; 48 | else if (input.equals("axis_neg2")) return "RS "+lAr; 49 | else if (input.equals("axis_pos5")) return "RS "+dAr; 50 | else if (input.equals("axis_neg5")) return "RS "+uAr; 51 | else if (input.equals("axis0")) return "LS "+lAr+rAr; 52 | else if (input.equals("axis1")) return "LS "+uAr+dAr; 53 | else if (input.equals("axis2")) return "RS "+lAr+rAr; 54 | else if (input.equals("axis5")) return "RS "+uAr+dAr; 55 | if (input.equals("dpadup")) return "UP"; 56 | else if (input.equals("dpadri")) return "RIGHT"; 57 | else if (input.equals("dpaddo")) return "DOWN"; 58 | else if (input.equals("dpadle")) return "LEFT"; 59 | return I18n.get(model.getOrCreate(Lists.newArrayList(input))[0].getName()); 60 | } 61 | 62 | 63 | @OnlyIn(Dist.CLIENT) 64 | public static final class Button { 65 | public ControllerModel model; 66 | public String value; 67 | public String name; 68 | public ResourceLocation icon; 69 | 70 | protected Button(String name, ControllerModel model, ResourceLocation icon, String value){ 71 | this.model = model; 72 | this.value = value; 73 | this.icon = icon; 74 | this.name = name.isEmpty() ? this.model.modelName+"."+value : name; 75 | } 76 | 77 | public ControllerModel getModel(){ 78 | return this.model; 79 | } 80 | 81 | public ResourceLocation getIcon() { 82 | return icon; 83 | } 84 | 85 | public String getValue(){ 86 | return this.value; 87 | } 88 | 89 | public String getName() { 90 | return name; 91 | } 92 | 93 | public boolean equals(Object object) { 94 | if (this == object) { 95 | return true; 96 | } 97 | if (object == null || this.getClass() != object.getClass()) { 98 | return false; 99 | } 100 | Button button = (Button)object; 101 | return this.value == button.value && this.model == button.model; 102 | } 103 | 104 | public int hashCode() { 105 | return Objects.hash(new Object[]{this.model, this.value}); 106 | } 107 | 108 | public String toString() { 109 | return this.name; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/resources/ControllerModelManager.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.resources; 2 | 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Map.Entry; 9 | 10 | import com.google.common.collect.Lists; 11 | import com.google.gson.JsonElement; 12 | import com.google.gson.JsonObject; 13 | import com.google.gson.JsonParser; 14 | import com.stereowalker.controllermod.ControllerMod; 15 | import com.stereowalker.controllermod.client.ControllerOptions; 16 | import com.stereowalker.controllermod.client.controller.ControllerModel; 17 | 18 | import net.minecraft.Util.OS; 19 | import net.minecraft.resources.ResourceLocation; 20 | import net.minecraft.server.packs.resources.Resource; 21 | import net.minecraft.server.packs.resources.ResourceManager; 22 | import net.minecraft.server.packs.resources.SimplePreparableReloadListener; 23 | import net.minecraft.util.profiling.ProfilerFiller; 24 | import net.minecraftforge.api.distmarker.Dist; 25 | import net.minecraftforge.api.distmarker.OnlyIn; 26 | 27 | @OnlyIn(Dist.CLIENT) 28 | public class ControllerModelManager extends SimplePreparableReloadListener> { 29 | public static final Map ALL_MODELS = new HashMap(); 30 | 31 | @Override 32 | protected Map prepare(ResourceManager manager, ProfilerFiller var2) { 33 | Map models = new HashMap<>(); 34 | ControllerModel.DEFAULTS.forEach(def -> models.put(def.defaultName, def)); 35 | for (ResourceLocation id : manager.listResources("controllermodels/", (s) -> s.endsWith(".json"))) { 36 | System.out.println(id); 37 | ResourceLocation modelId = new ResourceLocation( 38 | id.getNamespace(), 39 | id.getPath().replace("controllermodels/", "").replace(".json", "") 40 | ); 41 | try { 42 | Resource resource = manager.getResource(id); 43 | try (InputStream stream = resource.getInputStream(); 44 | InputStreamReader reader = new InputStreamReader(stream)) { 45 | 46 | JsonObject object = JsonParser.parseReader(reader).getAsJsonObject(); 47 | List dupe_buttons = Lists.newArrayList(); 48 | if (object.has("dupe_buttons")) 49 | object.get("dupe_buttons").getAsJsonArray().forEach((a) -> dupe_buttons.add(a.getAsString())); 50 | List positive_triggers = Lists.newArrayList(); 51 | List negative_triggers = Lists.newArrayList(); 52 | if (object.has("triggers")) 53 | object.get("triggers").getAsJsonArray().forEach((a) -> { 54 | if (a.getAsInt() > 0) positive_triggers.add(a.getAsInt()); 55 | else if (a.getAsInt() < 0) negative_triggers.add(a.getAsInt()*-1); 56 | }); 57 | ControllerModel model = new ControllerModel( 58 | object.get("modelName").getAsString(), 59 | object.get("GUID").getAsString(), 60 | object.get("os").getAsString().equals("windows") ? OS.WINDOWS : 61 | object.get("os").getAsString().equals("linux") ? OS.LINUX : OS.UNKNOWN, 62 | negative_triggers.toArray(new Integer[] {}), 63 | positive_triggers.toArray(new Integer[] {}), 64 | dupe_buttons); 65 | 66 | for (Entry el : object.get("buttons").getAsJsonObject().entrySet()) { 67 | JsonObject ob = el.getValue().getAsJsonObject(); 68 | ControllerModel.addButton(model, ob.get("name"), ob.get("alias"), ob.get("icon"), el.getKey()); 69 | } 70 | model.setKey(modelId); 71 | models.put(modelId, model); 72 | } 73 | } catch (Throwable e) { 74 | ControllerMod.debug("Failed to read textures!", e); 75 | } 76 | } 77 | 78 | 79 | System.out.println("Look 2 me"); 80 | ALL_MODELS.putAll(models); 81 | return models; 82 | } 83 | 84 | private static boolean firstTime = true; 85 | @Override 86 | protected void apply(Map var1, ResourceManager var2, ProfilerFiller var3) { 87 | ALL_MODELS.clear(); 88 | ALL_MODELS.putAll(var1); 89 | ControllerMod mod = ControllerMod.getInstance(); 90 | 91 | if (firstTime) { 92 | mod.connectControllers(); 93 | firstTime = false; 94 | } else { 95 | mod.disconnectControllers(); 96 | mod.controllerOptions = new ControllerOptions(mod.controllerOptions); 97 | mod.controllerOptions.loadOptions(); 98 | mod.connectControllers(); 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/mixin/GuiMixin.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Final; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.Redirect; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 11 | 12 | import com.mojang.blaze3d.platform.Window; 13 | import com.mojang.blaze3d.vertex.PoseStack; 14 | import com.stereowalker.controllermod.ControllerMod; 15 | import com.stereowalker.controllermod.client.PaperDollOptions; 16 | 17 | import net.minecraft.client.Minecraft; 18 | import net.minecraft.client.gui.Font; 19 | import net.minecraft.client.gui.Gui; 20 | import net.minecraft.client.gui.GuiComponent; 21 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 22 | import net.minecraft.world.entity.player.Player; 23 | import net.minecraft.world.item.ItemStack; 24 | 25 | @Mixin(Gui.class) 26 | public class GuiMixin extends GuiComponent { 27 | 28 | @Shadow public int screenWidth; 29 | @Shadow public int screenHeight; 30 | @Shadow @Final private Minecraft minecraft; 31 | @Shadow private void renderSlot(int x, int y, float partialTick, Player player, ItemStack stack, int i) {} 32 | 33 | 34 | @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;lerp(FFF)F", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD) 35 | public void render2(PoseStack arg0, float arg1, CallbackInfo ci, Font font, float f) { 36 | PaperDollOptions.renderPlayerDoll((Gui)(Object)this, arg0); 37 | } 38 | 39 | @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/Window;getGuiScaledWidth()I")) 40 | public int render_reditect_width(Window window) { 41 | return window.getGuiScaledWidth() - (ControllerMod.getSafeArea()*2); 42 | } 43 | 44 | @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/Window;getGuiScaledHeight()I")) 45 | public int render_reditect_height(Window window) { 46 | return window.getGuiScaledHeight() - (ControllerMod.getSafeArea()*2); 47 | } 48 | 49 | @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/Gui;fill(Lcom/mojang/blaze3d/vertex/PoseStack;IIIII)V")) 50 | public void render_all_blit(PoseStack poseStack, int minX, int minY, int maxX, int maxY, int color) { 51 | Gui.fill(poseStack, minX, minY, maxX + (ControllerMod.getSafeArea()*2), maxY + (ControllerMod.getSafeArea()*2), color); 52 | } 53 | 54 | @Redirect(method = {"lambda$renderEffects$0","m_93045_"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/Gui;blit(Lcom/mojang/blaze3d/vertex/PoseStack;IIIIILnet/minecraft/client/renderer/texture/TextureAtlasSprite;)V")) 55 | public void render_all_blit(PoseStack poseStack, int x, int y, int blitOffset, int width, int height, TextureAtlasSprite sprite) { 56 | Gui.blit(poseStack, x + ControllerMod.getSafeArea(), y + ControllerMod.getSafeArea(), blitOffset, width, height, sprite); 57 | } 58 | 59 | @Redirect(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/Gui;renderSlot(IIFLnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/item/ItemStack;I)V")) 60 | public void renderSlot_rediect(Gui gui, int x, int y, float partialTick, Player player, ItemStack stack, int i) { 61 | renderSlot(x + ControllerMod.getSafeArea(), y + ControllerMod.getSafeArea(), partialTick, player, stack, i); 62 | } 63 | 64 | @Inject(method = {"renderVignette","renderSpyglassOverlay","renderTextureOverlay"}, at = @At("HEAD")) 65 | public void disableSafeZone(CallbackInfo ci) { 66 | this.screenWidth = this.minecraft.getWindow().getGuiScaledWidth(); 67 | this.screenHeight = this.minecraft.getWindow().getGuiScaledHeight(); 68 | } 69 | 70 | @Inject(method = {"renderVignette","renderSpyglassOverlay","renderTextureOverlay"}, at = @At("TAIL")) 71 | public void enableSafeZone(CallbackInfo ci) { 72 | this.screenWidth = this.minecraft.getWindow().getGuiScaledWidth() - (ControllerMod.getSafeArea()*2); 73 | this.screenHeight = this.minecraft.getWindow().getGuiScaledHeight() - (ControllerMod.getSafeArea()*2); 74 | } 75 | 76 | @Override 77 | public void blit(PoseStack poseStack, int x, int y, int uOffset, int vOffset, int uWidth, int vHeight) { 78 | super.blit(poseStack, x + ControllerMod.getSafeArea(), y + ControllerMod.getSafeArea(), uOffset, vOffset, uWidth, vHeight); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/controllermodels/ps4_linux.json: -------------------------------------------------------------------------------- 1 | { 2 | "modelName": "ps4", 3 | "GUID": "050000004c050000cc09000000810000", 4 | "os": "linux", 5 | "dupe_buttons": [ 6 | "button13", 7 | "button14", 8 | "button15", 9 | "button16" 10 | ], 11 | "triggers": [ 12 | -2, 13 | -5 14 | ], 15 | "buttons": { 16 | "button0": { 17 | "name": "button.ps4", 18 | "alias": "face_button_down", 19 | "icon": "controllers/ps4_face_button_down.png" 20 | }, 21 | "button1": { 22 | "name": "button.ps4", 23 | "alias": "face_button_right", 24 | "icon": "controllers/ps4_face_button_right.png" 25 | }, 26 | "button2": { 27 | "name": "button.ps4", 28 | "alias": "face_button_up", 29 | "icon": "controllers/ps4_face_button_up.png" 30 | }, 31 | "button3": { 32 | "name": "button.ps4", 33 | "alias": "face_button_left", 34 | "icon": "controllers/ps4_face_button_left.png" 35 | }, 36 | "button4": { 37 | "name": "button.ps4", 38 | "alias": "bumper_left", 39 | "icon": "controllers/ps4_bumper_left.png" 40 | }, 41 | "button5": { 42 | "name": "button.ps4", 43 | "alias": "bumper_right", 44 | "icon": "controllers/ps4_bumper_right.png" 45 | }, 46 | "button6": { 47 | "name": "button.ps4", 48 | "alias": "left_trigger", 49 | "icon": "controllers/ps4_left_trigger.png" 50 | }, 51 | "button7": { 52 | "name": "button.ps4", 53 | "alias": "right_trigger", 54 | "icon": "controllers/ps4_right_trigger.png" 55 | }, 56 | "button8": { 57 | "name": "button.ps4", 58 | "alias": "select_button", 59 | "icon": "controllers/ps4_select_button.png" 60 | }, 61 | "button9": { 62 | "name": "button.ps4", 63 | "alias": "start_button", 64 | "icon": "controllers/ps4_start_button.png" 65 | }, 66 | "button10": { 67 | "name": "button.ps4", 68 | "alias": "guide_button", 69 | "icon": "controllers/wii_u_pro_guide_button.png" 70 | }, 71 | "button11": { 72 | "name": "button.ps4", 73 | "alias": "stick_left", 74 | "icon": "controllers/ps4_stick_left.png" 75 | }, 76 | "button12": { 77 | "name": "button.ps4", 78 | "alias": "stick_right", 79 | "icon": "controllers/ps4_stick_right.png" 80 | }, 81 | "dpadup": { 82 | "name": "button.nintendo", 83 | "alias": "dpad_up", 84 | "icon": "controllers/ps4_dpad_up.png" 85 | }, 86 | "dpaddo": { 87 | "name": "button.nintendo", 88 | "alias": "dpad_down", 89 | "icon": "controllers/ps4_dpad_down.png" 90 | }, 91 | "dpadle": { 92 | "name": "button.nintendo", 93 | "alias": "dpad_left", 94 | "icon": "controllers/ps4_dpad_left.png" 95 | }, 96 | "dpadri": { 97 | "name": "button.nintendo", 98 | "alias": "dpad_right", 99 | "icon": "controllers/ps4_dpad_right.png" 100 | }, 101 | "axis0": { 102 | "name": "axis.ps4.0", 103 | "alias": "left_stick_horizontal", 104 | "icon": "controllers/ps4_stick_left_horizontal.png" 105 | }, 106 | "axis1": { 107 | "name": "axis.ps4.1", 108 | "alias": "left_stick_vertical", 109 | "icon": "controllers/ps4_stick_left_vertical.png" 110 | }, 111 | "axis3": { 112 | "name": "axis.ps4.3", 113 | "alias": "right_stick_horizontal", 114 | "icon": "controllers/ps4_stick_right_horizontal.png" 115 | }, 116 | "axis4": { 117 | "name": "axis.ps4.4", 118 | "alias": "right_stick_vertical", 119 | "icon": "controllers/ps4_stick_right_vertical.png" 120 | }, 121 | "axis_neg0": { 122 | "name": "negat_axis.ps4.0", 123 | "alias": "left_stick_left", 124 | "icon": "controllers/ps4_stick_left_left.png" 125 | }, 126 | "axis_neg1": { 127 | "name": "negat_axis.ps4.1", 128 | "alias": "left_stick_up", 129 | "icon": "controllers/ps4_stick_left_up.png" 130 | }, 131 | "axis_neg3": { 132 | "name": "negat_axis.ps4.3", 133 | "alias": "right_stick_left", 134 | "icon": "controllers/ps4_stick_right_left.png" 135 | }, 136 | "axis_neg4": { 137 | "name": "negat_axis.ps4.4", 138 | "alias": "right_stick_up", 139 | "icon": "controllers/ps4_stick_right_up.png" 140 | }, 141 | "axis_pos0": { 142 | "name": "posit_axis.ps4.0", 143 | "alias": "left_stick_right", 144 | "icon": "controllers/ps4_stick_left_right.png" 145 | }, 146 | "axis_pos1": { 147 | "name": "posit_axis.ps4.1", 148 | "alias": "left_stick_down", 149 | "icon": "controllers/ps4_stick_left_down.png" 150 | }, 151 | "axis_pos3": { 152 | "name": "posit_axis.ps4.3", 153 | "alias": "right_stick_right", 154 | "icon": "controllers/ps4_stick_right_right.png" 155 | }, 156 | "axis_pos4": { 157 | "name": "posit_axis.ps4.4", 158 | "alias": "right_stick_down", 159 | "icon": "controllers/ps4_stick_right_down.png" 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/controllermodels/nintendo_wii_u_pro.json: -------------------------------------------------------------------------------- 1 | { 2 | "modelName": "nintendo_wii_u_pro", 3 | "GUID": "050000007e0500003003000001000000", 4 | "os": "linux", 5 | "dupe_buttons": [ 6 | "button20" 7 | ], 8 | "buttons": { 9 | "button0": { 10 | "name": "button.nintendo", 11 | "alias": "face_button_down", 12 | "icon": "controllers/switch_face_button_down.png" 13 | }, 14 | "button1": { 15 | "name": "button.nintendo", 16 | "alias": "face_button_right", 17 | "icon": "controllers/switch_face_button_right.png" 18 | }, 19 | "button2": { 20 | "name": "button.nintendo", 21 | "alias": "face_button_up", 22 | "icon": "controllers/switch_face_button_up.png" 23 | }, 24 | "button3": { 25 | "name": "button.nintendo", 26 | "alias": "face_button_left", 27 | "icon": "controllers/switch_face_button_left.png" 28 | }, 29 | "button4": { 30 | "name": "button.nintendo", 31 | "alias": "bumper_left", 32 | "icon": "controllers/switch_bumper_left.png" 33 | }, 34 | "button5": { 35 | "name": "button.nintendo", 36 | "alias": "bumper_right", 37 | "icon": "controllers/switch_bumper_right.png" 38 | }, 39 | "button6": { 40 | "name": "button.nintendo", 41 | "alias": "left_trigger", 42 | "icon": "controllers/switch_left_trigger.png" 43 | }, 44 | "button7": { 45 | "name": "button.nintendo", 46 | "alias": "right_trigger", 47 | "icon": "controllers/switch_right_trigger.png" 48 | }, 49 | "button8": { 50 | "name": "button.nintendo", 51 | "alias": "select_button", 52 | "icon": "controllers/switch_select_button.png" 53 | }, 54 | "button9": { 55 | "name": "button.nintendo", 56 | "alias": "start_button", 57 | "icon": "controllers/switch_start_button.png" 58 | }, 59 | "button10": { 60 | "name": "button.nintendo", 61 | "alias": "guide_button", 62 | "icon": "controllers/wii_u_pro_guide_button.png" 63 | }, 64 | "button11": { 65 | "name": "button.nintendo", 66 | "alias": "stick_left", 67 | "icon": "controllers/switch_stick_left.png" 68 | }, 69 | "button12": { 70 | "name": "button.nintendo", 71 | "alias": "stick_right", 72 | "icon": "controllers/switch_stick_right.png" 73 | }, 74 | "button13": { 75 | "name": "button.nintendo", 76 | "alias": "dpad_up", 77 | "icon": "controllers/wii_u_pro_dpad_up.png" 78 | }, 79 | "button14": { 80 | "name": "button.nintendo", 81 | "alias": "dpad_down", 82 | "icon": "controllers/wii_u_pro_dpad_down.png" 83 | }, 84 | "button15": { 85 | "name": "button.nintendo", 86 | "alias": "dpad_left", 87 | "icon": "controllers/wii_u_pro_dpad_left.png" 88 | }, 89 | "button16": { 90 | "name": "button.nintendo", 91 | "alias": "dpad_right", 92 | "icon": "controllers/wii_u_pro_dpad_right.png" 93 | }, 94 | "axis0": { 95 | "name": "axis.nintendo.0", 96 | "alias": "left_stick_horizontal", 97 | "icon": "controllers/switch_stick_left_horizontal.png" 98 | }, 99 | "axis1": { 100 | "name": "axis.nintendo.1", 101 | "alias": "left_stick_vertical", 102 | "icon": "controllers/switch_stick_left_vertical.png" 103 | }, 104 | "axis2": { 105 | "name": "axis.nintendo.2", 106 | "alias": "right_stick_horizontal", 107 | "icon": "controllers/switch_stick_right_horizontal.png" 108 | }, 109 | "axis3": { 110 | "name": "axis.nintendo.3", 111 | "alias": "right_stick_vertical", 112 | "icon": "controllers/switch_stick_right_vertical.png" 113 | }, 114 | "axis_neg0": { 115 | "name": "negat_axis.nintendo.0", 116 | "alias": "left_stick_left", 117 | "icon": "controllers/switch_stick_left_left.png" 118 | }, 119 | "axis_neg1": { 120 | "name": "negat_axis.nintendo.1", 121 | "alias": "left_stick_up", 122 | "icon": "controllers/switch_stick_left_up.png" 123 | }, 124 | "axis_neg2": { 125 | "name": "negat_axis.nintendo.2", 126 | "alias": "right_stick_left", 127 | "icon": "controllers/switch_stick_right_left.png" 128 | }, 129 | "axis_neg3": { 130 | "name": "negat_axis.nintendo.3", 131 | "alias": "right_stick_up", 132 | "icon": "controllers/switch_stick_right_up.png" 133 | }, 134 | "axis_pos0": { 135 | "name": "posit_axis.nintendo.0", 136 | "alias": "left_stick_right", 137 | "icon": "controllers/switch_stick_left_right.png" 138 | }, 139 | "axis_pos1": { 140 | "name": "posit_axis.nintendo.1", 141 | "alias": "left_stick_down", 142 | "icon": "controllers/switch_stick_left_down.png" 143 | }, 144 | "axis_pos2": { 145 | "name": "posit_axis.nintendo.2", 146 | "alias": "right_stick_right", 147 | "icon": "controllers/switch_stick_right_right.png" 148 | }, 149 | "axis_pos3": { 150 | "name": "posit_axis.nintendo.3", 151 | "alias": "right_stick_down", 152 | "icon": "controllers/switch_stick_right_down.png" 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/gui/toasts/ControllerStatusToast.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.gui.toasts; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | import com.google.common.collect.ImmutableList; 8 | import com.mojang.blaze3d.systems.RenderSystem; 9 | import com.mojang.blaze3d.vertex.PoseStack; 10 | import com.stereowalker.controllermod.ControllerMod; 11 | 12 | import net.minecraft.client.Minecraft; 13 | import net.minecraft.client.gui.Font; 14 | import net.minecraft.client.gui.components.toasts.Toast; 15 | import net.minecraft.client.gui.components.toasts.ToastComponent; 16 | import net.minecraft.client.renderer.GameRenderer; 17 | import net.minecraft.network.chat.Component; 18 | import net.minecraft.network.chat.TranslatableComponent; 19 | import net.minecraft.resources.ResourceLocation; 20 | import net.minecraft.util.FormattedCharSequence; 21 | 22 | public class ControllerStatusToast implements Toast { 23 | private long firstDrawTime; 24 | private boolean newDisplay; 25 | List subtitles; 26 | private final int width; 27 | private ControllerStatusToast.Type type; 28 | public static final ResourceLocation ICON = ControllerMod.getInstance().location("textures/gui/controller_icon.png"); 29 | public static final ResourceLocation TEXTURE_TOASTS = ControllerMod.getInstance().location("textures/gui/toasts.png"); 30 | 31 | public ControllerStatusToast(ControllerStatusToast.Type type, @Nullable Component subtitleComponent) { 32 | this(type, func_238537_a_(subtitleComponent), 160); 33 | } 34 | 35 | public static ControllerStatusToast func_238534_a_(ControllerStatusToast.Type type, Minecraft p_238534_0_, Component p_238534_3_) { 36 | Font fontrenderer = p_238534_0_.font; 37 | List list = fontrenderer.split(p_238534_3_, 200); 38 | int i = Math.max(200, list.stream().mapToInt(fontrenderer::width).max().orElse(200)); 39 | return new ControllerStatusToast(type, list, i + 30); 40 | } 41 | 42 | private ControllerStatusToast(ControllerStatusToast.Type type, List p_i232264_3_, int p_i232264_4_) { 43 | this.subtitles = p_i232264_3_; 44 | this.width = p_i232264_4_; 45 | this.type = type; 46 | } 47 | 48 | private static ImmutableList func_238537_a_(@Nullable Component p_238537_0_) { 49 | return p_238537_0_ == null ? ImmutableList.of() : ImmutableList.of(p_238537_0_.getVisualOrderText()); 50 | } 51 | 52 | @Override 53 | public int width() { 54 | return this.width; 55 | } 56 | 57 | @SuppressWarnings({ "resource" }) 58 | @Override 59 | public Toast.Visibility render(PoseStack matrixStack, ToastComponent toastGui, long drawTime) { 60 | if (this.newDisplay) { 61 | this.firstDrawTime = drawTime; 62 | this.newDisplay = false; 63 | } 64 | 65 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 66 | RenderSystem.setShaderTexture(0, TEXTURE_TOASTS); 67 | RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); 68 | int i = this.width(); 69 | toastGui.blit(matrixStack, 0, 0, 0, 32, i, this.height()); 70 | matrixStack.pushPose(); 71 | RenderSystem.enableBlend(); 72 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 73 | RenderSystem.setShaderTexture(0, ICON); 74 | toastGui.blit(matrixStack, 6, 6, 0 * 20, 0 * 20, 20, 20); 75 | RenderSystem.enableBlend(); 76 | matrixStack.popPose(); 77 | if (this.subtitles == null) { 78 | toastGui.getMinecraft().font.draw(matrixStack, type.getText(), 33.0F, 12.0F, -11534256); 79 | } else { 80 | toastGui.getMinecraft().font.draw(matrixStack, type.getText(), 33.0F, 7.0F, -11534256); 81 | 82 | for(int k1 = 0; k1 < this.subtitles.size(); ++k1) { 83 | toastGui.getMinecraft().font.draw(matrixStack, this.subtitles.get(k1), 33.0F, (float)(18 + k1 * 12), -16777216); 84 | } 85 | } 86 | 87 | return drawTime - this.firstDrawTime < 5000L ? Toast.Visibility.SHOW : Toast.Visibility.HIDE; 88 | } 89 | 90 | public void setType(ControllerStatusToast.Type type, @Nullable Component subtitleComponent) { 91 | this.type = type; 92 | this.subtitles = func_238537_a_(subtitleComponent); 93 | this.newDisplay = true; 94 | } 95 | 96 | public static void func_238536_a_(ToastComponent p_238536_0_, ControllerStatusToast.Type type, @Nullable Component p_238536_3_) { 97 | p_238536_0_.addToast(new ControllerStatusToast(type, p_238536_3_)); 98 | } 99 | 100 | public static void addOrUpdate(ToastComponent p_193657_0_, ControllerStatusToast.Type type, Component p_193657_2_) { 101 | ControllerStatusToast systemtoast = p_193657_0_.getToast(ControllerStatusToast.class, type); 102 | if (systemtoast == null) { 103 | func_238536_a_(p_193657_0_, type, p_193657_2_); 104 | } else { 105 | systemtoast.setType(type, p_193657_2_); 106 | } 107 | 108 | } 109 | 110 | public enum Type { 111 | CONNECT(new TranslatableComponent("controller.connected")), 112 | DISCONNECT(new TranslatableComponent("controller.disconnected")); 113 | 114 | Component text; 115 | private Type(Component text) { 116 | this.text = text; 117 | } 118 | 119 | public Component getText() { 120 | return text; 121 | } 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/gui/screen/ControllerSettingsScreen.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.gui.screen; 2 | 3 | import org.lwjgl.glfw.GLFW; 4 | 5 | import com.mojang.blaze3d.vertex.PoseStack; 6 | import com.stereowalker.controllermod.ControllerMod; 7 | import com.stereowalker.controllermod.client.ControllerOptions; 8 | import com.stereowalker.controllermod.client.controller.ControllerModel; 9 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 10 | import com.stereowalker.controllermod.resources.ControllerModelManager; 11 | 12 | import net.minecraft.client.gui.GuiComponent; 13 | import net.minecraft.client.gui.components.Button; 14 | import net.minecraft.client.gui.screens.Screen; 15 | import net.minecraft.network.chat.Component; 16 | import net.minecraft.network.chat.TextComponent; 17 | import net.minecraft.network.chat.TranslatableComponent; 18 | import net.minecraftforge.api.distmarker.Dist; 19 | import net.minecraftforge.api.distmarker.OnlyIn; 20 | 21 | @OnlyIn(Dist.CLIENT) 22 | public class ControllerSettingsScreen extends Screen { 23 | private final Screen previousScreen; 24 | private Button nextController; 25 | private Button prevController; 26 | private Button controller; 27 | private ControllerMod mod; 28 | 29 | public ControllerSettingsScreen(Screen screenIn) { 30 | super(new TranslatableComponent("options.controller_settings.title")); 31 | this.previousScreen = screenIn; 32 | this.mod = ControllerMod.getInstance(); 33 | } 34 | 35 | @Override 36 | public void init() { 37 | ControllerOptions options = this.mod.controllerOptions; 38 | options.lastGUID = ControllerMod.getInstance().getActiveController().getGUID(); 39 | options.saveOptions(); 40 | for (ControllerModel model : ControllerModelManager.ALL_MODELS.values()) { 41 | if (model.getGUID().equals( 42 | ControllerMod.getInstance().getActiveController().getGUID())) { 43 | this.mod.controllerOptions.controllerModel = model; 44 | } 45 | } 46 | boolean hasName = GLFW.glfwGetJoystickName(options.controllerNumber) != null; 47 | boolean controllerPresent = ControllerUtil.isControllerAvailable(ControllerMod.getInstance().controllerOptions.controllerNumber); 48 | prevController = this.addRenderableWidget(new Button(this.width / 2 - 155, this.height / 6, 20, 20, new TextComponent("<<"), (p_212984_1_) -> { 49 | if(options.controllerNumber>0)options.controllerNumber = options.controllerNumber-1; 50 | if (!ControllerUtil.isControllerAvailable(options.controllerNumber)) options.enableController = false; 51 | this.minecraft.setScreen(new ControllerSettingsScreen(previousScreen)); 52 | })); 53 | Component name; 54 | if (hasName) { 55 | name = new TranslatableComponent("<").append((options.controllerNumber+1)+"> "+GLFW.glfwGetJoystickName(options.controllerNumber)+" [").append(new TranslatableComponent(ControllerUtil.isControllerAvailable(options.controllerNumber) ? "controller.connected" : "controller.disconnected")).append("]"+" : ").append(new TranslatableComponent(options.enableController ? "options.on" : "options.off")); 56 | } else { 57 | name = new TranslatableComponent("<").append((options.controllerNumber+1)+"> "); 58 | } 59 | if (!controllerPresent) { 60 | this.mod.controllerOptions.controllerModel = ControllerModel.CUSTOM; 61 | } 62 | controller = this.addRenderableWidget(new Button(this.width / 2 - 125, this.height / 6, 250, 20, name, (p_212984_1_) -> { 63 | options.enableController = !options.enableController; 64 | this.minecraft.setScreen(new ControllerSettingsScreen(previousScreen)); 65 | })); 66 | nextController = this.addRenderableWidget(new Button(this.width / 2 + 135, this.height / 6, 20, 20, new TextComponent(">>"), (p_212984_1_) -> { 67 | if(options.controllerNumber { 72 | this.minecraft.setScreen(new PaperDollOptionsScreen(previousScreen)); 73 | })); 74 | Button trigger = this.addRenderableWidget(new Button(this.width / 2 + 5, this.height / 6 + 24, 150, 20, new TranslatableComponent("gui.triggerSetup"), (p_212984_1_) -> { 75 | this.minecraft.setScreen(new TriggerSetupScreen(this)); 76 | })); 77 | if (options.enableController && controllerPresent) { 78 | trigger.active = (this.mod.controllerOptions.controllerModel == ControllerModel.CUSTOM || ControllerMod.CONFIG.debug) && mod. 79 | getActiveController(). 80 | getAxes() != null && 81 | mod. 82 | getActiveController(). 83 | getAxes(). 84 | capacity() > 0; 85 | } 86 | else { 87 | trigger.active = false; 88 | } 89 | this.addRenderableWidget(new Button(this.width / 2 - 100, this.height / 6 + 168, 200, 20, new TranslatableComponent("gui.done"), (p_212984_1_) -> { 90 | this.minecraft.setScreen(this.previousScreen); 91 | })); 92 | nextController.active = options.controllerNumber0; 94 | controller.active = hasName && controllerPresent; 95 | } 96 | 97 | @Override 98 | public void removed() { 99 | ControllerMod.getInstance().controllerOptions.saveOptions(); 100 | } 101 | 102 | @Override 103 | public void render(PoseStack matrixStack, int mouseX, int mouseY, float partialTicks) { 104 | this.renderBackground(matrixStack); 105 | GuiComponent.drawCenteredString(matrixStack, this.font, this.title, this.width / 2, 15, 16777215); 106 | super.render(matrixStack, mouseX, mouseY, partialTicks); 107 | } 108 | } -------------------------------------------------------------------------------- /src/main/resources/assets/controllermod/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment0_": "///////////////////////////////////////////////////////////[CONTROLLER_BUTTONS]///////////////////////////////////////////////////////////", 3 | "button.ps4.face_button_left": "SQUARE", 4 | "button.ps4.face_button_down": "CROSS", 5 | "button.ps4.face_button_right": "CIRCLE", 6 | "button.ps4.face_button_up": "TRIANGLE", 7 | "button.ps4.bumper_left": "L1", 8 | "button.ps4.bumper_right": "R1", 9 | "button.ps4.left_trigger": "L2", 10 | "button.ps4.right_trigger": "R2", 11 | "button.ps4.start_button": "OPTIONS", 12 | "button.ps4.select_button": "SHARE", 13 | "button.ps4.stick_left": "L3", 14 | "button.ps4.stick_right": "R3", 15 | "button.ps4.touchpad": "TOUCHPAD", 16 | "button.ps4.dpad_up": "UP", 17 | "button.ps4.dpad_right": "RIGHT", 18 | "button.ps4.dpad_down": "DOWN", 19 | "button.ps4.dpad_left": "LEFT", 20 | "button.xbox_360.face_button_down": "A", 21 | "button.xbox_360.face_button_right": "B", 22 | "button.xbox_360.face_button_left": "X", 23 | "button.xbox_360.face_button_up": "Y", 24 | "button.xbox_360.bumper_left": "LB", 25 | "button.xbox_360.bumper_right": "RB", 26 | "button.xbox_360.select_button": "BACK", 27 | "_comment1_": "///////////////////////////////////////////////////////////[KEYBINDS]///////////////////////////////////////////////////////////", 28 | "key.categories.controller": "\u00A73\u00A7oController", 29 | "key.controller.hotbar_left": "Cycle Item Left", 30 | "key.controller.hotbar_right": "Cycle Item Right", 31 | "key.controller.split": "Split Items", 32 | "key.controller.quickMove": "Quick Move", 33 | "key.controller.pause": "Pause", 34 | "key.controller.back": "Back", 35 | "key.controller.left_click": "Left Click", 36 | "key.controller.camera_horizontal": "Camera Horizontal", 37 | "key.controller.camera_vertical": "Camera Vertical", 38 | "key.controller.move_horizontal": "Move Horizontal", 39 | "key.controller.move_vertical": "Move Vertical", 40 | "key.controller.mouse_horizontal": "Mouse Horizontal", 41 | "key.controller.mouse_vertical": "Mouse Vertical", 42 | "key.controller.scroll": "Scroll", 43 | "key.categories.on_screen_keyboard": "\u00A74\u00A7oOn-Screen Keyboard", 44 | "key.controller.keyboard": "Toggle Keyboard", 45 | "key.controller.keyboard_arrow_left": "Move Cursor Left", 46 | "key.controller.keyboard_arrow_right": "Move Cursor Right", 47 | "key.controller.keyboard_backspace": "Backspace", 48 | "key.controller.keyboard_caps": "Caps Lock", 49 | "key.controller.keyboard_left": "Navigate Left", 50 | "key.controller.keyboard_right": "Navigate Right", 51 | "key.controller.keyboard_up": "Navigate Up", 52 | "key.controller.keyboard_down": "Navigate Down", 53 | "key.controller.keyboard_space": "Space", 54 | "key.controller.keyboard_select": "Select Letter", 55 | "key.override.inventory": "Inventory", 56 | "key.override.jump": "Jump/Fly Up", 57 | "key.override.attack": "Attack/Destroy", 58 | "key.override.use": "Use Item/Place Block", 59 | "key.override.sneak": "Sneak/Fly Down", 60 | "key.override.togglePerspective": "Toggle Perspective", 61 | "key.override.drop": "Drop Item", 62 | "key.override.forward": "Walk Forward", 63 | "key.override.back": "Walk Backward", 64 | "key.override.left": "Strafe Left", 65 | "key.override.right": "Strafe Right", 66 | "key.override.chat": "Open Chat", 67 | "key.override.sprint": "Sprint", 68 | "_comment2_": "///////////////////////////////////////////////////////////[TITLES]///////////////////////////////////////////////////////////", 69 | "options.controller_settings.title": "Controller Settings", 70 | "options.controller_input.title": "Controller Bindings", 71 | "options.paper_doll.title": "Paper Doll Options", 72 | "_comment3_": "///////////////////////////////////////////////////////////[GUI]///////////////////////////////////////////////////////////", 73 | "controllermod.config.title": "Controller Support Config", 74 | "controllermod.debug_mode": "Debug Mode", 75 | "trigger_setup.title": "Trigger Setup", 76 | "controller.connected": "Connected", 77 | "controller.disconnected": "Disconnected", 78 | "options.controller_settings": "Controller Settings...", 79 | "controls.controllerbinds": "Controller Binds...", 80 | "gui.enableController": "Enable Controller", 81 | "gui.save": "Save", 82 | "gui.ingameSensitivity": "Gameplay Sensitivity", 83 | "gui.menuSensitivity": "Menu Sensitivity", 84 | "gui.invertYAxis": "Invert Y Axis", 85 | "gui.inverted": "Inverted", 86 | "gui.useAxisToMove": "Use Precise Movement", 87 | "gui.controller": "Controller", 88 | "gui.model": "Model", 89 | "gui.deadzone": "Deadzone", 90 | "gui.ingamePlayerNames": "In-Game Player Names", 91 | "gui.paperDollOptions": "Paper Doll Options", 92 | "gui.hideCoordinates": "Hide Coordinates", 93 | "gui.triggerSetup": "Trigger Setup", 94 | "gui.paper_doll.swimming": "Swimming", 95 | "gui.paper_doll.crawling": "Crawling", 96 | "gui.paper_doll.sprinting": "Sprinting", 97 | "gui.paper_doll.crouching": "Crouching", 98 | "gui.paper_doll.flying": "Flying", 99 | "gui.paper_doll.gliding": "Gliding", 100 | "gui.paper_doll.riding": "Riding", 101 | "gui.paper_doll.spinning": "Spinning", 102 | "gui.paper_doll.moving": "Moving", 103 | "gui.paper_doll.jumping": "Jumping", 104 | "gui.paper_doll.swinging_arm": "Swinging Arm", 105 | "gui.paper_doll.using_item": "Using Item", 106 | "gui.paper_doll.hurt": "Hurt", 107 | "gui.paper_doll.on_fire": "On Fire", 108 | 109 | "gui.positive_triggers": "Positive Triggers", 110 | "gui.negative_triggers": "Negative Triggers", 111 | "gui.trigger.unmark": "Unmark As Trigger", 112 | "gui.trigger.mark": "Mark As Trigger", 113 | "_comment4_": "///////////////////////////////////////////////////////////[MISC]///////////////////////////////////////////////////////////", 114 | "input_type.press": "Press", 115 | "input_type.toggle": "Toggle", 116 | "input_type.hold": "Hold", 117 | "_comment5_": "///////////////////////////////////////////////////////////[MISC]///////////////////////////////////////////////////////////", 118 | "model.ps4": "Dualshock 4", 119 | "model.xbox_360": "Xbox 360", 120 | "model.custom": "Custom", 121 | "model.nintendo_wii_u_pro": "Nintendo Wii U Pro" 122 | } -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/ControllerMod.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | 9 | import com.stereowalker.controllermod.client.ControllerHandler; 10 | import com.stereowalker.controllermod.client.ControllerOptions; 11 | import com.stereowalker.controllermod.client.OnScreenKeyboard; 12 | import com.stereowalker.controllermod.client.PaperDollOptions; 13 | import com.stereowalker.controllermod.client.controller.Controller; 14 | import com.stereowalker.controllermod.client.controller.ControllerBindings; 15 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 16 | import com.stereowalker.controllermod.config.Config; 17 | import com.stereowalker.controllermod.resources.ControllerModelManager; 18 | import com.stereowalker.unionlib.client.gui.screens.config.ConfigScreen; 19 | import com.stereowalker.unionlib.config.ConfigBuilder; 20 | import com.stereowalker.unionlib.mod.MinecraftMod; 21 | 22 | import net.minecraft.client.Minecraft; 23 | import net.minecraft.client.gui.screens.Screen; 24 | import net.minecraft.resources.ResourceLocation; 25 | import net.minecraftforge.api.distmarker.Dist; 26 | import net.minecraftforge.api.distmarker.OnlyIn; 27 | import net.minecraftforge.client.gui.OverlayRegistry; 28 | import net.minecraftforge.common.MinecraftForge; 29 | import net.minecraftforge.fml.common.Mod; 30 | import net.minecraft.util.Mth; 31 | 32 | @Mod(value = ControllerMod.MOD_ID) 33 | @OnlyIn(Dist.CLIENT) 34 | public class ControllerMod extends MinecraftMod 35 | { 36 | // 37 | public static int getSafeArea() {return Mth.ceil((1.0f - (CONFIG.safe_area/100.0f)) * 10.0f);} 38 | // 39 | public static ControllerMod instance; 40 | private ControllerHandler controllerHandler; 41 | public ControllerModelManager controllerModelManager; 42 | public OnScreenKeyboard onScreenKeyboard; 43 | public static final String MOD_ID = "controllermod"; 44 | public static final Logger LOGGER = LogManager.getLogger(MOD_ID); 45 | public static final Config CONFIG = new Config(); 46 | public List controllers; 47 | public ControllerOptions controllerOptions; 48 | public static final Controller EMPTY_CONTROLLER = new Controller(-1, "Empty", "Empty", 0); 49 | public static final ResourceLocation CONTROLLER_BUTTON_TEXTURES = new ResourceLocation(ControllerMod.MOD_ID, "textures/gui/controller_button.png"); 50 | 51 | public ControllerMod() 52 | { 53 | super(MOD_ID, new ResourceLocation(MOD_ID, "textures/gui/controller_icon2.png"), LoadType.CLIENT); 54 | MinecraftForge.EVENT_BUS.register(this); 55 | instance = this; 56 | ConfigBuilder.registerConfig(CONFIG); 57 | controllers = new ArrayList(); 58 | } 59 | 60 | @Override 61 | public void onModStartupInClient() { 62 | OverlayRegistry.registerOverlayTop("Paper Doll", (gui, mStack, partialTicks, screenWidth, screenHeight) -> { 63 | gui.setupOverlayRenderState(true, false); 64 | PaperDollOptions.renderPlayerDoll(gui, mStack); 65 | }); 66 | } 67 | 68 | @Override 69 | public void registerClientRelaodableResources(ReloadListeners listeners) { 70 | this.controllerModelManager = new ControllerModelManager(); 71 | listeners.listenTo(this.controllerModelManager); 72 | } 73 | 74 | @Override 75 | public void initClientAfterMinecraft(Minecraft mc) { 76 | LOGGER.info("Setting up all connected controlllers"); 77 | this.controllerHandler = new ControllerHandler(this, mc); 78 | this.controllerHandler.setup(mc.getWindow().getWindow()); 79 | this.onScreenKeyboard = new OnScreenKeyboard(mc); 80 | this.controllerOptions = new ControllerOptions(mc, mc.gameDirectory); 81 | ControllerBindings.registerAll(); 82 | this.controllerOptions.loadOptions(); 83 | } 84 | 85 | public void disconnectControllers() { 86 | LOGGER.info("Disconnecting all "+this.getTotalConnectedControllers()+" controllers"); 87 | this.controllers.clear(); 88 | } 89 | 90 | public void connectControllers() { 91 | LOGGER.info("Total Connected Controllers "+this.getTotalConnectedControllers()); 92 | for (int i = 0; i < this.getTotalConnectedControllers(); i++) { 93 | if (ControllerUtil.isControllerAvailable(i)) { 94 | Controller cont = new Controller(i); 95 | if (cont.getActualModel() == null) { 96 | LOGGER.info("Added ("+cont.getName()+") as Controller "+(i+1)+". This is a custom controller and it's ID is "+cont.getGUID()); 97 | } else { 98 | LOGGER.info("Added ("+cont.getName()+") as Controller "+(i+1)+". This is a registered "+cont.getActualModel()+" controller"); 99 | } 100 | this.controllers.add(new Controller(i)); 101 | } 102 | } 103 | } 104 | 105 | public ControllerHandler getControllerHandler() { 106 | return controllerHandler; 107 | } 108 | 109 | @Override 110 | public Screen getConfigScreen(Minecraft mc, Screen previousScreen) { 111 | return new ConfigScreen(previousScreen, CONFIG); 112 | } 113 | 114 | public int getTotalConnectedControllers() { 115 | int maxControllers = 0; 116 | for (int i = 0; i < 16; i++) { 117 | if (ControllerUtil.isControllerAvailable(i)) { 118 | maxControllers = i+1; 119 | } 120 | } 121 | return maxControllers; 122 | } 123 | 124 | public Controller getController(int id) { 125 | for(Controller controller : controllers) { 126 | if (controller.getId() == id) { 127 | return controller; 128 | } 129 | } 130 | return EMPTY_CONTROLLER; 131 | } 132 | 133 | public Controller getActiveController() { 134 | return getController(controllerOptions.controllerNumber) == null ? EMPTY_CONTROLLER : getController(controllerOptions.controllerNumber); 135 | } 136 | 137 | 138 | public static ControllerMod getInstance() { 139 | return instance; 140 | } 141 | 142 | public static void debug(String message) { 143 | if (CONFIG.debug)LOGGER.info(message); 144 | } 145 | 146 | public static void debug(String message, Object o1) { 147 | if (CONFIG.debug)LOGGER.info(message, o1); 148 | } 149 | 150 | public ResourceLocation location(String name) 151 | { 152 | return new ResourceLocation(MOD_ID, name); 153 | } 154 | 155 | public static class Locations { 156 | public static final ResourceLocation CURSOR = new ResourceLocation(ControllerMod.MOD_ID, "textures/gui/pointer.png"); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/gui/screen/ControllerInputOptionsScreen.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.gui.screen; 2 | 3 | import java.util.List; 4 | 5 | import org.lwjgl.glfw.GLFW; 6 | 7 | import com.google.common.collect.Lists; 8 | import com.mojang.blaze3d.vertex.PoseStack; 9 | import com.stereowalker.controllermod.ControllerMod; 10 | import com.stereowalker.controllermod.client.controller.ControllerMapping; 11 | import com.stereowalker.controllermod.client.controller.ControllerModel; 12 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 13 | import com.stereowalker.controllermod.client.controller.ControllerUtil.ListeningMode; 14 | import com.stereowalker.controllermod.client.gui.widget.list.ControllerBindingList; 15 | import com.stereowalker.controllermod.resources.ControllerModelManager; 16 | 17 | import net.minecraft.client.gui.GuiComponent; 18 | import net.minecraft.client.gui.components.Button; 19 | import net.minecraft.client.gui.screens.Screen; 20 | import net.minecraft.network.chat.CommonComponents; 21 | import net.minecraft.network.chat.TranslatableComponent; 22 | import net.minecraftforge.api.distmarker.Dist; 23 | import net.minecraftforge.api.distmarker.OnlyIn; 24 | 25 | @OnlyIn(Dist.CLIENT) 26 | public class ControllerInputOptionsScreen extends Screen { 27 | private final Screen previousScreen; 28 | /** The ID of the button that has been pressed. */ 29 | public ControllerMapping keyToSet; 30 | private int[] previousInputs; 31 | private ControllerBindingList keyBindingList; 32 | private ControllerMod mod; 33 | private Button buttonReset; 34 | 35 | public ControllerInputOptionsScreen(Screen previousScreen, ControllerMapping keyToSet, int[] previousInputs) { 36 | super(new TranslatableComponent("options.controller_input.title")); 37 | this.previousScreen = previousScreen; 38 | this.keyToSet = keyToSet; 39 | this.previousInputs = previousInputs; 40 | this.mod = ControllerMod.getInstance(); 41 | } 42 | 43 | @Override 44 | public void init() { 45 | boolean isModelEnforced = false; 46 | for (ControllerModel model : ControllerModelManager.ALL_MODELS.values()) { 47 | if (model.getGUID().equals( 48 | ControllerMod.getInstance().getActiveController().getGUID())) { 49 | this.mod.controllerOptions.controllerModel = model; 50 | isModelEnforced = true; 51 | } 52 | } 53 | if (!isModelEnforced && !ControllerUtil.isControllerAvailable(mod.controllerOptions.controllerNumber)) { 54 | this.mod.controllerOptions.controllerModel = ControllerModel.CUSTOM; 55 | isModelEnforced = true; 56 | } 57 | this.keyBindingList = new ControllerBindingList(this, this.minecraft, ControllerMod.getInstance()); 58 | this.addWidget(this.keyBindingList); 59 | this.buttonReset = this.addRenderableWidget(new Button(this.width / 2 - 165, this.height - 29, 100, 20, new TranslatableComponent("controls.resetAll"), (p_213125_1_) -> { 60 | for(ControllerMapping keybinding : mod.controllerOptions.controllerBindings) { 61 | keybinding.setToDefault(this.mod.controllerOptions.controllerModel); 62 | } 63 | 64 | ControllerMapping.resetMapping(); 65 | })); 66 | Button model = this.addRenderableWidget(new Button(this.width / 2 - 155 + 95, this.height - 29, 120, 20, new TranslatableComponent("gui.model").append(" : ").append(this.mod.controllerOptions.controllerModel.getDisplayName(ControllerMod.CONFIG.debug)), (p_212984_1_) -> { 67 | this.mod.controllerOptions.controllerModel = ControllerModel.nextModel(this.mod.controllerOptions.controllerModel); 68 | this.minecraft.setScreen(new ControllerInputOptionsScreen(previousScreen, keyToSet, new int[] {0})); 69 | })); 70 | model.active = !isModelEnforced; 71 | this.addRenderableWidget(new Button(this.width / 2 - 145 + 210, this.height - 29, 100, 20, CommonComponents.GUI_DONE, (p_213124_1_) -> { 72 | this.minecraft.setScreen(this.previousScreen); 73 | })); 74 | } 75 | 76 | @Override 77 | public boolean keyPressed(int keyCode, int scanCode, int modifiers) { 78 | if (keyCode == GLFW.GLFW_KEY_ESCAPE && keyToSet != null) { 79 | ControllerMod.getInstance().controllerOptions.setKeyBindingCode(this.mod.controllerOptions.controllerModel, keyToSet, Lists.newArrayList(" ")); 80 | ControllerMapping.resetMapping(); 81 | } 82 | return super.keyPressed(keyCode, scanCode, modifiers); 83 | } 84 | 85 | @Override 86 | public void removed() { 87 | mod.controllerOptions.saveOptions(); 88 | } 89 | 90 | private int awaitingTicks = 0; 91 | @Override 92 | public void tick() { 93 | if (ControllerMod.getInstance().controllerOptions.enableController && ControllerMod.getInstance().getActiveController() != null) { 94 | if (keyToSet != null) { 95 | List buttons; 96 | if (keyToSet.isAxis()) buttons = ControllerMod.getInstance().getActiveController().getAxesMoved(); 97 | else buttons = ControllerMod.getInstance().getActiveController().getButtonsDown(); 98 | ControllerUtil.listeningMode = ListeningMode.CHANGE_MAPPINGS; 99 | awaitingTicks++; 100 | if (awaitingTicks > 5 && awaitingTicks < 100 && buttons.size() > 0 && buttons.size() <= 2) { 101 | ControllerMod.debug(buttons.toString()); 102 | ControllerMod.getInstance().controllerOptions.setKeyBindingCode(this.mod.controllerOptions.controllerModel, keyToSet, keyToSet.isAxis() ? Lists.newArrayList(buttons.get(0)) : buttons); 103 | keyToSet = null; 104 | ControllerMapping.resetMapping(); 105 | } 106 | if (awaitingTicks >= 100) { 107 | List prev = Lists.newArrayList(); 108 | for (int i = 0; i < previousInputs.length; i++) { 109 | prev.add(ControllerUtil.getControllerInputId(previousInputs[i])); 110 | } 111 | ControllerMod.getInstance().controllerOptions.setKeyBindingCode(this.mod.controllerOptions.controllerModel, keyToSet, prev); 112 | keyToSet = null; 113 | ControllerMapping.resetMapping(); 114 | } 115 | } 116 | else { 117 | awaitingTicks = 0; 118 | ControllerUtil.listeningMode = ListeningMode.LISTEN_TO_MAPPINGS; 119 | } 120 | } else { 121 | keyToSet = null; 122 | } 123 | } 124 | 125 | public boolean isAwaitingInput() { 126 | return awaitingTicks > 0; 127 | } 128 | 129 | @Override 130 | public void render(PoseStack matrixStack, int mouseX, int mouseY, float partialTicks) { 131 | this.renderBackground(matrixStack); 132 | this.keyBindingList.render(matrixStack, mouseX, mouseY, partialTicks); 133 | GuiComponent.drawCenteredString(matrixStack, this.font, this.title, this.width / 2, 15, 16777215); 134 | boolean flag = false; 135 | 136 | for(ControllerMapping keybinding : mod.controllerOptions.controllerBindings) { 137 | if (!keybinding.isDefault(this.mod.controllerOptions.controllerModel)) { 138 | flag = true; 139 | break; 140 | } 141 | } 142 | 143 | this.buttonReset.active = flag; 144 | super.render(matrixStack, mouseX, mouseY, partialTicks); 145 | } 146 | } -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/gui/widget/list/TriggerAxesList.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.gui.widget.list; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import com.google.common.collect.ImmutableList; 7 | import com.mojang.blaze3d.vertex.PoseStack; 8 | import com.stereowalker.controllermod.ControllerMod; 9 | import com.stereowalker.controllermod.client.gui.screen.TriggerSetupScreen; 10 | 11 | import net.minecraft.ChatFormatting; 12 | import net.minecraft.client.Minecraft; 13 | import net.minecraft.client.gui.components.Button; 14 | import net.minecraft.client.gui.components.ContainerObjectSelectionList; 15 | import net.minecraft.client.gui.components.events.GuiEventListener; 16 | import net.minecraft.client.gui.narration.NarratableEntry; 17 | import net.minecraft.network.chat.Component; 18 | import net.minecraft.network.chat.MutableComponent; 19 | import net.minecraft.network.chat.TranslatableComponent; 20 | import net.minecraftforge.api.distmarker.Dist; 21 | import net.minecraftforge.api.distmarker.OnlyIn; 22 | 23 | @OnlyIn(Dist.CLIENT) 24 | public class TriggerAxesList extends ContainerObjectSelectionList { 25 | private ControllerMod mod; 26 | 27 | public TriggerAxesList(TriggerSetupScreen controls, Minecraft mcIn, ControllerMod modIn) { 28 | super(mcIn, controls.width + 45, controls.height, 43, controls.height - 32, 20); 29 | this.mod = modIn; 30 | this.addEntry(new TriggerAxesList.CategoryEntry(new TranslatableComponent("gui.positive_triggers"))); 31 | for (int i = 0; i < mod.getActiveController().getAxes().capacity(); i++) { 32 | this.addEntry(new TriggerAxesList.TriggerEntry(new TranslatableComponent("Positive Axis "+ i), true, i)); 33 | } 34 | 35 | this.addEntry(new TriggerAxesList.CategoryEntry(new TranslatableComponent("gui.negative_triggers"))); 36 | for (int i = 0; i < mod.getActiveController().getAxes().capacity(); i++) { 37 | this.addEntry(new TriggerAxesList.TriggerEntry(new TranslatableComponent("Negative Axis "+ i), false, i)); 38 | } 39 | } 40 | 41 | @Override 42 | protected int getScrollbarPosition() { 43 | return super.getScrollbarPosition() + 15 + 40; 44 | } 45 | 46 | @Override 47 | public int getRowWidth() { 48 | return super.getRowWidth() + 72; 49 | } 50 | 51 | @OnlyIn(Dist.CLIENT) 52 | public class CategoryEntry extends TriggerAxesList.Entry { 53 | private final Component labelText; 54 | private final int labelWidth; 55 | 56 | public CategoryEntry(Component p_i232280_2_) { 57 | this.labelText = p_i232280_2_; 58 | this.labelWidth = TriggerAxesList.this.minecraft.font.width(this.labelText); 59 | } 60 | 61 | @Override 62 | public void render(PoseStack p_230432_1_, int p_230432_2_, int p_230432_3_, int p_230432_4_, int p_230432_5_, int p_230432_6_, int p_230432_7_, int p_230432_8_, boolean p_230432_9_, float p_230432_10_) { 63 | TriggerAxesList.this.minecraft.font.draw(p_230432_1_, this.labelText, (float)(TriggerAxesList.this.minecraft.screen.width / 2 - this.labelWidth / 2), (float)(p_230432_3_ + p_230432_6_ - 9 - 1), 16777215); 64 | } 65 | 66 | @Override 67 | public boolean changeFocus(boolean focus) { 68 | return false; 69 | } 70 | 71 | @Override 72 | public List children() { 73 | return Collections.emptyList(); 74 | } 75 | 76 | @Override 77 | public List narratables() { 78 | return Collections.emptyList(); 79 | } 80 | } 81 | 82 | @OnlyIn(Dist.CLIENT) 83 | public class TriggerEntry extends TriggerAxesList.Entry { 84 | private final Button btnTrigger; 85 | private final Component labelText; 86 | private final boolean isPostitve; 87 | private final int axis; 88 | 89 | public TriggerEntry(Component p_i232280_2_, boolean isPostitve, int axis) { 90 | this.labelText = p_i232280_2_; 91 | this.isPostitve = isPostitve; 92 | this.axis = axis; 93 | this.btnTrigger = new Button(0, 0, 100, 20, new TranslatableComponent("gui.trigger.mark"), (p_214387_2_) -> { 94 | if (isPostitve) 95 | if (mod.controllerOptions.positiveTriggerAxes.contains(axis)) 96 | mod.controllerOptions.positiveTriggerAxes.remove(Integer.valueOf(axis)); 97 | else 98 | mod.controllerOptions.positiveTriggerAxes.add(Integer.valueOf(axis)); 99 | else 100 | if (mod.controllerOptions.negativeTriggerAxes.contains(axis)) 101 | mod.controllerOptions.negativeTriggerAxes.remove(Integer.valueOf(axis)); 102 | else 103 | mod.controllerOptions.negativeTriggerAxes.add(Integer.valueOf(axis)); 104 | 105 | mod.controllerOptions.saveOptions(); 106 | }) { 107 | @Override 108 | protected MutableComponent createNarrationMessage() { 109 | return new TranslatableComponent("narrator.controls.reset"); 110 | } 111 | }; 112 | } 113 | 114 | @Override 115 | public void render(PoseStack p_230432_1_, int p_230432_2_, int p_230432_3_, int p_230432_4_, int p_230432_5_, int p_230432_6_, int p_230432_7_, int p_230432_8_, boolean p_230432_9_, float p_230432_10_) { 116 | TriggerAxesList.this.minecraft.font.draw(p_230432_1_, this.labelText, (float)(p_230432_4_), (float)(p_230432_3_ + p_230432_6_ / 2 - 9 / 2), 16777215); 117 | 118 | this.btnTrigger.x = p_230432_4_ + 190; 119 | this.btnTrigger.y = p_230432_3_; 120 | this.btnTrigger.render(p_230432_1_, p_230432_7_, p_230432_8_, p_230432_10_); 121 | 122 | if (isPostitve) 123 | if (mod.controllerOptions.positiveTriggerAxes.contains(axis)) 124 | this.btnTrigger.setMessage(new TranslatableComponent("gui.trigger.unmark").withStyle(ChatFormatting.RED)); 125 | else 126 | this.btnTrigger.setMessage(new TranslatableComponent("gui.trigger.mark").withStyle(ChatFormatting.GREEN)); 127 | else 128 | if (mod.controllerOptions.negativeTriggerAxes.contains(axis)) 129 | this.btnTrigger.setMessage(new TranslatableComponent("gui.trigger.unmark").withStyle(ChatFormatting.RED)); 130 | else 131 | this.btnTrigger.setMessage(new TranslatableComponent("gui.trigger.mark").withStyle(ChatFormatting.GREEN)); 132 | } 133 | 134 | @Override 135 | public boolean changeFocus(boolean focus) { 136 | return false; 137 | } 138 | 139 | @Override 140 | public List children() { 141 | return ImmutableList.of(this.btnTrigger); 142 | } 143 | 144 | @Override 145 | public List narratables() { 146 | return ImmutableList.of(this.btnTrigger); 147 | } 148 | 149 | @Override 150 | public boolean mouseClicked(double mouseX, double mouseY, int button) { 151 | return this.btnTrigger.mouseClicked(mouseX, mouseY, button); 152 | } 153 | 154 | @Override 155 | public boolean mouseReleased(double mouseX, double mouseY, int button) { 156 | return this.btnTrigger.mouseReleased(mouseX, mouseY, button); 157 | } 158 | } 159 | 160 | @OnlyIn(Dist.CLIENT) 161 | public abstract static class Entry extends ContainerObjectSelectionList.Entry { 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/controller/Controller.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.controller; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.FloatBuffer; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import org.lwjgl.glfw.GLFW; 9 | 10 | import com.stereowalker.controllermod.ControllerMod; 11 | import com.stereowalker.controllermod.resources.ControllerModelManager; 12 | 13 | public class Controller { 14 | private int id; 15 | private String name; 16 | private String GUID; 17 | private long userPointer; 18 | 19 | public Controller(int id) { 20 | this(id, GLFW.glfwGetJoystickName(id), GLFW.glfwGetJoystickGUID(id), GLFW.glfwGetJoystickUserPointer(id)); 21 | } 22 | 23 | public Controller(int id, String name, String guid, long userPointer) { 24 | this.id = id; 25 | this.name = name; 26 | this.GUID = guid; 27 | this.userPointer = userPointer; 28 | } 29 | 30 | public int getId() { 31 | return id; 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public String getGUID() { 39 | return GUID; 40 | } 41 | 42 | public long getUserPointer() { 43 | return userPointer; 44 | } 45 | 46 | public FloatBuffer getAxes() { 47 | return GLFW.glfwGetJoystickAxes(id); 48 | } 49 | 50 | public float getAxis(int index) { 51 | if (getAxes() != null) { 52 | try { 53 | return getAxes().get(index); 54 | } 55 | catch (IndexOutOfBoundsException e) { 56 | return 0; 57 | } 58 | } 59 | return 0; 60 | } 61 | 62 | public ByteBuffer getHats() { 63 | return GLFW.glfwGetJoystickHats(id); 64 | } 65 | 66 | public byte getHat(int index) { 67 | if (getHats() != null) { 68 | try { 69 | return getHats().get(index); 70 | } 71 | catch (IndexOutOfBoundsException e) { 72 | return 0; 73 | } 74 | } 75 | return 0; 76 | } 77 | 78 | public ByteBuffer getButtons() { 79 | return GLFW.glfwGetJoystickButtons(id); 80 | } 81 | 82 | public byte getButton(int index) { 83 | if (getButtons() != null) { 84 | try { 85 | return getButtons().get(index); 86 | } 87 | catch (IndexOutOfBoundsException e) { 88 | return 0; 89 | } 90 | } 91 | return 0; 92 | } 93 | 94 | public byte getDpadUp() { 95 | return (byte) ((getHat(0) == GLFW.GLFW_HAT_UP || getHat(0) == GLFW.GLFW_HAT_RIGHT_UP || getHat(0) == GLFW.GLFW_HAT_LEFT_UP) ? 1 : 0); 96 | } 97 | 98 | public byte getDpadLeft() { 99 | return (byte) ((getHat(0) == GLFW.GLFW_HAT_LEFT || getHat(0) == GLFW.GLFW_HAT_LEFT_UP || getHat(0) == GLFW.GLFW_HAT_LEFT_DOWN) ? 1 : 0); 100 | } 101 | 102 | public byte getDpadDown() { 103 | return (byte) ((getHat(0) == GLFW.GLFW_HAT_DOWN || getHat(0) == GLFW.GLFW_HAT_RIGHT_DOWN || getHat(0) == GLFW.GLFW_HAT_LEFT_DOWN) ? 1 : 0); 104 | } 105 | 106 | public byte getDpadRight() { 107 | return (byte) ((getHat(0) == GLFW.GLFW_HAT_RIGHT || getHat(0) == GLFW.GLFW_HAT_RIGHT_DOWN || getHat(0) == GLFW.GLFW_HAT_RIGHT_UP) ? 1 : 0); 108 | } 109 | 110 | public List getButtonsDown() { 111 | List buttons = new ArrayList(); 112 | if (this != null) { 113 | if (this.getButtons() != null) { 114 | for (int i = 0; i < this.getButtons().capacity(); i++) { 115 | if (this.getButton(i) > ControllerMod.CONFIG.deadzone && this.getButton(i) <= 1.0F) buttons.add("button"+i); 116 | } 117 | if (getModel() != null) { 118 | for (int i = 0; i < this.getAxes().capacity(); i++) { 119 | List triggers0 = getModel() == ControllerModel.CUSTOM ? ControllerMod.getInstance().controllerOptions.positiveTriggerAxes : getModel().getControllerPositiveTriggers(); 120 | if (!triggers0.contains(i)) { 121 | if (this.getAxis(i) > ControllerMod.CONFIG.deadzone && this.getAxis(i) <= 1.0) buttons.add("axis_pos"+i); 122 | } 123 | 124 | List triggers1 = getModel() == ControllerModel.CUSTOM ? ControllerMod.getInstance().controllerOptions.negativeTriggerAxes : getModel().getControllerNegativeTriggers(); 125 | if (!triggers1.contains(i)) { 126 | if (-this.getAxis(i) > ControllerMod.CONFIG.deadzone && -this.getAxis(i) <= 1.0) buttons.add("axis_neg"+i); 127 | } 128 | } 129 | } 130 | byte UP = this.getDpadUp(); 131 | byte DOWN = this.getDpadDown(); 132 | byte LEFT = this.getDpadLeft(); 133 | byte RIGHT = this.getDpadRight(); 134 | if (UP > 0.1F) buttons.add("dpadup"); 135 | if (DOWN > 0.1F) buttons.add("dpaddo"); 136 | if (LEFT > 0.1F) buttons.add("dpadle"); 137 | if (RIGHT > 0.1F) buttons.add("dpadri"); 138 | } 139 | else { 140 | ControllerMod.debug("There are no buttons on this controller"); 141 | } 142 | } 143 | buttons.removeIf((cont) -> this.getModel().getDupeButtons().contains(cont)); 144 | return buttons; 145 | } 146 | 147 | public List getAxesMoved() { 148 | List axes = new ArrayList(); 149 | if (this != null) { 150 | if (this.getAxes() != null && getModel() != null) { 151 | for (int i = 0; i < this.getAxes().capacity(); i++) { 152 | List triggersPos = ControllerMod.getInstance().controllerOptions.controllerModel == ControllerModel.CUSTOM ? ControllerMod.getInstance().controllerOptions.positiveTriggerAxes : getModel().getControllerPositiveTriggers(); 153 | List triggersNeg = ControllerMod.getInstance().controllerOptions.controllerModel == ControllerModel.CUSTOM ? ControllerMod.getInstance().controllerOptions.negativeTriggerAxes : getModel().getControllerNegativeTriggers(); 154 | if (!triggersPos.contains(i) && !triggersNeg.contains(i)) 155 | if (this.getAxis(i) > ControllerMod.CONFIG.deadzone && this.getAxis(i) <= 1.0F) axes.add("axis"+i); 156 | else if (this.getAxis(i) < -ControllerMod.CONFIG.deadzone && this.getAxis(i) >= -1.0F) axes.add("axis"+i); 157 | } 158 | } 159 | else { 160 | if (this.getAxes() == null) ControllerMod.debug("There are no axes on this controller"); 161 | if (this.getModel() == null) ControllerMod.debug("The model on this controller is set to null"); 162 | } 163 | } 164 | return axes; 165 | } 166 | 167 | public boolean isButtonDown(String button) { 168 | if (getButtonsDown() != null && button != null) { 169 | return getButtonsDown().contains(button); 170 | } else { 171 | return false; 172 | } 173 | } 174 | 175 | public boolean areButtonsDown(List buttons) { 176 | for (int i = 0; i < buttons.size(); i++) { 177 | if (!isButtonDown(buttons.get(i))) { 178 | return false; 179 | } 180 | } 181 | return buttons.size() > 0; 182 | } 183 | 184 | public boolean isAxisMoved(String axis) { 185 | if (getAxesMoved() != null && axis != null) { 186 | return getAxesMoved().contains(axis); 187 | } else { 188 | return false; 189 | } 190 | } 191 | 192 | public ControllerModel getActualModel() { 193 | for (ControllerModel model : ControllerModelManager.ALL_MODELS.values()) { 194 | if (model.getGUID().equals(getGUID())) { 195 | return model; 196 | } 197 | } 198 | return null; 199 | } 200 | 201 | public ControllerModel getModel() { 202 | if (getActualModel() != null) 203 | return getActualModel(); 204 | else if (ControllerMod.getInstance().controllerOptions.controllerModel != null) 205 | return ControllerMod.getInstance().controllerOptions.controllerModel; 206 | else 207 | return ControllerModel.CUSTOM; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/mixin/MinecraftMixin.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.mixin; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import org.jetbrains.annotations.Nullable; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | import com.google.common.collect.Lists; 15 | import com.mojang.blaze3d.platform.Window; 16 | import com.mojang.blaze3d.platform.WindowEventHandler; 17 | import com.stereowalker.controllermod.ControllerMod; 18 | import com.stereowalker.controllermod.client.ControllerOptions; 19 | import com.stereowalker.controllermod.client.controller.Controller; 20 | import com.stereowalker.controllermod.client.controller.ControllerMapping; 21 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 22 | import com.stereowalker.controllermod.client.controller.ControllerUtil.ListeningMode; 23 | import com.stereowalker.controllermod.client.controller.UseCase; 24 | import com.stereowalker.controllermod.client.gui.screen.ControllerInputOptionsScreen; 25 | 26 | import net.minecraft.client.Minecraft; 27 | import net.minecraft.client.MouseHandler; 28 | import net.minecraft.client.gui.screens.PauseScreen; 29 | import net.minecraft.client.gui.screens.Screen; 30 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 31 | import net.minecraft.server.packs.resources.ReloadableResourceManager; 32 | import net.minecraft.util.thread.ReentrantBlockableEventLoop; 33 | 34 | @Mixin(Minecraft.class) 35 | public abstract class MinecraftMixin extends ReentrantBlockableEventLoop implements WindowEventHandler { 36 | 37 | @Shadow @Nullable public Screen screen; 38 | @Shadow @Final public MouseHandler mouseHandler; 39 | @Shadow @Final public File gameDirectory; 40 | @Shadow @Final private Window window; 41 | @Shadow @Final private ReloadableResourceManager resourceManager; 42 | 43 | public MinecraftMixin(String p_18765_) { 44 | super(p_18765_); 45 | } 46 | 47 | @Inject(method = "setScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/KeyMapping;releaseAll()V")) 48 | public void setScreen1_inject(CallbackInfo ci) { 49 | ControllerMapping.releaseAll(); 50 | } 51 | 52 | @Inject(method = "setScreen", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/BufferUploader;reset()V")) 53 | public void setScreen2_inject(CallbackInfo ci) { 54 | ControllerMapping.handleUnbindAll(); 55 | } 56 | 57 | boolean fromGame = false; 58 | @Inject(method = "tick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V")) 59 | public void tick_inject(CallbackInfo ci) { 60 | if(ControllerMod.getInstance().hasInitializedClient && ControllerUtil.isControllerAvailable(ControllerMod.getInstance().controllerOptions.controllerNumber) && ControllerMod.getInstance().controllerOptions.enableController) { 61 | ControllerOptions settings = ControllerMod.getInstance().controllerOptions; 62 | if (mouseHandler.isMouseGrabbed()) ControllerUtil.virtualmouse.grabMouse(); 63 | else ControllerUtil.virtualmouse.ungrabMouse(); 64 | if(!Minecraft.getInstance().isWindowActive()) Minecraft.getInstance().setWindowActive(true); 65 | Controller controller = ControllerMod.getInstance().getActiveController(); 66 | if (controller != null) { 67 | List case1 = null; 68 | //Inventory Keybinds 69 | if(screen instanceof AbstractContainerScreen) { 70 | // if(fromGame) { 71 | // ControllerUtil.unpressAllKeys(); 72 | // fromGame = false; 73 | // } 74 | case1 = Lists.newArrayList(UseCase.CONTAINER, UseCase.ANY_SCREEN, UseCase.ANYWHERE); 75 | } 76 | 77 | //Ingame Menu Keybinds 78 | else if(screen instanceof PauseScreen) { 79 | if(fromGame) { 80 | ControllerUtil.unpressAllKeys(); 81 | fromGame = false; 82 | } 83 | case1 = Lists.newArrayList(UseCase.ANY_SCREEN, UseCase.ANYWHERE); 84 | } 85 | 86 | //Any other menu 87 | else if(screen !=null && !(screen instanceof AbstractContainerScreen) && !(screen instanceof PauseScreen)) { 88 | if(screen instanceof ControllerInputOptionsScreen) { 89 | if(!((ControllerInputOptionsScreen)screen).isAwaitingInput()) { 90 | if(fromGame) { 91 | ControllerUtil.unpressAllKeys(); 92 | fromGame = false; 93 | } 94 | case1 = Lists.newArrayList(UseCase.ANY_SCREEN, UseCase.ANYWHERE); 95 | } 96 | } else { 97 | if(fromGame) { 98 | ControllerUtil.unpressAllKeys(); 99 | fromGame = false; 100 | } 101 | case1 = Lists.newArrayList(UseCase.ANY_SCREEN, UseCase.ANYWHERE); 102 | } 103 | } 104 | 105 | //Ingame Keybinds 106 | else if(screen == null) { 107 | fromGame = true; 108 | case1 = Lists.newArrayList(UseCase.INGAME, UseCase.ANYWHERE); 109 | } 110 | 111 | if (ControllerMod.getInstance().getControllerHandler().forceRelease()){ 112 | ControllerMod.getInstance().getControllerHandler().processControllerInput(controller, Lists.newArrayList(UseCase.ANY_SCREEN, UseCase.ANYWHERE, UseCase.CONTAINER, UseCase.INGAME)); 113 | } else { 114 | if (case1 != null) { 115 | if (!case1.contains(UseCase.INGAME) && ControllerUtil.listeningMode == ListeningMode.KEYBOARD) { 116 | case1 = Lists.newArrayList(UseCase.KEYBOARD); 117 | } 118 | ControllerMod.getInstance().getControllerHandler().processControllerInput(controller, case1); 119 | } 120 | } 121 | 122 | if (ControllerMod.getInstance().onScreenKeyboard.switchCooldown > 0) { 123 | ControllerMod.getInstance().onScreenKeyboard.switchCooldown--; 124 | } 125 | if (ControllerMod.getInstance().controllerOptions.controllerBindKeyboard.isDown(ControllerMod.getInstance().controllerOptions.controllerModel)) { 126 | if (ControllerUtil.listeningMode == ListeningMode.LISTEN_TO_MAPPINGS && ControllerMod.getInstance().onScreenKeyboard.switchCooldown == 0) { 127 | ControllerMod.getInstance().onScreenKeyboard.switchKeyboard(); 128 | } 129 | } 130 | 131 | float scrollAxis = settings.controllerBindScroll.getAxis(); 132 | float mouseXAxis = settings.controllerBindMouseHorizontal.getAxis(); 133 | float mouseYAxis = settings.controllerBindMouseVertical.getAxis(); 134 | 135 | if (case1 != null && case1.contains(UseCase.CONTAINER)) { 136 | ControllerUtil.updateMousePosition(mouseXAxis, mouseYAxis, controller, false, false); 137 | if (scrollAxis >= -1.0F && scrollAxis < -0.1F) 138 | mouseHandler.onScroll(window.getWindow(), 0.0D, -scrollAxis * ControllerMod.CONFIG.menu_sensitivity * 100.0D / 20.0D); 139 | if (scrollAxis <= 1.0F && scrollAxis > 0.1F) 140 | mouseHandler.onScroll(window.getWindow(), 0.0D, -scrollAxis * ControllerMod.CONFIG.menu_sensitivity * 100.0D / 20.0D); 141 | } 142 | else if (case1 != null && case1.contains(UseCase.ANY_SCREEN)) { 143 | ControllerUtil.updateMousePosition(mouseXAxis, mouseYAxis, controller, false, ControllerUtil.listeningMode == ListeningMode.LISTEN_TO_MAPPINGS); 144 | if (scrollAxis >= -1.0F && scrollAxis < -0.1D) 145 | mouseHandler.onScroll(window.getWindow(), 0.0D, -scrollAxis * ControllerMod.CONFIG.menu_sensitivity * 100.0D / 20.0D); 146 | if (scrollAxis <= 1.0F && scrollAxis > 0.1D) 147 | mouseHandler.onScroll(window.getWindow(), 0.0D, -scrollAxis * ControllerMod.CONFIG.menu_sensitivity * 100.0D / 20.0D); 148 | } 149 | } 150 | } 151 | } 152 | 153 | @Inject(method = "handleKeybinds", at = @At("TAIL")) 154 | public void handleKeybinds_inject(CallbackInfo ci) { 155 | if(this.screen==null) { 156 | if (ControllerMod.getInstance().controllerOptions.controllerBindHotbarLeft.isDown(ControllerMod.getInstance().controllerOptions.controllerModel)) { 157 | ControllerUtil.virtualmouse.scrollCallback(Minecraft.getInstance().getWindow().getWindow(), 0.0D, 1.0D); 158 | } 159 | if (ControllerMod.getInstance().controllerOptions.controllerBindHotbarRight.isDown(ControllerMod.getInstance().controllerOptions.controllerModel)) { 160 | ControllerUtil.virtualmouse.scrollCallback(Minecraft.getInstance().getWindow().getWindow(), 0.0D, -1.0D); 161 | } 162 | } 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/ControllerHandler.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client; 2 | 3 | import java.util.List; 4 | 5 | import org.lwjgl.glfw.GLFW; 6 | 7 | import com.google.common.collect.Lists; 8 | import com.stereowalker.controllermod.ControllerMod; 9 | import com.stereowalker.controllermod.client.controller.Controller; 10 | import com.stereowalker.controllermod.client.controller.ControllerMapping; 11 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 12 | import com.stereowalker.controllermod.client.controller.ControllerUtil.InputType; 13 | import com.stereowalker.controllermod.client.controller.ControllerUtil.ListeningMode; 14 | import com.stereowalker.controllermod.client.controller.UseCase; 15 | import com.stereowalker.controllermod.client.gui.toasts.ControllerStatusToast; 16 | 17 | import net.minecraft.client.Minecraft; 18 | import net.minecraft.client.resources.sounds.SimpleSoundInstance; 19 | import net.minecraft.network.chat.TextComponent; 20 | import net.minecraft.sounds.SoundEvents; 21 | 22 | public class ControllerHandler { 23 | private final Minecraft minecraft; 24 | private final ControllerMod controllerMod; 25 | 26 | public ControllerHandler(ControllerMod controllerModIn, Minecraft minecraftIn) { 27 | this.minecraft = minecraftIn; 28 | this.controllerMod = controllerModIn; 29 | } 30 | 31 | public void controllerConnectedCallback(int jid, int status){ 32 | boolean connected = status == GLFW.GLFW_CONNECTED; 33 | boolean disconnected = status == GLFW.GLFW_DISCONNECTED; 34 | Controller controller; 35 | if(connected) { 36 | GLFW.glfwGetGamepadName(jid); 37 | controller = new Controller(jid, GLFW.glfwGetJoystickName(jid), GLFW.glfwGetJoystickGUID(jid), GLFW.glfwGetJoystickUserPointer(jid)); 38 | controllerMod.controllers.add(controller); 39 | ControllerStatusToast.addOrUpdate(minecraft.getToasts(), ControllerStatusToast.Type.CONNECT, new TextComponent(controller.getName())); 40 | } 41 | else if (disconnected) { 42 | controller = controllerMod.getController(jid); 43 | if (controller != null) { 44 | ControllerStatusToast.addOrUpdate(minecraft.getToasts(), ControllerStatusToast.Type.DISCONNECT, new TextComponent(controller.getName())); 45 | controllerMod.controllers.remove(controller); 46 | } 47 | } 48 | else { 49 | controller = null; 50 | } 51 | if (controller != null) { 52 | 53 | System.out.println(jid +" "+controllerMod.controllers.size()+" "+GLFW.glfwGetGamepadName(jid)); 54 | } 55 | } 56 | 57 | private List previouslyUsed = Lists.newArrayList(); 58 | private boolean forceRelease = false; 59 | public void addToPrevoiuslyUsed(ControllerMapping ma) { 60 | previouslyUsed.add(ma); 61 | forceRelease = true; 62 | } 63 | 64 | public boolean forceRelease() { 65 | return forceRelease; 66 | } 67 | 68 | 69 | boolean left = false, right = false, up = false, down = false; 70 | public void processControllerInput(Controller controller, List useCase) { 71 | if (ControllerUtil.listeningMode == ListeningMode.KEYBOARD && !useCase.contains(UseCase.INGAME)) { 72 | if (controller.areButtonsDown(this.controllerMod.controllerOptions.controllerBindKeyboard.getButtonOnController(controller.getModel())) && this.controllerMod.onScreenKeyboard.switchCooldown == 0) { 73 | this.controllerMod.onScreenKeyboard.switchKeyboard(); 74 | } 75 | else { 76 | OnScreenKeyboard keyboard = this.controllerMod.onScreenKeyboard; 77 | ControllerOptions options = this.controllerMod.controllerOptions; 78 | int mods = keyboard.isCapsLocked ? GLFW.GLFW_MOD_CAPS_LOCK : 0; 79 | long handle = minecraft.getWindow().getWindow(); 80 | if (options.controllerBindKeyboardLeft.isBoundToButton(controller.getModel())) 81 | ControllerUtil.pushDown(options.controllerBindKeyboardLeft.getButtonOnController(controller.getModel()), controller, InputType.PRESS, 0.9f, () -> left = true, () -> left = false); 82 | if (options.controllerBindKeyboardRight.isBoundToButton(controller.getModel())) 83 | ControllerUtil.pushDown(options.controllerBindKeyboardRight.getButtonOnController(controller.getModel()), controller, InputType.PRESS, 0.9f, () -> right = true, () -> right = false); 84 | if (options.controllerBindKeyboardUp.isBoundToButton(controller.getModel())) 85 | ControllerUtil.pushDown(options.controllerBindKeyboardUp.getButtonOnController(controller.getModel()), controller, InputType.PRESS, 0.9f, () -> up = true, () -> up = false); 86 | if (options.controllerBindKeyboardDown.isBoundToButton(controller.getModel())) 87 | ControllerUtil.pushDown(options.controllerBindKeyboardDown.getButtonOnController(controller.getModel()), controller, InputType.PRESS, 0.9f, () -> down = true, () -> down = false); 88 | 89 | keyboard.changeKey(up, down, left, right); 90 | 91 | if (options.controllerBindKeyboardSelect.isBoundToButton(controller.getModel())) 92 | ControllerUtil.pushDown(options.controllerBindKeyboardSelect.getButtonOnController(controller.getModel()), controller, InputType.PRESS, ControllerMod.CONFIG.deadzone, () -> {minecraft.keyboardHandler.charTyped(handle, keyboard.getUnicodeKey(), mods); minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));}, () -> {}); 93 | if (options.controllerBindKeyboardBackspace.isBoundToButton(controller.getModel())) { 94 | int key = GLFW.GLFW_KEY_BACKSPACE; 95 | ControllerUtil.pushDown(options.controllerBindKeyboardBackspace.getButtonOnController(controller.getModel()), controller, InputType.PRESS, ControllerMod.CONFIG.deadzone, () -> minecraft.keyboardHandler.keyPress(handle, key, 0, 1, 0), () -> minecraft.keyboardHandler.keyPress(handle, key, 0, 0, 0)); 96 | } 97 | if (options.controllerBindKeyboardArrowLeft.isBoundToButton(controller.getModel())) { 98 | int key = GLFW.GLFW_KEY_LEFT; 99 | ControllerUtil.pushDown(options.controllerBindKeyboardArrowLeft.getButtonOnController(controller.getModel()), controller, InputType.PRESS, ControllerMod.CONFIG.deadzone, () -> minecraft.keyboardHandler.keyPress(handle, key, 0, 1, 0), () -> minecraft.keyboardHandler.keyPress(handle, key, 0, 0, 0)); 100 | } 101 | if (options.controllerBindKeyboardArrowRight.isBoundToButton(controller.getModel())) { 102 | int key = GLFW.GLFW_KEY_RIGHT; 103 | ControllerUtil.pushDown(options.controllerBindKeyboardArrowRight.getButtonOnController(controller.getModel()), controller, InputType.PRESS, ControllerMod.CONFIG.deadzone, () -> minecraft.keyboardHandler.keyPress(handle, key, 0, 1, 0), () -> minecraft.keyboardHandler.keyPress(handle, key, 0, 0, 0)); 104 | } 105 | if (options.controllerBindKeyboardSpace.isBoundToButton(controller.getModel())) { 106 | int key = GLFW.GLFW_KEY_SPACE; 107 | ControllerUtil.pushDown(options.controllerBindKeyboardSpace.getButtonOnController(controller.getModel()), controller, InputType.PRESS, ControllerMod.CONFIG.deadzone, () -> minecraft.keyboardHandler.charTyped(handle, key, mods), () -> {}); 108 | } 109 | if (options.controllerBindKeyboardCaps.isBoundToButton(controller.getModel())) 110 | ControllerUtil.pushDown(options.controllerBindKeyboardCaps.getButtonOnController(controller.getModel()), controller, InputType.PRESS, ControllerMod.CONFIG.deadzone, () -> keyboard.isCapsLocked = !keyboard.isCapsLocked, () -> {}); 111 | } 112 | } 113 | else if (ControllerUtil.listeningMode == ListeningMode.LISTEN_TO_MAPPINGS) { 114 | if (useCase.contains(UseCase.INGAME)) this.minecraft.keyboardHandler.setSendRepeatsToGui(false); 115 | int i = 0, j = 0; 116 | List currentlyUsing = ControllerMapping.retrieveActiveMappings(controller, useCase); 117 | //This should release buttons we are no longer holding 118 | //I'm using this type of loop because REI crashes when I use an Iterator 119 | for (int x = 0; x < previouslyUsed.size(); x++) { 120 | ControllerMapping binding = previouslyUsed.get(x); 121 | if ((!currentlyUsing.contains(binding) || forceRelease) && binding != null) { 122 | j++; 123 | if (!binding.isAxis()) { 124 | if (binding.isBoundToButton(controller.getModel()) && (useCase.contains(binding.getUseCase()))) { 125 | binding.release(); 126 | ControllerUtil.updateButtonState(binding, binding.getButtonOnController(controller.getModel()), controller, binding.getButtonOnKeyboardOrMouse(), binding.getInputType(controller.getModel())); 127 | } 128 | } else { 129 | binding.axis = 0; 130 | } 131 | } 132 | } 133 | previouslyUsed.clear(); 134 | forceRelease = false; 135 | for (ControllerMapping binding : currentlyUsing) { 136 | i++; 137 | if (binding.isAxis()) { 138 | if (binding.isBoundToButton(controller.getModel()) && (useCase.contains(binding.getUseCase()))) 139 | binding.axis = ControllerUtil.updateAxisState(binding.getButtonOnController(controller.getModel()).get(0), controller) * (binding.isAxisInverted(controller.getModel()) ? -1 : 1); 140 | else 141 | binding.axis = 0; 142 | } else { 143 | boolean flag = true; 144 | if (useCase.contains(UseCase.INGAME) && ControllerMod.CONFIG.usePreciseMovement && (binding.getDescripti() == minecraft.options.keyUp.getName() || binding.getDescripti() == minecraft.options.keyRight.getName() || binding.getDescripti() == minecraft.options.keyLeft.getName() || binding.getDescripti() == minecraft.options.keyDown.getName())) flag = false; 145 | if (useCase.contains(UseCase.CONTAINER) && /* binding.getDescripti() == minecraft.options.keyBindInventory.getName() || */binding.getDescripti() == minecraft.options.keyUse.getName()) flag = false; 146 | if (flag && binding != null) { 147 | if (binding.isBoundToButton(controller.getModel()) && (useCase.contains(binding.getUseCase()))) { 148 | // if (controller.isButtonDown(binding.getButtonOnController(controller.getModel()))) { 149 | binding.tick(); 150 | // } else { 151 | // binding.release(); 152 | // } 153 | ControllerUtil.updateButtonState(binding, binding.getButtonOnController(controller.getModel()), controller, binding.getButtonOnKeyboardOrMouse(), binding.getInputType(controller.getModel())); 154 | } 155 | } 156 | } 157 | previouslyUsed.add(binding); 158 | } 159 | if (i != 0 || j != 0) ControllerMod.debug("Pressed "+i+" bindings and released "+j); 160 | } 161 | } 162 | 163 | public void setup(long handle) { 164 | ControllerUtil.setGamepadCallbacks((a, b) -> { 165 | this.minecraft.execute(() -> { 166 | this.controllerConnectedCallback(a, b); 167 | }); 168 | }); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/OnScreenKeyboard.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.lang3.CharUtils; 6 | import org.apache.commons.lang3.StringEscapeUtils; 7 | import org.lwjgl.glfw.GLFW; 8 | 9 | import com.google.common.collect.Lists; 10 | import com.mojang.blaze3d.systems.RenderSystem; 11 | import com.mojang.blaze3d.vertex.BufferBuilder; 12 | import com.mojang.blaze3d.vertex.BufferUploader; 13 | import com.mojang.blaze3d.vertex.DefaultVertexFormat; 14 | import com.mojang.blaze3d.vertex.PoseStack; 15 | import com.mojang.blaze3d.vertex.Tesselator; 16 | import com.mojang.blaze3d.vertex.VertexFormat; 17 | import com.mojang.datafixers.util.Pair; 18 | import com.mojang.math.Matrix4f; 19 | import com.stereowalker.controllermod.client.controller.ControllerMapping; 20 | import com.stereowalker.controllermod.client.controller.ControllerUtil; 21 | import com.stereowalker.controllermod.client.controller.ControllerUtil.ListeningMode; 22 | 23 | import net.minecraft.ChatFormatting; 24 | import net.minecraft.client.Minecraft; 25 | import net.minecraft.client.gui.Font; 26 | import net.minecraft.client.gui.screens.Screen; 27 | import net.minecraft.client.renderer.GameRenderer; 28 | import net.minecraft.client.renderer.MultiBufferSource; 29 | import net.minecraft.network.chat.MutableComponent; 30 | import net.minecraft.network.chat.Style; 31 | import net.minecraft.network.chat.TextComponent; 32 | import net.minecraftforge.api.distmarker.Dist; 33 | import net.minecraftforge.api.distmarker.OnlyIn; 34 | 35 | @SuppressWarnings("deprecation") 36 | //TODO: Use the newer package "org.apache.commons.text" instead of "org.apache.commons.lang3" 37 | @OnlyIn(Dist.CLIENT) 38 | public class OnScreenKeyboard { 39 | 40 | enum Layout{ 41 | QWERTY(new String[][]{ 42 | new String[]{"11","22","33","44","55","66","77","8","99","00"}, 43 | new String[]{"Qq","Ww","Ee","Rr","Tt","Yy","Uu","Ii","Oo","Pp"}, 44 | new String[]{"Aa","Ss","Dd","Ff","Gg","Hh","Jj","Kk","Ll","\"'"}, 45 | new String[]{"Zz","Xx","Cc","Vv","Bb","Nn","Mm","<,",">.","?/"} 46 | }); 47 | 48 | List>> keys; 49 | int xSize = 0; 50 | int ySize = 0; 51 | private Layout(String[][] keys) { 52 | this.keys = Lists.newArrayList(); 53 | for (String[] s : keys) { 54 | this.keys.add(assignKeys(s, Lists.newArrayList())); 55 | } 56 | this.ySize = this.keys.size(); 57 | } 58 | 59 | List> assignKeys(String[] keyArray, List> keyList) { 60 | if (xSize != 0 && keyArray.length > xSize) { 61 | System.out.println("This is too large "); 62 | } 63 | else { 64 | for (String s : keyArray) { 65 | if (s.length() > 2) { 66 | System.out.println("Invalid key "+s); 67 | } else { 68 | int i = Integer.parseInt(CharUtils.unicodeEscaped(s.charAt(0)).substring(2), 16); 69 | int j = s.length() == 2 ? Integer.parseInt(CharUtils.unicodeEscaped(s.charAt(1)).substring(2), 16) : -1; 70 | keyList.add(Pair.of(i, j)); 71 | } 72 | } 73 | if (xSize == 0) { 74 | xSize = keyList.size(); 75 | } 76 | } 77 | return keyList; 78 | } 79 | 80 | int getKey(boolean shift, int x, int y) { 81 | return shift || keys.get(y).get(x).getSecond() == -1 ? keys.get(y).get(x).getFirst() : keys.get(y).get(x).getSecond(); 82 | } 83 | 84 | String unicode(boolean shift, int x, int y) { 85 | String hex = Integer.toHexString(getKey(shift, x, y)); 86 | if (hex.length() == 1) { 87 | return "\\u000"+hex; 88 | } else if (hex.length() == 2) { 89 | return "\\u00"+hex; 90 | } else if (hex.length() == 3) { 91 | return "\\u0"+hex; 92 | } else { 93 | return "\\u"+hex; 94 | } 95 | } 96 | } 97 | 98 | private final Minecraft minecraft; 99 | public int currentKey = GLFW.GLFW_KEY_A; 100 | public boolean isCapsLocked = false; 101 | public int switchCooldown; 102 | public int changeKeyCooldown; 103 | public Layout layout = Layout.QWERTY; 104 | 105 | public int xPos; 106 | public int yPos; 107 | 108 | public OnScreenKeyboard(Minecraft minecraft) { 109 | this.minecraft = minecraft; 110 | } 111 | 112 | public void switchKeyboard() { 113 | switchCooldown = 20; 114 | ControllerUtil.listeningMode = ControllerUtil.listeningMode == ListeningMode.KEYBOARD ? ListeningMode.LISTEN_TO_MAPPINGS : ListeningMode.KEYBOARD; 115 | currentKey = GLFW.GLFW_KEY_A; 116 | isCapsLocked = false; 117 | changeKeyCooldown = 0; 118 | 119 | xPos = 0; 120 | yPos = 0; 121 | ControllerMapping.releaseAll(); 122 | } 123 | 124 | public int[] getNextKey(boolean up, boolean down, boolean left, boolean right) { 125 | if (layout == Layout.QWERTY) { 126 | int i = layout.xSize - 1; 127 | int j = layout.ySize - 1; 128 | 129 | int k = xPos; 130 | int l = yPos; 131 | //Up - Down Controls 132 | if (down && yPos < j) { 133 | l = yPos+1; 134 | } else if (down && yPos == j) { 135 | l = 0; 136 | } else if (up && yPos > 0) { 137 | l = yPos-1; 138 | } else if (up && yPos == 0) { 139 | l = j; 140 | } 141 | 142 | if (right && xPos < i) { 143 | k = xPos+1; 144 | } else if (right && xPos == i) { 145 | k = 0; 146 | } else if (left && xPos > 0) { 147 | k = xPos-1; 148 | } else if (left && xPos == 0) { 149 | k = i; 150 | } 151 | 152 | 153 | return new int[]{layout.getKey(isCapsLocked, k, l), k, l}; 154 | } 155 | return new int[]{GLFW.GLFW_KEY_WORLD_1, xPos, yPos}; 156 | 157 | 158 | } 159 | 160 | 161 | public void drawKeyboard(PoseStack poseStack, Font font, int x, int y) { 162 | List> layers = Lists.newArrayList(); 163 | for (int j = 0; j < layout.ySize; j++) { 164 | layers.add(Lists.newArrayList()); 165 | for (int i = 0; i < layout.xSize; i++) { 166 | String ke = StringEscapeUtils.unescapeJava(layout.unicode(isCapsLocked, i, j)); 167 | if (xPos == i && yPos == j) { 168 | layers.get(j).add(new TextComponent(ke).withStyle(Style.EMPTY.withColor(getKeyboardColors("Highlighted-Text")[0]))); 169 | } else { 170 | layers.get(j).add(new TextComponent(ke).withStyle(Style.EMPTY.withColor(getKeyboardColors("Text")[0]))); 171 | } 172 | } 173 | } 174 | int width = 0; 175 | int textWidth = 0; 176 | int height = 0; 177 | for(List clienttooltipcomponent : layers) { 178 | int k = 0; 179 | for(MutableComponent mut : clienttooltipcomponent) { 180 | int l = 0; 181 | l = font.width(mut); 182 | 183 | if (l > textWidth) { 184 | textWidth = l; 185 | } 186 | } 187 | k += textWidth*1.5*clienttooltipcomponent.size()+3; 188 | if (k > width) { 189 | width = k; 190 | } 191 | 192 | height += 10; 193 | } 194 | 195 | // System.out.println(layer1); 196 | 197 | int j2 = x + 12; 198 | int k2 = y - 12; 199 | if (j2 + width > minecraft.screen.width) { 200 | j2 -= 28 + width; 201 | } 202 | 203 | if (k2 + height + 6 > minecraft.screen.height) { 204 | k2 = minecraft.screen.height - height - 6; 205 | } 206 | 207 | poseStack.pushPose(); 208 | float f = minecraft.screen.itemRenderer.blitOffset; 209 | minecraft.screen.itemRenderer.blitOffset = 400.0f; 210 | Tesselator tesselator = Tesselator.getInstance(); 211 | BufferBuilder bufferbuilder = tesselator.getBuilder(); 212 | RenderSystem.setShader(GameRenderer::getPositionColorShader); 213 | bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); 214 | Matrix4f matrix4f = poseStack.last().pose(); 215 | Screen.fillGradient(matrix4f, bufferbuilder, j2 - 3, k2 - 4, j2 + width + 3, k2 - 3, 400, getKeyboardColors("Background")[0], getKeyboardColors("Background")[0]); 216 | Screen.fillGradient(matrix4f, bufferbuilder, j2 - 3, k2 + height + 3, j2 + width + 3, k2 + height + 4, 400, getKeyboardColors("Background")[1], getKeyboardColors("Background")[1]); 217 | Screen.fillGradient(matrix4f, bufferbuilder, j2 - 3, k2 - 3, j2 + width + 3, k2 + height + 3, 400, getKeyboardColors("Background")[0], getKeyboardColors("Background")[1]); 218 | Screen.fillGradient(matrix4f, bufferbuilder, j2 - 4, k2 - 3, j2 - 3, k2 + height + 3, 400, getKeyboardColors("Background")[0], getKeyboardColors("Background")[1]); 219 | Screen.fillGradient(matrix4f, bufferbuilder, j2 + width + 3, k2 - 3, j2 + width + 4, k2 + height + 3, 400, getKeyboardColors("Background")[0], getKeyboardColors("Background")[1]); 220 | Screen.fillGradient(matrix4f, bufferbuilder, j2 - 3, k2 - 3 + 1, j2 - 3 + 1, k2 + height + 3 - 1, 400, getKeyboardColors("Border")[0], getKeyboardColors("Border")[1]); 221 | Screen.fillGradient(matrix4f, bufferbuilder, j2 + width + 2, k2 - 3 + 1, j2 + width + 3, k2 + height + 3 - 1, 400, getKeyboardColors("Border")[0], getKeyboardColors("Border")[1]); 222 | Screen.fillGradient(matrix4f, bufferbuilder, j2 - 3, k2 - 3, j2 + width + 3, k2 - 3 + 1, 400, getKeyboardColors("Border")[0], getKeyboardColors("Border")[0]); 223 | Screen.fillGradient(matrix4f, bufferbuilder, j2 - 3, k2 + height + 2, j2 + width + 3, k2 + height + 3, 400, getKeyboardColors("Border")[1], getKeyboardColors("Border")[1]); 224 | RenderSystem.enableDepthTest(); 225 | RenderSystem.disableTexture(); 226 | RenderSystem.enableBlend(); 227 | RenderSystem.defaultBlendFunc(); 228 | bufferbuilder.end(); 229 | BufferUploader.end(bufferbuilder); 230 | RenderSystem.disableBlend(); 231 | RenderSystem.enableTexture(); 232 | MultiBufferSource.BufferSource multibuffersource$buffersource = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); 233 | poseStack.translate(0.0D, 0.0D, 400.0D); 234 | int l1 = k2 + 1; 235 | for(int i2 = 0; i2 < layers.size(); ++i2) { 236 | int m1 = j2; 237 | List keyRow = layers.get(i2); 238 | for(int i3 = 0; i3 < keyRow.size(); ++i3) { 239 | MutableComponent clienttooltipcomponent1 = keyRow.get(i3); 240 | font.drawInBatch(clienttooltipcomponent1, (float)((m1 + (textWidth))- font.width(clienttooltipcomponent1) / 2), l1, -1, true, matrix4f, multibuffersource$buffersource, false, 0, 15728880); 241 | m1 += textWidth*1.5;// + (i3 == 0 ? 2 : 0); 242 | } 243 | l1 += 10; 244 | } 245 | // for(int i2 = 0; i2 < pClientTooltipComponents.size(); ++i2) { 246 | // ClientTooltipComponent clienttooltipcomponent1 = pClientTooltipComponents.get(i2); 247 | // clienttooltipcomponent1.renderText(preEvent.getFont(), j2, l1, matrix4f, multibuffersource$buffersource); 248 | // l1 += clienttooltipcomponent1.getHeight() + (i2 == 0 ? 2 : 0); 249 | // } 250 | 251 | multibuffersource$buffersource.endBatch(); 252 | poseStack.popPose(); 253 | minecraft.screen.itemRenderer.blitOffset = f; 254 | } 255 | 256 | public int[] getKeyboardColors(String id) { 257 | if (id.equals("Background")) 258 | return new int[] {0xff050429, 0xff1a1761}; 259 | if (id.equals("Text")) 260 | return new int[] {0x6dd1f2}; 261 | if (id.equals("Highlighted-Text")) 262 | return new int[] {0xffffff}; 263 | else 264 | return new int[] {0xa4d2f6ff, 0xa4d2f6ff}; 265 | 266 | } 267 | 268 | public int getUnicodeKey() { 269 | return layout.getKey(isCapsLocked, xPos, yPos); 270 | } 271 | 272 | public void changeKey(boolean up, boolean down, boolean left, boolean right) { 273 | int oldKey = currentKey; 274 | if (changeKeyCooldown == 0 && (up || down || left || right)) { 275 | int[] results = getNextKey(up, down, left, right); 276 | currentKey = results[0]; 277 | xPos = results[1]; 278 | yPos = results[2]; 279 | } 280 | 281 | if (oldKey != currentKey) 282 | changeKeyCooldown = 2; 283 | else if (changeKeyCooldown > 0) 284 | changeKeyCooldown--; 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/PaperDollOptions.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client; 2 | 3 | import java.io.PrintWriter; 4 | import java.util.Map; 5 | import java.util.function.Function; 6 | 7 | import org.lwjgl.opengl.GL11; 8 | 9 | import com.google.common.collect.Maps; 10 | import com.mojang.blaze3d.systems.RenderSystem; 11 | import com.mojang.blaze3d.vertex.PoseStack; 12 | import com.mojang.math.Quaternion; 13 | import com.mojang.math.Vector3f; 14 | import com.stereowalker.controllermod.ControllerMod; 15 | import com.stereowalker.controllermod.client.controller.ControllerMapping; 16 | import com.stereowalker.controllermod.client.controller.ControllerModel; 17 | 18 | import net.minecraft.ChatFormatting; 19 | import net.minecraft.client.Minecraft; 20 | import net.minecraft.client.gui.Gui; 21 | import net.minecraft.client.gui.GuiComponent; 22 | import net.minecraft.client.player.LocalPlayer; 23 | import net.minecraft.client.renderer.GameRenderer; 24 | import net.minecraft.client.renderer.MultiBufferSource; 25 | import net.minecraft.client.renderer.entity.EntityRenderDispatcher; 26 | import net.minecraft.client.resources.language.I18n; 27 | import net.minecraft.core.BlockPos; 28 | import net.minecraft.network.chat.Component; 29 | import net.minecraft.network.chat.MutableComponent; 30 | import net.minecraft.network.chat.TranslatableComponent; 31 | import net.minecraft.resources.ResourceLocation; 32 | import net.minecraft.world.entity.LivingEntity; 33 | import net.minecraft.world.phys.Vec2; 34 | import net.minecraftforge.api.distmarker.Dist; 35 | import net.minecraftforge.api.distmarker.OnlyIn; 36 | 37 | @OnlyIn(Dist.CLIENT) 38 | public class PaperDollOptions { 39 | 40 | public Map show = Maps.newHashMap(); 41 | public DollType lastDisplayedShow = DollType.NONE; 42 | public DollType currentDoll = DollType.NONE; 43 | 44 | public PaperDollOptions() { 45 | for (DollType dollShow : DollType.values()) { 46 | show.put(dollShow, dollShow.defaultV); 47 | } 48 | } 49 | 50 | private boolean shouldRender(DollType dollShow, LocalPlayer player) { 51 | if (dollShow == DollType.NONE) { 52 | return false; 53 | } else { 54 | return show.get(dollShow) && dollShow.renderCheck.apply(player); 55 | } 56 | } 57 | 58 | public void writeOptions(PrintWriter printwriter) { 59 | for (DollType dollShow : DollType.values()) { 60 | if (dollShow != DollType.NONE) printwriter.println(dollShow.getOptionsText()+":"+show.get(dollShow)); 61 | } 62 | } 63 | 64 | public void readOptions(String s, String s1) { 65 | for (DollType dollShow : DollType.values()) { 66 | if (dollShow != DollType.NONE && dollShow.getOptionsText().equals(s)) show.put(dollShow, "true".equals(s1)); 67 | } 68 | } 69 | 70 | 71 | public static int paperDollShownTicks = 0; 72 | public static float lastHeadYaw = 50.0F; 73 | public static float renderHeadYaw = 50.0F; 74 | public static final float maxYaw = 210.0F; 75 | public static final float minYaw = 120.0F; 76 | @SuppressWarnings("resource") 77 | public static void renderPlayerDoll(Gui gui, PoseStack poseStack) { 78 | LocalPlayer player = Minecraft.getInstance().player; 79 | PaperDollOptions paperDoll = ControllerMod.getInstance().controllerOptions.paperDoll; 80 | float diff = lastHeadYaw - player.yHeadRot; 81 | if (lastHeadYaw != Minecraft.getInstance().player.yHeadRot) { 82 | lastHeadYaw = lastHeadYaw - diff; 83 | float newRenderHeadYaw = renderHeadYaw; 84 | if (newRenderHeadYaw-diff >= minYaw && newRenderHeadYaw-diff <= maxYaw) { 85 | newRenderHeadYaw-=diff; 86 | } 87 | else if (newRenderHeadYaw-diff < minYaw) { 88 | newRenderHeadYaw = minYaw; 89 | } 90 | else if (newRenderHeadYaw-diff > maxYaw) { 91 | newRenderHeadYaw = maxYaw; 92 | } 93 | renderHeadYaw = newRenderHeadYaw; 94 | } 95 | if (!Minecraft.getInstance().options.renderDebug) { 96 | if (ControllerMod.CONFIG.show_paper_doll) { 97 | boolean renderDoll = false; 98 | for (DollType dollShow : DollType.values()) { 99 | if (dollShow != DollType.NONE && paperDoll.shouldRender(dollShow, player)) { 100 | if (paperDoll.currentDoll != DollType.NONE && paperDoll.currentDoll != dollShow) { 101 | paperDoll.lastDisplayedShow = paperDoll.currentDoll; 102 | } 103 | paperDoll.currentDoll = dollShow; 104 | renderDoll = true; 105 | break; 106 | } 107 | } 108 | if (!renderDoll && paperDoll.currentDoll != DollType.NONE) { 109 | paperDoll.lastDisplayedShow = paperDoll.currentDoll; 110 | paperDoll.currentDoll = DollType.NONE; 111 | } 112 | if (paperDoll.currentDoll != DollType.NONE) { 113 | paperDollShownTicks = 0; 114 | drawEntityOnScreen(20, 40, 17, -30, 0, Minecraft.getInstance().player); 115 | } else if (paperDollShownTicks < 200) { 116 | paperDollShownTicks++; 117 | drawEntityOnScreen(20, 40, 17, -30, 0, Minecraft.getInstance().player); 118 | } 119 | } 120 | 121 | if (ControllerMod.CONFIG.show_coordinates && !Minecraft.getInstance().player.isReducedDebugInfo()) { 122 | renderPosition(gui, poseStack); 123 | } 124 | 125 | if ((!Minecraft.getInstance().hasSingleplayerServer() || Minecraft.getInstance().getSingleplayerServer().isPublished()) && ControllerMod.CONFIG.ingame_player_names) { 126 | renderNames(gui, poseStack); 127 | } 128 | if (ControllerMod.CONFIG.show_button_hints) { 129 | renderButtonHints(gui, poseStack); 130 | } 131 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 132 | RenderSystem.setShaderTexture(0, GuiComponent.GUI_ICONS_LOCATION); 133 | RenderSystem.enableBlend(); 134 | RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); 135 | } 136 | } 137 | 138 | @SuppressWarnings("resource") 139 | @OnlyIn(Dist.CLIENT) 140 | public static void renderButtonHints(Gui gui, PoseStack matrixStack) { 141 | ControllerMapping map = ControllerMod.getInstance().controllerOptions.controllerKeyBindInventory; 142 | ControllerModel model = ControllerMod.getInstance().controllerOptions.controllerModel; 143 | if (map.isBoundToButton(model)) { 144 | int x1 = ControllerMod.getSafeArea() - 2; 145 | int y1 = gui.screenHeight - 12; 146 | ResourceLocation icon = model.getOrCreate(map.getButtonOnController(model))[0].getIcon(); 147 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 148 | RenderSystem.setShaderTexture(0, icon); 149 | Gui.blit(matrixStack, x1, y1 - 10, 0, 0, 20, 20, 20, 20); 150 | 151 | Minecraft.getInstance().font.drawShadow(matrixStack, I18n.get(map.getDescripti()), x1 + 20, y1 - 3, 0xffffff); 152 | } 153 | } 154 | 155 | @SuppressWarnings("resource") 156 | @OnlyIn(Dist.CLIENT) 157 | public static void renderPosition(Gui gui, PoseStack matrixStack) { 158 | Minecraft.getInstance().getProfiler().push("display-position"); 159 | RenderSystem.disableDepthTest(); 160 | 161 | BlockPos coordinates = Minecraft.getInstance().player.blockPosition(); 162 | String coordinatesText = "Position: "+coordinates.getX()+", "+coordinates.getY()+", "+coordinates.getZ(); 163 | 164 | int j = 9; 165 | int k = Minecraft.getInstance().font.width(coordinatesText); 166 | int y = 50; 167 | 168 | matrixStack.pushPose(); 169 | 170 | //ARGB 171 | Gui.fill(matrixStack, ControllerMod.getSafeArea(), y - 2, 3 + k + 1, y + j, 0x22020202); 172 | RenderSystem.enableDepthTest(); 173 | 174 | Minecraft.getInstance().font.draw(matrixStack, coordinatesText, ControllerMod.getSafeArea() + 3.0F, y+1, 0x555555); 175 | Minecraft.getInstance().font.draw(matrixStack, coordinatesText, ControllerMod.getSafeArea() + 2.0F, y, 0xffffff); 176 | matrixStack.popPose(); 177 | 178 | RenderSystem.disableBlend(); 179 | Minecraft.getInstance().getProfiler().pop(); 180 | } 181 | 182 | @SuppressWarnings("resource") 183 | @OnlyIn(Dist.CLIENT) 184 | public static void renderNames(Gui gui, PoseStack matrixStack) { 185 | Minecraft.getInstance().getProfiler().push("playerName"); 186 | Component playerName = Minecraft.getInstance().player.getName(); 187 | Minecraft.getInstance().font.draw(matrixStack, playerName, gui.screenWidth - Minecraft.getInstance().font.width(playerName), ControllerMod.getSafeArea(), ChatFormatting.WHITE.getColor()); 188 | RenderSystem.setShader(GameRenderer::getPositionTexShader); 189 | RenderSystem.setShaderTexture(0, GuiComponent.GUI_ICONS_LOCATION); 190 | Minecraft.getInstance().getProfiler().pop(); 191 | } 192 | 193 | @SuppressWarnings("deprecation") 194 | @OnlyIn(Dist.CLIENT) 195 | public static void drawEntityOnScreen(int posX, int posY, int scale, float mouseX, float mouseY, LivingEntity entity) { 196 | float f = (float)Math.atan((double)(mouseX / 40.0F)); 197 | float f1 = (float)Math.atan((double)(mouseY / 40.0F)); 198 | PoseStack matrixstack = new PoseStack(); 199 | matrixstack.pushPose(); 200 | matrixstack.translate((float)posX, (float)posY, 1050.0F); 201 | matrixstack.scale(1.0F, 1.0F, -1.0F); 202 | matrixstack.translate(0.0D, 0.0D, 1000.0D); 203 | matrixstack.scale((float)scale, (float)scale, (float)scale); 204 | Quaternion quaternion = Vector3f.ZP.rotationDegrees(180.0F); 205 | Quaternion quaternion1 = Vector3f.XP.rotationDegrees(f1 * 20.0F); 206 | quaternion.mul(quaternion1); 207 | matrixstack.mulPose(quaternion); 208 | float f2 = entity.yBodyRot; 209 | float f3 = entity.yRot; 210 | float f4 = entity.xRot; 211 | float f5 = entity.yHeadRotO; 212 | float f6 = entity.yHeadRot; 213 | entity.yBodyRot = 180.0F + f * 20.0F; 214 | // entity.yRot = 180.0F + f * 40.0F; 215 | // entity.xRot = -f1 * 20.0F; 216 | entity.yHeadRot = renderHeadYaw; 217 | entity.yHeadRotO = renderHeadYaw; 218 | 219 | EntityRenderDispatcher entityrenderermanager = Minecraft.getInstance().getEntityRenderDispatcher(); 220 | quaternion1.conj(); 221 | entityrenderermanager.overrideCameraOrientation(quaternion1); 222 | entityrenderermanager.setRenderShadow(false); 223 | MultiBufferSource.BufferSource irendertypebuffer$impl = Minecraft.getInstance().renderBuffers().bufferSource(); 224 | RenderSystem.runAsFancy(() -> { 225 | entityrenderermanager.render(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F, matrixstack, irendertypebuffer$impl, 15728880); 226 | }); 227 | irendertypebuffer$impl.endBatch(); 228 | entityrenderermanager.setRenderShadow(true); 229 | entity.yBodyRot = f2; 230 | entity.yRot = f3; 231 | entity.xRot = f4; 232 | entity.yHeadRotO = f5; 233 | entity.yHeadRot = f6; 234 | matrixstack.popPose(); 235 | } 236 | 237 | public enum DollType { 238 | ALWAYS_ON("AlwaysOn", "always_on", false, (player) -> true), 239 | CRAWLING("Crawling", "crawling", true, (player) -> player.isVisuallyCrawling()), 240 | CROUCHING("Crouching", "crouching", true, (player) -> player.isCrouching()), 241 | HURT("Hurt", "hurt", true, (player) -> player.hurtTime > 0), 242 | ON_FIRE("OnFire", "on_fire", true, (player) -> player.isOnFire()), 243 | FLYING("Flying", "flying", true, (player) -> player.getAbilities().flying), 244 | GLIDING("Gliding", "gliding", true, (player) -> player.isFallFlying()), 245 | MOVING("Moving", "moving", true, (player) -> !player.input.getMoveVector().equals(Vec2.ZERO)), 246 | JUMPING("Jumping", "jumping", true, (player) -> player.input.jumping), 247 | NONE("", "", false, null), 248 | RIDING("Riding", "riding", true, (player) -> player.isPassenger()), 249 | SPINNING("Spinning", "spinning", true, (player) -> player.isAutoSpinAttack()), 250 | SPRINTING("Sprinting", "sprinting", true, (player) -> player.isSprinting() && !player.isSwimming()), 251 | SWIMMING("Swimming", "swimming", true, (player) -> player.isVisuallySwimming() && player.isInWater()), 252 | SWINGING_ARM("SwingingArm", "swinging_arm", true, (player) -> player.swinging), 253 | USING_ITEM("UsingItem", "using_item", true, (player) -> player.isUsingItem()); 254 | 255 | String optionsText; 256 | String displayText; 257 | Function renderCheck; 258 | boolean defaultV; 259 | private DollType(String options, String display, boolean defaultV, Function renderCheck) { 260 | this.optionsText = options; 261 | this.displayText = display; 262 | this.renderCheck = renderCheck; 263 | this.defaultV = defaultV; 264 | } 265 | 266 | public String getOptionsText() { 267 | return "paperDoll_show"+optionsText; 268 | } 269 | 270 | public MutableComponent getDisplayText() { 271 | return new TranslatableComponent("gui.paper_doll."+displayText+""); 272 | } 273 | 274 | public boolean showInMenu() { 275 | return this != NONE && this != ALWAYS_ON; 276 | } 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/VirtualMouseHelper.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client; 2 | 3 | import java.nio.file.Path; 4 | import java.nio.file.Paths; 5 | import java.util.Arrays; 6 | 7 | import org.lwjgl.glfw.GLFWCursorPosCallbackI; 8 | import org.lwjgl.glfw.GLFWDropCallback; 9 | import org.lwjgl.glfw.GLFWMouseButtonCallbackI; 10 | import org.lwjgl.glfw.GLFWScrollCallbackI; 11 | 12 | import com.mojang.blaze3d.Blaze3D; 13 | import com.mojang.blaze3d.platform.InputConstants; 14 | 15 | import net.minecraft.client.KeyMapping; 16 | import net.minecraft.client.Minecraft; 17 | import net.minecraft.client.MouseHandler; 18 | import net.minecraft.client.gui.components.events.GuiEventListener; 19 | import net.minecraft.client.gui.screens.Screen; 20 | import net.minecraft.util.Mth; 21 | import net.minecraftforge.api.distmarker.Dist; 22 | import net.minecraftforge.api.distmarker.OnlyIn; 23 | 24 | @OnlyIn(Dist.CLIENT) 25 | public class VirtualMouseHelper extends MouseHandler { 26 | 27 | public VirtualMouseHelper(Minecraft minecraftIn) { 28 | super(minecraftIn); 29 | } 30 | 31 | /** 32 | * Will be called when a mouse button is pressed or released. 33 | * 34 | * @see GLFWMouseButtonCallbackI 35 | */ 36 | public void mouseButtonCallback(long handle, int button, int action, int mods) { 37 | if (handle == this.minecraft.getWindow().getWindow()) { 38 | boolean flag = action == 1; 39 | if (Minecraft.ON_OSX && button == 0) { 40 | if (flag) { 41 | if ((mods & 2) == 2) { 42 | button = 1; 43 | ++this.fakeRightMouse; 44 | } 45 | } else if (this.fakeRightMouse > 0) { 46 | button = 1; 47 | --this.fakeRightMouse; 48 | } 49 | } 50 | 51 | if (flag) { 52 | if (this.minecraft.options.touchscreen && this.clickDepth++ > 0) { 53 | return; 54 | } 55 | 56 | this.activeButton = button; 57 | this.mousePressedTime = Blaze3D.getTime(); 58 | } else if (this.activeButton != -1) { 59 | if (this.minecraft.options.touchscreen && --this.clickDepth > 0) { 60 | return; 61 | } 62 | 63 | this.activeButton = -1; 64 | } 65 | 66 | boolean[] aboolean = new boolean[]{false}; 67 | if (this.minecraft.getOverlay() == null) { 68 | if (this.minecraft.screen == null) { 69 | if (!this.mouseGrabbed && flag) { 70 | this.grabMouse(); 71 | } 72 | if (net.minecraftforge.client.ForgeHooksClient.onRawMouseClicked(button, action, mods)) return; 73 | } else { 74 | double d0 = this.xpos * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getWidth(); 75 | double d1 = this.ypos * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getHeight(); 76 | int p_198023_3_f = button; 77 | if (flag) { 78 | Screen.wrapScreenError(() -> { 79 | aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseClickedPre(this.minecraft.screen, d0, d1, p_198023_3_f); 80 | if (!aboolean[0]) aboolean[0] = this.minecraft.screen.mouseClicked(d0, d1, p_198023_3_f); 81 | if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseClickedPost(this.minecraft.screen, d0, d1, p_198023_3_f, aboolean[0]); 82 | }, "mouseClicked event handler", this.minecraft.screen.getClass().getCanonicalName()); 83 | } else { 84 | Screen.wrapScreenError(() -> { 85 | aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseReleasedPre(this.minecraft.screen, d0, d1, p_198023_3_f); 86 | if (!aboolean[0]) aboolean[0] = this.minecraft.screen.mouseReleased(d0, d1, p_198023_3_f); 87 | if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseReleasedPost(this.minecraft.screen, d0, d1, p_198023_3_f, aboolean[0]); 88 | }, "mouseReleased event handler", this.minecraft.screen.getClass().getCanonicalName()); 89 | } 90 | } 91 | } 92 | 93 | if (!aboolean[0] && (this.minecraft.screen == null || this.minecraft.screen.passEvents) && this.minecraft.getOverlay() == null) { 94 | if (button == 0) { 95 | this.isLeftPressed = flag; 96 | } else if (button == 2) { 97 | this.isMiddlePressed = flag; 98 | } else if (button == 1) { 99 | this.isRightPressed = flag; 100 | } 101 | 102 | KeyMapping.set(InputConstants.Type.MOUSE.getOrCreate(button), flag); 103 | if (flag) { 104 | if (this.minecraft.player.isSpectator() && button == 2) { 105 | this.minecraft.gui.getSpectatorGui().onMouseMiddleClick(); 106 | } else { 107 | KeyMapping.click(InputConstants.Type.MOUSE.getOrCreate(button)); 108 | } 109 | } 110 | } 111 | net.minecraftforge.client.ForgeHooksClient.fireMouseInput(button, action, mods); 112 | } 113 | } 114 | 115 | /** 116 | * Will be called when a scrolling device is used, such as a mouse wheel or scrolling area of a touchpad. 117 | * 118 | * @see GLFWScrollCallbackI 119 | */ 120 | public void scrollCallback(long handle, double xoffset, double yoffset) { 121 | if (handle == Minecraft.getInstance().getWindow().getWindow()) { 122 | double d0 = (this.minecraft.options.discreteMouseScroll ? Math.signum(yoffset) : yoffset) * this.minecraft.options.mouseWheelSensitivity; 123 | if (this.minecraft.getOverlay() == null) { 124 | if (this.minecraft.screen != null) { 125 | double d1 = this.xpos * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getWidth(); 126 | double d2 = this.ypos * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getHeight(); 127 | if (net.minecraftforge.client.ForgeHooksClient.onScreenMouseScrollPre(this, this.minecraft.screen, d0)) return; 128 | if (this.minecraft.screen.mouseScrolled(d1, d2, d0)) return; 129 | net.minecraftforge.client.ForgeHooksClient.onScreenMouseScrollPost(this, this.minecraft.screen, d0); 130 | } else if (this.minecraft.player != null) { 131 | if (this.accumulatedScroll != 0.0D && Math.signum(d0) != Math.signum(this.accumulatedScroll)) { 132 | this.accumulatedScroll = 0.0D; 133 | } 134 | 135 | this.accumulatedScroll += d0; 136 | int f1 = (int)this.accumulatedScroll; 137 | if (f1 == 0.0F) { 138 | return; 139 | } 140 | 141 | this.accumulatedScroll -= (double)f1; 142 | // if (net.minecraftforge.client.ForgeHooksClient.onMouseScrolled(this, d0)) return; 143 | if (this.minecraft.player.isSpectator()) { 144 | if (this.minecraft.gui.getSpectatorGui().isMenuActive()) { 145 | this.minecraft.gui.getSpectatorGui().onMouseScrolled(-f1); 146 | } else { 147 | float f = Mth.clamp(this.minecraft.player.getAbilities().getFlyingSpeed() + f1 * 0.005F, 0.0F, 0.2F); 148 | this.minecraft.player.getAbilities().setFlyingSpeed(f); 149 | } 150 | } else { 151 | this.minecraft.player.getInventory().swapPaint((double)f1); 152 | } 153 | } 154 | } 155 | } 156 | 157 | } 158 | 159 | @Override 160 | public void setup(long handle) { 161 | InputConstants.setupMouseCallbacks(handle, (p_228032_1_, p_228032_3_, p_228032_5_) -> { 162 | this.minecraft.execute(() -> { 163 | this.onMove(p_228032_1_, p_228032_3_, p_228032_5_); 164 | }); 165 | }, (p_228028_1_, p_228028_3_, p_228028_4_, p_228028_5_) -> { 166 | this.minecraft.execute(() -> { 167 | this.mouseButtonCallback(p_228028_1_, p_228028_3_, p_228028_4_, p_228028_5_); 168 | }); 169 | }, (p_228029_1_, p_228029_3_, p_228029_5_) -> { 170 | this.minecraft.execute(() -> { 171 | this.scrollCallback(p_228029_1_, p_228029_3_, p_228029_5_); 172 | }); 173 | }, (p_238227_1_, p_238227_3_, p_238227_4_) -> { 174 | Path[] apath = new Path[p_238227_3_]; 175 | 176 | for(int i = 0; i < p_238227_3_; ++i) { 177 | apath[i] = Paths.get(GLFWDropCallback.getName(p_238227_4_, i)); 178 | } 179 | 180 | this.minecraft.execute(() -> { 181 | this.onDrop(p_238227_1_, Arrays.asList(apath)); 182 | }); 183 | }); 184 | } 185 | 186 | /** 187 | * Will be called when the cursor is moved. 188 | * 189 | *

The callback function receives the cursor position, measured in screen coordinates but relative to the top-left 190 | * corner of the window client area. On platforms that provide it, the full sub-pixel cursor position is passed 191 | * on.

192 | * 193 | * @see GLFWCursorPosCallbackI 194 | */ 195 | @Override 196 | public void onMove(long handle, double xpos, double ypos) { 197 | if (handle == Minecraft.getInstance().getWindow().getWindow()) { 198 | if (this.ignoreFirstMove) { 199 | this.xpos = xpos; 200 | this.ypos = ypos; 201 | this.ignoreFirstMove = false; 202 | } 203 | 204 | GuiEventListener iguieventlistener = this.minecraft.screen; 205 | if (iguieventlistener != null && this.minecraft.getOverlay() == null) { 206 | double d0 = xpos * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getWidth(); 207 | double d1 = ypos * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getHeight(); 208 | Screen.wrapScreenError(() -> { 209 | iguieventlistener.mouseMoved(d0, d1); 210 | }, "mouseMoved event handler", iguieventlistener.getClass().getCanonicalName()); 211 | if (this.activeButton != -1 && this.mousePressedTime > 0.0D) { 212 | double d2 = (xpos - this.xpos) * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getWidth(); 213 | double d3 = (ypos - this.ypos) * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getHeight(); 214 | Screen.wrapScreenError(() -> { 215 | if (net.minecraftforge.client.ForgeHooksClient.onScreenMouseDragPre(this.minecraft.screen, d0, d1, this.activeButton, d2, d3)) return; 216 | if (iguieventlistener.mouseDragged(d0, d1, this.activeButton, d2, d3)) return; 217 | net.minecraftforge.client.ForgeHooksClient.onScreenMouseDragPost(this.minecraft.screen, d0, d1, this.activeButton, d2, d3); 218 | }, "mouseDragged event handler", iguieventlistener.getClass().getCanonicalName()); 219 | } 220 | } 221 | 222 | this.minecraft.getProfiler().push("mouse"); 223 | if (this.isMouseGrabbed() && this.minecraft.isWindowActive()) { 224 | this.accumulatedDX += xpos - this.xpos; 225 | this.accumulatedDY += ypos - this.ypos; 226 | } 227 | 228 | this.turnPlayer(); 229 | this.xpos = xpos; 230 | this.ypos = ypos; 231 | this.minecraft.getProfiler().pop(); 232 | } 233 | } 234 | 235 | @Override 236 | public void turnPlayer() { 237 | double d0 = Blaze3D.getTime(); 238 | double d1 = d0 - this.lastMouseEventTime; 239 | this.lastMouseEventTime = d0; 240 | if (this.isMouseGrabbed() && this.minecraft.isWindowActive()) { 241 | double d4 = this.minecraft.options.sensitivity * (double)0.6F + (double)0.2F; 242 | double d5 = d4 * d4 * d4 * 8.0D; 243 | double d2; 244 | double d3; 245 | if (this.minecraft.options.smoothCamera) { 246 | double d6 = this.smoothTurnX.getNewDeltaValue(this.accumulatedDX * d5, d1 * d5); 247 | double d7 = this.smoothTurnY.getNewDeltaValue(this.accumulatedDY * d5, d1 * d5); 248 | d2 = d6; 249 | d3 = d7; 250 | } else { 251 | this.smoothTurnX.reset(); 252 | this.smoothTurnY.reset(); 253 | d2 = this.accumulatedDX * d5; 254 | d3 = this.accumulatedDY * d5; 255 | } 256 | 257 | this.accumulatedDX = 0.0D; 258 | this.accumulatedDY = 0.0D; 259 | int i = 1; 260 | if (this.minecraft.options.invertYMouse) { 261 | i = -1; 262 | } 263 | 264 | this.minecraft.getTutorial().onMouse(d2, d3); 265 | if (this.minecraft.player != null) { 266 | this.minecraft.player.turn(d2, d3 * (double)i); 267 | } 268 | 269 | } else { 270 | this.accumulatedDX = 0.0D; 271 | this.accumulatedDY = 0.0D; 272 | } 273 | } 274 | 275 | /** 276 | * Will set the focus to ingame if the Minecraft window is the active with focus. Also clears any GUI screen 277 | * currently displayed 278 | */ 279 | @Override 280 | public void grabMouse() { 281 | if (this.minecraft.isWindowActive()) { 282 | if (!this.mouseGrabbed) { 283 | if (!Minecraft.ON_OSX) { 284 | KeyMapping.setAll(); 285 | } 286 | 287 | this.mouseGrabbed = true; 288 | this.xpos = (double)(this.minecraft.getWindow().getWidth() / 2); 289 | this.ypos = (double)(this.minecraft.getWindow().getHeight() / 2); 290 | InputConstants.grabOrReleaseMouse(this.minecraft.getWindow().getWindow(), 212995, this.xpos, this.ypos); 291 | this.minecraft.setScreen((Screen)null); 292 | // this.minecraft.leftClickCounter = 10000; 293 | this.ignoreFirstMove = true; 294 | } 295 | } 296 | } 297 | 298 | /** 299 | * Resets the player keystate, disables the ingame focus, and ungrabs the mouse cursor. 300 | */ 301 | public void ungrabMouse() { 302 | if (this.mouseGrabbed) { 303 | this.mouseGrabbed = false; 304 | this.xpos = (double)(this.minecraft.getWindow().getWidth() / 2); 305 | this.ypos = (double)(this.minecraft.getWindow().getHeight() / 2); 306 | InputConstants.grabOrReleaseMouse(this.minecraft.getWindow().getWindow(), 212993, this.xpos, this.ypos); 307 | } 308 | } 309 | } -------------------------------------------------------------------------------- /src/main/java/com/stereowalker/controllermod/client/gui/widget/list/ControllerBindingList.java: -------------------------------------------------------------------------------- 1 | package com.stereowalker.controllermod.client.gui.widget.list; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import org.apache.commons.lang3.ArrayUtils; 8 | 9 | import com.google.common.collect.ImmutableList; 10 | import com.google.common.collect.Lists; 11 | import com.mojang.blaze3d.vertex.PoseStack; 12 | import com.stereowalker.controllermod.ControllerMod; 13 | import com.stereowalker.controllermod.client.controller.ControllerMap; 14 | import com.stereowalker.controllermod.client.controller.ControllerMapping; 15 | import com.stereowalker.controllermod.client.controller.ControllerModel; 16 | import com.stereowalker.controllermod.client.controller.ControllerUtil.InputType; 17 | import com.stereowalker.controllermod.client.gui.screen.ControllerInputOptionsScreen; 18 | import com.stereowalker.unionlib.client.gui.components.OverlayImageButton; 19 | 20 | import net.minecraft.ChatFormatting; 21 | import net.minecraft.client.Minecraft; 22 | import net.minecraft.client.gui.components.Button; 23 | import net.minecraft.client.gui.components.ContainerObjectSelectionList; 24 | import net.minecraft.client.gui.components.events.GuiEventListener; 25 | import net.minecraft.client.gui.narration.NarratableEntry; 26 | import net.minecraft.network.chat.Component; 27 | import net.minecraft.network.chat.MutableComponent; 28 | import net.minecraft.network.chat.TextComponent; 29 | import net.minecraft.network.chat.TranslatableComponent; 30 | import net.minecraftforge.api.distmarker.Dist; 31 | import net.minecraftforge.api.distmarker.OnlyIn; 32 | 33 | @OnlyIn(Dist.CLIENT) 34 | public class ControllerBindingList extends ContainerObjectSelectionList { 35 | private final ControllerInputOptionsScreen controlsScreen; 36 | private int maxListLabelWidth; 37 | private ControllerMod mod; 38 | 39 | public ControllerBindingList(ControllerInputOptionsScreen controls, Minecraft mcIn, ControllerMod modIn) { 40 | super(mcIn, controls.width + 45, controls.height, 43, controls.height - 32, 20); 41 | this.controlsScreen = controls; 42 | this.mod = modIn; 43 | ControllerMapping[] akeybinding = ArrayUtils.clone(modIn.controllerOptions.controllerBindings); 44 | Arrays.sort(akeybinding); 45 | String s = null; 46 | 47 | for(ControllerMapping keybinding : akeybinding) { 48 | String s1 = keybinding.getCategory(); 49 | if (!s1.equals(s)) { 50 | s = s1; 51 | this.addEntry(new ControllerBindingList.CategoryEntry(new TranslatableComponent(s1))); 52 | } 53 | 54 | Component itextcomponent = new TranslatableComponent(keybinding.getDescripti()); 55 | int i = mcIn.font.width(itextcomponent); 56 | if (i > this.maxListLabelWidth) { 57 | this.maxListLabelWidth = i; 58 | } 59 | 60 | this.addEntry(new ControllerBindingList.KeyEntry(keybinding, itextcomponent)); 61 | } 62 | 63 | } 64 | 65 | @Override 66 | protected int getScrollbarPosition() { 67 | return super.getScrollbarPosition() + 15 + 40; 68 | } 69 | 70 | @Override 71 | public int getRowWidth() { 72 | return super.getRowWidth() + 72; 73 | } 74 | 75 | @OnlyIn(Dist.CLIENT) 76 | public class CategoryEntry extends ControllerBindingList.Entry { 77 | private final Component labelText; 78 | private final int labelWidth; 79 | 80 | public CategoryEntry(Component p_i232280_2_) { 81 | this.labelText = p_i232280_2_; 82 | this.labelWidth = ControllerBindingList.this.minecraft.font.width(this.labelText); 83 | } 84 | 85 | @Override 86 | public void render(PoseStack p_230432_1_, int p_230432_2_, int p_230432_3_, int p_230432_4_, int p_230432_5_, int p_230432_6_, int p_230432_7_, int p_230432_8_, boolean p_230432_9_, float p_230432_10_) { 87 | ControllerBindingList.this.minecraft.font.draw(p_230432_1_, this.labelText, (float)(ControllerBindingList.this.minecraft.screen.width / 2 - this.labelWidth / 2), (float)(p_230432_3_ + p_230432_6_ - 9 - 1), 16777215); 88 | } 89 | 90 | @Override 91 | public boolean changeFocus(boolean focus) { 92 | return false; 93 | } 94 | 95 | @Override 96 | public List children() { 97 | return Collections.emptyList(); 98 | } 99 | 100 | @Override 101 | public List narratables() { 102 | return Collections.emptyList(); 103 | } 104 | } 105 | 106 | @OnlyIn(Dist.CLIENT) 107 | public abstract static class Entry extends ContainerObjectSelectionList.Entry { 108 | } 109 | 110 | @OnlyIn(Dist.CLIENT) 111 | public class KeyEntry extends ControllerBindingList.Entry { 112 | /** The controllerBinding specified for this KeyEntry */ 113 | private final ControllerMapping controllerBinding; 114 | /** The localized key description for this KeyEntry */ 115 | private final Component keyDesc; 116 | private final OverlayImageButton btnChangeKeyBinding; 117 | private final Button btnInputType; 118 | private final Button btnReset; 119 | 120 | private KeyEntry(final ControllerMapping controllerBinding, final Component keyDesc) { 121 | this.controllerBinding = controllerBinding; 122 | this.keyDesc = keyDesc; 123 | ControllerModel model = ControllerMod.getInstance().controllerOptions.controllerModel; 124 | this.btnChangeKeyBinding = new OverlayImageButton(0, 0, 65 /*Forge: add space*/, 20, 125 | //Overlay1 126 | 0, 0, 20, 20, null, 20, 20, 127 | //Overlay2 128 | 0, 0, 20, 20, null, 20, 20, 129 | (p_214386_2_) -> { 130 | ControllerBindingList.this.controlsScreen.keyToSet = controllerBinding; 131 | }, keyDesc) { 132 | @Override 133 | protected MutableComponent createNarrationMessage() { 134 | return controllerBinding.isBoundToButton(model) ? new TranslatableComponent("narrator.controls.unbound", keyDesc) : new TranslatableComponent("narrator.controls.bound", keyDesc, super.createNarrationMessage()); 135 | } 136 | }; 137 | this.btnReset = new Button(0, 0, 50, 20, new TranslatableComponent("controls.reset"), (p_214387_2_) -> { 138 | controllerBinding.setToDefault(ControllerMod.getInstance().controllerOptions.controllerModel); 139 | ControllerBindingList.this.mod.controllerOptions.setKeyBindingCode(ControllerMod.getInstance().controllerOptions.controllerModel, controllerBinding, controllerBinding.getDefault(ControllerMod.getInstance().controllerOptions.controllerModel)); 140 | // ControllerBinding.resetKeyBindingArrayAndHash(); 141 | }) { 142 | protected MutableComponent createNarrationMessage() { 143 | return new TranslatableComponent("narrator.controls.reset", keyDesc); 144 | } 145 | }; 146 | this.btnInputType = new Button(0, 10, 70, 20, controllerBinding.getInputType(ControllerMod.getInstance().controllerOptions.controllerModel) != null ? controllerBinding.getInputType(ControllerMod.getInstance().controllerOptions.controllerModel).getDisplayName() : new TextComponent(""), (p_214387_2_) -> { 147 | if (controllerBinding.isAxis()) { 148 | ControllerBindingList.this.mod.controllerOptions.setKeyBindingInverted(ControllerMod.getInstance().controllerOptions.controllerModel, controllerBinding, !controllerBinding.isAxisInverted(ControllerMod.getInstance().controllerOptions.controllerModel)); 149 | } else { 150 | if (controllerBinding.getInputType(ControllerMod.getInstance().controllerOptions.controllerModel) == InputType.PRESS) ControllerBindingList.this.mod.controllerOptions.setKeyBindingInputType(ControllerMod.getInstance().controllerOptions.controllerModel, controllerBinding, InputType.TOGGLE); 151 | else if (controllerBinding.getInputType(ControllerMod.getInstance().controllerOptions.controllerModel) == InputType.TOGGLE) ControllerBindingList.this.mod.controllerOptions.setKeyBindingInputType(ControllerMod.getInstance().controllerOptions.controllerModel ,controllerBinding, InputType.HOLD); 152 | else ControllerBindingList.this.mod.controllerOptions.setKeyBindingInputType(ControllerMod.getInstance().controllerOptions.controllerModel, controllerBinding, InputType.PRESS); 153 | } 154 | }) { 155 | @Override 156 | protected MutableComponent createNarrationMessage() { 157 | return new TranslatableComponent("narrator.controls.reset", keyDesc); 158 | } 159 | }; 160 | } 161 | 162 | @Override 163 | public void render(PoseStack p_230432_1_, int p_230432_2_, int p_230432_3_, int p_230432_4_, int p_230432_5_, int p_230432_6_, int p_230432_7_, int p_230432_8_, boolean p_230432_9_, float p_230432_10_) { 164 | boolean flag = ControllerBindingList.this.controlsScreen.keyToSet == this.controllerBinding; 165 | ControllerModel model = ControllerMod.getInstance().controllerOptions.controllerModel; 166 | ControllerMap.Button[] button = model.getOrCreate(Lists.newArrayList(controllerBinding.getButtonOnController(model))); 167 | ControllerBindingList.this.minecraft.font.draw(p_230432_1_, this.keyDesc, (float)(p_230432_4_ + 65 - ControllerBindingList.this.maxListLabelWidth), (float)(p_230432_3_ + p_230432_6_ / 2 - 9 / 2), 16777215); 168 | this.btnInputType.x = p_230432_4_ + 166; 169 | this.btnInputType.y = p_230432_3_; 170 | if (controllerBinding.isAxis()) { 171 | this.btnInputType.setMessage(controllerBinding.isAxisInverted(model) ? new TranslatableComponent("gui.inverted") : new TranslatableComponent("Not Inverted")); 172 | } else { 173 | this.btnInputType.setMessage(controllerBinding.getInputType(model).getDisplayName()); 174 | } 175 | this.btnInputType.render(p_230432_1_, p_230432_7_, p_230432_8_, p_230432_10_); 176 | this.btnReset.x = p_230432_4_ + 190 + 50; 177 | this.btnReset.y = p_230432_3_; 178 | this.btnReset.active = !this.controllerBinding.isDefault(model); 179 | this.btnReset.render(p_230432_1_, p_230432_7_, p_230432_8_, p_230432_10_); 180 | this.btnChangeKeyBinding.x = p_230432_4_ + 98; 181 | this.btnChangeKeyBinding.y = p_230432_3_; 182 | this.btnChangeKeyBinding.setFirstOverlay(button[0].getIcon()); 183 | this.btnChangeKeyBinding.adjustFirstOverlay(0, 0); 184 | this.btnChangeKeyBinding.adjustSecondOverlay(0, 0); 185 | if (button.length > 1) { 186 | this.btnChangeKeyBinding.setSecondOverlay(button[1].getIcon()); 187 | this.btnChangeKeyBinding.adjustFirstOverlay(-15, 0); 188 | this.btnChangeKeyBinding.adjustSecondOverlay(15, 0); 189 | this.btnChangeKeyBinding.showMessage(); 190 | this.btnChangeKeyBinding.setMessage(new TextComponent("+")); 191 | } else { 192 | if (button[0].getIcon() != null) 193 | this.btnChangeKeyBinding.hideMessage(); 194 | this.btnChangeKeyBinding.setSecondOverlay(null); 195 | this.btnChangeKeyBinding.setMessage(new TextComponent(ControllerMap.map(controllerBinding.getButtonOnController(model).get(0), model))); 196 | } 197 | boolean flag1 = false; 198 | boolean keyCodeModifierConflict = false;//true; // less severe form of conflict, like SHIFT conflicting with SHIFT+G 199 | if (this.controllerBinding.isBoundToButton(model)) { 200 | for(ControllerMapping keybinding : ControllerMod.getInstance().controllerOptions.controllerBindings) { 201 | if (keybinding == this.controllerBinding || !this.controllerBinding.same(keybinding, model)) continue; 202 | flag1 = true; 203 | break; 204 | // keyCodeModifierConflict &= keybinding.hasKeyCodeModifierConflict(keybinding); 205 | } 206 | } 207 | 208 | if (flag) { 209 | this.btnChangeKeyBinding.setFirstOverlay(null); 210 | this.btnChangeKeyBinding.setSecondOverlay(null); 211 | this.btnChangeKeyBinding.showMessage(); 212 | if (button[0].getIcon() != null) 213 | this.btnChangeKeyBinding.setMessage((new TextComponent("> ")).append(" <").withStyle(ChatFormatting.YELLOW)); 214 | else 215 | this.btnChangeKeyBinding.setMessage((new TextComponent("> ")).append(this.btnChangeKeyBinding.getMessage().copy().withStyle(ChatFormatting.YELLOW)).append(" <").withStyle(ChatFormatting.YELLOW)); 216 | } else if (flag1) { 217 | this.btnChangeKeyBinding.showMessage(); 218 | if (button[0].getIcon() != null) 219 | this.btnChangeKeyBinding.setMessage(new TextComponent("CONFLICT").withStyle(keyCodeModifierConflict ? ChatFormatting.GOLD : ChatFormatting.RED)); 220 | else 221 | this.btnChangeKeyBinding.setMessage(this.btnChangeKeyBinding.getMessage().copy().withStyle(keyCodeModifierConflict ? ChatFormatting.GOLD : ChatFormatting.RED)); 222 | } 223 | 224 | this.btnChangeKeyBinding.render(p_230432_1_, p_230432_7_, p_230432_8_, p_230432_10_); 225 | } 226 | 227 | @Override 228 | public List children() { 229 | return ImmutableList.of(this.btnChangeKeyBinding, this.btnReset, this.btnInputType); 230 | } 231 | 232 | @Override 233 | public List narratables() { 234 | return ImmutableList.of(this.btnChangeKeyBinding, this.btnReset, this.btnInputType); 235 | } 236 | 237 | @Override 238 | public boolean mouseClicked(double mouseX, double mouseY, int button) { 239 | if (this.btnChangeKeyBinding.mouseClicked(mouseX, mouseY, button)) { 240 | return true; 241 | } else if (this.btnInputType.mouseClicked(mouseX, mouseY, button)) { 242 | return true; 243 | } else { 244 | return this.btnReset.mouseClicked(mouseX, mouseY, button); 245 | } 246 | } 247 | 248 | @Override 249 | public boolean mouseReleased(double mouseX, double mouseY, int button) { 250 | return this.btnChangeKeyBinding.mouseReleased(mouseX, mouseY, button) || this.btnReset.mouseReleased(mouseX, mouseY, button) || this.btnInputType.mouseReleased(mouseX, mouseY, button); 251 | } 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 2 | International Public License 3 | 4 | By exercising the Licensed Rights (defined below), You accept and agree 5 | to be bound by the terms and conditions of this Creative Commons 6 | Attribution-NonCommercial-NoDerivatives 4.0 International Public 7 | License ("Public License"). To the extent this Public License may be 8 | interpreted as a contract, You are granted the Licensed Rights in 9 | consideration of Your acceptance of these terms and conditions, and the 10 | Licensor grants You such rights in consideration of benefits the 11 | Licensor receives from making the Licensed Material available under 12 | these terms and conditions. 13 | 14 | 15 | Section 1 -- Definitions. 16 | 17 | a. Adapted Material means material subject to Copyright and Similar 18 | Rights that is derived from or based upon the Licensed Material 19 | and in which the Licensed Material is translated, altered, 20 | arranged, transformed, or otherwise modified in a manner requiring 21 | permission under the Copyright and Similar Rights held by the 22 | Licensor. For purposes of this Public License, where the Licensed 23 | Material is a musical work, performance, or sound recording, 24 | Adapted Material is always produced where the Licensed Material is 25 | synched in timed relation with a moving image. 26 | 27 | b. Copyright and Similar Rights means copyright and/or similar rights 28 | closely related to copyright including, without limitation, 29 | performance, broadcast, sound recording, and Sui Generis Database 30 | Rights, without regard to how the rights are labeled or 31 | categorized. For purposes of this Public License, the rights 32 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 33 | Rights. 34 | 35 | c. Effective Technological Measures means those measures that, in the 36 | absence of proper authority, may not be circumvented under laws 37 | fulfilling obligations under Article 11 of the WIPO Copyright 38 | Treaty adopted on December 20, 1996, and/or similar international 39 | agreements. 40 | 41 | d. Exceptions and Limitations means fair use, fair dealing, and/or 42 | any other exception or limitation to Copyright and Similar Rights 43 | that applies to Your use of the Licensed Material. 44 | 45 | e. Licensed Material means the artistic or literary work, database, 46 | or other material to which the Licensor applied this Public 47 | License. 48 | 49 | f. Licensed Rights means the rights granted to You subject to the 50 | terms and conditions of this Public License, which are limited to 51 | all Copyright and Similar Rights that apply to Your use of the 52 | Licensed Material and that the Licensor has authority to license. 53 | 54 | g. Licensor means the individual(s) or entity(ies) granting rights 55 | under this Public License. 56 | 57 | h. NonCommercial means not primarily intended for or directed towards 58 | commercial advantage or monetary compensation. For purposes of 59 | this Public License, the exchange of the Licensed Material for 60 | other material subject to Copyright and Similar Rights by digital 61 | file-sharing or similar means is NonCommercial provided there is 62 | no payment of monetary compensation in connection with the 63 | exchange. 64 | 65 | i. Share means to provide material to the public by any means or 66 | process that requires permission under the Licensed Rights, such 67 | as reproduction, public display, public performance, distribution, 68 | dissemination, communication, or importation, and to make material 69 | available to the public including in ways that members of the 70 | public may access the material from a place and at a time 71 | individually chosen by them. 72 | 73 | j. Sui Generis Database Rights means rights other than copyright 74 | resulting from Directive 96/9/EC of the European Parliament and of 75 | the Council of 11 March 1996 on the legal protection of databases, 76 | as amended and/or succeeded, as well as other essentially 77 | equivalent rights anywhere in the world. 78 | 79 | k. You means the individual or entity exercising the Licensed Rights 80 | under this Public License. Your has a corresponding meaning. 81 | 82 | 83 | Section 2 -- Scope. 84 | 85 | a. License grant. 86 | 87 | 1. Subject to the terms and conditions of this Public License, 88 | the Licensor hereby grants You a worldwide, royalty-free, 89 | non-sublicensable, non-exclusive, irrevocable license to 90 | exercise the Licensed Rights in the Licensed Material to: 91 | 92 | a. reproduce and Share the Licensed Material, in whole or 93 | in part, for NonCommercial purposes only; and 94 | 95 | b. produce and reproduce, but not Share, Adapted Material 96 | for NonCommercial purposes only. 97 | 98 | 2. Exceptions and Limitations. For the avoidance of doubt, where 99 | Exceptions and Limitations apply to Your use, this Public 100 | License does not apply, and You do not need to comply with 101 | its terms and conditions. 102 | 103 | 3. Term. The term of this Public License is specified in Section 104 | 6(a). 105 | 106 | 4. Media and formats; technical modifications allowed. The 107 | Licensor authorizes You to exercise the Licensed Rights in 108 | all media and formats whether now known or hereafter created, 109 | and to make technical modifications necessary to do so. The 110 | Licensor waives and/or agrees not to assert any right or 111 | authority to forbid You from making technical modifications 112 | necessary to exercise the Licensed Rights, including 113 | technical modifications necessary to circumvent Effective 114 | Technological Measures. For purposes of this Public License, 115 | simply making modifications authorized by this Section 2(a) 116 | (4) never produces Adapted Material. 117 | 118 | 5. Downstream recipients. 119 | 120 | a. Offer from the Licensor -- Licensed Material. Every 121 | recipient of the Licensed Material automatically 122 | receives an offer from the Licensor to exercise the 123 | Licensed Rights under the terms and conditions of this 124 | Public License. 125 | 126 | b. No downstream restrictions. You may not offer or impose 127 | any additional or different terms or conditions on, or 128 | apply any Effective Technological Measures to, the 129 | Licensed Material if doing so restricts exercise of the 130 | Licensed Rights by any recipient of the Licensed 131 | Material. 132 | 133 | 6. No endorsement. Nothing in this Public License constitutes or 134 | may be construed as permission to assert or imply that You 135 | are, or that Your use of the Licensed Material is, connected 136 | with, or sponsored, endorsed, or granted official status by, 137 | the Licensor or others designated to receive attribution as 138 | provided in Section 3(a)(1)(A)(i). 139 | 140 | b. Other rights. 141 | 142 | 1. Moral rights, such as the right of integrity, are not 143 | licensed under this Public License, nor are publicity, 144 | privacy, and/or other similar personality rights; however, to 145 | the extent possible, the Licensor waives and/or agrees not to 146 | assert any such rights held by the Licensor to the limited 147 | extent necessary to allow You to exercise the Licensed 148 | Rights, but not otherwise. 149 | 150 | 2. Patent and trademark rights are not licensed under this 151 | Public License. 152 | 153 | 3. To the extent possible, the Licensor waives any right to 154 | collect royalties from You for the exercise of the Licensed 155 | Rights, whether directly or through a collecting society 156 | under any voluntary or waivable statutory or compulsory 157 | licensing scheme. In all other cases the Licensor expressly 158 | reserves any right to collect such royalties, including when 159 | the Licensed Material is used other than for NonCommercial 160 | purposes. 161 | 162 | 163 | Section 3 -- License Conditions. 164 | 165 | Your exercise of the Licensed Rights is expressly made subject to the 166 | following conditions. 167 | 168 | a. Attribution. 169 | 170 | 1. If You Share the Licensed Material, You must: 171 | 172 | a. retain the following if it is supplied by the Licensor 173 | with the Licensed Material: 174 | 175 | i. identification of the creator(s) of the Licensed 176 | Material and any others designated to receive 177 | attribution, in any reasonable manner requested by 178 | the Licensor (including by pseudonym if 179 | designated); 180 | 181 | ii. a copyright notice; 182 | 183 | iii. a notice that refers to this Public License; 184 | 185 | iv. a notice that refers to the disclaimer of 186 | warranties; 187 | 188 | v. a URI or hyperlink to the Licensed Material to the 189 | extent reasonably practicable; 190 | 191 | b. indicate if You modified the Licensed Material and 192 | retain an indication of any previous modifications; and 193 | 194 | c. indicate the Licensed Material is licensed under this 195 | Public License, and include the text of, or the URI or 196 | hyperlink to, this Public License. 197 | 198 | For the avoidance of doubt, You do not have permission under 199 | this Public License to Share Adapted Material. 200 | 201 | 2. You may satisfy the conditions in Section 3(a)(1) in any 202 | reasonable manner based on the medium, means, and context in 203 | which You Share the Licensed Material. For example, it may be 204 | reasonable to satisfy the conditions by providing a URI or 205 | hyperlink to a resource that includes the required 206 | information. 207 | 208 | 3. If requested by the Licensor, You must remove any of the 209 | information required by Section 3(a)(1)(A) to the extent 210 | reasonably practicable. 211 | 212 | 213 | Section 4 -- Sui Generis Database Rights. 214 | 215 | Where the Licensed Rights include Sui Generis Database Rights that 216 | apply to Your use of the Licensed Material: 217 | 218 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 219 | to extract, reuse, reproduce, and Share all or a substantial 220 | portion of the contents of the database for NonCommercial purposes 221 | only and provided You do not Share Adapted Material; 222 | 223 | b. if You include all or a substantial portion of the database 224 | contents in a database in which You have Sui Generis Database 225 | Rights, then the database in which You have Sui Generis Database 226 | Rights (but not its individual contents) is Adapted Material; and 227 | 228 | c. You must comply with the conditions in Section 3(a) if You Share 229 | all or a substantial portion of the contents of the database. 230 | 231 | For the avoidance of doubt, this Section 4 supplements and does not 232 | replace Your obligations under this Public License where the Licensed 233 | Rights include other Copyright and Similar Rights. 234 | 235 | 236 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 237 | 238 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 239 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 240 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 241 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 242 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 243 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 244 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 245 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 246 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 247 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 248 | 249 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 250 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 251 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 252 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 253 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 254 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 255 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 256 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 257 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 258 | 259 | c. The disclaimer of warranties and limitation of liability provided 260 | above shall be interpreted in a manner that, to the extent 261 | possible, most closely approximates an absolute disclaimer and 262 | waiver of all liability. 263 | 264 | 265 | Section 6 -- Term and Termination. 266 | 267 | a. This Public License applies for the term of the Copyright and 268 | Similar Rights licensed here. However, if You fail to comply with 269 | this Public License, then Your rights under this Public License 270 | terminate automatically. 271 | 272 | b. Where Your right to use the Licensed Material has terminated under 273 | Section 6(a), it reinstates: 274 | 275 | 1. automatically as of the date the violation is cured, provided 276 | it is cured within 30 days of Your discovery of the 277 | violation; or 278 | 279 | 2. upon express reinstatement by the Licensor. 280 | 281 | For the avoidance of doubt, this Section 6(b) does not affect any 282 | right the Licensor may have to seek remedies for Your violations 283 | of this Public License. 284 | 285 | c. For the avoidance of doubt, the Licensor may also offer the 286 | Licensed Material under separate terms or conditions or stop 287 | distributing the Licensed Material at any time; however, doing so 288 | will not terminate this Public License. 289 | 290 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 291 | License. 292 | 293 | 294 | Section 7 -- Other Terms and Conditions. 295 | 296 | a. The Licensor shall not be bound by any additional or different 297 | terms or conditions communicated by You unless expressly agreed. 298 | 299 | b. Any arrangements, understandings, or agreements regarding the 300 | Licensed Material not stated herein are separate from and 301 | independent of the terms and conditions of this Public License. 302 | 303 | 304 | Section 8 -- Interpretation. 305 | 306 | a. For the avoidance of doubt, this Public License does not, and 307 | shall not be interpreted to, reduce, limit, restrict, or impose 308 | conditions on any use of the Licensed Material that could lawfully 309 | be made without permission under this Public License. 310 | 311 | b. To the extent possible, if any provision of this Public License is 312 | deemed unenforceable, it shall be automatically reformed to the 313 | minimum extent necessary to make it enforceable. If the provision 314 | cannot be reformed, it shall be severed from this Public License 315 | without affecting the enforceability of the remaining terms and 316 | conditions. 317 | 318 | c. No term or condition of this Public License will be waived and no 319 | failure to comply consented to unless expressly agreed to by the 320 | Licensor. 321 | 322 | d. Nothing in this Public License constitutes or may be interpreted 323 | as a limitation upon, or waiver of, any privileges and immunities 324 | that apply to the Licensor or You, including from the legal 325 | processes of any jurisdiction or authority. --------------------------------------------------------------------------------