From 8f08d4418837c699a5737c5facab26d5051f5f2d Mon Sep 17 00:00:00 2001 From: jimmy Date: Thu, 10 Sep 2026 00:47:18 +1200 Subject: [PATCH] Split cabaret figure-8s onto the floor and the wall, and make Speed a fader. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Floor 8 stays on the live ground aim; Wall 8 uses the Here–Out box. Pan/tilt speed is a slider so it matches Bright and Focus. Co-authored-by: Cursor --- scripts/make_cabaret_vc.py | 127 +++++++++++++++++++------------------ shows/cabaret.qxw | 36 ++++++----- 2 files changed, 86 insertions(+), 77 deletions(-) diff --git a/scripts/make_cabaret_vc.py b/scripts/make_cabaret_vc.py index 68ce04a..ab2c489 100644 --- a/scripts/make_cabaret_vc.py +++ b/scripts/make_cabaret_vc.py @@ -16,7 +16,8 @@ GROUP_C = [2, 3, 4, 5] GROUP_R = [6, 7] # Can 8ch: Dim=0, R=2, G=3, B=4 -# Mover 43ch: Focus=7, Center Bright=8; RGB heads 1–7 +# Mover 43ch: Pan/Tilt Speed=4, Focus=7, Center Bright=8; RGB heads 1–7 +MOVER_SPEED = 4 MOVER_FOCUS = 7 MOVER_DIM = 8 MOVER_R = [10, 14, 18, 22, 26, 30, 34] @@ -69,11 +70,11 @@ POSITIONS: list[tuple[str, tuple[int, int], tuple[int, int], str]] = [ POSITION_FUNC0 = 100 PADS_FUNC = POSITION_FUNC0 + len(POSITIONS) PADS_BG = "4282800750" # #465A6E pad grey-blue -FIGURE8_FUNC = 110 -FIGURE8_SIDE_FUNC = 111 +FIGURE8_FLOOR_FUNC = 110 +FIGURE8_WALL_FUNC = 111 FIGURE8_MS = 12000 -FIGURE8_BG = "4282664004" -FIGURE8_SIDE_BG = "4286611584" +FIGURE8_FLOOR_BG = "4282664004" +FIGURE8_WALL_BG = "4286611584" LOOK_PAIRS: list[tuple[str, str | None]] = [ ("Amber", None), ("Pink", "Amber"), @@ -132,11 +133,13 @@ def slider( value: int = 0, fg: str = "Default", cng: str = "None", + inverted: bool = False, ) -> str: ch_xml = "\n".join( f' {ch}' for fid, ch in channels ) - return f""" + inv = "true" if inverted else "false" + return f""" {appearance(fg=fg)} Level @@ -150,33 +153,6 @@ def slider( """ -def speed_dial( - wid: int, - caption: str, - x: int, - y: int, - w: int, - h: int, - func_ids: list[int], - *, - time_ms: int = FIGURE8_MS, - min_ms: int = 500, - max_ms: int = 30000, -) -> str: - fn_xml = "\n".join( - f' {fid}' - for fid in func_ids - ) - return f""" - -{appearance()} - 2 - - -{fn_xml} - """ - - def xypad( wid: int, caption: str, @@ -401,12 +377,23 @@ def position_button_specs() -> list[tuple[str, int, str]]: (name, POSITION_FUNC0 + i, bg) for i, (name, _m1, _m2, bg) in enumerate(POSITIONS) ] - + [("Fig 8", FIGURE8_FUNC, FIGURE8_BG), ("Side 8", FIGURE8_SIDE_FUNC, FIGURE8_SIDE_BG)] + + [ + ("Floor 8", FIGURE8_FLOOR_FUNC, FIGURE8_FLOOR_BG), + ("Wall 8", FIGURE8_WALL_FUNC, FIGURE8_WALL_BG), + ] ) -def figure8_bounds() -> tuple[int, int, int, int]: - """Pan/tilt centre and amplitude covering Here–Out (not the live Now aim).""" +def figure8_floor_center() -> tuple[int, int]: + """Now is the live floor aim; average both heads so the 8 stays on the ground.""" + now = next((m1, m2) for name, m1, m2, _bg in POSITIONS if name == "Now") + pans = [now[0][0], now[1][0]] + tilts = [now[0][1], now[1][1]] + return (pans[0] + pans[1]) // 2, (tilts[0] + tilts[1]) // 2 + + +def figure8_wall_bounds() -> tuple[int, int, int, int]: + """Pan/tilt centre and amplitude covering Here–Out (the wall looks).""" pans: list[int] = [] tilts: list[int] = [] for name, m1, m2, _bg in POSITIONS: @@ -461,22 +448,29 @@ def figure8_efx_block( def figure8_efx_xml() -> str: - pan_c, tilt_c, pan_amp, tilt_amp = figure8_bounds() - # Sideways ∞ is rotation 0. 90° is a vertical 8 (tilt 0 → 36 down); - # width/height are swapped so both still fill the Here–Out box. + floor_pan, floor_tilt = figure8_floor_center() + wall_pan, wall_tilt, wall_pan_amp, wall_tilt_amp = figure8_wall_bounds() + # Floor 8: around Now, tilt stays on the ground. Rotation 90 = upright 8. + # Wall 8: Here–Out box (tilt 0–36). Rotation 0 = 8 across the wall. return "\n".join( [ figure8_efx_block( - FIGURE8_FUNC, "Figure of 8", tilt_amp, pan_amp, 90, pan_c, tilt_c + FIGURE8_FLOOR_FUNC, + "Figure of 8 Floor", + 16, + 18, + 90, + floor_pan, + floor_tilt, ), figure8_efx_block( - FIGURE8_SIDE_FUNC, - "Figure of 8 Side", - pan_amp, - tilt_amp, + FIGURE8_WALL_FUNC, + "Figure of 8 Walls", + wall_pan_amp, + wall_tilt_amp, 0, - pan_c, - tilt_c, + wall_pan, + wall_tilt, ), ] ) @@ -554,10 +548,24 @@ def main() -> None: max_x = 0 max_y = 0 - def place_slider(caption, x, y, w, h, channels, value=0, fg="Default", cng="None"): + def place_slider( + caption, x, y, w, h, channels, value=0, fg="Default", cng="None", inverted=False + ): nonlocal wid, max_x, max_y widgets.append( - slider(wid, caption, x, y, w, h, channels, value=value, fg=fg, cng=cng) + slider( + wid, + caption, + x, + y, + w, + h, + channels, + value=value, + fg=fg, + cng=cng, + inverted=inverted, + ) ) wid += 1 max_x = max(max_x, x + w) @@ -688,20 +696,17 @@ def main() -> None: "4294902015", ) x += sl_w + 2 - widgets.append( - speed_dial( - wid, - "Speed", - x, - y0, - sl_w, - sl_h, - [FIGURE8_FUNC, FIGURE8_SIDE_FUNC], - ) + place_slider( + "Speed", + x, + y0, + sl_w, + sl_h, + [(M1, MOVER_SPEED), (M2, MOVER_SPEED)], + 0, + "4294967295", + inverted=True, ) - wid += 1 - max_x = max(max_x, x + sl_w) - max_y = max(max_y, y0 + sl_h) x += sl_w + 2 for name, _can_ch, mover_chs, fg, cng in RGB: place_slider( diff --git a/shows/cabaret.qxw b/shows/cabaret.qxw index b5d2746..8cc8458 100644 --- a/shows/cabaret.qxw +++ b/shows/cabaret.qxw @@ -381,7 +381,7 @@ 0,200,1,0,2,22,3,0 0,200,1,0,2,22,3,0 - + 8 Forward @@ -397,21 +397,21 @@ Forward Loop Eight - 18 - 30 + 16 + 18 90 - 170 + 77 1 0 - 18 + 153 1 0 - + 8 Forward @@ -523,21 +523,25 @@ 4294967295 - + Sunken - Default + 4294967295 Default None Default - 2 - - - 110 - 111 - + Level + + + 4 + 4 + + + 4294967295 + + @@ -736,7 +740,7 @@ Toggle 100 - -