* 2040 180684 * ** JOY.S ** ** ASTEROIDS FOR THE ATARI 3600 ** ** THIS FILE CONTAINS THE JOYSTICK HANDLING ROUTINE. ** JOY: LDX PLAYER LDA STATE,X ;CHECK IF SHIP IS OK BEQ EXECJOY ;ONLY CHECK JOYSTICK IF OK RTS EXECJOY: LDX OFFPLAY2 ;POWER STEERING BABY! LDA XVELH+24,X ;CALCULATE RATE OF TURN BPL ZSTTEMP ;A VELOCITY DEPENDENT VALUE EOR #$FF CLC ADC #1 ZSTTEMP: STA TEMP LDA YVELH+24,X BPL ZADDTEMP EOR #$FF CLC ADC #1 ZADDTEMP: CLC ADC TEMP STA TEMP LDA #9 SBC TEMP STA TEMP LDX PLAYER ;CHECK HYPERSPACE LDA HYPBUT1,X BMI LDSWCH JSR HYPERSPC LDSWCH: LDA SWCHAVAL ;GET JOYSTICK INPUT LDX PLAYER BEQ JOYONE ASL ;IF PLAYER2 THEN SHIFT 4 MORE ASL ASL ASL JOYONE: CKWEST: ASL ;SHIFT MSB INTO CARRY PHA ;SAVE ACC BCS CKEAST ;IF SET THEN NEXT, ACTIVE LOW JSR ROTLEFT ;CLEAR, ROTATE LEFT CKEAST: PLA ;RESTORE ACC ASL ;CHECK WEST BIT PHA ;SAVE ACC BCS CKSOUTH ;IF SET THEN NEXT JSR ROTRIGHT ;CLEAR, ROTATE RIGHT CKSOUTH: PLA ASL PHA BCS CKNORTH JSR DAMPX JSR DAMPY CKNORTH: PLA ;RESTORE ACC ASL ;CHECK NORTH BIT BCS DAMPTHR ;IF SET THEN DAMP BCC ADDTHRST ;IF CLEAR THEN THRUST * ROTATE SHIP ROUTINES ROTRIGHT: LDA SHIPDIR,X SEC SBC TEMP JMP SETSDIR ROTLEFT: LDA SHIPDIR,X CLC ADC TEMP SETSDIR: STA SHIPDIR,X LDY OFFPLAY2 LSR LSR LSR AND #$FE CLC ADC #SHIP1&255 STA ACYC+24,Y RTS * DAMPEN THRUST ROUTINE DAMPTHR: LDA MODE ;IN ONE-AT-A-TIME PLAY, CMP #01 ; (I.E., MODES $FF AND $00), BMI DAMPTN ; DON'T WORRY ABOUT OTHER PLAYER LDA STATE ;ELSE MAKE SURE BOTH PLAYERS ARE OK. ORA STATE+1 ; IF EITHER IS NOT, IT MUST BE THE BNE DAMPTN ; OTHER ONE! GO ON AS IF ONLY 1 IS OK. LDA SWCHAVAL ;ELSE MAKE SURE ONLY ONE THRUST TUNE IS AND THRBITS,X ; EVER PLAYING AT A TIME; BEQ NODAMPTN ; (IF = 0, THEN *HE* IS THRUSTING) DAMPTN: LDA #$11 ;DAMP THRUST TUNE JSR KILLTUNE ; (GET RID OF THE TUNE) NODAMPTN: LDA PLAYER ASL ASL TAY LDA #$00 STA SOFTCOLR+1,Y JSR DAMPX JSR DAMPY * CHECK THE FIRE BUTTON CHKFIRE: LDX PLAYER LDA FIREBUT1,X BMI FRESET LDA FIRESTAT,X BNE JOYBYE JMP DNSHOT FRESET: LDA #0 STA FIRESTAT,X JOYBYE: RTS * ADD THRUST ROUTINE ADDTHRST: LDA #$11 ;ADD THRUST SOUND JSR DOTUNE2 ;ONLY IF NOT ALREADY PLAYING LDA PLAYER ;CHANGE COLOR OF THRUST FLAME ASL ASL TAY LDA #$4F STA SOFTCOLR+1,Y LDX PLAYER LDA SHIPDIR,X LSR LSR LSR LSR TAY LDX OFFPLAY2 LDA XVELL+24,X STA TEMP+1 LDA XVELH+24,X LSR ROR TEMP+1 LSR ROR TEMP+1 LSR ROR TEMP+1 LSR ROR TEMP+1 LDA YVELL+24,X STA TEMP+2 LDA YVELH+24,X LSR ROR TEMP+2 LSR ROR TEMP+2 LSR ROR TEMP+2 LSR ROR TEMP+2 XTHRUST: LDA MAXVECT,Y BPL POSOXVEL NEGOXVEL: LDX TEMP+1 BPL ADDXVEL CMP TEMP+1 BCC ADDXVEL BCS DODAMPX POSOXVEL: LDX TEMP+1 BMI ADDXVEL CMP TEMP+1 BCS ADDXVEL DODAMPX: JSR DAMPX JMP YTHRUST ADDXVEL: LDA UNITVECT,Y ASL ASL ASL LDX OFFPLAY2 CLC ADC XVELL+24,X STA XVELL+24,X LDA XVELH+24,X ADC HUNTVECT,Y STA XVELH+24,X YTHRUST: TYA CLC ADC #$10 TAY LDA MAXVECT,Y BPL POSOYVEL NEGOYVEL: LDX TEMP+2 BPL ADDYVEL CMP TEMP+2 BCC ADDYVEL BCS DODAMPY POSOYVEL: LDX TEMP+2 BMI ADDYVEL CMP TEMP+2 BCS ADDYVEL DODAMPY: JSR DAMPY JMP CHKFIRE ADDYVEL: LDA UNITVECT,Y ASL ASL ASL LDX OFFPLAY2 CLC ADC YVELL+24,X STA YVELL+24,X LDA YVELH+24,X ADC HUNTVECT,Y STA YVELH+24,X JMP CHKFIRE DNSHOT: LDA MODE CMP #1 ;MODE - 1 BPL TDNSHOT ;MODES 1 AND 2 USE TDNSHOT LDX #3 NEXTSHOT: LDA STATUS+28,X BMI THISSHOT DEX BPL NEXTSHOT RTS TDNSHOT: LDX PLAYER ;ALLOW 2 SHOTS PER BEQ TPLAY1 ;PLAYER1 GETS 0 & 1 LDX #2 ;PLAYER2 GETS 2 & 3 TPLAY1: LDA STATUS+28,X BMI THISSHOT INX LDA STATUS+28,X BMI THISSHOT RTS THISSHOT: LDY PLAYER LDA SHIPDIR,Y LSR LSR LSR LSR TAY LDA #SHOT STA STATUS+28,X LDA #$EC STA SHOTCNT+2,X STX TEMP ;SAVE X LDX OFFPLAY2 LDA XPOSH+24,X LDX TEMP ;RESTORE CLC ADC SHNOSEX,Y CMP #XPOSMAX BCC SHXOK SBC #XPOSMAX SHXOK: STA XPOSH+28,X LDX OFFPLAY2 LDA YPOSH+24,X LDX TEMP ;RESTORE CLC ADC SHNOSEY,Y CMP #YPOSMAX BCC SHYOK SBC #YPOSMAX SHYOK: STA YPOSH+28,X LDX OFFPLAY2 LDA XPOSL+24,X LDX TEMP STA XPOSL+28,X LDX OFFPLAY2 LDA YPOSL+24,X LDX TEMP STA YPOSL+28,X LDA UNITVCTX,Y LDX OFFPLAY2 CLC ADC XVELH+24,X LDX TEMP STA XVELH+28,X LDX OFFPLAY2 LDA XVELL+24,X LDX TEMP STA XVELL+28,X LDA UNITVCTY,Y LDX OFFPLAY2 CLC ADC YVELH+24,X LDX TEMP STA YVELH+28,X LDX OFFPLAY2 LDA YVELL+24,X LDX TEMP STA YVELL+28,X LDA #$0E ;LOAD SOUND FOR HERO SHOTS JSR DOTUNE1 LDX PLAYER LDA #1 STA FIRESTAT,X RTS HYPERSPC: LDX PLAYER ;WHICH PLAYER LDA STATE,X ;STATE OF PLAYER BNE NOHYPER ;IF OK THEN CONTINUE LDA #2 ;STATE FOR HYPERSPACE STA STATE,X LDA #$2C ;$29+3 STA TIMER,X NOHYPER: RTS DAMPX: LDX OFFPLAY2 LDA XVELL+24,X ;IS VELOCITY ALREADY ZERO? ORA XVELH+24,X ; (LOW *OR* HIGH IS CHEAP MAGNITUDE) BEQ DAMPXRTS ;YES: NO DAMPING NEEDED ;COMPUTE XVEL * 3/256 LDA XVELL+24,X ;FIRST COMPUTE XVEL/128 ASL STA TEMP+1 LDA XVELH+24,X ROL ;ROL IN THE CARRY BIT STA TEMP LDA XVELL+24,X ;THEN ADD IN XVEL / 256 CLC ADC TEMP+1 STA TEMP+1 LDA XVELH+24,X BPL XHPOS INC XVELH+24,X ;BORROW TO CORRECT SBC #0 BELOW XHPOS: ADC TEMP STA TEMP LDX PLAYER LDA XVELLL,X ;ADJUST THE "NOISE" BYTE SEC SBC TEMP+1 STA XVELLL,X LDX OFFPLAY2 LDA XVELL+24,X SBC TEMP STA XVELL+24,X LDA XVELH+24,X SBC #0 STA XVELH+24,X LDA #0 STA CLAMP LDA XVELH+24,X ;CLAMP OFF TO STOP DRIFT BEQ ZCKPOSX CLC ADC #1 BNE DAMPXRTS LDA XVELL+24,X ;ZCKMINX CMP #(0-$20) & 255 BCC DAMPXRTS BCS ZSETX0 ZCKPOSX: LDA XVELL+24,X CMP #$20 BCS DAMPXRTS ZSETX0: LDA #1 STA CLAMP DAMPXRTS: RTS DAMPY: LDX OFFPLAY2 LDA YVELL+24,X ;IS VELOCITY ALREADY ZERO? ORA YVELH+24,X ; (LOW *OR* HIGH IS CHEAP MAGNITUDE) BEQ DAMPYRTS ;YES: NO DAMPING NEEDED ;COMPUTE YVEL * 3/256 LDA YVELL+24,X ;FIRST COMPUTE YVEL/128 ASL STA TEMP+1 LDA YVELH+24,X ROL ;ROL IN THE CARRY BIT STA TEMP LDA YVELL+24,X ;THEN ADD IN YVEL / 256 CLC ADC TEMP+1 STA TEMP+1 LDA YVELH+24,X BPL YHPOS INC YVELH+24,X ;BORROW TO CORRECT SBC #0 BELOW YHPOS: ADC TEMP STA TEMP LDX PLAYER LDA YVELLL,X ;ADJUST THE "NOISE" BYTE SEC SBC TEMP+1 STA YVELLL,X LDX OFFPLAY2 LDA YVELL+24,X SBC TEMP STA YVELL+24,X LDA YVELH+24,X SBC #0 STA YVELH+24,X LDA YVELH+24,X ;CLAMP OFF TO STOP DRIFT BEQ ZCKPOSY CLC ADC #1 BNE DAMPYRTS LDA YVELL+24,X ;ZCKMINX CMP #(0-$20) & 255 BCC DAMPYRTS BCS ZSETY0 ZCKPOSY: LDA YVELL+24,X CMP #$20 BCS DAMPYRTS ZSETY0: LDA CLAMP BEQ DAMPYRTS LDA #0 STA XVELL+24,X STA XVELH+24,X STA YVELL+24,X STA YVELH+24,X DAMPYRTS: RTS ** ROUTINE TO CHECK THE JOYSTICK AND UPDATE SOFTWARE REGISTERS. ** CKJOY: LDA SWCHA ;GET VALUES FROM TIA STA SWCHAVAL ;STORE IN SOFT REGISTERS LDX #1 ;DO PLAYERS 1 AND 0 ZNXTRJ: JSR READJOY ;READ HIS JOYSTICK DEX BPL ZNXTRJ LDA FIREBUT1 ;PLAYER 0 FIRE BUTTON IS STARTBUT STA STARTBUT LDA GAMSTATE ;CHECK IF IN AUTO PLAY STATE CMP #AUTOST BNE CKJOYRTS ;NO. DON'T DO RANDOM VIOLENCE PICKJOY: LDA #$FF ;CLEAR ALL BUTTONS STA FIREBUT1 STA FIREBUT2 STA HYPBUT1 STA HYPBUT2 LDA FRMCNT ;DON'T ALWAYS DO AND #$0C BNE CKJOYRTS LDA FRMCNT ;ALTERNATE FIRING LSR AND #1 TAX LDA #$7F STA FIREBUT1,X JSR NEWRAND ;RANDOM SHIP MOVEMENT AND #$07 TAX LDA JOYVALS,X STA SWCHAVAL CKJOYRTS: RTS * READJOY: READ JOYSTICK/BUTTONS. ON ENTRY X = PLAYER. Y IS TRASHED READJOY: LDY INPT4,X BPL GOTONE ;IF BIT 7 IS LO, OLD-STYLE BUTTON HIT LDA ONEBUT ;ARE WE ALREADY IN OLD-STYLE MODE? AND RJBITS,X BNE GOTONE2 ;YES. GO RIGHT TO ONE-BUTTON HANDLER. TXA ;OTHERWISE, COMPUTE INDEX INTO ASL ; PADDLE PORTS, FOR PLAYER X, TAY ; IN Y (X * 2) LDA INPT4A,Y ;READ LEFT BUTTON EOR #$FF ;INVERT THE SENSE! STA FIREBUT1,X LDA INPT4B,Y ; RIGHT BUTTON EOR #$FF RJSTOREH: STA HYPBUT1,X RJRTS: RTS ;HERE ON OLD-STYLE SINGLE BUTTON JOYSTICK PRESS. GOTONE: LDA ONEBUT ;TURN OFF TWO-PLAYER BIT IMMEDIATELY ORA RJBITS,X ; TO AVOID BURNING OUT HARDWARE STA SWCHB STA ONEBUT ;SAVE THE NEW VALUE GOTONE2: STY FIREBUT1,X ;Y CONTAINS CONTENTS OF INPT4 NOW LDA #$FF STA HYPBUT1,X ;CLEAR HYPERSPACE BUTTON LDA SWCHAVAL ;CHECK JOYSTICK REGISTER AND JOYTBL,X ; FOR THIS PLAYER'S CMP RJSBITS,X ; HYPERSPACE BIT BNE RJRTS ;IF BIT NOT LO, THEN NO HYPERSPACE LDA #$7F ;OTHERWISE, SET THE BIT LO BNE RJSTOREH ;BNE = JMP RJBITS: .DC.B $04,$10 ;TWO-PLAYER MODE BITS PER PLAYER RJSBITS: .DC.B $D0,$0D ;SOUTH JOYSTICK BITS PER PLAYER THRBITS: .DC.B $01,$10 ;NORTH BITS PER *OTHER* PLAYER JOYVALS: .DC.B $7F,$BF,$EF,$F7,$FB,$FE,$FF,$EE ;AUTOPLAY JOYSTICK VALUES