Romhacking => Programming => Topic started by: justin3009 on October 01, 2012, 12:55:17 pm

Title: Unsure how to track this VRAM?
Post by: justin3009 on October 01, 2012, 12:55:17 pm
The topic title is a bit misleading, but here's what I mean.

In X2 and X3, the buster shots VRAM graphics were stored in slightly different locations.  X3 had them stored at C600 while X2 had them at C500.  I have gotten the buster shots to be stored to C600 perfectly fine in X2 without any errors, but now the most annoying part is really starting to get me to me after a couple days.  I'm almost betting it's something simple too.

Right now, the game still thinks the buster graphics are stored at C500 and I cannot for the life of me find out WHERE to change where it reads them.  (Storage is fine).  I've traced both games code for shooting the buster and there honestly isn't any difference enough to dictate the location of where it's read, which is really starting to baffle me.  Is there any other method to do to trace it down?  Cause this essentially is the only cause of VRAM issues with Zero in X2 and I need to have them correctly read the right location.
Title: Re: Unsure how to track this VRAM?
Post by: FAST6191 on October 01, 2012, 02:10:07 pm
I have to ask the obvious question of are you sure this is not a calculated offset/result of some pointer maths as they can quite often come out of nowhere and not be seen in a basic tracing session; I have seen such things in many systems for both programming shorthand/high end optimisation and workarounds for immediate/maths/architecture limits. It is usually for just those reasons that changing runtime memory locations like this is ill advised.

I will of course defer to others as the idiosyncrasies of the SNES and 65816 are not my forte.
Title: Re: Unsure how to track this VRAM?
Post by: justin3009 on October 01, 2012, 02:39:49 pm
I'm honestly not sure to be honest.  I know with the life bar in X3, you actually had to change the OP Code storage by a couple bytes on each one to do it.  The issue with this one is that I don't necessarily know if that's what it uses or not.  I feel like a lot of the details are being missed or just going over my head.
Title: Re: Unsure how to track this VRAM?
Post by: Spikeman on October 02, 2012, 01:26:28 am
I'm not familiar with SNES so I'll have to defer, but you should post trace logs of the code in question plus any other knowledge you think might be helpful in investigating this.
Title: Re: Unsure how to track this VRAM?
Post by: Nightcrawler on October 02, 2012, 09:30:26 am
I assume the buster graphics are sprites. In that case, the VRAM address for that sprite to use is set in the OAM table. This data would be set by the game using $2102/$2103 for for the OAM address and then $2104 for the OAM data write. I assume you already know how the data gets to VRAM at the specified location (typically DMA or manual copy to the VRAM registers).

In a trace from shooting the buster, I'd probably expect to see a write to those OAM/sprite registers for each animation frame advancing the VRAM address to the next tile/s. However, it's possible some other trickery could be done. If it was more tricky, it's still easy to figure out what was being done by looking in VSNES at the OAM table with a two or three savestates during the animation.

At the end of the day, the concept is no more complicated than the sprite will use whatever VRAM address is assigned to it in the OAM table for display. The rest is in the details. ;)
Title: Re: Unsure how to track this VRAM?
Post by: justin3009 on October 02, 2012, 09:56:39 am
Yeah, it's a sprite.  I've traced it multitudes of times going through trying to figure out what's going on, but I haven't really figured it out.  I'm almost certain I'm missing something blatantly obvious.

Also to note, the VRAM storage/loading does not occur until the buster is shot from what I can gather and have compared in Savestates.  Also, the entire graphical data of the buster gets loaded straight up in VRAM.  I'll re-check it, but I think all the frames required are loaded on the fly and stay there until it's gone or overwritten. - Trace Log

