Well, I was going to test adding sprites with my free scroll patch, but after laying the screenshots over the map to get the positions and getting ready to paste the real sprites on them, I realized that there are no rips of Umihara Kawase sprites, excluding the player sprite! I can't rip them manually myself because the current SNES9x emulates the game incorrectly, and I honestly don't like ZSNES.
So, I though, why not stab two flies in one hit and get rips from each sprite in the game, for the benefit of the collective and to apply fresh clean sprites onto the maps? Here's my plan:
Umihara Kawase Shun: Second Edition Kanzenban for the DS is essentially a 3-in-1 game that also includes the SNES Umihara Kawase game. Since the DS has a filesystem of its own, by decompressing all of the game's files you can access them as if they were real folders and files in Windows Explorer/Finder.
This is particularly exciting because all of the files in the 'sfc' folder are actually the files the SNES game actually uses. You can, for example, search any of the files in the 'sfc/map/' from the original SNES ROM and find the level data. Some data has been re-encoded losslessly, but it's pretty much the same data.
So, instead of searching for the graphics individually in one giant chunk of a file (the SNES ROM), I looked into the 'sfc/obj/' folder and found files of each sprite set in the game. The files also contain palette and tilemap info, so one program that does exactly what I've explained below could easily spew out every single sprite in the game!
.BIN file structure:
All BINs have a $18 byte header that defines eight
things:
1. Where the block array begins [BLKADDR, 4 bytes]
2. Where the sprite definition begins [SPRADDR, 4 bytes]
3. Where the palette info begins [PALADDR, 4 bytes]
4. Where the graphics data begins [GFXADDR, 4 bytes]
5. Amount of blocks [BLKAM, 2 bytes]
6. Amount of sprites [SPRAM, 2 bytes]
7. Amount of palettes [PALAM, 2 bytes]
8. Amount of tiles in total [TOTAL, 2 bytes]
Let's take U3_KNG.bin, which is the Goldfish enemy's sprite file. First $18 bytes with appropriate annotations are below:
addr.+------------------------
| BLKADDR____ SPRADDR____
$000 | 18 00 00 00 88 00 00 00
+
| PALADDR____ GFXADDR____
$008 | A0 00 00 00 C0 00 00 00
+
| BLKAM SPRAM PALAM TOTAL
$010 | 0E 00 05 00 01 00 40 00
-----+------------------------
• Let's dive into the first
thing, BLKADDR. Sprites are built from blocks and one block is 8 bytes. This is the address where the 8-byte block array begins. The program reads the bytes backwards so it gets the correct address, which is 0x00000018.
• The second
thing, SPRADDR is the offset where the program starts reading the info of what blocks to use to build a sprite. This time it's at 0x00000088.
• Third
thing, PALADDR is self-explanatory. Where the Palette data begins. In this case, from 0x000000A0. Palettes are read the same way as the SNES ones I explained earlier in this thread, 1555 BGR.
• Fourth
thing, GFXADDR is also pretty obvious; where the graphics data begins. This time 0x000000C0. Format is
4bpp linear, reverse order.
• Fifth
thing, BLKAM is 0x000E. What this means is how many blocks there are in total. This time, 0x000E. Also, since one block is 8 bytes, you now know that the block data starts from 0x00000088 and is 112 bytes big (because BLKAM * 8 = $70).
• Sixth
thing, SPRAM is 0x0005. What this means is exactly how many sprites are exported in the end. This time, 0x0005. It takes four bytes to define a sprite, so you now know that the sprite data begins from 0x00000088 and is 20 bytes big (because SPRAM * 4 = $14).
• Seventh
thing, PALAM, is again pretty clear. Usually sprites have one or two palettes, but in this case it's 0x0001. One palette is 32, or, $20 bytes. There's one palette this time so obviously it takes only 32 bytes as is.
• The eighth
thing serves little purpose. It just tells us how many tiles there are in total. This time 64, or, $40.
So, after the header, we're in address 0x018. This is where the blocks are listed, I've written them down for easy readability and added annotations:
addr.+-xx XX yy YY tt pp BP UU-+--NR--.
$018 | F3 FF F6 FF 00 00 60 00 | 0000 |
$020 | F3 FF 06 00 08 00 50 00 | 0100 |
$028 | FA FF EE FF 18 00 00 00 | 0200 |
$030 | F2 FF F6 FF 0C 00 60 00 | 0300 |
$038 | F2 FF 06 00 14 00 50 00 | 0400 |
$040 | FA FF EE FF 25 00 00 00 | 0500 |
$048 | F2 FF F6 FF 19 00 60 00 | 0600 |
$050 | F2 FF 06 00 21 00 50 00 | 0700 |
$058 | FA FF EE FF 32 00 00 00 | 0800 |
$060 | F2 FF F6 FF 26 00 60 00 | 0900 |
$068 | F2 FF 06 00 2E 00 50 00 | 0A00 |
$070 | FA FF EE FF 3F 00 00 00 | 0B00 |
$078 | F2 FF F6 FF 33 00 60 00 | 0C00 |
$080 | F2 FF 06 00 3B 00 50 00 | 0D00 |
-----+-------------------------+------'
I'll explain each of the eight bytes here, using the first block an example.
xx XX = X position of block, two bytes, read backwards, so in this case it would be $FFF3. See
this grid for reference.
yy YY = Y position of block, two bytes, read backwards, so in this case it would be $FFF6.
tt pp = tile to use and its property
†. In this case it would be tile 00 with property 00.
BP = Block type
‡ and Palette to use for the block. The palette is always 0 so I don't see how this would be so useful.
UU = Unused.
NR = Block Number. Just for reference! This is not in the ROM, I just put it to the right of the table to help visualize what block we're in right now. You'll need to know this later. From the first block definition it's just counting upwards from 00 00, bytes backwards.
†: property byte is kind of funny. Of its 8 bits, only the first two are used. vhUU UUUU, where v means vertical flip of block's tiles and h horizontal flip, respectively (and U=unused).
‡: There are twelve block types. They essentially tell how the block is made, or, arrange a predetermined amount of tiles to a certain arrangement to form the block. See
this for reference. $C_, $D_, $E_ and $F_ are unused.
Now, if the program would read the data, it would now have the information of how many blocks there are in total, how to form the correct blocks and where to put them. However, this would lead into all blocks being on top of each other, forming one sprite-cake. The next bytes, SPRADDR tells where to snip them apart, or, how many blocks build a sprite. Again, I've formatted and annotated the data for easy understanding.
addr.+ AMONT FROMB-.
$088 | 02 00 00 00 |
$08C | 03 00 02 00 |
$090 | 03 00 05 00 |
$094 | 03 00 08 00 |
$098 | 03 00 0B 00 |
-----+-------------'
Because SPRAM is $0005, we know that this file defines only five sprites. It takes four bytes to define a sprite an again, these two-byte combos are read backwards.
AMONT = Amount of blocks this sprite is built from...
FROMB = ...when counting from this Block Number.
In this case, it would be like this:
• Sprite one is two blocks: 0000 and 0100.
• Sprite two is three blocks: 0200, 0300 and 0400.
• Sprite three is three blocks: 0500, 0600 and 0700.
• Sprite four is three blocks: 0800, 0900, 0A00.
• Sprite five is three blocks: 0B00, 0C00, 0D00
And that's it. Load next file and repeat. I did this
informational GIF that should help understand what's happening in the sprite creation. If you have a chance, view it frame by frame. Basically it's just "Get X, get Y, get tile, check if flips, use correct block type"
Wow, big post, probably not as clear as I want it to be... I'm tired @_@. Also, apologies again to be
that guy who can't do anything without a programmer. I just hope my general plan is acceptable. I can always fall back to ZSNES to get the sprites I need but I thought that this would be great too :G
Here's a
link to all the BINs in a ZIP
But yeah, concentrating on getting all 57 ZSTs now. :3DONE. Check 'em out, the raw files are ready for ogling
here. I'm having problems with Dropbox sharing right now so just change the 00.zst to 36.zst or anything.zst to view the map.
Another interesting thing, there are 57 files in the MAP folder of the DS version, though there are only 48 accessible maps in the game. Unused levels, mayhaps?