YesNoOk
avatar

SNES Sprite Ripping: The Introduction of Hex-Mapping (Read 8340 times)

Started by The Aboriginal One, June 06, 2009, 08:50:50 pm
Share this topic:
SNES Sprite Ripping: The Introduction of Hex-Mapping
New #1  June 06, 2009, 08:50:50 pm
  • ******
  • I am a ghost.
    • USA
    • www.bmarquis.com
Table of Contents:
Introduction to Thread
Lesson One: I Hate This Background. Lets Do Something About It!
Lesson Two: Hit Sparks, I Hate Hit Sparks...


Introduction to thread

This thread is merely and completely for the concept of Hex-Mapping. This thread will give you a technical understanding of how to HexMap to easily rip and localize sprites, palettes, and maps. Although this is for the Super Nintendo Entertainment System, other systems can be similar, with the difference of how they store their user data. This concept, if knowledgeable to the system, can be used on other systems as well.

Hex-Mapping is a concept I coined myself. Hex-Mapping is defined as learning how the system stores its graphics, and using Hexadecimal Editors and Cheat Utilities to exploit those Parts of memory that stores the sprites and colors in either that particular place in time, or throughout the whole file, either in realtime or at runtime, so that the environment of sprite ripping is optimal. This term, as of June 6, 2009, has these areas:

  • Changing the background color in realtime
  • Disabling layers
  • Disabling Objects


Lesson One: I Hate This Background. Lets Do Something About It!

Now, I personally use ZSNES for ripping my sprites. My game of choice: Dead Dance. I usually play as Syoh, and commence to whoop the shit out of Zazi. Now I want to rip them. I dunno why, but they insist on making Syoh's background green.


Now, usually you would like the Background color to be Magenta or something. I personally like Magenta. Lets go for Magenta!!! But how?

First, you'll need to know how color is stored for ingestion to the screen. There are many resources for how the SNES works, but here's a crash course for you to start you off.

The Super Nintendo stores all graphics information into Video-Random Access Memory, or VRAM. The palette information is stored in CG(Color Group) RAM, and the sprite info is stored in OAM, the Object Attribute Memory, but for right now, CGRAM is all we need.

What's easy about the Palette information of an SNES is that index 0 is the background color. Good, it sucks if it wasn't. What's hard though is the color info, but it's not that hard. SNES CGRAM stores 256 15-bit colors. The attribute per color is:
Code:
xbbbbbgg gggrrrrr
where x is an unused byte, bgr is the 5-bit color info in blue, green, and red respectfully.

Now to find Index 0. I urge you to download vSNES, for this is what you need for the next step.
http://vsnes.aep-emu.de/

Now, simply save the game using the save state. Don't close it, yet. Load the state in vSNES, and go to HEX Viewer. You'll get this screen:


Click on CGRAM.


As you can see, all 512 bytes of palette information is shown on this preview. the first 2 bytes, C104, is what I'm gunning for. Now that I have the palette map, lets find the current address of it in memory. now you need ArtMoney.
http://www.artmoney.ru/

Now point ArtMoney to your game and search for an exact value, the value of color 0. For me, it is C104. This is the tricky one, to search for it, you must flip the byte value, in my case, it's 04c1.


As you can see, I have two values. no need for trial and error, the next two bytes should match the ones in the palette map.


Add that one as a 2-byte integer. They differ per game so this is not an address for all, however, you can change it using a reference point. Anyway, lets change the color to Magenta.

Magenta is R255 G0 B255, but....those are 8-bit color values. we need to convert them to 5-bit color values. to do so, that's as simple as finding the closest multiple of 8 per color value and multiply it by 8 then subtract 1. 255 is closest to 256, and 0 is 0.

256/8-1 = 31 or 11111111 >>3 = 11111 for all you technical types.

so I got R32 G0 B32. Now, make it into an integer. to do so, use this equation:

I=(R*1024)+(G*32)+(B*1)

I get a huge number, 31775.

Now finally, plug it in to the value you just found, you will now have a nice magenta background.



Lesson Two: Hit Sparks, I Hate Hit Sparks...

Another thing I hate about sprite ripping is the hitsparks. You hit a person, you're bound to get them, and you will have to clean them up somehow. What if I said you don't have to?

Load up vSNES and your save state. I suggest you backup the state in case you mess up. Now, open the Memory Viewer:


SNES games use 4-bit info, so let's set it to 4-bits if not already there.


You will see all the graphics that are being used at the time of you saving the state. keep in mind, it will be loaded back either at the next round of the next fight. this will not affect the ROM Image in any way. Anyway, lets find those hit sparks.

You would also want to see them in better colors. to do so, just open palette viewer and scroll the leftmost color until you find one that's right for you.

The plus and minus buttons allows you to scroll through the memory viewer. do so until you reach the top-left corner of the sprite you wish to remove. If you can't reach it, set the x and y window size values to a lower number multiple of 8.



Look at the offset.



That's where you want to go on Hex Editor, So lets go there! Type in the offset you found in Memory Viewer into Hex Editor.



I changed the window size to 8 bytes x 8 bytes here because this is the amount of bytes you need to zero out for an 16x8 tile. Change all those values into zeros. Unfortunately, my tile is a 16x16 tile, as shown in this figure:



Now, this is how the SNES stores the tiles in VRAM. every 32 bytes of data starting from byte zero of the sprite is an 8x8 sub-sprite, every subsequent 32 bytes is an 8x8 sub-sprite to the right of the sprite is was before. it does that until the width is reached (in this case when 16 pixels of width is reached, or 64 bytes) and then skips another 512 bytes to do the same for the sub-sprites below the one before it. in example:

Byte OffsetSub-Sprite Dimension Offset
08x816x8
5128x1616x16

So lets zero the 64 bytes we found and then go to the offset+200, because 512 in decimal is 200 in Hex. Since we know that 64 bytes is an 16x8 tile, we zero out the 64 bytes starting from the new offset.



if you are wondering how to zero out the sprites by each other, just zero out the bytes after byte 64. each 64-bit group is another 16x8 sprite just go willy-nilly until you get them all. I've took the liberty to zero-out all the hit sparks and the shadow on Dead Dance
<-Before
After->

I also suggest using a faster hex editor. The hex Editor in vSnes is slow as molasses to me.
Accusare nemo se debet nisi coram Veridis
DYNOMITE
Last Edit: August 13, 2010, 05:25:52 am by B. Marquis
Re: SNES Sprite Ripping: The Introduction of Hex-Mapping
#2  August 08, 2009, 05:40:50 pm
  • avatar
  • ****
zomG, this is really good, no more hitspark cleaning, but it is still quite complex.  :sugoi: