x.1sav.dirent.gc-mc
Owner: these specifications, under a reserved name · Applies to: a card’s part · Status: normative schema, optional to carry
The 64 bytes a GameCube memory card keeps for one save, as fields rather than as a blob. This is the write half of
x.1sav.dirent, which normalizes the two times any card records but does
not rebuild an entry. The name sits under that key rather than beside it, the way each chip has a key of its own under
x.1sav.rtc.
Schema
Section titled “Schema”; ============================================================================; x.1sav.dirent.gc-mc - a GameCube directory entry, field by field;; An extension key for the Universal Saves Format, defined by these; specifications under a name reserved in the Vendor Names registry because a; GameCube entry has one layout and every tool that writes one writes it.;; The 64 bytes themselves are already carried verbatim in the part's `dirent`.; This key is the structured form, for the writer that has to build an entry; rather than copy one. Fields a writer regenerates are absent by design; the; page says which and why.;; The root here is the value carried under the key, not a bundle. A bundle; validates against the format's own schema whatever this holds, since an; extension value is `any` there; this file is what makes the shape checkable.; ============================================================================
dirent-gc-mc = { 0 => tstr .size 4, ; game_code - 0x00, "GFZE" 1 => tstr .size 2, ; maker_code - 0x04, "01" 2 => bstr .size (1..32), ; filename - 0x08, unpadded 3 => uint .size 1, ; banner_flags - 0x07 4 => uint .size 2, ; icon_format - 0x30, two bits per icon 5 => uint .size 2, ; anim_speed - 0x32, two bits per frame 6 => uint .size 1, ; permissions - 0x34 7 => uint .size 1, ; copy_counter - 0x35 ? 8 => uint .size 4, ; image_offset - 0x2c, absent where 0xffffffff ? 9 => uint .size 4, ; comments_offset - 0x3c, absent where 0xffffffff}game_code and maker_code are the ASCII identifiers at 0x00 and 0x04.
game’s serial usually holds them joined, but that is a hint a producer may
normalize or omit.
filename is the raw name at 0x08 without its padding, carried as bytes rather than text: a Japanese save names itself
in Shift-JIS and path is UTF-8 by construction, so transcoding in and back out
need not land on the same 32 bytes.
banner_flags, icon_format and anim_speed at 0x07, 0x30 and 0x32 stay packed as the hardware packs them, two bits
per icon and two bits per frame. The decoded picture is x.1sav.icon.
permissions and copy_counter at 0x34 and 0x35 are the copy protection bits and the count a console decrements.
image_offset and comments_offset at 0x2c and 0x3c point into the payload, and are absent where the entry holds
0xffffffff.
What a writer fills in
Section titled “What a writer fills in”Four fields of the 64 are not carried here.
| Field | Offset | Instead |
|---|---|---|
modtime | 0x28 | Carried as modified_at in x.1sav.dirent. A GameCube clock has no zone, so the reading takes the one-element form there and the value is a plain shift of epoch in either direction. |
first_block | 0x36 | The allocator’s, and regenerated. |
block_count | 0x38 | Payload size over the block size. |
| padding | 0x06, 0x3a | Constant 0xff and 0xffff. |
Re-serializing this key therefore reproduces the entry except for the fields a writer owns. A consumer that wants the
original 64 bytes reads the part’s dirent.
When to set it
Section titled “When to set it”When the producer parsed the entry, and when something downstream may have to build one. A producer MUST NOT write a field the entry does not hold: there is nothing to normalize here, so a value that is not the entry’s is wrong.