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