AUTO.S (27571B)
1 * auto 2 DemoDisk = 0 3 org = $5400 4 tr on 5 lst off 6 *------------------------------- 7 * 8 * PRINCE OF PERSIA 9 * Copyright 1989 Jordan Mechner 10 * 11 *------------------------------- 12 org org 13 14 jmp AUTOCTRL 15 jmp CHECKSTRIKE 16 jmp CHECKSTAB 17 jmp AUTOPLAYBACK 18 jmp CUTCHECK 19 20 jmp CUTGUARD 21 jmp ADDGUARD 22 jmp CUT 23 24 *------------------------------- 25 lst 26 put eq 27 lst 28 put gameeq 29 lst 30 put seqdata 31 lst 32 put soundnames 33 lst 34 put movedata 35 lst off 36 37 dum $f0 38 ztemp ds 1 39 prob ds 1 40 ]cutdir ds 1 41 ProgStart ds 2 42 dend 43 44 plus1 db -1,1 45 minus1 db 1,-1 46 47 * Thresholds for cut to new screen 48 49 TopCutEdgePl = ScrnTop+10 50 TopCutEdgeMi = ScrnTop-16 51 BotCutEdge = ScrnBottom+24 52 53 LeftCutEdge = ScrnLeft-4 54 RightCutEdge = ScrnRight+4 55 56 *------------------------------- 57 * Locations of special objects 58 59 flaskscrn = 24 60 flaskx = 3 61 flasky = 0 62 63 mirscrn = 4 64 mirx = 4 65 miry = 0 66 67 swordscrn = 15 68 swordx = 1 69 swordy = 0 70 71 mousetimer = 150 ;from topctrl 72 73 *------------------------------- 74 * Strike/block ranges 75 76 strikerange1 = 12 77 strikerange2 = 29 78 blockrange1 = 0 79 blockrange2 = 29 ;from TestStrike 80 81 *------------------------------- 82 * Other constants: 83 84 swordthres = 90 85 engardethres = 60 86 strikethres1 = strikerange1 87 strikethres2 = strikerange2 88 blockthres1 = 10 89 blockthres2 = blockrange2 90 tooclose = strikethres1 91 toofar = strikethres2+6 ;min dist at which you can advance safely 92 offguardthres = 8 93 jumpthres = 50 94 runthres = 40 95 blocktime = 4 96 97 *------------------------------- 98 * 99 * Fighter params (indexed by guardprog #) 100 * 101 * strikeprob = probability x255 of striking from ready posn 102 * restrikeprob = prob x 255 of restriking after blocking 103 * blockprob = prob x255 of blocking opponent's strike 104 * advprob = of advancing to within striking range 105 * refractimer = length of refractory period after being hit 106 * 107 * 0 1 2 3 4 5 6 7 8 9 10 11 108 109 strikeprob 110 db 075,100,075,075,075,050,100,220,000,060,040,060 111 restrikeprob 112 db 000,000,000,005,005,175,020,010,000,255,255,150 113 blockprob 114 db 000,150,150,200,200,255,200,250,000,255,255,255 115 impblockprob 116 db 000,075,075,100,100,145,100,250,000,145,255,175 117 advprob 118 db 255,200,200,200,255,255,200,000,000,255,100,100 119 refractimer 120 db 020,020,020,020,010,010,010,010,000,010,000,000 121 specialcolor 122 db 000,000,000,001,000,001,001,000,000,000,000,001 123 extrastrength 124 db 000,000,000,000,001,000,000,000,000,000,000,000 125 126 numprogs = 12 127 128 *------------------------------- 129 * Basic guard strength & uniform color (indexed by level #) 130 131 basicstrength 132 db 4,3,3,3,3,4,5 ;levels 0-6 133 db 4,4,5,5,5,4,6 ;levels 7-13 134 135 basiccolor 136 db 1,0,0,0,1,1,1 ;0 = blue, 1 = red 137 db 0,0,0,1,1,0,0 138 139 shadstrength = 4 140 141 *------------------------------- 142 * 143 * 10: kid (demo) 144 * 11: enemy (demo) 145 * 146 *------------------------------- 147 * 148 * Automatic enemy control routine 149 * 150 * In: Char vars reflect position in PRECEDING frame; 151 * Op vars reflect position in UPCOMING frame 152 * guardprog = program # 153 * 154 * (Exception: When used by kid fighting in demo, both 155 * Char & Op vars reflect preceding frame.) 156 * 157 *------------------------------- 158 ]rts rts 159 160 AUTOCTRL 161 jsr DoRelease 162 163 lda CharID 164 beq :5 ;control kid in demo 165 166 lda justblocked 167 beq :jb0 168 dec justblocked 169 170 :jb0 lda gdtimer 171 beq :gt0 172 dec gdtimer 173 :gt0 174 lda refract ;refractory period after being hit 175 beq :2 176 dec refract 177 :2 178 lda CharID 179 cmp #24 ;mouse? 180 beq :6 181 cmp #4 ;skel? 182 beq :3 183 cmp #2 ;guard? 184 bcc :1 185 lda level 186 cmp #13 ;vizier? 187 beq :4 188 jmp GuardProg 189 :1 jmp ShadowProg 190 :3 jmp SkelProg 191 :4 jmp VizierProg 192 :5 jmp KidProg 193 :6 jmp MouseProg 194 195 *------------------------------- 196 * M O U S E 197 *------------------------------- 198 MouseProg 199 lda CharFace 200 cmp #86 201 beq ]rts 202 lda CharAction 203 beq :1 ;already stopped 204 lda CharX 205 cmp #166 206 bcs ]rts 207 lda #Mleave 208 jsr jumpseq 209 jmp animchar ;sets CharAction = 0 210 211 :1 lda CharX 212 cmp #200 213 bcc ]rts 214 jmp VanishChar 215 216 *------------------------------- 217 * S H A D O W M A N 218 *------------------------------- 219 do DemoDisk 220 ShadowProg 221 SkelProg 222 VizierProg 223 brk 224 225 else 226 ShadowProg 227 lda level 228 cmp #4 229 bne :0 230 jmp ShadLevel4 231 232 :0 cmp #5 233 bne :1 234 jmp ShadLevel5 235 236 :1 cmp #6 237 bne :2 238 jmp ShadLevel6 239 240 :2 cmp #12 241 bne :3 242 jmp FinalShad 243 :3 244 ]rts rts 245 246 *------------------------------- 247 * Level-specific code for: 248 * Level 6 (plunge) 249 *------------------------------- 250 ShadLevel6 251 lda CharScrn 252 cmp #1 253 beq Shad6a 254 rts 255 256 * Level 6, screen 1 257 * When kid jumps chasm, step on plate 258 259 Shad6a 260 lda KidPosn 261 cmp #43 262 bne ]rts 263 lda KidX 264 cmp #$80 265 bcs ]rts 266 jsr DoPress 267 jmp DoFwd ;step fwd 268 269 *------------------------------- 270 * Level 5 (THIEF) 271 *------------------------------- 272 ShadLevel5 273 lda CharScrn 274 cmp #flaskscrn 275 beq Shad5 276 ]rts rts 277 278 * Level 5, screen 24 279 * When gate opens, steal potion 280 281 Shad5 282 lda PlayCount 283 bne :1 ;continue playback 284 285 lda #flaskscrn 286 ldx #1 ;x 287 ldy #0 ;y 288 jsr rdblock ;gate 289 lda (BlueSpec),y 290 cmp #20 291 bcc ]rts 292 ;begin playback 293 lda #0 294 sta PreRecPtr 295 296 :1 lda #ShadProg5 297 ldx #>ShadProg5 298 jsr AutoPlayback 299 300 lda CharX 301 cmp #15 302 bcs ]rts 303 jmp VanishChar 304 305 *------------------------------- 306 * Level 4 (mirror) 307 *------------------------------- 308 ShadLevel4 309 lda CharScrn 310 cmp #4 311 bne ]rts 312 lda CharX 313 cmp #80 314 bcc :gone 315 jmp DoFwd ;run o.s. 316 :gone jmp VanishChar 317 318 *------------------------------- 319 * Level 12 (final battle) 320 *------------------------------- 321 FinalShad 322 323 * Screen 15: Jump on top of kid 324 325 lda CharScrn 326 cmp #swordscrn 327 bne :cont 328 lda shadowaction 329 bne :cont ;already did it 330 lda OpX 331 cmp #150 332 bcs :hold ;hold shad at top until kid arrives 333 334 lda #1 335 sta shadowaction 336 bne :cont 337 338 :hold lda #shadpos12 339 ldx #>shadpos12 340 jmp csps 341 ]rts rts 342 343 * Continue 344 345 :cont lda CharSword 346 cmp #2 347 bcs :fight 348 lda OpSword 349 cmp #2 350 bcs :hostile 351 lda offguard 352 bne :face 353 :hostile 354 lda EnemyAlert 355 cmp #2 356 bcc :2 357 jsr getopdist 358 cmp #swordthres 359 bcs :2 ;wait until kid gets close 360 361 lda CharPosn 362 cmp #15 363 bne ]rts 364 jmp DoEngarde ;draw on kid 365 366 * turn to face kid 367 368 :2 jsr getopdist 369 bpl ]rts 370 jmp DoBack 371 372 * Normal fighting 373 374 :fight 375 lda offguard 376 beq :1 ;has kid put up sword? 377 lda refract 378 bne :1 ;yes--wait a moment-- 379 jmp DoDown ;--then lower your guard 380 381 :1 jmp EnGarde ;normal fighting 382 383 * Face to face--swords down 384 385 :face jsr getopdist 386 bmi :merge ;whammo! 387 388 lda EnemyAlert 389 cmp #2 390 bne :wait 391 lda OpPosn 392 cmp #3 393 bcc :wait 394 cmp #15 395 bcc :go 396 cmp #127 397 bcc :wait 398 cmp #133 399 bcs :wait 400 401 * If kid starts moving towards you, reciprocate 402 * (Accept startrun & stepfwd) 403 404 :go jmp DoFwd 405 406 * Kid & shadow reunite 407 408 :merge 409 lda #$ff ;white 410 sta lightcolor 411 lda #10 412 sta lightning 413 414 jsr boostmeter 415 416 lda #s_Rejoin 417 ldx #85 418 jsr cuesong 419 420 lda #42 421 sta mergetimer 422 423 lda #0 424 sta CharID 425 jsr SaveKid ;shadow turns into kid 426 jmp VanishChar 427 :wait 428 ]rts rts 429 430 *------------------------------- 431 * S K E L E T O N 432 *------------------------------- 433 SkelProg 434 lda #2 435 sta CharSword 436 jmp GuardProg 437 438 *------------------------------- 439 * V I Z I E R 440 *------------------------------- 441 VizierProg 442 jmp GuardProg 443 444 fin ;DemoDisk 445 446 *------------------------------- 447 * K I D (in demo) 448 *------------------------------- 449 KidProg 450 jmp GuardProg 451 452 *------------------------------- 453 * G U A R D 454 *------------------------------- 455 GuardProg 456 lda CharSword 457 cmp #2 ;Are you already en garde? 458 bcc Alert ;no 459 jmp EnGarde ;yes 460 ]rts rts 461 462 *------------------------------- 463 * 464 * Alert (not en garde) 465 * 466 *------------------------------- 467 Alert 468 lda KidLife 469 bpl ]rts ;kid's dead--relax 470 471 * If kid is behind you, turn to face him 472 473 jsr getopdist 474 ldx OpBlockY 475 cpx CharBlockY 476 bne :difflevel 477 cmp #-8 ;if kid is right on top of you, go en garde! 478 bcs :eng 479 :difflevel 480 ldx alertguard 481 beq :ok ;otherwise wait for a sound to alert you 482 ldx #0 483 stx alertguard 484 :alert 485 cmp #128 486 bcc :eng 487 cmp #-4 488 bcs :ok ;overlapping--stand still 489 jmp DoTurn ;turn around 490 491 * If you can see kid, go en garde 492 493 :ok cmp #128 494 bcs ]rts ;kid is behind you 495 496 :eng lda EnemyAlert 497 beq ]rts 498 499 lda level 500 cmp #13 501 bne :1 ;Vizier only: wait for music to finish 502 lda SongCue 503 bne ]rts 504 505 :1 jmp DoEngarde 506 ]rts rts 507 508 *------------------------------- 509 * 510 * En garde 511 * 512 *------------------------------- 513 EnGarde 514 lda CharPosn 515 cmp #166 516 beq ]rts 517 cmp #150 518 bcc ]rts ;wait till you're ready 519 520 lda EnemyAlert 521 cmp #2 522 bcs :ea2 523 cmp #1 ;EnemyAlert = 1: Kid is in sight, but a 524 beq ]rts ;gap or barrier separates you--stay put 525 526 * Kid is out of sight (EnemyAlert = 0) 527 * If kid has "dropped out" of fight, follow him down 528 529 lda droppedout ;flag set by CHECKFLOOR 530 beq :1 531 jmp FollowKid 532 533 * else return to alert position 534 535 :1 lda CharID 536 cmp #4 537 beq ]rts ;(except skeleton) 538 jmp DoDropguard 539 540 * EnemyAlert = 2: Clear stretch of floor to player 541 542 * If kid is stunned, let him recover... 543 544 :ea2 jsr getopdist 545 bmi :norec 546 cmp #12 547 bcc :norec ;unless he's right on top of you 548 lda OpPosn 549 cmp #102 550 bcc :norec 551 cmp #118 552 bcs :norec 553 lda OpAction 554 cmp #5 555 beq ]rts 556 :norec 557 558 * Advance to closest safe distance 559 560 jsr getopdist 561 cmp #toofar 562 bcs :outofrange 563 564 ldx CharSword 565 cpx #2 566 bcc :offg 567 568 cmp #tooclose 569 bcc :tooclose 570 jmp InRange 571 572 :offg cmp #offguardthres 573 bcc :tooclose 574 jmp InRange 575 ]rts rts 576 577 * Out of range 578 579 :outofrange 580 lda refract 581 bne ]rts 582 583 lda CharFace 584 cmp OpFace 585 beq :nojump ;chase him 586 587 lda OpPosn 588 cmp #7 589 bcc :norun 590 cmp #15 591 bcc :runwait 592 :norun 593 cmp #34 594 bcc :nojump 595 cmp #44 596 bcc :jumpwait ;If kid is running towards you, stay put 597 :nojump 598 jsr getinfront 599 jsr cmpspace ;Don't advance unless solid floor 600 beq :gap 601 jsr get2infront 602 jsr cmpspace 603 bne :solid 604 605 :gap jmp DoRetreat 606 :solid jmp DoAdvance 607 608 * Kid is trying to get past you--cut him down! 609 610 :jumpwait 611 jsr getopdist 612 cmp #jumpthres 613 bcs ]rts ;wait 614 jmp DoStrike 615 616 :runwait 617 jsr getopdist 618 cmp #runthres 619 bcs ]rts 620 :strike jmp DoStrike 621 622 * Too close to hit him 623 624 :tooclose 625 lda CharFace 626 cmp OpFace 627 beq :ret 628 jmp DoAdvance 629 :ret jmp DoRetreat 630 631 *------------------------------- 632 * 633 * Kid has "dropped out" of fight 634 * Advance until you run out of floor-- 635 * then decide whether to jump down after him 636 * 637 *------------------------------- 638 FollowKid 639 lda OpAction 640 cmp #2 641 beq :hanging 642 cmp #6 643 beq :hanging ;wait--kid is hanging on ledge 644 645 jsr getinfront 646 sta ztemp 647 jsr cmpbarr 648 bne :stopped 649 lda ztemp 650 jsr cmpspace 651 beq :atedge 652 jmp DoAdvance 653 654 * At edge of floor. Follow kid down ONLY if: 655 * (1) it's a 1-story drop to solid floor 656 * (2) kid is still down there 657 658 :atedge 659 jsr getinfront 660 inc tempblocky 661 jsr rdblock1 662 sta ztemp ;is it safe? 663 cmp #spikes 664 beq :stopped 665 cmp #loose 666 beq :stopped 667 jsr cmpbarr 668 bne :stopped 669 lda ztemp 670 jsr cmpspace 671 beq :stopped 672 673 lda CharBlockY 674 clc 675 adc #1 676 cmp OpBlockY 677 bne :stopped ;kid's not down there 678 679 * It looks safe--follow him down 680 681 jmp DoAdvance 682 683 :stopped lda #0 684 sta droppedout 685 jmp DoRetreat ;so you can kill him if he climbs up 686 :hanging 687 ]rts rts 688 689 *------------------------------- 690 * 691 * In range 692 * 693 *------------------------------- 694 InRange 695 lda OpSword ;is opponent armed & en garde? 696 cmp #2 697 beq :fight ;yes 698 699 * Opponent is unarmed or off guard--maul him! 700 701 lda refract 702 bne ]rts 703 704 jsr getopdist 705 cmp #strikethres2 706 bcc :1 707 jmp DoAdvance ;advance until within range... 708 :1 jmp DoStrike ;then strike 709 710 * Opponent is en garde--use strategy 711 712 :fight 713 jmp GenFight 714 715 *------------------------------- 716 * 717 * General Fighting Routine 718 * 719 * (Fighters are en garde, face to face, and too close to 720 * advance safely) 721 * 722 *------------------------------- 723 GenFight 724 jsr getopdist 725 cmp #blockthres1 726 bcc :outofrange 727 cmp #blockthres2 728 bcs :outofrange 729 730 jsr MaybeBlock ;block opponent's strike? 731 732 lda refract 733 bne ]rts 734 735 jsr getopdist 736 cmp #strikethres1 737 bcc :outofrange 738 cmp #strikethres2 739 bcs :outofrange 740 741 jmp MaybeStrike ;strike? 742 743 :outofrange 744 jmp MaybeAdvance ;advance to within strike range? 745 ]rts rts 746 747 *------------------------------- 748 * 749 * Advance to within strike range? 750 * (Only consider it if gdtimer = 0) 751 * 752 *------------------------------- 753 MaybeAdvance 754 lda guardprog 755 beq :dumb ;Guard #0 is too dumb to care 756 lda gdtimer 757 bne ]rts 758 759 :dumb jsr rndp 760 cmp advprob,x 761 bcs ]rts 762 763 jmp DoAdvance 764 765 *------------------------------- 766 * 767 * Block opponent's strike? 768 * 769 *------------------------------- 770 MaybeBlock 771 lda OpPosn 772 cmp #152 ;guy4 773 beq :99 774 cmp #153 ;guy5 775 beq :99 776 cmp #162 ;guy22 (block to strike) 777 bne ]rts 778 779 :99 lda justblocked 780 bne :impaired 781 jsr rndp 782 cmp blockprob,x 783 bcc :block 784 ]rts rts 785 786 :impaired 787 jsr rndp 788 cmp impblockprob,x 789 bcs ]rts 790 :block jmp DoBlock 791 792 *------------------------------- 793 * 794 * Strike? 795 * 796 *------------------------------- 797 MaybeStrike 798 ldx OpPosn 799 cpx #169 800 beq ]rts 801 cpx #151 ;opponent starting to strike? 802 beq ]rts ;yes--don't strike 803 804 ldx CharPosn 805 cpx #161 ;have I just blocked? 806 beq :restrike 807 cpx #150 808 beq :restrike ;yes--restrike? 809 810 jsr rndp 811 cmp strikeprob,x 812 bcs ]rts 813 jmp DoStrike 814 815 :restrike 816 jsr rndp 817 cmp restrikeprob,x 818 bcs ]rts 819 jmp DoStrike 820 821 *------------------------------- 822 DoRelease 823 lda #0 824 sta clrF 825 sta clrB 826 sta clrU 827 sta clrD 828 sta clrbtn 829 sta JSTKX 830 sta JSTKY 831 sta btn 832 rts 833 834 DoAdvance 835 DoFwd 836 lda #-1 837 sta clrF 838 sta JSTKX 839 rts 840 841 DoRetreat 842 DoBack 843 lda #-1 844 sta clrB 845 lda #1 846 sta JSTKX 847 rts 848 849 DoBlock 850 DoUp lda #-1 851 sta clrU 852 sta JSTKY 853 rts 854 855 DoTurn 856 DoDown lda #-1 857 sta clrD 858 lda #1 859 sta JSTKY 860 rts 861 862 DoStandup 863 lda #-1 864 sta clrU 865 jmp DoBack 866 867 DoDropguard 868 DoRunaway 869 lda #-1 870 sta clrD 871 jmp DoBack 872 873 DoEngarde 874 lda #-1 875 sta clrD 876 jmp DoFwd 877 878 DoStrike 879 DoPress 880 lda #-1 881 sta clrbtn 882 sta btn 883 rts 884 885 DoRelBtn 886 lda #0 887 sta btn 888 ]rts rts 889 890 *------------------------------- 891 * 892 * R N D P 893 * 894 * Return X = guardprog, A = rnd # 895 * 896 *------------------------------- 897 rndp 898 ldx guardprog 899 jmp rnd 900 901 *------------------------------- 902 * 903 * C H E C K S T R I K E 904 * 905 * Check for sword contact 906 * 907 * Going in: Kid & Shad vars represent position in 908 * UPCOMING frame 909 * 910 * Out: Kid & Shad vars 911 * (Return Action = 99 if stabbed) 912 * 913 *------------------------------- 914 CHECKSTRIKE 915 lda KidPosn 916 beq ]rts 917 cmp #219 918 bcc :noclimb 919 cmp #229 920 bcc ]rts ;on staircase 921 :noclimb 922 jsr LoadShadwOp 923 jsr TestStrike 924 jsr SaveShadwOp 925 926 jsr LoadKidwOp 927 jsr TestStrike 928 jsr SaveKidwOp 929 930 ]rts rts 931 932 *------------------------------- 933 TestStrike 934 935 lda CharSword 936 cmp #2 ;in fighting mode? 937 bne ]rts ;no 938 939 lda CharBlockY 940 cmp OpBlockY 941 bne ]rts 942 943 * Am I on a test (strike) frame? 944 945 lda CharPosn 946 cmp #153 ;guy5 (frame before full ext.) 947 beq :test 948 cmp #154 ;guy6 (full ext.) 949 bne ]rts 950 951 * I'm striking--is opponent blocking? 952 953 :test 954 jsr getopdist 955 cmp #blockrange1 956 bcc :nobloc 957 958 cmp #blockrange2 959 bcs :nobloc 960 961 lda OpPosn 962 cmp #161 963 beq :11 964 cmp #150 ;blocking? 965 bne :nobloc ;no 966 967 * Yes -- opponent blocks my strike 968 969 :1 lda #161 970 sta OpPosn ;change opp to "successful block" 971 972 :11 lda CharID 973 beq :12 ;am I a guard? 974 lda #blocktime ;yes--impair my blocking ability for a while 975 sta justblocked 976 977 :12 lda #blockedstrike 978 jsr jumpseq 979 jmp animchar 980 981 * Skewer opponent? 982 983 :nobloc 984 lda CharPosn 985 cmp #154 ;full ext 986 bne ]rts 987 988 jsr getopdist 989 990 ldx OpSword 991 cpx #2 992 bcs :ong 993 cmp #offguardthres 994 bcs :cont1 995 rts 996 :ong cmp #strikerange1 997 bcc ]rts 998 999 :cont1 cmp #strikerange2 1000 bcs ]rts 1001 1002 lda #99 "stabbed" 1003 sta OpAction 1004 ]rts rts 1005 1006 *------------------------------- 1007 * C H E C K S T A B 1008 *------------------------------- 1009 CHECKSTAB 1010 lda ShadAction 1011 cmp #99 1012 bne :1 1013 1014 lda KidAction 1015 cmp #99 1016 beq :doublestab 1017 :2 1018 jsr LoadShad 1019 jsr StabChar 1020 jsr SaveShad 1021 1022 jsr rndp 1023 lda refractimer,x 1024 sta refract 1025 1026 :1 lda KidAction 1027 cmp #99 1028 bne ]rts 1029 1030 jsr LoadKid 1031 jsr StabChar 1032 jmp SaveKid 1033 1034 * Both chars finish lunge simultaneously 1035 1036 :doublestab 1037 lda #1 1038 sta KidAction 1039 bne :2 ;player wins a tie 1040 ]rts rts 1041 1042 *------------------------------- 1043 * Change shadowman posn 1044 * In: A-X = shadpos L-H 1045 * Out: Char data 1046 *------------------------------- 1047 chgshadposn 1048 sta ztemp 1049 stx ztemp+1 1050 ldy #6 1051 :loop lda (ztemp),y 1052 sta Char,y 1053 dey 1054 bpl :loop 1055 1056 ldy #7 1057 lda (ztemp),y 1058 jsr jumpseq 1059 1060 lda #1 1061 sta CharID 1062 1063 lda #0 1064 sta PlayCount ;zero playback counter 1065 rts 1066 1067 * ... & save 1068 1069 csps jsr chgshadposn 1070 1071 lda #3 1072 sta guardprog 1073 1074 lda #shadstrength 1075 sta MaxOppStr 1076 sta OppStrength 1077 1078 jmp SaveShad 1079 1080 *------------------------------- 1081 * (Posn, X, Y, Face, BlockX, BlockY, Action) 1082 * 0 1 2 3 4 5 6 1083 1084 shadpos6a hex 0f,51,76,00,00,01,00 1085 db stand 1086 1087 shadpos5 hex 0f,37,37,00,ff,00,00 1088 db stand ;just o.s. to L 1089 1090 shadpos12 hex 0f,51,f0,00,00,00,00 1091 db stepfall 1092 1093 *------------------------------- 1094 EndProg = -2 1095 EndDemo = -1 1096 Ctr = 0 1097 Fwd = 1 1098 Back = 2 1099 Up = 3 1100 Down = 4 1101 Upfwd = 5 1102 Press = 6 1103 Release = 7 1104 1105 * Commands: 1106 * 1107 * -2 - end of programmed sequence 1108 * -1 - end of demo 1109 * 0 - center jstk & release btn 1110 * 1 - jstk fwd 1111 * 2 - jstk back 1112 * 3 - jstk up 1113 * 4 - jstk down 1114 * 5 - jstk up & fwd 1115 * 6 - press & hold btn 1116 * 7 - release btn 1117 1118 *------------------------------- 1119 * 1120 * Prerecorded sequence format: 1121 * 1122 * 1. Frame # (1 byte) 1123 * 2. Command (1 byte) 1124 * 1125 * 255 frames = approx. 25-30 seconds 1126 * 1127 *------------------------------- 1128 * Level 5 (THIEF): Steal potion 1129 1130 ShadProg5 1131 db 0,Ctr 1132 db 1,Fwd 1133 db 14,Ctr 1134 db 18,Press 1135 db 29,Release 1136 db 45,Back 1137 db 49,Fwd 1138 db 255,EndProg 1139 1140 *------------------------------- 1141 * 1142 * Play back prerecorded movement sequence 1143 * 1144 * In: A-X = program start addr 1145 * PlayCount = frame # 1146 * PreRecPtr = pointer to next command 1147 * 1148 *------------------------------- 1149 AUTOPLAYBACK 1150 sta ProgStart 1151 stx ProgStart+1 1152 1153 * Inc frame counter 1154 1155 lda PlayCount 1156 cmp #254 1157 bcs :rts 1158 inc PlayCount 1159 1160 * Look up time of next command 1161 1162 ldy PreRecPtr 1163 1164 lda PlayCount 1165 cmp (ProgStart),y 1166 bcs :next 1167 1168 * Not there yet--repeat last command 1169 1170 dey 1171 lda (ProgStart),y 1172 jmp :ex 1173 1174 * We're there-- 1175 1176 :next iny 1177 lda (ProgStart),y ;command 1178 iny 1179 sty PreRecPtr 1180 1181 * Execute command 1182 1183 :ex cmp #-1 1184 beq :enddemo 1185 cmp #0 1186 beq :ctr 1187 cmp #1 1188 beq :fwd 1189 cmp #2 1190 beq :back 1191 cmp #3 1192 beq :up 1193 cmp #4 1194 beq :down 1195 cmp #5 1196 beq :upfwd 1197 cmp #6 1198 beq :press 1199 cmp #7 1200 beq :release 1201 :rts 1202 ]rts rts 1203 1204 * Commands 1205 1206 :ctr jmp DoRelease 1207 :fwd jmp DoFwd 1208 :back jmp DoBack 1209 :up jmp DoUp 1210 :down jmp DoDown 1211 :upfwd jsr DoUp 1212 jmp DoFwd 1213 :press jmp DoPress 1214 :release jmp DoRelBtn 1215 1216 :enddemo ; lda autopilot 1217 ; bne :endpb 1218 jmp attractmode ;Game: end demo 1219 :endpb ; lda #0 ;Editor: end playback 1220 ; sta autopilot 1221 ; rts 1222 1223 *------------------------------- 1224 * 1225 * C U T C H E C K 1226 * 1227 * Cut with kid 1228 * 1229 *------------------------------- 1230 CUTCHECK 1231 lda CUTTIMER 1232 beq :ok 1233 1234 dec CUTTIMER 1235 ]rts rts 1236 1237 :ok 1238 jsr LoadKid 1239 jsr setupchar 1240 jsr getedges 1241 jsr cutchar ;cut with character 1242 bmi ]rts ;no cut 1243 sta ]cutdir 1244 1245 jsr SaveKid 1246 1247 lda CharScrn 1248 sta cutscrn 1249 1250 lda ShadFace 1251 cmp #86 ;is there a guard on old screen? 1252 beq ]rts ;no 1253 1254 * What to do with guard? Two choices: 1255 * 1256 * (1) UPDATE -- leave guard behind on old screen (& update 1257 * his coords so he'll still be there when we come back) 1258 * (2) TRANSFER -- transfer guard to new screen (& delete his 1259 * coords from old screen) 1260 1261 lda ShadLife 1262 bpl :update ;dead guard on old screen--leave him behind 1263 1264 lda ShadSword 1265 cmp #2 1266 bne :update 1267 1268 * Is there a live guard on new screen? 1269 1270 ldx KidScrn 1271 lda GdStartBlock-1,x 1272 cmp #30 1273 bcs :nonew ;no 1274 1275 lda GdStartSeqH-1,x 1276 beq :update ;yes 1277 1278 * If guard is too far o.s., leave him behind 1279 1280 :nonew 1281 lda ]cutdir 1282 beq :left 1283 cmp #1 1284 beq :right 1285 cmp #2 1286 beq :up 1287 1288 :down lda ShadBlockY 1289 cmp #3 1290 bcs :transfer 1291 bcc :update 1292 1293 :up lda ShadBlockY 1294 bmi :transfer 1295 bpl :update 1296 1297 :right lda ShadX 1298 cmp #ScrnWidth+25 ;25 is safety factor 1299 bcc :update 1300 bcs :transfer 1301 1302 :left lda ShadX 1303 cmp #256-ScrnWidth-25 1304 bcs :update 1305 1306 * Take him with us 1307 1308 :transfer jmp transferguard 1309 1310 * Leave him behind 1311 1312 :update jmp updateguard 1313 1314 *------------------------------- 1315 * 1316 * Transfer guard from old screen to new screen 1317 * (Also remove any dead guards from new scrn) 1318 * 1319 *------------------------------- 1320 transferguard 1321 lda #-1 1322 ldx KidScrn ;new scrn 1323 sta GdStartBlock-1,x 1324 ldx ShadScrn ;old scrn 1325 sta GdStartBlock-1,x 1326 1327 jsr LoadShad 1328 1329 lda ]cutdir 1330 jsr cut 1331 1332 jmp SaveShad 1333 1334 ]rts rts 1335 1336 *------------------------------- 1337 * 1338 * Leaving guard behind on old screen-- 1339 * update guard coords 1340 * 1341 *------------------------------- 1342 1343 updateguard 1344 lda ShadFace 1345 cmp #86 1346 beq ]rts ;no guard 1347 lda ShadID 1348 cmp #1 1349 beq ]rts ;not for shadman 1350 cmp #24 1351 beq ]rts ;or mouse 1352 :gd 1353 lda #0 ;arbitrary--ADDGUARD will reconstruct 1354 sta tempblockx ;CharBlockX from CharX 1355 lda ShadBlockY 1356 sta tempblocky 1357 jsr indexblock 1358 tya 1359 ldx ShadScrn 1360 sta GdStartBlock-1,x 1361 1362 lda ShadX 1363 sta GdStartX-1,x 1364 1365 lda ShadFace 1366 sta GdStartFace-1,x 1367 1368 lda guardprog 1369 sta GdStartProg-1,x 1370 1371 lda ShadLife 1372 bpl :ok 1373 lda #0 1374 sta GdStartSeqH-1,x 1375 beq :cont 1376 1377 :ok lda ShadSeq 1378 sta GdStartSeqL-1,x 1379 lda ShadSeq+1 1380 sta GdStartSeqH-1,x 1381 1382 * and deactivate enemy char 1383 1384 :cont lda #86 1385 sta ShadFace 1386 1387 lda #0 1388 sta OppStrength 1389 ]rts rts 1390 1391 *------------------------------- 1392 * 1393 * If enemy has fallen to screen below, catch him before 1394 * he wraps around to top of VisScrn 1395 * 1396 *------------------------------- 1397 CUTGUARD 1398 lda ShadFace 1399 cmp #86 1400 beq ]rts 1401 1402 lda ShadY 1403 cmp #BotCutEdge 1404 bcc ]rts 1405 1406 * If guard, remove him altogether 1407 1408 lda ShadID 1409 cmp #4 1410 beq :skel 1411 cmp #1 1412 beq :shad 1413 1414 ]RemoveGd 1415 jsr deadenemy ;music, etc. 1416 1417 ldx VisScrn 1418 lda #-1 1419 sta GdStartBlock-1,x 1420 lda #86 1421 sta ShadFace 1422 lda #0 1423 sta OppStrength 1424 lda #-1 1425 sta ChgOppStr 1426 ]rts rts 1427 1428 * If shad, vanish him 1429 1430 :shad lda ShadAction 1431 cmp #4 1432 bne ]rts 1433 jsr LoadShad 1434 jsr VanishChar 1435 jmp SaveShad 1436 1437 * If skel, change scrn 1438 1439 :skel lda ShadScrn 1440 jsr getdown 1441 sta ShadScrn 1442 cmp #3 1443 bne ]RemoveGd 1444 1445 * Skel lands on scrn 3 1446 1447 lda #Splat 1448 jsr addsound 1449 lda #$85 1450 sta ShadX 1451 lda #1 1452 sta ShadBlockY 1453 lda #0 1454 sta ShadFace 1455 lda #-1 1456 sta ShadLife 1457 jmp updateguard 1458 1459 *------------------------------- 1460 * 1461 * C U T C H A R 1462 * 1463 * Is character passing o.s.? If so, cut with him to next scrn 1464 * 1465 * Change CharX,Y,BlockY,Scrn to reflect posn on new scrn 1466 * 1467 * Return A = direction of cut, -1 if no cut 1468 * 1469 *------------------------------- 1470 cutchar 1471 lda CharY 1472 1473 ldx CharAction 1474 cpx #5 1475 beq :notup 1476 cpx #4 1477 beq :notup ;In freefall--cut only down 1478 cpx #3 1479 beq :notup 1480 1481 * Cut up/down? 1482 1483 cmp #TopCutEdgePl 1484 bcc :CUTUP 1485 1486 cmp #TopCutEdgeMi 1487 bcs :CUTUP 1488 :notup 1489 cmp #BotCutEdge 1490 bcs :CUTDOWN 1491 1492 * Cut left/right? 1493 1494 ldx CharPosn 1495 cpx #135 1496 bcc :nocu 1497 cpx #150 1498 bcc :nocut ;don't cut L/R on climbup 1499 :nocu cpx #110 1500 bcc :nosu 1501 cpx #120 1502 bcc :nocut ;or on standup 1503 :nosu cpx #150 1504 bcc :nost 1505 cpx #163 1506 bcc :nocut 1507 cpx #166 1508 bcc :nost 1509 cpx #169 1510 bcc :nocut ;or on strike/block 1511 :nost lda CharAction 1512 cmp #7 1513 beq :nocut ;or on turning 1514 1515 ldx CharFace ;-1=left, 0=right 1516 beq :faceR 1517 ;facing left 1518 lda leftej 1519 cmp #LeftCutEdge 1520 bcc :CUTLEFT 1521 beq :CUTLEFT 1522 1523 cmp #ScrnRight+1 1524 bcs :CUTRIGHT 1525 bcc :nocut 1526 1527 :faceR 1528 lda CharScrn 1529 ldx #9 1530 ldy CharBlockY 1531 jsr rdblock 1532 1533 cmp #panelwif 1534 beq :nocutr 1535 cmp #panelwof 1536 beq :nocutr ;don't cut R if a panel blocks view 1537 1538 lda rightej 1539 cmp #RightCutEdge 1540 bcs :CUTRIGHT 1541 1542 :nocutr lda rightej 1543 cmp #ScrnLeft-1 1544 bcc :CUTLEFT 1545 beq :CUTLEFT 1546 1547 :nocut lda #-1 1548 rts 1549 1550 :CUTLEFT jsr mirrmusic 1551 jsr milestone3 1552 lda #0 1553 bpl :cut 1554 1555 :CUTRIGHT jsr stealsword 1556 jsr jaffmusic 1557 lda #1 1558 bpl :cut 1559 1560 :CUTUP lda #2 1561 bpl :cut 1562 1563 * Level 6 ("Plunge"): Kid falls off screen 1 into next level 1564 1565 :CUTDOWN 1566 jsr infinity 1567 1568 lda level 1569 cmp #6 1570 bne :no6 1571 lda CharScrn 1572 cmp #1 1573 beq :nocut 1574 :no6 1575 lda #3 1576 :cut pha 1577 jsr cut 1578 pla 1579 ]rts rts 1580 1581 *------------------------------- 1582 * Level 12--fall off into infinity 1583 *------------------------------- 1584 infinity rts 1585 1586 *------------------------------- 1587 * Passed Level 3 milestone? 1588 *------------------------------- 1589 milestone3 1590 lda level 1591 cmp #3 1592 bne ]rts 1593 lda #7 ;scrn to R of gate 1594 ]mcheck cmp CharScrn 1595 bne ]rts 1596 lda #1 1597 sta milestone 1598 lda MaxKidStr 1599 sta origstrength 1600 rts 1601 1602 *------------------------------- 1603 * Level 12: Shadow steals sword 1604 *------------------------------- 1605 stealsword 1606 lda level 1607 cmp #12 1608 bne ]rts 1609 lda CharScrn 1610 cmp #18 ;scrn below swordscrn 1611 bne ]rts 1612 lda #swordscrn 1613 ldx #swordx 1614 ldy #swordy 1615 jsr rdblock 1616 lda #floor 1617 sta (BlueType),y 1618 rts 1619 1620 *------------------------------- 1621 * Level 13: Play Jaffar's Theme 1622 *------------------------------- 1623 jaffmusic 1624 lda level 1625 cmp #13 1626 bne ]rts 1627 lda exitopen 1628 bne ]rts 1629 lda CharScrn 1630 cmp #3 1631 bne ]rts 1632 lda #s_Jaffar 1633 ldx #25 1634 jmp cuesong 1635 1636 *------------------------------- 1637 * Level 4 ("Mirror"): Play danger theme for mirror 1638 *------------------------------- 1639 mirrmusic 1640 lda exitopen 1641 beq :no4 1642 cmp #77 1643 beq :no4 1644 lda level 1645 cmp #4 1646 bne :no4 1647 lda CharBlockY 1648 cmp #miry 1649 bne :no4 1650 lda CharScrn 1651 cmp #11 ;scrn to R of mirscrn 1652 bne :no4 1653 lda #s_Danger 1654 ldx #50 1655 jsr cuesong 1656 lda #77 1657 sta exitopen ;so we don't repeat theme 1658 :no4 1659 ]rts rts 1660 1661 *------------------------------- 1662 * 1663 * C U T 1664 * 1665 * Move char from CharScrn to adjacent screen 1666 * 1667 * In: A = cut dir: 0 = left, 1 = right, 2 = up, 3 = down 1668 * 1669 *------------------------------- 1670 CUT 1671 cmp #3 1672 beq Cdown 1673 cmp #1 1674 beq Cright 1675 cmp #2 1676 beq Cup 1677 1678 Cleft 1679 lda CharScrn 1680 jsr getleft ;get new screen # 1681 sta CharScrn 1682 1683 lda #140 1684 clc 1685 adc CharX 1686 sta CharX 1687 1688 ldx #1 ;new FromDir 1689 rts 1690 1691 Cright 1692 lda CharScrn 1693 jsr getright 1694 sta CharScrn 1695 1696 lda CharX 1697 sec 1698 sbc #140 1699 sta CharX 1700 1701 ldx #0 1702 rts 1703 1704 Cup 1705 lda CharScrn 1706 jsr getup 1707 sta CharScrn 1708 1709 lda CharBlockY 1710 clc 1711 adc #3 1712 sta CharBlockY 1713 1714 lda CharY 1715 clc 1716 adc #189 1717 sta CharY 1718 1719 ldx #3 1720 rts 1721 1722 Cdown 1723 lda CharScrn 1724 jsr getdown 1725 sta CharScrn 1726 1727 lda CharBlockY 1728 sec 1729 sbc #3 1730 sta CharBlockY 1731 1732 lda CharY 1733 sec 1734 sbc #189 1735 sta CharY 1736 1737 ldx #2 1738 ]rts rts 1739 1740 *------------------------------- 1741 * 1742 * A D D G U A R D 1743 * 1744 * On cut to new screen--if guard is there, bring him to life 1745 * Also handles hard-wired shadowman appearances 1746 * 1747 * In: VisScrn 1748 * 1749 *------------------------------- 1750 ADDGUARD 1751 lda #0 1752 sta offguard 1753 1754 * Level 12 1755 1756 lda level 1757 cmp #12 1758 bne :not12 1759 lda exitopen ;set when shadow drops 1760 bne ]rts 1761 lda mergetimer 1762 bne :1 ;shadow has been reabsorbed 1763 lda VisScrn 1764 cmp #swordscrn 1765 :1 bne ]rts 1766 sta CharScrn 1767 1768 ldx #swordx 1769 ldy #swordy 1770 jsr rdblock 1771 cmp #sword 1772 beq ]rts ;sword is still there 1773 lda #0 1774 sta shadowaction 1775 lda #1 1776 sta exitopen 1777 lda #shadpos12 1778 ldx #>shadpos12 1779 jmp csps 1780 1781 * Level 6 (Plunge) 1782 1783 :not12 1784 lda level 1785 cmp #6 ;plunge 1786 bne :not6 1787 1788 lda VisScrn 1789 sta CharScrn 1790 cmp #1 1791 bne AddNormalGd 1792 1793 lda exitopen 1794 cmp #77 1795 beq :norepeat 1796 lda #s_Danger 1797 ldx #50 1798 jsr cuesong 1799 lda #77 1800 sta exitopen 1801 :norepeat 1802 lda #shadpos6a 1803 ldx #>shadpos6a 1804 jmp csps 1805 1806 * Level 5 (Thief) 1807 1808 :not6 lda level 1809 cmp #5 ;thief 1810 bne :not5 1811 1812 lda VisScrn 1813 sta CharScrn 1814 cmp #flaskscrn 1815 bne AddNormalGd 1816 1817 ldx #flaskx 1818 ldy #flasky 1819 jsr rdblock 1820 cmp #flask 1821 bne ]rts ;potion is gone 1822 1823 lda #shadpos5 1824 ldx #>shadpos5 1825 jmp csps 1826 ]rts rts 1827 :not5 1828 1829 *------------------------------- 1830 AddNormalGd 1831 ldx VisScrn 1832 lda GdStartBlock-1,x 1833 cmp #30 1834 bcs ]rts ;no guard on this scrn 1835 1836 * Bring guard to life (or death) 1837 1838 stx CharScrn 1839 1840 jsr unindex ;return A = blockx, X = blocky 1841 stx CharBlockY 1842 1843 lda FloorY+1,x 1844 sta CharY 1845 1846 ldx VisScrn 1847 lda GdStartX-1,x 1848 sta CharX 1849 jsr getblockxp 1850 sta CharBlockX 1851 1852 ldx VisScrn 1853 lda GdStartFace-1,x 1854 sta CharFace 1855 1856 lda level 1857 cmp #3 1858 bne :3 1859 1860 lda #4 ;skel 1861 bne :4 1862 :3 lda #2 ;guard 1863 :4 sta CharID 1864 1865 lda GdStartSeqH-1,x 1866 bne :1 ;0 is code for fresh start 1867 1868 lda CharID 1869 cmp #4 1870 bne :5 1871 lda #2 1872 sta CharSword 1873 lda #landengarde ;skel (ready) 1874 bne :6 1875 :5 lda #0 1876 sta CharSword 1877 lda #alertstand ;guard 1878 :6 jsr jumpseq 1879 jmp :2 1880 1881 :1 sta CharSeq+1 1882 lda GdStartSeqL-1,x 1883 sta CharSeq 1884 1885 :2 jsr animchar 1886 1887 lda CharPosn 1888 cmp #185 ;killed 1889 beq :dead 1890 cmp #177 ;impaled 1891 beq :dead 1892 cmp #178 ;halved 1893 beq :dead 1894 1895 * Live guard 1896 1897 lda #-1 1898 sta CharLife 1899 1900 lda #0 1901 sta alertguard 1902 sta refract 1903 sta justblocked 1904 1905 jsr getgdstrength 1906 jmp :cont 1907 1908 * Dead guard 1909 1910 :dead lda #1 1911 sta CharLife 1912 lda #0 1913 sta OppStrength 1914 1915 * Continue 1916 1917 :cont lda #0 1918 sta CharXVel 1919 sta CharYVel 1920 lda #1 1921 sta CharAction 1922 1923 ldx VisScrn 1924 lda GdStartProg-1,x 1925 cmp #numprogs 1926 bcc :ok 1927 lda #3 ;default 1928 :ok sta guardprog 1929 1930 ldx level 1931 lda basiccolor,x 1932 ldx guardprog 1933 eor specialcolor,x ;0 = normal, 1 = special 1934 sta GuardColor ;0 = blue, 1 = red 1935 1936 jmp SaveShad ;save ShadVars 1937 1938 *------------------------------- 1939 * Get guard fighting strength 1940 *------------------------------- 1941 getgdstrength 1942 ldx level 1943 lda basicstrength,x 1944 ldx guardprog 1945 clc 1946 adc extrastrength,x 1947 sta MaxOppStr 1948 sta OppStrength 1949 ]rts rts 1950 1951 *------------------------------- 1952 lst 1953 ds 1 1954 usr $a9,17,$800,*-org 1955 lst off