-
Notifications
You must be signed in to change notification settings - Fork 0
/
sandfall.wat
220 lines (187 loc) · 3.85 KB
/
sandfall.wat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
(module
(import "console" "log" (func $log (param i32)))
(memory (export "memory") 1)
(global $width (mut i32) (i32.const 0))
(global $height (mut i32) (i32.const 0))
(global $span (mut i32) (i32.const 0))
(func $inspect (param $x i32) (result i32)
local.get $x
call $log
local.get $x
)
(func (export "init") (param $width i32) (param $height i32)
(local $i i32)
(local $span i32)
local.get $width
local.get $height
i32.mul
i32.const 16_384 ;; i32s/ page
i32.div_s
call $inspect
memory.grow
drop
local.get $width
global.set $width
local.get $height
global.set $height
local.get $width
i32.const 4
i32.mul
global.set $span
)
(func $stamp (export "stamp") (param $index i32) (param $red i32) (param $green i32) (param $blue i32)
local.get $index
i32.load
if
return
end
local.get $index
i32.const 0
i32.add
local.get $red
i32.store8
local.get $index
i32.const 1
i32.add
local.get $green
i32.store8
local.get $index
i32.const 2
i32.add
local.get $blue
i32.store8
local.get $index
i32.const 3
i32.add
i32.const 255
i32.store8
)
(func $block_stamp (export "block_stamp") (param $x i32) (param $y i32) (param $red i32) (param $green i32) (param $blue i32)
(local $index i32)
local.get $y
global.get $width
i32.mul
local.get $x
i32.add
i32.const 4
i32.mul
local.set $index
local.get $index
i32.const 0
i32.add
local.get $red
local.get $green
local.get $blue
call $stamp
local.get $index
i32.const 4
i32.add
local.get $red
local.get $green
local.get $blue
call $stamp
local.get $index
i32.const 8
i32.add
local.get $red
local.get $green
local.get $blue
call $stamp
local.get $index
i32.const 12
i32.add
local.get $red
local.get $green
local.get $blue
call $stamp
)
(func $put (param $index1 i32) (param $cell1 i32) (param $index2 i32) (result i32)
local.get $index2
i32.load
i32.eqz
if (result i32);; target cell is empty
local.get $index1
i32.const 0
i32.store
local.get $index2
local.get $cell1
i32.store
i32.const 1
else
i32.const 0
end
return
)
(func (export "step")
(local $i i32)
global.get $width
global.get $height
i32.const 1
i32.sub
i32.mul
i32.const 4
i32.mul
local.set $i ;; we don't want to step on last row of grid
(loop $while
local.get $i
i32.const 4
i32.sub
local.tee $i ;; decrements counter
call $next
local.get $i
i32.const 4 ;; skip top left cell
i32.gt_s
br_if $while
)
)
(func $next (param $index i32)
(local $cell i32)
(local $index_s i32)
(local $index_sw i32)
(local $index_se i32)
local.get $index
i32.load
local.tee $cell
i32.eqz
if ;; early exit on empty cell
return
end
local.get $index
global.get $span
i32.add
local.set $index_s
;; check south cell
local.get $index
local.get $cell
local.get $index_s
call $put
if
return
end
;; check south east cell
local.get $index
local.get $cell
local.get $index_s
i32.const 4
i32.add
call $put
if
return
end
;; check west and south west cell
local.get $index
i32.const 4
i32.sub
i32.load
i32.eqz
if
local.get $index
local.get $cell
local.get $index_s
i32.const 4
i32.sub
call $put
drop
end
)
)