( - VRAM changes.  The first image is where the buster was originally stored in X2 (C500).  It was bumped to C600 (Much like X3's) in the 2nd image.
Title: Re: Unsure how to track this VRAM?
Post by: Nightcrawler on October 02, 2012, 11:18:09 am
Forget about VRAM for now. As I said, you need to be thinking about the OAM table. I took a quick look at this for you. Use VSNES to understand. Normal buster bullet is sprite 16 when fired. You can then explore editing it's corresponding hex data in the OAM table. You're going to have to read on how OAM data is stored to understand.

There's a sprite section at the bottom of this document and all of the register definitions:

The game DMAs the entire 544 byte OAM table periodically (probably during NMI) to $2104 from $00:6000. $00:6000 looks to be mapped to CX4 chip RAM. It looks likes that's also the area that holds the result of the 'Build OAM' function ($00 is written to $7f4f) of the CX4. I would imagine it's using that function. You're going to have to do a bit of reading on the CX4.

You need to keep going backwards. It looks like the inputs to that function would be the next thing to figure out. Then, there's a good chance  editing it's source data would be the solution. If not, you keep going backwards to see what makes up that input data. You have to keep working backwards from what you know. Unfortunately, I don't do any work with the CX-4, so I can't be of too much more help there.

Why do you need to move the sprite's VRAM location so badly anyway?
Title: Re: Unsure how to track this VRAM?
Post by: justin3009 on October 02, 2012, 09:12:41 pm
I'm implementing Zero into X2 as a playable character, and in doing so, his sprites tend to take up more VRAM.  In which case it causes multiple errors across weapons when dashing.  That's the reason why the data was bumped in X3 most likely, as he takes up a lot more room than X and everything needs to be shoved so nothing gets overwritten.

Edit: It seems the buster is sprites 16-24 or so from what I'm viewing in VSNES.

Edit: $00/D391 BE 40 07    LDX $0740,y[$06:0742]   A:0002 X:10D8 Y:0002 P:envMxdIzc

This value was changed to 02 when Medium Buster was fired and the X value was changed to 7E10D8.

Edit 2: That seems to be which RAM area to store them to if more than 1 shot is fired on screen.

Edit 3: Okay, so the OAM from what I can see is clearly 8 bytes off from the original.  So the first byte of the buster in my savestate for the far left end is 3D.  But it SHOULD be 45.  Compared that to the other values we have:

3D = 45
3C = 44
2F = 37
2E = 36
2D = 35
2F = 37 (Flipped)
2E = 36 (Flipped)
2D = 35 (Flipped)

Edit: ... I just figured it out.. It's the Sprite Assembly bit.  Lol, well, that fixes that :'D
Title: Re: Unsure how to track this VRAM?
Post by: Nightcrawler on October 04, 2012, 09:20:37 am
Great! Let's see some screens!
Title: Re: Unsure how to track this VRAM?
Post by: Thanatos-Zero on October 04, 2012, 12:10:04 pm
How about something I designed for Justin?

Unfortunately I have to remade some parts of the legs, due suggestions from my dear colleagues of Sprite.INC.
Title: Re: Unsure how to track this VRAM?
Post by: justin3009 on October 05, 2012, 10:37:11 am

Zero is dashing in both images because that's when VRAM issues would occur.

But now since everything has been bumped, I've run into quite a few other issues.  I fixed an issue in Flame Stag's stage with the Slim Rock Columns that sank into lava, those are perfectly okay now.  But since that's happened, a number of enemies have their data overwritten by the Buster data.

Now the thing that scares me about that is I'm not sure all of them are fixable.  For the most part they are but I have to do some SERIOUS shuffling around of data, like it's ridiculous how much I'm going to have to shuffle things around.
Title: Re: Unsure how to track this VRAM?
Post by: Lenophis on October 05, 2012, 12:27:21 pm
Why do you need to move things forward in VRAM at all? Seems silly to redo basically everything. What am I missing?
Title: Re: Unsure how to track this VRAM?
Post by: justin3009 on October 05, 2012, 01:07:08 pm
Zero's data will OVERWRITE everything else in VRAM since it wasn't shifted.  The buster data would overwrite icons or random enemy graphics, dash graphics would be screwed up, some levels would glitch out, etc..

Not EVERYTHING has to be redone thankfully, it's just a few enemies and obstacles have to be bumped slightly forward for it to work.  Not a big deal in all honesty as it helps me learn more about how enemies are pieced together.  It's just extremely time consuming.

For example: Before hand if the weapon VRAM wasn't shifted above, they'd overwrite the icons themselves or they'd overwrite Zero's foot when he dashes.  Now, since that's all been shifted into X3's location (Which is ideally the best place for it and it should work regardless), some enemies are being overwritten as they're still in their old location.  It's not that bad to change, it's just time consuming, as said before, to find where it's all located.

Overall, it'll improve everything in the long run.  No VRAM issues for any other changes and it'll allow progress of anything else without any worries.
Title: Re: Unsure how to track this VRAM?
Post by: Nightcrawler on October 05, 2012, 01:26:43 pm
Yeah, I can see how this modification caused a big problem. You're sprite now uses more VRAM than it did initially. So unless everything after it also got bumped, you will always have a glitch where the next sprite the game puts in would be pointing to that VRAM you just used for the other sprite's expansion. Theoretically, you should be able to simply bump all subsequent sprites (except in the case if it were entirely full the last sprite would get cut and it's not feasible). Or, simply shuffle the single affected sprite in each scenario like you mentioned. Again, if all of the alotted VRAM is full, that won't work either and you're simply screwed without cutting something or making some sprite more efficient to take up less space. Either of those scenarios is not pretty. That's why ideally for expansions like this, we use free space and/or relocate to the end. Otherwise, it's an uphill struggle to fight the game like this. It's likely they are all properly bumped in X3 because they had the source code. It's much more difficult for us to figure out how to bump everything easily. It's worth looking into it and see if it's feasible though. It could be easy.

I have a potential better solution if the entire table is full. Remember, there are two possible OAM sprite tables in VRAM (Bases set via $2101). Looking at an MMX2 savestate, I see both are set to $C000 in VRAM. Both tables are set to the same location, so it's only effectively using one. Therefore, it should be possible to set the second table to some other free VRAM area, and have the new expanded sprite utilize the second sprite table. There is a table bit for each sprite in the OAM attribute data. One thing to watch out for is since both tables are set to the same location now, the programmers could be terribly lazy and not cared what the table bit was set to since they both go to the same place in the end and you'd have to write a few lines of code to set them all to 0. It's probably unlikely that was done though.

Well, I'm out for awhile. Good Luck! You're getting close to understanding how this whole thing works. Once you understand it all, you'll be able to figure out the path of least resistance and smartest solution. There's usually always more than one way. :)
Title: Re: Unsure how to track this VRAM?
Post by: justin3009 on October 05, 2012, 01:29:54 pm
Unless I'm viewing this wrong, but isn't the 2nd OAM table used to store the entire Enemy's sprite data and then it reads it from that area and stores it into the first section?  Maybe I'm guessing but I'm looking at C000 and then E000.  E000 has the ENTIRE sprite set of the enemies.

And it's not really so bad.  I've fixed 5 enemies that had bad VRAM with the bumped data, nothing has gone wrong since or caused any issues.  I think it's just a few enemies weren't naturally bumped. (I assume this is perfectly fine as some enemies are bumped, some aren't.)  Either way, I'll continue bumping them around.  If I have no issues, then I think this'll be okay.

It's time consuming but it's work to help understand how this game works more.


Just went through the game, these are the ONLY things with VRAM issues now.

Agile's Giant Beam Slash
Floating Towers in Wire Sponge's Level
Tire Enemy in Overdrive Ostrich's Level
Ride Armor Breakable block in Wheel Gator
Boss Door in Final Level 2 with Serges
Serges 4-way Bubble Explode
Splash Burner hitting an immune target

Those should all be easily possible to bump over just a tad and fix.  Then I'll do another test run of the game except this time purely use Zero and see how it handles.

Edit: Bumped them all and they work flawlessly from what I'm seeing.  I had to cheap Serges little ball though as for some reason the extra frame wasn't loading, so it just loads a repeated frame and it still works nicely.  Also ran into a bug with the I. Tracer and now know how to load only a specific amount of VRAM.  So a great learning lesson!  So now, time to run through the game as Zero with double buster shots!

Edit 2: Woops, I TOTALLY forgot about the original 8 bosses haha.  I'll have to bump a couple of their attacks and then everything works.  So far though, no other VRAM issues :)

Edit 3: Fixed them all!  Only VRAM issue left is the Introduction Level boss, but it's not even possible to face him with full armor.  I may do it just for completion sake, but otherwise all VRAM issues are completely fixed.  I had to edit Wire Sponge's little Smoke Puff animation a bit as well so the huge cloud of smoke is gone.  It still actually flows quite nicely.

Edit 4: Each time I say it's all working fine, I run into more VRAM issues, lol'd.  Most of them are easy to do.  Flame Stag's little Fire Dash though was... more complicated than I thought it would be.  I had to re-arrange and even redo the length of certain values.  But MOST of them thankfully are simple bugs that can be fixed quickly.

Violen's Bullet Fingers are bugged
Serges Bullets still bugged
Flame Stag's Ground/Wall Fireballs (This.. needs to be cut down.  There is NOT enough room for all the graphics).
Morph Moth Sparkles in Final Levels
Wire Sponge Lightning on Final Levels
Zero's Ground Pound
Needle enemy when Sigma spawns it