-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFunction.asm
1837 lines (1068 loc) · 26.2 KB
/
Function.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
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
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
include_macros equ 1
include_deb_mac equ 1
include_struc equ 1
include_sequates equ 1
include_scripts equ 1
include_flags equ 1
include_logic equ 1
include_error_codes equ 1
include include.asm
start32data
max_objects equ 30
object_list dd max_objects dup (?)
tmousex dd ?
tmousey dd ?
new_safe_x dd ?
new_safe_y dd ?
current_section dd -1
end32data
start32save_data
save_current_section dd -1
past_intro dd 0 ;set when past intro sequence
end32save_data
start32code
extrn logic_turn:near
extrn logic_simple_anim:near
extrn logic_anim:near
extrn logic_script:near
extrn remove_object_from_walk:near
fn_get_to proc
; always load a get-to script- S2(28Aug92tw)
; does NOT check to see if we're at the place
; this is because with doorways you walk to different
; places according to whether the door is open or closed
; so if you click on a closed door you walk to the closed
; door & open it - if you then click again you run the
; same get-to which will now walk you through the door
; because its open. this is also the reason that the
; action mode is passed here - because some get-to's
; need to know what you're going to do in order to get
; you to the right place - strange - but true
; esi is compact
; eax is target place id
; ebx is mode - doors need to know at get-to stage
; - before the action script
mov (cpt [esi]).c_up_flag,bx ;save mode for action script
push eax ;save target place id
movzx eax,(cpt [esi]).c_place ;where we currently are
add (cpt [esi]).c_mode,4 ;next level up
fetch_compact edi
mov edi,(cpt [edi]).c_get_to_table ;get get to table
pop eax
cherror edi,e,0,em_internal_error
get_to_loop: cmp ax,[edi] ;found entry?
je load_script
cherror wpt [edi],e,-1,em_internal_error ;if we get to end (-1) then place is missing
lea edi,4[edi]
jmp get_to_loop
load_script: movzx ebx,(cpt [esi]).c_mode ;get current mode
movzx eax,wpt 2[edi] ;get new script
mov c_base_sub[esi+ebx],eax
clear eax ;drop out of script
ret ;but stay in script mode
fn_get_to endp
fn_ar proc
; Set mega esi to route to eax=x,ebx=y
mov (cpt [esi]).c_down_flag,1 ;assume failure in-case logic is interupted by speech (esp Joey)
mov (cpt [esi]).c_ar_target_x,ax
mov (cpt [esi]).c_ar_target_y,bx
mov (cpt [esi]).c_logic,l_ar ;Set to AR mode
and (cpt [esi]).c_xcood,0fff8h
and (cpt [esi]).c_ycood,0fff8h
clear eax ;drop out of script
ret
fn_ar endp
fn_leaving proc
; mega is leaving this place for the next
; sub 1 from previous place's at flag S2(14Oct92tw)
; also clear the previous at-watch flag
; its possible that neither may have been set...
; * inc'ing & dec'ing has the effect of
; showing us how many people are at a place
; and not just anyone here, yes or no
mov (cpt[esi]).c_at_watch,0 ;clear the previous place's
;at watch flag - there might
;not have been one
movzx eax,(cpt[esi]).c_leaving ;get the previous flag
jife ax,no_previous_flag
sub dpt [offset script_variables+eax],1 ;decrement the script variable
mov (cpt[esi]).c_leaving,0 ;I shall do this only once
no_previous_flag: mov al,1 ;keep going
ret
fn_leaving endp
fn_ar_animate proc
; Set compact to animation
mov (cpt[esi]).c_mood,0 ;high level 'not stood still'
mov (cpt[esi]).c_logic,l_ar_anim
clear eax ;drop out of script
ret
fn_ar_animate endp
fn_turn_to proc
; turn compact esi to direction al
mov ebx,eax
clear eax
mov al,20 ;5 tables = 5 dwords
mul (cpt[esi]).c_dir ;get current direction
mov (cpt[esi]).c_dir,bx ;set new direction
add ax,(cpt[esi]).c_mega_set
lea eax,(cpt[esi+eax]).c_turn_table_up
mov eax,[eax+ebx*4] ;get direction data
jife eax,no_turn
mov (cpt[esi]).c_turn_prog,eax ;put turn program in
mov (cpt[esi]).c_logic,l_turning
call logic_turn
clear eax ;drop out of script
ret
no_turn: mov al,1 ;keep going
ret
fn_turn_to endp
fn_set_to_stand proc
; run the appropriate animation for what
; direction the mega is facing S2(3Sep92tw)
; the animator returns to script mode
; * processes first stand cycle to avoid gaps
mov (cpt[esi]).c_mood,1 ;high level stood still
movzx eax,(cpt[esi]).c_dir ;get direction
movzx ebx,(cpt[esi]).c_mega_set ;get mega set
lea ebx,(cpt[ebx+esi]).c_stand_up
mov ebx,[ebx+eax*4] ;get pointer to data
flodsws ax,ebx ;get frames offset
mov (cpt[esi]).c_offset,ax
mov (cpt[esi]).c_grafix_prog,ebx
mov (cpt[esi]).c_logic,l_simple_mod
call logic_simple_anim
clear eax ;drop out of script
ret
fn_set_to_stand endp
fn_foreground proc
; Make sprite eax a foreground sprite
fetch_compact
and bpt(cpt[esi]).c_status,0f8h
or bpt(cpt[esi]).c_status,st_foreground
mov eax,1
ret
fn_foreground endp
fn_toggle_grid proc
; Toggle a mega's grid plotting
mov al,st_grid_plot ;use this to continue script
xor bpt(cpt[esi]).c_status,al
ret
fn_toggle_grid endp
fn_run_anim_mod proc
; Set to l_animate mode
; coordinates yes
; sync no
; eax is animation number
fetch_compact edi
; edi points to animation data
flodsws ax,edi ;get sprite set
mov (cpt[esi]).c_offset,ax
mov (cpt[esi]).c_grafix_prog,edi
mov (cpt[esi]).c_logic,l_mod_animate
call logic_anim
clear eax ;drop from script
ret
fn_run_anim_mod endp
fn_reset_id proc
; used when a mega is to be restarted
; eg - when a smaller mega turn to larger
; - a mega changes rooms...
; eax is id, ebx is reset block
fetch_compact
mov eax,ebx
fetch_compact edi
reset_loop: movzx eax,wpt[edi]
add edi,2
cmp ax,-1
je done
flodsws bx,edi
mov [esi+eax],bx
jmp reset_loop
done: ret ;ax=-1 for continue script
fn_reset_id endp
fn_inc_mega_set proc
; esi is mega
mov eax,next_mega_set ;use this to continue script
add (cpt[esi]).c_mega_set,ax
ret
fn_inc_mega_set endp
fn_dec_mega_set proc
mov eax,next_mega_set ;use this to continue script
sub (cpt[esi]).c_mega_set,ax
ret
fn_dec_mega_set endp
fn_sort proc
; Set mega eax to sort mode
fetch_compact
and bpt(cpt[esi]).c_status,0f8h
mov al,st_sort ;use this to continue script
or bpt(cpt[esi]).c_status,al
ret
fn_sort endp
fn_add_human proc
; reintroduce the mouse so that the human
; can control the player
; could still be stwitched out at high-level
test [mouse_stop],-1
jne mouse_is_locked
or [mouse_status],6 ;cursor & mouse
mov eax,[new_safe_x]
mov [tmousex],eax ;restore cursor x and y
mov eax,[new_safe_y]
mov [tmousey],eax
cmp [amouse_y],2 ;stop mouse activating top line
jnc no_y_cor
mov [amouse_y],2
no_y_cor:
; force the pointer engine into running a get-off
; even if it's over nothing
; KWIK-FIX
; get off may contain script to remove mouse pointer text
; surely this script should be run just in case
; I am going to try it anyway
mov eax,[get_off]
jife eax,no_get_off
call script
no_get_off: mov [special_item],-1
mov [get_off],reset_mouse
mouse_is_locked: mov al,1
ret
fn_add_human endp
fn_interact proc
; esi is compact
; eax is target id
add (cpt[esi]).c_mode,4 ;next level up
mov (cpt[esi]).c_logic,l_script
fetch_compact edi
movzx eax,(cpt[edi]).c_action_script ;get target action script
movzx ebx,(cpt[esi]).c_mode ;put into correct mode
mov c_base_sub[esi+ebx],eax
clear eax ;drop out of script
ret
fn_interact endp
fn_await_sync proc
test (cpt[esi]).c_sync,-1
jne that_was_quick
; Set compact to l_wait_sync
mov (cpt[esi]).c_logic,l_wait_sync
clear eax ;drop out of script
ret
that_was_quick: mov al,1
ret
fn_await_sync endp
fn_pause proc
; Set mega to l_pause
; wait eax cycles
mov (cpt[esi]).c_flag,ax
mov (cpt[esi]).c_logic,l_pause
clear eax ;drop out of script
ret
fn_pause endp
fn_send_sync proc
; Send a sync to a mega
; eax is mega
; ebx is sync value
fetch_compact
mov (cpt[esi]).c_sync,bx
clear eax ;drop out of script
ret
fn_send_sync endp
fn_quit proc
clear eax ;just drop out of the script
ret
fn_quit endp
fn_run_frames proc
; Set to l_frames
; sync checks but not on this first cycle
; eax is sequence number
fetch_compact edi
mov (cpt[esi]).c_logic,l_frames
mov ax,[edi]
mov (cpt[esi]).c_offset,ax
add edi,2
cherror wpt[edi],e,0,em_internal_error
mov (cpt[esi]).c_grafix_prog,edi
call logic_simple_anim
clear eax ;drop out of script
ret
fn_run_frames endp
fn_set_alternate proc
; change current script
; takes a whole cycle
; esi is mega
; ax is script
mov (cpt[esi]).c_alt,ax
mov (cpt[esi]).c_logic,l_alt
clear eax ;stop the script
ret
fn_set_alternate endp
fn_simple_mod proc
; set to l_simple_mod mode S2(19Nov92tw)
; as FN_run_anim_mod except we ignore
; the x,y coordinates in the sequence data
; eax is anim seq number
fetch_compact edi
flodsws ax,edi
and eax,0ffffh
mov (cpt[esi]).c_offset,ax
cherror wpt[edi],e,0,em_internal_error
mov (cpt[esi]).c_grafix_prog,edi
mov (cpt[esi]).c_logic,l_simple_mod
call logic_simple_anim
clear eax
ret
fn_simple_mod endp
fn_random proc
; eax is a number to and the random number with
push eax
call do_random
pop ebx
movzx eax,wpt[random+2]
and eax,ebx
mov [rnd],eax
mov al,1 ;continue script
ret
fn_random endp
fn_clear_stop proc
mov [mouse_stop],0
mov al,1
ret
fn_clear_stop endp
fn_idle proc
; set the player idling
mov (cpt[esi]).c_logic,0
mov al,1 ;script continues
ret
fn_idle endp
fn_kill_id proc
; remove compact eax from game
jife eax,fk_ret ;id 0 = kill text
push esi
fetch_compact
bt (cpt[esi]).c_status,7 ;plotted into grid?
jnc not_on_grid
call remove_object_from_walk
not_on_grid: mov (cpt[esi]).c_status,0
pop esi
fk_ret: mov al,1 ;continue
ret
fn_kill_id endp
fn_start_menu proc
; initialise the top menu bar S2(9Oct92tw)
; eax contains the address of the 1st object (o0 for game menu, k0 for linc)
add eax,offset script_variables
push eax
; (1) FIRST, SET UP THE 2 ARROWS SO THEY APPEAR ON SCREEN
mov edx,[screen]
mov eax,47
fetch_compact
mov (cpt[esi]).c_status,st_mouse+st_foreground+st_logic+st_recreate
mov (cpt[esi]).c_screen,dx
mov eax,48
fetch_compact
mov (cpt[esi]).c_status,st_mouse+st_foreground+st_logic+st_recreate
mov (cpt[esi]).c_screen,dx
; (2) COPY OBJECTS FROM NON-ZERO INVENTORY VARIABLES INTO OBJECT DISPLAY LIST (& COUNT THEM)
; sort the objects and pad with blanks
pop esi
mov edi,offset object_list
mov ecx,max_objects
clear edx
menu_create: lodsd
jife eax,empty_slot
stosd
inc edx
empty_slot: loop menu_create
mov [menu_length],edx ;save menu length
; (3) OK, NOW TOP UP THE LIST WITH THE REQUIRED NO. OF BLANK OBJECTS (for min display length 11)
cmp edx,11
jnc stage_4
mov eax,51 ;id of first blank
mov ecx,11
sub ecx,edx
do_blank: stosd
inc eax
loop do_blank
; (4) KILL ID's OF ALL 20 OBJECTS SO UNWANTED ICONS (SCROLLED OFF) DON'T REMAIN ON SCREEN
; (There should be a better way of doing this - only kill id of 12th item when menu has scrolled right)
stage_4: mov esi,offset object_list
mov ecx,max_objects
reset_icons_loop: lodsd
jife eax,menu_5
fetch_compact edi
mov (cpt[edi]).c_status,st_logic
loop reset_icons_loop
; (5) NOW FIND OUT WHICH OBJECT TO START THE DISPLAY FROM (depending on scroll offset)
menu_5: mov esi,offset object_list
cmp edx,11 ;check we can scroll
jnc can_scroll
mov [scroll_offset],0
jmp stage_6
can_scroll: mov ebx,[scroll_offset]
sub edx,11 ;make edx no we can scroll
cmp ebx,edx
jc calc_bytes
mov ebx,edx
mov [scroll_offset],ebx
calc_bytes: shl ebx,2 ;no of bytes to skip in object list
add esi,ebx
; (6) AND FINALLY, INITIALISE THE 11 OBJECTS SO THEY APPEAR ON SCREEEN
stage_6: mov edx,[menu] ;check if id_std_menu_logic
;sub edx,id_std_menu_logic
mov ebp,[screen]
mov ecx,11
mov ebx,128+28 ;rolling x coordinate
menu_int_loop: lodsd
fetch_compact edi
mov (cpt[edi]).c_status,st_mouse+st_foreground+st_logic+st_recreate
mov (cpt[edi]).c_screen,bp
mov (cpt[edi]).c_xcood,bx
add bx,24
mov (cpt[edi]).c_ycood,112
cmp edx,2
jne next_object
mov (cpt[edi]).c_ycood,136 ;set y-coord to fully down because menu fully down
; and so player might be scrolling new icons into view
next_object: loop menu_int_loop
mov al,1 ;carry on
ret
fn_start_menu endp
fn_assign_base proc
; start id processing a base script S2(26Aug92tw)
; used when player clicks on something, or,
; when a mega is to have a new base... etc.
; eax is id
; ebx is script
fetch_compact
mov (cpt[esi]).c_mode,c_base_mode
mov (cpt[esi]).c_logic,l_script
mov (cpt[esi]).c_base_sub,ebx
mov al,1 ;keep going
ret
fn_assign_base endp
fn_toggle_mouse proc
; Toggle the mouse highlighting
; eax is id
fetch_compact
xor (cpt[esi]).c_status,st_mouse
mov al,1
ret
fn_toggle_mouse endp
fn_move_items proc
; Move a list of id's to another screen
; eax is list number
; ebx is screen number
mov edi,[offset move_list+eax*4]
move_loop: flodswl eax,edi
jife eax,move_done
fetch_compact
mov (cpt[esi]).c_screen,bx
jmp move_loop
move_done: mov al,1
ret
fn_move_items endp
fn_send_fast_sync proc
; send a sync to a mega, continue with current script
; eax is mega id
; ebx is sync value
fetch_compact
mov (cpt[esi]).c_sync,bx
mov al,1
ret
fn_send_fast_sync endp
fn_background proc
; set us to background
and (cpt[esi]).c_status,0fff8h
or (cpt[esi]).c_status,st_background
mov al,1
ret
fn_background endp
fn_we_wait proc
; We have hit another mega
; we are going to wait for it to move
; esi is us
; eax is it's id
mov (cpt[esi]).c_waiting_for,ax
fn_we_wait endp
;NOWT IN YERE
stop_and_wait proc
; 2nd entry point called from logic_ar_animate
add (cpt[esi]).c_mode,4
movzx eax,(cpt[esi]).c_stop_script
movzx ebx,(cpt[esi]).c_mode
mov c_base_sub[esi+ebx],eax
mov (cpt[esi]).c_logic,l_script
jmp logic_script
stop_and_wait endp
fn_no_sprite_engine proc
; stop the compact printing S2(29Oct92tw)
; remove foreground, background & sort
and (cpt[esi]).c_status,0fff8h
mov al,1
ret
fn_no_sprite_engine endp
fn_face_id proc
; return the direction to turn to face another id
; esi is us
; eax is id to turn to
; pass back result in c_just_flag
fetch_compact edi
mov ax,(cpt[esi]).c_xcood
sub ax,(cpt[edi]).c_xcood ;check left
jnc its_to_left
; we're to the left
neg ax
mov (cpt[esi]).c_get_to_flag,3
jmp vertical_check
its_to_left: mov (cpt[esi]).c_get_to_flag,2
vertical_check: ;now check y
; ax is x diff
mov bx,(cpt[esi]).c_ycood
; we must find the true bottom of the sprite
; it is not enough to use y coord because changing
; sprite offsets can ruin the formula - instead we
; will use the bottom of the mouse collision area
mov cx,(cpt[edi]).c_ycood
add cx,(cpt[edi]).c_mouse_rel_y
add cx,(cpt[edi]).c_mouse_size_y
sub bx,cx
jnc its_above
neg bx
cmp bx,ax ;check if hor > ver
jc end_of_fn
mov (cpt[esi]).c_get_to_flag,1 ;we will face down
end_of_fn: mov al,1
ret
its_above: cmp bx,ax
jc end_of_fn
mov (cpt[esi]).c_get_to_flag,0
mov al,1
ret
fn_face_id endp
fn_start_sub proc
; Run a subroutine
add (cpt[esi]).c_mode,4
movzx ebx,(cpt[esi]).c_mode
mov c_base_sub[esi+ebx],eax
clear eax ;drop out
ret
fn_start_sub endp
fn_send_request proc
; send an interaction script to id
; eax is id of target
; ebx is script
fetch_compact
mov (cpt[esi]).c_request,bx
clear eax ;drop out
ret
fn_send_request endp
fn_check_request proc
; check for interaction request S2(23Sep92tw)
; setup if found
; should be called from base -
; (anything above base will be destroyed)
mov al,1 ;assume script continue
test (cpt[esi]).c_request,-1
je fcr_ret
mov (cpt[esi]).c_mode,c_action_mode ;into action mode
movzx ebx,(cpt[esi]).c_request ;get script
mov (cpt[esi]).c_action_sub,ebx
clear eax ;drop from script
mov (cpt[esi]).c_request,ax ;and trash request
fcr_ret: ret
fn_check_request endp
fn_stop_mode proc
; switch compact into stop mode
mov (cpt[esi]).c_logic,l_stopped
clear eax ;stop the script
ret
fn_stop_mode endp
fn_fetch_place proc
; fetch the c_place of a mega
fetch_compact
movzx eax,(cpt[esi]).c_place
mov [result],eax
mov al,1
ret
fn_fetch_place endp