iigs tile editing basically works

This commit is contained in:
Jeremy Penner 2021-08-28 22:04:54 -04:00
parent f54ebea6bc
commit dc61bb08e0
8 changed files with 128 additions and 57 deletions

View file

@ -1,3 +1,5 @@
(local {: putpixel : make-canvas} (require :editor.tiledraw))
(fn pal-from-bit [bit]
(if bit
(values [20 207 253] [255 106 60])
@ -6,25 +8,6 @@
(fn pal-from-byte [byte]
(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]
(local byte (string.byte (bytes:sub ibyte ibyte)))
(var prevstate nil)
@ -105,32 +88,5 @@
(for [y 0 7]
(draw-byte gfx (+ y 1) 0 y))))))
(fn TileCache [tiles ?spritegen]
{: tiles
: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}
{: tile-to-sprite : char-to-sprite : portrait-to-sprite : screen-to-sprite : scanline-to-sprite : screen-y-to-offset
: tilestrip-to-sprite : pal-from-bit : pal-from-byte : draw-byte}

21
editor/tiledraw/iigs.fnl Normal file
View 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
View 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

View file

@ -15,5 +15,6 @@
: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-bits (fn [self] self.bit)
:pixel-storage-divisor #8
}

12
editor/tileedit/iigs.fnl Normal file
View 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
}

View file

@ -3,7 +3,7 @@
(local tiles (require :game.tiles))
(local files (require :game.files))
(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))
@ -16,7 +16,7 @@
[:gfx]))
(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]
(-> (get-byte tile ibyte)
(bit.band (bit.lshift mask ibit))
@ -30,11 +30,13 @@
(fn set-tile-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]
(local (w h) (self:tilesize))
(or (-?> self.tilecache.tiles (. self.itile) (. (or self.tilekey :gfx))) (string.rep "\0" (/ (* w h) 8))))
(files.platform-methods TileView :editor.tileedit :map-bitxy :pixel-color :draw-on :draw-off :draw-bits)
(or (-?> self.tilecache.tiles (. self.itile) (. (or self.tilekey :gfx)))
(string.rep "\0" (/ (* w h) (self:pixel-storage-divisor)))))
(fn TileView.draw-pixel [self x y colorbg ?colorfg]
(renderer.draw_rect x y pixel-size pixel-size colorbg)
@ -76,6 +78,25 @@
(each [iflag flagname (ipairs (tiles.flags))]
(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]
(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))
(self:draw-tile-flags (+ x editor-w pixel-size) y)
(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))]
(local selector-h (self:draw-tile-selector x selector-y (- self.size.x 20) key))
(set selector-y (+ selector-y selector-h pixel-size)))

View file

@ -1,6 +1,5 @@
(local util (require :lib.util))
(local lume (require :lib.lume))
(local tiledraw (require :editor.tiledraw))
(local files (util.hot-table ...))
@ -51,7 +50,8 @@
(if (util.file-exists (filename))
(let [game (util.readjson (filename))]
(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)
{:tiles [] :portraits [] :font [] :levels []}))
files.game)
@ -64,15 +64,19 @@
(util.writejson (filename) game)))
(fn new-cache [game key]
(let [spritegen (match key
(let [tiledraw (require :editor.tiledraw)
spritegen (match key
:font tiledraw.char-to-sprite
:brushes tiledraw.char-to-sprite
:portraits tiledraw.portrait-to-sprite
_ tiledraw.tile-to-sprite)
gfx (. game key)]
(print gfx key)
(tiledraw.TileCache gfx spritegen)))
(fn files.cache [key]
(when (= (. files.game key) nil)
(tset files.game key []))
(when (= (?. files :tilecaches key) nil)
(util.nested-tset files [:tilecaches key] (new-cache files.game key)))
(. files.tilecaches key))
@ -89,7 +93,8 @@
(fn files.platform [] (or files.game.platform :ii))
(fn files.platform-methods [cls module-prefix ...]
(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)
(files.load))

1
neutgs/game.json Normal file
View file

@ -0,0 +1 @@
{"platform": "iigs"}