From cb245b853f2f0572a0dd2d2bb6e788c12e68e561 Mon Sep 17 00:00:00 2001 From: nn <53490794+nn357@users.noreply.github.com> Date: Mon, 9 Nov 2026 04:56:39 +0900 Subject: [PATCH 1/9] inital version addhelmet toggle, tidy up sprite code, found a bug in the old one where a cmp against 8D (which had already been masked) always failed but just so happened to fall thru into the correct code anyway. consolidate a few routines to save so much stack push/pulling consolidate the sprite enable / disable / pallets' into a single table. --- patches/rom_map/Bank 85.txt | 2 +- patches/src/map_area.asm | 403 +++++++----------- rust/maprando-web/src/seed.rs | 2 + .../seed/help/helmet_spawn_icon.html | 26 ++ .../templates/seed/help/save_icons.html | 2 +- .../templates/seed/map_appearance.html | 15 + rust/maprando/src/customize.rs | 6 + 7 files changed, 210 insertions(+), 246 deletions(-) create mode 100644 rust/maprando-web/templates/seed/help/helmet_spawn_icon.html diff --git a/patches/rom_map/Bank 85.txt b/patches/rom_map/Bank 85.txt index ff56a4d64e..24ca857513 100644 --- a/patches/rom_map/Bank 85.txt +++ b/patches/rom_map/Bank 85.txt @@ -20,6 +20,6 @@ ACA0 - ACFF: load_flash_suit AD00 - AD40: ; crash_handle_springball.asm AD43 - AEDB: ; reserve_backward_fill.asm AEE0 - B599: ; crash_handle_base.asm -B600 - B93E: ; map_area.asm +B600 - B8E5: ; map_area.asm C000 - C450: ; savestate.asm C500 - C900: ; pause_menu_objectives.asm diff --git a/patches/src/map_area.asm b/patches/src/map_area.asm index b1a9a63200..f092623546 100644 --- a/patches/src/map_area.asm +++ b/patches/src/map_area.asm @@ -1782,7 +1782,7 @@ assert pc() <= !bank_b6_freespace_end org !bank_85_freespace3_start assert pc() == !map_icon_settings -dw $0000 ; modified by customize.rs for toggling map tiles on / off. set bits high to disable tiles (bosses), (minibosses), (saves) +dw $0000 ; modified by customize.rs for toggling map tiles on / off. set bits high to disable tiles (bosses), (minibosses), (saves), (helmet) ; write map icons and save markers to VRAM @@ -1813,7 +1813,6 @@ write_sprites: LDA #$0060 STA $36 ; initialize dachora state/frame count -.no_animals PLY PLX PLB @@ -1828,16 +1827,11 @@ sprite_table: ; [$b6xxxx, vram addr] .. null-terminated hook_map_icons: PHP PHB - -; draw save slot markers - LDA !map_icon_settings ; test if draw saves disabled on generation? - BIT #$0004 - BNE .finished_drawing_saves LDX #$0000 .load_lp LDA $702602,X ; area AND #$00FF - CMP #$0006 ; valid area set? + CMP #$0006 ; valid area? BCS .next CMP $1F5B ; current area? BNE .next @@ -1845,134 +1839,112 @@ hook_map_icons: LDA $702603,X ; sprite PHX ; save slot index PHA ; save sprite ID -; adjust coords for scroll LDA $702604,X ; coords JSR convert_coord_to_map PLA ; sprite -; A=sprite, X/Y=adjusted coords - JSR draw_sprite + JSR draw_sprite ; handles save/helmet toggles itself PLX ; index - .next INX #4 CPX #$000C BNE .load_lp + .finished_drawing_saves ; draw ship/bosses/mini-bosses/animals if appropriate - LDX #$0000 PHK PLB - + LDY #$0000 ; Y = marker table index .marker_lp - LDA marker_table,X ; boss byte|bit or FFFF to skip check - BNE .valid_entry - JMP .exit - -; check boss bit -.valid_entry - PHX ; index + LDA marker_table,Y ; boss byte|bit, $FFFF = always shown, 0 = end + BEQ .exit CMP #$FFFF - BEQ .boss_alive + BEQ .marker_draw PHA - AND #$FF00 XBA - TAX + AND #$00FF + TAX ; X = byte offset into $7ED828 PLA + AND #$00FF ; A = bit mask + AND $7ED828,X ; boss defeated? + BEQ .marker_draw ; no, show the marker + CPY #((marker_table_2-marker_table)*2) ; mother brain? + BNE .marker_next ; other dead bosses just lose their marker - AND #$00FF - AND $7ED828,X ; boss bit set? - BEQ .boss_alive - PLA ; index - CMP #((marker_table_2-marker_table)*2) ; mother brain? - BEQ .check_animals - JMP .next_marker_2 - -.check_animals ; MB dead, skip to dachora table if animals enabled +; mother brain dead: skip the remaining markers, show the animals instead LDA $7ED821 AND #$0080 ; already saved? - BNE .no_dachora + BNE .exit + JSR animate_dachora + LDY #(marker_table_dachora-marker_table) + BRA .marker_lp + +.marker_draw + JSR draw_marker +.marker_next + TYA + CLC + ADC #(marker_table_2-marker_table) ; index++ + TAY + BRA .marker_lp -; determine which dachora state to show (blink animation) -; $36: frame count, $37 = state (00-02) +.exit + PLB + PLP + RTL + +animate_dachora: +; $36 = (blink state << 8) | frames left until the next change DEC $36 LDA $36 - AND #$00FF ; frames - BNE .no_change - LDA $36 - XBA - AND #$00FF ; state - INC - CMP #$0003 - BNE .no_wrap - LDA #$0060 ; ~1.5s - BRA .save_state -.no_wrap - XBA - EOR #$0004 ; 4-frame delay between states -.save_state - STA $36 - XBA AND #$00FF - ASL #5 ; state*20h + BNE .done ; still counting down + LDA $36 ; low byte is 0 here, so A = state<<8 CLC - ADC #dachora_icon_open ; A = dachora_icon + state*20h -; update VRAM based on state + ADC #$0100 ; next state + CMP #$0300 + BCC .short_delay + LDA #$0060 ; wrapped to state 0, ~1.5s + BRA .set +.short_delay + ORA #$0004 ; 4-frame delay between states +.set + STA $36 + AND #$FF00 ; state<<8 + LSR #3 ; state*20h + CLC + ADC #dachora_icon_open TAX LDA #$2980 - JSR write_to_vram + JMP write_to_vram ; tail call +.done + RTS -.no_change - LDX #(marker_table_dachora-marker_table) ; set index to dachora table - BRA .marker_lp ; restart loop with new index -.no_dachora - JMP .exit - -.boss_alive - PLX ; index - PHX - LDA marker_table+2,X ; state header - TAX +draw_marker: +; Y = marker table index (preserved) + PHY + LDX marker_table+2,Y ; state header LDA $8F0010,X TAX LDA $B80000,X ; area AND #$00FF CMP $1F5B ; current area? - BNE .next_marker - PLX ; index - PHX - LDA marker_table+4,X ; room header - PHX - TAX - LDA $8F0000,X ; x/y coords - PLX ; index + BNE .done + + LDX marker_table+4,Y ; room x/y coords + LDA $8F0000,X ; A = y:x tile coords PHA - AND #$FF00 - XBA - CPX #((marker_table_2-marker_table)*2) - BCS .not_ship_1 - CLC - ADC #$0004 ; landing site map y adjustment -.not_ship_1 - TAY - PLA - AND #$00FF - CPX #((marker_table_2-marker_table)*2) - BCS .not_ship_2 - CLC - ADC #$0004 ; landing site map x adjustment -.not_ship_2 - TAX + CPY #((marker_table_2-marker_table)*2) + BCS .not_ship + ADC #$0404 ; ships: +4 tiles x and y (carry is clear here) +.not_ship JSR check_partial_reveal - BCC .next_marker - PLX ; index - PHX - PHX - LDA marker_table+4,X ; room coords - TAX - LDA $8F0000,X - JSR convert_coord_to_map + PLA ; room coords (PLA doesn't touch carry) + BCC .done + + JSR convert_coord_to_map ; X,Y = pixel position TXA - PLX ; index + PLX ; peek the index + PHX CLC ADC marker_table+8,X ; sprite x adjustment PHA @@ -1981,20 +1953,11 @@ hook_map_icons: ADC marker_table+10,X ; sprite y adjustment TAY LDA marker_table+6,X ; sprite id - PLX + PLX ; adjusted x JSR draw_sprite -.next_marker - PLA ; index -.next_marker_2 - CLC - ADC #(marker_table_2-marker_table) ; index++ - TAX - JMP .marker_lp - -.exit - PLB - PLP - RTL +.done + PLY + RTS ; marker table format ; boss bit ($7ED828 byte | bit), state header address, room header coords, sprite id, x adjustment, y adjustment @@ -2021,171 +1984,123 @@ marker_table_dachora: dw $0000 convert_coord_to_map: -; A = coords (x,y) -; returns X,Y - TAX - AND #$00FF - ASL - ASL - ASL - SEC - SBC $B1 - PHA - TXA - PLX - AND #$FF00 +; A = coords (x low byte, y high byte) +; returns X,Y = pixel position relative to map scroll + TAX ; keep copy XBA - ASL - ASL - ASL + AND #$00FF ; y + ASL #3 SEC SBC $B3 TAY + TXA + AND #$00FF ; x + ASL #3 + SEC + SBC $B1 + TAX RTS write_to_vram: ; constant: size = 0x20, src bank = $b6 ; A = vram addr ; X = src addr - PHA - PHX +; queues a 7-byte entry at $D0+$0330: size, src addr, bank, vram addr + PHA ; vram addr + PHX ; src addr LDX $0330 LDA #$0020 - STA $D0,x - INX - INX + STA $D0,x ; size PLA - STA $D0,x - INX - INX + STA $D2,x ; src addr LDA #$00B6 - STA $D0,x - INX + STA $D4,x ; bank (spills $00 into +5) PLA - STA $D0,x - INX - INX - STX $0330 + STA $D5,x ; vram addr, overwrites the spill + TXA + CLC + ADC #$0007 + STA $0330 RTS check_partial_reveal: -; X = x map coord -; Y = y map coord -; result in carry flag - PHP +; A = packed tile coords (x low byte, y high byte) +; returns carry set if the tile is partially revealed + TAX ; keep y:x copy + XBA + AND #$00FF ; y + INC + ASL #2 ; (y+1)*4 + STA $12 TXA - AND #$00FF - PHA AND #$0020 - STA $22 - PLA - AND #$001F - STA $12 - AND #$0007 - PHA ; save bit subindex of tile - LDA $12 - LSR - LSR - LSR - STA $14 - TYA - AND #$00FF - INC - STA $16 + ASL #2 ; x >= 32 ? $80 : 0 (right half of map) CLC - ADC $22 - ASL - ASL + ADC $12 + STA $12 + TXA + AND #$0018 + LSR #3 ; byte column 0-3 CLC - ADC $14 - TAX - SEP #$20 + ADC $12 ; byte offset within area + STA $12 + TXA - XBA + AND #$0007 + TAX + LDA $90AC04,X ; bit mask for x&7 + AND #$00FF + STA $14 + LDA $1F5B - XBA + AND #$00FF + XBA ; area*$100 + ORA $12 TAX - LDA $702700,X ; partial revealed byte - PLX ; bit subindex of ship tile - AND $90AC04,X ; check bit - BEQ .not_revealed - PLP - SEC + LDA $702700,X ; partial revealed byte + AND $14 + CMP #$0001 ; carry = (A != 0) RTS -.not_revealed - PLP - CLC - RTS - draw_sprite: ; A=sprite, X/Y=coords - CPY #$0020 ; check if above top map border - BCC .sprite_is_disabled + CPY #$0020 ; above top map border? + BCC .return AND #$007F - BRA .check_sprites -.sprite_enabled - PHA ; sprite - CMP #$0008 - BEQ .save_icon - CMP #$000E - BEQ .save_icon - CMP #$000F - BEQ .save_icon - CMP #$0018 - BEQ .dachora - CMP #$008D - BEQ .helmet - CMP #$004F - BCS .dachora - -.helmet - LDA #$0E00 ; helmet/ship/boss palette - BRA .write -.dachora - LDA #$0800 ; dachora palette - BRA .write -.save_icon - LDA #$0400 ; save icon palette - -.write + PHA ; sprite id for the draw call + CMP #$004F ; fold $4F-$52 onto table slots $19-$1C + BCC .lookup + SBC #$0036 ; carry is already set +.lookup + PHX ; keep x coord + TAX + LDA.l sprite_props,X ; long, so it doesn't depend on DB + PLX + AND #$00FF + STA $03 ; scratch + AND #$000F ; this sprite's disable bit(s) + AND.l !map_icon_settings + BNE .skip + LDA $03 + AND #$00F0 + ASL #5 ; palette number -> OAM attr bits 9-11 STA $03 - PLA ; sprite + PLA ; sprite id JSL $81891F -.sprite_is_disabled +.return RTS - -.check_sprites - PHA - CMP #$0013 - BEQ .test_miniboss - CMP #$000A - BEQ .test_boss - CMP #$000B - BEQ .test_ship - CMP #$000C - BEQ .test_ship - BRA .sprite_not_disabled -.test_boss - LDA !map_icon_settings - AND #$0001 - BRA .finished_spritecheck -.test_miniboss - LDA !map_icon_settings - AND #$0002 - BRA .finished_spritecheck -.test_ship - LDA !map_icon_settings - AND #$0004 -.finished_spritecheck - BNE .sprite_disabled -.sprite_not_disabled +.skip PLA - BRA .sprite_enabled -.sprite_disabled - PLA - BRA .sprite_is_disabled - + RTS + +; (palette << 4) | disable mask in !map_icon_settings +; palettes: 2 = save icon, 4 = dachora, 7 = helmet/ship/boss (default) +sprite_props: + db $70,$70,$70,$70,$70,$70,$70,$70 ; 00-07 + db $24,$70,$71,$74,$74,$78,$24,$24 ; 08 save, 0A boss, 0B/0C ship, 0D helmet, 0E/0F save + db $70,$70,$70,$72,$70,$70,$70,$70 ; 10-17 (13 = miniboss) + db $40,$40,$40,$40,$40 ; 18 dachora, 19-1C = 4F-52 dachora arms +print pc assert pc() <= !bank_85_freespace3_end ; Fixes FX for rare bug when entering right-sided door through East Pants Room diff --git a/rust/maprando-web/src/seed.rs b/rust/maprando-web/src/seed.rs index b8dd906ed0..5dd4e9a2b3 100644 --- a/rust/maprando-web/src/seed.rs +++ b/rust/maprando-web/src/seed.rs @@ -182,6 +182,7 @@ struct CustomizeRequest { save_icons: Text, boss_icons: Text, miniboss_icons: Text, + helmet_spawn_icon: Text, room_names: Text, statues_hallway_tiling: Text, statues_hallway_audio: Text, @@ -373,6 +374,7 @@ async fn customize_seed( boss_icons: req.boss_icons.0, miniboss_icons: req.miniboss_icons.0, save_icons: req.save_icons.0, + helmet_spawn_icon: req.helmet_spawn_icon.0, statues_hallway_tiling: match req.statues_hallway_tiling.0.as_str() { "Disabled" => StatuesHallwayTiling::Disabled, "Default" => StatuesHallwayTiling::Default, diff --git a/rust/maprando-web/templates/seed/help/helmet_spawn_icon.html b/rust/maprando-web/templates/seed/help/helmet_spawn_icon.html new file mode 100644 index 0000000000..9d535db391 --- /dev/null +++ b/rust/maprando-web/templates/seed/help/helmet_spawn_icon.html @@ -0,0 +1,26 @@ + + + + \ No newline at end of file diff --git a/rust/maprando-web/templates/seed/help/save_icons.html b/rust/maprando-web/templates/seed/help/save_icons.html index b65d82a5df..44e5e5ead4 100644 --- a/rust/maprando-web/templates/seed/help/save_icons.html +++ b/rust/maprando-web/templates/seed/help/save_icons.html @@ -14,7 +14,7 @@

