;Super Status Bar Advanced v2, by Kaijyuu. Patch updated by GreenHammerBro. ;See image file "ASSB_map.png" on how to use the status bar tiles. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Defines ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; !RAM_BAR = $7FA000 ;>Free ram for status bar (needs $140 (320 decimal) bytes) !RAM_DecCoins = $7FA140 ; !ShowZeroes = 0 ; !HP_Mod = 1 ; !HP_OFFSET = $092 ; !PP_OFFSET = $0D2 ; !AIR_T_OFFSET = $10C ; !AIR_OFFSET = $114 ; !Drown_dec_HP = $0117 ; !varram = $702000 ; 270 bytes !vwfmode = !varram ; 1 byte ;Valid numbers for these offsets: $000-$13F ;Use even numbers ONLY! ;Properties (palette/ect) are set in the DATA_TILES tables, or using Smallhacker's status bar editor ;They are not updated automatically if you just change these ;If you move the time counter, for example, it will probably be white until you change the properties byte ;of the tiles it writes to (through ASM, since it writes using DMA). ;If you want to remove a counter/routine controlled tile(s), change the "1"'s in labels that have "!Enable" ;in its name to 0. Note that it does not guarantee there will be a blank tile left behind when removed. !IRQ_line_Y_pos = $C0 ;\($26 by default), layer 3 status bar/HUD IRQ/cutoff line Y position (in pixels), ;/If you are not using the last row of 8x8 tiles, change it to $24. !Enable_TIME = 0 ;>display time limit: 0 = false (will be black squares on 1st and 2nd digits, ; Also, you need to disable the "time bonus" that happens if beating the level), ; 1 = true. !TIME_OFFSET = $0E6 ;>Position of numbers of the time limit (not the word "TIME" itself) !TIME_SPEED = $28 ;>($28 by default) how many frames before each (or "period") decrement of time limit, put ; "$3C" for real seconds because the game runs 60 fps or HZ (barring lags and slowdowns). !timer_warning = 0 ;>if the timer hits below 100, the "TIME" and digits palette changes to red and if ; it is less than 10, will play the "beeping" sound, inspired by SM3DL/SM3DW/NSMB2. ; 0 = false, 1 = true. !Enable_SCORE = 1 ;>Display score: 0 = false (will display last 0 digit, also you need to download GHB's ; disable score patch, modify the status bar hijacks and insert it in so the goal ; doesn't still give you points), 1 = true. !SCORE_OFFSET = $0EE ;>Position of score counter. !Enable_LIVES = 0 ;>Display lives: 0 = false (always says 0 lives), 1 = true. !LIVES_OFFSET = $0C8 ;>Position of lives counter !Enable_COINS = 1 ;>Display coin counter (numbers only): 0 = false (always says 0 coins), 1 = true. !COINS_OFFSET = $0B8 ;>Position of coin counter !Enable_NAME = 0 ;>Show Mario/Luigi name: 0 = false (always say "MARIO"), 1 = true. !NAME_OFFSET = $084 ;>Position of player name (MARIO/LUIGI) !Enable_DRAGON = 0 ;>Display (repeating by # of icons) yoshi coins: 0 = false, 1 = true. !DRAGON_OFFSET = $090 ;>Position of dragon coins (yoshi coins, whatever) !TILE_EMPTY = $FC ;>Tile number that represents "no yoshi coins" !TILE_FULL = $2E ;>tile number that represents "yoshi coin(s) collected" !Enable_STARS = 0 ;>display bonus stars: 0 = false (you might want to use a custom goal, the victory bonus ; stars are now useless), 1 = true. !STARS_OFFSET = $0D8 ;>Position of bonus stars counter (large numbers next to item box normally) ; This corresponds to the BOTTOM LEFT corner (bottom half of the tens digit) of the counter !ITEM_X = $78 ;>X position of item in item box (screen) DOES NOT AFFECT WHERE ITEM DROPS FROM !ITEM_Y = $0F ;>Y position of item in item box (screen) DOES NOT AFFECT WHERE ITEM DROPS FROM !ITEM_PRIORITY = $30 ;>Priority bits of item in item box. (can be used to force palette/flip/ect too) ; YXPPCCCT !ITEM_SIZE = $02 ;>Size/high x position bit of item box item sprite tile. $02 = 16x16, $00 = 8x8 ; Setting the first bit ($01/$03) will push it far off the screen to the left ; With a high x position ($F0-FF), it will still be visible though. ; Just on the left side of the screen ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;SA1 detector: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; if read1($00FFD5) == $23 !SA1 = 1 sa1rom else !SA1 = 0 endif ; Example usage if !SA1 ; SA-1 base addresses ;Give thanks to absentCrowned for this: ;http://www.smwcentral.net/?p=viewthread&t=71953 !Base1 = $3000 ;>$0000-$00FF -> $3000-$30FF !Base2 = $6000 ;>$0100-$0FFF -> $6100-$6FFF and $1000-$1FFF -> $7000-$7FFF else ; Non SA-1 base addresses !Base1 = $0000 !Base2 = $0000 endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Hijacks: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ORG $008292 ;\Move the cutoff Irq line (not for smw's mode 7 bosses however). LDY #!IRQ_line_Y_pos ;/ ORG $00835C ;\Move the cutoff Irq line (for smw's mode 7 bosses). LDY #!IRQ_line_Y_pos ;/ ORG $008D8A ; hijack status bar initilization routine autoclean JML MAIN_2 ORG $008DB6 BRA SKIP_UNUSED ; skip past unused code ; This spot was chosen for compatibility with sprite status bar and stripe image uploader ; (sprite status bar requires some RAM address tweaks within it's code to be compatible with this) ORG $008DE2 ; near end of DrawStatusBar (error on asar, just because of ":") SKIP_UNUSED: autoclean JML MAIN ;Point to new routine ORG $008E1A ; hijack routine that updates status bar tiles in RAM autoclean JML MAIN_3 ORG $0090D0 ; make this into a JSL routine instead JSR RTL ORG $0090AE db !ITEM_X ; set item box item x position ORG $0090B3 db !ITEM_Y ; set item box item y position ORG $0090B8 db !ITEM_PRIORITY ; set item box item priority bits ORG $0090CC db !ITEM_SIZE ; set item box item size/high x bit if !HP_Mod incsrc "hp_hijacks_constants.asm" endif org $008CFF ;\ Hijack game mode 04 JML MAIN_2 ;/ and jump to our routine org $0082A4 ;NMI hijack autoclean JML PreStatusBar NOP #2 org $00838F ;IRQ hijack autoclean JML PostStatusBar NOP org $009090 autoclean JML ItemBoxItem incsrc "levelheight.asm" incsrc "coins_routine.asm" incsrc "tilemap_include.asm" incsrc "hp_hijacks_code.asm" incsrc "levelheight2.asm" ;below code is for the normal screen ;below code is for the status bar ItemBoxItem: STA $0207,y LDA #$18 : STA $0204,y LDA #$C7 : STA $0205,y LDA.b #$C0 : STA $0206,y TYA : LSR #2 : TAY LDA #$02 : STA $0421,y LDY $0DC2 ;restore hijack BNE + JML $0090D0 + JMP.w ItemFix - JML $008394 PostStatusBar: BIT $4212 : BVC $FB ;wait for h-blank LDA $0D9B : BNE - LDA #$FF : STA $2100 ;f-blank the scanline STZ $420C ;disable HDMA STZ $420B ;disable DMA LDA #$5A : AND #$FC : STA $2109 ;layer 3 tilemap location & size STZ $2111 ;static layer 3 STZ $2111 LDA #$08-1 : STA $2112 ;Fix a layer 3 STZ $2112 LDA #$14 : STA $212C ;layer 3 & sprites on mainscreen AND #$10 : STA $212E ;no window for layer 3 STZ $2121 REP #$20 LDA #$8070 : STA $2102 ;FirstSprite = x38 (item box item) LDA #$808C ASL : INC A : STA $2126 STZ $2130 ;disable subscreen & color math LDY #$02 LDA #$2700 : STA $4310 LDA.w #.HDMAtable STA $4312 STA $4318 LDX.b #.HDMAtable>>16 STX $4314 LDX #$01 : STX $431A STX $2105 ;gfx mode 1 (layer 3 standard priority) STY $420C INY : STY $2125 ;inverted clipping window for sprites SEP #$20 LDA #$03 CMP !vwfmode BCS + LDA #$FF STA $2125 + BIT $4212 : BVC $FB ;wait for h-blank again LDA $0DAE : STA $2100 ;restore brightness JML $0083B2 .HDMAtable db $07,$00 db $0E,$26 db $01,$00 db $00 PreStatusBar: LDA $0D9B ORA !vwfmode BNE + LDA $22 : STA $2111 LDA $23 : STA $2111 LDA $24 : STA $2112 LDA $25 : STA $2112 LDA $3E : STA $2105 LDA $40 : STA $2131 ;color math LDA #$53 : STA $2109 ;layer 3 tilemap location STZ $2121 : STZ $4314 LDA $0703 : STA $2122 LDA $0704 : STA $2122 REP #$20 LDA $0D9D : STA $212C : STA $212E LDA #$0907 : STA $4312 LDA #$001E : STA $4315 LDA #$2202 : STA $4310 SEP #$20 STA $420B JML $0082B0 + lda !vwfmode bne .SpecialNMI stz $2111 stz $2111 stz $2112 stz $2112 JML $0082B0 .SpecialNMI REP #$20 LDA $0D9D : STA $212C : STA $212E sep #$20 stz $2111 stz $2111 stz $2112 stz $2112 JML $0082B0 .NMITable db $00,$00,$00,$01,$01 db $01,$01,$01,$01,$01 db $01,$01,$01,$00,$00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Tables for tiles. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA_TILES: ;\This is the data for the tiles not regularly uploaded by SMW db $FC,$38 ;|First number is the tile number, second is the properties db $FC,$38 ;|YXPCCCTT db $FC,$38 ;|Y = y flip, X = flip, P = priority, CCC = palette number (4 color palettes remember) db $FC,$38 ;|TT = page number db $FC,$38 ;|Ex: $38 = 00111000 db $FC,$38 ;|priority bit set, palette 7 (of 8) db $FC,$38 ;|FC is a blank tile with SMW's original l3 graphics db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;|This whole block is the top row of status bar tile space. db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;/ DATA_TILES2: ;\Start of second line, the first 14 8x8 spaces on second row db $FC,$38 ;|seen on ASSB map.png. db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;/ ; ; Item box would be here. Already DMA'd in SMW's regular code ; Not included here for compatibility with the status bar editor tool ; DATA_TILES3: db $FC,$38 ;\End of second line, The last 14 8x8 spaces (the right 14) db $FC,$38 ;|on the second row seen on ASSB_map.png. db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;/ DATA_TILES4: ; two tiles at the upper middle left db $FC,$38 ;\Third line, the first two 8x8 spaces (two tiles left from the NAME text). db $FC,$38 ;/ DATA_TILES5: ; two tiles at the upper middle right db $FC,$38 ;\Third line, the last two 8x8 spaces (two tiles right from the coin counter db $FC,$38 ;/(not the coin and "X" symbol)). DATA_TILES6: ; three tiles at the lower middle left db $FC,$38 ;\Fourth line, the first 3 8x8 spaces before the "X" symbol and lives counter. db $FC,$38 ;| db $FC,$38 ;/ DATA_TILES7: ; two tiles at the lower middle right db $FC,$38 ;\Fourth line, the last two 8x8 spaces after the last 0 on the score counter. db $FC,$38 ;/ DATA_TILES8: ; bottom row db $FC,$38 ;\Fifth line, the first 14 8x8 spaces. db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;/ ; ; Item box would be here. Already DMA'd in SMW's regular code ; Not included here for compatibility with the status bar editor tool ; DATA_TILES9: db $FC,$38 ;\Fifth line, the last 14 8x8 spaces. db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;| db $FC,$38 ;/ DMA_BAR: db $01,$18,!RAM_BAR,!RAM_BAR>>8,!RAM_BAR>>16,$40,$01 ;^ ">>X", where x is how many times the number is divided by 2, so that it converts ;the freeram into DMA table bytes. if !Enable_COINS == 1 ;enable coin animation CoinFlip: db $2E,$69,$6A,$6B endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Main code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ZeroDec: REP #$20 LDA #$0000 STA !RAM_DecCoins STA !RAM_DecCoins+2 SEP #$20 STZ $0100 STZ $0109 JML $00805B MAIN_2: ; Uploads tiles to ram and DMAs new tiles PHB PHK PLB PHY PHX PHB LDA #$00 ; set bank to 00 PHA PLB REP #$10 ; 16 bit X Y LDY #$0007 ; LDX #$0063 ; Upload status bar tiles to ram UPLOAD_STATBAR1: ; LDA $8C81,y ; Top of item box STA !RAM_BAR,X ; DEX DEY BPL UPLOAD_STATBAR1 LDY #$0037 ; top middle of status bar LDX #$00BB UPLOAD_STATBAR2: LDA $8C89,Y STA !RAM_BAR,X DEX DEY BPL UPLOAD_STATBAR2 LDY #$0035 ; low middle of status bar LDX #$00FB UPLOAD_STATBAR3: LDA $8CC1,Y STA !RAM_BAR,X DEX DEY BPL UPLOAD_STATBAR3 LDY #$0007 ; bottom of item box LDX #$0123 UPLOAD_STATBAR4: LDA $8CF7,Y STA !RAM_BAR,X DEX DEY BPL UPLOAD_STATBAR4 PLB ; reset bank LDY #$005B ; get tiles from here and store to RAM LDX #$005B UPLOAD_STATBAR5: LDA DATA_TILES,Y STA !RAM_BAR,x DEX DEY BPL UPLOAD_STATBAR5 LDY #$001F LDX #$0083 UPLOAD_STATBAR6: LDA DATA_TILES3,Y STA !RAM_BAR,x DEX DEY BPL UPLOAD_STATBAR6 LDY #$0009 LDX #$00C5 UPLOAD_STATBAR7: LDA DATA_TILES5,Y STA !RAM_BAR,x DEX DEY BPL UPLOAD_STATBAR7 LDY #$001F LDX #$011B UPLOAD_STATBAR8: LDA DATA_TILES7,Y STA !RAM_BAR,x DEX DEY BPL UPLOAD_STATBAR8 LDY #$001B LDX #$013F UPLOAD_STATBAR9: LDA DATA_TILES9,Y STA !RAM_BAR,x DEX DEY BPL UPLOAD_STATBAR9 LDA #!TIME_SPEED ; Recover old code STA $0F30+!Base2 ; #$28 -> Timer frame counter DMA_STATBAR: SEP #$10 ; 8 bit X Y LDA #$80 STA $2115 LDA #$00 ;| STA $2116 ;| Set Address for VRAM Read/Write to x5322 LDA #$5B ;| Address for VRAM Read/Write (Low Byte) STA $2117 ;| LDX #$06 ;\ $06 bytes - LDA DMA_BAR,X ;| Get data from table STA $4310,X ;| Store to DMA registers DEX ;| Decrease X BPL - ;/ Loop code LDA #$02 ;\ Activate DMA channel 1 STA $420B ;| Regular DMA Channel Enable PLX PLY PLB JML $008D8F MAIN: PHB PHY PHX ; wrapper thingy PHK PLB ;------------------------------------------------------------------- ;this code below adds the red timer and/or beeping warning. if !timer_warning == 1 LDA $0F31+!Base2 ;\If all digits = 0, then no warning ORA $0F32+!Base2 ;|(so its safe to use in a level with no time ORA $0F33+!Base2 ;|limit). BEQ no_red_timer ;/ LDA $0F31+!Base2 ;\If timer >= 100, then use defualt color BNE no_red_timer ;/ LDA $0F32+!Base2 ;\If timer >= 10 then no warning sound BNE no_warning_sound ;/ LDA $0F30+!Base2 ;\If frame counter <> max then don't play 10 second warning CMP #!TIME_SPEED ;| BNE no_warning_sound ;/ LDA #$23 ;\play sound each time the timer has 1 smw second subtracted STA $1DFC+!Base2 ;/ no_warning_sound: LDA.b #%00101100 ;".b" so asar reconizes as its a byte; this is the color if < 100 BRA store_prop no_red_timer: LDA.b #%00111100 ;>color for >= 100 store_prop: STA !RAM_BAR+!TIME_OFFSET+1 ;\digits STA !RAM_BAR+!TIME_OFFSET+3 ;| STA !RAM_BAR+!TIME_OFFSET+5 ;/ STA !RAM_BAR+$A7 ;\the word "TIME". STA !RAM_BAR+$A9 ;| STA !RAM_BAR+$AB ;/ endif ;------------------------------------------------------------------- ; If you would like to add any subroutines that are run every frame the status bar is, ; feel free to stick them right here. However this runs during v-blank; HDMA AND TOP OF ; THE SCREEN WILL GLITCH OUT IF YOU PUT TOO MUCH CODES HERE! I don't know how much is ; the limit that will glitch, if you are too concern, use uberasm (but disable the ; status bar hijack first) and write HUD using gamemode 13 and 14. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Graphical Layer 3 air meter, by GreenHammerBro. ; ;Unlike 0x400's (aka. 1024)'s air meter, this one isn't blocky, the smallest ;amount of fill unit is a pixel, not 8x8 tile at a time. Just like my ;graphical hp meter. ; ;Each pixel equals to 1 air point. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Freeram: !Freeram_AirPoints = $5C ;>1 byte. !Freeram_Init = $58 ;>1 byte, must clear on level load. !Freeram_HideTmr = $62 ;>1 byte ;Length of the bar (how many 8x8 tiles, minus the extra 2 end tiles), IN DECIMAL. ;The longer, the more air points you have at max. If you change this, CTRL+F ;"bytes to HUD tiles" and add more if you increase and remove if you decrease. !Length = 5 ;What format the status bar are you using: ;*$01: 1 byte per 8x8 tile, for smw's status bar and other status bar patches ; using that format (like SMB3 status bar). ;*$02: if 2 bytes per 8x8 tile (using the super status bar patch). !StatusSize = $02 ;How low does the airpoints need to be to warn the player: !WarningLevel = $08 ;Warning SFX: !WarningSfxNum = $23 !WarningSfxRam = $1DFC ;8x8 fraction tiles: !val_tile0_8 = $68 ;0/8 (tile $FC = invisible tile.) !val_tile1_8 = $67 ;1/8 !val_tile2_8 = $66 ;2/8 !val_tile3_8 = $65 ;... !val_tile4_8 = $59 !val_tile5_8 = $58 !val_tile6_8 = $57 !val_tile7_8 = $56 !val_tile8_8 = $55 ;...8/8 (full tile) ;end tiles: !LeftEndTile = $38 !RightEndTile = $39 ;How fast airpoints gets deducted (when in water) or gained (after getting ;out of water), based on $7E0014. Only use these values (from fast to slow): ;$01, $03, $07, $0F, $1F, $3F, or $7F. !IncrementSpd = $01 !DecrementSpd = $0F ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;This section of code runs only once to start the meter full, must reset on ;level load ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Inital: LDA !Freeram_Init ;\If init already triggered, return BNE UpdateAirPoints ;/ INC ;\A smaller way of setting the freeram. STA !Freeram_Init ;/ LDA.b #!Length*8 ;\Start with full air points/pixels. STA !Freeram_AirPoints ;/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;This routine increments or decrements the air points when in water, the ;speed is based on the frame counter of $7E0014. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UpdateAirPoints: LDA $9D ;>or if freeze is set... ORA $71 ;>Add more ram that freezes the air meter. BNE .Return ;>...then return LDA $75 ;>If mario is out of water... ORA $85 ;>(this is because there is something that clears $75 every frame) BEQ .Increment ;>Then increment ;.Decrement LDA $14 ;\if certain bits are set for the frame counter... AND.b #!DecrementSpd ;/ BNE .Return LDA !Freeram_AirPoints BEQ .NoAirPointsLeft ;>Just in case if there is an underflow (like custom death animation). DEC A ;\If airpoints has been decremented to zero, BEQ .NoAirPointsLeft ;/kill the player. STA !Freeram_AirPoints ;>Store AirPoints -1 to AirPoints. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;I had to place the warning sounds here so it only plays ;during deduction of the air points. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LDA !Freeram_AirPoints ;\If player is low on air, play warning sounds. CMP.b #!WarningLevel ;| BCS .Return ;/ ;Warning LDA $14 ;\Play warning sounds certain frames AND #$1F ;| BNE .Return ;| LDA #!WarningSfxNum ;|\Feel free to change this to a different sfx. STA !WarningSfxRam ;// BRA DrawAirBar .NoAirPointsLeft LDA #$00 ;\so you can use long address STA !Freeram_AirPoints ;/ REP #$20 LDA !Health SEC SBC !Drown_dec_HP STA !Health BPL + STZ !Health + LDA $14 AND #$003F BNE + LDA !Drown_dec_HP CMP.w #15 BCS + INC !Drown_dec_HP + SEP #$20 BRA DrawAirBar ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Refill air points ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .Increment LDA $14 ;\if certain bits are set for the frame counter... AND.b #!IncrementSpd ;/ BNE .Return LDA !Freeram_AirPoints INC A ;\If increments past the maximum air points, CMP.b #!Length*8 ;|then cap it BCS .CapAirPoints ;/ STA !Freeram_AirPoints ;>Store AirPoints +1 to AirPoints. BRA DrawAirBar .CapAirPoints LDA.b #!Length*8 ;\Set air points to max STA !Freeram_AirPoints ;/ .Return ;^If you want to instantly refill after the player exits water (like in ;minecraft), simply remove the code between the sublabel ".Increment" ;and ".CapAirPoints". ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;draw meter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DrawAirBar: ;.HideTmrChk LDA !Freeram_AirPoints ;\If meter is full, set timer to hide it. CMP.b #!Length*8 ;| BCS .AboutToHideMeter ;/ LDA.b #60 ;\set timer to display bar while not 100% filled STA !Freeram_HideTmr ;/ BRA .CalculateIntoTiles ;>display bar. .AboutToHideMeter LDA !Freeram_HideTmr BEQ .InvisibleBar ;>Don't underflow. DEC A BNE .CalculateIntoTiles .InvisibleBar LDA #$00 ;\set timer to 0 just in case. STA !Freeram_HideTmr ;/ LDX.b #!Length-1 ;>I had to add .b becuase of a bug of xkas always assuming .l (a 3-byte value) when you have 2+ numbers. - LDA #$FC ;\Clear out the tiles with #$FC STA $00,x ;/ DEX BPL - STA !RAM_BAR+!AIR_T_OFFSET STA !RAM_BAR+!AIR_T_OFFSET+2 STA !RAM_BAR+!AIR_T_OFFSET+4 STA !RAM_BAR+!AIR_T_OFFSET+6 STA !RAM_BAR+!AIR_OFFSET ;>left end tile. STA !Length*2+!RAM_BAR+!AIR_OFFSET+2 ;>it should be (!RAM_BAR+!AIR_OFFSET+!Length*2)+2 in asar JMP .SkipTable .CalculateIntoTiles STA !Freeram_HideTmr ;>Store the decreased version of !Freeram_HideTmr into itself. LDA.b #!LeftEndTile ;\Left end tile. STA !RAM_BAR+!AIR_OFFSET ;/ LDA.b #!RightEndTile ;\Right end tile. STA !RAM_BAR+!AIR_OFFSET+(!StatusSize*!Length+2);/(+2 because of the left end AND middle tiles) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;draw bar (note that this is much faster than before, doesn't have to draw ;empty tile that is going to be replaced with a filled tile, making the ;routine that draws empty pointless). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Draw full 8x8 tiles: + LDA #$0A STA !RAM_BAR+!AIR_T_OFFSET LDA #$12 STA !RAM_BAR+!AIR_T_OFFSET+2 LDA #$1B STA !RAM_BAR+!AIR_T_OFFSET+4 LDA #$78 STA !RAM_BAR+!AIR_T_OFFSET+6 LDA !Freeram_AirPoints ;>How much fill in bar (in pixels; each 8x8 tile's maximum is 8). LSR #$03 ;>amount of fill divide by 8 (rounded down), being how many full 8x8 tiles. CMP.b #!Length ;\Prevent buffer overflow when number of full 8x8 BCC .NotFull ;/tiles takes !Length amount of bytes. ;.Full LDA.b #!Length ;>Load the maximum 8x8s in the fillable space. JSR WriteFull8x8s ;>Write full 8x8s on ALL fillable space. BRA .NoEmptyTile ;>And skip the fraction tile and 0/8 tile drawing routine. .NotFull JSR WriteFull8x8s .FractionTile ;Write fraction tile: LDA !Freeram_AirPoints ;\Modulo 8 for tile tables. AND #$07 ;/ TAY ;>Transfer fraction tiles to X LDA fraction_tiles,y ;>Load fraction tiles (loops within 0-7) STA $00,x ;>Store on position depending on amount of full 8x8 tiles ;Write empty tiles after fraction: INX ;>the first empty tile after the fraction tile. CPX #!Length ;\If empty about to be located past the last fillable 8x8, BCS .NoEmptyTile ;/don't write empty on +1 extra index. - LDA #!val_tile0_8 ;\write empty tiles after the fraction tile. STA $00,x ;| INX ;| CPX.b #!Length ;/ BCC - .NoEmptyTile ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Convert the bytes to HUD tiles. ; ;Here is a template: ; LDA $XXXX ;>scratch ram, tile data stored, increments by 1 each new tile. ; STA !StatusSize*X+!RAM_BAR+!AIR_OFFSET ;the X increments up by 1 each new tile. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .SkipTable LDA $00 ;\Middle tiles, where the fillable region is. STA !StatusSize*1+!RAM_BAR+!AIR_OFFSET ;| LDA $01 ;| STA !StatusSize*2+!RAM_BAR+!AIR_OFFSET ;| LDA $02 ;| STA !StatusSize*3+!RAM_BAR+!AIR_OFFSET ;| LDA $03 ;| STA !StatusSize*4+!RAM_BAR+!AIR_OFFSET ;| LDA $04 ;| STA !StatusSize*5+!RAM_BAR+!AIR_OFFSET ;/ JMP DMA_STATBAR ;>BUT DO NOT DELETE THIS LINE!! fraction_tiles: db !val_tile0_8,!val_tile1_8,!val_tile2_8,!val_tile3_8,!val_tile4_8,!val_tile5_8,!val_tile6_8,!val_tile7_8 ;Write full 8x8 tiles (placed before fraction) ;Both used when the bar is at least 8 pxls ;and if the bar is 100% filled. ;Input and output: Y=how many full 8x8 tiles. WriteFull8x8s: TAX ;>Transfer number of full 8x8s to X BEQ + ;>If there are no full 8x8 tile, skip. PHX ;>Save X since after the following loop, needs the X back. DEX ;>because index 0 exist (index value 0 is *AT* $7E0001). - LDA #!val_tile8_8 ;\write full tiles that is before STA $00,x ;/fraction tiles. DEX ;>Next index BPL - ;>if zero or positive, loop and repeat drawing full 8x8s PLX ;>Get number of full 8x8s back into Y + RTS DATA_008DF5: db $40,$41,$42,$43,$44 ;>luigi's name? DATA_008E06: db $B7 DATA_008E07: db $C3,$B8,$B9,$BA,$BB,$BA,$BF,$BC db $BD,$BE,$BF,$C0,$C3,$C1,$B9,$C2 db $C4,$B7,$C5 MAIN_3: PHB PHK PLB ; wrapper ; Basically copy/pasted code from all.log ; modified to use new RAM addresses CODE_008E1A: LDA $1493+!Base2 ;\If level is ending or sprites are locked, CODE_008E1D: ORA $9D ;|branch to $8E6F CODE_008E1F: BNE CODE_008E6F_OR_008E95 CODE_008E21: LDA $0D9B+!Base2 ;\If gamemode trigger = "Bowser's battle mode" CODE_008E24: CMP #$C1 ;|branch to $8E6F CODE_008E26: BEQ CODE_008E6F_OR_008E95 ;/ if !Enable_TIME == 1 ;>begin timer routine. CODE_008E28: DEC $0F30+!Base2 ;\If timer frame counter-1 is positive (-1 is in between #$00-#$7F?) CODE_008E2B: BPL CODE_008E6F ;/branch to $8E6F CODE_008E2D: LDA #!TIME_SPEED ;\Another timer frame counter? CODE_008E2F: STA $0F30+!Base2 ;/ CODE_008E32: LDA $0F31+!Base2 ;\ CODE_008E35: ORA $0F32+!Base2 ;|If time is 0, CODE_008E38: ORA $0F33+!Base2 ;|branch to $8E6F CODE_008E3B: BEQ CODE_008E6F ;/ CODE_008E3D: LDX #$02 ;\Check digits? CODE_008E3F: DEC $0F31+!Base2,X ;| CODE_008E42: BPL CODE_008E4C ;| CODE_008E44: LDA #$09 ;| CODE_008E46: STA $0F31+!Base2,X ;| CODE_008E49: DEX CODE_008E4A: BPL CODE_008E3F CODE_008E4C: LDA $0F31+!Base2 ;\ CODE_008E4F: BNE CODE_008E60 ;| CODE_008E51: LDA $0F32+!Base2 ;| CODE_008E54: AND $0F33+!Base2 ;|If time is 99, CODE_008E57: CMP #$09 ;|speed up the music CODE_008E59: BNE CODE_008E60 ;| CODE_008E5B: LDA #$FF ;| CODE_008E5D: STA $1DF9+!Base2 ;| CODE_008E60: LDA $0F31+!Base2 ;\ CODE_008E63: ORA $0F32+!Base2 ;| CODE_008E66: ORA $0F33+!Base2 ;|If time is 0, CODE_008E69: BNE CODE_008E6F ;|JSL to $00F606 CODE_008E6B: JSL $00F606 ;| if !Enable_TIME == 1 CODE_008E6F_OR_008E95: endif CODE_008E6F: LDA $0F31+!Base2 ;\Display timer (the number themselves) on HUD CODE_008E72: STA !RAM_BAR+!TIME_OFFSET ;| CODE_008E75: LDA $0F32+!Base2 ;| CODE_008E78: STA !RAM_BAR+!TIME_OFFSET+2 ;| CODE_008E7B: LDA $0F33+!Base2 ;| CODE_008E7E: STA !RAM_BAR+!TIME_OFFSET+4 ;/ CODE_008E81: LDX #$00 ;\Remove unnecessary digits place. CODE_008E83: LDY #$00 ;| CODE_008E85: LDA $0F31+!Base2,Y ;| CODE_008E88: BNE CODE_008E95_IF_THEN ;| CODE_008E8A: LDA #$FC ;| CODE_008E8C: STA !RAM_BAR+!TIME_OFFSET,X ;/ CODE_008E8F: INY CODE_008E90: INX INX CODE_008E91: CPY #$02 CODE_008E93: BNE CODE_008E85 endif ;>end of timer routine ;------------------------------------------------------------------ if !Enable_TIME != 1 ;>"if !define <> 1". CODE_008E6F_OR_008E95: endif CODE_008E95_IF_THEN: if !Enable_SCORE == 1 ;>begin score CODE_008E95: LDX #$03 CODE_008E97: LDA $0F36+!Base2,X CODE_008E9A: STA $00 CODE_008E9C: STZ $01 CODE_008E9E: REP #$20 ; 16 bit A ; Accum (16 bit) CODE_008EA0: LDA $0F34+!Base2,X CODE_008EA3: SEC CODE_008EA4: SBC #$423F CODE_008EA7: LDA $00 CODE_008EA9: SBC #$000F CODE_008EAC: BCC CODE_008EBF ADDR_008EAE: SEP #$20 ; 8 bit A ; Accum (8 bit) ADDR_008EB0: LDA #$0F ADDR_008EB2: STA $0F36+!Base2,X ADDR_008EB5: LDA #$42 ADDR_008EB7: STA $0F35+!Base2,X ADDR_008EBA: LDA #$3F ADDR_008EBC: STA $0F34+!Base2,X CODE_008EBF: SEP #$20 ; 8 bit A ; Accum (8 bit) CODE_008EC1: DEX CODE_008EC2: DEX CODE_008EC3: DEX CODE_008EC4: BPL CODE_008E97 ;>loop CODE_008EC6: LDA $0F36+!Base2 ;\ Store high byte of Mario's score in $00 CODE_008EC9: STA $00 ;/ CODE_008ECB: STZ $01 ;>Store x00 in $01 CODE_008ECD: LDA $0F35+!Base2 ;\ Store mid byte of Mario's score in $03 CODE_008ED0: STA $03 ;/ CODE_008ED2: LDA $0F34+!Base2 ;\ Store low byte of Mario's score in $02 CODE_008ED5: STA $02 ;/ CODE_008ED7: LDX #$00 CODE_008ED9: LDY #$00 CODE_008EDB: JSR CODE_009012 LDX #$00 if !ShowZeroes - CPX #$06 BEQ BlankAtStart LDA #$00 STA !RAM_BAR-4+!COINS_OFFSET,x INX INX CPX #$0C BNE - BRA DontStoreZero BlankAtStart: LDA #$FC STA !RAM_BAR-4+!COINS_OFFSET,x else LDA #$FC ; hijacked routine STA !RAM_BAR-4+!COINS_OFFSET,x endif DontStoreZero: CODE_008EDE: LDX #$00 ;\ CODE_008EE0: LDA !RAM_BAR+!SCORE_OFFSET,X ;| CODE_008EE3: BNE CODE_008EEF ;| LDA #$FC ;|Replace all leading zeroes in the score with spaces STA !RAM_BAR+!SCORE_OFFSET,X ;| CODE_008EEA: INX ;| INX CODE_008EEB: CPX #$0C ;| CODE_008EED: BNE CODE_008EE0 ;| >loop CODE_008EEF: LDA $0DB3+!Base2 ; Get current player CODE_008EF2: BEQ CODE_008F1D_IF_THEN ; If player is Mario, branch to $8F1D CODE_008EF4: LDA $0F39+!Base2 ;\ Store high byte of Luigi's score in $00 CODE_008EF7: STA $00 ;/ CODE_008EF9: STZ $01 ; Store x00 in $01 CODE_008EFB: LDA $0F38+!Base2 ;\ Store mid byte of Luigi's score in $03 CODE_008EFE: STA $03 ;/ CODE_008F00: LDA $0F37+!Base2 ;\ Store low byte of Luigi's score in $02 CODE_008F03: STA $02 ;/ CODE_008F05: LDX #$00 CODE_008F07: LDY #$00 if !Enable_SCORE == 1 ;\Somehow asar is complaining me that the subroutine CODE_008F09: JSR CODE_009012 ;|still exist (and assume its not found) even though endif ;/the user disables the bonus stars... very odd. CODE_008F0C: LDX #$00 ;\ CODE_008F0E: LDA !RAM_BAR+!SCORE_OFFSET,X ;| CODE_008F11: BNE CODE_008F1D_IF_THEN ;| CODE_008F13: LDA #$FC ;|Replace all leading zeroes in the score with spaces CODE_008F15: STA !RAM_BAR+!SCORE_OFFSET,X ;| CODE_008F18: INX ;| INX CODE_008F19: CPX #$0C ;| CODE_008F1B: BNE CODE_008F0E ;/>loop endif ;>end score. ;-------------------------------------------------------------------- CODE_008F1D_IF_THEN: if !Enable_COINS == 1 ;begin coin routine. LDA $71 ; This routine sets a small 8x8 animation CMP #$09 ; on the Coin item. BEQ CODE_008F1D ; LDA $14 ; LSR A ; LSR A ; LSR A ; AND #$03 ; TAX ; LDA.w CoinFlip,x ; STA !RAM_BAR-8+!COINS_OFFSET ; CODE_008F1D: LDA !RAM_DecCoins BEQ EndDec LDA !RAM_DecCoins+1 ORA !RAM_DecCoins+2 BEQ EndDec REP #$20 LDA !RAM_DecCoins DEC A STA !RAM_DecCoins SEP #$20 LDA !RAM_DecCoins+1 DEC A STA !RAM_DecCoins+1 LDA #$FF CMP !RAM_DecCoins+1 BNE EndDec LDA !RAM_DecCoins+2 DEC A STA !RAM_DecCoins+2 EndDec: LDA $13CC BEQ EndInc IncCoins: DEC $13CC REP #$20 LDA !RAM_DecCoins+1 CMP #$270F BCC NotMax LDA #$270F STA !RAM_DecCoins+1 SEP #$20 BRA EndInc NotMax: SEP #$20 LDA !RAM_DecCoins+1 INC A ; !RAM_DecCoins+1 = Lowest 256 values. STA !RAM_DecCoins+1 BNE EndInc LDA !RAM_DecCoins+2 INC A ; !RAM_DecCoins+2 = Lowest 65536 values. STA !RAM_DecCoins+2 EndInc: endif ;>end of coins routine. CODE_008F3B_IF_THEN: ;Poison/heal effect: LDA $9D ;\Freeze time check. ORA $13D4+!Base2 ;| BNE + ;/ LDA $14 AND #$07 BNE + REP #$20 LDA !Health ;\If Health is Zero... BEQ DeathIfHPZero ;/Don't bother calculating rest LDA !DeltaHP ;\In case at least one of the above checks are at least 1 BEQ + ;/would ignore this. BMI ++ ;>drain HP ;incrementHP: ;\Decrement to zero so it stops DEC !DeltaHP ;/incrementing HP (slowly clear flag) LDA !Health ;\Increment HP INC A ;/ CMP !MaxHealth ;\If incremented HP is maxed, then set to max. BCS +++ ;/ STA !Health ;>store incremented HP. JMP + ;drainHP: ++ LDA !DeltaHP ;\Increment to zero so it stops INC A ;|draining HP (slowly clear the flag). STA !DeltaHP ;/ LDA !Health ;\decrease HP and check DEC A ;/ CMP #$0001 ;\If HP decrement to 0, then death BMI ++ ;/ STA !Health ;>drain HP JMP + DeathIfHPZero: ++ LDY $1490+!Base2 ;\If player has star power, then BNE ++++ ;/Player's HP is 1. STZ !Health ; SEP #$20 LDA $71 ;\Don't replay death CMP #$09 ;| BEQ + ;/ JSL $00F60A ;>death BRA + ;>in case you don't have to replace every RTS with a JMP/BRA. ++++ LDA #$0001 STA !Health STZ !DeltaHP BRA + ;capHP: +++ LDA !MaxHealth ;\no healing past maximum STA !Health ;| STZ !DeltaHP ;/ + REP #$20 LDA !Health CMP #$03E8 ;\ Checks, if a value is lower then $03E8 (=1000) BCC + ; | LDA #$03E7 ;/ + JSR HexDec16 SEP #$20 STX $04 ;>Ones STY $02 ;>Tens JSR HexToDec ;>convert the hundreds digit after 99 STA $00 ;>Hundreds REP #$20 LDA !Health CMP #$000A ;\show only ones place if HP < 10 BCC + ;/ CMP #$0064 ;\show only ones and tens if HP >= 10 and < 99 BCC ++ ;/ SEP #$20 BRA +++ + SEP #$20 : LDA #$FC : STA $00 : STA $02 : BRA +++ ;>hide hundreds and tens ++ SEP #$20 : LDA #$FC : STA $00 ;>hide hundreds only +++ LDA $00 : STA !RAM_BAR+!HP_OFFSET ;>write hundreds place. LDA $02 : STA !RAM_BAR+!HP_OFFSET+2 ;>write tens place. LDA $04 : STA !RAM_BAR+!HP_OFFSET+4 ;>write ones place. REP #$20 LDA !MaxHealth CMP #$03E8 ;\ Checks, if a value is lower then $03E8 (=1000) BCC + ; | LDA #$03E7 ;/ + JSR HexDec16 SEP #$20 STX $04 ;>Ones STY $02 ;>Tens JSR HexToDec ;>convert the hundreds digit after 99 STA $00 ;>Hundreds REP #$20 LDA !MaxHealth CMP #$000A ;\show only ones place if HP < 10 BCC + ;/ CMP #$0064 ;\show only ones and tens if HP >= 10 and < 99 BCC ++ ;/ SEP #$20 BRA +++ + SEP #$20 : LDA #$FC : STA $00 : STA $02 : BRA +++ ;>hide hundreds and tens ++ SEP #$20 : LDA #$FC : STA $00 ;>hide hundreds only +++ LDA $00 : STA !RAM_BAR+!HP_OFFSET+$8 ;>write hundreds place. LDA $02 : STA !RAM_BAR+!HP_OFFSET+$A ;>write tens place. LDA $04 : STA !RAM_BAR+!HP_OFFSET+$C ;>write ones place. REP #$20 LDA !MP CMP #$03E8 ;\ Checks, if a value is lower then $03E8 (=1000) BCC + ; | LDA #$03E7 ;/ + JSR HexDec16 SEP #$20 STX $04 ;>Ones STY $02 ;>Tens JSR HexToDec ;>convert the hundreds digit after 99 STA $00 ;>Hundreds REP #$20 LDA !MP CMP #$000A ;\show only ones place if PP < 10 BCC + ;/ CMP #$0064 ;\show only ones and tens if PP >= 10 and < 99 BCC ++ ;/ SEP #$20 BRA +++ + SEP #$20 : LDA #$FC : STA $00 : STA $02 : BRA +++ ;>hide hundreds and tens ++ SEP #$20 : LDA #$FC : STA $00 ;>hide hundreds only +++ LDA $00 : STA !RAM_BAR+!PP_OFFSET ;>write hundreds place. LDA $02 : STA !RAM_BAR+!PP_OFFSET+2 ;>write tens place. LDA $04 : STA !RAM_BAR+!PP_OFFSET+4 ;>write ones place. REP #$20 LDA !MaxMP CMP #$03E8 ;\ Checks, if a value is lower then $03E8 (=1000) BCC + ; | LDA #$03E7 ;/ + JSR HexDec16 SEP #$20 STX $04 ;>Ones STY $02 ;>Tens JSR HexToDec ;>convert the hundreds digit after 99 STA $00 ;>Hundreds REP #$20 LDA !MaxMP CMP #$000A ;\show only ones place if PP < 10 BCC + ;/ CMP #$0064 ;\show only ones and tens if PP >= 10 and < 99 BCC ++ ;/ SEP #$20 BRA +++ + SEP #$20 : LDA #$FC : STA $00 : STA $02 : BRA +++ ;>hide hundreds and tens ++ SEP #$20 : LDA #$FC : STA $00 ;>hide hundreds only +++ LDA $00 : STA !RAM_BAR+!PP_OFFSET+$8 ;>write hundreds place. LDA $02 : STA !RAM_BAR+!PP_OFFSET+$A ;>write tens place. LDA $04 : STA !RAM_BAR+!PP_OFFSET+$C ;>write ones place. CheckIfBowser: LDA $0D9B ;\ CMP #$C1 ; | BNE NoBowser ; | STZ $0DC2 ; | STZ $0DBC ; | BRA CODE_008F73_IF_THEN ; | Remove Mario head in Special Battles NoBowser: ; | LDA $0109 ; | BNE CODE_008F73_IF_THEN ; | LDA #$01 ; | STA $0DC2 ; | STA $0DBC ;/ if !Enable_LIVES == 1 ;>begin lives CODE_008F3B: LDA $0DBE+!Base2 ;\ If amount of lives is negative, CODE_008F3E: BMI CODE_008F49 ;/ branch to $8F49 CODE_008F40: CMP #$62 ;\ If amount of lives is less than 98, CODE_008F42: BCC CODE_008F49 ;/ branch to $8F49 CODE_008F44: LDA #$62 ;\ Set amount of lives to 98 CODE_008F46: STA $0DBE+!Base2 ;\ CODE_008F49: LDA $0DBE+!Base2 ;\ CODE_008F4C: INC A ;|Get amount of lives in decimal CODE_008F4D: JSR HexToDec ;/ CODE_008F58: STA !RAM_BAR+!LIVES_OFFSET+2 ;/ CODE_008F50: TXA ;\ CODE_008F51: BNE CODE_008F55 ;|If 10s is 0, replace with space CODE_008F53: LDA #$FC ;| CODE_008F55: STA !RAM_BAR+!LIVES_OFFSET ;> Write lives to status bar. endif ;>end of lives if !Enable_STARS == 1 ;>begin bonus stars CODE_008F5B: LDX $0DB3+!Base2 ;\ Get bonus stars CODE_008F5E: LDA $0F48+!Base2,X ;/ CODE_008F61: CMP #$64 ;\ If bonus stars is less than 100, CODE_008F63: BCC CODE_008F73_IF_THEN ;/ branch to $8F73 CODE_008F65: LDA #$FF ;\ Start bonus game when the level ends CODE_008F67: STA $1425+!Base2 ;/ CODE_008F6A: LDA $0F48+!Base2,X ;\ CODE_008F6D: SEC ;|Subtract bonus stars by 100 CODE_008F6E: SBC #$64 ;| CODE_008F70: STA $0F48+!Base2,X ;/ endif ;end bonus stars CODE_008F73_IF_THEN: if !Enable_COINS == 1 ;>begin coins 2 REP #$20 LDA !RAM_DecCoins+1 ;\ Get amount of coins in decimal JSR HexDec16 ;/ SEP #$20 STX $04 ;>Ones STY $02 ;>Tens JSR HexToDec ;>convert the hundreds digit after 99 STA $00 ;>Hundreds STX $06 ;>Thousands if !ShowZeroes != 1 REP #$20 LDA !RAM_DecCoins+1 CMP #$000A ;\show only ones place if Coins < 10 BCC + ;/ CMP #$0064 ;\show only ones and tens if Coins >= 10 and < 99 BCC ++ ;/ CMP #$03E8 ;\show only ones and tens and thousands if Coins >= 100 and < 999 BCC +++ ;/ SEP #$20 BRA ++++ + SEP #$20 : LDA #$FC : STA $00 : STA $02 : STA $06 : BRA ++++ ;>hide hundreds and tens and thousands ++ SEP #$20 : LDA #$FC : STA $00 : STA $06 : BRA ++++ ;>hide hundreds and thousands +++ SEP #$20 : LDA #$FC : STA $06 ;>hide thousands only ++++ endif LDA $06 : STA !RAM_BAR+!COINS_OFFSET-4 ;>write thousands place. LDA $00 : STA !RAM_BAR+!COINS_OFFSET-2 ;>write hundreds place. LDA $02 : STA !RAM_BAR+!COINS_OFFSET ;>write tens place. LDA $04 : STA !RAM_BAR+!COINS_OFFSET+2 ;>write ones place. endif ;>end of coin routine 2 CODE_008F84: SEP #$20 ; 8 bit A ; Accum (8 bit) if !Enable_STARS == 1 ;>begin bonus stars 2 CODE_008F86: LDX $0DB3+!Base2 ; Load Character into X CODE_008F89: STZ $00 CODE_008F8B: STZ $01 CODE_008F8D: STZ $03 CODE_008F8F: LDA $0F48+!Base2,X CODE_008F92: STA $02 CODE_008F94: LDX #$00 CODE_008F96: LDY #$10 CODE_008F98: JSR CODE_009051 CODE_008F9B: LDX #$00 CODE_008F9D: LDA !RAM_BAR+!STARS_OFFSET,X CODE_008FA0: BNE CODE_008FAF CODE_008FA2: LDA #$FC CODE_008FA4: STA !RAM_BAR+!STARS_OFFSET,X CODE_008FA7: STA !RAM_BAR+!STARS_OFFSET-$40,X CODE_008FAA: INX INX CODE_008FAB: CPX #$02 CODE_008FAD: BNE CODE_008F9D CODE_008FAF: LDA !RAM_BAR+!STARS_OFFSET,X CODE_008FB2: ASL CODE_008FB3: TAY CODE_008FB4: LDA DATA_008E06,Y CODE_008FB7: STA !RAM_BAR+!STARS_OFFSET-$40,X CODE_008FBA: LDA DATA_008E07,Y CODE_008FBD: STA !RAM_BAR+!STARS_OFFSET,X CODE_008FC0: INX INX CODE_008FC1: CPX #$04 CODE_008FC3: BNE CODE_008FAF ;>loop endif ;>end bonus stars 2 LDA #$00 PHA PLB CODE_008FC5: JSL $009079 ; Draw item box item sprite PHK PLB if !Enable_NAME == 1 ;>begin name CODE_008FC8: LDA $0DB3+!Base2 CODE_008FCB: BEQ CODE_008FD8_IF_THEN CODE_008FCD: LDY #$04 LDX #$08 CODE_008FCF: LDA DATA_008DF5,Y ;>player name tiles CODE_008FD2: STA !RAM_BAR+!NAME_OFFSET,X CODE_008FD5: DEY DEX DEX CODE_008FD6: BPL CODE_008FCF ;>loop endif ;>end of name CODE_008FD8_IF_THEN: if !Enable_DRAGON == 1 CODE_008FD8: LDA $1422+!Base2 ;>yoshi coins CODE_008FDB: CMP #$05 CODE_008FDD: BCC CODE_008FE1 CODE_008FDF: LDA #$00 CODE_008FE1: DEC A CODE_008FE2: STA $00 CODE_008FE4: LDX #$00 CODE_008FE6: LDY #!TILE_EMPTY CODE_008FE8: LDA $00 CODE_008FEA: BMI CODE_008FEE CODE_008FEC: LDY #!TILE_FULL CODE_008FEE: TYA CODE_008FEF: STA !RAM_BAR+!DRAGON_OFFSET,X CODE_008FF2: DEC $00 CODE_008FF4: INX INX CODE_008FF5: CPX #$08 CODE_008FF7: BNE CODE_008FE6 endif ;>end of yoshi coins PLB JML $008FF9 ; return DATA_008FFA: db $01,$00 DATA_008FFC: db $A0,$86,$00,$00,$10,$27,$00,$00 db $E8,$03,$00,$00,$64,$00,$00,$00 db $0A,$00,$00,$00,$01,$00 if !Enable_SCORE == 1 ;>begin of score 2 CODE_009012: SEP #$20 ; 8 bit A ; Accum (8 bit) LDA #$00 CODE_009014: STA !RAM_BAR+!SCORE_OFFSET,X CODE_009017: REP #$20 ; 16 bit A ; Accum (16 bit) CODE_009019: LDA $02 CODE_00901B: SEC CODE_00901C: SBC DATA_008FFC,Y CODE_00901F: STA $06 CODE_009021: LDA $00 CODE_009023: SBC DATA_008FFA,Y CODE_009026: STA $04 CODE_009028: BCC CODE_009039 CODE_00902A: LDA $06 CODE_00902C: STA $02 CODE_00902E: LDA $04 CODE_009030: STA $00 CODE_009032: SEP #$20 ; 8 bit A ; Accum (8 bit) CODE_009034: LDA !RAM_BAR+!SCORE_OFFSET,X INC A STA !RAM_BAR+!SCORE_OFFSET,x CODE_009037: BRA CODE_009017 ;>loop CODE_009039: INX INX CODE_00903A: INY CODE_00903B: INY CODE_00903C: INY CODE_00903D: INY CODE_00903E: CPY #$18 CODE_009040: BNE CODE_009012 ;>loop CODE_009042: SEP #$20 ; 8 bit A ; Accum (8 bit) Return009044: RTS endif ;end of score 2 ;-------------------------------------------------------------------------- HexToDec: LDX #$00 ;| CODE_009047: CMP #$0A ;| CODE_009049: BCC Return009050 ;|Sets A to 10s of original A CODE_00904B: SBC #$0A ;|Sets X to 1s of original A CODE_00904D: INX ;| CODE_00904E: BRA CODE_009047 ;|>loop Return009050: RTS HexDec16: STA $4204 ;\hexdec for ones and tens. LDY #$0A ;| STY $4206 ;| JSR .Waste24Cycles ;| LDX $4216 ;| LDA $4214 ;| STA $4204 ;| LDY #$0A ;| STY $4206 ;| JSR .Waste24Cycles ;| LDY $4216 ;| LDA $4214 ;| RTS ;| .Waste24Cycles ;|\waste cycles. JSR .Return ;|| .Return ;|| RTS ;// ;------------------------------------------- if !Enable_STARS == 1 ;>stars subroutine CODE_009051: SEP #$20 ; Accum (8 bit) LDA #$00 CODE_009053: STA !RAM_BAR+!STARS_OFFSET,X CODE_009056: REP #$20 ; Accum (16 bit) CODE_009058: LDA $02 CODE_00905A: SEC CODE_00905B: SBC DATA_008FFC,Y CODE_00905E: STA $06 CODE_009060: BCC CODE_00906D CODE_009062: LDA $06 CODE_009064: STA $02 CODE_009066: SEP #$20 ; Accum (8 bit) CODE_009068: LDA !RAM_BAR+!STARS_OFFSET,X INC A STA !RAM_BAR+!STARS_OFFSET,x CODE_00906B: BRA CODE_009056 ;>loop CODE_00906D: INX INX CODE_00906E: INY CODE_00906F: INY CODE_009070: INY CODE_009071: INY CODE_009072: CPY #$18 CODE_009074: BNE CODE_009051 ;>loop CODE_009076: SEP #$20 ; Accum (8 bit) Return009078: RTS endif ;>end of bonus stars StatusBarGFX: incbin smb3_status_gfx.bin