diff --git a/patches/ips/pause_menu_objectives.ips b/patches/ips/pause_menu_objectives.ips index dec655bff..5672335b7 100644 Binary files a/patches/ips/pause_menu_objectives.ips and b/patches/ips/pause_menu_objectives.ips differ diff --git a/patches/rom_map/Bank 85.txt b/patches/rom_map/Bank 85.txt index e7bf5015a..e3b2c9f91 100644 --- a/patches/rom_map/Bank 85.txt +++ b/patches/rom_map/Bank 85.txt @@ -22,3 +22,4 @@ AD43 - AEDB: ; reserve_backward_fill.asm AEE0 - B599: ; crash_handle_base.asm B600 - B93E: ; map_area.asm C000 - C450: ; savestate.asm +C500 - C700: ; pause_menu_objectives.asm diff --git a/patches/src/constants.asm b/patches/src/constants.asm index d5c357be6..4861e0807 100644 --- a/patches/src/constants.asm +++ b/patches/src/constants.asm @@ -47,6 +47,7 @@ !objectives_num = $82FFFC ; bits 0-15 !objectives_addrs = $8FEBC0 !objectives_bitmasks #= !objectives_addrs+(2*!objectives_max) +!objectives_tiles = $8FED00 ; range of item PLMs in bank 84 !item_plm_start = #$DF89 diff --git a/patches/src/pause_menu_objectives.asm b/patches/src/pause_menu_objectives.asm index 3c67e5b75..740f113f1 100644 --- a/patches/src/pause_menu_objectives.asm +++ b/patches/src/pause_menu_objectives.asm @@ -30,6 +30,9 @@ incsrc "constants.asm" !bank_85_free_space2_start = $85AA00 !bank_85_free_space2_end = $85AAA0 +!bank_85_free_space3_start = $85C500 +!bank_85_free_space3_end = $85C700 + !bank_B6_free_space_start = $B6F200 !bank_B6_free_space_end = $B6F660 @@ -274,7 +277,7 @@ draw_samus_indicator: rts print "82 end: ", PC -warnpc !bank_82_free_space_end +assert pc() <= !bank_82_free_space_end ;;; continue in bank 85 for obj screen management code org !bank_85_free_space_start @@ -334,65 +337,7 @@ pad_0: RTS check_objs: -;;; check objectives and add check marks - LDY.w #!line_size*2 ; start of 1st line - LDA !objectives_num : AND #$7FFF - STA !tmp_tile_offset ; # objectives - BEQ .exit - LDX #$0000 - -.obj_check_lp - PHX - JSR check_objective - BEQ .nocheck - - ; find the next check character and mark it green - TYX - JSR find_next_check - LDA #$250B ; check mark (green) - STA !BG1_tilemap, x - BRA .next - -.nocheck: - ; find the next check character and skip marking it - TYX ; X <- position in tilemap - JSR find_next_check - -.next: - INX : INX ; advance to next position in tilemap - TXY - PLX ; X <- objective number - INX - CPX !tmp_tile_offset - BNE .obj_check_lp -.exit - PLB - RTS - -check_objective: ; X = index - PHX - TXA - ASL - TAX - LDA.w #$007E - STA.b $02 - LDA.l !objectives_addrs, X - STA.b $00 - LDA.l !objectives_bitmasks, X - STA.b $04 - LDA.b [$00] - PLX - BIT.b $04 - RTS - -find_next_check: - LDA !BG1_tilemap, x - CMP !check_char ; tile to switch? - BEQ .found - INX : INX - BRA find_next_check -.found: - RTS + JMP check_objs_2 ;;; direct DMA of BG1 tilemap to VRAM blit_objs: @@ -744,6 +689,7 @@ func_map2obj_load_obj: STA $0723 ; Screen fade delay = 1 STA $0725 ; Screen fade counter = 1 INC !pause_index ; Pause index = B (map screen to objective screen - fading in) + %queueGfxDMA(obj_letters, $2800, $00C0) ; Color-coded area letters LDA !room_name_option BEQ .skip_name JSR fill_bottom_frame @@ -854,7 +800,7 @@ obj_bg1_tilemap: dw $280F, "OBJECTIVES", $280F print "85 end: ", pc -warnpc !bank_85_free_space_end +assert pc() <= !bank_85_free_space_end ;; routines for bottom frame screen swap / map switching org !bank_85_free_space2_start @@ -925,13 +871,212 @@ fix_palette: STA $7EC04A RTS -warnpc !bank_85_free_space2_end +assert pc() <= !bank_85_free_space2_end + +org !bank_85_free_space3_start +check_objs_2: +;;; check objectives and add check marks / area letters +;;; PHB is on stack + LDY.w #!line_size*2 ; start of 1st line + LDA !objectives_num : AND #$7FFF + BEQ .exit + STZ $16 ; obj index + +.obj_check_lp + LDX $16 + JSR objective_done + BEQ .check_if_seen +; find the next check character and mark it done + JSR find_next_check + LDA #$250B ; check mark + BRA .write_tile + +.check_if_seen + PHY ; tilemap ptr + LDA $16 + ASL + ASL + ASL + SEC + SBC $16 ; n*7, straight from the index + TAX ; obj tiles table ptr + CLC + LDA !objectives_tiles+5,X ; grid size to check + SEC + SBC #$0101 ; valid size? + BCC .skip_check + STA $1A ; grid x-1, y-1 + LDA !objectives_tiles,X ; room hdr + PHX + TAX + LDA $8F0002,X ; x, y origin + PLX + CLC + ADC !objectives_tiles+3,X ; add offset from top/left of room + STA $18 + LDA !objectives_tiles+2,X ; state hdr offset + AND #$00FF + CLC + ADC !objectives_tiles,X ; room hdr + TAX + LDA $8F0010,X + TAX + LDA $B80000,X ; area + AND #$00FF + STA $1E + JSR check_partial_reveal +.skip_check + PLY + JSR find_next_check ; carry preserved + BCC .next + LDA $1E ; area + CLC + ADC #$2A80 ; area letters (VRAM) +.write_tile + STA !BG1_tilemap,X + +.next: + INX : INX ; advance to next position in tilemap + TXY + INC $16 + LDA !objectives_num : AND #$7FFF + CMP $16 + BNE .obj_check_lp + +.exit + PLB + RTS + +objective_done: +; X = index + TXA + ASL + TAX + LDA.l !objectives_bitmasks,X + STA.b $04 + LDA.l !objectives_addrs,X + TAX + LDA.l $7e0000,X + BIT.b $04 + RTS + +find_next_check: +; Y = tilemap ptr + PHP + TYX +.next_lp + LDA !BG1_tilemap,X + CMP !check_char ; tile to switch? + BEQ .found + INX : INX + BRA .next_lp +.found: + PLP + RTS + +check_partial_reveal: +; $18 = origin x, y (already offset adjusted) +; $1A = grid size x-1, y-1 +; $1C = columns left +; $1D = rows left +; result in carry flag + PHP + LDA $1A + STA $1C + LDA $18 + PHA + AND #$FF00 + XBA + TAY + PLA + AND #$00FF + TAX +; X, Y = origin +.next + PHX ; save current x, y + PHY + 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 + CLC + ADC $22 + ASL + ASL + CLC + ADC $14 + TAX + SEP #$20 + TXA + XBA + LDA $1E ; area + XBA + TAX + LDA $702700,X ; partial revealed byte + PLX ; bit subindex of tile + AND $90AC04,X ; check bit + BEQ .not_revealed + PLY + PLX + PLP + SEC + RTS + +.not_revealed + LDA $1C + BEQ .x_done + PLY ; current x, y + PLX + DEC + STA $1C ; cols-- + INX + REP #$30 + BRA .next + +.x_done + LDA $1D + BEQ .done + PLY ; current x, y + PLX + DEC + STA $1D ; rows-- + LDA $1A + STA $1C + LDA $18 + REP #$30 + AND #$00FF + TAX + INY + BRA .next + +.done + PLY ; fix stack + PLX + PLP + CLC + RTS + +assert pc() <= !bank_85_free_space3_end org !bank_B6_free_space_start obj_txt_ptrs: ;; max size for single screen: (30 char dw + terminating dw) * 18 lines = 1116 bytes -warnpc !bank_B6_free_space_end +assert pc() <= !bank_B6_free_space_end ; objective screen tiles ; 'Q' @@ -961,8 +1106,8 @@ org $b6a0c0 ; check mark org $b6a160 - db $01, $00, $03, $00, $06, $00, $8C, $00, $D8, $00, $70, $00, $20, $00, $00, $00 - db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 + db $01, $01, $03, $03, $06, $06, $8C, $8C, $D8, $D8, $70, $70, $20, $20, $00, $00 + db $01, $01, $03, $03, $06, $06, $8C, $8C, $D8, $D8, $70, $70, $20, $20, $00, $00 ; top of 'OBJ' button org $b6a180 @@ -1004,3 +1149,23 @@ db $7C, $00, $C6, $00, $C6, $00, $7C, $00, $C6, $00, $C6, $00, $7C, $00, $00, $0 db $FF, $7C, $FF, $C6, $FF, $C6, $FF, $7C, $FF, $C6, $FF, $C6, $FF, $7C, $FF, $00 db $7C, $00, $C6, $00, $C6, $00, $7E, $00, $06, $00, $C6, $00, $7C, $00, $00, $00 db $FF, $7C, $FF, $C6, $FF, $C6, $FF, $7E, $FF, $06, $FF, $C6, $FF, $7C, $FF, $00 + +obj_letters: +; C +db $7C, $7C, $C6, $C6, $C6, $C6, $C0, $C0, $C6, $C6, $C6, $C6, $7C, $7C, $00, $00 +db $83, $7C, $39, $C6, $39, $C6, $3F, $C0, $39, $C6, $39, $C6, $83, $7C, $FF, $00 +; B +db $00, $FC, $00, $C6, $00, $C6, $00, $FC, $00, $C6, $00, $C6, $00, $FC, $00, $00 +db $FF, $FC, $FF, $C6, $FF, $C6, $FF, $FC, $FF, $C6, $FF, $C6, $FF, $FC, $FF, $00 +; N +db $00, $C6, $00, $E6, $00, $F6, $00, $DE, $00, $CE, $00, $C6, $00, $C6, $00, $00 +db $39, $C6, $19, $E6, $09, $F6, $21, $DE, $31, $CE, $39, $C6, $39, $C6, $FF, $00 +; W +db $C6, $00, $C6, $00, $D6, $00, $D6, $00, $7C, $00, $6C, $00, $44, $00, $00, $00 +db $39, $C6, $39, $C6, $29, $D6, $29, $D6, $83, $7C, $93, $6C, $BB, $44, $FF, $00 +; M +db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 +db $39, $C6, $11, $EE, $01, $FE, $29, $D6, $39, $C6, $39, $C6, $39, $C6, $FF, $00 +; T +db $00, $FC, $00, $30, $00, $30, $00, $30, $00, $30, $00, $30, $00, $30, $00, $00 +db $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00, $FF, $00 diff --git a/rust/maprando/src/patch.rs b/rust/maprando/src/patch.rs index 2f2b93210..43e8d8e4c 100644 --- a/rust/maprando/src/patch.rs +++ b/rust/maprando/src/patch.rs @@ -3577,29 +3577,48 @@ impl Patcher<'_> { obj_coords_vec.sort(); for (obj_i, coords) in obj_coords_vec.iter().enumerate() { let obj = obj_coords[coords]; - let (addr, mask) = match obj { - Kraid => (0xD829, 1), - Ridley => (0xD82A, 1), - Phantoon => (0xD82B, 1), - Draygon => (0xD82C, 1), - SporeSpawn => (0xD829, 2), - Crocomire => (0xD82A, 2), - Botwoon => (0xD82C, 2), - GoldenTorizo => (0xD82A, 4), - MetroidRoom1 => (0xD822, 1), - MetroidRoom2 => (0xD822, 2), - MetroidRoom3 => (0xD822, 4), - MetroidRoom4 => (0xD822, 8), - BombTorizo => (0xD828, 4), - BowlingStatue => (0xD823, 1), - AcidChozoStatue => (0xD821, 0x10), - PitRoom => (0xD823, 2), - BabyKraidRoom => (0xD823, 4), - PlasmaRoom => (0xD823, 8), - MetalPiratesRoom => (0xD823, 0x10), + let ( + addr, + mask, + room_hdr, + offset_state_hdr, + offset_x, + offset_y, + obj_tiles_x, + obj_tiles_y, + ) = match obj { + Kraid => (0xD829, 1, 0xA59F, 18, 0, 0, 2, 2), + Ridley => (0xD82A, 1, 0xB32E, 18, 0, 0, 1, 2), + Phantoon => (0xD82B, 1, 0xCD13, 18, 0, 0, 1, 1), + Draygon => (0xD82C, 1, 0xDA60, 18, 0, 0, 2, 2), + SporeSpawn => (0xD829, 2, 0x9DC7, 18, 0, 0, 1, 3), + Crocomire => (0xD82A, 2, 0xA98D, 18, 0, 0, 8, 1), + Botwoon => (0xD82C, 2, 0xD95E, 18, 0, 0, 2, 1), + GoldenTorizo => (0xD82A, 4, 0xB283, 18, 0, 0, 2, 2), + MetroidRoom1 => (0xD822, 1, 0xDAE1, 18, 0, 0, 6, 1), + MetroidRoom2 => (0xD822, 2, 0xDB31, 18, 0, 0, 1, 2), + MetroidRoom3 => (0xD822, 4, 0xDB7D, 18, 0, 0, 6, 1), + MetroidRoom4 => (0xD822, 8, 0xDBCD, 18, 0, 0, 1, 2), + BombTorizo => (0xD828, 4, 0x9804, 23, 0, 0, 1, 1), + BowlingStatue => (0xD823, 1, 0xC98E, 18, 4, 1, 1, 1), + AcidChozoStatue => (0xD821, 0x10, 0xB1E5, 13, 0, 0, 1, 1), + PitRoom => (0xD823, 2, 0x99BD, 13, 0, 0, 3, 1), + BabyKraidRoom => (0xD823, 4, 0xA521, 18, 0, 0, 6, 1), + PlasmaRoom => (0xD823, 8, 0xD2AA, 13, 0, 0, 2, 3), + MetalPiratesRoom => (0xD823, 0x10, 0xB62B, 13, 0, 0, 3, 1), }; self.rom.write_u16(snes2pc(0x8FEBC0) + obj_i * 2, addr)?; self.rom.write_u16(snes2pc(0x8FEBE8) + obj_i * 2, mask)?; + self.rom + .write_u16(snes2pc(0x8FED00) + obj_i * 7, room_hdr)?; + self.rom + .write_u8(snes2pc(0x8FED02) + obj_i * 7, offset_state_hdr)?; + self.rom.write_u8(snes2pc(0x8FED03) + obj_i * 7, offset_x)?; + self.rom.write_u8(snes2pc(0x8FED04) + obj_i * 7, offset_y)?; + self.rom + .write_u8(snes2pc(0x8FED05) + obj_i * 7, obj_tiles_x)?; + self.rom + .write_u8(snes2pc(0x8FED06) + obj_i * 7, obj_tiles_y)?; } Ok(()) diff --git a/scripts/build_ips.py b/scripts/build_ips.py index 0438568c1..d26e6edb0 100644 --- a/scripts/build_ips.py +++ b/scripts/build_ips.py @@ -132,7 +132,7 @@ def check_range(filename, other_filename, overlap_start, overlap_end): ], 'pause_menu_objectives': [ ['map_area', 0x82910A, 0x82910D], - ['hud_expansion_opaque', 0xB69A00, 0xB6AD40] + ['hud_expansion_opaque', 0xB69A00, 0xB6AE00] ], 'hud_expansion_opaque': [ ['max_ammo_display_fast', 0x858851, 0x858A93],