JSFiddle - React, Tailwind, and code Playground

by arian_

HTML

<h1>ds mii format to wii format converter</h1>
<p>drop a ds format (".ncd") mii file or its 74 byte data in hex here<br>
or, drop a save file/state/memdump from tomodachi collection here, and if you get lucky, you should seee sooometthiinggg....</p>
<form id="dataForm">
    <input type="file" id="fileInput">
    <br>
    <input type="text" id="miiDataInput" placeholder="Base64 or Hex Mii Data">
    <br>
    <input type="submit">
</form>

<h2>result list</h2>
<ul id="outputList"></ul>

JavaScript

const DATA_LENGTH = 74; // sizeof(RFLCharData)
const NAME_OFFSET = 0x2; // name offset in RFLCharData
const MAX_NAME_LENGTH = 0x14; // 20 bytes/10 utf16 chars

// Constants for DeSmuME save state parsing
const DST_MAGIC_BYTES = new Uint8Array([0x44, 0x65, 0x53, 0x6D, 0x75, 0x4D, 0x45, 0x20]); // "DeSmuME SState"
const DST_ZLIB_OFFSET = 0x20; // Offset where zlib data starts
const DST_ZLIB_SIGNATURE = 0x78; // The first byte of zlib data

// Constants for endian swap types
const FFLI_SWAP_ENDIAN_TYPE_U8 = 0;
const FFLI_SWAP_ENDIAN_TYPE_U16 = 1;
const FFLI_SWAP_ENDIAN_TYPE_U32 = 2;

// Swap descriptor for RFL mii data
const SWAP_ENDIAN_DESC_RFL = [
    { type: FFLI_SWAP_ENDIAN_TYPE_U16, count: 11 },
    { type: FFLI_SWAP_ENDIAN_TYPE_U8,  count: 10 },
    { type: FFLI_SWAP_ENDIAN_TYPE_U16, count: 11 },
    { type: FFLI_SWAP_ENDIAN_TYPE_U16, count: 10 } // creator name
];

/**
  * Swap the endianness of an array of integers based on the descriptor.
  * @param {Uint8Array} data - The byte array to swap.
  * @param {Array} swapDesc - The swap descriptor array.
  */
function swapEndian(data, swapDesc) {
    let offset = 0;
    for (let desc of swapDesc) {
        swapEndianArray(data, offset, desc.count, desc.type);
        offset += desc.count * (desc.type === FFLI_SWAP_ENDIAN_TYPE_U8 ? 1 :
                                desc.type === FFLI_SWAP_ENDIAN_TYPE_U16 ? 2 :
                                4);
    }
}

/**
  * Swap the endianness of an array of integers.
  * @param {Uint8Array} data - The byte array to swap.
  * @param {number} start - The starting offset in the array.
  * @param {number} count - The number of elements to swap.
  * @param {number} type - The type of elements (U8, U16, or U32).
  */
function swapEndianArray(data, start, count, type) {
    const size = type === FFLI_SWAP_ENDIAN_TYPE_U8 ? 1 :
    type === FFLI_SWAP_ENDIAN_TYPE_U16 ? 2 :
    4; // U32

    for (let i = 0; i < count; i++) {
        const index = start + (i * size);
        if (type...