Hacking NDS ROM File Format

  • Thread starter Thread starter pekalicious
  • Start date Start date
  • Views Views 33,373
  • Replies Replies 20
I need someone to verify if all of my following notes are correct:

Step 1.
According to this specification, the offset for the icon and titles information resides at the address 0x68 and is of length 4 bytes.
In a random NDS ROM using a Hex Editor I get the following bytes: 00 E0 19 00
Reversing these bytes gives me the address I am looking for, namely, 00 19 E0 00


Step 2.
I use these four bytes and go to the specified address. From thereon, according to the same specification, the first 32 bytes (2+2+28) are various information I currently don't care. The next 512 bytes are the icon data followed by 32 bytes of the color palette data.

Step 2-A.

Now, the title data are arranged exactly as DanThenManMS mentioned in this thread:

DanTheManMS said:
I had to draw a picture to figure it out, but I think I understand it. Okay, so let's just take a look at a single tile first. This tile is defined by a block of bytes, 4 wide by 8 tall. If you write this out as a series of bits, at 8 bits to a byte this gives you a block that is 8 rows of 32 bits each. At 4 bits to a pixel ("4bit depth") this gives you 8 rows of 8 pixels, or in other words, an 8x8 block of pixels (a "tile"). You then have a 4x4 arrangement of these tiles, which gives you a 32x32 pixel image.

This diagram I whipped together might help explain what I'm trying to say here:

Code:
Here's the 4x8 arrangement of bytes for a single tile:

B B B B
B B B B
B B B B
B B B B
B B B B
B B B B
B B B B
B B B B

If we expand that out into bits, we get something like:

11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111
11110000 11110000 11110000 11110000
00001111 00001111 00001111 00001111

Then space it out into pixels, 4 bits per pixel:

1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111
1111 0000 1111 0000 1111 0000 1111 0000
0000 1111 0000 1111 0000 1111 0000 1111

Which turns into pixels of various colors:

Pixl Pixl Pixl Pixl Pixl Pixl Pixl Pixl
Pixl Pixl Pixl Pixl Pixl Pixl Pixl Pixl
Pixl Pixl Pixl Pixl Pixl Pixl Pixl Pixl
Pixl Pixl Pixl Pixl Pixl Pixl Pixl Pixl
Pixl Pixl Pixl Pixl Pixl Pixl Pixl Pixl
Pixl Pixl Pixl Pixl Pixl Pixl Pixl Pixl
Pixl Pixl Pixl Pixl Pixl Pixl Pixl Pixl
Pixl Pixl Pixl Pixl Pixl Pixl Pixl Pixl

So then a single tile looks like this in the end, 8x8 pixels:

- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 
- - - - - - - - 

Then a 4x4 grid of those:

- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + + 
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +

+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 

- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + + 
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +
- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +

+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - - 
+ + + + + + + +ÂÂ- - - - - - - -ÂÂ+ + + + + + + +ÂÂ- - - - - - - -

Hope this is correct, and if it is, hope it helped.

So let's look at the first four bytes of the icon data:
original hex binary data split binary data corresponding decimals (indexes to the color palette)
78 87 49 AA 01111000 10000111 01001001 10101010 0111 1000 1000 0111 0100 1001 1010 1010 7 8 8 7 4 9 10 10

Step 2-B.
DanTheManMS said:
I read the next 32 bytes for the color palette. Again, according to the previous specification, these 32 bytes holds 16 colors, 2 bytes for each color.
The first two color bytes are 3D 2B, we reverse these and get 2B 3D:
2B 3D 00101011 00111101
Now, according to this post, NDS ROMs use the same scheme as GBA, which, as stated in this specification, is:
QUOTE said:
X BBBBB GGGGG RRRRR
So, in our previous color data we get:
2B 3D 0 01010 11001 11101 0 10 25 29

As you can see, the numbers are really low, and I suspect that something is wrong. Here are all the colors I parsed from a ROM:
b,g,r
10,25,29
16,24,29
11,19,26
0,1,2
6,12,18
8,16,23
3,7,12
3,8,13
4,9,14
5,10,16
7,13,21
2,6,11
1,4,8
0,3,7
1,5,10
0,0,0

This is how I create a color in Java using the first two bytes:

Code:
byte c1b1 = palette[0];
byte c1b2 = palette[1];
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
// Use ByteBuffer to "stick" together two bytes into a short
ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.BIG_ENDIAN);
bb.put(c1b2);
bb.put(c1b1);
int c2 = bb.getShort(0); // Format is 0BBBBBGGGGGRRRRR
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
int b = (c2 & 0x7C00) >> 10;
int g = (c2 & 0x3E0) >> 5;
int r = (c2 & 0x1F);
Color c = new Color(r,g,b);

If I paint the image now, I only see a black 32x32 image.
But, if I brighten the colors of each component A LOT I will see the image!

CODE
Color c = new Color(r,g,b).brighter().brighter().brighter().brighter().brighter();

I am guessing that each color has a prefix or that I need to define another color space. Not really sure.

Does anybody know?
 

Site & Scene News

Popular threads in this forum