map editor!!

This commit is contained in:
Jeremy Penner 2020-10-18 20:13:26 -04:00
parent 033d308662
commit dbc618acaa
10 changed files with 164 additions and 61 deletions

40
editor/gfxedit.fnl Normal file
View file

@ -0,0 +1,40 @@
(local View (require :core.view))
(local tiles (require :game.tiles))
(local tiledraw (require :editor.tiledraw))
(local util (require :lib.util))
(local {: attach-imstate : mouse-inside : activate : active? : button} (util.require :editor.imstate))
(local GraphicsEditView (View:extend))
(local sprite-scale 4)
(set GraphicsEditView.sprite-scale sprite-scale)
(fn GraphicsEditView.new [self]
(GraphicsEditView.super.new self)
(set self.tilecache (tiledraw.TileCache (tiles.loadtiles)))
(set self.itile 1)
(attach-imstate self))
(fn GraphicsEditView.select-rel [self ditile]
(local itile (+ self.itile ditile))
(when (>= itile 1) (set self.itile itile)))
(fn GraphicsEditView.draw-sprite [self x y itile]
(love.graphics.draw (self.tilecache:sprite itile) x y 0 sprite-scale sprite-scale))
(fn GraphicsEditView.draw-tile-selector [self x y w]
(var tilex x)
(var tiley y)
(local tile-size (* 16 sprite-scale))
(for [itile 1 (length self.tilecache.tiles)]
(self:draw-sprite tilex tiley itile)
(when (= itile self.itile)
(love.graphics.rectangle :line (- tilex 2) (- tiley 2) (+ (* 14 sprite-scale) 4) (+ tile-size 4)))
(when (button self [:tile itile] tilex tiley tile-size tile-size)
(set self.itile itile))
(set tilex (+ tilex tile-size))
(when (>= (+ tilex tile-size) (+ x w))
(set tilex x)
(set tiley (+ tiley tile-size 4)))))
GraphicsEditView

View file

@ -1,5 +1,6 @@
(require :editor.lite) (require :editor.lite)
(local TileView (require :editor.tileedit)) (local TileView (require :editor.tileedit))
(local MapEditView (require :editor.mapedit))
(local core (require :core)) (local core (require :core))
(local command (require :core.command)) (local command (require :core.command))
(local keymap (require :core.keymap)) (local keymap (require :core.keymap))
@ -7,7 +8,11 @@
(command.add nil { (command.add nil {
"honeylisp:edit-tiles" (fn [] "honeylisp:edit-tiles" (fn []
(local node (core.root_view:get_active_node)) (local node (core.root_view:get_active_node))
(node:add_view (TileView))) ; allow hot reload (node:add_view (TileView)))
"honeylisp:edit-map" (fn []
(local node (core.root_view:get_active_node))
(node:add_view (MapEditView))
)
}) })
(command.add :editor.tileedit { (command.add :editor.tileedit {
@ -19,7 +24,6 @@
#(when (= (length (system.get_clipboard)) 64) #(when (= (length (system.get_clipboard)) 64)
(core.active_view:update-tile (: (system.get_clipboard) :fromhex))) (core.active_view:update-tile (: (system.get_clipboard) :fromhex)))
}) })
(keymap.add { (keymap.add {
"ctrl+s" "tileedit:save" "ctrl+s" "tileedit:save"
"left" "tileedit:previous-tile" "left" "tileedit:previous-tile"
@ -28,3 +32,14 @@
"ctrl+v" "tileedit:paste" "ctrl+v" "tileedit:paste"
}) })
(command.add :editor.mapedit {
"mapedit:next-tile" #(core.active_view:select-rel 1)
"mapedit:previous-tile" #(core.active_view:select-rel -1)
"mapedit:save" (fn [] (core.active_view:save) (core.log "Saved map"))
})
(keymap.add {
"ctrl+s" "mapedit:save"
"left" "mapedit:previous-tile"
"right" "mapedit:next-tile"
})

66
editor/mapedit.fnl Normal file
View file