Save icons

This option affects how the pause menu map appears:

  • Enabled: The three most recently used save stations are shown, color coded as follows: yellow for the most recent save (same appearance as in the vanilla game), orange for the previous save, and pink for the next to be overwritten. Samus's spawn point is also shown as a helmet until three saves have been used. An icon is also drawn for the Ship, with the same appearance as in the vanilla game. -
  • Disabled: Icons are not drawn for saves, the spawn point, nor the Ship. +
  • Disabled: Icons are not drawn for saves or the Ship.

diff --git a/rust/maprando-web/templates/seed/map_appearance.html b/rust/maprando-web/templates/seed/map_appearance.html index f99bf19f61..a7686310d0 100644 --- a/rust/maprando-web/templates/seed/map_appearance.html +++ b/rust/maprando-web/templates/seed/map_appearance.html @@ -88,4 +88,19 @@ + + +
+
+ +
+
+ + + + +
\ No newline at end of file diff --git a/rust/maprando/src/customize.rs b/rust/maprando/src/customize.rs index 39dbe85140..6305ad4b49 100644 --- a/rust/maprando/src/customize.rs +++ b/rust/maprando/src/customize.rs @@ -183,6 +183,7 @@ pub struct CustomizeSettings { pub save_icons: bool, pub boss_icons: bool, pub miniboss_icons: bool, + pub helmet_spawn_icon: bool, pub reserve_hud_style: bool, pub vanilla_screw_attack_animation: bool, pub palette_theme: PaletteTheme, @@ -209,6 +210,7 @@ impl Default for CustomizeSettings { save_icons: true, boss_icons: true, miniboss_icons: true, + helmet_spawn_icon: true, reserve_hud_style: true, vanilla_screw_attack_animation: true, room_names: true, @@ -587,6 +589,10 @@ pub fn customize_rom( if !settings.save_icons { map_icon_settings |= 4; } + if !settings.helmet_spawn_icon { + map_icon_settings |= 8; + } + rom.write_u16(snes2pc(0x85B600), map_icon_settings)?; // Fix Phantoon power-on sequence to not overwrite the first two palettes, since those contain From b018b111db8f85ad3602fb07ed99967468e5404a Mon Sep 17 00:00:00 2001 From: nn <53490794+nn357@users.noreply.github.com> Date: Mon, 9 Nov 2026 10:19:49 +0900 Subject: [PATCH 2/9] Update map_area.ips --- patches/ips/map_area.ips | Bin 4576 -> 4486 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/patches/ips/map_area.ips b/patches/ips/map_area.ips index bbffbc2a3383e5db75430381a231830011872be7..ff409f6d5e0aa7e9af5bd7aa38f7281bdeac0fac 100644 GIT binary patch delta 458 zcmXw!J4nM&6o!x9h#2C7TIJ%>tF4a=K5z(bI>sufh>CW}A|$v}aS%ZphX_{GKq&|= zT?%b{BP4OKby4gf1W}OU;36n4nLAi-eEh>b|2dqG^WWFtX7KEQYp#3)*e=eE9Hszr zg6VRX119NCoO9EOhT1@^$(G5kU3#Z_<-mFT*}I&uT%k}dyB*>uUj{>_&tTW{y4!q> z!SSEAKCkmCIF01ROl^Yd5YF1i3I`eW=CEtwR!9pJa5~ZgR-mE)NUzFDprRTEG=Yb5 zI2^`G>dVNg{P1YEEzRX7t$YLQ8F>JklJ}8-)03OBXuBuUi)Tn-7&2nZIwnnayi~+% zvzEAz*CJNtYQ`$j53EXwVBJm3OUttCz}rP8{%_9>Ni3f9p)7%2y!?A4dYTepdNt+|Fpbzfb|vH37Y! zkBx&^7y})B2v9WgceYmY2*lSzFPNI+OC#R(^3hvJZVPN}NU{|DQz*K)yu1<$(RRrj M4SBkFsb?y`0fn}+O#lD@ delta 569 zcmX|8L1@!Z82;x=X`I1%ikrKRdLV9goxym=3E7Cc*bu;~y|;(OCsDNY zCVVY`2)#dZpPTGC=B@nuRPBWEtVwb<&{Y3;6`3-;^`=ujK1@5t3EW*p8sA|`RguBS z>xu-%qLK!+zgVqSjqCwy<&0%Hx>5^xD{Ist6&NXPp+{+?z;bX=GCm9w2pIP(uEDeIB| From e00d1e0a9eb58cb93e921f4d226be1826a8bb7ce Mon Sep 17 00:00:00 2001 From: nn <53490794+nn357@users.noreply.github.com> Date: Mon, 9 Nov 2026 10:26:15 +0900 Subject: [PATCH 3/9] update website text to match other style --- rust/maprando-web/templates/seed/map_appearance.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/maprando-web/templates/seed/map_appearance.html b/rust/maprando-web/templates/seed/map_appearance.html index a7686310d0..97b1921232 100644 --- a/rust/maprando-web/templates/seed/map_appearance.html +++ b/rust/maprando-web/templates/seed/map_appearance.html @@ -94,7 +94,7 @@
From 3922c9016b919237e9592a200a807671eb5b0faa Mon Sep 17 00:00:00 2001 From: nn <53490794+nn357@users.noreply.github.com> Date: Mon, 9 Nov 2026 10:39:43 +0900 Subject: [PATCH 4/9] Update helmet_spawn_icon.html --- rust/maprando-web/templates/seed/help/helmet_spawn_icon.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/maprando-web/templates/seed/help/helmet_spawn_icon.html b/rust/maprando-web/templates/seed/help/helmet_spawn_icon.html index 9d535db391..8e15e3d5d8 100644 --- a/rust/maprando-web/templates/seed/help/helmet_spawn_icon.html +++ b/rust/maprando-web/templates/seed/help/helmet_spawn_icon.html @@ -7,7 +7,7 @@