( Nasu : pixel editor ) |00 @System/vector $2 &pad $6 &r $2 &g $2 &b $2 |10 @Console/vector $2 &read $1 &pad $5 &write $1 |20 @Screen/vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 |80 @Controller/vector $2 &button $1 &key $1 |90 @Mouse/vector $2 &x $2 &y $2 &state $1 &chord $1 |a0 @File/vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 |000 @state/timer $1 @settings/depth $1 &color $1 &blend $1 &ratio $1 &tool $1 &focus $2 &zoom $1 &brush $1 &dir $1 @cursor/x $2 &y $2 &last $1 @selection &x1 $1 &y1 $1 &x2 $1 &y2 $1 &zx $1 &zy $1 &a $1 @frame &x1 $2 &y1 $2 &x2 $2 &y2 $2 &width $2 &height $2 @filepath $40 ( ext ) $4 @toolview &x1 $2 &y1 $2 &x2 $2 &y2 $2 @colorview &x1 $2 &y1 $2 &x2 $2 &y2 $2 @blendview &x1 $2 &y1 $2 &x2 $2 &y2 $2 @dataview &x1 $2 &y1 $2 &x2 $2 &y2 $2 @preview &x1 $2 &y1 $2 &x2 $2 &y2 $2 @zoomview &x1 $2 &y1 $2 &x2 $2 &y2 $2 @tileview &x1 $2 &y1 $2 &x2 $2 &y2 $2 @nametableview &x $2 &y $2 &x2 $2 &y2 $2 |100 @on-reset ( -> ) ( | meta ) ;meta #06 DEO2 ( | theme ) #079f .System/r DEO2 #0d7f .System/g DEO2 #0cdf .System/b DEO2 ( | size ) #012e .Screen/width DEO2 #00f0 .Screen/height DEO2 ( | vectors ) ;on-console .Console/vector DEO2 ( | set defaults ) #0108 .frame/width STZ2 #00c8 .frame/height STZ2 [ LIT2 01 -settings/depth ] STZ [ LIT2 01 -settings/color ] STZ [ LIT2 81 -settings/blend ] STZ [ LIT2 32 -settings/ratio ] STZ [ LIT2 01 -settings/tool ] STZ [ LIT2 00 -settings/brush ] STZ ( | place ) .Screen/width DEI2 #01 SFT2 .frame/width LDZ2 #01 SFT2 SUB2 #001b .frame/width LDZ2 .frame/height LDZ2 ;frame .frame/x1 LDZ2 #0001 SUB2 .frame/y1 LDZ2 #0038 ADD2 #007f DUP2 ;tileview .frame/x1 LDZ2 #0089 ADD2 .frame/y1 LDZ2 #0038 ADD2 #007f DUP2 ;nametableview .frame/x1 LDZ2 #0001 SUB2 .frame/y1 LDZ2 #001f #002f ;zoomview .frame/x1 LDZ2 #002f ADD2 .frame/y1 LDZ2 #001f #002f ;preview .frame/x1 LDZ2 #005f ADD2 .frame/y1 LDZ2 #0020 #002f ;colorview .frame/x1 LDZ2 #008f ADD2 .frame/y1 LDZ2 #001f #002f ;blendview .frame/x1 LDZ2 #00bf ADD2 .frame/y1 LDZ2 #0048 #002f ;dataview .tileview/x1 LDZ2 .tileview/y2 LDZ2 #0008 ADD2 .frame/width LDZ2 #0008 ;toolview ( | static drawings ) load-theme ( | begin ) file-new untrap BRK @meta 00 &body ( name ) "Nasu 0a ( details ) "A 20 "Sprite 20 "Editor 0a ( author ) "By 20 "Hundred 20 "Rabbits 0a ( date ) "11 20 "Mar 20 "2026 00 01 ( icon ) 83 =appicon @manifest ( ... ) ( > ) 09 "Nasu $1 ( - ) 00 00 =about/toggle "About $1 ( - ) 01 "n =file-new "New $1 ( - ) 01 "r =trap "Rename $1 ( - ) 01 "o =file-open "Open $1 ( - ) 00 00 =file-open-mono "OpenMono $1 ( - ) 01 "s =file-save "Save $1 ( - ) 00 00 =file-save-mono "SaveMono $1 ( - ) 01 "p =save-theme "SaveTheme $1 ( - ) 01 "q =exit "Exit $1 ( > ) 0a "Edit $1 ( - ) 01 "c =edit-copy-chr "Copy $1 ( - ) 05 "C =edit-copy-icn "CopyMono $1 ( - ) 01 "v =edit-paste "Paste $1 ( - ) 05 "V =edit-paste-icn "PasteMono $1 ( - ) 01 "x =edit-cut "Cut $1 ( - ) 00 08 =edit-erase "Erase $1 ( - ) 00 "i =edit-invert "Invert $1 ( - ) 00 "c =edit-colorize "Colorize $1 ( - ) 00 00 =edit-flipx "Horizontal $1 ( - ) 00 00 =edit-flipy "Veritcal $1 ( > ) 02 "Options $1 ( - ) 02 00 =toggle-zoom "Zoom $1 ( - ) 00 "d =toggle-dir "Direction $1 ( > ) 0a "Move $1 ( - ) 10 00 =move-up "Up $1 ( - ) 20 00 =move-down "Down $1 ( - ) 40 00 =move-left "Left $1 ( - ) 80 00 =move-right "Right $1 ( - ) 14 00 =move-dech "Decr.H $1 ( - ) 24 00 =move-inch "Incr.H $1 ( - ) 44 00 =move-decw "Decr.W $1 ( - ) 84 00 =move-incw "Incr.W $1 ( - ) 00 1b =move-reset "Reset $1 ( - ) 01 "a =select-all "SelectAll $1 ( > ) 07 "Tool $1 ( - ) 00 "q =tool-brush "Brush $1 ( - ) 00 "w =tool-selector "Selector $1 ( - ) 00 "e =tool-zoom "Zoom $1 ( - ) 00 "1 =pick-color1 "Background $1 ( - ) 00 "2 =pick-color2 "ColorA $1 ( - ) 00 "3 =pick-color3 "ColorB $1 ( - ) 00 "4 =pick-color4 "ColorC $1 $1 ( @|vectors ) @untrap ( -- ) #0000 .Screen/vector DEO2 ;on-button .Controller/vector DEO2 ;on-mouse .Mouse/vector DEO2 #01 ( release mouse ) [ LIT2 00 -Mouse/state ] DEO JMP2r @trap ( -- ) ;on-frame-trap .Screen/vector DEO2 ;on-button-trap .Controller/vector DEO2 ;on-mouse-trap .Mouse/vector DEO2 ( | clear cursor ) #40 ( release mouse ) [ LIT2 00 -Mouse/state ] DEO JMP2r @on-console ( -> ) #00 ( | start ) [ LIT &listening $1 ] ?{ #01 ,&listening STR ;filepath #0040 } .Console/read DEI DUPk #1f GTH SWP #7f LTH AND ?{ #00 ,&listening STR } capture-trap #01 BRK @on-button-trap ( -> ) #00 .Controller/key DEI DUP #0d EQU #03 MUL SUB capture-trap #01 BRK @capture-trap ( button -- ) DUP ?{ POP JMP2r } [ #08 ] NEQk NIP ?{ ;filepath spop POP JMP2r } [ #0a ] NEQk NIP ?{ file-open } [ #7f ] NEQk NIP ?{ ;filepath #0040 POP JMP2r } [ #20 ] GTHk NIP ?{ untrap POP JMP2r } ;filepath slen NIP #3f EQU ?{ DUP ;filepath sput } POP JMP2r @on-mouse-trap ( -> ) ( | release trap on touch ) .Mouse/state DEI ?{ BRK } untrap BRK @on-frame-trap ( -> ) .state/timer LDZ DUP #07 AND ?{ DUP #03 SFT #01 AND #30 SFT INC } INC .state/timer STZ BRK @on-button ( -> ) .Controller/button DEI2 find-modkey ORAk #00 EQU ?{ DUP2 JSR2 } POP2 BRK @on-mouse ( -> ) .Mouse/y DEI2 #000c LTH2 ?trap-menu ( color ) [ LIT2 42 -Mouse/state ] DEI #00 NEQ ADD ( addr* ) ;brush-icn #00 .settings/tool LDZ #30 SFT ADD2 update-cursor [ LIT2 01 -Screen/auto ] DEO .Mouse/state DEI #00 EQU ?{ .Mouse/x DEI2 .Mouse/y DEI2 .tileview within-rect ?on-touch-tileview .Mouse/x DEI2 .Mouse/y DEI2 .nametableview within-rect ?on-touch-nametable .Mouse/x DEI2 .Mouse/y DEI2 .toolview within-rect ?on-touch-toolview .Mouse/x DEI2 .Mouse/y DEI2 .blendview within-rect ?on-touch-blendview .Mouse/x DEI2 .Mouse/y DEI2 .colorview within-rect ?on-touch-colorview .Mouse/x DEI2 .Mouse/y DEI2 .preview within-rect ?on-touch-preview .Mouse/x DEI2 .Mouse/y DEI2 .zoomview within-rect ?on-touch-zoomview } ( | release-record ) #0000 .Mouse/state DEO .cursor/last STZ BRK @on-touch-tileview ( -> ) .Mouse/x DEI2 .tileview/x1 LDZ2 SUB2 .Mouse/y DEI2 .tileview/y1 LDZ2 SUB2 ( | test ) #02 .settings/tool LDZ EQU ?&zoom #01 .settings/zoom LDZ EQU ?&zoomed #01 .settings/tool LDZ EQU ?&select ( | paint ) .settings/color LDZ .Mouse/state DEI #01 EQU MUL state/ BRK &zoom ( x* y* -> ) #33 SFT2 NIP STH #33 SFT2 NIP STHr toggle-zoom ( release mouse ) [ LIT2 00 -Mouse/state ] DEO BRK &zoomed ( x* y* -> ) SWP2 #03 SFT2 #00 .selection/zx LDZ ADD2 SWP2 #03 SFT2 #00 .selection/zy LDZ ADD2 .settings/color LDZ .Mouse/state DEI #01 EQU MUL state/ BRK &select ( x* y* -> ) #03 SFT2 NIP STH #03 SFT2 NIP STH SWPr .Mouse/state DEI DUP .cursor/last LDZ ORAk #00 EQU ?{ DUP2 #0100 NEQ2 ?{ STH2kr } DUP2 #0101 NEQ2 ?{ STH2kr } } POP2 POP2r .cursor/last STZ BRK @on-touch-nametable ( -> ) ( | id ) ( ) .Mouse/y DEI2 .nametableview/y LDZ2 SUB2 #43 SFT2 ( ) .Mouse/x DEI2 .nametableview/x LDZ2 SUB2 #03 SFT2 ADD2 #0003 MUL2 ;nametable ADD2 STH2 .settings/focus LDZ2 ;spritesheet SUB2 STH2kr STA2 .settings/blend LDZ INC2r INC2r STH2r STA state/ BRK @on-touch-toolview ( -> ) ( release mouse ) [ LIT2 00 -Mouse/state ] DEO .Mouse/x DEI2 .toolview/x1 LDZ2 SUB2 #03 SFT2 NIP ( ) [ #20 ] NEQk NIP ?{ file-save POP BRK } [ #1e ] NEQk NIP ?{ file-open POP BRK } [ #1d ] NEQk NIP ?{ file-new POP BRK } [ #04 ] NEQk NIP ?{ #00 POP BRK } [ #05 ] NEQk NIP ?{ #01 POP BRK } [ #06 ] NEQk NIP ?{ #02 } INCk .settings/color LDZ NEQ ?{ #00 POP BRK } [ #02 ] GTHk NIP ?{ INCk POP BRK } [ #08 ] LTHk NIP ?{ trap POP BRK } POP BRK @on-touch-zoomview ( -> ) .Mouse/y DEI2 .zoomview/y1 LDZ2 SUB2 #0020 LTH2 ?{ .Mouse/x DEI2 .zoomview/x1 LDZ2 SUB2 #03 SFT2 NIP ( ) DUP #00 EQU .Mouse/state DEI #01 EQU #0101 NEQ2 ?{ ;op-shiftu state/ } DUP #00 EQU .Mouse/state DEI #01 GTH #0101 NEQ2 ?{ ;op-shiftd state/ } DUP #01 EQU .Mouse/state DEI #01 EQU #0101 NEQ2 ?{ ;op-shiftr state/ } DUP #01 EQU .Mouse/state DEI #01 GTH #0101 NEQ2 ?{ ;op-shiftl state/ } POP ( release mouse ) [ LIT2 00 -Mouse/state ] DEO !&finish } .Mouse/x DEI2 .zoomview/x1 LDZ2 SUB2 #02 SFT2 #00 .selection/x1 LDZ #30 SFT2 ADD2 ( ) .Mouse/y DEI2 .zoomview/y1 LDZ2 SUB2 #02 SFT2 #00 .selection/y1 LDZ #30 SFT2 ADD2 .settings/color LDZ .Mouse/state DEI #01 EQU MUL &finish state/ BRK @on-touch-preview ( -> ) ( y ) .Mouse/y DEI2 .preview/y1 LDZ2 SUB2 #03 SFT2 NIP #03 AND ( x ) .Mouse/x DEI2 .preview/x1 LDZ2 SUB2 #03 SFT2 NIP #40 SFT ADD #11 ADD .settings/ratio STZ ( release mouse ) [ LIT2 00 -Mouse/state ] DEO BRK @on-touch-colorview ( -> ) .Mouse/y DEI2 .colorview/y1 LDZ2 SUB2 #03 SFT2 NIP ( ) [ #00 ] NEQk NIP ?{ .System/r STHk /set-color STHr /set-nibble } ( ) [ #01 ] NEQk NIP ?{ .System/g STHk /set-color STHr /set-nibble } ( ) [ #02 ] NEQk NIP ?{ .System/b STHk /set-color STHr /set-nibble } POP BRK &set-nibble ( -- ) .settings/color LDZ #01 SFT ADD DEO JMP2r &set-color ( -- ) .settings/color LDZ STHk #01 SFT ADD DEI STHr #01 AND STHk #0f SWP [ #60 SFT SFT ] AND STHr #00 EQU .Mouse/x DEI2 .colorview/x1 LDZ2 SUB2 #01 SFT2 NIP ( clamp to #0f ) DUP #01 GTH SUB SWP [ #60 SFT SFT ] ADD JMP2r @on-touch-blendview ( -> ) ( ) .Mouse/x DEI2 .blendview/x1 LDZ2 SUB2 #03 SFT2 NIP ( ) .Mouse/y DEI2 .blendview/y1 LDZ2 SUB2 #03 SFT2 NIP #20 SFT ADD [ #0f GTHk NIP ] ?{ DUP .settings/blend STHk LDZ #b0 AND ADD STHr STZ !&end } #03 AND ( ) [ #02 NEQk NIP ] ?{ .settings/blend STHk LDZ #20 EOR STHr STZ } ( ) [ #03 NEQk NIP ] ?{ .settings/blend STHk LDZ #10 EOR STHr STZ } &end POP ( | release mouse ) [ LIT2 00 -Mouse/state ] DEO BRK ( @|helpers ) @toggle-dir ( -- ) [ LIT2 00 -settings/dir ] LDZ EQU .settings/dir STZ ! @toggle-zoom ( -- ) .settings/zoom LDZk #00 EQU SWP STZ ! @ ( color -- ) .settings/color STZ ! @ ( tool -- ) .settings/tool STZ ! @clamp-selection ( -- ) ( ) .selection/x1 LDZ #0f STHk LTH ?&ok-limitx1 STHkr .selection/x1 STZ &ok-limitx1 POPr ( ) .selection/y1 LDZ #0f STHk LTH ?&ok-limity1 STHkr .selection/y1 STZ &ok-limity1 POPr ( ) .selection/x2 LDZ #0f STHk LTH ?&ok-limitx2 STHkr .selection/x2 STZ &ok-limitx2 POPr ( ) .selection/y2 LDZ #0f STHk LTH ?&ok-limity2 STHkr .selection/y2 STZ &ok-limity2 POPr ( | invert ) ( ) .selection/x2 LDZ .selection/x1 LDZ STHk GTH ?&ok-flipx STHkr .selection/x2 STZ &ok-flipx POPr ( ) .selection/y2 LDZ .selection/y1 LDZ STHk GTH ?&ok-flipy STHkr .selection/y2 STZ &ok-flipy POPr JMP2r @ ( x y -- ) #7f AND .selection/zy STZ #7f AND .selection/zx STZ JMP2r @ ( x y -- ) #0f AND ( ) DUP .selection/y1 STZ ( ) .selection/y2 STZ #0f AND ( ) DUP .selection/x1 STZ ( ) .selection/x2 STZ ! @ ( x y -- ) .selection/y2 STZ .selection/x2 STZ clamp-selection ! @ ( -- ) .selection LDZ2 get-tile-addr .settings/focus STZ2 JMP2r @ ( x y -- ) .settings/zoom LDZ ? DUP .selection/y2 LDZ ADD #0f AND .selection/y2 STZ .selection/y1 LDZ ADD #0f AND .selection/y1 STZ DUP .selection/x2 LDZ ADD #0f AND .selection/x2 STZ .selection/x1 LDZ ADD #0f AND .selection/x1 STZ ( | clamp ) .selection/x2 LDZ .selection/x1 LDZ GTH ?{ .selection/x1 LDZ .selection/x2 STZ } .selection/y2 LDZ .selection/y1 LDZ GTH ?{ .selection/y1 LDZ .selection/y2 STZ } .selection/x1 LDZ #30 SFT .selection/y1 LDZ #30 SFT ( | focus ) ! @ ( x y -- ) ( | set zoom ) .selection/zy LDZ ADD SWP .selection/zx LDZ ADD SWP ( | set from ) .selection/zx LDZ #03 SFT .selection/zy LDZ #03 SFT ! @ ( x y -- ) .selection/y2 LDZ ADD #0f AND .selection/y2 STZ .selection/x2 LDZ ADD #0f AND .selection/x2 STZ ( | clamp ) .selection/x2 LDZ .selection/x1 LDZ GTH ?{ .selection/x1 LDZ .selection/x2 STZ } .selection/y2 LDZ .selection/y1 LDZ GTH ?{ .selection/y1 LDZ .selection/y2 STZ } ( | focus ) ! @is-mono ( filepath -- f ) scap #0004 SUB2 ( ) LDA2k [ LIT2 ".i ] EQU2 STH ( ) INC2 INC2 LDA2 [ LIT2 "cn ] EQU2 STHr AND JMP2r @get-tile-addr ( x y -- addr* ) #40 SFT ADD #00 SWP #40 SFT2 ;spritesheet ADD2 JMP2r @get-pixel ( x* y* -- color ) ( | channel 1 ) ( ) OVR2 SWP2 get-pixel-addr [ STH2k ] LDA ( ) ROT ROT NIP #07 AND [ STHk ] ( ) #07 SWP SUB SFT #01 AND ( | channel 2 ) ( ) [ STHr ] [ STH2r ] #0008 ADD2 LDA SWP ( ) #07 SWP SUB SFT #01 AND ( ) DUP ADD ADD JMP2r @get-pixel-addr ( x* y* -- addr* ) ( | clamp ) #007f AND2 SWP2 #007f AND2 SWP2 ( | get row ) DUP2 #0007 AND2 ( | get tile ) SWP2 #83 SFT2 ADD2 SWP2 #43 SFT2 ADD2 ;spritesheet ADD2 JMP2r @ ( x* y* color -- ) STH OVR2 SWP2 get-pixel-addr ( ch1 ) OVR2 OVR2 STHkr #00 ( ch2 ) #0008 ADD2 STHr #01 ( >> ) @ ( x* addr* color -- ) STH2 LDAk STH SWP2 NIP STHr SWP STH2r SFT #01 AND ?&do-set ( mask ) #0107 ROT #07 AND SUB #40 SFT SFT #ff EOR AND ( save ) ROT ROT STA JMP2r &do-set ( mask ) #0107 ROT #07 AND SUB #40 SFT SFT ORA ( save ) ROT ROT STA JMP2r @has-nametable ( -- bool ) ;nametable STH2k #0300 ADD2 STH2r &>loop LDAk #00 EQU ?{ POP2 POP2 #01 JMP2r } INC2 GTH2k ?&>loop POP2 POP2 #00 JMP2r @get-strw ( str* -- width* ) slen #30 SFT2 JMP2r @state/ ( -- ) [ LIT2 01 _&changed ] STR !/ @state/ ( -- ) [ LIT2 03 _&changed ] STR ( >> ) @state/ ( -- ) .toolview/x2 LDZ2 #0008 SUB2 .Screen/x DEO2 .toolview/y1 LDZ2 .Screen/y DEO2 ;save-icn .Screen/addr DEO2 [ LIT2 &changed $1 -Screen/sprite ] DEO JMP2r ( @|filter ) @ ( op* -- ) ,&fn STR2 .selection/y2 LDZ INC #30 SFT .selection/y1 LDZ #30 SFT &>ver STHk .selection/x2 LDZ INC #30 SFT .selection/x1 LDZ #30 SFT &>hor #00 OVR #00 STHkr [ LIT2 &fn $2 ] JSR2 INC GTHk ?&>hor POP2 POPr INC GTHk ?&>ver POP2 JMP2r @filter-colorize ( x* y* -- ) OVR2 OVR2 get-pixel INC #03 AND ! @filter-flipx ( x* y* -- ) ( | ignore second half ) OVR2 ( ) [ LIT2 00 -selection/x1 ] LDZ #30 SFT2 ( ) [ LIT2 00 -selection/x2 ] LDZ INC #30 SFT2 OVR2 SUB2 #01 SFT2 ( ) ADD2 LTH2 ?{ POP2 POP2 JMP2r } ( write ) STH2 DUP2 ,&x1 STR2 ( ) [ LIT2 00 -selection/x2 ] LDZ INC #30 SFT2 #0001 SUB2 SWP2 SUB2 ( ) [ LIT2 00 -selection/x1 ] LDZ #30 SFT2 ADD2 ,&x2 STR2 ( ) [ LIT2 &x1 $2 ] STH2kr get-pixel ,&c1 STR ( ) [ LIT2 &x2 $2 ] STH2kr get-pixel ,&c2 STR ,&x2 LDR2 STH2kr [ LIT &c1 $1 ] ,&x1 LDR2 STH2r [ LIT &c2 $1 ] ! @filter-flipy ( x* y* -- ) ( | ignore second half ) DUP2 ( ) [ LIT2 00 -selection/y1 ] LDZ #30 SFT2 ( ) [ LIT2 00 -selection/y2 ] LDZ INC #30 SFT2 OVR2 SUB2 #01 SFT2 ( ) ADD2 LTH2 ?{ POP2 POP2 JMP2r } ( | write ) DUP2 ,&y1 STR2 ( ) [ LIT2 00 -selection/y2 ] LDZ INC #30 SFT2 #0001 SUB2 SWP2 SUB2 [ LIT2 00 -selection/y1 ] LDZ #30 SFT2 ADD2 ,&y2 STR2 DUP2 [ LIT2 &y1 $2 ] get-pixel ,&c1 STR DUP2 [ LIT2 &y2 $2 ] get-pixel ,&c2 STR DUP2 ,&y2 LDR2 [ LIT &c1 $1 ] ,&y1 LDR2 [ LIT &c2 $1 ] ! ( @|map ) @ ( op* -- ) .settings/dir LDZ ? ,&fn STR2 .selection/y2 LDZ INC .selection/y1 LDZ &>ver .selection/x2 LDZ INC .selection/x1 LDZ &>hor OVR2 NIP OVR SWP get-tile-addr [ LIT2 &fn $2 ] JSR2 INC GTHk ?&>hor POP2 INC GTHk ?&>ver POP2 JMP2r @ ( op* -- ) ,&fn STR2 .selection/x2 LDZ INC .selection/x1 LDZ &>ver .selection/y2 LDZ INC .selection/y1 LDZ &>hor OVR2 NIP OVR get-tile-addr [ LIT2 &fn $2 ] JSR2 INC GTHk ?&>hor POP2 INC GTHk ?&>ver POP2 JMP2r @op-erase ( addr* -- ) #0010 ! @op-invert ( addr* -- ) ,&t STR2 #1000 &>loop #00 OVR [ LIT2 &t $2 ] ADD2 LDA2k #ffff EOR2 SWP2 STA2 INC INC GTHk ?&>loop POP2 JMP2r @op-shiftu ( addr* -- ) DUP2k #0007 ADD2 SWP2 LDAk STH &>ch1 INC2k LDA STH DUP2 STHr ROT ROT STA INC2 GTH2k ?&>ch1 POP2 ( cap ) STHr ROT ROT STA #0008 ADD2 DUP2 #0007 ADD2 SWP2 LDAk STH &>ch2 INC2k LDA STH DUP2 STHr ROT ROT STA INC2 GTH2k ?&>ch2 POP2 ( cap ) STHr ROT ROT STA JMP2r @op-shiftd ( addr* -- ) DUP2k #0007 ADD2 LDAk STH &>ch1 DUP2 #0001 SUB2 LDA STH DUP2 STHr ROT ROT STA #0001 SUB2 LTH2k ?&>ch1 POP2 ( cap ) STHr ROT ROT STA #0008 ADD2 DUP2 #0007 ADD2 LDAk STH &>ch2 DUP2 #0001 SUB2 LDA STH DUP2 STHr ROT ROT STA #0001 SUB2 LTH2k ?&>ch2 POP2 ( cap ) STHr ROT ROT STA JMP2r @op-shiftl ( addr* -- ) STH2 #0800 &>loop ( 1 ) #00 OVR STH2kr ADD2 ( 1 ) LDAk rol ROT ROT STA ( 2 ) #00 OVR STH2kr #0008 ADD2 ADD2 ( 2 ) LDAk rol ROT ROT STA INC GTHk ?&>loop POP2 POP2r JMP2r @op-shiftr ( addr* -- ) STH2 #0800 &>loop ( 1 ) #00 OVR STH2kr ADD2 ( 1 ) LDAk ror ROT ROT STA ( 2 ) #00 OVR STH2kr #0008 ADD2 ADD2 ( 2 ) LDAk ror ROT ROT STA INC GTHk ?&>loop POP2 POP2r JMP2r @op-read ( addr* -- ) .File/read DEO2 JMP2r @op-write ( addr* -- ) [ LIT2 &length $2 ] ( ) DUP2 .File/length DEO2 ( ) ;&buf SWP2 ;&buf .File/write DEO2 JMP2r &buf $10 ( @|drawing ) @ ( -- ) @ ( -- ) ! @ ( -- ) .settings/zoom LDZ ? .tileview/x1 LDZ2 .Screen/x DEO2 .tileview/y1 LDZ2 .Screen/y DEO2 ( | draw tiles ) ;spritesheet .Screen/addr DEO2 [ LIT2 f6 -Screen/auto ] DEO #1000 &>loop [ LIT2 81 -Screen/sprite ] DEO INC GTHk ?&>loop POP2 ( | draw selection ) #06 .selection/x2 LDZ .selection/x1 LDZ SUB #40 SFT ADD .Screen/auto DEO #00 .selection/x1 LDZ #30 SFT2 .tileview/x1 LDZ2 ADD2 .Screen/x DEO2 #00 .selection/y1 LDZ #30 SFT2 .tileview/y1 LDZ2 ADD2 .Screen/y DEO2 .selection LDZ2 get-tile-addr ,&sprite STR2 .selection/y2 LDZ .selection/y1 LDZ SUB INC #00 &>loop-sel #00 OVR #80 SFT2 [ LIT2 &sprite $2 ] ADD2 .Screen/addr DEO2 [ LIT2 84 -Screen/sprite ] DEO INC GTHk ?&>loop-sel POP2 [ LIT2 01 -Screen/auto ] DEO ( | draw selection size ) .selection/y2 LDZ #0f EQU ?{ .selection/x2 LDZ .selection/x1 LDZ SUB #02 LTH ?{ ( x ) [ LIT2 00 -selection/x1 ] LDZ #30 SFT2 .tileview/x1 LDZ2 ADD2 .Screen/x DEO2 ( y ) [ LIT2 00 -selection/y2 ] LDZ INC #30 SFT2 .tileview/y1 LDZ2 ADD2 .Screen/y DEO2 #04 ;/color STA ( w ) .selection/x2 LDZ .selection/x1 LDZ SUB INC #40 SFT ( h ) .selection/y2 LDZ .selection/y1 LDZ SUB INC ORA ( | draw dir ) ;dir-icn #00 .settings/dir LDZ #30 SFT2 ADD2 .Screen/addr DEO2 [ LIT2 05 -Screen/sprite ] DEO } } JMP2r @ ( -- ) ( | clear ) ;fill-icn .Screen/addr DEO2 .tileview/x1 LDZ2 .Screen/x DEO2 .tileview/y1 LDZ2 .Screen/y DEO2 [ LIT2 f2 -Screen/auto ] DEO #f0 &>times [ LIT2 00 -Screen/sprite ] DEO INC DUP ?&>times POP ( | draw ) [ LIT2 01 -Screen/auto ] DEO ;pixel-icn .Screen/addr DEO2 #1000 &>ver #00 OVR #30 SFT .tileview/y1 LDZ2 ADD2 .Screen/y DEO2 .tileview/x1 LDZ2 .Screen/x DEO2 #1000 &>hor OVR2 NIP OVR SWP ( y ) .selection/zy LDZ ADD #00 SWP ( x ) ROT .selection/zx LDZ ADD #00 SWP SWP2 get-pixel .Screen/sprite DEO INC GTHk ?&>hor POP2 INC GTHk ?&>ver POP2 ( | guide hor ) #0007 .selection/zy LDZ SUB #0007 AND2 #30 SFT2 #0001 SUB2 #0008 ADD2 STH2 .tileview/x1 LDZ2 .tileview/y1 LDZ2 STH2kr ADD2 #0a .selection/zy LDZ #07 AND #00 EQU ?{ .tileview/x1 LDZ2 .tileview/y1 LDZ2 STH2kr ADD2 #0040 ADD2 #0a } POP2r ( | guide ver ) #0007 .selection/zx LDZ SUB #0007 AND2 #30 SFT2 #0001 SUB2 #0008 ADD2 STH2 .tileview/x1 LDZ2 STH2kr ADD2 .tileview/y1 LDZ2 #0a .selection/zx LDZ #07 AND #00 EQU ?{ .tileview/x1 LDZ2 STH2kr ADD2 #0040 ADD2 .tileview/y1 LDZ2 #0a } POP2r JMP2r @ ( -- ) [ LIT2 00 -Screen/auto ] DEO #1000 &>ver ( > y ) #00 OVR #30 SFT2 .nametableview/y LDZ2 ADD2 .Screen/y DEO2 STHk .nametableview/x LDZ2 .Screen/x DEO2 #1000 &>hor ( > x ) #00 OVR #30 SFT2 .nametableview/x LDZ2 ADD2 .Screen/x DEO2 ( id ) #00 OVR STHkr #40 SFT ADD ( addr* ) #0003 MUL2 ;nametable ADD2 LDA2k ;spritesheet ADD2 .Screen/addr DEO2 ( color ) INC2 INC2 LDA .Screen/sprite DEO INC GTHk ?&>hor POP2 POPr .nametableview/x LDZ2 .Screen/x DEO2 INC GTHk ?&>ver POP2 JMP2r @ ( -- ) ;bigpixel-icn .Screen/addr DEO2 #0800 &>ver #00 OVRk #00 .selection/y1 LDZ #30 SFT ADD2 ,&y STR2 #20 SFT .zoomview/y1 LDZ2 ADD2 .Screen/y DEO2 #0800 &>hor #00 OVRk #00 .selection/x1 LDZ #30 SFT ADD2 ,&x STR2 #20 SFT .zoomview/x1 LDZ2 ADD2 .Screen/x DEO2 [ LIT2 &x $2 ] [ LIT2 &y $2 ] get-pixel .Screen/sprite DEO INC GTHk ?&>hor POP2 INC GTHk ?&>ver POP2 ( | frame ) .zoomview/x1 LDZ2 .Screen/x DEO2 .zoomview/y1 LDZ2 .Screen/y DEO2 #0404 ;frame2-chr ( | label ) [ LIT2 01 -Screen/auto ] DEO .zoomview/y2 LDZ2 #0008 SUB2 .Screen/y DEO2 .zoomview/x1 LDZ2 .Screen/x DEO2 ;arrow-ver-icns .Screen/addr DEO2 [ LIT2 02 -Screen/sprite ] DEO ;arrow-hor-icns .Screen/addr DEO2 [ LIT2 02 -Screen/sprite ] DEO JMP2r @ ( -- ) ( | stash address ) .settings/focus LDZ2 STH2k .Screen/addr DEO2 #0400 &>ver #00 OVR #30 SFT .preview/y1 LDZ2 ADD2 .Screen/y DEO2 #0400 &>hor #00 OVR #30 SFT .preview/x1 LDZ2 ADD2 .Screen/x DEO2 ( | get x,y ) OVR2 NIP OVR SWP ( | check if within ratio ) .settings/ratio LDZ #0f AND LTH STH .settings/ratio LDZ #04 SFT LTH STHr #0101 NEQ2 ?&outside ( get tile ) STH2kr .Screen/addr DEO2 ( get blending ) .settings/blend LDZ .Screen/sprite DEO ( incr ) STH2r #0008 [ .settings/depth LDZ #30 SFT #00 SWP ADD2 ] ADD2 STH2 !&resume &outside ;halftone-icn .Screen/addr DEO2 [ LIT2 03 -Screen/sprite ] DEO &resume INC GTHk ?&>hor POP2 INC GTHk ?&>ver POP2 POP2r ( | label ) .preview/x1 LDZ2 .Screen/x DEO2 .preview/y2 LDZ2 #0008 SUB2 .Screen/y DEO2 #03 ;/color STA .settings/ratio LDZ ! @ ( -- ) .colorview/y2 LDZ2 #0008 SUB2 .Screen/y DEO2 .colorview/x1 LDZ2 .Screen/x DEO2 #03 ;/color STA .System/r /get-color .System/g /get-color .System/b /get-color .colorview/x1 LDZ2 .colorview/y1 LDZ2 [ LIT2 00 -Screen/auto ] DEO OVR2 OVR2 .System/r /get-color /slider OVR2 OVR2 #0008 ADD2 .System/g /get-color /slider #0010 ADD2 .System/b /get-color /slider [ LIT2 01 -Screen/auto ] DEO JMP2r &slider ( x* y* value -- ) STH .Screen/y DEO2 .Screen/x DEO2 #1000 &>loop DUP STHkr GTH #30 SFT #00 SWP ;slider-icns ADD2 .Screen/addr DEO2 [ LIT2 02 -Screen/sprite ] DEO .Screen/x DEI2k INC2 INC2 ROT DEO2 INC GTHk ?&>loop POP2 POPr JMP2r &get-color .settings/color LDZ STHk #01 SFT ADD DEI #01 STHr #01 AND SUB #20 SFT SFT #0f AND JMP2r @ ( -- ) [ LIT2 00 -Screen/auto ] DEO #1000 &>loop #00 OVR #03 AND #30 SFT2 .blendview/x1 LDZ2 ADD2 .Screen/x DEO2 #00 OVR #32 SFT2 .blendview/y1 LDZ2 ADD2 .Screen/y DEO2 ;fill-icn .Screen/addr DEO2 [ LIT2 00 -Screen/sprite ] DEO .settings/focus LDZ2 .Screen/addr DEO2 DUP .settings/blend LDZ #b0 AND ADD .Screen/sprite DEO INC GTHk ?&>loop POP2 [ LIT2 01 -Screen/auto ] DEO ( | label ) .blendview/x1 LDZ2 .Screen/x DEO2 .blendview/y2 LDZ2 #0008 SUB2 .Screen/y DEO2 #03 ;/color STA ( get blending ) .settings/blend LDZ ( | y ) .blendview/x1 LDZ2 #0010 ADD2 .Screen/x DEO2 .settings/blend LDZ #20 AND #00 NEQ STH ;arrow-ver-icns #00 STHkr #30 SFT2 ADD2 .Screen/addr DEO2 #02 STHr SUB .Screen/sprite DEO ( | x ) .blendview/x1 LDZ2 #0018 ADD2 .Screen/x DEO2 .settings/blend LDZ #10 AND #00 NEQ STH ;arrow-hor-icns #00 STHkr #30 SFT2 ADD2 .Screen/addr DEO2 #02 STHr SUB .Screen/sprite DEO JMP2r @ ( -- ) ( | position ) .dataview/x1 LDZ2 .Screen/x DEO2 .dataview/y2 LDZ2 #0008 SUB2 .Screen/y DEO2 #03 ;/color STA .selection LDZ2 SWP #40 SFT ADD .dataview/y1 LDZ2 .Screen/y DEO2 #0400 &>loop .dataview/x1 LDZ2 .Screen/x DEO2 #00 OVR DUP ADD .settings/focus LDZ2 ADD2 #01 ;/color STA ( ch1 ) LDA2k .Screen/x DEI2k #000c ADD2 ROT DEO2 #02 ;/color STA ( ch2 ) #0008 ADD2 LDA2 ( | skip line ) .dataview/x1 LDZ2 .Screen/x DEO2 INC GTHk ?&>loop POP2 JMP2r @ ( -- ) .toolview/y1 LDZ2 .Screen/y DEO2 ( | colors ) .toolview/x1 LDZ2 .Screen/x DEO2 ;circle-icns #00 .settings/color LDZ #01 EQU #30 SFT2 ADD2 .Screen/addr DEO2 [ LIT2 01 -Screen/sprite ] DEO ;circle-icns #00 .settings/color LDZ #02 EQU #30 SFT2 ADD2 .Screen/addr DEO2 [ LIT2 02 -Screen/sprite ] DEO ;circle-icns #00 .settings/color LDZ #03 EQU #30 SFT2 ADD2 .Screen/addr DEO2 [ LIT2 03 -Screen/sprite ] DEO ( | tools ) .Screen/x DEI2k #0008 ADD2 ROT DEO2 ;brush-icn .Screen/addr DEO2 #01 .settings/tool LDZ #00 EQU ADD .Screen/sprite DEO ;select-icn .Screen/addr DEO2 #01 .settings/tool LDZ #01 EQU ADD .Screen/sprite DEO ;zoom-icns [ #00 .settings/zoom LDZ #30 SFT2 ADD2 ] .Screen/addr DEO2 #01 .settings/tool LDZ #02 EQU ADD .Screen/sprite DEO ( | file i/o ) state/ .toolview/x2 LDZ2 STH2k #0018 SUB2 .Screen/x DEO2 ;load-icn .Screen/addr DEO2 [ LIT2 01 -Screen/sprite ] DEO STH2r #0020 SUB2 .Screen/x DEO2 ;make-icn .Screen/addr DEO2 [ LIT2 01 -Screen/sprite ] DEO ( | filepath ) #01 ! @ ( color -- ) .toolview/x1 LDZ2 #0040 ADD2 .Screen/x DEO2 .toolview/y1 LDZ2 INC2 .Screen/y DEO2 ( | clear ) DUP #00 EQU ? ;/color STA ;filepath ( | scroll ) DUP2 slen #0013 GTH2 #00 SWP ;filepath slen #0013 SUB2 MUL2 ADD2 POP2 JMP2r @ ( color -- ) POP ;fill-icn .Screen/addr DEO2 [ LIT2 01 -Screen/auto ] DEO #1300 &>l [ LIT2 00 -Screen/sprite ] DEO INC GTHk ?&>l POP2 JMP2r @ ( width color auto addr* -- ) .Screen/addr DEO2 &blank .Screen/auto DEO STH #00 &>l2 STHkr .Screen/sprite DEO INC GTHk ?&>l2 POP2 POPr JMP2r @ ( -- ) .tileview/x1 LDZ2 .Screen/x DEO2 .tileview/y1 LDZ2 .Screen/y DEO2 #1010 ;frame2-chr .nametableview/x LDZ2 .Screen/x DEO2 .nametableview/y LDZ2 .Screen/y DEO2 #1010 ;frame2-chr [ LIT2 01 -Screen/auto ] DEO JMP2r ( drawing primitives ) @ ( text* -- ) DUP2 get-strw STH2 .Screen/x DEI2k STH2r SUB2 ROT DEO2 @ ( str* -- str* ) LDAk #00 EQU ?{ [ LIT2 01 -Screen/auto ] DEO &>while LDAk INC2 LDAk ?&>while } INC2 JMP2r @ ( short* -- ) SWP @ ( byte -- ) DUP #04 SFT @ ( char -- ) #0f AND DUP #09 GTH #27 MUL ADD #30 ADD ( >> ) @ ( char -- ) #20 SUB #00 SWP #30 SFT2 ;font ADD2 .Screen/addr DEO2 [ LIT2 &color 03 -Screen/sprite ] DEO JMP2r @ ( w h chr* -- ) STH2 ,&h STR ,&w STR .Screen/x DEI2 DUP2 #0008 SUB2 .Screen/x DEO2 .Screen/y DEI2 #0008 SUB2 DUP2 .Screen/y DEO2 ( ul ) #00 STH2kr #05 /single ( uu ) [ LIT &w $1 ] #00 STH2kr #0010 ADD2 #01 /repeat ( ur ) #10 STH2kr #06 ,&single JSR ( rr ) [ LIT &h $1 ] #00 STH2kr #0020 ADD2 #02 /repeat #0008 ADD2 .Screen/y DEO2 #0008 SUB2 .Screen/x DEO2 ( ll ) ,&h LDR #10 STH2kr #0020 ADD2 #02 /repeat ( dl ) #20 STH2kr #01 ,&single JSR ( bb ) ,&w LDR #20 STH2kr #0010 ADD2 #01 /repeat ( dr ) #30 STH2r #00 !&single &repeat ( times color addr* auto -- ) .Screen/auto DEO .Screen/addr DEO2 STH #00 &>l STHkr /paint INC GTHk ?&>l POP2 POPr JMP2r &single ( color addr* auto -- ) .Screen/auto DEO .Screen/addr DEO2 &paint ( mask -- ) [ LIT &color 85 ] SWP ORA .Screen/sprite DEO JMP2r @ ( x* y* color -- ) STH .Screen/y DEO2 .Screen/x DEO2 ;&sprite .Screen/addr DEO2 [ LIT2 f2 -Screen/auto ] DEO STHr .Screen/sprite DEO [ LIT2 01 -Screen/auto ] DEO JMP2r &sprite aa00 0000 0000 0000 @ ( x* y* color -- ) STH .Screen/y DEO2 .Screen/x DEO2 ;&sprite .Screen/addr DEO2 [ LIT2 f1 -Screen/auto ] DEO STHr .Screen/sprite DEO [ LIT2 01 -Screen/auto ] DEO JMP2r &sprite 8000 8000 8000 8000 ( @|options ) @file-new ( -- ) #00 ( | clear ) ;spritesheet #1300 ( | rename to untitled.txt ) ;filepath #0040 ;untitled-txt ;filepath state/ ! @file-open ( -- ) ;filepath is-mono ?file-open-mono ( | clear ) ;spritesheet #1300 load-theme ( | spritesheet ) ;filepath .File/name DEO2 #1000 .File/length DEO2 ;spritesheet .File/read DEO2 ( | nametable ) ;nametable-ext ;filepath scap #0004 ;filepath .File/name DEO2 #0300 .File/length DEO2 ;nametable .File/read DEO2 ;filepath scap #0004 SUB2 #0004 state/ ! @file-open-mono ( -- ) ;spritesheet #1300 ( | spritesheet ) ;filepath .File/name DEO2 #0008 .File/length DEO2 #0000 &>loop #00 OVR #40 SFT2 ;spritesheet ADD2 .File/read DEO2 INC NEQk ?&>loop POP2 state/ ! @file-save ( -- ) ;filepath is-mono ?file-save-mono ( | spritesheet ) ;filepath .File/name DEO2 #1000 .File/length DEO2 ;spritesheet .File/write DEO2 ( | nametable ) has-nametable #00 EQU ?{ ;nametable-ext ;filepath scap #0004 ;filepath .File/name DEO2 #0300 .File/length DEO2 ;nametable .File/write DEO2 ;filepath scap #0004 SUB2 #0004 } !state/ @file-save-mono ( -- ) ;filepath .File/name DEO2 #0008 .File/length DEO2 #0000 &>loop #00 OVR #40 SFT2 ;spritesheet ADD2 .File/write DEO2 INC NEQk ?&>loop POP2 !state/ @save-theme ( -- ) .System/r DEI2 #fffa STA2 .System/g DEI2 #fffc STA2 .System/b DEI2 #fffe STA2 ;load-theme/path .File/name DEO2 #0006 .File/length DEO2 #fffa .File/write DEO2 JMP2r @snarf-txt ".snarf $1 @edit-copy-icn ( -- ) ;snarf-txt .File/name DEO2 #0008 ;op-write/length STA2 ;op-write ! @edit-copy-chr ( -- ) ;snarf-txt .File/name DEO2 #0010 ;op-write/length STA2 ;op-write ! @edit-paste ( -- ) ;snarf-txt .File/name DEO2 #0010 .File/length DEO2 ;op-read state/ ! @edit-paste-icn ( -- ) ;snarf-txt .File/name DEO2 #0008 .File/length DEO2 ;op-read state/ ! @edit-cut ( -- ) edit-copy-chr ;op-erase state/ ! @edit-erase ( -- ) ;op-erase state/ ! @edit-invert ( -- ) ;op-invert state/ ! @edit-colorize ( -- ) ;filter-colorize state/ ! @edit-flipx ( -- ) ;filter-flipx state/ ! @edit-flipy ( -- ) ;filter-flipy state/ ! @tool-brush ( -- ) #00 ! @tool-selector ( -- ) #01 ! @tool-zoom ( -- ) #02 ! @move-up ( -- ) #00ff ! @move-down ( -- ) #0001 ! @move-left ( -- ) #ff00 ! @move-right ( -- ) #0100 ! @move-dech ( -- ) #00ff ! @move-inch ( -- ) #0001 ! @move-decw ( -- ) #ff00 ! @move-incw ( -- ) #0100 ! @move-reset ( -- ) .selection/x1 LDZ2 .selection/x2 STZ2 ! @select-all ( -- ) #0000 #0f0f ! ( pick ) @pick-color1 ( -- ) #00 ! @pick-color2 ( -- ) #01 ! @pick-color3 ( -- ) #02 ! @pick-color4 ( -- ) #03 ! @ ( x1 y1 w* h* rect* -- ) STH2 ( | size to rect ) STH2 STH2 OVR2 STH2r ADD2 OVR2 STH2r ADD2 STH2r DUP2 ROT2 SWP2 #0006 ADD2 STA2 DUP2 ROT2 SWP2 #0004 ADD2 STA2 DUP2 ROT2 SWP2 INC2 INC2 STA2 DUP2 ROT2 SWP2 STA2 POP2 JMP2r @within-rect ( x* y* rect -- flag ) STH ( y LTH rect.y1 ) DUP2 STHkr INC2 INC2 LDZ2 LTH2 ?&skip ( y GTH rect.y2 ) DUP2 STHkr #06 ADD LDZ2 GTH2 ?&skip SWP2 ( x LTH rect.x1 ) DUP2 STHkr LDZ2 LTH2 ?&skip ( x GTH rect.x2 ) DUP2 STHkr #04 ADD LDZ2 GTH2 ?&skip POP2 POP2 POPr #01 JMP2r &skip POP2 POP2 POPr #00 JMP2r ( @|stdlib ) @rol ( byte -- byte ) DUP #07 SFT SWP DUP ADD ADD JMP2r @ror ( byte -- byte ) DUP #70 SFT SWP #01 SFT ADD JMP2r @ ( src* dst* len* -- ) SWP2 STH2 OVR2 ADD2 SWP2 &>loop LDAk STH2kr STA INC2r INC2 GTH2k ?&>loop POP2 POP2 POP2r JMP2r ( @|assets ) @untitled-txt "untitled10x10.chr $1 @nametable-ext ".nmt $1 ~src/manifest.tal