emulators.wii_nand
Placement rules for a Wii NAND title save, shared by Dolphin and RetroArch's Dolphin core.
Placement rules for a Wii NAND title save, shared by Dolphin and RetroArch's Dolphin core.
Both keep the emulated NAND as an ordinary tree: title/<high>/<low>/data/...
holds a title's save, and sys, ticket, a system title and a title's
content are the console's own. Where the tree lives differs (Wii in
Dolphin's user folder, saves/dolphin-emu/User/Wii under RetroArch), so the
caller names it. The functions here take no emulator, so they stay pure.
attributeSAVE_SHAPE= 'title/<00010000|00010001|00010004>/<title id>/data/...'The save shape a save KindSpec advertises for a Wii session.
attributeNAND_EXPECTED= f'a Wii save, {SAVE_SHAPE}'What a Wii save member must look like, for refusals.
attributeNAND_TITLE_RE= re.compile('title', re.ASCII)The NAND folder every installed title's data sits under.
attributeNAND_HIGH_RE= re.compile('0001000[014]', re.ASCII)A title id's high half for a title with player saves: a disc, a channel, or a disc with a channel.
attributeNAND_LOW_RE= re.compile('[0-9A-Fa-f]{8}', re.ASCII)A title id's low half: the four-character game code, in hex.
funcunwrap(parts, wrappers) -> tuple[str, ...]Strip the first wrapper a member path arrived under.
A wrapper is only stripped when something is left below it, so a file named like a wrapper folder is not emptied away.
parampartstuple[str, ...]The member's components.
paramwrapperstuple[tuple[str, ...], ...]Candidate leading folders, longest first.
Returns
tupleThe components below the wrapper, or parts when none matched.
funcis_nand_system(rest) -> boolTell whether a NAND path is system or install data rather than a title's save.
Such a path is placed as named, so the plan check refuses it against the emulator's protected globs as emulator configuration, which tells the player more than a layout refusal would.
paramresttuple[str, ...]The path's components below the NAND root.
Returns
boolTrue under sys or ticket, a system title (title/00000001), or a title's content.
funcnand_leaf_refusal(member, expected=NAND_EXPECTED) -> imports.ImportRefusalRefuse a Wii member that is not under a title's data folder, naming what it looks like.
parammemberimports.ImportMemberThe member.
paramexpectedstr= NAND_EXPECTEDThe accepted shape, in words.
Returns
webstation_broker.imports.ImportRefusalA conversion refusal for an SD-card export, a source refusal for a
funcplace_nand(member, session, *, subtree, wrappers, expected=NAND_EXPECTED) -> Union[imports.Placement, imports.ImportRefusal]Place a file of a Wii title's save under <subtree>/title/<high>/<low>/data.
The path is found below at most one wrapper. A title reads its save from the folder named for its own id, so the title is held strictly to the session's game. System and install data is placed as named, for the plan check to refuse as protected.
parammemberimports.ImportMemberThe member.
paramsessionimports.SessionIdentityThe session's identity.
paramsubtreestrWhere the NAND tree lives, relative to the save root.
paramwrapperstuple[tuple[str, ...], ...]The leading folders a NAND path may arrive under, longest first.
paramexpectedstr= NAND_EXPECTEDThe accepted shape, in words.
Returns
typing.UnionThe placement, or a refusal.