This page contains notes for the game Final Fight (SNES).
Addresses correspond to the USA version unless noted otherwise.
RAM Addresses#
7E004F - toggled every time title screen appears to alternate between the 2 gameplay demos 00=Slum 01=Subway. value is x2 and stored to 7EFFFD
7E0088 - ending cutscene main counter
7E0089 - ending cutscene progress counter
7E008A - ending countdown timer (16-bit)
7E008F - character selected on character select screen 00=Cody 01=Haggar
7E00CB - debug invincibility 00=off 01=on
7E00CC - demo mode 00=on 01=off
7E00CD - number of players 01=1 player 02=2 players
7E00E6 - incremented every time lives or countdown timer HUD is updated (and possibly other HUD updates) possibly RNG related TODO: check if 8 or 16-bit
7E0109 - random number, range 00-03. used to get another random number from one of the next 4 bytes in RAM
7E010A - random number, +1 each time updater is run
7E010B - random number, +3 each time updater is run
7E010C - random number, +7 each time updater is run
7E010D - random number, +9 each time updater is run
7E0120 - main screens TODO 12=Option Mode
7E0121 - progress for main screens
7E012E - countdown timer, used on title screen and character select screen
7E0400 - S0 palette
7E0420 - S1 palette
7E0440 - S2 palette
7E0460 - S3 palette
7E0480 - S4 palette
7E04A0 - S5 palette
7E04C0 - S6 palette
7E04E0 - S7 palette
7E0500 - 00 palette (player 1 character during gameplay) $20/32 bytes - 16 colors
7E0520 - 01 palette
7E0540 - 02 palette
7E0560 - 03 palette
7E0580 - 04 palette
7E05A0 - 05 palette
7E05C0 - 06 palette
7E05E0 - 07 pallete
7E0CA0 - game status: 00=character select 02=open stage 04=open stage 06=active gameplay 08=clear area 0A=clear round (TODO: add the rest)
7E0CB0 - Round: 00=Slum 01=Subway 02=West Side 03=Industrial Area 04=Bay Area 05=Up Town 06=Break Car 07=Break Glass
7E0CB1 - Area (Round-Max): 00-02, 01-03, 02-02, 03-01, 04-00, 05-03, 06-00, 07-00
7E0CB2 - rounds cleared counter
7E0CB3 - bonus round flag 00=false 01=true
7E0CB4 - frame counter, range 0000-FFFF (16-bit)
7E0CB6 - current DifficultyA
7E0CB8 - DifficultyA (unused)
7E0CBA - DifficultyB
7E0CBC - countdown timer ones digit
7E0CBD - countdown timer tens digit
7E0CBE - counter responsible for lowering the countdown timer by 1 (16-bit) it's set to $01E0 (8 seconds)
7E0CC4 - round max time ones digit
7E0CC5 - round max time tens digit
7E0CC6 - initial DifficultyA
7E0CC8 - DifficultyB frame counter (16-bit): 00=0258 (600 frames, 10 seconds), 01=0258 (600 frames, 10 seconds), 02=01E0 (480 frames, 8 seconds), 03=012C (300 frames, 5 seconds)
7E0CCA - Platform height in Round (verify if 8 or 16-bit)
7E0CCC - counter for number of continues used
7E0CCE - Platform height of wall or object (drum can, tire, etc.) player is standing next to
7E0CD0 - Value is #00 during normal gameplay, writing #01 forces current level's end (gameplay pauses and HUD floats away) but will get stuck if boss isn't dead, and GO! will continue flashing.
Is #FF while loading new level and screen is black.
7E0CD1 - Value is #00 during normal gameplay, is set to #01 when level ends or during new level map or bonus stage announcement text.
If set to #01 during normal gameplay the timer will stop and the game cannot be paused, but the player can still walk around.
7E0CD2 = #00 until certain bosses die (all except Sodom?) and it changes to #01. This causes all on-screen normal enemies to immediately die, ends the level script and disables the player's hitbox.
Forcing it to #01 during normal gameplay also triggers these effects. Force back to #00 to resume normal gameplay.
7E0CD7 - When GO! -> is flashing, this = #01. Changing it from 00 to 01 manually prevents GO!-> from appearing.
7E0CE1 - Status byte for Sodom's audience. Only matters on level 01-03. Default is #00.
As soon as Sodom activates his code writes #01 to this address, triggering the audience to cheer.
Overwriting it with #01 at any time while on level 01-03 before reaching Sodom will cause the audience to begin cheering.
7E0D00 - Player 1 status 00=not active 01=active. Also the player's direct page index.
7E0D01 - Player 1 status bits? - bit 04=holding weapon
7E0D02 - Player 1 unknown, set to $08 when lost life, set to $0A on player init.
7E0D03 - Player 1 action index, value x2 for pointer table starting at SNES address $02A71E (list incomplete, needs more research and verification)
00=default 02=grab 04=knocked down 06=dead? 08=get up/start to throw enemy 0A=walking 0C=stop walking 0E=jump
10=special move 12=land from jump 14=punch 16=dummy (table pointer is same as 14 punch, reserved for Guy's missing wall kick) 18=pick up item 1A=throw enemy 1C=TODO 1E=throw knife
20=use weapon 22=debug animation test
7E0D04 - Player 1 action sub1
7E0D05 - Player 1 action sub2
7E0D07 - Player 1 X coord (16-bit)
7E0D09 - Player 1 Y coord
7E0D0A - Player 1 Y coord (jumping) (16-bit)
7E0D0D - Player 1 Y coord (16-bit)
7E0D0F - Player 1 temporary invincibility countdown timer
7E0D11 - Player 1 controller 00=controller 1 02=controller 2
7E0D12 - Player 1 character 00=Guy 02=Cody 04=Haggar
7E0D14 - Player 1 current HP
7E0D16 - Player 1 previous HP
7E0D18 - Player 1 max HP (80)
7E0D20 - Player 1 direction facing 00=right 01=left
7E0D21 - Player 1 unknown, set to $00 immediately after loading player palette
7E0D22 - Player 1 pointer to offense damage table (bank) TODO: $02 for all player characters?
7E0D23 - Player 1 unknown, loads 7E0D12 player index to get a byte from a table starting at SNES address 01A66D, value is $30 for all 3 player characters
7E0D28 - Player 1 pointer to offense damage table (lower 16 bits) (Cody=E971)
7E0D2E - Player 1 related to tile properties
7E0D2F - Player 1 tile properties index of tile player is currently standing on
7E0D3A - Player 1 temporary invincibility flicker countdown timer
7E0D4C - Player 1 start address in RAM of equipped weapon (+7E0000) (16-bit) 0000=no weapon
7E0D4E - Player 1 height of platform or object (drum can, tire, etc.) player is standing on (verify if 8 or 16-bit)
7E0D60 - Player 1 related to dealing damage, may be an attack type index
7E0D64 - Player 1 controller button presses (16-bit)
7E0D66 - Player 1 controller button presses (16-bit)
7E0D68 - Player 1 TODO various bits 10=spawn point type
7E0D6E - Player 1 lives remaining, range 01-09 (note HUD value is -1, range displayed is 0-8)
7E0D6F - Player 1 9th life (when this is 01, HUD shows 9 lives)
7E0D74 - Player 1 set to 23 when pick up knife (or other weapons/objects?) Set to $00 when throwing knife
7E0D78 - Player 1 current frame of walking animation. Remains unchanged while the player is not walking, player will resume from the current frame when walking again.
7E0E07 - X coord scrolled in round
7E0E0A - Y coord related in round? (16-bit)
Enemy and boss RAM areas all follow a similar structure to the player's RAM area. Many instructions, such as those relating to movement and collision, are shared between the player, enemies
and bosses through careful use of the direct page register.
7E1000 - Enemy 0's direct page index.
7E10B0 - Enemy 1's direct page index.
7E1140 - Enemy 2's direct page index.
7E11E0 - Boss' direct page index & status byte. 00 = No boss on level. 01 = Boss on level, but not currently drawn. 03 = Boss on level and close enough to be drawn.
7E11E1 - Status byte relating to the boss' current action. Different for every boss.
7E11F1 - When a level is loaded that contains a boss, this byte holds the current round number * 2 for use as an offset for boss AI.
7E11F4 - Boss current HP
7E11F6 - Boss previous HP
7E11F8 - Boss max HP
7E1202 - Boss pointer to max HP and defense, and ? table (bank)
7E1208 - Boss pointer to max HP and defense, and ? table (lower 16 bits)
7E120A - Boss pointer to unknown table (lower 16 bits)
7E1223 - Boss defense (updated based on current DifficultyA)
7E1243 - Boss current DifficultyA
7EFFEF - show high score table after Capcom logo 00=off 02=on (used to show high scores after the game is finished and reboots)
7EFFF0 - Extra Joy (perform special move with A button) 00=on 01=off
7EFFF1 - number of times a new game has been started
7EFFF2 - unused, always #$00, and read as part of a RAM sanity check to make sure its $00
7EFFF3
7EFFF4 - Option Mode DifficultyA. value set corresponds to initial DifficultyA table starting SNES address 019E43: 01=00,02=02,03=03,04=04,05=05,06=06,07=07,08=08
7EFFF5 - Option Mode DifficultyB
7EFFF6 - Extend: 00=100000 ONLY, 02=200000 ONLY, 04=200000 EVERY, 06=NOTHING
7EFFF7 - Option Mode player (lives)
7EFFF8
7EFFF9
7EFFFA - debug mode 00=off 01=on
7EFFFB - unknown, music related timer?
7EFFFC - demo recorder 00=off 01=playback mode 80=record mode
7EFFFD - demo recorder Round 00=Slum 02=Subway
7EFFFE - Option Mode Round
7EFFFF - Option Mode Area
Difficulty System#
DifficultyA#
Start New Life#
$02/A22A 20 63 A2 JSR $A263 [$02:A263] //Spawn point
$02/A22D A9 10 LDA #$10 //Respawn type bit
$02/A22F 24 68 BIT $68 [$00:0D68]
$02/A231 F0 25 BEQ $25 [$A258] //Skip to $A258 if respawn type bit not set
Respawn type bit set
$02/A233 A5 09 LDA $09 [$00:0D09] //?
$02/A235 85 0C STA $0C [$00:0D0C]
$02/A237 C2 20 REP #$20
$02/A239 A5 0A LDA $0A [$00:0D0A]
$02/A23B 85 0D STA $0D [$00:0D0D] //Copy Y coord
$02/A23D 18 CLC
$02/A23E 69 00 01 ADC #$0100 //Set jump height (allows player to fall from top of the screen)
$02/A241 85 0A STA $0A [$00:0D0A]
$02/A243 E2 20 SEP #$20
$02/A245 A9 B4 LDA #$B4 //Temporary invincibility
$02/A247 85 3A STA $3A [$00:0D3A] //Temporary invincibility flicker timer
$02/A249 85 0F STA $0F [$00:0D0F] //Temporary invincibility timer
$02/A24B A9 02 LDA #$02
$02/A24D 85 02 STA $02 [$00:0D02]
$02/A24F A9 02 LDA #$02
$02/A251 85 03 STA $03 [$00:0D03]
$02/A253 64 04 STZ $04 [$00:0D04]
$02/A255 64 05 STZ $05 [$00:0D05]
$02/A257 60 RTS
Respawn type bit not set*
$02/A258 A9 02 LDA #$02
$02/A25A 85 02 STA $02 [$00:0D02]
$02/A25C 64 03 STZ $03 [$00:0D03]
$02/A25E 64 04 STZ $04 [$00:0D04]
$02/A260 64 05 STZ $05 [$00:0D05]
$02/A262 60 RTS
*This seems to be unused. If the bit is not set, the player spawns on the ground with no temporary invincibility.
Spawn Point#
$02/A263 AD 06 0E LDA $0E06 [$00:0E06]
$02/A266 85 06 STA $06 [$00:0D06]
$02/A268 AD 09 0E LDA $0E09 [$00:0E09]
$02/A26B 85 09 STA $09 [$00:0D09]
$02/A26D C2 20 REP #$20
$02/A26F AD 07 0E LDA $0E07 [$00:0E07] //X coord scrolled in stage
$02/A272 18 CLC
$02/A273 69 40 00 ADC #$0040 //X coord from left edge of screen + #$0040
$02/A276 85 07 STA $07 [$00:0D07]
$02/A278 AD 0A 0E LDA $0E0A [$00:0E0A] //Y coord
$02/A27B 18 CLC
$02/A27C 69 30 00 ADC #$0030 //Y coord from bottom edge of screen + #$0030
$02/A27F 85 0A STA $0A [$00:0D0A]
$02/A281 E2 20 SEP #$20
$02/A283 60 RTS
Lost Life#
$02/A2AF 22 5A A4 01 JSL $01A45A[$01:A45A] //Lower Current DifficultyA Using DifficultyB Setting
$02/A2B3 20 E6 A2 JSR $A2E6 [$02:A2E6] //Subtract Lives
$02/A2B6 D0 15 BNE $15 [$A2CD] //Skip to $A2CD if lives remaining
Lost all lives
$02/A2B8 64 00 STZ $00 [$00:0D00] //Set player to inactive status
$02/A2BA 64 01 STZ $01 [$00:0D01]
$02/A2BC 64 26 STZ $26 [$00:0D26]
$02/A2BE 64 54 STZ $54 [$00:0D54]
$02/A2C0 64 55 STZ $55 [$00:0D55]
$02/A2C2 A9 08 LDA #$08
$02/A2C4 85 02 STA $02 [$00:0D02]
$02/A2C6 64 03 STZ $03 [$00:0D03]
$02/A2C8 64 04 STZ $04 [$00:0D04]
$02/A2CA 64 05 STZ $05 [$00:0D05]
$02/A2CC 60 RTS
Lives remaining
$02/A2CD A6 18 LDX $18 [$00:0D18] //Load max HP (80)
$02/A2CF 86 14 STX $14 [$00:0D14] //Store max HP to current HP
$02/A2D1 86 16 STX $16 [$00:0D16] //Store max HP to previous HP
$02/A2D3 64 20 STZ $20 [$00:0D20] //Set player direction facing to right
$02/A2D5 A9 10 LDA #$10 //Set respawn type bit
$02/A2D7 85 68 STA $68 [$00:0D68]
$02/A2D9 64 02 STZ $02 [$00:0D02]
$02/A2DB 64 03 STZ $03 [$00:0D03]
$02/A2DD 64 04 STZ $04 [$00:0D04]
$02/A2DF 64 05 STZ $05 [$00:0D05]
$02/A2E1 22 8D A6 01 JSL $01A68D[$01:A68D] //Reload Round Countdown Timer
$02/A2E5 60 RTS
Subtract Lives#
$02/A2E6 C6 6E DEC $6E [$00:0D6E] //Lives -1
$02/A2E8 10 06 BPL $06 [$A2F0] //Skip to $A2F0 if not losing the 9th life
$02/A2EA A9 09 LDA #$09 //Appears as 8 lives on HUD
$02/A2EC 85 6E STA $6E [$00:0D6E] //Store lives
$02/A2EE C6 6F DEC $6F [$00:0D6F] //Remove 9th life
$02/A2F0 22 DE E5 00 JSL $00E5DE[$00:E5DE] //Update lives HUD
$02/A2F4 A5 6E LDA $6E [$00:0D6E] //Lives
$02/A2F6 05 6F ORA $6F [$00:0D6F] //Lives 9 and beyond
$02/A2F8 60 RTS //Exit, with accumulator about to be used to determine if player ran out of lives
Debug Invincibility and Bullets#
$02/A756 AD 1A 01 LDA $011A [$00:011A] //Controller 2
$02/A759 2D 12 01 AND $0112 [$00:0112] //Controller 2
$02/A75C 89 40 BIT #$40 //X button
$02/A75E F0 09 BEQ $09 [$A769] //Skip to $A769 if X button not pressed
Debug invincibility
$02/A760 AD CB 00 LDA $00CB [$00:00CB] //Debug invincibility
$02/A763 49 01 EOR #$01 //Toggle
$02/A765 8D CB 00 STA $00CB [$00:00CB] //Update invincibility status
$02/A768 60 RTS
$02/A769 89 80 BIT #$80 //A button
$02/A76B F0 30 BEQ $30 [$A79D] //Skip to $A79D if A not pressed
Debug bullets
$02/A76D 22 B2 AC 00 JSL $00ACB2[$00:ACB2] //Check if 3 bullets not already onscreen (needs verification) These are slots for weapon items. Bullets and molotovs are treated as weapons. -Rotwang
$02/A771 D0 2A BNE $2A [$A79D] //Skip to $A79D if no more bullets allowed
$02/A773 A9 01 LDA #$01 //Create active bullet
$02/A775 9D 00 00 STA $0000,x[$00:1C00]
$02/A778 A9 06 LDA #$06 //Bullet object index*
$02/A77A 9D 11 00 STA $0011,x
$02/A77D A5 20 LDA $20 [$00:0D20] //Player direction facing (set this operation to A9 00 / LDA #$00 to always shoot to the right)
$02/A77F 9D 20 00 STA $0020,x //Set bullet direction to the same as player facing
$02/A782 C2 20 REP #$20
$02/A784 A5 07 LDA $07 [$00:0D07] //Player X coord
$02/A786 18 CLC
$02/A787 69 20 00 ADC #$0020
$02/A78A 9D 07 00 STA $0007,x //Bullet spawn point is player X coord + #$20
$02/A78D A5 0A LDA $0A [$00:0D0A] //Player Y coord
$02/A78F 18 CLC
$02/A790 69 20 00 ADC #$0020
$02/A793 9D 0A 00 STA $000A,x //Bullet spawn point is player Y coord + #$20
$02/A796 A5 0D LDA $0D [$00:0D0D] //Player Y coord
$02/A798 9D 0D 00 STA $000D,x //Bullet spawn Y coord (another, unknown difference)
$02/A79B E2 20 SEP #$20
$02/A79D 60 RTS
*Change this value (eg, using PAR code 02A779xx) to spawn other weapons
Unknown $02AEF8#
This seems to be comparing Player 1's X and Y coords versus Player 2.
|
|
To do: |
$02/AEF8 B9 00 00 LDA $0000,y[$00:0D80] //Player 2 active status
$02/AEFB F0 24 BEQ $24 [$AF21] //Skip to $AF21 if not in 2 player mode
$02/AEFD C2 20 REP #$20
$02/AEFF A5 0D LDA $0D [$00:0D0D]
$02/AF01 38 SEC
$02/AF02 F9 0D 00 SBC $000D,y
$02/AF05 30 07 BMI $07 [$AF0E]
$02/AF07 C9 0D 00 CMP #$000D
$02/AF0A 90 09 BCC $09 [$AF15]
$02/AF0C 80 13 BRA $13 [$AF21]
$02/AF0E C9 F0 FF CMP #$FFF0
$02/AF11 B0 02 BCS $02 [$AF15]
$02/AF15 B9 07 00 LDA $0007,y
$02/AF18 38 SEC
$02/AF19 ED 04 00 SBC $0004 [$00:0004]
$02/AF1C C9 78 00 CMP #$0078
$02/AF1F 90 0A BCC $0A [$AF2B]
$02/AF21 E2 20 SEP #$20
$02/AF23 AD 00 00 LDA $0000 [$00:0000]
$02/AF26 14 6A TRB $6A [$00:0D6A]
$02/AF28 A9 00 LDA #$00
$02/AF2A 60 RTS
$02/AF2B E2 20 SEP #$20
$02/AF2D AD 00 00 LDA $0000 [$00:0000]
$02/AF30 04 6A TSB $6A [$00:0D6A]
$02/AF32 A9 01 LDA #$01
$02/AF34 60 RTS
Check if Jumping and Setup Jump#
$02/B04A A5 65 LDA $65 [$00:0D65]
$02/B04C 25 67 AND $67 [$00:0D67]
$02/B04E 89 80 BIT #$80 //Player 1 B button
$02/B050 F0 0C BEQ $0C [$B05E] //Skip to $B05E if B not pressed
Jump
$02/B052 64 44 STZ $44 [$00:0D44]
$02/B054 64 47 STZ $47 [$00:0D47]
$02/B056 A9 0E LDA #$0E //Jumping animation
$02/B058 85 03 STA $03 [$00:0D03]
$02/B05A 64 04 STZ $04 [$00:0D04]
$02/B05C 64 05 STZ $05 [$00:0D05]
$02/B05E 60 RTS
TODO#
$02/B05F 20 B1 B2 JSR $B2B1 [$02:B2B1] //Check for Special Move and Setup
$02/B062 F0 33 BEQ $33 [$B097] //Skip to $B097 if performing special move
$02/B064 A5 65 LDA $65 [$00:0D65]
$02/B066 25 67 AND $67 [$00:0D67]
$02/B068 29 40 AND #$40 //Player 1 Y button
$02/B06A F0 2B BEQ $2B [$B097] //Skip to $B097 if button not pressed
$02/B06C 20 E5 B0 JSR $B0E5 [$02:B0E5] //TODO
$02/B06F D0 03 BNE $03 [$B074] //TODO
$02/B071 4C 9C B0 JMP $B09C [$02:B09C] //Skip to $B09C if picked up object on ground
$02/B074 A5 74 LDA $74 [$00:0D74]
$02/B076 D0 08 BNE $08 [$B080]
$02/B078 20 18 B2 JSR $B218 [$02:B218]
$02/B07B D0 03 BNE $03 [$B080]
...
$02/B080 20 A7 B0 JSR $B0A7 [$02:B0A7]
$02/B083 F0 12 BEQ $12 [$B097] //Skip to $B097 if using a weapon
$02/B085 A5 70 LDA $70 [$00:0D70]
$02/B087 D0 05 BNE $05 [$B08E]
$02/B089 64 71 STZ $71 [$00:0D71]
$02/B08B 4C 7D B2 JMP $B27D [$02:B27D]
...
$02/B097 60 RTS
Pick up TODO (weapon or item?)#
$02/B098 A9 23 LDA #$23 //?
$02/B09A 85 74 STA $74 [$00:0D74]
$02/B09C A9 18 LDA #$18 //Pick up animation
$02/B09E 85 03 STA $03 [$00:0D03]
$02/B0A0 64 04 STZ $04 [$00:0D04]
$02/B0A2 64 05 STZ $05 [$00:0D05]
$02/B0A4 4C C8 AC JMP $ACC8 [$02:ACC8]
Check for and use Weapon#
$02/B0A7 A9 04 LDA #$04
$02/B0A9 24 01 BIT $01 [$00:0D01] //Holding a weapon bit
$02/B0AB F0 30 BEQ $30 [$B0DD] //Skip to $B0DD if not holding weapon
$02/B0AD A6 4C LDX $4C [$00:0D4C] //Weapon object start address in RAM
$02/B0AF F0 28 BEQ $28 [$B0D9] //Skip to $B0D9 if lost weapon
$02/B0B1 BD 11 00 LDA $0011,x[$00:0012] //Weapon type
$02/B0B4 D0 18 BNE $18 [$B0CE] //Skip to $B0CE if not holding knife
$02/B0B6 A5 12 LDA $12 [$00:0D12] //Player character
$02/B0B8 C9 02 CMP #$02 //Haggar
$02/B0BA D0 05 BNE $05 [$B0C1] //Skip to $B0C1 if playing as Haggar
$02/B0BC 20 E0 B0 JSR $B0E0 [$02:B0E0] //Check if Enemy in Range
$02/B0BF D0 0D BNE $0D [$B0CE] //Skip to $B0CE if within stabbing range
Throw knife
$02/B0C1 A9 1E LDA #$1E //Throw knife animation
$02/B0C3 85 03 STA $03 [$00:0D03]
$02/B0C5 64 04 STZ $04 [$00:0D04]
$02/B0C7 64 05 STZ $05 [$00:0D05]
$02/B0C9 64 74 STZ $74 [$00:0D74]
$02/B0CB A9 00 LDA #$00 //Using weapon = true
$02/B0CD 60 RTS
Use weapon (inc. stab with knife if Cody is close to enemy)
$02/B0CE A9 20 LDA #$20 //Use weapon animation
$02/B0D0 85 03 STA $03 [$00:0D03]
$02/B0D2 64 04 STZ $04 [$00:0D04]
$02/B0D4 64 05 STZ $05 [$00:0D05]
$02/B0D6 A9 00 LDA #$00 //Using weapon = true
$02/B0D8 60 RTS
$02/B0D9 A9 04 LDA #$04
$02/B0DB 14 01 TRB $01 [$00:0D01] //Reset holding a weapon bit
$02/B0DD A9 01 LDA #$01 //Using weapon = false
$02/B0DF 60 RTS
Check if Enemy in Range#
$02/B0E0 A9 0F LDA #$0F //Handle only lower 4 bits
$02/B0E2 24 6A BIT $6A [$00:0D6A] //Bit 01=?, Bit 02=enemy close, Bit 04 =?, Bit 08=?
$02/B0E4 60 RTS
Check for Special Move and Setup#
$02/B2B1 AD B0 0C LDA $0CB0 [$00:0CB0] //Round
$02/B2B4 C9 06 CMP #$06 //Break Car
$02/B2B6 F0 37 BEQ $37 [$B2EF] //Skip to $B2EF if on Break Car round
$02/B2B8 AF F0 FF 7E LDA $7EFFF0[$7E:FFF0] //Extra Joy
$02/B2BC D0 08 BNE $08 [$B2C6] //Skip to $B2C6 if extra joy off
$02/B2BE A5 64 LDA $64 [$00:0D64]
$02/B2C0 25 66 AND $66 [$00:0D66]
$02/B2C2 29 80 AND #$80 //Player 1 A button
$02/B2C4 D0 10 BNE $10 [$B2D6] //Skip to $B2D6 if A button pressed (perform special move)
$02/B2C6 A5 65 LDA $65 [$00:0D65]
$02/B2C8 25 67 AND $67 [$00:0D67]
$02/B2CA 89 C0 BIT #$C0 //Player 1 Y and B buttons
$02/B2CC F0 21 BEQ $21 [$B2EF] //Skip to $B2EF is not pressing Y or B buttons
$02/B2CE 05 67 ORA $67 [$00:0D67]
$02/B2D0 29 C0 AND #$C0 //Examine status of Y and B buttons only
$02/B2D2 C9 C0 CMP #$C0
$02/B2D4 D0 19 BNE $19 [$B2EF] //Skip to $B2EF if both buttons not pressed
Perform special move
$02/B2D6 A6 14 LDX $14 [$00:0D14] //Current HP
$02/B2D8 F0 15 BEQ $15 [$B2EF] //Skip to $B2EF if no HP left to perform special move
$02/B2DA 30 13 BMI $13 [$B2EF] //Skip to $B2EF if negative HP/dead (?)
$02/B2DC 64 77 STZ $77 [$00:0D77]
$02/B2DE 64 71 STZ $71 [$00:0D71]
$02/B2E0 64 70 STZ $70 [$00:0D70]
$02/B2E2 64 47 STZ $47 [$00:0D47]
$02/B2E4 A9 10 LDA #$10 //Special move animation
$02/B2E6 85 03 STA $03 [$00:0D03]
$02/B2E8 64 04 STZ $04 [$00:0D04]
$02/B2EA 64 05 STZ $05 [$00:0D05]
$02/B2EC A9 00 LDA #$00 //Performing special move = true
$02/B2EE 60 RTS
$02/B2EF A9 01 LDA #$01 //Performing special move = false
$02/B2F1 60 RTS
Boss AI Table in Final Fight Guy (J)#
.00:CCDD Boss_init: ; CODE XREF: .00:C999�P
.00:CCDD REP #$20 ; ' '
.00:CCDF .A16
.00:CCDF LDA #$11E0
.00:CCE2 TCD
.00:CCE3 SEP #$20 ; ' '
.00:CCE5 .A8
.00:CCE5 LDA D,0
.00:CCE7 BEQ boss_init_exit
.00:CCE9 BMI loc_CCF0
.00:CCEB JSR Boss_init_Get_level_ID
.00:CCEE BRA boss_init_exit
.00:CCF0 ; ---------------------------------------------------------------------------
.00:CCF0
.00:CCF0 loc_CCF0: ; CODE XREF: Boss_init+C�j
.00:CCF0 LDA #$80 ; 'Ç'
.00:CCF2 TRB D,0
.00:CCF4
.00:CCF4 boss_init_exit: ; CODE XREF: Boss_init+A�j
.00:CCF4 ; Boss_init+11�j
.00:CCF4 RTL
.00:CCF4 ; End of function Boss_init
.00:CCF4
.00:CCF5 .A8
.00:CCF5 .I16
.00:CCF5
.00:CCF5 ; =============== S U B R O U T I N E =======================================
.00:CCF5
.00:CCF5
.00:CCF5 Boss_init_Get_level_ID: ; CODE XREF: Boss_init+E�p
.00:CCF5 LDA #0
.00:CCF7 XBA
.00:CCF8 LDA D,$11 ; Gets previously stored levelID*2 from bossram to determine which boss is active.
.00:CCF8 ; 00 = Slums
.00:CCF8 ; 02 = Subway
.00:CCF8 ; 04 = West Side
.00:CCF8 ; 06 = Industrial Area
.00:CCF8 ; 08 = Bay Area
.00:CCF8 ; 0A = Uptown
.00:CCFA TAX
.00:CCFB JMP ($CCFE,X) ; Boss init jump table
.00:CCFB ; End of function Boss_init_Get_level_ID
.00:CCFB
.00:CCFB ; ---------------------------------------------------------------------------
.00:CCFE .BYTE $C
.00:CCFF .BYTE $CD ; - ; Damnd
.00:CD00 .BYTE $11
.00:CD01 .BYTE $CD ; - ; Sodom
.00:CD02 .BYTE $16
.00:CD03 .BYTE $CD ; - ; EDI-E
.00:CD04 .BYTE $1B
.00:CD05 .BYTE $CD ; Abigail
.00:CD06 .BYTE $1B
.00:CD07 .BYTE $CD ; - ; Abigail
.00:CD08 .BYTE $20
.00:CD09 .BYTE $CD ; - ; Belger
.00:CD0A .BYTE $25 ; %
.00:CD0B .BYTE $CD ; - ; Unknown - probably bonus stage
.00:CD0C ; ---------------------------------------------------------------------------
.00:CD0C
.00:CD0C loc_CD0C:
.00:CD0C JSL Damnd_AI_begin ; $04C0C1
.00:CD10 RTS
.00:CD11 ; ---------------------------------------------------------------------------
.00:CD11 JSL Sodom_AI_begin ; $06B4A0
.00:CD15 RTS
.00:CD16 ; ---------------------------------------------------------------------------
.00:CD16 JSL EDI_E_AI_Begin ; $06C944
.00:CD1A RTS
.00:CD1B ; ---------------------------------------------------------------------------
.00:CD1B JSL Abigail_AI_Begin ; $06D69D
.00:CD1F RTS
.00:CD20 ; ---------------------------------------------------------------------------
.00:CD20 JSL Belger_AI_Begin ; $06E1CA
.00:CD24 RTS
.00:CD25 ; ---------------------------------------------------------------------------
.00:CD25 JSL Unknown_Boss_AI_Begin ;06F181
.00:CD29 RTS
Breakable Objects#
Random Reward Tables#
|
|
To do: |
If bit $80 is set for the reward type, the lower 4 bits are used as an index to load one of the 16 possible random reward tables. Each table is 32 bytes long. If the RNG lands on a $FF byte, there's no reward.
$80#
03FA97 FF00 FFFF FFFF FFFF FFFF 00FF FFFF FFFF
03FAA7 FFFF FFFF FF00 FFFF FFFF FFFF FFFF FFFF
29/32 $FF (nothing) 90.625%
03/32 $00 Barbecue 09.375%
$81#
03FAB7 FF00 FF12 FF02 12FF 12FF FF02 FF12 FF02
03FAC7 02FF 12FF 02FF 12FF FF02 FF12 0200 FFFF
16/32 $FF (nothing) 50.000%
07/32 $02 Hamburger 21.875%
07/32 $12 Vitamine 21.875%
02/32 $00 Barbecue 06.250%
$82#
03FAD7 08FF 0A08 FF0C 080C 0AFF 0A0C 080A FF0C
03FAE7 0C0A FF0C 080A 0CFF 080A FF08 FF0A 080C
08/32 $08 Banana 25%
08/32 $0A Apple 25%
08/32 $0C Grapes 25%
08/32 $FF (nothing) 25%
$83#
03FAF7 1400 100E 1412 100E 0EFF 1210 0E14 1012
03FB07 1012 0E14 100E 1210 140E 00FF 1412 0E10
08/32 $0E Rootbeer 25.00%
08/32 $10 Soft drink 25.00%
06/32 $12 Vitamine 18.75%
06/32 $14 Gum 18.75%
02/32 $00 Barbecue 06.25%
02/32 $FF (nothing) 06.25%
$84#
03FB17 FFFF FF16 FFFF FFFF FFFF FFFF FFFF FFFF
03FB27 FFFF FFFF FFFF FFFF 18FF FFFF FFFF FFFF
30/32 $FF (nothing) 87.500%
01/32 $16 Diamond 06.250%
01/32 $18 Gold bar 06.250%
$85#
03FB37 1AFF 1CFF 1C16 FF1A 1CFF FF1A FFFF 1CFF
03FB47 1CFF FF1A FFFF 1CFF 1AFF FF1C FF1C 1AFF
17/32 $FF (nothing) 53.125%
08/32 $1C Necklace 25.000%
06/32 $1A Ruby 18.750%
01/32 $16 Diamond 03.125%
$86#
03FB57 161E 1E20 FF16 1E1E 20FF 1E20 1E16 1E20
03FB67 1E1E 20FF 16FF 1E20 FF1E 1E16 1EFF 1E20
14/32 $1E Dollar 43.750%
07/32 $20 Yen 21.875%
06/32 $FF (nothing) 18.750%
05/32 $16 Diamond 15.625%
$87#
03FB77 2422 24FF 2622 1826 2426 22FF 2224 FF26
03FB87 2224 1826 2422 26FF 2224 FF18 2624 2622
08/32 $22 Hat 25.000%
08/32 $24 Radio 25.000%
08/32 $26 Hammer 25.000%
05/32 $FF (nothing) 15.625%
03/32 $18 Gold bar 09.375%
$88#
03FB97 2828 2828 2828 2828 2828 2828 2828 2828
03FBA7 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
16/32 $28 Knife 50%
16/32 $FF (nothing) 50%
$89#
03FBB7 FFFF FFFF FFFF 28FF FFFF FFFF FFFF FFFF
03FBC7 FF2A FFFF FFFF FFFF FFFF FFFF FF2C FFFF
29/32 $FF (nothing) 90.625%
01/32 $28 Knife 03.125%
01/32 $2A Muramasa! 03.125%
01/32 $2C Pipe 03.125%
$8A#
03FBD7 FF28 2A2C 28FF 2A28 2C2C 282A FF2C FF2A
03FBE7 2AFF 282A FF2C 282A 2CFF 282A 2C28 2CFF
08/32 $28 Knife 25%
08/32 $2A Muramasa! 25%
08/32 $2C Pipe 25%
08/32 $FF (nothing) 25%
$8B#
03FBF7 FF2A FFFF FF2A FFFF FFFF FF2A FFFF FFFF
03FC07 FFFF FF2A FFFF FFFF 2AFF FFFF FF2A FFFF
26/32 $FF (nothing) 81.25%
06/32 $2A Muramasa! 18.75%
$8C#
03FC17 2A00 1600 2A16 002A 1616 2A00 2A16 002A
03FC27 0016 2A2A 0016 FF00 162A FF00 1600 2A16
10/32 $00 Barbecue 31.25%
10/32 $16 Diamond 31.25%
10/32 $2A Muramasa! 31.25%
02/32 $FF (nothing) 06.25%
$8D#
03FC37 FF02 2CFF 2202 2CFF 22FF FFFF 22FF 2CFF
03FC47 2C22 FF02 FFFF 22FF FF02 FF2C FFFF 02FF
17/32 $FF (nothing) 53.125%
05/32 $02 Hamburger 15.625%
05/32 $22 Hat 15.625%
05/32 $2C Pipe 15.625%
$8E#
Contains every item except $22 Hat
03FC57 0000 0204 0406 080A 0A0C 100E 0E12 1416
03FC67 181A 1A1C 1C1E 1E20 2424 2628 2A2C FFFF
02/32 $00 Barbecue 06.250%
02/32 $04 Pizza 06.250%
02/32 $0A Apple 06.250%
02/32 $0E Rootbeer 06.250%
02/32 $1A Ruby 06.250%
02/32 $1C Necklace 06.250%
02/32 $1E Dollar 06.250%
02/32 $24 Radio 06.250%
02/32 $FF (nothing) 06.250%
01/32 $02 Hamburger 03.125%
01/32 $06 Curry 03.125%
01/32 $08 Banana 03.125%
01/32 $0C Grapes 03.125%
01/32 $10 Soft drink 03.125%
01/32 $12 Vitamine 03.125%
01/32 $14 Gum 03.125%
01/32 $16 Diamond 03.125%
01/32 $18 Gold bar 03.125%
01/32 $20 Yen 03.125%
01/32 $26 Hammer 03.125%
01/32 $28 Knife 03.125%
01/32 $2A Muramasa! 03.125%
01/32 $2C Pipe 03.125%
$8F#
03FC77 2628 FF14 FF28 FFFF 26FF FF14 FFFF 28FF
03FC87 14FF FF26 FF28 FFFF 1428 FF26 FFFF FF28
18/32 $FF (nothing) 56.25%
06/32 $28 Knife 18.75%
04/32 $14 Gum 12.50%
04/32 $26 Hammer 12.50%