uxn/projects/examples/demos/life.tal

384 lines
7.6 KiB
Tal
Raw Normal View History

2022-03-25 15:05:11 -04:00
( Game Of Life:
2021-05-05 23:16:27 -04:00
Any live cell with fewer than two live neighbours dies, as if by underpopulation.
2021-05-06 13:38:38 -04:00
Any live cell with two or three live neighbours lives on to the next generation.
Any live cell with more than three live neighbours dies, as if by overpopulation.
Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. )
2021-05-05 21:38:28 -04:00
2022-02-08 23:04:18 -05:00
%+ { ADD } %- { SUB }
2021-05-09 23:43:33 -04:00
%< { LTH } %> { GTH } %= { EQU } %! { NEQ }
2022-02-08 23:04:18 -05:00
%++ { ADD2 } %-- { SUB2 }
2021-05-09 23:43:33 -04:00
%<< { LTH2 } %>> { GTH2 } %== { EQU2 } %!! { NEQ2 }
2021-05-05 21:38:28 -04:00
2021-08-17 18:24:37 -04:00
%2/ { #01 SFT }
%8/ { #03 SFT }
2021-05-24 17:36:15 -04:00
%2// { #01 SFT2 } %8// { #03 SFT2 }
2021-05-24 17:52:11 -04:00
%2** { #10 SFT2 } %8** { #30 SFT2 }
2021-08-17 18:24:37 -04:00
%40** { #60 SFT2 }
%8MOD { #07 AND } %2MOD { #01 AND }
2022-02-08 23:04:18 -05:00
%TOS { #00 SWP }
%RTN { JMP2r }
2021-08-17 18:24:37 -04:00
%SFL { #40 SFT SFT }
2021-05-05 21:38:28 -04:00
2022-02-08 23:04:18 -05:00
%WIDTH { #40 }
%HEIGHT { #40 }
%LENGTH { #0200 }
%WIDTH-MOD { #3f AND }
%HEIGHT-MOD { #3f AND }
2021-11-26 17:29:20 -05:00
%IN-RANGE { INCk SWP SUB2 GTH }
2021-08-17 18:24:37 -04:00
2021-05-05 23:16:27 -04:00
%BANK1 { #8000 } %BANK2 { #a000 }
2021-05-05 21:38:28 -04:00
2021-08-15 16:25:58 -04:00
%GET-ITERATORS { SWP2k POP NIP }
%GET-ITER { OVR2 NIP OVR SWP }
2021-05-05 21:38:28 -04:00
2022-02-03 22:52:12 -05:00
%AUTO-NONE { #00 .Screen/auto DEO }
%AUTO-X { #01 .Screen/auto DEO }
2021-05-05 21:38:28 -04:00
( devices )
|00 @System [ &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 ]
2021-11-26 17:29:20 -05:00
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]
2022-02-08 23:04:18 -05:00
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
2021-09-08 20:51:23 -04:00
|30 @Audio0 [ &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
2021-05-06 13:38:38 -04:00
|80 @Controller [ &vector $2 &button $1 &key $1 ]
2021-05-31 18:08:34 -04:00
|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &wheel $1 ]
2021-05-05 21:38:28 -04:00
( variables )
|0000
2021-08-07 23:03:13 -04:00
@world [ &frame $1 &count $2 ]
2021-05-06 13:38:38 -04:00
@anchor [ &x $2 &y $2 ]
2021-05-05 23:16:27 -04:00
@pointer [ &x $2 &y $2 ]
2021-11-26 17:29:20 -05:00
@rle [ &x $1 &y $1 &n $1 ]
2021-05-05 21:38:28 -04:00
( program )
|0100 ( -> )
2022-02-08 23:04:18 -05:00
( theme )
#02cf .System/r DEO2
#02ff .System/g DEO2
2021-08-07 23:03:13 -04:00
#024f .System/b DEO2
2021-05-05 21:38:28 -04:00
( vectors )
2021-11-26 17:29:20 -05:00
;on-input .Console/vector DEO2
2021-05-05 21:38:28 -04:00
;on-frame .Screen/vector DEO2
2021-05-05 23:16:27 -04:00
;on-mouse .Mouse/vector DEO2
2021-05-06 13:38:38 -04:00
;on-control .Controller/vector DEO2
2021-05-05 21:38:28 -04:00
( glider )
#07 #03 ;set-cell JSR2
#07 #04 ;set-cell JSR2
#05 #04 ;set-cell JSR2
#07 #05 ;set-cell JSR2
#06 #05 ;set-cell JSR2
2021-05-24 17:36:15 -04:00
.Screen/width DEI2 2// WIDTH TOS -- .anchor/x STZ2
.Screen/height DEI2 2// HEIGHT TOS -- .anchor/y STZ2
2021-05-05 21:38:28 -04:00
2021-08-07 23:03:13 -04:00
BRK
@on-frame-paused ( -> )
2021-05-06 13:38:38 -04:00
2021-05-05 21:38:28 -04:00
BRK
@on-frame ( -> )
2021-05-05 23:33:48 -04:00
2021-05-11 14:12:07 -04:00
.Mouse/state DEI #00 = #01 JCN [ BRK ]
2021-05-05 21:38:28 -04:00
2021-08-17 18:24:37 -04:00
( incr frame ) .world/frame LDZ INC [ DUP ] .world/frame STZ
2021-05-11 14:14:52 -04:00
( reset count ) #0000 .world/count STZ2
2021-05-05 21:38:28 -04:00
2022-02-08 23:04:18 -05:00
#03 AND #00 = #01 JCN [ BRK ]
2021-05-05 21:38:28 -04:00
( clear buffer )
2022-02-08 23:04:18 -05:00
BANK2 LENGTH ;mclr JSR2
2021-05-05 21:38:28 -04:00
2021-08-07 23:03:13 -04:00
( run grid )
#00 HEIGHT
&ver
#00 WIDTH
&hor
GET-ITERATORS
( x y ) DUP2
( neighbours ) DUP2 ;get-neighbours JSR2
( state ) ROT ROT ;get-cell JSR2
,run-cell JSR
2021-08-17 18:24:37 -04:00
SWP INC SWP
2021-08-07 23:03:13 -04:00
LTHk ,&hor JCN
POP2
2021-08-17 18:24:37 -04:00
SWP INC SWP
2021-08-07 23:03:13 -04:00
LTHk ,&ver JCN
POP2
2021-05-05 21:38:28 -04:00
( move buffer )
2022-02-08 23:04:18 -05:00
BANK2 BANK1 LENGTH ;mcpy JSR2
2021-05-05 21:38:28 -04:00
2021-05-05 23:16:27 -04:00
;draw-grid JSR2
BRK
2021-08-07 23:03:13 -04:00
@run-cell ( x y neighbours state -- )
#00 = ,&dead JCN
&alive
DUP #02 < ,&dies JCN
DUP #03 > ,&dies JCN
&lives POP ,save-cell JSR RTN
&dies POP POP2 RTN
&dead
DUP #03 = ,&birth JCN POP POP2 RTN
&birth POP ,save-cell JSR RTN
RTN
@save-cell ( x y -- )
( get index )
2021-08-17 18:24:37 -04:00
HEIGHT-MOD SWP WIDTH-MOD SWP
TOS 8** ROT 8/ TOS ++ [ BANK2 ++ ]
2021-08-07 23:03:13 -04:00
( incr count )
2021-08-17 18:24:37 -04:00
.world/count LDZ2 INC2 .world/count STZ2
2021-08-07 23:03:13 -04:00
( save in buffer )
STH2
2022-02-08 23:04:18 -05:00
DUP2 POP 8MOD #01 SWP SFL
2021-08-07 23:03:13 -04:00
LDAkr STHr SWP ORA
STH2r STA
RTN
2021-05-05 23:16:27 -04:00
@on-mouse ( -> )
( clear last cursor )
2022-02-08 23:04:18 -05:00
;cursor .Screen/addr DEO2
.pointer/x LDZ2 .Screen/x DEO2
.pointer/y LDZ2 .Screen/y DEO2
#40 .Screen/sprite DEO
2021-05-05 23:16:27 -04:00
( record pointer positions )
2021-07-09 14:38:45 -04:00
.Mouse/x DEI2 DUP2 .pointer/x STZ2 .Screen/x DEO2
2022-02-08 23:04:18 -05:00
.Mouse/y DEI2 DUP2 .pointer/y STZ2 .Screen/y DEO2
2021-05-05 23:16:27 -04:00
( colorize on state )
#42 [ .Mouse/state DEI #00 ! ] + .Screen/sprite DEO
2021-05-05 23:16:27 -04:00
2021-05-11 14:12:07 -04:00
.Mouse/state DEI #00 ! #01 JCN [ BRK ]
2021-05-05 23:16:27 -04:00
2021-08-17 18:24:37 -04:00
.Mouse/x DEI2 DUP2 .anchor/x LDZ2 >> ROT ROT .anchor/x LDZ2 WIDTH DUP ADD TOS ++ INC2 << #0101 ==
.Mouse/y DEI2 DUP2 .anchor/y LDZ2 >> ROT ROT .anchor/y LDZ2 HEIGHT DUP ADD TOS ++ << #0101 ==
2021-05-11 14:12:07 -04:00
#0101 == #01 JCN [ BRK ]
2021-05-05 23:16:27 -04:00
2021-08-17 18:24:37 -04:00
.Mouse/x DEI2 .anchor/x LDZ2 SUB2 2/ NIP
.Mouse/y DEI2 .anchor/y LDZ2 SUB2 2/ NIP
2021-05-05 23:16:27 -04:00
;set-cell JSR2
2021-05-05 23:33:48 -04:00
;draw-grid JSR2
2021-05-05 23:16:27 -04:00
BRK
2021-05-06 13:38:38 -04:00
@on-control ( -> )
2021-05-11 14:12:07 -04:00
.Controller/key DEI #20 ! ,&no-toggle JCN
2021-08-07 23:03:13 -04:00
;on-frame
.Screen/vector DEI2 ;on-frame-paused == ,&swap JCN
POP2 ;on-frame-paused
&swap
.Screen/vector DEO2
&no-toggle
2021-05-06 13:38:38 -04:00
2022-02-08 23:04:18 -05:00
.Controller/button DEI #08 ! ,&no-reset JCN
BANK1 #1000 ;mclr JSR2
BANK2 #1000 ;mclr JSR2
&no-reset
2021-05-06 13:38:38 -04:00
BRK
2021-05-05 23:16:27 -04:00
@draw-grid ( -- )
2021-08-07 23:03:13 -04:00
( draw cell count )
.anchor/x LDZ2 .Screen/x DEO2
.anchor/y LDZ2 HEIGHT DUP ADD TOS ++ .Screen/y DEO2
2022-02-03 22:52:12 -05:00
AUTO-X
2021-08-07 23:03:13 -04:00
.world/count LDZ2 #03 ;draw-short JSR2
2022-02-03 22:52:12 -05:00
AUTO-NONE
2021-05-05 23:16:27 -04:00
2021-08-07 23:03:13 -04:00
HEIGHT #00
2021-05-05 21:38:28 -04:00
&ver
2022-02-08 23:04:18 -05:00
DUP TOS 2** .anchor/y LDZ2 ++ .Screen/y DEO2
2021-08-07 23:03:13 -04:00
WIDTH #00
2021-05-05 21:38:28 -04:00
&hor
2022-02-08 23:04:18 -05:00
DUP TOS 2** .anchor/x LDZ2 ++ .Screen/x DEO2
2021-08-17 18:24:37 -04:00
GET-ITER ,get-cell JSR INC .Screen/pixel DEO
INC GTHk ,&hor JCN
2021-05-12 21:28:45 -04:00
POP2
2021-08-17 18:24:37 -04:00
INC GTHk ,&ver JCN
2021-05-05 21:38:28 -04:00
POP2
2021-05-05 23:16:27 -04:00
RTN
2021-05-05 21:38:28 -04:00
@get-index ( x y -- index* )
2021-08-17 18:24:37 -04:00
HEIGHT-MOD SWP WIDTH-MOD SWP
TOS 8** ROT 8/ TOS ++ [ BANK1 ++ ]
2021-05-05 21:38:28 -04:00
RTN
@set-cell ( x y -- )
2021-05-05 23:16:27 -04:00
DUP2 ,get-index JSR STH2
2022-02-08 23:04:18 -05:00
POP 8MOD #01 SWP SFL
2021-05-12 21:28:45 -04:00
LDAkr STHr SWP ORA
2021-05-05 23:16:27 -04:00
STH2r STA
2021-05-05 21:38:28 -04:00
RTN
2021-11-26 17:29:20 -05:00
@unset-cell ( x y -- )
DUP2 ,get-index JSR STH2
POP 8MOD #01 SWP SFL #ff EOR
LDAkr STHr SWP AND
STH2r STA
RTN
2021-05-05 21:38:28 -04:00
@get-cell ( x y -- cell )
2022-02-08 23:04:18 -05:00
DUP2 ,get-index JSR LDA
2021-08-15 16:25:58 -04:00
NIP SWP
2021-08-17 18:24:37 -04:00
8MOD
SFT 2MOD
2021-05-05 21:38:28 -04:00
2022-02-08 23:04:18 -05:00
RTN
2021-05-05 21:38:28 -04:00
@get-neighbours ( x y -- neighbours )
2021-08-07 23:03:13 -04:00
( -1,-1 ) DUP2 #01 - [ SWP #01 - SWP ] ,get-cell JSR STH
2021-05-12 21:28:45 -04:00
( 0,-1 ) DUP2 #01 - ,get-cell JSR STH ADDr
2021-08-17 18:24:37 -04:00
( +1,-1 ) DUP2 #01 - [ SWP INC SWP ] ,get-cell JSR STH ADDr
2021-08-07 23:03:13 -04:00
( -1, 0 ) DUP2 [ SWP #01 - SWP ] ,get-cell JSR STH ADDr
2021-08-17 18:24:37 -04:00
( +1, 0 ) DUP2 [ SWP INC SWP ] ,get-cell JSR STH ADDr
( -1,+1 ) DUP2 INC [ SWP #01 - SWP ] ,get-cell JSR STH ADDr
( 0,+1 ) DUP2 INC ,get-cell JSR STH ADDr
( +1,+1 ) INC [ SWP INC SWP ] ,get-cell JSR STH ADDr
2021-05-05 21:38:28 -04:00
STHr
RTN
2021-05-06 13:38:38 -04:00
@draw-short ( short* color -- )
2022-02-08 23:04:18 -05:00
STH
SWP STHkr ,draw-byte JSR
STHr
2022-02-03 22:52:12 -05:00
2022-02-08 23:04:18 -05:00
@draw-byte ( byte color -- )
2022-02-03 22:52:12 -05:00
2022-02-08 23:04:18 -05:00
STH
DUP #04 SFT STHkr ,draw-hex JSR #0f AND
STHr
2022-02-03 22:52:12 -05:00
2022-02-08 23:04:18 -05:00
@draw-hex ( char color -- )
2022-02-03 22:52:12 -05:00
2022-02-08 23:04:18 -05:00
SWP TOS 8** ;font-hex ++ .Screen/addr DEO2
.Screen/sprite DEO
2021-05-06 13:38:38 -04:00
RTN
2022-02-08 23:04:18 -05:00
@mclr ( addr* len* -- )
OVR2 ++ SWP2
&loop
STH2k #00 STH2r STA
INC2 GTH2k ,&loop JCN
POP2 POP2
JMP2r
@mcpy ( src* dst* len* -- )
SWP2 STH2
OVR2 ++ SWP2
&loop
LDAk STH2kr STA INC2r
INC2 GTH2k ,&loop JCN
POP2 POP2
POP2r
JMP2r
( input )
2021-11-26 17:29:20 -05:00
@on-input ( -> )
,&main JSR
BRK
&main
.Console/read DEI #20 GTH JMP JMP2r ( ignore whitespace )
.Console/read DEI LIT 'b EQU ,unset-run JCN
.Console/read DEI LIT 'o EQU ,set-run JCN
.Console/read DEI LIT '$ EQU ,input-eol JCN
.Console/read DEI LIT '! EQU ,input-eop JCN
LIT2 '0 '9 .Console/read DEI IN-RANGE ,input-number JCN
;on-ignore-until-eol .Console/vector DEO2
JMP2r
@unset-run ( -- )
;unset-cell ,run JMP ( tail call )
@set-run ( -- )
;set-cell ( fall through )
@run ( cell-fn* -- )
STH2
;on-frame-paused .Screen/vector DEO2
.rle/n LDZk #00 ROT STZ
DUP #00 NEQ JMP INC
&loop ( count / cell-fn* )
DUP #00 EQU ,&end JCN
.rle/x LDZ .rle/y LDZ STH2kr JSR2
.rle/x LDZk INC SWP STZ
#01 SUB
,&loop JMP
&end
POP POP2r
JMP2r
@input-number ( -- )
.rle/n LDZk #0a MUL
.Console/read DEI LIT '0 SUB
ADD SWP STZ
JMP2r
@input-eol ( -- )
WIDTH .rle/x LDZ SUB .rle/n STZ
,unset-run JSR
#00 .rle/x STZ
.rle/y LDZk INC SWP STZ
JMP2r
@input-eop ( -- )
,input-eol JSR
HEIGHT .rle/y LDZ GTH ,input-eop JCN
;on-frame .Screen/vector DEO2
#00 .rle/y STZ
BRK
@on-ignore-until-eol ( -> )
.Console/read DEI #0a EQU JMP BRK
;on-input .Console/vector DEO2
BRK
2022-02-08 23:04:18 -05:00
@cursor
2021-05-12 21:28:45 -04:00
80c0 e0f0 f8e0 1000
@font-hex
2021-05-06 13:38:38 -04:00
007c 8282 8282 827c 0030 1010 1010 1010
007c 8202 7c80 80fe 007c 8202 1c02 827c
000c 1424 4484 fe04 00fe 8080 7c02 827c
007c 8280 fc82 827c 007c 8202 1e02 0202
007c 8282 7c82 827c 007c 8282 7e02 827c
007c 8202 7e82 827e 00fc 8282 fc82 82fc
007c 8280 8080 827c 00fc 8282 8282 82fc
2021-05-12 21:28:45 -04:00
007c 8280 f080 827c 007c 8280 f080 8080