-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdungeon.s
240 lines (223 loc) · 4.64 KB
/
dungeon.s
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
.include "global.inc"
.export rand_passable
.export rand_floor
.export is_floor
.export is_passable
.export within_bounds
.export update_seen
.export was_seen
.export get_byte_mask
.export get_byte_offset
.segment "ZEROPAGE"
dlevel: .res 1
xpos: .res 1
ypos: .res 1
down_x: .res 1 ; down stair x
down_y: .res 1 ; down stair y
up_x: .res 1 ; up stair x
up_y: .res 1 ; up stair y
.segment "BSS"
tiles: .res maxtiles ; represents a 256x240 walkable grid in bits, 1 = walkable; 0 = impassable
seen: .res maxtiles
.segment "CODE"
; pick start x from 0-31 and y from 0-23
; updates xpos and ypos with coordinates
; clobbers: x
.proc randxy
randy:
jsr prng
lsr
lsr
lsr
cmp #max_height
bcs randy
sta ypos
randx:
jsr prng
lsr
lsr
lsr
cmp #max_width
bcs randx
sta xpos
;
; ensure rand x & y are within max_length of edges
jsr within_bounds
bne randxy
rts
.endproc
; check if tile is floor (doesn't check mobs)
; out: 0 if passable
; clobbers: a1, y, and x
.proc is_floor
jsr get_byte_offset
tay
jsr get_byte_mask
and tiles, y
bne tile_passable
jmp fail
tile_passable:
; success!
lda #0
rts
fail:
lda #1
rts
.endproc
; check if tile passable (checks mobs)
; out: 0 if passable
; clobbers: a1, y, and x
.proc is_passable
jsr get_byte_offset
tay
jsr get_byte_mask
and tiles, y
bne tile_passable
jmp fail
tile_passable:
; ensure no mobs at x, y
jsr mob_at
beq fail
; success!
lda #0
rts
fail:
lda #1
rts
.endproc
; update the seen tile at xpos and ypos
; clobbers: a1, x, and y
; updates: seen
.proc update_seen
jsr get_byte_offset
tay
jsr get_byte_mask
ora seen, y
sta seen, y
.endproc
; was the tile seen before?
; clobbers: a1, x, and y
; out: 0 if seen
.proc was_seen
jsr get_byte_offset
tay
jsr get_byte_mask
and seen, y
bne success
; failure
lda #1
rts
success:
lda #0
rts
.endproc
; rand passable xy
; clobbers: a1, x, and y
; todo ensure we don't hit endless loop if out of x,y
.proc rand_passable
jsr randxy
jsr is_passable
bne rand_passable
rts
.endproc
; rand floor xy
; clobbers: a1, x, and y
; todo ensure we don't hit endless loop if out of x,y
.proc rand_floor
jsr randxy
jsr is_floor
bne rand_floor
rts
.endproc
; is x & y within bounds?
; out: 0 if within bounds of map
; clobbers: accum
.proc within_bounds
; ensure not within 3 pixels of left or right
lda xpos
cmp #min_bound
bcc within_bounds_fail
cmp #max_width-min_bound
bcs within_bounds_fail
; ensure not within 3 pixels of top or bottom
lda ypos
cmp #min_bound
bcc within_bounds_fail
cmp #max_height-min_bound
bcs within_bounds_fail
within_bounds_success:
lda #0
rts
within_bounds_fail:
lda #1
rts
.endproc
; get byte offset for x,y
; out: offset to first byte in tiles (x/8 + y*4)
; clobbers: a1
.proc get_byte_offset
lda xpos
lsr
lsr
lsr
sta a1
lda ypos
asl
asl
clc
adc a1
rts
.endproc
; get byte mask for x
; out: byte mask
; clobbers: a1 and x
.proc get_byte_mask
lda xpos
; get 3 lowest bits (number 0-7)
and #%00000111
; now, we have the remainder (bit 0-7)
sta a1
ldx #0
sec
get_byte_mask_loop:
ror
cpx a1
beq get_byte_mask_done
inx
jmp get_byte_mask_loop
get_byte_mask_done:
rts
.endproc
; the tiles are arranged like so:
;
; 00000000 00000000 00000000 00000000
; 01000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000100 10000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
;
; 00000000 00000000 00000000 00000000
; 01000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000100 10000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
;
; 00000000 00000000 00000000 00000000
; 01000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000100 10000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
; 00000000 00000000 00000000 00000000
;
; bit at x,y of 1,1 would be in quadrant 0 with offset 0
; bit at x,y of 8,3 would be in quadrant 1 with offset 1
; bit at x,y of 1,9 would be in quadrant 4 with offset 32
; bit at x,y of 8,11 would be in quadrant 5 with offset 33