Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified patches/ips/mb_barrier_clear.ips
Binary file not shown.
2 changes: 1 addition & 1 deletion patches/patch_manifest.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion patches/rom_map/Bank 82.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ FF00 - FF10: reserve_hud.asm
FF10 - FF30: escape.asm
FF30 - FF80: reserve_hud.asm
FF80 - FFFC: pause_menu_objectives.asm
FFFC - FFFE: fast_pause_menu
FFFC - FFFE: objectives/fast_pause_menu
FFFE - end: custom etank color
6 changes: 6 additions & 0 deletions patches/src/constants.asm
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@
!nmi_area4 = $1F86
!nmi_area5 = $1F87
!nmi_area6 = $1F88

; Objectives
!objectives_max = $0014
!objectives_num = $82FFFC ; bits 0-15
!objectives_addrs = $8FEBC0
!objectives_bitmasks #= !objectives_addrs+(2*!objectives_max)
140 changes: 93 additions & 47 deletions patches/src/mb_barrier_clear.asm
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,68 @@ lorom
!bank_84_freespace_start = $84F200
!bank_84_freespace_end = $84F300

org $83AAD2
dw $EB00 ; Set door ASM for Rinka Room toward Mother Brain

macro check_objective(i,plm)
lda.w #$007E
sta.b $02
lda.l ObjectiveAddrs+<i>
sta.b $00
lda.l ObjectiveBitmasks+<i>
sta.b $04
lda.b [$00]
bit.b $04
beq ?skip ; skip clearing if objective not done
incsrc "constants.asm"

macro clear_plm(plm)
jsl $8483D7
db <plm>
db $04
dw clear_barrier_plm
?skip:
endmacro

org $83AAD2
dw $EB00 ; Set door ASM for Rinka Room toward Mother Brain

; Free space in bank $8F
org $8FEB00
; clear barriers in mother brain room based on main bosses killed:
%check_objective(0,$39)
%check_objective(2,$38)
%check_objective(4,$37)
%check_objective(6,$36)
door_asm_start:
; 2 potential scenarios for barriers:
; obj_num <= 4, clear individually from left to right
; obj_num > 4, maintain all 4 until all obj's cleared
lda !objectives_num : and $7FFF
cmp #$0005
bcc normal_objs ; <= 4 ?

ldx #$0000
tay
; iterate through all obj's
.check_lp
jsr check_objective
beq motherbrain
dey
bne .check_lp

; either none or all cleared
clear_all:
ldx #$FFFB
bra start_obj_checks

; # obj's - 4
normal_objs:
sec
sbc #$0004
tax

; starting value of X determines check/clear behavior
; X = 0 for stock behavior (4 objs)
; X < 0 will clear until 0, then check (for 0-3 objs)
; X = -4 will clear all objs
start_obj_checks:
jsr check_objective
beq .skip_1
%clear_plm($36)
.skip_1
jsr check_objective
beq .skip_2
%clear_plm($37)
.skip_2
jsr check_objective
beq .skip_3
%clear_plm($38)
.skip_3
jsr check_objective
beq motherbrain
%clear_plm($39)

motherbrain:
lda $7ed82d
Expand All @@ -46,43 +80,55 @@ motherbrain:
jsl remove_spikes
done:
rts

check_objective:
; X >= 0 obj to check; X < 0 = return obj cleared
; also increments X
phx
txa
bmi .bypass_check
asl
tax
lda.w #$007E
sta.b $02
lda.l ObjectiveAddrs, X
sta.b $00
lda.l ObjectiveBitmasks, X
plx
inx
sta.b $04
lda.b [$00]
bit.b $04
rts
.bypass_check
plx
inx
lda #$0001
rts

warnpc $8FEBC0
org $8FEBC0
warnpc !objectives_addrs

org !objectives_addrs
ObjectiveAddrs:
dw $D829, $D82A, $D82B, $D82C
dw $0000, $0000, $0000, $0000, $0000
dw $0000, $0000, $0000, $0000, $0000
dw $0000, $0000, $0000, $0000, $0000
dw $0000, $0000, $0000, $0000, $0000
dw $0000, $0000, $0000, $0000, $0000
ObjectiveBitmasks:
dw $0001, $0001, $0001, $0001
dw $0001, $0001, $0001, $0001, $0001
dw $0001, $0001, $0001, $0001, $0001
dw $0001, $0001, $0001, $0001, $0001
dw $0001, $0001, $0001, $0001, $0001
dw $0001, $0001, $0001, $0001, $0001

; OBJECTIVE: None (must match address in patch.rs)
warnpc $8FECA0
org $8FECA0

jsl $8483D7
db $39
db $04
dw clear_barrier_plm

jsl $8483D7
db $38
db $04
dw clear_barrier_plm

jsl $8483D7
db $37
db $04
dw clear_barrier_plm

jsl $8483D7
db $36
db $04
dw clear_barrier_plm

jmp motherbrain

jmp clear_all ; this section can be removed once patch.rs is updated

warnpc $8FED00


; Remove invisible spikes where Mother Brain used to be (common routine used by both the left and right door ASMs)
org !bank_84_freespace_start

Expand Down
13 changes: 5 additions & 8 deletions patches/src/pause_menu_objectives.asm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ arch 65816

math pri on

incsrc "constants.asm"

!bank_82_free_space_start = $82FF80
!bank_82_free_space_end = $82FFFC

Expand Down Expand Up @@ -72,11 +74,6 @@ org $82A61D

!n_lines = #$0012

!ObjectiveAddrs = $8FEBC0
!ObjectiveBitmasks = $8FEBE8

!n_objectives = $82fffc

;;; character conversion table
table "tables/pause_menu_objectives_chars.tbl",RTL

Expand Down Expand Up @@ -313,7 +310,7 @@ pad_0:
check_objs:
;;; check objectives and add check marks
LDY.w #!line_size*2 ; start of 1st line
LDA !n_objectives : AND $7FFF
LDA !objectives_num : AND $7FFF
STA !tmp_tile_offset ; # objectives
BEQ .check_animals
LDX #$0000
Expand Down Expand Up @@ -355,9 +352,9 @@ check_objective: ; X = index
TAX
LDA.w #$007E
STA.b $02
LDA.l !ObjectiveAddrs, X
LDA.l !objectives_addrs, X
STA.b $00
LDA.l !ObjectiveBitmasks, X
LDA.l !objectives_bitmasks, X
STA.b $04
LDA.b [$00]
PLX
Expand Down
58 changes: 25 additions & 33 deletions rust/maprando/src/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,39 +396,31 @@ fn apply_orig_ips_patches(rom: &mut Rom, randomization: &Randomization) -> Resul
apply_ips_patch(rom, &patch_path)?;
}

// Overwrite door ASM for entering Mother Brain room from right, used for clearing objective barriers:
if randomization.objectives.len() == 0 {
// Check for None objectives
rom.write_u16(snes2pc(0x83AAD2), 0xECA0)?;
} else if randomization.objectives.len() == 4 {
for (i, obj) in randomization.objectives.iter().enumerate() {
use Objective::*;
let (var, 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),
};
rom.write_u16(snes2pc(0x8FEBC0) + i * 2, var)?;
rom.write_u16(snes2pc(0x8FEBC8) + i * 2, mask)?;
}
} else {
panic!("Unimplemented objective count != 4")
for (i, obj) in randomization.objectives.iter().enumerate() {
use Objective::*;
let (var, 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),
};
rom.write_u16(snes2pc(0x8FEBC0) + i * 2, var)?;
rom.write_u16(snes2pc(0x8FEBE8) + i * 2, mask)?;
}
Ok(())
}
Expand Down