;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;Edits By: Chdata/Fakescaper (Works in air) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RAM_AirMeter = $7F8827 ;; Where to place the meter relative to the screen boarder MeterPositionX = $E8 MeterPositionY = $1E ;; Possible values for the below variables: ;; (fast) $00, $01, $03, $07, $0f, $1f, $3f, $7f, $ff (slow) CountDownFrequency = $03 CountUpFrequency = $00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; INIT and MAIN routines ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DCB "INIT" LDA #$FF STA RAM_AirMeter RTL DCB "MAIN" PHB PHK PLB JSR MainSub PLB RTL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Sprite Main ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MainSub: LDA RAM_AirMeter ; Play warning sounds CMP #$1C BEQ Sound CMP #$14 BEQ Sound CMP #$0C BNE NoSound Sound: LDA #$2a STA $1DFC NoSound: ;; LDA RAM_AirMeter ; Change Mario's face blue ;; CMP #$30 ;; BCS NoChangePal ;; ;; LDY #$86 ;; STY $2121 ;; ;; LDA #$31 ;; STA $2122 ;; LDA #$7e ;; STA $2122 ;; ;; LDY #$8e ;; STY $2121 ;; ;; LDA #$ad ;; STA $2122 ;; LDA #$6d ;; STA $2122 ;; NoPalChange: LDA RAM_AirMeter ; If the meter is full... CMP #$FF ; BNE Gfx ; ...and it has been for some time... LDA $1540,x ; BEQ NoGfx ; ...then skip the graphics routine Gfx: JSR SubGfx ; Draw the sprite NoGfx: LDA $9D ; Return if sprites are locked BNE Return0 LDA $1493 ;If level end, do nothing to the meter BNE SkipMeter LDA $75 ;BEQ CountUp CountDown: LDA $13 AND #CountDownFrequency BNE SkipMeter LDA RAM_AirMeter DEC A BNE SetMeter BRA KillMario CountUp: LDA $13 AND #CountUpFrequency BNE SkipMeter LDA RAM_AirMeter CMP #$FF BEQ SkipMeter LDA #$48 STA $1540,x LDA RAM_AirMeter INC A ;; LDA #$FF ; NOTE: Reinstate to make the meter instantly reset when not in water SetMeter: STA RAM_AirMeter SkipMeter: LDA $1a ; Position = Screen boundary CLC ADC #$80 STA $E4,x ; This is done so the sprite stays on screen LDA $1b ADC #$00 STA $14E0,x LDA $1c STA $D8,x LDA $1d STA $14D4,x Return0: RTS KillMario: LDA #$90 STA $7D LDA #$09 ; Set death animation STA $71 STA $1DFB ; Set death music LDA #$01 STA $0DDA LDA #$30 ; Set time until we return to the OW STA $1496 STA $9D STZ $140D STZ $1407 STZ $188A RTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Graphics Routine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NumTiles = $05 SpriteTileDispX: dcb $00,$08,$10,$18,$20,$27 SpriteTileDispY: dcb $28,$20,$18,$10,$08,$01 SpriteGfxProp: dcb $80,$00,$00,$00,$00,$00 Palettes: dcb $09,$05,$0B SubGfx: JSR GetPalette ;; LDA $15F6,x ; NOTE: Reinstate to use the palette from the cfg file STA $02 LDA RAM_AirMeter ; Load address to be timed LSR LSR LSR STA $03 LDY $15EA,x ; get offset to sprite OAM PHX LDX #NumTiles GfxLoopStart: LDA #MeterPositionX STA $0300,Y LDA #MeterPositionY CLC ADC SpriteTileDispY,x STA $0301,Y LDA $03 JSR CalculateTile STA $0302,Y LDA $02 ORA SpriteGfxProp,x ORA #$20 STA $0303,Y INY INY INY INY DEX BPL GfxLoopStart PLX LDY #$00 LDA #NumTiles JSL $01B7B3 RTS GetPalette: LDY #$00 LDA RAM_AirMeter CMP #$55 BCC LoadPalette INY CMP #$AA BCC LoadPalette INY LoadPalette: LDA Palettes,y RTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CalculateTile: CPX #$00 BEQ EndPiece CPX #NumTiles BEQ EndPiece PHA TXA DEC A ASL ASL ASL STA $00 PLA SEC SBC $00 BMI EmptyTile CMP #$08 BCS FullTile AND #$07 CLC ADC #$47 CMP #$4B BCC Return CLC ADC #$0C Return: RTS FullTile: LDA #$46 RTS EmptyTile: LDA #$47 RTS EndPiece: LDA #$56 RTS