├── LICENSE ├── lib ├── ini4j.jar ├── jinput.jar ├── jinput-dx8.dll ├── jinput-raw.dll ├── rxjava-core.jar ├── jinput-dx8_64.dll ├── jinput-raw_64.dll ├── jinput-wintab.dll ├── libjinput-linux.so ├── libjinput-linux64.so └── libjinput-osx.jnilib ├── src ├── content │ ├── gametitles │ │ ├── minecraft.png │ │ └── mincecraft.png │ ├── inputdevices │ │ ├── generic.png │ │ ├── xbox360.png │ │ ├── xbox_one.png │ │ └── xbox360 │ │ │ ├── back.png │ │ │ ├── d-pad.png │ │ │ ├── start.png │ │ │ ├── facebutton_a.png │ │ │ ├── facebutton_b.png │ │ │ ├── facebutton_x.png │ │ │ ├── facebutton_y.png │ │ │ ├── left_bumper.png │ │ │ ├── left_trigger.png │ │ │ ├── right_bumper.png │ │ │ ├── right_trigger.png │ │ │ ├── left_thumbstick.png │ │ │ └── right_thumbstick.png │ └── chrome │ │ └── sensitivitypanel_filler.png └── com │ └── joshjcarrier │ ├── minecontrol │ ├── AppInfo.java │ ├── framework │ │ ├── profiles │ │ │ ├── IMouseProfile.java │ │ │ ├── GamePadProfileList.java │ │ │ ├── SecondaryMouseProfile.java │ │ │ ├── PrimaryMouseProfile.java │ │ │ └── GamePadProfile.java │ │ ├── input │ │ │ ├── Buttons.java │ │ │ └── AutomationBinding.java │ │ └── modes │ │ │ └── MinecraftGameMode.java │ ├── ui │ │ ├── models │ │ │ ├── GameTitleWrapper.java │ │ │ ├── MouseProfileWrapper.java │ │ │ ├── AutomationBindingWrapper.java │ │ │ ├── GamePadWrapper.java │ │ │ └── GamePadProfileWrapper.java │ │ ├── controls │ │ │ ├── renderers │ │ │ │ ├── GameTitleWrapperListCellRenderer.java │ │ │ │ ├── GamePadWrapperListCellRenderer.java │ │ │ │ └── BaseWrapperListCellRenderer.java │ │ │ ├── AutomationBindingsControl.java │ │ │ └── ButtonDescriptorPanel.java │ │ ├── actions │ │ │ └── SimpleAction.java │ │ ├── ContentResources.java │ │ ├── views │ │ │ ├── AboutView.java │ │ │ ├── MainView.java │ │ │ └── GamePadProfileView.java │ │ └── controllers │ │ │ ├── MainController.java │ │ │ └── GamePadProfileController.java │ └── App.java │ ├── rxautomation │ ├── methods │ │ ├── IAutomationMethod.java │ │ ├── MouseMoveXAutomationMethod.java │ │ ├── MouseMoveYAutomationMethod.java │ │ ├── NoOpAutomationMethod.java │ │ ├── AutomationMethodFactory.java │ │ ├── SensitivityAppAutomationMethod.java │ │ ├── MouseMoveAutomationRunner.java │ │ ├── MouseWheelAutomationMethod.java │ │ ├── KeyboardAutomationMethod.java │ │ ├── MouseButtonAutomationMethod.java │ │ └── DiscreteDelegateAutomationMethod.java │ ├── persistence │ │ ├── IAutomationReader.java │ │ ├── IAutomationWriter.java │ │ ├── NestedAutomationWriter.java │ │ ├── AutomationWriter.java │ │ ├── AutomationReader.java │ │ └── NestedAutomationReader.java │ └── projection │ │ ├── IRxAutomationProjection.java │ │ ├── PassThruRxAutomationProjection.java │ │ ├── BinaryRxAutomationProjection.java │ │ ├── BufferedSwitchRxAutomationProjection.java │ │ └── ActionPotentialRxAutomationProjection.java │ ├── Pair.java │ ├── rxjinput │ ├── RxControllerList.java │ └── RxController.java │ ├── persistence │ ├── IStorage.java │ ├── IniStorage.java │ └── PropertiesStorage.java │ └── rxgamepad │ ├── RxGamePadList.java │ └── RxGamePad.java ├── .project ├── .settings └── org.eclipse.jdt.core.prefs ├── .classpath ├── minecontrol2.iml ├── .gitignore └── README.md /LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/LICENSE -------------------------------------------------------------------------------- /lib/ini4j.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/ini4j.jar -------------------------------------------------------------------------------- /lib/jinput.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/jinput.jar -------------------------------------------------------------------------------- /lib/jinput-dx8.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/jinput-dx8.dll -------------------------------------------------------------------------------- /lib/jinput-raw.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/jinput-raw.dll -------------------------------------------------------------------------------- /lib/rxjava-core.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/rxjava-core.jar -------------------------------------------------------------------------------- /lib/jinput-dx8_64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/jinput-dx8_64.dll -------------------------------------------------------------------------------- /lib/jinput-raw_64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/jinput-raw_64.dll -------------------------------------------------------------------------------- /lib/jinput-wintab.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/jinput-wintab.dll -------------------------------------------------------------------------------- /lib/libjinput-linux.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/libjinput-linux.so -------------------------------------------------------------------------------- /lib/libjinput-linux64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/libjinput-linux64.so -------------------------------------------------------------------------------- /lib/libjinput-osx.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/lib/libjinput-osx.jnilib -------------------------------------------------------------------------------- /src/content/gametitles/minecraft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/gametitles/minecraft.png -------------------------------------------------------------------------------- /src/content/inputdevices/generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/generic.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360.png -------------------------------------------------------------------------------- /src/content/gametitles/mincecraft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/gametitles/mincecraft.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox_one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox_one.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/back.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/d-pad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/d-pad.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/start.png -------------------------------------------------------------------------------- /src/content/chrome/sensitivitypanel_filler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/chrome/sensitivitypanel_filler.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/facebutton_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/facebutton_a.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/facebutton_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/facebutton_b.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/facebutton_x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/facebutton_x.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/facebutton_y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/facebutton_y.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/left_bumper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/left_bumper.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/left_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/left_trigger.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/right_bumper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/right_bumper.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/right_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/right_trigger.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/left_thumbstick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/left_thumbstick.png -------------------------------------------------------------------------------- /src/content/inputdevices/xbox360/right_thumbstick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshjcarrier/minecontrol/HEAD/src/content/inputdevices/xbox360/right_thumbstick.png -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/AppInfo.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol; 2 | 3 | public class AppInfo 4 | { 5 | public static String ProductName = "Minecontrol"; 6 | public static String BuildVersion = "0.0.0.00000000"; 7 | } 8 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/IAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 4 | 5 | public interface IAutomationMethod { 6 | void automate(Float value); 7 | 8 | String getName(); 9 | 10 | void write(IAutomationWriter automationWriter); 11 | } 12 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/persistence/IAutomationReader.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.persistence; 2 | 3 | public interface IAutomationReader { 4 | String read(String key); 5 | String readMethod(); 6 | String readProjection(); 7 | Boolean readBoolean(String key); 8 | Integer readInt(String key); 9 | Integer readInt(String key, Integer defaultValue); 10 | } 11 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/persistence/IAutomationWriter.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.persistence; 2 | 3 | public interface IAutomationWriter { 4 | public void write(String key, Boolean value); 5 | public void write(String key, Integer value); 6 | public void write(String key, String value); 7 | public void writeMethod(String value); 8 | public void writeProjection(String value); 9 | } 10 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/Pair.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier; 2 | 3 | public class Pair { 4 | private final TKey key; 5 | private final TValue value; 6 | 7 | public Pair(TKey key, TValue value) { 8 | this.key = key; 9 | this.value = value; 10 | } 11 | 12 | public TKey getKey() { 13 | return key; 14 | } 15 | 16 | public TValue getValue() { 17 | return value; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/framework/profiles/IMouseProfile.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.framework.profiles; 2 | 3 | public interface IMouseProfile { 4 | public int getSensitivityX(); 5 | 6 | public int getSensitivityY(); 7 | 8 | public boolean isInvertY(); 9 | 10 | public void setSensitivityX(int value); 11 | 12 | public void setSensitivityY(int value); 13 | 14 | public void setInvertY(boolean value); 15 | } 16 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | minecontrol2 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/framework/input/Buttons.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.framework.input; 2 | 3 | /** 4 | * Digital inputs. 5 | * @author joshjcarrier 6 | * 7 | */ 8 | public enum Buttons 9 | { 10 | A, 11 | B, 12 | BACK, 13 | DPAD_DOWN, 14 | DPAD_LEFT, 15 | DPAD_RIGHT, 16 | DPAD_UP, 17 | LEFT_SHOULDER, 18 | LEFT_STICK, 19 | LEFT_TRIGGER, 20 | RIGHT_SHOULDER, 21 | RIGHT_STICK, 22 | RIGHT_TRIGGER, 23 | START, 24 | X, 25 | Y 26 | } 27 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/projection/IRxAutomationProjection.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.projection; 2 | 3 | import com.joshjcarrier.rxautomation.methods.IAutomationMethod; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 5 | import com.joshjcarrier.Pair; 6 | import rx.Observable; 7 | 8 | public interface IRxAutomationProjection { 9 | Observable> map(IAutomationMethod automationMethod, Observable source); 10 | 11 | void write(IAutomationWriter automationWriter); 12 | } 13 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/framework/input/AutomationBinding.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.framework.input; 2 | 3 | import com.joshjcarrier.rxautomation.methods.IAutomationMethod; 4 | 5 | public class AutomationBinding { 6 | private final IAutomationMethod automationMethod; 7 | 8 | public AutomationBinding(IAutomationMethod automationMethod) { 9 | this.automationMethod = automationMethod; 10 | } 11 | 12 | public IAutomationMethod getAutomationMethod() { 13 | return this.automationMethod; 14 | } 15 | 16 | public String getName() { 17 | return this.automationMethod.getName(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.5 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.5 12 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxjinput/RxControllerList.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxjinput; 2 | 3 | import net.java.games.input.Controller; 4 | import net.java.games.input.ControllerEnvironment; 5 | import rx.Observable; 6 | import rx.util.functions.Func1; 7 | 8 | public class RxControllerList { 9 | 10 | public Observable getAll() { 11 | return Observable.from(ControllerEnvironment.getDefaultEnvironment().getControllers()) 12 | .map(new Func1() { 13 | @Override 14 | public RxController call(Controller controller) { 15 | return new RxController(controller); 16 | } 17 | }); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/framework/profiles/GamePadProfileList.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.framework.profiles; 2 | 3 | import com.joshjcarrier.persistence.IStorage; 4 | import com.joshjcarrier.rxgamepad.RxGamePad; 5 | import rx.Observable; 6 | 7 | import java.util.Arrays; 8 | 9 | public class GamePadProfileList { 10 | private final IStorage storage; 11 | 12 | public GamePadProfileList(IStorage storage) { 13 | this.storage = storage; 14 | } 15 | 16 | public Observable getAll(RxGamePad rxGamePad) { 17 | GamePadProfile profile = new GamePadProfile("default", rxGamePad, this.storage); 18 | profile.restore(); 19 | return Observable.from(Arrays.asList(profile)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/persistence/IStorage.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.persistence; 2 | 3 | public interface IStorage 4 | { 5 | public abstract void commit(); 6 | 7 | public abstract void load(); 8 | 9 | public abstract String read(String section, String name); 10 | 11 | public abstract boolean readBoolean(String section, String name); 12 | 13 | public abstract float read(String section, String name, float defaultValue); 14 | 15 | public abstract int read(String section, String name, int defaultValue); 16 | 17 | public abstract void write(String section, String name, String value); 18 | 19 | public abstract void write(String section, String name, boolean value); 20 | 21 | public abstract void write(String section, String name, float value); 22 | 23 | public abstract void write(String section, String name, int value); 24 | } -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/models/GameTitleWrapper.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.models; 2 | 3 | import java.net.URL; 4 | 5 | public class GameTitleWrapper 6 | { 7 | private final String title; 8 | private final String publisher; 9 | private final String tileResourceUri; 10 | 11 | public GameTitleWrapper(String title, String publisher, String tileResourceUri) 12 | { 13 | this.title = title; 14 | this.publisher = publisher; 15 | this.tileResourceUri = tileResourceUri; 16 | } 17 | 18 | public String getTitle() 19 | { 20 | return title; 21 | } 22 | 23 | public String getPublisher() 24 | { 25 | return publisher; 26 | } 27 | 28 | public URL getTileResource() 29 | { 30 | return this.getClass().getClassLoader().getResource("content/gametitles/" + this.tileResourceUri + ".png"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/MouseMoveXAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 4 | 5 | public class MouseMoveXAutomationMethod implements IAutomationMethod { 6 | private final MouseMoveAutomationRunner mouseMoveAutomationRunner; 7 | 8 | public MouseMoveXAutomationMethod(MouseMoveAutomationRunner mouseMoveAutomationRunner) { 9 | this.mouseMoveAutomationRunner = mouseMoveAutomationRunner; 10 | } 11 | 12 | public void automate(Float value) { 13 | this.mouseMoveAutomationRunner.xValue = value; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Mouse move X axis"; 19 | } 20 | 21 | @Override 22 | public void write(IAutomationWriter automationWriter) { 23 | automationWriter.write("method", "mouse-mv-x"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/MouseMoveYAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 4 | 5 | public class MouseMoveYAutomationMethod implements IAutomationMethod { 6 | private final MouseMoveAutomationRunner mouseMoveAutomationRunner; 7 | 8 | public MouseMoveYAutomationMethod(MouseMoveAutomationRunner mouseMoveAutomationRunner) { 9 | this.mouseMoveAutomationRunner = mouseMoveAutomationRunner; 10 | } 11 | 12 | public void automate(Float value) { 13 | this.mouseMoveAutomationRunner.yValue = value; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Mouse move Y axis"; 19 | } 20 | 21 | @Override 22 | public void write(IAutomationWriter automationWriter) { 23 | automationWriter.write("method", "mouse-mv-y"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/controls/renderers/GameTitleWrapperListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.controls.renderers; 2 | 3 | import java.awt.Image; 4 | 5 | import javax.swing.ImageIcon; 6 | 7 | import com.joshjcarrier.minecontrol.ui.models.GameTitleWrapper; 8 | 9 | /** 10 | * List cell renderer for the {@link GameTitleWrapper} class. 11 | * @author joshjcarrier 12 | * 13 | */ 14 | public class GameTitleWrapperListCellRenderer extends BaseWrapperListCellRenderer 15 | { 16 | private static final long serialVersionUID = -7527303933458736931L; 17 | 18 | @Override 19 | protected void updateListCell(GameTitleWrapper value) 20 | { 21 | ImageIcon icon = new ImageIcon(value.getTileResource()); 22 | Image newimg = icon.getImage().getScaledInstance(30, 30, Image.SCALE_SMOOTH); 23 | this.iconLabel.setIcon(new ImageIcon(newimg)); 24 | 25 | this.titleLabel.setText(value.getTitle()); 26 | this.publisherLabel.setText(value.getPublisher()); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/models/MouseProfileWrapper.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.models; 2 | 3 | import com.joshjcarrier.minecontrol.framework.profiles.IMouseProfile; 4 | 5 | public class MouseProfileWrapper { 6 | private final IMouseProfile mouseProfile; 7 | 8 | public MouseProfileWrapper(IMouseProfile mouseProfile) { 9 | this.mouseProfile = mouseProfile; 10 | } 11 | 12 | public int getSensitivityX() { 13 | return this.mouseProfile.getSensitivityX(); 14 | } 15 | 16 | public int getSensitivityY() { 17 | return this.mouseProfile.getSensitivityY(); 18 | } 19 | 20 | public boolean isInvertY() { 21 | return this.mouseProfile.isInvertY(); 22 | } 23 | 24 | public void setSensitivityX(int value) { 25 | this.mouseProfile.setSensitivityX(value); 26 | } 27 | 28 | public void setSensitivityY(int value) { 29 | this.mouseProfile.setSensitivityY(value); 30 | } 31 | 32 | public void setInvertY(boolean value) { 33 | this.mouseProfile.setInvertY(value); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/NoOpAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 5 | 6 | public class NoOpAutomationMethod implements IAutomationMethod { 7 | private static final String METHOD_ID = "noop"; 8 | 9 | public static IAutomationMethod load(IAutomationReader automationReader) { 10 | try { 11 | String methodId = automationReader.readMethod(); 12 | if(!methodId.equalsIgnoreCase(METHOD_ID)) { 13 | return null; 14 | } 15 | 16 | return new NoOpAutomationMethod(); 17 | } catch (Exception e) { 18 | return null; 19 | } 20 | } 21 | 22 | @Override 23 | public void automate(Float value) { 24 | // No op by default 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return ""; 30 | } 31 | 32 | @Override 33 | public void write(IAutomationWriter configurationSettings) { 34 | configurationSettings.writeMethod(METHOD_ID); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/AutomationMethodFactory.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 4 | 5 | public class AutomationMethodFactory { 6 | public static IAutomationMethod load(IAutomationReader automationReader) { 7 | // chain of command 8 | IAutomationMethod automationMethod = KeyboardAutomationMethod.load(automationReader); 9 | if(automationMethod == null) { 10 | automationMethod = DiscreteDelegateAutomationMethod.load(automationReader); 11 | } 12 | 13 | if(automationMethod == null) { 14 | automationMethod = MouseButtonAutomationMethod.load(automationReader); 15 | } 16 | 17 | if(automationMethod == null) { 18 | automationMethod = MouseWheelAutomationMethod.load(automationReader); 19 | } 20 | 21 | if(automationMethod == null) { 22 | automationMethod = SensitivityAppAutomationMethod.load(automationReader); 23 | } 24 | 25 | if(automationMethod == null) { 26 | automationMethod = NoOpAutomationMethod.load(automationReader); 27 | } 28 | 29 | return automationMethod; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxgamepad/RxGamePadList.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxgamepad; 2 | 3 | import com.joshjcarrier.rxjinput.RxController; 4 | import com.joshjcarrier.rxjinput.RxControllerList; 5 | import rx.Observable; 6 | import rx.util.functions.Func1; 7 | 8 | public class RxGamePadList { 9 | private final RxControllerList rxControllerList; 10 | 11 | public RxGamePadList() { 12 | this.rxControllerList = new RxControllerList(); 13 | } 14 | 15 | public Observable getAll() { 16 | return this.rxControllerList.getAll() 17 | .filter(new Func1() { 18 | @Override 19 | public Boolean call(RxController rxController) { 20 | return !rxController.getName().toLowerCase().contains("mouse") 21 | && !rxController.getName().toLowerCase().contains("keyboard"); 22 | } 23 | }) 24 | .map(new Func1() { 25 | @Override 26 | public RxGamePad call(RxController rxController) { 27 | return new RxGamePad(rxController); 28 | } 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/persistence/NestedAutomationWriter.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.persistence; 2 | 3 | public class NestedAutomationWriter implements IAutomationWriter { 4 | private final String sectionName; 5 | private final IAutomationWriter automationWriter; 6 | 7 | public NestedAutomationWriter(String sectionName, IAutomationWriter automationWriter) { 8 | this.sectionName = sectionName; 9 | this.automationWriter = automationWriter; 10 | } 11 | 12 | @Override 13 | public void write(String key, Boolean value) { 14 | this.automationWriter.write(this.sectionName + "." + key, value); 15 | } 16 | 17 | @Override 18 | public void write(String key, Integer value) { 19 | this.automationWriter.write(this.sectionName + "." + key, value); 20 | } 21 | 22 | @Override 23 | public void write(String key, String value) { 24 | this.automationWriter.write(this.sectionName + "." + key, value); 25 | } 26 | 27 | @Override 28 | public void writeMethod(String value) { 29 | this.automationWriter.write(this.sectionName + ".method", value); 30 | } 31 | 32 | @Override 33 | public void writeProjection(String value) { 34 | this.automationWriter.write(this.sectionName + ".projection", value); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/actions/SimpleAction.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.actions; 2 | 3 | import java.awt.event.ActionEvent; 4 | import java.beans.PropertyChangeListener; 5 | import java.util.HashMap; 6 | import java.util.HashSet; 7 | 8 | import javax.swing.Action; 9 | 10 | public abstract class SimpleAction implements Action { 11 | 12 | public abstract void actionPerformed(ActionEvent e); 13 | 14 | private boolean isEnabled = true; 15 | private HashMap properties = new HashMap(); 16 | private HashSet propertyChangeListeners = new HashSet(); 17 | 18 | public void setEnabled(boolean b) { 19 | this.isEnabled = b; 20 | } 21 | 22 | public void removePropertyChangeListener(PropertyChangeListener listener) { 23 | this.propertyChangeListeners.add(listener); 24 | } 25 | 26 | public void putValue(String key, Object value) { 27 | this.properties.put(key, value); 28 | } 29 | 30 | public boolean isEnabled() { 31 | return this.isEnabled; 32 | } 33 | 34 | public Object getValue(String key) { 35 | return this.properties.get(key); 36 | } 37 | 38 | public void addPropertyChangeListener(PropertyChangeListener listener) { 39 | this.propertyChangeListeners.add(listener); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/persistence/AutomationWriter.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.persistence; 2 | 3 | import com.joshjcarrier.persistence.IStorage; 4 | 5 | public class AutomationWriter implements IAutomationWriter { 6 | private final String rootName; 7 | private final String sectionName; 8 | private final IStorage storage; 9 | 10 | public AutomationWriter(String rootName, String sectionName, IStorage storage) { 11 | this.rootName = rootName; 12 | this.sectionName = sectionName; 13 | this.storage = storage; 14 | } 15 | 16 | @Override 17 | public void write(String key, Boolean value) { 18 | this.storage.write(this.rootName, this.sectionName + "." + key, value); 19 | } 20 | 21 | @Override 22 | public void write(String key, Integer value) { 23 | this.storage.write(this.rootName, this.sectionName + "." + key, value); 24 | } 25 | 26 | @Override 27 | public void write(String key, String value) { 28 | this.storage.write(this.rootName, this.sectionName + "." + key, value); 29 | } 30 | 31 | @Override 32 | public void writeMethod(String value) { 33 | this.write("method", value); 34 | } 35 | 36 | @Override 37 | public void writeProjection(String value) { 38 | this.write("projection", value); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/SensitivityAppAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 5 | 6 | public class SensitivityAppAutomationMethod implements IAutomationMethod { 7 | private final static String METHOD_ID = "app-sensitivity"; 8 | 9 | public static IAutomationMethod load(IAutomationReader automationReader) { 10 | try { 11 | String methodId = automationReader.readMethod(); 12 | if(!methodId.equalsIgnoreCase(METHOD_ID)) { 13 | return null; 14 | } 15 | 16 | return new SensitivityAppAutomationMethod(); 17 | } catch (Exception e) { 18 | return null; 19 | } 20 | } 21 | 22 | @Override 23 | public void automate(Float value) { 24 | if (value == 1f) { 25 | MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_MODE = !MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_MODE; 26 | } 27 | } 28 | 29 | @Override 30 | public String getName() { 31 | return "Minecontrol toggle mouse profile"; 32 | } 33 | 34 | @Override 35 | public void write(IAutomationWriter automationWriter) { 36 | automationWriter.writeMethod(METHOD_ID); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/models/AutomationBindingWrapper.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.models; 2 | 3 | import com.joshjcarrier.minecontrol.framework.input.AutomationBinding; 4 | 5 | public class AutomationBindingWrapper { 6 | private final AutomationBinding automationBinding; 7 | private String name; // caches because the equals check is real slow 8 | 9 | public AutomationBindingWrapper(AutomationBinding automationBinding) { 10 | this.automationBinding = automationBinding; 11 | } 12 | 13 | public AutomationBinding getAutomationBinding() { 14 | return this.automationBinding; 15 | } 16 | 17 | public String getName() { 18 | if(this.name == null) { 19 | this.name = this.automationBinding.getName(); 20 | } 21 | return this.name; 22 | } 23 | 24 | @Override 25 | public boolean equals(Object o) { 26 | if (!(o instanceof AutomationBindingWrapper)) { 27 | return false; 28 | } 29 | 30 | AutomationBindingWrapper otherAutomationBinding = (AutomationBindingWrapper)o; 31 | return getName().equals(otherAutomationBinding.getName()); 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | return getName().hashCode(); 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return " " + this.getName(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/persistence/AutomationReader.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.persistence; 2 | 3 | import com.joshjcarrier.persistence.IStorage; 4 | 5 | public class AutomationReader implements IAutomationReader { 6 | private final String rootName; 7 | private final String sectionName; 8 | private final IStorage storage; 9 | 10 | public AutomationReader(String rootName, String sectionName, IStorage storage) { 11 | this.rootName = rootName; 12 | this.sectionName = sectionName; 13 | this.storage = storage; 14 | } 15 | 16 | public String read(String key) { 17 | return this.storage.read(this.rootName, this.sectionName + "." + key); 18 | } 19 | 20 | @Override 21 | public String readMethod() { 22 | return this.read("method"); 23 | } 24 | 25 | @Override 26 | public String readProjection() { 27 | return this.read("projection"); 28 | } 29 | 30 | @Override 31 | public Boolean readBoolean(String key) { 32 | return Boolean.parseBoolean(read(key)); 33 | } 34 | 35 | @Override 36 | public Integer readInt(String key) { 37 | return Integer.parseInt(read(key)); 38 | } 39 | 40 | @Override 41 | public Integer readInt(String key, Integer defaultValue) { 42 | return this.storage.read(this.rootName, this.sectionName + "." + key, defaultValue); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/persistence/NestedAutomationReader.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.persistence; 2 | 3 | public class NestedAutomationReader implements IAutomationReader { 4 | private final String sectionName; 5 | private final IAutomationReader automationReader; 6 | 7 | public NestedAutomationReader(String sectionName, IAutomationReader automationReader) { 8 | this.sectionName = sectionName; 9 | this.automationReader = automationReader; 10 | } 11 | 12 | @Override 13 | public String read(String key) { 14 | return this.automationReader.read(this.sectionName + "." + key); 15 | } 16 | 17 | @Override 18 | public String readMethod() { 19 | return this.automationReader.read(this.sectionName + ".method"); 20 | } 21 | 22 | @Override 23 | public String readProjection() { 24 | return this.automationReader.read(this.sectionName + ".projection"); 25 | } 26 | 27 | @Override 28 | public Boolean readBoolean(String key) { 29 | return this.automationReader.readBoolean(this.sectionName + "." + key); 30 | } 31 | 32 | @Override 33 | public Integer readInt(String key) { 34 | return this.automationReader.readInt(this.sectionName + "." + key); 35 | } 36 | 37 | @Override 38 | public Integer readInt(String key, Integer defaultValue) { 39 | return this.automationReader.readInt(this.sectionName + "." + key, defaultValue); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/models/GamePadWrapper.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.models; 2 | 3 | import com.joshjcarrier.minecontrol.ui.ContentResources; 4 | import com.joshjcarrier.rxgamepad.RxGamePad; 5 | 6 | import java.net.URL; 7 | import java.util.List; 8 | 9 | /** 10 | * User experience wrapper for the {@link RxGamePad} class. 11 | * @author joshjcarrier 12 | * 13 | */ 14 | public class GamePadWrapper 15 | { 16 | private final RxGamePad rxGamePad; 17 | private final List profiles; 18 | 19 | public GamePadWrapper(RxGamePad rxGamePad, List profiles) { 20 | this.rxGamePad = rxGamePad; 21 | this.profiles = profiles; 22 | } 23 | 24 | public List getProfiles() 25 | { 26 | return this.profiles; 27 | } 28 | 29 | public String getName() 30 | { 31 | return this.rxGamePad.getName(); 32 | } 33 | 34 | public URL getTileResource() 35 | { 36 | if (this.getName().toLowerCase().contains("xbox")) 37 | { 38 | if (this.getName().toLowerCase().contains("one")) { 39 | return this.getClass().getClassLoader().getResource(ContentResources.INPUTDEVICE_XBOX_ONE); 40 | } 41 | 42 | return this.getClass().getClassLoader().getResource(ContentResources.INPUTDEVICE_XBOX360); 43 | } 44 | 45 | return this.getClass().getClassLoader().getResource(ContentResources.INPUTDEVICE_GENERIC); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/projection/PassThruRxAutomationProjection.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.projection; 2 | 3 | import com.joshjcarrier.rxautomation.methods.IAutomationMethod; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 5 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 6 | import com.joshjcarrier.Pair; 7 | import rx.Observable; 8 | import rx.util.functions.Func1; 9 | 10 | public class PassThruRxAutomationProjection implements IRxAutomationProjection { 11 | private static final String PROJECTION_ID = "pass-thru"; 12 | 13 | public static IRxAutomationProjection load(IAutomationReader automationReader) { 14 | try { 15 | String projectionId = automationReader.readProjection(); 16 | if(projectionId.equalsIgnoreCase(PROJECTION_ID)) { 17 | return new PassThruRxAutomationProjection(); 18 | } 19 | } catch (Exception e) { 20 | // do nothing 21 | } 22 | 23 | return null; 24 | } 25 | 26 | @Override 27 | public Observable> map(final IAutomationMethod automationMethod, Observable source) { 28 | return source.map(new Func1>() { 29 | @Override 30 | public Pair call(Float aFloat) { 31 | return new Pair(automationMethod, aFloat); 32 | } 33 | }); 34 | } 35 | 36 | @Override 37 | public void write(IAutomationWriter automationWriter) { 38 | automationWriter.writeProjection(PROJECTION_ID); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxgamepad/RxGamePad.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxgamepad; 2 | 3 | import com.joshjcarrier.rxjinput.RxController; 4 | import net.java.games.input.Component; 5 | import rx.Observable; 6 | 7 | import java.util.HashMap; 8 | 9 | public class RxGamePad { 10 | 11 | private final RxController rxController; 12 | 13 | public RxGamePad(RxController rxController) { 14 | this.rxController = rxController; 15 | } 16 | 17 | public Observable getComponentById(Component.Identifier componentId) { 18 | return this.rxController.getComponent(componentId); 19 | } 20 | 21 | public HashMap getButtonLabels() { 22 | return new HashMap() { 23 | private static final long serialVersionUID = 3658388604108766926L; 24 | 25 | { 26 | put(Component.Identifier.Button._0, "A"); 27 | put(Component.Identifier.Button._1, "B"); 28 | put(Component.Identifier.Button._2, "X"); 29 | put(Component.Identifier.Button._3, "Y"); 30 | put(Component.Identifier.Button._4, "Left shoulder"); 31 | put(Component.Identifier.Button._5, "Right shoulder"); 32 | put(Component.Identifier.Button._6, "Back"); 33 | put(Component.Identifier.Button._7, "Start"); 34 | put(Component.Identifier.Button._8, "Left joystick press"); 35 | put(Component.Identifier.Button._9, "Right joystick press"); 36 | 37 | put(Component.Identifier.Axis.POV, "D-Pad"); 38 | } 39 | }; 40 | } 41 | 42 | public String getName() { 43 | return this.rxController.getName(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /minecontrol2.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/projection/BinaryRxAutomationProjection.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.projection; 2 | 3 | import com.joshjcarrier.rxautomation.methods.IAutomationMethod; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 5 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 6 | import com.joshjcarrier.Pair; 7 | import rx.Observable; 8 | import rx.util.functions.Func1; 9 | 10 | public class BinaryRxAutomationProjection implements IRxAutomationProjection { 11 | private static final String PROJECTION_ID = "binary"; 12 | 13 | public static IRxAutomationProjection load(IAutomationReader automationReader) { 14 | try { 15 | String projectionId = automationReader.readProjection(); 16 | if(projectionId.equalsIgnoreCase(PROJECTION_ID)) { 17 | return new BinaryRxAutomationProjection(); 18 | } 19 | } catch (Exception e) { 20 | // do nothing 21 | } 22 | 23 | return null; 24 | } 25 | 26 | public Observable> map(final IAutomationMethod automationMethod, Observable source) { 27 | return source.map(new Func1>() { 28 | @Override 29 | public Pair call(Float aFloat) { 30 | if(aFloat >= 0) { 31 | return new Pair(automationMethod, aFloat > 0 ? 1f : 0f); 32 | } 33 | 34 | return new Pair(automationMethod, -aFloat > 0 ? -1f : 0f); 35 | } 36 | }).distinctUntilChanged(); 37 | } 38 | 39 | @Override 40 | public void write(IAutomationWriter automationWriter) { 41 | automationWriter.writeProjection(PROJECTION_ID); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/ContentResources.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui; 2 | 3 | public final class ContentResources 4 | { 5 | public static String GAMETITLE_MINECRAFT = "content/gametitles/minecraft.png"; 6 | 7 | public static String INPUTDEVICE_GENERIC = "content/inputdevices/generic.png"; 8 | public static String INPUTDEVICE_XBOX_ONE = "content/inputdevices/xbox_one.png"; 9 | public static String INPUTDEVICE_XBOX360 = "content/inputdevices/xbox360.png"; 10 | 11 | public static String CHROME_SENSITIVITYPANEL_FILLER = "content/chrome/sensitivitypanel_filler.png"; 12 | 13 | public static String BUTTON_XBOX360_BACK = "content/inputdevices/xbox360/back.png"; 14 | public static String BUTTON_XBOX360_DPAD = "content/inputdevices/xbox360/d-pad.png"; 15 | public static String BUTTON_XBOX360_A = "content/inputdevices/xbox360/facebutton_a.png"; 16 | public static String BUTTON_XBOX360_B = "content/inputdevices/xbox360/facebutton_b.png"; 17 | public static String BUTTON_XBOX360_X = "content/inputdevices/xbox360/facebutton_x.png"; 18 | public static String BUTTON_XBOX360_Y = "content/inputdevices/xbox360/facebutton_y.png"; 19 | public static String BUTTON_XBOX360_LEFTSHOULDER = "content/inputdevices/xbox360/left_bumper.png"; 20 | public static String BUTTON_XBOX360_LEFTSTICK = "content/inputdevices/xbox360/left_thumbstick.png"; 21 | public static String BUTTON_XBOX360_LEFTTRIGGER = "content/inputdevices/xbox360/left_trigger.png"; 22 | public static String BUTTON_XBOX360_RIGHTSHOULDER = "content/inputdevices/xbox360/right_bumper.png"; 23 | public static String BUTTON_XBOX360_RIGHTSTICK = "content/inputdevices/xbox360/right_thumbstick.png"; 24 | public static String BUTTON_XBOX360_RIGHTTRIGGER = "content/inputdevices/xbox360/right_trigger.png"; 25 | public static String BUTTON_XBOX360_START = "content/inputdevices/xbox360/start.png"; 26 | } 27 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/App.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol; 2 | 3 | import com.joshjcarrier.minecontrol.framework.profiles.GamePadProfileList; 4 | import com.joshjcarrier.minecontrol.ui.controllers.MainController; 5 | import com.joshjcarrier.minecontrol.ui.views.MainView; 6 | import com.joshjcarrier.persistence.IStorage; 7 | import com.joshjcarrier.persistence.IniStorage; 8 | import com.joshjcarrier.rxgamepad.RxGamePadList; 9 | 10 | import javax.swing.*; 11 | 12 | /** 13 | * Application entry point. 14 | * @author joshjcarrier 15 | * 16 | */ 17 | public class App 18 | { 19 | public App() 20 | { 21 | // TODO sync with minecontrol runtime 22 | // controller reader service async 23 | IStorage storage = new IniStorage(); 24 | storage.load(); 25 | RxGamePadList rxGamePadList = new RxGamePadList(); 26 | GamePadProfileList gamePadProfileList = new GamePadProfileList(storage); 27 | MainController mainController = new MainController(rxGamePadList, gamePadProfileList); 28 | 29 | MainView view = mainController.index(); 30 | view.setVisible(true); 31 | } 32 | 33 | /** 34 | * @param args 35 | */ 36 | public static void main(String[] args) 37 | { 38 | try 39 | { 40 | // Get the native look and feel class name 41 | String nativeLF = UIManager.getSystemLookAndFeelClassName(); 42 | 43 | // Install the native look and feel, allowing startup to proceed with default look and feel if native not possible 44 | try { 45 | UIManager.setLookAndFeel(nativeLF); 46 | } catch (InstantiationException e) { 47 | } catch (ClassNotFoundException e) { 48 | } catch (UnsupportedLookAndFeelException e) { 49 | } catch (IllegalAccessException e) { 50 | } 51 | 52 | new App(); 53 | } 54 | catch(Exception ex) 55 | { 56 | JOptionPane.showMessageDialog(null, ex + "\r\n" + ex.getStackTrace()[0] + "\r\nContact josh@joshjcarrier.com .", AppInfo.ProductName + " failure", JOptionPane.ERROR_MESSAGE); 57 | ex.printStackTrace(); 58 | System.exit(1); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/framework/profiles/SecondaryMouseProfile.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.framework.profiles; 2 | 3 | import com.joshjcarrier.persistence.IStorage; 4 | import com.joshjcarrier.rxautomation.methods.MouseMoveAutomationRunner; 5 | 6 | public class SecondaryMouseProfile implements IMouseProfile { 7 | private final String SENSITIVITY_X_KEY = "mouse.secondary.x.sensitivity"; 8 | private final String SENSITIVITY_Y_KEY = "mouse.secondary.y.sensitivity"; 9 | private final String profileName; 10 | private final IStorage storage; 11 | 12 | public SecondaryMouseProfile(String profileName, IStorage storage) { 13 | this.profileName = profileName; 14 | this.storage = storage; 15 | 16 | restore(); 17 | } 18 | 19 | public int getSensitivityX() { 20 | return MouseMoveAutomationRunner.SECONDARY_SENSITIVITY_X; 21 | } 22 | 23 | public int getSensitivityY() { 24 | return MouseMoveAutomationRunner.SECONDARY_SENSITIVITY_Y; 25 | } 26 | 27 | public boolean isInvertY() { 28 | return false; 29 | } 30 | 31 | public void setSensitivityX(int value) { 32 | MouseMoveAutomationRunner.SECONDARY_SENSITIVITY_X = value; 33 | write(); 34 | } 35 | 36 | public void setSensitivityY(int value) { 37 | MouseMoveAutomationRunner.SECONDARY_SENSITIVITY_Y = value; 38 | write(); 39 | } 40 | 41 | public void setInvertY(boolean value) { 42 | } 43 | 44 | private void restore() { 45 | MouseMoveAutomationRunner.SECONDARY_SENSITIVITY_X = this.storage.read(this.profileName, SENSITIVITY_X_KEY, MouseMoveAutomationRunner.SECONDARY_SENSITIVITY_X); 46 | MouseMoveAutomationRunner.SECONDARY_SENSITIVITY_Y = this.storage.read(this.profileName, SENSITIVITY_Y_KEY, MouseMoveAutomationRunner.SECONDARY_SENSITIVITY_Y); 47 | } 48 | 49 | private void write() { 50 | this.storage.write(this.profileName, SENSITIVITY_X_KEY, getSensitivityX()); 51 | this.storage.write(this.profileName, SENSITIVITY_Y_KEY, getSensitivityY()); 52 | this.storage.commit(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/MouseMoveAutomationRunner.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import java.awt.*; 4 | 5 | public class MouseMoveAutomationRunner implements Runnable { 6 | private static Robot humanInterfaceDeviceService; 7 | 8 | static { 9 | 10 | try 11 | { 12 | humanInterfaceDeviceService = new Robot(); 13 | 14 | // this prevents the OS from ignoring events generated too quickly in succession 15 | humanInterfaceDeviceService.setAutoDelay(5); 16 | } 17 | catch (AWTException e) 18 | { 19 | // TODO 2.0+ throw exception 20 | e.printStackTrace(); 21 | } 22 | } 23 | 24 | public static boolean PRIMARY_SENSITIVITY_MODE = true; 25 | public static boolean INVERT_Y = false; 26 | public static int PRIMARY_SENSITIVITY_X = 45; 27 | public static int PRIMARY_SENSITIVITY_Y = 25; 28 | public static int SECONDARY_SENSITIVITY_X = 25; 29 | public static int SECONDARY_SENSITIVITY_Y = 25; 30 | public float xValue, yValue; 31 | 32 | public MouseMoveXAutomationMethod getXAutomationMethod() { 33 | return new MouseMoveXAutomationMethod(this); 34 | } 35 | 36 | public MouseMoveYAutomationMethod getYAutomationMethod() { 37 | return new MouseMoveYAutomationMethod(this); 38 | } 39 | 40 | @Override 41 | public void run() { 42 | while(true) { 43 | try { 44 | if (xValue != 0 || yValue != 0) 45 | { 46 | PointerInfo info = MouseInfo.getPointerInfo(); 47 | 48 | // TODO 2.1+ smoothen mouse 49 | humanInterfaceDeviceService.mouseMove( 50 | (int) (info.getLocation().x + (0.2 * xValue * (PRIMARY_SENSITIVITY_MODE ? PRIMARY_SENSITIVITY_X : SECONDARY_SENSITIVITY_X))), 51 | (int) (info.getLocation().y + (0.2 * yValue * (PRIMARY_SENSITIVITY_MODE ? PRIMARY_SENSITIVITY_Y : SECONDARY_SENSITIVITY_Y) * (INVERT_Y ? -1 : 1)))); 52 | } 53 | 54 | Thread.sleep(5); 55 | } catch (InterruptedException e) { 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/controls/renderers/GamePadWrapperListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.controls.renderers; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Image; 6 | import java.net.URL; 7 | 8 | import javax.swing.ImageIcon; 9 | 10 | import com.joshjcarrier.minecontrol.ui.models.GamePadWrapper; 11 | 12 | /** 13 | * List cell renderer for the {@link GamePadWrapper} class. 14 | * @author joshjcarrier 15 | * 16 | */ 17 | public class GamePadWrapperListCellRenderer extends BaseWrapperListCellRenderer 18 | { 19 | private static final long serialVersionUID = -5353456488841978539L; 20 | 21 | public GamePadWrapperListCellRenderer() 22 | { 23 | titleLabel.setFont(new Font("Verdana", Font.BOLD, 12)); 24 | publisherLabel.setFont(new Font("Verdana", Font.ITALIC, 10)); 25 | } 26 | 27 | @Override 28 | protected void updateListCell(GamePadWrapper value) 29 | { 30 | URL iconUrl = value.getTileResource(); 31 | 32 | ImageIcon icon = new ImageIcon(iconUrl); 33 | Image newimg = icon.getImage().getScaledInstance(30, 30, java.awt.Image.SCALE_SMOOTH); 34 | this.iconLabel.setIcon(new ImageIcon(newimg)); 35 | 36 | String normalizedControllerName = value.getName().toLowerCase(); 37 | if (normalizedControllerName.contains("xbox")) 38 | { 39 | this.titleLabel.setText("Microsoft Xbox Controller"); 40 | this.titleLabel.setForeground(Color.BLACK); 41 | this.publisherLabel.setText(value.getName()); 42 | } 43 | else if (normalizedControllerName.contains("keyboard")) 44 | { 45 | this.titleLabel.setText("Keyboard"); 46 | this.titleLabel.setForeground(Color.GRAY); 47 | this.publisherLabel.setText(value.getName()); 48 | } 49 | else if (normalizedControllerName.contains("mouse")) 50 | { 51 | this.titleLabel.setText("Mouse"); 52 | this.titleLabel.setForeground(Color.GRAY); 53 | this.publisherLabel.setText(value.getName()); 54 | } 55 | else 56 | { 57 | this.titleLabel.setText(value.getName()); 58 | this.titleLabel.setForeground(Color.BLACK); 59 | this.publisherLabel.setText(""); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/projection/BufferedSwitchRxAutomationProjection.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.projection; 2 | 3 | import com.joshjcarrier.rxautomation.methods.IAutomationMethod; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 5 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 6 | import com.joshjcarrier.Pair; 7 | import rx.Observable; 8 | import rx.util.functions.Func1; 9 | import rx.util.functions.Func2; 10 | 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class BufferedSwitchRxAutomationProjection implements IRxAutomationProjection { 15 | private static final String PROJECTION_ID = "buffered-switch"; 16 | 17 | public static IRxAutomationProjection load(IAutomationReader automationReader) { 18 | try { 19 | String projectionId = automationReader.readProjection(); 20 | if(projectionId.equalsIgnoreCase(PROJECTION_ID)) { 21 | return new BufferedSwitchRxAutomationProjection(); 22 | } 23 | } catch (Exception e) { 24 | // do nothing 25 | } 26 | 27 | return null; 28 | } 29 | 30 | @Override 31 | public Observable> map(final IAutomationMethod automationMethod, Observable source) { 32 | return source.buffer(2) 33 | .scan(0f, new Func2, Float>() { 34 | @Override 35 | public Float call(Float aFloat, List floats) { 36 | if(aFloat >= 0) { 37 | return aFloat == 0 ? Collections.max(floats) : 0; 38 | } 39 | 40 | return aFloat == 0 ? Collections.min(floats) : 0; 41 | } 42 | }).map(new Func1>() { 43 | @Override 44 | public Pair call(Float aFloat) { 45 | return new Pair(automationMethod, aFloat); 46 | } 47 | }); 48 | } 49 | 50 | @Override 51 | public void write(IAutomationWriter automationWriter) { 52 | automationWriter.writeProjection(PROJECTION_ID); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | .idea/ 19 | 20 | # External tool builders 21 | .externalToolBuilders/ 22 | 23 | # Locally stored "Eclipse launch configurations" 24 | *.launch 25 | 26 | # CDT-specific 27 | .cproject 28 | 29 | # PDT-specific 30 | .buildpath 31 | 32 | 33 | ################# 34 | ## Visual Studio 35 | ################# 36 | 37 | ## Ignore Visual Studio temporary files, build results, and 38 | ## files generated by popular Visual Studio add-ons. 39 | 40 | # User-specific files 41 | *.suo 42 | *.user 43 | *.sln.docstates 44 | 45 | # Build results 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | *_i.c 49 | *_p.c 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.vspscc 64 | .builds 65 | *.dotCover 66 | 67 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 68 | #packages/ 69 | 70 | # Visual C++ cache files 71 | ipch/ 72 | *.aps 73 | *.ncb 74 | *.opensdf 75 | *.sdf 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | 81 | # ReSharper is a .NET coding add-in 82 | _ReSharper* 83 | 84 | # Installshield output folder 85 | [Ee]xpress 86 | 87 | # DocProject is a documentation generator add-in 88 | DocProject/buildhelp/ 89 | DocProject/Help/*.HxT 90 | DocProject/Help/*.HxC 91 | DocProject/Help/*.hhc 92 | DocProject/Help/*.hhk 93 | DocProject/Help/*.hhp 94 | DocProject/Help/Html2 95 | DocProject/Help/html 96 | 97 | # Click-Once directory 98 | publish 99 | 100 | # Others 101 | [Bb]in 102 | [Oo]bj 103 | sql 104 | TestResults 105 | *.Cache 106 | ClientBin 107 | stylecop.* 108 | ~$* 109 | *.dbmdl 110 | Generated_Code #added for RIA/Silverlight projects 111 | 112 | # Backup & report files from converting an old project file to a newer 113 | # Visual Studio version. Backup files are not needed, because we have git ;-) 114 | _UpgradeReport_Files/ 115 | Backup*/ 116 | UpgradeLog*.XML 117 | 118 | 119 | 120 | ############ 121 | ## Windows 122 | ############ 123 | 124 | # Windows image file caches 125 | Thumbs.db 126 | 127 | # Folder config file 128 | Desktop.ini 129 | 130 | 131 | 132 | drop/ 133 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/framework/profiles/PrimaryMouseProfile.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.framework.profiles; 2 | 3 | import com.joshjcarrier.persistence.IStorage; 4 | import com.joshjcarrier.rxautomation.methods.MouseMoveAutomationRunner; 5 | 6 | public class PrimaryMouseProfile implements IMouseProfile { 7 | private final String SENSITIVITY_X_KEY = "mouse.primary.x.sensitivity"; 8 | private final String SENSITIVITY_Y_KEY = "mouse.primary.y.sensitivity"; 9 | private final String INVERT_Y_KEY = "mouse.primary.y.invert"; 10 | private final String profileName; 11 | private final IStorage storage; 12 | 13 | public PrimaryMouseProfile(String profileName, IStorage storage) { 14 | this.profileName = profileName; 15 | this.storage = storage; 16 | restore(); 17 | } 18 | 19 | public int getSensitivityX() { 20 | return MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_X; 21 | } 22 | 23 | public int getSensitivityY() { 24 | return MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_Y; 25 | } 26 | 27 | public boolean isInvertY() { 28 | return MouseMoveAutomationRunner.INVERT_Y; 29 | } 30 | 31 | public void setSensitivityX(int value) { 32 | MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_X = value; 33 | write(); 34 | } 35 | 36 | public void setSensitivityY(int value) { 37 | MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_Y = value; 38 | write(); 39 | } 40 | 41 | public void setInvertY(boolean value) { 42 | MouseMoveAutomationRunner.INVERT_Y = value; 43 | write(); 44 | } 45 | 46 | private void restore() { 47 | MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_X = this.storage.read(this.profileName, SENSITIVITY_X_KEY, MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_X); 48 | MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_Y = this.storage.read(this.profileName, SENSITIVITY_Y_KEY, MouseMoveAutomationRunner.PRIMARY_SENSITIVITY_Y); 49 | MouseMoveAutomationRunner.INVERT_Y = this.storage.readBoolean(this.profileName, INVERT_Y_KEY); 50 | } 51 | 52 | private void write() { 53 | this.storage.write(this.profileName, SENSITIVITY_X_KEY, getSensitivityX()); 54 | this.storage.write(this.profileName, SENSITIVITY_Y_KEY, getSensitivityY()); 55 | this.storage.write(this.profileName, INVERT_Y_KEY, isInvertY()); 56 | this.storage.commit(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/MouseWheelAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.minecontrol.framework.modes.MinecraftGameMode; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 5 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 6 | 7 | import java.awt.*; 8 | 9 | public class MouseWheelAutomationMethod implements IAutomationMethod { 10 | private static final String METHOD_ID = "mouse-wheel"; 11 | private static final String SCROLL_KEY = "scroll"; 12 | private static Robot humanInterfaceDeviceService; 13 | 14 | static { 15 | 16 | try 17 | { 18 | humanInterfaceDeviceService = new Robot(); 19 | 20 | // this prevents the OS from ignoring events generated too quickly in succession 21 | humanInterfaceDeviceService.setAutoDelay(5); 22 | } 23 | catch (AWTException e) 24 | { 25 | // TODO 2.0+ throw exception 26 | e.printStackTrace(); 27 | } 28 | } 29 | 30 | private final int scrollAmount; 31 | 32 | public MouseWheelAutomationMethod(int scrollAmount) { 33 | 34 | this.scrollAmount = scrollAmount; 35 | } 36 | 37 | public static IAutomationMethod load(IAutomationReader automationReader) { 38 | try { 39 | String methodId = automationReader.readMethod(); 40 | if(!methodId.equalsIgnoreCase(METHOD_ID)) { 41 | return null; 42 | } 43 | 44 | Integer scrollAmount = automationReader.readInt(SCROLL_KEY); 45 | 46 | return new MouseWheelAutomationMethod(scrollAmount); 47 | } catch (Exception e) { 48 | return null; 49 | } 50 | } 51 | 52 | public void automate(Float value) { 53 | if(value == 1f) { 54 | humanInterfaceDeviceService.mouseWheel(scrollAmount); 55 | } 56 | else if(value == -1f) { 57 | humanInterfaceDeviceService.mouseWheel(-scrollAmount); 58 | } 59 | } 60 | 61 | @Override 62 | public String getName() { 63 | String name = this.scrollAmount > 0 ? "Mouse scroll down" : "Mouse scroll up"; 64 | 65 | String helperText = MinecraftGameMode.getMouseScrollText(this.scrollAmount); 66 | if (helperText != "") { 67 | helperText = " [" + helperText +"]"; 68 | } 69 | 70 | return name + helperText; 71 | } 72 | 73 | @Override 74 | public void write(IAutomationWriter automationWriter) { 75 | automationWriter.writeMethod(METHOD_ID); 76 | automationWriter.write(SCROLL_KEY, this.scrollAmount); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/views/AboutView.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.views; 2 | 3 | import java.awt.Font; 4 | import java.awt.GridBagConstraints; 5 | import java.awt.GridBagLayout; 6 | import java.awt.Insets; 7 | 8 | import javax.swing.BorderFactory; 9 | import javax.swing.JDialog; 10 | import javax.swing.JLabel; 11 | import javax.swing.JPanel; 12 | 13 | import com.joshjcarrier.minecontrol.AppInfo; 14 | 15 | public class AboutView extends JDialog 16 | { 17 | private static final long serialVersionUID = 3018102427542810766L; 18 | 19 | public AboutView() 20 | { 21 | this.setTitle("About " + AppInfo.ProductName); 22 | 23 | JPanel panel = new JPanel(new GridBagLayout()); 24 | panel.setBorder(BorderFactory.createEmptyBorder(4, 10, 4, 10)); 25 | GridBagConstraints gridConstraints = new GridBagConstraints(); 26 | gridConstraints.fill = GridBagConstraints.BOTH; 27 | gridConstraints.insets = new Insets(5, 0, 0, 5); 28 | 29 | Font headerFont = new Font("Verdana", Font.BOLD | Font.ITALIC, 16); 30 | JLabel headerLabel = new JLabel(AppInfo.ProductName); 31 | headerLabel.setFont(headerFont); 32 | gridConstraints.gridy = 0; 33 | gridConstraints.gridx = 0; 34 | panel.add(headerLabel, gridConstraints); 35 | 36 | gridConstraints.gridy += 1; 37 | panel.add(new JLabel("For the latest update information visit www.joshjcarrier.com."), gridConstraints); 38 | 39 | gridConstraints.gridy += 1; 40 | panel.add(new JLabel(""), gridConstraints); 41 | 42 | gridConstraints.gridy += 1; 43 | panel.add(new JLabel(AppInfo.ProductName + " is released under the BSD license and made possibly by these open source works:"), gridConstraints); 44 | 45 | gridConstraints.gridy += 1; 46 | panel.add(new JLabel("ini4j the Java .ini library (Apache 2)"), gridConstraints); 47 | 48 | gridConstraints.gridy += 1; 49 | panel.add(new JLabel("Jinput Java game controller API (BSD 2)"), gridConstraints); 50 | 51 | gridConstraints.gridy += 1; 52 | panel.add(new JLabel("RxJava Reactive Extensions (Apache 2)"), gridConstraints); 53 | 54 | gridConstraints.gridy += 1; 55 | panel.add(new JLabel("XNA Button Pack � Jeff Jenkins (CCA3.0 Unported)"), gridConstraints); 56 | 57 | gridConstraints.gridy += 1; 58 | panel.add(new JLabel(""), gridConstraints); 59 | 60 | gridConstraints.gridy += 1; 61 | panel.add(new JLabel("Minecraft and the Minecraft cube are registered trademarks of Mojang Specifications and/or its affiliates."), gridConstraints); 62 | 63 | this.add(panel); 64 | 65 | this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 66 | this.setResizable(false); 67 | this.pack(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/KeyboardAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.minecontrol.framework.modes.MinecraftGameMode; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 5 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 6 | 7 | import java.awt.*; 8 | import java.awt.event.KeyEvent; 9 | 10 | public class KeyboardAutomationMethod implements IAutomationMethod { 11 | private static Robot humanInterfaceDeviceService; 12 | private static final String METHOD_ID = "kbd-btn"; 13 | private static final String PKEI_KEY = "pkei"; 14 | private final int primaryKeyEventId; 15 | 16 | static { 17 | 18 | try 19 | { 20 | humanInterfaceDeviceService = new Robot(); 21 | 22 | // this prevents the OS from ignoring events generated too quickly in succession 23 | humanInterfaceDeviceService.setAutoDelay(5); 24 | } 25 | catch (AWTException e) 26 | { 27 | // TODO 2.0+ throw exception 28 | e.printStackTrace(); 29 | } 30 | } 31 | 32 | public KeyboardAutomationMethod(int primaryKeyEventId) { 33 | this.primaryKeyEventId = primaryKeyEventId; 34 | } 35 | 36 | public static IAutomationMethod load(IAutomationReader automationReader) { 37 | try{ 38 | String methodId = automationReader.readMethod(); 39 | if(!methodId.equalsIgnoreCase(METHOD_ID)) { 40 | return null; 41 | } 42 | 43 | Integer primaryKeyEventId = automationReader.readInt(PKEI_KEY); 44 | 45 | return new KeyboardAutomationMethod(primaryKeyEventId); 46 | } catch (Exception e) { 47 | return null; 48 | } 49 | } 50 | 51 | boolean isPrimaryKeyPressed; 52 | 53 | // TODO come and clean this up. have abstraction on Robot to do performance optimization 54 | public void automate(Float value) { 55 | if (value != 0) { 56 | if (!this.isPrimaryKeyPressed) { 57 | this.isPrimaryKeyPressed = true; 58 | humanInterfaceDeviceService.keyPress(this.primaryKeyEventId); 59 | } 60 | } else { 61 | if (this.isPrimaryKeyPressed) { 62 | humanInterfaceDeviceService.keyRelease(this.primaryKeyEventId); 63 | this.isPrimaryKeyPressed = false; 64 | } 65 | } 66 | } 67 | 68 | @Override 69 | public String getName() { 70 | String helperText = MinecraftGameMode.getKeyText(this.primaryKeyEventId); 71 | if (helperText != "") { 72 | helperText = " [" + helperText +"]"; 73 | } 74 | return KeyEvent.getKeyText(this.primaryKeyEventId) + helperText; 75 | } 76 | 77 | @Override 78 | public void write(IAutomationWriter automationWriter) { 79 | automationWriter.writeMethod(METHOD_ID); 80 | automationWriter.write(PKEI_KEY, this.primaryKeyEventId); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/controls/renderers/BaseWrapperListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.controls.renderers; 2 | 3 | import java.awt.Component; 4 | import java.awt.Font; 5 | import java.awt.GridBagConstraints; 6 | import java.awt.GridBagLayout; 7 | 8 | import javax.swing.JLabel; 9 | import javax.swing.JList; 10 | import javax.swing.JPanel; 11 | import javax.swing.ListCellRenderer; 12 | 13 | /** 14 | * List cell renderer for the {@link BaseWrapperListCellRenderer} class. 15 | * @author joshjcarrier 16 | * 17 | */ 18 | public abstract class BaseWrapperListCellRenderer extends JPanel implements ListCellRenderer 19 | { 20 | private static final long serialVersionUID = -2297820527959875027L; 21 | 22 | protected final JLabel iconLabel; 23 | protected final JLabel publisherLabel; 24 | protected final JLabel titleLabel; 25 | 26 | protected BaseWrapperListCellRenderer() 27 | { 28 | this.setLayout(new GridBagLayout()); 29 | 30 | GridBagConstraints gridConstraints = new GridBagConstraints(); 31 | 32 | iconLabel = new JLabel(); 33 | gridConstraints.gridx = 0; 34 | gridConstraints.gridy = 0; 35 | gridConstraints.gridheight = 2; 36 | gridConstraints.gridwidth = 1; 37 | gridConstraints.weightx = 0; 38 | gridConstraints.ipadx = 4; 39 | gridConstraints.fill = GridBagConstraints.NONE; 40 | this.add(iconLabel, gridConstraints); 41 | 42 | titleLabel = new JLabel(); 43 | titleLabel.setFont(new Font("Verdana", Font.BOLD, 14)); 44 | gridConstraints.gridx = 1; 45 | gridConstraints.gridy = 0; 46 | gridConstraints.gridheight = 1; 47 | gridConstraints.gridwidth = 1; 48 | gridConstraints.weightx = 1; 49 | gridConstraints.ipadx = 0; 50 | gridConstraints.fill = GridBagConstraints.HORIZONTAL; 51 | this.add(titleLabel, gridConstraints); 52 | 53 | publisherLabel = new JLabel(); 54 | publisherLabel.setFont(new Font("Verdana", Font.ITALIC, 12)); 55 | gridConstraints.gridx = 1; 56 | gridConstraints.gridy = 1; 57 | gridConstraints.gridheight = 1; 58 | gridConstraints.gridwidth = 1; 59 | gridConstraints.weightx = 1; 60 | gridConstraints.ipadx = 0; 61 | gridConstraints.fill = GridBagConstraints.HORIZONTAL; 62 | this.add(publisherLabel, gridConstraints); 63 | } 64 | 65 | public final Component getListCellRendererComponent( 66 | JList list, 67 | Object value, 68 | int index, 69 | boolean isSelected, 70 | boolean cellHasFocus) 71 | { 72 | // regular combobox list behavior 73 | if (isSelected) 74 | { 75 | this.setBackground(list.getSelectionBackground()); 76 | this.setForeground(list.getSelectionForeground()); 77 | } 78 | else 79 | { 80 | this.setBackground(list.getBackground()); 81 | this.setForeground(list.getForeground()); 82 | } 83 | 84 | // custom update 85 | @SuppressWarnings("unchecked") 86 | T typedValue = (T) value; 87 | if (typedValue != null) 88 | { 89 | updateListCell(typedValue); 90 | } 91 | 92 | return this; 93 | } 94 | 95 | protected abstract void updateListCell(T value); 96 | } 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Minecontrol v2.0 2 | ======================================== 3 | 4 | ### INFO 5 | Play *any* game with your Xbox 360 controller! Minecontrol converts joystick input into WASD keyboard pulses and mouse movements to maximize compatibility with any controller-disabled game! 6 | 7 | This is the successor for [Minecontrol for Minecraft v1.x](https://bitbucket.org/joshjcarrier/minecontrol-for-minecraft). 8 | 9 | ![v2.0.0](http://javadocs.files.wordpress.com/2013/03/minecontrol2.png) 10 | 11 | ##### Features: 12 | * NEW: rearchitected again for more fun 13 | * D-Pad mapping to WASD 14 | * refreshed UI 15 | * switch any button mapping to toggle mode (press once/hold key) 16 | * Xbox 360 controller support (Windows, Mac OSX/Linux/alternate controllers experimental) 17 | * Convert left joystick into WASD pulses, regulated by how much you push on the stick 18 | * Convert right joytick into mouse movements, also regulated by how much you push on the stick 19 | * Invert right joystick Y axis 20 | * Convert the trigger joystick into mouse movements 21 | * Map all controller buttons, joystick buttons, shoulders, to a huge set of available keyboard buttons or mouse commands 22 | 23 | For more information visit www.joshjcarrier.com. Stay up to date with the latest version! 24 | 25 | ### INSTALLATION 26 | 1. Plug in your controller to your computer. Make sure your computer detects it! 27 | 2. Visit http://update.joshjcarrier.com/minecontrol and run the Java Web Start (JNLP) file to run Minecontrol. Running from this URL or the placed desktop icon will keep you up to date with the latest version. 28 | 3. Your Xbox controller should already be configured for use. Use the configuration panel to map keys to your likings! 29 | Enjoy! 30 | 31 | ### UNINSTALLATION 32 | 1. Uninstall from your OS control panel. This application uninstalls like any standard Java Web Start application. 33 | 34 | Note: preferences are saved in your home directory, as .minecontrol2.txt. 35 | 36 | ### SOURCE 37 | http://github.com/joshjcarrier/minecontrol 38 | 39 | To run from Eclipse/IntelliJ you will need the VM arguments "-Djava.library.path=lib" 40 | 41 | ### CONTRIBUTING 42 | Tips on adding game profiles, controller profiles, automation methods and more coming soon. 43 | 44 | ### BUILD STATUS 45 | [![Build Status](http://ci.joshjcarrier.com:8080/buildStatus/icon?job=Minecontrol 2.x)](http://ci.joshjcarrier.com:8080/job/Minecontrol%202.x/) update.joshjcarrier.com/minecontrol 46 | 47 | [![Build Status](http://ci.joshjcarrier.com:8080/buildStatus/icon?job=Minecontrol 2.x BETA)](http://ci.joshjcarrier.com:8080/job/Minecontrol%202.x%20BETA/) beta.joshjcarrier.com/minecontrol 48 | 49 | ### FOLLOW 50 | http://javadocs.wordpress.com/category/java-projects/minecontrol/ 51 | 52 | ### LICENSE 53 | See the included license agreement in the repository. 54 | 55 | This software includes binaries from **JInput**, **RxJava** and **ini4j**. 56 | It also contains works from **XNA Button Pack – Jeff Jenkins**. 57 | **Minecraft** and the Minecraft cube are registered trademarks of Mojang Specifications and/or its affiliates. 58 | 59 | *Josh Carrier * 60 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/framework/modes/MinecraftGameMode.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.framework.modes; 2 | 3 | import java.awt.event.KeyEvent; 4 | import java.awt.event.MouseEvent; 5 | 6 | public class MinecraftGameMode 7 | { 8 | public static String getKeyText(int keyEventId) { 9 | switch(keyEventId) 10 | { 11 | case KeyEvent.VK_1: 12 | return "Item 1"; 13 | case KeyEvent.VK_2: 14 | return "Item 2"; 15 | case KeyEvent.VK_3: 16 | return "Item 3"; 17 | case KeyEvent.VK_4: 18 | return "Item 4"; 19 | case KeyEvent.VK_5: 20 | return "Item 5"; 21 | case KeyEvent.VK_6: 22 | return "Item 6"; 23 | case KeyEvent.VK_7: 24 | return "Item 7"; 25 | case KeyEvent.VK_8: 26 | return "Item 8"; 27 | case KeyEvent.VK_9: 28 | return "Item 9"; 29 | case KeyEvent.VK_ESCAPE: 30 | return "Menu/Pause"; 31 | case KeyEvent.VK_F1: 32 | return "Heads-up display"; 33 | case KeyEvent.VK_F2: 34 | return "Screenshot"; 35 | case KeyEvent.VK_F3: 36 | return "Debug overlay"; 37 | case KeyEvent.VK_F5: 38 | return "Change perspective"; 39 | case KeyEvent.VK_F8: 40 | return "Mouse smoothing (cinematic)"; 41 | case KeyEvent.VK_F11: 42 | return "Full-screen mode"; 43 | case KeyEvent.VK_SHIFT: 44 | return "Sneak"; 45 | case KeyEvent.VK_W: 46 | return "Forward"; 47 | case KeyEvent.VK_A: 48 | return "Left"; 49 | case KeyEvent.VK_S: 50 | return "Back"; 51 | case KeyEvent.VK_D: 52 | return "Right"; 53 | case KeyEvent.VK_SPACE: 54 | return "Jump"; 55 | case KeyEvent.VK_E: 56 | return "Inventory"; 57 | case KeyEvent.VK_Q: 58 | return "Drop"; 59 | case KeyEvent.VK_T: 60 | return "Chat"; 61 | case KeyEvent.VK_SLASH: 62 | return "Command"; 63 | case KeyEvent.VK_TAB: 64 | return "List players"; 65 | } 66 | 67 | return ""; 68 | } 69 | 70 | public static String getMouseButtonText(int mouseEventId) { 71 | switch(mouseEventId) 72 | { 73 | case MouseEvent.BUTTON1_MASK: 74 | return "Action"; 75 | case MouseEvent.BUTTON2_MASK: 76 | return "Pick block"; 77 | case MouseEvent.BUTTON3_MASK: 78 | return "Use item"; 79 | } 80 | 81 | return ""; 82 | } 83 | 84 | public static String getMouseScrollText(int scrollAmount) { 85 | if (scrollAmount > 0) 86 | { 87 | return "Next item"; 88 | } 89 | 90 | return "Previous item"; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/controllers/MainController.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.controllers; 2 | 3 | import com.joshjcarrier.minecontrol.framework.profiles.GamePadProfile; 4 | import com.joshjcarrier.minecontrol.framework.profiles.GamePadProfileList; 5 | import com.joshjcarrier.minecontrol.ui.models.GamePadProfileWrapper; 6 | import com.joshjcarrier.minecontrol.ui.models.GamePadWrapper; 7 | import com.joshjcarrier.minecontrol.ui.views.GamePadProfileView; 8 | import com.joshjcarrier.minecontrol.ui.views.MainView; 9 | import com.joshjcarrier.rxgamepad.RxGamePad; 10 | import com.joshjcarrier.rxgamepad.RxGamePadList; 11 | import rx.util.functions.Func1; 12 | 13 | import java.util.List; 14 | 15 | public class MainController { 16 | private final RxGamePadList rxGamePadList; 17 | private final GamePadProfileList gamePadProfileList; 18 | private GamePadWrapper activeGamePad; 19 | private GamePadProfileWrapper activeProfile; 20 | 21 | public MainController(RxGamePadList rxGamePadList, GamePadProfileList gamePadProfileList) { 22 | this.rxGamePadList = rxGamePadList; 23 | this.gamePadProfileList = gamePadProfileList; 24 | } 25 | 26 | public List getGamePads() { 27 | return this.rxGamePadList.getAll() 28 | .map(new Func1() { 29 | @Override 30 | public GamePadWrapper call(RxGamePad rxGamePad) { 31 | List profiles = gamePadProfileList.getAll(rxGamePad).map(new Func1() { 32 | @Override 33 | public GamePadProfileWrapper call(GamePadProfile gamePadProfile) { 34 | return new GamePadProfileWrapper(gamePadProfile); 35 | } 36 | }) 37 | .toList() 38 | .toBlockingObservable() 39 | .first(); 40 | return new GamePadWrapper(rxGamePad, profiles); 41 | } 42 | }) 43 | .toList() 44 | .toBlockingObservable() 45 | .first();// temporary to maintain interface 46 | } 47 | 48 | public GamePadWrapper getActiveGamePad() { 49 | return this.activeGamePad; 50 | } 51 | 52 | public void setActiveGamePad(GamePadWrapper gamePadWrapper) { 53 | if(this.activeProfile != null) { 54 | activeProfile.deactivate(); 55 | } 56 | 57 | this.activeGamePad = gamePadWrapper; 58 | this.activeProfile = gamePadWrapper.getProfiles().get(0); 59 | this.activeProfile.activate(); 60 | } 61 | 62 | public GamePadProfileView navigateToGamePadProfile() { 63 | if (this.activeProfile == null) { 64 | return null; 65 | } 66 | 67 | GamePadProfileController gamePadProfileController = new GamePadProfileController(this.activeProfile); 68 | return new GamePadProfileView(gamePadProfileController); 69 | } 70 | 71 | public MainView index() { 72 | return new MainView(this); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/projection/ActionPotentialRxAutomationProjection.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.projection; 2 | 3 | import com.joshjcarrier.Pair; 4 | import com.joshjcarrier.rxautomation.methods.IAutomationMethod; 5 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 6 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 7 | import rx.Observable; 8 | import rx.util.Timestamped; 9 | import rx.util.functions.Func1; 10 | 11 | public class ActionPotentialRxAutomationProjection implements IRxAutomationProjection { 12 | private static final String PROJECTION_ID = "action-potential"; 13 | 14 | public static IRxAutomationProjection load(IAutomationReader automationReader) { 15 | try { 16 | String projectionId = automationReader.readProjection(); 17 | if(projectionId.equalsIgnoreCase(PROJECTION_ID)) { 18 | return new ActionPotentialRxAutomationProjection(); 19 | } 20 | } catch (Exception e) { 21 | // do nothing 22 | } 23 | 24 | return null; 25 | } 26 | 27 | public Observable> map(final IAutomationMethod automationMethod, Observable source) { 28 | return source 29 | .map(new Func1() { 30 | @Override 31 | public Float call(Float value) { 32 | if (value >= 0) { 33 | return value > 0.7 ? 1f : 0f; 34 | } else { 35 | return -value > 0.7 ? -1f : 0f; 36 | } 37 | } 38 | }) 39 | .distinctUntilChanged() 40 | .timestamp() 41 | .flatMap(new Func1, Observable>() { 42 | long lastNonZeroMillis = 0L; 43 | 44 | @Override 45 | public Observable call(Timestamped timestampedFloat) { 46 | if (timestampedFloat.getValue() < 0) { 47 | // past the refractory period, fire again 48 | if (timestampedFloat.getTimestampMillis() - lastNonZeroMillis > 100) { 49 | lastNonZeroMillis = timestampedFloat.getTimestampMillis(); 50 | return Observable.from(timestampedFloat.getValue(), 0f); 51 | } 52 | } else if(timestampedFloat.getValue() > 0) { 53 | return Observable.just(timestampedFloat.getValue()); 54 | } 55 | 56 | return Observable.just(0f); 57 | } 58 | }) 59 | .distinctUntilChanged() 60 | .map(new Func1>() { 61 | @Override 62 | public Pair call(Float aFloat) { 63 | return new Pair(automationMethod, aFloat); 64 | } 65 | }); 66 | } 67 | 68 | @Override 69 | public void write(IAutomationWriter automationWriter) { 70 | automationWriter.writeProjection(PROJECTION_ID); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxjinput/RxController.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxjinput; 2 | 3 | import net.java.games.input.Component; 4 | import net.java.games.input.Controller; 5 | import net.java.games.input.Event; 6 | import net.java.games.input.EventQueue; 7 | import rx.Observable; 8 | import rx.observables.ConnectableObservable; 9 | import rx.util.functions.Action1; 10 | import rx.util.functions.Func1; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | import java.util.concurrent.TimeUnit; 15 | 16 | public class RxController { 17 | private final Controller controller; 18 | private final ConnectableObservable events; 19 | 20 | public RxController(final Controller controller) { 21 | this.controller = controller; 22 | 23 | this.events = Observable 24 | .interval(5, TimeUnit.MILLISECONDS) 25 | .flatMap(new Func1>() { 26 | 27 | 28 | { 29 | // primes the event queue with pending controller events 30 | //controller.poll(); 31 | //this.queue = controller.getEventQueue(); 32 | } 33 | 34 | public Observable call(Long arg0) { 35 | controller.poll(); 36 | EventQueue queue = controller.getEventQueue(); 37 | Collection events = new ArrayList(); 38 | 39 | Event event = new Event(); 40 | while (queue.getNextEvent(event)) { 41 | events.add(event); 42 | event = new Event(); // this allocation necessary? 43 | } 44 | 45 | return Observable.from(events); 46 | } 47 | }) 48 | .publish(); // allow multiple observables to draw from single poll source 49 | } 50 | 51 | @Deprecated // only for transition purposes 52 | public Controller getInternalController() { 53 | return this.controller; 54 | } 55 | 56 | public Observable getComponent(final Component.Identifier id) { 57 | this.events.connect(); 58 | 59 | return this.events 60 | .filter(new Func1() { 61 | @Override 62 | public Boolean call(Event event) { 63 | return event.getComponent().getIdentifier() == id; 64 | } 65 | }) 66 | .map(new Func1() { 67 | @Override 68 | public Float call(Event event) { 69 | Float data = event.getComponent().getPollData(); 70 | 71 | // debounce joystick 72 | if(data > 0 && data <= 0.17) { 73 | data = 0f; 74 | } 75 | else if(-data > 0 && -data <= 0.17) { 76 | data = 0f; 77 | } 78 | 79 | return data; 80 | } 81 | }); 82 | } 83 | 84 | public Observable getEvents() { 85 | return this.events; 86 | } 87 | 88 | public String getName() { return this.controller.getName(); } 89 | } 90 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/controls/AutomationBindingsControl.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.controls; 2 | 3 | import com.joshjcarrier.minecontrol.ui.actions.SimpleAction; 4 | import com.joshjcarrier.minecontrol.ui.models.AutomationBindingWrapper; 5 | import rx.util.functions.Action1; 6 | 7 | import javax.swing.*; 8 | import java.awt.*; 9 | import java.awt.event.ActionEvent; 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | 13 | public class AutomationBindingsControl extends JPanel { 14 | private static final long serialVersionUID = -3729294863824556950L; 15 | 16 | private final JComboBox buttonMappingComboBox; 17 | private final JCheckBox keyToggleModeCheckBox; 18 | private Action1 bindingChangedAction; 19 | private Action1 projectionChangedAction; 20 | 21 | public AutomationBindingsControl(boolean isToggled, AutomationBindingWrapper selectedBinding, Collection bindings) { 22 | this(isToggled, selectedBinding, bindings, true); 23 | } 24 | 25 | public AutomationBindingsControl(boolean isToggled, AutomationBindingWrapper selectedBinding, Collection bindings, boolean isToggleEnabled) { 26 | this.setLayout(new GridBagLayout()); 27 | GridBagConstraints gridConstraints = new GridBagConstraints(); 28 | 29 | gridConstraints.gridx = 0; 30 | gridConstraints.weightx = 1; 31 | ArrayList selectableButtonMappings = new ArrayList(); 32 | selectableButtonMappings.addAll(bindings); 33 | this.buttonMappingComboBox = new JComboBox(selectableButtonMappings.toArray()); 34 | this.buttonMappingComboBox.setSelectedItem(selectedBinding); 35 | this.buttonMappingComboBox.setAction(new SimpleAction() 36 | { 37 | @Override 38 | public void actionPerformed(ActionEvent e) 39 | { 40 | AutomationBindingWrapper binding = (AutomationBindingWrapper)buttonMappingComboBox.getSelectedItem(); 41 | 42 | if (bindingChangedAction != null) 43 | { 44 | bindingChangedAction.call(binding); 45 | } 46 | } 47 | }); 48 | this.add(this.buttonMappingComboBox, gridConstraints); 49 | 50 | gridConstraints.gridx = 1; 51 | gridConstraints.weighty = 0; 52 | this.keyToggleModeCheckBox = new JCheckBox(); 53 | this.keyToggleModeCheckBox.setSelected(isToggled); 54 | this.keyToggleModeCheckBox.setAction(new SimpleAction() 55 | { 56 | @Override 57 | public void actionPerformed(ActionEvent e) 58 | { 59 | if (projectionChangedAction != null) 60 | { 61 | projectionChangedAction.call(keyToggleModeCheckBox.isSelected()); 62 | } 63 | } 64 | }); 65 | this.keyToggleModeCheckBox.setText("Toggle mode"); 66 | this.keyToggleModeCheckBox.setToolTipText("When selected, the mapped key will continue to be held until the button is pressed again."); 67 | this.keyToggleModeCheckBox.setEnabled(isToggleEnabled); 68 | this.add(this.keyToggleModeCheckBox, gridConstraints); 69 | } 70 | 71 | public void onBindingChanged(Action1 a) 72 | { 73 | this.bindingChangedAction = a; 74 | } 75 | 76 | public void onProjectionChanged(Action1 a) 77 | { 78 | this.projectionChangedAction = a; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/persistence/IniStorage.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.persistence; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | 8 | import org.ini4j.Ini; 9 | 10 | import com.joshjcarrier.minecontrol.AppInfo; 11 | 12 | public class IniStorage implements IStorage 13 | { 14 | private Ini cache; 15 | 16 | public IniStorage() 17 | { 18 | this.cache = new Ini(); 19 | } 20 | 21 | public void commit() 22 | { 23 | String settingsFilePath = this.getSettingsFilePath(); 24 | if (settingsFilePath == null) 25 | { 26 | return; 27 | } 28 | 29 | try 30 | { 31 | this.cache.setComment(AppInfo.ProductName + " v" + AppInfo.BuildVersion); 32 | this.cache.store(new FileOutputStream(settingsFilePath)); 33 | } 34 | catch (IOException e) 35 | { 36 | // failed to save settings -- silently fail for now. 37 | } 38 | } 39 | 40 | public void load() 41 | { 42 | String settingsFilePath = this.getSettingsFilePath(); 43 | 44 | FileInputStream settingsStream = null; 45 | try 46 | { 47 | settingsStream = new FileInputStream(settingsFilePath); 48 | this.cache.load(settingsStream); 49 | } 50 | catch (FileNotFoundException e) 51 | { 52 | // it's okay to not have an existing settings file. 53 | } 54 | catch (IOException e) 55 | { 56 | // maybe the settings file is corrupt, so delete it 57 | e.printStackTrace(); 58 | } 59 | finally 60 | { 61 | if (settingsStream != null) 62 | { 63 | try 64 | { 65 | settingsStream.close(); 66 | } 67 | catch (IOException e) 68 | { 69 | // tried to dispose of the stream nicely, oh well. 70 | } 71 | } 72 | } 73 | } 74 | 75 | public String read(String section, String name) 76 | { 77 | return this.cache.fetch(section, name); 78 | } 79 | 80 | public boolean readBoolean(String section, String name) 81 | { 82 | try 83 | { 84 | return this.cache.fetch(section, name, Boolean.class); 85 | } 86 | catch (Exception e) 87 | { 88 | return false; 89 | } 90 | } 91 | 92 | public float read(String section, String name, float defaultValue) 93 | { 94 | try 95 | { 96 | return this.cache.fetch(section, name, Float.class); 97 | } 98 | catch (Exception e) 99 | { 100 | return defaultValue; 101 | } 102 | } 103 | 104 | public int read(String section, String name, int defaultValue) 105 | { 106 | try 107 | { 108 | return this.cache.fetch(section, name, Integer.class); 109 | } 110 | catch (Exception e) 111 | { 112 | return defaultValue; 113 | } 114 | } 115 | 116 | public void write(String section, String name, String value) 117 | { 118 | this.cache.put(section, name, value); 119 | } 120 | 121 | public void write(String section, String name, boolean value) 122 | { 123 | this.cache.put(section, name, value); 124 | } 125 | 126 | public void write(String section, String name, float value) 127 | { 128 | this.cache.put(section, name, value); 129 | } 130 | 131 | public void write(String section, String name, int value) 132 | { 133 | this.cache.put(section, name, value); 134 | } 135 | 136 | private String getSettingsFilePath() 137 | { 138 | try 139 | { 140 | String userHomeDir = System.getProperty("user.home"); 141 | if(userHomeDir == null) 142 | { 143 | return null; 144 | } 145 | 146 | return userHomeDir + "/.minecontrol2.txt"; 147 | } 148 | catch (SecurityException ioEx) {} 149 | 150 | return null; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/persistence/PropertiesStorage.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.persistence; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.util.Properties; 8 | 9 | import com.joshjcarrier.minecontrol.AppInfo; 10 | 11 | /** 12 | * Stores data within a properties file. 13 | * @author joshjcarrier 14 | * 15 | */ 16 | public class PropertiesStorage implements IStorage 17 | { 18 | private Properties cache; 19 | 20 | public PropertiesStorage() 21 | { 22 | cache = new Properties(); 23 | } 24 | 25 | public void commit() 26 | { 27 | String settingsFilePath = this.getSettingsFilePath(); 28 | if (settingsFilePath == null) 29 | { 30 | return; 31 | } 32 | 33 | try 34 | { 35 | this.cache.store(new FileOutputStream(settingsFilePath), AppInfo.ProductName + " v" + AppInfo.BuildVersion); 36 | } 37 | catch (IOException e) 38 | { 39 | // failed to save settings -- silently fail for now. 40 | } 41 | } 42 | 43 | public void load() 44 | { 45 | String settingsFilePath = this.getSettingsFilePath(); 46 | 47 | FileInputStream settingsStream = null; 48 | try 49 | { 50 | settingsStream =new FileInputStream(settingsFilePath); 51 | cache.load(settingsStream); 52 | } 53 | catch (FileNotFoundException e) 54 | { 55 | // it's okay to not have an existing settings file. 56 | } 57 | catch (IOException e) 58 | { 59 | // maybe the settings file is corrupt, so delete it 60 | e.printStackTrace(); 61 | } 62 | finally 63 | { 64 | if (settingsStream != null) 65 | { 66 | try 67 | { 68 | settingsStream.close(); 69 | } 70 | catch (IOException e) 71 | { 72 | // tried to dispose of the stream nicely, oh well. 73 | } 74 | } 75 | } 76 | } 77 | 78 | public String read(String section, String name) 79 | { 80 | return this.cache.getProperty(section + "." + name); 81 | } 82 | 83 | public boolean readBoolean(String section, String name) 84 | { 85 | String stringValue = this.read(section, name); 86 | return Boolean.parseBoolean(stringValue); 87 | } 88 | 89 | public float read(String section, String name, float defaultValue) 90 | { 91 | String stringValue = this.read(section, name); 92 | try 93 | { 94 | return Float.parseFloat(stringValue); 95 | } 96 | catch (NumberFormatException ex) 97 | { 98 | return defaultValue; 99 | } 100 | } 101 | 102 | public int read(String section, String name, int defaultValue) 103 | { 104 | String stringValue = this.read(section, name); 105 | try 106 | { 107 | return Integer.parseInt(stringValue); 108 | } 109 | catch (NumberFormatException ex) 110 | { 111 | return defaultValue; 112 | } 113 | } 114 | 115 | public void write(String section, String name, String value) 116 | { 117 | this.cache.put(section + "." + name, value); 118 | } 119 | 120 | public void write(String section, String name, boolean value) 121 | { 122 | this.write(section, name, String.valueOf(value)); 123 | } 124 | 125 | public void write(String section, String name, float value) 126 | { 127 | this.write(section, name, String.valueOf(value)); 128 | } 129 | 130 | public void write(String section, String name, int value) 131 | { 132 | this.write(section, name, String.valueOf(value)); 133 | } 134 | 135 | private String getSettingsFilePath() 136 | { 137 | try 138 | { 139 | String userHomeDir = System.getProperty("user.home"); 140 | if(userHomeDir == null) 141 | { 142 | return null; 143 | } 144 | 145 | return userHomeDir + "/.minecontrol2.txt"; 146 | } 147 | catch (SecurityException ioEx) {} 148 | 149 | return null; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/controls/ButtonDescriptorPanel.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.controls; 2 | 3 | import java.awt.Font; 4 | import java.awt.GridLayout; 5 | import java.awt.Image; 6 | import java.net.URL; 7 | 8 | import javax.swing.ImageIcon; 9 | import javax.swing.JLabel; 10 | import javax.swing.JPanel; 11 | import javax.swing.SwingConstants; 12 | 13 | import com.joshjcarrier.minecontrol.framework.input.Buttons; 14 | import com.joshjcarrier.minecontrol.ui.ContentResources; 15 | import com.joshjcarrier.minecontrol.ui.views.GamePadProfileView; 16 | 17 | public class ButtonDescriptorPanel extends JPanel 18 | { 19 | private static final long serialVersionUID = -390648248728862955L; 20 | 21 | public ButtonDescriptorPanel(String canonicalName, String iconResource) 22 | { 23 | this.setLayout(new GridLayout()); 24 | 25 | Font headerFont = new Font("Verdana", Font.BOLD, 10); 26 | JLabel nameLabel = new JLabel(canonicalName); 27 | nameLabel.setFont(headerFont); 28 | nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); 29 | this.add(nameLabel); 30 | 31 | JLabel iconLabel = new JLabel(); 32 | URL iconUrl = GamePadProfileView.class.getClassLoader().getResource(iconResource); 33 | ImageIcon icon = new ImageIcon(iconUrl); 34 | Image newimg = icon.getImage().getScaledInstance(24, 24, java.awt.Image.SCALE_SMOOTH); 35 | iconLabel.setIcon(new ImageIcon(newimg)); 36 | iconLabel.setToolTipText(canonicalName); 37 | iconLabel.setHorizontalAlignment(SwingConstants.CENTER); 38 | this.add(iconLabel); 39 | } 40 | 41 | public ButtonDescriptorPanel(Buttons button) 42 | { 43 | this(getCanonicalName(button), getButtonResource(button)); 44 | } 45 | 46 | private static String getCanonicalName(Buttons button) 47 | { 48 | switch(button) 49 | { 50 | case BACK: 51 | return "Back"; 52 | case DPAD_DOWN: 53 | return "D-Pad down"; 54 | case DPAD_LEFT: 55 | return "D-Pad left"; 56 | case DPAD_RIGHT: 57 | return "D-Pad right"; 58 | case DPAD_UP: 59 | return "D-Pad up"; 60 | case LEFT_SHOULDER: 61 | return "Left shoulder"; 62 | case LEFT_STICK: 63 | return "Left joystick press"; 64 | case LEFT_TRIGGER: 65 | return "Left trigger"; 66 | case RIGHT_SHOULDER: 67 | return "Right shoulder"; 68 | case RIGHT_STICK: 69 | return "Right joystick press"; 70 | case RIGHT_TRIGGER: 71 | return "Right trigger"; 72 | case START: 73 | return "Start"; 74 | default: 75 | return button.name(); 76 | } 77 | } 78 | 79 | private static String getButtonResource(Buttons button) 80 | { 81 | switch(button) 82 | { 83 | case A: 84 | return ContentResources.BUTTON_XBOX360_A; 85 | case B: 86 | return ContentResources.BUTTON_XBOX360_B; 87 | case BACK: 88 | return ContentResources.BUTTON_XBOX360_BACK; 89 | case DPAD_DOWN: 90 | return ContentResources.BUTTON_XBOX360_DPAD; 91 | case DPAD_LEFT: 92 | return ContentResources.BUTTON_XBOX360_DPAD; 93 | case DPAD_RIGHT: 94 | return ContentResources.BUTTON_XBOX360_DPAD; 95 | case DPAD_UP: 96 | return ContentResources.BUTTON_XBOX360_DPAD; 97 | case LEFT_SHOULDER: 98 | return ContentResources.BUTTON_XBOX360_LEFTSHOULDER; 99 | case LEFT_STICK: 100 | return ContentResources.BUTTON_XBOX360_LEFTSTICK; 101 | case LEFT_TRIGGER: 102 | return ContentResources.BUTTON_XBOX360_LEFTTRIGGER; 103 | case RIGHT_SHOULDER: 104 | return ContentResources.BUTTON_XBOX360_RIGHTSHOULDER; 105 | case RIGHT_STICK: 106 | return ContentResources.BUTTON_XBOX360_RIGHTSTICK; 107 | case RIGHT_TRIGGER: 108 | return ContentResources.BUTTON_XBOX360_RIGHTTRIGGER; 109 | case START: 110 | return ContentResources.BUTTON_XBOX360_START; 111 | case X: 112 | return ContentResources.BUTTON_XBOX360_X; 113 | case Y: 114 | return ContentResources.BUTTON_XBOX360_Y; 115 | default: 116 | return ContentResources.INPUTDEVICE_XBOX360; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/models/GamePadProfileWrapper.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.models; 2 | 3 | import com.joshjcarrier.minecontrol.framework.input.AutomationBinding; 4 | import com.joshjcarrier.minecontrol.framework.profiles.GamePadProfile; 5 | import com.joshjcarrier.minecontrol.ui.ContentResources; 6 | import com.joshjcarrier.rxautomation.methods.IAutomationMethod; 7 | import com.joshjcarrier.rxautomation.projection.BinaryRxAutomationProjection; 8 | import com.joshjcarrier.rxautomation.projection.BufferedSwitchRxAutomationProjection; 9 | import net.java.games.input.Component; 10 | 11 | import java.util.HashMap; 12 | 13 | public class GamePadProfileWrapper { 14 | private final GamePadProfile gamePadProfile; 15 | 16 | public GamePadProfileWrapper(GamePadProfile gamePadProfile) { 17 | this.gamePadProfile = gamePadProfile; 18 | } 19 | 20 | public void activate() { 21 | this.gamePadProfile.activate(); 22 | } 23 | 24 | public void deactivate() { 25 | this.gamePadProfile.deactivate(); 26 | } 27 | 28 | public HashMap getGamePadButtonLabels() { 29 | return this.gamePadProfile.getGamePadButtonLabels(); 30 | } 31 | 32 | public HashMap getGamePadButtonIcons() { 33 | return new HashMap() { 34 | private static final long serialVersionUID = 3258388604108766926L; 35 | 36 | { 37 | put(Component.Identifier.Button._0, ContentResources.BUTTON_XBOX360_A); 38 | put(Component.Identifier.Button._1, ContentResources.BUTTON_XBOX360_B); 39 | put(Component.Identifier.Button._2, ContentResources.BUTTON_XBOX360_X); 40 | put(Component.Identifier.Button._3, ContentResources.BUTTON_XBOX360_Y); 41 | put(Component.Identifier.Button._4, ContentResources.BUTTON_XBOX360_LEFTSHOULDER); 42 | put(Component.Identifier.Button._5, ContentResources.BUTTON_XBOX360_RIGHTSHOULDER); 43 | put(Component.Identifier.Button._6, ContentResources.BUTTON_XBOX360_BACK); 44 | put(Component.Identifier.Button._7, ContentResources.BUTTON_XBOX360_START); 45 | put(Component.Identifier.Button._8, ContentResources.BUTTON_XBOX360_LEFTSTICK); 46 | put(Component.Identifier.Button._9, ContentResources.BUTTON_XBOX360_RIGHTSTICK); 47 | 48 | put(Component.Identifier.Axis.POV, ContentResources.BUTTON_XBOX360_DPAD); 49 | } 50 | }; 51 | } 52 | 53 | public String getName() { 54 | return this.gamePadProfile.getName(); 55 | } 56 | 57 | public AutomationBindingWrapper getAutomationBinding(Component.Identifier identifier) { 58 | return new AutomationBindingWrapper(new AutomationBinding(this.gamePadProfile.getAutomationMethod(identifier))); 59 | } 60 | 61 | @Deprecated // TODO shouldn't poke hole through wrapper 62 | public IAutomationMethod getAutomationMethodBadBadBad(Component.Identifier identifier) { 63 | return this.gamePadProfile.getAutomationMethod(identifier); 64 | } 65 | 66 | @Deprecated // replace with info from projection strategy 67 | public boolean isBufferAutomationProjection(Component.Identifier identifier) { 68 | return this.gamePadProfile.getAutomationProjection(identifier) instanceof BufferedSwitchRxAutomationProjection; 69 | } 70 | 71 | public void setAutomationBinding(Component.Identifier identifier, AutomationBindingWrapper automationBindingWrapper) { 72 | this.gamePadProfile.setAutomationMethod(identifier, automationBindingWrapper.getAutomationBinding().getAutomationMethod()); 73 | } 74 | 75 | public void setThresholdAutomationProjection(Component.Identifier identifier) { 76 | this.gamePadProfile.setAutomationProjection(identifier, new BinaryRxAutomationProjection()); 77 | } 78 | 79 | public void setBufferAutomationProjection(Component.Identifier identifier) { 80 | this.gamePadProfile.setAutomationProjection(identifier, new BufferedSwitchRxAutomationProjection()); 81 | } 82 | 83 | public MouseProfileWrapper getPrimaryMouseProfile() { 84 | return new MouseProfileWrapper(this.gamePadProfile.getPrimaryMouseProfile()); 85 | } 86 | 87 | public MouseProfileWrapper getSecondaryMouseProfile() { 88 | return new MouseProfileWrapper(this.gamePadProfile.getSecondaryMouseProfile()); 89 | } 90 | 91 | @Override 92 | public String toString() { 93 | return getName(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/MouseButtonAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.minecontrol.framework.modes.MinecraftGameMode; 4 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 5 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 6 | 7 | import java.awt.*; 8 | import java.awt.event.MouseEvent; 9 | 10 | public class MouseButtonAutomationMethod implements IAutomationMethod { 11 | private static final String METHOD_ID = "mouse-btn"; 12 | private static final String PMEI_KEY = "pmei"; 13 | private static final String SMEI_KEY = "smei"; 14 | private final int primaryMouseEventId; 15 | private final int secondaryMouseEventId; 16 | private static Robot humanInterfaceDeviceService; 17 | 18 | static { 19 | 20 | try 21 | { 22 | humanInterfaceDeviceService = new Robot(); 23 | 24 | // this prevents the OS from ignoring events generated too quickly in succession 25 | humanInterfaceDeviceService.setAutoDelay(10); 26 | } 27 | catch (AWTException e) 28 | { 29 | // TODO 2.0+ throw exception 30 | e.printStackTrace(); 31 | } 32 | } 33 | 34 | public MouseButtonAutomationMethod(int primaryMouseEventId) { 35 | this(primaryMouseEventId, primaryMouseEventId); 36 | } 37 | 38 | public MouseButtonAutomationMethod(int primaryMouseEventId, int secondaryMouseEventId) { 39 | this.primaryMouseEventId = primaryMouseEventId; 40 | this.secondaryMouseEventId = secondaryMouseEventId; 41 | } 42 | 43 | public static IAutomationMethod load(IAutomationReader automationReader) { 44 | try { 45 | String methodId = automationReader.readMethod(); 46 | if(!methodId.equalsIgnoreCase(METHOD_ID)) { 47 | return null; 48 | } 49 | 50 | Integer primaryMouseEventId = automationReader.readInt(PMEI_KEY); 51 | Integer secondaryMouseEventId = automationReader.readInt(SMEI_KEY); 52 | 53 | return new MouseButtonAutomationMethod(primaryMouseEventId, secondaryMouseEventId); 54 | } catch (Exception e) { 55 | return null; 56 | } 57 | } 58 | 59 | private boolean isPrimaryMousePressed; 60 | private boolean isSecondaryMousePressed; 61 | 62 | // TODO optimization in the mouse robot 63 | public void automate(Float value) { 64 | if(value == 1f) { 65 | if (this.isSecondaryMousePressed) { 66 | humanInterfaceDeviceService.mouseRelease(this.secondaryMouseEventId); 67 | this.isSecondaryMousePressed = false; 68 | } 69 | 70 | humanInterfaceDeviceService.mousePress(this.primaryMouseEventId); 71 | this.isPrimaryMousePressed = true; 72 | } 73 | else if(value == -1f) { 74 | if (this.isPrimaryMousePressed) { 75 | humanInterfaceDeviceService.mouseRelease(this.primaryMouseEventId); 76 | this.isPrimaryMousePressed = false; 77 | } 78 | 79 | humanInterfaceDeviceService.mousePress(this.secondaryMouseEventId); 80 | this.isSecondaryMousePressed = true; 81 | } 82 | else { 83 | if (this.isPrimaryMousePressed) { 84 | humanInterfaceDeviceService.mouseRelease(this.primaryMouseEventId); 85 | this.isPrimaryMousePressed = false; 86 | } 87 | 88 | if (this.isSecondaryMousePressed) { 89 | humanInterfaceDeviceService.mouseRelease(this.secondaryMouseEventId); 90 | this.isSecondaryMousePressed = false; 91 | } 92 | } 93 | } 94 | 95 | @Override 96 | public String getName() { 97 | String name; 98 | switch(this.primaryMouseEventId) 99 | { 100 | case MouseEvent.BUTTON1_MASK: 101 | name = "Mouse left click (button 1)"; 102 | break; 103 | case MouseEvent.BUTTON2_MASK: 104 | name = "Mouse middle click (button 2)"; 105 | break; 106 | case MouseEvent.BUTTON3_MASK: 107 | name = "Mouse right click (button 3)"; 108 | break; 109 | default: 110 | name = "Mouse event unknown"; 111 | break; 112 | } 113 | 114 | String helperText = MinecraftGameMode.getMouseButtonText(this.primaryMouseEventId); 115 | if (helperText != "") { 116 | helperText = " [" + helperText +"]"; 117 | } 118 | 119 | return name + helperText; 120 | } 121 | 122 | @Override 123 | public void write(IAutomationWriter automationWriter) { 124 | automationWriter.writeMethod(METHOD_ID); 125 | automationWriter.write(PMEI_KEY, this.primaryMouseEventId); 126 | automationWriter.write(SMEI_KEY, this.secondaryMouseEventId); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/views/MainView.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.views; 2 | 3 | import com.joshjcarrier.minecontrol.AppInfo; 4 | import com.joshjcarrier.minecontrol.ui.ContentResources; 5 | import com.joshjcarrier.minecontrol.ui.controllers.MainController; 6 | import com.joshjcarrier.minecontrol.ui.controls.renderers.GamePadWrapperListCellRenderer; 7 | import com.joshjcarrier.minecontrol.ui.controls.renderers.GameTitleWrapperListCellRenderer; 8 | import com.joshjcarrier.minecontrol.ui.models.GamePadWrapper; 9 | import com.joshjcarrier.minecontrol.ui.models.GameTitleWrapper; 10 | 11 | import javax.swing.*; 12 | import javax.swing.border.MatteBorder; 13 | import java.awt.*; 14 | import java.awt.event.ActionEvent; 15 | import java.awt.event.ActionListener; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.Random; 19 | 20 | /** 21 | * The main view. 22 | * @author joshjcarrier 23 | * 24 | */ 25 | public class MainView extends JFrame 26 | { 27 | private static final long serialVersionUID = -46316333717547118L; 28 | 29 | public MainView(final MainController mainController) 30 | { 31 | this.setTitle(AppInfo.ProductName); 32 | 33 | ImageIcon icon = new ImageIcon(this.getClass().getClassLoader().getResource(ContentResources.INPUTDEVICE_XBOX_ONE)); 34 | this.setIconImage(icon.getImage()); 35 | 36 | JPanel contentPanel = createContentPanel(mainController); 37 | contentPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 0)); 38 | this.add(contentPanel); 39 | 40 | this.setResizable(false); 41 | this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 42 | this.pack(); 43 | } 44 | 45 | private static JPanel createContentPanel(final MainController mainController) 46 | { 47 | JPanel contentPanel = new JPanel(new GridBagLayout()); 48 | GridBagConstraints gridConstraints = new GridBagConstraints(); 49 | gridConstraints.fill = GridBagConstraints.HORIZONTAL; 50 | 51 | MatteBorder panelBorder = BorderFactory.createMatteBorder(1, 0, 0, 0, Color.LIGHT_GRAY); 52 | 53 | JPanel gameTitleSelectionPanel = createGameTitleSelectionPanel(); 54 | gameTitleSelectionPanel.setBorder(BorderFactory.createTitledBorder(panelBorder, "MODE")); 55 | gridConstraints.gridx = 0; 56 | gridConstraints.gridy = 0; 57 | contentPanel.add(gameTitleSelectionPanel, gridConstraints); 58 | 59 | JPanel controllerSelectionPanel = createControllerSelectionPanel(mainController); 60 | controllerSelectionPanel.setBorder(BorderFactory.createTitledBorder(panelBorder, "DEVICE")); 61 | gridConstraints.gridx = 0; 62 | gridConstraints.gridy = 1; 63 | contentPanel.add(controllerSelectionPanel, gridConstraints); 64 | 65 | JPanel profilePanel = createProfilePanel(mainController); 66 | profilePanel.setBorder(BorderFactory.createTitledBorder(panelBorder, "PROFILE")); 67 | gridConstraints.gridx = 0; 68 | gridConstraints.gridy = 2; 69 | contentPanel.add(profilePanel, gridConstraints); 70 | 71 | JPanel footerPanel = createFooterPanel(); 72 | footerPanel.setBorder(BorderFactory.createEmptyBorder(6, 4, 0, 4)); 73 | gridConstraints.gridx = 0; 74 | gridConstraints.gridy = 3; 75 | contentPanel.add(footerPanel, gridConstraints); 76 | 77 | return contentPanel; 78 | } 79 | 80 | private static JPanel createGameTitleSelectionPanel() 81 | { 82 | JPanel panel = new JPanel(new GridLayout(1, 1)); 83 | 84 | ArrayList gameTitles = new ArrayList(); 85 | Random rand = new Random(System.currentTimeMillis()); 86 | int meatloaf = rand.nextInt(10); 87 | if (meatloaf == 0) 88 | { 89 | gameTitles.add(new GameTitleWrapper("Mincecraft", "Mojang Specifications", "mincecraft")); 90 | } 91 | else 92 | { 93 | gameTitles.add(new GameTitleWrapper("Minecraft", "Mojang Specifications", "minecraft")); 94 | } 95 | 96 | final JComboBox gameTitlesComboBox = new JComboBox(gameTitles.toArray()); 97 | GameTitleWrapperListCellRenderer gameTileListCellRenderer = new GameTitleWrapperListCellRenderer(); 98 | gameTileListCellRenderer.setPreferredSize(new Dimension(300, 35)); 99 | gameTitlesComboBox.setRenderer(gameTileListCellRenderer); 100 | 101 | panel.add(gameTitlesComboBox); 102 | 103 | return panel; 104 | } 105 | 106 | private static JPanel createControllerSelectionPanel(final MainController mainController) 107 | { 108 | JPanel panel = new JPanel(new GridLayout(1, 1)); 109 | 110 | List gamePads = mainController.getGamePads(); 111 | final JComboBox controllersComboBox = new JComboBox(gamePads.toArray()); 112 | GamePadWrapperListCellRenderer inputReaderDeviceListCellRenderer = new GamePadWrapperListCellRenderer(); 113 | inputReaderDeviceListCellRenderer.setPreferredSize(new Dimension(300, 35)); 114 | controllersComboBox.setRenderer(inputReaderDeviceListCellRenderer); 115 | controllersComboBox.addActionListener(new ActionListener() 116 | { 117 | public void actionPerformed(ActionEvent event) 118 | { 119 | GamePadWrapper gamePad = (GamePadWrapper)controllersComboBox.getSelectedItem(); 120 | mainController.setActiveGamePad(gamePad); 121 | } 122 | }); 123 | 124 | panel.add(controllersComboBox); 125 | 126 | // fire initial selection logic 127 | if(controllersComboBox.getItemCount() > 0) 128 | { 129 | controllersComboBox.setSelectedIndex(0); 130 | } 131 | 132 | // default gamepad selection 133 | for (GamePadWrapper device : gamePads) 134 | { 135 | if (device.getName().toLowerCase().contains("xbox")) 136 | { 137 | controllersComboBox.setSelectedItem(device); 138 | break; 139 | } 140 | } 141 | 142 | return panel; 143 | } 144 | 145 | private static JPanel createProfilePanel(final MainController mainController) 146 | { 147 | JPanel panel = new JPanel(new GridBagLayout()); 148 | GridBagConstraints gridConstraints = new GridBagConstraints(); 149 | gridConstraints.fill = GridBagConstraints.HORIZONTAL; 150 | 151 | JComboBox profilesComboBox = new JComboBox(mainController.getActiveGamePad().getProfiles().toArray()); 152 | gridConstraints.gridx = 0; 153 | gridConstraints.weightx = 1; 154 | gridConstraints.insets = new Insets(0, 0, 0, 10); 155 | panel.add(profilesComboBox, gridConstraints); 156 | 157 | JButton configurationButton = new JButton("Configure"); 158 | configurationButton.addActionListener(new ActionListener() 159 | { 160 | public void actionPerformed(ActionEvent event) 161 | { 162 | GamePadProfileView view = mainController.navigateToGamePadProfile(); 163 | if (view != null) { 164 | view.setModal(true); 165 | view.setVisible(true); 166 | } 167 | } 168 | }); 169 | 170 | gridConstraints.gridx = 1; 171 | gridConstraints.weightx = 0; 172 | gridConstraints.insets = new Insets(0, 0, 0, 0); 173 | panel.add(configurationButton, gridConstraints); 174 | 175 | return panel; 176 | } 177 | 178 | private static JPanel createFooterPanel() 179 | { 180 | JPanel panel = new JPanel(new GridBagLayout()); 181 | GridBagConstraints gridConstraints = new GridBagConstraints(); 182 | 183 | JLabel copyrightLabel = new JLabel("v" + AppInfo.BuildVersion + ". 2014 Josh Carrier "); 184 | copyrightLabel.setFont(new Font("Verdana", Font.PLAIN, 10)); 185 | copyrightLabel.setForeground(Color.DARK_GRAY); 186 | panel.add(copyrightLabel, gridConstraints); 187 | 188 | JButton aboutButton = new JButton(":)"); 189 | aboutButton.setToolTipText("About " + AppInfo.ProductName); 190 | aboutButton.addActionListener(new ActionListener() 191 | { 192 | public void actionPerformed(ActionEvent event) 193 | { 194 | AboutView aboutView = new AboutView(); 195 | aboutView.setModal(true); 196 | aboutView.setVisible(true); 197 | } 198 | }); 199 | panel.add(aboutButton); 200 | 201 | return panel; 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/rxautomation/methods/DiscreteDelegateAutomationMethod.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.rxautomation.methods; 2 | 3 | import com.joshjcarrier.rxautomation.persistence.*; 4 | 5 | public class DiscreteDelegateAutomationMethod implements IAutomationMethod { 6 | private final static String METHOD_ID = "discrete-delegate"; 7 | private final static String PRIMARY_ID = "primary"; 8 | private final static String SECONDARY_ID = "secondary"; 9 | private final static String TERTIARY_ID = "tertiary"; 10 | private final static String QUATERNARY_ID = "quaternary"; 11 | 12 | private final IAutomationMethod primaryAutomationMethod; 13 | private final IAutomationMethod secondaryAutomationMethod; 14 | private final IAutomationMethod tertiaryAutomationMethod; 15 | private final IAutomationMethod quaternaryAutomationMethod; 16 | 17 | public DiscreteDelegateAutomationMethod( 18 | IAutomationMethod primaryAutomationMethod, 19 | IAutomationMethod secondaryAutomationMethod, 20 | IAutomationMethod tertiaryAutomationMethod, 21 | IAutomationMethod quaternaryAutomationMethod) { 22 | 23 | this.primaryAutomationMethod = primaryAutomationMethod; 24 | this.secondaryAutomationMethod = secondaryAutomationMethod; 25 | this.tertiaryAutomationMethod = tertiaryAutomationMethod; 26 | this.quaternaryAutomationMethod = quaternaryAutomationMethod; 27 | } 28 | 29 | public DiscreteDelegateAutomationMethod( 30 | IAutomationMethod primaryAutomationMethod, 31 | IAutomationMethod secondaryAutomationMethod) 32 | { 33 | this(primaryAutomationMethod, secondaryAutomationMethod, primaryAutomationMethod, primaryAutomationMethod); 34 | } 35 | 36 | public static IAutomationMethod load(IAutomationReader automationReader) { 37 | try { 38 | String methodId = automationReader.readMethod(); 39 | if(!methodId.equalsIgnoreCase(METHOD_ID)) { 40 | return null; 41 | } 42 | 43 | IAutomationReader primaryAutomationReader = new NestedAutomationReader(PRIMARY_ID, automationReader); 44 | IAutomationMethod primaryAutomationMethod = AutomationMethodFactory.load(primaryAutomationReader); 45 | 46 | IAutomationReader secondaryAutomationReader = new NestedAutomationReader(SECONDARY_ID, automationReader); 47 | IAutomationMethod secondaryAutomationMethod = AutomationMethodFactory.load(secondaryAutomationReader); 48 | if(primaryAutomationMethod == null || secondaryAutomationMethod == null) { 49 | return null; 50 | } 51 | 52 | IAutomationReader tertiaryAutomationReader = new NestedAutomationReader(TERTIARY_ID, automationReader); 53 | IAutomationMethod tertiaryAutomationMethod = AutomationMethodFactory.load(tertiaryAutomationReader); 54 | if (tertiaryAutomationMethod == null) { 55 | tertiaryAutomationMethod = primaryAutomationMethod; 56 | } 57 | 58 | IAutomationReader quaternaryAutomationReader = new NestedAutomationReader(QUATERNARY_ID, automationReader); 59 | IAutomationMethod quaternaryAutomationMethod = AutomationMethodFactory.load(quaternaryAutomationReader); 60 | if (quaternaryAutomationMethod == null) { 61 | quaternaryAutomationMethod = primaryAutomationMethod; 62 | } 63 | 64 | return new DiscreteDelegateAutomationMethod(primaryAutomationMethod, secondaryAutomationMethod, tertiaryAutomationMethod, quaternaryAutomationMethod); 65 | } catch (Exception e) { 66 | return null; 67 | } 68 | } 69 | 70 | public IAutomationMethod getPrimaryAutomationMethod() { 71 | return this.primaryAutomationMethod; 72 | } 73 | 74 | public IAutomationMethod getSecondaryAutomationMethod() { 75 | return this.secondaryAutomationMethod; 76 | } 77 | 78 | public IAutomationMethod getTertiaryAutomationMethod() { 79 | return this.tertiaryAutomationMethod; 80 | } 81 | 82 | public IAutomationMethod getQuaternaryAutomationMethod() { 83 | return this.quaternaryAutomationMethod; 84 | } 85 | 86 | @Override 87 | public void automate(Float value) { 88 | if (value == 1f) { 89 | this.secondaryAutomationMethod.automate(0f); 90 | 91 | if (this.tertiaryAutomationMethod != null) { 92 | this.tertiaryAutomationMethod.automate(0f); 93 | } 94 | 95 | if (this.quaternaryAutomationMethod != null) { 96 | this.quaternaryAutomationMethod.automate(0f); 97 | } 98 | 99 | this.primaryAutomationMethod.automate(1f); 100 | } else if (value == -1f || (this.secondaryAutomationMethod != this.primaryAutomationMethod && value == 0.25f)) { 101 | this.primaryAutomationMethod.automate(0f); 102 | 103 | if (this.tertiaryAutomationMethod != null) { 104 | this.tertiaryAutomationMethod.automate(0f); 105 | } 106 | 107 | if (this.quaternaryAutomationMethod != null) { 108 | this.quaternaryAutomationMethod.automate(0f); 109 | } 110 | 111 | this.secondaryAutomationMethod.automate(1f); 112 | } else if (this.tertiaryAutomationMethod != this.primaryAutomationMethod && value == 0.5f) { 113 | this.primaryAutomationMethod.automate(0f); 114 | this.secondaryAutomationMethod.automate(0f); 115 | 116 | if (this.quaternaryAutomationMethod != null) { 117 | this.quaternaryAutomationMethod.automate(0f); 118 | } 119 | 120 | if (this.tertiaryAutomationMethod != null) { 121 | this.tertiaryAutomationMethod.automate(1f); 122 | } 123 | } else if (this.quaternaryAutomationMethod != this.primaryAutomationMethod && value == 0.75f) { 124 | this.primaryAutomationMethod.automate(0f); 125 | this.secondaryAutomationMethod.automate(0f); 126 | 127 | if (this.tertiaryAutomationMethod != null) { 128 | this.tertiaryAutomationMethod.automate(0f); 129 | } 130 | 131 | if (this.quaternaryAutomationMethod != null) { 132 | this.quaternaryAutomationMethod.automate(1f); 133 | } 134 | } else { 135 | this.primaryAutomationMethod.automate(0f); 136 | this.secondaryAutomationMethod.automate(0f); 137 | 138 | if (this.tertiaryAutomationMethod != null) { 139 | this.tertiaryAutomationMethod.automate(0f); 140 | } 141 | 142 | if (this.quaternaryAutomationMethod != null) { 143 | this.quaternaryAutomationMethod.automate(0f); 144 | } 145 | } 146 | } 147 | 148 | @Override 149 | public String getName() { 150 | return this.primaryAutomationMethod.getName() 151 | + "+" + this.secondaryAutomationMethod.getName() 152 | + "+" + this.tertiaryAutomationMethod.getName() 153 | + "+" + this.quaternaryAutomationMethod.getName(); 154 | } 155 | 156 | @Override 157 | public void write(IAutomationWriter automationWriter) { 158 | automationWriter.writeMethod(METHOD_ID); 159 | IAutomationWriter primaryNestedAutomationWriter = new NestedAutomationWriter(PRIMARY_ID, automationWriter); 160 | this.primaryAutomationMethod.write(primaryNestedAutomationWriter); 161 | 162 | IAutomationWriter secondaryNestedAutomationWriter = new NestedAutomationWriter(SECONDARY_ID, automationWriter); 163 | this.secondaryAutomationMethod.write(secondaryNestedAutomationWriter); 164 | 165 | if (this.tertiaryAutomationMethod != this.primaryAutomationMethod) { 166 | IAutomationWriter tertiaryNestedAutomationWriter = new NestedAutomationWriter(TERTIARY_ID, automationWriter); 167 | this.tertiaryAutomationMethod.write(tertiaryNestedAutomationWriter); 168 | } 169 | 170 | if (this.quaternaryAutomationMethod != this.primaryAutomationMethod) { 171 | IAutomationWriter quaternaryNestedAutomationWriter = new NestedAutomationWriter(QUATERNARY_ID, automationWriter); 172 | this.quaternaryAutomationMethod.write(quaternaryNestedAutomationWriter); 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/controllers/GamePadProfileController.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.controllers; 2 | 3 | import com.joshjcarrier.minecontrol.AppInfo; 4 | import com.joshjcarrier.minecontrol.framework.input.AutomationBinding; 5 | import com.joshjcarrier.minecontrol.ui.models.AutomationBindingWrapper; 6 | import com.joshjcarrier.minecontrol.ui.models.GamePadProfileWrapper; 7 | import com.joshjcarrier.rxautomation.methods.*; 8 | 9 | import java.awt.event.KeyEvent; 10 | import java.util.*; 11 | 12 | public class GamePadProfileController { 13 | private final GamePadProfileWrapper gamePadProfile; 14 | 15 | public GamePadProfileController(GamePadProfileWrapper gamePadProfile) { 16 | this.gamePadProfile = gamePadProfile; 17 | } 18 | 19 | public List getAutomationBindings() { 20 | List automationBindings = new ArrayList(){ 21 | { 22 | add(new AutomationBinding(new NoOpAutomationMethod())); 23 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_A))); 24 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_B))); 25 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_C))); 26 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_COMMA))); 27 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_CONTROL))); 28 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_D))); 29 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_DELETE))); 30 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_DOWN))); 31 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_E))); 32 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_END))); 33 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_ENTER))); 34 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_ESCAPE))); 35 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F))); 36 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F1))); 37 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F2))); 38 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F3))); 39 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F4))); 40 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F5))); 41 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F6))); 42 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F7))); 43 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F8))); 44 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F9))); 45 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F10))); 46 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F11))); 47 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_F12))); 48 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_G))); 49 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_H))); 50 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_HOME))); 51 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_I))); 52 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_INSERT))); 53 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_J))); 54 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_K))); 55 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_L))); 56 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_LEFT))); 57 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_M))); 58 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_N))); 59 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_O))); 60 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_P))); 61 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_PAGE_DOWN))); 62 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_PAGE_UP))); 63 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_PERIOD))); 64 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_Q))); 65 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_R))); 66 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_RIGHT))); 67 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_S))); 68 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_SHIFT))); 69 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_SPACE))); 70 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_T))); 71 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_TAB))); 72 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_U))); 73 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_UP))); 74 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_V))); 75 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_W))); 76 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_X))); 77 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_Y))); 78 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_Z))); 79 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_1))); 80 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_2))); 81 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_3))); 82 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_4))); 83 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_5))); 84 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_6))); 85 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_7))); 86 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_8))); 87 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_9))); 88 | add(new AutomationBinding(new KeyboardAutomationMethod(KeyEvent.VK_0))); 89 | add(new AutomationBinding(new MouseButtonAutomationMethod(KeyEvent.BUTTON1_MASK))); 90 | add(new AutomationBinding(new MouseButtonAutomationMethod(KeyEvent.BUTTON2_MASK))); 91 | add(new AutomationBinding(new MouseButtonAutomationMethod(KeyEvent.BUTTON3_MASK))); 92 | add(new AutomationBinding(new MouseWheelAutomationMethod(-1))); 93 | add(new AutomationBinding(new MouseWheelAutomationMethod(1))); 94 | add(new AutomationBinding(new SensitivityAppAutomationMethod())); 95 | } 96 | }; 97 | 98 | List automationBindingWrappers = new ArrayList(); 99 | for(AutomationBinding automationBinding : automationBindings) { 100 | automationBindingWrappers.add(new AutomationBindingWrapper(automationBinding)); 101 | } 102 | 103 | return automationBindingWrappers; 104 | } 105 | 106 | public GamePadProfileWrapper getGamePadProfile() { 107 | return this.gamePadProfile; 108 | } 109 | 110 | public String getTitle() { 111 | return AppInfo.ProductName + " - Controller profile \"" + this.gamePadProfile.getName() + "\""; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/framework/profiles/GamePadProfile.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.framework.profiles; 2 | 3 | import com.joshjcarrier.Pair; 4 | import com.joshjcarrier.persistence.IStorage; 5 | import com.joshjcarrier.rxautomation.methods.*; 6 | import com.joshjcarrier.rxautomation.persistence.AutomationReader; 7 | import com.joshjcarrier.rxautomation.persistence.AutomationWriter; 8 | import com.joshjcarrier.rxautomation.persistence.IAutomationReader; 9 | import com.joshjcarrier.rxautomation.persistence.IAutomationWriter; 10 | import com.joshjcarrier.rxautomation.projection.*; 11 | import com.joshjcarrier.rxgamepad.RxGamePad; 12 | import net.java.games.input.Component; 13 | import rx.Observable; 14 | import rx.Subscription; 15 | import rx.util.functions.Action1; 16 | 17 | import java.awt.event.KeyEvent; 18 | import java.util.ArrayList; 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | public class GamePadProfile { 23 | private final String name; 24 | private final RxGamePad rxGamePad; 25 | private final IStorage storage; 26 | 27 | private Subscription activeSubscription; 28 | private MouseMoveAutomationRunner mouseMoveAutomationRunner = new MouseMoveAutomationRunner(); 29 | private IMouseProfile primaryMouseProfile; 30 | private IMouseProfile secondaryMouseProfile; 31 | 32 | public GamePadProfile(String name, RxGamePad rxGamePad, IStorage storage){ 33 | this.name = name; 34 | this.rxGamePad = rxGamePad; 35 | this.storage = storage; 36 | this.primaryMouseProfile = new PrimaryMouseProfile(name, storage); 37 | this.secondaryMouseProfile = new SecondaryMouseProfile(name, storage); 38 | 39 | // TODO move and terminate thread elsewhere 40 | Thread t = new Thread(mouseMoveAutomationRunner); 41 | t.start(); 42 | } 43 | 44 | public Observable> getKeyEvents() { 45 | ArrayList>> keyEvents = new ArrayList>>(); 46 | 47 | for(Map.Entry entry : automationMethodHashMap.entrySet()) { 48 | 49 | IRxAutomationProjection projector = identifierToProjectionMap.get(entry.getKey()); 50 | Observable> keyEvent = projector.map(entry.getValue(), this.rxGamePad.getComponentById(entry.getKey())); 51 | keyEvents.add(keyEvent); 52 | } 53 | 54 | return Observable.merge(keyEvents); 55 | } 56 | 57 | public void activate(){ 58 | if(this.activeSubscription != null && !this.activeSubscription.isUnsubscribed()) { 59 | return; 60 | } 61 | 62 | this.activeSubscription = getKeyEvents().subscribe(new Action1>() { 63 | @Override 64 | public void call(Pair iAutomationMethodFloatPair) { 65 | iAutomationMethodFloatPair.getKey().automate(iAutomationMethodFloatPair.getValue()); 66 | } 67 | }); 68 | } 69 | 70 | public void deactivate() { 71 | if(this.activeSubscription != null) { 72 | this.activeSubscription.unsubscribe(); 73 | } 74 | } 75 | 76 | public IAutomationMethod getAutomationMethod(Component.Identifier identifier) { 77 | IAutomationMethod method = this.automationMethodHashMap.get(identifier); 78 | if(method == null) { 79 | method = new NoOpAutomationMethod(); 80 | this.automationMethodHashMap.put(identifier, method); 81 | this.identifierToProjectionMap.put(identifier, new PassThruRxAutomationProjection()); 82 | } 83 | 84 | return method; 85 | } 86 | 87 | public IRxAutomationProjection getAutomationProjection(Component.Identifier identifier) { 88 | IRxAutomationProjection projection = this.identifierToProjectionMap.get(identifier); 89 | if(projection == null) { 90 | projection = new PassThruRxAutomationProjection(); 91 | this.identifierToProjectionMap.put(identifier, projection); 92 | } 93 | 94 | return projection; 95 | } 96 | 97 | public HashMap getGamePadButtonLabels() { 98 | return this.rxGamePad.getButtonLabels(); 99 | } 100 | 101 | public String getName() { 102 | return this.name; 103 | } 104 | 105 | public IMouseProfile getPrimaryMouseProfile() { 106 | return this.primaryMouseProfile; 107 | } 108 | 109 | public IMouseProfile getSecondaryMouseProfile() { 110 | return this.secondaryMouseProfile; 111 | } 112 | 113 | public void restore() { 114 | for(Map.Entry identifierAutomationMethodEntry : this.automationMethodHashMap.entrySet()) { 115 | IAutomationReader automationReader = new AutomationReader(getName(), "bind." + identifierAutomationMethodEntry.getKey().toString(), this.storage); 116 | 117 | IAutomationMethod automationMethod = AutomationMethodFactory.load(automationReader); 118 | 119 | if(automationMethod != null) { 120 | this.automationMethodHashMap.put(identifierAutomationMethodEntry.getKey(), automationMethod); 121 | } 122 | } 123 | 124 | for(Map.Entry identifierAutomationProjection : this.identifierToProjectionMap.entrySet()) { 125 | IAutomationReader automationReader = new AutomationReader(getName(), "bind." + identifierAutomationProjection.getKey().toString(), this.storage); 126 | 127 | // chain of command 128 | IRxAutomationProjection automationProjection = BinaryRxAutomationProjection.load(automationReader); 129 | 130 | if(automationProjection == null) { 131 | automationProjection = BufferedSwitchRxAutomationProjection.load(automationReader); 132 | } 133 | 134 | if(automationProjection == null) { 135 | automationProjection = ActionPotentialRxAutomationProjection.load(automationReader); 136 | } 137 | 138 | if(automationProjection == null) { 139 | automationProjection = PassThruRxAutomationProjection.load(automationReader); 140 | } 141 | 142 | if(automationProjection != null) { 143 | this.identifierToProjectionMap.put(identifierAutomationProjection.getKey(), automationProjection); 144 | } 145 | } 146 | } 147 | 148 | public void save() { 149 | for(Map.Entry identifierAutomationMethodEntry : this.automationMethodHashMap.entrySet()) { 150 | IAutomationWriter writer = new AutomationWriter(getName(), "bind." + identifierAutomationMethodEntry.getKey().toString(), this.storage); 151 | identifierAutomationMethodEntry.getValue().write(writer); 152 | 153 | IRxAutomationProjection projection = getAutomationProjection(identifierAutomationMethodEntry.getKey()); 154 | projection.write(writer); 155 | } 156 | 157 | this.storage.commit(); 158 | } 159 | 160 | public void setAutomationMethod(Component.Identifier identifier, IAutomationMethod automationMethod) { 161 | this.automationMethodHashMap.put(identifier, automationMethod); 162 | deactivate(); 163 | activate(); 164 | save(); 165 | } 166 | 167 | public void setAutomationProjection(Component.Identifier identifier, IRxAutomationProjection automationProjection) { 168 | this.identifierToProjectionMap.put(identifier, automationProjection); 169 | deactivate(); 170 | activate(); 171 | save(); 172 | } 173 | 174 | private HashMap identifierToProjectionMap = new HashMap() 175 | { 176 | public static final long serialVersionUID = 8658388604108766926L; 177 | { 178 | put(Component.Identifier.Button._0, new PassThruRxAutomationProjection()); 179 | put(Component.Identifier.Button._1, new PassThruRxAutomationProjection()); 180 | put(Component.Identifier.Button._2, new PassThruRxAutomationProjection()); 181 | put(Component.Identifier.Button._3, new PassThruRxAutomationProjection()); 182 | put(Component.Identifier.Button._4, new PassThruRxAutomationProjection()); 183 | put(Component.Identifier.Button._5, new PassThruRxAutomationProjection()); 184 | put(Component.Identifier.Button._6, new PassThruRxAutomationProjection()); 185 | put(Component.Identifier.Button._7, new PassThruRxAutomationProjection()); 186 | put(Component.Identifier.Button._8, new BufferedSwitchRxAutomationProjection()); 187 | put(Component.Identifier.Button._9, new PassThruRxAutomationProjection()); 188 | 189 | put(Component.Identifier.Axis.RX, new BinaryRxAutomationProjection()); 190 | put(Component.Identifier.Axis.RY, new BinaryRxAutomationProjection()); 191 | 192 | put(Component.Identifier.Axis.X, new BinaryRxAutomationProjection()); 193 | put(Component.Identifier.Axis.Y, new BinaryRxAutomationProjection()); 194 | put(Component.Identifier.Axis.Z, new ActionPotentialRxAutomationProjection()); 195 | 196 | put(Component.Identifier.Axis.POV, new PassThruRxAutomationProjection()); 197 | } 198 | }; 199 | 200 | private HashMap automationMethodHashMap = new HashMap() 201 | { 202 | public static final long serialVersionUID = 4658388604108766926L; 203 | { 204 | put(Component.Identifier.Button._0, new KeyboardAutomationMethod(KeyEvent.VK_SPACE)); 205 | put(Component.Identifier.Button._1, new KeyboardAutomationMethod(KeyEvent.VK_Q)); 206 | put(Component.Identifier.Button._2, new MouseButtonAutomationMethod(KeyEvent.BUTTON2_MASK)); 207 | put(Component.Identifier.Button._3, new KeyboardAutomationMethod(KeyEvent.VK_E)); 208 | put(Component.Identifier.Button._4, new MouseWheelAutomationMethod(-1)); 209 | put(Component.Identifier.Button._5, new MouseWheelAutomationMethod(1)); 210 | put(Component.Identifier.Button._6, new SensitivityAppAutomationMethod()); 211 | put(Component.Identifier.Button._7, new KeyboardAutomationMethod(KeyEvent.VK_ESCAPE)); 212 | put(Component.Identifier.Button._8, new KeyboardAutomationMethod(KeyEvent.VK_SHIFT)); 213 | put(Component.Identifier.Button._9, new KeyboardAutomationMethod(KeyEvent.VK_SPACE)); 214 | 215 | put(Component.Identifier.Axis.RX, mouseMoveAutomationRunner.getXAutomationMethod()); 216 | put(Component.Identifier.Axis.RY, mouseMoveAutomationRunner.getYAutomationMethod()); 217 | 218 | put(Component.Identifier.Axis.X, new DiscreteDelegateAutomationMethod(new KeyboardAutomationMethod(KeyEvent.VK_D), new KeyboardAutomationMethod(KeyEvent.VK_A))); 219 | put(Component.Identifier.Axis.Y, new DiscreteDelegateAutomationMethod(new KeyboardAutomationMethod(KeyEvent.VK_S), new KeyboardAutomationMethod(KeyEvent.VK_W))); 220 | put(Component.Identifier.Axis.Z, new DiscreteDelegateAutomationMethod(new MouseButtonAutomationMethod(KeyEvent.BUTTON3_MASK), new MouseButtonAutomationMethod(KeyEvent.BUTTON1_MASK))); 221 | 222 | put(Component.Identifier.Axis.POV, new DiscreteDelegateAutomationMethod( 223 | new KeyboardAutomationMethod(KeyEvent.VK_TAB), 224 | new KeyboardAutomationMethod(KeyEvent.VK_F5), 225 | new KeyboardAutomationMethod(KeyEvent.VK_F3), 226 | new KeyboardAutomationMethod(KeyEvent.VK_F2))); 227 | } 228 | }; 229 | } 230 | -------------------------------------------------------------------------------- /src/com/joshjcarrier/minecontrol/ui/views/GamePadProfileView.java: -------------------------------------------------------------------------------- 1 | package com.joshjcarrier.minecontrol.ui.views; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Font; 5 | import java.awt.GridBagConstraints; 6 | import java.awt.GridBagLayout; 7 | import java.awt.GridLayout; 8 | import java.awt.Image; 9 | import java.awt.Insets; 10 | import java.awt.event.ActionEvent; 11 | import java.net.URL; 12 | import java.util.*; 13 | 14 | import javax.swing.BorderFactory; 15 | import javax.swing.ImageIcon; 16 | import javax.swing.JButton; 17 | import javax.swing.JCheckBox; 18 | import javax.swing.JDialog; 19 | import javax.swing.JLabel; 20 | import javax.swing.JPanel; 21 | import javax.swing.JSlider; 22 | import javax.swing.JTabbedPane; 23 | import javax.swing.border.Border; 24 | import javax.swing.event.ChangeEvent; 25 | import javax.swing.event.ChangeListener; 26 | 27 | import com.joshjcarrier.minecontrol.framework.input.AutomationBinding; 28 | import com.joshjcarrier.minecontrol.ui.ContentResources; 29 | import com.joshjcarrier.minecontrol.ui.actions.SimpleAction; 30 | import com.joshjcarrier.minecontrol.ui.controllers.GamePadProfileController; 31 | import com.joshjcarrier.minecontrol.ui.controls.AutomationBindingsControl; 32 | import com.joshjcarrier.minecontrol.ui.controls.ButtonDescriptorPanel; 33 | import com.joshjcarrier.minecontrol.ui.models.AutomationBindingWrapper; 34 | import com.joshjcarrier.minecontrol.ui.models.GamePadProfileWrapper; 35 | import com.joshjcarrier.minecontrol.ui.models.MouseProfileWrapper; 36 | import com.joshjcarrier.rxautomation.methods.DiscreteDelegateAutomationMethod; 37 | import com.joshjcarrier.rxautomation.methods.IAutomationMethod; 38 | import net.java.games.input.Component; 39 | import rx.util.functions.Action0; 40 | import rx.util.functions.Action1; 41 | 42 | public class GamePadProfileView extends JDialog 43 | { 44 | private static final long serialVersionUID = -424815020280281748L; 45 | 46 | public GamePadProfileView(GamePadProfileController gamePadProfileController) 47 | { 48 | setTitle(gamePadProfileController.getTitle()); 49 | 50 | ImageIcon icon = new ImageIcon(this.getClass().getClassLoader().getResource(ContentResources.INPUTDEVICE_XBOX_ONE)); 51 | this.setIconImage(icon.getImage()); 52 | 53 | Border emptyBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5); 54 | JPanel contentPanel = new JPanel(new GridLayout(1, 1)); 55 | 56 | JTabbedPane tabbedPane = new JTabbedPane(); 57 | 58 | JPanel mappingPanel = createMappingPanel(gamePadProfileController); 59 | mappingPanel.setBorder(emptyBorder); 60 | tabbedPane.addTab("MAPPING", mappingPanel); 61 | 62 | JPanel sensitivityPanel = createSensitivityPanel(gamePadProfileController.getGamePadProfile()); 63 | sensitivityPanel.setBorder(emptyBorder); 64 | tabbedPane.addTab("LOOK/SENSITIVITY", sensitivityPanel); 65 | 66 | contentPanel.add(tabbedPane); 67 | this.add(contentPanel, BorderLayout.CENTER); 68 | 69 | JPanel footerPanel = createFooterPanel(); 70 | footerPanel.setBorder(emptyBorder); 71 | this.add(footerPanel, BorderLayout.SOUTH); 72 | 73 | this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 74 | this.setResizable(false); 75 | this.pack(); 76 | } 77 | 78 | private JPanel createFooterPanel() 79 | { 80 | JPanel panel = new JPanel(new GridBagLayout()); 81 | GridBagConstraints gridConstraints = new GridBagConstraints(); 82 | gridConstraints.fill = GridBagConstraints.BOTH; 83 | 84 | JLabel confirmLabel = new JLabel("Changes automatically save and apply."); 85 | confirmLabel.setFont(new Font("Verdana", Font.ITALIC, 10)); 86 | gridConstraints.gridx = 0; 87 | gridConstraints.weightx = 1; 88 | panel.add(confirmLabel, gridConstraints); 89 | 90 | JButton closeButton = new JButton(); 91 | closeButton.setAction(new SimpleAction() 92 | { 93 | @Override 94 | public void actionPerformed(ActionEvent e) 95 | { 96 | setVisible(false); 97 | dispose(); 98 | } 99 | }); 100 | closeButton.setText("Close"); 101 | gridConstraints.gridx = 1; 102 | gridConstraints.weightx = 0; 103 | gridConstraints.insets = new Insets(0, 10, 0, 0); 104 | panel.add(closeButton, gridConstraints); 105 | 106 | return panel; 107 | } 108 | 109 | private static JPanel createMappingPanel(final GamePadProfileController gamePadProfileController) 110 | { 111 | JPanel panel = new JPanel(new GridBagLayout()); 112 | GridBagConstraints gridConstraints = new GridBagConstraints(); 113 | gridConstraints.fill = GridBagConstraints.BOTH; 114 | gridConstraints.insets = new Insets(5, 0, 0, 0); 115 | 116 | Font headerFont = new Font("Verdana", Font.BOLD, 12); 117 | JLabel controllerHeader = new JLabel("Controller Input"); 118 | controllerHeader.setFont(headerFont); 119 | gridConstraints.gridx = 0; 120 | gridConstraints.gridy = 0; 121 | gridConstraints.weightx = 1; 122 | gridConstraints.ipadx = 60; 123 | panel.add(controllerHeader, gridConstraints); 124 | 125 | JLabel mappingHeader = new JLabel("Mapping"); 126 | mappingHeader.setFont(headerFont); 127 | gridConstraints.gridx = 1; 128 | gridConstraints.gridy = 0; 129 | gridConstraints.weightx = 0; 130 | gridConstraints.ipadx = 0; 131 | panel.add(mappingHeader, gridConstraints); 132 | 133 | List automationBindingWrappers = gamePadProfileController.getAutomationBindings(); 134 | final GamePadProfileWrapper gamePadProfile = gamePadProfileController.getGamePadProfile(); 135 | HashMap gamePadButtonIcons = gamePadProfile.getGamePadButtonIcons(); 136 | List> gamePadLabels = new ArrayList>(gamePadProfile.getGamePadButtonLabels().entrySet()); 137 | Collections.sort(gamePadLabels, new Comparator>() { 138 | @Override 139 | public int compare(Map.Entry identifierStringEntry, Map.Entry identifierStringEntry2) { 140 | return identifierStringEntry.getKey().getName().compareTo(identifierStringEntry2.getKey().getName()); 141 | } 142 | }); 143 | 144 | for (final Map.Entry gamePadButtonLabel : gamePadLabels) 145 | { 146 | // TODO switching on type is bad! non contractual! 147 | IAutomationMethod automationMethod = gamePadProfile.getAutomationMethodBadBadBad(gamePadButtonLabel.getKey()); 148 | if(automationMethod instanceof DiscreteDelegateAutomationMethod) { 149 | DiscreteDelegateAutomationMethod badBadBadAutomationMethod = (DiscreteDelegateAutomationMethod)automationMethod; 150 | 151 | AutomationBindingWrapper primaryAutomationBindingWrapper = new AutomationBindingWrapper(new AutomationBinding(badBadBadAutomationMethod.getPrimaryAutomationMethod())); 152 | gridConstraints.gridy += 1; 153 | gridConstraints.gridx = 0; 154 | panel.add(new ButtonDescriptorPanel(gamePadButtonLabel.getValue() + " left", gamePadButtonIcons.get(gamePadButtonLabel.getKey())), gridConstraints); 155 | 156 | final AutomationBindingsControl primaryAutomationBindingsControl = new AutomationBindingsControl(gamePadProfile.isBufferAutomationProjection(gamePadButtonLabel.getKey()), primaryAutomationBindingWrapper, automationBindingWrappers, false); 157 | primaryAutomationBindingsControl.onBindingChanged(new Action1() { 158 | @Override 159 | public void call(AutomationBindingWrapper selectedAutomationBinding) { 160 | DiscreteDelegateAutomationMethod badAutomationMethod = (DiscreteDelegateAutomationMethod)gamePadProfile.getAutomationMethodBadBadBad(gamePadButtonLabel.getKey()); 161 | 162 | gamePadProfile.setAutomationBinding(gamePadButtonLabel.getKey(), new AutomationBindingWrapper( 163 | new AutomationBinding( 164 | new DiscreteDelegateAutomationMethod( 165 | selectedAutomationBinding.getAutomationBinding().getAutomationMethod(), 166 | badAutomationMethod.getSecondaryAutomationMethod(), 167 | badAutomationMethod.getTertiaryAutomationMethod(), 168 | badAutomationMethod.getQuaternaryAutomationMethod())))); 169 | } 170 | }); 171 | primaryAutomationBindingsControl.onProjectionChanged(new Action1() { 172 | @Override 173 | public void call(Boolean isToggled) { 174 | if (isToggled) { 175 | gamePadProfile.setBufferAutomationProjection(gamePadButtonLabel.getKey()); 176 | } else { 177 | gamePadProfile.setThresholdAutomationProjection(gamePadButtonLabel.getKey()); 178 | } 179 | } 180 | }); 181 | 182 | gridConstraints.gridx = 1; 183 | panel.add(primaryAutomationBindingsControl, gridConstraints); 184 | 185 | AutomationBindingWrapper secondaryAutomationBindingWrapper = new AutomationBindingWrapper(new AutomationBinding(badBadBadAutomationMethod.getSecondaryAutomationMethod())); 186 | gridConstraints.gridy += 1; 187 | gridConstraints.gridx = 0; 188 | panel.add(new ButtonDescriptorPanel(gamePadButtonLabel.getValue() + " up", gamePadButtonIcons.get(gamePadButtonLabel.getKey())), gridConstraints); 189 | 190 | final AutomationBindingsControl secondaryAutomationBindingsControl = new AutomationBindingsControl(gamePadProfile.isBufferAutomationProjection(gamePadButtonLabel.getKey()), secondaryAutomationBindingWrapper, automationBindingWrappers, false); 191 | secondaryAutomationBindingsControl.onBindingChanged(new Action1() { 192 | @Override 193 | public void call(AutomationBindingWrapper selectedAutomationBinding) { 194 | DiscreteDelegateAutomationMethod badAutomationMethod = (DiscreteDelegateAutomationMethod)gamePadProfile.getAutomationMethodBadBadBad(gamePadButtonLabel.getKey()); 195 | 196 | gamePadProfile.setAutomationBinding(gamePadButtonLabel.getKey(), new AutomationBindingWrapper( 197 | new AutomationBinding( 198 | new DiscreteDelegateAutomationMethod( 199 | badAutomationMethod.getPrimaryAutomationMethod(), 200 | selectedAutomationBinding.getAutomationBinding().getAutomationMethod(), 201 | badAutomationMethod.getTertiaryAutomationMethod(), 202 | badAutomationMethod.getQuaternaryAutomationMethod())))); 203 | } 204 | }); 205 | secondaryAutomationBindingsControl.onProjectionChanged(new Action1() { 206 | @Override 207 | public void call(Boolean isToggled) { 208 | if (isToggled) { 209 | gamePadProfile.setBufferAutomationProjection(gamePadButtonLabel.getKey()); 210 | } else { 211 | gamePadProfile.setThresholdAutomationProjection(gamePadButtonLabel.getKey()); 212 | } 213 | } 214 | }); 215 | 216 | gridConstraints.gridx = 1; 217 | panel.add(secondaryAutomationBindingsControl, gridConstraints); 218 | 219 | AutomationBindingWrapper tertiaryAutomationBindingWrapper = new AutomationBindingWrapper(new AutomationBinding(badBadBadAutomationMethod.getTertiaryAutomationMethod())); 220 | gridConstraints.gridy += 1; 221 | gridConstraints.gridx = 0; 222 | panel.add(new ButtonDescriptorPanel(gamePadButtonLabel.getValue() + " right", gamePadButtonIcons.get(gamePadButtonLabel.getKey())), gridConstraints); 223 | 224 | final AutomationBindingsControl tertiaryAutomationBindingsControl = new AutomationBindingsControl(gamePadProfile.isBufferAutomationProjection(gamePadButtonLabel.getKey()), tertiaryAutomationBindingWrapper, automationBindingWrappers, false); 225 | tertiaryAutomationBindingsControl.onBindingChanged(new Action1() { 226 | @Override 227 | public void call(AutomationBindingWrapper selectedAutomationBinding) { 228 | DiscreteDelegateAutomationMethod badAutomationMethod = (DiscreteDelegateAutomationMethod)gamePadProfile.getAutomationMethodBadBadBad(gamePadButtonLabel.getKey()); 229 | 230 | gamePadProfile.setAutomationBinding(gamePadButtonLabel.getKey(), new AutomationBindingWrapper( 231 | new AutomationBinding( 232 | new DiscreteDelegateAutomationMethod( 233 | badAutomationMethod.getPrimaryAutomationMethod(), 234 | badAutomationMethod.getSecondaryAutomationMethod(), 235 | selectedAutomationBinding.getAutomationBinding().getAutomationMethod(), 236 | badAutomationMethod.getQuaternaryAutomationMethod())))); 237 | } 238 | }); 239 | tertiaryAutomationBindingsControl.onProjectionChanged(new Action1() { 240 | @Override 241 | public void call(Boolean isToggled) { 242 | if (isToggled) { 243 | gamePadProfile.setBufferAutomationProjection(gamePadButtonLabel.getKey()); 244 | } else { 245 | gamePadProfile.setThresholdAutomationProjection(gamePadButtonLabel.getKey()); 246 | } 247 | } 248 | }); 249 | 250 | gridConstraints.gridx = 1; 251 | panel.add(tertiaryAutomationBindingsControl, gridConstraints); 252 | 253 | AutomationBindingWrapper quaternaryAutomationBindingWrapper = new AutomationBindingWrapper(new AutomationBinding(badBadBadAutomationMethod.getQuaternaryAutomationMethod())); 254 | gridConstraints.gridy += 1; 255 | gridConstraints.gridx = 0; 256 | panel.add(new ButtonDescriptorPanel(gamePadButtonLabel.getValue() + " down", gamePadButtonIcons.get(gamePadButtonLabel.getKey())), gridConstraints); 257 | 258 | final AutomationBindingsControl quaternaryAutomationBindingsControl = new AutomationBindingsControl(gamePadProfile.isBufferAutomationProjection(gamePadButtonLabel.getKey()), quaternaryAutomationBindingWrapper, automationBindingWrappers, false); 259 | quaternaryAutomationBindingsControl.onBindingChanged(new Action1() { 260 | @Override 261 | public void call(AutomationBindingWrapper selectedAutomationBinding) { 262 | DiscreteDelegateAutomationMethod badAutomationMethod = (DiscreteDelegateAutomationMethod)gamePadProfile.getAutomationMethodBadBadBad(gamePadButtonLabel.getKey()); 263 | 264 | gamePadProfile.setAutomationBinding(gamePadButtonLabel.getKey(), new AutomationBindingWrapper( 265 | new AutomationBinding( 266 | new DiscreteDelegateAutomationMethod( 267 | badAutomationMethod.getPrimaryAutomationMethod(), 268 | badAutomationMethod.getSecondaryAutomationMethod(), 269 | badAutomationMethod.getTertiaryAutomationMethod(), 270 | selectedAutomationBinding.getAutomationBinding().getAutomationMethod())))); 271 | } 272 | }); 273 | quaternaryAutomationBindingsControl.onProjectionChanged(new Action1() { 274 | @Override 275 | public void call(Boolean isToggled) { 276 | if (isToggled) { 277 | gamePadProfile.setBufferAutomationProjection(gamePadButtonLabel.getKey()); 278 | } else { 279 | gamePadProfile.setThresholdAutomationProjection(gamePadButtonLabel.getKey()); 280 | } 281 | } 282 | }); 283 | 284 | gridConstraints.gridx = 1; 285 | panel.add(quaternaryAutomationBindingsControl, gridConstraints); 286 | 287 | continue; 288 | } 289 | 290 | gridConstraints.gridy += 1; 291 | 292 | gridConstraints.gridx = 0; 293 | panel.add(new ButtonDescriptorPanel(gamePadButtonLabel.getValue(), gamePadButtonIcons.get(gamePadButtonLabel.getKey())), gridConstraints); 294 | 295 | final AutomationBindingsControl automationBindingsControl = new AutomationBindingsControl(gamePadProfile.isBufferAutomationProjection(gamePadButtonLabel.getKey()), gamePadProfile.getAutomationBinding(gamePadButtonLabel.getKey()), automationBindingWrappers); 296 | automationBindingsControl.onBindingChanged(new Action1() { 297 | @Override 298 | public void call(AutomationBindingWrapper selectedAutomationBinding) { 299 | gamePadProfile.setAutomationBinding(gamePadButtonLabel.getKey(), selectedAutomationBinding); 300 | } 301 | }); 302 | automationBindingsControl.onProjectionChanged(new Action1() { 303 | @Override 304 | public void call(Boolean isToggled) { 305 | if (isToggled) { 306 | gamePadProfile.setBufferAutomationProjection(gamePadButtonLabel.getKey()); 307 | } else { 308 | gamePadProfile.setThresholdAutomationProjection(gamePadButtonLabel.getKey()); 309 | } 310 | } 311 | }); 312 | 313 | gridConstraints.gridx = 1; 314 | panel.add(automationBindingsControl, gridConstraints); 315 | } 316 | 317 | gridConstraints.gridy = 1; 318 | gridConstraints.gridx = 2; 319 | panel.add(new JLabel(" ")); // REVIEW: real cheap way of adding a spacer between the columns 320 | 321 | JLabel readonlyButtonsHeader = new JLabel("Read-only Mappings"); 322 | readonlyButtonsHeader.setFont(headerFont); 323 | gridConstraints.gridy = 0; 324 | gridConstraints.gridx = 3; 325 | panel.add(readonlyButtonsHeader, gridConstraints); 326 | 327 | gridConstraints.gridy = 1; 328 | gridConstraints.gridx = 3; 329 | panel.add(new ButtonDescriptorPanel("Left joystick: up", ContentResources.BUTTON_XBOX360_LEFTSTICK), gridConstraints); 330 | gridConstraints.gridx = 4; 331 | panel.add(new JLabel("W (pulse mode) [Forward]"), gridConstraints); 332 | 333 | gridConstraints.gridy += 1; 334 | gridConstraints.gridx = 3; 335 | panel.add(new ButtonDescriptorPanel("Left joystick: down", ContentResources.BUTTON_XBOX360_LEFTSTICK), gridConstraints); 336 | gridConstraints.gridx = 4; 337 | panel.add(new JLabel("S (pulse mode) [Back]"), gridConstraints); 338 | 339 | gridConstraints.gridy += 1; 340 | gridConstraints.gridx = 3; 341 | panel.add(new ButtonDescriptorPanel("Left joystick: left", ContentResources.BUTTON_XBOX360_LEFTSTICK), gridConstraints); 342 | gridConstraints.gridx = 4; 343 | panel.add(new JLabel("A (pulse mode) [Left]"), gridConstraints); 344 | 345 | gridConstraints.gridy += 1; 346 | gridConstraints.gridx = 3; 347 | panel.add(new ButtonDescriptorPanel("Left joystick: right", ContentResources.BUTTON_XBOX360_LEFTSTICK), gridConstraints); 348 | gridConstraints.gridx = 4; 349 | panel.add(new JLabel("D (pulse mode) [Right]"), gridConstraints); 350 | 351 | gridConstraints.gridy += 1; 352 | gridConstraints.gridx = 3; 353 | panel.add(new ButtonDescriptorPanel("Right joystick", ContentResources.BUTTON_XBOX360_RIGHTSTICK), gridConstraints); 354 | gridConstraints.gridx = 4; 355 | panel.add(new JLabel("Mouse [Turn/Aim]"), gridConstraints); 356 | 357 | gridConstraints.gridy += 1; 358 | gridConstraints.gridx = 3; 359 | panel.add(new ButtonDescriptorPanel("Left trigger", ContentResources.BUTTON_XBOX360_LEFTTRIGGER), gridConstraints); 360 | gridConstraints.gridx = 4; 361 | panel.add(new JLabel("Mouse right press/release (button 3) [Use item]"), gridConstraints); 362 | 363 | gridConstraints.gridy += 1; 364 | gridConstraints.gridx = 3; 365 | panel.add(new ButtonDescriptorPanel("Right trigger", ContentResources.BUTTON_XBOX360_RIGHTTRIGGER), gridConstraints); 366 | gridConstraints.gridx = 4; 367 | panel.add(new JLabel("Mouse left press/release (button 1) [Attack/Dig]"), gridConstraints); 368 | 369 | return panel; 370 | } 371 | 372 | private static JPanel createSensitivityPanel(final GamePadProfileWrapper gamePadProfile) 373 | { 374 | JPanel panel = new JPanel(new GridBagLayout()); 375 | GridBagConstraints gridConstraints = new GridBagConstraints(); 376 | gridConstraints.fill = GridBagConstraints.HORIZONTAL; 377 | gridConstraints.insets = new Insets(5, 0, 0, 0); 378 | gridConstraints.weightx = 1; 379 | 380 | /* Sliders for look movement sensitivity */ 381 | gridConstraints.gridy = 0; 382 | panel.add(new JLabel("X, Y Look sensitivity (movement mode)"), gridConstraints); 383 | 384 | final MouseProfileWrapper primaryMouseProfile = gamePadProfile.getPrimaryMouseProfile(); 385 | final JSlider lookHorizontalSlider = new JSlider(); 386 | lookHorizontalSlider.setMajorTickSpacing(10); 387 | lookHorizontalSlider.setMinorTickSpacing(1); 388 | lookHorizontalSlider.setPaintTicks(true); 389 | lookHorizontalSlider.setPaintLabels(true); 390 | lookHorizontalSlider.setSnapToTicks(true); 391 | lookHorizontalSlider.setValue(primaryMouseProfile.getSensitivityX()); 392 | lookHorizontalSlider.setToolTipText("Sets how responsive looking left and right in mouse mode 1 (default mode) will be."); 393 | lookHorizontalSlider.setMinimum(0); 394 | lookHorizontalSlider.setMaximum(100); 395 | lookHorizontalSlider.addChangeListener(new ChangeListener() { 396 | public void stateChanged(ChangeEvent e) 397 | { 398 | primaryMouseProfile.setSensitivityX(lookHorizontalSlider.getValue()); 399 | } 400 | }); 401 | 402 | gridConstraints.gridy = 1; 403 | panel.add(lookHorizontalSlider, gridConstraints); 404 | 405 | final JSlider lookVerticalSlider = new JSlider(); 406 | lookVerticalSlider.setMajorTickSpacing(10); 407 | lookVerticalSlider.setMinorTickSpacing(1); 408 | lookVerticalSlider.setPaintTicks(true); 409 | lookVerticalSlider.setPaintLabels(true); 410 | lookVerticalSlider.setSnapToTicks(true); 411 | lookVerticalSlider.setValue(primaryMouseProfile.getSensitivityY()); 412 | lookVerticalSlider.setToolTipText("Sets how responsive looking left and right in mouse mode 1 (default mode) will be."); 413 | lookVerticalSlider.setMinimum(0); 414 | lookVerticalSlider.setMaximum(100); 415 | lookVerticalSlider.addChangeListener(new ChangeListener() { 416 | public void stateChanged(ChangeEvent e) 417 | { 418 | primaryMouseProfile.setSensitivityY(lookVerticalSlider.getValue()); 419 | } 420 | }); 421 | 422 | gridConstraints.gridy = 2; 423 | panel.add(lookVerticalSlider, gridConstraints); 424 | 425 | /* Sliders for mouse movement sensitivity */ 426 | gridConstraints.gridy = 3; 427 | panel.add(new JLabel("X, Y Look sensitivity (mouse mode)"), gridConstraints); 428 | 429 | final MouseProfileWrapper secondaryMouseProfile = gamePadProfile.getSecondaryMouseProfile(); 430 | final JSlider lookMouseHorizontalSlider = new JSlider(); 431 | lookMouseHorizontalSlider.setMajorTickSpacing(5); 432 | lookMouseHorizontalSlider.setMinorTickSpacing(1); 433 | lookMouseHorizontalSlider.setPaintTicks(true); 434 | lookMouseHorizontalSlider.setPaintLabels(true); 435 | lookMouseHorizontalSlider.setSnapToTicks(true); 436 | lookMouseHorizontalSlider.setValue(secondaryMouseProfile.getSensitivityX()); 437 | lookMouseHorizontalSlider.setToolTipText("Sets how responsive looking left and right in mouse mode 2 will be. Enter this mode by mapping a button to \"\"."); 438 | lookMouseHorizontalSlider.setMinimum(0); 439 | lookMouseHorizontalSlider.setMaximum(40); 440 | lookMouseHorizontalSlider.addChangeListener(new ChangeListener() { 441 | public void stateChanged(ChangeEvent e) 442 | { 443 | secondaryMouseProfile.setSensitivityX(lookMouseHorizontalSlider.getValue()); 444 | } 445 | }); 446 | 447 | gridConstraints.gridy = 4; 448 | panel.add(lookMouseHorizontalSlider, gridConstraints); 449 | 450 | final JSlider lookMouseVerticalSlider = new JSlider(); 451 | lookMouseVerticalSlider.setMajorTickSpacing(5); 452 | lookMouseVerticalSlider.setMinorTickSpacing(1); 453 | lookMouseVerticalSlider.setPaintTicks(true); 454 | lookMouseVerticalSlider.setPaintLabels(true); 455 | lookMouseVerticalSlider.setSnapToTicks(true); 456 | lookMouseVerticalSlider.setValue(secondaryMouseProfile.getSensitivityY()); 457 | lookMouseVerticalSlider.setToolTipText("Sets how responsive looking up and down in mouse mode 2 will be. Enter this mode by mapping a button to \"\"."); 458 | lookMouseVerticalSlider.setMinimum(0); 459 | lookMouseVerticalSlider.setMaximum(40); 460 | lookMouseVerticalSlider.addChangeListener(new ChangeListener() { 461 | public void stateChanged(ChangeEvent e) 462 | { 463 | secondaryMouseProfile.setSensitivityY(lookMouseVerticalSlider.getValue()); 464 | } 465 | }); 466 | 467 | gridConstraints.gridy = 5; 468 | panel.add(lookMouseVerticalSlider, gridConstraints); 469 | 470 | final JCheckBox invertPitchCheckBox = new JCheckBox(); 471 | invertPitchCheckBox.setAction(new SimpleAction() { 472 | @Override 473 | public void actionPerformed(ActionEvent e) 474 | { 475 | primaryMouseProfile.setInvertY(invertPitchCheckBox.isSelected()); 476 | } 477 | }); 478 | 479 | invertPitchCheckBox.setText("Invert look up/down"); 480 | invertPitchCheckBox.setToolTipText("When selected, pushing up on the right joystick moves the mouse down."); 481 | invertPitchCheckBox.setSelected(primaryMouseProfile.isInvertY()); 482 | gridConstraints.gridy = 6; 483 | panel.add(invertPitchCheckBox, gridConstraints); 484 | 485 | // filler at bottom 486 | JPanel fillerPanel = new JPanel(); 487 | Random rand = new Random(System.currentTimeMillis()); 488 | int niceSettingsssYouHaveThere = rand.nextInt(4); 489 | if(niceSettingsssYouHaveThere == 0) 490 | { 491 | JLabel iconLabel = new JLabel(); 492 | URL iconUrl = GamePadProfileView.class.getClassLoader().getResource(ContentResources.CHROME_SENSITIVITYPANEL_FILLER); 493 | 494 | ImageIcon icon = new ImageIcon(iconUrl); 495 | Image newimg = icon.getImage().getScaledInstance(120, 120, java.awt.Image.SCALE_SMOOTH); 496 | iconLabel.setIcon(new ImageIcon(newimg)); 497 | fillerPanel.add(iconLabel, BorderLayout.CENTER); 498 | } 499 | 500 | gridConstraints.gridy = 7; 501 | gridConstraints.weighty = 1; 502 | panel.add(fillerPanel, gridConstraints); 503 | 504 | return panel; 505 | } 506 | } 507 | --------------------------------------------------------------------------------