How To Detect SM64 ROM Versions In C
#1
void check_rom()
{
// Read byte by byte so endian-ness is irrelevant
    fseek(rom, 0, SEEK_SET);
// 59th byte starts region ID
    fseek(rom, 59, SEEK_SET);
    fread(&rom_byte_1, 1, 1, rom);
    fread(&rom_byte_2, 1, 1, rom);
    fread(&rom_byte_3, 1, 1, rom);
    fread(&rom_byte_4, 1, 1, rom);
    
    if(rom_byte_1 == 0x4E && rom_byte_2 == 0x53 && rom_byte_3 == 0x4D && rom_byte_4 == 0x4A) //NSMJ in hex, both OG japan and shindou ROMs contain this
    {
    fseek(rom, 0, SEEK_SET);
// 35th byte starts ER M in OG japan and ERMA in shindou, how convenient. This is because shindou says the game name is SUPERMARIO64, all other versions say SUPER MARIO 64
    fseek(rom, 35, SEEK_SET);
    fread(&rom_byte_1, 1, 1, rom);
    fread(&rom_byte_2, 1, 1, rom);
    fread(&rom_byte_3, 1, 1, rom);
    fread(&rom_byte_4, 1, 1, rom);
        if(rom_byte_1 == 0x45 && rom_byte_2 == 0x52 && rom_byte_3 == 0x20 && rom_byte_4 == 0x4D) //ER M in hex
        {
        printf("Validated ROM as .z64 Japan\n");
        }
        else if(rom_byte_1 == 0x45 && rom_byte_2 == 0x52 && rom_byte_3 == 0x4D && rom_byte_4 == 0x41) //ERMA in hex
        {
        printf("Validated ROM as .z64 Shindou Edition\n");
        }
        else
        {
// Should be impossible
        printf("Error: Can not figure out if this is the original Japan or the Shindou Edition ROM!\n");
        end_input = TRUE;
        }
    }
    else if(rom_byte_1 == 0x4E && rom_byte_2 == 0x53 && rom_byte_3 == 0x4D && rom_byte_4 == 0x45) //NSMJ in hex
    {
    printf("Validated ROM as .z64 USA\n");
    }
    else if(rom_byte_1 == 0x4E && rom_byte_2 == 0x53 && rom_byte_3 == 0x4D && rom_byte_4 == 0x50) //NSME in hex
    {
    printf("Validated ROM as .z64 PAL\n");
    }
    else
    {
    fseek(rom, 0, SEEK_SET);
    fread(&rom_byte_1, 1, 1, rom);
    fread(&rom_byte_2, 1, 1, rom);
    fread(&rom_byte_3, 1, 1, rom);
    fread(&rom_byte_4, 1, 1, rom);
        if(rom_byte_1 == 0x37 && rom_byte_2 == 0x80 && rom_byte_3 == 0x40 && rom_byte_4 == 0x12) // First 4 bytes of a little endian sm64 rom which is NOT supported
        {
        printf("This is a little-endian, .n64 format SM64 ROM file. SM64GSW requires a big-endian, .z64 format SM64 ROM file.\n");
        end_input = TRUE;
        }
        else
        {
        printf("Error: This does not appear to be a valid SM64 ROM!\n");
        end_input = TRUE;
        }
    }
}

This is a little snippet of the SM64GSW v1.4 I'm working on, and I thought this could be useful to others. The above code was figured out by myself using a hex editor on various .z64 (A.K.A Big-Endian PROPER file format ROMs). This is 3-BSD licensed as SM64GSW is 3-BSD licensed (but does not include this code yet) https://github.com/alex-free/sm64gsw . Of course simple file markers are not copyrightable so feel free to use them in other software, no matter the license Smile
Reply




Users browsing this thread: 2 Guest(s)