(local GraphicsEditView (require :editor.gfxedit)) (local util (require :lib.util)) (local lume (require :lib.lume)) (local style (require :core.style)) (local {: char-to-sprite : scanline-to-sprite : screen-y-to-offset} (util.require :editor.tiledraw)) (local {: mouse-inside : activate : active? : checkbox : textfield : textbutton} (util.require :editor.imstate)) (local ScreenEditView (GraphicsEditView:extend)) (local screen-scale 4) (local screenw 280) (local screenh 192) (fn ScreenEditView.new [self filename] (ScreenEditView.super.new self) (set self.screenfilename filename) (set self.scanlines []) (self:reload)) (fn gfxshift [byte offset] (local pixels (bit.band (string.byte byte) 0x7f)) (local color (bit.band (string.byte byte) 0x80)) (bit.bor color (if (> offset 0) (bit.band (bit.lshift pixels offset) 0x7f) (bit.rshift pixels (- offset))))) (fn brush-mask-at [brush xoffset y] (values (gfxshift (brush.gfx:sub y y) xoffset) (gfxshift (brush.mask:sub y y) xoffset))) (fn paint-byte [src brush mask] (if (not= (bit.band mask 0x7f) 0) (-> src (bit.band (bit.bxor 0xff mask)) (bit.bor brush)) src)) (fn paint-byte-at [screen brush y xbyte xoffset yoffset] (if (and (>= xbyte 0) (< xbyte 40) (>= y 0) (< y screenh)) (let [ibyte (+ (screen-y-to-offset y) xbyte) srcbyte (screen:sub (+ ibyte 1) (+ ibyte 1)) painted (paint-byte (string.byte srcbyte) (brush-mask-at brush xoffset yoffset))] (util.splice screen ibyte (string.char painted))) screen)) (fn paint [screen brush x y] (var result screen) (for [row y (+ y 7)] (local xbyte (math.floor (/ x 7))) (local xoffset-left (% x 7)) (local xoffset-right (- xoffset-left 7)) (local yoffset (+ (- row y) 1)) (set result (paint-byte-at result brush row xbyte xoffset-left yoffset)) (set result (paint-byte-at result brush row (+ xbyte 1) xoffset-right yoffset))) result) (fn ScreenEditView.draw-screen-editor [self x y] (local (w h) (values (* screenw screen-scale) (* screenh screen-scale))) (activate self :screen x y w h) (var screen self.screen) (when (and self.itile (mouse-inside x y w h)) (local mx (math.floor (/ (- (love.mouse.getX) x) screen-scale))) (local my (math.floor (/ (- (love.mouse.getY) y) screen-scale))) (set screen (paint screen (. self.tilecache.tiles self.itile) (bit.band (- mx 3) 0xfffe) (- my 4))) (when (active? self :screen) (set self.screen screen))) (for [scany 0 (- screenh 1)] (local scanline (or (. self.scanlines scany) {})) (local ibyte (screen-y-to-offset scany)) (local linehash (screen:sub (+ ibyte 1) (+ ibyte 40))) (when (not= scanline.linehash linehash) (set scanline.linehash linehash) (set scanline.sprite (scanline-to-sprite screen scany)) (tset self.scanlines scany scanline)) (love.graphics.draw scanline.sprite x (+ y (* scany screen-scale)) 0 screen-scale screen-scale))) (fn ScreenEditView.reload [self] (ScreenEditView.super.reload self) (local (loaded screen) (pcall #(util.readjson self.screenfilename))) (set self.screen (if (not loaded) (string.rep "\0" 0x2000) (screen:fromhex)))) (fn ScreenEditView.save [self] (util.writejson self.screenfilename (self.screen:tohex))) (fn ScreenEditView.draw [self] (self:draw_background style.background) (love.graphics.setColor 1 1 1 1) (self:draw-screen-editor (+ self.position.x 10) (+ self.position.y 10)) (self:draw-tile-selector (+ self.position.x 10) (+ self.position.y 20 (* screenh screen-scale)) (- self.size.x 20))) (fn ScreenEditView.resource-key [self] "brushes") (fn ScreenEditView.tilesize [self] (values 8 8)) (fn ScreenEditView.get_name [self] (.. "Screen: " self.screenfilename)) ScreenEditView