uxn/projects/software/noodle.usm

612 lines
14 KiB
Plaintext

(
app/noodle : illustration program
alt-click - drag canvas
TODO
- Only draw-canvas when mouse has changed
- Only draw-canvas target tile
- Resize buttons
- Zoom
- Clear all button
- Toggle guides
- Complete save/load
- Limit size
- Draw point inbetween
- Pixel cleanup brush
)
%RTN { JMP2r }
%RTN? { JMP2r? }
%++ { #0001 ADD2 } %-- { #0001 SUB2 }
%2/ { #0001 SHR2 } %2* { #0001 SHL2 }
%8/ { #0003 SHR2 } %8* { #0003 SHL2 }
%8- { #0008 SUB2 } %8+ { #0008 ADD2 }
%MOD8 { #0007 AND2 }
;center { x 2 y 2 }
;toolbar { x1 2 y1 2 x2 2 y2 2 }
;cursor { x 2 y 2 x0 2 y0 2 size 1 patt 1 drag 1 zoom 1 }
;zoom { x 2 y 2 }
;rect { x1 2 y1 2 x2 2 y2 2 }
;color { byte 1 }
;pos { x 2 y 2 }
;pix { x 2 y 2 }
;px { x 1 y 1 }
|0100 @RESET
( load file )
,filepath ,load-file JSR2
( find screen center )
~Screen.width #0002 DIV2 =center.x
~Screen.height #0002 DIV2 =center.y
#0010 =toolbar.x1 #0010 =toolbar.y1
( default brush )
#04 =cursor.size
#0020 =canvas.w #0010 =canvas.h ( 380x260 )
( center canvas )
~center.x ~canvas.w 8* 2/ SUB2 =canvas.x1
~center.y ~canvas.h 8* 2/ SUB2 =canvas.y1
,draw-background JSR2
,fit-canvas JSR2
( fit toolbar )
~toolbar.x1 #0010 ADD2 =toolbar.x2
~toolbar.y1 #0040 ADD2 =toolbar.y2
,draw-toolbar JSR2
BRK
@FRAME
,draw-cursor JSR2
( release drag )
,$no-release ~Mouse.state #00 EQU ~cursor.drag #01 EQU #0101 NEQ2 JMP2?
#0000 #0000 ~Screen.width ~Screen.height #00 ,fill-rect JSR2
~canvas.x1 -- ~canvas.y1 -- ~canvas.x2 ~canvas.y2 #10 ,line-rect JSR2
,draw-background JSR2
,fit-canvas JSR2
,draw-toolbar JSR2
#00 =cursor.drag
$no-release
,$no-touch ~Mouse.state #00 EQU JMP2?
( drag )
,$no-drag ~Controller #02 NEQ JMP2?
~canvas.x1 -- ~canvas.y1 -- ~canvas.x2 ~canvas.y2 #10 ,line-rect JSR2
~canvas.x1 ~Mouse.x ~cursor.x0 SUB2 ADD2 =canvas.x1
~canvas.y1 ~Mouse.y ~cursor.y0 SUB2 ADD2 =canvas.y1
~canvas.w 8* ~canvas.x1 ADD2 =canvas.x2
~canvas.h 8* ~canvas.y1 ADD2 =canvas.y2
~canvas.x1 -- ~canvas.y1 -- ~canvas.x2 ~canvas.y2 #13 ,line-rect JSR2
#01 =cursor.drag
,$touch-end JMP2
$no-drag
( in toolbar )
,$no-touch-toolbar ~Mouse.x CLN2r ~toolbar.x1 GTH2 STH2r ~toolbar.x2 LTH2 #0101 NEQ2 JMP2?
,$no-touch-toolbar ~Mouse.y CLN2r ~toolbar.y1 GTH2 STH2r ~toolbar.y2 LTH2 #0101 NEQ2 JMP2?
( release ) #00 =Mouse.state
,$no-touch-size ~Mouse.x ~toolbar.x1 SUB2 8/ #0000 NEQ2 JMP2?
~Mouse.y ~toolbar.y1 SUB2 8/ SWP POP =cursor.size
( draw ) ,draw-toolbar JSR2
,$touch-end JMP2
$no-touch-size
,$no-touch-brush ~Mouse.x ~toolbar.x1 SUB2 8/ #0001 NEQ2 JMP2?
~Mouse.y ~toolbar.y1 SUB2 8/ SWP POP =cursor.patt
( draw ) ,draw-toolbar JSR2
,$touch-end JMP2
$no-touch-brush
$no-touch-toolbar
( in canvas )
,$no-touch-canvas ~Mouse.x CLN2r ~canvas.x1 GTH2 STH2r ~canvas.x2 LTH2 #0101 NEQ2 JMP2?
,$no-touch-canvas ~Mouse.y CLN2r ~canvas.y1 GTH2 STH2r ~canvas.y2 LTH2 #0101 NEQ2 JMP2?
~Mouse.x ~canvas.x1 SUB2 ~Mouse.y ~canvas.y1 SUB2 ,paint JSR2
$no-touch-canvas
( background interface )
~Mouse.x ~Screen.width #0020 SUB2 SUB2 8/
DUP2
#0000 NEQ2 ,$no-toggle-zoom ROT JMP2?
~cursor.zoom #00 EQU =cursor.zoom
( release ) #00 =Mouse.state
~cursor.zoom =Console.byte
,redraw JSR2
$no-toggle-zoom
DUP2
#0001 NEQ2 ,$no-load-button ROT JMP2?
( release ) #00 =Mouse.state
#bb =Console.byte
$no-load-button
DUP2
#0002 NEQ2 ,$no-save-button ROT JMP2?
( release ) #00 =Mouse.state
#cc =Console.byte
$no-save-button
POP2
$touch-end
$no-touch
,$no-ctrl ~Controller #00 EQU JMP2?
,$no-ctrl-up ~Controller #10 EQU JMP2?
~zoom.y ++ =zoom.y
$no-ctrl-up
,$no-ctrl-down ~Controller #20 EQU JMP2?
~zoom.y -- =zoom.y
$no-ctrl-down
,$no-ctrl-left ~Controller #40 EQU JMP2?
~zoom.x ++ =zoom.x
$no-ctrl-left
,$no-ctrl-right ~Controller #80 EQU JMP2?
~zoom.x -- =zoom.x
$no-ctrl-right
,draw-canvas JSR2
$no-ctrl
~Mouse.x =cursor.x0
~Mouse.y =cursor.y0
BRK
@load-file ( path )
=File.name #8000 =File.length ,data =File.load
RTN
@fit-canvas
~canvas.w 8* ~canvas.x1 ADD2 =canvas.x2
~canvas.h 8* ~canvas.y1 ADD2 =canvas.y2
~canvas.x1 -- ~canvas.y1 -- ~canvas.x2 ~canvas.y2 #01 ,line-rect JSR2
,draw-canvas JSR2
RTN
@paint ( x y )
,erase ~Mouse.state #10 EQU JMP2?
#0003 SUB2 =pos.y #0003 SUB2 =pos.x ( cursor offset )
( trim if zoomed )
,$no-zoom ~cursor.zoom #01 NEQ JMP2?
~pos.x 8/ ~zoom.x ADD2 #0003 SUB2 =pos.x
~pos.y 8/ ~zoom.y ADD2 #0003 SUB2 =pos.y
$no-zoom
( center zoom on paint )
,$no-follow ~cursor.zoom JMP2?
~pos.x ~canvas.w 2/ SUB2 #0003 ADD2 =zoom.x
~pos.y ~canvas.h 2/ SUB2 #0003 ADD2 =zoom.y
$no-follow
#00 =px.x #00 =px.y
$ver
#00 =px.x
$hor
( addr ) ,size_icn #00 ~cursor.size 8* ADD2
( byte ) #00 ~px.y ADD2 LDR #07 ~px.x SUB SHR #01 AND
#00 EQU ,$no-pixel ROT JMP2?
,$no-pixel ,patternize JSR2 #00 EQU JMP2?
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 ,add-pixel JSR2
$no-pixel
( incr ) ~px.x #01 ADD =px.x
,$hor ~px.x #08 LTH JMP2?
( incr ) ~px.y #01 ADD =px.y
,$ver ~px.y #08 LTH JMP2?
,draw-canvas JSR2
,draw-toolbar JSR2
RTN
@erase ( x y )
#0003 SUB2 =pos.y #0003 SUB2 =pos.x ( cursor offset )
( trim if zoomed )
,$no-zoom ~cursor.zoom #01 NEQ JMP2?
~pos.x 8/ ~zoom.x ADD2 #0003 SUB2 =pos.x
~pos.y 8/ ~zoom.y ADD2 #0003 SUB2 =pos.y
$no-zoom
( center zoom on paint )
,$no-follow ~cursor.zoom JMP2?
~pos.x ~canvas.w 2/ SUB2 #0003 ADD2 =zoom.x
~pos.y ~canvas.h 2/ SUB2 #0003 ADD2 =zoom.y
$no-follow
#00 =px.x #00 =px.y
$ver
#00 =px.x
$hor
( addr ) ,size_icn #00 ~cursor.size 8* ADD2
( byte ) #00 ~px.y ADD2 LDR #07 ~px.x SUB SHR #01 AND
#00 EQU ,$no-pixel ROT JMP2?
,$no-pixel ,patternize JSR2 #00 EQU JMP2?
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 ,remove-pixel JSR2
$no-pixel
( incr ) ~px.x #01 ADD =px.x
,$hor ~px.x #08 LTH JMP2?
( incr ) ~px.y #01 ADD =px.y
,$ver ~px.y #08 LTH JMP2?
,draw-canvas JSR2
,draw-toolbar JSR2
RTN
@patternize
,$noplain ~cursor.patt #00 NEQ JMP2?
#01 RTN
$noplain
,$notone1 ~cursor.patt #01 NEQ JMP2?
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 ADD2 #0001 AND2 #0000 EQU2
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 SUB2 #0001 AND2 #0000 EQU2
#0101 EQU2
RTN
$notone1
,$notone2 ~cursor.patt #02 NEQ JMP2?
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 ADD2 #0003 AND2 #0000 EQU2
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 SUB2 #0003 AND2 #0000 EQU2
#0101 EQU2
RTN
$notone2
,$notone3 ~cursor.patt #03 NEQ JMP2?
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 ADD2 #0005 AND2 #0000 EQU2
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 SUB2 #0005 AND2 #0000 EQU2
#0101 EQU2
RTN
$notone3
,$notone4 ~cursor.patt #04 NEQ JMP2?
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 ADD2 #0003 AND2 #0000 EQU2
RTN
$notone4
,$notone5 ~cursor.patt #05 NEQ JMP2?
~pos.x #00 ~px.x ADD2 ~pos.y #00 ~px.y ADD2 SUB2 #0003 AND2 #0000 EQU2
RTN
$notone5
,$notone6 ~cursor.patt #06 NEQ JMP2?
~pos.x #00 ~px.x ADD2 #0001 AND2 SWP POP RTN
$notone6
,$notone7 ~cursor.patt #07 NEQ JMP2?
~pos.y #00 ~px.y ADD2 #0001 AND2 SWP POP RTN
$notone7
#00
RTN
@get-pixel ( x y )
SWP POP #07 AND =px.y
SWP POP #07 AND =px.x
( get tile ) ~pix.x 8/ ~pix.y 8/ ~canvas.w MUL2 ADD2 8*
( add addr ) ,data ADD2
#00 ~px.y ADD2 LDR #07 ~px.x SUB SHR #01 AND
RTN
@add-pixel ( x y )
=pix.y =pix.x
( get tile addr ) ,data ~pix.x 8/ ~pix.y 8/ ~canvas.w MUL2 ADD2 8* ~pix.y MOD8 ADD2 ADD2
( load ) DUP2 LDR
( mask ) #01 #07 ~pix.x MOD8 SWP POP SUB SHL ORA
( save ) ROT ROT STR
RTN
@remove-pixel ( x y )
=pix.y =pix.x
( get tile addr ) ,data ~pix.x 8/ ~pix.y 8/ ~canvas.w MUL2 ADD2 8* ~pix.y MOD8 ADD2 ADD2
( load ) DUP2 LDR
( mask ) #01 #07 ~pix.x MOD8 SWP POP SUB SHL #ff XOR AND
( save ) ROT ROT STR
RTN
( Drawing )
@redraw
,draw-background JSR2
,draw-canvas JSR2
,draw-toolbar JSR2
RTN
@draw-canvas
,draw-canvas-zoom ~cursor.zoom #01 EQU JMP2?
~canvas.y1 =Sprite.y
,data =Sprite.addr
$ver
~canvas.x1 =Sprite.x
$hor
( draw ) #09 =Sprite.color
( incr ) ~Sprite.x 8+ =Sprite.x
( incr ) ~Sprite.addr 8+ =Sprite.addr
,$hor ~Sprite.x ~canvas.x2 NEQ2 JMP2?
( incr ) ~Sprite.y 8+ =Sprite.y
,$ver ~Sprite.y ~canvas.y2 NEQ2 JMP2?
RTN
@draw-canvas-zoom
~zoom.y =pix.y
~canvas.y1 =Sprite.y
,data =Sprite.addr
$ver
~canvas.x1 =Sprite.x
~zoom.x =pix.x
$hor
( incr ) ,bigpixel_icn #0008 #00 ~pix.x ~pix.y ,get-pixel JSR2 MUL2 ADD2 =Sprite.addr
( draw ) #09 =Sprite.color
( incr ) ~Sprite.x 8+ =Sprite.x
( incr ) ~pix.x ++ =pix.x
,$hor ~Sprite.x ~canvas.x2 NEQ2 JMP2?
( incr ) ~Sprite.y 8+ =Sprite.y
( incr ) ~pix.y ++ =pix.y
,$ver ~Sprite.y ~canvas.y2 NEQ2 JMP2?
RTN
@draw-cursor
~cursor.x ~Mouse.x NEQU2
~cursor.y ~Mouse.y NEQU2
#0000 EQU2
~Mouse.state
#00 NEQ
#0101 EQU2 RTN? ( Return if unchanged )
,blank_icn =Sprite.addr
( clear brush size )
~cursor.x #0003 SUB2 =Sprite.x
~cursor.y #0003 SUB2 =Sprite.y
#10 =Sprite.color
( clear last cursor )
~cursor.x =Sprite.x
~cursor.y =Sprite.y
#10 =Sprite.color
( record cursor positions )
~Mouse.x =cursor.x
~Mouse.y =cursor.y
( draw new cursor )
,$outside-canvas ~Mouse.x CLN2r ~canvas.x1 GTH2 STH2r ~canvas.x2 LTH2 #0101 NEQ2 JMP2?
,$outside-canvas ~Mouse.y CLN2r ~canvas.y1 GTH2 STH2r ~canvas.y2 LTH2 #0101 NEQ2 JMP2?
~cursor.x #0003 SUB2 =Sprite.x
~cursor.y #0003 SUB2 =Sprite.y
,brush_view #00 ~cursor.size 8* ADD2 =Sprite.addr
#11 ~Mouse.state #02 MUL ADD =Sprite.color
,$outside-canvas ~Mouse.state #00 EQU JMP2?
RTN
$outside-canvas
~cursor.x =Sprite.x
~cursor.y =Sprite.y
,brush_pointer #00 ~Controller #02 EQU 8* ADD2 =Sprite.addr
#1f =Sprite.color
RTN
@draw-toolbar
~toolbar.x1 -- ~toolbar.y1 -- ~toolbar.x2 ~toolbar.y2 #02 ,line-rect JSR2
~toolbar.x1 #0002 SUB2 ~toolbar.y1 #0002 SUB2 ~toolbar.x2 ~toolbar.y2 #01 ,line-rect JSR2
~toolbar.x1 =Sprite.x
~toolbar.y1 =Sprite.y
,size_icn =Sprite.addr
( draw brush sizes )
$sizes
( draw ) #09 ~Sprite.y ~toolbar.y1 SUB2 8/ SWP POP ~cursor.size EQU #02 MUL ADD =Sprite.color
( incr ) ~Sprite.y 8+ =Sprite.y
( incr ) ~Sprite.addr 8+ =Sprite.addr
,$sizes ~Sprite.y ~toolbar.y1 #0040 ADD2 LTH2 JMP2?
( draw brush patterns )
~toolbar.x1 8+ =Sprite.x
~toolbar.y1 =Sprite.y
,pattern_icn =Sprite.addr
$patterns
( draw ) #09 ~Sprite.y ~toolbar.y1 SUB2 8/ SWP POP ~cursor.patt EQU #02 MUL ADD =Sprite.color
( incr ) ~Sprite.y 8+ =Sprite.y
( incr ) ~Sprite.addr 8+ =Sprite.addr
,$patterns ~Sprite.y ~toolbar.y1 #0040 ADD2 LTH2 JMP2?
RTN
@draw-background
( draw hor line )
#0000 =Screen.x ~center.y =Screen.y
#0000 ~Screen.width ( from/to )
$draw-hor NOP
( draw ) #01 =Screen.color
( incr ) SWP2 #0002 ADD2 DUP2 =Screen.x SWP2
OVR2 OVR2 LTH2 ^$draw-hor SWP JMP?
POP2 POP2
( draw ver line )
~center.x =Screen.x #0000 =Screen.y
#0000 ~Screen.height ( from/to )
$draw-ver NOP
( draw ) #01 =Screen.color
( incr ) SWP2 #0002 ADD2 DUP2 =Screen.y SWP2
OVR2 OVR2 LTH2 ^$draw-ver SWP JMP?
POP2 POP2
( draw save/load/guides icons )
~Screen.width #0018 SUB2 =Sprite.x
~Screen.height #0010 SUB2 =Sprite.y
,load_icn =Sprite.addr
#01 =Sprite.color
~Screen.width #0010 SUB2 =Sprite.x
,save_icn =Sprite.addr
#01 =Sprite.color
~Screen.width #0020 SUB2 =Sprite.x
,zoom_icn #00 ~cursor.zoom 8* ADD2 =Sprite.addr
#01 =Sprite.color
( draw width )
~Screen.width #0048 SUB2 =Sprite.x
,font_hex ~canvas.w #f0 AND #04 SHR #08 MUL ADD2 =Sprite.addr
( draw ) #02 =Sprite.color
~Sprite.x 8+ =Sprite.x
,font_hex ~canvas.w #0f AND #08 MUL ADD2 =Sprite.addr
( draw ) #02 =Sprite.color
~Sprite.x 8+ =Sprite.x
( draw height )
,font_hex ~canvas.h #f0 AND #04 SHR #08 MUL ADD2 =Sprite.addr
( draw ) #02 =Sprite.color
~Sprite.x 8+ =Sprite.x
,font_hex ~canvas.h #0f AND #08 MUL ADD2 =Sprite.addr
( draw ) #02 =Sprite.color
RTN
( Generics )
@line-rect ( x1 y1 x2 y2 color )
( load ) =color =rect.y2 =rect.x2 DUP2 =Screen.y =rect.y1 DUP2 =Screen.x =rect.x1
$hor
( incr ) ~Screen.x ++ =Screen.x
( draw ) ~rect.y1 =Screen.y ~color =Screen.color
( draw ) ~rect.y2 =Screen.y ~color =Screen.color
,$hor ~Screen.x ~rect.x2 NEQ2 JMP2?
~rect.y1 =Screen.y
$ver
( draw ) ~rect.x1 =Screen.x ~color =Screen.color
( draw ) ~rect.x2 =Screen.x ~color =Screen.color
( incr ) ~Screen.y ++ =Screen.y
,$ver ~Screen.y ~rect.y2 ++ NEQ2 JMP2?
RTN
@fill-rect ( x1 y1 x2 y2 color )
( load ) =color =rect.y2 =rect.x2 DUP2 =Screen.y =rect.y1 DUP2 =Screen.x =rect.x1
$ver
~rect.x1 =Screen.x
$hor
( draw ) ~color =Screen.color
( incr ) ~Screen.x ++ =Screen.x
,$hor ~Screen.x ~rect.x2 NEQ2 JMP2?
( incr ) ~Screen.y ++ =Screen.y
,$ver ~Screen.y ~rect.y2 NEQ2 JMP2?
RTN
@size_icn
[ 0000 0010 0000 0000 ]
[ 0000 1038 1000 0000 ]
[ 0000 3838 3800 0000 ]
[ 0010 387c 3810 0000 ]
[ 0038 7c7c 7c38 0000 ]
[ 1038 7cfe 7c38 1000 ]
[ 387c fefe fe7c 3800 ]
[ 7cfe fefe fefe 7c00 ]
@pattern_icn
[ fe82 baba ba82 fe00 ]
[ fed6 aad6 aad6 fe00 ]
[ fe92 82d6 8292 fe00 ]
[ fe82 92aa 9282 fe00 ]
[ fea6 ca92 a6ca fe00 ]
[ feca a692 caa6 fe00 ]
[ feaa aaaa aaaa fe00 ]
[ fe82 fe82 fe82 fe00 ]
@brush_view
[ 0000 0010 0000 0000 ]
[ 0000 1028 1000 0000 ]
[ 0000 3828 3800 0000 ]
[ 0010 2844 2810 0000 ]
[ 0038 4444 4438 0000 ]
[ 1028 4482 4428 1000 ]
[ 3844 8282 8244 3800 ]
[ 7c82 8282 8282 7c00 ]
[ 7cfe fefe fefe 7c00 ]
@zoom_icn
[ 3048 8484 4834 0200 ]
[ 3245 8284 4834 0200 ]
@bigpixel_icn
[ 5580 0080 0080 0080 ]
[ 55ff 7fff 7fff 7fff ]
@brush_pointer [ 80c0 e0f0 f8e0 1000 ]
@brush_hand [ 4040 4070 f8f8 f870 ]
@mode_guidesoff [ 0038 4492 2810 0000 ]
@mode_guideson [ 0000 0082 4438 0000 ]
@load_icn [ feaa d6aa d4aa f400 ]
@save_icn [ fe82 8282 848a f400 ]
@blank_icn [ 0000 0000 0000 0000 ]
@filepath [ projects/picture.bit 00 ]
@font_hex
[
003c 464a 5262 3c00 0018 0808 0808 1c00
003c 4202 3c40 7e00 003c 421c 0242 3c00
000c 1424 447e 0400 007e 407c 0242 3c00
003c 407c 4242 3c00 007e 0204 0810 1000
003c 423c 4242 3c00 003c 4242 3e02 3c00
003c 4242 7e42 4200 007c 427c 4242 7c00
003c 4240 4042 3c00 007c 4242 4242 7c00
007e 4078 4040 7e00 007e 4078 4040 4000
]
|2000 ;canvas { w 2 h 2 x1 2 y1 2 x2 2 y2 2 }
|3000 @data [ ]
|F000 @ERROR BRK
|FF00 ;Console { pad 8 char 1 byte 1 short 2 }
|FF10 ;Screen { width 2 height 2 pad 4 x 2 y 2 color 1 }
|FF20 ;Sprite { pad 8 x 2 y 2 addr 2 color 1 }
|FF30 ;Controller { buttons 1 }
|FF40 ;Keys { key 1 }
|FF50 ;Mouse { x 2 y 2 state 1 chord 1 }
|FF60 ;File { pad 8 name 2 length 2 load 2 save 2 }
|FFF0 .RESET .FRAME .ERROR ( vectors )
|FFF8 [ c0fd c0f3 c0f2 ] ( palette )