From 33e8cff79f01946f330d647f4547f7d50c234a82 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Thu, 26 Oct 2017 19:26:54 -0700 Subject: [PATCH] Some initial pixel drawing with the mouse --- Makefile | 2 +- cmd/doodle/main.go | 4 +- doodle.go | 211 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 202 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 6fb1d5c..dd8ea37 100644 --- a/Makefile +++ b/Makefile @@ -31,4 +31,4 @@ test: # `make clean` cleans everything up. .PHONY: clean clean: -rm -rf bin dist + rm -rf bin dist diff --git a/cmd/doodle/main.go b/cmd/doodle/main.go index 1170f61..0487c96 100644 --- a/cmd/doodle/main.go +++ b/cmd/doodle/main.go @@ -2,6 +2,7 @@ package main import ( "flag" + "runtime" "github.com/kirsle/doodle" ) @@ -19,8 +20,9 @@ func init() { } func main() { + runtime.LockOSThread() flag.Parse() app := doodle.New(debug) - _ = app + app.Run() } diff --git a/doodle.go b/doodle.go index 03e0d98..5d57913 100644 --- a/doodle.go +++ b/doodle.go @@ -1,6 +1,10 @@ package doodle -import "github.com/veandco/go-sdl2/sdl" +import ( + "fmt" + + "github.com/veandco/go-sdl2/sdl" +) // Version number. const Version = "0.0.0-alpha" @@ -9,19 +13,44 @@ const Version = "0.0.0-alpha" type Doodle struct { Debug bool + running bool + events EventState + width int + height int + window *sdl.Window + surface *sdl.Surface renderer *sdl.Renderer } +// EventState keeps track of important events. +type EventState struct { + CursorX int32 + CursorY int32 + LastX int32 + LastY int32 + LeftClick bool + LastLeft bool + RightClick bool + LastRight bool +} + // New initializes the game object. func New(debug bool) *Doodle { d := &Doodle{ - Debug: debug, + Debug: debug, + running: true, + width: 800, + height: 600, } + return d +} +// Run initializes SDL and starts the main loop. +func (d *Doodle) Run() error { // Initialize SDL. if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil { - panic(err) + return err } defer sdl.Quit() @@ -30,30 +59,186 @@ func New(debug bool) *Doodle { "Doodle v"+Version, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, - 800, - 600, + d.width, + d.height, sdl.WINDOW_SHOWN, ) if err != nil { - panic(err) + return err } defer window.Destroy() + d.window = window - surface, err := window.GetSurface() + // Blank out the window in white. + renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) if err != nil { panic(err) } + d.renderer = renderer + defer renderer.Destroy() + for i := 0; i < 10; i++ { + d.Loop() + // renderer.Clear() + // rect := sdl.Rect{ + // X: 0, + // Y: 0, + // W: 800, + // H: 600, + // } + // renderer.SetDrawColor(0, 0, 0, 255) + // renderer.FillRect(&rect) + // + // renderer.SetDrawColor(0, 255, 0, 255) + // renderer.DrawPoint(10*i, 10*i) + // + // renderer.Present() + // + // sdl.Delay(250) + } + + for d.running { + err = d.Loop() + if err != nil { + return err + } + } + + // surface, err := window.GetSurface() + // if err != nil { + // panic(err) + // } + // d.surface = surface + // + // rect := sdl.Rect{ + // X: 0, + // Y: 0, + // W: 200, + // H: 200, + // } + // surface.FillRect(&rect, 0xffff0000) + // window.UpdateSurface() + // + // sdl.Delay(2500) + return nil +} + +// TODO: not a global +type Pixel struct { + start bool + x int32 + y int32 +} + +var pixelHistory []Pixel + +// Loop runs one loop of the game engine. +func (d *Doodle) Loop() error { + // Poll for events. + d.PollEvents() + + d.renderer.Clear() rect := sdl.Rect{ X: 0, Y: 0, - W: 200, - H: 200, + W: 800, + H: 600, } - surface.FillRect(&rect, 0xffff0000) - window.UpdateSurface() + d.renderer.SetDrawColor(255, 255, 255, 255) + d.renderer.FillRect(&rect) - sdl.Delay(2500) + // Clicking? Log all the pixels while doing so. + if d.events.LeftClick { + fmt.Printf("Pixel at %dx%d\n", d.events.CursorX, d.events.CursorY) + pixel := Pixel{ + start: d.events.LeftClick && !d.events.LastLeft, + x: d.events.CursorX, + y: d.events.CursorY, + } + pixelHistory = append(pixelHistory, pixel) + } - return d + // Colorize all those pixels. + d.renderer.SetDrawColor(0, 0, 0, 255) + for i, pixel := range pixelHistory { + fmt.Printf("Draw: %v\n", pixel) + if pixel.start == false && i > 0 { + start := pixelHistory[i-1] + fmt.Printf("Line from %dx%d -> %dx%d\n", start.x, start.y, pixel.x, pixel.y) + d.renderer.DrawLine( + int(start.x), + int(start.y), + int(pixel.x), + int(pixel.y), + ) + } else { + d.renderer.DrawPoint( + int(pixel.x), int(pixel.y), + ) + } + // d.renderer.FillRect(&sdl.Rect{pixel.x, pixel.y, 10, 10}) + } + + d.renderer.Present() + sdl.Delay(1000 / 60) + + return nil +} + +// PollEvents checks for keyboard/mouse/etc. events. +func (d *Doodle) PollEvents() { + for { + event := sdl.PollEvent() + if event == nil { + break + } + + // Handle the event. + switch t := event.(type) { + case *sdl.QuitEvent: + d.running = false + case *sdl.MouseMotionEvent: + fmt.Printf("[%d ms] MouseMotion type:%d id:%d x:%d y:%d xrel:%d yrel:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel, + ) + d.events.LastX = d.events.CursorX + d.events.LastY = d.events.CursorY + d.events.CursorX = t.X + d.events.CursorY = t.Y + case *sdl.MouseButtonEvent: + fmt.Printf("[%d ms] MouseButton type:%d id:%d x:%d y:%d button:%d state:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State, + ) + + d.events.LastX = d.events.CursorX + d.events.LastY = d.events.CursorY + d.events.CursorX = t.X + d.events.CursorY = t.Y + + d.events.LastLeft = d.events.LeftClick + d.events.LastRight = d.events.RightClick + + // Clicking? + if t.Button == 1 { + if t.State == 1 && d.events.LeftClick == false { + d.events.LeftClick = true + } else if t.State == 0 && d.events.LeftClick == true { + d.events.LeftClick = false + } + } + d.events.RightClick = t.Button == 3 && t.State == 1 + case *sdl.MouseWheelEvent: + fmt.Printf("[%d ms] MouseWheel type:%d id:%d x:%d y:%d\n", + t.Timestamp, t.Type, t.Which, t.X, t.Y, + ) + case *sdl.KeyDownEvent: + fmt.Printf("[%d ms] Keyboard type:%d sym:%c modifiers:%d state:%d repeat:%d\n", + t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat, + ) + case *sdl.KeyUpEvent: + fmt.Printf("[%d ms] Keyboard type:%d sym:%c modifiers:%d state:%d repeat:%d\n", + t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat, + ) + } + } }