commit 68

This commit is contained in:
Moritz Ruth 2025-03-10 20:47:46 +01:00
parent bf8eaacb00
commit 2153b67d8f
Signed by: moritzruth
GPG key ID: C9BBAB79405EE56D
12 changed files with 379 additions and 11 deletions

View file

@ -13,6 +13,17 @@ import kotlin.time.Duration.Companion.seconds
fun ShowBuilderContext.act1() = act("Erster Akt") { fun ShowBuilderContext.act1() = act("Erster Akt") {
scene("Ouvertüre") { scene("Ouvertüre") {
lightStep(StepCue.Custom("1%")) {
backlightBar.color.static(Color.WHITE)
backlightBar.brightness.static(1.percent)
}
for (i in 10.rangeTo(100) step 10) {
lightStep(StepCue.Custom("$i%")) {
backlightBar.brightness.static(i.percent)
}
}
step(StepCue.MusicStart("Ouvertüre", 10.seconds)) { step(StepCue.MusicStart("Ouvertüre", 10.seconds)) {
curtainState = CurtainState.CLOSED curtainState = CurtainState.CLOSED
@ -256,7 +267,7 @@ fun ShowBuilderContext.act1() = act("Erster Akt") {
} }
} }
songDuett() songDuettMinaJonathan()
step(StepCue.Text("Mina", "So markiere ich, was mir gehört.")) { step(StepCue.Text("Mina", "So markiere ich, was mir gehört.")) {
actors { actors {

View file

@ -1,7 +1,106 @@
package de.moritzruth.dracula_musical.act package de.moritzruth.dracula_musical.act
import de.moritzruth.dracula_musical.device.*
import de.moritzruth.dracula_musical.song.songDuettDraculaMina
import de.moritzruth.dracula_musical.song.songMaskenball
import de.moritzruth.dracula_musical.song.songRepriseMaskenball
import de.moritzruth.theaterdsl.show.ShowBuilderContext import de.moritzruth.theaterdsl.show.ShowBuilderContext
import de.moritzruth.theaterdsl.show.StepCue
import de.moritzruth.theaterdsl.value.percent
import kotlin.time.Duration.Companion.seconds
fun ShowBuilderContext.act2() = act("Zweiter Akt") { fun ShowBuilderContext.act2() = act("Zweiter Akt") {
scene("Maskenball") {
songMaskenball()
step(StepCue.Text("Van Helsing", "Na dann, gute Nacht.")) {
actors {
-"Van Helsing / durch Mitte"
-"Dr. Sewart / durch Mitte"
+"Dracula / durch Mitte"
+"Jonathan / durch Mitte"
}
}
step(StepCue.Text("Hawkins", "Geil!")) {
actors {
-"Hawkins / nach links"
}
}
step(StepCue.Text("Ascot", "Bringen Sie Mister Harker zur Tür!")) {
actors {
-"Jonathan / durch Mitte"
-"Ascot / durch Mitte"
-"Oberschwester / durch Mitte"
-"Lucy / durch Mitte"
}
}
}
scene("Tanz mit einem Vampir") {
songDuettDraculaMina()
step(StepCue.Text("Ascot", "Mina präsentiert Dracula ihren Hals")) {
actors {
+"Ascot / durch Mitte"
+"Oberschwester / durch Mitte"
+"Lucy / durch Mitte"
}
onRun {
Washs.both { it.brightness.off(0.4.seconds) }
backlightBar.brightness.off(0.4.seconds)
sidelight.brightness.off(0.4.seconds)
FrontLights.all { it.brightness.fade(100.percent, 3.seconds) }
}
}
step(StepCue.Text("Ascot", "Oberschwester!")) {
actors {
-"Ascot / durch Mitte"
-"Oberschwester / durch Mitte"
-"Mina / durch Mitte"
}
onRun {
FrontLights.all { it.brightness.fade(40.percent, 20.seconds) }
}
}
step(StepCue.Text("Dracula", "Darf ich bitten?")) {
actors {
-"Dracula / durch Mitte"
-"Lucy / durch Mitte"
}
}
songRepriseMaskenball()
}
scene("Van Helsing") {
step(StepCue.Text("Tante 1", "Verhungert!")) {
actors {
+"Hawkins / durch Mitte"
+"Dr. Sewart / durch Mitte"
+"Van Helsing / durch Mitte"
}
}
step(StepCue.Text("Van Helsing", "Alle raus, habe ich gesagt!")) {
actors {
-"Besucher des Maskenballs / durch Mitte"
-"Kaffeetanten / durch Mitte"
-"Hawkins / durch Mitte"
}
}
lightStep(StepCue.Custom("Lucy bedroht Dr. Sewart (mit Musik)")) {
BlinderBars.all {
it.brightness.fade(100.percent, 2.seconds)
it.preset.static(StairvilleSplb.Preset.STUB) // switching, hectic
it.presetSpeed.static(100.percent)
}
}
}
} }

View file

@ -7,10 +7,12 @@ import de.moritzruth.theaterdsl.dmx.DmxAddress
import de.moritzruth.theaterdsl.dmx.DmxDataWriter import de.moritzruth.theaterdsl.dmx.DmxDataWriter
import de.moritzruth.theaterdsl.dmx.DmxValue import de.moritzruth.theaterdsl.dmx.DmxValue
import de.moritzruth.theaterdsl.value.Color import de.moritzruth.theaterdsl.value.Color
import de.moritzruth.theaterdsl.value.Percentage
import de.moritzruth.theaterdsl.value.degrees import de.moritzruth.theaterdsl.value.degrees
import de.moritzruth.theaterdsl.value.percent import de.moritzruth.theaterdsl.value.percent
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.persistentSetOf
import kotlin.math.pow
class StairvilleClb4(override val firstChannel: DmxAddress) : Device { class StairvilleClb4(override val firstChannel: DmxAddress) : Device {
override val numberOfChannels: UInt = 14u override val numberOfChannels: UInt = 14u
@ -41,7 +43,9 @@ class StairvilleClb4(override val firstChannel: DmxAddress) : Device {
} }
writer.writePercentage(strobeSpeed.getCurrentValue()) writer.writePercentage(strobeSpeed.getCurrentValue())
writer.writePercentage(brightness.getCurrentValue())
val adjustedBrightness = brightness.getCurrentValue().value.pow(2.5)
writer.writePercentage(Percentage(adjustedBrightness))
} }
val brightness = PercentageDV(0.percent) val brightness = PercentageDV(0.percent)

View file

@ -5,7 +5,9 @@ import de.moritzruth.theaterdsl.device.Device
import de.moritzruth.theaterdsl.device.PercentageDV import de.moritzruth.theaterdsl.device.PercentageDV
import de.moritzruth.theaterdsl.dmx.DmxAddress import de.moritzruth.theaterdsl.dmx.DmxAddress
import de.moritzruth.theaterdsl.dmx.DmxDataWriter import de.moritzruth.theaterdsl.dmx.DmxDataWriter
import de.moritzruth.theaterdsl.value.Percentage
import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.persistentSetOf
import kotlin.math.pow
class StairvilleTlb(override val firstChannel: DmxAddress) : Device { class StairvilleTlb(override val firstChannel: DmxAddress) : Device {
override val numberOfChannels: UInt = 5u override val numberOfChannels: UInt = 5u
@ -15,7 +17,9 @@ class StairvilleTlb(override val firstChannel: DmxAddress) : Device {
writer.writePercentage(red) writer.writePercentage(red)
writer.writePercentage(green) writer.writePercentage(green)
writer.writePercentage(blue) writer.writePercentage(blue)
writer.writePercentage(brightness.getCurrentValue())
val adjustedBrightness = brightness.getCurrentValue().value.pow(2.5)
writer.writePercentage(Percentage(adjustedBrightness))
writer.writePercentage(strobeSpeed.getCurrentValue()) writer.writePercentage(strobeSpeed.getCurrentValue())
} }

View file

@ -162,7 +162,7 @@ fun SceneBuilderContext.songDraculasZorn() {
} }
} }
lightStep(StepCue.Custom("Musik: Einsatz der E-Gitarre")) { lightStep(StepCue.Custom("Musik: Einsetzen der E-Gitarre")) {
backlightBar.color.fade(Color(hue = 0.degrees, saturation = 100.percent), 2.seconds) backlightBar.color.fade(Color(hue = 0.degrees, saturation = 100.percent), 2.seconds)
backlightBar.brightness.fade(75.percent, 2.seconds) backlightBar.brightness.fade(75.percent, 2.seconds)
@ -245,7 +245,7 @@ fun SceneBuilderContext.songDraculasZorn() {
Washs.both { it.brightness.fade(100.percent, 2.seconds) } Washs.both { it.brightness.fade(100.percent, 2.seconds) }
} }
lightStep(StepCue.Custom("Musik: Einsatz der E-Gitarre")) { lightStep(StepCue.Custom("Musik: Einsetzen der E-Gitarre")) {
backlightBar.strobeSpeed.fade(80.percent, 3.seconds) backlightBar.strobeSpeed.fade(80.percent, 3.seconds)
BlinderBars.all { BlinderBars.all {

View file

@ -0,0 +1,93 @@
package de.moritzruth.dracula_musical.song
import de.moritzruth.dracula_musical.device.*
import de.moritzruth.theaterdsl.show.SceneBuilderContext
import de.moritzruth.theaterdsl.show.StepCue
import de.moritzruth.theaterdsl.value.Color
import de.moritzruth.theaterdsl.value.degrees
import de.moritzruth.theaterdsl.value.percent
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
fun SceneBuilderContext.songDuettDraculaMina() {
step(StepCue.MusicStart("Duett: Dracula & Mina", 4.minutes + 30.seconds)) {
rightSpotTarget = "Mina"
rightSpotTarget = "Dracula"
onRun {
FrontLights.all { it.brightness.fade(25.percent, 30.seconds) }
Spots.right.brightness.fade(100.percent, 30.seconds)
Spots.left.brightness.fade(100.percent, 30.seconds)
backlightBar.brightness.off(20.seconds)
sidelight.brightness.fade(50.percent, 50.seconds)
sidelight.color1.fadeRandomAround(25.degrees, 30.degrees, 10.seconds)
sidelight.color2.fadeRandomAround(230.degrees, 30.degrees, 10.seconds)
sidelight.color3.fadeRandomAround(25.degrees, 30.degrees, 10.seconds)
sidelight.color4.fadeRandomAround(230.degrees, 30.degrees, 10.seconds)
}
}
lightStep(StepCue.Custom("Musik: Strophe")) {
FrontLights.all { it.brightness.off(15.seconds) }
}
lightStep(StepCue.Text("Mina", "Ich kenne dich!", "Anfang")) {
BlinderBars.all {
it.preset.static(StairvilleSplb.Preset.STUB) // flowy, dreamy
it.presetSpeed.static(10.percent)
it.brightness.fade(25.percent, 2.seconds)
}
Washs.both {
it.pointAtAudience()
it.colorWheelMode.static(CoemarProWash.ColorWheelMode.DarkBlue)
}
Tops.both {
it.startRoomMovement(2.5)
it.colorWheelMode.static(FuturelightDmh160.ColorWheelMode.Rotate(10.percent))
it.prismMode.static(FuturelightDmh160.PrismMode.FACETS_8)
it.prismRotationSpeed.static(5.percent)
}
}
lightStep(StepCue.Text("Dracula", "…mit aller Kraft!", "letzte Silbe")) {
Washs.both {
it.pointAtCeiling(9.seconds)
it.brightness.fade(100.percent, 3.seconds)
}
}
lightStep(StepCue.Text("Mina", "Komm zu mir!", "Anfang")) {
Tops.both { it.brightness.fade(100.percent, 3.seconds) }
}
lightStep(StepCue.Text("Dracula", "Komm zu mir!", "Anfang")) {
Washs.both { it.brightness.off(4.seconds) }
}
lightStep(StepCue.Text("Dracula & Mina", "Komm!", "Anfang")) {
Tops.both { it.brightness.off(4.seconds) }
Washs.both {
it.pointAtStageCenter()
it.colorWheelMode.static(CoemarProWash.ColorWheelMode.Red)
it.beamAngle.static(0.percent)
}
Spots.right.brightness.off(6.seconds)
sidelight.brightness.off(6.seconds)
backlightBar.color.static(Color.RED)
backlightBar.brightness.fade(100.percent, 6.seconds)
}
lightStep(StepCue.MusicEnd) {
Spots.left.brightness.off(3.seconds)
backlightBar.brightness.pulse(1.8.seconds, 0.15.seconds, 0.2.seconds, startDelay = 0.seconds)
sidelight.brightness.pulse(1.8.seconds, 0.15.seconds, 0.3.seconds, startDelay = 0.4.seconds)
Washs.both { it.brightness.pulse(1.8.seconds, 0.15.seconds, 0.3.seconds, startDelay = 0.4.seconds) }
}
}

View file

@ -9,7 +9,7 @@ import de.moritzruth.theaterdsl.value.percent
import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
fun SceneBuilderContext.songDuett() { fun SceneBuilderContext.songDuettMinaJonathan() {
lightStep(StepCue.MusicStart("Duett", 3.minutes + 15.seconds)) { lightStep(StepCue.MusicStart("Duett", 3.minutes + 15.seconds)) {
FrontLights.all { it.brightness.fade(40.percent, 5.seconds) } FrontLights.all { it.brightness.fade(40.percent, 5.seconds) }
Washs.both { Washs.both {

View file

@ -28,7 +28,7 @@ fun SceneBuilderContext.songEsIstAngerichtet() {
} }
} }
lightStep(StepCue.Custom("Musik: Drums setzen ein")) { lightStep(StepCue.Custom("Musik: Einsetzen der Drums")) {
backlightBar.brightness.pulse(1.6.seconds, 0.15.seconds, 0.2.seconds, startDelay = 0.seconds, peak = 20.percent) backlightBar.brightness.pulse(1.6.seconds, 0.15.seconds, 0.2.seconds, startDelay = 0.seconds, peak = 20.percent)
Washs.both { it.brightness.pulse(1.6.seconds, 0.1.seconds, 0.3.seconds, startDelay = 0.4.seconds, peak = 100.percent) } Washs.both { it.brightness.pulse(1.6.seconds, 0.1.seconds, 0.3.seconds, startDelay = 0.4.seconds, peak = 100.percent) }

View file

@ -556,7 +556,7 @@ fun SceneBuilderContext.songFinaleErsterAkt() {
props { props {
it[PropPosition.LEFT] = null it[PropPosition.LEFT] = null
it[PropPosition.BACKDROP] = "Dorfplatz"
} }
curtainState = CurtainState.CLOSED curtainState = CurtainState.CLOSED

View file

@ -0,0 +1,89 @@
package de.moritzruth.dracula_musical.song
import de.moritzruth.dracula_musical.device.*
import de.moritzruth.theaterdsl.show.CurtainState
import de.moritzruth.theaterdsl.show.SceneBuilderContext
import de.moritzruth.theaterdsl.show.StepCue
import de.moritzruth.theaterdsl.value.Color
import de.moritzruth.theaterdsl.value.degrees
import de.moritzruth.theaterdsl.value.percent
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
fun SceneBuilderContext.songMaskenball() {
step(StepCue.MusicStart("Maskenball", 2.minutes + 20.seconds)) {
actors {
+"Hawkins / von links"
+"Eloïse / von links"
+"Françoise / von links"
+"Bernadette / von links"
// TODO: Expand
+"Besucher des Maskenballs / von links & durch Mitte"
}
curtainState = CurtainState.OPEN
onRun {
backlightBar.color.static(Color(hue = 310.degrees, saturation = 80.percent))
backlightBar.brightness.fade(40.percent, 5.seconds)
Tops.both {
it.startRoomMovement(5.0)
it.colorWheelMode.static(FuturelightDmh160.ColorWheelMode.Rotate(60.percent))
it.prismMode.static(FuturelightDmh160.PrismMode.FACETS_3)
it.prismRotationSpeed.static(10.percent)
}
Washs.both {
it.pointAtCeiling()
it.colorWheelMode.static(CoemarProWash.ColorWheelMode.Rotate(80.percent))
}
}
}
lightStep(StepCue.Custom("Musik: Einsetzen der Drums")) {
backlightBar.color.cycle(8.seconds)
backlightBar.brightness.fade(80.percent, 5.seconds)
Tops.both { it.brightness.fade(100.percent, 1.seconds) }
Washs.both { it.brightness.fade(100.percent, 1.seconds) }
FrontLights.all { it.brightness.fade(100.percent, 2.seconds) }
BlinderBars.all {
it.preset.static(StairvilleSplb.Preset.STUB) // theatre-like, warm
it.presetSpeed.static(40.percent)
it.brightness.fade(25.percent, 2.seconds)
}
}
lightStep(StepCue.Custom("Musik: Breakdown am Ende")) {
BlinderBars.all { it.presetSpeed.fade(0.percent, 5.seconds) }
Washs.both { it.brightness.off(5.seconds) }
}
lightStep(StepCue.Custom("Musik: Schlussschlag")) {
backlightBar.color.cycle(20.seconds)
Tops.both { it.brightness.off(5.seconds) }
Washs.both { it.brightness.pulseOnce(0.2.seconds, 5.seconds) }
BlinderBars.all { it.brightness.off(5.seconds) }
}
step(StepCue.MusicEnd) {
actors {
-"Eloïse / durch Mitte"
-"Françoise / durch Mitte"
-"Bernadette / durch Mitte"
-"Besucher des Maskenballs / durch Mitte"
+"Van Helsing / durch Mitte"
+"Dr. Sewart / durch Mitte"
+"Ascot / durch Mitte"
+"Oberschwester / durch Mitte"
+"Lucy / durch Mitte"
+"Mina / steht rechts"
}
onRun {
backlightBar.brightness.fade(20.percent, 5.seconds)
}
}
}

View file

@ -0,0 +1,66 @@
package de.moritzruth.dracula_musical.song
import de.moritzruth.dracula_musical.device.*
import de.moritzruth.theaterdsl.show.SceneBuilderContext
import de.moritzruth.theaterdsl.show.StepCue
import de.moritzruth.theaterdsl.value.Color
import de.moritzruth.theaterdsl.value.percent
import kotlin.time.Duration.Companion.seconds
fun SceneBuilderContext.songRepriseMaskenball() {
step(StepCue.MusicStart("Reprise: Maskenball", 50.seconds)) {
actors {
// TODO: Expand
+"Besucher des Maskenballs / durch Mitte"
+"Kaffeetanten / durch Mitte"
+"Lucy / im Off" // TODO: which side?
}
onRun {
Tops.both {
it.startRoomMovement(5.0)
it.colorWheelMode.static(FuturelightDmh160.ColorWheelMode.Rotate(60.percent))
it.prismMode.static(FuturelightDmh160.PrismMode.FACETS_3)
it.prismRotationSpeed.static(10.percent)
it.brightness.fade(100.percent, 3.seconds)
}
Washs.both {
it.pointAtCeiling()
it.colorWheelMode.static(CoemarProWash.ColorWheelMode.Rotate(80.percent))
it.brightness.fade(100.percent, 3.seconds)
}
backlightBar.color.cycle(8.seconds)
backlightBar.brightness.fade(50.percent, 3.seconds)
BlinderBars.all {
it.preset.static(StairvilleSplb.Preset.STUB) // theatre-like, warm
it.presetSpeed.static(40.percent)
it.brightness.fade(25.percent, 2.seconds)
}
}
}
lightStep(StepCue.Custom("Lucy schreit")) {
Tops.both {
it.pan.static(it.pan.getCurrentValue())
it.tilt.static(it.pan.getCurrentValue())
it.colorWheelMode.static(FuturelightDmh160.ColorWheelMode.White)
it.prismMode.static(FuturelightDmh160.PrismMode.FROST)
it.brightness.off(10.seconds)
}
backlightBar.color.fade(Color.WARM_WHITE, 0.5.seconds)
backlightBar.brightness.pulseOnce(2.seconds, 6.seconds, end = 30.percent)
BlinderBars.all {
it.presetSpeed.fade(0.percent, 2.seconds)
it.brightness.pulseOnce(1.seconds, 3.seconds, peak = 50.percent)
}
FrontLights.all { it.brightness.fade(100.percent, 5.seconds) }
}
step(StepCue.MusicEnd) {}
}

View file

@ -236,7 +236,9 @@ class ColorDV(private val initialStaticValue: Color = Color.WHITE) : DynamicValu
data class Cycle(val start: Color, val interval: Duration) : State data class Cycle(val start: Color, val interval: Duration) : State
data class FadeRandomAround(val hue: Angle, val deviation: Angle, val interval: Duration) : State data class FadeRandomAround(val hue: Angle, val deviation: Angle, val interval: Duration) : State {
val seed: Int = Random.nextInt()
}
} }
private var stateChangeMark = TimeSource.Monotonic.markNow() private var stateChangeMark = TimeSource.Monotonic.markNow()
@ -271,8 +273,8 @@ class ColorDV(private val initialStaticValue: Color = Color.WHITE) : DynamicValu
} }
is State.FadeRandomAround -> { is State.FadeRandomAround -> {
val startRandom = Random((elapsedTime / s.interval).toInt() - 1) val startRandom = Random(((elapsedTime / s.interval).toInt() - 1).xor(s.seed))
val endRandom = Random((elapsedTime / s.interval).toInt()) val endRandom = Random((elapsedTime / s.interval).toInt().xor(s.seed))
val progress = (elapsedTime / s.interval).mod(1.0) val progress = (elapsedTime / s.interval).mod(1.0)
val startHue = s.hue.degrees - s.deviation.degrees + startRandom.nextDouble() * s.deviation.degrees * 2 val startHue = s.hue.degrees - s.deviation.degrees + startRandom.nextDouble() * s.deviation.degrees * 2
val endHue = s.hue.degrees - s.deviation.degrees + endRandom.nextDouble() * s.deviation.degrees * 2 val endHue = s.hue.degrees - s.deviation.degrees + endRandom.nextDouble() * s.deviation.degrees * 2