Announcement

Collapse
No announcement yet.

[NES] Freedom Force (USA)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [NES] Freedom Force (USA)

    Cannot Die (health will still decrease)
    AAVATLEA

    No damage from machineguns and most grenades
    AEXALAPA + SZNAZESU

    No damage from rockets
    AEXAYEAA + SZNAYESU

    Take less damage in later levels
    PEOEYAZA + SZVEIESU

    No damage from missiles 1P
    SZOLLKSE

    No damage from missiles 2P
    SZELYKSE

    Levels complete after killing 1 enemy
    ENXTAYAP

    Levels complete instantly
    AEXTPYLA

    Skip bonus round (still get the bonus)
    ESNIXLEY

    Freeze timer in bonus round
    SZOIULVG

    No errors in bonus round
    SXUSVLVT

    Infinite ammo 1P (alternate to Galoob code)
    SXKVANVK

    Infinite ammo 2P (alternate to Galoob code)
    SXSTLNVK

    Infinite errors allowed (alternate to Galoob code)
    NNOVAYTE

    No errors allowed (increase difficulty)
    PEOVAYTA

    Items stay on screen longer
    NNSLIEGK + SGOLGEOS

    Picking up .38 cal gives you grenade launcher 1P
    ZASZVYAA

    Picking up .44 mag gives you grenade launcher 1P
    ZAKZOYPA

    Picking up .38 cal gives you grenade launcher 2P
    ZESZUYAA

    Picking up .44 mag gives you grenade launcher 2P
    ZEUXVYPA


    Well, I had a lot of fun making codes for this game! I made about half these codes before checking the DB (bad habit of mine), then checked the codes DB and saw some of these are already worked out in RAW format. However I always try to make assembly code hacks where possible to make GG codes, so they can be used on a real console with a Game Genie.

    A couple notable codes that really improve gameplay in my eyes are the "Items stay on screen longer" and the lesser damage codes. I find the amount of damage inflicted to the player to be excessive, considering if you die once it's game over.


    PS: I also took a crack at making a "No screen blanking" code for playing this on an emulator, to try to get rid of the annoying screen blanking required for the light gun. I had success getting rid of the blanking and keeping some sort of hit detection, unfortunately though one shot will hit everything on the screen.

    My work on it is as the end of the notes below. If any devs want to have a look at it that would be great! A working "no screen blanking" code would be awesome!


    Code Development Notes:


    Spoiler Alert! Click to view...

    Cannot Die (both players, health will still decrease)
    AAVATLEA

    Code:
    Initially I tried making codes to prevent the player's health from decreasing,
    however it would require a lot of GG codes because there are multiple routines
    for reducing the player's health.
    
    Instead I focused on what happens when the player runs out of health to prevent
    the player from dying.
    
    An idle loop constantly checks on 1P/2P health remaining. If it falls low enough, 
    a value will be loaded into $C3 which indicates player death. Changing the value 
    loaded at $8365 will prevent player death when health gets to zero.
    
     06:8357:AE 16 05  LDX $0516 = #$00
     06:835A:A5 C1     LDA $00C1 = #$00
     06:835C:10 03     BPL $8361
     06:835E:AE 26 05  LDX $0526 = #$18
     06:8361:CA        DEX
     06:8362:8A        TXA
     06:8363:10 04     BPL $8369
    >06:8365:A9 80     LDA #$80
     06:8367:85 C3     STA $00C3 = #$00
     06:8369:20 56 AE  JSR $AE56
    
    
       8366:00:80 = AAVATLEA


    No damage from machineguns and most grenades
    AEXALAPA + SZNAZESU

    No damage from rockets
    AEXAYEAA + SZNAYESU

    Take less damage in later levels
    PEOEYAZA + SZVEIESU

    Code:
    Health points deducted are stored at $83-$85, initialized here:
    
     06:806D:BD 9F 80  LDA $809F,X @ $809F = #$02
    >06:8070:85 83     STA $0083 = #$00
     06:8072:BD A3 80  LDA $80A3,X @ $80A3 = #$01
    >06:8075:85 85     STA $0085 = #$00
     06:8077:BD A7 80  LDA $80A7,X @ $80A7 = #$08
    >06:807A:85 84     STA $0084 = #$00
    
    $83 is used for enemy pistols, $84 for rocket launchers, and $85 for
    machineguns and grenades. An indexed table is used for later levels.
    
    Setting $80A3 to 00 causes enemy machineguns/grenades to do no damage.
    
    For the code to work on every level, the indexed LDA (BD) must be
    changed to an absolute LDA (AD).
    
       80A3:00:01 = AEXALAPA
       8072:AD:BD = SZNAZESU
    
    Changing $80A7 will change the amount of damage rocket launchers do. It
    also needs an indexing fix for later levels.
    
       80A7:00:08 = AEXAYEAA
       8077:AD:BD = SZNAYESU
    
    
    After more playtesting I realized $0083 is also adjusted to higher 
    multiples in later levels, resulting in lots of damage quickly. 
    Setting it to a value of 01 results in less damage in later levels.
    
       809F:01:02 = PEOEYAZA
       806D:AD:BD = SZVEIESU
    
    These codes work for both 1P and 2P.
    No damage from missiles 1P
    SZOLLKSE

    No damage from missiles 2P
    SZELYKSE

    Code:
    Missiles (on the last level) have their own code to hurt the player.
    Normally a missile will do 22 HP worth of damage, pretty brutal considering
    each player has a maximum of 24 HP.
    
     06:B3FD:A5 C1     LDA $00C1 = #$80     # Check for 1P/2P
     06:B3FF:10 0C     BPL $B40D            # If 1P, go to $B40D
     06:B401:AD 26 05  LDA $0526 = #$0C
     06:B404:38        SEC
     06:B405:E9 16     SBC #$16             # Deduct 22 of the 24 possible HP (2P)
    >06:B407:8D 26 05  STA $0526 = #$0C
     06:B40A:4C 3B A8  JMP $A83B
     06:B40D:AD 16 05  LDA $0516 = #$00
     06:B410:38        SEC
     06:B411:E9 16     SBC #$16             # Deduct 22 of the 24 possible HP (1P)
     06:B413:8D 16 05  STA $0516 = #$00
     06:B416:4C 3B A8  JMP $A83B
    
    Changing $B407/$B413 to a LDA will prevent this from happening.
    
       B413:AD:8D = SZOLLKSE (1P)
       B407:AD:8D = SZELYKSE (2P)

    Levels are completed after killing 1 enemy
    ENXTAYAP

    Levels are completed instantly
    AEXTPYLA

    Code:
    The counter for enemies killed is stored at $C2, and incremented in several places.
    
    >06:A235:E6 C2     INC $00C2 = #$03
     06:A237:20 A9 AD  JSR $ADA9
    
    Initially I tried changing $A235 to DEC $00C2, it worked initially however in later 
    levels other code is used to adjust $C2.
    
    Instead, I checked the read of $C2 and there is an idle loop that checks the value
    and once enough enemies are killed it will jump to $E7E9 to end the level:
    
     07:E79E:A5 C2     LDA $00C2 = #$0A
     07:E7A0:10 03     BPL $E7A5
     07:E7A2:4C E9 E7  JMP $E7E9
    
    Changing $E7A0 to a BEQ will cause the level to end after killing one enemy.
    
       E7A0:F0:10 = ENXTAYAP
    
    A variation is to always take the branch to $E7E9 by zeroing the branch value.
    This will end the level immediately.
    
       E7A1:00:03 = AEXTPYLA

    Skip bonus round (still get the bonus)
    ESNIXLEY

    Code:
    Tinkering with RAM I found that $0700-$0707 hold the letters on the bonus screen.
    I set a read breakpoint and found this loop:
    
    >07:DBE4:BD 00 07  LDA $0700,X @ $0704 = #$1B
     07:DBE7:C9 1B     CMP #$1B
     07:DBE9:D0 02     BNE $DBED
     07:DBEB:E6 10     INC $0010 = #$00
     07:DBED:CA        DEX
     07:DBEE:10 F4     BPL $DBE4
     07:DBF0:A5 10     LDA $0010 = #$00
     07:DBF2:F0 03     BEQ $DBF7
     07:DBF4:4C F7 DA  JMP $DAF7
    
    The value at $10 seems to be a "round completion" register of some kind. It
    normally contains 01 when the bonus round is running.
    
    Changing the BEQ instruction to BNE results in the bonus round automatically 
    ending.  Player still gets the bonus. :)
    
       DBF2:D0:F0 = ESNIXLEY

    Freeze timer in bonus round
    SZOIULVG

    Code:
    The value for the bonus timer is stored at $88/89.  
    The code here decrements the second digit:
    
    >07:DB13:C6 89     DEC $0089 = #$04
    
    Changing this to a LDA prevents the timer from decreasing.
    
       DB13:A5:C6 = SZOIULVG

    No errors in bonus round
    SXUSVLVT

    Code:
    The error counter for the bonus round is stored at $A5.  
    The code here increments it:
    
    >07:DBBE:E6 A5     INC $00A5 = #$02
    
    Changing this to a LDA prevents the error counter from increasing.
    
       DBBE:A5:E6 = SXUSVLVT
    
    (so awesome that the code val/cmp is an inversion of the instruction at $DBBE. hah)


    Infinite ammo 1P (alternate)
    SXKVANVK

    Infinite ammp 2P (alternate)
    SXSTLNVK

    Code:
    The counter for remaining ammo is at $0515 (1P) / $0525 (2P). 
    Ammo value is decremented here:
    
    1P:
    >07:E7C8:CE 15 05  DEC $0515 = #$24
    
    2P:
    >07:E7D3:CE 25 05  DEC $0525 = #$23
    
    Changing this to a LDA gives infinite ammo.
    
    E7C8:AD:CE = SXKVANVK
    E7D3:AD:CE = SXSTLNVK
    
    PS: I noticed after I made this that Galoob also has a code for Infinite Ammo, 
    but it targets a slightly different region so I decided to keep this code.



    Infinite errors allowed (alternate)
    NNOVAYTE

    No errors allowed (increase difficulty)
    PEOVAYTA


    Code:
    The number of hostages killed is stored at $0517 (1P) / $0527 (2P).  The value is 
    checked in several places, but this is the one that matters. If too many hostages 
    have been killed the jump to $E98D is taken and then it's all over.
    
    This code works for both 1P and 2P, because the routine at $C391 loads the
    appropriate player specific value from $0517 / $0527:
    
     07:C391:A4 C1     LDY $00C1 = #$80
     07:C393:30 04     BMI $C399
     07:C395:BD 10 05  LDA $0510,X @ $0517 = #$06
     07:C398:60        RTS -----------------------------------------
     07:C399:BD 20 05  LDA $0520,X @ $0527 = #$06
     07:C39C:60        RTS -----------------------------------------
    
    >07:E797:C9 06     CMP #$06
     07:E799:90 03     BCC $E79E
     07:E79B:4C 8D E9  JMP $E98D
     07:E79E:A5 C2     LDA $00C2 = #$00
    
    Changing the compare to #$FF will result in the jump to $E98D never
    being taken, so killing hostages won't end the level.
    
       E798:FF:06 = NNOVAYTE
    
    A difficulty variation on this code is easy, simply making it so
    that only one civilian killed will end the level.
    
       E798:01:06 = PEOVAYTA
    
    PS: I noticed after I made this code that Galoob made one as well,
    but it's slighty different (uses LDA instead of changing the CMP 
    value) so I decided to keep this code.


    Items stay on screen longer
    NNSLIEGK + SGOLGEOS

    Code:
    The default item timeout seems to be random, sometimes items are on screen
    for a couple seconds, most times they just flash and then disappear as soon
    as you notice them. This sucks! I made a code to deal with this.
    
    The value at $A1 indicates whether bonus item is available on screen.
    
     06:AEF6:A9 01     LDA #$01
     06:AEF8:85 A1     STA $00A1 = #$01
     06:AEFA:20 1F A8  JSR $A81F
       06:A81F:A5 87     LDA $0087 = #$00
       06:A821:0A        ASL
       06:A822:0A        ASL
       06:A823:0A        ASL
       06:A824:0A        ASL
      >06:A825:AA        TAX
       06:A826:60        RTS -----------------------------------------
     06:AEFD:BD 0F 04  LDA $040F,X @ $040F = #$00
     06:AF00:30 03     BMI $AF05
    >06:AF02:4C 0A B0  JMP $B00A
     06:AF05:20 A9 AD  JSR $ADA9
    
    
    A loop determines how long the item stays on the screen for by comparing
    against the table starting at $B0D5:
    
     06:B011:BD 00 04  LDA $0400,X @ $0400 = #$12
    >06:B014:D9 D5 B0  CMP $B0D5,Y @ $B0D7 = #$30
     06:B017:D0 07     BNE $B020
     06:B019:A9 00     LDA #$00
     06:B01B:85 A1     STA $00A1 = #$01
     06:B01D:4C 3B A8  JMP $A83B
    
    Changing $B0D5 to $FF results in a longer screen time for the first item slot.
    
       B0D5:FF:4C = NNSLIEGK
    
    The indexed compare (D9) also needs to be changed to an absolute compare (CD)
    so that the long timeout value is used for all items.
    
       B014:CD:D9 = SGOLGEOS
    
    This code works for both 1P and 2P.


    Picking up .38 cal gives you grenade launcher 1P
    ZASZVYAA

    Picking up .38 cal gives you grenade launcher 2P
    ZESZUYAA

    Picking up .44 mag gives you grenade launcher 1P
    ZAKZOYPA

    Picking up .44 mag gives you grenade launcher 2P
    ZEUXVYPA

    Code:
    I like using the grenade launcher, who doesn't? But when a .38 or .44 pops up
    and you are firing the grenade launcher, you may lose it because you pick up 
    the new weapon.  I made codes so that you always get the grenade launcher. :)
    
    The weapon status indicator is at $C7. It's valid for both players.
       00 = .38 calibre
       01 = .44 magnum  
       02 = Grenade Launcher!
    
    Picking up G.L:
    
    1P:
     06:AF2B:A9 02     LDA #$02
    >06:AF2D:85 C7     STA $00C7 = #$00
    
    2P:
     06:AFA8:A9 02     LDA #$02
    >06:AFAA:85 C7     STA $00C7 = #$00
    
    ========================
    
    Picking up .38 cal:
    
    1P:
     06:AF55:A9 00     LDA #$00
    >06:AF57:85 C7     STA $00C7 = #$02
    
    2P:
     06:AFD2:A9 00     LDA #$00
    >06:AFD4:85 C7     STA $00C7 = #$02
    
    Actually let's make that .38 cal a grenade launcher!
    
       AF56:02:00 = ZASZVYAA
       AFD3:02:00 = ZESZUYAA
    
    ========================
    
    Picking up .44 mag:
    1P:
     06:AF40:A9 01     LDA #$01
    >06:AF42:85 C7     STA $00C7 = #$02
    
    2P:
     06:AFBD:A9 01     LDA #$01
    >06:AFBF:85 C7     STA $00C7 = #$02
    
    Actually let's make that .44 mag a grenade launcher!
    
       AF41:02:01 = ZAKZOYPA
       AFBE:02:01 = ZEUXVYPA


    INCOMPLETE/BETA CODE:
    No screen blanking (for using emulators w/mouse click)
    UINVOYOS + ENVGPLAZ + ZEVGZLZU

    Major bug: screen blanking is gone but every enemy/hostage gets hit now.

    Code:
    I have an LCD TV and in order to play this game I use an emulator with a modded light 
    zapper (wireless gyroscope bluetooth mouse, feels much like using a Wiimote).
    
    As such I was looking for a way to remove the screen blanking that the game normally 
    uses for the light zapper to operate.
    
    
    The routine at $C3D1 is what handles the hit detection and blanking of the screen.
    
    >07:EF78:20 D1 C3  JSR $C3D1
    
    >07:C3D1:A9 AA     LDA #$AA
     07:C3D3:85 F0     STA $00F0 = #$FF
     07:C3D5:A5 FE     LDA $00FE = #$1E
     07:C3D7:29 E1     AND #$E1
     07:C3D9:85 FE     STA $00FE = #$1E
     07:C3DB:A9 00     LDA #$00
     07:C3DD:85 DE     STA $00DE = #$20
     07:C3DF:85 DD     STA $00DD = #$80
     07:C3E1:20 32 B5  JSR $B532
     07:C3E4:20 5D B5  JSR $B55D
     07:C3E7:20 00 C0  JSR $C000
     07:C3EA:20 00 C0  JSR $C000
     07:C3ED:A5 C7     LDA $00C7 = #$02
     07:C3EF:29 03     AND #$03
     07:C3F1:C9 02     CMP #$02
     07:C3F3:F0 09     BEQ $C3FE
     07:C3F5:A5 FE     LDA $00FE = #$1E
     07:C3F7:09 14     ORA #$14
     07:C3F9:85 FE     STA $00FE = #$1E
     07:C3FB:4C 19 C4  JMP $C419
    
    It seems that $FE has to do with the blanking, also $DE/DD have to do with
    palettes I believe.  The routine at $C000 seems to be a delay routine.
    
    The first thing I tried is a simple hack, C3D1:60:A9 (RTS) but then no hits 
    are registered at all on the screen. Go figure.
    
    I was able to bypass most of this and keep the hit detection working by making
    two patches.  First, I made the jump at $EF78 go to $C3DB, to skip over the
    setting of $F0 and $FE to prevent the screen blanking.
    
       EF79:DB:D1 = UINVOYOS
    
    Just doing that by itself however seems to break the hit detection.
    
    Doing some playing around, I tried inserting a branch at $C3E1 to skip past
    the four JSR's and end up at $C3ED.  This by itself makes the flashes much
    quicker but the screen still turns black for a brief second.
    
       C3E1:F0:20 = ENVGPLAZ 
       C3E2:0A:32 = ZEVGZLZU
    
    However combining these two patches seems to make the black flashes go away
    and keeps the hit detection intact.  There is still a quick flash of garbled 
    graphics that I believe are normally covered by the blanked screen, but it's 
    less distracting than the complete blackout.
    
    The new code flow looks like this:
    
    >07:EF78:20 DB C3  JSR $C3DB
    
    >07:C3DB:A9 00     LDA #$00
     07:C3DD:85 DE     STA $00DE = #$50
     07:C3DF:85 DD     STA $00DD = #$80
     07:C3E1:F0 0A     BEQ $C3ED
    
     07:C3E3:B5 20 5D B5 20 00 C0 20 00 C0 
    
     07:C3ED:A5 C7     LDA $00C7 = #$00
     07:C3EF:29 03     AND #$03
     07:C3F1:C9 02     CMP #$02
     07:C3F3:F0 09     BEQ $C3FE
     07:C3F5:A5 FE     LDA $00FE = #$1E
     07:C3F7:09 14     ORA #$14
     07:C3F9:85 FE     STA $00FE = #$1E
     07:C3FB:4C 19 C4  JMP $C419
    
    
    After playtesting, I realized that this does actually completely break the 
    hit detection.  Now every enemy/hostage is hit automatically no matter where you
    aim.  Ahh crap.  Maybe I will revisit this code at some point. Would be awesome!
    "One man's garbage is another man-person's good un-garbage." -- Ricky from Trailer Park Boys
Working...
X