@ -0,0 +1,66 @@
(local GraphicsEditView (require :editor.gfxedit))
(local style (require :core.style))
(local util (require :lib.util))
(local {: mouse-inside : activate : active?} (util.require :editor.imstate))
(local MapEditView (GraphicsEditView:extend))
(local mapw 20)
(local maph 12)
(local tilew (* GraphicsEditView.sprite-scale 14))
(local tileh (* GraphicsEditView.sprite-scale 16))
(fn MapEditView.new [self]
(MapEditView.super.new self)
(set self.map (string.rep "\0" (* mapw maph))))
; map is stored bottom-to-top
(fn imap-from-xy [mx my]
(+ mx -1 (* mapw (- maph my))))
(fn update-map [map mx my itile]
(local imap (imap-from-xy mx my))
(local enctile
(bit.bor
(bit.lshift (bit.band (- itile 1) 0x07) 5)
(bit.rshift (bit.band (- itile 1) 0xf8) 3)))
(..
(map:sub 1 imap)
(string.char enctile)
(map:sub (+ imap 2))))
(fn MapEditView.itile-from-xy [self mx my]
(local imap (+ (imap-from-xy mx my) 1))
(local enctile (string.byte (self.map:sub imap imap)))
(+ 1 (bit.bor
(bit.lshift (bit.band enctile 0x1f) 3)
(bit.rshift (bit.band enctile 0xe0) 5))))
(fn MapEditView.set-tile [self mx my itile]
(set self.map (update-map self.map mx my itile)))
(fn MapEditView.draw-map-editor [self x y]
(activate self :map x y (* tilew mapw) (* tileh maph))
(for [mx 1 mapw] (for [my 1 maph]
(local tilex (+ x (* (- mx 1) tilew)))
(local tiley (+ y (* (- my 1) tileh)))
(local itile (self:itile-from-xy mx my))
(self:draw-sprite tilex tiley itile)
(when (and (active? self :map) (mouse-inside tilex tiley tilew tileh) (not= itile self.itile))
(self:set-tile mx my self.itile)))))
(fn MapEditView.save [self]
(util.writejson "game/map00001.json" (self.map:tohex)))
(fn MapEditView.draw [self]
(self:draw_background style.background)
(love.graphics.setColor 1 1 1 1)
(self:draw-map-editor (+ self.position.x 10) (+ self.position.y 10))
(self:draw-tile-selector
(+ self.position.x 10)
(+ self.position.y 20 (* tileh maph))
(- self.size.x 20)))
(fn MapEditView.get_name [self] "Map Editor")
MapEditView

View file

@ -57,4 +57,17 @@
(love.graphics.setColor 1 1 1 1) (love.graphics.setColor 1 1 1 1)
canvas) canvas)
{: tile-to-sprite : pal-from-bit : pal-from-byte} (fn TileCache [tiles]
{: tiles
:tilesprites []
:update-tile
(fn [self itile tile]
(tset self.tiles itile tile)
(tset self.tilesprites itile nil))
:sprite
(fn [self itile]
(when (and (= nil (. self.tilesprites itile)) (not= nil (. self.tiles itile)))
(tset self.tilesprites itile (tile-to-sprite (. self.tiles itile))))
(. self.tilesprites itile))})
{: tile-to-sprite : pal-from-bit : pal-from-byte : TileCache}

View file

