Romhacking.net

Romhacking => Newcomer's Board => Topic started by: frsj8112 on January 04, 2016, 08:24:27 am

Title: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 04, 2016, 08:24:27 am
Hi guys!

I've been away for a while, my family has had me occupied  ;)

One of my favorite NES games is Kid Icarus, but the password system is so tedious to use.
So I wanted to get more in to NES hacking other than text altering.

I've followed some of our forum friends hacks (Retrorain, umaggot) and I do understand the principle of storing information in the $6000-$8FFF RAM range.

I've managed to hijack a routine in the ROM (bank 7, always available in Kid Icarus if I've understood it correctly) and moved it inside a new routine, made by me, just to see if it works.

So everytime I collect a heart that's been left when an enemy has been killed, the heart counter will increase and that value will be stored at $6200. I used $6200 because there seemed to be values written to$6000-$60AC.

And that is now working successfully.

But now I would like to try and load data from SRAM.
I was thinking of hacking the menu after you press start at the title screen. If i push the start button at Continue, how can I then hijack into my load-routine and then start my game with hearts loaded from my SRAM?

Sorry for the newbie questions, but we're all newbs at the beginning right?  ;)
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 04, 2016, 11:16:08 am
Just a quick fix:  On-cartridge RAM is in range 6000-7FFF (not 8FFF)


For saved games you typically need 2 copies for everything:
1)  The value the game actually uses
2)  The "saved" value

When you save a game, you just copy all of #1's values to #2.  And when you load a game, you copy all of #2's values to #1.

In your case, your continue code would copy the heart value from SRAM to regular RAM, then would just jump to the game's normal starting code.  The only thing to note is that you'll have to jump to AFTER the point where it zero's out the initial heart value.
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 04, 2016, 12:34:27 pm
Thanks Disch, I missed that about the SRAM range :)

Title: Re: Kid Icarus, adding SRAM save function
Post by: snarfblam on January 04, 2016, 06:12:41 pm
All I did in Metroid + Saving (http://www.romhacking.net/hacks/1186/) was copy the password to SRAM when a gameover occurred, and copy it back to the password RAM and jump to the routine that decodes it when the player starts. On top of that, you can copy any additional variables to SRAM you see fit and copy them back when the player starts, e.g. I saved the player's health in addition to information encoded in the password.
Title: Re: Kid Icarus, adding SRAM save function
Post by: dACE on January 05, 2016, 02:20:59 am
Now - this is interesting. Kid Icarus is the only physical cartridge I actually still own.

Have you looked anything at the FDS version? It has a zelda-style save feature (if im not misstaken).

Snarfblam: about how many bytes, as an absolute minimum, of custom ASM would you need to allocate space for inside a Rom - to be able to implement a 'simple' password to sram feature (approximately)?

/dACE
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 05, 2016, 11:43:37 am
Typical copy loop:

Code: [Select]
LDX #length_of_bytes_to_copy - 1
loop:
  lda source, X
  sta dest, X
  dex
  bpl loop  ; only works if copying 128 bytes or less
jmp back_to_original_game_code

Assuming source and dest are 16 bit addresses, that's 14 bytes for a one-way copy.  You'll need 2 (one for saving and one for loading), so that's 28 bytes.

You'd be able to combine both into a single routine by using pointers, but prepping the pointers would take more space than the above code.


Also, the password idea is pretty neat.  I hadn't even considered that.


EDIT:

I suppose you could shave 2 bytes off that code if you RTS out of it rather than JMP back.  =P
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 05, 2016, 02:26:48 pm
So i'm back again after a while of studying read and writes to RAM and "Password SRAM" :)

I did follow snarfblam's advice do use the password system to dump the "Password SRAM" in between 600D-6027 to the range 610D-6127. And now that data is saved between resets, yay :)

Now to hijack the screen where the password's are entered. I've sorted out the loading from the new range 610D-6127, but i want to skip the password screen entirely.

I'll be back.

January 07, 2016, 04:58:07 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Darn, this hijacking the menu screen to jump into my loading routine was hard!

does anyone of you guru's have any tips on how to do this?
i can see that the RAM values 00B1 and 00B2 are used but then it gets too complicated understand where the password screen is fetched from :/
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 08, 2016, 02:38:07 pm
My approach here would be:

1)  Go to the continue screen and start inputting a password.  Watch RAM to see where the password is being stored as you input it.

2)  Set a read breakpoint on the first password byte.  Then press start to finish.  The breakpoint will trip as the game analyzes your password.

