News:

11 March 2016 - Forum Rules

Main Menu

Mega Man X3 menu hacking

Started by justin3009, March 26, 2012, 10:28:05 PM

Previous topic - Next topic

justin3009

I've been looking at Mega Man X3 still, of course, but I'm beginning to wonder now as it'd save a lot more time and be essentially much easier to be flexible in the future?

How difficult would it be to convert a password system to saving in SRAM and such?  Is that even feasible?
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Ryusui

Well, for a start, you'd need to reconfigure the header or whatever to indicate it uses SRAM in the first place.

The easy way I can think of would be to simply skip over the password screens and replace them with a routine that saves the relevant data to SRAM. The password entry screen would similarly simply load the saved data. There'd be only one save slot, of course, but it should be doable without having to code any new interfaces or whatnot.
In the event of a firestorm, the salad bar will remain open.

justin3009

QuoteWell, for a start, you'd need to reconfigure the header or whatever to indicate it uses SRAM in the first place.
- I'll have to figure that out.  I think it has at least something because it seems to save the latest password whenever you reset the game, or at least from what I've seen.

QuoteThe easy way I can think of would be to simply skip over the password screens and replace them with a routine that saves the relevant data to SRAM. The password entry screen would similarly simply load the saved data. There'd be only one save slot, of course, but it should be doable without having to code any new interfaces or whatnot.

The password screen essentially only loads up data, that's really about it.  Even one save slot would be 100% perfect.  I think the only difficult spot would be trying to figure out how to store things to SRAM.  I think once I can figure that out, the rest should somewhat fall into place since it'll just be heavy memory loading which can probably be used with MVN's and such.. or at least I think so.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Ryusui

Quote from: justin3009 on March 26, 2012, 10:52:02 PM
- I'll have to figure that out.  I think it has at least something because it seems to save the latest password whenever you reset the game, or at least from what I've seen.

Soft reset doesn't blank the memory. X-Men 2 for Sega Genesis has a part where you need to reset a computer, and resetting the console is how you proceed.
In the event of a firestorm, the salad bar will remain open.

justin3009

Ah okay, that makes sense there at least.

Is there any documents that could essentially help start studying storage to SRAM?  I've looked at a couple of things that helped explain it (The basics of it all which I already knew of) and that's about it.  Unless I'm missing something.

If not, would I just have to study another game to see how it stores it?
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

henke37

SRAM is pretty simple in theory. You simply have a pile of bytes that are retained between runs. You may need to lock and unlock the area, but other than that, it is just another pile of bytes.

justin3009

That I can understand, it's just how does one go about storing and loading data from SRAM?  What exactly dictates to do that?
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

KingMike

Well, what I have done is... when the game displays a password, read the password data and store to SRAM.
When the password entry screen appears, instead of loading default data, load the saved data into the password data (essentially auto-entering the saved data as the currently-input password). (such that one needs to simply press Start on the password screen to continue with the saved data.)
Actually, I took the idea from the GBA port of NES Metroid, which allows you to have the game "remember" one password in the game's save memory.
Might be a bit trickier if you want the game to actually display the saved password, if the initial display (with the default password) is hard-coded.
"My watch says 30 chickens" Google, 2018

justin3009

#8
I had that in mind, or at least having just one giant save being presented that dictates what weapons you have, how many heart pieces, what armor pieces, what chip pieces, the basic general stuff.  There's not much information to display for a Mega Man game.

What actually dictates the game to store and load from SRAM though?  What would it even look like for ASM wise?

Edit: So I went through and did a log for Tales of Phantasia.

$C2/53DA 08          PHP                     A:0000 X:2000 Y:0006 P:envMxdiZc
$C2/53DB DA          PHX                     A:0000 X:2000 Y:0006 P:envMxdiZc
$C2/53DC E2 20       SEP #$20                A:0000 X:2000 Y:0006 P:envMxdiZc
$C2/53DE BD 35 00    LDA $0035,x[$7E:2035]   A:0000 X:2000 Y:0006 P:envMxdiZc - What save you're on.
$C2/53E1 8F 0D 7F B0 STA $B07F0D[$B0:7F0D]   A:0000 X:2000 Y:0006 P:envMxdiZc - Stores in SRAM what save slot is latest.
$C2/53E5 22 3B E5 C0 JSL $C0E53B[$C0:E53B]   A:0000 X:2000 Y:0006 P:envMxdiZc


