feat(sacn): zweite Slot-Belegung "rgb" fuer pixelorientierte Werkzeuge
LedFx und Verwandte denken in RGB-Pixeln: Ihr e131-Geraet schreibt je Pixel genau drei Kanaele. Unsere Belegung beginnt mit einem Master-Dimmer, also landet deren erstes Pixel auf Dimmer, R, G - ein rotes Effektbild (255,0,0) hiesse bei uns "Dimmer 255, Rot 0, Gruen 0" und damit Dunkelheit. Von Hand eintragen liess sich eine Lampe schon, sie zeigte aber Unsinn. Der Dimmer bleibt fuer DMX-Pulte richtig, deshalb eine zweite Belegung statt einer anderen: layout = "dimmer" (Vorgabe, unveraendert) oder "rgb" (R,G,B, drei Slots auf jedem Board). Im rgb-Layout ist eine Lampe genau ein Pixel. Ein Board ohne Farbkanaele bekommt trotzdem ein Farbtripel. Genommen wird der groesste der drei Werte auf beide Weisskanaele: die Lampe folgt sichtbar der Helligkeit des Effekts, ohne dass ein Farbmodell in den DMX-Pfad kommt - genau das wird dort sonst bewusst vermieden. Die Obergrenze fuer start_slot haengt jetzt am Layout (512 - slots + 1). Ein Wechsel, der einen bisher zulaessigen start_slot unzulaessig macht, wird abgelehnt statt still verschoben: eine Lampe, die nach einer Einstellung woanders im Universe liegt als angegeben, findet niemand wieder. Das neue Settings-Feld beginnt bei Offset 216, dem sizeof davor, und ist durch eine eigene Pruefung zur Uebersetzungszeit und einen Migrationstest abgesichert - derselbe Fallstrick, der beim Schlussreview fuer sacn_enabled gefunden wurde.
This commit is contained in:
+34
-10
@@ -16,10 +16,11 @@ static uint32_t s_last_ms;
|
||||
void nl_dmx_init(const nl_board_t *board)
|
||||
{
|
||||
s_board = board;
|
||||
s_slots = nl_board_dmx_slots(board);
|
||||
s_cfg.start_slot = 1;
|
||||
s_cfg.hold = false;
|
||||
s_cfg.release_fade_ms = 0;
|
||||
s_cfg.rgb_layout = false;
|
||||
s_slots = nl_board_dmx_slots(board, false);
|
||||
s_streaming = false;
|
||||
s_override = false;
|
||||
s_prio = 0;
|
||||
@@ -35,6 +36,9 @@ void nl_dmx_configure(const nl_dmx_cfg_t *cfg)
|
||||
* sein, den es nicht sehen kann. */
|
||||
if (s_cfg.start_slot < 1u)
|
||||
s_cfg.start_slot = 1u;
|
||||
/* Die Slotzahl haengt am Layout, nicht nur am Board - hier nachziehen, sonst liest
|
||||
* nl_dmx_feed() beim Umschalten die falsche Anzahl. */
|
||||
s_slots = nl_board_dmx_slots(s_board, s_cfg.rgb_layout);
|
||||
}
|
||||
|
||||
bool nl_dmx_active(void) { return s_override; }
|
||||
@@ -106,17 +110,37 @@ void nl_dmx_feed(const nl_e131_packet_t *p, uint32_t now_ms)
|
||||
s_streaming = true;
|
||||
|
||||
s = p->slots + (s_cfg.start_slot - 1u);
|
||||
dim = s[0];
|
||||
memset(ch, 0, sizeof ch);
|
||||
if (s_board->has_rgb) {
|
||||
ch[NL_CH_R] = scale(s[1], dim);
|
||||
ch[NL_CH_G] = scale(s[2], dim);
|
||||
ch[NL_CH_B] = scale(s[3], dim);
|
||||
ch[NL_CH_CW] = scale(s[4], dim);
|
||||
ch[NL_CH_WW] = scale(s[5], dim);
|
||||
if (s_cfg.rgb_layout) {
|
||||
/* Drei Kanaele, kein Dimmer: so schreiben pixelorientierte Werkzeuge (LedFx und
|
||||
* Verwandte) je Pixel genau R,G,B. Eine Lampe ist damit ein Pixel. */
|
||||
if (s_board->has_rgb) {
|
||||
ch[NL_CH_R] = s[0];
|
||||
ch[NL_CH_G] = s[1];
|
||||
ch[NL_CH_B] = s[2];
|
||||
} else {
|
||||
/* Ein Board ohne Farbkanaele bekommt trotzdem ein Farbtripel. Genommen wird der
|
||||
* groesste der drei Werte auf beide Weisskanaele: die Lampe folgt damit sichtbar
|
||||
* der Helligkeit des Effekts, ohne dass ein Farbmodell in den DMX-Pfad kommt -
|
||||
* genau das wird hier sonst bewusst vermieden. */
|
||||
uint8_t v = s[0] > s[1] ? s[0] : s[1];
|
||||
if (s[2] > v)
|
||||
v = s[2];
|
||||
ch[NL_CH_CW] = v;
|
||||
ch[NL_CH_WW] = v;
|
||||
}
|
||||
} else {
|
||||
ch[NL_CH_CW] = scale(s[1], dim);
|
||||
ch[NL_CH_WW] = scale(s[2], dim);
|
||||
dim = s[0];
|
||||
if (s_board->has_rgb) {
|
||||
ch[NL_CH_R] = scale(s[1], dim);
|
||||
ch[NL_CH_G] = scale(s[2], dim);
|
||||
ch[NL_CH_B] = scale(s[3], dim);
|
||||
ch[NL_CH_CW] = scale(s[4], dim);
|
||||
ch[NL_CH_WW] = scale(s[5], dim);
|
||||
} else {
|
||||
ch[NL_CH_CW] = scale(s[1], dim);
|
||||
ch[NL_CH_WW] = scale(s[2], dim);
|
||||
}
|
||||
}
|
||||
nl_engine_override(ch);
|
||||
s_override = true;
|
||||
|
||||
Reference in New Issue
Block a user