News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Is there a way to identify the offset where specific graphics are?(GBC)  (Read 708 times)

Nebba

  • Jr. Member
  • **
  • Posts: 14
    • View Profile
Is there a way to identify the offset where specific sprite or background are? This will make locating and editing graphic easier. Im editing a GBC game.

FAST6191

  • Hero Member
  • *****
  • Posts: 3167
    • View Profile
Two primary methods that are not brute force (GB/GBC games are often small enough that you can afford to side there pressing page down in your tile editor to go through the entire ROM), or corruption (rather out of fashion but corrupt enough parts of the ROM and you will eventually see results in the game, you then presumably finding the last batch of corruption was related to the graphics).

1) Loopback searching. Games tend to have to copy the graphics from the ROM to the area of memory handling graphics (usually called VRAM, short for video RAM). Find these graphics in VRAM (if they are on screen they are in the VRAM), dump this data from your emulator and search the ROM for it. Compression (seen on the GB/GBC but not so very common as it got on later systems) can get in the way but generally as you can't afford to be wasting time converting graphics formats then as it appears in memory is as it is stored in the ROM. Not flawless but a good start.

2) Tracing. King of all methods of finding data, but will require you know some assembly (though can be a very small amount that is required, more is better though). https://www.romhacking.net/documents/361/ is for the GBA but the principles it espouses work for basically everything. As the VRAM is a whole 16 kilobytes ( http://bgb.bircd.org/pandocs.htm#gameboytechnicaldata ) for the GBC and 8 for the GB then they tend to only keep what they need. To that end find when it appears in RAM (can have a nice VRAM viewer as you are playing a game, though usual guess is part of the loading of a new room/start a new level/start the game or just before you get to one) and set a break on write to that area. Play the game (savestate, downloaded save from online somewhere, cheats, turbo mode... all valid things to be using to speed this up) to the point just before it loads, tell it to break and tell you when something wrote it. Hopefully you have a direct line back to a "read this location in the ROM" type setup (raw reads of the ROM can be a thing in some systems, others will have DMA/direct memory access handle it*, others still will have some contraption in memory you feed commands to that in turn go fetch data from the disc/cart/... but that does tend to only be later systems like the DS and things based on optical media or floppy discs).
Some systems will have lesser tracing methods like BIOS call watching -- the GBA for instance has compression used extensively but most things will use the commands the BIOS has. As these commands are obvious when used you can make a log of them and then have the command, location in the ROM and type of compression all told by it in the log.
Some emulators will have similarly quite useful methods for narrowing down code wherein they note things as they are fetched and/or executed, and thus you can then wait/do other things, and then do the thing you want to see and have the emulator tell you what new thing just happened. http://fceux.com/web/help/CodeDataLogger.html being the primary example in console emulation, and slowly being introduced by other emulators. Most use it to find code (want to learn about jumping in a game? Walk around, wait around... the emulator will then have seen any timers, music, walking, idle animations but then you jump and it will tell you "wait, something new has happened" or be in a lot) but data also works for this.

*generally you want to be leaving your CPU to do actually interesting processing tasks. To that end developers of consoles soon learned to include a DMA setup to allow game devs to use that rather than burdening a CPU with fetching data when it could be doing something more useful to the running of the game.