From b1c8a696e4e40ea1ae72f886e0cfb4468eb737e8 Mon Sep 17 00:00:00 2001 From: Martin Ashby Date: Mon, 21 May 2018 10:16:32 +0100 Subject: Moved unicorn to it's own package --- FakeUnicorn.go | 94 -------------------------------------------------------- RealUnicorn.go | 67 ---------------------------------------- Server.go | 54 +++++++++++++------------------- Unicorn.go | 79 ----------------------------------------------- Unicorn_test.go | 80 ----------------------------------------------- unicorn.zip | Bin 7539 -> 0 bytes 6 files changed, 21 insertions(+), 353 deletions(-) delete mode 100644 FakeUnicorn.go delete mode 100644 RealUnicorn.go delete mode 100644 Unicorn.go delete mode 100644 Unicorn_test.go delete mode 100644 unicorn.zip diff --git a/FakeUnicorn.go b/FakeUnicorn.go deleted file mode 100644 index d282ba5..0000000 --- a/FakeUnicorn.go +++ /dev/null @@ -1,94 +0,0 @@ -package main - -import ( - "github.com/veandco/go-sdl2/sdl" -) - -type FakeUnicorn struct { - BaseUnicorn - displayWidth int32 - displayHeight int32 - window *sdl.Window - renderer *sdl.Renderer -} - -// NewFake ... -// Constructs a new fake unicorn out of paint and glue -func NewFake(width, height uint8) (*FakeUnicorn, error) { - if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil { - return nil, err - } - - unicorn := &FakeUnicorn{ - BaseUnicorn{ - pixels: makePixels(width, height), - }, - 300, - 300, - nil, - nil, - } - if err := unicorn.createWindow(); err != nil { - unicorn.Close() - return nil, err - } - if err := unicorn.createRenderer(); err != nil { - unicorn.Close() - return nil, err - } - return unicorn, nil -} - -func (f *FakeUnicorn) createWindow() error { - window, err := sdl.CreateWindow("Fake Unicorn", - sdl.WINDOWPOS_UNDEFINED, - sdl.WINDOWPOS_UNDEFINED, - f.displayWidth, - f.displayHeight, - sdl.WINDOW_SHOWN) - f.window = window - return err -} - -func (f *FakeUnicorn) createRenderer() error { - renderer, err := sdl.CreateRenderer(f.window, -1, sdl.RENDERER_ACCELERATED) - f.renderer = renderer - return err -} - -func (f *FakeUnicorn) Close() error { - if f.window != nil { - f.window.Destroy() - } - if f.renderer != nil { - f.renderer.Destroy() - } - return nil -} - -func (f *FakeUnicorn) Show() { - width, height := f.GetWidth(), f.GetHeight() - for x := uint8(0); x < width; x++ { - for y := uint8(0); y < height; y++ { - r, g, b := rgb(f.pixels[x][y]) - if err := f.renderer.SetDrawColor(r, g, b, uint8(255)); err != nil { - panic(err) - } - cellWidth := f.displayWidth / int32(width) - cellHeight := f.displayHeight / int32(height) - if err := f.renderer.FillRect(&sdl.Rect{ - X: cellWidth * int32(x), - Y: f.displayHeight - (cellHeight * int32(y)) - cellHeight, // SDL Y coordinate is from the top - W: cellWidth, - H: cellHeight, - }); err != nil { - panic(err) - } - } - } - f.renderer.Present() -} - -func (f *FakeUnicorn) Off() { - f.Close() -} diff --git a/RealUnicorn.go b/RealUnicorn.go deleted file mode 100644 index 31fd229..0000000 --- a/RealUnicorn.go +++ /dev/null @@ -1,67 +0,0 @@ -package main - -import ( - //"golang.org/x/exp/io/spi" - "github.com/ecc1/spi" - "log" -) - -type RealUnicorn struct { - BaseUnicorn - device *spi.Device -} - -// NewReal ... -// Constructs a new real unicorn from fairy dust and sprinkles -func NewReal() (*RealUnicorn, error) { - /*dev, err := spi.Open(&spi.Devfs{ - Dev: "/dev/spidev0.0", - Mode: spi.Mode3, - MaxSpeed: 9000000, - })*/ - dev, err := spi.Open("/dev/spidev0.0", 9000000, 0) - if err != nil { - return nil, err - } - //dev.SetBitOrder(spi.LSBFirst) - - return &RealUnicorn{ - BaseUnicorn{ - pixels: makePixels(16, 16), - }, - dev, - }, nil -} - -func (u *RealUnicorn) Show() { - // Width * height * colours + leading bit - width := int(u.GetWidth()) - height := int(u.GetHeight()) - sz := (width*height*3)+1 - write := make([]byte, sz) - - // Add the leading bit - write[0] = 0x72 - // Add all the pixel values - ix := 1 - for x := 0; x < width; x++ { - for y := 0; y < height; y++ { - for j := 0; j < 3; j++ { - write[ix] = byte(u.pixels[x][y][j]) - ix++ - } - } - } - // Write to the device - //err := u.device.Tx(write, nil) - err := u.device.Transfer(write) - if err != nil { - log.Printf("Error writing to SPI device %v", err) - } -} -func (u *RealUnicorn) Off() { - u.Close() -} -func (u *RealUnicorn) Close() error { - return u.device.Close() -} diff --git a/Server.go b/Server.go index eee725d..38dd493 100644 --- a/Server.go +++ b/Server.go @@ -3,17 +3,20 @@ package main import ( "encoding/json" "fmt" + "github.com/gorilla/websocket" - //"github.com/veandco/go-sdl2/sdl" + //"github.com/veandco/go-sdl2/sdl" "io/ioutil" "log" "net/http" "path" "strings" + + "github.com/MFAshby/unicornpaint/unicorn" ) var ( - unicorn Unicorn + un unicorn.Unicorn upgrader = websocket.Upgrader{ ReadBufferSize: 1024, @@ -81,9 +84,9 @@ func getState() *State { } // Irritating conversion function - pixels := unicorn.GetPixels() - width := unicorn.GetWidth() - height := unicorn.GetHeight() + pixels := un.GetPixels() + width := un.GetWidth() + height := un.GetHeight() px2 := make([][]uint8arr, width) for x := uint8(0); x < width; x++ { @@ -100,7 +103,8 @@ func getState() *State { } func savePic(saveFileName string) { - pixels := unicorn.GetPixels() + pixels := un.GetPixels() + // Save to PNG instead data, err := json.Marshal(pixels) if err != nil { log.Printf("Failed to save picture to JSON %v", err) @@ -131,11 +135,11 @@ func loadPic(saveFileName string) { height := len(newPixels[0]) for x := 0; x < width; x++ { for y := 0; y < height; y++ { - r, g, b := rgb(newPixels[x][y]) - unicorn.SetPixel(uint8(x), uint8(y), r, g, b) + r, g, b := unicorn.Rgb(newPixels[x][y]) + un.SetPixel(uint8(x), uint8(y), r, g, b) } } - unicorn.Show() + un.Show() } func upgradeHandler(w http.ResponseWriter, r *http.Request) { @@ -169,11 +173,11 @@ func upgradeHandler(w http.ResponseWriter, r *http.Request) { case noop: // Don't do anything case setPixel: - unicorn.SetPixel(cmd.X, cmd.Y, cmd.R, cmd.G, cmd.B) - unicorn.Show() + un.SetPixel(cmd.X, cmd.Y, cmd.R, cmd.G, cmd.B) + un.Show() case clear: - unicorn.Clear() - unicorn.Show() + un.Clear() + un.Show() case save: savePic(cmd.SaveName) case load: @@ -185,19 +189,6 @@ func upgradeHandler(w http.ResponseWriter, r *http.Request) { } } -/*func handleSdlEvents() { - running := true - for running { - for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { - switch event.(type) { - case *sdl.QuitEvent: - running = false - break - } - } - } -}*/ - func handleClients() { for { select { @@ -212,19 +203,18 @@ func handleClients() { } func main() { - uni, err := GetUnicorn() + uni, err := unicorn.GetUnicorn() if err != nil { log.Fatalf("Couldn't get a unicorn :( %v", err) } - unicorn = uni + un = uni log.Println("Starting server on port 3001") http.Handle("/", http.FileServer(http.Dir("build"))) http.HandleFunc("/ws", upgradeHandler) go http.ListenAndServe(":3001", nil) - //go handleClients() - handleClients() - //handleSdlEvents() + go handleClients() + un.MainLoop() } func doBroadcast(obj interface{}) { @@ -238,5 +228,3 @@ func doBroadcast(obj interface{}) { } } } - - diff --git a/Unicorn.go b/Unicorn.go deleted file mode 100644 index 8042358..0000000 --- a/Unicorn.go +++ /dev/null @@ -1,79 +0,0 @@ -package main - -import ( - // "log" -) - -// Unicorn ... -// Object representing the Unicorn HAT to be controlled -type Unicorn interface { - // Not all unicorns are the same size - GetWidth() uint8 - GetHeight() uint8 - - // Array of pixels, indexed x, then y, then color (rgb) - GetPixels() [][][]uint8 - - // Set an individual pixel - SetPixel(x, y, r, g, b uint8) - - // Flip the display buffer - Show() - - // Set all pixels back to black - Clear() - - // Turns off the LEDs - Off() -} - -// GetUnicorn ... -// Get a unicorn. Tries to get you a real one, -// if it can't find one then gives you a fake one. -func GetUnicorn() (unicorn Unicorn, err error) { - unicorn, err = NewReal() - //if err != nil { - // log.Println("Couldn't get a real unicorn, trying a fake one") - // unicorn, err = NewFake(uint8(16), uint8(16)) - //} - return -} - -type BaseUnicorn struct { - pixels [][][]uint8 -} - -func (f *BaseUnicorn) GetWidth() uint8 { - return uint8(len(f.pixels)) -} -func (f *BaseUnicorn) GetHeight() uint8 { - if len(f.pixels) > 0 { - return uint8(len(f.pixels[0])) - } - return 0 -} -func (f *BaseUnicorn) GetPixels() [][][]uint8 { - return f.pixels -} -func (f *BaseUnicorn) SetPixel(x, y, r, g, b uint8) { - f.pixels[x][y] = []uint8{r, g, b} -} -func (f *BaseUnicorn) Clear() { - f.pixels = makePixels(f.GetWidth(), f.GetHeight()) -} - -func makePixels(width, height uint8) [][][]uint8 { - pixels := make([][][]uint8, width) - for x := uint8(0); x < width; x++ { - pixels[x] = make([][]uint8, height) - for y := uint8(0); y < height; y++ { - pixels[x][y] = []uint8{0, 0, 0} - } - } - return pixels -} - - -func rgb(pixel []uint8) (uint8, uint8, uint8) { - return pixel[0], pixel[1], pixel[2] -} diff --git a/Unicorn_test.go b/Unicorn_test.go deleted file mode 100644 index 4b06a73..0000000 --- a/Unicorn_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package main - -import ( - "reflect" - "testing" - "time" -) - -func TestGetUnicorn(t *testing.T) { - -} - -func TestFakeUnicorn(t *testing.T) { - unicorn, err := NewFake(uint8(16), uint8(16)) - if err != nil { - t.Errorf("Got an error making a fake unicorn, shouldn't happen") - } - defer unicorn.Close() - - // Check simple functions - if unicorn.GetHeight() != 16 { - t.Errorf("Height was wrong, expecting 16") - } - if unicorn.GetWidth() != 16 { - t.Errorf("Width was wrong, expecting 16") - } - // Pixels should be black to start with - pixels := unicorn.GetPixels() - for x := uint8(0); x < 16; x++ { - for y := uint8(0); y < 16; y++ { - if !reflect.DeepEqual(pixels[x][y], []uint8{0, 0, 0}) { - t.Errorf("Expecting black pixels to start with") - } - } - } - - // Should be able to set a pixel, no others should change - unicorn.SetPixel(0, 0, uint8(255), uint8(255), uint8(255)) - pixels = unicorn.GetPixels() - if !reflect.DeepEqual(pixels[0][0], []uint8{255, 255, 255}) { - t.Errorf("Pixel wasn't set when it should be") - } - for x := uint8(0); x < 16; x++ { - for y := uint8(0); y < 16; y++ { - if x == 0 && y == 0 { - continue - } - if !reflect.DeepEqual(pixels[x][y], []uint8{0, 0, 0}) { - t.Errorf("Expecting black pixels to start with") - } - } - } - - // Should be able to set a second pixel - unicorn.SetPixel(3, 4, uint8(4), uint8(5), uint8(6)) - pixels = unicorn.GetPixels() - for x := uint8(0); x < 16; x++ { - for y := uint8(0); y < 16; y++ { - checkcolor := []uint8{0, 0, 0} - if x == 0 && y == 0 { - checkcolor = []uint8{255, 255, 255} - } else if x == 3 && y == 4 { - checkcolor = []uint8{4, 5, 6} - } - if !reflect.DeepEqual(pixels[x][y], checkcolor) { - t.Errorf("Got incorrect pixel color at %d %d", x, y) - } - } - } - - unicorn.Show() - time.Sleep(time.Duration(500) * time.Millisecond) - unicorn.SetPixel(10, 10, uint8(255), uint8(255), uint8(0)) - unicorn.Show() - time.Sleep(time.Duration(500) * time.Millisecond) - - unicorn.SetPixel(0, 15, uint8(255), uint8(0), uint8(0)) - unicorn.Show() - time.Sleep(time.Duration(500) * time.Millisecond) -} diff --git a/unicorn.zip b/unicorn.zip deleted file mode 100644 index 70bc7af..0000000 Binary files a/unicorn.zip and /dev/null differ -- cgit v1.2.3-ZIG