$C0/E53B 08          PHP                     A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E53C 8B          PHB                     A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E53D DA          PHX                     A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E53E 5A          PHY                     A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E53F E2 20       SEP #$20                A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E541 85 0E       STA $0E    [$00:000E]   A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E543 A9 7E       LDA #$7E                A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E545 48          PHA                     A:007E X:2000 Y:0006 P:envMxdizc
$C0/E546 AB          PLB                     A:007E X:2000 Y:0006 P:envMxdizc
$C0/E547 64 0C       STZ $0C    [$00:000C]   A:007E X:2000 Y:0006 P:envMxdizc
$C0/E549 C2 20       REP #$20                A:007E X:2000 Y:0006 P:envMxdizc
$C0/E54B A9 00 0A    LDA #$0A00              A:007E X:2000 Y:0006 P:envmxdizc
$C0/E54E E2 20       SEP #$20                A:0A00 X:2000 Y:0006 P:envmxdizc
$C0/E550 8F 1B 21 00 STA $00211B[$00:211B]   A:0A00 X:2000 Y:0006 P:envMxdizc
$C0/E554 EB          XBA                     A:0A00 X:2000 Y:0006 P:envMxdizc
$C0/E555 8F 1B 21 00 STA $00211B[$00:211B]   A:000A X:2000 Y:0006 P:envMxdizc
$C0/E559 A5 0E       LDA $0E    [$00:000E]   A:000A X:2000 Y:0006 P:envMxdizc
$C0/E55B 8F 1C 21 00 STA $00211C[$00:211C]   A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E55F 8F 1C 21 00 STA $00211C[$00:211C]   A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E563 C2 20       REP #$20                A:0000 X:2000 Y:0006 P:envMxdiZc
$C0/E565 AF 34 21 00 LDA $002134[$00:2134]   A:0000 X:2000 Y:0006 P:envmxdiZc
$C0/E569 18          CLC                     A:0000 X:2000 Y:0006 P:envmxdiZc
$C0/E56A 69 00 61    ADC #$6100              A:0000 X:2000 Y:0006 P:envmxdiZc
$C0/E56D AA          TAX                     A:6100 X:2000 Y:0006 P:envmxdizc
$C0/E56E 86 1C       STX $1C    [$00:001C]   A:6100 X:6100 Y:0006 P:envmxdizc
$C0/E570 AF F1 E8 C0 LDA $C0E8F1[$C0:E8F1]   A:6100 X:6100 Y:0006 P:envmxdizc
$C0/E574 9F 00 00 B0 STA $B00000,x[$B0:6100] A:6154 X:6100 Y:0006 P:envmxdizc
$C0/E578 AF F3 E8 C0 LDA $C0E8F3[$C0:E8F3]   A:6154 X:6100 Y:0006 P:envmxdizc
$C0/E57C 9F 02 00 B0 STA $B00002,x[$B0:6102] A:656C X:6100 Y:0006 P:envmxdizc
$C0/E580 E2 20       SEP #$20                A:656C X:6100 Y:0006 P:envmxdizc
- I haven't really checked much but B06100 or rather just "100" is the offset location in SRAM where it starts storing names and what not.  So I assume I can do something similar like this in Mega Man but I may need a little more help.  Essentially though, Mega Man is a whole ton easier since it doesn't have to record storyline points exactly, levels, characters, etc..  Just weapons, heart tanks, the very very basic stuff which takes little to absolutely no room.

I may need some help to get started on this though.

Edit: Definitely for starters, I'm trying to figure out how the game dictates if it uses an SRAM or not.  I'm assuming that code loads right away as the game starts but I'm not even sure ._.  Any pointers on this?

Edit 2: Got it.  FFD8 was 00 originally.  Changed it to 01 and the game now creates an SRAM file 2KB in size which should be more than enough room.  Had a little help to figure it out but he gave me the SNES Dev docs so that helped more.

Edit 3: GOT IT!  I figured out how to store and load from SRAM as well.  70:0100 is offset 100 in SRAM.  I stored 40 there for a weapon test value and it works absolutely flawlessly ;3
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

justin3009

#9
So I'm testing out some things with seeing if I can make other sprites appear on the screen for purposes that I need and this is what happens.

- Nothing appears.. at all on SNES9X.

Yet when you go to ZSNES.

- It appears ~_~...

I'm going to assume this is another one of those screwed up emulator issues that's between SNES9X and ZSNES but I want to be sure on it.

Edit: This same thing happens with any other sprite on the screen.
Edit 2: It seems to even happen with things that are on BG Layer 1 and 2.  I'm not sure why it'd work on ZSNES but not SNES9X..
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Ryusui

Try BSNES if you can. That's the acid test if something's screwing up.

It's not only the only emulator I know of that can render the Cathedral of Shadows in SMT1 without glitching, it's also accurate enough that it triggers the anti-repro message in the Breath of Fire 2 retrans.

EDIT: Thinking about it, are you updating the OAM during VBlank? If that sentence was Greek to you, I suggest you do a bit more research before you continue.
In the event of a firestorm, the salad bar will remain open.

justin3009

#11
BSNES doesn't work at all now since the SRAM thing was implemented.  So I'm rather.. stuck with what I have right now.

