-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroom_map.asm
406 lines (324 loc) · 8.99 KB
/
room_map.asm
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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
section .data
ROOMMAP_MINIMUM_ROOM_WH equ 5
ROOMMAP_BLANKING_CHAR db ' '
ROOMMAP_WALLFILL_CHAR db '#'
ROOMMAP_NL_CHAR db 10
ROOMMAP_SPACING_CHAR db ' '
; a room map should be defined by:
; - a overall height and width
; - pointers for a BSPTree, BSP_NODE Array, Room array, room connection matrix, and overall Map
; - a count of the number of rooms for the sake of indexing into arrays and matrices
ROOM_MAP_SZ equ 52
ROOM_MAP_H_OFF equ 0
ROOM_MAP_W_OFF equ 4
ROOM_MAP_ROOMCNT_OFF equ 8
ROOM_MAP_BSPTREE_OFF equ 12
ROOM_MAP_BSPARRY_OFF equ 20
ROOM_MAP_ROOMARY_OFF equ 28
ROOM_MAP_ROOMMTX_OFF equ 36
ROOM_MAP_MAPMTRX_OFF equ 44
; a room should be defined by 2 sets of X and Y
; which will represent oposite corners, which can then be mapped into space
ROOM_DATA_SZ equ 16
ROOM_DATA_X1_OFF equ 0
ROOM_DATA_Y1_OFF equ 4
ROOM_DATA_X2_OFF equ 8
ROOM_DATA_Y2_OFF equ 12
section .text
; ROOMMAP* create_map(int height, int width)
; creates a blank ROOMMAP and fills its entire area with walls
; does not generate any rooms or room related structures
ROOMMAP_create_map:
push rbp
mov rbp,rsp
push rsi
push rdi
mov rdi, ROOM_MAP_SZ
mov rsi, 1
call basically_calloc
pop rdi
pop rsi
mov DWORD [rax + ROOM_MAP_H_OFF], edi
mov DWORD [rax + ROOM_MAP_W_OFF], esi
push rax ; pushing location of ROOM_MAP structure
mov rax, rdi
imul rsi ; rax should now hold required number of bytes for the map
push rax ; pushing number of bytes for map
mov rdi, rax
call basically_malloc
mov rdi, rax
pop rcx ; popping number of bytes for map
push rdi ; pushing location of MAP array/matrix
mov al, BYTE [ROOMMAP_WALLFILL_CHAR]
rep stosb
pop rdi ; popping location of MAP array/matrix
pop rax ; popping location of ROOM_MAP structure
mov QWORD [rax + ROOM_MAP_MAPMTRX_OFF], rdi
mov rsp,rbp
pop rbp
ret
; void print_map(ROOMMAP* room_map)
ROOMMAP_print_map:
push rbp
mov rbp, rsp
mov rcx, rdi
mov rsi, QWORD [rcx + ROOM_MAP_MAPMTRX_OFF]
xor rdx,rdx
mov edx, DWORD [rcx + ROOM_MAP_H_OFF]
ROOMMAP_print_map_loop:
push rsi
push rcx
push rdx
mov rdx, rcx
xor rcx, rcx
mov ecx, DWORD [rdx + ROOM_MAP_W_OFF]
ROOMMAP_print_map_innerLoop:
push rcx
push rsi
mov rax, 1
mov rdi, 1
mov rdx, 1
syscall
mov rax, 1
mov rdi, 1
mov rsi, ROOMMAP_SPACING_CHAR
mov rdx, 1
syscall
pop rsi
pop rcx
add rsi, 1
loop ROOMMAP_print_map_innerLoop
mov rax, 1
mov rdi, 1
mov rsi, ROOMMAP_NL_CHAR
mov rdx, 1
syscall
pop rdx
pop rcx
pop rsi
xor eax, eax
mov eax, DWORD [rcx + ROOM_MAP_W_OFF]
add rsi, rax
dec rdx
cmp rdx, 0
jge ROOMMAP_print_map_loop
mov rsp, rbp
pop rbp
ret
; void generate_rooms(ROOMMAP* room_map, int target_area);
ROOMMAP_generate_rooms:
push rbp
mov rbp, rsp
push rdi
push rsi
mov esi, 0
mov edx, DWORD [rdi + ROOM_MAP_W_OFF]
mov ecx, DWORD [rdi + ROOM_MAP_H_OFF]
mov edi, 0
call BSP_create_node_with_values
pop rsi
pop rdi
mov QWORD [rdi + ROOM_MAP_BSPTREE_OFF], rax ; save newly created BSP Tree root node to the map structure
push rdi
push rsi
; rsi is already correct for the next call
mov rdi, rax
push rdi
call BSP_split_to_area
pop rdi
call BSP_flatten_leaf_nodes
pop rsi ; restore original parameter values
pop rdi
mov QWORD [rdi + ROOM_MAP_BSPARRY_OFF], rax ; saving the flattened BSP array of leaf nodes
mov DWORD [rdi + ROOM_MAP_ROOMCNT_OFF], edx ; saving the number of partitions in said array
push rdi
xor rsi,rsi
mov rdi, ROOM_DATA_SZ
mov esi, edx
call basically_calloc
pop rdi
mov QWORD [rdi + ROOM_MAP_ROOMARY_OFF], rax ; saving newly allocated space for array of room data all initialized to zero
xor rax,rax
xor rdx,rdx
mov eax, DWORD [rdi + ROOM_MAP_ROOMCNT_OFF]
mov edx, eax
imul rdx
push rdi
push rax
mov rdi, rax
call basically_malloc
mov rdi, rax
pop rcx
xor rax,rax
push rdi
rep stosb
pop rax
pop rdi
mov QWORD [rdi + ROOM_MAP_ROOMMTX_OFF], rax
push rdi
call ROOMMAP_populate_room_array
pop rdi
push rdi
call ROOMMAP_draw_room_array
pop rdi
mov rsp, rbp
pop rbp
ret
; void populate_room_array(ROOMMAP* room_map)
; meant as a subroutine of generate_rooms, assumes all structures exist already and that the count is set
ROOMMAP_populate_room_array:
push rbp
mov rbp,rsp
xor rcx,rcx
ROOMMAP_populate_room_array_lp:
mov rax, ROOM_DATA_SZ
imul rcx
add rax, [rdi+ROOM_MAP_ROOMARY_OFF] ; rax should now hold the location of a single room array element (4 integers representing the ul and lr corners of a room)
push rax ; rax pushed but will be popped into rdx later
mov rax, 8 ; this one is an array of pointers, and not directly an array of structs... so 8 bytes is the correct size here
imul rcx
add rax, [rdi+ROOM_MAP_BSPARRY_OFF] ; rax should now hold the location of a single BSP_NODE structure representing one of the partitions
mov rax, [rax] ; dereferencing rax, because it was a pointer to a pointer to the struct instead of a pointer to the struct itself
pop rdx ; rdx should now hold the location of a single room array element
push rcx
; these next two blocks set the corners of each room such that each section contains a 5x5 room
mov ecx, DWORD [rax + BSP_NODE_X_OFF]
; random ul corner X position within half of section
push rax
push rcx
push rdx
mov ecx, DWORD [rax + BSP_NODE_W_OFF]
shr ecx, 1
xor rax,rax
push rcx
call genrand
pop rcx
cqo
idiv rcx
mov rax,rdx
pop rdx
pop rcx
add ecx, eax
mov DWORD [rdx + ROOM_DATA_X1_OFF], ecx
pop rax
; random width
push rax
push rcx
push rdx
mov ecx, DWORD [rax + BSP_NODE_W_OFF]
shr ecx, 1
xor rax,rax
push rcx
call genrand
pop rcx
cqo
idiv rcx
mov rax,rdx
pop rdx
pop rcx
cmp eax, ROOMMAP_MINIMUM_ROOM_WH
jge ROOMMAP_populate_rooms_over_min_w
add eax, ROOMMAP_MINIMUM_ROOM_WH
ROOMMAP_populate_rooms_over_min_w:
add ecx, eax
mov DWORD [rdx + ROOM_DATA_X2_OFF], ecx
pop rax
mov ecx, DWORD [rax + BSP_NODE_Y_OFF]
; random ul corner Y position within half of section
push rax
push rcx
push rdx
mov ecx, DWORD [rax + BSP_NODE_H_OFF]
shr ecx, 1
xor rax,rax
call genrand
cqo
idiv rcx
mov rax,rdx
pop rdx
pop rcx
mov DWORD [rdx + ROOM_DATA_Y1_OFF], ecx
pop rax
; random height
push rax
push rcx
push rdx
mov ecx, DWORD [rax + BSP_NODE_H_OFF]
shr ecx, 1
xor rax,rax
push rcx
call genrand
pop rcx
cqo
idiv rcx
mov rax,rdx
pop rdx
pop rcx
cmp eax, ROOMMAP_MINIMUM_ROOM_WH
jge ROOMMAP_populate_rooms_over_min_h
add eax, ROOMMAP_MINIMUM_ROOM_WH
ROOMMAP_populate_rooms_over_min_h:
add ecx, eax
mov DWORD [rdx + ROOM_DATA_Y2_OFF], ecx
pop rax
pop rcx
inc ecx
cmp ecx, DWORD [rdi + ROOM_MAP_ROOMCNT_OFF]
jl ROOMMAP_populate_room_array_lp
mov rsp,rbp
pop rbp
ret
; void draw_room_array(ROOMMAP* room_map)
; meant as a subroutine of generate_rooms, assmes all structures exist already and room array has been populated
ROOMMAP_draw_room_array:
push rbp
mov rbp, rsp
; for each room
; need width and height of room, width of overall map/matrix, and upper left corner of room position in array
xor rcx,rcx
ROOMMAP_draw_room_array_lp:
push rcx
push rdi
mov rax, ROOM_DATA_SZ
imul rcx
add rax, [rdi+ROOM_MAP_ROOMARY_OFF] ; rax should now hold the location of a single room array element (4 integers representing the ul and lr corners of a room)
mov rsi, rax ; moved to rsi to free rax for math operations
xor rax,rax
xor rdx,rdx
mov eax, DWORD [rsi + ROOM_DATA_Y1_OFF] ; Y value of ul corner of room
mov edx, DWORD [rdi + ROOM_MAP_W_OFF] ; width of map
imul rdx ; eax now contains offset to start of correct row
mov rdx,rax
add edx, DWORD [rsi + ROOM_DATA_X1_OFF] ; adding the X value of the ul corner brings edx/rdx to the correct offset for the ul corner
xor rax,rax
mov eax, DWORD [rsi + ROOM_DATA_Y2_OFF]
sub eax, DWORD [rsi + ROOM_DATA_Y1_OFF] ; eax contains overall height of room (number of rows to draw)
xor rcx,rcx
ROOMMAP_draw_room_array_lp2:
push rcx
push rax
xor rax,rax
mov eax, DWORD [rsi + ROOM_DATA_X2_OFF]
sub eax, DWORD [rsi + ROOM_DATA_X1_OFF] ; eax contains width of room
push rdi
mov rdi, [rdi + ROOM_MAP_MAPMTRX_OFF] ; start of map matrix
add rdi, rdx ; offset to start writing from
mov rcx, rax ; width of room as counter
xor rax,rax
mov al, BYTE [ROOMMAP_BLANKING_CHAR] ; character to write
rep stosb
pop rdi
add edx, DWORD [rdi + ROOM_MAP_W_OFF] ; effectively moves to next row start location
pop rax
pop rcx
inc ecx
cmp ecx, eax
jl ROOMMAP_draw_room_array_lp2
pop rdi
pop rcx
inc ecx
cmp ecx, DWORD [rdi + ROOM_MAP_ROOMCNT_OFF]
jl ROOMMAP_draw_room_array_lp
mov rsp, rbp
pop rbp
ret