@ -1,29 +1,22 @@
(local core (require :core)) (local GraphicsEditView (require :editor.gfxedit))
(local command (require :core.command))
(local style (require :core.style)) (local style (require :core.style))
(local View (require :core.view))
(local tiles (require :game.tiles)) (local tiles (require :game.tiles))
(local tiledraw (require :editor.tiledraw)) (local tiledraw (require :editor.tiledraw))
(local lume (require :lib.lume))
(local util (require :lib.util)) (local util (require :lib.util))
(local {: attach-imstate : mouse-inside : activate : active? : button} (util.require :editor.imstate)) (local {: mouse-inside : activate : active?} (util.require :editor.imstate))
(local TileView (View:extend))
(local TileView (GraphicsEditView:extend))
(local pixel-size 24) (local pixel-size 24)
(local sprite-scale 4)
(local xy-to-ibit [])
(for [x 0 15] (tset xy-to-ibit x []))
(for [y 0 15]
(tset (. xy-to-ibit 0) y (+ (* y 8) 7))
(for [ibit 0 6]
(tset (. xy-to-ibit (+ ibit 1)) y (+ (* y 8) ibit))))
(for [y 0 15] (for [x 0 7]
(tset (. xy-to-ibit (+ x 8)) y (+ (* (+ y 16) 8) x))))
(fn map-bitxy [x y] (fn map-bitxy [x y]
(when (and (>= x 0) (< x 16) (>= y 0) (< y 16)) (when (and (>= x 0) (< x 16) (>= y 0) (< y 16))
(local ibit (. xy-to-ibit x y)) (local ibyte (if (< x 8) y (+ y 16)))
(values (math.floor (/ ibit 8)) (% ibit 8)))) (local ibit
(if (= x 0) 7
(< x 8) (- x 1)
(- x 8)))
(values ibyte ibit)))
(fn get-byte [tile ibyte] (fn get-byte [tile ibyte]
(: (tile:sub (+ ibyte 1) (+ ibyte 1)) :byte)) (: (tile:sub (+ ibyte 1) (+ ibyte 1)) :byte))
@ -49,14 +42,7 @@
(fn draw-bit [bit x y even] (fn draw-bit [bit x y even]
(renderer.draw_rect x y pixel-size pixel-size (if bit [255 255 255] [0 0 0]))) (renderer.draw_rect x y pixel-size pixel-size (if bit [255 255 255] [0 0 0])))
(fn TileView.new [self] (fn TileView.tile [self] (or (. self.tilecache.tiles self.itile) (string.rep "\0" 32)))
(TileView.super.new self)
(set self.tiles (tiles.loadtiles))
(set self.itile 1)
(set self.tilesprites [])
(attach-imstate self))
(fn TileView.tile [self] (or (. self.tiles self.itile) (string.rep "\0" 32)))
(fn TileView.draw-tile-editor [self tile x y] (fn TileView.draw-tile-editor [self tile x y]
(when (not (active? self :tile)) (when (not (active? self :tile))
@ -76,39 +62,15 @@
(love.graphics.setColor 1 1 1 1)) (love.graphics.setColor 1 1 1 1))
(fn TileView.update-tile [self newtile] (fn TileView.update-tile [self newtile]
(tset self.tiles self.itile newtile) (self.tilecache:update-tile self.itile newtile))
(tset self.tilesprites self.itile nil))
(fn TileView.save [self] (tiles.savetiles self.tiles)) (fn TileView.save [self] (tiles.savetiles self.tilecache.tiles))
(fn TileView.select-rel [self ditile]
(local itile (+ self.itile ditile))
(when (>= itile 1) (set self.itile itile)))
(fn TileView.tilesprite [self itile]
(when (and (= nil (. self.tilesprites itile)) (not= nil (. self.tiles itile)))
(tset self.tilesprites itile (tiledraw.tile-to-sprite (. self.tiles itile))))
(. self.tilesprites itile))
(fn TileView.draw-tile-selector [self x y]
(var tilex x)
(var tiley y)
(local tile-size (* 16 sprite-scale))
(each [itile _ (ipairs self.tiles)]
(love.graphics.draw (self:tilesprite itile) tilex tiley 0 sprite-scale sprite-scale)
(when (= itile self.itile)
(love.graphics.rectangle :line (- tilex 2) (- tiley 2) (+ (* 14 sprite-scale) 4) (+ tile-size 4)))
(when (button self [:tile itile] tilex tiley tile-size tile-size)
(set self.itile itile))
(set tilex (+ tilex tile-size))
(when (>= (+ tilex tile-size) (+ self.position.x self.size.x -10))
(set tilex (+ self.position.x 10))
(set tiley (+ tiley tile-size 4)))))
(fn TileView.draw [self] (fn TileView.draw [self]
(self:draw_background style.background) (self:draw_background style.background)
(local (x y) (values (+ self.position.x 10) (+ self.position.y 10))) (local (x y) (values (+ self.position.x 10) (+ self.position.y 10)))
(self:draw-tile-editor (self:tile) x y) (self:draw-tile-editor (self:tile) x y)
(self:draw-tile-selector x (+ y (* 18 (+ pixel-size 1))))) (self:draw-tile-selector x (+ y (* 18 (+ pixel-size 1))) (- self.size.x 20)))
(fn TileView.get_name [self] "Tile Editor") (fn TileView.get_name [self] "Tile Editor")

View file

@ -152,13 +152,15 @@
; hotswap-safe debug stub at root of call stack ; hotswap-safe debug stub at root of call stack
; but REPL debug stub should be very available as a task ; but REPL debug stub should be very available as a task
; 19x11 means full map is 209 bytes ; 20x12 means full map is 240 bytes - we have an extra 16 bytes at the end to mess with?
(: (prg:org 0x6800) :append :map [:bytes (string.rep "\0\032\064\096\128\160\192\224\001\033\065\097\129\161\193" 17)]) (tile.appendmaps (prg:org 0x6800))
; (: (prg:org 0x6800) :append :map [:bytes (string.rep "\0\032\064\096\128\160\192\224\001\033\065\097\129\161\193" 17)])
(code1:append :main (code1:append :main
[:jsr :reset] [:jsr :reset]
[:jsr :interpret] [:jsr :interpret]
[:vm :hires ; :mixed [:vm :hires ; :mixed
:cleargfx :cleargfx ; :drawmap
(vm:forever (vm:forever
(vm:hotswap-sync) :drawmap (vm:hotswap-sync) :drawmap
) )

1
game/map00001.json Normal file
View file

@ -0,0 +1 @@
"2121212141212121212121212121412121212121610261616102616161026161616161026161612161C0C0C0C0C0C0C0C0C0C0C061C0C0C0C0C0612161C0C0C0C0C0C0C0C0C0C0C081C080C0C0C0024161C0C0C0C0C0C0C0C0C0C0C0C1C0C0C0E0C0612161C0C0C0C0C0C0C0C0C0C0C06161616161616121616161616161C1816161616161C0C0C0C0C0612161C0C0C0C0C0C0C0C0C0C0C061C0C0C0C0C0022161E0C0C0C0C0C0C0C0C0C0C081C0C0C0C0C0612161C0C0C0C0C0C0C0C0C0C0C061C0C0C0C0C0614161C0C0C0C0C0C0C0C0C0C0C061C0C0C0C0C061216161616161616161228161616161616161610221"

View file

@ -15,5 +15,9 @@
(each [_ tile (ipairs tiles)] (each [_ tile (ipairs tiles)]
(org:append [:bytes tile]))) (org:append [:bytes tile])))
{: loadtiles : savetiles : appendtiles} (fn appendmaps [org]
(local map (: (util.readjson "game/map00001.json") :fromhex))
(org:append :map [:bytes map]))
{: loadtiles : savetiles : appendtiles : appendmaps}

View file

@ -1 +1 @@
["000000020A0820404A4020080A02000000010141511005025302051051410100","00000000020A0820404A4020080A020000000101415110050253020510514101","808080C0C0C0E0C0D0C8C04040404080808083858585828A9282820A08081980","8080C0A0A0A0C0C0D0C8C0501010188080808183838782828A8A920202020380","8080E0B0B0B098C0D0D0C840404060808080878D8D8D99828A8A920202020780","8080C0E0E0E0B0C0D0C8C040404060808080838787878D828A92820202020780","0000000000000000000000000000000000000000000000000000000000000000","007C0C0C0C0C7C007C7E7EAA88888800001F181818181F001F0F979590909000","007C2C0C0C2C7C007C7E7EAA88888800001F18191C191F001F0F979590909000","D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","D5D5D5D5D5F5F5FDDDD5D5D5D5D5D5D5AAAAAAAAAEAEBFBFBFABAAAAAAAAAAAA","F7F7DDDDF7F7DDDDF7F7DDDDF7F7DDDDEEEEBBBBEEEEBBBBEEEEBBBBEEEEBBBB","F787A5B1B3B3B1B1B3B3B1B1B3B381DDEEE8B2A6E6E6A6A6E6E6A6A6E6E6A0BB","F78785818383818183838181838381DDEEE8B0A0E0E0A0A0E0E0A0A0E0E0A0BB","F7F7CDCDCFCF898183838585878FDDDDEEECA4A4E4E4A0A0E0E0A0A0E0E8BBBB","F7F7CDCDCFCF898123232525878FDDDDEEECA4A4E4E0A0216565252561E8BBBB","F7F781D1D3D3D1D1D3D3D1D1D383DDDDEEEE808ACACE8A8BCACA8A8ACAC0BBBB","F7F7ABFBFBFBFBBBBBFBFBFBFBABDDDDEEEED5DFDFDFDFDDDDDFDFDFDFD5BBBB","F7F72B7B7B7B2B6B6B2B7B7B7B2BDDDDEEEE555F5F5F555757555F5F5F55BBBB","F7F3C58DB7F4D98187B7DDDDB7979DC5EECEA1B1ECECB8BAEEECB9B0E6CE8B9B"] ["000000020A0820404A4020080A02000000010141511005025302051051410100","00000000020A0820404A4020080A020000000101415110050253020510514101","808080C0C0C0E0C0D0C8C04040404080808083858585828A9282820A08081980","8080C0A0A0A0C0C0D0C8C0501010188080808183838782828A8A920202020380","8080E0B0B0B098C0D0D0C840404060808080878D8D8D99828A8A920202020780","8080C0E0E0E0B0C0D0C8C040404060808080838787878D828A92820202020780","80808C8080808080B08080808C808080808C80808083B0808080808080868080","007C0C0C0C0C7C007C7E7EAA88888800001F181818181F001F0F979590909000","007C2C0C0C2C7C007C7E7EAA88888800001F18191C191F001F0F979590909000","D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","D5D5D5D5D5F5F5FDDDD5D5D5D5D5D5D5AAAAAAAAAEAEBFBFBFABAAAAAAAAAAAA","FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF","FF8FA7B3B3B3B3B3B3B3B3B3B3B383FFFFF8F2E6E6E6E6E6E6E6E6E6E6E6E0FF","FF8F87838383838383838383838383FFFFF8F0E0E0E0E0E0E0E0E0E0E0E0E0FF","FFFFCFCFCFCF898183838787878FFFFFFFFCE4E4E4E4E0E0E0E0E0E0F0F8FFFF","FFFFCFCFCFCF898123232727878FFFFFFFFCE4E4E4E0E0616565656571F8FFFF","FFFF83D3D3D3D3D3D3D3D3D3D383FFFFFFFFC0CACACECACBCACACACACAC0FFFF","FFFFABFBFBFBFBBBBBFBFBFBFBABFFFFFFFFD5DFDFDFDFDDDDDFDFDFDFD5FFFF","FFFF2B7B7B7B2B6B6B2B7B7B7B2BFFFFFFFF555F5F5F555757555F5F5F55FFFF","FFF3C78FBFFCF98187BFFFFFBF9F9FC7FFCFE1F1FCFCF8FEFEFCF9F0E6CE8F9F"]

View file

@ -11,7 +11,7 @@
"serial:switch-machine" #(link:switch :serial) "serial:switch-machine" #(link:switch :serial)
}) })
(command.add #(not= link.name :gsplus) { (command.add #(not= link.name :gsplus) {
"gsplus:switch-machine" #(link.switch :gsplus) "gsplus:switch-machine" #(link:switch :gsplus)
}) })
(command.add #(link.machine:connected?) { (command.add #(link.machine:connected?) {
"honeylisp:upload" (fn [] "honeylisp:upload" (fn []