3)  Find the start of the routine (this is typically where I have a copy of the full game disassembly -- so I can disect it and take notes).

4)  Do the same thing for when the game gives you a password.  Get to such a screen, look at RAM to see where the password is stored.

5)  Set write breakpoint on that area of RAM, then rewind/load state and get the game to show the password again, triggering the breakpoint.

6)  Find the start of the routine



The idea here being... to save the game, you'd change whatever code is calling the #6 routine and change it so instead of actually drawing the password screen, you'd just have it save the password to SRAM.  Then to load the game, you'd change the #3 routine so instead of taking the user to an input screen, it just loads the password from SRAM.


Free space shouldn't be an issue, as you're effectively stripping the entire password display and input screens, so you can wipe all of that code and replace it with your own.  Though you will want to keep the password generation/parsing code in tact.
Title: Re: Kid Icarus, adding SRAM save function
Post by: dACE on January 08, 2016, 06:32:14 pm
Also, regarding space - there is a MMC3 patch for Kid Icarus.
If I understand it correctly - that would free up a heap-load of free space for custom ASM.

/dACE
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 08, 2016, 07:34:51 pm
Cart before the horse.  There's no point in changing mappers unless you gain something from it.  Replacing the password screen with a simple save mechanism should not require ROM expansion or a mapper change.  If you find yourself needing that, you are doing something very wrong.

Plus, honestly... if you're going to change mappers to make more space for asm hacks, you're better off doing it yourself so you can know what changes are made and what the implications of calling swap routines are.  Slapping on an external patch introduces a bunch of potential compatibility issues.  That patch might be using space that you're using for your asm hacks... or maybe it moves the swap routine around, or maybe it uses some extra area in RAM, etc, etc.  I hold that pre-made mapper hacks are all but worthless.
Title: Re: Kid Icarus, adding SRAM save function
Post by: snarfblam on January 09, 2016, 12:47:12 pm
I hold that pre-made mapper hacks are all but worthless.

If they came with source and documentation, they would at least be usable (though still of questionable benefit). I wonder how many of these mapper hacks do things like safeguard against corrupted register writes and unexpected bank configurations when NMI jumps into the middle of things.

Regarding space, I would think that if you're adding a save feature, you're going to have some stuff that won't be needed anymore. The first thing that comes to mind is nametable data for password display and entry screens. Find that and you easily have enough space for a minimal SRAM hack.
Title: Re: Kid Icarus, adding SRAM save function
Post by: Kea on January 09, 2016, 01:57:41 pm
People upload mapper hacks without including source+doc? That's missing 90% of the point...

But in general, it's best to work with the original mapper if at all possible. Using a different mapper can complicate your work and introduce new bugs, especially if you're using a mapper patch and don't know what it's actually modifying.
Title: Re: Kid Icarus, adding SRAM save function
Post by: dACE on January 09, 2016, 03:29:23 pm
Yeah - mapper conversion or rom-expansion was a terrible idea for getting more space...

What was I thinking!

FYI - Here is the patch I was referring to:
http://www.romhacking.net/hacks/2455/ (http://www.romhacking.net/hacks/2455/)

I have not downloaded it - but the author is reassuring that: Documentation is included

EDIT

So - I took a look at the documentation and it's not very much.

Still - infidelity (the author) is probably still around if there are any questions about what's been done (and how it has been done).
/dACE
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 09, 2016, 07:24:54 pm
I just downloaded the patch to look.  Documentation is spotty at best.  He lists a bunch of offsets and what he changed the values to, and tells you where the swap routine is... but there aren't really comments on what any of the changes really do.

I guess it's useful in making sure it doesn't clobber offsets you've already modified, but apart from that you're left just as much in the dark as you would be if you just applied the patch blindly.

People upload mapper hacks without including source+doc?

I don't get why people do it at all.  There have been discussions on this on these boards in the past, and I'll say here what I've said there:  Mapper hacks are completely useless to casual hackers.  The only person that is going to get any use out of a mapper change is someone who is doing heavy code writes and who has a decent understanding of mappers and NES architecture.  And that kind of hacker would not only have no problem doing the mapper hack themselves -- but they'd be better off for it because it would expose them to internal mechanics of the game they're hacking.

I honestly can't fathom how these kinds of hacks would be of use to anyone.

A document?  Sure.  Trace some code and throw it up as a doc, or put it on datacrystal or something.  But I just don't see the value of a patch.

