How to decode the Nintendo logo from gameboy?

2020-07-03 05:24发布

问题:

I've tried to decode the following bitmap using the background pallete scheme described at http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Graphics

CE ED 66 66 CC 0D 00 0B 03 73 00 83 00 0C 00 0D 00 08 11 1F 88 89 00 0E DC CC 6E E6 DD DD D9 99 BB BB 67 63 6E 0E EC CC DD DC 99 9F BB B9 33 3E

source: http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header#0104-0133_-_Nintendo_Logo

But I only got something that resembles a noise.

In what direction should I go? Is it using compression? I can't find more information about this dump in the internet.

Best so far (20x zoom):

回答1:

There is no compression or encrytion at all. The logo is binary encoded: 1 is black and 0 is white/green/whatever you want to call the background color of the game boy).

Simply put the hexadecimal string in the correct order and then convert the hex chars to binary:

Hexadecimal:

C 6 C 0 0 0 0 0 0 1 8 0
E 6 C 0 3 0 0 0 0 1 8 0
E 6 0 0 7 8 0 0 0 1 8 0
D 6 D B 3 3 C D 8 F 9 E

D 6 D D B 6 6 E D 9 B 3
C E D 9 B 7 E C D 9 B 3
C E D 9 B 6 0 C D 9 B 3
C 6 D 9 B 3 E C C F 9 E

Binary:

1100 0110 1100 0000 0000 0000 0000 0000 0000 0001 1000 0000
1110 0110 1100 0000 0011 0000 0000 0000 0000 0001 1000 0000
1110 0110 0000 0000 0111 1000 0000 0000 0000 0001 1000 0000
1101 0110 1101 1011 0011 0011 1100 1101 1000 1111 1001 1110
1101 0110 1101 1101 1011 0110 0110 1110 1101 1001 1011 0011
1100 1110 1101 1001 1011 0111 1110 1100 1101 1001 1011 0011
1100 1110 1101 1001 1011 0110 0000 1100 1101 1001 1011 0011
1100 0110 1101 1001 1011 0011 1110 1100 1100 1111 1001 1110

There you go. Your Nintendo logo (w/o 0 and spaces):

11   11 11                             11       
111  11 11        11                   11       
111  11          1111                  11       
11 1 11 11 11 11  11  1111  11 11   11111  1111 
11 1 11 11 111 11 11 11  11 111 11 11  11 11  11
11  111 11 11  11 11 111111 11  11 11  11 11  11
11  111 11 11  11 11 11     11  11 11  11 11  11
11   11 11 11  11 11  11111 11  11  11111  1111 

Using instead of 1:

██   ██ ██                             ██       
███  ██ ██        ██                   ██       
███  ██          ████                  ██       
██ █ ██ ██ ██ ██  ██  ████  ██ ██   █████  ████ 
██ █ ██ ██ ███ ██ ██ ██  ██ ███ ██ ██  ██ ██  ██
██  ███ ██ ██  ██ ██ ██████ ██  ██ ██  ██ ██  ██
██  ███ ██ ██  ██ ██ ██     ██  ██ ██  ██ ██  ██
██   ██ ██ ██  ██ ██  █████ ██  ██  █████  ████ 


回答2:

In addition to the answer by PBurggraf, here is a snippet of my code that I used to check my understanding of it.

static const uint8_t data[] = {
    0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, 0x03, 0x73, 0x00, 0x83,
    0x00, 0x0C, 0x00, 0x0D, 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E,
    0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99, 0xBB, 0xBB, 0x67, 0x63,
    0x6E, 0x0E, 0xEC, 0xCC, 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E,
};

for(int y=0; y<8; ++y)
{
    int i = ((y/2)%2)+(y/4)*24;
    for(int x=0; x<12; ++x,i+=2)
    {
        const uint8_t nibble = (y%2) ? (data[i]&0xF) : (data[i]>>4);
        for(int b=4; b--;) std::cout << (((nibble>>b)&1) ? "*" : " ");
    }
    std::cout << std::endl;
}

It outputs:

**   ** **                             **       
***  ** **        **                   **       
***  **          ****                  **       
** * ** ** ** **  **  ****  ** **   *****  **** 
** * ** ** *** ** ** **  ** *** ** **  ** **  **
**  *** ** **  ** ** ****** **  ** **  ** **  **
**  *** ** **  ** ** **     **  ** **  ** **  **
**   ** ** **  ** **  ***** **  **  *****  **** 

Hope it helps someone.



回答3:

Clarification:

And there is a kind of enryption/compression on the logo.

  1. You must sort the hexstring (decrypt)
  2. You must draw each bit 4 times (decompress) As pokechu22 said before.