mirror of
https://github.com/pmret/papermario.git
synced 2024-11-18 08:52:40 +01:00
262428c68a
* Remove splat from repo * refactor scraps * requirements update
969 lines
22 KiB
Python
969 lines
22 KiB
Python
import shutil
|
||
from splat.segtypes.n64.segment import N64Segment
|
||
from pathlib import Path
|
||
from splat.util import options
|
||
import re
|
||
|
||
import pylibyaml
|
||
import yaml as yaml_loader
|
||
|
||
|
||
CHARSET_COMMON = {
|
||
0xF7: " ",
|
||
0xF0: "[BR]\n",
|
||
0xF1: "[Wait]",
|
||
0xF2: {None: lambda d: (f"[Pause {d[0]}]", 1)},
|
||
0xF3: "[Variant0]",
|
||
0xF4: "[Variant1]",
|
||
0xF5: "[Variant2]",
|
||
0xF6: "[Variant3]",
|
||
0xFB: "[Next]\n",
|
||
0xFC: {
|
||
0x01: "[Style right]\n",
|
||
0x02: "[Style left]\n",
|
||
0x03: "[Style center]\n",
|
||
0x04: "[Style tattle]\n",
|
||
0x05: {
|
||
None: lambda d: (
|
||
f"[Style choice pos={d[0]},{d[1]} size={d[2]},{d[3]}]\n",
|
||
4,
|
||
)
|
||
},
|
||
0x06: "[Style inspect]\n",
|
||
0x07: "[Style sign]\n",
|
||
0x08: {None: lambda d: (f"[Style lamppost height={d[0]}]\n", 1)},
|
||
0x09: {None: lambda d: (f"[Style postcard index={d[0]}]\n", 1)},
|
||
0x0A: "[Style popup]\n",
|
||
0x0B: "[Style popup2]\n",
|
||
0x0C: {
|
||
None: lambda d: (
|
||
f"[Style upgrade pos={d[0]},{d[1]} size={d[2]},{d[3]}]\n",
|
||
4,
|
||
)
|
||
},
|
||
0x0D: "[Style narrate]\n",
|
||
0x0E: "[Style epilogue]\n",
|
||
},
|
||
0xFF: {
|
||
0x00: {
|
||
0: "[Font standard]\n",
|
||
1: "[Font menu]\n",
|
||
2: "[Font menu2]\n",
|
||
3: "[Font title]\n",
|
||
4: "[Font subtitle]\n",
|
||
},
|
||
0x04: "[Yield]",
|
||
0x05: {
|
||
# 0x0A: "[color:normal]",
|
||
# 0x20: "[color:red]",
|
||
# 0x21: "[color:pink]",
|
||
# 0x22: "[color:purple]",
|
||
# 0x23: "[color:blue]",
|
||
# 0x24: "[color:cyan]",
|
||
# 0x25: "[color:green]",
|
||
# 0x26: "[color:yellow]",
|
||
# 0x00: "[color=normal ctx=diary]",
|
||
# 0x07: "[color=red ctx=diary]",
|
||
# 0x17: "[color=dark ctx=inspect]",
|
||
# 0x18: "[color=normal ctx=sign]",
|
||
# 0x19: "[color=red ctx=sign]",
|
||
# 0x1A: "[color=blue ctx=sign]",
|
||
# 0x1B: "[color=green ctx=sign]",
|
||
# 0x28: "[color=red ctx=popup]",
|
||
# 0x29: "[color=pink ctx=popup]",
|
||
# 0x2A: "[color=purple ctx=popup]",
|
||
# 0x2B: "[color=blue ctx=popup]",
|
||
# 0x2C: "[color=teal ctx=popup]",
|
||
# 0x2D: "[color=green ctx=popup]",
|
||
# 0x2E: "[color=yellow ctx=popup]",
|
||
# 0x2F: "[color=normal ctx=popup]",
|
||
None: lambda d: (f"[Color 0x{d[0]:X}]", 1),
|
||
},
|
||
0x07: "[InputOff]\n",
|
||
0x08: "[InputOn]\n",
|
||
0x09: "[DelayOff]\n",
|
||
0x0A: "[DelayOn]\n",
|
||
0x0B: {None: lambda d: (f"[CharWidth {d[0]}]", 1)},
|
||
0x0C: {None: lambda d: (f"[Scroll {d[0]}]", 1)},
|
||
0x0D: {None: lambda d: (f"[Size {d[0]},{d[1]}]\n", 2)},
|
||
0x0E: "[SizeReset]\n",
|
||
0x0F: {None: lambda d: (f"[Speed delay={d[0]} chars={d[1]}]", 2)},
|
||
0x10: {None: lambda d: (f"[SetPosX {(d[0] << 8) + d[1]}]", 2)},
|
||
0x11: {None: lambda d: (f"[SetPosY {d[0]}]", 1)},
|
||
0x12: {None: lambda d: (f"[Right {d[0]}]", 1)},
|
||
0x13: {None: lambda d: (f"[Down {d[0]}]", 1)},
|
||
0x14: {None: lambda d: (f"[Up {d[0]}]", 1)},
|
||
0x15: {None: lambda d: (f"[InlineImage index={d[0]}]\n", 1)},
|
||
0x16: {
|
||
None: lambda d: (
|
||
f"[AnimSprite spriteID=0x{d[0]:02X}{d[1]:02X} raster={d[2]}]\n",
|
||
3,
|
||
)
|
||
},
|
||
0x17: {None: lambda d: (f"[ItemIcon itemID=0x{d[0]:02X}{d[1]:02X}]\n", 2)},
|
||
0x18: {
|
||
None: lambda d: (
|
||
f"[Image index={d[0]} pos={(d[1] << 8) + d[2]},{d[3]} hasBorder={d[4]} alpha={d[5]} fadeAmount={d[6]}]\n",
|
||
7,
|
||
)
|
||
},
|
||
0x19: {None: lambda d: (f"[HideImage fadeAmount={d[0]}]\n", 1)},
|
||
0x1A: {None: lambda d: (f"[AnimDelay index={d[1]} delay={d[2]}]", 3)},
|
||
0x1B: {None: lambda d: (f"[AnimLoop {d[0]} {d[1]}]", 2)},
|
||
0x1C: {None: lambda d: (f"[AnimDone {d[0]}]", 1)},
|
||
0x1E: {None: lambda d: (f"[Cursor {d[0]}]", 1)},
|
||
0x1F: {None: lambda d: (f"[EndChoice {d[0]}]", 1)},
|
||
0x20: {None: lambda d: (f"[SetCancel {d[0]}]", 1)},
|
||
0x21: {None: lambda d: (f"[Option {d[0]}]", 1)},
|
||
0x22: "[SavePos]",
|
||
0x23: "[RestorePos]",
|
||
0x24: {
|
||
0xFF: {
|
||
0x05: {
|
||
0x10: {0x98: {0xFF: {0x25: "[A]"}}},
|
||
0x11: {0x99: {0xFF: {0x25: "[B]"}}},
|
||
0x12: {0xA1: {0xFF: {0x25: "[START]"}}},
|
||
0x13: {
|
||
0x9D: {0xFF: {0x25: "[C-UP]"}},
|
||
0x9E: {0xFF: {0x25: "[C-DOWN]"}},
|
||
0x9F: {0xFF: {0x25: "[C-LEFT]"}},
|
||
0xA0: {0xFF: {0x25: "[C-RIGHT]"}},
|
||
},
|
||
0x14: {0x9C: {0xFF: {0x25: "[Z]"}}},
|
||
}
|
||
}
|
||
},
|
||
# 0x24: "[SaveColor]",
|
||
# 0x25: "[RestoreColor]",
|
||
0x26: {
|
||
0x00: "[Shake]",
|
||
0x01: "[Wave]",
|
||
0x02: "[NoiseOutline]",
|
||
0x03: {None: lambda d: (f"[Static {d[0]}]", 1)},
|
||
0x05: {None: lambda d: (f"[Blur dir={['x', 'y', 'xy'][d[0]]}]", 1)},
|
||
0x07: {None: lambda d: (f"[DitherFade {d[0]}]", 1)},
|
||
0x0A: "[PrintRising]",
|
||
0x0B: "[PrintGrowing]",
|
||
0x0C: "[SizeJitter]",
|
||
0x0D: "[SizeWave]",
|
||
0x0E: "[DropShadow]",
|
||
},
|
||
0x27: {
|
||
0x00: "[/Shake]",
|
||
0x01: "[/Wave]",
|
||
0x03: "[/Static]",
|
||
0x05: "[/Blur]",
|
||
0x07: "[/DitherFade]",
|
||
0x0A: "[/PrintRising]",
|
||
0x0B: "[/PrintGrowing]",
|
||
0x0C: "[/SizeJitter]",
|
||
0x0D: "[/SizeWave]",
|
||
0x0E: "[/DropShadow]",
|
||
},
|
||
0x28: {None: lambda d: (f"[Var {d[0]}]", 1)},
|
||
0x29: {None: lambda d: (f"[CenterX {d[0]}]", 1)},
|
||
0x2B: "[EnableCDownNext]",
|
||
0x2C: {
|
||
None: lambda d: (
|
||
f"[CustomVoice soundIDs=0x{d[0]:02X}{d[1]:02X}{d[2]:02X}{d[3]:02X},0x{d[4]:02X}{d[5]:02X}{d[6]:02X}{d[7]:02X}]",
|
||
8,
|
||
)
|
||
},
|
||
0x2E: {None: lambda d: (f"[Volume {d[0]}]", 1)},
|
||
0x2F: {
|
||
0: "[Voice normal]\n",
|
||
1: "[Voice bowser]\n",
|
||
2: "[Voice star]\n",
|
||
None: lambda d: (f"[Voice {d[0]}]\n", 1),
|
||
},
|
||
# None: lambda d: (f"[func_{d[0]:02X}]", 1),
|
||
},
|
||
None: lambda d: (f"[Raw 0x{d[0]:02X}]", 1),
|
||
}
|
||
|
||
CHARSET_STANDARD = {
|
||
**CHARSET_COMMON,
|
||
0x00: "[NOTE]",
|
||
0x01: "!",
|
||
0x02: '"',
|
||
0x03: "#",
|
||
0x04: "$",
|
||
0x05: "%",
|
||
0x06: "&",
|
||
0x07: "'",
|
||
0x08: "(",
|
||
0x09: ")",
|
||
0x0A: "*",
|
||
0x0B: "+",
|
||
0x0C: ",",
|
||
0x0D: "-",
|
||
0x0E: ".",
|
||
0x0F: "/",
|
||
0x10: "0",
|
||
0x11: "1",
|
||
0x12: "2",
|
||
0x13: "3",
|
||
0x14: "4",
|
||
0x15: "5",
|
||
0x16: "6",
|
||
0x17: "7",
|
||
0x18: "8",
|
||
0x19: "9",
|
||
0x1A: ":",
|
||
0x1B: ";",
|
||
0x1C: "<",
|
||
0x1D: "=",
|
||
0x1E: ">",
|
||
0x1F: "?",
|
||
0x20: "@",
|
||
0x21: "A",
|
||
0x22: "B",
|
||
0x23: "C",
|
||
0x24: "D",
|
||
0x25: "E",
|
||
0x26: "F",
|
||
0x27: "G",
|
||
0x28: "H",
|
||
0x29: "I",
|
||
0x2A: "J",
|
||
0x2B: "K",
|
||
0x2C: "L",
|
||
0x2D: "M",
|
||
0x2E: "N",
|
||
0x2F: "O",
|
||
0x30: "P",
|
||
0x31: "Q",
|
||
0x32: "R",
|
||
0x33: "S",
|
||
0x34: "T",
|
||
0x35: "U",
|
||
0x36: "V",
|
||
0x37: "W",
|
||
0x38: "X",
|
||
0x39: "Y",
|
||
0x3A: "Z",
|
||
0x3B: "\\[",
|
||
0x3C: "¥",
|
||
0x3D: "]",
|
||
0x3E: "^",
|
||
0x3F: "_",
|
||
0x40: "`",
|
||
0x41: "a",
|
||
0x42: "b",
|
||
0x43: "c",
|
||
0x44: "d",
|
||
0x45: "e",
|
||
0x46: "f",
|
||
0x47: "g",
|
||
0x48: "h",
|
||
0x49: "i",
|
||
0x4A: "j",
|
||
0x4B: "k",
|
||
0x4C: "l",
|
||
0x4D: "m",
|
||
0x4E: "n",
|
||
0x4F: "o",
|
||
0x50: "p",
|
||
0x51: "q",
|
||
0x52: "r",
|
||
0x53: "s",
|
||
0x54: "t",
|
||
0x55: "u",
|
||
0x56: "v",
|
||
0x57: "w",
|
||
0x58: "x",
|
||
0x59: "y",
|
||
0x5A: "z",
|
||
0x5B: "{",
|
||
0x5C: "|",
|
||
0x5D: "}",
|
||
0x5E: "~",
|
||
0x5F: "°",
|
||
0x60: "À",
|
||
0x61: "Á",
|
||
0x62: "Â",
|
||
0x63: "Ä",
|
||
0x64: "Ç",
|
||
0x65: "È",
|
||
0x66: "É",
|
||
0x67: "Ê",
|
||
0x68: "Ë",
|
||
0x69: "Ì",
|
||
0x6A: "Í",
|
||
0x6B: "Î",
|
||
0x6C: "Ï",
|
||
0x6D: "Ñ",
|
||
0x6E: "Ò",
|
||
0x6F: "Ó",
|
||
0x70: "Ô",
|
||
0x71: "Ö",
|
||
0x72: "Ù",
|
||
0x73: "Ú",
|
||
0x74: "Û",
|
||
0x75: "Ü",
|
||
0x76: "ß",
|
||
0x77: "à",
|
||
0x78: "á",
|
||
0x79: "â",
|
||
0x7A: "ä",
|
||
0x7B: "ç",
|
||
0x7C: "è",
|
||
0x7D: "é",
|
||
0x7E: "ê",
|
||
0x7F: "ë",
|
||
0x80: "ì",
|
||
0x81: "í",
|
||
0x82: "î",
|
||
0x83: "ï",
|
||
0x84: "ñ",
|
||
0x85: "ò",
|
||
0x86: "ó",
|
||
0x87: "ô",
|
||
0x88: "ö",
|
||
0x89: "ù",
|
||
0x8A: "ú",
|
||
0x8B: "û",
|
||
0x8C: "ü",
|
||
0x8D: "¡",
|
||
0x8E: "¿",
|
||
0x8F: "ª",
|
||
0x90: "[HEART]",
|
||
0x91: "[STAR]",
|
||
0x92: "[UP]",
|
||
0x93: "[DOWN]",
|
||
0x94: "[LEFT]",
|
||
0x95: "[RIGHT]",
|
||
0x96: "[CIRCLE]",
|
||
0x97: "[CROSS]",
|
||
0x98: "[~A]",
|
||
0x99: "[~B]",
|
||
0x9A: "[~L]",
|
||
0x9B: "[~R]",
|
||
0x9C: "[~Z]",
|
||
0x9D: "[~C-UP]",
|
||
0x9E: "[~C-DOWN]",
|
||
0x9F: "[~C-LEFT]",
|
||
0xA0: "[~C-RIGHT]",
|
||
0xA1: "[~START]",
|
||
0xA2: "“",
|
||
0xA3: "”",
|
||
0xA4: "‘",
|
||
0xA5: "’",
|
||
}
|
||
|
||
CHARSET_CREDITS = {
|
||
**CHARSET_COMMON,
|
||
0x00: "A",
|
||
0x01: "B",
|
||
0x02: "C",
|
||
0x03: "D",
|
||
0x04: "E",
|
||
0x05: "F",
|
||
0x06: "G",
|
||
0x07: "H",
|
||
0x08: "I",
|
||
0x09: "J",
|
||
0x0A: "K",
|
||
0x0B: "L",
|
||
0x0C: "M",
|
||
0x0D: "N",
|
||
0x0E: "O",
|
||
0x0F: "P",
|
||
0x10: "Q",
|
||
0x11: "R",
|
||
0x12: "S",
|
||
0x13: "T",
|
||
0x14: "U",
|
||
0x15: "V",
|
||
0x16: "W",
|
||
0x17: "X",
|
||
0x18: "Y",
|
||
0x19: "Z",
|
||
0x1A: "'",
|
||
0x1B: ".",
|
||
0x1C: ",",
|
||
0x1D: "0",
|
||
0x1E: "1",
|
||
0x1F: "2",
|
||
0x20: "3",
|
||
0x21: "4",
|
||
0x22: "5",
|
||
0x23: "6",
|
||
0x24: "7",
|
||
0x25: "8",
|
||
0x26: "9",
|
||
0x27: "©",
|
||
0x28: "&",
|
||
}
|
||
|
||
CHARSET_JP_COMMON = {
|
||
**CHARSET_COMMON,
|
||
0xF3: "[Charset Kana]",
|
||
0xF4: "[Charset Latin]",
|
||
0xF5: "[Charset Kanji]",
|
||
0xF6: "[Charset Buttons]",
|
||
0xF7: " ",
|
||
0xF8: " ",
|
||
0xF9: "[HALFSPACE]",
|
||
0xFF: {
|
||
**CHARSET_COMMON[0xFF],
|
||
0x24: {
|
||
0xFF: {
|
||
0x05: {
|
||
0x10: {0xF6: {0x00: {0xFF: {0x25: "[A]"}}}},
|
||
0x11: {0xF6: {0x01: {0xFF: {0x25: "[B]"}}}},
|
||
0x12: {0xF6: {0x02: {0xFF: {0x25: "[START]"}}}},
|
||
0x13: {
|
||
0xF6: {
|
||
0x03: {0xFF: {0x25: "[C-UP]"}},
|
||
0x04: {0xFF: {0x25: "[C-DOWN]"}},
|
||
0x05: {0xFF: {0x25: "[C-LEFT]"}},
|
||
0x06: {0xFF: {0x25: "[C-RIGHT]"}},
|
||
}
|
||
},
|
||
0x14: {
|
||
0xF6: {
|
||
0x07: {0xFF: {0x25: "[Z]"}},
|
||
0x08: {0xFF: {0x25: "[L]"}},
|
||
0x09: {0xFF: {0x25: "[R]"}},
|
||
}
|
||
},
|
||
}
|
||
}
|
||
},
|
||
},
|
||
}
|
||
|
||
CHARSET_KANA = {
|
||
**CHARSET_JP_COMMON,
|
||
0x00: "あ",
|
||
0x01: "い",
|
||
0x02: "う",
|
||
0x03: "え",
|
||
0x04: "お",
|
||
0x05: "か",
|
||
0x06: "き",
|
||
0x07: "く",
|
||
0x08: "け",
|
||
0x09: "こ",
|
||
0x0A: "さ",
|
||
0x0B: "し",
|
||
0x0C: "す",
|
||
0x0D: "せ",
|
||
0x0E: "そ",
|
||
0x0F: "た",
|
||
0x10: "ち",
|
||
0x11: "つ",
|
||
0x12: "て",
|
||
0x13: "と",
|
||
0x14: "な",
|
||
0x15: "に",
|
||
0x16: "ぬ",
|
||
0x17: "ね",
|
||
0x18: "の",
|
||
0x19: "は",
|
||
0x1A: "ひ",
|
||
0x1B: "ふ",
|
||
0x1C: "へ",
|
||
0x1D: "ほ",
|
||
0x1E: "ま",
|
||
0x1F: "み",
|
||
0x20: "む",
|
||
0x21: "め",
|
||
0x22: "も",
|
||
0x23: "や",
|
||
0x24: "ゆ",
|
||
0x25: "よ",
|
||
0x26: "ら",
|
||
0x27: "り",
|
||
0x28: "る",
|
||
0x29: "れ",
|
||
0x2A: "ろ",
|
||
0x2B: "わ",
|
||
0x2C: "を",
|
||
0x2D: "ん",
|
||
0x2E: "ゔ",
|
||
0x2F: "が",
|
||
0x30: "ぎ",
|
||
0x31: "ぐ",
|
||
0x32: "げ",
|
||
0x33: "ご",
|
||
0x34: "ざ",
|
||
0x35: "じ",
|
||
0x36: "ず",
|
||
0x37: "ぜ",
|
||
0x38: "ぞ",
|
||
0x39: "だ",
|
||
0x3A: "ぢ",
|
||
0x3B: "づ",
|
||
0x3C: "で",
|
||
0x3D: "ど",
|
||
0x3E: "ば",
|
||
0x3F: "び",
|
||
0x40: "ぶ",
|
||
0x41: "べ",
|
||
0x42: "ぼ",
|
||
0x43: "ぱ",
|
||
0x44: "ぴ",
|
||
0x45: "ぷ",
|
||
0x46: "ぺ",
|
||
0x47: "ぽ",
|
||
0x48: "ぁ",
|
||
0x49: "ぃ",
|
||
0x4A: "ぅ",
|
||
0x4B: "ぇ",
|
||
0x4C: "ぉ",
|
||
0x4D: "っ",
|
||
0x4E: "ゃ",
|
||
0x4F: "ゅ",
|
||
0x50: "ょ",
|
||
0x51: "ア",
|
||
0x52: "イ",
|
||
0x53: "ウ",
|
||
0x54: "エ",
|
||
0x55: "オ",
|
||
0x56: "カ",
|
||
0x57: "キ",
|
||
0x58: "ク",
|
||
0x59: "ケ",
|
||
0x5A: "コ",
|
||
0x5B: "サ",
|
||
0x5C: "シ",
|
||
0x5D: "ス",
|
||
0x5E: "セ",
|
||
0x5F: "ソ",
|
||
0x60: "タ",
|
||
0x61: "チ",
|
||
0x62: "ツ",
|
||
0x63: "テ",
|
||
0x64: "ト",
|
||
0x65: "ナ",
|
||
0x66: "ニ",
|
||
0x67: "ヌ",
|
||
0x68: "ネ",
|
||
0x69: "ノ",
|
||
0x6A: "ハ",
|
||
0x6B: "ヒ",
|
||
0x6C: "フ",
|
||
0x6D: "ヘ",
|
||
0x6E: "ホ",
|
||
0x6F: "マ",
|
||
0x70: "ミ",
|
||
0x71: "ム",
|
||
0x72: "メ",
|
||
0x73: "モ",
|
||
0x74: "ヤ",
|
||
0x75: "ユ",
|
||
0x76: "ヨ",
|
||
0x77: "ラ",
|
||
0x78: "リ",
|
||
0x79: "ル",
|
||
0x7A: "レ",
|
||
0x7B: "ロ",
|
||
0x7C: "ワ",
|
||
0x7D: "ヲ",
|
||
0x7E: "ン",
|
||
0x7F: "ヴ",
|
||
0x80: "ガ",
|
||
0x81: "ギ",
|
||
0x82: "グ",
|
||
0x83: "ゲ",
|
||
0x84: "ゴ",
|
||
0x85: "ザ",
|
||
0x86: "ジ",
|
||
0x87: "ズ",
|
||
0x88: "ゼ",
|
||
0x89: "ゾ",
|
||
0x8A: "ダ",
|
||
0x8B: "ヂ",
|
||
0x8C: "ヅ",
|
||
0x8D: "デ",
|
||
0x8E: "ド",
|
||
0x8F: "バ",
|
||
0x90: "ビ",
|
||
0x91: "ブ",
|
||
0x92: "ベ",
|
||
0x93: "ボ",
|
||
0x94: "パ",
|
||
0x95: "ピ",
|
||
0x96: "プ",
|
||
0x97: "ペ",
|
||
0x98: "ポ",
|
||
0x99: "ァ",
|
||
0x9A: "ィ",
|
||
0x9B: "ゥ",
|
||
0x9C: "ェ",
|
||
0x9D: "ォ",
|
||
0x9E: "ッ",
|
||
0x9F: "ャ",
|
||
0xA0: "ュ",
|
||
0xA1: "ョ",
|
||
0xA2: "ー",
|
||
0xA3: "~",
|
||
0xA4: {0xA5: {0xA6: "[LONGDASH]"}},
|
||
0xA7: "0",
|
||
0xA8: "1",
|
||
0xA9: "2",
|
||
0xAA: "3",
|
||
0xAB: "4",
|
||
0xAC: "5",
|
||
0xAD: "6",
|
||
0xAE: "7",
|
||
0xAF: "8",
|
||
0xB0: "9",
|
||
0xB1: "[UP]",
|
||
0xB2: "[DOWN]",
|
||
0xB3: "[LEFT]",
|
||
0xB4: "[RIGHT]",
|
||
0xB5: "!",
|
||
0xB6: "?",
|
||
0xB7: "+",
|
||
0xB8: "-",
|
||
0xB9: "/",
|
||
0xBA: ".",
|
||
0xBB: "&",
|
||
0xBC: "#",
|
||
0xBD: "[HEART]",
|
||
0xBE: "[STAR]",
|
||
0xBF: "(",
|
||
0xC0: ")",
|
||
0xC1: "『",
|
||
0xC2: "』",
|
||
0xC3: "・",
|
||
0xC4: "[HIRAGANA SmallN]",
|
||
0xC5: "[KATAKANA SmallN]",
|
||
# existing characters without small counterparts
|
||
# 0xC4: "ん",
|
||
# 0xC5: "ン",
|
||
0xC6: "星",
|
||
# 0xC7 is unused
|
||
}
|
||
|
||
CHARSET_LATIN = {
|
||
**CHARSET_JP_COMMON,
|
||
0x00: "A",
|
||
0x01: "B",
|
||
0x02: "C",
|
||
0x03: "D",
|
||
0x04: "E",
|
||
0x05: "F",
|
||
0x06: "G",
|
||
0x07: "H",
|
||
0x08: "I",
|
||
0x09: "J",
|
||
0x0A: "K",
|
||
0x0B: "L",
|
||
0x0C: "M",
|
||
0x0D: "N",
|
||
0x0E: "O",
|
||
0x0F: "P",
|
||
0x10: "Q",
|
||
0x11: "R",
|
||
0x12: "S",
|
||
0x13: "T",
|
||
0x14: "U",
|
||
0x15: "V",
|
||
0x16: "W",
|
||
0x17: "X",
|
||
0x18: "Y",
|
||
0x19: "Z",
|
||
0x1A: "z",
|
||
}
|
||
|
||
CHARSET_KANJI = {
|
||
**CHARSET_JP_COMMON,
|
||
0x00: "上",
|
||
0x01: "下",
|
||
0x02: "左",
|
||
0x03: "右",
|
||
0x04: "中",
|
||
0x05: "東",
|
||
0x06: "西",
|
||
0x07: "南",
|
||
0x08: "北",
|
||
0x09: "一",
|
||
0x0A: "二",
|
||
0x0B: "三",
|
||
0x0C: "名",
|
||
0x0D: "国",
|
||
0x0E: "城",
|
||
0x0F: "姫",
|
||
0x10: "大",
|
||
0x11: "王",
|
||
0x12: "花",
|
||
0x13: "世",
|
||
0x14: "界",
|
||
0x15: "草",
|
||
0x16: "気",
|
||
0x17: "間",
|
||
0x18: "門",
|
||
0x19: "家",
|
||
0x1A: "地",
|
||
0x1B: "岩",
|
||
0x1C: "駅",
|
||
0x1D: "山",
|
||
0x1E: "海",
|
||
0x1F: "火",
|
||
0x20: "水",
|
||
0x21: "氷",
|
||
0x22: "日",
|
||
0x23: "根",
|
||
0x24: "雲",
|
||
0x25: "口",
|
||
0x26: "原",
|
||
0x27: "前",
|
||
0x28: "店",
|
||
0x29: "天",
|
||
0x2A: "森",
|
||
0x2B: "木",
|
||
0x2C: "力",
|
||
0x2D: "空",
|
||
0x2E: "人",
|
||
0x2F: "島",
|
||
0x30: "出",
|
||
0x31: "入",
|
||
0x32: "本",
|
||
0x33: "石",
|
||
0x34: "村",
|
||
0x35: "休",
|
||
0x36: "先",
|
||
0x37: "見",
|
||
0x38: "近",
|
||
0x39: "方",
|
||
0x3A: "法",
|
||
0x3B: "手",
|
||
0x3C: "紙",
|
||
0x3D: "引",
|
||
0x3E: "場",
|
||
0x3F: "所",
|
||
0x40: "使",
|
||
0x41: "回",
|
||
0x42: "道",
|
||
0x43: "物",
|
||
0x44: "弟",
|
||
0x45: "子",
|
||
0x46: "汽",
|
||
0x47: "車",
|
||
0x48: "何",
|
||
0x49: "黒",
|
||
0x4A: "分",
|
||
0x4B: "時",
|
||
0x4C: "屋",
|
||
0x4D: "音",
|
||
0x4E: "目",
|
||
0x4F: "行",
|
||
0x50: "絵",
|
||
0x51: "月",
|
||
0x52: "野",
|
||
0x53: "外",
|
||
0x54: "図",
|
||
0x55: "部",
|
||
0x56: "小",
|
||
0x57: "風",
|
||
0x58: "魔",
|
||
0x59: "元",
|
||
0x5A: "太",
|
||
0x5B: "陽",
|
||
0x5C: "実",
|
||
0x5D: "赤",
|
||
0x5E: "雪",
|
||
0x5F: "谷",
|
||
0x60: "通",
|
||
0x61: "[CIRCLE]",
|
||
0x62: "[CROSS]",
|
||
0x63: "長",
|
||
0x64: "話",
|
||
0x65: "色",
|
||
0x66: "光",
|
||
0x67: "合",
|
||
0x68: "青",
|
||
0x69: "黄",
|
||
0x6A: "[NOTE]",
|
||
0x6B: "当",
|
||
0x6C: "数",
|
||
0x6D: "兄",
|
||
0x6E: "用",
|
||
0x6F: "心",
|
||
0x70: "今",
|
||
0x71: "正",
|
||
0x72: "直",
|
||
0x73: "全",
|
||
0x74: "体",
|
||
0x75: "夜",
|
||
0x76: "面",
|
||
0x77: "虫",
|
||
0x78: "x",
|
||
}
|
||
|
||
CHARSET_BUTTONS = {
|
||
**CHARSET_JP_COMMON,
|
||
0x00: "[~A]",
|
||
0x01: "[~B]",
|
||
0x02: "[~START]",
|
||
0x03: "[~C-UP]",
|
||
0x04: "[~C-DOWN]",
|
||
0x05: "[~C-LEFT]",
|
||
0x06: "[~C-RIGHT]",
|
||
0x07: "[~Z]",
|
||
0x08: "[~L]",
|
||
0x09: "[~R]",
|
||
}
|
||
|
||
|
||
class N64SegPm_msg(N64Segment):
|
||
def __init__(
|
||
self,
|
||
rom_start,
|
||
rom_end,
|
||
type,
|
||
name,
|
||
vram_start,
|
||
args,
|
||
yaml,
|
||
):
|
||
super().__init__(
|
||
rom_start,
|
||
rom_end,
|
||
type,
|
||
name,
|
||
vram_start,
|
||
args=args,
|
||
yaml=yaml,
|
||
)
|
||
|
||
self.files = yaml.get("files", []) if isinstance(yaml, dict) else []
|
||
|
||
with (Path(__file__).parent / f"{self.name}.yaml").open("r") as f:
|
||
self.msg_names = yaml_loader.load(f.read(), Loader=yaml_loader.SafeLoader)
|
||
|
||
def split(self, rom_bytes):
|
||
data = rom_bytes[self.rom_start : self.rom_end]
|
||
|
||
section_offsets = []
|
||
pos = 0
|
||
while True:
|
||
offset = int.from_bytes(data[pos : pos + 4], byteorder="big")
|
||
|
||
if offset == 0:
|
||
break
|
||
|
||
section_offsets.append(offset)
|
||
pos += 4
|
||
|
||
msg_dir = options.opts.asset_path / self.name
|
||
msg_dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
for i, section_offset in enumerate(section_offsets):
|
||
name = f"{i:02X}"
|
||
if len(self.files) >= i:
|
||
name = self.files[i]
|
||
|
||
msg_offsets = []
|
||
pos = section_offset
|
||
while True:
|
||
offset = int.from_bytes(data[pos : pos + 4], byteorder="big")
|
||
|
||
if offset == section_offset:
|
||
break
|
||
|
||
msg_offsets.append(offset)
|
||
pos += 4
|
||
|
||
# self.log(f"Reading {len(msg_offsets)} messages in section {name} (0x{i:02X})")
|
||
|
||
path = msg_dir / Path(name + ".msg")
|
||
|
||
with open(path, "w") as self.f:
|
||
for j, msg_offset in enumerate(msg_offsets):
|
||
if j != 0:
|
||
self.f.write("\n")
|
||
|
||
msg_name = None
|
||
for d in self.msg_names:
|
||
section, index, goodname = d[:3]
|
||
|
||
if i == section and j == index:
|
||
msg_name = goodname
|
||
break
|
||
|
||
if msg_name is None:
|
||
self.f.write(f"#message:{i:02X}:{j:03X} {{\n\t")
|
||
else:
|
||
self.f.write(f"#message:{i:02X}:({msg_name}) {{\n\t")
|
||
self.write_message_markup(data[msg_offset:])
|
||
self.f.write("\n}\n")
|
||
|
||
def get_linker_entries(self):
|
||
from splat.segtypes.linker_entry import LinkerEntry
|
||
|
||
base_path = options.opts.asset_path / f"{self.name}"
|
||
out_paths = [base_path / Path(f + ".msg") for f in self.files]
|
||
|
||
return [LinkerEntry(self, out_paths, base_path, ".data", ".data")]
|
||
|
||
@staticmethod
|
||
def get_default_name(addr):
|
||
return "msg"
|
||
|
||
def write_message_markup(self, data):
|
||
pos = 0
|
||
if "ver/jp" in str(options.opts.target_path):
|
||
self.root_charset = CHARSET_KANA
|
||
else:
|
||
self.root_charset = CHARSET_STANDARD
|
||
|
||
while data[pos] != 0xFD:
|
||
self.charset = self.root_charset
|
||
|
||
while True:
|
||
char = data[pos]
|
||
|
||
if char in self.charset:
|
||
value = self.charset[char]
|
||
elif None in self.charset:
|
||
value = self.charset[None]
|
||
|
||
if value is None:
|
||
value = fallback
|
||
|
||
if isinstance(value, str):
|
||
self.write_markup(value)
|
||
pos += 1
|
||
break
|
||
elif callable(value):
|
||
markup, delta = value(data[pos:])
|
||
self.write_markup(markup)
|
||
pos += delta
|
||
break
|
||
elif isinstance(value, dict):
|
||
if None in self.charset:
|
||
fallback = self.charset[None]
|
||
self.charset = value
|
||
pos += 1
|
||
else:
|
||
raise ValueError(value)
|
||
|
||
self.write_markup("[End]")
|
||
|
||
def write_markup(self, markup):
|
||
self.f.write(re.sub("\n", "\n\t", markup))
|
||
|
||
markup_lower = markup.lower()
|
||
|
||
if markup_lower == "[font title]\n" or markup_lower == "[font subtitle]\n":
|
||
self.root_charset = CHARSET_CREDITS
|
||
elif markup_lower == "[font standard]":
|
||
self.root_charset = CHARSET_STANDARD
|
||
elif "ver/jp" in str(options.opts.target_path):
|
||
if markup_lower == "[charset kana]":
|
||
self.root_charset = CHARSET_KANA
|
||
elif markup_lower == "[charset latin]":
|
||
self.root_charset = CHARSET_LATIN
|
||
elif markup_lower == "[charset kanji]":
|
||
self.root_charset = CHARSET_KANJI
|
||
elif markup_lower == "[charset buttons]":
|
||
self.root_charset = CHARSET_BUTTONS
|
||
|
||
def cache(self):
|
||
return (self.yaml, self.rom_end, self.msg_names)
|