Remove devices list and device vector length check

This commit is contained in:
NeilClack
2026-04-23 17:26:22 -05:00
parent 9575833392
commit 05a7098886
8 changed files with 71 additions and 80 deletions
+6
View File
@@ -103,13 +103,17 @@ func openDeviceLocked(name string) error {
// Play loads a WAV (as music) and plays it. If loopForever is true, loops forever. // Play loads a WAV (as music) and plays it. If loopForever is true, loops forever.
// If something is already playing, it stops and replaces it. // If something is already playing, it stops and replaces it.
func Play(path string, loopForever bool, cfg *db.AppConfig) error { func Play(path string, loopForever bool, cfg *db.AppConfig) error {
// Check if audio is enabled or disabled
if !cfg.AudioEnabled { if !cfg.AudioEnabled {
return nil return nil
} }
// Lock the mutex
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
// Check if mixer has been initialized and that a device is open
// JUMP: This is where the issue is...
if !inited || !deviceOpen { if !inited || !deviceOpen {
logger.Error("audio mixer not initialized") logger.Error("audio mixer not initialized")
return errors.New("audio mixer not initialized") return errors.New("audio mixer not initialized")
@@ -126,10 +130,12 @@ func Play(path string, loopForever bool, cfg *db.AppConfig) error {
currentMusic = nil currentMusic = nil
} }
// Load the music file
m, err := mix.LoadMUS(path) m, err := mix.LoadMUS(path)
if err != nil { if err != nil {
return fmt.Errorf("LoadMUS(%q): %w", path, err) return fmt.Errorf("LoadMUS(%q): %w", path, err)
} }
// Set current music to the loaded music file
currentMusic = m currentMusic = m
currentPath = path currentPath = path
if loopForever { if loopForever {
+35 -41
View File
@@ -5,7 +5,6 @@ import (
"github.com/go-gl/gl/v3.3-core/gl" "github.com/go-gl/gl/v3.3-core/gl"
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
"gorm.io/gorm"
"rhemawavetech.com/rhemawave/internal/colors" "rhemawavetech.com/rhemawave/internal/colors"
"rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/db"
"rhemawavetech.com/rhemawave/internal/fontManager" "rhemawavetech.com/rhemawave/internal/fontManager"
@@ -25,7 +24,7 @@ type AudioDevices struct {
selectedIndex int selectedIndex int
verticalMargin int32 verticalMargin int32
CfgPtr *db.AppConfig CfgPtr *db.AppConfig
dbPtr *gorm.DB // DbPtr *gorm.DB
} }
func (p *AudioDevices) Init(ctx *PageCtx) error { func (p *AudioDevices) Init(ctx *PageCtx) error {
@@ -57,7 +56,7 @@ func (p *AudioDevices) Init(ctx *PageCtx) error {
} }
// Get font size from database // Get font size from database
baseFontSize := p.Base.Context.CfgPtr.StandardFontSize baseFontSize := p.Context.CfgPtr.StandardFontSize
// Calculate scales // Calculate scales
titleScale := float32(64) / float32(baseFontSize) titleScale := float32(64) / float32(baseFontSize)
@@ -85,7 +84,7 @@ func (p *AudioDevices) Init(ctx *PageCtx) error {
} }
// Get currently selected device from database // Get currently selected device from database
currentDevice := p.Base.Context.CfgPtr.SelectedAudioDevice currentDevice := p.Context.CfgPtr.SelectedAudioDevice
// Create UI items for each device // Create UI items for each device
for i, name := range devices { // Iterate over the devices for i, name := range devices { // Iterate over the devices
@@ -103,7 +102,7 @@ func (p *AudioDevices) Init(ctx *PageCtx) error {
} }
} }
on := p.Base.Context.CfgPtr.AudioEnabled on := p.Context.CfgPtr.AudioEnabled
audioStatus := "Turn Audio On" audioStatus := "Turn Audio On"
if on { if on {
@@ -166,11 +165,11 @@ func (p *AudioDevices) HandleEvent(event *sdl.Event) error {
// Handle audio disable // Handle audio disable
if selection == "Turn Audio Off" || selection == "Turn Audio On" { if selection == "Turn Audio Off" || selection == "Turn Audio On" {
newStatus := !p.Base.Context.CfgPtr.AudioEnabled newStatus := !p.Context.CfgPtr.AudioEnabled
updatedConfig := p.Base.Context.CfgPtr updatedConfig := p.Context.CfgPtr
updatedConfig.AudioEnabled = newStatus updatedConfig.AudioEnabled = newStatus
p.Base.Context.DbPtr.Save(&updatedConfig) p.Context.DbPtr.Save(&updatedConfig)
p.Base.Context.RefreshConfig() p.Context.RefreshConfig()
return nil return nil
} }
@@ -186,12 +185,12 @@ func (p *AudioDevices) HandleEvent(event *sdl.Event) error {
} }
// Save settings // Save settings
p.Base.Context.CfgPtr.SelectedAudioDevice = deviceName p.Context.CfgPtr.SelectedAudioDevice = deviceName
p.Base.Context.CfgPtr.AudioEnabled = true p.Context.CfgPtr.AudioEnabled = true
p.Base.Context.DbPtr.Save(p.Base.Context.CfgPtr) p.Context.DbPtr.Save(p.Context.CfgPtr)
p.Base.Context.RefreshConfig() p.Context.RefreshConfig()
case sdl.K_BACKSPACE: case sdl.K_BACKSPACE:
p.Base.Context.NavigateTo(SETTINGS) p.Context.NavigateTo(SETTINGS)
} }
return nil return nil
@@ -202,36 +201,31 @@ func (p *AudioDevices) Render() error {
p.RenderTexture(p.textShader, p.title.ID, p.title.Position(), p.title.RawDimensions(), p.title.Color) p.RenderTexture(p.textShader, p.title.ID, p.title.Position(), p.title.RawDimensions(), p.title.Color)
p.RenderTexture(p.textShader, p.prompt.ID, p.prompt.Position(), p.prompt.RawDimensions(), p.prompt.Color) p.RenderTexture(p.textShader, p.prompt.ID, p.prompt.Position(), p.prompt.RawDimensions(), p.prompt.Color)
// No devices to display
if len(p.devices) == 0 {
return nil
}
// Render highlight box behind highlighted item // Render highlight box behind highlighted item
p.RenderSolidColorQuad( //p.RenderSolidColorQuad(
p.solidShader, // p.solidShader,
p.devices[p.highlightIndex].Position(), // p.devices[p.highlightIndex].Position(),
p.devices[p.highlightIndex].RawDimensions(), // p.devices[p.highlightIndex].RawDimensions(),
colors.White, // colors.White,
) //)
// Render device items with appropriate colors // Render device items with appropriate colors
for i, item := range p.devices { //for i, item := range p.devices {
if i == p.highlightIndex && i == p.selectedIndex { // if i == p.highlightIndex && i == p.selectedIndex {
// Currently highlighted AND selected device - dark green // // Currently highlighted AND selected device - dark green
item.Color = colors.DarkGreen // item.Color = colors.DarkGreen
} else if i == p.highlightIndex { // } else if i == p.highlightIndex {
// Just highlighted - black (shows on white background) // // Just highlighted - black (shows on white background)
item.Color = colors.Black // item.Color = colors.Black
} else if i == p.selectedIndex { // } else if i == p.selectedIndex {
// Just selected - green // // Just selected - green
item.Color = colors.Green // item.Color = colors.Green
} else { // } else {
// Normal item - white // // Normal item - white
item.Color = colors.White // item.Color = colors.White
} // }
p.RenderTexture(p.textShader, item.ID, item.Position(), item.RawDimensions(), item.Color) // p.RenderTexture(p.textShader, item.ID, item.Position(), item.RawDimensions(), item.Color)
} //}
return nil return nil
} }
+4 -4
View File
@@ -154,9 +154,9 @@ func (p *EmailAddressPage) HandleEvent(event *sdl.Event) error {
sdl.StopTextInput() sdl.StopTextInput()
// Save email address to database // Save email address to database
p.Base.Context.CfgPtr.EmailAddress = p.inputText p.Context.CfgPtr.EmailAddress = p.inputText
p.Base.Context.DbPtr.Save(p.Base.Context.CfgPtr) p.Context.DbPtr.Save(p.Context.CfgPtr)
p.Base.Context.RefreshConfig() p.Context.RefreshConfig()
if p.isFirstTimeSetup { if p.isFirstTimeSetup {
// First-time setup: navigate to License Key page // First-time setup: navigate to License Key page
@@ -253,7 +253,7 @@ func (p *EmailAddressPage) Update(dt float32) error {
// Render performs page drawing logic. // Render performs page drawing logic.
func (p *EmailAddressPage) Render() error { func (p *EmailAddressPage) Render() error {
// Get base font size from database // Get base font size from database
baseFontSize := p.Base.Context.CfgPtr.StandardFontSize baseFontSize := p.Context.CfgPtr.StandardFontSize
sm := shaderManager.Get() sm := shaderManager.Get()
+6 -6
View File
@@ -74,7 +74,7 @@ func (p *Home) Init(ctx *PageCtx) error {
} }
// Create license info textures if data exists // Create license info textures if data exists
if p.Base.Context.CfgPtr.EmailAddress != "" || p.Base.Context.CfgPtr.LicenseKey != "" { if p.Context.CfgPtr.EmailAddress != "" || p.Context.CfgPtr.LicenseKey != "" {
p.hasLicenseInfo = true p.hasLicenseInfo = true
// Create heading // Create heading
@@ -84,8 +84,8 @@ func (p *Home) Init(ctx *PageCtx) error {
} }
// Create email display if exists // Create email display if exists
if p.Base.Context.CfgPtr.EmailAddress != "" { if p.Context.CfgPtr.EmailAddress != "" {
emailText := fmt.Sprintf("Email: %s", p.Base.Context.CfgPtr.EmailAddress) emailText := fmt.Sprintf("Email: %s", p.Context.CfgPtr.EmailAddress)
p.emailDisplay, err = NewStringItem(emailText, font, colors.White) p.emailDisplay, err = NewStringItem(emailText, font, colors.White)
if err != nil { if err != nil {
return fmt.Errorf("unable to create email display texture: %w", err) return fmt.Errorf("unable to create email display texture: %w", err)
@@ -93,8 +93,8 @@ func (p *Home) Init(ctx *PageCtx) error {
} }
// Create license key display if exists // Create license key display if exists
if p.Base.Context.CfgPtr.LicenseKey != "" { if p.Context.CfgPtr.LicenseKey != "" {
licenseKeyText := fmt.Sprintf("License Key: %s", p.Base.Context.CfgPtr.LicenseKey) licenseKeyText := fmt.Sprintf("License Key: %s", p.Context.CfgPtr.LicenseKey)
p.licenseKeyDisplay, err = NewStringItem(licenseKeyText, font, colors.White) p.licenseKeyDisplay, err = NewStringItem(licenseKeyText, font, colors.White)
if err != nil { if err != nil {
return fmt.Errorf("unable to create license key display texture: %w", err) return fmt.Errorf("unable to create license key display texture: %w", err)
@@ -103,7 +103,7 @@ func (p *Home) Init(ctx *PageCtx) error {
} }
// Get base font size from database // Get base font size from database
baseFontSize := p.Base.Context.CfgPtr.StandardFontSize baseFontSize := p.Context.CfgPtr.StandardFontSize
p.baseFontSize = baseFontSize p.baseFontSize = baseFontSize
+8 -8
View File
@@ -77,7 +77,7 @@ func (p *LicenseKeyPage) Init(ctx *PageCtx) error {
p.titleTextureHeight = titleHeight p.titleTextureHeight = titleHeight
// Load existing license key from database // Load existing license key from database
licenseKey := p.Base.Context.CfgPtr.LicenseKey licenseKey := p.Context.CfgPtr.LicenseKey
if licenseKey != "" { if licenseKey != "" {
p.inputText = licenseKey p.inputText = licenseKey
@@ -165,7 +165,7 @@ func (p *LicenseKeyPage) HandleEvent(event *sdl.Event) error {
} }
// Allow escape back to settings if coming from settings // Allow escape back to settings if coming from settings
sdl.StopTextInput() sdl.StopTextInput()
p.Base.Context.NavigateTo(SETTINGS) p.Context.NavigateTo(SETTINGS)
case sdl.K_RETURN: case sdl.K_RETURN:
// Validate license key - check empty first, then length, then characters // Validate license key - check empty first, then length, then characters
cleaned := strings.ReplaceAll(p.inputText, "-", "") cleaned := strings.ReplaceAll(p.inputText, "-", "")
@@ -188,9 +188,9 @@ func (p *LicenseKeyPage) HandleEvent(event *sdl.Event) error {
sdl.StopTextInput() sdl.StopTextInput()
// Save license key to database // Save license key to database
p.Base.Context.CfgPtr.LicenseKey = p.inputText p.Context.CfgPtr.LicenseKey = p.inputText
p.Base.Context.DbPtr.Save(p.Base.Context.CfgPtr) p.Context.DbPtr.Save(p.Context.CfgPtr)
p.Base.Context.RefreshConfig() p.Context.RefreshConfig()
// Write license key to plain text file for the updater // Write license key to plain text file for the updater
if homeDir, err := os.UserHomeDir(); err == nil { if homeDir, err := os.UserHomeDir(); err == nil {
@@ -202,10 +202,10 @@ func (p *LicenseKeyPage) HandleEvent(event *sdl.Event) error {
if p.isFirstTimeSetup { if p.isFirstTimeSetup {
// First-time setup: rewind to Welcome page // First-time setup: rewind to Welcome page
p.Base.Context.NavigateTo(HOME) p.Context.NavigateTo(HOME)
} else { } else {
// Coming from settings: rewind back to settings // Coming from settings: rewind back to settings
p.Base.Context.NavigateTo(SETTINGS) p.Context.NavigateTo(SETTINGS)
} }
case sdl.K_BACKSPACE: case sdl.K_BACKSPACE:
if len(p.inputText) > 0 { if len(p.inputText) > 0 {
@@ -303,7 +303,7 @@ func (p *LicenseKeyPage) Update(dt float32) error {
// Render performs page drawing logic. // Render performs page drawing logic.
func (p *LicenseKeyPage) Render() error { func (p *LicenseKeyPage) Render() error {
// Get base font size from database // Get base font size from database
baseFontSize := p.Base.Context.CfgPtr.StandardFontSize baseFontSize := p.Context.CfgPtr.StandardFontSize
sm := shaderManager.Get() sm := shaderManager.Get()
+3 -3
View File
@@ -42,7 +42,7 @@ func (p *LogViewerPage) Init(ctx *PageCtx) error {
return fmt.Errorf("failed base page initialization: %w", err) return fmt.Errorf("failed base page initialization: %w", err)
} }
if result := p.Base.Context.DbPtr.Order("timestamp desc").Limit(250).Find(&logs); result.Error != nil { if result := p.Context.DbPtr.Order("timestamp desc").Limit(250).Find(&logs); result.Error != nil {
logger.Error("error querying database for logs: %s", result.Error) logger.Error("error querying database for logs: %s", result.Error)
return fmt.Errorf("%s", result.Error) return fmt.Errorf("%s", result.Error)
} }
@@ -115,7 +115,7 @@ func (p *LogViewerPage) HandleEvent(event *sdl.Event) error {
if e.Type == sdl.KEYDOWN { if e.Type == sdl.KEYDOWN {
switch e.Keysym.Sym { switch e.Keysym.Sym {
case sdl.K_BACKSPACE: case sdl.K_BACKSPACE:
p.Base.Context.NavigateTo(SETTINGS) p.Context.NavigateTo(SETTINGS)
case sdl.K_UP: case sdl.K_UP:
p.scrollOffset -= p.lineHeight p.scrollOffset -= p.lineHeight
if p.scrollOffset < 0 { if p.scrollOffset < 0 {
@@ -159,7 +159,7 @@ func (p *LogViewerPage) Update(dt float32) error {
} }
func (p *LogViewerPage) Render() error { func (p *LogViewerPage) Render() error {
baseFontSize := p.Base.Context.CfgPtr.StandardFontSize baseFontSize := p.Context.CfgPtr.StandardFontSize
sm := shaderManager.Get() sm := shaderManager.Get()
textShader, _ := sm.Get("text") textShader, _ := sm.Get("text")
+1 -1
View File
@@ -61,7 +61,7 @@ func (p *MessagePage) Init(ctx *PageCtx) error {
return fmt.Errorf("unable to create instructions string texture: %w", err) return fmt.Errorf("unable to create instructions string texture: %w", err)
} }
baseFontSize := float32(p.Base.Context.CfgPtr.StandardFontSize) baseFontSize := float32(p.Context.CfgPtr.StandardFontSize)
p.message.Scale(float32(48) / baseFontSize) p.message.Scale(float32(48) / baseFontSize)
p.instructions.Scale(float32(28) / baseFontSize) p.instructions.Scale(float32(28) / baseFontSize)
+8 -17
View File
@@ -231,7 +231,7 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
// Get line pattern from database // Get line pattern from database
var err error var err error
linePatternName := p.Base.Context.CfgPtr.LinePattern linePatternName := p.Context.CfgPtr.LinePattern
p.activePattern, err = linePattern.Get(linePatternName) p.activePattern, err = linePattern.Get(linePatternName)
if err != nil { if err != nil {
@@ -239,7 +239,7 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
} }
// Initialize color pattern // Initialize color pattern
var baseColors = []sdl.Color{ baseColors := []sdl.Color{
colors.Tan, colors.Tan,
colors.PeachPuff, colors.PeachPuff,
colors.LightCyan, colors.LightCyan,
@@ -252,7 +252,7 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
// Get font sizes from database (optimize: load once, cache as int32) // Get font sizes from database (optimize: load once, cache as int32)
// Match the working page's logic exactly: // Match the working page's logic exactly:
p.fontScale = float32(32) / float32(p.Base.Context.CfgPtr.StandardFontSize) p.fontScale = float32(32) / float32(p.Context.CfgPtr.StandardFontSize)
// Font setup // Font setup
nLines := int(float32(p.ScreenHeight) / 32.0) // 32 is your target visual size nLines := int(float32(p.ScreenHeight) / 32.0) // 32 is your target visual size
@@ -291,7 +291,7 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
} }
// Audio setup // Audio setup
audioDeviceName := p.Base.Context.CfgPtr.SelectedAudioDevice audioDeviceName := p.Context.CfgPtr.SelectedAudioDevice
// Switch audio devices if needed // Switch audio devices if needed
if mixer.CurrentDevice() != audioDeviceName { if mixer.CurrentDevice() != audioDeviceName {
@@ -302,12 +302,12 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
// Start audio playback // Start audio playback
// selectedAudio := p.Base.Context.CfgPtr.SelectedAudio // selectedAudio := p.Context.CfgPtr.SelectedAudio
assetsDir := p.Base.Context.CfgPtr.AssetsDir assetsDir := p.Context.CfgPtr.AssetsDir
audioFile := filepath.Join(assetsDir, "audio/audio.wav") audioFile := filepath.Join(assetsDir, "audio/audio.wav")
logger.Info("Attempting to play %s", audioFile) logger.Info("Attempting to play %s", audioFile)
if err := mixer.Play(audioFile, true, p.Base.Context.CfgPtr); err != nil { if err := mixer.Play(audioFile, true, p.Context.CfgPtr); err != nil {
logger.Error("Mixer returned an error: %v", err) // ADD THIS logger.Error("Mixer returned an error: %v", err) // ADD THIS
} }
@@ -414,15 +414,6 @@ func (p *ScrollerPage) HandleEvent(event *sdl.Event) error {
if !p.autoVelocity { if !p.autoVelocity {
p.velocity -= p.increment 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
} }
@@ -594,7 +585,7 @@ func (p *ScrollerPage) Destroy() error {
return nil return nil
} }
mixer.Stop(1000, p.Base.Context.CfgPtr) mixer.Stop(1000, p.Context.CfgPtr)
// GL cleanup — delete all text textures // GL cleanup — delete all text textures
if p.lines != nil { if p.lines != nil {