Skip to content

Extracting NES and N64 ROMs from The Legend of Zelda: Collector's Edition (GameCube) #305

@RealRelativeEase

Description

@RealRelativeEase

I stumbled upon a blogpost by @sethmlarson which makes the extraction process for the Zelda Collection which had been released on GameCube a lot easier. Just download this script, put it in the same folder as the .tgc files extracted via the Dolphin file system browser and run python [name of script].py. The script will extract all of the ROMs, No-Intro names and iNES 2.0 header included.

I took the liberty of making an edit to the script to make it compatible with the PAL version of the compilation, updating the No-Intro names in the process:

# License: MIT

import hashlib
import os.path


def extract_nes(data: bytes, length: int) -> bytes:
    offset = data.find(b"NES\x1A")
    if length == 0x20000:
        header = b"\x4E\x45\x53\x1A\x08\x00\x12\x08\x00\x00\x70\x07\x00\x00\x00\x01"
    elif length == 0x40000:
        header = b"\x4E\x45\x53\x1A\x08\x10\x12\x08\x00\x00\x70\x00\x00\x00\x00\x01"
    else:
        raise ValueError(f"Unknown header for ROM length: {length}")
    offset += len(header)
    return (
        header +
        data[offset:offset+length]
    )


def extract_n64(data: bytes, length: int) -> bytes:
    offset = data.find(b"\x80\x37\x12\x40")
    return data[offset:offset+length]


def main():
    for to_file, from_tgc, rom_type, length in (
        # ROM names and lengths from No-Intro: https://datomatic.no-intro.org/
        ("Legend of Zelda, The (USA) (Zelda Collection).nes", "EUR_NES_ZELDA1.tgc", "NES", 0x20000),
        ("Zelda II - The Adventure of Link (USA) (Zelda Collection).nes", "EUR_NES_ZELDA2.tgc", "NES", 0x40000),
        ("Legend of Zelda, The - Ocarina of Time (Europe) (GameCube).z64", "zelda_PAL_093003.tgc", "N64", 0x2000000),
        ("Legend of Zelda, The - Majora's Mask (Europe) (GameCube).z64", "majora_PAL_100403c.tgc", "N64", 0x2000000),
        ("Legend of Zelda, The (USA) (Zelda Collection).nes", "USA_NES_ZELDA1.tgc", "NES", 0x20000),
        ("Zelda II - The Adventure of Link (USA) (Zelda Collection).nes", "USA_NES_ZELDA2.tgc", "NES", 0x40000),
        ("Legend of Zelda, The - Ocarina of Time (USA) (GameCube).z64", "zelda_ENG_090903.tgc", "N64", 0x2000000),
        ("Legend of Zelda, The - Majora's Mask (USA) (GameCube).z64", "majora_ENG_091003.tgc", "N64", 0x2000000),
    ):
        if not os.path.isfile(from_tgc):
            print(f"File not found: {from_tgc}")
            continue
        with open(from_tgc, "rb") as f:
            data = f.read()
        if rom_type == "NES":
            rom = extract_nes(data, length)
        elif rom_type == "N64":
            rom = extract_n64(data, length)
        else:
            raise ValueError(f"Unknown ROM type: {rom_type}")
        rom_md5 = hashlib.md5(rom).hexdigest()
        with open(to_file, "wb") as f:
            f.truncate()
            f.write(rom)
        print(f"Extracted {to_file} ({rom_md5})...")


if __name__ == "__main__":
    main()

I don't have a Japanese copy of the collection, so I can't provide an edit for that release. But I would assume that it uses the Famicom Disk System versions instead of the Western releases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions