papermario/tools/msg/parse_compile.py

948 lines
34 KiB
Python
Raw Normal View History

#! /usr/bin/python3
from sys import argv
from collections import OrderedDict
import re
import msgpack # way faster than pickle
class Message:
def __init__(self, name, section, index):
self.name = name
self.section = section
self.index = index
self.bytes = [] # XXX: bytearray would be better
def try_convert_int(s):
try:
return int(s, base=0)
except:
return s
def parse_command(source):
if source[0] != "[":
2021-02-10 01:12:28 +01:00
return None, [], source
source = source[1:] # "["
inside_brackets = ""
while source[0] != "]":
if source[0] == "\n":
2021-02-10 01:12:28 +01:00
return None, [], source
inside_brackets += source[0]
source = source[1:]
source = source[1:] # "]"
2021-02-10 01:12:28 +01:00
command, *raw_args = inside_brackets.split(":")
2021-02-10 01:12:28 +01:00
"""
args = []
named_args = {}
if "=" in command:
key, value = command.split("=", 1)
command = key
named_args[key] = try_convert_int(value)
for arg in args:
if "=" in arg:
key, value = arg.split("=", 1)
named_args[key.lower()] = try_convert_int(value.lower())
else:
2021-02-10 01:12:28 +01:00
args.append(try_convert_int(arg))
"""
2021-02-10 01:12:28 +01:00
args = []
for arg in raw_args:
args.append(try_convert_int(arg.lower()))
2021-02-10 01:12:28 +01:00
return command.lower(), args, source
def color_to_code(color, style):
"""
COLORS = {
"diary": {
"normal": 0x00,
"red": 0x07,
},
"inspect": {
"dark": 0x17,
},
"button": {
"blue": 0x10,
"green": 0x11,
"red": 0x12,
"yellow": 0x13,
"gray": 0x14,
"grey": 0x14,
},
"popup": {
"red": 0x28,
"pink": 0x29,
"purple": 0x2A,
"blue": 0x2B,
"teal": 0x2C,
"green": 0x2D,
"yellow": 0x2E,
"normal": 0x2F,
},
"sign": {
"normal": 0x18,
"red": 0x19,
"blue": 0x1A,
"green": 0x1B,
}
}
2021-02-10 01:12:28 +01:00
"""
COLORS = {}
if type(color) is int:
return color
2021-02-10 01:12:28 +01:00
return COLORS.get(ctx, {
# [style:left], [style:right]
"normal": 0x0A,
"red": 0x20,
"pink": 0x21,
"purple": 0x22,
"blue": 0x23,
"cyan": 0x24,
"green": 0x25,
"yellow": 0x26,
}).get(color)
def resolve_effect(fx):
if type(fx) is int:
return fx
FX = {
"jitter": 0x00,
"wavy": 0x01,
"noise": 0x02,
"fadednoise": 0x03, # 1 arg
"unknown": 0x04,
"fadedjitter": 0x05, # 1 arg
"rainbow": 0x06,
"faded": 0x07, # 1 arg
"wavyb": 0x08,
"rainbowb": 0x09,
"shrinking": 0x0a,
"growing": 0x0b,
"sizejitter": 0x0c,
"sizewave": 0x0d,
"dropshadow": 0x0e,
}
return FX.get(fx)
CHARSET = {
2021-02-10 01:12:28 +01:00
#"𝅘𝅥𝅮": 0x00,
"!": 0x01,
'"': 0x02,
"#": 0x03,
"$": 0x04,
"%": 0x05,
"&": 0x06,
"'": 0x07,
"(": 0x08,
")": 0x09,
"*": 0x0A,
"+": 0x0B,
",": 0x0C,
"-": 0x0D,
".": 0x0E,
"/": 0x0F,
"0": 0x10,
"1": 0x11,
"2": 0x12,
"3": 0x13,
"4": 0x14,
"5": 0x15,
"6": 0x16,
"7": 0x17,
"8": 0x18,
"9": 0x19,
":": 0x1A,
";": 0x1B,
"<": 0x1C,
"=": 0x1D,
">": 0x1E,
"?": 0x1F,
"@": 0x20,
"A": 0x21,
"B": 0x22,
"C": 0x23,
"D": 0x24,
"E": 0x25,
"F": 0x26,
"G": 0x27,
"H": 0x28,
"I": 0x29,
"J": 0x2A,
"K": 0x2B,
"L": 0x2C,
"M": 0x2D,
"N": 0x2E,
"O": 0x2F,
"P": 0x30,
"Q": 0x31,
"R": 0x32,
"S": 0x33,
"T": 0x34,
"U": 0x35,
"V": 0x36,
"W": 0x37,
"X": 0x38,
"Y": 0x39,
"Z": 0x3A,
"[": 0x3B,
"¥": 0x3C,
"]": 0x3D,
"^": 0x3E,
"_": 0x3F,
"`": 0x40,
"a": 0x41,
"b": 0x42,
"c": 0x43,
"d": 0x44,
"e": 0x45,
"f": 0x46,
"g": 0x47,
"h": 0x48,
"i": 0x49,
"j": 0x4A,
"k": 0x4B,
"l": 0x4C,
"m": 0x4D,
"n": 0x4E,
"o": 0x4F,
"p": 0x50,
"q": 0x51,
"r": 0x52,
"s": 0x53,
"t": 0x54,
"u": 0x55,
"v": 0x56,
"w": 0x57,
"x": 0x58,
"y": 0x59,
"z": 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,
2021-02-10 01:12:28 +01:00
# "♥": 0x90,
# "★": 0x91,
# "↑": 0x92,
# "↓": 0x93,
# "←": 0x94,
# "→": 0x95,
# "●": 0x96,
# "✖": 0x97,
"": 0xA2,
"": 0xA3,
"": 0xA4,
"": 0xA5,
" ": 0xF7,
2021-02-10 01:12:28 +01:00
# "Ⓐ": [0xFF, 0x24, 0xFF, 0x05, 0x10, 0x98, 0xFF, 0x25],
# "Ⓑ": [0xFF, 0x24, 0xFF, 0x05, 0x11, 0x99, 0xFF, 0x25],
# "Ⓢ": [0xFF, 0x24, 0xFF, 0x05, 0x12, 0xA1, 0xFF, 0x25],
# "▲": [0xFF, 0x24, 0xFF, 0x05, 0x13, 0x9D, 0xFF, 0x25],
# "▼": [0xFF, 0x24, 0xFF, 0x05, 0x13, 0x9E, 0xFF, 0x25],
# "◀": [0xFF, 0x24, 0xFF, 0x05, 0x13, 0x9F, 0xFF, 0x25],
# "▶": [0xFF, 0x24, 0xFF, 0x05, 0x13, 0xA0, 0xFF, 0x25],
# "Ⓛ": [0xFF, 0x24, 0xFF, 0x05, 0x14, 0x9A, 0xFF, 0x25],
# "Ⓡ": [0xFF, 0x24, 0xFF, 0x05, 0x14, 0x9B, 0xFF, 0x25],
# "Ⓩ": [0xFF, 0x24, 0xFF, 0x05, 0x14, 0x9C, 0xFF, 0x25],
}
CHARSET_CREDITS = {
"A": 0x00,
"B": 0x01,
"C": 0x02,
"D": 0x03,
"E": 0x04,
"F": 0x05,
"G": 0x06,
"H": 0x07,
"I": 0x08,
"J": 0x09,
"K": 0x0A,
"L": 0x0B,
"M": 0x0C,
"N": 0x0D,
"O": 0x0E,
"P": 0x0F,
"Q": 0x10,
"R": 0x11,
"S": 0x12,
"T": 0x13,
"U": 0x14,
"V": 0x15,
"W": 0x16,
"X": 0x17,
"Y": 0x18,
"Z": 0x19,
"'": 0x1A,
".": 0x1B,
",": 0x1C,
"0": 0x1D,
"1": 0x1E,
"2": 0x1F,
"3": 0x20,
"4": 0x21,
"5": 0x22,
"6": 0x23,
"7": 0x24,
"8": 0x25,
"9": 0x26,
"©": 0x27,
"&": 0x28,
" ": 0xF7,
}
2021-02-10 01:12:28 +01:00
def strip_c_comments(text):
def replacer(match):
s = match.group(0)
if s.startswith('/'):
return " "
else:
return s
pattern = re.compile(
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE
)
return re.sub(pattern, replacer, text)
if __name__ == "__main__":
if len(argv) < 3:
print("usage: parse_compile.py [in.msg] [out.msgpack]")
exit(1)
_, filename, outfile = argv
messages = []
message = None
with open(filename, "r") as f:
2021-02-10 01:12:28 +01:00
source = strip_c_comments(f.read())
lineno = 1
2021-02-10 01:12:28 +01:00
directive = ""
indent_level = 0
charset = CHARSET
font_stack = [0]
sound_stack = [0]
color_stack = [0x0A]
2021-02-10 01:12:28 +01:00
style = None
explicit_end = False
while len(source) > 0:
2021-02-10 15:26:58 +01:00
if source[0] == "\r" or source[0] == "\t":
2021-02-10 01:12:28 +01:00
source = source[1:]
continue
if source[0] == "\n":
lineno += 1
source = source[1:]
2021-02-10 01:12:28 +01:00
for i in range(indent_level):
2021-02-10 15:26:58 +01:00
if source[0] == "\t":
2021-02-10 01:12:28 +01:00
source = source[1:]
else:
break
continue
if message is None:
2021-02-10 01:12:28 +01:00
directive = ""
while source[0] != " ":
if source[0] == "\n":
lineno += 1
elif source[0] == "\r":
pass
else:
directive += source[0]
source = source[1:]
directive = directive.split(":")
if directive[0] != "#message" or len(directive) != 3:
print(f"{filename}:{lineno}: expected #message:SECTION:INDEX directive")
exit(1)
section = int(directive[1], 16)
if directive[2].startswith("(") and directive[2].endswith(")"):
name = directive[2][1:-1]
index = None
else:
2021-02-10 01:12:28 +01:00
name = None
index = int(directive[2], 16)
directive = ""
message = Message(name, section, index)
messages.append(message)
2021-02-10 01:12:28 +01:00
while source[0] != "{":
source = source[1:]
if source[0] == "\n":
lineno += 1
elif source[0] == "\r":
pass
elif source[0] == "{":
break
elif source[0] != " " and source[0] != "\t":
print(f"{filename}:{lineno}: expected opening brace ('{{')")
exit(1)
2021-02-10 01:12:28 +01:00
source = source[1:] # {
# count indent level
indent_level = 0
2021-02-10 15:26:58 +01:00
"""
2021-02-10 01:12:28 +01:00
while source[0] == " " or source[0] == "\t" or source[0] == "\n" or source[0] == "\r":
if source[0] == " " or source[0] == "\t":
indent_level += 1
source = source[1:]
2021-02-10 15:26:58 +01:00
"""
else:
2021-02-10 01:12:28 +01:00
command, args, source = parse_command(source)
if command:
2021-02-10 01:12:28 +01:00
if command == "end":
message.bytes += [0xFD]
2021-02-10 01:12:28 +01:00
explicit_end = True
elif command == "raw":
2021-02-10 01:12:28 +01:00
message.bytes += [*args]
#elif command == "func":
# message.bytes += [0xFF, *args]
elif command == "br":
message.bytes += [0xF0]
2021-02-10 01:12:28 +01:00
elif command == "wait":
message.bytes += [0xF1]
2021-02-10 01:12:28 +01:00
elif command == "pause":
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xF2, args[0]]
elif command == "next":
message.bytes += [0xFB]
2021-02-10 01:12:28 +01:00
elif command == "func_04":
message.bytes += [0xFF, 0x04]
elif command == "pushcolor":
message.bytes += [0xFF, 0x24]
elif command == "popcolor":
message.bytes += [0xFF, 0x25]
elif command == "color":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: color command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
color = color_to_code(args[0], style)
if color is None:
2021-02-10 01:12:28 +01:00
print(f"{filename}:{lineno}: unknown color")
exit(1)
message.bytes += [0xFF, 0x05, color]
color_stack.append(color)
2021-02-10 01:12:28 +01:00
#elif command == "/color":
# color_stack.pop()
# message.bytes += [0xFF, 0x05, color_stack[0]]
elif command == "style":
message.bytes += [0xFC]
2021-02-10 01:12:28 +01:00
style = args[0]
args = args[1:]
if type(style) is int:
2021-02-10 01:12:28 +01:00
message.bytes += [style, *args]
else:
if style == "right":
message.bytes += [0x01]
elif style == "left":
message.bytes += [0x02]
elif style == "center":
message.bytes += [0x03]
elif style == "tattle":
message.bytes += [0x04]
elif style == "choice":
2021-02-10 01:12:28 +01:00
if len(args) != 4:
print(f"{filename}:{lineno}: 'choice' style requires 4 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0x05, *args]
elif style == "inspect":
message.bytes += [0x06]
elif style == "sign":
message.bytes += [0x07]
elif style == "lamppost":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: 'lamppost' style requires 1 parameter")
exit(1)
message.bytes += [0x08, args[0]]
elif style == "postcard":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: 'lamppost' style requires 1 parameter")
exit(1)
message.bytes += [0x09, args[0]]
elif style == "popup":
message.bytes += [0x0A]
elif style == "upgrade":
2021-02-10 01:12:28 +01:00
if len(args) != 4:
print(f"{filename}:{lineno}: 'upgrade' style requires 4 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0x0C, *args]
elif style == "narrate":
message.bytes += [0x0D]
elif style == "epilogue":
message.bytes += [0x0E]
elif command == "font":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: font command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
font = args[0]
if font == "normal":
font = 0
elif font == "title":
font = 3
elif font == "subtitle":
font = 4
if type(font) is not int:
print(f"{filename}:{lineno}: unknown font '{font}'")
exit(1)
message.bytes += [0xFF, 0x00, font]
font_stack.append(font)
if font == 3 or font == 4:
charset = CHARSET_CREDITS
else:
charset = CHARSET
2021-02-10 01:12:28 +01:00
# elif command == "/font":
# font_stack.pop()
# message.bytes += [0xFF, 0x00, font_stack[0]]
# if font == 3 or font == 4:
# charset = CHARSET_CREDITS
# else:
# charset = CHARSET
elif command == "inputoff":
message.bytes += [0xFF, 0x07]
2021-02-10 01:12:28 +01:00
elif command == "inputon":
message.bytes += [0xFF, 0x08]
2021-02-10 01:12:28 +01:00
elif command == "delayoff":
message.bytes += [0xFF, 0x09]
2021-02-10 01:12:28 +01:00
elif command == "delayon":
message.bytes += [0xFF, 0x0A]
elif command == "kerning":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x0B, args[0]]
elif command == "scroll":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x0C, args[0]]
elif command == "size":
2021-02-10 01:12:28 +01:00
if len(args) != 2:
print(f"{filename}:{lineno}: {command} command requires 2 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x0D, *args]
elif command == "sizereset":
message.bytes += [0xFF, 0x0E]
elif command == "speed":
2021-02-10 01:12:28 +01:00
if len(args) != 2:
print(f"{filename}:{lineno}: {command} command requires 2 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x0F, *args]
# elif command == "pos":
# if "y" not in named_args:
# print(f"{filename}:{lineno}: pos command requires parameter: y (x is optional)")
# exit(1)
# if "x" in named_args:
# message.bytes += [0xFF, 0x10, named_args["x"], named_args["y"]]
# else:
# message.bytes += [0xFF, 0x11, named_args["y"]]
elif command == "setprintpos":
if len(args) != 2:
print(f"{filename}:{lineno}: {command} command requires 2 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x10, *args]
elif command == "setprinty":
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x11, *args]
elif command == "indent":
if len(args) != 1:
print(f"{filename}:{lineno}: indent command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x12, args[0]]
# elif command == "image":
# if len(args) == 1:
# message.bytes += [0xFF, 0x15, args[0]]
# elif len(args) == 7:
# message.bytes += [0xFF, 0x18, *args]
# else:
# print(f"{filename}:{lineno}: image command requires 1 or 7 parameters")
# exit(1)
elif command == "image1":
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x15, *args]
elif command == "image7":
if len(args) != 7:
print(f"{filename}:{lineno}: {command} command requires 7 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x18, *args]
elif command == "sprite":
2021-02-10 01:12:28 +01:00
if len(args) != 3:
print(f"{filename}:{lineno}: sprite command requires 3 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x16, *args]
elif command == "item":
2021-02-10 01:12:28 +01:00
if len(args) != 2:
print(f"{filename}:{lineno}: item command requires 2 parameters")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x17, *args]
elif command == "cursor":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: cursor command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x1E, *args]
elif command == "option":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: option command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x21, *args]
elif command == "endchoice":
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x1F, args[0]]
elif command == "setcancel":
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x20, args[0]]
elif command == "startfx":
message.bytes += [0xFF, 0x26, resolve_effect(args[0]), *args[1:]]
elif command == "endfx":
message.bytes += [0xFF, 0x27, resolve_effect(args[0]), *args[1:]]
# elif command == "shaky":
# message.bytes += [0xFF, 0x26, 0x00]
# elif command == "/shaky":
# message.bytes += [0xFF, 0x27, 0x00]
# elif command == "wavy":
# message.bytes += [0xFF, 0x26, 0x01]
# elif command == "/wavy":
# message.bytes += [0xFF, 0x27, 0x01]
# elif command == "shaky":
# if "opacity" in named_args:
# print(f"{filename}:{lineno}: shaky command doesn't accept parameter 'fade' (hint: did you mean 'faded-shaky'?)")
# exit(1)
# message.bytes += [0xFF, 0x26, 0x00]
# elif command == "/shaky":
# message.bytes += [0xFF, 0x27, 0x00]
# elif command == "noise":
# message.bytes += [0xFF, 0x26, 0x03, named_args.get("fade", 3)]
# elif command == "/noise":
# message.bytes += [0xFF, 0x27, 0x03]
# elif command == "faded-shaky":
# message.bytes += [0xFF, 0x26, 0x05, named_args.get("fade", 5)]
# elif command == "/faded-shaky":
# message.bytes += [0xFF, 0x27, 0x05]
# elif command == "fade":
# message.bytes += [0xFF, 0x26, 0x07, named_args.get("fade", 7)]
# elif command == "/fade":
# message.bytes += [0xFF, 0x27, 0x07]
# elif command == "shout" or command == "shrinking":
# message.bytes += [0xFF, 0x26, 0x0A]
# elif command == "/shout" or command == "/shrinking":
# message.bytes += [0xFF, 0x27, 0x0A]
# elif command == "whisper" or command == "growing":
# message.bytes += [0xFF, 0x26, 0x0B]
# elif command == "/whisper" or command == "/growing":
# message.bytes += [0xFF, 0x27, 0x0B]
# elif command == "scream" or command == "shaky-size":
# message.bytes += [0xFF, 0x26, 0x0C]
# elif command == "/scream" or command == "/shaky-size":
# message.bytes += [0xFF, 0x27, 0x0C]
# elif command == "chortle" or command == "wavy-size":
# message.bytes += [0xFF, 0x26, 0x0D]
# elif command == "/chortle" or command == "/wavy-size":
# message.bytes += [0xFF, 0x27, 0x0D]
# elif command == "shadow":
# message.bytes += [0xFF, 0x26, 0x0E]
# elif command == "/shadow":
# message.bytes += [0xFF, 0x27, 0x0E]
elif command == "var":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: var command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x28, *args]
elif command == "func_29":
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x29, *args]
elif command == "volume":
2021-02-10 01:12:28 +01:00
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
message.bytes += [0xFF, 0x2E, *args]
elif command == "speechsound":
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
2021-02-10 01:12:28 +01:00
sound = args[0]
2021-02-10 01:12:28 +01:00
# if sound == "normal":
# sound = 0
# elif sound == "bowser":
# sound = 1
# elif sound == "star":
# sound = 2
if type(sound) is not int:
print(f"{filename}:{lineno}: unknown sound '{sound}'")
exit(1)
message.bytes += [0xFF, 0x2F, sound]
sound_stack.append(sound)
2021-02-10 01:12:28 +01:00
# elif command == "/sound":
# sound_stack.pop()
# message.bytes += [0xFF, 0x2F, sound_stack[0]]
# elif command == "a":
# color_code = color_to_code(named_args.get("color", "blue"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0x98, 0xFF, 0x25]
# elif command == "b":
# color_code = color_to_code(named_args.get("color", "green"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0x99, 0xFF, 0x25]
# elif command == "l":
# color_code = color_to_code(named_args.get("color", "gray"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0x9A, 0xFF, 0x25]
# elif command == "r":
# color_code = color_to_code(named_args.get("color", "gray"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0x9B, 0xFF, 0x25]
# elif command == "z":
# color_code = color_to_code(named_args.get("color", "gray"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0x9C, 0xFF, 0x25]
# elif command == "c-up":
# color_code = color_to_code(named_args.get("color", "yellow"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0x9D, 0xFF, 0x25]
# elif command == "c-down":
# color_code = color_to_code(named_args.get("color", "yellow"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0x9E, 0xFF, 0x25]
# elif command == "c-left":
# color_code = color_to_code(named_args.get("color", "yellow"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0x9F, 0xFF, 0x25]
# elif command == "c-right":
# color_code = color_to_code(named_args.get("color", "yellow"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0xA0, 0xFF, 0x25]
# elif command == "start":
# color_code = color_to_code(named_args.get("color", "red"), named_args.get("ctx", "button"))
# message.bytes += [0xFF, 0x24, 0xFF, 0x05, color_code, 0xA1, 0xFF, 0x25]
elif command == "a":
2021-02-10 01:12:28 +01:00
message.bytes += [0x98]
elif command == "b":
2021-02-10 01:12:28 +01:00
message.bytes += [0x99]
elif command == "l":
2021-02-10 01:12:28 +01:00
message.bytes += [0x9a]
elif command == "r":
2021-02-10 01:12:28 +01:00
message.bytes += [0x9b]
elif command == "z":
2021-02-10 01:12:28 +01:00
message.bytes += [0x9c]
elif command == "c-up":
2021-02-10 01:12:28 +01:00
message.bytes += [0x9d]
elif command == "c-down":
2021-02-10 01:12:28 +01:00
message.bytes += [0x9e]
elif command == "c-left":
2021-02-10 01:12:28 +01:00
message.bytes += [0x9f]
elif command == "c-right":
2021-02-10 01:12:28 +01:00
message.bytes += [0xa0]
elif command == "start":
2021-02-10 01:12:28 +01:00
message.bytes += [0xa1]
elif command == "note":
message.bytes += [0x00]
elif command == "heart":
message.bytes += [0x90]
elif command == "star":
message.bytes += [0x91]
2021-02-10 01:12:28 +01:00
elif command == "up":
if len(args) == 1:
message.bytes += [0xFF, 0x14, args[0]]
else:
message.bytes += [0x92]
elif command == "down":
if len(args) == 1:
message.bytes += [0xFF, 0x13, args[0]]
else:
message.bytes += [0x93]
elif command == "left":
message.bytes += [0x94]
2021-02-10 01:12:28 +01:00
elif command == "right":
message.bytes += [0x95]
elif command == "circle":
message.bytes += [0x96]
elif command == "cross":
message.bytes += [0x97]
2021-02-10 01:12:28 +01:00
# elif command == "wait":
# print(f"{filename}:{lineno}: unknown command 'wait' (hint: did you mean 'prompt'?)")
# exit(1)
# elif command == "pause":
# print(f"{filename}:{lineno}: unknown command 'pause' (hint: did you mean 'sleep'?)")
# exit(1)
elif command == "func_1a":
if len(args) != 3:
print(f"{filename}:{lineno}: {command} command requires 3 parameters")
exit(1)
message.bytes += [0xFF, 0x1A, *args]
elif command == "func_1b":
if len(args) != 2:
print(f"{filename}:{lineno}: {command} command requires 2 parameters")
exit(1)
message.bytes += [0xFF, 0x1B, *args]
elif command == "func_1c":
if len(args) != 1:
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
exit(1)
message.bytes += [0xFF, 0x1C, *args]
elif command == "startanim":
message.bytes += [0xFF, 0x22]
elif command == "endanim":
message.bytes += [0xFF, 0x23]
elif command == "func_2b":
message.bytes += [0xFF, 0x2b]
else:
print(f"{filename}:{lineno}: unknown command '{command}'")
exit(1)
else:
2021-02-10 01:12:28 +01:00
if source[0] == "}":
if not explicit_end:
2021-02-10 14:43:55 +01:00
print(f"{filename}:{lineno}: warning: string lacks an [end] command")
#message.bytes += [0xFD]
2021-02-10 01:12:28 +01:00
explicit_end = False
# padding
while len(message.bytes) % 4 != 0:
message.bytes += [0x00]
message = None
source = source[1:] # }
indent_level = 0
continue
if source[0] == "\\":
source = source[1:]
if source[0] in charset:
data = charset[source[0]]
if type(data) is int:
message.bytes.append(data)
else:
message.bytes += data
source = source[1:]
else:
print(f"{filename}:{lineno}: unsupported character '{source[0]}' for current font")
exit(1)
if message != None:
print(f"{filename}: missing [/message]")
exit(1)
with open(outfile, "wb") as f:
msgpack.pack([{
"section": message.section,
"index": message.index,
"name": message.name,
"bytes": bytes(message.bytes),
} for message in messages], f)