--- /dev/null
+/* This file is part of LED Pattern Editor.
+ *
+ * Copyright (C) 2010 Philipp Zabel
+ *
+ * LED Pattern Editor is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LED Pattern Editor is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LED Pattern Editor. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class LedPatternRX51 : LedPattern {
+ public string led_map;
+ public List<LedCommandRX51> engine1;
+ public List<LedCommandRX51> engine2;
+
+ public void parse (string line) {
+ string[] key_value = line.split ("=");
+
+ if (key_value.length != 2) {
+ print ("pattern line does not contain '=': %s\n", line);
+ return;
+ }
+
+ string[] p = key_value[1].split (";");
+ if (p.length != 6) {
+ print ("pattern does not contain 6 components: %d\n", p.length);
+ return;
+ }
+
+ if (p[4].length > 16*4 || p[5].length > 16*4) {
+ print ("pattern too long!\n");
+ return;
+ }
+
+ name = key_value[0];
+ priority = p[0].to_int ();
+ screen_on = p[1].to_int ();
+ timeout = p[2].to_int ();
+ led_map = p[3];
+ engine1 = parse_pattern (p[4]);
+ engine2 = parse_pattern (p[5]);
+
+ if (engine1.first ().data.code != 0x9d80) {
+ print ("engine1 pattern doesn't start with refresh mux command\n");
+ }
+ if (engine2.first ().data.code != 0x9d80) {
+ print ("engine2 pattern doesn't start with refresh mux command\n");
+ }
+
+ on_changed ();
+ }
+
+ private List<LedCommandRX51> parse_pattern (string pattern) {
+ var list = new List<LedCommandRX51> ();
+ var length = pattern.length;
+
+ if (length % 4 != 0)
+ return list;
+
+ char *p = ((char*) pattern) + length - 4;
+ while (p >= (char*) pattern) {
+ var command = new LedCommandRX51.with_code ((uint16) ((string) p).to_ulong (null, 16));
+ command.changed.connect (on_changed);
+ list.prepend (command);
+ p[0] = '\0';
+ p -= 4;
+ }
+
+ return list;
+ }
+
+ public string dump () {
+ return "%s=%d;%d;%d;%s;%s;%s".printf (name, priority, screen_on, timeout, led_map,
+ dump_pattern (engine1), dump_pattern (engine2));
+ }
+
+ private string dump_pattern (List<LedCommandRX51> list) {
+ string result = "";
+ foreach (LedCommandRX51 command in list) {
+ result += "%04x".printf (command.code);
+ }
+ return result;
+ }
+
+ public LedPatternRX51 copy () {
+ var pattern = new LedPatternRX51 ();
+
+ pattern.name = name.dup ();
+ pattern.priority = priority;
+ pattern.screen_on = screen_on;
+ pattern.timeout = timeout;
+
+ pattern.duration = duration;
+
+ pattern.led_map = led_map;
+ pattern.engine1 = deep_copy (pattern, engine1);
+ pattern.engine2 = deep_copy (pattern, engine2);
+
+ return pattern;
+ }
+
+ public List<LedCommandRX51> deep_copy (LedPatternRX51 pattern, List<LedCommandRX51> list) {
+ var list2 = new List<LedCommandRX51> ();
+
+ foreach (LedCommandRX51 command in list) {
+ var command2 = command.copy ();
+ command2.changed.connect (pattern.on_changed);
+ list2.append (command2);
+ }
+
+ return list2;
+ }
+
+ public void replace_with (LedPatternRX51 pattern) {
+ name = pattern.name;
+ priority = pattern.priority;
+ screen_on = pattern.screen_on;
+ timeout = pattern.timeout;
+
+ duration = pattern.duration;
+
+ led_map = pattern.led_map;
+ engine1 = deep_copy (this, pattern.engine1);
+ engine2 = deep_copy (this, pattern.engine2);
+
+ changed ();
+ }
+
+ void on_changed () {
+ // calculate timing and level info
+ double time = 0;
+ int level = 0;
+ foreach (LedCommandRX51 command in engine1) {
+ command.time = time;
+ time += command.duration;
+ if (command.type == CommandType.SET_PWM) {
+ level = command.level;
+ } else {
+ command.level = level;
+ level += command.steps;
+ }
+ if (level < 0)
+ level = 0;
+ if (level > 255)
+ level = 255;
+ }
+ duration = time;
+ changed ();
+ }
+}
+
+class LedCommandRX51 : LedCommand {
+ public uint16 code;
+
+ public LedCommandRX51 () {
+ }
+
+ public LedCommandRX51.with_code (uint16 _code) {
+ code = _code;
+ if ((code & 0x8000) == 0) {
+ if (code == 0x0000) {
+ type = CommandType.REPEAT;
+ } else if ((code & 0x3e00) != 0) {
+ type = CommandType.RAMP_WAIT;
+ steps = code & 0xff;
+ step_time = code >> 9;
+ if ((code & 0x4000) == 0)
+ step_time = (code >> 9) * 0.49;
+ else {
+ step_time = ((code & 0x3e00) >> 9) * 15.6;
+ }
+ duration = step_time * (steps + 1);
+ if ((code & 0x100) != 0)
+ steps = -steps;
+ } else {
+ type = CommandType.SET_PWM;
+ level = code & 0xff;
+ }
+ } else {
+ if (code == 0x9d80)
+ type = CommandType.RESET_MUX;
+ if (code == 0xc000)
+ type = CommandType.STOP;
+ //if (code == 0xe0??)
+ // type = CommandType.TRIGGER_WAIT;
+ }
+ }
+
+ public override void set_pwm (int _level) {
+ code = 0x4000 | _level;
+ base.set_pwm (_level);
+ }
+
+ public override void ramp_wait (double _step_time, int _steps) requires (_step_time >= 0.49) {
+ int step_time;
+ if (_step_time <= 31*0.49) {
+ step_time = (int) ((_step_time + 0.001) / 0.49);
+ code = (uint16) step_time << 9;
+ _step_time = step_time * 0.49;
+ } else if (_step_time <= 31*15.6) {
+ step_time = (int) ((_step_time + 0.01) / 15.6);
+ code = 0x4000 | (step_time << 9);
+ _step_time = step_time * 15.6;
+ } else {
+ return;
+ }
+ if (_steps < 0) {
+ code |= 0x100 | (-_steps);
+ } else {
+ code |= _steps;
+ }
+ base.ramp_wait (_step_time, _steps);
+ }
+
+ public LedCommandRX51 copy () {
+ var command = new LedCommandRX51 ();
+
+ command.type = type;
+ command.time = time;
+ command.step_time = step_time;
+ command.duration = duration;
+ command.level = level;
+ command.steps = steps;
+
+ command.code = code;
+
+ return command;
+ }
+}
--- /dev/null
+/* This file is part of LED Pattern Editor.
+ *
+ * Copyright (C) 2010 Philipp Zabel
+ *
+ * LED Pattern Editor is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LED Pattern Editor is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LED Pattern Editor. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class LedPattern : Object {
+ enum ScreenOn {
+ DISPLAY_OFF = 0,
+ DISPLAY_ON = 1,
+ DISPLAY_OFF_ACT_DEAD = 2,
+ DISPLAY_ON_ACT_DEAD = 3,
+ DISPLAY_OFF_OR_ACT_DEAD = 4,
+ DISABLED = 5
+ }
+
+ public string name;
+ public int priority;
+ public int screen_on;
+ public int timeout;
+
+ public double duration;
+
+ public signal void changed ();
+}
+
+enum CommandType {
+ UNKNOWN,
+ RESET_MUX,
+ SET_PWM,
+ RAMP_WAIT,
+ REPEAT,
+ STOP
+}
+
+class LedCommand : Object {
+ public CommandType type;
+ public double time;
+ public double step_time;
+ public double duration;
+ public int level;
+ public int steps;
+
+ public virtual void set_pwm (int _level) {
+ type = CommandType.SET_PWM;
+ level = _level;
+ changed ();
+ }
+
+ public virtual void ramp_wait (double _step_time, int _steps) {
+ type = CommandType.RAMP_WAIT;
+ step_time = _step_time;
+ steps = _steps;
+ if (steps < 0)
+ duration = step_time * (1 - steps);
+ else
+ duration = step_time * (steps + 1);
+ changed ();
+ }
+
+ public signal void changed ();
+}
+