-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathADTF_Revive.s
515 lines (396 loc) · 10.3 KB
/
ADTF_Revive.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
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
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
.include "ADTF_Macros.s"
.include "ADTF_Ev_Op.s"
.include "ADTF_Map.s"
.include "ADTF_Inventory.s"
.ifdef DEBUG
.include "ADTF_Debug.s"
.endif
.file "ADTF_Revive.s"
#Note to self
# arg0 is at 8(%ebp)
# arg1 at 12(%ebp)
# etc.
#FIXME: Saves are almost always version incompatible,
#This could be avoided by having current/saved/next event as strings, not pointers
.data
persisted_data:
saved_event: .long 0
current_event: .long 0
next_event: .long 0
cur_x: .long 0
cur_y: .long 0
fame: .long 0
moves: .long 0
is_iron_man: .long 0
persisted_data_length: .long . - persisted_data
op_table: .skip (10 * 4)
.text
.global _main
_main:
frame
.ifdef DEBUG
call print_tables
.endif
movl $ev_main_menu, next_event
L0_start:
call clr
movl next_event, %eax
movl %eax, current_event
.ifdef DEBUG
call_1 get_event_name, current_event
call_2 debug_out, current_event, %eax
println $newline
.endif
load_ev_flag current_event
jmp_table $L0_switch_table, %eax
#TODO: add handler for pseudo events
L0_event_handler:
call_2 get_member, current_event, $1
println %eax
print $newline
movl current_event, %eax
call_3 print_options, $op_table, %eax, $1
jmp L0_pick_op
L0_nonstd:
movl current_event, %eax
call_3 print_options, $op_table, %eax, $0
L0_pick_op:
pushl %eax
print $newline
popl %eax
incl %eax
call_2 get_num_between, $1, %eax
decl %eax
call_2 get_member $op_table, %eax
pushl %eax
call_1 call_if_not_zero, 8(%eax)
popl %eax
movl 4(%eax), %eax
movl %eax, next_event #load next event
jmp L0_end
L0_msg_handler:
call_2 get_member, current_event, $1
println %eax
print $newline
call pause
movl current_event, %eax #load current event
pushl %eax
call_1 call_if_not_zero, 12(%eax)
popl %eax
movl 8(%eax), %eax
movl %eax, next_event #load next event
jmp L0_end
L0_pseudo:
call_2 get_member, current_event, $1
call *%eax
call_2 get_member, current_event, $2
movl %eax, next_event
print $newline
call pause
jmp L0_end
L0_end:
.ifdef DEBUG
print $next_event_is
call_1 get_event_name, next_event
println %eax
.endif
jmp L0_start
movl $0, %eax
leave
ret
clr:
frame
.ifndef DEBUG
call clear_screen
.else
println $devider
.endif
leave
ret
print_option_and_store:
frame
#arg0 = option pointer
#arg1 = index
#arg2 = global option table pointer
printI 12(%ebp)
#get text
call_2 get_member, 8(%ebp), $0
.ifdef DEBUG
print %eax
print $space
call_1 get_option_name, 8(%ebp)
call_2 debug_out, 8(%ebp), %eax
print $newline
.else
println %eax
.endif
#store in global table
call_3 set_member, 16(%ebp), 12(%ebp), 8(%ebp)
leave
ret
print_options:
frame
#arg0 = global option table pointer
#arg1 = current event pointer
#arg2 = boolean, if std event
#return = number of printed options
movl 12(%ebp), %eax #load event pointer
movl $0, %esi #iteration index
pushl %eax #save eax
L1_start:
load_ev_opcount (%esp)
cmpl %eax, %esi
jge L1_test_std
load_op (%esp), %esi #load option
call_3 print_option_and_store, %eax, %esi, 8(%ebp)
incl %esi
jmp L1_start
L1_test_std:
cmpl $0, 16(%ebp)
je L1_end
call_3 print_option_and_store, $ev_glbl_op_in_game_menu, %esi, 8(%ebp)
incl %esi
call_3 print_option_and_store, $ev_glbl_op_travel, %esi, 8(%ebp)
incl %esi
L1_end:
movl %esi, %eax #return total number of printed options
leave
ret
travel_populate_option:
frame
#arg0 = x
#arg1 = y
#arg2 = option ptr
#arg3 = text template
#arg4 = on_exit if known
call_2 is_in_map_bounds, 8(%ebp), 12(%ebp)
cmpl $0, %eax
je L4_unknown
call_2 get_map_event_ptr, 8(%ebp), 12(%ebp)
call_3 set_member, 16(%ebp), $1, %eax
call_3 set_member, 16(%ebp), $2, 24(%ebp)
call_2 get_map_long_name, 8(%ebp), 12(%ebp)
pushl %eax
call_2 get_member, 16(%ebp), $0
popl %ebx
call_3 str_cat, 20(%ebp), %ebx, %eax
jmp L4_end
L4_unknown:
call_3 set_member, 16(%ebp), $1, $ev_travel_invalid
call_3 set_member, 16(%ebp), $2, $0 #null out on_exit
call_2 get_member, 16(%ebp), $0
call_3 str_cat, 20(%ebp), $txt_wasteland, %eax
L4_end:
leave
ret
save_game:
frame
movl persisted_data_length, %eax
addl inventory_length, %eax
subl %eax, %esp #create buffer
pushl %esp #save 1 - buffer pointer
pushl %eax #save 2 - bytes to write
movl 4(%esp), %eax
call_3 mem_cpy, $persisted_data, %eax, persisted_data_length
movl 4(%esp), %eax
addl persisted_data_length, %eax
call_3 mem_cpy, $inventory, %eax, inventory_length
popl %eax #restore 2
popl %ebx #restore 1
call_3 save_bytes, %ebx, %eax, $stream
cmpl $0, %eax
je L7_fail
println $save_success_text
jmp L7_end
L7_fail:
call_1 print_error, $save_fail_text
L7_end:
leave
ret
load_game:
frame
call clr
movl persisted_data_length, %eax
addl inventory_length, %eax
subl %eax, %esp #create buffer
pushl %esp #save 1 - buffer pointer
movl (%esp), %ebx
call_3 load_bytes, %ebx, %eax, $stream
cmpl $0, %eax
je L8_fail
println $load_success_text
movl (%esp), %eax
call_3 mem_cpy, %eax, $persisted_data, persisted_data_length
popl %eax #restore 1
addl persisted_data_length, %eax
call_3 mem_cpy, %eax, $inventory, inventory_length
call_3 set_member, $ev_main_menu_op_load, $1, saved_event
jmp L8_end
L8_fail:
call_1 print_error, $load_fail_text
call_3 set_member, $ev_main_menu_op_load, $2, $ev_main_menu
L8_end:
print $newline
call pause
leave
ret
#here follow some void() functions that are fired by options and messages. (in lack of lambdas/anonymous functions)
travel_populate_options:
frame
call exec_save_event
movl cur_y, %eax
decl %eax
call_5 travel_populate_option, cur_x, %eax, $ev_travel_op_north, $txt_north_template, $on_travel_north
movl cur_x, %eax
incl %eax
call_5 travel_populate_option, %eax, cur_y, $ev_travel_op_east, $txt_east_template, $on_travel_east
movl cur_y, %eax
incl %eax
call_5 travel_populate_option, cur_x, %eax, $ev_travel_op_south, $txt_south_template, $on_travel_south
movl cur_x, %eax
decl %eax
call_5 travel_populate_option, %eax, cur_y, $ev_travel_op_west, $txt_west_template, $on_travel_west
leave
ret
#pseudo message event
print_character_stats:
frame
print $moves_txt
printNumln moves
print $fame_txt
printNumln moves
print $is_iron_man_txt
cmpl $0, is_iron_man
je L5_fail
println $true_txt
jmp L5_end
L5_fail:
println $false_txt
L5_end:
print $newline
call print_inventory
leave
ret
#pseudo message event
print_help:
frame
println $help1Txt
println $help2Txt
println $help3Txt
println $help4Txt
println $help5Txt
leave
ret
on_travel_north:
frame
incl moves
decl cur_y
call_2 set_discovered, cur_x, cur_y
leave
ret
on_travel_east:
frame
incl moves
incl cur_x
call_2 set_discovered, cur_x, cur_y
leave
ret
on_travel_south:
frame
incl moves
incl cur_y
call_2 set_discovered, cur_x, cur_y
leave
ret
on_travel_west:
frame
incl moves
decl cur_x
call_2 set_discovered, cur_x, cur_y
leave
ret
exec_save_event:
frame
movl current_event, %eax
movl %eax, saved_event
leave
ret
exec_op_back_to_saved:
frame
call_3 set_member, $ev_glbl_op_back_ev, $1, saved_event
leave
ret
exec_exit:
frame
call_1 exit, $0
leave
ret
ironman_final:
frame
#arg0 = op pointer
call_2 set_discovered, $0, $0
call_2 get_map_event_ptr, $0, $0
call_3 set_member, 8(%ebp), $1, %eax
leave
ret
exec_yes_ironman:
frame
movl $1, is_iron_man
call_1 ironman_final, $ev_ask_ironman_op_yes
leave
ret
exec_no_ironman:
frame
movl $0, is_iron_man
call_1 ironman_final, $ev_ask_ironman_op_no
leave
ret
.data
L0_switch_table:
.long L0_event_handler
.long L0_msg_handler
.long L0_nonstd
.long L0_pseudo
txt_north_template: .string "North - "
txt_south_template: .string "South - "
txt_east_template: .string "East - "
txt_west_template: .string "West - "
txt_wasteland: .string "wasteland"
save_success_text: .string "Save successful"
save_fail_text: .string "Save fail"
load_success_text: .string "Load successful"
load_fail_text: .string "Load failed"
moves_txt: .string "Moves: "
fame_txt: .string "Fame: "
is_iron_man_txt: .string "Is iron man: "
true_txt: .string "True"
false_txt: .string "False"
stream: .string "J:/testsave"
#help screen
help1Txt: .string "How to play this game you ask? Well let me tell you: \n"
help2Txt: .string "When you start a new game you will be put in the starting location. You will be presented with some options, this is called an 'event'. \n"
help3Txt: .string "You progress through the game by finishing events, this is done by choosing one of the options. Upon completion of an event you will either travel, get an item or die. Some events require you to have certain items to be able to complete them with a good outcome (not dieing). \n"
help4Txt: .string "You can check your inventory through the in-game menu option which will be available at standard events. When you select character stats from the in-game menu, the player name, their inventory and their score (expressed in number of moves and fame) will be printed on the screen. \n"
help5Txt: .string "The travel option is also accessable at standard events. During traveling it might be usefull to know that option 1 is North, option 2 is East, option 3 is South and option 4 is West. If 'wasteland' is an option this means that their is no location to travel to. \n"
#event struct layout:
# text
# message event flag (will be 0)
# option count
# option table...
#
#message event layout:
# text
# message event flag (will be 1)
# next event
# onExit routine
#option layout:
# text
# next event
# onExit routine
#event types:
# 0 std
# 1 message
# 2 non-std
next_event_is: .string "Next event is: "
event_at: .string "Event at: "
devider: .string "================================================="