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.
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:
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.