iigs tile editing basically works
This commit is contained in:
parent
f54ebea6bc
commit
dc61bb08e0
|
@ -1,3 +1,5 @@
|
||||||
|
(local {: putpixel : make-canvas} (require :editor.tiledraw))
|
||||||
|
|
||||||
(fn pal-from-bit [bit]
|
(fn pal-from-bit [bit]
|
||||||
(if bit
|
(if bit
|
||||||
(values [20 207 253] [255 106 60])
|
(values [20 207 253] [255 106 60])
|
||||||
|
@ -6,25 +8,6 @@
|
||||||
(fn pal-from-byte [byte]
|
(fn pal-from-byte [byte]
|
||||||
(pal-from-bit (not= 0 (bit.band byte 0x80))))
|
(pal-from-bit (not= 0 (bit.band byte 0x80))))
|
||||||
|
|
||||||
(fn putpixel [x y color]
|
|
||||||
(when color
|
|
||||||
(love.graphics.setColor (/ (. color 1) 255) (/ (. color 2) 255) (/ (. color 3) 255))
|
|
||||||
(love.graphics.points (+ x 0.5) (+ y 0.5))))
|
|
||||||
|
|
||||||
(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 prevcanvas)
|
|
||||||
(love.graphics.setScissor (table.unpack scissor))
|
|
||||||
(love.graphics.setColor 1 1 1 1)
|
|
||||||
canvas)
|
|
||||||
|
|
||||||
(fn draw-byte [bytes ibyte xoffset y ?state ?prevpal]
|
(fn draw-byte [bytes ibyte xoffset y ?state ?prevpal]
|
||||||
(local byte (string.byte (bytes:sub ibyte ibyte)))
|
(local byte (string.byte (bytes:sub ibyte ibyte)))
|
||||||
(var prevstate nil)
|
(var prevstate nil)
|
||||||
|
@ -105,32 +88,5 @@
|
||||||
(for [y 0 7]
|
(for [y 0 7]
|
||||||
(draw-byte gfx (+ y 1) 0 y))))))
|
(draw-byte gfx (+ y 1) 0 y))))))
|
||||||
|
|
||||||
(fn TileCache [tiles ?spritegen]
|
{: tile-to-sprite : char-to-sprite : portrait-to-sprite : screen-to-sprite : scanline-to-sprite : screen-y-to-offset
|
||||||
{: tiles
|
: tilestrip-to-sprite : pal-from-bit : pal-from-byte : draw-byte}
|
||||||
:spritegen (or ?spritegen tile-to-sprite)
|
|
||||||
:tilesprites []
|
|
||||||
:tile (fn [self itile] (or (. self.tiles itile) {:flags {}}))
|
|
||||||
:cachekey (fn [itile ?key] (.. (or ?key :gfx) itile))
|
|
||||||
:update-tile
|
|
||||||
(fn [self itile tile ?key]
|
|
||||||
(tset self.tiles itile
|
|
||||||
(-> (self:tile itile)
|
|
||||||
(doto (tset (or ?key :gfx) tile))))
|
|
||||||
(tset self.tilesprites (self.cachekey itile ?key) nil))
|
|
||||||
:set-flag
|
|
||||||
(fn [self itile flag clear]
|
|
||||||
(tset (. self.tiles itile :flags) flag (if clear nil true)))
|
|
||||||
:load
|
|
||||||
(fn [self tiles]
|
|
||||||
(set self.tiles tiles)
|
|
||||||
(set self.tilesprites []))
|
|
||||||
:sprite
|
|
||||||
(fn [self itile ?key]
|
|
||||||
(local key (self.cachekey itile ?key))
|
|
||||||
(when (and (= nil (. self.tilesprites key)) (not= nil (. self.tiles itile)))
|
|
||||||
(tset self.tilesprites key (self.spritegen (. self.tiles itile (or ?key :gfx)))))
|
|
||||||
(. self.tilesprites key))})
|
|
||||||
|
|
||||||
{: tile-to-sprite : tilestrip-to-sprite : portrait-to-sprite : char-to-sprite : scanline-to-sprite
|
|
||||||
: screen-y-to-offset : pal-from-bit : pal-from-byte : TileCache : make-canvas : draw-byte}
|
|
||||||
|
|
21
editor/tiledraw/iigs.fnl
Normal file
21
editor/tiledraw/iigs.fnl
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
(local {: putpixel : make-canvas} (require :editor.tiledraw))
|
||||||
|
|
||||||
|
; converted from http://pixeljoint.com/forum/forum_posts.asp?TID=12795 (db16)
|
||||||
|
; maybe check out https://lospec.com/palette-list ?
|
||||||
|
(local pal [[1 0 1] [4 2 3] [3 3 6] [4 4 4] [8 4 3] [3 6 2] [13 4 4] [7 7 6]
|
||||||
|
[5 7 12] [13 7 2] [8 9 10] [6 10 2] [13 10 9] [6 12 12] [13 13 5] [13 14 13]])
|
||||||
|
(fn gs-to-rgb [color] (icollect [_ v (ipairs color)] (* v 0x11)))
|
||||||
|
|
||||||
|
(fn tile-to-sprite [tile]
|
||||||
|
(if tile (make-canvas 16 16 (fn [canvas]
|
||||||
|
(for [y 0 15]
|
||||||
|
(for [x 0 15 2]
|
||||||
|
(let [ibyte (+ (* y 8) (math.floor (/ x 2)) 1)
|
||||||
|
byte (string.byte (tile:sub ibyte ibyte))
|
||||||
|
_ (print x y ibyte byte)
|
||||||
|
left (bit.band (bit.rshift byte 4) 0xf)
|
||||||
|
right (bit.band byte 0xf)]
|
||||||
|
(putpixel x y (gs-to-rgb (. pal (+ left 1))))
|
||||||
|
(putpixel (+ x 1) y (gs-to-rgb (. pal (+ right 1)))))))))))
|
||||||
|
|
||||||
|
{: tile-to-sprite : pal : gs-to-rgb}
|
53
editor/tiledraw/init.fnl
Normal file
53
editor/tiledraw/init.fnl
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
(local files (require :game.files))
|
||||||
|
(local TileDraw {})
|
||||||
|
|
||||||
|
(fn TileDraw.putpixel [x y color]
|
||||||
|
(when color
|
||||||
|
(love.graphics.setColor (/ (. color 1) 255) (/ (. color 2) 255) (/ (. color 3) 255))
|
||||||
|
(love.graphics.points (+ x 0.5) (+ y 0.5))))
|
||||||
|
|
||||||
|
(fn TileDraw.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 prevcanvas)
|
||||||
|
(love.graphics.setScissor (table.unpack scissor))
|
||||||
|
(love.graphics.setColor 1 1 1 1)
|
||||||
|
canvas)
|
||||||
|
|
||||||
|
(files.platform-methods TileDraw :editor.tiledraw
|
||||||
|
:tile-to-sprite :char-to-sprite :portrait-to-sprite :screen-to-sprite :screen-y-to-offset :tilestrip-to-sprite
|
||||||
|
:pal-from-bit :pal-from-byte :draw-byte)
|
||||||
|
|
||||||
|
(fn TileDraw.TileCache [tiles ?spritegen]
|
||||||
|
{: tiles
|
||||||
|
:spritegen (or ?spritegen TileDraw.tile-to-sprite)
|
||||||
|
:tilesprites []
|
||||||
|
:tile (fn [self itile] (or (. self.tiles itile) {:flags {}}))
|
||||||
|
:cachekey (fn [itile ?key] (.. (or ?key :gfx) itile))
|
||||||
|
:update-tile
|
||||||
|
(fn [self itile tile ?key]
|
||||||
|
(tset self.tiles itile
|
||||||
|
(-> (self:tile itile)
|
||||||
|
(doto (tset (or ?key :gfx) tile))))
|
||||||
|
(tset self.tilesprites (self.cachekey itile ?key) nil))
|
||||||
|
:set-flag
|
||||||
|
(fn [self itile flag clear]
|
||||||
|
(tset (. self.tiles itile :flags) flag (if clear nil true)))
|
||||||
|
:load
|
||||||
|
(fn [self tiles]
|
||||||
|
(set self.tiles tiles)
|
||||||
|
(set self.tilesprites []))
|
||||||
|
:sprite
|
||||||
|
(fn [self itile ?key]
|
||||||
|
(local key (self.cachekey itile ?key))
|
||||||
|
(when (and (= nil (. self.tilesprites key)) (not= nil (. self.tiles itile)))
|
||||||
|
(tset self.tilesprites key (self.spritegen (. self.tiles itile (or ?key :gfx)))))
|
||||||
|
(. self.tilesprites key))})
|
||||||
|
|
||||||
|
TileDraw
|
|
@ -15,5 +15,6 @@
|
||||||
:draw-off (fn [self] (set self.bit nil))
|
:draw-off (fn [self] (set self.bit nil))
|
||||||
:draw-on (fn [self b] (when (= self.bit nil) (set self.bit (if (= b 1) 0 1))))
|
:draw-on (fn [self b] (when (= self.bit nil) (set self.bit (if (= b 1) 0 1))))
|
||||||
:draw-bits (fn [self] self.bit)
|
:draw-bits (fn [self] self.bit)
|
||||||
|
:pixel-storage-divisor #8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
editor/tileedit/iigs.fnl
Normal file
12
editor/tileedit/iigs.fnl
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
(local {: pal : gs-to-rgb} (require :editor.tiledraw.iigs))
|
||||||
|
|
||||||
|
{:map-bitxy (fn [self x y]
|
||||||
|
(let [ibyte (+ (* y 8) (bit.rshift x 1))
|
||||||
|
ibit (match (% x 2) 0 4 1 0)]
|
||||||
|
(values ibyte ibit 0x0f)))
|
||||||
|
:pixel-color (fn [self b] (gs-to-rgb (. pal (+ b 1))))
|
||||||
|
:draw-bits #(- $1.icolor 1)
|
||||||
|
:palette #(icollect [_ color (ipairs pal)] (gs-to-rgb color))
|
||||||
|
:pixel-storage-divisor #2
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
(local tiles (require :game.tiles))
|
(local tiles (require :game.tiles))
|
||||||
(local files (require :game.files))
|
(local files (require :game.files))
|
||||||
(local util (require :lib.util))
|
(local util (require :lib.util))
|
||||||
(local {: mouse-inside : activate : active? : checkbox : textfield} (util.require :editor.imstate))
|
(local {: mouse-inside : activate : active? : checkbox : textfield : button} (util.require :editor.imstate))
|
||||||
|
|
||||||
(local TileView (GraphicsEditView:extend))
|
(local TileView (GraphicsEditView:extend))
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
[:gfx]))
|
[:gfx]))
|
||||||
|
|
||||||
(fn get-byte [tile ibyte]
|
(fn get-byte [tile ibyte]
|
||||||
(: (tile:sub (+ ibyte 1) (+ ibyte 1)) :byte))
|
(or (: (tile:sub (+ ibyte 1) (+ ibyte 1)) :byte) 0))
|
||||||
(fn get-bits [tile ibyte ibit mask]
|
(fn get-bits [tile ibyte ibit mask]
|
||||||
(-> (get-byte tile ibyte)
|
(-> (get-byte tile ibyte)
|
||||||
(bit.band (bit.lshift mask ibit))
|
(bit.band (bit.lshift mask ibit))
|
||||||
|
@ -30,11 +30,13 @@
|
||||||
(fn set-tile-bits [tile ibyte ibit mask bits]
|
(fn set-tile-bits [tile ibyte ibit mask bits]
|
||||||
(util.splice tile ibyte (string.char (set-bits tile ibyte ibit mask bits))))
|
(util.splice tile ibyte (string.char (set-bits tile ibyte ibit mask bits))))
|
||||||
|
|
||||||
|
(files.platform-methods TileView :editor.tileedit :map-bitxy :pixel-color :draw-on :draw-off :draw-bits
|
||||||
|
:palette :pixel-storage-divisor)
|
||||||
|
|
||||||
(fn TileView.tile [self]
|
(fn TileView.tile [self]
|
||||||
(local (w h) (self:tilesize))
|
(local (w h) (self:tilesize))
|
||||||
(or (-?> self.tilecache.tiles (. self.itile) (. (or self.tilekey :gfx))) (string.rep "\0" (/ (* w h) 8))))
|
(or (-?> self.tilecache.tiles (. self.itile) (. (or self.tilekey :gfx)))
|
||||||
|
(string.rep "\0" (/ (* w h) (self:pixel-storage-divisor)))))
|
||||||
(files.platform-methods TileView :editor.tileedit :map-bitxy :pixel-color :draw-on :draw-off :draw-bits)
|
|
||||||
|
|
||||||
(fn TileView.draw-pixel [self x y colorbg ?colorfg]
|
(fn TileView.draw-pixel [self x y colorbg ?colorfg]
|
||||||
(renderer.draw_rect x y pixel-size pixel-size colorbg)
|
(renderer.draw_rect x y pixel-size pixel-size colorbg)
|
||||||
|
@ -76,6 +78,25 @@
|
||||||
(each [iflag flagname (ipairs (tiles.flags))]
|
(each [iflag flagname (ipairs (tiles.flags))]
|
||||||
(set y (self:draw-tile-flag flagname x (+ y style.padding.y)))))
|
(set y (self:draw-tile-flag flagname x (+ y style.padding.y)))))
|
||||||
|
|
||||||
|
(fn TileView.draw-tile-palette [self x y w]
|
||||||
|
(local pal (self:palette))
|
||||||
|
(if pal
|
||||||
|
(do (var cx x)
|
||||||
|
(var cy y)
|
||||||
|
(each [icolor color (ipairs pal)]
|
||||||
|
(when (>= cx w)
|
||||||
|
(set cx x)
|
||||||
|
(set cy (+ cy pixel-size style.padding.y)))
|
||||||
|
(when (button self [:pal icolor] cx cy pixel-size pixel-size)
|
||||||
|
(set self.icolor icolor))
|
||||||
|
(renderer.draw_rect cx cy pixel-size pixel-size color)
|
||||||
|
(when (= icolor self.icolor)
|
||||||
|
(love.graphics.setColor 1 1 1 1)
|
||||||
|
(love.graphics.rectangle :line (- cx 2) (- cy 2) (+ pixel-size 4) (+ pixel-size 4)))
|
||||||
|
(set cx (+ cx pixel-size style.padding.x)))
|
||||||
|
(+ pixel-size style.padding.y))
|
||||||
|
0))
|
||||||
|
|
||||||
(fn TileView.update-tile [self newtile]
|
(fn TileView.update-tile [self newtile]
|
||||||
(self.tilecache:update-tile self.itile newtile self.tilekey))
|
(self.tilecache:update-tile self.itile newtile self.tilekey))
|
||||||
|
|
||||||
|
@ -87,6 +108,7 @@
|
||||||
(local (editor-w editor-h) (self:draw-tile-editor (self:tile) x y))
|
(local (editor-w editor-h) (self:draw-tile-editor (self:tile) x y))
|
||||||
(self:draw-tile-flags (+ x editor-w pixel-size) y)
|
(self:draw-tile-flags (+ x editor-w pixel-size) y)
|
||||||
(var selector-y (+ y editor-h pixel-size))
|
(var selector-y (+ y editor-h pixel-size))
|
||||||
|
(set selector-y (+ selector-y (self:draw-tile-palette x selector-y (- self.size.x 20))))
|
||||||
(each [_ key (ipairs (self:tilekeys))]
|
(each [_ key (ipairs (self:tilekeys))]
|
||||||
(local selector-h (self:draw-tile-selector x selector-y (- self.size.x 20) key))
|
(local selector-h (self:draw-tile-selector x selector-y (- self.size.x 20) key))
|
||||||
(set selector-y (+ selector-y selector-h pixel-size)))
|
(set selector-y (+ selector-y selector-h pixel-size)))
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
(local util (require :lib.util))
|
(local util (require :lib.util))
|
||||||
(local lume (require :lib.lume))
|
(local lume (require :lib.lume))
|
||||||
(local tiledraw (require :editor.tiledraw))
|
|
||||||
|
|
||||||
(local files (util.hot-table ...))
|
(local files (util.hot-table ...))
|
||||||
|
|
||||||
|
@ -51,7 +50,8 @@
|
||||||
(if (util.file-exists (filename))
|
(if (util.file-exists (filename))
|
||||||
(let [game (util.readjson (filename))]
|
(let [game (util.readjson (filename))]
|
||||||
(each [k v (pairs game)]
|
(each [k v (pairs game)]
|
||||||
(tset game k (lume.map v #(deserialize k (clone $1) game))))
|
(when (= (type v) :table)
|
||||||
|
(tset game k (lume.map v #(deserialize k (clone $1) game)))))
|
||||||
game)
|
game)
|
||||||
{:tiles [] :portraits [] :font [] :levels []}))
|
{:tiles [] :portraits [] :font [] :levels []}))
|
||||||
files.game)
|
files.game)
|
||||||
|
@ -64,15 +64,19 @@
|
||||||
(util.writejson (filename) game)))
|
(util.writejson (filename) game)))
|
||||||
|
|
||||||
(fn new-cache [game key]
|
(fn new-cache [game key]
|
||||||
(let [spritegen (match key
|
(let [tiledraw (require :editor.tiledraw)
|
||||||
|
spritegen (match key
|
||||||
:font tiledraw.char-to-sprite
|
:font tiledraw.char-to-sprite
|
||||||
:brushes tiledraw.char-to-sprite
|
:brushes tiledraw.char-to-sprite
|
||||||
:portraits tiledraw.portrait-to-sprite
|
:portraits tiledraw.portrait-to-sprite
|
||||||
_ tiledraw.tile-to-sprite)
|
_ tiledraw.tile-to-sprite)
|
||||||
gfx (. game key)]
|
gfx (. game key)]
|
||||||
|
(print gfx key)
|
||||||
(tiledraw.TileCache gfx spritegen)))
|
(tiledraw.TileCache gfx spritegen)))
|
||||||
|
|
||||||
(fn files.cache [key]
|
(fn files.cache [key]
|
||||||
|
(when (= (. files.game key) nil)
|
||||||
|
(tset files.game key []))
|
||||||
(when (= (?. files :tilecaches key) nil)
|
(when (= (?. files :tilecaches key) nil)
|
||||||
(util.nested-tset files [:tilecaches key] (new-cache files.game key)))
|
(util.nested-tset files [:tilecaches key] (new-cache files.game key)))
|
||||||
(. files.tilecaches key))
|
(. files.tilecaches key))
|
||||||
|
@ -89,7 +93,8 @@
|
||||||
(fn files.platform [] (or files.game.platform :ii))
|
(fn files.platform [] (or files.game.platform :ii))
|
||||||
(fn files.platform-methods [cls module-prefix ...]
|
(fn files.platform-methods [cls module-prefix ...]
|
||||||
(each [_ key (ipairs [...])]
|
(each [_ key (ipairs [...])]
|
||||||
(tset cls key (fn [...] ((. (require (.. module-prefix :. (files.platform))) key) ...)))))
|
(tset cls key (fn [...] (let [f (. (require (.. module-prefix :. (files.platform))) key)]
|
||||||
|
(when f (f ...)))))))
|
||||||
|
|
||||||
(when (= files.game nil)
|
(when (= files.game nil)
|
||||||
(files.load))
|
(files.load))
|
||||||
|
|
1
neutgs/game.json
Normal file
1
neutgs/game.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"platform": "iigs"}
|
Loading…
Reference in a new issue