But maybe that's just be being a grouchy old curmudgeon.
Title: Re: Kid Icarus, adding SRAM save function
Post by: KingMike on January 09, 2016, 10:42:34 pm
Note that when saving/loading a password from SRAM, you'd probably want to avoid an error by adding a checksum to the password itself to ensure a valid password is stored. And maybe if the test fails, load a default "new game" password.
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 09, 2016, 11:07:37 pm
Passwords are checksummed already -- that's the mechanic that prevents you from just inputting random garbage and having it launch you into the game.

But yeah, you're right... when loading a game, you'll want to check for a failed password load just in case, and probably jump to new game code as a fallback.
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 12, 2016, 05:49:21 pm
Ok guys, this is how far I've come with this.

https://youtu.be/hDOA7-xtcmc

The save to sram runs in the same way as the password generator. Which means that the items, arrow strength, amount of hearts etc etc, when you enter a new stage, will be added to the SRAM at $6200.

Then when I reset and choose Continue and the press Start, the values from the $6200 range will be copied over to the range $600D and then re-using the password loading routine to copy those values to the in-game CPU RAM (see the almightyguru document for the value locations).

So I think I'm getting somewhere. But i still need to get rid of the password screen when continuing a game. And when selecting a new game, the same routines are called, so the game loads from SRAM, but starts at the first level, so I need to have some check to see if Im selecting New game or Continue.
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 12, 2016, 06:43:07 pm
New Game and Continue code should fork at some point -- probably immediately after the 'Start' button is processed from the new game/continue screen.

New Game will have 2 basic steps:
1)  var initialization... resetting hearts to zero, strength to 1, etc)
2)  JMP/JSR to somewhere I'll call "Entry", which is where it actually starts running the game.

Continue will have a different set of steps:
1)  It will draw the password screen
2)  It will have a big routine to get the password input from the user
3)  It will run that input and run it through a password decrypter, which verifies it and converts it to # hearts, life, level, etc
4)  It will JMP/JSR to the same 'Entry' spot that the New Game code jumps to.



You do not want to disrupt anything with the New Game path.  It sounds like you are, so your changes are probably a little screwy.

Instead, you want to hijack the Continue code to completely cut out steps 1 and 2... and replace it with a small routine that copies the password from SRAM to whatever spot the password screen uses to hold the input password.  Then you just let step 3 take over and decrypt the password normally.



The 'Entry' spot shouldn't be too hard to find... as it might be the only point at which the NewGame/Continue code rejoins after forking.
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 18, 2016, 06:53:49 pm
Hi again, I've corrected the issues with selecting New game and SRAM being loaded.

Also I've followed your advice Disch and I managed to find where to hijack the menu, so that when selecting Continue, the game loads the values from SRAM and then bypasses the password screen and starts up the game.

Now i only have to tackle the Game over screen, so it skips the zero's and says like:
GAME SAVED
PRESS START TO CONTINUE

Video to see the current result: https://youtu.be/DOPzZdyE2qk
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 18, 2016, 08:47:03 pm
Now i only have to tackle the Game over screen, so it skips the zero's and says like:
GAME SAVED
PRESS START TO CONTINUE

Text changes are pretty straightforward.

As for removing the password display --- that's as simple as NOP'ing out a JSR.  When the game draws this screen it's almost certainly doing a JSR to a routine that writes the password to the display.  NOP that JSR out and you'll prevent it from drawing it.

1)  Save a state just before dying
2)  Die
3)  At the game-over screen, fire up the PPU editor and hover over the first '0' in the password to see what PPU address it's located at
4)  Set a write breakpoint at that address in PPU memory
5)  Load state
6)  Die again
7)  Breakpoint should trigger exactly twice:  Once for when the game clears the screen, and again for when it draws the password.  (but you might want to repeat steps 5-7 until you know it's drawing the password)
8 )  Trace the code that leads to that breakpoint (you can use FCEUX's trace logger) to find the JSR you're interested in.
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 19, 2016, 04:15:45 am
Thanks again Disch, i've found the routine that spits out the password and that has now been bypassed.

How would I approach to add more text under Game Saved?
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 19, 2016, 12:44:15 pm
Find the text in the ROM and change it   :P

There's a number of guides on this site for easy ways to find and change text.  Though if you want to take the ASM approach, you can do exactly what you did to find the password print routine.  Set a PPU breakpoint on wherever the text is being drawn and trace to the code to find the text itself.

Remember that all the code you bypassed for password printing, password input, etc --- all of that is free space now, since the game is no longer using it.  So if you need additional space to hold more text, or if you need to squeeze in a new routine or two... you have a ton of space to work with.
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 20, 2016, 04:10:22 pm
Hehe of course ;)

