Big refactor
Signed-off-by: Martyn Ranyard <m@rtyn.berlin>
This commit is contained in:
parent
2202ba2fc0
commit
bed25ca03c
|
@ -0,0 +1,27 @@
|
|||
package patterns
|
||||
|
||||
func Even(number int) bool {
|
||||
return number %2 == 0
|
||||
}
|
||||
|
||||
func FillPanel(w int, h int, r byte, g byte, b byte) [][]RGBcolor {
|
||||
grid := make([][]RGBcolor, w)
|
||||
for i := 0; i < w; i++ {
|
||||
grid[i] = make([]RGBcolor, h)
|
||||
}
|
||||
for x := 0; x < w; x++ {
|
||||
for y := 0; y < h; y++ {
|
||||
var rgb [3]byte
|
||||
rgb[0] = r
|
||||
rgb[1] = g
|
||||
rgb[2] = b
|
||||
grid[x][y] = rgb
|
||||
}
|
||||
}
|
||||
return grid
|
||||
}
|
||||
|
||||
|
||||
func FillPanelRGB(w int, h int, colour RGBcolor) [][]RGBcolor {
|
||||
return FillPanel(w,h,colour[0],colour[1],colour[2])
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package patterns
|
||||
|
||||
import "math"
|
||||
|
||||
var sineoffset int = 0
|
||||
var lastSineSpeed uint16 = 0
|
||||
|
||||
func Sinewave(w int, h int, bgColor RGBcolor, fgColor RGBcolor, speed uint16) [][]RGBcolor {
|
||||
if speed != lastSineSpeed {
|
||||
lastSineSpeed = speed
|
||||
sineoffset = 0
|
||||
}
|
||||
sineoffset += int(speed/40)
|
||||
background := FillPanelRGB(w,h,bgColor)
|
||||
for x := 0; x < w; x++ {
|
||||
y := int(math.Round((math.Sin(float64(x+sineoffset))+1) / 2 * float64(h-1)))
|
||||
background[x][y] = fgColor
|
||||
}
|
||||
return background
|
||||
}
|
||||
|
||||
var lastSinePos int = 0
|
||||
|
||||
func SineChase(w int, h int, bgColor RGBcolor, fgColor RGBcolor, speed uint16) [][]RGBcolor {
|
||||
if speed != lastSineSpeed {
|
||||
lastSineSpeed = speed
|
||||
lastSinePos = 0
|
||||
}
|
||||
background := FillPanelRGB(w,h,bgColor)
|
||||
y := int(math.Round((math.Sin(float64(lastSinePos))+1) / 2 * float64(h-1)))
|
||||
background[lastSinePos][y] = fgColor
|
||||
lastSinePos += 1
|
||||
if lastSinePos >= w {
|
||||
lastSinePos = 0
|
||||
}
|
||||
return background
|
||||
}
|
||||
|
||||
func ZigZag(w int, h int) [][]RGBcolor {
|
||||
var bgColor = [3]byte{0,0,0}
|
||||
var fgColor = [3]byte{255,0,0}
|
||||
//var a = [5]int{2, 4, 6, 8, 10}
|
||||
background := FillPanelRGB(w,h,bgColor)
|
||||
for x := 0; x < w; x++ {
|
||||
y := x % (h-1)
|
||||
background[x][y] = fgColor
|
||||
}
|
||||
return background
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package patterns
|
||||
|
||||
// gradient returns from fromX to toX fading from (fromR,fromG,fromB) to (toR,toG,toB)
|
||||
// at least that's the idea.
|
||||
func Gradient(fromR byte, fromG byte, fromB byte, toR byte, toG byte, toB byte, fromX int, toX int) []byte {
|
||||
ret := make([]byte, toX*3)
|
||||
var stepR float32 = (float32(toR) - float32(fromR)) / (float32(toX) - float32(fromX))
|
||||
var stepG float32 = (float32(toG) - float32(fromG)) / (float32(toX) - float32(fromX))
|
||||
var stepB float32 = (float32(toB) - float32(fromB)) / (float32(toX) - float32(fromX))
|
||||
for i := fromX; i < toX*3; i += 3 {
|
||||
ret[i] = fromR + byte(float32(i/3)*stepR)
|
||||
ret[i+1] = fromG + byte(float32(i/3)*stepG)
|
||||
ret[i+2] = fromB + byte(float32(i/3)*stepB)
|
||||
}
|
||||
return ret
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package patterns
|
||||
|
||||
import "math/rand"
|
||||
import "time"
|
||||
|
||||
func RedPanel(w int, h int) [][]RGBcolor {
|
||||
return FillPanel(w, h, 255, 0, 0)
|
||||
}
|
||||
|
||||
var lastColour RGBcolor
|
||||
var lastIteration uint16 = 0
|
||||
|
||||
func RandomColourPanel(w int, h int, speed uint16) [][]RGBcolor {
|
||||
if lastIteration > 0 {
|
||||
lastIteration -= 40
|
||||
}
|
||||
if lastIteration <= 0 {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
var newColour RGBcolor
|
||||
newColour[0] = byte(r.Intn(255))
|
||||
newColour[1] = byte(r.Intn(255))
|
||||
newColour[2] = byte(r.Intn(255))
|
||||
lastColour = newColour
|
||||
lastIteration = speed
|
||||
}
|
||||
return FillPanel(w, h, lastColour[0], lastColour[1], lastColour[2])
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package patterns
|
||||
|
||||
import "math"
|
||||
|
||||
type RGBcolor = [3]byte
|
||||
|
||||
func plasmaRGBFromVal(val byte) (byte, byte, byte) {
|
||||
var r byte
|
||||
var g byte
|
||||
var b byte
|
||||
if val < 85 {
|
||||
r = val * 3
|
||||
g = 255 - r
|
||||
b = 0
|
||||
} else if val < 170 {
|
||||
b = (val - 85) * 3
|
||||
r = 255 - b
|
||||
g = 0
|
||||
} else {
|
||||
g = (val - 170) * 3
|
||||
b = 255 - g
|
||||
r = 0
|
||||
}
|
||||
return r, g, b
|
||||
}
|
||||
|
||||
|
||||
func LinearPlasma(l int) []byte {
|
||||
line := make([]byte, l*3)
|
||||
for i := 0; i < l*3; i += 3 {
|
||||
val := byte(i % 256)
|
||||
r, g, b := plasmaRGBFromVal(val)
|
||||
line[i] = r
|
||||
line[i+1] = g
|
||||
line[i+2] = b
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
||||
var offset float64 = 0.5
|
||||
|
||||
func PlasmaPanel(w int, h int, speed uint16) [][]RGBcolor {
|
||||
grid := make([][]RGBcolor, w)
|
||||
for i := 0; i < w; i++ {
|
||||
grid[i] = make([]RGBcolor, h)
|
||||
}
|
||||
scale := math.Pi * 2.0 / float64(w)
|
||||
step := float64(5 * speed / 40)
|
||||
offset -= step
|
||||
if offset < 0 {
|
||||
offset += 1.0
|
||||
}
|
||||
for y := 0; y < h; y++ {
|
||||
for x := 0; x < w; x++ {
|
||||
u := math.Cos((float64(x) + offset) * scale)
|
||||
v := math.Cos((float64(y) + offset) * scale)
|
||||
w := math.Cos((float64(w) + offset) * scale)
|
||||
e := (u + v + w + 3.0) / 6.0
|
||||
r, g, b := plasmaRGBFromVal(byte((offset + e) * 255))
|
||||
var rgb [3]byte
|
||||
rgb[0] = r
|
||||
rgb[1] = g
|
||||
rgb[2] = b
|
||||
grid[x][y] = rgb
|
||||
}
|
||||
}
|
||||
return grid
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package patterns
|
||||
|
||||
func AlternateRGBLinear(R0 byte, G0 byte, B0 byte, R1 byte, G1 byte, B1 byte, fromX int, toX int) []byte {
|
||||
ret := make([]byte, toX*3)
|
||||
for i := fromX; i < toX*3; i += 3 {
|
||||
if Even(i) {
|
||||
ret[i] = R0
|
||||
ret[i+1] = G0
|
||||
ret[i+2] = B0
|
||||
} else {
|
||||
ret[i] = R1
|
||||
ret[i+1] = G1
|
||||
ret[i+2] = B1
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package queue
|
||||
|
||||
type QueueItem struct {
|
||||
Effect string
|
||||
Duration uint16
|
||||
Speed uint16 //only used by some patterns
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package remapping
|
||||
|
||||
type RGBcolor = [3]byte
|
||||
|
||||
func Even(number int) bool {
|
||||
return number %2 == 0
|
||||
}
|
||||
|
||||
func Slice512(s []byte) [512]byte {
|
||||
var ret [512]byte
|
||||
for i := range s {
|
||||
if i < 512 {
|
||||
ret[i] = s[i]
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func SliceUnlenthed(s [512]byte) []byte {
|
||||
ret := make([]byte, 512)
|
||||
for i := range s {
|
||||
ret[i] = s[i]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func SliceRearrange(rowwidth int, rows int, alternaterows bool, inslice []byte) [][]byte {
|
||||
var flippedslice []byte
|
||||
if alternaterows {
|
||||
flippedslice = make([]byte, len(inslice)+3)
|
||||
for r := 0; r < rows; r++ {
|
||||
rowzero := (r * rowwidth * 3)
|
||||
if Even(r) {
|
||||
for c := 0; c < (rowwidth)*3; c += 3 {
|
||||
flippedslice[rowzero+c] = inslice[rowzero+c]
|
||||
flippedslice[rowzero+c+1] = inslice[rowzero+c+1]
|
||||
flippedslice[rowzero+c+2] = inslice[rowzero+c+2]
|
||||
}
|
||||
} else {
|
||||
x := rowwidth * 3
|
||||
for c := 0; c < (rowwidth)*3; c += 3 {
|
||||
x = x - 3
|
||||
flippedslice[rowzero+x] = inslice[rowzero+c]
|
||||
flippedslice[rowzero+x+1] = inslice[rowzero+c+1]
|
||||
flippedslice[rowzero+x+2] = inslice[rowzero+c+2]
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
flippedslice = inslice
|
||||
}
|
||||
currentUniverse := 0
|
||||
currentUniversePosition := 0
|
||||
universes := make([][]byte, (len(flippedslice)/510)+1)
|
||||
currentUniverseSlice := make([]byte, 511)
|
||||
currentRowReverse := false
|
||||
for i := range flippedslice {
|
||||
if currentUniversePosition >= 510 {
|
||||
universes[currentUniverse] = currentUniverseSlice
|
||||
if !currentRowReverse {
|
||||
currentRowReverse = true
|
||||
} else {
|
||||
currentRowReverse = false
|
||||
}
|
||||
currentUniverse += 1
|
||||
currentUniversePosition = 0
|
||||
currentUniverseSlice = make([]byte, 511)
|
||||
}
|
||||
currentUniverseSlice[currentUniversePosition] = flippedslice[i]
|
||||
currentUniversePosition += 1
|
||||
}
|
||||
universes[currentUniverse] = currentUniverseSlice
|
||||
return universes
|
||||
}
|
||||
|
||||
func XYGridToLinear(w int, h int, grid [][]RGBcolor) []byte {
|
||||
ret := make([]byte, w*h*3)
|
||||
i := 0
|
||||
for y := 0; y < h; y++ {
|
||||
for x := 0; x < w; x++ {
|
||||
ret[i] = grid[x][y][0]
|
||||
ret[i+1] = grid[x][y][1]
|
||||
ret[i+2] = grid[x][y][2]
|
||||
i += 3
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package webserver
|
||||
|
||||
import (
|
||||
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
queue "git.martyn.berlin/martyn/LEDController/internal/queue"
|
||||
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func HealthHandler(response http.ResponseWriter, request *http.Request) {
|
||||
response.Header().Add("Content-type", "text/plain")
|
||||
fmt.Fprint(response, "I'm okay jack!")
|
||||
}
|
||||
|
||||
func NotFoundHandler(response http.ResponseWriter, request *http.Request) {
|
||||
response.WriteHeader(404)
|
||||
fmt.Fprint(response, "I'm lost!")
|
||||
}
|
||||
|
||||
func RootHandler(response http.ResponseWriter, request *http.Request) {
|
||||
response.Header().Add("Content-type", "text/plain")
|
||||
fmt.Fprint(response, "Not implemented")
|
||||
}
|
||||
|
||||
var globalQueue chan queue.QueueItem;
|
||||
|
||||
func PatternHandler(response http.ResponseWriter, request *http.Request) {
|
||||
vars := mux.Vars(request)
|
||||
response.Header().Add("Content-type", "text/plain")
|
||||
var e queue.QueueItem
|
||||
e.Effect = vars["pattern"]
|
||||
i, _ := strconv.Atoi(vars["duration"])
|
||||
e.Duration = uint16(i)
|
||||
_, found := vars["speed"]
|
||||
if found {
|
||||
i, _ := strconv.Atoi(vars["speed"])
|
||||
e.Speed = uint16(i)
|
||||
fmt.Printf("Speed passed %d\n",e.Speed)
|
||||
} else {
|
||||
e.Speed = 40
|
||||
}
|
||||
globalQueue <- e
|
||||
fmt.Fprint(response, "OKAY")
|
||||
}
|
||||
|
||||
func HandleHTTP(queueChannel chan queue.QueueItem) {
|
||||
globalQueue = queueChannel
|
||||
r := mux.NewRouter()
|
||||
loggedRouter := handlers.LoggingHandler(os.Stdout, r)
|
||||
r.NotFoundHandler = http.HandlerFunc(NotFoundHandler)
|
||||
r.HandleFunc("/", RootHandler)
|
||||
r.HandleFunc("/healthz", HealthHandler)
|
||||
r.HandleFunc("/pattern/{pattern}/{duration}", PatternHandler)
|
||||
r.HandleFunc("/pattern/{pattern}/{duration}/{speed}", PatternHandler)
|
||||
http.Handle("/", r)
|
||||
srv := &http.Server{
|
||||
Handler: loggedRouter,
|
||||
Addr: "0.0.0.0:5353",
|
||||
WriteTimeout: 15 * time.Second,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
}
|
||||
fmt.Println("Listening on 0.0.0.0:5353")
|
||||
srv.ListenAndServe()
|
||||
}
|
218
main.go
218
main.go
|
@ -1,154 +1,114 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
"fmt"
|
||||
|
||||
webserver "git.martyn.berlin/martyn/LEDController/internal/webserver"
|
||||
queue "git.martyn.berlin/martyn/LEDController/internal/queue"
|
||||
remapping "git.martyn.berlin/martyn/LEDController/internal/remapping"
|
||||
patterns "git.martyn.berlin/martyn/LEDController/internal/patterns"
|
||||
|
||||
"github.com/Hundemeier/go-sacn/sacn"
|
||||
)
|
||||
|
||||
func even(number int) bool {
|
||||
return number%2 == 0
|
||||
}
|
||||
type RGBcolor = [3]byte
|
||||
|
||||
func slice_rearrange(rowwidth int, rows int, alternaterows bool, inslice []byte) [][]byte {
|
||||
var flippedslice []byte
|
||||
if alternaterows {
|
||||
flippedslice = make([]byte, len(inslice)+3)
|
||||
for r := 0; r < rows; r++ {
|
||||
rowzero := (r*rowwidth*3)
|
||||
if even(r) {
|
||||
for c := 0; c < (rowwidth)*3; c+=3 {
|
||||
flippedslice[rowzero+c] = inslice[rowzero+c]
|
||||
flippedslice[rowzero+c+1] = inslice[rowzero+c+1]
|
||||
flippedslice[rowzero+c+2] = inslice[rowzero+c+2]
|
||||
}
|
||||
} else {
|
||||
x := rowwidth*3
|
||||
for c := 0; c < (rowwidth)*3; c+=3 {
|
||||
x = x-3
|
||||
fmt.Println(x)
|
||||
flippedslice[rowzero+x] = inslice[rowzero+c]
|
||||
flippedslice[rowzero+x+1] = inslice[rowzero+c+1]
|
||||
flippedslice[rowzero+x+2] = inslice[rowzero+c+2]/*
|
||||
flippedslice[rowzero+c] = inslice[rowzero+(((rowwidth-1)*3)-c)]
|
||||
flippedslice[rowzero+c+1] = inslice[rowzero+(((rowwidth-1)*3)-c)-1]
|
||||
flippedslice[rowzero+c+2] = inslice[rowzero+(((rowwidth-1)*3)-c)-2]*/
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
flippedslice = inslice
|
||||
}
|
||||
currentUniverse := 0
|
||||
currentUniversePosition := 0
|
||||
universes := make([][]byte, (len(flippedslice)/510)+1)
|
||||
currentUniverseSlice := make([]byte, 511)
|
||||
currentRowReverse := false;
|
||||
for i := range(flippedslice) {
|
||||
if currentUniversePosition >= 510 {
|
||||
fmt.Println("Reached end of universe!")
|
||||
universes[currentUniverse] = currentUniverseSlice
|
||||
if (!currentRowReverse) {
|
||||
currentRowReverse = true
|
||||
} else {
|
||||
currentRowReverse = false
|
||||
}
|
||||
currentUniverse += 1
|
||||
currentUniversePosition = 0
|
||||
currentUniverseSlice = make([]byte, 511)
|
||||
}
|
||||
currentUniverseSlice[currentUniversePosition] = flippedslice[i]
|
||||
currentUniversePosition += 1
|
||||
}
|
||||
universes[currentUniverse] = currentUniverseSlice
|
||||
return universes
|
||||
}
|
||||
var currentFrame [2][512]byte
|
||||
var channels [2]chan<-[512]byte
|
||||
var sema = make(chan struct{}, 1) // a binary semaphore guarding currentFrame
|
||||
|
||||
func alternate(R0 byte, G0 byte, B0 byte, R1 byte, G1 byte, B1 byte, fromX int, toX int) []byte {
|
||||
ret := make([]byte, toX*3);
|
||||
for i := fromX; i < toX*3; i+=3 {
|
||||
if even(i) {
|
||||
ret[i] = R0
|
||||
ret[i+1] = G0
|
||||
ret[i+2] = B0
|
||||
} else {
|
||||
ret[i] = R1
|
||||
ret[i+1] = G1
|
||||
ret[i+2] = B1
|
||||
var currentEffect queue.QueueItem;
|
||||
var globalEffectChannel = make(chan queue.QueueItem, 1024)
|
||||
|
||||
func foreverLoop() {
|
||||
for /*ever*/ {
|
||||
time.Sleep(40 * time.Millisecond) //25fps
|
||||
for u := 0; u < 2; u++ {
|
||||
sema <- struct{}{} // acquire token
|
||||
channels[u] <- currentFrame[u]
|
||||
<- sema
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// gradient returns from fromX to toX fading from (fromR,fromG,fromB) to (toR,toG,toB)
|
||||
// at least that's the idea.
|
||||
func gradient(fromR byte, fromG byte, fromB byte, toR byte, toG byte, toB byte, fromX int, toX int) []byte {
|
||||
ret := make([]byte, toX*3);
|
||||
var stepR float32 = (float32(toR) - float32(fromR)) / (float32(toX) - float32(fromX))
|
||||
var stepG float32 = (float32(toG) - float32(fromG)) / (float32(toX) - float32(fromX))
|
||||
var stepB float32 = (float32(toB) - float32(fromB)) / (float32(toX) - float32(fromX))
|
||||
for i := fromX; i < toX*3; i+=3 {
|
||||
ret[i] = fromR+byte(float32(i/3)*stepR)
|
||||
ret[i+1] = fromG+byte(float32(i/3)*stepG)
|
||||
ret[i+2] = fromB+byte(float32(i/3)*stepB)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func slice512(s []byte) [512]byte {
|
||||
var ret [512]byte
|
||||
for i := range(s) {
|
||||
if i < 512 {
|
||||
ret[i] = s[i]
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func sliceUnlenthed(s [512]byte) []byte {
|
||||
ret := make([]byte, 512)
|
||||
for i := range(s) {
|
||||
ret[i] = s[i]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func main() {
|
||||
go func() {
|
||||
fmt.Printf("Starting webserver on port %s\n", "5353")
|
||||
webserver.HandleHTTP(globalEffectChannel)
|
||||
}()
|
||||
//instead of "" you could provide an ip-address that the socket should bind to
|
||||
trans, err := sacn.NewTransmitter("", [16]byte{1, 2, 3}, "test")
|
||||
trans, err := sacn.NewTransmitter("", [16]byte{1, 2}, "test")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
//activates the first universe
|
||||
ch1, err := trans.Activate(1)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
//activates the universes
|
||||
for i := 0; i < 2; i++ {
|
||||
channels[i], err = trans.Activate(uint16(i+1))
|
||||
//deactivate the channel on exit
|
||||
defer close(channels[i])
|
||||
trans.SetMulticast(uint16(i+1), false) //this specific setup will not multicast on windows,
|
||||
trans.SetDestinations(uint16(i+1), []string{"192.168.1.139"})
|
||||
}
|
||||
ch2, err := trans.Activate(2)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
//deactivate the channel on exit
|
||||
defer close(ch1)
|
||||
defer close(ch2)
|
||||
|
||||
//set a unicast destination, and/or use multicast
|
||||
trans.SetMulticast(1, false)//this specific setup will not multicast on windows,
|
||||
//because no bind address was provided
|
||||
// Plasma for start frame
|
||||
rearranged := remapping.SliceRearrange(68, 4, true, remapping.XYGridToLinear(68, 4, patterns.PlasmaPanel(68, 4, 40)))
|
||||
currentFrame[0] = remapping.Slice512(rearranged[0])
|
||||
currentFrame[1] = remapping.Slice512(rearranged[1])
|
||||
var e queue.QueueItem
|
||||
e.Effect = "red"
|
||||
e.Duration = 40 * 50
|
||||
globalEffectChannel <- e
|
||||
e.Effect = "plasma"
|
||||
e.Duration = 0
|
||||
e.Speed = 40
|
||||
globalEffectChannel <- e
|
||||
|
||||
//set some example ip-addresses
|
||||
trans.SetDestinations(1, []string{"192.168.1.139"})
|
||||
trans.SetMulticast(2, false)//this specific setup will not multicast on windows,
|
||||
trans.SetDestinations(2, []string{"192.168.1.139"})
|
||||
|
||||
//send some random data for 10 seconds
|
||||
for i := 0; i < 20; i++ {
|
||||
channels := slice_rearrange(68,4,true,gradient(255,255,255,0,0,0,0,272))
|
||||
ch1 <- slice512(channels[0])
|
||||
ch2 <- slice512(channels[1])
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
go func() {
|
||||
for /*ever*/ {
|
||||
if currentEffect.Duration > 0 {
|
||||
currentEffect.Duration -= 40
|
||||
} else {
|
||||
if len(globalEffectChannel) > 0 {
|
||||
currentEffect = <- globalEffectChannel
|
||||
}
|
||||
}
|
||||
var rearranged [][]byte
|
||||
switch currentEffect.Effect {
|
||||
case "line":
|
||||
rearranged = remapping.SliceRearrange(68, 4, true, remapping.XYGridToLinear(68, 4, patterns.ZigZag(68, 4)))
|
||||
case "plasma":
|
||||
rearranged = remapping.SliceRearrange(68, 4, true, remapping.XYGridToLinear(68, 4, patterns.PlasmaPanel(68, 4, currentEffect.Speed)))
|
||||
case "red":
|
||||
rearranged = remapping.SliceRearrange(68, 4, false, remapping.XYGridToLinear(68, 4, patterns.RedPanel(68,4)))
|
||||
case "random":
|
||||
rearranged = remapping.SliceRearrange(68, 4, false, remapping.XYGridToLinear(68, 4, patterns.RandomColourPanel(68,4,currentEffect.Speed)))
|
||||
case "linearplasma":
|
||||
rearranged = remapping.SliceRearrange(68, 4, false, patterns.LinearPlasma(68*4))
|
||||
case "gradientred":
|
||||
rearranged = remapping.SliceRearrange(68, 4, false, patterns.Gradient(255, 0, 0, 0, 0, 255, 0, 68*4))
|
||||
case "sine":
|
||||
var black patterns.RGBcolor
|
||||
var red patterns.RGBcolor
|
||||
red[0] = 255
|
||||
rearranged = remapping.SliceRearrange(68, 4, true, remapping.XYGridToLinear(68, 4, patterns.Sinewave(68, 4, black, red, currentEffect.Speed)))
|
||||
case "sinechase":
|
||||
var black patterns.RGBcolor
|
||||
var red patterns.RGBcolor
|
||||
red[0] = 255
|
||||
rearranged = remapping.SliceRearrange(68, 4, true, remapping.XYGridToLinear(68, 4, patterns.SineChase(68, 4, black, red, currentEffect.Speed)))
|
||||
default:
|
||||
rearranged = remapping.SliceRearrange(68, 4, false, remapping.XYGridToLinear(68, 4, patterns.FillPanel(68,4, 128,0,128)))
|
||||
}
|
||||
//rearranged := remapping.SliceRearrange(68,4,true,linearPlasma(68*4))
|
||||
sema <- struct{}{} // acquire token
|
||||
currentFrame[0] = remapping.Slice512(rearranged[0])
|
||||
currentFrame[1] = remapping.Slice512(rearranged[1])
|
||||
<- sema
|
||||
time.Sleep(40 * time.Millisecond)
|
||||
}
|
||||
}()
|
||||
foreverLoop();
|
||||
}
|
Loading…
Reference in New Issue