// ATTENTION: TED // // # Integrated Multi-Domain Rhema Wave Generation System // // This module implements the complete Rhema Wave generation system by synchronizing multiple // subsystems that operate simultaneously across spatial, temporal, and chromatic // domains to produce a unified frequency-structured visual output for subliminal proclamation display. // // The technology addresses the fundamental challenge of presenting textual proclamation content // in a format optimized for subconscious processing rather than conscious reading. Conventional // subliminal text systems use isolated techniques (simple masking, single-frequency flashing, or // uniform scrolling) that operate in only one domain. Our system integrates four mathematically- // synchronized subsystems, each generating Fibonacci-based patterns in different domains, creating // a compound frequency signature designed to enhance subconscious absorption while maintaining // conscious illegibility. // // The system architecture integrates: // // 1. Spatial Character Transformation - Each rendered character undergoes Fibonacci-based // block scrambling (described separately), creating local spatial frequency patterns at // the character level. // // 2. Spatial Line Distribution - Text lines contain varying word counts following an oscillating // Fibonacci sequence (1, 1, 2, 3, 5, 8, 13... then reversing), creating a macro-level // two-dimensional wave pattern in the display geometry and ensuring balanced temporal // exposure of proclamation content segments. // // 3. Temporal Color Modulation - Sequential words receive colors from an intent-based palette, // with color duration determined by an oscillating Fibonacci sequence, creating rhythmic // chromatic variation synchronized with natural mathematical progression. // // 4. Temporal Velocity Modulation - Display scroll velocity oscillates between negative and // positive extremes with acceleration/deceleration rates and hold periods, creating a // "breathing" temporal rhythm for the entire visual field. // // The key innovation lies in the temporal and mathematical synchronization of these subsystems. // All four operate on Fibonacci-derived parameters, creating harmonic relationships between the // spatial frequencies (character scrambling, line wave patterns), chromatic frequencies (color // duration oscillation), and temporal frequencies (scroll velocity modulation). This multi-domain // integration produces what we term the "Rhema Wave" - a compound frequency signature where // spatial, temporal, and chromatic patterns reinforce each other through mathematical harmony. // // Key differentiators from existing solutions: // - Integrates four distinct Fibonacci-based frequency generators in a single system // - Synchronizes pattern generation across spatial, temporal, and chromatic domains // - Creates compound frequency signatures rather than isolated single-domain effects // - Maintains character-specific and content-specific mathematical structure throughout // - Uses bidirectional oscillation across multiple subsystems for rhythmic coherence // - Combines macro-level (line patterns, velocity) and micro-level (character, color) modulation // // The system loads proclamation text content, processes it through all four subsystems simultaneously, // and generates a continuously scrolling display where every element - from individual character // pixels to overall scroll rhythm - contributes to the unified Rhema Wave output. The mathematical // relationships between subsystems create interference patterns and harmonic resonances designed // to enhance subconscious processing of the proclamation content while maintaining conscious // illegibility through the character scrambling subsystem. package page import ( "fmt" "math" "path/filepath" "strconv" "strings" "github.com/go-gl/gl/v3.3-core/gl" "github.com/veandco/go-sdl2/sdl" "rhemawavetech.com/rhemawave/internal/colors" "rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/fontManager" "rhemawavetech.com/rhemawave/internal/mixer" colorPattern "rhemawavetech.com/rhemawave/internal/pattern/color" linePattern "rhemawavetech.com/rhemawave/internal/pattern/line" "rhemawavetech.com/rhemawave/internal/shaderManager" ) type Line struct { words []StringItem width int32 } // LineDeque is a double-ended queue for Line values backed by a circular buffer. // It avoids O(n) prepend and prevents capacity leaks from head-of-slice removal. type LineDeque struct { buf []Line head, tail int count int } func NewLineDeque(cap int) *LineDeque { if cap < 4 { cap = 4 } return &LineDeque{buf: make([]Line, cap)} } func (d *LineDeque) Len() int { return d.count } func (d *LineDeque) grow() { newCap := len(d.buf) * 2 newBuf := make([]Line, newCap) for i := 0; i < d.count; i++ { newBuf[i] = d.buf[(d.head+i)%len(d.buf)] } d.buf = newBuf d.head = 0 d.tail = d.count } func (d *LineDeque) PushBack(l Line) { if d.count == len(d.buf) { d.grow() } d.buf[d.tail] = l d.tail = (d.tail + 1) % len(d.buf) d.count++ } func (d *LineDeque) PushFront(l Line) { if d.count == len(d.buf) { d.grow() } d.head = (d.head - 1 + len(d.buf)) % len(d.buf) d.buf[d.head] = l d.count++ } func (d *LineDeque) PopFront() Line { l := d.buf[d.head] d.buf[d.head] = Line{} // clear for GC d.head = (d.head + 1) % len(d.buf) d.count-- return l } func (d *LineDeque) PopBack() Line { d.tail = (d.tail - 1 + len(d.buf)) % len(d.buf) l := d.buf[d.tail] d.buf[d.tail] = Line{} // clear for GC d.count-- return l } func (d *LineDeque) Front() Line { return d.buf[d.head] } func (d *LineDeque) Back() Line { return d.buf[(d.tail-1+len(d.buf))%len(d.buf)] } func (d *LineDeque) Get(i int) *Line { return &d.buf[(d.head+i)%len(d.buf)] } func (d *LineDeque) Set(i int, l Line) { d.buf[(d.head+i)%len(d.buf)] = l } func (d *LineDeque) Clear() { for i := 0; i < d.count; i++ { d.buf[(d.head+i)%len(d.buf)] = Line{} } d.head, d.tail, d.count = 0, 0, 0 } type ScrollerPage struct { Base words []string wordIndex int lines *LineDeque lineHeight int32 fontScale float32 shader *shaderManager.Shader activePattern linePattern.LinePattern font *fontManager.FontEntry spaceWidth int32 lineCtx *linePattern.LineRenderContext colorPattern *colorPattern.ColorPattern scrollOffset float32 scrollY float32 increment float32 velocity float32 // Time-based velocity control velocityFloor float32 velocityCeiling float32 velocityStep float32 velocityDelay float32 velocityDirection int velocityTimer float32 velocityState int autoVelocity bool hold float32 } func (p *ScrollerPage) Init(app ApplicationInterface) error { p.increment = 100.0 p.velocity = 800.0 p.SetAutoVelocity(true, -4000.0, 4000.0, 100.0, 2.5, 6.0) sm := shaderManager.Get() fm := fontManager.Get() // Get font font, ok := fm.GetFont("Scrambled") if !ok { return fmt.Errorf("unable to fetch font 'Scrambled'") } p.font = font p.Base.Init(app) // Get text shader textShader, ok := sm.Get("text") if !ok { return fmt.Errorf("text shader not found") } p.shader = textShader // Load proclamation words from database if err := p.loadProclamations(); err != nil { // Don't stop execution, just show fallback words p.words = strings.Fields("No Proclamations Selected!") } p.wordIndex = 0 // Get line pattern from database linePatternName, err := db.GetConfigValue("line_pattern") if err != nil { return fmt.Errorf("retrieving line_pattern from db: %w", err) } p.activePattern, err = linePattern.Get(linePatternName) if err != nil { return fmt.Errorf("failed to load line pattern '%s': %w", linePatternName, err) } // Initialize color pattern var baseColors = []sdl.Color{ colors.Tan, colors.PeachPuff, colors.LightCyan, colors.LightSeaGreen, colors.MediumTurquoise, colors.DarkCyan, colors.MediumPurple, } p.colorPattern = colorPattern.NewColorPattern(baseColors) // Get font sizes from database (optimize: load once, cache as int32) standardFontSizeStr, err := db.GetConfigValue("standard_font_size") if err != nil { return fmt.Errorf("retrieving standard_font_size from db: %w", err) } standardFontSize, err := strconv.Atoi(standardFontSizeStr) if err != nil { return fmt.Errorf("parsing standard_font_size: %w", err) } baseFontSizeStr, err := db.GetConfigValue("init_font_size") if err != nil { return fmt.Errorf("retrieving init_font_size from db: %w", err) } baseFontSize, err := strconv.Atoi(baseFontSizeStr) if err != nil { return fmt.Errorf("parsing init_font_size: %w", err) } // Font setup (optimized: calculate once, reuse) p.fontScale = float32(standardFontSize) / float32(baseFontSize) nLines := int(p.ScreenHeight / int32(standardFontSize)) p.lines = NewLineDeque(nLines * 2) // Calculate space width once spaceGlyph, ok := fm.GetGlyph(p.font.Name, ' ') if !ok { return fmt.Errorf("failed to get space glyph") } p.spaceWidth = int32(float32(spaceGlyph.Advance) * p.fontScale) // Get line height from a sample string tmpStrID, _, H, err := fm.NewCreateStringTexture(p.font.Name, "Mg", p.shader) if err != nil { return fmt.Errorf("failed to create sample texture: %w", err) } p.lineHeight = int32(float32(H) * p.fontScale) gl.DeleteTextures(1, &tmpStrID) p.lineCtx = &linePattern.LineRenderContext{ ScreenWidth: p.ScreenWidth, Font: p.font, FontScale: p.fontScale, SpaceWidth: p.spaceWidth, } // Create initial lines for i := 0; i < nLines; i++ { if err := p.createLine(i, true); err != nil { return fmt.Errorf("failed to create initial line %d: %w", i, err) } } // Audio setup audioDeviceName, err := db.GetConfigValue("audio_device_name") if err != nil { return fmt.Errorf("retrieving audio_device_name from db: %w", err) } // Switch audio devices if needed if mixer.CurrentDevice() != audioDeviceName { if err := mixer.SwitchDevice(audioDeviceName); err != nil { } else { } } // Start audio playback selectedAudio, err := db.GetConfigValue("selected_audio") if err != nil { return fmt.Errorf("retrieving selected_audio from db: %w", err) } assetsDir, err := db.GetConfigValue("assets_dir") if err != nil { return fmt.Errorf("retrieving assets_dir from db: %w", err) } if selectedAudio == "" { } else { if err := mixer.Play(filepath.Join(assetsDir, selectedAudio), true); err != nil { } } currentDevice := mixer.CurrentDevice() if currentDevice == "" { currentDevice = "default" } return nil } // loadProclamations loads selected proclamations from the database func (p *ScrollerPage) loadProclamations() error { p.words = []string{} // Get all selected proclamations from database proclamations, err := db.GetProclamations() if err != nil { return fmt.Errorf("retrieving proclamations from db: %w", err) } // Build word list from selected, available proclamations for _, proclamation := range proclamations { if proclamation.Selected && proclamation.Available { // Split content into words and add to list words := strings.Fields(proclamation.Content) p.words = append(p.words, words...) } } if len(p.words) == 0 { p.words = strings.Fields("No Proclamations Selected!") return fmt.Errorf("no proclamations selected or available") } return nil } // createLine is a helper to generate a new line at a specific index // isInitial determines if this is during initialization (positions from top) // or dynamic creation (positions relative to existing lines) func (p *ScrollerPage) createLine(index int, isInitial bool) error { words := p.activePattern.GetNextLine(p.words, &p.wordIndex, p.lineCtx) line := Line{words: []StringItem{}} for _, word := range words { if word == "" { continue } item, err := NewStringItem(word, p.font, p.colorPattern.Color()) if err != nil { return fmt.Errorf("unable to create string item for word '%s': %w", word, err) } item.W = int32(float32(item.W) * p.fontScale) item.H = int32(float32(item.H) * p.fontScale) if len(line.words) > 0 { line.width += p.spaceWidth } line.words = append(line.words, item) line.width += item.W } // Calculate horizontal position (centered) startX := p.ScreenCenterX - (line.width / 2) // Calculate vertical position var baseY int32 if isInitial { baseY = int32(p.scrollY) - int32(p.lineHeight)*int32(index) } else { baseY = 0 // Will be set by caller based on context } // Position all words in the line for j := range line.words { if j == 0 { line.words[j].X = startX } else { line.words[j].X = line.words[j-1].X + line.words[j-1].W + p.spaceWidth } line.words[j].Y = baseY } if isInitial { p.lines.PushBack(line) } return nil } func (p *ScrollerPage) HandleEvent(event *sdl.Event) error { switch e := (*event).(type) { case *sdl.KeyboardEvent: if e.Type != sdl.KEYDOWN { return nil } switch e.Keysym.Sym { case sdl.K_UP: if !p.autoVelocity { p.velocity += p.increment } case sdl.K_DOWN: if !p.autoVelocity { p.velocity -= p.increment } case sdl.K_a: p.autoVelocity = !p.autoVelocity if p.autoVelocity { // Reset to initial state when enabling p.velocity = p.velocityFloor p.velocityDirection = 1 p.velocityState = 0 p.velocityTimer = 0.0 } } return nil } return nil } func (p *ScrollerPage) Update(dt float32) error { p.updateAutoVelocity(dt) p.scrollOffset += dt * p.velocity move := int32(p.scrollOffset) if move == 0 { return nil } p.scrollOffset -= float32(move) // Move all lines vertically for i := 0; i < p.lines.Len(); i++ { line := p.lines.Get(i) for j := range line.words { line.words[j].Y += move } } // Handle line replacement based on scroll direction if p.velocity > 0 { // Moving up: replace lines that go off top for p.lines.Len() > 0 && len(p.lines.Front().words) > 0 && p.lines.Front().words[0].Y > p.ScreenHeight { old := p.lines.PopFront() for _, word := range old.words { gl.DeleteTextures(1, &word.ID) } if err := p.addLineAtBottom(); err != nil { return err } } } else if p.velocity < 0 { // Moving down: replace lines that go off bottom for p.lines.Len() > 0 { back := p.lines.Back() if len(back.words) == 0 || back.words[0].Y+back.words[0].H >= 0 { break } old := p.lines.PopBack() for _, word := range old.words { gl.DeleteTextures(1, &word.ID) } if err := p.addLineAtTop(); err != nil { return err } } } return nil } // addLineAtBottom creates and adds a new line at the bottom of the display func (p *ScrollerPage) addLineAtBottom() error { newWords := p.activePattern.GetNextLine(p.words, &p.wordIndex, p.lineCtx) line := Line{words: []StringItem{}} for _, word := range newWords { if word == "" { continue } item, err := NewStringItem(word, p.font, p.colorPattern.Color()) if err != nil { return fmt.Errorf("unable to create string item for word '%s': %w", word, err) } item.W = int32(float32(item.W) * p.fontScale) item.H = int32(float32(item.H) * p.fontScale) if len(line.words) > 0 { line.width += p.spaceWidth } line.words = append(line.words, item) line.width += item.W } startX := p.ScreenCenterX - (line.width / 2) // Position relative to last existing line var baseY int32 if p.lines.Len() > 0 && len(p.lines.Back().words) > 0 { baseY = p.lines.Back().words[0].Y - int32(p.lineHeight) } else { baseY = -int32(p.lineHeight) } for j := range line.words { if j == 0 { line.words[j].X = startX } else { line.words[j].X = line.words[j-1].X + line.words[j-1].W + p.spaceWidth } line.words[j].Y = baseY } p.lines.PushBack(line) return nil } // addLineAtTop creates and adds a new line at the top of the display func (p *ScrollerPage) addLineAtTop() error { newWords := p.activePattern.GetNextLine(p.words, &p.wordIndex, p.lineCtx) line := Line{words: []StringItem{}} for _, word := range newWords { if word == "" { continue } item, err := NewStringItem(word, p.font, p.colorPattern.Color()) if err != nil { return fmt.Errorf("unable to create string item for word '%s': %w", word, err) } item.W = int32(float32(item.W) * p.fontScale) item.H = int32(float32(item.H) * p.fontScale) if len(line.words) > 0 { line.width += p.spaceWidth } line.words = append(line.words, item) line.width += item.W } startX := p.ScreenCenterX - (line.width / 2) // Position relative to first existing line var baseY int32 if p.lines.Len() > 0 && len(p.lines.Front().words) > 0 { baseY = p.lines.Front().words[0].Y + int32(p.lineHeight) } else { baseY = p.ScreenHeight } for j := range line.words { if j == 0 { line.words[j].X = startX } else { line.words[j].X = line.words[j-1].X + line.words[j-1].W + p.spaceWidth } line.words[j].Y = baseY } p.lines.PushFront(line) return nil } func (p *ScrollerPage) Render() error { p.BeginTextureRendering(p.shader) for i := 0; i < p.lines.Len(); i++ { line := p.lines.Get(i) for _, word := range line.words { if word.ID == 0 { continue } p.RenderTextureBatched(p.shader, word.ID, word.Position(), word.RawDimensions(), word.Color) } } p.EndTextureRendering() return nil } func (p *ScrollerPage) Destroy() error { if p == nil { return nil } mixer.Stop(1000) // GL cleanup — delete all text textures for i := 0; i < p.lines.Len(); i++ { line := p.lines.Get(i) for j := range line.words { if id := line.words[j].ID; id != 0 { gl.DeleteTextures(1, &line.words[j].ID) line.words[j].ID = 0 } } } gl.Flush() // Drop references for GC p.lines = nil p.words = nil p.lineCtx = nil p.font = nil p.shader = nil p.colorPattern = nil return nil } // SetAutoVelocity configures the automatic velocity system for the ScrollerPage. func (p *ScrollerPage) SetAutoVelocity(enabled bool, floor, ceiling, step, delay, hold float32) { p.autoVelocity = enabled p.velocityFloor = -float32(math.Abs(float64(floor))) p.velocityCeiling = float32(math.Abs(float64(ceiling))) p.velocityStep = float32(math.Abs(float64(step))) p.velocityDelay = delay p.hold = hold // Initialize state p.velocityDirection = 1 p.velocityState = 0 p.velocityTimer = 0.0 p.velocity = p.velocityFloor } // updateAutoVelocity handles automatic velocity changes func (p *ScrollerPage) updateAutoVelocity(dt float32) { if !p.autoVelocity { return } switch p.velocityState { case 0: // Changing velocity if p.velocityDirection == 1 { p.velocity += p.velocityStep * dt if p.velocity >= p.velocityCeiling { p.velocity = p.velocityCeiling p.velocityState = 1 p.velocityTimer = 0.0 } } else { p.velocity -= p.velocityStep * dt if p.velocity <= p.velocityFloor { p.velocity = p.velocityFloor p.velocityState = 2 p.velocityTimer = 0.0 } } case 1: // Waiting at ceiling p.velocityTimer += dt if p.velocityTimer >= p.velocityDelay { p.velocityDirection = -1 p.velocityState = 0 } case 2: // Waiting at floor p.velocityTimer += dt if p.velocityTimer >= p.velocityDelay { p.velocityDirection = 1 p.velocityState = 0 } } }