Yes, but I have found the text and the pointer to the string as well. I've moved the string to another location in the ROM and adjusted the pointer, so that is working fine.
But I don't seem to get the line break to work.

There's one string that's appearing just before the last stage (Medusa stage), which says:
"Pit equipped himself
with the 3 treasures"

So there's a line break just after himself, which is in the form FE 25 29. So it's like "himself FE 25 29 with"

But if I add like FE 15 15, the game interprets those as tiles and not a line break. it then looks like this:
(http://v2.pxl.se/i/JU.png)

Any ideas?
Title: Re: Kid Icarus, adding SRAM save function
Post by: Disch on January 20, 2016, 06:24:08 pm
The drawing routine it's using might not support a line break then.

You'll have to draw a second string.

String drawing usually loads a source pointer and a destination coordinate or address to somewhere in memory, then JSRs to a routine that does the actual drawing.

Since you found the "Game Saved" string, set a read breakpoint on it, and that'll take you right to the drawing routine.  Trace the stack up to see how the game triggers that string draw, and do it again for a different string in a different position.  It'll probably take you right to the same place as the JSR you NOP'd when you removed the password display.

Remember, you have all the free space in the world if you need it.
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 21, 2016, 06:49:27 pm
Thanks again Disch, your info is giving my brain a real workout!! ;)

But I managed to make something here:
(http://v2.pxl.se/i/Jl.png)

I broke out the routine that reads the characters into $2007 and when it is done with "Game saved!" it does another check to then go into loading "Push start button" to another PPU adress and then to $2007.
Title: Re: Kid Icarus, adding SRAM save function
Post by: SunGodPortal on January 21, 2016, 07:07:00 pm
Just want to say that this is really cool. I love hacks like this and would love to see more of them. So many of those old games could really benefit from something like this (Legend of the Mystical Ninja, River City Ransom, The Guardian Legend, etc...).

:thumbsup:
Title: Re: Kid Icarus, adding SRAM save function
Post by: KingMike on January 21, 2016, 11:43:28 pm
Just want to say that this is really cool. I love hacks like this and would love to see more of them. So many of those old games could really benefit from something like this (Legend of the Mystical Ninja, River City Ransom, The Guardian Legend, etc...).

:thumbsup:
Interesting as the Japanese version of RCR should sort of have that already (it didn't use SRAM, but it used a Japanese-only memory card device called ASCII Turbo File. One of only a couple non-ASCII-made games to use it.)
Title: Re: Kid Icarus, adding SRAM save function
Post by: SunGodPortal on January 22, 2016, 12:03:43 am
Quote
Interesting as the Japanese version of RCR should sort of have that already (it didn't use SRAM, but it used a Japanese-only memory card device called ASCII Turbo File. One of only a couple non-ASCII-made games to use it.)

Interesting indeed. Sounds like part of the work is already done then. I'd love to do some hacks like this but for the time being I am dedicated almost exclusively to A Link to the Past since there are so few people who are willing to negotiate with Hyrule Magic. We are few and completed ALttP hacks are even fewer.
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 22, 2016, 03:19:34 am
Just want to say that this is really cool. I love hacks like this and would love to see more of them. So many of those old games could really benefit from something like this (Legend of the Mystical Ninja, River City Ransom, The Guardian Legend, etc...).

:thumbsup:

Thanks SGP!
And again a big thanks to Disch for pushing me to learn more and more, this has been a blast :)
Title: Re: Kid Icarus, adding SRAM save function
Post by: RyanfaeScotland on January 22, 2016, 08:31:28 am
What a great topic. Really enjoyable to read through and see you progressing with your project and skills. Had a look through your past posts as well and the Spy vs Spy one is just as satisfying to read, good effort on sticking in and seeing things through to the end. :)
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on January 22, 2016, 09:51:44 am
Many thanks Ryan, most appreciated!!

Title: Re: Kid Icarus, adding SRAM save function
Post by: dACE on February 23, 2016, 06:33:33 pm
No public release of this save hack...at all...?

/dACE

February 26, 2016, 05:54:04 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Komigen frsj8112 - dela med dig  ;)

/dACE
Title: Re: Kid Icarus, adding SRAM save function
Post by: frsj8112 on February 28, 2016, 03:34:43 pm
Maybe, I have to test it through and make sure that all works as it should :)