summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/demo.seq110
-rw-r--r--doc/SEQUENCE.md53
-rw-r--r--src/generated/timeline.cc26
-rw-r--r--tools/seq_compiler.cc45
4 files changed, 147 insertions, 87 deletions
diff --git a/assets/demo.seq b/assets/demo.seq
index 35935a7..44df234 100644
--- a/assets/demo.seq
+++ b/assets/demo.seq
@@ -8,10 +8,10 @@
#
# QUICK REFERENCE:
# SEQUENCE <start> <priority> [optional_end]
-# EFFECT <ClassName> <start> <end> <priority>
+# EFFECT <+|=|-> <ClassName> <start> <end>
#
+# Priority modifiers: + (increment), = (same), - (decrement/background)
# Time notation: 0b (beats), 0.0 (seconds)
-# Priority: Higher numbers render later (on top)
#
# VALIDATION & VISUALIZATION:
# ./build/seq_compiler assets/demo.seq # Validate only
@@ -19,86 +19,88 @@
#
# ============================================================================
+# BPM 120
+
SEQUENCE 0b 0
- EFFECT FlashEffect 0.0 1. 0
- EFFECT FadeEffect 0.1 1. 1 # Add fade
- EFFECT FlashCubeEffect .2 3 -1 # Background cube (priority -1 = behind everything)
- EFFECT SolarizeEffect 0 4b 3 # Color inversion (last)
+ EFFECT - FlashCubeEffect .2 3 # Background cube (priority -1 = behind everything)
+ EFFECT + FlashEffect 0.0 1. # Priority 0
+ EFFECT + FadeEffect 0.1 1. # Priority 1
+ EFFECT + SolarizeEffect 0 4b # Priority 2 (was 3, now contiguous)
SEQUENCE 4b 0
- EFFECT FlashEffect 0.0 0.2 4 # Add flash after solarize
- EFFECT FlashCubeEffect 0.1 3. -1
+ EFFECT - FlashCubeEffect 0.1 3. # Priority -1
+ EFFECT + FlashEffect 0.0 0.2 # Priority 0 (was 4, now contiguous)
SEQUENCE 6b 1
- EFFECT ParticlesEffect 0 4 1 # Particles layer
- EFFECT GaussianBlurEffect 0 8 1 # Blur
+ EFFECT + ParticlesEffect 0 4 # Priority 0
+ EFFECT = GaussianBlurEffect 0 8 # Priority 0 (same layer)
SEQUENCE 7b 0
- EFFECT FadeEffect 0.1 1.0 5 # Add fade
- EFFECT HeptagonEffect 0.0 .2 0 # Main geometric effect
+ EFFECT + HeptagonEffect 0.0 .2 # Priority 0
+ EFFECT + FadeEffect 0.1 1.0 # Priority 1 (was 5, now contiguous)
# Post-processing chain (priority 10 = applied after scene rendering)
# Effects are applied in priority order: lower numbers first
SEQUENCE 8b 3
- EFFECT ThemeModulationEffect 0 4 0 # Brightness modulation (first)
- EFFECT HeptagonEffect 0.0 4.0 0 # Main geometric effect
- EFFECT GaussianBlurEffect 0 8 1 # Blur
- EFFECT ChromaAberrationEffect 0 6 2 # Color separation
- EFFECT SolarizeEffect 0 10 3 # Color inversion (last)
+ EFFECT + ThemeModulationEffect 0 4 # Priority 0
+ EFFECT = HeptagonEffect 0.0 4.0 # Priority 0 (same layer)
+ EFFECT + GaussianBlurEffect 0 8 # Priority 1
+ EFFECT + ChromaAberrationEffect 0 6 # Priority 2
+ EFFECT + SolarizeEffect 0 10 # Priority 3
SEQUENCE 12b 2
- EFFECT FlashCubeEffect .2 3 -1 # Background cube (priority -1 = behind everything)
- EFFECT HeptagonEffect 0 4 0
- EFFECT ParticlesEffect 0 4 1 # Particles layer
+ EFFECT - FlashCubeEffect .2 3 # Priority -1 (background)
+ EFFECT + HeptagonEffect 0 4 # Priority 0
+ EFFECT + ParticlesEffect 0 4 # Priority 1
SEQUENCE 15b 2
- EFFECT FlashCubeEffect .2 3 -1 # Background cube (priority -1 = behind everything)
- EFFECT FlashEffect 0.0 1 0
+ EFFECT - FlashCubeEffect .2 3 # Priority -1 (background)
+ EFFECT + FlashEffect 0.0 1 # Priority 0
SEQUENCE 16b 10
- EFFECT FlashCubeEffect .2 3 -1 # Background cube (priority -1 = behind everything)
- EFFECT GaussianBlurEffect 0 8 1 # Blur
- EFFECT FlashEffect 0.0 0.2 4 # Add flash after solarize
- EFFECT FlashEffect 1b 0.2 4 # Add flash after solarize
+ EFFECT - FlashCubeEffect .2 3 # Priority -1 (background)
+ EFFECT + GaussianBlurEffect 0 8 # Priority 0
+ EFFECT + FlashEffect 0.0 0.2 # Priority 1
+ EFFECT = FlashEffect 1b 0.2 # Priority 1 (same layer)
SEQUENCE 17b 2
- EFFECT ThemeModulationEffect 0 4 0 # Brightness modulation (first)
- EFFECT HeptagonEffect 0.2 2.0 1 # Main geometric effect
- EFFECT ParticlesEffect 0 4 1 # Particles layer
- EFFECT GaussianBlurEffect 0 8 3 # Blur
- EFFECT Hybrid3DEffect 0 4 2 # 3D objects (priority 2 = foreground)
- EFFECT ChromaAberrationEffect 0 6 4 # Color separation
+ EFFECT + ThemeModulationEffect 0 4 # Priority 0
+ EFFECT + HeptagonEffect 0.2 2.0 # Priority 1
+ EFFECT = ParticlesEffect 0 4 # Priority 1 (same layer)
+ EFFECT + Hybrid3DEffect 0 4 # Priority 2
+ EFFECT + GaussianBlurEffect 0 8 # Priority 3
+ EFFECT + ChromaAberrationEffect 0 6 # Priority 4
SEQUENCE 24b 1
- EFFECT ThemeModulationEffect 0 8 0 # Brightness modulation (first)
- EFFECT HeptagonEffect 0.2 2.0 1 # Main geometric effect
- EFFECT Hybrid3DEffect 0 20 2 # 3D objects (priority 2 = foreground)
- EFFECT GaussianBlurEffect 0 8 3 # Blur
- EFFECT ChromaAberrationEffect 0 10 4 # Color separation
- EFFECT SolarizeEffect 0 10 5 # Color inversion (last)
+ EFFECT + ThemeModulationEffect 0 8 # Priority 0
+ EFFECT + HeptagonEffect 0.2 2.0 # Priority 1
+ EFFECT + Hybrid3DEffect 0 20 # Priority 2
+ EFFECT + GaussianBlurEffect 0 8 # Priority 3
+ EFFECT + ChromaAberrationEffect 0 10 # Priority 4
+ EFFECT + SolarizeEffect 0 10 # Priority 5
SEQUENCE 32b 0
- EFFECT ThemeModulationEffect 0 4 0 # Brightness modulation (first)
- EFFECT HeptagonEffect 0 16 1 # Main geometric effect
- EFFECT ChromaAberrationEffect 0 16 3 # Color separation
- EFFECT GaussianBlurEffect 0 8 4 # Blur
+ EFFECT + ThemeModulationEffect 0 4 # Priority 0
+ EFFECT + HeptagonEffect 0 16 # Priority 1
+ EFFECT + ChromaAberrationEffect 0 16 # Priority 2
+ EFFECT + GaussianBlurEffect 0 8 # Priority 3
SEQUENCE 48b 0
- EFFECT ThemeModulationEffect 0 4 0 # Brightness modulation (first)
- EFFECT HeptagonEffect 0.2 2.0 1 # Main geometric effect
- EFFECT GaussianBlurEffect 0 8 3 # Blur
- EFFECT SolarizeEffect 0 2 5 # Color inversion (last)
+ EFFECT + ThemeModulationEffect 0 4 # Priority 0
+ EFFECT + HeptagonEffect 0.2 2.0 # Priority 1
+ EFFECT + GaussianBlurEffect 0 8 # Priority 2
+ EFFECT + SolarizeEffect 0 2 # Priority 3
SEQUENCE 56b 0
- EFFECT ThemeModulationEffect 0 8 0 # Brightness modulation (first)
- EFFECT HeptagonEffect 0.2 2.0 0 # Main geometric effect
- EFFECT Hybrid3DEffect 0 4 1 # 3D objects (priority 2 = foreground)
- EFFECT HeptagonEffect 0 16 2 # Main geometric effect
- EFFECT ChromaAberrationEffect 0 16 3 # Color separation
- EFFECT GaussianBlurEffect 0 8 4 # Blur
+ EFFECT + ThemeModulationEffect 0 8 # Priority 0
+ EFFECT = HeptagonEffect 0.2 2.0 # Priority 0 (same layer)
+ EFFECT + Hybrid3DEffect 0 4 # Priority 1
+ EFFECT + HeptagonEffect 0 16 # Priority 2
+ EFFECT + ChromaAberrationEffect 0 16 # Priority 3
+ EFFECT + GaussianBlurEffect 0 8 # Priority 4
SEQUENCE 62b 0
- EFFECT ThemeModulationEffect 0 3 0 # Brightness modulation (first)
- EFFECT SolarizeEffect 0 3 5 # Color inversion (last)
+ EFFECT + ThemeModulationEffect 0 3 # Priority 0
+ EFFECT + SolarizeEffect 0 3 # Priority 1
# Demo automatically exits at this time (supports beat notation)
END_DEMO 65b
diff --git a/doc/SEQUENCE.md b/doc/SEQUENCE.md
index 05cdc93..614339e 100644
--- a/doc/SEQUENCE.md
+++ b/doc/SEQUENCE.md
@@ -79,17 +79,26 @@ SEQUENCE <global_start> <priority> [optional_end]
### EFFECT Declaration
```
-EFFECT <EffectClassName> <local_start> <local_end> <priority> [constructor_args...]
+EFFECT <+|=|-> <EffectClassName> <local_start> <local_end> [constructor_args...]
```
**Parameters:**
+- Priority modifier (one of):
+ - `+`: Increment priority (or start at 0 if first effect)
+ - `=`: Keep same priority as previous effect
+ - `-`: Decrement priority (or start at -1 if first effect, for background layers)
- `EffectClassName`: C++ class name (must be declared in `demo_effects.h`)
- `local_start`: Start time relative to sequence start (beats or seconds)
- `local_end`: End time relative to sequence start (beats or seconds)
-- `priority`: Render order within sequence (lower = drawn first/background)
- - Negative priorities draw behind everything
- `constructor_args`: Optional additional parameters (rarely used)
+**Priority System:**
+- Effects are assigned priorities based on their order in the file
+- First effect: `+` starts at 0, `-` starts at -1, `=` starts at 0
+- Subsequent effects: `+` increments, `=` keeps same, `-` decrements
+- Priorities determine render order (lower = drawn first/background)
+- Effects should be listed in desired priority order within each sequence
+
---
## Time Notation
@@ -223,36 +232,46 @@ White flash on strong beat hits.
### Basic Sequence
```
SEQUENCE 0 0
- EFFECT FlashEffect 0.0 0.5 1 # Starts immediately, runs 0.5s, priority 1
- EFFECT HeptagonEffect 0.2 10 0 # Starts at 0.2s, runs until 10s, priority 0
+ EFFECT + FlashEffect 0.0 0.5 # Priority 0 (first with +)
+ EFFECT + HeptagonEffect 0.2 10 # Priority 1 (increment)
+```
+
+### Same Priority (Layered Effects)
+```
+SEQUENCE 0 0
+ EFFECT + Flash 0.0 0.5 # Priority 0
+ EFFECT = Fade 0.1 0.3 # Priority 0 (same as Flash)
+ EFFECT + Other 0.2 3 # Priority 1 (increment)
+```
+
+### Background Elements
+```
+SEQUENCE 0 0
+ EFFECT - FlashCube 0 10 # Priority -1 (background)
+ EFFECT = BgEffect 0 5 # Priority -1 (same layer)
+ EFFECT + MainEffect 0 10 # Priority 0 (foreground)
```
### Sequence with Explicit End Time
```
SEQUENCE 8b 0 [5.0]
- EFFECT ParticlesEffect 0 120 1 # Would run 120s, but sequence ends at 5s
+ EFFECT + Particles 0 120 # Would run 120s, but sequence ends at 5s
```
### Post-Processing Chain
```
SEQUENCE 0 10
- EFFECT GaussianBlurEffect 0 60 1 # Applied first
- EFFECT ChromaAberrationEffect 0 60 2 # Applied second
- EFFECT SolarizeEffect 0 60 3 # Applied last
-```
-
-### Background Element
-```
-SEQUENCE 0 0
- EFFECT FlashCubeEffect 0 10 -1 # priority -1 = background layer
+ EFFECT + GaussianBlur 0 60 # Priority 0 (applied first)
+ EFFECT + ChromaAberration 0 60 # Priority 1 (applied second)
+ EFFECT + Solarize 0 60 # Priority 2 (applied last)
```
### Music-Synchronized Effects
```
# BPM 120
SEQUENCE 0b 0 # Start at beat 0 (0.0s)
- EFFECT FlashEffect 0b 1b 1 # Flash from beat 0 to beat 1 (0-0.5s)
- EFFECT HeptagonEffect 4b 8b 0 # Main effect from beat 4 to 8 (2-4s)
+ EFFECT + Flash 0b 1b # Flash from beat 0 to beat 1 (0-0.5s)
+ EFFECT + Heptagon 4b 8b # Main effect from beat 4 to 8 (2-4s)
```
---
diff --git a/src/generated/timeline.cc b/src/generated/timeline.cc
index 381c403..0b69b09 100644
--- a/src/generated/timeline.cc
+++ b/src/generated/timeline.cc
@@ -12,35 +12,35 @@ void LoadTimeline(MainSequence& main_seq, WGPUDevice device, WGPUQueue queue, WG
seq->add_effect(std::make_shared<FlashCubeEffect>(device, queue, format), .2f, 1.500000f, -1);
seq->add_effect(std::make_shared<FlashEffect>(device, queue, format), 0.0f, 1.f, 0);
seq->add_effect(std::make_shared<FadeEffect>(device, queue, format), 0.1f, 1.f, 1);
- seq->add_effect(std::make_shared<SolarizeEffect>(device, queue, format), 0.000000f, 2.000000f, 3);
+ seq->add_effect(std::make_shared<SolarizeEffect>(device, queue, format), 0.000000f, 2.000000f, 2);
main_seq.add_sequence(seq, 0.000000f, 0);
}
{
auto seq = std::make_shared<Sequence>();
seq->add_effect(std::make_shared<FlashCubeEffect>(device, queue, format), 0.1f, 3.f, -1);
- seq->add_effect(std::make_shared<FlashEffect>(device, queue, format), 0.0f, 0.2f, 4);
+ seq->add_effect(std::make_shared<FlashEffect>(device, queue, format), 0.0f, 0.2f, 0);
main_seq.add_sequence(seq, 2.000000f, 0);
}
{
auto seq = std::make_shared<Sequence>();
seq->add_effect(std::make_shared<HeptagonEffect>(device, queue, format), 0.0f, .2f, 0);
- seq->add_effect(std::make_shared<FadeEffect>(device, queue, format), 0.1f, 1.0f, 5);
+ seq->add_effect(std::make_shared<FadeEffect>(device, queue, format), 0.1f, 1.0f, 1);
main_seq.add_sequence(seq, 3.500000f, 0);
}
{
auto seq = std::make_shared<Sequence>();
seq->add_effect(std::make_shared<ThemeModulationEffect>(device, queue, format), 0.000000f, 2.000000f, 0);
seq->add_effect(std::make_shared<HeptagonEffect>(device, queue, format), 0.000000f, 8.000000f, 1);
- seq->add_effect(std::make_shared<ChromaAberrationEffect>(device, queue, format), 0.000000f, 8.000000f, 3);
- seq->add_effect(std::make_shared<GaussianBlurEffect>(device, queue, format), 0.000000f, 4.000000f, 4);
+ seq->add_effect(std::make_shared<ChromaAberrationEffect>(device, queue, format), 0.000000f, 8.000000f, 2);
+ seq->add_effect(std::make_shared<GaussianBlurEffect>(device, queue, format), 0.000000f, 4.000000f, 3);
main_seq.add_sequence(seq, 16.000000f, 0);
}
{
auto seq = std::make_shared<Sequence>();
seq->add_effect(std::make_shared<ThemeModulationEffect>(device, queue, format), 0.000000f, 2.000000f, 0);
seq->add_effect(std::make_shared<HeptagonEffect>(device, queue, format), 0.2f, 2.0f, 1);
- seq->add_effect(std::make_shared<GaussianBlurEffect>(device, queue, format), 0.000000f, 4.000000f, 3);
- seq->add_effect(std::make_shared<SolarizeEffect>(device, queue, format), 0.000000f, 1.000000f, 5);
+ seq->add_effect(std::make_shared<GaussianBlurEffect>(device, queue, format), 0.000000f, 4.000000f, 2);
+ seq->add_effect(std::make_shared<SolarizeEffect>(device, queue, format), 0.000000f, 1.000000f, 3);
main_seq.add_sequence(seq, 24.000000f, 0);
}
{
@@ -56,13 +56,13 @@ void LoadTimeline(MainSequence& main_seq, WGPUDevice device, WGPUQueue queue, WG
{
auto seq = std::make_shared<Sequence>();
seq->add_effect(std::make_shared<ThemeModulationEffect>(device, queue, format), 0.000000f, 1.500000f, 0);
- seq->add_effect(std::make_shared<SolarizeEffect>(device, queue, format), 0.000000f, 1.500000f, 5);
+ seq->add_effect(std::make_shared<SolarizeEffect>(device, queue, format), 0.000000f, 1.500000f, 1);
main_seq.add_sequence(seq, 31.000000f, 0);
}
{
auto seq = std::make_shared<Sequence>();
- seq->add_effect(std::make_shared<ParticlesEffect>(device, queue, format), 0.000000f, 2.000000f, 1);
- seq->add_effect(std::make_shared<GaussianBlurEffect>(device, queue, format), 0.000000f, 4.000000f, 1);
+ seq->add_effect(std::make_shared<ParticlesEffect>(device, queue, format), 0.000000f, 2.000000f, 0);
+ seq->add_effect(std::make_shared<GaussianBlurEffect>(device, queue, format), 0.000000f, 4.000000f, 0);
main_seq.add_sequence(seq, 3.000000f, 1);
}
{
@@ -110,9 +110,9 @@ void LoadTimeline(MainSequence& main_seq, WGPUDevice device, WGPUQueue queue, WG
{
auto seq = std::make_shared<Sequence>();
seq->add_effect(std::make_shared<FlashCubeEffect>(device, queue, format), .2f, 1.500000f, -1);
- seq->add_effect(std::make_shared<GaussianBlurEffect>(device, queue, format), 0.000000f, 4.000000f, 1);
- seq->add_effect(std::make_shared<FlashEffect>(device, queue, format), 0.0f, 0.2f, 4);
- seq->add_effect(std::make_shared<FlashEffect>(device, queue, format), 0.500000f, 0.2f, 4);
+ seq->add_effect(std::make_shared<GaussianBlurEffect>(device, queue, format), 0.000000f, 4.000000f, 0);
+ seq->add_effect(std::make_shared<FlashEffect>(device, queue, format), 0.0f, 0.2f, 1);
+ seq->add_effect(std::make_shared<FlashEffect>(device, queue, format), 0.500000f, 0.2f, 1);
main_seq.add_sequence(seq, 8.000000f, 10);
}
}
diff --git a/tools/seq_compiler.cc b/tools/seq_compiler.cc
index 45cfc1a..7ac921f 100644
--- a/tools/seq_compiler.cc
+++ b/tools/seq_compiler.cc
@@ -467,13 +467,52 @@ int main(int argc, char* argv[]) {
<< ": EFFECT found outside of SEQUENCE\n";
return 1;
}
- std::string class_name, start, end, priority;
- if (!(ss >> class_name >> start >> end >> priority)) {
+ std::string priority_mod, class_name, start, end;
+ if (!(ss >> priority_mod >> class_name >> start >> end)) {
std::cerr << "Error line " << line_num
- << ": EFFECT requires <Class> <start> <end> <priority>\n";
+ << ": EFFECT requires <+|=|-> <Class> <start> <end>\n";
return 1;
}
+ // Validate priority modifier
+ if (priority_mod != "+" && priority_mod != "=" && priority_mod != "-") {
+ std::cerr << "Error line " << line_num
+ << ": Priority modifier must be '+', '=', or '-', got: " << priority_mod << "\n";
+ return 1;
+ }
+
+ // Calculate priority based on modifier and sequence state
+ static int current_priority = 0;
+ static bool first_in_sequence = true;
+ static const SequenceEntry* last_seq = nullptr;
+
+ // Reset priority tracking for new sequence
+ if (current_seq != last_seq) {
+ current_priority = 0;
+ first_in_sequence = true;
+ last_seq = current_seq;
+ }
+
+ // Handle first effect in sequence
+ if (first_in_sequence) {
+ if (priority_mod == "-") {
+ current_priority = -1; // Background layer
+ } else {
+ current_priority = 0; // Default start (+ or =)
+ }
+ first_in_sequence = false;
+ } else {
+ // Update priority based on modifier for subsequent effects
+ if (priority_mod == "+") {
+ current_priority++;
+ } else if (priority_mod == "-") {
+ current_priority--;
+ }
+ // '=' keeps current_priority unchanged
+ }
+
+ std::string priority = std::to_string(current_priority);
+
// Convert beat notation to time
std::string start_time = convert_to_time(start, bpm);
std::string end_time = convert_to_time(end, bpm);