Effects support added

master
Dmitry Isaenko 2019-10-17 00:16:27 +03:00
parent d4c138cf33
commit 11582fd69d
14 changed files with 545 additions and 508 deletions

View File

@ -6,7 +6,7 @@
<groupId>loper</groupId>
<artifactId>LogiLed</artifactId>
<version>0.1-SNAPSHOT</version>
<version>0.2-SNAPSHOT</version>
<!-- <url></url> -->
<description>

View File

@ -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<String, Byte> getEffect(){
final RadioMenuItem item = (RadioMenuItem) effectsToggleGrp.getSelectedToggle();
/*
HashMap<LoEffects, byte[]> effectsSet = new HashMap<>();
byte[] meta;
final HashMap<String, Byte> 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;
}
}

View File

@ -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; // ???
}
}
}

View File

@ -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<String, List<byte[][]>> 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();
}
});
}

View File

@ -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<String, Byte> LoCodepage;
static {
Map<String, Byte> 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;

View File

@ -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{

View File

@ -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){

View File

@ -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<byte[]> keyLedCommands;
/**
* Used to set keys & leds
* @param keyLedSet : set of rules, always not empty and not null
* */
public Communications(HashMap<String, List<byte[][]>> 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
* */

View File

@ -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<String, Byte> 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<String, Byte> 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<String, Byte> 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<String, Byte> 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<String, Byte> 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<String, Byte> 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<String, Byte> 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<String, Byte> 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<String, Byte> 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<String, Byte> 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<String, Byte> 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
};
}
}

View File

@ -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<Byte> keysToDisable){
}
@Override
public void run() {
if (command == null)
return;
UsbConnect usbConnect = new UsbConnect();
if (!usbConnect.isConnected())
return;
handler = usbConnect.getHandlerKbrd();
write(command);
usbConnect.close();
}
}

View File

@ -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<byte[]> keyLedCommands;
/**
* Used to set keys & leds
* @param keyLedSet : set of rules, always not empty and not null
* */
public KeyLedThread(HashMap<String, List<byte[][]>> 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();
}
}

View File

@ -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;
}
}

View File

@ -16,24 +16,30 @@
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</padding>
<children>
<MenuButton fx:id="effectsMenu" mnemonicParsing="false">
<items>
<RadioMenuItem fx:id="disRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_disable">
<toggleGroup>
<ToggleGroup fx:id="effectsToggleGrp" />
</toggleGroup></RadioMenuItem>
<RadioMenuItem fx:id="constRMI" mnemonicParsing="false" onAction="#selectEffect" selected="true" text="%effect_constant" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="breathRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_breath" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="circlesOnPressRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_cirles_on_press" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="cycleRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_cycle" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="hWaveFrwRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_horizontal" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="vWaveFrwRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_vertical" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="cntrToEdgWaveRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_center_to_edge" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="hWaveBkwRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_horizontal_reverse" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="vWaveBkwRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_vertical_reverse" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="edgToCntrWaveRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_edge_to_center" toggleGroup="$effectsToggleGrp" />
</items>
</MenuButton>
<HBox spacing="5.0">
<children>
<MenuButton fx:id="effectsMenu" mnemonicParsing="false">
<items>
<RadioMenuItem fx:id="disRMI" mnemonicParsing="false" onAction="#selectEffect" selected="true" text="%effect_disable">
<toggleGroup>
<ToggleGroup fx:id="effectsToggleGrp" />
</toggleGroup>
</RadioMenuItem>
<RadioMenuItem fx:id="constRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_constant" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="breathRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_breath" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="circlesOnPressRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_cirles_on_press" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="cycleRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_cycle" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="hWaveFrwRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_horizontal" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="vWaveFrwRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_vertical" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="cntrToEdgWaveRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_center_to_edge" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="hWaveBkwRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_horizontal_reverse" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="vWaveBkwRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_vertical_reverse" toggleGroup="$effectsToggleGrp" />
<RadioMenuItem fx:id="edgToCntrWaveRMI" mnemonicParsing="false" onAction="#selectEffect" text="%effect_wave_edge_to_center" toggleGroup="$effectsToggleGrp" />
</items>
</MenuButton>
<ColorPicker fx:id="mainClrPkr" visible="false" />
</children>
</HBox>
<Separator prefWidth="200.0" />
<HBox alignment="CENTER_LEFT" maxHeight="-Infinity" minHeight="-Infinity" prefHeight="35.0">
<children>
@ -45,6 +51,5 @@
<Label fx:id="mainSlideInfoLbl" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="40.0" textFill="DIMGRAY" visible="false" />
</children>
</HBox>
<ColorPicker fx:id="mainClrPkr" visible="false" />
</children>
</VBox>

View File

@ -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=Волна от центра к краям