Announcement

Collapse
No announcement yet.

[NES] Karnov (USA/Japan) - K-Mark Health Meter MOD

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

  • [NES] Karnov (USA/Japan) - K-Mark Health Meter MOD

    I thought it would be nice to have more than two hits in Karnov, so I have created a patch which changes the game slightly, to give the player a bit of a health meter.

    As you progress through the game, you collect 'K-marks', little K icons. Once you get to 50 of them, you get a free life.

    With this patch, K-marks also act as a health meter. You can still get hit and will turn blue, however if you're hit when blue and have K-marks, you will simply lose K-marks instead of dying. Once you run out of K-marks, you will die like usual.

    This patch works on both the USA and Japan versions of the game.

    To apply, either use the IPS file with Lunar IPS Patcher, or you can use a Hex Editor such as HxD to make the following two edits to the ROM file:

    Code:
    0x1CA41: 4C 10 FF
    0x1FF20: A5 BA F0 09 C6 BA A9 C0 85 68 4C 8A CB A5 5D 4A 4C 34 CA
    Enjoy!

    I have playtested it but if anyone else wants to try it and report any bugs if found that would be awesome!


    Development Notes:

    Spoiler Alert! Click to view...


    The routine at $CA31 is what initiates player death:

    Code:
     07:CA30:60        RTS -----------------------------------------
    >07:CA31:A5 5D     LDA $005D = #$00
     07:CA33:4A        LSR
     07:CA34:B0 19     BCS $CA4F
     07:CA36:A5 62     LDA $0062 = #$00
     07:CA38:29 80     AND #$80
     07:CA3A:09 19     ORA #$19
     07:CA3C:85 62     STA $0062 = #$00
     07:CA3E:A5 64     LDA $0064 = #$B0
     07:CA40:38        SEC
     07:CA41:E9 20     SBC #$20
     07:CA43:85 64     STA $0064 = #$B0
     07:CA45:A9 02     LDA #$02
     07:CA47:20 1D C8  JSR $C81D
    I created a hook at $CA31 to redirect to my own routine:

    Code:
    PATCH:
    CA31: 4C 10 FF
    
    changes the code at $CA31 to:
    
    >07:CA31:4C 10 FF  JMP $FF10
     07:CA34:B0 19     BCS $CA4F
    Also, during testing when I almost had this working, I noticed that the player's
    K-marks would almost all instantly disappear when hit. This is because the player
    had no invincibility when hit, so every frame of gameplay registers another hit.

    So I gave the player a bit of invincibility when hit, just like usual.

    Normally $0068 is set to $C0 to become temporarily invincible:

    Code:
     07:CB7E:A9 C0     LDA #$C0
     07:CB80:05 68     ORA $0068 = #$00
    >07:CB82:85 68     STA $0068 = #$00
     07:CB84:A9 80     LDA #$80
     07:CB86:85 69     STA $0069 = #$12
     07:CB88:A9 00     LDA #$00
     07:CB8A:60        RTS -----------------------------------------
    We can simply store a value of C0 in $68 to turn invincible. Awesome!


    Here's my new routine that handles the K-mark Health Meter. I placed it at $FF10:

    Code:
    FF10: A5 BA F0 09 C6 BA A9 C0 85 68 4C 8A CB A5 5D 4A 4C 34 CA
    
    ASSEMBLY:
    =========
    FF10: A5 BA     LDA $00BA       # Load K-mark counter
    FF12: F0 09     BEQ AllowDeath  # If zero, allow death
    
    :RemoveKMark
    FF14: C6 BA     DEC $00BA       # Otherwise remove one K-mark
    FF16: A9 C0     LDA #$C0        # Load 'invincible' value of #$C0
    FF18: 85 68     STA $0068       # Turn the player invincible temporarily
    FF1A: 4C 8A CB  JMP $CA30       # Then return without dying
    
    :AllowDeath                     # Branch here if the player has no K-marks
    FF1D: A5 5D     LDA $5D         # (code from $CA31) Load value at $5D
    FF1F: 4A        LSR             # (code from $CA33) Logical shift right
    FF20: 4C 34 CA  JMP $CA34       # We now return you to your regular programming at $CA34
    Works like a charm! I'm quite proud of this little hack!
    Attached Files
    "One man's garbage is another man-person's good un-garbage." -- Ricky from Trailer Park Boys
Working...
X