TOPCTRL.S (25807B)
1 * topctrl 2 org = $2000 3 EditorDisk = 0 4 FinalDisk = 1 5 DemoDisk = 0 6 ThreeFive = 1 ;3.5" disk? 7 tr on 8 lst off 9 *------------------------------- 10 * 11 * PRINCE OF PERSIA 12 * Copyright 1989 Jordan Mechner 13 * 14 *------------------------------- 15 org org 16 17 jmp START 18 jmp RESTART 19 jmp STARTRESUME 20 jmp INITSYSTEM 21 jmp showpage 22 23 jmp showpage 24 jmp GOATTRACT 25 26 *------------------------------- 27 lst 28 put eq 29 lst 30 put gameeq 31 lst 32 put seqdata 33 lst 34 put movedata 35 lst 36 put soundnames 37 lst off 38 39 *------------------------------- 40 * 18-sector ID bytes 41 42 POPside1 = $a9 43 POPside2 = $ad 44 45 FirstSideB = 3 ;1st level on Side B 46 LastSideB = 14 ;& last 47 48 *------------------------------- 49 * Soft switches 50 51 ALTZPon = $c009 52 ALTZPoff = $c008 53 RAMWRTaux = $c005 54 RAMWRTmain = $c004 55 RAMRDaux = $c003 56 RAMRDmain = $c002 57 TEXTon = $c051 58 PAGE2off = $c054 59 60 kresurrect = "R" 61 62 *------------------------------- 63 * Misc. changeable parameters 64 65 initmaxstr = 3 66 67 BTLtimer = 20 ;back to life 68 wtlflash = 15 ;weightless 69 70 mousetimer = 150 71 72 *------------------------------- 73 * message #s 74 75 LevelMsg = 1 76 ContMsg = 2 77 TimeMsg = 3 78 79 leveltimer = 20 ;level message timer 80 contflash = 95 81 contoff = 15 82 deadenough = 4 83 84 *------------------------------- 85 * Mirror location 86 87 mirlevel = 4 88 mirscrn = 4 89 mirx = 4 90 miry = 0 91 92 *------------------------------- 93 * 94 * Start a new game 95 * 96 * In: A = level # (0 for demo, 1 for game) 97 * 98 *------------------------------- 99 START 100 sta ALTZPon 101 jsr StartGame 102 jmp RESTART 103 104 *------------------------------- 105 * 106 * Resume saved game 107 * 108 *------------------------------- 109 STARTRESUME 110 sta ALTZPon 111 lda #4 ;arbitrary value >1 112 jsr StartGame 113 jmp ResumeGame 114 115 *------------------------------- 116 * 117 * Initialize system (Called from MASTER upon bootup) 118 * 119 *------------------------------- 120 INITSYSTEM 121 sta ALTZPon 122 123 jsr setcenter ;Center joystick 124 125 jsr setfastaux ;bgtable in auxmem 126 127 lda #FinalDisk!1 128 sta develment 129 130 jsr initgame 131 132 ldx #0 133 txa 134 :loop sta $0,x 135 inx 136 bne :loop 137 138 sta ALTZPoff 139 rts 140 141 *------------------------------- 142 * 143 * Start a game 144 * 145 * In: A = level # (0 for demo, 1 for new game, >1 for 146 * resumed game) 147 * 148 *------------------------------- 149 StartGame 150 sta level 151 sta NextLevel 152 153 cmp #1 154 bne :notfirst 155 lda #s_Danger 156 ldx #25 157 jsr cuesong ;Cue "Danger" theme if level 1 158 :notfirst 159 160 lda #initmaxstr 161 sta origstrength ;set initial strength 162 163 jmp initgame 164 165 *------------------------------- 166 * 167 * Resume saved game 168 * 169 *------------------------------- 170 ResumeGame 171 do DemoDisk 172 rts 173 else 174 175 jsr flipdisk ;Ask player to flip disk 176 lda #POPside2 177 sta BBundID ;& expect side 2 from now on 178 179 :cont jsr loadgame ;Load saved-game info from disk 180 181 lda SavLevel ;Has a game been saved? 182 bpl :ok ;Yes 183 184 * No game saved--start new game instead 185 186 jsr flipdisk 187 lda #POPside1 188 sta BBundID 189 190 lda #1 191 sta level 192 sta NextLevel 193 jmp RESTART 194 195 * Restore strength & timer 196 197 :ok lda SavStrength 198 sta origstrength 199 200 lda SavTimer+1 201 sta FrameCount+1 202 lda SavTimer 203 sta FrameCount 204 205 lda SavNextMsg 206 sta NextTimeMsg 207 208 * & resume from beginning of level 209 210 lda #1 211 sta timerequest ;show time remaining 212 lda #$80 213 sta yellowflag ;pass copy prot. test 214 lda SavLevel 215 sta level 216 sta NextLevel 217 jmp RESTART 218 219 fin 220 221 *------------------------------- 222 * 223 * Initialize vars before starting game 224 * 225 *------------------------------- 226 initgame 227 lda #0 228 sta blackflag 229 sta redrawflg 230 sta inmenu 231 sta inbuilder 232 sta recheck0 233 sta SINGSTEP 234 sta ManCtrl 235 sta vibes 236 sta invert 237 sta milestone 238 sta timerequest 239 sta FrameCount 240 sta FrameCount+1 241 sta NextTimeMsg 242 243 lda #$ff 244 sta MinLeft 245 sta SecLeft 246 247 lda #1 ;no delay 248 sta SPEED 249 rts 250 251 *------------------------------- 252 * 253 * Restart current level 254 * 255 *------------------------------- 256 RESTART 257 sta ALTZPon 258 sta $c010 ;clr kbd strobe 259 260 ldx #$ff ; 261 txs ;added 2/5/90!!! 262 263 do EditorDisk 264 jsr reloadblue 265 else 266 267 lda #" " 268 jsr lrcls 269 jsr vblank 270 lda PAGE2off 271 lda TEXTon 272 273 ldx level 274 jsr LoadLevelX ;load blueprint & image sets from disk 275 fin 276 277 jsr setinitials ;Set initial states as specified in blueprint 278 279 jsr initialguards ;& guards 280 281 * Zero a lot of vars & tables 282 283 lda #0 284 sta SINGSTEP 285 sta vibes 286 sta AMtimer 287 sta VisScrn 288 sta exitopen 289 sta lightning 290 sta mergetimer 291 sta numtrans 292 sta nummob 293 sta EnemyAlert 294 sta createshad 295 sta stunned 296 sta heroic 297 sta ChgKidStr 298 sta OppStrength ;no opponent 299 sta msgtimer 300 sta PreRecPtr 301 sta PlayCount 302 303 ldx SongCue 304 cpx #s_Danger 305 beq :1st 306 sta SongCue 307 :1st 308 309 jsr zerosound 310 311 jsr zeropeels 312 313 jsr initCDbuf ;initialize collision detection buffers 314 315 jsr initinput 316 317 lda #1 318 sta gotsword 319 320 lda #-1 321 sta cutorder 322 323 lda #2 324 sta ShadID ;default opponent is guard 325 lda #86 326 sta ShadFace 327 328 jsr startkid 329 330 do EditorDisk 331 else 332 333 lda level 334 cmp #1 335 bne :gotswd 336 lda #0 337 sta gotsword ;Start Level 1 w/o sword 338 :gotswd 339 fin 340 341 lda level 342 beq :nomsg 343 cmp #14 344 beq :nomsg ;don't announce level 0 or 14 345 cmp #13 346 bne :1 347 lda skipmessage 348 beq :1 349 lda #0 350 sta skipmessage 351 beq :nomsg ;skip level 13 message 1st time 352 :1 lda #LevelMsg 353 sta message 354 lda #leveltimer 355 sta msgtimer 356 :nomsg 357 358 jsr entrance ;entrance slams shut 359 360 jsr FirstFrame ;Generate & display first frame 361 362 jmp MainLoop 363 364 *------------------------------- 365 * 366 * Main loop 367 * 368 *------------------------------- 369 MainLoop 370 jsr rnd 371 372 lda #0 373 sta ChgKidStr 374 sta ChgOppStr 375 376 jsr strobe ;Strobe kbd & jstk 377 378 jsr demokeys 379 bpl :4 380 lda #1 381 jmp START ;During demo, press any key to play 382 :4 383 jsr misctimers 384 385 jsr NextFrame ;Determine what next frame should look like 386 387 jsr flashon 388 389 jsr FrameAdv ;Draw next frame & show it 390 391 jsr playback ;Play sounds 392 jsr zerosound ;& zero sound table 393 394 jsr flashoff 395 396 jsr songcues ;Play music 397 398 lda NextLevel 399 cmp level 400 beq MainLoop ;Continue until we change levels 401 402 jsr yellowcheck ;copy protect! 403 404 jmp LoadNextLevel 405 406 *------------------------------- 407 * 408 * Load next level 409 * 410 * In: NextLevel = # of next level 411 * level = # of current level 412 * 413 * Out: level = NextLevel 414 * 415 *------------------------------- 416 LoadNextLevel 417 lda NextLevel 418 cmp #14 419 beq LoadNext1 420 lda #1 421 sta timerequest ;show time remaining 422 423 LoadNext1 424 lda MaxKidStr 425 sta origstrength ;save new strength level 426 lda #0 427 sta milestone 428 429 do EditorDisk 430 lda level 431 sta NextLevel 432 jmp RESTART 433 fin 434 435 * NextLevel must be in range 1 - LastSideB 436 437 lda NextLevel 438 cmp #LastSideB+1 439 bcs :illegal 440 cmp #1 441 bcs :2 442 :illegal lda level ;Illegal value--restart current level 443 sta NextLevel 444 jmp RESTART 445 446 * Load from correct side of disk 447 448 :2 ldx #POPside2 449 cmp #FirstSideB 450 bcs :1 451 ldx #POPside1 452 :1 cpx BBundID ;do we need to flip disk? 453 beq :ok ;no 454 stx BBundID ;yes 455 jsr flipdisk 456 457 :ok lda NextLevel 458 sta level ;set new level 459 cmp #2 460 beq :cut1 461 cmp #4 462 beq :cut2 463 cmp #6 464 beq :cut3 465 cmp #8 466 beq :cut8 467 cmp #9 468 beq :cut4 469 cmp #12 470 beq :cut5 ;Princess cuts before certain levels 471 472 :cont jmp RESTART ;Start new level 473 474 * Princess cuts before certain levels 475 476 :cut1 lda #1 477 ]pcut pha 478 :repeat jsr cutprincess ;cut to princess's room... 479 jsr setrecheck0 480 jsr recheckyel ;if wrong-disk error, recheck track 0 481 bne :repeat ;& repeat 482 pla 483 jsr playcut ;& play cut #1 484 jmp :cont 485 486 :cut2 lda #2 487 bne ]pcut 488 :cut3 lda #3 489 bne ]pcut 490 :cut4 lda #4 491 bne ]pcut 492 :cut5 lda #5 493 bne ]pcut 494 :cut8 lda #8 495 bne ]pcut 496 497 *------------------------------- 498 * 499 * N E X T F R A M E 500 * 501 * Determine what next frame should look like 502 * 503 * In: All data reflects last (currently displayed) frame. 504 * 505 *------------------------------- 506 NextFrame 507 jsr animmobs ;Update mobile objects (MOBs) 508 509 jsr animtrans ;Update transitional objects (TROBs) 510 511 jsr bonesrise ;Bring skeleton to life? 512 513 jsr checkalert ;Determine EnemyAlert value 514 515 jsr DoKid ;Update kid 516 517 jsr DoShad ;Update shadowman (or other opponent) 518 519 jsr checkstrike 520 jsr checkstab ;Check for sword strikes 521 :1 522 jsr addsfx ;Add additional sound fx 523 524 jsr chgmeters ;Change strength meters 525 526 jsr cutcheck ;Has kid moved offscreen? 527 jsr PrepCut ;If so, prepare to cut to new screen 528 529 jsr cutguard ;If guard has fallen offscreen, vanish him 530 531 do EditorDisk 532 rts 533 fin 534 535 * Level 0 (Demo): When kid exits screen 24, end demo 536 537 lda level 538 bne :no0 539 lda KidScrn 540 cmp #24 541 bne :cont 542 jmp GOATTRACT 543 544 * Level 6: When kid falls off screen 1, cut to next level 545 546 :no0 do DemoDisk 547 else 548 549 lda level 550 cmp #6 551 bne :no6 552 lda KidScrn 553 cmp #1 554 bne :cont 555 lda KidY 556 cmp #20 557 bcs :cont 558 lda #-1 559 sta KidY 560 inc NextLevel 561 jmp :cont 562 563 * Level 12: When kid exits screen 23, cut to next level 564 565 :no6 cmp #12 566 bne :cont 567 lda KidScrn 568 cmp #23 569 bne :cont 570 inc NextLevel 571 lda #1 572 sta skipmessage ;but don't announce level # 573 jmp LoadNext1 ;or show time 574 575 fin 576 577 * Continue... 578 579 :cont lda level 580 cmp #14 581 bcs :stopped 582 cmp #13 583 bcc :ticking 584 lda exitopen 585 bne :stopped ;Timer stops when you kill Vizier on level 13 586 587 :ticking jsr keeptime 588 589 :stopped jsr showtime ;if timerequest <> 0 590 591 lda level 592 cmp #13 593 bcs :safe ;You have one chance to finish Level 13 594 ;after time runs out 595 lda MinLeft 596 ora SecLeft 597 bne :safe 598 jmp YouLose ;time's up--you lose 599 :safe 600 ]rts rts 601 602 *------------------------------- 603 * 604 * F R A M E A D V A N C E 605 * 606 * Draw new frame (on hidden hi-res page) & show it 607 * 608 *------------------------------- 609 FrameAdv 610 lda cutplan ;set by PrepCut 611 bne :cut 612 613 jsr DoFast 614 jmp PageFlip ;Update current screen... 615 616 :cut jmp DoCleanCut ;or draw new screen from scratch 617 618 *------------------------------- 619 * 620 * F I R S T F R A M E 621 * 622 * Generate & display first frame 623 * 624 *------------------------------- 625 FirstFrame 626 lda KidScrn 627 sta cutscrn 628 629 jsr PrepCut 630 631 jmp DoCleanCut 632 633 *------------------------------- 634 * 635 * D O K I D 636 * 637 * Update kid 638 * 639 *------------------------------- 640 DoKid 641 jsr LoadKidwOp ;Load kid as character (w/opponent) 642 643 jsr rereadblocks 644 645 jsr unholy ;If shadowman dies, kid dies 646 647 jsr ctrlplayer ;Detect & act on commands from player 648 649 lda invert 650 beq :3 651 lda CharLife 652 bmi :3 653 lda #2 654 sta redrawflg 655 lda #0 656 sta invert 657 jmp inverty ;Screen flips back rightside up when you're dead 658 :3 659 jsr wtlessflash 660 661 lda CharScrn 662 beq :skip ;Skip all this if kid is on null screen: 663 664 jsr animchar ;Get next frame from sequence table 665 666 jsr gravity ;Adjust Y-velocity 667 jsr addfall ;Add falling velocity 668 669 jsr setupchar 670 jsr rereadblocks 671 jsr getedges 672 673 jsr firstguard ;Check for collision w/guard 674 675 jsr checkbarr ;Check for collisions w/vertical barriers 676 677 jsr collisions ;React to collisions detected above 678 679 jsr checkgate ;Knocked to side by closing gate? 680 681 jsr checkfloor ;Is there floor underfoot? If not, fall 682 683 jsr checkpress ;Is kid stepping on a pressure plate? 684 ;If so, add pressplate (& whatever it 685 ;triggers) to trans list. 686 687 jsr checkspikes ;Trigger spikes? 688 689 jsr checkimpale ;impaled by spikes? 690 jsr checkslice ;sliced by slicer? 691 :1 692 jsr shakeloose ;shake loose floors 693 694 :skip jsr SaveKid ;Save all changes to char data 695 ]rts rts 696 697 *------------------------------- 698 * 699 * D O S H A D 700 * 701 * Update shadowman (or other opponent) 702 * 703 *------------------------------- 704 DoShad 705 lda ShadFace 706 cmp #86 707 beq ]rts ;"no character" code 708 709 jsr LoadShadwOp 710 jsr rereadblocks 711 712 jsr unholy 713 714 jsr ShadCtrl ;Opponent control module 715 716 lda CharScrn 717 cmp VisScrn 718 bne :os 719 720 jsr animchar 721 722 lda CharX 723 cmp #ScrnLeft-14 724 bcc :os 725 cmp #ScrnRight+14 726 bcs :os ;Skip all this if char is offscreen 727 728 jsr gravity 729 jsr addfall 730 731 jsr setupchar 732 jsr rereadblocks 733 jsr getedges 734 735 jsr enemycoll 736 737 jsr checkfloor 738 jsr checkpress 739 jsr checkspikes 740 jsr checkimpale 741 jsr checkslice2 742 743 :os jmp SaveShad 744 745 *------------------------------- 746 * 747 * Add all visible characters to object table 748 * 749 *------------------------------- 750 addchars 751 jsr :reflection 752 jsr :shadowman 753 jsr :kid 754 755 jsr checkmeters 756 757 ]rts rts 758 759 *------------------------------- 760 * Draw kid's reflection in mirror 761 762 :reflection 763 jmp reflection 764 765 *------------------------------- 766 * Draw shadowman or other opponent 767 768 :shadowman 769 lda ShadFace 770 cmp #86 ;Is there a shadowman? 771 beq ]rts ;no 772 lda ShadScrn 773 cmp VisScrn ;Is he visible? 774 bne ]rts ;no 775 776 jsr setupshad ;Add shadowman to object table 777 778 lda ChgOppStr 779 bpl :s1 780 jsr setupcomix ;Add impact star if he's been hurt 781 :s1 jmp setupsword ;Add sword 782 783 *------------------------------- 784 * Draw kid 785 786 :kid lda KidScrn 787 beq ]rts 788 cmp VisScrn 789 bne ]rts 790 791 jsr setupkid ;Add kid to obj table 792 793 lda ChgKidStr 794 bpl :s2 795 jsr setupcomix ;Add impact star 796 :s2 jmp setupsword ;Add sword 797 798 *------------------------------- 799 * 800 * S E T U P K I D 801 * 802 * Add kid to object table 803 * Crop edges, index char, mark fredbuf/floorbuf 804 * 805 *------------------------------- 806 setupkid 807 jsr LoadKid 808 jsr rereadblocks 809 810 lda CharPosn 811 bne :cont ;Delay loop if CharPosn = 0 812 lda #25 813 jmp pause 814 815 :cont jsr setupchar 816 jsr unevenfloor 817 818 jsr getedges 819 jsr indexchar 820 jsr quickfg 821 jsr quickfloor 822 jsr cropchar 823 824 jmp addkidobj ;add kid to obj table 825 826 *------------------------------- 827 * 828 * S E T U P S H A D 829 * 830 * Add shadowman to obj table 831 * 832 *------------------------------- 833 setupshad 834 jsr LoadShad 835 jsr rereadblocks 836 837 jsr setupchar 838 jsr unevenfloor 839 840 jsr getedges 841 jsr indexchar 842 jsr quickfg 843 jsr quickfloor 844 jsr cropchar 845 846 lda CharID 847 cmp #1 ;Shadowman? 848 bne :1 ;no 849 lda level 850 cmp #mirlevel 851 bne :2 852 lda CharScrn 853 cmp #mirscrn 854 bne :2 855 lda #mirx ;Clip shadman at L as he jumps out of mirror 856 asl 857 asl 858 clc 859 adc #1 860 sta FCharCL 861 :2 jmp addshadobj 862 863 :1 jmp addguardobj 864 865 *------------------------------- 866 * 867 * Cut to new screen 868 * 869 * DoQuickCut: Show bg before adding characters 870 * DoCleanCut: Show frame only when complete 871 * 872 *------------------------------- 873 UseQuick = 0 874 875 do UseQuick 876 877 DoQuickCut 878 jsr fastspeed ;IIGS 879 880 lda #0 881 sta PAGE 882 jsr drawbg ;draw bg on p1 883 884 jsr PageFlip 885 886 jsr copyscrn ;copy bg to p2 887 jsr DoFast ;add chars 888 889 jsr PageFlip ;show complete frame 890 jmp normspeed 891 892 else 893 894 DoCleanCut 895 jsr fastspeed ;IIGS 896 897 lda #$20 898 sta PAGE 899 jsr drawbg ;draw bg on p2 900 901 lda #0 902 sta PAGE 903 jsr copyscrn ;copy bg to p1 904 905 jsr DoFast ;add chars 906 907 ;jsr vblank2 908 jsr PageFlip 909 jmp normspeed 910 911 fin 912 913 *------------------------------- 914 * 915 * D R A W B G 916 * 917 * Clear screen & draw background (on hidden hi-res page) 918 * Show black lo-res screen to cover transition 919 * 920 *------------------------------- 921 drawbg 922 lda #0 923 sta cutplan 924 925 lda #2 926 sta CUTTIMER ;min # of frames between cuts 927 928 lda #" " 929 jsr lrclse 930 jsr vblank 931 lda PAGE2off 932 lda TEXTon 933 934 jsr DoSure ;draw b.g. w/o chars 935 936 jmp markmeters ;mark strength meters 937 938 *------------------------------- 939 * 940 * D O S U R E 941 * 942 * Clear screen and redraw entire b.g. from scratch 943 * 944 *------------------------------- 945 DoSure 946 lda VisScrn 947 sta SCRNUM 948 949 jsr zerolsts ;zero image lists 950 951 jsr sure ;Assemble image lists 952 953 jsr zeropeels ;Zero peel buffers 954 jsr zerored ;and redraw buffers 955 ;(for next DoFast call) 956 957 jmp drawall ;Dump contents of image lists to screen 958 959 *------------------------------- 960 * 961 * D O F A S T 962 * 963 * Do a fast screen update 964 * (Redraw objects and as little of b.g. as possible) 965 * 966 *------------------------------- 967 DoFast 968 jsr zerolsts ;zero image lists 969 970 lda VisScrn 971 sta SCRNUM 972 973 jsr develpatch 974 975 jsr addmobs ;Add MOBS to object list 976 977 jsr addchars ;Add characters to object list 978 ;(incl. strength meters) 979 980 jsr fast ;Assemble image lists (including objects 981 ;from obj list and necessary portions of bg) 982 983 jsr dispmsg ;Superimpose message (if any) 984 :1 985 jmp drawall ;Dump contents of image lists to screen 986 ]rts rts 987 988 *------------------------------- 989 * 990 * Lightning flashes 991 * 992 *------------------------------- 993 flashon 994 lda lightning 995 beq :1 996 lda lightcolor 997 bne :2 998 :1 lda ChgKidStr 999 bpl ]rts 1000 lda #$11 ;Flash red if kid's been hurt 1001 :2 jmp doflashon 1002 1003 flashoff 1004 lda lightning 1005 beq :1 1006 dec lightning 1007 bpl :2 1008 1009 :1 lda ChgKidStr 1010 bpl ]rts 1011 :2 jmp doflashoff 1012 1013 *------------------------------- 1014 * 1015 * Initialize collision detection buffers 1016 * 1017 *------------------------------- 1018 initCDbuf 1019 ldx #9 1020 lda #$ff 1021 :zloop sta SNlastframe,x 1022 sta SNthisframe,x 1023 sta SNbelow,x 1024 sta SNabove,x 1025 dex 1026 bpl :zloop 1027 1028 sta BlockYlast 1029 ]rts rts 1030 1031 *------------------------------- 1032 * 1033 * Prepare to cut? 1034 * 1035 * In: VisScrn = current screen 1036 * cutscrn = screen we want to be on 1037 * 1038 * If cutscrn <> VisScrn, make necessary preparations 1039 * & return cutplan = 1 1040 * 1041 *------------------------------- 1042 PrepCut 1043 lda cutscrn 1044 beq ]rts ;never cut to screen 0 1045 cmp VisScrn 1046 beq ]rts ;If cutscrn = VisScrn, we don't need to cut 1047 1048 lda cutscrn 1049 sta VisScrn 1050 cmp #5 1051 bne :1 1052 lda level 1053 cmp #14 1054 bne :1 1055 jmp YouWin ;Level 14, screen 5 is princess's room--you win! 1056 1057 :1 lda #1 1058 sta cutplan 1059 1060 jsr getscrns ;Get neighboring screen #s 1061 1062 jsr LoadKid 1063 jsr addslicers 1064 jsr addtorches 1065 jsr crumble ;Activate slicers, torches, etc. 1066 1067 jmp addguard ;Add guard (if any) 1068 1069 *------------------------------- 1070 * 1071 * Time's up--you lose 1072 * 1073 *------------------------------- 1074 YouLose 1075 jsr cutprincess ;cut to princess's room... 1076 lda #6 1077 jsr playcut ;& play cut #6 1078 1079 jmp GOATTRACT ;go to title sequence 1080 1081 *------------------------------- 1082 * 1083 * You win 1084 * 1085 *------------------------------- 1086 YouWin jsr cutprincess 1087 lda #7 1088 jsr playcut ;Play cut #7 1089 jmp epilog ;Play epilog (& hang) 1090 1091 *------------------------------- 1092 * 1093 * Control player 1094 * 1095 * In/out: Char vars 1096 * 1097 *------------------------------- 1098 ctrlplayer 1099 jsr kill0 ;If char is on screen 0, kill him off 1100 1101 jsr PlayerCtrl ;Control player 1102 1103 lda CharLife 1104 bmi ]rts ;If char is still alive, return 1105 1106 * When player dies, CharLife is set to 0. 1107 * Inc CharLife until = #deadenough; then put up message 1108 1109 :dead lda CharPosn 1110 jsr cold? 1111 bne ]rts ;wait till char has stopped moving 1112 1113 lda CharLife 1114 bne :inc 1115 jsr deathsong ;cue death music 1116 1117 :inc lda CharLife 1118 cmp #deadenough 1119 bcs :deadenough 1120 inc CharLife 1121 ]rts rts 1122 1123 :deadenough 1124 lda level 1125 beq :gameover ;Your death ends demo 1126 1127 lda SongCue 1128 bne ]rts ;wait for song to finish before putting up msg 1129 1130 lda MinLeft 1131 ora SecLeft 1132 bne :timeleft 1133 jmp YouLose ;if you die with time = 0, you lose 1134 1135 * Otherwise: "Press Button to Continue" 1136 1137 :timeleft 1138 lda message 1139 cmp #ContMsg 1140 bne :1 1141 lda msgtimer 1142 bne :ok 1143 1144 :1 lda #ContMsg 1145 sta message 1146 lda #255 1147 sta msgtimer ;Put up continue message 1148 1149 :ok cmp #1 1150 beq :gameover ;End game when msgtimer = 1 1151 1152 do FinalDisk 1153 else 1154 1155 lda develment 1156 beq :nodevel 1157 lda keypress 1158 cmp #kresurrect 1159 beq :raise ;TEMP! 1160 :nodevel 1161 fin 1162 1163 lda BTN0 1164 ora BTN1 1165 bpl ]rts 1166 jmp RESTART ;Button press restarts level 1167 1168 :gameover 1169 do EditorDisk 1170 jmp RESTART 1171 else 1172 jmp GOATTRACT 1173 fin 1174 1175 * Raise kid from the dead (TEMP!) 1176 1177 do FinalDisk 1178 else 1179 :raise 1180 lda #0 1181 sta msgtimer 1182 sta SongCue 1183 1184 lda #BTLtimer 1185 sta backtolife 1186 1187 jsr LoadKid 1188 1189 lda MaxKidStr 1190 sta ChgKidStr 1191 1192 lda #stand 1193 jsr jumpseq 1194 jmp startkid1 1195 1196 fin 1197 1198 *------------------------------- 1199 * 1200 * Play death song 1201 * 1202 *------------------------------- 1203 deathsong 1204 lda ShadID 1205 cmp #1 1206 beq :shad ;if opponent was shadowman 1207 lda heroic ;was kid engaged in battle at time of death? 1208 bne :1 ;yes--"heroic death" music 1209 lda #s_Accid ;no--"accidental death" music 1210 bne :2 1211 :shad lda #s_Shadow 1212 bne :2 1213 :1 lda #s_Heroic 1214 :2 ldx #255 1215 jmp cuesong 1216 ]rts rts 1217 1218 *------------------------------- 1219 * 1220 * If char is on screen 0, kill him off 1221 * 1222 *------------------------------- 1223 kill0 1224 lda CharLife 1225 bpl ]rts 1226 lda CharScrn 1227 bne ]rts 1228 lda #Splat 1229 jsr addsound 1230 lda #100 1231 jsr decstr 1232 lda #0 1233 sta msgtimer 1234 sta CharLife 1235 lda #185 1236 sta CharPosn 1237 ]rts rts 1238 1239 *------------------------------- 1240 * 1241 * Go to attract mode 1242 * 1243 *------------------------------- 1244 GOATTRACT 1245 do DemoDisk 1246 else 1247 1248 lda BBundID 1249 cmp #POPside1 ;does he need to flip disk? 1250 beq :ok ;no 1251 1252 do ThreeFive 1253 else 1254 lda BGset1 1255 bpl :flip 1256 ldx #4 1257 jsr LoadLevelX ;get "FLIP DISK" msg into memory 1258 fin 1259 1260 :flip jsr flipdisk ;ask him to flip disk 1261 1262 fin 1263 1264 lda #POPside1 1265 sta BBundID 1266 1267 :ok jmp attractmode 1268 1269 *------------------------------- 1270 * 1271 * Shake loose floors when character jumps 1272 * 1273 *------------------------------- 1274 shakeloose 1275 lda jarabove 1276 bmi :jarbelow 1277 bne :jarabove 1278 ]rts rts 1279 1280 :jarbelow 1281 lda #0 1282 sta jarabove 1283 1284 lda CharBlockY 1285 jmp shakem ;shake every loose floorboard on level 1286 1287 :jarabove 1288 lda #0 1289 sta jarabove 1290 1291 lda CharBlockY 1292 sec 1293 sbc #1 1294 jmp shakem 1295 1296 *------------------------------- 1297 * 1298 * If strength meters have changed, mark affected 1299 * blocks for redraw 1300 * 1301 *------------------------------- 1302 checkmeters 1303 lda ChgKidStr 1304 beq :1 1305 jsr MarkKidMeter 1306 1307 :1 lda ChgOppStr 1308 beq ]rts 1309 jmp MarkOppMeter 1310 1311 *------------------------------- 1312 * 1313 * Change strength meters as specified 1314 * 1315 *------------------------------- 1316 chgmeters 1317 lda level 1318 cmp #12 1319 bne :cont 1320 lda OpID 1321 ora CharID 1322 cmp #1 ;kid vs. shadowman? 1323 bne :cont 1324 ;yes 1325 lda ChgKidStr 1326 bpl :1 1327 sta ChgOppStr 1328 bne :cont 1329 1330 :1 lda ChgOppStr 1331 bpl :cont 1332 sta ChgKidStr 1333 1334 * Kid's meter 1335 1336 :cont lda KidStrength 1337 clc 1338 adc ChgKidStr 1339 1340 cmp MaxKidStr 1341 beq :ok1 1342 bcs :opp 1343 1344 :ok1 sta KidStrength 1345 1346 * Opponent's meter 1347 1348 :opp lda OppStrength 1349 clc 1350 adc ChgOppStr 1351 1352 cmp MaxOppStr 1353 beq :ok2 1354 bcs ]rts 1355 1356 :ok2 sta OppStrength 1357 ]rts rts 1358 1359 *------------------------------- 1360 * 1361 * Slam player's entrance shut (add it to trans list) 1362 * 1363 *------------------------------- 1364 entrance 1365 lda KidScrn 1366 jsr calcblue 1367 1368 ldy #29 1369 1370 :loop lda (BlueType),y 1371 and #idmask 1372 cmp #exit 1373 bne :cont ;find player's entrance 1374 1375 lda KidScrn 1376 jmp closeexit ;& return 1377 1378 :cont dey 1379 bpl :loop 1380 1381 ]rts rts 1382 1383 *------------------------------- 1384 * 1385 * Play song cues 1386 * 1387 * In: SongCue (0 = none, non0 = song #) 1388 * SongCount 1389 * 1390 *------------------------------- 1391 songcues 1392 do EditorDisk 1393 rts 1394 fin 1395 1396 ldx SongCue 1397 beq ]rts 1398 lda level 1399 beq ]rts ;no music in demo 1400 1401 lda SongCount 1402 bne :cont 1403 lda #0 1404 sta SongCue ;when SongCount reaches 0, forget it 1405 ]rts rts 1406 :cont dec SongCount 1407 1408 lda KidPosn 1409 bne :1 1410 lda NextLevel 1411 cmp level 1412 beq ]rts ;Play only one song once kid has reached stairs 1413 1414 :1 lda KidPosn 1415 jsr static? 1416 bne ]rts 1417 1418 lda ShadFace 1419 cmp #86 1420 beq :ok 1421 lda ShadScrn 1422 cmp VisScrn 1423 bne :ok 1424 lda ShadPosn 1425 jsr static? 1426 bne ]rts 1427 :ok 1428 lda trobcount ;(set by animtrans if there are any 1429 bne ]rts ;slicers or other fast-moving objects 1430 ;that it wouldn't look good to freeze) 1431 lda nummob 1432 bne ]rts 1433 lda lightning 1434 bne ]rts ;wait for no MOBs and no lightning 1435 lda mergetimer 1436 bmi :ok2 1437 bne ]rts 1438 lda ChgKidStr 1439 ora ChgOppStr 1440 bne ]rts ;& no impact stars 1441 :ok2 1442 1443 * Prepare for minimal animation 1444 1445 lda PAGE 1446 eor #$20 1447 sta PAGE 1448 1449 jsr listtorches 1450 1451 * Play song 1452 1453 lda SongCue 1454 jsr minit 1455 1456 sta $c010 ;clr kbd 1457 1458 :loop jsr burn 1459 jsr musickeys 1460 1461 jsr mplay 1462 cmp #0 1463 bne :loop 1464 1465 :done lda #0 1466 sta SongCue 1467 1468 :rtn lda PAGE 1469 eor #$20 1470 sta PAGE 1471 1472 jmp clearjoy 1473 1474 *------------------------------- 1475 * 1476 * Add additional sound fx 1477 * 1478 *------------------------------- 1479 addsfx 1480 lda #167 ;blocked strike 1481 cmp KidPosn ;if char is striking... 1482 bne :1 1483 lda #SwordClash1 1484 bne :clash 1485 :1 cmp ShadPosn 1486 bne :2 1487 lda #SwordClash2 1488 :clash jmp addsound 1489 :2 1490 ]rts rts 1491 1492 *------------------------------- 1493 * 1494 * Display message ("Press button to continue" or "Level #" 1495 * or "# minutes left") 1496 * 1497 *------------------------------- 1498 dispmsg 1499 lda msgtimer 1500 beq ]rts 1501 dec msgtimer 1502 1503 lda KidLife 1504 bmi :alive 1505 1506 * Kid is dead -- message is "Press button to continue" 1507 1508 lda msgtimer 1509 cmp #contoff 1510 bcc ]rts 1511 1512 cmp #contflash 1513 bcs :steady 1514 1515 and #7 1516 cmp #3 1517 bcs ]rts 1518 cmp #2 1519 bne :steady 1520 1521 lda soundon 1522 bne :2 1523 jsr gtone ;if sound off 1524 :2 lda #FlashMsg 1525 jsr addsound 1526 1527 :steady jmp continuemsg ;Kid is dead--superimpose continue msg 1528 1529 * Kid is alive -- message is "Level #" or "# Minutes" 1530 1531 :alive lda msgtimer 1532 cmp #leveltimer-2 1533 bcs ]rts 1534 1535 lda message 1536 cmp #LevelMsg 1537 bne :1 1538 jmp printlevel 1539 1540 :1 cmp #TimeMsg 1541 bne ]rts 1542 jmp timeleftmsg 1543 1544 *------------------------------- 1545 * 1546 * Display "Turn disk over" and wait for button press 1547 * 1548 *------------------------------- 1549 flipdisk 1550 do ThreeFive 1551 lda #1 1552 sta purpleflag ;pass copy-protect! 1553 rts 1554 fin 1555 1556 do DemoDisk 1557 jmp GOATTRACT 1558 else 1559 1560 * 1st copy protection check 1561 1562 lda redherring 1563 eor redherring2 1564 cmp #POPside1 ;passed 1st check? 1565 beq :1 1566 lda #POPside1 1567 sta BBundID 1568 jmp attractmode 1569 1570 * Passed copy protection--continue 1571 1572 :1 lda #" " 1573 jsr lrcls 1574 1575 jsr zerolsts 1576 jsr zeropeels 1577 lda #1 1578 sta genCLS 1579 1580 jsr flipdiskmsg 1581 1582 jsr drawall 1583 1584 jsr vblank 1585 jsr PageFlip 1586 1587 lda $c010 ;clr kbd strobe 1588 :loop 1589 lda $c061 1590 ora $c062 1591 ora $c000 1592 bpl :loop 1593 1594 fin 1595 1596 * Flip to clr text scrn 1597 1598 showtext jsr vblank 1599 lda PAGE2off 1600 lda TEXTon 1601 ]rts rts 1602 1603 *------------------------------- 1604 * 1605 * Is character moving? 1606 * 1607 * In: A = CharPosn 1608 * Out: 0 if static, 1 if moving 1609 * 1610 *------------------------------- 1611 static? 1612 cmp #0 1613 beq ]ok 1614 cmp #15 ;stand 1615 beq ]ok 1616 cmp #229 ;brandish sword 1617 beq ]ok 1618 cmp #109 ;crouching 1619 beq ]ok 1620 cmp #171 ;en garde 1621 beq ]ok 1622 cmp #166 ;alert stand (for gd.) 1623 beq ]ok 1624 cold? 1625 cmp #185 ;dead 1626 beq ]ok 1627 cmp #177 ;impaled 1628 beq ]ok 1629 cmp #178 ;halves 1630 beq ]ok 1631 lda #1 1632 rts 1633 ]ok lda #0 1634 ]rts rts 1635 1636 *------------------------------- 1637 * 1638 * Clear all jstk flags 1639 * 1640 *------------------------------- 1641 clearjoy 1642 jsr LoadSelect 1643 lda #0 1644 sta clrF 1645 sta clrB 1646 sta clrU 1647 sta clrD 1648 jmp SaveSelect 1649 1650 *------------------------------- 1651 * 1652 * Misc. timers (Call every cycle) 1653 * 1654 *------------------------------- 1655 misctimers 1656 lda mergetimer 1657 beq :3 1658 bmi :3 1659 dec mergetimer 1660 bne :3 1661 dec mergetimer ;goes from 1 to -1 1662 :3 1663 1664 * Level 8: When you've spent a certain amount of time on 1665 * screen 16 once exit is open, mouse rescues you 1666 1667 lda level 1668 cmp #8 ;mouse level 1669 bne :12 1670 lda CharScrn 1671 cmp #16 1672 bne :12 1673 lda exitopen 1674 beq :12 1675 cmp #mousetimer 1676 bcc :11 1677 bne :12 1678 :10 jsr mouserescue 1679 :11 inc exitopen 1680 :12 1681 ]rts rts 1682 1683 *------------------------------- 1684 * 1685 * Screen flashes towards end of weightlessness period 1686 * 1687 *------------------------------- 1688 wtlessflash 1689 lda weightless 1690 beq ]rts 1691 ldx #0 1692 sec 1693 sbc #1 1694 sta weightless 1695 beq :3 1696 ldx #$ff 1697 cmp #wtlflash 1698 bcs :3 1699 lda vibes 1700 eor #$ff 1701 tax 1702 :3 stx vibes ;Screen flashes as weightlessness ends 1703 ]rts rts 1704 1705 *------------------------------- 1706 * yellow copy protection 1707 * (call right before 1st princess cut) 1708 * In: A = next level 1709 *------------------------------- 1710 yellowcheck 1711 cmp #2 1712 bne ]rts 1713 jsr showtext 1714 ldx #10 1715 jmp yellow ;in gamebg 1716 ;sets yellowflag ($7c) hibit 1717 1718 *------------------------------- 1719 * 1720 * Temp development patch for screen redraw 1721 * (also used for invert Y) 1722 * 1723 *------------------------------- 1724 develpatch 1725 do 0 1726 lda blackflag ;blackout? 1727 beq :1 1728 lda #1 1729 sta genCLS 1730 fin 1731 1732 :1 lda redrawflg ;forced redraw? 1733 beq ]rts 1734 dec redrawflg 1735 1736 jsr markmeters 1737 jmp sure 1738 1739 *------------------------------- 1740 lst 1741 ds 1 1742 usr $a9,4,$a00,*-org 1743 lst off