In this final entry about hacking Cory in the House DS, I will be discussing the sprite files for the dialog heads. The same ones we use as emoticons here. This was probably the most amount of time we spent on determining back in 2008 only find absolutely nothing in regards to how these files stored their data. And of course after mucking around with them four years later, I was able to determine where each pixel was stored along with the location and color data. A lot of determining this was pretty much a ton of trial and error and a bunch of just messing around with my program until things started looking closer and closer to an image that made sense. Figuring this out was the most difficult due to most, if not all, the header data between all the dialog head sprites were exactly the same. That meant I couldn't figure out what each part of the header represented, however since it was all the same, I didn't have much to worry about, unless I were to work on the sprites that weren't dialog head sprites. Unfortunately, what I was able to figure out only worked on the dialog head sprites, as all the other sprites would come up with jumbled image. Had it worked, we could have changes things like the title screen, Disney logo, inventory items, etc. Not to mention there are texture files, while they are not the same file extension as sprites, they look somewhat similar in where the pixels are stored, so we could've made Cory look like whatever we wanted. Maybe some other day.
But with that all out of the way, there are 3 files for each sprite: an obj file and two inc files. The obj file contains all the data about the sprite such as the length, width, and the color of each pixel. The location of the pixel followed a pattern of where the it was stored in the file, which I will get to later. The two inc files contained the exact same data between all other sprites other than the name of the file, so for dialog head sprites, I have no clue what they were used for. So, for this entry I will just be discussing the obj files. One of the first things I did to determine what was stored in these obj files was to compare what two different files and see what their differences and similaries were.
I got something like this when comparing the Normal and Happy Cory sprites
It wouldn't seem very helpful at first glance, but we know two things, the header of the files are exactly the same and some parts look very similar but are using different values. Such as the left file used 27 and 28 while the right used 2B and 2A. The patterns of 00 were also similar near the beginning of the differences. After a long while, I was able to deduce that these were the pixels of the file, they were not compressed (thankfully), and each value was a color. I was also able to correctly deduce that these values map to a color somewhere else as the values were very close to each other and they only took 1 byte to store each pixel. I would assume that 256 colors would not be enough to accurately portray Cory's visage. Another point was that the differences at the start were consistently different, and someone back in 2008 tried swapping two files to see what would happen and the colors went out of whack. This meant that a palette is stored for each sprite rather than using the same one for all of them, otherwise swapping the files would not have changed the colors used.
In the end, this is what I was able to determine as the structure of the obj file:
The first four bytes are the file signature. You'll see these in many different file types, they quickly let the program know that it's reading the right type of file before trying to process it. The next seven chunks of 4 bytes are offsets to each header value (note that like in the other files, these are increasing in size: 34, 40, 42, 4A, etc.) These values are used to tell how far to read each bit of data, which I grouped in orange blocks. I was only able to determine where the length and width are stored in these header blocks, which I highlighted in yellow (40 is 64 in hexadecimal, so it's a 64x64 image). The rest of the file is where all pixels are stored. Note that I highlighted in green 8 byte chunks and then highlighted 8 of these chunks. Every 64 bytes is an 8x8 tile, so the first 8 bytes are the top row, then next 8 bytes are the 2nd row, and so on. Now the part that took a lot of messing around to figure out, which was how these 8x8 tiles are arranged. After some time, I was able to find out that they are stored as four groups of 8x8 tiles to make a 16x16 tile and are arranged as top-left, top-right, bottom-left, bottom-right. These 16x16 tiles are then stored in this fashion:
The partially filled in numbers are the order in the file that those pixels are stored. The 16x16 tiles are arranged from the top-left and move to the right until the width is met, then it moves to the next row and continues until all the tiles are arranged to make a 64x64 image. And that's it really, I had got my program to read the obj files, and was able to get the image to display.
Well almost, I put each value as a random color because I wasn't aware of where or how the palettes were stored. The good news was that they're stored in a file called "Palettes.bin" and the other good news was that they are stored in a common Nintendo DS 16-bit color format, so it was relatively easy to convert then to 24-bit color that most people use. The palette file was also easy to read, it simply followed this pattern: number of colors in the sprite, definition of each color, number of colors in the sprite, definition of each color, and so on. The only thing was that I could not find anywhere that mapped each palette to what sprites, so I just brute forced my way through all the dialog head sprites until the colors matched.
And that was that, I knew enough about the sprite and palette files that I quickly wrote a sprite importer and exporter and created this YouTube video replacing Cory with the avatar I had at the time complete with witty dialog and laugh track to emphasize the unbeatable humor.
That was everything I was able to accomplish in the couple months I worked on this. For anyone interested, the download link to the ROM hacker can be found here. It will require a ROM unpacker to unpack the ROM file before using and to pack the ROM after editing, but it works pretty well for what it does.
But with that all out of the way, there are 3 files for each sprite: an obj file and two inc files. The obj file contains all the data about the sprite such as the length, width, and the color of each pixel. The location of the pixel followed a pattern of where the it was stored in the file, which I will get to later. The two inc files contained the exact same data between all other sprites other than the name of the file, so for dialog head sprites, I have no clue what they were used for. So, for this entry I will just be discussing the obj files. One of the first things I did to determine what was stored in these obj files was to compare what two different files and see what their differences and similaries were.
I got something like this when comparing the Normal and Happy Cory sprites
It wouldn't seem very helpful at first glance, but we know two things, the header of the files are exactly the same and some parts look very similar but are using different values. Such as the left file used 27 and 28 while the right used 2B and 2A. The patterns of 00 were also similar near the beginning of the differences. After a long while, I was able to deduce that these were the pixels of the file, they were not compressed (thankfully), and each value was a color. I was also able to correctly deduce that these values map to a color somewhere else as the values were very close to each other and they only took 1 byte to store each pixel. I would assume that 256 colors would not be enough to accurately portray Cory's visage. Another point was that the differences at the start were consistently different, and someone back in 2008 tried swapping two files to see what would happen and the colors went out of whack. This meant that a palette is stored for each sprite rather than using the same one for all of them, otherwise swapping the files would not have changed the colors used.
In the end, this is what I was able to determine as the structure of the obj file:
The first four bytes are the file signature. You'll see these in many different file types, they quickly let the program know that it's reading the right type of file before trying to process it. The next seven chunks of 4 bytes are offsets to each header value (note that like in the other files, these are increasing in size: 34, 40, 42, 4A, etc.) These values are used to tell how far to read each bit of data, which I grouped in orange blocks. I was only able to determine where the length and width are stored in these header blocks, which I highlighted in yellow (40 is 64 in hexadecimal, so it's a 64x64 image). The rest of the file is where all pixels are stored. Note that I highlighted in green 8 byte chunks and then highlighted 8 of these chunks. Every 64 bytes is an 8x8 tile, so the first 8 bytes are the top row, then next 8 bytes are the 2nd row, and so on. Now the part that took a lot of messing around to figure out, which was how these 8x8 tiles are arranged. After some time, I was able to find out that they are stored as four groups of 8x8 tiles to make a 16x16 tile and are arranged as top-left, top-right, bottom-left, bottom-right. These 16x16 tiles are then stored in this fashion:
The partially filled in numbers are the order in the file that those pixels are stored. The 16x16 tiles are arranged from the top-left and move to the right until the width is met, then it moves to the next row and continues until all the tiles are arranged to make a 64x64 image. And that's it really, I had got my program to read the obj files, and was able to get the image to display.
Well almost, I put each value as a random color because I wasn't aware of where or how the palettes were stored. The good news was that they're stored in a file called "Palettes.bin" and the other good news was that they are stored in a common Nintendo DS 16-bit color format, so it was relatively easy to convert then to 24-bit color that most people use. The palette file was also easy to read, it simply followed this pattern: number of colors in the sprite, definition of each color, number of colors in the sprite, definition of each color, and so on. The only thing was that I could not find anywhere that mapped each palette to what sprites, so I just brute forced my way through all the dialog head sprites until the colors matched.
And that was that, I knew enough about the sprite and palette files that I quickly wrote a sprite importer and exporter and created this YouTube video replacing Cory with the avatar I had at the time complete with witty dialog and laugh track to emphasize the unbeatable humor.
That was everything I was able to accomplish in the couple months I worked on this. For anyone interested, the download link to the ROM hacker can be found here. It will require a ROM unpacker to unpack the ROM file before using and to pack the ROM after editing, but it works pretty well for what it does.