And most likely not.  I've tried doing research on such things but all it does is cause more confusion.

Edit: Yikes, those numbers are actually Layer 2.  Any Layer 1-2 and sprites don't appear on SNES9X when adding them in manually.  Guessing that still means I should V-Blank?

Edit 2: Figured it out!  Stored 80 to 8D 00 21 (6:2100) and then it shows up in SNES9X :3
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

justin3009

I've been futzing around with this for awhile, even before saving was working and I am just completely baffled.  This same thing occurs in Tales of Phantasia and I can't really seem to figure out what causes it or why it does it.  Changing really anything around the tile data itself causes the menu to blow up with scrambled data, so I'm left clueless on any idea why it happens.

- This is how I have it right now without really anything.
- Alter one tile map byte and it does it in four places.

I've gone through the code and watched it loop and I really don't see anything to indicate why it loops :/  I'm really confused.

http://pastebin.com/Jk86dex1 - This is basically the code that sets everything up.  The first bytes load up normally but then it hits special tiles that are used everywhere and it repeats them throughout the screen.  I have no clue HOW to break that sequence or what even causes it.  I assume it's one of the bytes that destroys the game screen when altered but I'm unsure.

Example: Go to 23F807.  You should see 38 E9 84.  Alter E9 to E8.  It'll change the 4 tiles you see in the screenshots.  84 is the direction.  Upside down, horizontal, etc..  I'm guessing 38 is what has something to do with it.  If not, then maybe 80 11.  Either way, I can't alter any of it without the game going crazy.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Ryusui

My recommendation? Take a hatchet to as much of the code as possible and create your own. Instead of leaving the precise drawing details to a routine that was designed to construct something completely different, create a routine designed specifically to draw your custom save screen.

By the way, I'm already impressed with how much you've gotten done. :3
In the event of a firestorm, the salad bar will remain open.

justin3009

-_-... I didn't even think of that until you mentioned it.  The most simple solutions always avoid me xD;

I'm using a really ugly cheap method for right now, but I'm actually thinking about a new system for certain screens that could essentially be more dynamic, heck, maybe a whole new routine!   But for now, I'm doing the cheap method of storing individual tile errors into the right area.  Except when it comes to repeated tiles, then I just loop them.

I might see if I can put in a new routine to have a table that reads the tile, then the value after is how many times it goes through the loop to write it.  I'll test that out later after I have the menu look ready.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Mauron

In the current situation, $00:00FE is used for the looping - 8 is loaded in there at first, and it's decremented twice per loop.
Mauron wuz here.

justin3009

I've been posting a horde of questions lately but it's mainly due to the save screen I'm working on >.< So sorry about all the spam.

Okay so, I'm lost on what to do to refresh the actual screen to remove data that isn't there.  I've actually tried having a separate routine to blank out the data with other junk but.. it doesn't work that way.

- Here's what it shows.  The darkened data means you do not have the item.
- Slot 3 is literally empty.  There is no data at all present and it even ignores the entire routine so it doesn't write to the screen.  I'm not sure what to do to refresh or anything so it doesn't show the data.

What I plan to do is for the entire screen to blank out of data and just say 'NO DATA AVAILABLE' as text but I can't even remove anything off the screen >.<
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Ryusui

Okay, what do you mean by "blank out the data with other junk"? One way or another, you're going to have to blank out that data in order to clear the screen.

Just overwrite it all with blank tiles. Redraw the entire menu if you have to. (And by the way, looking good! Is there any way to simply make the uncollected weapons not show, though? That's what the later games do.)
In the event of a firestorm, the salad bar will remain open.

justin3009

#18
I feared as much >.<  It's getting tedious as hell to write a horde of similar routines just to blank out data on certain circumstances. 

Drawing the menu again would be the best way to go about it but the game instantly crashes if that data is even attempted to be loaded again.  I probably have to set something for it to work again.  That'd actually fix everything if I could load that data again instead of having like 300 different things trying to blank it out.

Essentially I could have the icons just not appear but I'd have to blank out the data either way.

Edit: Well, found a way to... semi re-draw the whole menu but it lags like crazy for a second then flickers xD;  I'm guessing that's unavoidable.  I may have to go the routine way.

Edit 2: -_-.. derp.  I'm an idiot.  Just have the routine for blanking the tiles show up everytime you move the cursor.. Voila.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Nightcrawler

'Erasing' is simply a tilemap issue. All you need to do is a write a single value (pointing to a blank green menu tile) to the tilemap area that you want to erase. A single loop can do it. It can't possibly be slow. If you write a simple routine to blank the tilemap, you'd reuse this every time you switch save spots. I think you're over-complicating the situation.
TransCorp - Over 20 years of community dedication.
Dual Orb 2, Wozz, Emerald Dragon, Tenshi No Uta, Glory of Heracles IV SFC/SNES Translations