From 11582fd69db8d85b4e9bd861f229ea619210a4bb Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Thu, 17 Oct 2019 00:16:27 +0300 Subject: [PATCH] Effects support added --- pom.xml | 2 +- .../Controllers/EffectsController.java | 83 +++++-- .../java/logiled/Controllers/LoCodepage.java | 227 ------------------ .../logiled/Controllers/MainController.java | 14 +- .../java/logiled/Controllers/RuleBox.java | 121 +++++++++- src/main/java/logiled/MainFx.java | 2 +- src/main/java/logiled/RainbowHexDump.java | 3 + src/main/java/logiled/USB/Communications.java | 225 ----------------- src/main/java/logiled/USB/EffectsThread.java | 145 +++++++++++ src/main/java/logiled/USB/GameModeThread.java | 41 ++++ src/main/java/logiled/USB/KeyLedThread.java | 97 ++++++++ src/main/java/logiled/USB/LoThread.java | 46 ++++ src/main/resources/EffectsPane.fxml | 43 ++-- src/main/resources/locale_rus.properties | 4 +- 14 files changed, 545 insertions(+), 508 deletions(-) delete mode 100644 src/main/java/logiled/Controllers/LoCodepage.java delete mode 100644 src/main/java/logiled/USB/Communications.java create mode 100644 src/main/java/logiled/USB/EffectsThread.java create mode 100644 src/main/java/logiled/USB/GameModeThread.java create mode 100644 src/main/java/logiled/USB/KeyLedThread.java create mode 100644 src/main/java/logiled/USB/LoThread.java diff --git a/pom.xml b/pom.xml index 8c17ad1..c81797d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ loper LogiLed - 0.1-SNAPSHOT + 0.2-SNAPSHOT diff --git a/src/main/java/logiled/Controllers/EffectsController.java b/src/main/java/logiled/Controllers/EffectsController.java index db60126..cddb4e6 100644 --- a/src/main/java/logiled/Controllers/EffectsController.java +++ b/src/main/java/logiled/Controllers/EffectsController.java @@ -6,6 +6,7 @@ import javafx.fxml.Initializable; import javafx.scene.control.*; import java.net.URL; +import java.nio.ByteBuffer; import java.util.HashMap; import java.util.ResourceBundle; @@ -58,13 +59,12 @@ public class EffectsController implements Initializable { mainSlideInfoLbl.setVisible(false); break; case "constRMI": - case "breathRMI": mainClrPkr.setVisible(true); mainSlide.setVisible(false); mainSlideInfoLbl.setVisible(false); break; - case "cycleRMI": - mainClrPkr.setVisible(false); + case "circlesOnPressRMI": + mainClrPkr.setVisible(true); mainSlide.setVisible(true); mainSlideInfoLbl.setVisible(true); mainSlide.setMin(20.0); @@ -73,7 +73,7 @@ public class EffectsController implements Initializable { mainSlide.setBlockIncrement(10.0); mainSlide.setValue(20.0); break; - case "circlesOnPressRMI": + case "breathRMI": mainClrPkr.setVisible(true); mainSlide.setVisible(true); mainSlideInfoLbl.setVisible(true); @@ -83,6 +83,7 @@ public class EffectsController implements Initializable { mainSlide.setBlockIncrement(100.0); mainSlide.setValue(1000.0); break; + case "cycleRMI": case "hWaveFrwRMI": case "vWaveFrwRMI": case "cntrToEdgWaveRMI": @@ -101,49 +102,83 @@ public class EffectsController implements Initializable { } } - public String getEffect(){ + public HashMap getEffect(){ final RadioMenuItem item = (RadioMenuItem) effectsToggleGrp.getSelectedToggle(); - /* - HashMap effectsSet = new HashMap<>(); - byte[] meta; + + final HashMap effectsSet = new HashMap<>(); + + final byte red = (byte) (mainClrPkr.getValue().getRed()*255); + final byte green = (byte) (mainClrPkr.getValue().getGreen()*255); + final byte blue = (byte) (mainClrPkr.getValue().getBlue()*255); + + ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); + buffer.putLong((long) mainSlide.getValue()); + byte[] a = buffer.array(); + byte valHigh = a[6]; // E.g. 1000 = 0x03 0xe8; high = 0x03, low = 0xe8 + byte valLow = a[7]; switch (item.getId()){ case "disRMI": - effectsSet.put(LoEffects.DISABLE, null); + effectsSet.put("EFFECT", LoEffects.DISABLE.getValue()); break; case "constRMI": - effectsSet.put(LoEffects.CONSTANT_COLOR, ); + effectsSet.put("EFFECT", LoEffects.CONSTANT_COLOR.getValue()); + effectsSet.put("RED", red); + effectsSet.put("GREEN", green); + effectsSet.put("BLUE", blue); break; case "breathRMI": - effectsSet.put(LoEffects.BREATH, ); - break; - case "cycleRMI": - effectsSet.put(LoEffects.CYCLE, ); + effectsSet.put("EFFECT", LoEffects.BREATH.getValue()); + effectsSet.put("RED", red); + effectsSet.put("GREEN", green); + effectsSet.put("BLUE", blue); + effectsSet.put("TIME_HIGH", valHigh); + effectsSet.put("TIME_LOW", valLow); break; case "circlesOnPressRMI": - effectsSet.put(LoEffects.CIRCLES_ON_PRESS, ); + effectsSet.put("EFFECT", LoEffects.CIRCLES_ON_PRESS.getValue()); + effectsSet.put("RED", red); + effectsSet.put("GREEN", green); + effectsSet.put("BLUE", blue); + effectsSet.put("TIME_LOW", valLow); + break; + case "cycleRMI": + effectsSet.put("EFFECT", LoEffects.CYCLE.getValue()); + effectsSet.put("TIME_HIGH", valHigh); + effectsSet.put("TIME_LOW", valLow); break; case "hWaveFrwRMI": - effectsSet.put(LoEffects.WAVE_HORIZONTAL_FRW, ); + effectsSet.put("EFFECT", LoEffects.WAVE_HORIZONTAL_FRW.getValue()); + effectsSet.put("TIME_HIGH", valHigh); + effectsSet.put("TIME_LOW", valLow); break; case "vWaveFrwRMI": - effectsSet.put(LoEffects.WAVE_VERTICAL_FRW, ); + effectsSet.put("EFFECT", LoEffects.WAVE_VERTICAL_FRW.getValue()); + effectsSet.put("TIME_HIGH", valHigh); + effectsSet.put("TIME_LOW", valLow); break; case "cntrToEdgWaveRMI": - effectsSet.put(LoEffects.WAVE_CENTER_TO_EDGE, ); + effectsSet.put("EFFECT", LoEffects.WAVE_CENTER_TO_EDGE.getValue()); + effectsSet.put("TIME_HIGH", valHigh); + effectsSet.put("TIME_LOW", valLow); break; case "hWaveBkwRMI": - effectsSet.put(LoEffects.WAVE_HORIZONTAL_BKW, ); + effectsSet.put("EFFECT", LoEffects.WAVE_HORIZONTAL_BKW.getValue()); + effectsSet.put("TIME_HIGH", valHigh); + effectsSet.put("TIME_LOW", valLow); break; case "vWaveBkwRMI": - effectsSet.put(LoEffects.WAVE_VERTICAL_BKW, ); + effectsSet.put("EFFECT", LoEffects.WAVE_VERTICAL_BKW.getValue()); + effectsSet.put("TIME_HIGH", valHigh); + effectsSet.put("TIME_LOW", valLow); break; case "edgToCntrWaveRMI": - effectsSet.put(LoEffects.WAVE_EDGE_TO_CENTER, ); + effectsSet.put("EFFECT", LoEffects.WAVE_EDGE_TO_CENTER.getValue()); + effectsSet.put("TIME_HIGH", valHigh); + effectsSet.put("TIME_LOW", valLow); break; } - */ - //System.out.println(LoEffects.DISABLE.getValue()); - return item.getId(); + + return effectsSet; } } \ No newline at end of file diff --git a/src/main/java/logiled/Controllers/LoCodepage.java b/src/main/java/logiled/Controllers/LoCodepage.java deleted file mode 100644 index 17e732e..0000000 --- a/src/main/java/logiled/Controllers/LoCodepage.java +++ /dev/null @@ -1,227 +0,0 @@ -package logiled.Controllers; -// TODO: rewrite to ENUM -class LoCodepage { - static byte getCode(String id){ - switch (id){ - case "l_game": - return 0x2; - case "l_caps": - return 0x3; - case "k_a": - return 0x4; - case "k_b": - return 0x5; - case "k_c": - return 0x6; - case "k_d": - return 0x7; - case "k_e": - return 0x8; - case "k_f": - return 0x9; - case "k_g": - return 0xA; - case "k_h": - return 0xB; - case "k_i": - return 0xC; - case "k_j": - return 0xD; - case "k_k": - return 0xE; - case "k_l": - return 0xF; - case "k_m": - return 0x10; - case "k_n": - return 0x11; - case "k_o": - return 0x12; - case "k_p": - return 0x13; - case "k_q": - return 0x14; - case "k_r": - return 0x15; - case "k_s": - return 0x16; - case "k_t": - return 0x17; - case "k_u": - return 0x18; - case "k_v": - return 0x19; - case "k_w": - return 0x1A; - case "k_x": - return 0x1B; - case "k_y": - return 0x1C; - case "k_z": - return 0x1D; - case "k_1": - return 0x1E; - case "k_2": - return 0x1F; - case "k_3": - return 0x20; - case "k_4": - return 0x21; - case "k_5": - return 0x22; - case "k_6": - return 0x23; - case "k_7": - return 0x24; - case "k_8": - return 0x25; - case "k_9": - return 0x26; - case "k_0": - return 0x27; - case "k_enter": - return 0x28; - case "k_esc": - return 0x29; - case "k_backspace": - return 0x2a; - case "k_tab": - return 0x2b; - case "k_space": - return 0x2c; - case "k_dash": - return 0x2d; - case "k_equal": - return 0x2e; - case "k_bracket_open": - return 0x2f; - case "k_bracket_close": - return 0x30; - // nothing for 0x31 - case "k_backslash": - return 0x32; // (ISO version only?) - case "k_semicolon": - return 0x33; - case "k_quotation": - return 0x34; - case "k_tilde": - return 0x35; - case "k_comma": - return 0x36; - case "k_dot": - return 0x37; - case "k_shash": - return 0x38; - case "k_caps": - return 0x39; - case "k_f1": - return 0x3a; - case "k_f2": - return 0x3b; - case "k_f3": - return 0x3c; - case "k_f4": - return 0x3d; - case "k_f5": - return 0x3e; - case "k_f6": - return 0x3f; - case "k_f7": - return 0x40; - case "k_f8": - return 0x41; - case "k_f9": - return 0x42; - case "k_f10": - return 0x43; - case "k_f11": - return 0x44; - case "k_f12": - return 0x45; - case "k_prtscr": - return 0x46; - case "k_scrl": - return 0x47; - case "k_pause": - return 0x48; - case "k_ins": - return 0x49; - case "k_home": - return 0x4a; - case "k_pg_up": - return 0x4b; - case "k_del": - return 0x4c; - case "k_end": - return 0x4d; - case "k_pg_dn": - return 0x4e; - case "k_arr_right": - return 0x4f; - case "k_arr_left": - return 0x50; - case "k_arr_down": - return 0x51; - case "k_arr_up": - return 0x52; - case "k_num": - return 0x53; - case "k_num_slash": - return 0x54; - case "k_num_asterisk": - return 0x55; - case "k_num_minus": - return 0x56; - case "k_num_plus": - return 0x57; - /* not confirmed */ - case "k_num_enter": - return 0x58; - case "k_num_1": - return 0x59; - case "k_num_2": - return 0x5a; - case "k_num_3": - return 0x5b; - case "k_num_4": - return 0x5c; - case "k_num_5": - return 0x5d; - case "k_num_6": - return 0x5e; - case "k_num_7": - return 0x5f; - case "k_num_8": - return 0x60; - case "k_num_9": - return 0x61; - case "k_num_0": - return 0x62; - case "k_num_period": - return 0x63; - /*---------------*/ - // nothing for 0x64 (ISO version) - case "k_menu": - return 0x65; - - case "k_l_ctrl": - return (byte) 0xe0; - case "k_l_shift": - return (byte) 0xe1; - case "k_l_alt": - return (byte) 0xe2; - case "k_win": - return (byte) 0xe3; - case "k_r_ctrl": - return (byte) 0xe4; - case "k_r_shift": - return (byte) 0xe5; - case "k_r_alt": - return (byte) 0xe6; - case "k_fn": - return (byte) 0xe7; - default: - return 0x00; // ??? - } - } -} diff --git a/src/main/java/logiled/Controllers/MainController.java b/src/main/java/logiled/Controllers/MainController.java index 8319ed6..18378ac 100644 --- a/src/main/java/logiled/Controllers/MainController.java +++ b/src/main/java/logiled/Controllers/MainController.java @@ -5,7 +5,8 @@ import javafx.fxml.Initializable; import javafx.scene.control.*; import logiled.About.AboutWindow; import logiled.MessagesConsumer; -import logiled.USB.Communications; +import logiled.USB.EffectsThread; +import logiled.USB.KeyLedThread; import java.net.URL; import java.util.HashMap; @@ -34,6 +35,7 @@ public class MainController implements Initializable { @FXML private MenuItem aboutMenuItem; + // TODO: add block & release-button function @Override public void initialize(URL url, ResourceBundle resourceBundle) { @@ -46,14 +48,16 @@ public class MainController implements Initializable { HashMap> rules = KeysLedsController.getRules(); if (rules == null) return; - Communications communications = new Communications(rules); - Thread commThread = new Thread(communications); + KeyLedThread keyLedThread = new KeyLedThread(rules); + Thread commThread = new Thread(keyLedThread); commThread.setDaemon(true); commThread.start(); } else if (MainTabPane.getSelectionModel().getSelectedItem().getId().equals("EffectsTab")) { - // TODO - System.out.println(EffectsController.getEffect()); + EffectsThread effectsThread = new EffectsThread(EffectsController.getEffect()); + Thread commThread = new Thread(effectsThread); + commThread.setDaemon(true); + commThread.start(); } }); } diff --git a/src/main/java/logiled/Controllers/RuleBox.java b/src/main/java/logiled/Controllers/RuleBox.java index 4628680..81560eb 100644 --- a/src/main/java/logiled/Controllers/RuleBox.java +++ b/src/main/java/logiled/Controllers/RuleBox.java @@ -9,8 +9,7 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.paint.Color; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class RuleBox extends HBox { // todo: add class to selected toggle user data; provide interface to add buttons to selected toggle @@ -37,6 +36,120 @@ public class RuleBox extends HBox { // todo: add class to selected toggle user private final ColorPicker colorPicker; private final RadioButton radBtn; + private static final Map LoCodepage; + + static { + Map stMap = new HashMap<>(); + stMap.put("l_game", ((byte) 0x2)); + stMap.put("l_caps",((byte) 0x3)); + stMap.put("k_a",((byte) 0x4)); + stMap.put("k_b",((byte) 0x5)); + stMap.put("k_c",((byte) 0x6)); + stMap.put("k_d",((byte) 0x7)); + stMap.put("k_e",((byte) 0x8)); + stMap.put("k_f",((byte) 0x9)); + stMap.put("k_g",((byte) 0xA)); + stMap.put("k_h",((byte) 0xB)); + stMap.put("k_i",((byte) 0xC)); + stMap.put("k_j",((byte) 0xD)); + stMap.put("k_k",((byte) 0xE)); + stMap.put("k_l",((byte) 0xF)); + stMap.put("k_m",((byte) 0x10)); + stMap.put("k_n",((byte) 0x11)); + stMap.put("k_o",((byte) 0x12)); + stMap.put("k_p",((byte) 0x13)); + stMap.put("k_q",((byte) 0x14)); + stMap.put("k_r",((byte) 0x15)); + stMap.put("k_s",((byte) 0x16)); + stMap.put("k_t",((byte) 0x17)); + stMap.put("k_u",((byte) 0x18)); + stMap.put("k_v",((byte) 0x19)); + stMap.put("k_w",((byte) 0x1A)); + stMap.put("k_x",((byte) 0x1B)); + stMap.put("k_y",((byte) 0x1C)); + stMap.put("k_z",((byte) 0x1D)); + stMap.put("k_1",((byte) 0x1E)); + stMap.put("k_2",((byte) 0x1F)); + stMap.put("k_3",((byte) 0x20)); + stMap.put("k_4",((byte) 0x21)); + stMap.put("k_5",((byte) 0x22)); + stMap.put("k_6",((byte) 0x23)); + stMap.put("k_7",((byte) 0x24)); + stMap.put("k_8",((byte) 0x25)); + stMap.put("k_9",((byte) 0x26)); + stMap.put("k_0",((byte) 0x27)); + stMap.put("k_enter",((byte) 0x28)); + stMap.put("k_esc",((byte) 0x29)); + stMap.put("k_backspace",((byte) 0x2a)); + stMap.put("k_tab",((byte) 0x2b)); + stMap.put("k_space",((byte) 0x2c)); + stMap.put("k_dash",((byte) 0x2d)); + stMap.put("k_equal",((byte) 0x2e)); + stMap.put("k_bracket_open",((byte) 0x2f)); + stMap.put("k_bracket_close",((byte) 0x30)); + stMap.put("k_backslash",((byte) 0x32)); + stMap.put("k_semicolon",((byte) 0x33)); + stMap.put("k_quotation",((byte) 0x34)); + stMap.put("k_tilde",((byte) 0x35)); + stMap.put("k_comma",((byte) 0x36)); + stMap.put("k_dot",((byte) 0x37)); + stMap.put("k_shash",((byte) 0x38)); + stMap.put("k_caps",((byte) 0x39)); + stMap.put("k_f1",((byte) 0x3a)); + stMap.put("k_f2",((byte) 0x3b)); + stMap.put("k_f3",((byte) 0x3c)); + stMap.put("k_f4",((byte) 0x3d)); + stMap.put("k_f5",((byte) 0x3e)); + stMap.put("k_f6",((byte) 0x3f)); + stMap.put("k_f7",((byte) 0x40)); + stMap.put("k_f8",((byte) 0x41)); + stMap.put("k_f9",((byte) 0x42)); + stMap.put("k_f10",((byte) 0x43)); + stMap.put("k_f11",((byte) 0x44)); + stMap.put("k_f12",((byte) 0x45)); + stMap.put("k_prtscr",((byte) 0x46)); + stMap.put("k_scrl",((byte) 0x47)); + stMap.put("k_pause",((byte) 0x48)); + stMap.put("k_ins",((byte) 0x49)); + stMap.put("k_home",((byte) 0x4a)); + stMap.put("k_pg_up",((byte) 0x4b)); + stMap.put("k_del",((byte) 0x4c)); + stMap.put("k_end",((byte) 0x4d)); + stMap.put("k_pg_dn",((byte) 0x4e)); + stMap.put("k_arr_right",((byte) 0x4f)); + stMap.put("k_arr_left",((byte) 0x50)); + stMap.put("k_arr_down",((byte) 0x51)); + stMap.put("k_arr_up",((byte) 0x52)); + stMap.put("k_num",((byte) 0x53)); + stMap.put("k_num_slash",((byte) 0x54)); + stMap.put("k_num_asterisk",((byte) 0x55)); + stMap.put("k_num_minus",((byte) 0x56)); + stMap.put("k_num_plus",((byte) 0x57)); + stMap.put("k_num_enter",((byte) 0x58)); + stMap.put("k_num_1",((byte) 0x59)); + stMap.put("k_num_2",((byte) 0x5a)); + stMap.put("k_num_3",((byte) 0x5b)); + stMap.put("k_num_4",((byte) 0x5c)); + stMap.put("k_num_5",((byte) 0x5d)); + stMap.put("k_num_6",((byte) 0x5e)); + stMap.put("k_num_7",((byte) 0x5f)); + stMap.put("k_num_8",((byte) 0x60)); + stMap.put("k_num_9",((byte) 0x61)); + stMap.put("k_num_0",((byte) 0x62)); + stMap.put("k_num_period",((byte) 0x63)); + stMap.put("k_menu",((byte) 0x65)); + stMap.put("k_l_ctrl",((byte) 0xe0)); + stMap.put("k_l_shift",((byte) 0xe1)); + stMap.put("k_l_alt",((byte) 0xe2)); + stMap.put("k_win",((byte) 0xe3)); + stMap.put("k_r_ctrl",((byte) 0xe4)); + stMap.put("k_r_shift",((byte) 0xe5)); + stMap.put("k_r_alt",((byte) 0xe6)); + stMap.put("k_fn",((byte) 0xe7)); + + LoCodepage = Collections.unmodifiableMap(stMap); + } + public RuleBox(){ super(); Insets insets = new Insets(3.0, 3.0, 3.0, 3.0); @@ -122,7 +235,7 @@ public class RuleBox extends HBox { // todo: add class to selected toggle user if (id.startsWith("l_")) continue; byte[] keyInfo = new byte[4]; // Where 0 - special key/indicator code; 1 - red; 2 - green; 3 - blue - keyInfo[0] = LoCodepage.getCode(id); + keyInfo[0] = LoCodepage.get(id); keyInfo[1] = red; keyInfo[2] = green; keyInfo[3] = blue; @@ -150,7 +263,7 @@ public class RuleBox extends HBox { // todo: add class to selected toggle user if (id.startsWith("k_")) continue; byte[] keyInfo = new byte[4]; // Where 0 - special key/indicator code; 1 - red; 2 - green; 3 - blue - keyInfo[0] = LoCodepage.getCode(id); + keyInfo[0] = LoCodepage.get(id); keyInfo[1] = red; keyInfo[2] = green; keyInfo[3] = blue; diff --git a/src/main/java/logiled/MainFx.java b/src/main/java/logiled/MainFx.java index 5ac05b9..fa08ac9 100644 --- a/src/main/java/logiled/MainFx.java +++ b/src/main/java/logiled/MainFx.java @@ -11,7 +11,7 @@ import java.util.Locale; import java.util.ResourceBundle; public class MainFx extends Application { - public static final String appVersion = "v0.1"; + public static final String appVersion = "v0.2"; @Override public void start(Stage primaryStage) throws Exception{ diff --git a/src/main/java/logiled/RainbowHexDump.java b/src/main/java/logiled/RainbowHexDump.java index 3dd1ec3..9f3985a 100644 --- a/src/main/java/logiled/RainbowHexDump.java +++ b/src/main/java/logiled/RainbowHexDump.java @@ -24,9 +24,12 @@ public class RainbowHexDump { System.out.println(">"+ANSI_RED+byteArray.length+ANSI_RESET); for (byte b: byteArray) System.out.print(String.format("%02x ", b)); + System.out.println(); + /* System.out.print("\t\t\t" + new String(byteArray, StandardCharsets.UTF_8) + "\n"); + */ } public static void hexDumpUTF16LE(byte[] byteArray){ diff --git a/src/main/java/logiled/USB/Communications.java b/src/main/java/logiled/USB/Communications.java deleted file mode 100644 index 47cc89d..0000000 --- a/src/main/java/logiled/USB/Communications.java +++ /dev/null @@ -1,225 +0,0 @@ -package logiled.USB; - -import logiled.MessagesConsumer; -import org.usb4java.DeviceHandle; -import org.usb4java.LibUsb; - -import java.nio.ByteBuffer; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -public class Communications implements Runnable{ - // Keys and indicators individual settings - private static final byte[] commit = { - 0x11, (byte) 0xff, 0x0c, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - - private static final byte[] indicators = { // we have 2 leds on G513 - // KEY RED GRN BLU -//- - 0x12, (byte) 0xff, 0x0c, 0x3a, 0x00, 0x40, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] keys = { // Can store 14 rules - // LED RED GRN BLU -//- - 0x12, (byte) 0xff, 0x0c, 0x3a, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - // -========= Effects =========- - private static final byte[] disable_colors = { - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] constant_color = { - // RED GRN BLU - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] wave_horizontal = { - // !! !! - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] wave_vertical = { - // !! !! - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] wave_center_to_edge = { - // !! !! - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] wave_horizontal_reverse = { - // !! !! - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] wave_vertical_reverse = { - // !! !! - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] wave_edge_to_center = { - // !! !! - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] cycle = { - // !! !! - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] breathe = { - // RED GRN BLU !! !! - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - private static final byte[] cirles_on_press = { - // RED GRN BLU ms - 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - - // Game-key settings - //private static final byte[] game_key_rule - private static final byte[] game_key_set_default = { - 0x11, (byte) 0xff, 0x03, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - - private DeviceHandle handler; - - // What would be sent to keyboard - private List keyLedCommands; - - /** - * Used to set keys & leds - * @param keyLedSet : set of rules, always not empty and not null - * */ - public Communications(HashMap> keyLedSet){ - keyLedCommands = new ArrayList<>(); - - int appendTo = 8; - - byte[] command = Arrays.copyOfRange(indicators, 0, indicators.length); - - for (byte[][] singleRuleSet : keyLedSet.get("Led")){ - for (byte[] keyLedSetting: singleRuleSet) { - System.arraycopy(keyLedSetting, 0, command, appendTo, 4); - appendTo += 4; - } - } - - if (appendTo > 8) { - keyLedCommands.add(Arrays.copyOfRange(command, 0, command.length)); - appendTo = 8; - } - - command = Arrays.copyOfRange(keys, 0, keys.length); - - for (byte[][] singleRuleSet : keyLedSet.get("Key")) { - for (byte[] keyLedSetting : singleRuleSet){ - if (appendTo == 64){ - keyLedCommands.add(Arrays.copyOfRange(command, 0, command.length)); - command = Arrays.copyOfRange(keys, 0, keys.length); - appendTo = 8; - } - System.arraycopy(keyLedSetting, 0, command, appendTo, 4); - appendTo += 4; - } - } - - if (appendTo > 8) - keyLedCommands.add(Arrays.copyOfRange(command, 0, command.length)); - // Add commit command to the end - keyLedCommands.add(commit); - } - - @Override - public void run() { - // If no commands in the query, then nothing to do - if (keyLedCommands.size() == 0) - return; - - UsbConnect usbConnect = new UsbConnect(); - - if (!usbConnect.isConnected()) - return; - - handler = usbConnect.getHandlerKbrd(); - - for (byte[] cmd : keyLedCommands) - if (write(cmd)) - break; - - usbConnect.close(); - } - /** - * Write to keyboard - * @param message : what to sent - * @return true in case of failure - * false for success - * */ - private boolean write(byte[] message){ - ByteBuffer writeBuffer = ByteBuffer.allocateDirect(message.length); //writeBuffer.order() equals BIG_ENDIAN; - writeBuffer.put(message); // Don't do writeBuffer.rewind(); - int result; - - if (message.length > 20) - result = LibUsb.controlTransfer(handler, (byte) 0x21, (byte) 0x09, (short) 0x212, (short) 1, writeBuffer, 2000); - else - result = LibUsb.controlTransfer(handler, (byte) 0x21, (byte) 0x09, (short) 0x211, (short) 1, writeBuffer, 2000); - - if (result < 0){ - MessagesConsumer.getInstance().inform("Data transfer failed: "+UsbErrorCodes.getErrCode(result)); - return true; - } - - ByteBuffer readBuffer = ByteBuffer.allocateDirect(64); - IntBuffer readBufTrans = IntBuffer.allocate(1); - LibUsb.interruptTransfer(handler, (byte) 0x82, readBuffer, readBufTrans, 1000); - /* - readBuffer.rewind(); - byte[] arr = new byte[readBuffer.get()]; - readBuffer.get(arr); - RainbowHexDump.hexDumpUTF8(arr); - */ - return false; - } -} -/* - ANY - 0x11, 0xff, ???, 0x3c - - waves - cwave - !! !! - 0x11, 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x56, 0x00 0x00, ----, ----, ----, ----, ====, 0x64, ????, ?!!?, 0x00, 0x00, 0x00 - - hwave - vwave - !! !! - 0x11, 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x55, 0x00 0x00, ----, ----, ----, ----, ====, 0x64, ????, ?!!?, 0x00, 0x00, 0x00 - - cycle - !! !! - 0x11, 0xff, 0x0d, 0x3c, 0x00, 0x03, 0x55, 0x00 0x00, ----, ----, ----, ----, 0x00, 0x64, ????, ?!!?, 0x00, 0x00, 0x00 - - breathing - - 0x11, 0xff, 0x0d, 0x3c, 0x00, 0x02, RED_, GRN_, BLU_ ----, ----, ----, ----, 0x00, 0x64, ????, ?!!?, 0x00, 0x00, 0x00 - ----------------------- - hwave - new - 11 ff 0d 3c 00 04 00 00 00 00 00 00 e8 06 64 03 00 00 00 00 - - -* */ \ No newline at end of file diff --git a/src/main/java/logiled/USB/EffectsThread.java b/src/main/java/logiled/USB/EffectsThread.java new file mode 100644 index 0000000..b4ada53 --- /dev/null +++ b/src/main/java/logiled/USB/EffectsThread.java @@ -0,0 +1,145 @@ +package logiled.USB; + +import logiled.Controllers.LoEffects; + +import java.util.HashMap; + +public class EffectsThread extends LoThread implements Runnable{ + + private byte[] command; + + /** + * Used to set effects + * @param effectData : set of rules, always not empty and not null + * */ + public EffectsThread(HashMap effectData){ + switch (LoEffects.values()[effectData.get("EFFECT")]){ + case DISABLE: + command = effectDisable(); + break; + case CONSTANT_COLOR: + command = effectConstantColor(effectData); + break; + case BREATH: + command = effectBreath(effectData); + break; + case CIRCLES_ON_PRESS: + command = effectCirlesOnPress(effectData); + break; + case CYCLE: + command = effectCycle(effectData); + break; + case WAVE_HORIZONTAL_FRW: + command = effectWaveHorizontalFrw(effectData); + break; + case WAVE_VERTICAL_FRW: + command = effectWaveVerticalFrw(effectData); + break; + case WAVE_CENTER_TO_EDGE: + command = effectWaveCenterToEdge(effectData); + break; + case WAVE_HORIZONTAL_BKW: + command = effectWaveHorizontalBkw(effectData); + break; + case WAVE_VERTICAL_BKW: + command = effectWaveVerticalBkw(effectData); + break; + case WAVE_EDGE_TO_CENTER: + command = effectWaveEdgeToCenter(effectData); + } + } + + @Override + public void run() { + if (command == null) + return; + + UsbConnect usbConnect = new UsbConnect(); + + if (!usbConnect.isConnected()) + return; + + handler = usbConnect.getHandlerKbrd(); + + write(command); + + usbConnect.close(); + } + + private byte[] effectDisable(){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectConstantColor(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x01, effectData.get("RED"), effectData.get("GREEN"), effectData.get("BLUE"), 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectBreath(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x02, effectData.get("RED"), effectData.get("GREEN"), effectData.get("BLUE"), effectData.get("TIME_HIGH"), effectData.get("TIME_LOW"), 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectCirlesOnPress(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x06, effectData.get("RED"), effectData.get("GREEN"), effectData.get("BLUE"), 0x00, 0x00, effectData.get("TIME_LOW"), 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectCycle(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, effectData.get("TIME_HIGH"), effectData.get("TIME_LOW"), 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectWaveHorizontalFrw(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, effectData.get("TIME_LOW"), 0x01, 0x64, effectData.get("TIME_HIGH"), + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectWaveVerticalFrw(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, effectData.get("TIME_LOW"), 0x02, 0x64, effectData.get("TIME_HIGH"), + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectWaveCenterToEdge(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, effectData.get("TIME_LOW"), 0x03, 0x64, effectData.get("TIME_HIGH"), + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectWaveHorizontalBkw(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, effectData.get("TIME_LOW"), 0x06, 0x64, effectData.get("TIME_HIGH"), + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectWaveVerticalBkw(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, effectData.get("TIME_LOW"), 0x07, 0x64, effectData.get("TIME_HIGH"), + 0x00, 0x00, 0x00, 0x00 + }; + } + + private byte[] effectWaveEdgeToCenter(HashMap effectData){ + return new byte[] { + 0x11, (byte) 0xff, 0x0d, 0x3c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, effectData.get("TIME_LOW"), 0x08, 0x64, effectData.get("TIME_HIGH"), + 0x00, 0x00, 0x00, 0x00 + }; + } +} diff --git a/src/main/java/logiled/USB/GameModeThread.java b/src/main/java/logiled/USB/GameModeThread.java new file mode 100644 index 0000000..0f7294c --- /dev/null +++ b/src/main/java/logiled/USB/GameModeThread.java @@ -0,0 +1,41 @@ +package logiled.USB; + +import java.util.List; + +public class GameModeThread extends LoThread implements Runnable{ + + // Game-key settings + //private static final byte[] game_key_rule + private static final byte[] game_key_set_default = { + 0x11, (byte) 0xff, 0x03, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + private byte[] command; + + /** + * Used to set keys & leds + * @param keysToDisable : list of keys that has to be disables in 'Game Mode', always not empty and not null + * */ + public GameModeThread(List keysToDisable){ + + } + + @Override + public void run() { + if (command == null) + return; + + UsbConnect usbConnect = new UsbConnect(); + + if (!usbConnect.isConnected()) + return; + + handler = usbConnect.getHandlerKbrd(); + + write(command); + + usbConnect.close(); + } + +} diff --git a/src/main/java/logiled/USB/KeyLedThread.java b/src/main/java/logiled/USB/KeyLedThread.java new file mode 100644 index 0000000..6fd504e --- /dev/null +++ b/src/main/java/logiled/USB/KeyLedThread.java @@ -0,0 +1,97 @@ +package logiled.USB; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class KeyLedThread extends LoThread implements Runnable{ + // Keys and indicators individual settings + private static final byte[] commit = { + 0x11, (byte) 0xff, 0x0c, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + private static final byte[] indicators = { // we have 2 leds on G513 + // KEY RED GRN BLU -//- + 0x12, (byte) 0xff, 0x0c, 0x3a, 0x00, 0x40, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + private static final byte[] keys = { // Can store 14 rules + // LED RED GRN BLU -//- + 0x12, (byte) 0xff, 0x0c, 0x3a, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + + // What would be sent to keyboard + private List keyLedCommands; + + /** + * Used to set keys & leds + * @param keyLedSet : set of rules, always not empty and not null + * */ + public KeyLedThread(HashMap> keyLedSet){ + keyLedCommands = new ArrayList<>(); + + int appendTo = 8; + + byte[] command = Arrays.copyOfRange(indicators, 0, indicators.length); + + for (byte[][] singleRuleSet : keyLedSet.get("Led")){ + for (byte[] keyLedSetting: singleRuleSet) { + System.arraycopy(keyLedSetting, 0, command, appendTo, 4); + appendTo += 4; + } + } + + if (appendTo > 8) { + keyLedCommands.add(Arrays.copyOfRange(command, 0, command.length)); + appendTo = 8; + } + + command = Arrays.copyOfRange(keys, 0, keys.length); + + for (byte[][] singleRuleSet : keyLedSet.get("Key")) { + for (byte[] keyLedSetting : singleRuleSet){ + if (appendTo == 64){ + keyLedCommands.add(Arrays.copyOfRange(command, 0, command.length)); + command = Arrays.copyOfRange(keys, 0, keys.length); + appendTo = 8; + } + System.arraycopy(keyLedSetting, 0, command, appendTo, 4); + appendTo += 4; + } + } + + if (appendTo > 8) + keyLedCommands.add(Arrays.copyOfRange(command, 0, command.length)); + // Add commit command to the end + keyLedCommands.add(commit); + } + + @Override + public void run() { + // If no commands in the query, then nothing to do + if (keyLedCommands.size() == 0) + return; + + UsbConnect usbConnect = new UsbConnect(); + + if (!usbConnect.isConnected()) + return; + + handler = usbConnect.getHandlerKbrd(); + + for (byte[] cmd : keyLedCommands) + if (write(cmd)) + break; + + usbConnect.close(); + } + +} \ No newline at end of file diff --git a/src/main/java/logiled/USB/LoThread.java b/src/main/java/logiled/USB/LoThread.java new file mode 100644 index 0000000..6b777fb --- /dev/null +++ b/src/main/java/logiled/USB/LoThread.java @@ -0,0 +1,46 @@ +package logiled.USB; + +import logiled.MessagesConsumer; +import org.usb4java.DeviceHandle; +import org.usb4java.LibUsb; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +abstract class LoThread { + + DeviceHandle handler; + + /** + * Write to keyboard + * @param message : what to sent + * @return true in case of failure + * false for success + * */ + boolean write(byte[] message){ + ByteBuffer writeBuffer = ByteBuffer.allocateDirect(message.length); //writeBuffer.order() equals BIG_ENDIAN; + writeBuffer.put(message); // Don't do writeBuffer.rewind(); + int result; + + if (message.length > 20) + result = LibUsb.controlTransfer(handler, (byte) 0x21, (byte) 0x09, (short) 0x212, (short) 1, writeBuffer, 2000); + else + result = LibUsb.controlTransfer(handler, (byte) 0x21, (byte) 0x09, (short) 0x211, (short) 1, writeBuffer, 2000); + + if (result < 0){ + MessagesConsumer.getInstance().inform("Data transfer failed: "+UsbErrorCodes.getErrCode(result)); + return true; + } + + ByteBuffer readBuffer = ByteBuffer.allocateDirect(64); + IntBuffer readBufTrans = IntBuffer.allocate(1); + LibUsb.interruptTransfer(handler, (byte) 0x82, readBuffer, readBufTrans, 1000); + /* + readBuffer.rewind(); + byte[] arr = new byte[readBuffer.get()]; + readBuffer.get(arr); + RainbowHexDump.hexDumpUTF8(arr); + */ + return false; + } +} diff --git a/src/main/resources/EffectsPane.fxml b/src/main/resources/EffectsPane.fxml index fd43adb..32ddbc8 100644 --- a/src/main/resources/EffectsPane.fxml +++ b/src/main/resources/EffectsPane.fxml @@ -16,24 +16,30 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -45,6 +51,5 @@ - diff --git a/src/main/resources/locale_rus.properties b/src/main/resources/locale_rus.properties index 021cf0a..1b24fdb 100644 --- a/src/main/resources/locale_rus.properties +++ b/src/main/resources/locale_rus.properties @@ -13,8 +13,8 @@ effect_constant=Постоянный цвет effect_breath=Дыхание effect_cirles_on_press=Круги при нажатии effect_cycle=Цикл -effect_wave_horizontal=Волна по-горизонтали -effect_wave_horizontal_reverse=Волна по-горизонтали (обратная) +effect_wave_horizontal=Волна горизонтальная +effect_wave_horizontal_reverse=Волна горизонтальная (обратная) effect_wave_vertical=Волна вертикальная effect_wave_vertical_reverse=Волна вертикальная (обратная) effect_wave_center_to_edge=Волна от центра к краям