From 5b3e679b2aa4b1b31696c49e32ade2eb665d6d67 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sat, 20 Oct 2018 19:49:59 -0700 Subject: [PATCH 1/5] WIP --- doodads/actor.go | 3 -- doodads/drawing.go | 75 +++++++++++++++++++++++++++++++++++++++++ doodads/dummy/dummy.go | 16 +++++++++ doodads/dummy/player.go | 11 ++++++ doodle.go | 3 +- editor_scene.go | 1 + fps.go | 4 +-- play_scene.go | 33 +++++++++++++++--- uix/actor.go | 48 ++++++++++++++++++++++++++ uix/canvas.go | 26 ++++---------- 10 files changed, 190 insertions(+), 30 deletions(-) create mode 100644 doodads/drawing.go create mode 100644 doodads/dummy/dummy.go create mode 100644 doodads/dummy/player.go create mode 100644 uix/actor.go diff --git a/doodads/actor.go b/doodads/actor.go index 89707d1..9be2e1b 100644 --- a/doodads/actor.go +++ b/doodads/actor.go @@ -20,9 +20,6 @@ type Actor interface { // Movement commands. MoveBy(render.Point) // Add {X,Y} to current Position. MoveTo(render.Point) // Set current Position to {X,Y}. - - // Implement the Draw function. - Draw(render.Engine) } // GetBoundingRect computes the full pairs of points for the collision box diff --git a/doodads/drawing.go b/doodads/drawing.go new file mode 100644 index 0000000..c333ccf --- /dev/null +++ b/doodads/drawing.go @@ -0,0 +1,75 @@ +package doodads + +import ( + "git.kirsle.net/apps/doodle/render" + uuid "github.com/satori/go.uuid" +) + +// Drawing is a Doodad Actor that is based on drawings made inside the game. +type Drawing struct { + Doodad *Doodad + + id string + point render.Point + velocity render.Point + size render.Rect + grounded bool +} + +// NewDrawing creates a Drawing actor based on a Doodad drawing. If you pass +// an empty ID string, it will make a random UUIDv4 ID. +func NewDrawing(id string, doodad *Doodad) Drawing { + if id == "" { + id = uuid.Must(uuid.NewV4()).String() + } + return Drawing{ + id: id, + Doodad: doodad, + size: doodad.Rect(), + } +} + +// ID to get the Drawing ID. +func (d *Drawing) ID() string { + return d.id +} + +// Position returns the Drawing's position. +func (d *Drawing) Position() render.Point { + return d.point +} + +// Velocity returns the Drawing's velocity. +func (d *Drawing) Velocity() render.Point { + return d.velocity +} + +// Size returns the Drawing's size. +func (d *Drawing) Size() render.Rect { + return d.size +} + +// Grounded returns whether the Drawing is standing on solid ground. +func (d *Drawing) Grounded() bool { + return d.grounded +} + +// SetGrounded sets the grounded state. +func (d *Drawing) SetGrounded(v bool) { + d.grounded = v +} + +// MoveBy a relative value. +func (d *Drawing) MoveBy(by render.Point) { + d.point.Add(by) +} + +// MoveTo an absolute world value. +func (d *Drawing) MoveTo(to render.Point) { + d.point = to +} + +// Draw the drawing. +func (d *Drawing) Draw(e render.Engine) { + +} diff --git a/doodads/dummy/dummy.go b/doodads/dummy/dummy.go new file mode 100644 index 0000000..2dc79d7 --- /dev/null +++ b/doodads/dummy/dummy.go @@ -0,0 +1,16 @@ +// Package dummy implements a dummy doodads.Drawing. +package dummy + +import "git.kirsle.net/apps/doodle/doodads" + +// Drawing is a dummy doodads.Drawing that has no data. +type Drawing struct { + doodads.Drawing +} + +// NewDrawing creates a new dummy drawing. +func NewDrawing(id string, doodad *doodads.Doodad) *Drawing { + return &Drawing{ + Drawing: doodads.NewDrawing(id, doodad), + } +} diff --git a/doodads/dummy/player.go b/doodads/dummy/player.go new file mode 100644 index 0000000..5f4a018 --- /dev/null +++ b/doodads/dummy/player.go @@ -0,0 +1,11 @@ +// Package dummy implements a dummy doodads.Drawing. +package dummy + +import "git.kirsle.net/apps/doodle/doodads" + +// NewPlayer creates a dummy player object. +func NewPlayer() *Drawing { + return &Drawing{ + Drawing: doodads.NewDrawing("PLAYER", doodads.New(32)), + } +} diff --git a/doodle.go b/doodle.go index 4f129cf..a437fd8 100644 --- a/doodle.go +++ b/doodle.go @@ -8,6 +8,7 @@ import ( "git.kirsle.net/apps/doodle/balance" "git.kirsle.net/apps/doodle/enum" "git.kirsle.net/apps/doodle/events" + "git.kirsle.net/apps/doodle/pkg/userdir" "git.kirsle.net/apps/doodle/render" "github.com/kirsle/golog" ) @@ -216,7 +217,7 @@ func (d *Doodle) EditDrawing(filename string) error { func (d *Doodle) PlayLevel(filename string) error { log.Info("Loading level from file: %s", filename) scene := &PlayScene{ - Filename: filename, + Filename: userdir.LevelPath(filename), } d.Goto(scene) return nil diff --git a/editor_scene.go b/editor_scene.go index f67f6b8..5c29c0e 100644 --- a/editor_scene.go +++ b/editor_scene.go @@ -58,6 +58,7 @@ func (s *EditorScene) Setup(d *Doodle) error { if s.Level != nil { log.Debug("EditorScene.Setup: received level from scene caller") s.UI.Canvas.LoadLevel(s.Level) + s.UI.Canvas.InstallActors(s.Level.Actors) } else if s.filename != "" && s.OpenFile { log.Debug("EditorScene.Setup: Loading map from filename at %s", s.filename) if err := s.LoadLevel(s.filename); err != nil { diff --git a/fps.go b/fps.go index f1b6147..5321331 100644 --- a/fps.go +++ b/fps.go @@ -42,7 +42,7 @@ var ( // DrawDebugOverlay draws the debug FPS text on the SDL canvas. func (d *Doodle) DrawDebugOverlay() { - if !d.Debug || !DebugOverlay { + if !DebugOverlay { return } @@ -97,7 +97,7 @@ func (d *Doodle) DrawDebugOverlay() { // DrawCollisionBox draws the collision box around a Doodad. func (d *Doodle) DrawCollisionBox(actor doodads.Actor) { - if !d.Debug || !DebugCollision { + if !DebugCollision { return } diff --git a/play_scene.go b/play_scene.go index 659d70a..aaa3ee7 100644 --- a/play_scene.go +++ b/play_scene.go @@ -5,6 +5,7 @@ import ( "git.kirsle.net/apps/doodle/balance" "git.kirsle.net/apps/doodle/doodads" + "git.kirsle.net/apps/doodle/doodads/dummy" "git.kirsle.net/apps/doodle/events" "git.kirsle.net/apps/doodle/level" "git.kirsle.net/apps/doodle/render" @@ -21,7 +22,7 @@ type PlayScene struct { drawing *uix.Canvas // Player character - Player doodads.Actor + Player *uix.Actor } // Name of the scene. @@ -40,12 +41,14 @@ func (s *PlayScene) Setup(d *Doodle) error { if s.Level != nil { log.Debug("PlayScene.Setup: received level from scene caller") s.drawing.LoadLevel(s.Level) + s.drawing.InstallActors(s.Level.Actors) } else if s.Filename != "" { log.Debug("PlayScene.Setup: loading map from file %s", s.Filename) s.LoadLevel(s.Filename) } - s.Player = doodads.NewPlayer() + player := dummy.NewPlayer() + s.Player = uix.NewActor(player.ID(), &level.Actor{}, player.Doodad) if s.Level == nil { log.Debug("PlayScene.Setup: no grid given, initializing empty grid") @@ -60,6 +63,17 @@ func (s *PlayScene) Setup(d *Doodle) error { // Loop the editor scene. func (s *PlayScene) Loop(d *Doodle, ev *events.State) error { + // Has the window been resized? + if resized := ev.Resized.Read(); resized { + w, h := d.Engine.WindowSize() + if w != d.width || h != d.height { + d.width = w + d.height = h + s.drawing.Resize(render.NewRect(int32(d.width), int32(d.height))) + return nil + } + } + // Switching to Edit Mode? if ev.KeyName.Read() == "e" { log.Info("Edit Mode, Go!") @@ -70,7 +84,7 @@ func (s *PlayScene) Loop(d *Doodle, ev *events.State) error { return nil } - // s.drawing.Loop(ev) + s.drawing.Loop(ev) s.movePlayer(ev) return nil } @@ -84,9 +98,16 @@ func (s *PlayScene) Draw(d *Doodle) error { s.drawing.Present(d.Engine, s.drawing.Point()) // Draw our hero. - s.Player.Draw(d.Engine) + { + d.Engine.DrawBox(render.RGBA(255, 255, 153, 255), render.Rect{ + X: s.Player.Position().X, + Y: s.Player.Position().Y, + W: s.Player.Size().W, + H: s.Player.Size().H, + }) + } - // Draw out bounding boxes. + // Draw our bounding boxes. d.DrawCollisionBox(s.Player) return nil @@ -141,6 +162,8 @@ func (s *PlayScene) LoadLevel(filename string) error { s.Level = level s.drawing.LoadLevel(s.Level) + s.drawing.InstallActors(s.Level.Actors) + s.drawing.AddActor(s.Player) return nil } diff --git a/uix/actor.go b/uix/actor.go new file mode 100644 index 0000000..06f710b --- /dev/null +++ b/uix/actor.go @@ -0,0 +1,48 @@ +package uix + +import ( + "git.kirsle.net/apps/doodle/doodads" + "git.kirsle.net/apps/doodle/level" + "git.kirsle.net/apps/doodle/render" + uuid "github.com/satori/go.uuid" +) + +// Actor is an object that marries together the three things that make a +// Doodad instance "tick" while inside a Canvas: +// +// - uix.Actor is a doodads.Drawing so it fulfills doodads.Actor to be a +// dynamic object during gameplay. +// - It has a pointer to the level.Actor indicating its static level data +// as defined in the map: its spawn coordinate and configuration. +// - A uix.Canvas that can present the actor's graphics to the screen. +type Actor struct { + doodads.Drawing + Actor *level.Actor + Canvas *Canvas +} + +// NewActor sets up a uix.Actor. +// If the id is blank, a new UUIDv4 is generated. +func NewActor(id string, levelActor *level.Actor, doodad *doodads.Doodad) *Actor { + if id == "" { + id = uuid.Must(uuid.NewV4()).String() + } + + size := int32(doodad.Layers[0].Chunker.Size) + can := NewCanvas(int(size), false) + can.Name = id + can.actor = levelActor + + // TODO: if the Background is render.Invisible it gets defaulted to + // White somewhere and the Doodad masks the level drawing behind it. + can.SetBackground(render.RGBA(0, 0, 1, 0)) + + can.LoadDoodad(doodad) + can.Resize(render.NewRect(size, size)) + + return &Actor{ + Drawing: doodads.NewDrawing(id, doodad), + Actor: levelActor, + Canvas: can, + } +} diff --git a/uix/canvas.go b/uix/canvas.go index 58c5062..c0737e2 100644 --- a/uix/canvas.go +++ b/uix/canvas.go @@ -53,12 +53,6 @@ type Canvas struct { Scroll render.Point // Scroll offset for which parts of canvas are visible. } -// Actor is an instance of an actor with a Canvas attached. -type Actor struct { - Actor *level.Actor - Canvas *Canvas -} - // NewCanvas initializes a Canvas widget. // // If editable is true, Scrollable is also set to true, which means the arrow @@ -123,23 +117,17 @@ func (w *Canvas) InstallActors(actors level.ActorMap) error { return fmt.Errorf("InstallActors: %s", err) } - size := int32(doodad.Layers[0].Chunker.Size) - can := NewCanvas(int(size), false) - can.Name = id - can.actor = actor - // TODO: if the Background is render.Invisible it gets defaulted to - // White somewhere and the Doodad masks the level drawing behind it. - can.SetBackground(render.RGBA(0, 0, 1, 0)) - can.LoadDoodad(doodad) - can.Resize(render.NewRect(size, size)) - w.actors = append(w.actors, &Actor{ - Actor: actor, - Canvas: can, - }) + w.actors = append(w.actors, NewActor(id, actor, doodad)) } return nil } +// AddActor injects additional actors into the canvas, such as a Player doodad. +func (w *Canvas) AddActor(actor *Actor) error { + w.actors = append(w.actors, actor) + return nil +} + // SetSwatch changes the currently selected swatch for editing. func (w *Canvas) SetSwatch(s *level.Swatch) { w.Palette.ActiveSwatch = s -- 2.30.2 From 6713dd7bfc93c00604f3351bfaf147ea7ecbb234 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sun, 28 Oct 2018 17:33:24 -0700 Subject: [PATCH 2/5] Play: Autoscrolling and Bounded Level Support Implement scrolling behavior in Play Mode by allowing the Canvas to follow a specific actor and keep it in view. The Canvas has a FollowActor property which holds an ID of the actor to follow (if blank, no actor is being followed). In Play Mode the Player is followed and when they get too close to the left or right edges of the screen, the level will scroll to try and catch them. If the player is moving very fast they can outrun the camera. The bounded levels are enforced in Play Mode and the camera won't scroll to view pixels out-of-bounds and the Doodad actors inside the level aren't allowed to exit its boundaries. This is global, not only for the Player doodad but any Doodad that came with the level as well. Other changes: - Restructured Canvas widget code into many new files. The Canvas widget is shaping up to be where most of the magic happens, which is okay because it's close to the action and pulling the strings from outside would be harder, even tho as a UI element you think it should be lightweight. - Debug Overlay: added room for Scenes to insert their own custom Debug Overlay key/value pairs (the values are string pointers so the Scene can update them freely): - The core labels are FPS, Scene and Mouse. The Pixel (world coordinate under cursor) is removed from the core labels. - Edit Scene provides Pixel, Tool and Swatch - Play Scene provides Pixel, Player, Viewport, Scroll --- Ideas.md | 53 +++--- balance/numbers.go | 9 + doodads/actor.go | 1 + doodads/drawing.go | 5 + doodads/player.go | 81 --------- editor_scene.go | 21 ++- editor_ui.go | 3 +- fps.go | 43 ++++- level/page_type.go | 7 +- play_scene.go | 71 ++++++-- scene.go | 3 + uix/canvas.go | 360 ++++++---------------------------------- uix/canvas_actors.go | 115 +++++++++++++ uix/canvas_present.go | 171 +++++++++++++++++++ uix/canvas_scrolling.go | 187 +++++++++++++++++++++ 15 files changed, 695 insertions(+), 435 deletions(-) delete mode 100644 doodads/player.go create mode 100644 uix/canvas_actors.go create mode 100644 uix/canvas_present.go create mode 100644 uix/canvas_scrolling.go diff --git a/Ideas.md b/Ideas.md index 3e4ca85..79c1b23 100644 --- a/Ideas.md +++ b/Ideas.md @@ -222,11 +222,14 @@ Probably mostly DRM free. Will want some sort of account server early-on though. * The texture file will be a square (rectangular maybe ok) with four quadrants from which the textures will be extracted. For example if the overall image size was 100x100 pixels, it will be divided into the four 50x50 quadrants. - 1. `TL`: Top left corner is the top left edge of the "page" the level is on - 2. `TR`: Top right corner is the repeated "top of page" texture. - 3. `BL`: Bottom left corner is the repeated "left of page" texture. - 4. `BR`: Bottom right corner is the repeated background texture that extends + 1. `Corner`: Top left corner is the top left edge of the "page" the level is on + 2. `Top`: Top right corner is the repeated "top of page" texture. + 3. `Left`: Bottom left corner is the repeated "left of page" texture. + 4. `Repeat`: Bottom right corner is the repeated background texture that extends infinitely in all directions. +* The Repeat texture is used all the time, and the other three are used when the + level type has boundaries (on the top and left edges in particular) to draw + decorative borders instead of the Repeat texture. * Levels will be able to choose a "page type" which controls how the wallpaper will be drawn and how the level boundaries may be constrained. There will be four options: @@ -241,22 +244,14 @@ Probably mostly DRM free. Will want some sort of account server early-on though. wall. 3. **Bounded:** The map has a fixed width and height and is bounded on all four edges. - 4. **Bounded, Mirrored Wallpaper:** same as Bounded but with a different - wallpaper behavior. -* The page types will have their own behaviors with how wallpapers are drawn: - * **Unbounded:** only the `BR` texture from the wallpaper is used, repeated - infinitely in the X and Y directions. The top-left, top, and left edge - textures are not used. - * **No Negative Space:** the `TL` texture is drawn at coordinate `(0,0)`. - To its right, the `TR` texture is repeated forever in the X direction, and - along the left edge of the page, the `BL` texture is repeated in the Y - direction. The remaining whitespace on the page repeats the `BR` texture - infinitely. - * **Bounded:** same as No Negative Space. - * **Bounded, Mirrored Wallpaper:** same as No Negative Space, but all of the - _other_ corners and edges are textured too, with mirror images of the Top, - Top Left, and Left textures. This would look silly on the "ruled notebook" - texture, but could be useful to emborder the level with a fancy texture. + 4. **Bordered:** same as Bounded but the right and bottom edges are decorated + using mirrors of the top and left textures. This would look silly on notebook + paper (having an extra red line and blank margin) but would work for + wrap-around textures like paper placemats. + 5. **Full Page:** special level type that treats the wallpaper image as a + literal full page scan to be drawn on top of. The level is bounded by the + literal dimensions of the wallpaper image which is drawn once instead of + cut up and tiled as per the usual behavior. * The game will come with a few built-in textures for levels to refer to by name. These textures don't need to be distributed with the map files themselves, as every copy of the game should include these (or a sensible fallback would @@ -264,6 +259,24 @@ Probably mostly DRM free. Will want some sort of account server early-on though. * The map author can also attach their own custom texture that will be included inside the map file. +### Default Wallpapers + +**notebook**: standard ruled notebook paper with a red line alone the Left +dge and a blank margin along the Top, with a Corner and the blue lines +aking up the Repeat in all directions. + +![notebook.png](../assets/wallpapers/notebook.png) + +**graph**: graph paper made up of a grid of light grey or blue lines. + +**dots**: graph paper made of dots at the intersections but not the lines in +between. + +**legal**: yellow lined notebook paper (legal pad). + +**placemat**: a placemat texture with a wavy outline that emborders the map +on all four sides. To be used with the Bordered level type. + # Text Console * Create a rudimentary dev console for entering text commands in-game. It diff --git a/balance/numbers.go b/balance/numbers.go index 2149fca..7305b8f 100644 --- a/balance/numbers.go +++ b/balance/numbers.go @@ -9,6 +9,15 @@ var ( // Speed to scroll a canvas with arrow keys in Edit Mode. CanvasScrollSpeed int32 = 8 + // Window scrolling behavior in Play Mode. + ScrollboxHoz = 64 // horizontal pixels close to canvas border + ScrollboxVert = 128 + ScrollMaxVelocity = 24 + + // Player speeds + PlayerMaxVelocity = 12 + Gravity = 2 + // Default chunk size for canvases. ChunkSize = 128 diff --git a/doodads/actor.go b/doodads/actor.go index 9be2e1b..15f2191 100644 --- a/doodads/actor.go +++ b/doodads/actor.go @@ -13,6 +13,7 @@ type Actor interface { // Position and velocity, not saved to disk. Position() render.Point Velocity() render.Point + SetVelocity(render.Point) Size() render.Rect Grounded() bool SetGrounded(bool) diff --git a/doodads/drawing.go b/doodads/drawing.go index c333ccf..35c5c63 100644 --- a/doodads/drawing.go +++ b/doodads/drawing.go @@ -44,6 +44,11 @@ func (d *Drawing) Velocity() render.Point { return d.velocity } +// SetVelocity to set the speed. +func (d *Drawing) SetVelocity(v render.Point) { + d.velocity = v +} + // Size returns the Drawing's size. func (d *Drawing) Size() render.Rect { return d.size diff --git a/doodads/player.go b/doodads/player.go deleted file mode 100644 index 0b63c1c..0000000 --- a/doodads/player.go +++ /dev/null @@ -1,81 +0,0 @@ -package doodads - -import ( - "git.kirsle.net/apps/doodle/render" -) - -// PlayerID is the Doodad ID for the player character. -const PlayerID = "PLAYER" - -// Player is a special doodad for the player character. -type Player struct { - point render.Point - velocity render.Point - size render.Rect - grounded bool -} - -// NewPlayer creates the special Player Character doodad. -func NewPlayer() *Player { - return &Player{ - point: render.Point{ - X: 100, - Y: 100, - }, - size: render.Rect{ - W: 32, - H: 32, - }, - } -} - -// ID of the Player singleton. -func (p *Player) ID() string { - return PlayerID -} - -// Position of the player. -func (p *Player) Position() render.Point { - return p.point -} - -// MoveBy a relative delta position. -func (p *Player) MoveBy(by render.Point) { - p.point.X += by.X - p.point.Y += by.Y -} - -// MoveTo an absolute position. -func (p *Player) MoveTo(to render.Point) { - p.point = to -} - -// Velocity returns the player's current velocity. -func (p *Player) Velocity() render.Point { - return p.velocity -} - -// Size returns the player's size. -func (p *Player) Size() render.Rect { - return p.size -} - -// Grounded returns if the player is grounded. -func (p *Player) Grounded() bool { - return p.grounded -} - -// SetGrounded sets if the player is grounded. -func (p *Player) SetGrounded(v bool) { - p.grounded = v -} - -// Draw the player sprite. -func (p *Player) Draw(e render.Engine) { - e.DrawBox(render.RGBA(255, 255, 153, 255), render.Rect{ - X: p.point.X, - Y: p.point.Y, - W: p.size.W, - H: p.size.H, - }) -} diff --git a/editor_scene.go b/editor_scene.go index 5281ee7..f0c646f 100644 --- a/editor_scene.go +++ b/editor_scene.go @@ -31,6 +31,11 @@ type EditorScene struct { Level *level.Level Doodad *doodads.Doodad + // Custom debug overlay labels. + debTool *string + debSwatch *string + debWorldIndex *string + // Last saved filename by the user. filename string } @@ -42,6 +47,16 @@ func (s *EditorScene) Name() string { // Setup the editor scene. func (s *EditorScene) Setup(d *Doodle) error { + // Debug overlay labels. + s.debTool = new(string) + s.debSwatch = new(string) + s.debWorldIndex = new(string) + customDebugLabels = []debugLabel{ + {"Pixel:", s.debWorldIndex}, + {"Tool:", s.debTool}, + {"Swatch:", s.debSwatch}, + } + // Initialize the user interface. It references the palette and such so it // must be initialized after those things. s.d = d @@ -107,6 +122,11 @@ func (s *EditorScene) Setup(d *Doodle) error { // Loop the editor scene. func (s *EditorScene) Loop(d *Doodle, ev *events.State) error { + // Update debug overlay labels. + *s.debTool = s.UI.Canvas.Tool.String() + *s.debSwatch = s.UI.Canvas.Palette.ActiveSwatch.Name + *s.debWorldIndex = s.UI.Canvas.WorldIndexAt(s.UI.cursor).String() + // Has the window been resized? if resized := ev.Resized.Read(); resized { w, h := d.Engine.WindowSize() @@ -262,6 +282,5 @@ func (s *EditorScene) SaveDoodad(filename string) error { // Destroy the scene. func (s *EditorScene) Destroy() error { - debugWorldIndex = render.Origin return nil } diff --git a/editor_ui.go b/editor_ui.go index 0e0d6b5..784649f 100644 --- a/editor_ui.go +++ b/editor_ui.go @@ -163,11 +163,10 @@ func (u *EditorUI) Loop(ev *events.State) error { // Update status bar labels. { - debugWorldIndex = u.Canvas.WorldIndexAt(u.cursor) u.StatusMouseText = fmt.Sprintf("Rel:(%d,%d) Abs:(%s)", ev.CursorX.Now, ev.CursorY.Now, - debugWorldIndex, + *u.Scene.debWorldIndex, ) u.StatusPaletteText = fmt.Sprintf("%s Tool", u.Canvas.Tool, diff --git a/fps.go b/fps.go index 5321331..57f2193 100644 --- a/fps.go +++ b/fps.go @@ -34,12 +34,15 @@ var ( fpsSkipped uint32 fpsInterval uint32 = 1000 - // XXX: some opt-in WorldIndex variables for the debug overlay. - // This is the world pixel that the mouse cursor is over, - // the Cursor + Scroll position of the canvas. - debugWorldIndex render.Point + // Custom labels for scenes to add to the debug overlay view. + customDebugLabels []debugLabel ) +type debugLabel struct { + key string + variable *string +} + // DrawDebugOverlay draws the debug FPS text on the SDL canvas. func (d *Doodle) DrawDebugOverlay() { if !DebugOverlay { @@ -51,19 +54,45 @@ func (d *Doodle) DrawDebugOverlay() { Yoffset int32 = 20 // leave room for the menu bar Xoffset int32 = 5 keys = []string{ - " FPS:", + "FPS:", "Scene:", - "Pixel:", "Mouse:", } values = []string{ fmt.Sprintf("%d (skip: %dms)", fpsCurrent, fpsSkipped), d.Scene.Name(), - debugWorldIndex.String(), fmt.Sprintf("%d,%d", d.event.CursorX.Now, d.event.CursorY.Now), } ) + // Insert custom keys. + for _, custom := range customDebugLabels { + keys = append(keys, custom.key) + if custom.variable == nil { + values = append(values, "") + } else if len(*custom.variable) == 0 { + values = append(values, `""`) + } else { + values = append(values, *custom.variable) + } + } + + // Find the longest key. + var longest int + for _, key := range keys { + if len(key) > longest { + longest = len(key) + } + } + + // Space pad the keys to align them. + for i, key := range keys { + if len(key) < longest { + key = strings.Repeat(" ", longest-len(key)) + key + keys[i] = key + } + } + key := ui.NewLabel(ui.Label{ Text: strings.Join(keys, "\n"), Font: render.Text{ diff --git a/level/page_type.go b/level/page_type.go index 668c0a6..870f82c 100644 --- a/level/page_type.go +++ b/level/page_type.go @@ -28,5 +28,10 @@ const ( // - The wallpaper hoz mirrors Left along the X=Width plane // - The wallpaper vert mirrors Top along the Y=Width plane // - The wallpaper 180 rotates the Corner for opposite corners - Bordered + Bordered // TODO: to be implemented + + // FullPage treats the wallpaper image as a literal full scan of a page. + // - The level boundaries are fixed to the wallpaper image's dimensions. + // - Used to e.g. scan in real letterhead paper and draw a map on it. + FullPage // TODO: to be implemented ) diff --git a/play_scene.go b/play_scene.go index 1c62022..bf6546c 100644 --- a/play_scene.go +++ b/play_scene.go @@ -2,6 +2,7 @@ package doodle import ( "fmt" + "math" "git.kirsle.net/apps/doodle/balance" "git.kirsle.net/apps/doodle/doodads" @@ -22,6 +23,12 @@ type PlayScene struct { d *Doodle drawing *uix.Canvas + // Custom debug labels. + debPosition *string + debViewport *string + debScroll *string + debWorldIndex *string + // Player character Player *uix.Actor } @@ -34,6 +41,20 @@ func (s *PlayScene) Name() string { // Setup the play scene. func (s *PlayScene) Setup(d *Doodle) error { s.d = d + + // Initialize debug bound variables. + s.debPosition = new(string) + s.debViewport = new(string) + s.debScroll = new(string) + s.debWorldIndex = new(string) + customDebugLabels = []debugLabel{ + {"Pixel:", s.debWorldIndex}, + {"Player:", s.debPosition}, + {"Viewport:", s.debViewport}, + {"Scroll:", s.debScroll}, + } + + // Initialize the drawing canvas. s.drawing = uix.NewCanvas(balance.ChunkSize, false) s.drawing.MoveTo(render.Origin) s.drawing.Resize(render.NewRect(int32(d.width), int32(d.height))) @@ -49,15 +70,19 @@ func (s *PlayScene) Setup(d *Doodle) error { s.LoadLevel(s.Filename) } - player := dummy.NewPlayer() - s.Player = uix.NewActor(player.ID(), &level.Actor{}, player.Doodad) - if s.Level == nil { log.Debug("PlayScene.Setup: no grid given, initializing empty grid") s.Level = level.New() s.drawing.LoadLevel(d.Engine, s.Level) + s.drawing.InstallActors(s.Level.Actors) } + player := dummy.NewPlayer() + s.Player = uix.NewActor(player.ID(), &level.Actor{}, player.Doodad) + s.Player.MoveTo(render.NewPoint(128, 128)) + s.drawing.AddActor(s.Player) + s.drawing.FollowActor = s.Player.ID() + d.Flash("Entered Play Mode. Press 'E' to edit this map.") return nil @@ -65,6 +90,12 @@ func (s *PlayScene) Setup(d *Doodle) error { // Loop the editor scene. func (s *PlayScene) Loop(d *Doodle, ev *events.State) error { + // Update debug overlay variables. + *s.debWorldIndex = s.drawing.WorldIndexAt(render.NewPoint(ev.CursorX.Now, ev.CursorY.Now)).String() + *s.debPosition = s.Player.Position().String() + *s.debViewport = s.drawing.Viewport().String() + *s.debScroll = s.drawing.Scroll.String() + // Has the window been resized? if resized := ev.Resized.Read(); resized { w, h := d.Engine.WindowSize() @@ -86,8 +117,11 @@ func (s *PlayScene) Loop(d *Doodle, ev *events.State) error { return nil } - s.drawing.Loop(ev) s.movePlayer(ev) + if err := s.drawing.Loop(ev); err != nil { + log.Error("Drawing Loop: %s", err) + } + return nil } @@ -118,20 +152,22 @@ func (s *PlayScene) Draw(d *Doodle) error { // movePlayer updates the player's X,Y coordinate based on key pressed. func (s *PlayScene) movePlayer(ev *events.State) { delta := s.Player.Position() - var playerSpeed int32 = 8 - var gravity int32 = 2 + var playerSpeed = int32(balance.PlayerMaxVelocity) + var gravity = int32(balance.Gravity) + + var velocity render.Point if ev.Down.Now { - delta.Y += playerSpeed + velocity.Y = playerSpeed } if ev.Left.Now { - delta.X -= playerSpeed + velocity.X = -playerSpeed } if ev.Right.Now { - delta.X += playerSpeed + velocity.X = playerSpeed } if ev.Up.Now { - delta.Y -= playerSpeed + velocity.Y = -playerSpeed } // Apply gravity. @@ -141,16 +177,24 @@ func (s *PlayScene) movePlayer(ev *events.State) { if ok { // Collision happened with world. } - delta = info.MoveTo + _ = info.MoveTo // Apply gravity if not grounded. if !s.Player.Grounded() { // Gravity has to pipe through the collision checker, too, so it // can't give us a cheated downward boost. - delta.Y += gravity + velocity.Y += gravity } - s.Player.MoveTo(delta) + // Cap the max speed. + if int(math.Abs(float64(velocity.X))) > balance.PlayerMaxVelocity { + velocity.X = int32(balance.PlayerMaxVelocity) + } + if int(math.Abs(float64(velocity.Y))) > balance.PlayerMaxVelocity { + velocity.Y = int32(balance.PlayerMaxVelocity) + } + + s.Player.SetVelocity(velocity) } // LoadLevel loads a level from disk. @@ -165,7 +209,6 @@ func (s *PlayScene) LoadLevel(filename string) error { s.Level = level s.drawing.LoadLevel(s.d.Engine, s.Level) s.drawing.InstallActors(s.Level.Actors) - s.drawing.AddActor(s.Player) return nil } diff --git a/scene.go b/scene.go index 1c04c43..3220661 100644 --- a/scene.go +++ b/scene.go @@ -20,6 +20,9 @@ type Scene interface { // Goto a scene. First it unloads the current scene. func (d *Doodle) Goto(scene Scene) error { + // Reset any custom debug overlay entries. + customDebugLabels = []debugLabel{} + // Teardown existing scene. if d.Scene != nil { d.Scene.Destroy() diff --git a/uix/canvas.go b/uix/canvas.go index 9413a34..430bb47 100644 --- a/uix/canvas.go +++ b/uix/canvas.go @@ -9,7 +9,6 @@ import ( "git.kirsle.net/apps/doodle/doodads" "git.kirsle.net/apps/doodle/events" "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/pkg/userdir" "git.kirsle.net/apps/doodle/pkg/wallpaper" "git.kirsle.net/apps/doodle/render" "git.kirsle.net/apps/doodle/ui" @@ -34,6 +33,9 @@ type Canvas struct { // to remove the mask. MaskColor render.Color + // Actor ID to follow the camera on automatically, i.e. the main player. + FollowActor string + // Debug tools // NoLimitScroll suppresses the scroll limit for bounded levels. NoLimitScroll bool @@ -134,29 +136,6 @@ func (w *Canvas) LoadDoodad(d *doodads.Doodad) { w.Load(d.Palette, d.Layers[0].Chunker) } -// InstallActors adds external Actors to the canvas to be superimposed on top -// of the drawing. -func (w *Canvas) InstallActors(actors level.ActorMap) error { - w.actors = make([]*Actor, 0) - for id, actor := range actors { - log.Info("InstallActors: %s", id) - - doodad, err := doodads.LoadJSON(userdir.DoodadPath(actor.Filename)) - if err != nil { - return fmt.Errorf("InstallActors: %s", err) - } - - w.actors = append(w.actors, NewActor(id, actor, doodad)) - } - return nil -} - -// AddActor injects additional actors into the canvas, such as a Player doodad. -func (w *Canvas) AddActor(actor *Actor) error { - w.actors = append(w.actors, actor) - return nil -} - // SetSwatch changes the currently selected swatch for editing. func (w *Canvas) SetSwatch(s *level.Swatch) { w.Palette.ActiveSwatch = s @@ -177,21 +156,54 @@ func (w *Canvas) setup() { // Loop is called on the scene's event loop to handle mouse interaction with // the canvas, i.e. to edit it. func (w *Canvas) Loop(ev *events.State) error { - if w.Scrollable { - // Arrow keys to scroll the view. - scrollBy := render.Point{} - if ev.Right.Now { - scrollBy.X -= balance.CanvasScrollSpeed - } else if ev.Left.Now { - scrollBy.X += balance.CanvasScrollSpeed - } - if ev.Down.Now { - scrollBy.Y -= balance.CanvasScrollSpeed - } else if ev.Up.Now { - scrollBy.Y += balance.CanvasScrollSpeed - } - if !scrollBy.IsZero() { - w.ScrollBy(scrollBy) + // Process the arrow keys scrolling the level in Edit Mode. + // canvas_scrolling.go + w.loopEditorScroll(ev) + if err := w.loopFollowActor(ev); err != nil { + log.Error("Follow actor: %s", err) // not fatal but nice to know + } + w.loopConstrainScroll() + + // Move any actors. + for _, a := range w.actors { + if v := a.Velocity(); v != render.Origin { + // orig := a.Drawing.Position() + a.MoveBy(v) + + // Keep them contained inside the level. + if w.wallpaper.pageType > level.Unbounded { + var ( + orig = w.WorldIndexAt(a.Drawing.Position()) + moveBy render.Point + size = a.Canvas.Size() + ) + + // Bound it on the top left edges. + if orig.X < 0 { + moveBy.X = -orig.X + } + if orig.Y < 0 { + moveBy.Y = -orig.Y + } + + // Bound it on the right bottom edges. XXX: downcast from int64! + if w.wallpaper.maxWidth > 0 { + if int64(orig.X+size.W) > w.wallpaper.maxWidth { + var delta = int32(w.wallpaper.maxWidth - int64(orig.X+size.W)) + moveBy.X = delta + } + } + if w.wallpaper.maxHeight > 0 { + if int64(orig.Y+size.H) > w.wallpaper.maxHeight { + var delta = int32(w.wallpaper.maxHeight - int64(orig.Y+size.H)) + moveBy.Y = delta + } + } + + if !moveBy.IsZero() { + a.MoveBy(moveBy) + } + } } } @@ -275,273 +287,3 @@ func (w *Canvas) ScrollBy(by render.Point) { func (w *Canvas) Compute(e render.Engine) { } - -// Present the canvas. -func (w *Canvas) Present(e render.Engine, p render.Point) { - var ( - S = w.Size() - Viewport = w.Viewport() - ) - // w.MoveTo(p) // TODO: when uncommented the canvas will creep down the Workspace frame in EditorMode - w.DrawBox(e, p) - e.DrawBox(w.Background(), render.Rect{ - X: p.X + w.BoxThickness(1), - Y: p.Y + w.BoxThickness(1), - W: S.W - w.BoxThickness(2), - H: S.H - w.BoxThickness(2), - }) - - // Constrain the scroll view if the level is bounded. - if w.Scrollable && !w.NoLimitScroll { - // Constrain the top and left edges. - if w.wallpaper.pageType > level.Unbounded { - if w.Scroll.X > 0 { - w.Scroll.X = 0 - } - if w.Scroll.Y > 0 { - w.Scroll.Y = 0 - } - } - - // Constrain the bottom and right for limited world sizes. - if w.wallpaper.maxWidth > 0 && w.wallpaper.maxHeight > 0 { - var ( - // TODO: downcast from int64! - mw = int32(w.wallpaper.maxWidth) - mh = int32(w.wallpaper.maxHeight) - ) - if Viewport.W > mw { - delta := Viewport.W - mw - w.Scroll.X += delta - } - if Viewport.H > mh { - delta := Viewport.H - mh - w.Scroll.Y += delta - } - } - } - - // Draw the wallpaper. - if w.wallpaper.Valid() { - err := w.PresentWallpaper(e, p) - if err != nil { - log.Error(err.Error()) - } - } - - // Get the chunks in the viewport and cache their textures. - for coord := range w.chunks.IterViewportChunks(Viewport) { - if chunk, ok := w.chunks.GetChunk(coord); ok { - var tex render.Texturer - if w.MaskColor != render.Invisible { - tex = chunk.TextureMasked(e, w.MaskColor) - } else { - tex = chunk.Texture(e) - } - src := render.Rect{ - W: tex.Size().W, - H: tex.Size().H, - } - - // If the source bitmap is already bigger than the Canvas widget - // into which it will render, cap the source width and height. - // This is especially useful for Doodad buttons because the drawing - // is bigger than the button. - if src.W > S.W { - src.W = S.W - } - if src.H > S.H { - src.H = S.H - } - - dst := render.Rect{ - X: p.X + w.Scroll.X + w.BoxThickness(1) + (coord.X * int32(chunk.Size)), - Y: p.Y + w.Scroll.Y + w.BoxThickness(1) + (coord.Y * int32(chunk.Size)), - - // src.W and src.H will be AT MOST the full width and height of - // a Canvas widget. Subtract the scroll offset to keep it bounded - // visually on its right and bottom sides. - W: src.W, - H: src.H, - } - - // TODO: all this shit is in TrimBox(), make it DRY - - // 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 - w.BoxThickness(1)) - (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 - w.BoxThickness(1)) - (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 + w.BoxThickness(1) - dst.W -= delta - src.X += delta - } - if dst.Y < p.Y { - delta := p.Y - dst.Y - dst.Y = p.Y + w.BoxThickness(1) - dst.H -= delta - src.Y += delta - } - - // Trim the destination width so it doesn't overlap the Canvas border. - if dst.W >= S.W-w.BoxThickness(1) { - dst.W = S.W - w.BoxThickness(1) - } - - e.Copy(tex, src, dst) - } - } - - w.drawActors(e, p) - - // XXX: Debug, show label in canvas corner. - if balance.DebugCanvasLabel { - rows := []string{ - w.Name, - - // XXX: debug options, uncomment for more details - - // Size of the canvas - // fmt.Sprintf("S=%d,%d", S.W, S.H), - - // Viewport of the canvas - // fmt.Sprintf("V=%d,%d:%d,%d", - // Viewport.X, Viewport.Y, - // Viewport.W, Viewport.H, - // ), - } - if w.actor != nil { - rows = append(rows, - fmt.Sprintf("WP=%s", w.actor.Point), - ) - } - label := ui.NewLabel(ui.Label{ - Text: strings.Join(rows, "\n"), - Font: render.Text{ - FontFilename: balance.ShellFontFilename, - Size: balance.ShellFontSizeSmall, - Color: render.White, - }, - }) - label.SetBackground(render.RGBA(0, 0, 50, 150)) - label.Compute(e) - label.Present(e, render.Point{ - X: p.X + S.W - label.Size().W - w.BoxThickness(1), - Y: p.Y + w.BoxThickness(1), - }) - } -} - -// drawActors superimposes the actors on top of the drawing. -func (w *Canvas) drawActors(e render.Engine, p render.Point) { - var ( - Viewport = w.ViewportRelative() - S = w.Size() - ) - - // See if each Actor is in range of the Viewport. - for _, a := range w.actors { - var ( - actor = a.Actor // Static Actor instance from Level file, DO NOT CHANGE - can = a.Canvas // Canvas widget that draws the actor - actorPoint = actor.Point // XXX TODO: DO NOT CHANGE - actorSize = can.Size() - ) - - // Create a box of World Coordinates that this actor occupies. The - // Actor X,Y from level data is already a World Coordinate; - // accomodate for the size of the Actor. - actorBox := render.Rect{ - X: actorPoint.X, - Y: actorPoint.Y, - W: actorSize.W, - H: actorSize.H, - } - - // Is any part of the actor visible? - if !Viewport.Intersects(actorBox) { - continue // not visible on screen - } - - drawAt := render.Point{ - X: p.X + w.Scroll.X + actorPoint.X + w.BoxThickness(1), - Y: p.Y + w.Scroll.Y + actorPoint.Y + w.BoxThickness(1), - } - resizeTo := actorSize - - // XXX TODO: when an Actor hits the left or top edge and shrinks, - // scrolling to offset that shrink is currently hard to solve. - scrollTo := render.Origin - - // Handle cropping and scaling if this Actor's canvas can't be - // completely visible within the parent. - if drawAt.X+resizeTo.W > p.X+S.W { - // Hitting the right edge, shrunk the width now. - delta := (drawAt.X + resizeTo.W) - (p.X + S.W) - resizeTo.W -= delta - } else if drawAt.X < p.X { - // Hitting the left edge. Cap the X coord and shrink the width. - delta := p.X - drawAt.X // positive number - drawAt.X = p.X - // scrollTo.X -= delta // TODO - resizeTo.W -= delta - } - - if drawAt.Y+resizeTo.H > p.Y+S.H { - // Hitting the bottom edge, shrink the height. - delta := (drawAt.Y + resizeTo.H) - (p.Y + S.H) - resizeTo.H -= delta - } else if drawAt.Y < p.Y { - // Hitting the top edge. Cap the Y coord and shrink the height. - delta := p.Y - drawAt.Y - drawAt.Y = p.Y - // scrollTo.Y -= delta // TODO - resizeTo.H -= delta - } - - if resizeTo != actorSize { - can.Resize(resizeTo) - can.ScrollTo(scrollTo) - } - can.Present(e, drawAt) - - // Clean up the canvas size and offset. - can.Resize(actorSize) // restore original size in case cropped - can.ScrollTo(render.Origin) - } -} diff --git a/uix/canvas_actors.go b/uix/canvas_actors.go new file mode 100644 index 0000000..457d207 --- /dev/null +++ b/uix/canvas_actors.go @@ -0,0 +1,115 @@ +package uix + +import ( + "fmt" + + "git.kirsle.net/apps/doodle/doodads" + "git.kirsle.net/apps/doodle/level" + "git.kirsle.net/apps/doodle/pkg/userdir" + "git.kirsle.net/apps/doodle/render" +) + +// InstallActors adds external Actors to the canvas to be superimposed on top +// of the drawing. +func (w *Canvas) InstallActors(actors level.ActorMap) error { + w.actors = make([]*Actor, 0) + for id, actor := range actors { + doodad, err := doodads.LoadJSON(userdir.DoodadPath(actor.Filename)) + if err != nil { + return fmt.Errorf("InstallActors: %s", err) + } + + w.actors = append(w.actors, NewActor(id, actor, doodad)) + } + return nil +} + +// AddActor injects additional actors into the canvas, such as a Player doodad. +func (w *Canvas) AddActor(actor *Actor) error { + w.actors = append(w.actors, actor) + return nil +} + +// drawActors is a subroutine of Present() that superimposes the actors on top +// of the level drawing. +func (w *Canvas) drawActors(e render.Engine, p render.Point) { + var ( + Viewport = w.ViewportRelative() + S = w.Size() + ) + + // See if each Actor is in range of the Viewport. + for i, a := range w.actors { + if a == nil { + log.Error("Canvas.drawActors: null actor at index %d (of %d actors)", i, len(w.actors)) + continue + } + var ( + actor = a.Actor // Static Actor instance from Level file, DO NOT CHANGE + can = a.Canvas // Canvas widget that draws the actor + actorPoint = actor.Point // XXX TODO: DO NOT CHANGE + actorSize = can.Size() + ) + + // Create a box of World Coordinates that this actor occupies. The + // Actor X,Y from level data is already a World Coordinate; + // accomodate for the size of the Actor. + actorBox := render.Rect{ + X: actorPoint.X, + Y: actorPoint.Y, + W: actorSize.W, + H: actorSize.H, + } + + // Is any part of the actor visible? + if !Viewport.Intersects(actorBox) { + continue // not visible on screen + } + + drawAt := render.Point{ + X: p.X + w.Scroll.X + actorPoint.X + w.BoxThickness(1), + Y: p.Y + w.Scroll.Y + actorPoint.Y + w.BoxThickness(1), + } + resizeTo := actorSize + + // XXX TODO: when an Actor hits the left or top edge and shrinks, + // scrolling to offset that shrink is currently hard to solve. + scrollTo := render.Origin + + // Handle cropping and scaling if this Actor's canvas can't be + // completely visible within the parent. + if drawAt.X+resizeTo.W > p.X+S.W { + // Hitting the right edge, shrunk the width now. + delta := (drawAt.X + resizeTo.W) - (p.X + S.W) + resizeTo.W -= delta + } else if drawAt.X < p.X { + // Hitting the left edge. Cap the X coord and shrink the width. + delta := p.X - drawAt.X // positive number + drawAt.X = p.X + // scrollTo.X -= delta // TODO + resizeTo.W -= delta + } + + if drawAt.Y+resizeTo.H > p.Y+S.H { + // Hitting the bottom edge, shrink the height. + delta := (drawAt.Y + resizeTo.H) - (p.Y + S.H) + resizeTo.H -= delta + } else if drawAt.Y < p.Y { + // Hitting the top edge. Cap the Y coord and shrink the height. + delta := p.Y - drawAt.Y + drawAt.Y = p.Y + // scrollTo.Y -= delta // TODO + resizeTo.H -= delta + } + + if resizeTo != actorSize { + can.Resize(resizeTo) + can.ScrollTo(scrollTo) + } + can.Present(e, drawAt) + + // Clean up the canvas size and offset. + can.Resize(actorSize) // restore original size in case cropped + can.ScrollTo(render.Origin) + } +} diff --git a/uix/canvas_present.go b/uix/canvas_present.go new file mode 100644 index 0000000..9e7dd38 --- /dev/null +++ b/uix/canvas_present.go @@ -0,0 +1,171 @@ +package uix + +import ( + "fmt" + "strings" + + "git.kirsle.net/apps/doodle/balance" + "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/ui" +) + +// Present the canvas. +func (w *Canvas) Present(e render.Engine, p render.Point) { + var ( + S = w.Size() + Viewport = w.Viewport() + ) + // w.MoveTo(p) // TODO: when uncommented the canvas will creep down the Workspace frame in EditorMode + w.DrawBox(e, p) + e.DrawBox(w.Background(), render.Rect{ + X: p.X + w.BoxThickness(1), + Y: p.Y + w.BoxThickness(1), + W: S.W - w.BoxThickness(2), + H: S.H - w.BoxThickness(2), + }) + + // Draw the wallpaper. + if w.wallpaper.Valid() { + err := w.PresentWallpaper(e, p) + if err != nil { + log.Error(err.Error()) + } + } + + // Get the chunks in the viewport and cache their textures. + for coord := range w.chunks.IterViewportChunks(Viewport) { + if chunk, ok := w.chunks.GetChunk(coord); ok { + var tex render.Texturer + if w.MaskColor != render.Invisible { + tex = chunk.TextureMasked(e, w.MaskColor) + } else { + tex = chunk.Texture(e) + } + src := render.Rect{ + W: tex.Size().W, + H: tex.Size().H, + } + + // If the source bitmap is already bigger than the Canvas widget + // into which it will render, cap the source width and height. + // This is especially useful for Doodad buttons because the drawing + // is bigger than the button. + if src.W > S.W { + src.W = S.W + } + if src.H > S.H { + src.H = S.H + } + + dst := render.Rect{ + X: p.X + w.Scroll.X + w.BoxThickness(1) + (coord.X * int32(chunk.Size)), + Y: p.Y + w.Scroll.Y + w.BoxThickness(1) + (coord.Y * int32(chunk.Size)), + + // src.W and src.H will be AT MOST the full width and height of + // a Canvas widget. Subtract the scroll offset to keep it bounded + // visually on its right and bottom sides. + W: src.W, + H: src.H, + } + + // TODO: all this shit is in TrimBox(), make it DRY + + // 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 - w.BoxThickness(1)) - (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 - w.BoxThickness(1)) - (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 + w.BoxThickness(1) + dst.W -= delta + src.X += delta + } + if dst.Y < p.Y { + delta := p.Y - dst.Y + dst.Y = p.Y + w.BoxThickness(1) + dst.H -= delta + src.Y += delta + } + + // Trim the destination width so it doesn't overlap the Canvas border. + if dst.W >= S.W-w.BoxThickness(1) { + dst.W = S.W - w.BoxThickness(1) + } + + e.Copy(tex, src, dst) + } + } + + w.drawActors(e, p) + + // XXX: Debug, show label in canvas corner. + if balance.DebugCanvasLabel { + rows := []string{ + w.Name, + + // XXX: debug options, uncomment for more details + + // Size of the canvas + // fmt.Sprintf("S=%d,%d", S.W, S.H), + + // Viewport of the canvas + // fmt.Sprintf("V=%d,%d:%d,%d", + // Viewport.X, Viewport.Y, + // Viewport.W, Viewport.H, + // ), + } + if w.actor != nil { + rows = append(rows, + fmt.Sprintf("WP=%s", w.actor.Point), + ) + } + label := ui.NewLabel(ui.Label{ + Text: strings.Join(rows, "\n"), + Font: render.Text{ + FontFilename: balance.ShellFontFilename, + Size: balance.ShellFontSizeSmall, + Color: render.White, + }, + }) + label.SetBackground(render.RGBA(0, 0, 50, 150)) + label.Compute(e) + label.Present(e, render.Point{ + X: p.X + S.W - label.Size().W - w.BoxThickness(1), + Y: p.Y + w.BoxThickness(1), + }) + } +} diff --git a/uix/canvas_scrolling.go b/uix/canvas_scrolling.go new file mode 100644 index 0000000..3c5f506 --- /dev/null +++ b/uix/canvas_scrolling.go @@ -0,0 +1,187 @@ +package uix + +import ( + "errors" + "fmt" + + "git.kirsle.net/apps/doodle/balance" + "git.kirsle.net/apps/doodle/events" + "git.kirsle.net/apps/doodle/level" + "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/ui" +) + +/* +Loop() subroutine to scroll the canvas using arrow keys (for edit mode). + +If w.Scrollable is false this function won't do anything. + +Cursor keys will scroll the drawing by balance.CanvasScrollSpeed per tick. +If the level pageType is constrained, the scrollable viewport will be +constrained to fit the bounds of the level. + +The debug boolean `NoLimitScroll=true` will override the bounded level scroll +restriction and allow scrolling into out-of-bounds areas of the level. +*/ +func (w *Canvas) loopEditorScroll(ev *events.State) error { + if !w.Scrollable { + return errors.New("canvas not scrollable") + } + + // Arrow keys to scroll the view. + scrollBy := render.Point{} + if ev.Right.Now { + scrollBy.X -= balance.CanvasScrollSpeed + } else if ev.Left.Now { + scrollBy.X += balance.CanvasScrollSpeed + } + if ev.Down.Now { + scrollBy.Y -= balance.CanvasScrollSpeed + } else if ev.Up.Now { + scrollBy.Y += balance.CanvasScrollSpeed + } + if !scrollBy.IsZero() { + w.ScrollBy(scrollBy) + } + + return nil +} + +/* +Loop() subroutine to constrain the scrolled view to within a bounded level. +*/ +func (w *Canvas) loopConstrainScroll() error { + if w.NoLimitScroll { + return errors.New("NoLimitScroll enabled") + } + + var capped bool + + // Constrain the top and left edges. + if w.wallpaper.pageType > level.Unbounded { + if w.Scroll.X > 0 { + w.Scroll.X = 0 + capped = true + } + if w.Scroll.Y > 0 { + w.Scroll.Y = 0 + capped = true + } + } + + // Constrain the bottom and right for limited world sizes. + if w.wallpaper.maxWidth+w.wallpaper.maxHeight > 0 { + var ( + // TODO: downcast from int64! + mw = int32(w.wallpaper.maxWidth) + mh = int32(w.wallpaper.maxHeight) + Viewport = w.Viewport() + ) + if Viewport.W > mw { + delta := Viewport.W - mw + w.Scroll.X += delta + capped = true + } + if Viewport.H > mh { + delta := Viewport.H - mh + w.Scroll.Y += delta + capped = true + } + } + + if capped { + return errors.New("scroll limited by level constraint") + } + + return nil +} + +/* +Loop() subroutine for Play Mode to follow an actor in the camera's view. + +Does nothing if w.FollowActor is an empty string. Set it to the ID of an Actor +to follow. If the actor exists, the Canvas will scroll to keep it on the +screen. +*/ +func (w *Canvas) loopFollowActor(ev *events.State) error { + // Are we following an actor? + if w.FollowActor == "" { + return nil + } + + var ( + P = w.Point() + S = w.Size() + ) + + // Find the actor. + for _, actor := range w.actors { + if actor.ID() != w.FollowActor { + continue + } + + actor.Canvas.SetBorderSize(2) + actor.Canvas.SetBorderColor(render.Yellow) + actor.Canvas.SetBorderStyle(ui.BorderSolid) + + var ( + APosition = actor.Position() // relative to screen + APoint = actor.Drawing.Position() + ASize = actor.Canvas.Size() + scrollBy render.Point + ) + + // Scroll left + if APosition.X-P.X <= int32(balance.ScrollboxHoz) { + var delta = APoint.X - P.X + if delta > int32(balance.ScrollMaxVelocity) { + delta = int32(balance.ScrollMaxVelocity) + } + + if delta < 0 { + // constrain in case they're FAR OFF SCREEN so we don't flip back around + delta = -delta + } + scrollBy.X = delta + } + + // Scroll right + if APosition.X >= S.W-ASize.W-int32(balance.ScrollboxHoz) { + var delta = S.W - ASize.W - int32(balance.ScrollboxHoz) + if delta > int32(balance.ScrollMaxVelocity) { + delta = int32(balance.ScrollMaxVelocity) + } + scrollBy.X = -delta + } + + // Scroll up + if APosition.Y-P.Y <= int32(balance.ScrollboxVert) { + var delta = APoint.Y - P.Y + if delta > int32(balance.ScrollMaxVelocity) { + delta = int32(balance.ScrollMaxVelocity) + } + + if delta < 0 { + delta = -delta + } + scrollBy.Y = delta + } + + // Scroll down + if APosition.Y >= S.H-ASize.H-int32(balance.ScrollboxVert) { + var delta = S.H - ASize.H - int32(balance.ScrollboxVert) + if delta > int32(balance.ScrollMaxVelocity) { + delta = int32(balance.ScrollMaxVelocity) + } + scrollBy.Y = -delta + } + + if scrollBy != render.Origin { + w.ScrollBy(scrollBy) + } + + return nil + } + + return fmt.Errorf("actor ID '%s' not found in level", w.FollowActor) +} -- 2.30.2 From b58976527a0899ec7e25c12351df55307f556fe6 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sun, 30 Dec 2018 13:50:24 -0800 Subject: [PATCH 3/5] Add test wallpaper and minor code tweaks --- assets/wallpapers/test-128x128.png | Bin 0 -> 375 bytes balance/debug.go | 10 +++++----- balance/numbers.go | 5 +++-- commands.go | 11 +++++++++++ doodads/actor.go | 2 ++ doodads/collision.go | 23 +++++++++++++++-------- doodads/drawing.go | 11 +++++++++++ doodle.go | 14 ++++++++------ fps.go | 10 ++++++++-- pkg/wallpaper/wallpaper_test.go | 2 +- play_scene.go | 2 +- render/color.go | 27 +++++++++++++++++++-------- render/interface.go | 14 +++++++++++++- render/point.go | 11 ++++++++++- render/sdl/fps.go | 22 ---------------------- ui/theme/theme.go | 2 +- uix/canvas_scrolling.go | 2 +- 17 files changed, 109 insertions(+), 59 deletions(-) create mode 100644 assets/wallpapers/test-128x128.png delete mode 100644 render/sdl/fps.go diff --git a/assets/wallpapers/test-128x128.png b/assets/wallpapers/test-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..736302d2ad79b8780d96a4a1cd77ed80463cb6f2 GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1SEZ8zRh7^V6^jeaSW-L^XAS)&I1NKM;(@z z{GWQ;kWct7i+;zSUw_lKZ~nvBFITXeDS`C>SA!^nHbWT08iokQ4fGdybLNfRf&JCB k_6-B*2)N(>0mJbB|HiK@|7}b% 0 { // make sure it won't roll under - delay = uint32(TargetFPS - int(tmp)) + if !fpsDoNotCap { + elapsed := time.Now().Sub(start) + tmp := elapsed / time.Millisecond + if TargetFPS-int(tmp) > 0 { // make sure it won't roll under + delay = uint32(TargetFPS - int(tmp)) + } + d.Engine.Delay(delay) } - d.Engine.Delay(delay) // Track how long this frame took to measure FPS over time. d.TrackFPS(delay) diff --git a/fps.go b/fps.go index 57f2193..4de911a 100644 --- a/fps.go +++ b/fps.go @@ -33,6 +33,7 @@ var ( fpsFrames int fpsSkipped uint32 fpsInterval uint32 = 1000 + fpsDoNotCap bool // remove the FPS delay cap in Main Loop // Custom labels for scenes to add to the debug overlay view. customDebugLabels []debugLabel @@ -49,17 +50,22 @@ func (d *Doodle) DrawDebugOverlay() { return } + var framesSkipped = fmt.Sprintf("(skip: %dms)", fpsSkipped) + if fpsDoNotCap { + framesSkipped = "uncapped" + } + var ( darken = balance.DebugStrokeDarken Yoffset int32 = 20 // leave room for the menu bar - Xoffset int32 = 5 + Xoffset int32 = 20 keys = []string{ "FPS:", "Scene:", "Mouse:", } values = []string{ - fmt.Sprintf("%d (skip: %dms)", fpsCurrent, fpsSkipped), + fmt.Sprintf("%d %s", fpsCurrent, framesSkipped), d.Scene.Name(), fmt.Sprintf("%d,%d", d.event.CursorX.Now, d.event.CursorY.Now), } diff --git a/pkg/wallpaper/wallpaper_test.go b/pkg/wallpaper/wallpaper_test.go index 72d3c1e..4efcecf 100644 --- a/pkg/wallpaper/wallpaper_test.go +++ b/pkg/wallpaper/wallpaper_test.go @@ -28,7 +28,7 @@ func TestWallpaper(t *testing.T) { img := image.NewRGBA(image.Rect(0, 0, width, height)) draw.Draw( // Corner: red - img, // dst Image + img, // dst Image image.Rect(0, 0, qWidth, qHeight), // r Rectangle image.NewUniform(red), // src Image image.Point{0, 0}, // sp Point diff --git a/play_scene.go b/play_scene.go index bf6546c..c1cf8bb 100644 --- a/play_scene.go +++ b/play_scene.go @@ -173,7 +173,7 @@ func (s *PlayScene) movePlayer(ev *events.State) { // Apply gravity. // var onFloor bool - info, ok := doodads.CollidesWithGrid(s.Player, s.Level.Chunker, delta) + info, ok := doodads.CollidesWithGrid(s.Player, s.Level.Chunker, delta, s.drawing.Scroll) if ok { // Collision happened with world. } diff --git a/render/color.go b/render/color.go index c16cda2..f953e49 100644 --- a/render/color.go +++ b/render/color.go @@ -156,15 +156,15 @@ func (c *Color) UnmarshalJSON(b []byte) error { } // Add a relative color value to the color. -func (c Color) Add(r, g, b, a int32) Color { +func (c Color) Add(r, g, b, a int) Color { var ( - R = int32(c.Red) + r - G = int32(c.Green) + g - B = int32(c.Blue) + b - A = int32(c.Alpha) + a + R = int(c.Red) + r + G = int(c.Green) + g + B = int(c.Blue) + b + A = int(c.Alpha) + a ) - cap8 := func(v int32) uint8 { + cap8 := func(v int) uint8 { if v > 255 { v = 255 } else if v < 0 { @@ -182,11 +182,22 @@ func (c Color) Add(r, g, b, a int32) Color { } // Lighten a color value. -func (c Color) Lighten(v int32) Color { +func (c Color) Lighten(v int) Color { return c.Add(v, v, v, 0) } // Darken a color value. -func (c Color) Darken(v int32) Color { +func (c Color) Darken(v int) Color { return c.Add(-v, -v, -v, 0) } + +// Transparentize adjusts the alpha level of a color. +func (c Color) Transparentize(v int) Color { + return c.Add(0, 0, 0, int(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/render/interface.go b/render/interface.go index 1a30ad9..a64d498 100644 --- a/render/interface.go +++ b/render/interface.go @@ -125,7 +125,8 @@ func (r Rect) Add(other Rect) Rect { } } -// Add a point to move the rect. +// Add (or subtract) a point to move the rect. This is usually the method you +// want to use: negative Point values will subtract the rect's position. func (r Rect) AddPoint(other Point) Rect { return Rect{ X: r.X + other.X, @@ -135,6 +136,17 @@ func (r Rect) AddPoint(other Point) Rect { } } +// SubtractPoint is the inverse of AddPoint. Use this only if you need to +// invert the Point being added. +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 diff --git a/render/point.go b/render/point.go index 272238c..49f8576 100644 --- a/render/point.go +++ b/render/point.go @@ -69,12 +69,21 @@ func (p Point) Inside(r Rect) bool { (p.Y >= y1 && p.Y <= y2)) } -// Add (or subtract) the other point to your current point. +// Add (or subtract) the other point to your current point. This is usually +// the one you want: if the other Point has negative values it will subtract +// them from this Point, or if they are positive it will add them. func (p *Point) Add(other Point) { p.X += other.X p.Y += other.Y } +// Subtract is the inverse of Add. Use this if you want to force a subtraction +// operation (i.e. to invert a Point before adding it). +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) { diff --git a/render/sdl/fps.go b/render/sdl/fps.go deleted file mode 100644 index 4c625c9..0000000 --- a/render/sdl/fps.go +++ /dev/null @@ -1,22 +0,0 @@ -package sdl - -import ( - "git.kirsle.net/apps/doodle/level" -) - -// Frames to cache for FPS calculation. -const ( - maxSamples = 100 - TargetFPS = 1000 / 60 -) - -var ( - fpsCurrentTicks uint32 // current time we get sdl.GetTicks() - fpsLastTime uint32 // last time we printed the fpsCurrentTicks - fpsCurrent int - fpsFrames int - fpsSkipped uint32 - fpsInterval uint32 = 1000 -) - -var pixelHistory []level.Pixel diff --git a/ui/theme/theme.go b/ui/theme/theme.go index 23c3186..1994128 100644 --- a/ui/theme/theme.go +++ b/ui/theme/theme.go @@ -8,5 +8,5 @@ var ( ButtonHoverColor = render.RGBA(200, 255, 255, 255) ButtonOutlineColor = render.Black - BorderColorOffset int32 = 40 + BorderColorOffset = 40 ) diff --git a/uix/canvas_scrolling.go b/uix/canvas_scrolling.go index 3c5f506..7c13aff 100644 --- a/uix/canvas_scrolling.go +++ b/uix/canvas_scrolling.go @@ -127,7 +127,7 @@ func (w *Canvas) loopFollowActor(ev *events.State) error { var ( APosition = actor.Position() // relative to screen APoint = actor.Drawing.Position() - ASize = actor.Canvas.Size() + ASize = actor.Drawing.Size() scrollBy render.Point ) -- 2.30.2 From a316bafb124604e9b4616bf008c4b1c0cc885adc Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sun, 30 Dec 2018 14:22:50 -0800 Subject: [PATCH 4/5] Reorganize the package layout Move all Doodle source code into the src/ subpackage and move the publicly shareable stuff into lib/, for example lib/ui and lib/render. This cleans up the git root and helps make the Doodle UI library more easily publishable as a separate open source project. Currently both lib/ui and lib/render import one or two things from doodle/src that need to be broken apart. --- cmd/doodad/commands/convert.go | 2 +- cmd/doodle/main.go | 6 +++--- {render => lib/render}/color.go | 0 {render => lib/render}/functions.go | 0 {render => lib/render}/interface.go | 2 +- {render => lib/render}/log.go | 0 {render => lib/render}/point.go | 0 {render => lib/render}/point_test.go | 2 +- {render => lib/render}/rect_test.go | 2 +- {render => lib/render}/sdl/canvas.go | 2 +- {render => lib/render}/sdl/events.go | 2 +- {render => lib/render}/sdl/log.go | 0 {render => lib/render}/sdl/sdl.go | 4 ++-- {render => lib/render}/sdl/text.go | 4 ++-- {render => lib/render}/sdl/texture.go | 2 +- {render => lib/render}/sdl/utils.go | 2 +- lib/ui/README.md | 8 ++++++++ {ui => lib/ui}/button.go | 4 ++-- {ui => lib/ui}/check_button.go | 4 ++-- {ui => lib/ui}/checkbox.go | 2 +- {ui => lib/ui}/debug.go | 0 {ui => lib/ui}/dragdrop.go | 0 {ui => lib/ui}/frame.go | 2 +- {ui => lib/ui}/frame_pack.go | 4 +++- {ui => lib/ui}/functions.go | 2 +- {ui => lib/ui}/image.go | 2 +- {ui => lib/ui}/label.go | 2 +- {ui => lib/ui}/log.go | 0 {ui => lib/ui}/supervisor.go | 4 ++-- {ui => lib/ui}/theme/theme.go | 2 +- {ui => lib/ui}/widget.go | 4 ++-- {ui => lib/ui}/window.go | 2 +- pkg/wallpaper/texture.go | 2 +- pkg/wallpaper/wallpaper.go | 2 +- {balance => src/balance}/README.md | 0 {balance => src/balance}/debug.go | 2 +- {balance => src/balance}/numbers.go | 0 {balance => src/balance}/shell.go | 2 +- {balance => src/balance}/theme.go | 4 ++-- commands.go => src/commands.go | 2 +- config.go => src/config.go | 0 {doodads => src/doodads}/actor.go | 4 ++-- {doodads => src/doodads}/collision.go | 4 ++-- {doodads => src/doodads}/doodad.go | 6 +++--- {doodads => src/doodads}/drawing.go | 2 +- {doodads => src/doodads}/dummy/dummy.go | 2 +- {doodads => src/doodads}/dummy/player.go | 2 +- {doodads => src/doodads}/json.go | 0 doodle.go => src/doodle.go | 8 ++++---- {draw => src/draw}/line.go | 2 +- {draw => src/draw}/line_test.go | 2 +- editor_scene.go => src/editor_scene.go | 10 +++++----- .../editor_scene_debug.go | 2 +- editor_ui.go => src/editor_ui.go | 16 ++++++++-------- editor_ui_doodad.go => src/editor_ui_doodad.go | 10 +++++----- editor_ui_palette.go => src/editor_ui_palette.go | 6 +++--- {enum => src/enum}/enum.go | 0 {events => src/events}/debug.go | 0 {events => src/events}/events.go | 0 {events => src/events}/log.go | 0 {events => src/events}/types.go | 0 fps.go => src/fps.go | 8 ++++---- guitest_scene.go => src/guitest_scene.go | 8 ++++---- {level => src/level}/actors.go | 2 +- {level => src/level}/base_test.go | 0 {level => src/level}/chunk.go | 4 ++-- {level => src/level}/chunk_map.go | 2 +- {level => src/level}/chunk_test.go | 2 +- {level => src/level}/chunker.go | 2 +- {level => src/level}/chunker_test.go | 2 +- {level => src/level}/filesystem.go | 0 {level => src/level}/json.go | 0 {level => src/level}/log.go | 0 {level => src/level}/page_type.go | 0 {level => src/level}/palette.go | 2 +- {level => src/level}/swatch.go | 2 +- {level => src/level}/types.go | 4 ++-- log.go => src/log.go | 0 main_scene.go => src/main_scene.go | 8 ++++---- play_scene.go => src/play_scene.go | 14 +++++++------- scene.go => src/scene.go | 4 +++- shell.go => src/shell.go | 8 ++++---- {uix => src/uix}/actor.go | 6 +++--- {uix => src/uix}/canvas.go | 12 ++++++------ {uix => src/uix}/canvas_actors.go | 6 +++--- {uix => src/uix}/canvas_editable.go | 8 ++++---- {uix => src/uix}/canvas_present.go | 6 +++--- {uix => src/uix}/canvas_scrolling.go | 10 +++++----- {uix => src/uix}/canvas_wallpaper.go | 4 ++-- {uix => src/uix}/draw_modes.go | 0 {uix => src/uix}/log.go | 0 91 files changed, 149 insertions(+), 137 deletions(-) rename {render => lib/render}/color.go (100%) rename {render => lib/render}/functions.go (100%) rename {render => lib/render}/interface.go (99%) rename {render => lib/render}/log.go (100%) rename {render => lib/render}/point.go (100%) rename {render => lib/render}/point_test.go (95%) rename {render => lib/render}/rect_test.go (96%) rename {render => lib/render}/sdl/canvas.go (97%) rename {render => lib/render}/sdl/events.go (98%) rename {render => lib/render}/sdl/log.go (100%) rename {render => lib/render}/sdl/sdl.go (96%) rename {render => lib/render}/sdl/text.go (97%) rename {render => lib/render}/sdl/texture.go (96%) rename {render => lib/render}/sdl/utils.go (90%) create mode 100644 lib/ui/README.md rename {ui => lib/ui}/button.go (96%) rename {ui => lib/ui}/check_button.go (96%) rename {ui => lib/ui}/checkbox.go (97%) rename {ui => lib/ui}/debug.go (100%) rename {ui => lib/ui}/dragdrop.go (100%) rename {ui => lib/ui}/frame.go (97%) rename {ui => lib/ui}/frame_pack.go (99%) rename {ui => lib/ui}/functions.go (93%) rename {ui => lib/ui}/image.go (97%) rename {ui => lib/ui}/label.go (98%) rename {ui => lib/ui}/log.go (100%) rename {ui => lib/ui}/supervisor.go (98%) rename {ui => lib/ui}/theme/theme.go (82%) rename {ui => lib/ui}/widget.go (99%) rename {ui => lib/ui}/window.go (98%) rename {balance => src/balance}/README.md (100%) rename {balance => src/balance}/debug.go (98%) rename {balance => src/balance}/numbers.go (100%) rename {balance => src/balance}/shell.go (92%) rename {balance => src/balance}/theme.go (91%) rename commands.go => src/commands.go (99%) rename config.go => src/config.go (100%) rename {doodads => src/doodads}/actor.go (96%) rename {doodads => src/doodads}/collision.go (98%) rename {doodads => src/doodads}/doodad.go (91%) rename {doodads => src/doodads}/drawing.go (97%) rename {doodads => src/doodads}/dummy/dummy.go (87%) rename {doodads => src/doodads}/dummy/player.go (82%) rename {doodads => src/doodads}/json.go (100%) rename doodle.go => src/doodle.go (96%) rename {draw => src/draw}/line.go (94%) rename {draw => src/draw}/line_test.go (96%) rename editor_scene.go => src/editor_scene.go (97%) rename editor_scene_debug.go => src/editor_scene_debug.go (85%) rename editor_ui.go => src/editor_ui.go (97%) rename editor_ui_doodad.go => src/editor_ui_doodad.go (94%) rename editor_ui_palette.go => src/editor_ui_palette.go (90%) rename {enum => src/enum}/enum.go (100%) rename {events => src/events}/debug.go (100%) rename {events => src/events}/events.go (100%) rename {events => src/events}/log.go (100%) rename {events => src/events}/types.go (100%) rename fps.go => src/fps.go (95%) rename guitest_scene.go => src/guitest_scene.go (97%) rename {level => src/level}/actors.go (96%) rename {level => src/level}/base_test.go (100%) rename {level => src/level}/chunk.go (98%) rename {level => src/level}/chunk_map.go (98%) rename {level => src/level}/chunk_test.go (99%) rename {level => src/level}/chunker.go (99%) rename {level => src/level}/chunker_test.go (99%) rename {level => src/level}/filesystem.go (100%) rename {level => src/level}/json.go (100%) rename {level => src/level}/log.go (100%) rename {level => src/level}/page_type.go (100%) rename {level => src/level}/palette.go (97%) rename {level => src/level}/swatch.go (96%) rename {level => src/level}/types.go (96%) rename log.go => src/log.go (100%) rename main_scene.go => src/main_scene.go (91%) rename play_scene.go => src/play_scene.go (94%) rename scene.go => src/scene.go (94%) rename shell.go => src/shell.go (97%) rename {uix => src/uix}/actor.go (91%) rename {uix => src/uix}/canvas.go (97%) rename {uix => src/uix}/canvas_actors.go (96%) rename {uix => src/uix}/canvas_editable.go (94%) rename {uix => src/uix}/canvas_present.go (97%) rename {uix => src/uix}/canvas_scrolling.go (95%) rename {uix => src/uix}/canvas_wallpaper.go (97%) rename {uix => src/uix}/draw_modes.go (100%) rename {uix => src/uix}/log.go (100%) diff --git a/cmd/doodad/commands/convert.go b/cmd/doodad/commands/convert.go index 2ebfba3..8062fd6 100644 --- a/cmd/doodad/commands/convert.go +++ b/cmd/doodad/commands/convert.go @@ -14,7 +14,7 @@ import ( "git.kirsle.net/apps/doodle" "git.kirsle.net/apps/doodle/doodads" "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" "github.com/urfave/cli" "golang.org/x/image/bmp" ) diff --git a/cmd/doodle/main.go b/cmd/doodle/main.go index 531f91f..839c30d 100644 --- a/cmd/doodle/main.go +++ b/cmd/doodle/main.go @@ -4,9 +4,9 @@ import ( "flag" "runtime" - "git.kirsle.net/apps/doodle" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/render/sdl" + "git.kirsle.net/apps/doodle/lib/render/sdl" + "git.kirsle.net/apps/doodle/src" + "git.kirsle.net/apps/doodle/src/balance" _ "image/png" ) diff --git a/render/color.go b/lib/render/color.go similarity index 100% rename from render/color.go rename to lib/render/color.go diff --git a/render/functions.go b/lib/render/functions.go similarity index 100% rename from render/functions.go rename to lib/render/functions.go diff --git a/render/interface.go b/lib/render/interface.go similarity index 99% rename from render/interface.go rename to lib/render/interface.go index a64d498..5d307fc 100644 --- a/render/interface.go +++ b/lib/render/interface.go @@ -4,7 +4,7 @@ import ( "fmt" "math" - "git.kirsle.net/apps/doodle/events" + "git.kirsle.net/apps/doodle/src/events" ) // Engine is the interface for the rendering engine, keeping SDL-specific stuff diff --git a/render/log.go b/lib/render/log.go similarity index 100% rename from render/log.go rename to lib/render/log.go diff --git a/render/point.go b/lib/render/point.go similarity index 100% rename from render/point.go rename to lib/render/point.go diff --git a/render/point_test.go b/lib/render/point_test.go similarity index 95% rename from render/point_test.go rename to lib/render/point_test.go index d56a70a..0cfe102 100644 --- a/render/point_test.go +++ b/lib/render/point_test.go @@ -4,7 +4,7 @@ import ( "strconv" "testing" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) func TestPointInside(t *testing.T) { diff --git a/render/rect_test.go b/lib/render/rect_test.go similarity index 96% rename from render/rect_test.go rename to lib/render/rect_test.go index 882b6fc..c6d8bb4 100644 --- a/render/rect_test.go +++ b/lib/render/rect_test.go @@ -4,7 +4,7 @@ import ( "strconv" "testing" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) func TestIntersection(t *testing.T) { diff --git a/render/sdl/canvas.go b/lib/render/sdl/canvas.go similarity index 97% rename from render/sdl/canvas.go rename to lib/render/sdl/canvas.go index 2272c49..0095585 100644 --- a/render/sdl/canvas.go +++ b/lib/render/sdl/canvas.go @@ -2,7 +2,7 @@ package sdl import ( - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" "github.com/veandco/go-sdl2/sdl" ) diff --git a/render/sdl/events.go b/lib/render/sdl/events.go similarity index 98% rename from render/sdl/events.go rename to lib/render/sdl/events.go index 5a8bad3..277bd4a 100644 --- a/render/sdl/events.go +++ b/lib/render/sdl/events.go @@ -3,7 +3,7 @@ package sdl import ( "errors" - "git.kirsle.net/apps/doodle/events" + "git.kirsle.net/apps/doodle/src/events" // XXX: break it up "github.com/veandco/go-sdl2/sdl" ) diff --git a/render/sdl/log.go b/lib/render/sdl/log.go similarity index 100% rename from render/sdl/log.go rename to lib/render/sdl/log.go diff --git a/render/sdl/sdl.go b/lib/render/sdl/sdl.go similarity index 96% rename from render/sdl/sdl.go rename to lib/render/sdl/sdl.go index 2b6bb8e..5abd80f 100644 --- a/render/sdl/sdl.go +++ b/lib/render/sdl/sdl.go @@ -4,8 +4,8 @@ package sdl import ( "time" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/events" "github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/ttf" ) diff --git a/render/sdl/text.go b/lib/render/sdl/text.go similarity index 97% rename from render/sdl/text.go rename to lib/render/sdl/text.go index dc00129..94b53bd 100644 --- a/render/sdl/text.go +++ b/lib/render/sdl/text.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/events" "github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/ttf" ) diff --git a/render/sdl/texture.go b/lib/render/sdl/texture.go similarity index 96% rename from render/sdl/texture.go rename to lib/render/sdl/texture.go index 192da48..b7843cc 100644 --- a/render/sdl/texture.go +++ b/lib/render/sdl/texture.go @@ -3,7 +3,7 @@ package sdl import ( "fmt" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" "github.com/veandco/go-sdl2/sdl" ) diff --git a/render/sdl/utils.go b/lib/render/sdl/utils.go similarity index 90% rename from render/sdl/utils.go rename to lib/render/sdl/utils.go index efcbf9c..3c7f260 100644 --- a/render/sdl/utils.go +++ b/lib/render/sdl/utils.go @@ -1,7 +1,7 @@ package sdl import ( - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" "github.com/veandco/go-sdl2/sdl" ) diff --git a/lib/ui/README.md b/lib/ui/README.md new file mode 100644 index 0000000..2db9b9f --- /dev/null +++ b/lib/ui/README.md @@ -0,0 +1,8 @@ +# Doodle UI + +This is a UI toolkit designed for Doodle but made generally available. + +## Ties to Break + +lib/ui and lib/render both currently import doodle/src/events as their only +dependency on Doodle. This module should be moved to a better common location. diff --git a/ui/button.go b/lib/ui/button.go similarity index 96% rename from ui/button.go rename to lib/ui/button.go index e7240ca..708c88a 100644 --- a/ui/button.go +++ b/lib/ui/button.go @@ -4,8 +4,8 @@ import ( "errors" "fmt" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui/theme" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui/theme" ) // Button is a clickable button. diff --git a/ui/check_button.go b/lib/ui/check_button.go similarity index 96% rename from ui/check_button.go rename to lib/ui/check_button.go index dd56f58..838667c 100644 --- a/ui/check_button.go +++ b/lib/ui/check_button.go @@ -4,8 +4,8 @@ import ( "fmt" "strconv" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui/theme" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui/theme" ) // CheckButton implements a checkbox and radiobox widget. It's based on a diff --git a/ui/checkbox.go b/lib/ui/checkbox.go similarity index 97% rename from ui/checkbox.go rename to lib/ui/checkbox.go index 59b26fd..e98d7d2 100644 --- a/ui/checkbox.go +++ b/lib/ui/checkbox.go @@ -1,6 +1,6 @@ package ui -import "git.kirsle.net/apps/doodle/render" +import "git.kirsle.net/apps/doodle/lib/render" // Checkbox combines a CheckButton with a widget like a Label. type Checkbox struct { diff --git a/ui/debug.go b/lib/ui/debug.go similarity index 100% rename from ui/debug.go rename to lib/ui/debug.go diff --git a/ui/dragdrop.go b/lib/ui/dragdrop.go similarity index 100% rename from ui/dragdrop.go rename to lib/ui/dragdrop.go diff --git a/ui/frame.go b/lib/ui/frame.go similarity index 97% rename from ui/frame.go rename to lib/ui/frame.go index ee15af6..fe3be40 100644 --- a/ui/frame.go +++ b/lib/ui/frame.go @@ -3,7 +3,7 @@ package ui import ( "fmt" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Frame is a widget that contains other widgets. diff --git a/ui/frame_pack.go b/lib/ui/frame_pack.go similarity index 99% rename from ui/frame_pack.go rename to lib/ui/frame_pack.go index 228f8fc..7915567 100644 --- a/ui/frame_pack.go +++ b/lib/ui/frame_pack.go @@ -1,6 +1,8 @@ package ui -import "git.kirsle.net/apps/doodle/render" +import ( + "git.kirsle.net/apps/doodle/lib/render" +) // Pack provides configuration fields for Frame.Pack(). type Pack struct { diff --git a/ui/functions.go b/lib/ui/functions.go similarity index 93% rename from ui/functions.go rename to lib/ui/functions.go index bceca8b..9780a30 100644 --- a/ui/functions.go +++ b/lib/ui/functions.go @@ -1,6 +1,6 @@ package ui -import "git.kirsle.net/apps/doodle/render" +import "git.kirsle.net/apps/doodle/lib/render" // AbsolutePosition computes a widget's absolute X,Y position on the // window on screen by crawling its parent widget tree. diff --git a/ui/image.go b/lib/ui/image.go similarity index 97% rename from ui/image.go rename to lib/ui/image.go index 94e9993..32d57fd 100644 --- a/ui/image.go +++ b/lib/ui/image.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // ImageType for supported image formats. diff --git a/ui/label.go b/lib/ui/label.go similarity index 98% rename from ui/label.go rename to lib/ui/label.go index 8f3cfdf..0aefbc1 100644 --- a/ui/label.go +++ b/lib/ui/label.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // DefaultFont is the default font settings used for a Label. diff --git a/ui/log.go b/lib/ui/log.go similarity index 100% rename from ui/log.go rename to lib/ui/log.go diff --git a/ui/supervisor.go b/lib/ui/supervisor.go similarity index 98% rename from ui/supervisor.go rename to lib/ui/supervisor.go index 43ae0bd..4c599eb 100644 --- a/ui/supervisor.go +++ b/lib/ui/supervisor.go @@ -4,8 +4,8 @@ import ( "errors" "sync" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/events" ) // Event is a named event that the supervisor will send. diff --git a/ui/theme/theme.go b/lib/ui/theme/theme.go similarity index 82% rename from ui/theme/theme.go rename to lib/ui/theme/theme.go index 1994128..d8e5d89 100644 --- a/ui/theme/theme.go +++ b/lib/ui/theme/theme.go @@ -1,6 +1,6 @@ package theme -import "git.kirsle.net/apps/doodle/render" +import "git.kirsle.net/apps/doodle/lib/render" // Color schemes. var ( diff --git a/ui/widget.go b/lib/ui/widget.go similarity index 99% rename from ui/widget.go rename to lib/ui/widget.go index bcc6db8..e7b2328 100644 --- a/ui/widget.go +++ b/lib/ui/widget.go @@ -1,8 +1,8 @@ package ui import ( - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui/theme" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui/theme" ) // BorderStyle options for widget.SetBorderStyle() diff --git a/ui/window.go b/lib/ui/window.go similarity index 98% rename from ui/window.go rename to lib/ui/window.go index 4347c63..a956e7f 100644 --- a/ui/window.go +++ b/lib/ui/window.go @@ -3,7 +3,7 @@ package ui import ( "fmt" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Window is a frame with a title bar. diff --git a/pkg/wallpaper/texture.go b/pkg/wallpaper/texture.go index 71a81ad..40e7f8c 100644 --- a/pkg/wallpaper/texture.go +++ b/pkg/wallpaper/texture.go @@ -8,7 +8,7 @@ import ( "os" "git.kirsle.net/apps/doodle/pkg/userdir" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" "golang.org/x/image/bmp" ) diff --git a/pkg/wallpaper/wallpaper.go b/pkg/wallpaper/wallpaper.go index 05885d0..98482a8 100644 --- a/pkg/wallpaper/wallpaper.go +++ b/pkg/wallpaper/wallpaper.go @@ -7,7 +7,7 @@ import ( "path/filepath" "strings" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Wallpaper is a repeatable background image to go behind levels. diff --git a/balance/README.md b/src/balance/README.md similarity index 100% rename from balance/README.md rename to src/balance/README.md diff --git a/balance/debug.go b/src/balance/debug.go similarity index 98% rename from balance/debug.go rename to src/balance/debug.go index 9e55043..0274b38 100644 --- a/balance/debug.go +++ b/src/balance/debug.go @@ -5,7 +5,7 @@ import ( "strconv" "strings" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Debug related variables that can toggle on or off certain features and diff --git a/balance/numbers.go b/src/balance/numbers.go similarity index 100% rename from balance/numbers.go rename to src/balance/numbers.go diff --git a/balance/shell.go b/src/balance/shell.go similarity index 92% rename from balance/shell.go rename to src/balance/shell.go index 12ef517..dbc3711 100644 --- a/balance/shell.go +++ b/src/balance/shell.go @@ -1,7 +1,7 @@ package balance import ( - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Shell related variables. diff --git a/balance/theme.go b/src/balance/theme.go similarity index 91% rename from balance/theme.go rename to src/balance/theme.go index 192a2ad..7da0987 100644 --- a/balance/theme.go +++ b/src/balance/theme.go @@ -1,8 +1,8 @@ package balance import ( - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" ) // Theme and appearance variables. diff --git a/commands.go b/src/commands.go similarity index 99% rename from commands.go rename to src/commands.go index 095bd5e..324370a 100644 --- a/commands.go +++ b/src/commands.go @@ -5,7 +5,7 @@ import ( "fmt" "strconv" - "git.kirsle.net/apps/doodle/enum" + "git.kirsle.net/apps/doodle/src/enum" ) // Command is a parsed shell command. diff --git a/config.go b/src/config.go similarity index 100% rename from config.go rename to src/config.go diff --git a/doodads/actor.go b/src/doodads/actor.go similarity index 96% rename from doodads/actor.go rename to src/doodads/actor.go index 2a77289..cb0994c 100644 --- a/doodads/actor.go +++ b/src/doodads/actor.go @@ -1,8 +1,8 @@ package doodads import ( - "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/level" ) // Actor is a reusable run-time drawing component used in Doodle. Actors are an diff --git a/doodads/collision.go b/src/doodads/collision.go similarity index 98% rename from doodads/collision.go rename to src/doodads/collision.go index fe8b264..833c1d9 100644 --- a/doodads/collision.go +++ b/src/doodads/collision.go @@ -1,8 +1,8 @@ package doodads import ( - "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/level" ) // Collide describes how a collision occurred. diff --git a/doodads/doodad.go b/src/doodads/doodad.go similarity index 91% rename from doodads/doodad.go rename to src/doodads/doodad.go index ea2fa33..71eb690 100644 --- a/doodads/doodad.go +++ b/src/doodads/doodad.go @@ -1,9 +1,9 @@ package doodads import ( - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/level" ) // Doodad is a reusable component for Levels that have scripts and graphics. diff --git a/doodads/drawing.go b/src/doodads/drawing.go similarity index 97% rename from doodads/drawing.go rename to src/doodads/drawing.go index 99837c0..fd74a2f 100644 --- a/doodads/drawing.go +++ b/src/doodads/drawing.go @@ -1,7 +1,7 @@ package doodads import ( - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" uuid "github.com/satori/go.uuid" ) diff --git a/doodads/dummy/dummy.go b/src/doodads/dummy/dummy.go similarity index 87% rename from doodads/dummy/dummy.go rename to src/doodads/dummy/dummy.go index 2dc79d7..7160f1b 100644 --- a/doodads/dummy/dummy.go +++ b/src/doodads/dummy/dummy.go @@ -1,7 +1,7 @@ // Package dummy implements a dummy doodads.Drawing. package dummy -import "git.kirsle.net/apps/doodle/doodads" +import "git.kirsle.net/apps/doodle/src/doodads" // Drawing is a dummy doodads.Drawing that has no data. type Drawing struct { diff --git a/doodads/dummy/player.go b/src/doodads/dummy/player.go similarity index 82% rename from doodads/dummy/player.go rename to src/doodads/dummy/player.go index 5f4a018..c0a69db 100644 --- a/doodads/dummy/player.go +++ b/src/doodads/dummy/player.go @@ -1,7 +1,7 @@ // Package dummy implements a dummy doodads.Drawing. package dummy -import "git.kirsle.net/apps/doodle/doodads" +import "git.kirsle.net/apps/doodle/src/doodads" // NewPlayer creates a dummy player object. func NewPlayer() *Drawing { diff --git a/doodads/json.go b/src/doodads/json.go similarity index 100% rename from doodads/json.go rename to src/doodads/json.go diff --git a/doodle.go b/src/doodle.go similarity index 96% rename from doodle.go rename to src/doodle.go index 268c5a6..540708e 100644 --- a/doodle.go +++ b/src/doodle.go @@ -5,11 +5,11 @@ import ( "strings" "time" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/enum" - "git.kirsle.net/apps/doodle/events" + "git.kirsle.net/apps/doodle/lib/render" "git.kirsle.net/apps/doodle/pkg/userdir" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/enum" + "git.kirsle.net/apps/doodle/src/events" "github.com/kirsle/golog" ) diff --git a/draw/line.go b/src/draw/line.go similarity index 94% rename from draw/line.go rename to src/draw/line.go index a174164..bc98a87 100644 --- a/draw/line.go +++ b/src/draw/line.go @@ -3,7 +3,7 @@ package draw import ( "math" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Line is a generator that returns the X,Y coordinates to draw a line. diff --git a/draw/line_test.go b/src/draw/line_test.go similarity index 96% rename from draw/line_test.go rename to src/draw/line_test.go index eb1cabb..db03fb9 100644 --- a/draw/line_test.go +++ b/src/draw/line_test.go @@ -5,7 +5,7 @@ import ( "testing" "git.kirsle.net/apps/doodle/draw" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) func TestLine(t *testing.T) { diff --git a/editor_scene.go b/src/editor_scene.go similarity index 97% rename from editor_scene.go rename to src/editor_scene.go index f0c646f..f9e3d1d 100644 --- a/editor_scene.go +++ b/src/editor_scene.go @@ -7,12 +7,12 @@ import ( "os" "strings" - "git.kirsle.net/apps/doodle/doodads" - "git.kirsle.net/apps/doodle/enum" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/level" + "git.kirsle.net/apps/doodle/lib/render" "git.kirsle.net/apps/doodle/pkg/userdir" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/src/doodads" + "git.kirsle.net/apps/doodle/src/enum" + "git.kirsle.net/apps/doodle/src/events" + "git.kirsle.net/apps/doodle/src/level" ) // EditorScene manages the "Edit Level" game mode. diff --git a/editor_scene_debug.go b/src/editor_scene_debug.go similarity index 85% rename from editor_scene_debug.go rename to src/editor_scene_debug.go index f2ceea0..c0ce20d 100644 --- a/editor_scene_debug.go +++ b/src/editor_scene_debug.go @@ -1,6 +1,6 @@ package doodle -import "git.kirsle.net/apps/doodle/uix" +import "git.kirsle.net/apps/doodle/src/uix" // TODO: build flags to not include this in production builds. // This adds accessors for private variables from the dev console. diff --git a/editor_ui.go b/src/editor_ui.go similarity index 97% rename from editor_ui.go rename to src/editor_ui.go index 784649f..6d97df2 100644 --- a/editor_ui.go +++ b/src/editor_ui.go @@ -5,15 +5,15 @@ import ( "path/filepath" "strconv" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/doodads" - "git.kirsle.net/apps/doodle/enum" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/level" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/userdir" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" - "git.kirsle.net/apps/doodle/uix" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/doodads" + "git.kirsle.net/apps/doodle/src/enum" + "git.kirsle.net/apps/doodle/src/events" + "git.kirsle.net/apps/doodle/src/level" + "git.kirsle.net/apps/doodle/src/uix" ) // Width of the panel frame. diff --git a/editor_ui_doodad.go b/src/editor_ui_doodad.go similarity index 94% rename from editor_ui_doodad.go rename to src/editor_ui_doodad.go index 433641c..2a53c8b 100644 --- a/editor_ui_doodad.go +++ b/src/editor_ui_doodad.go @@ -7,12 +7,12 @@ package doodle import ( "fmt" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/doodads" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/userdir" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" - "git.kirsle.net/apps/doodle/uix" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/doodads" + "git.kirsle.net/apps/doodle/src/uix" ) // DraggableActor is a Doodad being dragged from the Doodad palette. diff --git a/editor_ui_palette.go b/src/editor_ui_palette.go similarity index 90% rename from editor_ui_palette.go rename to src/editor_ui_palette.go index d48c6fc..e41755f 100644 --- a/editor_ui_palette.go +++ b/src/editor_ui_palette.go @@ -1,9 +1,9 @@ package doodle import ( - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" + "git.kirsle.net/apps/doodle/src/balance" ) // setupPaletteFrame configures the Color Palette tab for Edit Mode. diff --git a/enum/enum.go b/src/enum/enum.go similarity index 100% rename from enum/enum.go rename to src/enum/enum.go diff --git a/events/debug.go b/src/events/debug.go similarity index 100% rename from events/debug.go rename to src/events/debug.go diff --git a/events/events.go b/src/events/events.go similarity index 100% rename from events/events.go rename to src/events/events.go diff --git a/events/log.go b/src/events/log.go similarity index 100% rename from events/log.go rename to src/events/log.go diff --git a/events/types.go b/src/events/types.go similarity index 100% rename from events/types.go rename to src/events/types.go diff --git a/fps.go b/src/fps.go similarity index 95% rename from fps.go rename to src/fps.go index 4de911a..2ccdfce 100644 --- a/fps.go +++ b/src/fps.go @@ -4,10 +4,10 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/doodads" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/doodads" ) // Frames to cache for FPS calculation. diff --git a/guitest_scene.go b/src/guitest_scene.go similarity index 97% rename from guitest_scene.go rename to src/guitest_scene.go index 1b349eb..5a64dac 100644 --- a/guitest_scene.go +++ b/src/guitest_scene.go @@ -3,10 +3,10 @@ package doodle import ( "fmt" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/events" + "git.kirsle.net/apps/doodle/lib/ui" ) // GUITestScene implements the main menu of Doodle. diff --git a/level/actors.go b/src/level/actors.go similarity index 96% rename from level/actors.go rename to src/level/actors.go index 332c044..caeb08d 100644 --- a/level/actors.go +++ b/src/level/actors.go @@ -1,7 +1,7 @@ package level import ( - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" uuid "github.com/satori/go.uuid" ) diff --git a/level/base_test.go b/src/level/base_test.go similarity index 100% rename from level/base_test.go rename to src/level/base_test.go diff --git a/level/chunk.go b/src/level/chunk.go similarity index 98% rename from level/chunk.go rename to src/level/chunk.go index a0aa78d..c2c79b5 100644 --- a/level/chunk.go +++ b/src/level/chunk.go @@ -7,9 +7,9 @@ import ( "math" "os" - "git.kirsle.net/apps/doodle/balance" + "git.kirsle.net/apps/doodle/lib/render" "git.kirsle.net/apps/doodle/pkg/userdir" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/src/balance" "github.com/satori/go.uuid" "golang.org/x/image/bmp" ) diff --git a/level/chunk_map.go b/src/level/chunk_map.go similarity index 98% rename from level/chunk_map.go rename to src/level/chunk_map.go index 45a1075..a5b5def 100644 --- a/level/chunk_map.go +++ b/src/level/chunk_map.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // MapAccessor implements a chunk accessor by using a map of points to their diff --git a/level/chunk_test.go b/src/level/chunk_test.go similarity index 99% rename from level/chunk_test.go rename to src/level/chunk_test.go index 7ebf3ff..cad45aa 100644 --- a/level/chunk_test.go +++ b/src/level/chunk_test.go @@ -5,7 +5,7 @@ import ( "testing" "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Test the high level Chunker. diff --git a/level/chunker.go b/src/level/chunker.go similarity index 99% rename from level/chunker.go rename to src/level/chunker.go index 127c5db..0bcb0de 100644 --- a/level/chunker.go +++ b/src/level/chunker.go @@ -5,7 +5,7 @@ import ( "fmt" "math" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Chunker is the data structure that manages the chunks of a level, and diff --git a/level/chunker_test.go b/src/level/chunker_test.go similarity index 99% rename from level/chunker_test.go rename to src/level/chunker_test.go index d417a3d..c48a31b 100644 --- a/level/chunker_test.go +++ b/src/level/chunker_test.go @@ -5,7 +5,7 @@ import ( "testing" "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) func TestWorldSize(t *testing.T) { diff --git a/level/filesystem.go b/src/level/filesystem.go similarity index 100% rename from level/filesystem.go rename to src/level/filesystem.go diff --git a/level/json.go b/src/level/json.go similarity index 100% rename from level/json.go rename to src/level/json.go diff --git a/level/log.go b/src/level/log.go similarity index 100% rename from level/log.go rename to src/level/log.go diff --git a/level/page_type.go b/src/level/page_type.go similarity index 100% rename from level/page_type.go rename to src/level/page_type.go diff --git a/level/palette.go b/src/level/palette.go similarity index 97% rename from level/palette.go rename to src/level/palette.go index 3061760..7c34b61 100644 --- a/level/palette.go +++ b/src/level/palette.go @@ -1,7 +1,7 @@ package level import ( - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // DefaultPalette returns a sensible default palette. diff --git a/level/swatch.go b/src/level/swatch.go similarity index 96% rename from level/swatch.go rename to src/level/swatch.go index 2dc1c46..a6304e0 100644 --- a/level/swatch.go +++ b/src/level/swatch.go @@ -3,7 +3,7 @@ package level import ( "fmt" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" ) // Swatch holds details about a single value in the palette. diff --git a/level/types.go b/src/level/types.go similarity index 96% rename from level/types.go rename to src/level/types.go index b603734..f91bd03 100644 --- a/level/types.go +++ b/src/level/types.go @@ -4,8 +4,8 @@ import ( "encoding/json" "fmt" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/balance" ) // Useful variables. diff --git a/log.go b/src/log.go similarity index 100% rename from log.go rename to src/log.go diff --git a/main_scene.go b/src/main_scene.go similarity index 91% rename from main_scene.go rename to src/main_scene.go index b559382..e646587 100644 --- a/main_scene.go +++ b/src/main_scene.go @@ -1,10 +1,10 @@ package doodle import ( - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/events" + "git.kirsle.net/apps/doodle/lib/ui" ) // MainScene implements the main menu of Doodle. diff --git a/play_scene.go b/src/play_scene.go similarity index 94% rename from play_scene.go rename to src/play_scene.go index c1cf8bb..ac19857 100644 --- a/play_scene.go +++ b/src/play_scene.go @@ -4,13 +4,13 @@ import ( "fmt" "math" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/doodads" - "git.kirsle.net/apps/doodle/doodads/dummy" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/uix" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/doodads" + "git.kirsle.net/apps/doodle/src/doodads/dummy" + "git.kirsle.net/apps/doodle/src/events" + "git.kirsle.net/apps/doodle/src/level" + "git.kirsle.net/apps/doodle/src/uix" ) // PlayScene manages the "Edit Level" game mode. diff --git a/scene.go b/src/scene.go similarity index 94% rename from scene.go rename to src/scene.go index 3220661..1cedea1 100644 --- a/scene.go +++ b/src/scene.go @@ -1,6 +1,8 @@ package doodle -import "git.kirsle.net/apps/doodle/events" +import ( + "git.kirsle.net/apps/doodle/src/events" +) // Scene is an abstraction for a game mode in Doodle. The app points to one // scene at a time and that scene has control over the main loop, and its own diff --git a/shell.go b/src/shell.go similarity index 97% rename from shell.go rename to src/shell.go index 23c828e..609ab0f 100644 --- a/shell.go +++ b/src/shell.go @@ -5,10 +5,10 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/events" "github.com/robertkrimen/otto" ) diff --git a/uix/actor.go b/src/uix/actor.go similarity index 91% rename from uix/actor.go rename to src/uix/actor.go index 06f710b..2335bac 100644 --- a/uix/actor.go +++ b/src/uix/actor.go @@ -1,9 +1,9 @@ package uix import ( - "git.kirsle.net/apps/doodle/doodads" - "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src/doodads" + "git.kirsle.net/apps/doodle/src/level" uuid "github.com/satori/go.uuid" ) diff --git a/uix/canvas.go b/src/uix/canvas.go similarity index 97% rename from uix/canvas.go rename to src/uix/canvas.go index 430bb47..1ecf68c 100644 --- a/uix/canvas.go +++ b/src/uix/canvas.go @@ -5,13 +5,13 @@ import ( "os" "strings" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/doodads" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/level" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/pkg/wallpaper" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/doodads" + "git.kirsle.net/apps/doodle/src/events" + "git.kirsle.net/apps/doodle/src/level" ) // Canvas is a custom ui.Widget that manages a single drawing. diff --git a/uix/canvas_actors.go b/src/uix/canvas_actors.go similarity index 96% rename from uix/canvas_actors.go rename to src/uix/canvas_actors.go index 457d207..2d56c4e 100644 --- a/uix/canvas_actors.go +++ b/src/uix/canvas_actors.go @@ -3,10 +3,10 @@ package uix import ( "fmt" - "git.kirsle.net/apps/doodle/doodads" - "git.kirsle.net/apps/doodle/level" + "git.kirsle.net/apps/doodle/lib/render" "git.kirsle.net/apps/doodle/pkg/userdir" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/src/doodads" + "git.kirsle.net/apps/doodle/src/level" ) // InstallActors adds external Actors to the canvas to be superimposed on top diff --git a/uix/canvas_editable.go b/src/uix/canvas_editable.go similarity index 94% rename from uix/canvas_editable.go rename to src/uix/canvas_editable.go index 184c5e2..15561d7 100644 --- a/uix/canvas_editable.go +++ b/src/uix/canvas_editable.go @@ -1,10 +1,10 @@ package uix import ( - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" + "git.kirsle.net/apps/doodle/src/events" + "git.kirsle.net/apps/doodle/src/level" ) // loopEditable handles the Loop() part for editable canvases. diff --git a/uix/canvas_present.go b/src/uix/canvas_present.go similarity index 97% rename from uix/canvas_present.go rename to src/uix/canvas_present.go index 9e7dd38..cb6bb65 100644 --- a/uix/canvas_present.go +++ b/src/uix/canvas_present.go @@ -4,9 +4,9 @@ import ( "fmt" "strings" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" + "git.kirsle.net/apps/doodle/src/balance" ) // Present the canvas. diff --git a/uix/canvas_scrolling.go b/src/uix/canvas_scrolling.go similarity index 95% rename from uix/canvas_scrolling.go rename to src/uix/canvas_scrolling.go index 7c13aff..a51aca3 100644 --- a/uix/canvas_scrolling.go +++ b/src/uix/canvas_scrolling.go @@ -4,11 +4,11 @@ import ( "errors" "fmt" - "git.kirsle.net/apps/doodle/balance" - "git.kirsle.net/apps/doodle/events" - "git.kirsle.net/apps/doodle/level" - "git.kirsle.net/apps/doodle/render" - "git.kirsle.net/apps/doodle/ui" + "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" + "git.kirsle.net/apps/doodle/src/balance" + "git.kirsle.net/apps/doodle/src/events" + "git.kirsle.net/apps/doodle/src/level" ) /* diff --git a/uix/canvas_wallpaper.go b/src/uix/canvas_wallpaper.go similarity index 97% rename from uix/canvas_wallpaper.go rename to src/uix/canvas_wallpaper.go index 827dadc..c1a9076 100644 --- a/uix/canvas_wallpaper.go +++ b/src/uix/canvas_wallpaper.go @@ -1,9 +1,9 @@ package uix import ( - "git.kirsle.net/apps/doodle/level" + "git.kirsle.net/apps/doodle/lib/render" "git.kirsle.net/apps/doodle/pkg/wallpaper" - "git.kirsle.net/apps/doodle/render" + "git.kirsle.net/apps/doodle/src/level" ) // Wallpaper configures the wallpaper in a Canvas. diff --git a/uix/draw_modes.go b/src/uix/draw_modes.go similarity index 100% rename from uix/draw_modes.go rename to src/uix/draw_modes.go diff --git a/uix/log.go b/src/uix/log.go similarity index 100% rename from uix/log.go rename to src/uix/log.go -- 2.30.2 From f473609bb5c3023b0717b7f41edf805977ee8d86 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sun, 30 Dec 2018 14:46:29 -0800 Subject: [PATCH 5/5] Add build time, hash and version info to binaries Add urfave/cli to the doodle.exe binary to add a --version command. Both doodle.exe and doodad.exe will now print their git commit hash and build date along with their version number when asked. % ./bin/doodle --version doodle version 0.0.7-alpha build a316baf. Built on 2018-12-30T14:44:43-08:00 --- Makefile | 3 +- cmd/doodad/commands/convert.go | 6 +- cmd/doodad/main.go | 22 ++++++- cmd/doodle/main.go | 108 +++++++++++++++++++++++---------- pkg/wallpaper/texture.go | 2 +- src/guitest_scene.go | 2 +- src/main_scene.go | 2 +- 7 files changed, 102 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 2f08226..b17e095 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,11 @@ SHELL := /bin/bash VERSION=$(shell grep -e 'Version' doodle.go | head -n 1 | cut -d '"' -f 2) BUILD=$(shell git describe --always) +BUILD_DATE=$(shell date -Iseconds) CURDIR=$(shell curdir) # Inject the build version (commit hash) into the executable. -LDFLAGS := -ldflags "-X main.Build=$(BUILD)" +LDFLAGS := -ldflags "-X main.Build=$(BUILD) -X main.BuildDate=$(BUILD_DATE)" # `make setup` to set up a new environment, pull dependencies, etc. .PHONY: setup diff --git a/cmd/doodad/commands/convert.go b/cmd/doodad/commands/convert.go index 8062fd6..e078d83 100644 --- a/cmd/doodad/commands/convert.go +++ b/cmd/doodad/commands/convert.go @@ -11,10 +11,10 @@ import ( "image/png" - "git.kirsle.net/apps/doodle" - "git.kirsle.net/apps/doodle/doodads" - "git.kirsle.net/apps/doodle/level" "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/src" + "git.kirsle.net/apps/doodle/src/doodads" + "git.kirsle.net/apps/doodle/src/level" "github.com/urfave/cli" "golang.org/x/image/bmp" ) diff --git a/cmd/doodad/main.go b/cmd/doodad/main.go index b976f43..656fcf2 100644 --- a/cmd/doodad/main.go +++ b/cmd/doodad/main.go @@ -2,22 +2,38 @@ package main import ( + "fmt" "log" "os" "sort" + "time" - "git.kirsle.net/apps/doodle" "git.kirsle.net/apps/doodle/cmd/doodad/commands" + "git.kirsle.net/apps/doodle/src" "github.com/urfave/cli" ) -var Build = "N/A" +// Build number is the git commit hash. +var ( + Build = "" + BuildDate string +) + +func init() { + if BuildDate == "" { + BuildDate = time.Now().Format(time.RFC3339) + } +} func main() { app := cli.NewApp() app.Name = "doodad" app.Usage = "command line interface for Doodle" - app.Version = doodle.Version + " build " + Build + app.Version = fmt.Sprintf("%s build %s. Built on %s", + doodle.Version, + Build, + BuildDate, + ) app.Flags = []cli.Flag{ cli.BoolFlag{ diff --git a/cmd/doodle/main.go b/cmd/doodle/main.go index 839c30d..aceb8ce 100644 --- a/cmd/doodle/main.go +++ b/cmd/doodle/main.go @@ -1,59 +1,101 @@ package main import ( - "flag" + "fmt" + "log" + "os" "runtime" + "sort" + "time" "git.kirsle.net/apps/doodle/lib/render/sdl" "git.kirsle.net/apps/doodle/src" "git.kirsle.net/apps/doodle/src/balance" + "github.com/urfave/cli" _ "image/png" ) // Build number is the git commit hash. -var Build string - -// Command line args var ( - debug bool - edit bool - guitest bool + Build = "" + BuildDate string ) func init() { - flag.BoolVar(&debug, "debug", false, "Debug mode") - flag.BoolVar(&edit, "edit", false, "Edit the map given on the command line. Default is to play the map.") - flag.BoolVar(&guitest, "guitest", false, "Enter the GUI Test scene.") + if BuildDate == "" { + BuildDate = time.Now().Format(time.RFC3339) + } } func main() { runtime.LockOSThread() - flag.Parse() - args := flag.Args() - var filename string - if len(args) > 0 { - filename = args[0] - } - - // SDL engine. - engine := sdl.New( - "Doodle v"+doodle.Version, - balance.Width, - balance.Height, + app := cli.NewApp() + app.Name = "doodle" + app.Usage = "command line interface for Doodle" + app.Version = fmt.Sprintf("%s build %s. Built on %s", + doodle.Version, + Build, + BuildDate, ) - app := doodle.New(debug, engine) - app.SetupEngine() - if guitest { - app.Goto(&doodle.GUITestScene{}) - } else if filename != "" { - if edit { - app.EditFile(filename) - } else { - app.PlayLevel(filename) - } + app.Flags = []cli.Flag{ + cli.BoolFlag{ + Name: "debug, d", + Usage: "enable debug level logging", + }, + cli.BoolFlag{ + Name: "edit, e", + Usage: "edit the map given on the command line (instead of play it)", + }, + cli.BoolFlag{ + Name: "guitest", + Usage: "enter the GUI Test scene on startup", + }, + } + + app.Action = func(c *cli.Context) error { + if c.Bool("version") { + fmt.Printf("This is Project Doodle, v%s build %s ", + doodle.Version, + Build, + ) + return nil + } + + var filename string + if c.NArg() > 0 { + filename = c.Args().Get(0) + } + + // SDL engine. + engine := sdl.New( + "Doodle v"+doodle.Version, + balance.Width, + balance.Height, + ) + + game := doodle.New(c.Bool("debug"), engine) + game.SetupEngine() + if c.Bool("guitest") { + game.Goto(&doodle.GUITestScene{}) + } else if filename != "" { + if c.Bool("edit") { + game.EditFile(filename) + } else { + game.PlayLevel(filename) + } + } + game.Run() + return nil + } + + sort.Sort(cli.FlagsByName(app.Flags)) + sort.Sort(cli.CommandsByName(app.Commands)) + + err := app.Run(os.Args) + if err != nil { + log.Fatal(err) } - app.Run() } diff --git a/pkg/wallpaper/texture.go b/pkg/wallpaper/texture.go index 40e7f8c..45a6b23 100644 --- a/pkg/wallpaper/texture.go +++ b/pkg/wallpaper/texture.go @@ -7,8 +7,8 @@ import ( "image" "os" - "git.kirsle.net/apps/doodle/pkg/userdir" "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/pkg/userdir" "golang.org/x/image/bmp" ) diff --git a/src/guitest_scene.go b/src/guitest_scene.go index 5a64dac..e949a41 100644 --- a/src/guitest_scene.go +++ b/src/guitest_scene.go @@ -4,9 +4,9 @@ import ( "fmt" "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/src/balance" "git.kirsle.net/apps/doodle/src/events" - "git.kirsle.net/apps/doodle/lib/ui" ) // GUITestScene implements the main menu of Doodle. diff --git a/src/main_scene.go b/src/main_scene.go index e646587..de72fee 100644 --- a/src/main_scene.go +++ b/src/main_scene.go @@ -2,9 +2,9 @@ package doodle import ( "git.kirsle.net/apps/doodle/lib/render" + "git.kirsle.net/apps/doodle/lib/ui" "git.kirsle.net/apps/doodle/src/balance" "git.kirsle.net/apps/doodle/src/events" - "git.kirsle.net/apps/doodle/lib/ui" ) // MainScene implements the main menu of Doodle. -- 2.30.2