1 module rivald.cycle; 2 3 // 4 // Rivald 5 // 6 import rivald.error; 7 import rivald.util; 8 import rivald.values; 9 10 // 11 // Std 12 // 13 import std.bitmanip : nativeToLittleEndian; 14 import std.exception : enforce; 15 16 /// Point representation 17 struct Point 18 { 19 // color 20 ubyte red; 21 ubyte green; 22 ubyte blue; 23 // relative position in the cycle 24 ubyte pos; 25 } 26 27 /// Cycle representation 28 class Cycle 29 { 30 private: 31 ubyte led = Led.LOGO; 32 ushort duration = 5000; 33 bool repeat = true; 34 ubyte trigger_buttons; 35 Point[] points; 36 37 public: 38 39 /** 40 * Cycle constructor 41 * 42 * Params: 43 * led = Led ID (0 or 1) 44 */ 45 this(ubyte led) 46 { 47 enforce!RivalError(led == Led.LOGO || led == Led.WHEEL, "Invalid Led ID."); 48 49 this.led = led; 50 } 51 52 /** 53 * Sets the points 54 * 55 * Params: 56 * points = Points in the cycle 57 */ 58 void setPoints(Point[] points) 59 { 60 this.points = points; 61 } 62 63 /** 64 * Sets the duration 65 * 66 * Params: 67 * duration = Duration of the cycle 68 */ 69 void setDuration(ushort duration) 70 { 71 this.duration = duration; 72 } 73 74 /** 75 * Sets the repeat bool 76 * 77 * Params: 78 * repeat = If cycle repeats 79 */ 80 void setRepeat(bool repeat) 81 { 82 this.repeat = repeat; 83 } 84 85 /** 86 * Sets the trigger buttons 87 * 88 * Params: 89 * buttons = Button representation 90 * 91 * https://github.com/FFY00/rival310-re/blob/master/5B.md 92 */ 93 void setDuration(ubyte buttons) 94 { 95 this.trigger_buttons = buttons; 96 } 97 98 /** 99 * Contructs the buffer 100 * 101 * Returns: Contructed buffer 102 * 103 * https://github.com/FFY00/rival310-re/blob/master/5B.md 104 */ 105 ubyte[Size.LONG] getBuffer() 106 { 107 ubyte[Size.LONG] buf; 108 109 buf[0] = Command.LED; 110 buf[2] = led; 111 112 if(!repeat) 113 buf[19] = 1; 114 115 buf[27] = cast(ubyte) points.length; 116 117 bool first_point; 118 ubyte i; 119 ushort cycle_size; 120 CYCLE: foreach(point; points) 121 { 122 if(!first_point) 123 { 124 buf[28] = point.red; 125 buf[29] = point.green; 126 buf[30] = point.blue; 127 first_point = true; 128 } 129 130 buf[31 + (i * 4)] = point.red; 131 buf[32 + (i * 4)] = point.green; 132 buf[33 + (i * 4)] = point.blue; 133 buf[34 + (i * 4)] = point.pos; 134 135 cycle_size += point.pos; 136 137 if(cycle_size >= 255) 138 break CYCLE; 139 140 i++; 141 } 142 143 duration = cast(short) min_threshold(duration, buf[27] * 330); 144 ubyte[2] dur = nativeToLittleEndian(duration); 145 buf[3] = dur[0]; 146 buf[4] = dur[1]; 147 148 return buf; 149 } 150 151 }