This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Battletoads and graphics

Battletoads and graphics
by on (#90212)
Hey guys, you probably remember me from such videos as "Brad Corrupts" and well, that's probably all you know me from (okay, and I'm the Admin of the ever so dying Zophar's Domain, but I try not to talk about that place much anymore)

Anyway, my next project will be Battletoads, and all I have to say at RARE at this point is, FUCK YOU.

So, I'm making a thread basically asking for help. This is what I'm looking for. I'm looking for the offsets of all graphics tile data, compressed and uncompressed. The uncompressed stuff should be pretty easy, but I don't know what methods they used for compressing the graphics. My main method of finding such data is by using a tile viewer, but if it's compressed in such a way that it's indistinguishable from other data, there will be no way to find it.

Sadly, I was able to find little to no research done on Battletoads (except for that text compression thread. That's some great stuff, and I got to learn huffman compression, which is awesome.) and I'm hoping someone out here might have poked around in the ROM a bit and would have some notes to share.

If not, I'm hoping someone here can help me in finding all the CHR data myself. I believe the ROM is split into 8 32k banks (given the info from the text compression is correct) but I don't really know how said banks are utilized, and my 6502/NES ASM skills are near nonexistent (although I have ASM experience in other architectures)

Anyway, any help at all would be greatly appreciated.

(also, my apologies if this is in the wrong forum)

by on (#90213)
Have you tried other romhacking-specific boards like Acmlm's (board2/jul) or Romhacking.net?

Otherwise, use a corrupter to find compressed graphics, and use data breakpoints to find the code that reads it, then step through with a debugger or trace logger to see what's going on. Alternatively, use data breakpoints when it starts writing to VRAM instead of a corrupter.

I think player sprites are uncompressed.

Edit: I can clearly see graphics throughout the ROM in a tile editor. I'm guessing some kind of RLE or LZ compression scheme, since they are clearly byte-aligned.

by on (#90215)
Dwedit wrote:
Have you tried other romhacking-specific boards like Acmlm's (board2/jul) or Romhacking.net?


I've looked through the posts (and acmlm's archives) and have found very little. I have, however, contacted a couple of people who have done some work on battletoads to see if they have any documentation that I would need to write my script.

As for making a thread, this is the first one that I made, as you guys would probably be the most knowledgeable on how Battletoads works.

Dwedit wrote:
Otherwise, use a corrupter to find compressed graphics, and use data breakpoints to find the code that reads it, then step through with a debugger or trace logger to see what's going on. Alternatively, use data breakpoints when it starts writing to VRAM instead of a corrupter.


As I said, my NES debugging is nonexistent, and I believe I would have to go through the entire game to achieve that, no? There has to be an easier way.... right?

Dwedit wrote:
I think player sprites are uncompressed.


Probably, I don't think that'll be an issue.

Dwedit wrote:
Edit: I can clearly see graphics throughout the ROM in a tile editor. I'm guessing some kind of RLE or LZ compression scheme, since they are clearly byte-aligned.


Yeah, I can too, but there are some areas where I'm not too sure if it's graphics data or something else, not to mention other areas that may contain graphics, but are unseen with a tile viewer.

by on (#90222)
I think a lot of us are knowledgeable about how the NES works in general, but not about specific proprietary game engines. Emulator authors know how they work to the extent that they need certain hardware features correctly emulated, but CHR decompression needs only a working CPU and working $2006/$2007 ports on the PPU. I imagine that people primarily interested in reverse engineering proprietary game engines hang out at the Romhacking.net board. One exception is tokumaru, who reverse engineered Bee 52's Markov-chain CHR format.

by on (#90228)
What exactly are you wanting to do to Battletoads?

I've never looked into it but I recall Battletoads manages to upload ALOT of data to VRAM each frame. So if it really does compress graphics I would imagine it only does so with static graphics, not the Toad's sprites and not any animated background tiles since time is important there and there isn't any large amount of RAM to decompress to on the CPU bus.

by on (#90230)
For the battletoad character sprites, I did see that the game first writes code to RAM somewhere to efficiently copy sprites into CHR-RAM. You can see from watching CHR-RAM in an emulator that it only ever stores one frame of the battletoad, and uploads a new one as needed. Try tracing a few frames, and look for execution from RAM ($0000-$07FF), verify that it's writing to CHR-RAM, and then search backwards to find out when that code was written to RAM (which should should show you where the sprite's data came from). That's how I figured out the text compression, anyway, find the final resting place of the data (e.g. nametable), and search backwards in a trace until you see where it was written, repeat until you find the source data. (Yes, you're going to have to learn 6502 assembly.)

Enemy/other character sprites seem to be static throughout a level, so far as I've seen. They are much more likely to be compressed than the Battletoads sprites, since there's no per-frame maintenance there.

Background CHR data, usually there's a set of tiles that are animated, probably updated in the same way as the battletoad sprites.

I don't know anything about the level data, or nametables, other than the game maps seem to be made with 32x32 blocks (i.e. 4x4 tiles) for the most part, so probably there's a palette of 16-byte (18-byte with attrib?) tiles somewhere, and the level data indexes them?

Cutscene nametables and CHR data probably have their own compression scheme going on, though I think they're all together in page 6 with the text data I mentioned in the other thread.

If you're just trying to rip tiles, I'd maybe just suggest playing through the game and dumping the CHR-RAM/nametables to a file every time you see something new in there (about once a level + animation cycles).

If you're trying to romhack, well, good luck. It's a big game with a lot of code. This game obviously had a lot of development time, and kind of has a little of everything in it. Each ROM page might have a completely different way of doing things (e.g. some levels do parallax by animating background tiles, others do it by timed code and changing the scroll register). Multidirectional scrolling levels might be stored straightforwardly in the ROM, but the horizontal scrolling levels might just be a list of timings and events or something.

Personally I think it would take me maybe 100-200 hours of work to reverse engineer the whole game, after which it would be completely rom-hackable and reprogrammable... but then I think of other things I could do with that time.

by on (#90250)
tepples wrote:
I think a lot of us are knowledgeable about how the NES works in general, but not about specific proprietary game engines. Emulator authors know how they work to the extent that they need certain hardware features correctly emulated, but CHR decompression needs only a working CPU and working $2006/$2007 ports on the PPU. I imagine that people primarily interested in reverse engineering proprietary game engines hang out at the Romhacking.net board. One exception is tokumaru, who reverse engineered Bee 52's Markov-chain CHR format.


Yeah, I realize that, and I just made a topic in RHDN as I hope to get some help there, but given the nature of the game and how the game is used as a benchmark of sorts, I was kinda hoping that someone here would have documented it some.

MottZilla wrote:
What exactly are you wanting to do to Battletoads?


Simple, corrupt it (for entertainment purposes), but in order to do so I need to figure out where all the CHR data is (as corrupting CHR is rather boring/lame). While that's trivial for games with CHR ROM, it's a pain for games with CHR RAM, especially this one.

rainwarrior wrote:
If you're just trying to rip tiles, I'd maybe just suggest playing through the game and dumping the CHR-RAM/nametables to a file every time you see something new in there (about once a level + animation cycles).

If you're trying to romhack, well, good luck. It's a big game with a lot of code. This game obviously had a lot of development time, and kind of has a little of everything in it. Each ROM page might have a completely different way of doing things (e.g. some levels do parallax by animating background tiles, others do it by timed code and changing the scroll register). Multidirectional scrolling levels might be stored straightforwardly in the ROM, but the horizontal scrolling levels might just be a list of timings and events or something.

Personally I think it would take me maybe 100-200 hours of work to reverse engineer the whole game, after which it would be completely rom-hackable and reprogrammable... but then I think of other things I could do with that time.


All I want to find out is the ROM map, at least enough to know where all the CHR stuff is.

by on (#90580)
So, I suppose I'm on my own at this point? :|

by on (#90584)
Well, if nobody gave you anything yet it's because this information is not out there, and you can't really expect people to get out of their way to do a lot of research just for someone else's project, unless they're also interested.

by on (#90586)
If you're just trying to find stuff, I can see most of the graphics in YY-CHR. Compressed graphics just look a little different and aren't whole, but since they are still byte aligned, they are partially recognizable.

by on (#90617)
I told you everything I already know about it.

If you have a really specific question, and it wouldn't take me long to figure out, I can maybe answer it for you. If it's time intensive, though, I could maybe give you tips on how to figure it out, but that's about it.

by on (#90809)
Dwedit wrote:
If you're just trying to find stuff, I can see most of the graphics in YY-CHR. Compressed graphics just look a little different and aren't whole, but since they are still byte aligned, they are partially recognizable.


okay, that info'll help, thanks.

by on (#91907)
Another thought: instead of dealing with the compression, in an emulator with scripting support, you could just wait until the level is loaded, and then corrupt CHR RAM at that point.

by on (#91908)
Except I think he wants to know where the graphics are so he can AVOID corrupting them and only change program code when he randomly changes bytes.
Quote:
I need to figure out where all the CHR data is (as corrupting CHR is rather boring/lame)

by on (#91910)
Kasumi wrote:
Except I think he wants to know where the graphics are so he can AVOID corrupting them and only change program code

Can't FCEUX do both code/data logging and movie playback? Try this: Play back a TAS of the game with CDL turned on, save the CDL, and then corrupt only areas that show up as code in the CDL. Or do the existing movies of Battletoads desync in FCEUX?

by on (#91919)
Ah, didn't realize he wanted the opposite, but he can do the same thing... wait until the level is loaded, then corrupt the ROM in memory. CHR-RAM will be fine since it's already loaded.

Tepples' idea is good too.

by on (#91954)
What about just using the offsets in Game Genie codes for Battletoads? In effect, Codemasters has already figured out the non-graphic areas that effect gameplay.