diff --git a/cmd/doodad/commands/convert.go b/cmd/doodad/commands/convert.go index f840178..a1c188e 100644 --- a/cmd/doodad/commands/convert.go +++ b/cmd/doodad/commands/convert.go @@ -11,7 +11,7 @@ import ( "image/png" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/branding" "git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/level" diff --git a/cmd/doodad/commands/edit_level.go b/cmd/doodad/commands/edit_level.go index 6eaffae..0ea138b 100644 --- a/cmd/doodad/commands/edit_level.go +++ b/cmd/doodad/commands/edit_level.go @@ -3,7 +3,7 @@ package commands import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/log" "github.com/urfave/cli" diff --git a/cmd/doodle/main.go b/cmd/doodle/main.go index 5858185..5949223 100644 --- a/cmd/doodle/main.go +++ b/cmd/doodle/main.go @@ -8,7 +8,7 @@ import ( "sort" "time" - "git.kirsle.net/apps/doodle/lib/render/sdl" + "git.kirsle.net/go/render/sdl" doodle "git.kirsle.net/apps/doodle/pkg" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/bindata" diff --git a/dev-assets/doodads/azulian/azulian.js b/dev-assets/doodads/azulian/azulian.js index 8a335d1..1599b48 100644 --- a/dev-assets/doodads/azulian/azulian.js +++ b/dev-assets/doodads/azulian/azulian.js @@ -16,12 +16,12 @@ function main() { Vx = 0; Vy = 0; - if (ev.Right.Now) { + if (ev.Right) { if (!Self.IsAnimating()) { Self.PlayAnimation("walk-right", null); } Vx = playerSpeed; - } else if (ev.Left.Now) { + } else if (ev.Left) { if (!Self.IsAnimating()) { Self.PlayAnimation("walk-left", null); } diff --git a/lib/draw/line.go b/lib/draw/line.go index bc98a87..68d8bdb 100644 --- a/lib/draw/line.go +++ b/lib/draw/line.go @@ -3,7 +3,7 @@ package draw import ( "math" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Line is a generator that returns the X,Y coordinates to draw a line. diff --git a/lib/draw/line_test.go b/lib/draw/line_test.go index 7e20f21..4df1032 100644 --- a/lib/draw/line_test.go +++ b/lib/draw/line_test.go @@ -5,7 +5,7 @@ import ( "testing" "git.kirsle.net/apps/doodle/lib/draw" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) func TestLine(t *testing.T) { diff --git a/lib/render/README.md b/lib/render/README.md deleted file mode 100644 index fde0e4b..0000000 --- a/lib/render/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Render: Go Graphics Library - -Render is a graphics library written in Go which targets desktop applications on -Windows, MacOS and Linux as well as WebAssembly to run in the browser. - -For desktop systems it uses SDL2 under the hood, and in WebAssembly it interacts -with an HTML Canvas element for drawing. diff --git a/lib/render/canvas/canvas.go b/lib/render/canvas/canvas.go deleted file mode 100644 index e492099..0000000 --- a/lib/render/canvas/canvas.go +++ /dev/null @@ -1,39 +0,0 @@ -package canvas - -import ( - "syscall/js" -) - -// Canvas represents an HTML5 Canvas object. -type Canvas struct { - Value js.Value - ctx2d js.Value -} - -// GetCanvas gets an HTML5 Canvas object from the DOM. -func GetCanvas(id string) Canvas { - canvasEl := js.Global().Get("document").Call("getElementById", id) - canvas2d := canvasEl.Call("getContext", "2d") - - c := Canvas{ - Value: canvasEl, - ctx2d: canvas2d, - } - - canvasEl.Set("width", c.ClientW()) - canvasEl.Set("height", c.ClientH()) - - return c -} - -// ClientW returns the client width. -func (c Canvas) ClientW() int { - return js.Global().Get("window").Get("innerWidth").Int() - // return c.Value.Get("clientWidth").Int() -} - -// ClientH returns the client height. -func (c Canvas) ClientH() int { - return js.Global().Get("window").Get("innerHeight").Int() - // return c.Value.Get("clientHeight").Int() -} diff --git a/lib/render/canvas/draw.go b/lib/render/canvas/draw.go deleted file mode 100644 index f16381c..0000000 --- a/lib/render/canvas/draw.go +++ /dev/null @@ -1,77 +0,0 @@ -package canvas - -import ( - "fmt" - "syscall/js" - - "git.kirsle.net/apps/doodle/lib/render" -) - -// Methods here implement the drawing functions of the render.Engine - -// RGBA turns a color into CSS RGBA string. -func RGBA(c render.Color) string { - return fmt.Sprintf("rgba(%d,%d,%d,%f)", - c.Red, - c.Green, - c.Blue, - float64(c.Alpha)/255, - ) -} - -// Clear the canvas to a certain color. -func (e *Engine) Clear(color render.Color) { - e.canvas.ctx2d.Set("fillStyle", RGBA(color)) - e.canvas.ctx2d.Call("fillRect", 0, 0, e.width, e.height) -} - -// SetTitle sets the window title. -func (e *Engine) SetTitle(title string) { - js.Global().Get("document").Set("title", title) -} - -// DrawPoint draws a pixel. -func (e *Engine) DrawPoint(color render.Color, point render.Point) { - e.canvas.ctx2d.Set("fillStyle", RGBA(color)) - e.canvas.ctx2d.Call("fillRect", - int(point.X), - int(point.Y), - 1, - 1, - ) -} - -// DrawLine draws a line between two points. -func (e *Engine) DrawLine(color render.Color, a, b render.Point) { - e.canvas.ctx2d.Set("fillStyle", RGBA(color)) - for pt := range render.IterLine(a, b) { - e.canvas.ctx2d.Call("fillRect", - int(pt.X), - int(pt.Y), - 1, - 1, - ) - } -} - -// DrawRect draws a rectangle. -func (e *Engine) DrawRect(color render.Color, rect render.Rect) { - e.canvas.ctx2d.Set("strokeStyle", RGBA(color)) - e.canvas.ctx2d.Call("strokeRect", - int(rect.X), - int(rect.Y), - int(rect.W), - int(rect.H), - ) -} - -// DrawBox draws a filled rectangle. -func (e *Engine) DrawBox(color render.Color, rect render.Rect) { - e.canvas.ctx2d.Set("fillStyle", RGBA(color)) - e.canvas.ctx2d.Call("fillRect", - int(rect.X), - int(rect.Y), - int(rect.W), - int(rect.H), - ) -} diff --git a/lib/render/canvas/engine.go b/lib/render/canvas/engine.go deleted file mode 100644 index ab458cf..0000000 --- a/lib/render/canvas/engine.go +++ /dev/null @@ -1,86 +0,0 @@ -package canvas - -import ( - "syscall/js" - "time" - - "git.kirsle.net/apps/doodle/lib/render/event" -) - -// Engine implements a rendering engine targeting an HTML canvas for -// WebAssembly targets. -type Engine struct { - canvas Canvas - startTime time.Time - width int - height int - ticks uint32 - - // Private fields. - events *event.State - running bool - textures map[string]*Texture // cached texture PNG images - - // Event channel. WASM subscribes to events asynchronously using the - // JavaScript APIs, whereas SDL2 polls the event queue which orders them - // all up for processing. This channel will order and queue the events. - queue chan Event -} - -// New creates the Canvas Engine. -func New(canvasID string) (*Engine, error) { - canvas := GetCanvas(canvasID) - - engine := &Engine{ - canvas: canvas, - startTime: time.Now(), - events: event.NewState(), - width: canvas.ClientW(), - height: canvas.ClientH(), - queue: make(chan Event, 1024), - textures: map[string]*Texture{}, - } - - return engine, nil -} - -// WindowSize returns the size of the canvas window. -func (e *Engine) WindowSize() (w, h int) { - // Good time to recompute it first? - var ( - window = js.Global().Get("window") - width = window.Get("innerWidth").Int() - height = window.Get("innerHeight").Int() - ) - e.canvas.Value.Set("width", width) - e.canvas.Value.Set("height", height) - return e.canvas.ClientW(), e.canvas.ClientH() -} - -// GetTicks returns the number of milliseconds since the engine started. -func (e *Engine) GetTicks() uint32 { - ms := time.Since(e.startTime) * time.Millisecond - return uint32(ms) -} - -// TO BE IMPLEMENTED... - -func (e *Engine) Setup() error { - return nil -} - -func (e *Engine) Present() error { - return nil -} - -// Delay for a moment. -func (e *Engine) Delay(delay uint32) { - time.Sleep(time.Duration(delay) * time.Millisecond) -} - -// Teardown tasks. -func (e *Engine) Teardown() {} - -func (e *Engine) Loop() error { - return nil -} diff --git a/lib/render/canvas/events.go b/lib/render/canvas/events.go deleted file mode 100644 index 7b20f91..0000000 --- a/lib/render/canvas/events.go +++ /dev/null @@ -1,216 +0,0 @@ -package canvas - -import ( - "syscall/js" - - "git.kirsle.net/apps/doodle/lib/render/event" -) - -// EventClass to categorize JavaScript events. -type EventClass int - -// EventClass values. -const ( - MouseEvent EventClass = iota - ClickEvent - KeyEvent - ResizeEvent - WindowEvent -) - -// Event object queues up asynchronous JavaScript events to be processed linearly. -type Event struct { - Name string // mouseup, keydown, etc. - Class EventClass - - // Mouse events. - X int - Y int - LeftClick bool - RightClick bool - - // Key events. - KeyName string - State bool - Repeat bool -} - -// AddEventListeners sets up bindings to collect events from the browser. -func (e *Engine) AddEventListeners() { - // Window resize. - js.Global().Get("window").Call( - "addEventListener", - "resize", - js.FuncOf(func(this js.Value, args []js.Value) interface{} { - e.queue <- Event{ - Name: "resize", - Class: WindowEvent, - } - return nil - }), - ) - - // Mouse movement. - e.canvas.Value.Call( - "addEventListener", - "mousemove", - js.FuncOf(func(this js.Value, args []js.Value) interface{} { - var ( - x = args[0].Get("pageX").Int() - y = args[0].Get("pageY").Int() - ) - - e.queue <- Event{ - Name: "mousemove", - Class: MouseEvent, - X: x, - Y: y, - } - return nil - }), - ) - - // Mouse clicks. - for _, ev := range []string{"mouseup", "mousedown"} { - ev := ev - e.canvas.Value.Call( - "addEventListener", - ev, - js.FuncOf(func(this js.Value, args []js.Value) interface{} { - var ( - x = args[0].Get("pageX").Int() - y = args[0].Get("pageY").Int() - which = args[0].Get("which").Int() - ) - - // Is a mouse button pressed down? - checkDown := func(number int) bool { - if which == number { - return ev == "mousedown" - } - return false - } - - e.queue <- Event{ - Name: ev, - Class: ClickEvent, - X: x, - Y: y, - LeftClick: checkDown(1), - RightClick: checkDown(3), - } - return false - }), - ) - } - - // Supress context menu. - e.canvas.Value.Call( - "addEventListener", - "contextmenu", - js.FuncOf(func(this js.Value, args []js.Value) interface{} { - args[0].Call("preventDefault") - return false - }), - ) - - // Keyboard keys - for _, ev := range []string{"keydown", "keyup"} { - ev := ev - js.Global().Get("document").Call( - "addEventListener", - ev, - js.FuncOf(func(this js.Value, args []js.Value) interface{} { - var ( - event = args[0] - key = event.Get("key").String() - repeat = event.Get("repeat").Bool() - - pressed = ev == "keydown" - ) - - if key == "F3" { - args[0].Call("preventDefault") - } - - e.queue <- Event{ - Name: ev, - Class: KeyEvent, - KeyName: key, - Repeat: repeat, - State: pressed, - } - return nil - }), - ) - } -} - -// PollEvent returns the next event in the queue, or null. -func (e *Engine) PollEvent() *Event { - select { - case event := <-e.queue: - return &event - default: - return nil - } - return nil -} - -// Poll for events. -func (e *Engine) Poll() (*event.State, error) { - s := e.events - - for event := e.PollEvent(); event != nil; event = e.PollEvent() { - switch event.Class { - case WindowEvent: - s.WindowResized = true - case MouseEvent: - s.CursorX = event.X - s.CursorY = event.Y - case ClickEvent: - s.CursorX = event.X - s.CursorY = event.Y - s.Button1 = event.LeftClick - s.Button2 = event.RightClick - case KeyEvent: - switch event.KeyName { - case "Escape": - if event.Repeat { - continue - } - - s.Escape = event.State - case "Enter": - if event.Repeat { - continue - } - - s.Enter = event.State - case "F3": - s.SetKeyDown("F3", event.State) - case "ArrowUp": - s.Up = event.State - case "ArrowLeft": - s.Left = event.State - case "ArrowRight": - s.Right = event.State - case "ArrowDown": - s.Down = event.State - case "Shift": - s.Shift = event.State - continue - case "Alt": - s.Alt = event.State - case "Control": - s.Ctrl = event.State - case "Backspace": - s.SetKeyDown(`\b`, event.State) - default: - s.SetKeyDown(event.KeyName, event.State) - } - } - } - - return e.events, nil -} diff --git a/lib/render/canvas/text.go b/lib/render/canvas/text.go deleted file mode 100644 index a4ce4aa..0000000 --- a/lib/render/canvas/text.go +++ /dev/null @@ -1,88 +0,0 @@ -package canvas - -// Text rendering functions using the HTML 5 canvas. - -import ( - "fmt" - "path/filepath" - "strings" - - "git.kirsle.net/apps/doodle/lib/render" -) - -// FontFilenameToName converts a FontFilename to its CSS font name. -// -// The CSS font name is set to the base of the filename, without the .ttf -// file extension. For example, "fonts/DejaVuSans.ttf" uses the CSS font -// family name "DejaVuSans" and that's what this function returns. -// -// Fonts must be defined in the index.html style sheet when serving the -// wasm build of Doodle. -// -// If filename is "", returns "serif" as a sensible default. -func FontFilenameToName(filename string) string { - if filename == "" { - return "DejaVuSans,serif" - } - return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename)) -} - -// DrawText draws text on the canvas. -func (e *Engine) DrawText(text render.Text, point render.Point) error { - font := FontFilenameToName(text.FontFilename) - e.canvas.ctx2d.Set("font", - fmt.Sprintf("%dpx %s,serif", text.Size, font), - ) - - e.canvas.ctx2d.Set("textBaseline", "top") - - write := func(dx, dy int, color render.Color) { - e.canvas.ctx2d.Set("fillStyle", color.ToHex()) - e.canvas.ctx2d.Call("fillText", - text.Text, - int(point.X)+dx, - int(point.Y)+dy, - ) - } - - // Does the text have a stroke around it? - if text.Stroke != render.Invisible { - e.canvas.ctx2d.Set("fillStyle", text.Stroke.ToHex()) - write(-1, -1, text.Stroke) - write(-1, 0, text.Stroke) - write(-1, 1, text.Stroke) - write(1, -1, text.Stroke) - write(1, 0, text.Stroke) - write(1, 1, text.Stroke) - write(0, -1, text.Stroke) - write(0, 1, text.Stroke) - } - - // Does it have a drop shadow? - if text.Shadow != render.Invisible { - write(1, 1, text.Shadow) - } - - // Draw the text itself. - write(0, 0, text.Color) - - return nil -} - -// ComputeTextRect computes and returns a Rect for how large the text would -// appear if rendered. -func (e *Engine) ComputeTextRect(text render.Text) (render.Rect, error) { - font := FontFilenameToName(text.FontFilename) - e.canvas.ctx2d.Set("font", - fmt.Sprintf("%dpx %s,serif", text.Size, font), - ) - - measure := e.canvas.ctx2d.Call("measureText", text.Text) - rect := render.Rect{ - // TODO: the only TextMetrics widely supported in browsers is - // the width. For height, use the text size for now. - W: int32(measure.Get("width").Int()), - H: int32(text.Size), - } - return rect, nil -} diff --git a/lib/render/canvas/texture.go b/lib/render/canvas/texture.go deleted file mode 100644 index be6da8a..0000000 --- a/lib/render/canvas/texture.go +++ /dev/null @@ -1,91 +0,0 @@ -package canvas - -import ( - "bytes" - "encoding/base64" - "errors" - "image" - "image/png" - "syscall/js" - - "git.kirsle.net/apps/doodle/lib/render" -) - -// Texture can hold on to cached image textures. -type Texture struct { - data string // data:image/png URI - image js.Value // DOM image element - canvas js.Value // Warmed up canvas element - ctx2d js.Value // 2D drawing context for the canvas. - width int - height int -} - -// StoreTexture caches a texture from a bitmap. -func (e *Engine) StoreTexture(name string, img image.Image) (render.Texturer, error) { - var ( - fh = bytes.NewBuffer([]byte{}) - imageSize = img.Bounds().Size() - width = imageSize.X - height = imageSize.Y - ) - - // Encode to PNG format. - if err := png.Encode(fh, img); err != nil { - return nil, err - } - - var dataURI = "data:image/png;base64," + base64.StdEncoding.EncodeToString(fh.Bytes()) - - tex := &Texture{ - data: dataURI, - width: width, - height: height, - } - - // Preheat a cached Canvas object. - canvas := js.Global().Get("document").Call("createElement", "canvas") - canvas.Set("width", width) - canvas.Set("height", height) - tex.canvas = canvas - - ctx2d := canvas.Call("getContext", "2d") - tex.ctx2d = ctx2d - - // Load as a JS Image object. - image := js.Global().Call("eval", "new Image()") - image.Call("addEventListener", "load", js.FuncOf(func(this js.Value, args []js.Value) interface{} { - ctx2d.Call("drawImage", image, 0, 0) - return nil - })) - image.Set("src", tex.data) - tex.image = image - - // Cache the texture in memory. - e.textures[name] = tex - - return tex, nil -} - -// Size returns the dimensions of the texture. -func (t *Texture) Size() render.Rect { - return render.NewRect(int32(t.width), int32(t.height)) -} - -// LoadTexture recalls a cached texture image. -func (e *Engine) LoadTexture(name string) (render.Texturer, error) { - if tex, ok := e.textures[name]; ok { - return tex, nil - } - - return nil, errors.New("no bitmap data stored for " + name) -} - -// Copy a texturer bitmap onto the canvas. -func (e *Engine) Copy(t render.Texturer, src, dist render.Rect) { - tex := t.(*Texture) - - // e.canvas.ctx2d.Call("drawImage", tex.image, dist.X, dist.Y) - e.canvas.ctx2d.Call("drawImage", tex.canvas, dist.X, dist.Y) - -} diff --git a/lib/render/color.go b/lib/render/color.go deleted file mode 100644 index 70de13b..0000000 --- a/lib/render/color.go +++ /dev/null @@ -1,226 +0,0 @@ -package render - -import ( - "encoding/json" - "errors" - "fmt" - "image/color" - "regexp" - "strconv" -) - -var ( - // Regexps to parse hex color codes. Three formats are supported: - // * reHexColor3 uses only 3 hex characters, like #F90 - // * reHexColor6 uses standard 6 characters, like #FF9900 - // * reHexColor8 is the standard 6 plus alpha channel, like #FF9900FF - reHexColor3 = regexp.MustCompile(`^([A-Fa-f0-9])([A-Fa-f0-9])([A-Fa-f0-9])$`) - reHexColor6 = regexp.MustCompile(`^([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})$`) - reHexColor8 = regexp.MustCompile(`^([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})$`) -) - -// Color holds an RGBA color value. -type Color struct { - Red uint8 - Green uint8 - Blue uint8 - Alpha uint8 -} - -// RGBA creates a new Color. -func RGBA(r, g, b, a uint8) Color { - return Color{ - Red: r, - Green: g, - Blue: b, - Alpha: a, - } -} - -// FromColor creates a render.Color from a Go color.Color -func FromColor(from color.Color) Color { - // downscale a 16-bit color value to 8-bit. input range 0x0000..0xffff - downscale := func(in uint32) uint8 { - var scale = float64(in) / 0xffff - return uint8(scale * 0xff) - } - r, g, b, a := from.RGBA() - return RGBA( - downscale(r), - downscale(g), - downscale(b), - downscale(a), - ) -} - -// MustHexColor parses a color from hex code or panics. -func MustHexColor(hex string) Color { - color, err := HexColor(hex) - if err != nil { - panic(err) - } - return color -} - -// HexColor parses a color from hexadecimal code. -func HexColor(hex string) (Color, error) { - c := Black // default color - - if len(hex) > 0 && hex[0] == '#' { - hex = hex[1:] - } - - var m []string - if len(hex) == 3 { - m = reHexColor3.FindStringSubmatch(hex) - } else if len(hex) == 6 { - m = reHexColor6.FindStringSubmatch(hex) - } else if len(hex) == 8 { - m = reHexColor8.FindStringSubmatch(hex) - } else { - return c, errors.New("not a valid length for color code; only 3, 6 and 8 supported") - } - - // Any luck? - if m == nil { - return c, errors.New("not a valid hex color code") - } - - // Parse the color values. 16=base, 8=bit size - red, _ := strconv.ParseUint(m[1], 16, 8) - green, _ := strconv.ParseUint(m[2], 16, 8) - blue, _ := strconv.ParseUint(m[3], 16, 8) - - // Alpha channel available? - var alpha uint64 = 255 - if len(m) == 5 { - alpha, _ = strconv.ParseUint(m[4], 16, 8) - } - - c.Red = uint8(red) - c.Green = uint8(green) - c.Blue = uint8(blue) - c.Alpha = uint8(alpha) - return c, nil -} - -func (c Color) String() string { - return fmt.Sprintf( - "Color<#%02x%02x%02x+%02x>", - c.Red, c.Green, c.Blue, c.Alpha, - ) -} - -// ToHex converts a render.Color to standard #RRGGBB hexadecimal format. -func (c Color) ToHex() string { - return fmt.Sprintf( - "#%02x%02x%02x", - c.Red, c.Green, c.Blue, - ) -} - -// ToColor converts a render.Color into a Go standard color.Color -func (c Color) ToColor() color.RGBA { - return color.RGBA{ - R: c.Red, - G: c.Green, - B: c.Blue, - A: c.Alpha, - } -} - -// Transparent returns whether the alpha channel is zeroed out and the pixel -// won't appear as anything when rendered. -func (c Color) Transparent() bool { - return c.Alpha == 0x00 -} - -// MarshalJSON serializes the Color for JSON. -func (c Color) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf( - `"#%02x%02x%02x"`, - c.Red, c.Green, c.Blue, - )), nil -} - -// UnmarshalJSON reloads the Color from JSON. -func (c *Color) UnmarshalJSON(b []byte) error { - var hex string - err := json.Unmarshal(b, &hex) - if err != nil { - return err - } - - parsed, err := HexColor(hex) - if err != nil { - return err - } - - c.Red = parsed.Red - c.Blue = parsed.Blue - c.Green = parsed.Green - c.Alpha = parsed.Alpha - return nil -} - -// IsZero returns if the color is all zeroes (invisible). -func (c Color) IsZero() bool { - return c.Red+c.Green+c.Blue+c.Alpha == 0 -} - -// Add a relative color value to the color. -func (c Color) Add(r, g, b, a int) Color { - var ( - R = int(c.Red) + r - G = int(c.Green) + g - B = int(c.Blue) + b - A = int(c.Alpha) + a - ) - - cap8 := func(v int) uint8 { - if v > 255 { - v = 255 - } else if v < 0 { - v = 0 - } - return uint8(v) - } - - return Color{ - Red: cap8(R), - Green: cap8(G), - Blue: cap8(B), - Alpha: cap8(A), - } -} - -// AddColor adds another Color to your Color. -func (c Color) AddColor(other Color) Color { - return c.Add( - int(other.Red), - int(other.Green), - int(other.Blue), - int(other.Alpha), - ) -} - -// Lighten a color value. -func (c Color) Lighten(v int) Color { - return c.Add(v, v, v, 0) -} - -// Darken a color value. -func (c Color) Darken(v int) Color { - return c.Add(-v, -v, -v, 0) -} - -// Transparentize adjusts the alpha value. -func (c Color) Transparentize(v int) Color { - return c.Add(0, 0, 0, v) -} - -// SetAlpha sets the alpha value to a specific setting. -func (c Color) SetAlpha(v uint8) Color { - c.Alpha = v - return c -} diff --git a/lib/render/ellipse.go b/lib/render/ellipse.go deleted file mode 100644 index d259f3c..0000000 --- a/lib/render/ellipse.go +++ /dev/null @@ -1,64 +0,0 @@ -package render - -// MidpointEllipse implements an ellipse plotting algorithm. -func MidpointEllipse(center, radius Point) chan Point { - yield := make(chan Point) - go func() { - - var ( - pos = NewPoint(radius.X, 0) - delta = NewPoint( - 2*radius.Y*radius.Y*pos.X, - 2*radius.X*radius.X*pos.Y, - ) - err = radius.X*radius.X - - radius.Y*radius.Y*radius.X + - (radius.Y*radius.Y)/4 - ) - - for delta.Y < delta.X { - yield <- NewPoint(center.X+pos.X, center.Y+pos.Y) - yield <- NewPoint(center.X+pos.X, center.Y-pos.Y) - yield <- NewPoint(center.X-pos.X, center.Y+pos.Y) - yield <- NewPoint(center.X-pos.X, center.Y-pos.Y) - - pos.Y++ - - if err < 0 { - delta.Y += 2 * radius.X * radius.X - err += delta.Y + radius.X*radius.X - } else { - pos.X-- - delta.Y += 2 * radius.X * radius.X - delta.X -= 2 * radius.Y * radius.Y - err += delta.Y - delta.X + radius.X*radius.X - } - } - - err = radius.X*radius.X*(pos.Y*pos.Y+pos.Y) + - radius.Y*radius.Y*(pos.X-1)*(pos.X-1) - - radius.Y*radius.Y*radius.X*radius.X - - for pos.X >= 0 { - yield <- NewPoint(center.X+pos.X, center.Y+pos.Y) - yield <- NewPoint(center.X+pos.X, center.Y-pos.Y) - yield <- NewPoint(center.X-pos.X, center.Y+pos.Y) - yield <- NewPoint(center.X-pos.X, center.Y-pos.Y) - - pos.X-- - - if err > 0 { - delta.X -= 2 * radius.Y * radius.Y - err += radius.Y*radius.Y - delta.X - } else { - pos.Y++ - delta.Y += 2 * radius.X * radius.X - delta.X -= 2 * radius.Y * radius.Y - err += delta.Y - delta.X + radius.Y*radius.Y - } - } - - close(yield) - }() - return yield -} diff --git a/lib/render/event/event.go b/lib/render/event/event.go deleted file mode 100644 index 1787e4c..0000000 --- a/lib/render/event/event.go +++ /dev/null @@ -1,109 +0,0 @@ -package event - -import "strings" - -// State holds the current state of key/mouse events. -type State struct { - // Mouse buttons. - Button1 bool // Left - Button2 bool // Middle - Button3 bool // Right - - // Special keys - Escape bool - Enter bool - Shift bool - Ctrl bool - Alt bool - Up bool - Left bool - Right bool - Down bool - - // Pressed keys. - keydown map[string]interface{} - - // Cursor position - CursorX int - CursorY int - - // Window resized - WindowResized bool -} - -// NewState creates a new event.State. -func NewState() *State { - return &State{ - keydown: map[string]interface{}{}, - } -} - -// SetKeyDown sets that a named key is pressed down. -func (s *State) SetKeyDown(name string, down bool) { - if down { - s.keydown[name] = nil - } else { - delete(s.keydown, name) - } -} - -// KeyDown returns whether a named key is currently pressed. -func (s *State) KeyDown(name string) bool { - _, ok := s.keydown[name] - return ok -} - -// KeysDown returns a list of all key names currently pressed down. -// Set shifted to True to return the key symbols correctly shifted -// (uppercase, or symbols on number keys, etc.) -func (s *State) KeysDown(shifted bool) []string { - var ( - result = make([]string, len(s.keydown)) - i = 0 - ) - - for key := range s.keydown { - if shifted && s.Shift { - if symbol, ok := shiftMap[key]; ok { - result[i] = symbol - } else { - result[i] = strings.ToUpper(key) - } - } else { - result[i] = key - } - - i++ - } - return result -} - -// ResetKeyDown clears all key-down states. -func (s *State) ResetKeyDown() { - s.keydown = map[string]interface{}{} -} - -// shiftMap maps keys to their Shift versions. -var shiftMap = map[string]string{ - "`": "~", - "1": "!", - "2": "@", - "3": "#", - "4": "$", - "5": "%", - "6": "^", - "7": "&", - "8": "*", - "9": "(", - "0": ")", - "-": "_", - "=": "+", - "[": "{", - "]": "}", - `\`: "|", - ";": ":", - `'`: `"`, - ",": "<", - ".": ">", - "/": "?", -} diff --git a/lib/render/functions.go b/lib/render/functions.go deleted file mode 100644 index 7b719a3..0000000 --- a/lib/render/functions.go +++ /dev/null @@ -1,108 +0,0 @@ -package render - -import ( - "fmt" - "regexp" - "strconv" -) - -var regexpResolution = regexp.MustCompile(`^(\d+)x(\d+)$`) - -// ParseResolution turns a resolution string like "1024x768" and returns the -// width and height values. -func ParseResolution(resi string) (int, int, error) { - m := regexpResolution.FindStringSubmatch(resi) - if m == nil { - return 0, 0, fmt.Errorf("invalid resolution format, should be %s", - regexpResolution.String(), - ) - } - - width, err := strconv.Atoi(m[1]) - if err != nil { - return 0, 0, err - } - - height, err := strconv.Atoi(m[2]) - if err != nil { - return 0, 0, err - } - - return width, height, nil -} - -// TrimBox helps with Engine.Copy() to trim a destination box so that it -// won't overflow with the parent container. -func TrimBox(src, dst *Rect, p Point, S Rect, thickness int32) { - // Constrain source width to not bigger than Canvas width. - if src.W > S.W { - src.W = S.W - } - if src.H > S.H { - src.H = S.H - } - - // If the destination width will cause it to overflow the widget - // box, trim off the right edge of the destination rect. - // - // Keep in mind we're dealing with chunks here, and a chunk is - // a small part of the image. Example: - // - Canvas is 800x600 (S.W=800 S.H=600) - // - Chunk wants to render at 790,0 width 100,100 or whatever - // dst={790, 0, 100, 100} - // - Chunk box would exceed 800px width (X=790 + W=100 == 890) - // - Find the delta how much it exceeds as negative (800 - 890 == -90) - // - Lower the Source and Dest rects by that delta size so they - // stay proportional and don't scale or anything dumb. - if dst.X+src.W > p.X+S.W { - // NOTE: delta is a negative number, - // so it will subtract from the width. - delta := (p.X + S.W - thickness) - (dst.W + dst.X) - src.W += delta - dst.W += delta - } - if dst.Y+src.H > p.Y+S.H { - // NOTE: delta is a negative number - delta := (p.Y + S.H - thickness) - (dst.H + dst.Y) - src.H += delta - dst.H += delta - } - - // The same for the top left edge, so the drawings don't overlap - // menu bars or left side toolbars. - // - Canvas was placed 80px from the left of the screen. - // Canvas.MoveTo(80, 0) - // - A texture wants to draw at 60, 0 which would cause it to - // overlap 20 pixels into the left toolbar. It needs to be cropped. - // - The delta is: p.X=80 - dst.X=60 == 20 - // - Set destination X to p.X to constrain it there: 20 - // - Subtract the delta from destination W so we don't scale it. - // - Add 20 to X of the source: the left edge of source is not visible - if dst.X < p.X { - // NOTE: delta is a positive number, - // so it will add to the destination coordinates. - delta := p.X - dst.X - dst.X = p.X + thickness - dst.W -= delta - src.X += delta - } - if dst.Y < p.Y { - delta := p.Y - dst.Y - dst.Y = p.Y + thickness - dst.H -= delta - src.Y += delta - } - - // Trim the destination width so it doesn't overlap the Canvas border. - if dst.W >= S.W-thickness { - dst.W = S.W - thickness - } -} - -// AbsInt32 returns the absolute value of an int32. -func AbsInt32(v int32) int32 { - if v < 0 { - return -v - } - return v -} diff --git a/lib/render/interface.go b/lib/render/interface.go deleted file mode 100644 index b97e289..0000000 --- a/lib/render/interface.go +++ /dev/null @@ -1,196 +0,0 @@ -package render - -import ( - "fmt" - "image" - - "git.kirsle.net/apps/doodle/lib/render/event" -) - -// Engine is the interface for the rendering engine, keeping SDL-specific stuff -// far away from the core of Doodle. -type Engine interface { - Setup() error - - // Poll for events like keypresses and mouse clicks. - Poll() (*event.State, error) - GetTicks() uint32 - WindowSize() (w, h int) - - // Present presents the current state to the screen. - Present() error - - // Clear the full canvas and set this color. - Clear(Color) - SetTitle(string) - DrawPoint(Color, Point) - DrawLine(Color, Point, Point) - DrawRect(Color, Rect) - DrawBox(Color, Rect) - DrawText(Text, Point) error - ComputeTextRect(Text) (Rect, error) - - // Texture caching. - StoreTexture(name string, img image.Image) (Texturer, error) - LoadTexture(name string) (Texturer, error) - Copy(t Texturer, src, dst Rect) - - // Delay for a moment using the render engine's delay method, - // implemented by sdl.Delay(uint32) - Delay(uint32) - - // Tasks that the Setup function should defer until tear-down. - Teardown() - - Loop() error // maybe? -} - -// Texturer is a stored image texture used by the rendering engine while -// abstracting away its inner workings. -type Texturer interface { - Size() Rect -} - -// Rect has a coordinate and a width and height. -type Rect struct { - X int32 - Y int32 - W int32 - H int32 -} - -// NewRect creates a rectangle of size `width` and `height`. The X,Y values -// are initialized to zero. -func NewRect(width, height int32) Rect { - return Rect{ - W: width, - H: height, - } -} - -func (r Rect) String() string { - return fmt.Sprintf("Rect<%d,%d,%d,%d>", - r.X, r.Y, r.W, r.H, - ) -} - -// Point returns the rectangle's X,Y values as a Point. -func (r Rect) Point() Point { - return Point{ - X: r.X, - Y: r.Y, - } -} - -// Bigger returns if the given rect is larger than the current one. -func (r Rect) Bigger(other Rect) bool { - // TODO: don't know why this is ! - return !(other.X < r.X || // Lefter - other.Y < r.Y || // Higher - other.W > r.W || // Wider - other.H > r.H) // Taller -} - -// Intersects with the other rectangle in any way. -func (r Rect) Intersects(other Rect) bool { - // Do a bidirectional compare. - compare := func(a, b Rect) bool { - var corners = []Point{ - NewPoint(b.X, b.Y), - NewPoint(b.X, b.Y+b.H), - NewPoint(b.X+b.W, b.Y), - NewPoint(b.X+b.W, b.Y+b.H), - } - for _, pt := range corners { - if pt.Inside(a) { - return true - } - } - return false - } - - return compare(r, other) || compare(other, r) || false -} - -// IsZero returns if the Rect is uninitialized. -func (r Rect) IsZero() bool { - return r.X == 0 && r.Y == 0 && r.W == 0 && r.H == 0 -} - -// Add another rect. -func (r Rect) Add(other Rect) Rect { - return Rect{ - X: r.X + other.X, - Y: r.Y + other.Y, - W: r.W + other.W, - H: r.H + other.H, - } -} - -// Add a point to move the rect. -func (r Rect) AddPoint(other Point) Rect { - return Rect{ - X: r.X + other.X, - Y: r.Y + other.Y, - W: r.W, - H: r.H, - } -} - -// SubtractPoint is the inverse of AddPoint. Use this only if you need to invert -// the Point being added. -// -// This does r.X - other.X, r.Y - other.Y and keeps the width/height the same. -func (r Rect) SubtractPoint(other Point) Rect { - return Rect{ - X: r.X - other.X, - Y: r.Y - other.Y, - W: r.W, - H: r.H, - } -} - -// Text holds information for drawing text. -type Text struct { - Text string - Size int - Color Color - Padding int32 - PadX int32 - PadY int32 - Stroke Color // Stroke color (if not zero) - Shadow Color // Drop shadow color (if not zero) - FontFilename string // Path to *.ttf file on disk -} - -func (t Text) String() string { - return fmt.Sprintf(`Text<"%s" %dpx %s>`, t.Text, t.Size, t.Color) -} - -// IsZero returns if the Text is the zero value. -func (t Text) IsZero() bool { - return t.Text == "" && t.Size == 0 && t.Color == Invisible && t.Padding == 0 && t.Stroke == Invisible && t.Shadow == Invisible -} - -// Common color names. -var ( - Invisible = Color{} - White = RGBA(255, 255, 255, 255) - Grey = RGBA(153, 153, 153, 255) - Black = RGBA(0, 0, 0, 255) - SkyBlue = RGBA(0, 153, 255, 255) - Blue = RGBA(0, 0, 255, 255) - DarkBlue = RGBA(0, 0, 153, 255) - Red = RGBA(255, 0, 0, 255) - DarkRed = RGBA(153, 0, 0, 255) - Green = RGBA(0, 255, 0, 255) - DarkGreen = RGBA(0, 153, 0, 255) - Cyan = RGBA(0, 255, 255, 255) - DarkCyan = RGBA(0, 153, 153, 255) - Yellow = RGBA(255, 255, 0, 255) - Orange = RGBA(255, 153, 0, 255) - DarkYellow = RGBA(153, 153, 0, 255) - Magenta = RGBA(255, 0, 255, 255) - Purple = RGBA(153, 0, 153, 255) - Pink = RGBA(255, 153, 255, 255) -) diff --git a/lib/render/point.go b/lib/render/point.go deleted file mode 100644 index 6ef757d..0000000 --- a/lib/render/point.go +++ /dev/null @@ -1,109 +0,0 @@ -package render - -import ( - "fmt" - "strconv" - "strings" -) - -// Point holds an X,Y coordinate value. -type Point struct { - X int32 - Y int32 -} - -// Common points. -var ( - Origin Point -) - -// NewPoint makes a new Point at an X,Y coordinate. -func NewPoint(x, y int32) Point { - return Point{ - X: x, - Y: y, - } -} - -func (p Point) String() string { - return fmt.Sprintf("%d,%d", p.X, p.Y) -} - -// ParsePoint to parse a point from its string representation. -func ParsePoint(v string) (Point, error) { - halves := strings.Split(v, ",") - if len(halves) != 2 { - return Point{}, fmt.Errorf("'%s': not a valid coordinate string", v) - } - x, errX := strconv.Atoi(halves[0]) - y, errY := strconv.Atoi(halves[1]) - if errX != nil || errY != nil { - return Point{}, fmt.Errorf("invalid coordinate string (X: %v; Y: %v)", - errX, - errY, - ) - } - return Point{ - X: int32(x), - Y: int32(y), - }, nil -} - -// IsZero returns if the point is the zero value. -func (p Point) IsZero() bool { - return p.X == 0 && p.Y == 0 -} - -// Inside returns whether the Point falls inside the rect. -// -// NOTICE: the W and H are zero-relative, so a 100x100 box at coordinate -// X,Y would still have W,H of 100. -func (p Point) Inside(r Rect) bool { - var ( - x1 = r.X - y1 = r.Y - x2 = r.X + r.W - y2 = r.Y + r.H - ) - return ((p.X >= x1 && p.X <= x2) && - (p.Y >= y1 && p.Y <= y2)) -} - -// Add (or subtract) the other point to your current point. -func (p *Point) Add(other Point) { - p.X += other.X - p.Y += other.Y -} - -// Subtract the other point from your current point. -func (p *Point) Subtract(other Point) { - p.X -= other.X - p.Y -= other.Y -} - -// MarshalText to convert the point into text so that a render.Point may be used -// as a map key and serialized to JSON. -func (p *Point) MarshalText() ([]byte, error) { - return []byte(fmt.Sprintf("%d,%d", p.X, p.Y)), nil -} - -// UnmarshalText to restore it from text. -func (p *Point) UnmarshalText(b []byte) error { - halves := strings.Split(strings.Trim(string(b), `"`), ",") - if len(halves) != 2 { - return fmt.Errorf("'%s': not a valid coordinate string", b) - } - - x, errX := strconv.Atoi(halves[0]) - y, errY := strconv.Atoi(halves[1]) - if errX != nil || errY != nil { - return fmt.Errorf("Point.UnmarshalJSON: Atoi errors (X=%s Y=%s)", - errX, - errY, - ) - } - - p.X = int32(x) - p.Y = int32(y) - return nil -} diff --git a/lib/render/point_test.go b/lib/render/point_test.go deleted file mode 100644 index d40c5da..0000000 --- a/lib/render/point_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package render_test - -import ( - "strconv" - "testing" - - "git.kirsle.net/apps/doodle/lib/render" -) - -func TestPointInside(t *testing.T) { - type testCase struct { - rect render.Rect - p render.Point - shouldPass bool - } - tests := []testCase{ - testCase{ - rect: render.Rect{ - X: 0, - Y: 0, - W: 500, - H: 500, - }, - p: render.NewPoint(128, 256), - shouldPass: true, - }, - testCase{ - rect: render.Rect{ - X: 100, - Y: 80, - W: 40, - H: 60, - }, - p: render.NewPoint(128, 256), - shouldPass: false, - }, - testCase{ - // true values when debugging why Doodads weren't - // considered inside the viewport. - rect: render.Rect{ - X: 0, - Y: -232, - H: 874, - W: 490, - }, - p: render.NewPoint(509, 260), - shouldPass: false, - }, - } - - for _, test := range tests { - if test.p.Inside(test.rect) != test.shouldPass { - t.Errorf("Failed: %s inside %s should be %s", - test.p, - test.rect, - strconv.FormatBool(test.shouldPass), - ) - } - } -} diff --git a/lib/render/rect_test.go b/lib/render/rect_test.go deleted file mode 100644 index f0528c1..0000000 --- a/lib/render/rect_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package render_test - -import ( - "strconv" - "testing" - - "git.kirsle.net/apps/doodle/lib/render" -) - -func TestIntersection(t *testing.T) { - newRect := func(x, y, w, h int) render.Rect { - return render.Rect{ - X: int32(x), - Y: int32(y), - W: int32(w), - H: int32(h), - } - } - - type TestCase struct { - A render.Rect - B render.Rect - Expect bool - } - var tests = []TestCase{ - { - A: newRect(0, 0, 1000, 1000), - B: newRect(200, 200, 100, 100), - Expect: true, - }, - { - A: newRect(200, 200, 100, 100), - B: newRect(0, 0, 1000, 1000), - Expect: true, - }, - { - A: newRect(0, 0, 100, 100), - B: newRect(100, 0, 100, 100), - Expect: true, - }, - { - A: newRect(0, 0, 99, 99), - B: newRect(100, 0, 99, 99), - Expect: false, - }, - { - // Real coords of a test doodad! - A: newRect(183, 256, 283, 356), - B: newRect(0, -232, 874, 490), - Expect: true, - }, - { - A: newRect(183, 256, 283, 356), - B: newRect(0, -240, 874, 490), - Expect: false, // XXX: must be true - }, - { - A: newRect(0, 30, 9, 62), - B: newRect(16, 0, 32, 64), - Expect: false, - }, - { - A: newRect(0, 30, 11, 62), - B: newRect(7, 4, 17, 28), - Expect: false, - }, - } - - for _, test := range tests { - actual := test.A.Intersects(test.B) - if actual != test.Expect { - t.Errorf( - "%s collision with %s: expected %s, got %s", - test.A, - test.B, - strconv.FormatBool(test.Expect), - strconv.FormatBool(actual), - ) - } - } -} diff --git a/lib/render/sdl/canvas.go b/lib/render/sdl/canvas.go deleted file mode 100644 index 0095585..0000000 --- a/lib/render/sdl/canvas.go +++ /dev/null @@ -1,57 +0,0 @@ -// Package sdl provides an SDL2 renderer for Doodle. -package sdl - -import ( - "git.kirsle.net/apps/doodle/lib/render" - "github.com/veandco/go-sdl2/sdl" -) - -// Clear the canvas and set this color. -func (r *Renderer) Clear(color render.Color) { - if color != r.lastColor { - r.renderer.SetDrawColor(color.Red, color.Green, color.Blue, color.Alpha) - } - r.renderer.Clear() -} - -// DrawPoint puts a color at a pixel. -func (r *Renderer) DrawPoint(color render.Color, point render.Point) { - if color != r.lastColor { - r.renderer.SetDrawColor(color.Red, color.Green, color.Blue, color.Alpha) - } - r.renderer.DrawPoint(point.X, point.Y) -} - -// DrawLine draws a line between two points. -func (r *Renderer) DrawLine(color render.Color, a, b render.Point) { - if color != r.lastColor { - r.renderer.SetDrawColor(color.Red, color.Green, color.Blue, color.Alpha) - } - r.renderer.DrawLine(a.X, a.Y, b.X, b.Y) -} - -// DrawRect draws a rectangle. -func (r *Renderer) DrawRect(color render.Color, rect render.Rect) { - if color != r.lastColor { - r.renderer.SetDrawColor(color.Red, color.Green, color.Blue, color.Alpha) - } - r.renderer.DrawRect(&sdl.Rect{ - X: rect.X, - Y: rect.Y, - W: rect.W, - H: rect.H, - }) -} - -// DrawBox draws a filled rectangle. -func (r *Renderer) DrawBox(color render.Color, rect render.Rect) { - if color != r.lastColor { - r.renderer.SetDrawColor(color.Red, color.Green, color.Blue, color.Alpha) - } - r.renderer.FillRect(&sdl.Rect{ - X: rect.X, - Y: rect.Y, - W: rect.W, - H: rect.H, - }) -} diff --git a/lib/render/sdl/events.go b/lib/render/sdl/events.go deleted file mode 100644 index a5b8014..0000000 --- a/lib/render/sdl/events.go +++ /dev/null @@ -1,176 +0,0 @@ -package sdl - -import ( - "errors" - "fmt" - - "git.kirsle.net/apps/doodle/lib/render/event" - "github.com/veandco/go-sdl2/sdl" -) - -// Debug certain SDL events -var ( - DebugWindowEvents = false - DebugMouseEvents = false - DebugClickEvents = true - DebugKeyEvents = false -) - -// Poll for events. -func (r *Renderer) Poll() (*event.State, error) { - s := r.events - - // helper function to push keyboard key names on keyDown events only. - pushKey := func(name string, state uint8) { - s.SetKeyDown(name, state == 1) - } - - for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { - switch t := event.(type) { - case *sdl.QuitEvent: - return s, errors.New("quit") - case *sdl.WindowEvent: - if DebugWindowEvents { - if t.Event == sdl.WINDOWEVENT_RESIZED { - fmt.Printf("[%d ms] tick:%d Window Resized to %dx%d", - t.Timestamp, - r.ticks, - t.Data1, - t.Data2, - ) - } - } - - if t.Event == sdl.WINDOWEVENT_RESIZED { - s.WindowResized = true - } - case *sdl.MouseMotionEvent: - if DebugMouseEvents { - fmt.Printf("[%d ms] tick:%d MouseMotion type:%d id:%d x:%d y:%d xrel:%d yrel:%d", - t.Timestamp, r.ticks, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel, - ) - } - - // Push the cursor position. - s.CursorX = int(t.X) - s.CursorY = int(t.Y) - case *sdl.MouseButtonEvent: - if DebugClickEvents { - fmt.Printf("[%d ms] tick:%d MouseButton type:%d id:%d x:%d y:%d button:%d state:%d\n", - t.Timestamp, r.ticks, t.Type, t.Which, t.X, t.Y, t.Button, t.State, - ) - } - - // Push the cursor position. - s.CursorX = int(t.X) - s.CursorY = int(t.Y) - - // Store the clicked state of the mouse button. - if t.Button == 1 { - s.Button1 = t.State == 1 - } else if t.Button == 2 { - s.Button2 = t.State == 1 - } else if t.Button == 3 { - s.Button3 = t.State == 1 - } - // - // // Is a mouse button pressed down? - // checkDown := func(number uint8, target *events.BoolTick) bool { - // if t.Button == number { - // var eventName string - // if t.State == 1 && target.Now == false { - // eventName = "DOWN" - // } else if t.State == 0 && target.Now == true { - // eventName = "UP" - // } - // - // if eventName != "" { - // target.Push(eventName == "DOWN") - // } - // return true - // } - // return false - // } - // - // if checkDown(1, s.Button1) || checkDown(3, s.Button2) || checkDown(2, s.Button3) { - // // Return the event immediately. - // return s, nil - // } - case *sdl.MouseWheelEvent: - if DebugMouseEvents { - fmt.Printf("[%d ms] tick:%d MouseWheel type:%d id:%d x:%d y:%d", - t.Timestamp, r.ticks, t.Type, t.Which, t.X, t.Y, - ) - } - case *sdl.KeyboardEvent: - if DebugKeyEvents { - fmt.Printf("[%d ms] tick:%d Keyboard type:%d sym:%c modifiers:%d state:%d repeat:%d\n", - t.Timestamp, r.ticks, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat, - ) - } - - switch t.Keysym.Scancode { - case sdl.SCANCODE_ESCAPE: - if t.Repeat == 1 { - continue - } - s.Escape = t.State == 1 - case sdl.SCANCODE_RETURN: - if t.Repeat == 1 { - continue - } - s.Enter = t.State == 1 - case sdl.SCANCODE_F1: - pushKey("F1", t.State) - case sdl.SCANCODE_F2: - pushKey("F2", t.State) - case sdl.SCANCODE_F3: - pushKey("F3", t.State) - case sdl.SCANCODE_F4: - pushKey("F4", t.State) - case sdl.SCANCODE_F5: - pushKey("F5", t.State) - case sdl.SCANCODE_F6: - pushKey("F6", t.State) - case sdl.SCANCODE_F7: - pushKey("F7", t.State) - case sdl.SCANCODE_F8: - pushKey("F8", t.State) - case sdl.SCANCODE_F9: - pushKey("F9", t.State) - case sdl.SCANCODE_F10: - pushKey("F10", t.State) - case sdl.SCANCODE_F11: - pushKey("F11", t.State) - case sdl.SCANCODE_F12: - pushKey("F12", t.State) - case sdl.SCANCODE_UP: - s.Up = t.State == 1 - case sdl.SCANCODE_LEFT: - s.Left = t.State == 1 - case sdl.SCANCODE_RIGHT: - s.Right = t.State == 1 - case sdl.SCANCODE_DOWN: - s.Down = t.State == 1 - case sdl.SCANCODE_LSHIFT: - case sdl.SCANCODE_RSHIFT: - s.Shift = t.State == 1 - case sdl.SCANCODE_LALT: - case sdl.SCANCODE_RALT: - s.Alt = t.State == 1 - case sdl.SCANCODE_LCTRL: - s.Ctrl = t.State == 1 - case sdl.SCANCODE_RCTRL: - s.Ctrl = t.State == 1 - case sdl.SCANCODE_BACKSPACE: - // Make it a key event with "\b" as the sequence. - s.SetKeyDown(`\b`, t.State == 1 || t.Repeat == 1) - default: - // Push the string value of the key. - s.SetKeyDown(string(t.Keysym.Sym), t.State == 1) - } - } - } - - return s, nil -} diff --git a/lib/render/sdl/sdl.go b/lib/render/sdl/sdl.go deleted file mode 100644 index 35799ef..0000000 --- a/lib/render/sdl/sdl.go +++ /dev/null @@ -1,120 +0,0 @@ -// Package sdl provides an SDL2 renderer for Doodle. -package sdl - -import ( - "fmt" - "time" - - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" - "github.com/veandco/go-sdl2/sdl" - "github.com/veandco/go-sdl2/ttf" -) - -// Renderer manages the SDL state. -type Renderer struct { - // Configurable fields. - title string - width int32 - height int32 - startTime time.Time - - // Private fields. - events *event.State - window *sdl.Window - renderer *sdl.Renderer - running bool - ticks uint64 - textures map[string]*Texture // cached textures - - // Optimizations to minimize SDL calls. - lastColor render.Color -} - -// New creates the SDL renderer. -func New(title string, width, height int) *Renderer { - return &Renderer{ - events: event.NewState(), - title: title, - width: int32(width), - height: int32(height), - textures: map[string]*Texture{}, - } -} - -// Teardown tasks when exiting the program. -func (r *Renderer) Teardown() { - r.renderer.Destroy() - r.window.Destroy() - sdl.Quit() -} - -// Setup the renderer. -func (r *Renderer) Setup() error { - // Initialize SDL. - if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil { - return fmt.Errorf("sdl.Init: %s", err) - } - - // Initialize SDL_TTF. - if err := ttf.Init(); err != nil { - return fmt.Errorf("ttf.Init: %s", err) - } - - // Create our window. - window, err := sdl.CreateWindow( - r.title, - sdl.WINDOWPOS_CENTERED, - sdl.WINDOWPOS_CENTERED, - r.width, - r.height, - sdl.WINDOW_SHOWN|sdl.WINDOW_RESIZABLE, - ) - if err != nil { - return err - } - r.window = window - - // Blank out the window in white. - renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) - if err != nil { - panic(err) - } - renderer.SetDrawBlendMode(sdl.BLENDMODE_BLEND) - r.renderer = renderer - - return nil -} - -// SetTitle sets the SDL window title. -func (r *Renderer) SetTitle(title string) { - r.title = title - r.window.SetTitle(title) -} - -// GetTicks gets SDL's current tick count. -func (r *Renderer) GetTicks() uint32 { - return sdl.GetTicks() -} - -// WindowSize returns the SDL window size. -func (r *Renderer) WindowSize() (int, int) { - w, h := r.window.GetSize() - return int(w), int(h) -} - -// Present the current frame. -func (r *Renderer) Present() error { - r.renderer.Present() - return nil -} - -// Delay using sdl.Delay -func (r *Renderer) Delay(time uint32) { - sdl.Delay(time) -} - -// Loop is the main loop. -func (r *Renderer) Loop() error { - return nil -} diff --git a/lib/render/sdl/text.go b/lib/render/sdl/text.go deleted file mode 100644 index 1347254..0000000 --- a/lib/render/sdl/text.go +++ /dev/null @@ -1,183 +0,0 @@ -package sdl - -import ( - "fmt" - "sync" - - "git.kirsle.net/apps/doodle/lib/render" - "github.com/veandco/go-sdl2/sdl" - "github.com/veandco/go-sdl2/ttf" -) - -// TODO: font filenames -var defaultFontFilename = "DejaVuSans.ttf" - -// Font holds cached SDL_TTF structures for loaded fonts. They are created -// automatically when fonts are either preinstalled (InstallFont) or loaded for -// the first time as demanded by the DrawText method. -type Font struct { - Filename string - data []byte // raw binary data of font - ttf *ttf.Font -} - -var ( - fonts = map[string]*ttf.Font{} // keys like "DejaVuSans@14" by font size - installedFont = map[string][]byte{} // installed font files' binary handles - fontsMu sync.RWMutex -) - -// InstallFont preloads the font cache using TTF binary data in memory. -func InstallFont(filename string, binary []byte) { - fontsMu.Lock() - installedFont[filename] = binary - fontsMu.Unlock() -} - -// LoadFont loads and caches the font at a given size. -func LoadFont(filename string, size int) (*ttf.Font, error) { - if filename == "" { - filename = defaultFontFilename - } - - // Cached font available? - keyName := fmt.Sprintf("%s@%d", filename, size) - if font, ok := fonts[keyName]; ok { - return font, nil - } - - // Do we have this font in memory? - var ( - font *ttf.Font - err error - ) - - if binary, ok := installedFont[filename]; ok { - var RWops *sdl.RWops - RWops, err = sdl.RWFromMem(binary) - if err != nil { - return nil, fmt.Errorf("LoadFont(%s): RWFromMem: %s", filename, err) - } - - font, err = ttf.OpenFontRW(RWops, 0, size) - } else { - font, err = ttf.OpenFont(filename, size) - } - - // Error opening the font? - if err != nil { - return nil, fmt.Errorf("LoadFont(%s): %s", filename, err) - } - - // Cache this font name and size. - fonts[keyName] = font - - return font, nil -} - -// ComputeTextRect computes and returns a Rect for how large the text would -// appear if rendered. -func (r *Renderer) ComputeTextRect(text render.Text) (render.Rect, error) { - var ( - rect render.Rect - font *ttf.Font - surface *sdl.Surface - color = ColorToSDL(text.Color) - err error - ) - - if font, err = LoadFont(text.FontFilename, text.Size); err != nil { - return rect, err - } - - if surface, err = font.RenderUTF8Blended(text.Text, color); err != nil { - return rect, err - } - defer surface.Free() - - rect.W = surface.W - rect.H = surface.H - return rect, err -} - -// DrawText draws text on the canvas. -func (r *Renderer) DrawText(text render.Text, point render.Point) error { - var ( - font *ttf.Font - surface *sdl.Surface - tex *sdl.Texture - err error - ) - - if font, err = LoadFont(text.FontFilename, text.Size); err != nil { - return err - } - - write := func(dx, dy int32, color sdl.Color) { - if surface, err = font.RenderUTF8Blended(text.Text, color); err != nil { - return - } - defer surface.Free() - - if tex, err = r.renderer.CreateTextureFromSurface(surface); err != nil { - return - } - defer tex.Destroy() - - tmp := &sdl.Rect{ - X: point.X + dx, - Y: point.Y + dy, - W: surface.W, - H: surface.H, - } - r.renderer.Copy(tex, nil, tmp) - } - - // Does the text have a stroke around it? - if text.Stroke != render.Invisible { - color := ColorToSDL(text.Stroke) - write(-1, -1, color) - write(-1, 0, color) - write(-1, 1, color) - write(1, -1, color) - write(1, 0, color) - write(1, 1, color) - write(0, -1, color) - write(0, 1, color) - } - - // Does it have a drop shadow? - if text.Shadow != render.Invisible { - write(1, 1, ColorToSDL(text.Shadow)) - } - - // Draw the text itself. - write(0, 0, ColorToSDL(text.Color)) - - return err -} - -// shiftMap maps keys to their Shift versions. -var shiftMap = map[string]string{ - "`": "~", - "1": "!", - "2": "@", - "3": "#", - "4": "$", - "5": "%", - "6": "^", - "7": "&", - "8": "*", - "9": "(", - "0": ")", - "-": "_", - "=": "+", - "[": "{", - "]": "}", - `\`: "|", - ";": ":", - `'`: `"`, - ",": "<", - ".": ">", - "/": "?", -} diff --git a/lib/render/sdl/texture.go b/lib/render/sdl/texture.go deleted file mode 100644 index 27b0cc7..0000000 --- a/lib/render/sdl/texture.go +++ /dev/null @@ -1,84 +0,0 @@ -package sdl - -import ( - "bytes" - "fmt" - "image" - - "git.kirsle.net/apps/doodle/lib/render" - "github.com/veandco/go-sdl2/sdl" - "golang.org/x/image/bmp" -) - -// Copy a texture into the renderer. -func (r *Renderer) Copy(t render.Texturer, src, dst render.Rect) { - if tex, ok := t.(*Texture); ok { - var ( - a = RectToSDL(src) - b = RectToSDL(dst) - ) - r.renderer.Copy(tex.tex, &a, &b) - } -} - -// Texture can hold on to SDL textures for caching and optimization. -type Texture struct { - tex *sdl.Texture - width int32 - height int32 -} - -// StoreTexture caches an SDL texture from a bitmap. -func (r *Renderer) StoreTexture(name string, img image.Image) (render.Texturer, error) { - var ( - fh = bytes.NewBuffer([]byte{}) - ) - - err := bmp.Encode(fh, img) - if err != nil { - return nil, fmt.Errorf("NewTexture: bmp.Encode: %s", err) - } - - // Create an SDL RWOps from the bitmap data in memory. - sdlRW, err := sdl.RWFromMem(fh.Bytes()) - if err != nil { - return nil, fmt.Errorf("NewTexture: sdl.RWFromMem: %s", err) - } - - surface, err := sdl.LoadBMPRW(sdlRW, true) - if err != nil { - return nil, fmt.Errorf("NewTexture: sdl.LoadBMPRW: %s", err) - } - defer surface.Free() - - // TODO: chroma key color hardcoded to white here - key := sdl.MapRGB(surface.Format, 255, 255, 255) - surface.SetColorKey(true, key) - - texture, err := r.renderer.CreateTextureFromSurface(surface) - if err != nil { - return nil, fmt.Errorf("NewBitmap: create texture: %s", err) - } - - tex := &Texture{ - width: surface.W, - height: surface.H, - tex: texture, - } - r.textures[name] = tex - - return tex, nil -} - -// Size returns the dimensions of the texture. -func (t *Texture) Size() render.Rect { - return render.NewRect(t.width, t.height) -} - -// LoadTexture initializes a texture from a bitmap image. -func (r *Renderer) LoadTexture(name string) (render.Texturer, error) { - if tex, ok := r.textures[name]; ok { - return tex, nil - } - return nil, fmt.Errorf("LoadTexture(%s): not found in texture cache", name) -} diff --git a/lib/render/sdl/utils.go b/lib/render/sdl/utils.go deleted file mode 100644 index 3c7f260..0000000 --- a/lib/render/sdl/utils.go +++ /dev/null @@ -1,26 +0,0 @@ -package sdl - -import ( - "git.kirsle.net/apps/doodle/lib/render" - "github.com/veandco/go-sdl2/sdl" -) - -// ColorToSDL converts Doodle's Color type to an sdl.Color. -func ColorToSDL(c render.Color) sdl.Color { - return sdl.Color{ - R: c.Red, - G: c.Green, - B: c.Blue, - A: c.Alpha, - } -} - -// RectToSDL converts Doodle's Rect type to an sdl.Rect. -func RectToSDL(r render.Rect) sdl.Rect { - return sdl.Rect{ - X: r.X, - Y: r.Y, - W: r.W, - H: r.H, - } -} diff --git a/lib/render/shapes.go b/lib/render/shapes.go deleted file mode 100644 index fb873cb..0000000 --- a/lib/render/shapes.go +++ /dev/null @@ -1,105 +0,0 @@ -package render - -import ( - "math" -) - -// IterLine is a generator that returns the X,Y coordinates to draw a line. -// https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm) -func IterLine(p1 Point, p2 Point) chan Point { - var ( - x1 = p1.X - y1 = p1.Y - x2 = p2.X - y2 = p2.Y - ) - generator := make(chan Point) - - go func() { - var ( - dx = float64(x2 - x1) - dy = float64(y2 - y1) - ) - var step float64 - if math.Abs(dx) >= math.Abs(dy) { - step = math.Abs(dx) - } else { - step = math.Abs(dy) - } - - dx = dx / step - dy = dy / step - x := float64(x1) - y := float64(y1) - for i := 0; i <= int(step); i++ { - generator <- Point{ - X: int32(x), - Y: int32(y), - } - x += dx - y += dy - } - - close(generator) - }() - - return generator -} - -// IterRect loops through all the points forming a rectangle between the -// top-left point and the bottom-right point. -func IterRect(p1, p2 Point) chan Point { - generator := make(chan Point) - - go func() { - var ( - TopLeft = p1 - BottomRight = p2 - TopRight = Point{ - X: BottomRight.X, - Y: TopLeft.Y, - } - BottomLeft = Point{ - X: TopLeft.X, - Y: BottomRight.Y, - } - dedupe = map[Point]interface{}{} - ) - - // Trace all four edges and yield it. - var edges = []struct { - A Point - B Point - }{ - {TopLeft, TopRight}, - {TopLeft, BottomLeft}, - {BottomLeft, BottomRight}, - {TopRight, BottomRight}, - } - for _, edge := range edges { - for pt := range IterLine(edge.A, edge.B) { - if _, ok := dedupe[pt]; !ok { - generator <- pt - dedupe[pt] = nil - } - } - } - - close(generator) - }() - - return generator -} - -// IterEllipse iterates an Ellipse using two Points as the top-left and -// bottom-right corners of a rectangle that encompasses the ellipse. -func IterEllipse(A, B Point) chan Point { - var ( - width = AbsInt32(B.X - A.X) - height = AbsInt32(B.Y - A.Y) - radius = NewPoint(width/2, height/2) - center = NewPoint(AbsInt32(B.X-radius.X), AbsInt32(B.Y-radius.Y)) - ) - - return MidpointEllipse(center, radius) -} diff --git a/lib/ui/button.go b/lib/ui/button.go index 708c88a..511227c 100644 --- a/lib/ui/button.go +++ b/lib/ui/button.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui/theme" ) diff --git a/lib/ui/check_button.go b/lib/ui/check_button.go index 838667c..5074c94 100644 --- a/lib/ui/check_button.go +++ b/lib/ui/check_button.go @@ -4,7 +4,7 @@ import ( "fmt" "strconv" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui/theme" ) diff --git a/lib/ui/checkbox.go b/lib/ui/checkbox.go index e98d7d2..d47835f 100644 --- a/lib/ui/checkbox.go +++ b/lib/ui/checkbox.go @@ -1,6 +1,6 @@ package ui -import "git.kirsle.net/apps/doodle/lib/render" +import "git.kirsle.net/go/render" // Checkbox combines a CheckButton with a widget like a Label. type Checkbox struct { diff --git a/lib/ui/eg/main.go b/lib/ui/eg/main.go index 6116cfc..276a502 100644 --- a/lib/ui/eg/main.go +++ b/lib/ui/eg/main.go @@ -1,7 +1,7 @@ package main import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" ) diff --git a/lib/ui/frame.go b/lib/ui/frame.go index e438f23..03da8b6 100644 --- a/lib/ui/frame.go +++ b/lib/ui/frame.go @@ -3,7 +3,7 @@ package ui import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Frame is a widget that contains other widgets. diff --git a/lib/ui/frame_pack.go b/lib/ui/frame_pack.go index cece214..f160263 100644 --- a/lib/ui/frame_pack.go +++ b/lib/ui/frame_pack.go @@ -1,7 +1,7 @@ package ui import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Pack provides configuration fields for Frame.Pack(). diff --git a/lib/ui/functions.go b/lib/ui/functions.go index 9780a30..9689cd9 100644 --- a/lib/ui/functions.go +++ b/lib/ui/functions.go @@ -1,6 +1,6 @@ package ui -import "git.kirsle.net/apps/doodle/lib/render" +import "git.kirsle.net/go/render" // AbsolutePosition computes a widget's absolute X,Y position on the // window on screen by crawling its parent widget tree. diff --git a/lib/ui/image.go b/lib/ui/image.go index c6ef2b0..d58e740 100644 --- a/lib/ui/image.go +++ b/lib/ui/image.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // ImageType for supported image formats. diff --git a/lib/ui/label.go b/lib/ui/label.go index 86a9f1d..f670aca 100644 --- a/lib/ui/label.go +++ b/lib/ui/label.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // DefaultFont is the default font settings used for a Label. diff --git a/lib/ui/main_window.go b/lib/ui/main_window.go index 5cf5487..6d3c837 100644 --- a/lib/ui/main_window.go +++ b/lib/ui/main_window.go @@ -6,8 +6,8 @@ import ( "fmt" "time" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/sdl" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/sdl" ) // Target frames per second for the MainWindow to render at. diff --git a/lib/ui/menu.go b/lib/ui/menu.go index adebbaa..077773c 100644 --- a/lib/ui/menu.go +++ b/lib/ui/menu.go @@ -3,7 +3,7 @@ package ui import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Menu is a rectangle that holds menu items. diff --git a/lib/ui/supervisor.go b/lib/ui/supervisor.go index b5fda2f..2d92812 100644 --- a/lib/ui/supervisor.go +++ b/lib/ui/supervisor.go @@ -4,8 +4,8 @@ import ( "errors" "sync" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" ) // Event is a named event that the supervisor will send. diff --git a/lib/ui/theme/theme.go b/lib/ui/theme/theme.go index d8e5d89..33ce4b4 100644 --- a/lib/ui/theme/theme.go +++ b/lib/ui/theme/theme.go @@ -1,6 +1,6 @@ package theme -import "git.kirsle.net/apps/doodle/lib/render" +import "git.kirsle.net/go/render" // Color schemes. var ( diff --git a/lib/ui/widget.go b/lib/ui/widget.go index 57a00a2..0f0ec71 100644 --- a/lib/ui/widget.go +++ b/lib/ui/widget.go @@ -3,7 +3,7 @@ package ui import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui/theme" ) diff --git a/lib/ui/window.go b/lib/ui/window.go index a956e7f..6d76c04 100644 --- a/lib/ui/window.go +++ b/lib/ui/window.go @@ -3,7 +3,7 @@ package ui import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Window is a frame with a title bar. diff --git a/pkg/balance/debug.go b/pkg/balance/debug.go index 561b3b2..3a3d85e 100644 --- a/pkg/balance/debug.go +++ b/pkg/balance/debug.go @@ -5,7 +5,7 @@ import ( "strconv" "strings" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Debug related variables that can toggle on or off certain features and diff --git a/pkg/balance/shell.go b/pkg/balance/shell.go index a5b361b..836e893 100644 --- a/pkg/balance/shell.go +++ b/pkg/balance/shell.go @@ -1,6 +1,6 @@ package balance -import "git.kirsle.net/apps/doodle/lib/render" +import "git.kirsle.net/go/render" // Shell related variables. var ( diff --git a/pkg/balance/theme.go b/pkg/balance/theme.go index 5ffdd15..893760a 100644 --- a/pkg/balance/theme.go +++ b/pkg/balance/theme.go @@ -1,7 +1,7 @@ package balance import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" ) diff --git a/pkg/collision/actors_test.go b/pkg/collision/actors_test.go index 11c2800..d7e71f2 100644 --- a/pkg/collision/actors_test.go +++ b/pkg/collision/actors_test.go @@ -3,7 +3,7 @@ package collision_test import ( "testing" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/collision" ) diff --git a/pkg/collision/collide_actors.go b/pkg/collision/collide_actors.go index 378d81a..a0f452f 100644 --- a/pkg/collision/collide_actors.go +++ b/pkg/collision/collide_actors.go @@ -4,7 +4,7 @@ import ( "errors" "math" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // BoxCollision holds the result of a collision BetweenBoxes. diff --git a/pkg/collision/collide_level.go b/pkg/collision/collide_level.go index 5d2a0e1..b5e97e5 100644 --- a/pkg/collision/collide_level.go +++ b/pkg/collision/collide_level.go @@ -3,7 +3,7 @@ package collision import ( "sync" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/level" ) diff --git a/pkg/collision/debug_box.go b/pkg/collision/debug_box.go index 8392af7..1a3d15a 100644 --- a/pkg/collision/debug_box.go +++ b/pkg/collision/debug_box.go @@ -3,7 +3,7 @@ package collision import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // CollisionBox holds all of the coordinate pairs to draw the collision box diff --git a/pkg/collision/level_test.go b/pkg/collision/level_test.go index 65a8365..499ac95 100644 --- a/pkg/collision/level_test.go +++ b/pkg/collision/level_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/collision" "git.kirsle.net/apps/doodle/pkg/doodads/dummy" "git.kirsle.net/apps/doodle/pkg/level" diff --git a/pkg/doodads/actor.go b/pkg/doodads/actor.go index 037b1f7..d970db2 100644 --- a/pkg/doodads/actor.go +++ b/pkg/doodads/actor.go @@ -1,7 +1,7 @@ package doodads import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Actor is a reusable run-time drawing component used in Doodle. Actors are an diff --git a/pkg/doodads/doodad.go b/pkg/doodads/doodad.go index e84470e..c9fe3ed 100644 --- a/pkg/doodads/doodad.go +++ b/pkg/doodads/doodad.go @@ -1,7 +1,7 @@ package doodads import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/level" ) diff --git a/pkg/doodads/drawing.go b/pkg/doodads/drawing.go index 1347162..43515c2 100644 --- a/pkg/doodads/drawing.go +++ b/pkg/doodads/drawing.go @@ -1,7 +1,7 @@ package doodads import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "github.com/google/uuid" ) diff --git a/pkg/doodads/dummy.go b/pkg/doodads/dummy.go index 5dac759..d072565 100644 --- a/pkg/doodads/dummy.go +++ b/pkg/doodads/dummy.go @@ -1,7 +1,7 @@ package doodads import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/level" ) diff --git a/pkg/doodle.go b/pkg/doodle.go index 7155f30..3ae8a03 100644 --- a/pkg/doodle.go +++ b/pkg/doodle.go @@ -6,8 +6,8 @@ import ( "strings" "time" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/branding" "git.kirsle.net/apps/doodle/pkg/enum" diff --git a/pkg/drawtool/history_test.go b/pkg/drawtool/history_test.go index 7bcf742..431821f 100644 --- a/pkg/drawtool/history_test.go +++ b/pkg/drawtool/history_test.go @@ -3,7 +3,7 @@ package drawtool import ( "testing" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) func TestHistory(t *testing.T) { diff --git a/pkg/drawtool/stroke.go b/pkg/drawtool/stroke.go index 501548d..6fc9dfa 100644 --- a/pkg/drawtool/stroke.go +++ b/pkg/drawtool/stroke.go @@ -1,6 +1,6 @@ package drawtool -import "git.kirsle.net/apps/doodle/lib/render" +import "git.kirsle.net/go/render" /* Stroke holds temporary pixel data with a shape and color. diff --git a/pkg/editor_scene.go b/pkg/editor_scene.go index 5dd0e6d..ce4affd 100644 --- a/pkg/editor_scene.go +++ b/pkg/editor_scene.go @@ -6,8 +6,8 @@ import ( "os" "strings" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/drawtool" diff --git a/pkg/editor_ui.go b/pkg/editor_ui.go index 0f1f108..c5bed28 100644 --- a/pkg/editor_ui.go +++ b/pkg/editor_ui.go @@ -5,8 +5,8 @@ import ( "path/filepath" "strconv" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/branding" diff --git a/pkg/editor_ui_doodad.go b/pkg/editor_ui_doodad.go index 9b647f0..13d58ef 100644 --- a/pkg/editor_ui_doodad.go +++ b/pkg/editor_ui_doodad.go @@ -7,7 +7,7 @@ package doodle import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/doodads" diff --git a/pkg/editor_ui_palette.go b/pkg/editor_ui_palette.go index 783e383..801b599 100644 --- a/pkg/editor_ui_palette.go +++ b/pkg/editor_ui_palette.go @@ -3,7 +3,7 @@ package doodle import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/log" diff --git a/pkg/editor_ui_toolbar.go b/pkg/editor_ui_toolbar.go index a97397c..880668e 100644 --- a/pkg/editor_ui_toolbar.go +++ b/pkg/editor_ui_toolbar.go @@ -1,7 +1,7 @@ package doodle import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/drawtool" diff --git a/pkg/fps.go b/pkg/fps.go index dc63422..be4c93f 100644 --- a/pkg/fps.go +++ b/pkg/fps.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/collision" diff --git a/pkg/guitest_scene.go b/pkg/guitest_scene.go index dd780d0..6d31073 100644 --- a/pkg/guitest_scene.go +++ b/pkg/guitest_scene.go @@ -3,8 +3,8 @@ package doodle import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/branding" diff --git a/pkg/level/actors.go b/pkg/level/actors.go index ad89bde..3d1ba1d 100644 --- a/pkg/level/actors.go +++ b/pkg/level/actors.go @@ -1,7 +1,7 @@ package level import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "github.com/google/uuid" ) diff --git a/pkg/level/chunk.go b/pkg/level/chunk.go index cc103f8..dcbcc1a 100644 --- a/pkg/level/chunk.go +++ b/pkg/level/chunk.go @@ -6,7 +6,7 @@ import ( "image" "math" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/shmem" diff --git a/pkg/level/chunk_map.go b/pkg/level/chunk_map.go index 3342830..8ea49ac 100644 --- a/pkg/level/chunk_map.go +++ b/pkg/level/chunk_map.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "github.com/vmihailenco/msgpack" ) diff --git a/pkg/level/chunk_test.go b/pkg/level/chunk_test.go index 4cd8cd5..c08b0c2 100644 --- a/pkg/level/chunk_test.go +++ b/pkg/level/chunk_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/level" ) diff --git a/pkg/level/chunker.go b/pkg/level/chunker.go index 903e0cd..96cecec 100644 --- a/pkg/level/chunker.go +++ b/pkg/level/chunker.go @@ -5,7 +5,7 @@ import ( "fmt" "math" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/log" "github.com/vmihailenco/msgpack" ) diff --git a/pkg/level/chunker_test.go b/pkg/level/chunker_test.go index cba5d78..0951664 100644 --- a/pkg/level/chunker_test.go +++ b/pkg/level/chunker_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/level" ) diff --git a/pkg/level/palette.go b/pkg/level/palette.go index 232250f..dc65c2c 100644 --- a/pkg/level/palette.go +++ b/pkg/level/palette.go @@ -1,6 +1,6 @@ package level -import "git.kirsle.net/apps/doodle/lib/render" +import "git.kirsle.net/go/render" // DefaultPalette returns a sensible default palette. func DefaultPalette() *Palette { diff --git a/pkg/level/swatch.go b/pkg/level/swatch.go index 96e8863..0e5c52b 100644 --- a/pkg/level/swatch.go +++ b/pkg/level/swatch.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Swatch holds details about a single value in the palette. diff --git a/pkg/level/types.go b/pkg/level/types.go index b0a8e77..f182ddb 100644 --- a/pkg/level/types.go +++ b/pkg/level/types.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/drawtool" ) diff --git a/pkg/main_scene.go b/pkg/main_scene.go index eeaf801..6c978d6 100644 --- a/pkg/main_scene.go +++ b/pkg/main_scene.go @@ -1,8 +1,8 @@ package doodle import ( - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/branding" diff --git a/pkg/menu_scene.go b/pkg/menu_scene.go index 3d39d14..1c85c98 100644 --- a/pkg/menu_scene.go +++ b/pkg/menu_scene.go @@ -3,8 +3,8 @@ package doodle import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/enum" diff --git a/pkg/play_scene.go b/pkg/play_scene.go index 002de6a..56d7057 100644 --- a/pkg/play_scene.go +++ b/pkg/play_scene.go @@ -3,8 +3,8 @@ package doodle import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/collision" diff --git a/pkg/scene.go b/pkg/scene.go index f9b43c4..4353a65 100644 --- a/pkg/scene.go +++ b/pkg/scene.go @@ -1,7 +1,7 @@ package doodle import ( - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/pkg/log" ) diff --git a/pkg/scripting/events.go b/pkg/scripting/events.go index d1a03a0..b6e725e 100644 --- a/pkg/scripting/events.go +++ b/pkg/scripting/events.go @@ -3,7 +3,7 @@ package scripting import ( "errors" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render/event" "github.com/robertkrimen/otto" ) diff --git a/pkg/scripting/vm.go b/pkg/scripting/vm.go index 498e887..57cf67f 100644 --- a/pkg/scripting/vm.go +++ b/pkg/scripting/vm.go @@ -5,7 +5,7 @@ import ( "reflect" "time" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/shmem" "github.com/robertkrimen/otto" diff --git a/pkg/shell.go b/pkg/shell.go index a1cdfd9..8c87464 100644 --- a/pkg/shell.go +++ b/pkg/shell.go @@ -5,8 +5,8 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/log" diff --git a/pkg/shmem/globals.go b/pkg/shmem/globals.go index 51da194..f687091 100644 --- a/pkg/shmem/globals.go +++ b/pkg/shmem/globals.go @@ -3,7 +3,7 @@ package shmem import ( "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" ) // Shared globals for easy access throughout the app. diff --git a/pkg/sprites/sprites.go b/pkg/sprites/sprites.go index 5750d33..d975799 100644 --- a/pkg/sprites/sprites.go +++ b/pkg/sprites/sprites.go @@ -8,7 +8,7 @@ import ( "os" "runtime" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/bindata" "git.kirsle.net/apps/doodle/pkg/log" diff --git a/pkg/uix/actor.go b/pkg/uix/actor.go index e8fd36f..d4aefad 100644 --- a/pkg/uix/actor.go +++ b/pkg/uix/actor.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/level" "github.com/google/uuid" diff --git a/pkg/uix/actor_collision.go b/pkg/uix/actor_collision.go index b7c96e0..a4afc23 100644 --- a/pkg/uix/actor_collision.go +++ b/pkg/uix/actor_collision.go @@ -5,7 +5,7 @@ import ( "sync" "time" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/collision" "git.kirsle.net/apps/doodle/pkg/doodads" diff --git a/pkg/uix/actor_events.go b/pkg/uix/actor_events.go index e72d9be..c1b9f0f 100644 --- a/pkg/uix/actor_events.go +++ b/pkg/uix/actor_events.go @@ -1,6 +1,6 @@ package uix -import "git.kirsle.net/apps/doodle/lib/render" +import "git.kirsle.net/go/render" // CollideEvent holds data sent to an actor's Collide handler. type CollideEvent struct { diff --git a/pkg/uix/canvas.go b/pkg/uix/canvas.go index 51d734a..4177c5f 100644 --- a/pkg/uix/canvas.go +++ b/pkg/uix/canvas.go @@ -6,8 +6,8 @@ import ( "runtime" "strings" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/bindata" diff --git a/pkg/uix/canvas_actors.go b/pkg/uix/canvas_actors.go index d475883..351984e 100644 --- a/pkg/uix/canvas_actors.go +++ b/pkg/uix/canvas_actors.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/doodads" "git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/log" diff --git a/pkg/uix/canvas_cursor.go b/pkg/uix/canvas_cursor.go index 30b4b8f..0339700 100644 --- a/pkg/uix/canvas_cursor.go +++ b/pkg/uix/canvas_cursor.go @@ -1,7 +1,7 @@ package uix import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/shmem" ) diff --git a/pkg/uix/canvas_editable.go b/pkg/uix/canvas_editable.go index 32e6da5..aff91d4 100644 --- a/pkg/uix/canvas_editable.go +++ b/pkg/uix/canvas_editable.go @@ -1,8 +1,8 @@ package uix import ( - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/drawtool" "git.kirsle.net/apps/doodle/pkg/level" diff --git a/pkg/uix/canvas_present.go b/pkg/uix/canvas_present.go index 12c2c11..90a76eb 100644 --- a/pkg/uix/canvas_present.go +++ b/pkg/uix/canvas_present.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/log" diff --git a/pkg/uix/canvas_scrolling.go b/pkg/uix/canvas_scrolling.go index e17e03b..d5f9fdd 100644 --- a/pkg/uix/canvas_scrolling.go +++ b/pkg/uix/canvas_scrolling.go @@ -4,8 +4,8 @@ import ( "errors" "fmt" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/event" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/event" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/level" ) diff --git a/pkg/uix/canvas_strokes.go b/pkg/uix/canvas_strokes.go index 447aa4b..9d3edac 100644 --- a/pkg/uix/canvas_strokes.go +++ b/pkg/uix/canvas_strokes.go @@ -1,7 +1,7 @@ package uix import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/drawtool" diff --git a/pkg/uix/canvas_wallpaper.go b/pkg/uix/canvas_wallpaper.go index 897043b..e51b89b 100644 --- a/pkg/uix/canvas_wallpaper.go +++ b/pkg/uix/canvas_wallpaper.go @@ -1,7 +1,7 @@ package uix import ( - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/level" "git.kirsle.net/apps/doodle/pkg/wallpaper" ) diff --git a/pkg/wallpaper/texture.go b/pkg/wallpaper/texture.go index 7ad83b2..9102135 100644 --- a/pkg/wallpaper/texture.go +++ b/pkg/wallpaper/texture.go @@ -6,7 +6,7 @@ import ( "errors" "image" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/shmem" "git.kirsle.net/apps/doodle/pkg/userdir" ) diff --git a/pkg/wallpaper/wallpaper.go b/pkg/wallpaper/wallpaper.go index 7c9a56f..3f89d46 100644 --- a/pkg/wallpaper/wallpaper.go +++ b/pkg/wallpaper/wallpaper.go @@ -9,7 +9,7 @@ import ( "runtime" "strings" - "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/go/render" "git.kirsle.net/apps/doodle/pkg/bindata" ) diff --git a/wasm/main_wasm.go b/wasm/main_wasm.go index e165aeb..93eb136 100644 --- a/wasm/main_wasm.go +++ b/wasm/main_wasm.go @@ -7,8 +7,8 @@ import ( "syscall/js" - "git.kirsle.net/apps/doodle/lib/render" - "git.kirsle.net/apps/doodle/lib/render/canvas" + "git.kirsle.net/go/render" + "git.kirsle.net/go/render/canvas" doodle "git.kirsle.net/apps/doodle/pkg" "git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/branding"