diff --git a/editor/gfxedit.fnl b/editor/gfxedit.fnl index a782293..c51470a 100644 --- a/editor/gfxedit.fnl +++ b/editor/gfxedit.fnl @@ -41,7 +41,7 @@ (love.graphics.rectangle :line (- tilex 2) (- tiley 2) (+ tilew 4) (+ tileh 4))) (when (button self [:tile itile] tilex tiley tilew tileh) (set self.itile itile)) - (set tilex (+ tilex tilew)) + (set tilex (+ tilex tilew 4)) (when (>= (+ tilex tilew) (+ x w)) (set tilex x) (set tiley (+ tiley tileh 4))))) diff --git a/editor/mapedit.fnl b/editor/mapedit.fnl index 9c53870..6f54a93 100644 --- a/editor/mapedit.fnl +++ b/editor/mapedit.fnl @@ -1,8 +1,9 @@ - (local GraphicsEditView (require :editor.gfxedit)) +(local GraphicsEditView (require :editor.gfxedit)) (local style (require :core.style)) (local util (require :lib.util)) (local lume (require :lib.lume)) (local {: mouse-inside : activate : active? : checkbox : textfield : textbutton} (util.require :editor.imstate)) +(local {: tilestrip-to-sprite} (util.require :editor.tiledraw)) (local MapEditView (GraphicsEditView:extend)) (local sprite-scale 3) @@ -14,6 +15,7 @@ (fn MapEditView.new [self] (MapEditView.super.new self) (set self.sprite-scale sprite-scale) + (set self.stripcache {}) (self:reload)) ; map is stored bottom-to-top @@ -74,38 +76,54 @@ (love.graphics.circle :line xEnd yEnd (/ tilew 5)) (love.graphics.setColor 1 1 1))) +(fn MapEditView.draw-tilestrip [self x y my] + ; stripcache leaks but honestly who cares + (local tilestrip []) + (var stripid "") + (for [mx 1 mapw] + (local itile (self:itile-from-xy mx my)) + (local tile (. self.tilecache.tiles itile :gfx)) + (table.insert tilestrip tile) + (set stripid (.. stripid (string.char itile)))) + (var sprite (. self.stripcache stripid)) + (when (= sprite nil) + (set sprite (tilestrip-to-sprite tilestrip)) + (tset self.stripcache stripid sprite)) + (love.graphics.draw sprite x y 0 self.sprite-scale self.sprite-scale)) + (fn MapEditView.draw-map-editor [self x y] (activate self :map x y (* tilew mapw) (* tileh maph)) (var iobject-over nil) - (for [mx 1 mapw] (for [my 1 maph] - (local tilex (+ x (* (- mx 1) tilew))) + (for [my 1 maph] (local tiley (+ y (* (- my 1) tileh))) - (local itile (self:itile-from-xy mx my)) - (local iobject (self:iobject-from-xy mx my)) - (self:draw-sprite tilex tiley itile) - (when (and (not= iobject nil) (= self.itile nil)) - (love.graphics.setColor 1 0 (if (and (= self.itile nil) (= iobject self.iobject)) 1 0)) - (love.graphics.setLineWidth 3) - (love.graphics.rectangle :line tilex tiley tilew tileh) - (love.graphics.setColor 1 1 1)) - (when (and (mouse-inside tilex tiley tilew tileh) (not= iobject nil)) - (set iobject-over iobject)) - (when (and self.itile (active? self :map) (mouse-inside tilex tiley tilew tileh) (not= itile self.itile)) - (self:set-tile mx my self.itile)) - (when (and (= self.itile nil) (active? self :map) (mouse-inside tilex tiley tilew tileh)) - (match self.imstate.left - :pressed (set self.iobject-linking iobject) - :released - (if (and (not= iobject nil) (= self.iobject-linking iobject)) - (set self.iobject iobject) + (self:draw-tilestrip x tiley my) + (for [mx 1 mapw] + (local tilex (+ x (* (- mx 1) tilew))) + (local itile (self:itile-from-xy mx my)) + (local iobject (self:iobject-from-xy mx my)) + (when (and (not= iobject nil) (= self.itile nil)) + (love.graphics.setColor 1 0 (if (and (= self.itile nil) (= iobject self.iobject)) 1 0)) + (love.graphics.setLineWidth 3) + (love.graphics.rectangle :line tilex tiley tilew tileh) + (love.graphics.setColor 1 1 1)) + (when (and (mouse-inside tilex tiley tilew tileh) (not= iobject nil)) + (set iobject-over iobject)) + (when (and self.itile (active? self :map) (mouse-inside tilex tiley tilew tileh) (not= itile self.itile)) + (self:set-tile mx my self.itile)) + (when (and (= self.itile nil) (active? self :map) (mouse-inside tilex tiley tilew tileh)) + (match self.imstate.left + :pressed (set self.iobject-linking iobject) + :released + (if (and (not= iobject nil) (= self.iobject-linking iobject)) + (set self.iobject iobject) - (not= self.iobject-linking nil) - (tset (self:linking-obj) :link iobject) + (not= self.iobject-linking nil) + (tset (self:linking-obj) :link iobject) - (= iobject nil) - (let [tile (self.tilecache:tile itile)] - (table.insert self.level.objects {:x mx :y my :func (or tile.word "")}) - (set self.iobject (length self.level.objects)))))))) + (= iobject nil) + (let [tile (self.tilecache:tile itile)] + (table.insert self.level.objects {:x mx :y my :func (or tile.word "")}) + (set self.iobject (length self.level.objects)))))))) (when (= self.itile nil) (for [iobject 1 (length self.level.objects)] (self:draw-link-line x y iobject [0 0 1 0.3])) diff --git a/editor/tiledraw.fnl b/editor/tiledraw.fnl index cfba956..5435d70 100644 --- a/editor/tiledraw.fnl +++ b/editor/tiledraw.fnl @@ -13,65 +13,69 @@ (fn make-canvas [w h f] (local canvas (love.graphics.newCanvas w h)) + (local prevcanvas (love.graphics.getCanvas)) (canvas:setFilter :nearest :nearest) (local scissor [(love.graphics.getScissor)]) (love.graphics.setScissor) (love.graphics.setCanvas canvas) (love.graphics.clear 0 0 0) (f canvas) - (love.graphics.setCanvas) + (love.graphics.setCanvas prevcanvas) (love.graphics.setScissor (table.unpack scissor)) (love.graphics.setColor 1 1 1 1) canvas) -(fn tile-to-sprite [tile] - (make-canvas 14 16 (fn [canvas] +(fn draw-byte [bytes ibyte xoffset y ?state ?prevpal] + (local byte (string.byte (bytes:sub ibyte ibyte))) + (var prevstate nil) + (var state (or ?state :off)) + (var pal [(pal-from-byte byte)]) + (var prevpal (or ?prevpal pal)) + (for [bitx 0 6] + (local x (+ bitx xoffset)) + (local bit (not= 0 (bit.band byte (bit.lshift 1 bitx)))) + (local prevart (. prevpal (+ 1 (% x 2)))) + (local art (. pal (+ 1 (% x 2)))) + (set prevstate state) + (set prevpal pal) + (set state + (match [prevstate bit] + [:off false] :off + [:off true] :rising + [:rising false] :falling + [:rising true] :on + [:falling false] :off + [:falling true] :rising + [:on true] :on + [:on false] :falling)) + (local white [255 255 255]) + (local (prevcolor color) + (match [prevstate state] + [_ :on] (values white white) + [:off :rising] (values nil art) + [:falling :rising] (values prevart art))) + (putpixel (- x 1) y prevcolor) + (putpixel x y color)) + (values state pal)) + +(fn tilestrip-to-sprite [tiles] + (make-canvas (* 14 (length tiles)) 16 (fn [canvas] (for [y 0 15] - (local byte1 (string.byte (tile:sub (+ y 1) (+ y 1)))) - (local byte2 (string.byte (tile:sub (+ y 17) (+ y 17)))) - (local pal1 [(pal-from-byte byte1)]) - (local pal2 [(pal-from-byte byte2)]) - (var prevstate :off) - (var state :off) - (for [x 0 13] - (local byte (if (< x 7) byte1 byte2)) - (local bitx (if (< x 7) x (- x 7))) - (local bit (not= 0 (bit.band byte (bit.lshift 1 bitx)))) - (local prevpal (if (< x 8) pal1 pal2)) - (local pal (if (< x 7) pal1 pal2)) - (local prevart (. prevpal (+ 1 (% x 2)))) - (local art (. pal (+ 1 (% x 2)))) - (set prevstate state) - (set state - (match [prevstate bit] - [:off false] :off - [:off true] :rising - [:rising false] :falling - [:rising true] :on - [:falling false] :off - [:falling true] :rising - [:on true] :on - [:on false] :falling)) - (local white [255 255 255]) - (local (prevcolor color) - (match [prevstate state] - [_ :on] (values white white) - [:off :rising] (values nil art) - [:falling :rising] (values prevart art))) - (putpixel (- x 1) y prevcolor) - (putpixel x y color)))))) + (var state nil) + (var prevpal nil) + (each [itile tile (ipairs tiles)] + (local x (* (- itile 1) 14)) + (set (state prevpal) (draw-byte tile (+ y 1) x y state prevpal)) + (set (state prevpal) (draw-byte tile (+ y 17) (+ x 7) y state prevpal))))))) + +(fn tile-to-sprite [tile] (tilestrip-to-sprite [tile])) (fn portrait-to-sprite [gfx] - (print "generating portrait") - (local tl (tile-to-sprite (gfx:sub 1 32))) - (local bl (tile-to-sprite (gfx:sub 33 64))) - (local tr (tile-to-sprite (gfx:sub 65 96))) - (local br (tile-to-sprite (gfx:sub 97 128))) + (local top (tilestrip-to-sprite [(gfx:sub 1 32) (gfx:sub 65 96)])) + (local bottom (tilestrip-to-sprite [(gfx:sub 33 64) (gfx:sub 97 128)])) (make-canvas 28 32 (fn [canvas] - (love.graphics.draw tl 0 0) - (love.graphics.draw bl 0 16) - (love.graphics.draw tr 14 0) - (love.graphics.draw br 14 16)))) + (love.graphics.draw top 0 0) + (love.graphics.draw bottom 0 16)))) (fn TileCache [tiles ?spritegen] {: tiles @@ -97,4 +101,5 @@ (tset self.tilesprites itile (self.spritegen (. self.tiles itile :gfx)))) (. self.tilesprites itile))}) -{: tile-to-sprite : portrait-to-sprite : pal-from-bit : pal-from-byte : TileCache} +{: tile-to-sprite : tilestrip-to-sprite : portrait-to-sprite : pal-from-bit : pal-from-byte : TileCache} +