Line 2: |
Line 2: |
| | | |
| See [[Mii Maker]] for the application chiefly designed to create, edit, delete, and trade Miis or convert them from and to a QR code. | | See [[Mii Maker]] for the application chiefly designed to create, edit, delete, and trade Miis or convert them from and to a QR code. |
| + | |
| + | The default endianness in this page is little-endian, unless explicitly specified. |
| | | |
| ==Mii Database== | | ==Mii Database== |
Line 18: |
Line 20: |
| | 0x4 | | | 0x4 |
| | 0x4 | | | 0x4 |
− | | Header 0x00010000 | + | | Header 0x00000100 |
| |- | | |- |
| | 0x8 | | | 0x8 |
− | | 0x23F7 | + | | 0x23F0 (100 * 0x5C) |
| | Array of owned (saved in Mii Maker) Miis. Order in file is unrelated to canonical order in-app. | | | Array of owned (saved in Mii Maker) Miis. Order in file is unrelated to canonical order in-app. |
| |- | | |- |
− | | 0x23FC | + | | 0x23F8 |
| | 0x4 | | | 0x4 |
| | Header "CFHE" | | | Header "CFHE" |
| |- | | |- |
− | | 0x23F8 | + | | 0x23FC |
− | | 0x4 | + | | 0x2 |
− | | Header 0xFFFFFFFF | + | | Linked list tail index. 0xFFFF if the list is empty |
| + | |- |
| + | | 0x23FE |
| + | | 0x2 |
| + | | Linked list head index. 0xFFFF if the list is empty |
| |- | | |- |
| | 0x2400 | | | 0x2400 |
− | | 0xA410 | + | | 0xA410 (3000 * 0xE) |
− | | Array of objects? See chapter | + | | Linked list of objects? See chapter |
| |- | | |- |
| | 0xC810 | | | 0xC810 |
− | | 0x10 | + | | 0xE |
− | | Terminator? 00 [..] 00 08 83 | + | | Padding? |
| + | |- |
| + | | 0xC81E |
| + | | 0x2 |
| + | | Checksum of all of the above (the first 0xC81E byte). See section [[#Checksum|below]]. |
| |- | | |- |
| | 0xC820 | | | 0xC820 |
Line 46: |
Line 56: |
| | 0xC824 | | | 0xC824 |
| | 0x4 | | | 0x4 |
− | | Header? 0x39000000 | + | | Mii count in this section. Maximum 100 |
| |- | | |- |
− | | 0xC861 | + | | 0xC828 |
− | | 0x2B | + | | 0x64 (100 * 0x1) |
− | | Weird padding? 0x00 | + | | Order index of Mii in this section? |
| |- | | |- |
| | 0xC88C | | | 0xC88C |
− | | 0x1C20 (?) | + | | 0x1C20 (100 * 0x48) |
− | | Array of Miis contributed from games, used for Mii Plaza "invitations" feature.<br/>The format isn't that of a full Mii. | + | | Array of Miis contributed from games, used for Mii Plaza "invitations" feature.<br/>The format isn't that of a full Mii. The "author" field is missing |
| |- | | |- |
| | 0xE4AC | | | 0xE4AC |
− | | 0x14 | + | | 0x12 |
− | | 01 00 [..] 00 D2 74 | + | | 01 00 [..] 00 |
| + | |- |
| + | | 0xE4BE |
| + | | 0x2 |
| + | | Checksum over the data above starting from 0xC820 |
| |- | | |- |
| | 0xE4C0 | | | 0xE4C0 |
− | | 0x3D860 | + | | 0x3D860 (3000 * 0x54) |
− | | Empty (00) | + | | Another array of Miis. Seems related to the CFHE section. <br/>The Mii format in this section is modified. The "author" field is missing, A 4-byte timestamp (seconds since 2000) together with 8-byte zeros(?) is appended at the end. |
| |} | | |} |
| + | When encrypted in QR codes, 4 additional bytes are added. Two null bytes and a CRC-16. It's the exact same CRC-16 as for the Wii blocks on the 0x5e first bytes. It seems that the CRC is ignored, the Mii Maker expecting the result of APT:Unwrap to detect integrity loss. |
| + | |
| + | ==CFHE object== |
| + | |
| + | A 0xE-byte long linked list node. The format is 4-byte Mii ID (See Mii format) + 6-byte MAC + 2-byte previous node index (prev) + 2-byte next node index (next). |
| + | |
| + | An invalid node has value: ID = 0, MAC = 0, prev = 0x7FFF, next = 0x7FFF. |
| + | |
| + | The highest bit of these fields has some special meaning and isn't part of the index value. |
| + | |
| + | ==Checksum== |
| + | |
| + | The algorithm used to verify the integrity of the database is based on [http://srecord.sourceforge.net/crc16-ccitt.html CRC16-CCITT], though it's an incorrect implementation. It is the same algorithm used to verify [http://wiibrew.org/wiki/Mii_Data#Block_format Mii Data on the Wii]. |
| + | |
| + | To obtain the correct value for the checksum, apply the algorithm to the first 0xC81E bytes of the database. This can be done using [https://gbatemp.net/threads/tutorial-give-your-mii-gold-pants-and-use-it-for-streetpass.379146/page-24#post-6569186 FixCRC]; alternativly a pseudocode implementation of the checksum algorithm is given below: |
| + | |
| + | <source lang="python"> |
| + | def crc16_CCITTWii(u8[]: data) -> u16: |
| + | """Calculate a checksum of data using the CRC16-CCITT implementation of the Wii |
| + | |
| + | This implementation uses 0x0000 as the starting value, which is different |
| + | from what CRC16-CCITT specifies. |
| + | """ |
| + | |
| + | # note: a correct implementation of CRC16-CCITT |
| + | # would initialize this to 0xffff |
| + | u32 crc := 0x0 |
| + | |
| + | for byte in data: |
| + | # Iterate over every of the 8 bits in byte. |
| + | # Begin with the most significant bit. (7, 6, ... , 1, 0) |
| + | for bit in 7..0: |
| + | # & - binary `and'; <</>> - bitshift left/right; ^ - binary `xor' |
| + | crc := ( |
| + | (crc << 1) | ((byte >> bit) & 0x1) |
| + | ^ (0x1021 if crc & 0x8000 else 0) |
| + | ) |
| + | |
| + | for _ in 0..15: |
| + | crc := (crc << 1) ^ (0x1021 if crc & 0x8000 else 0) |
| + | |
| + | # only return the lowest 16 bit of crc |
| + | return (u16) (crc & 0xffff) |
| + | |
| + | checksum := crc16_CCITTWii(miidb[0:0xc81e]) # checksum over the first 0xc81e bytes |
| + | </source> |
| | | |
| ==Mii format== | | ==Mii format== |
− |
| |
− | Note: 0x18-3B have been copied as-is from [https://www.3dbrew.org/w/index.php?title=Mii_Maker&oldid=11464 the QR code specification], so they're unverified.
| |
| | | |
| {| class="wikitable" | | {| class="wikitable" |
Line 76: |
Line 134: |
| |- | | |- |
| | 0x0 | | | 0x0 |
− | | 0x4 | + | | 0x1 |
− | | Mii ID | + | | Always 3? |
| |- | | |- |
− | | 0x4
| |
− | | 0x4
| |
− | | System ID (identifies owner, for purpose of enforcing editing restrictions and blue pants).<br/>Is not tied to the MAC address anymore.
| |
− | |-
| |
− | | 0x8
| |
| | 0x1 | | | 0x1 |
− | | Unknown (always 71?) | + | | 0x1 |
| + | | bit 0: allow copying<br/>bit 1: private name?<br/>bit 2-3: region lock (0=no lock, 1=JPN, 2=USA, 3=EUR)<br/>bit4-5:character set(0=JPN+USA+EUR, 1=CHN, 2=KOR, 3=TWN) |
| |- | | |- |
− | | 0x9 | + | | 0x2 |
| | 0x1 | | | 0x1 |
− | | Allow Copying (?) (A2=on?) | + | | Mii position shown on the selection screen<br/>bit 0-3: page index <br/>bit 4-7: slot index |
| |- | | |- |
− | | 0xA
| |
| | 0x3 | | | 0x3 |
− | | unknown; apparently constant for the same source console | + | | 0x1 |
| + | | bit 0-3: ?<br/>bit 4-6: version? (1=Wii, 2=DSi, 3=3DS) |
| |- | | |- |
− | | 0xD | + | | 0x4 |
− | | 0x1 | + | | 0x8 |
− | | unknown; apparently constant for the same source console - subtract 2 for personal Mii? | + | | System ID (identifies owner, for purpose of enforcing editing restrictions and blue pants).<br/>Is not tied to the MAC address anymore. |
| |- | | |- |
− | | 0xE | + | | 0xC |
− | | 0x2 | + | | 0x4 |
− | | unknown; variable (range A-F may alternatively be a timestamp?) | + | | Mii ID (big-endian 32bit unsigned integer):<br/>Bit 0..27: (bit[0..27] * 2) = date of creation (seconds since 01/01/2010 00:00:00)<br/>Bit 28: Always set?<br/>Bit 29: set for temporary Mii<br/>Bit 30: Set for DSi mii?<br/>Bit 31: not set iff Mii is special |
| |- | | |- |
| | 0x10 | | | 0x10 |
Line 113: |
Line 167: |
| | 0x18 | | | 0x18 |
| | 0x2 | | | 0x2 |
− | | Bit-mapped: Birthday (4bit-day,5bit-month), Sex, Shirt, ?? | + | | bit 0: sex (0 if male, 1 if female)<br/>bit 1-4: birthday month<br/>bit 5-9: birthday day<br/>bit 10-13: favorite color<br/>bit 14: favorite mii (0 if false, 1 if true) |
| |- | | |- |
| | 0x1A | | | 0x1A |
Line 141: |
Line 195: |
| | 0x34 | | | 0x34 |
| | 0x4 | | | 0x4 |
− | | unknown | + | | bit 0-5: eye style<br/>bit 6-8: eye color <br/>bit 9-12: eye scale <br/>bit 13-15: eye yscale<br/>bit 16-20: eye rotation<br/>bit 21-24: eye x spacing<br/>bit 25-29: eye y position |
| |- | | |- |
| | 0x38 | | | 0x38 |
− | | 0x1 | + | | 0x4 |
− | | bit 0-4: eyebrow style<br/>bit 5-7: eyebrow color | + | | bit 0-4: eyebrow style<br/>bit 5-7: eyebrow color <br/>bit 8-11: eyebrow scale<br/>bit 12-14: eyebrow yscale <br/>bit 16-19: eyebrow rotation<br/>bit 21-24: eyebrow x spacing<br/>bit 25-29: eyebrow y position |
| |- | | |- |
− | | 0x39 | + | | 0x3C |
− | | 0x1 | + | | 0x2 |
− | | bit 0-3: eyebrow scale<br/>bit 4-6: eyebrow yscale | + | | bit 0-4: nose style<br/>bit 5-8: nose scale<br/>bit 9-13: nose y position |
| |- | | |- |
− | | 0x3A | + | | 0x3E |
| | 0x2 | | | 0x2 |
− | | note that the bytes are swapped over (little-endian layout)<br/>bit 0-3: eyebrow rotation<br/>bit 5-8: eyebrow x spacing<br/>bit 9-13: eyebrow y position | + | | bit 0-5: mouse style<br/>biy 6-8: mouse color<br/>bit 9-12: mouse scale<br/>bit 13-15: mouse yscale |
| |- | | |- |
− | | 0x3C | + | | 0x40 |
− | | 0x4 | + | | 0x2 |
− | | unknown | + | | bit 0-4: mouse y position<br/>bit 5-7: mustach style |
| + | |- |
| + | | 0x42 |
| + | | 0x2 |
| + | | bit 0-2: beard style<br/>bit 3-5: beard color<br/>bit 6-9: mustache scale<br/>bit 10-14:mustache y position |
| |- | | |- |
− | | 0x40 | + | | 0x44 |
− | | 0x1 | + | | 0x2 |
− | | Allow Copying (?) (0D on 0E off 8D on) | + | | bit 0-3: glasses style<br/>bit 4-6: glasses color<br/>bit 7-10: glasses scale<br/>bit 11-15: glasses y position |
| |- | | |- |
− | | 0x41 | + | | 0x46 |
− | | 0x7 | + | | 0x2 |
− | | unknown | + | | bit 0: enable mole<br/>bit 1-4: mole scale<br/>bit 5-9: mole x position<br/>bit 10-14: mole y position |
| |- | | |- |
| | 0x48 | | | 0x48 |
Line 171: |
Line 229: |
| | UTF-16 Author Name (10 chars max, 0000 terminated) | | | UTF-16 Author Name (10 chars max, 0000 terminated) |
| |} | | |} |
− |
| |
− | ==CFHE object==
| |
− |
| |
− | A 0xE-byte long item.
| |
− |
| |
− | On my database, they're all 0000 0000 0000 0000 0000 FF7F FF7F.
| |
− |
| |
− | Wild speculation: blacklist of already scanned celebrity (gold) Mii QRs?
| |
− |
| |
− | Alternative interpretation: FFFF FFFF 0000 0000 0000 0000 0000 is the 1st item; FF7F FF7F 0000 [...] the 2nd, etc;
| |
| | | |
| ==Mii categories (pants colors)== | | ==Mii categories (pants colors)== |
| | | |
− | Initial digits have been mirrored from David Hawley's defunct Wii research. Some information may be outdated.
| + | ====Special (gold) Miis==== |
− | | |
− | Specialness will override any other color and make the
| |
− | | |
− | ===Special (gold) Miis=== | |
| Specialness will override any other color and make the Mii non-editable. | | Specialness will override any other color and make the Mii non-editable. |
| | | |
| Copying is rumored to have to be disabled. | | Copying is rumored to have to be disabled. |
| | | |
− | First digit of Mii ID: 0, 1, 4, 5
| + | Zeroed system-id and timestamp? |
| | | |
− | ===Imported (blue) Miis=== | + | ====Imported (blue) Miis==== |
| Any (non-gold) Mii with a different System ID will appear as a foreign one. | | Any (non-gold) Mii with a different System ID will appear as a foreign one. |
| | | |
| There is also a range of Mii IDs that are always foreign and uneditable, regardless of the System ID: | | There is also a range of Mii IDs that are always foreign and uneditable, regardless of the System ID: |
| | | |
− | First digit of Mii ID: C, D
| |
| | | |
− | ===Regular (black/red) Miis=== | + | ====Regular (black/red) Miis==== |
| Always editable, since they can only appear as such on the console that created them. | | Always editable, since they can only appear as such on the console that created them. |
| | | |
− | First digit of Mii ID: 2, 3, 6, 7, 8, 9, A, B, E, F
| + | |
| + | ====Personal (red) Mii==== |
| + | A red Mii that happens to be the first in the file! |
| | | |
| ==Mii values== | | ==Mii values== |
− |
| |
| Each of the following values were found with NTR Debugger: | | Each of the following values were found with NTR Debugger: |
| If you want to access the value, grab the given "NTR address" and add 0x08815000. | | If you want to access the value, grab the given "NTR address" and add 0x08815000. |
Line 510: |
Line 554: |
| | | |
| <nowiki>{ | | <nowiki>{ |
− | faces: [
| + | face: [ |
| 0x00,0x01,0x08, | | 0x00,0x01,0x08, |
| 0x02,0x03,0x09, | | 0x02,0x03,0x09, |