이 페이지는 슈퍼 마리오 브라더스의 버그를 다루는 페이지입니다.
가시돌이 알 버그#
여기에 가시돌이 알의 속도가 어떻게 계산되고 저장되는지 나온다.
DifLoop: lda PRDiffAdjustData,y ;3개의 값을 얻고 저장
sta $01,x ;$01~$03 범위로
iny
iny ;Y 4바이트의 각 값을 증가
iny
iny
dex ;각 X 값을 감소
bpl DifLoop ;세 값이 써질때까지 구간 반복
ldx ObjectOffset ;적 오브젝트 버퍼 오프셋을 얻음
jsr PlayerLakituDiff ;적을 움직이고, 방향을 바꾸고, 값 - 차이를 얻음
ldy Player_X_Speed ;플레이어의 X축 속도를 체크
cpy #$08
bcs SetSpSpd ;만약 특정값보다 더 빨리 움직이면, 다른 곳으로 분기
tay ;그렇지 않으면 A에 현재 Y값을 저장
lda PseudoRandomBitReg+1,x
and #%00000011 ;LSFR 부분 중 하나를 얻고 두 개의 LSB를 저장
beq UsePosv ;어떤 비트도 지정되어있지 않으면 분기
tya
eor #%11111111 ;그렇지 않으면 Y의 두개의 컴플리먼트를 얻음
tay
iny
UsePosv: tya ;A로부터 얻은 값을 Y에 넣고 A로 돌아감 A=SpeedVar
SetSpSpd: jsr SmallBBox ;바운딩 박스 컨트롤 등을 지정 A=SpeedVar
...
잘 하고 있다. A 레지스터는 제대로 된 속도값을 저장하고 있다.
SmallBBox: lda #$09 ;특정 바운딩 박스 사이즈 컨트롤을 설정 A=09
bne SetBBox ;무조건적인 분기 A=09
이런, 바운딩 박스 서브루틴으로 점프했더니 A의 값을 덮어씌워버렸다! 위에서 했던 모든 것이 헛수고가 되었다.
SetBBox: sta Enemy_BoundBoxCtrl,x ;여기에 바운딩 박스 컨트롤을 설정 A=09
lda #$02 ;왼쪽 방향으로의 이동을 설정 A=02
sta Enemy_MovingDir,x A=02
InitVStf: lda #$00 ;Y축 속도 초기화 A=00
sta Enemy_Y_Speed,x ;관성(이동력)도 초기화 A=00
sta Enemy_Y_MoveForce,x A=00
rts A=00
여기서 A 값이 00이 되고 말았다. 이제 게임은 SetSpSpd 서브루틴으로 점프한다...
...
ldy #$02 ;Y를 02(왼쪽)으로 설정 A=00
sta Enemy_X_Speed,x ;가시돌이 알의 속도를 A(00)로 설정 A=00
cmp #$00 ;속도가 음수인지 확인하지만... A=00
bmi SpinyRte ;...A는 항상 00. 분기 없음. A=00
dey ;Y를 01(오른쪽)로 설정
SpinyRte: sty Enemy_MovingDir,x ;이동 방향 설정.
...그리고 속도는 0으로 설정된다. 이동 방향은 오른쪽으로 설정되지만, 알은 수평으로 움직이지 않으며, 적 가시돌이가 스폰될 때 방향이 리셋된다는 것 뿐이다.
이 버그를 수정하기 위해선 그냥 'jsr SmallBBox'를 dey opcode 뒤에 놓으면 되는데, 이 패치로 가능하다:
|
File: SMBSpinyEggPatch.ips (25 B) (info) |
(Source: doppelganger's SMBDis)