package rgb import "fmt" type Zone string const ( ZoneLogo Zone = "logo" ZoneBacklight Zone = "backlight" ZoneSide Zone = "side" ) type EffectTarget struct { Zone Zone ID uint8 } var impact80BacklightEffects = [...]string{ "none", "solid_color", "alphas_mods", "gradient_up_down", "gradient_left_right", "breathing", "band_sat", "band_val", "band_pinwheel_sat", "band_pinwheel_val", "band_spiral_sat", "band_spiral_val", "cycle_all", "cycle_left_right", "cycle_up_down", "cycle_out_in", "cycle_out_in_dual", "rainbow_moving_chevron", "cycle_pinwheel", "cycle_spiral", "dual_beacon", "rainbow_beacon", "rainbow_pinwheels", "flower_blooming", "raindrops", "jellybean_raindrops", "hue_breathing", "hue_pendulum", "hue_wave", "pixel_flow", "digital_rain", "solid_reactive", "solid_reactive_wide", "solid_reactive_multiwide", "solid_reactive_cross", "solid_reactive_multicross", "solid_reactive_nexus", "solid_reactive_multinexus", "splash", "multisplash", "solid_splash", "solid_multisplash", "starlight", "starlight_dual_hue", "starlight_dual_sat", "riverflow", } var impact80LogoEffects = [...]string{ "none", "wave", "fixed_wave", "spectrum", "breathing", "light", "shutdown", } var impact80SideEffects = [...]string{ "none", "wave", "fixed_wave", "spectrum", "breathing", "light", "shutdown", } var impact80EffectAliases = map[Zone]map[string]string{ ZoneLogo: { "off": "none", "breathe": "breathing", "rainbow": "spectrum", "rainbow_wave": "wave", "solid": "light", }, ZoneBacklight: { "off": "none", "breathe": "breathing", "rainbow": "rainbow_moving_chevron", "solid": "solid_color", }, ZoneSide: { "off": "none", "breathe": "breathing", "rainbow": "spectrum", "rainbow_wave": "wave", "solid": "light", }, } func AllZones() []Zone { return []Zone{ZoneLogo, ZoneBacklight, ZoneSide} } func ParseZone(value string) (Zone, error) { zone := Zone(value) switch zone { case ZoneLogo, ZoneBacklight, ZoneSide: return zone, nil default: return "", fmt.Errorf("unknown zone: %s", value) } } func (z Zone) Channel() uint8 { switch z { case ZoneLogo: return 2 case ZoneBacklight: return 3 case ZoneSide: return 4 default: return 0 } } func EffectName(zone Zone, id uint8) string { names := impact80EffectNames(zone) if int(id) >= len(names) { return "unknown" } return names[id] } func DefaultEffect(zone Zone) uint8 { switch zone { case ZoneLogo, ZoneSide: return 4 case ZoneBacklight: return 5 default: return 0 } } func ResolveEffect(name string, zones []Zone) ([]EffectTarget, []Zone, error) { for _, zone := range zones { if impact80EffectNames(zone) == nil { return nil, nil, fmt.Errorf("unknown zone: %s", zone) } } known := false for _, zone := range AllZones() { if _, ok := resolveEffectID(zone, name); ok { known = true break } } if !known { return nil, nil, fmt.Errorf("unknown effect: %s", name) } explicit := len(zones) == 1 var targets []EffectTarget var skipped []Zone for _, zone := range zones { id, ok := resolveEffectID(zone, name) if !ok { if explicit { return nil, nil, fmt.Errorf("effect %s is not supported on zone %s", name, zone) } skipped = append(skipped, zone) continue } targets = append(targets, EffectTarget{Zone: zone, ID: id}) } return targets, skipped, nil } func impact80EffectNames(zone Zone) []string { switch zone { case ZoneLogo: return impact80LogoEffects[:] case ZoneBacklight: return impact80BacklightEffects[:] case ZoneSide: return impact80SideEffects[:] default: return nil } } func resolveEffectID(zone Zone, name string) (uint8, bool) { for id, effectName := range impact80EffectNames(zone) { if effectName == name { return uint8(id), true } } if canonical, ok := impact80EffectAliases[zone][name]; ok { return resolveEffectID(zone, canonical) } return 0, false } func Impact80EffectName(value uint8) string { return EffectName(ZoneLogo, value) } func ParseImpact80Effect(name string) (uint8, error) { if name == "static" { return 5, nil } targets, _, err := ResolveEffect(name, []Zone{ZoneLogo}) if err != nil { return 0, err } return targets[0].ID, nil }