mirror of
https://github.com/pmret/papermario.git
synced 2024-11-09 20:42:41 +01:00
Merge pull request #177 from nanaian/srmsg
Modify message syntax to match Star Rod
This commit is contained in:
commit
af5415006e
@ -11,3 +11,6 @@ indent_size = 2
|
||||
|
||||
[{Makefile,*.mk}]
|
||||
indent_style = tab
|
||||
|
||||
[*.msg]
|
||||
indent_style = tab
|
||||
|
17
configure.py
17
configure.py
@ -315,9 +315,8 @@ async def main():
|
||||
description="ld_addrs_h $in")
|
||||
n.newline()
|
||||
|
||||
# $msg_combine_headers
|
||||
n.rule("msg_combine",
|
||||
command="$python tools/msg/combine.py $out $in --headers $msg_combine_headers",
|
||||
command="$python tools/msg/combine.py $out $in",
|
||||
description="combine messages")
|
||||
n.rule("msg",
|
||||
command="$python tools/msg/parse_compile.py $in $out",
|
||||
@ -386,9 +385,11 @@ async def main():
|
||||
n.build(add_generated_header("$builddir/include/ld_addrs.h"), "ld_addrs_h", "$builddir/$target.ld")
|
||||
|
||||
# messages
|
||||
msg_files = []
|
||||
msg_files = set()
|
||||
for d in ASSET_DIRS:
|
||||
msg_files.extend(glob(d + "/**/*.msg", recursive=True))
|
||||
for f in glob(d + "/msg/**/*.msg", recursive=True):
|
||||
msg_files.add(find_asset(f[len(d)+1:]))
|
||||
msg_files = list(msg_files)
|
||||
for msg_file in msg_files:
|
||||
n.build(
|
||||
f"$builddir/{msg_file.split('/', 1)[1]}.bin",
|
||||
@ -396,15 +397,13 @@ async def main():
|
||||
msg_file,
|
||||
implicit="tools/msg/parse_compile.py",
|
||||
)
|
||||
msg_headers = [add_generated_header(f"$builddir/include/{msg_file.split('/', 1)[1]}.h") for msg_file in msg_files]
|
||||
msg_bins = list(set([f"$builddir/{msg_file.split('/', 1)[1]}.bin" for msg_file in msg_files]))
|
||||
#msg_headers = [add_generated_header(f"$builddir/include/{msg_file.split('/', 1)[1]}.h") for msg_file in msg_files]
|
||||
msg_bins = [f"$builddir/{msg_file.split('/', 1)[1]}.bin" for msg_file in msg_files]
|
||||
n.build(
|
||||
"$builddir/msg.bin",
|
||||
["$builddir/msg.bin", add_generated_header(f"$builddir/include/message_ids.h")],
|
||||
"msg_combine",
|
||||
msg_bins,
|
||||
implicit="tools/msg/combine.py",
|
||||
implicit_outputs=msg_headers,
|
||||
variables={ "msg_combine_headers": msg_headers }
|
||||
)
|
||||
n.build("$builddir/msg.o", "bin", "$builddir/msg.bin")
|
||||
|
||||
|
@ -5,12 +5,7 @@
|
||||
|
||||
typedef s32 MessageID;
|
||||
|
||||
#define MESSAGE_ID(section, index) (((section << 0x10) + index))
|
||||
|
||||
#define MessageID_TATTLE_KMR_03 MESSAGE_ID(0x19, 0x3B)
|
||||
#define MessageID_TATTLE_KMR_12 MESSAGE_ID(0x19, 0x40)
|
||||
|
||||
#define MessageID_SIGN_MUSHROOM_GOOMBA_TRAP MESSAGE_ID(0x1D, 0x167)
|
||||
#define MessageID_SIGN_GOOMBA_KINGS_FORTRESS_AHEAD MESSAGE_ID(0x1D, 0x168)
|
||||
// Prefer editing splat.yaml's msg ids section than using this directly!
|
||||
#define MESSAGE_ID(section, index) (((section << 16) + index))
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "kmr_03.h"
|
||||
#include "message_ids.h"
|
||||
#include "../../partners.h"
|
||||
|
||||
Script N(Main);
|
||||
@ -61,7 +62,7 @@ MapConfig N(config) = {
|
||||
.entryList = N(entryList),
|
||||
.entryCount = ENTRY_COUNT(N(entryList)),
|
||||
.background = &gBackgroundImage,
|
||||
.tattle = MessageID_TATTLE_KMR_03,
|
||||
.tattle = MSG_kmr_03_tattle,
|
||||
};
|
||||
|
||||
Script N(Script_802406C0) = SCRIPT({
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "kmr_12.h"
|
||||
#include "message_ids.h"
|
||||
#include "sprite/npc/goomba.h"
|
||||
|
||||
Script N(ExitWest) = EXIT_WALK_SCRIPT(60, 0, "kmr_07", 1);
|
||||
@ -59,7 +60,7 @@ Script N(ReadWestSign) = SCRIPT({
|
||||
// "Eat a Mushroom to regain your energy!"
|
||||
suspend group 1;
|
||||
DisablePlayerInput(TRUE);
|
||||
ShowMessageAtScreenPos(MessageID_SIGN_MUSHROOM_GOOMBA_TRAP, 160, 40);
|
||||
ShowMessageAtScreenPos(MSG_kmr_12_sign_trap, 160, 40);
|
||||
resume group 1;
|
||||
|
||||
SI_FLAG(0) = FALSE;
|
||||
@ -201,7 +202,7 @@ Script N(ReadEastSign) = SCRIPT({
|
||||
|
||||
func_802D5830(1);
|
||||
DisablePlayerInput(1);
|
||||
ShowMessageAtScreenPos(MessageID_SIGN_GOOMBA_KINGS_FORTRESS_AHEAD, 160, 40);
|
||||
ShowMessageAtScreenPos(MSG_kmr_12_sign_to_fortress, 160, 40);
|
||||
DisablePlayerInput(0);
|
||||
func_802D5830(0);
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "kmr_12.h"
|
||||
#include "message_ids.h"
|
||||
|
||||
Vec4f N(entryList)[] = {
|
||||
{ -126.0f, 0.0f, 12.0f, 90.0f }, // west, towards Red/Blue Goomba miniboss room
|
||||
@ -10,7 +11,7 @@ MapConfig N(config) = {
|
||||
.entryList = N(entryList),
|
||||
.entryCount = ENTRY_COUNT(N(entryList)),
|
||||
.background = &gBackgroundImage,
|
||||
.tattle = MessageID_TATTLE_KMR_12,
|
||||
.tattle = MSG_kmr_12_tattle,
|
||||
};
|
||||
|
||||
Script N(PlayMusic) = SCRIPT({
|
||||
|
@ -16,30 +16,38 @@ class Message:
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(argv) < 3:
|
||||
print("usage: combine.py [out.bin] [compiled...] --headers [out.h]")
|
||||
print("usage: combine.py [out.bin] [out.h] [compiled...]")
|
||||
exit(1)
|
||||
|
||||
_, outfile, *infiles = argv
|
||||
_, outfile, header_file, *infiles = argv
|
||||
|
||||
messages = []
|
||||
header_files = []
|
||||
#header_files = []
|
||||
|
||||
for i, infile in enumerate(infiles):
|
||||
if infile == "--headers":
|
||||
header_files = infiles[i+1:]
|
||||
break
|
||||
# if infile == "--headers":
|
||||
# header_files = infiles[i+1:]
|
||||
# break
|
||||
|
||||
with open(infile, "rb") as f:
|
||||
messages.extend(Message(msg, i) for msg in msgpack.unpack(f))
|
||||
|
||||
with open(outfile, "wb") as f:
|
||||
# sectioned+indexed, followed by just sectioned, followed by just indexed, followed by named (unsectioned & unindexed)
|
||||
messages.sort(key=lambda msg: bool(msg.section)<<2 + bool(msg.index))
|
||||
#messages.sort(key=lambda msg: bool(msg.section)<<2 + bool(msg.index))
|
||||
|
||||
names = set()
|
||||
|
||||
sections = [] * 0x2E
|
||||
messages_by_file = {}
|
||||
sections = []
|
||||
#messages_by_file = {}
|
||||
|
||||
# this logic could probably be a bit better (i.e. read ahead, so no overwriting happens)
|
||||
def section_get_unused_id(section):
|
||||
max_index = 0
|
||||
for index in section:
|
||||
if index > max_index:
|
||||
max_index = index
|
||||
return max_index + 1
|
||||
|
||||
for message in messages:
|
||||
if message.section is None:
|
||||
@ -47,35 +55,44 @@ if __name__ == "__main__":
|
||||
for section_idx, section in enumerate(sections):
|
||||
if len(section) < 0xFFF:
|
||||
break
|
||||
message.section = section_idx
|
||||
else:
|
||||
section_idx = message.section
|
||||
while len(sections) <= section_idx:
|
||||
sections.append([])
|
||||
sections.append({})
|
||||
section = sections[section_idx]
|
||||
|
||||
index = message.index if message.index is not None else len(section)
|
||||
if message.index is None:
|
||||
message.index = section_get_unused_id(section)
|
||||
|
||||
if message.name:
|
||||
if message.name in names:
|
||||
print(f"warning: multiple messages with name '{message.name}'")
|
||||
else:
|
||||
names.add(message.name)
|
||||
# if message.name:
|
||||
# if message.name in names:
|
||||
# print(f"error: multiple messages with name '{message.name}'")
|
||||
# exit(1)
|
||||
# else:
|
||||
# names.add(message.name)
|
||||
|
||||
if message.header_file_index in messages_by_file:
|
||||
messages_by_file[message.header_file_index].add(message)
|
||||
else:
|
||||
messages_by_file[message.header_file_index] = set([message])
|
||||
# if message.header_file_index in messages_by_file:
|
||||
# messages_by_file[message.header_file_index].add(message)
|
||||
# else:
|
||||
# messages_by_file[message.header_file_index] = set([message])
|
||||
|
||||
section.append(message.bytes)
|
||||
if message.index in section:
|
||||
print(f"warning: multiple messages allocated to id {section_idx:02X}:{message.index:03X}")
|
||||
|
||||
section[message.index] = message
|
||||
|
||||
f.seek((len(sections) + 1) * 4) # skip past table of contents
|
||||
|
||||
section_offsets = []
|
||||
for section in sections:
|
||||
# convert dict into sorted list
|
||||
section = [msg for idx, msg in sorted(section.items(), key=lambda ele: ele[0])]
|
||||
|
||||
message_offsets = []
|
||||
for message in section:
|
||||
message_offsets.append(f.tell())
|
||||
f.write(message)
|
||||
f.write(message.bytes)
|
||||
|
||||
section_offset = f.tell()
|
||||
section_offsets.append(section_offset)
|
||||
@ -92,34 +109,17 @@ if __name__ == "__main__":
|
||||
f.write(offset.to_bytes(4, byteorder="big"))
|
||||
f.write(b'\0\0\0\0')
|
||||
|
||||
for i, header_file in enumerate(header_files):
|
||||
messages = messages_by_file.get(i, [])
|
||||
|
||||
h = (
|
||||
f"#ifndef _MESSAGE_IDS_{i}_H_\n"
|
||||
f"#define _MESSAGE_IDS_{i}_H_\n"
|
||||
with open(header_file, "w") as f:
|
||||
f.write(
|
||||
f"#ifndef _MESSAGE_IDS_H_\n"
|
||||
f"#define _MESSAGE_IDS_H_\n"
|
||||
"\n"
|
||||
'#include "messages.h"\n'
|
||||
"\n"
|
||||
)
|
||||
|
||||
for message in messages:
|
||||
h += f"#define MessageID_{message.name} MESSAGE_ID({message.section}, {message.index})\n"
|
||||
if message.name:
|
||||
f.write(f"#define MSG_{message.name} MESSAGE_ID(0x{message.section:02X}, 0x{message.index:03X})\n")
|
||||
|
||||
h += "\n#endif\n"
|
||||
h_lines = h.splitlines()
|
||||
|
||||
# this doesnt work properly with ninja. the build is fast enough anyway
|
||||
"""
|
||||
# only rewrite the header file if its content changed
|
||||
with open(header_file, "r") as f:
|
||||
cur_h_lines = f.read().splitlines()
|
||||
is_different = cur_h_lines != h_lines
|
||||
|
||||
if is_different:
|
||||
with open(header_file, "w") as f:
|
||||
f.write(h)
|
||||
"""
|
||||
|
||||
with open(header_file, "w") as f:
|
||||
f.write(h)
|
||||
f.write("\n#endif\n")
|
||||
|
@ -21,21 +21,22 @@ def try_convert_int(s):
|
||||
|
||||
def parse_command(source):
|
||||
if source[0] != "[":
|
||||
return None, [], {}, source
|
||||
return None, [], source
|
||||
source = source[1:] # "["
|
||||
|
||||
inside_brackets = ""
|
||||
while source[0] != "]":
|
||||
if source[0] == "\n":
|
||||
return None, [], {}, source
|
||||
return None, [], source
|
||||
|
||||
inside_brackets += source[0]
|
||||
source = source[1:]
|
||||
source = source[1:] # "]"
|
||||
|
||||
command, *args = inside_brackets.split(" ")
|
||||
command, *raw_args = inside_brackets.split(":")
|
||||
|
||||
positional_args = []
|
||||
"""
|
||||
args = []
|
||||
named_args = {}
|
||||
|
||||
if "=" in command:
|
||||
@ -48,22 +49,18 @@ def parse_command(source):
|
||||
key, value = arg.split("=", 1)
|
||||
named_args[key.lower()] = try_convert_int(value.lower())
|
||||
else:
|
||||
positional_args.append(try_convert_int(arg))
|
||||
args.append(try_convert_int(arg))
|
||||
"""
|
||||
|
||||
return command.lower(), positional_args, named_args, source
|
||||
args = []
|
||||
for arg in raw_args:
|
||||
args.append(try_convert_int(arg.lower()))
|
||||
|
||||
def color_to_code(color, ctx="normal"):
|
||||
return command.lower(), args, source
|
||||
|
||||
def color_to_code(color, style):
|
||||
"""
|
||||
COLORS = {
|
||||
"normal": {
|
||||
"normal": 0x0A,
|
||||
"red": 0x20,
|
||||
"pink": 0x21,
|
||||
"purple": 0x22,
|
||||
"blue": 0x23,
|
||||
"cyan": 0x24,
|
||||
"green": 0x25,
|
||||
"yellow": 0x26,
|
||||
},
|
||||
"diary": {
|
||||
"normal": 0x00,
|
||||
"red": 0x07,
|
||||
@ -96,14 +93,50 @@ def color_to_code(color, ctx="normal"):
|
||||
"green": 0x1B,
|
||||
}
|
||||
}
|
||||
"""
|
||||
COLORS = {}
|
||||
|
||||
if type(color) is int:
|
||||
return color
|
||||
|
||||
return COLORS.get(ctx, {}).get(color)
|
||||
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 = {
|
||||
"𝅘𝅥𝅮": 0x00,
|
||||
#"𝅘𝅥𝅮": 0x00,
|
||||
"!": 0x01,
|
||||
'"': 0x02,
|
||||
"#": 0x03,
|
||||
@ -247,29 +280,29 @@ CHARSET = {
|
||||
"¡": 0x8D,
|
||||
"¿": 0x8E,
|
||||
"ª": 0x8F,
|
||||
"♥": 0x90,
|
||||
"★": 0x91,
|
||||
"↑": 0x92,
|
||||
"↓": 0x93,
|
||||
"←": 0x94,
|
||||
"→": 0x95,
|
||||
"●": 0x96,
|
||||
"✖": 0x97,
|
||||
# "♥": 0x90,
|
||||
# "★": 0x91,
|
||||
# "↑": 0x92,
|
||||
# "↓": 0x93,
|
||||
# "←": 0x94,
|
||||
# "→": 0x95,
|
||||
# "●": 0x96,
|
||||
# "✖": 0x97,
|
||||
"“": 0xA2,
|
||||
"”": 0xA3,
|
||||
"‘": 0xA4,
|
||||
"’": 0xA5,
|
||||
" ": 0xF7,
|
||||
"Ⓐ": [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],
|
||||
# "Ⓐ": [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 = {
|
||||
@ -317,6 +350,19 @@ CHARSET_CREDITS = {
|
||||
" ": 0xF7,
|
||||
}
|
||||
|
||||
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]")
|
||||
@ -328,88 +374,142 @@ if __name__ == "__main__":
|
||||
|
||||
message = None
|
||||
with open(filename, "r") as f:
|
||||
source = f.read()
|
||||
source = strip_c_comments(f.read())
|
||||
lineno = 1
|
||||
|
||||
directive = ""
|
||||
indent_level = 0
|
||||
|
||||
charset = CHARSET
|
||||
font_stack = [0]
|
||||
sound_stack = [0]
|
||||
color_stack = [0x0A]
|
||||
style = None
|
||||
explicit_end = False
|
||||
|
||||
while len(source) > 0:
|
||||
if source.startswith("\n"):
|
||||
lineno += 1
|
||||
if source[0] == "\r" or source[0] == "\t":
|
||||
source = source[1:]
|
||||
continue
|
||||
|
||||
if message is None:
|
||||
if source.startswith("//"):
|
||||
while source[0] != "\n":
|
||||
source = source[1:]
|
||||
else:
|
||||
command, positional_args, named_args, source = parse_command(source)
|
||||
if source[0] == "\n":
|
||||
lineno += 1
|
||||
source = source[1:]
|
||||
|
||||
if not command:
|
||||
print(f"{filename}:{lineno}: expected [message]")
|
||||
for i in range(indent_level):
|
||||
if source[0] == "\t":
|
||||
source = source[1:]
|
||||
else:
|
||||
break
|
||||
|
||||
continue
|
||||
|
||||
if message is None:
|
||||
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:
|
||||
name = None
|
||||
index = int(directive[2], 16)
|
||||
|
||||
directive = ""
|
||||
|
||||
message = Message(name, section, index)
|
||||
messages.append(message)
|
||||
|
||||
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)
|
||||
|
||||
name = positional_args[0] if len(positional_args) > 0 else None
|
||||
message = Message(name, named_args.get("section"), named_args.get("index"))
|
||||
messages.append(message)
|
||||
source = source[1:] # {
|
||||
|
||||
# count indent level
|
||||
indent_level = 0
|
||||
"""
|
||||
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:]
|
||||
"""
|
||||
else:
|
||||
command, positional_args, named_args, source = parse_command(source)
|
||||
command, args, source = parse_command(source)
|
||||
|
||||
if command:
|
||||
if command == "/message":
|
||||
if command == "end":
|
||||
message.bytes += [0xFD]
|
||||
|
||||
# padding
|
||||
while len(message.bytes) % 4 != 0:
|
||||
message.bytes += [0x00]
|
||||
|
||||
message = None
|
||||
explicit_end = True
|
||||
elif command == "raw":
|
||||
message.bytes += [*positional_args]
|
||||
elif command == "func":
|
||||
message.bytes += [0xFF, *positional_args]
|
||||
message.bytes += [*args]
|
||||
#elif command == "func":
|
||||
# message.bytes += [0xFF, *args]
|
||||
elif command == "br":
|
||||
message.bytes += [0xF0]
|
||||
elif command == "prompt":
|
||||
elif command == "wait":
|
||||
message.bytes += [0xF1]
|
||||
elif command == "sleep":
|
||||
if len(positional_args) == 0:
|
||||
print(f"{filename}:{lineno}: {command} command requires a positional parameter")
|
||||
elif command == "pause":
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xF2, positional_args[0]]
|
||||
message.bytes += [0xF2, args[0]]
|
||||
elif command == "next":
|
||||
message.bytes += [0xFB]
|
||||
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":
|
||||
if "color" not in named_args:
|
||||
print(f"{filename}:{lineno}: color command requires a 'color' parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: color command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
color = color_to_code(**named_args)
|
||||
color = color_to_code(args[0], style)
|
||||
|
||||
if color is None:
|
||||
print(f"{filename}:{lineno}: unknown color combination {named_args}")
|
||||
print(f"{filename}:{lineno}: unknown color")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x05, color]
|
||||
color_stack.append(color)
|
||||
elif command == "/color":
|
||||
color_stack.pop()
|
||||
message.bytes += [0xFF, 0x05, color_stack[0]]
|
||||
#elif command == "/color":
|
||||
# color_stack.pop()
|
||||
# message.bytes += [0xFF, 0x05, color_stack[0]]
|
||||
elif command == "style":
|
||||
if "style" not in named_args:
|
||||
print(f"{filename}:{lineno}: style command requires a 'style' parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFC]
|
||||
|
||||
style = named_args["style"]
|
||||
style = args[0]
|
||||
args = args[1:]
|
||||
if type(style) is int:
|
||||
message.bytes += [style, *positional_args]
|
||||
message.bytes += [style, *args]
|
||||
else:
|
||||
if style == "right":
|
||||
message.bytes += [0x01]
|
||||
@ -420,37 +520,45 @@ if __name__ == "__main__":
|
||||
elif style == "tattle":
|
||||
message.bytes += [0x04]
|
||||
elif style == "choice":
|
||||
if "w" not in named_args or "h" not in named_args or "x" not in named_args or "y" not in named_args:
|
||||
print(f"{filename}:{lineno}: 'choice' style requires parameters: x, y, w, h")
|
||||
if len(args) != 4:
|
||||
print(f"{filename}:{lineno}: 'choice' style requires 4 parameters")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0x05, named_args["x"], named_args["y"], named_args["w"], named_args["h"]]
|
||||
message.bytes += [0x05, *args]
|
||||
elif style == "inspect":
|
||||
message.bytes += [0x06]
|
||||
elif style == "sign":
|
||||
message.bytes += [0x07]
|
||||
elif style == "lamppost":
|
||||
message.bytes += [0x08]
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: 'lamppost' style requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0x08, args[0]]
|
||||
elif style == "postcard":
|
||||
message.bytes += [0x09]
|
||||
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":
|
||||
if "w" not in named_args or "h" not in named_args or "x" not in named_args or "y" not in named_args:
|
||||
print(f"{filename}:{lineno}: 'upgrade' style requires parameters: x, y, w, h")
|
||||
if len(args) != 4:
|
||||
print(f"{filename}:{lineno}: 'upgrade' style requires 4 parameters")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0x0C, named_args["w"], named_args["x"], named_args["h"], named_args["y"]]
|
||||
message.bytes += [0x0C, *args]
|
||||
elif style == "narrate":
|
||||
message.bytes += [0x0D]
|
||||
elif style == "epilogue":
|
||||
message.bytes += [0x0E]
|
||||
elif command == "font":
|
||||
if "font" not in named_args:
|
||||
print(f"{filename}:{lineno}: font command requires a 'font' parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: font command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
font = named_args["font"]
|
||||
font = args[0]
|
||||
|
||||
if font == "normal":
|
||||
font = 0
|
||||
@ -470,203 +578,213 @@ if __name__ == "__main__":
|
||||
charset = CHARSET_CREDITS
|
||||
else:
|
||||
charset = CHARSET
|
||||
elif command == "/font":
|
||||
font_stack.pop()
|
||||
message.bytes += [0xFF, 0x00, font_stack[0]]
|
||||
# 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 == "noskip":
|
||||
# if font == 3 or font == 4:
|
||||
# charset = CHARSET_CREDITS
|
||||
# else:
|
||||
# charset = CHARSET
|
||||
elif command == "inputoff":
|
||||
message.bytes += [0xFF, 0x07]
|
||||
elif command == "/noskip":
|
||||
elif command == "inputon":
|
||||
message.bytes += [0xFF, 0x08]
|
||||
elif command == "instant":
|
||||
elif command == "delayoff":
|
||||
message.bytes += [0xFF, 0x09]
|
||||
elif command == "/instant":
|
||||
elif command == "delayon":
|
||||
message.bytes += [0xFF, 0x0A]
|
||||
elif command == "kerning":
|
||||
if "kerning" not in named_args:
|
||||
print(f"{filename}:{lineno}: kerning command requires a 'kerning' parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x0B, named_args["kerning"]]
|
||||
message.bytes += [0xFF, 0x0B, args[0]]
|
||||
elif command == "scroll":
|
||||
if len(positional_args) == 0:
|
||||
print(f"{filename}:{lineno}: scroll command requires a positional parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x0C, positional_args[0]]
|
||||
message.bytes += [0xFF, 0x0C, args[0]]
|
||||
elif command == "size":
|
||||
if "x" not in named_args or "y" not in named_args:
|
||||
print(f"{filename}:{lineno}: size command requires parameters: x, y")
|
||||
if len(args) != 2:
|
||||
print(f"{filename}:{lineno}: {command} command requires 2 parameters")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x0D, named_args["x"], named_args["y"]]
|
||||
elif command == "/size":
|
||||
message.bytes += [0xFF, 0x0D, *args]
|
||||
elif command == "sizereset":
|
||||
message.bytes += [0xFF, 0x0E]
|
||||
elif command == "speed":
|
||||
if "delay" not in named_args or "chars" not in named_args:
|
||||
print(f"{filename}:{lineno}: speed command requires parameters: delay, chars")
|
||||
if len(args) != 2:
|
||||
print(f"{filename}:{lineno}: {command} command requires 2 parameters")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x0F, named_args["delay"], named_args["chars"]]
|
||||
elif command == "pos":
|
||||
if "y" not in named_args:
|
||||
print(f"{filename}:{lineno}: pos command requires parameter: y (x is optional)")
|
||||
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)
|
||||
|
||||
if "x" in named_args:
|
||||
message.bytes += [0xFF, 0x10, named_args["x"], named_args["y"]]
|
||||
else:
|
||||
message.bytes += [0xFF, 0x11, named_args["y"]]
|
||||
message.bytes += [0xFF, 0x10, *args]
|
||||
elif command == "setprinty":
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x11, *args]
|
||||
elif command == "indent":
|
||||
if len(positional_args) == 0:
|
||||
print(f"{filename}:{lineno}: indent command requires a positional parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: indent command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x12, positional_args[0]]
|
||||
elif command == "down":
|
||||
if len(positional_args) == 0:
|
||||
print(f"{filename}:{lineno}: down command requires a positional parameter")
|
||||
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)
|
||||
|
||||
message.bytes += [0xFF, 0x13, positional_args[0]]
|
||||
elif command == "up":
|
||||
if len(positional_args) == 0:
|
||||
print(f"{filename}:{lineno}: up command requires a positional parameter")
|
||||
message.bytes += [0xFF, 0x15, *args]
|
||||
elif command == "image7":
|
||||
if len(args) != 7:
|
||||
print(f"{filename}:{lineno}: {command} command requires 7 parameters")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x14, positional_args[0]]
|
||||
elif command == "image":
|
||||
if len(positional_args) == 1:
|
||||
message.bytes += [0xFF, 0x15, positional_args[0]]
|
||||
elif len(positional_args) == 7:
|
||||
message.bytes += [0xFF, 0x18, *positional_args]
|
||||
else:
|
||||
print(f"{filename}:{lineno}: image command requires 1 or 7 positional parameters")
|
||||
exit(1)
|
||||
message.bytes += [0xFF, 0x18, *args]
|
||||
elif command == "sprite":
|
||||
if len(positional_args) != 3:
|
||||
print(f"{filename}:{lineno}: sprite command requires 3 positional parameters")
|
||||
if len(args) != 3:
|
||||
print(f"{filename}:{lineno}: sprite command requires 3 parameters")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x16, *positional_args]
|
||||
message.bytes += [0xFF, 0x16, *args]
|
||||
elif command == "item":
|
||||
if len(positional_args) != 2:
|
||||
print(f"{filename}:{lineno}: item command requires 2 positional parameters")
|
||||
if len(args) != 2:
|
||||
print(f"{filename}:{lineno}: item command requires 2 parameters")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x17, *positional_args]
|
||||
message.bytes += [0xFF, 0x17, *args]
|
||||
elif command == "cursor":
|
||||
if len(positional_args) != 1:
|
||||
print(f"{filename}:{lineno}: cursor command requires 1 positional parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: cursor command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x1E, *positional_args]
|
||||
message.bytes += [0xFF, 0x1E, *args]
|
||||
elif command == "option":
|
||||
if len(positional_args) != 1:
|
||||
print(f"{filename}:{lineno}: option command requires 1 positional parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: option command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x21, *positional_args]
|
||||
elif command == "choice":
|
||||
if len(positional_args) != 1:
|
||||
print(f"{filename}:{lineno}: choice command requires 1 positional parameter")
|
||||
message.bytes += [0xFF, 0x21, *args]
|
||||
elif command == "endchoice":
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x1E, positional_args[0], 0xFF, 0x21, positional_args[0]]
|
||||
elif command == "choicecount":
|
||||
if "choicecount" not in named_args:
|
||||
print(f"{filename}:{lineno}: choicecount command requires a 'choicecount' parameter")
|
||||
message.bytes += [0xFF, 0x1F, args[0]]
|
||||
elif command == "setcancel":
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x1F, named_args["choicecount"]]
|
||||
elif command == "cancel":
|
||||
if "cancel" not in named_args:
|
||||
print(f"{filename}:{lineno}: cancel command requires a 'cancel' parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x20, named_args["cancel"]]
|
||||
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]
|
||||
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":
|
||||
if len(positional_args) != 1:
|
||||
print(f"{filename}:{lineno}: var command requires 1 positional parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: var command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x28, *positional_args]
|
||||
elif command == "center":
|
||||
if len(positional_args) != 1:
|
||||
print(f"{filename}:{lineno}: center command requires 1 positional parameter")
|
||||
message.bytes += [0xFF, 0x28, *args]
|
||||
elif command == "func_29":
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x29, *positional_args]
|
||||
message.bytes += [0xFF, 0x29, *args]
|
||||
elif command == "volume":
|
||||
if "volume" not in named_args:
|
||||
print(f"{filename}:{lineno}: volume command requires a 'volume' parameter")
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
message.bytes += [0xFF, 0x2E, named_args["volume"]]
|
||||
elif command == "sound":
|
||||
if "sound" not in named_args:
|
||||
print(f"{filename}:{lineno}: sound command requires a 'sound' parameter")
|
||||
message.bytes += [0xFF, 0x2E, *args]
|
||||
elif command == "speechsound":
|
||||
if len(args) != 1:
|
||||
print(f"{filename}:{lineno}: {command} command requires 1 parameter")
|
||||
exit(1)
|
||||
|
||||
sound = named_args["sound"]
|
||||
sound = args[0]
|
||||
|
||||
if sound == "normal":
|
||||
sound = 0
|
||||
elif sound == "bowser":
|
||||
sound = 1
|
||||
elif sound == "spirit":
|
||||
sound = 2
|
||||
# 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}'")
|
||||
@ -674,67 +792,132 @@ if __name__ == "__main__":
|
||||
|
||||
message.bytes += [0xFF, 0x2F, sound]
|
||||
sound_stack.append(sound)
|
||||
elif command == "/sound":
|
||||
sound_stack.pop()
|
||||
message.bytes += [0xFF, 0x2F, sound_stack[0]]
|
||||
# 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":
|
||||
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]
|
||||
message.bytes += [0x98]
|
||||
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]
|
||||
message.bytes += [0x99]
|
||||
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]
|
||||
message.bytes += [0x9a]
|
||||
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]
|
||||
message.bytes += [0x9b]
|
||||
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]
|
||||
message.bytes += [0x9c]
|
||||
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]
|
||||
message.bytes += [0x9d]
|
||||
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]
|
||||
message.bytes += [0x9e]
|
||||
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]
|
||||
message.bytes += [0x9f]
|
||||
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]
|
||||
message.bytes += [0xa0]
|
||||
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]
|
||||
message.bytes += [0xa1]
|
||||
elif command == "note":
|
||||
message.bytes += [0x00]
|
||||
elif command == "heart":
|
||||
message.bytes += [0x90]
|
||||
elif command == "star":
|
||||
message.bytes += [0x91]
|
||||
elif command == "arrow-up":
|
||||
message.bytes += [0x92]
|
||||
elif command == "arrow-down":
|
||||
message.bytes += [0x93]
|
||||
elif command == "arrow-left":
|
||||
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]
|
||||
elif command == "arrow-right":
|
||||
elif command == "right":
|
||||
message.bytes += [0x95]
|
||||
elif command == "circle":
|
||||
message.bytes += [0x96]
|
||||
elif command == "cross":
|
||||
message.bytes += [0x97]
|
||||
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 == "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:
|
||||
if source[0] == "}":
|
||||
if not explicit_end:
|
||||
print(f"{filename}:{lineno}: warning: string lacks an [end] command")
|
||||
#message.bytes += [0xFD]
|
||||
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:]
|
||||
|
||||
|
103
tools/splat.yaml
103
tools/splat.yaml
@ -9432,55 +9432,60 @@ segments:
|
||||
- start: 0x1B83000
|
||||
type: PaperMarioMessages
|
||||
files:
|
||||
- intro
|
||||
- end/postgame
|
||||
- toad_town/gate
|
||||
- toad_town/castle
|
||||
- toad_town/bridge
|
||||
- toad_town/train
|
||||
- toad_town/warehouse
|
||||
- toad_town/docks
|
||||
- toad_town/minigames
|
||||
- castle_grounds
|
||||
- shooting_star_summit
|
||||
- prologue
|
||||
- chapter1
|
||||
- chapter2
|
||||
- chapter3
|
||||
- chapter4
|
||||
- chapter5
|
||||
- chapter6
|
||||
- chapter7
|
||||
- chapter8
|
||||
- peach_interludes
|
||||
- koopa_koot_quests
|
||||
- advice/russ_t
|
||||
- toad_town/bulletin_news
|
||||
- toad_town/bulletin_gossip
|
||||
- world/map_tattles
|
||||
- world/npc_tattles
|
||||
- world/entity_tattles
|
||||
- battle/enemy_tattles
|
||||
- ui/misc
|
||||
- ui/choices
|
||||
- ui/pause
|
||||
- diary_letters
|
||||
- advice/merlon
|
||||
- advice/merluvlee
|
||||
- item/descriptions_23 # TODO: difference between 23,24,25
|
||||
- item/descriptions_24
|
||||
- item/descriptions_25
|
||||
- item/names
|
||||
- shops
|
||||
- partner_descriptions
|
||||
- battle/enemy_names
|
||||
- battle/mario_moves
|
||||
- battle/partner_moves
|
||||
- quiz/questions
|
||||
- quiz/options
|
||||
- end/credits
|
||||
- [0x1C84D30, bin]
|
||||
- [0x1E00000, bin] # sprites here; Star Rod considers this a copy of sprite/npc.bin, but that doesnt appear to be true
|
||||
- 00_introduction
|
||||
- 01_postgame_celebration
|
||||
- 02_toad_town_gate_sector
|
||||
- 03_toad_town_castle_sector
|
||||
- 04_toad_town_bridge_sector
|
||||
- 05_toad_town_train_sector
|
||||
- 06_toad_town_warehouse_sector
|
||||
- 07_toad_town_docks_sector
|
||||
- 08_minigames
|
||||
- 09_castle_grounds
|
||||
- 0A_shooting_star_summit
|
||||
- 0B_prologue
|
||||
- 0C_chapter_1
|
||||
- 0D_chapter_2
|
||||
- 0E_chapter_3
|
||||
- 0F_chapter_4
|
||||
- 10_chapter_5
|
||||
- 11_chapter_6
|
||||
- 12_chapter_7
|
||||
- 13_chapter_8
|
||||
- 14_peach_segments
|
||||
- 15_koopa_koot_favors
|
||||
- 16_russ_t_advice
|
||||
- 17_news_bulletin
|
||||
- 18_gossip_bulletin
|
||||
- 19_map_tattles
|
||||
- 1A_npc_tattles
|
||||
- 1B_entity_tattles
|
||||
- 1C_enemy_tattles
|
||||
- 1D_menus
|
||||
- 1E_choices
|
||||
- 1F_pause
|
||||
- 20_party_letters_luigi_diary
|
||||
- 21_advice_fortunes
|
||||
- 22_treasure_fortunes
|
||||
- 23_item_descriptions # TODO: difference between 23,24,25 (shops, menus, pickups?)
|
||||
- 24_item_descriptions
|
||||
- 25_item_descriptions
|
||||
- 26_item_names
|
||||
- 27_shop_messages
|
||||
- 28_partner_descriptions
|
||||
- 29_enemy_names
|
||||
- 2A_mario_moves
|
||||
- 2B_partner_moves
|
||||
- 2C_quiz_questions
|
||||
- 2D_quiz_options
|
||||
- 2E_credits
|
||||
ids:
|
||||
- [0x19, 0x03B, kmr_03_tattle]
|
||||
- [0x19, 0x040, kmr_12_tattle]
|
||||
- [0x1D, 0x167, kmr_12_sign_trap]
|
||||
- [0x1D, 0x168, kmr_12_sign_to_fortress]
|
||||
- [0x1C84D30, bin] # junk(?)
|
||||
- [0x1E00000, bin] # junk (player sprite data; can be zeroed out with no effect)
|
||||
- [0x1E40000, PaperMarioMapFS]
|
||||
- [0x27FEE22, bin]
|
||||
- [0x2800000]
|
||||
|
@ -1,8 +1,9 @@
|
||||
from segtypes.n64.segment import N64Segment
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
CHARSET = {
|
||||
0x00: "𝅘𝅥𝅮",
|
||||
0x00: "[note]",
|
||||
0x01: "!",
|
||||
0x02: '"',
|
||||
0x03: "#",
|
||||
@ -146,142 +147,163 @@ CHARSET = {
|
||||
0x8D: "¡",
|
||||
0x8E: "¿",
|
||||
0x8F: "ª",
|
||||
0x90: "♥",
|
||||
0x91: "★",
|
||||
0x92: "↑",
|
||||
0x93: "↓",
|
||||
0x94: "←",
|
||||
0x95: "→",
|
||||
0x96: "●",
|
||||
0x97: "✖",
|
||||
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: "’",
|
||||
0xF7: " ",
|
||||
0xF0: "[br]\n",
|
||||
0xF1: "[prompt]",
|
||||
0xF2: {None: lambda d: (f"[sleep {d[0]}]", 1)},
|
||||
0xF1: "[wait]",
|
||||
0xF2: {None: lambda d: (f"[pause:{d[0]}]", 1)},
|
||||
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 x={d[0]} y={d[1]} w={d[2]} h={d[3]}]\n", 4)},
|
||||
0x06: "[style=inspect]\n",
|
||||
0x07: "[style=sign]\n",
|
||||
0x08: "[style=lamppost]\n",
|
||||
0x09: "[style=postcard]\n",
|
||||
0x0A: "[style=popup]\n",
|
||||
0x0C: {None: lambda d: (f"[style=upgrade x={d[1]} y={d[3]} w={d[0]} h={d[2]}]\n", 4)},
|
||||
0x0D: "[style=narrate]\n",
|
||||
0x0E: "[style=epilogue]\n",
|
||||
0x01: "[style:right]\n",
|
||||
0x02: "[style:left]\n",
|
||||
0x03: "[style:center]\n",
|
||||
0x04: "[style:tattle]\n",
|
||||
0x05: {None: lambda d: (f"[style:choice:{d[0]}:{d[1]}:{d[2]}:{d[3]}]\n", 4)},
|
||||
0x06: "[style:inspect]\n",
|
||||
0x07: "[style:sign]\n",
|
||||
0x08: {None: lambda d: (f"[style:lamppost:{d[0]}]\n", 1)},
|
||||
0x09: {None: lambda d: (f"[style:postcard:{d[0]}]\n", 1)},
|
||||
0x0A: "[style:popup]\n",
|
||||
0x0C: {None: lambda d: (f"[style:upgrade:{d[0]}:{d[1]}:{d[2]}:{d[3]}]\n", 4)},
|
||||
0x0D: "[style:narrate]\n",
|
||||
0x0E: "[style:epilogue]\n",
|
||||
},
|
||||
0xFF: {
|
||||
0x00: {
|
||||
0: "[font=normal]",
|
||||
3: "[font=title]\n",
|
||||
4: "[font=subtitle]\n",
|
||||
0: "[font:normal]",
|
||||
3: "[font:title]\n",
|
||||
4: "[font:subtitle]\n",
|
||||
},
|
||||
0x04: "[func_04]",
|
||||
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]",
|
||||
# 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]",
|
||||
# 0x00: "[color=normal ctx=diary]",
|
||||
# 0x07: "[color=red ctx=diary]",
|
||||
|
||||
0x17: "[color=dark ctx=inspect]",
|
||||
# 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]",
|
||||
# 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]",
|
||||
# 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: "[noskip]\n",
|
||||
0x08: "[/noskip]\n",
|
||||
0x09: "[instant]\n",
|
||||
0x0A: "[/instant]\n",
|
||||
0x0B: {None: lambda d: (f"[kerning={d[0]}]", 1)},
|
||||
0x0C: {None: lambda d: (f"[scroll {d[0]}]", 1)},
|
||||
0x0D: {None: lambda d: (f"[size x={d[0]} y={d[0]}]\n", 2)},
|
||||
0x0E: "[/size]\n",
|
||||
0x0F: {None: lambda d: (f"[speed delay={d[0]} chars={d[1]}]", 2)},
|
||||
0x10: {None: lambda d: (f"[pos x={d[0]} y={d[1]}]", 2)},
|
||||
0x11: {None: lambda d: (f"[pos y={d[0]}]", 1)},
|
||||
0x12: {None: lambda d: (f"[indent {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"[image {d[0]}]\n", 1)},
|
||||
0x16: {None: lambda d: (f"[sprite {d[0]} {d[1]} {d[2]}]\n", 3)},
|
||||
0x17: {None: lambda d: (f"[item {d[0]} {d[1]}]\n", 2)},
|
||||
0x18: {None: lambda d: (f"[image {d[0]} {d[1]} {d[2]} {d[3]} {d[4]} {d[5]} {d[6]}]\n", 7)},
|
||||
0x1E: {None: lambda d: (f"[cursor {d[0]}]", 1)},
|
||||
0x1F: {None: lambda d: (f"[choicecount={d[0]}]", 1)},
|
||||
0x20: {None: lambda d: (f"[cancel={d[0]}]", 1)},
|
||||
0x21: {None: lambda d: (f"[option {d[0]}]", 1)},
|
||||
0x24: {0xFF: {0x05: {
|
||||
0x10: {0x98: {0xFF: {0x25: "Ⓐ"}}},
|
||||
0x11: {0x99: {0xFF: {0x25: "Ⓑ"}}},
|
||||
0x12: {0xA1: {0xFF: {0x25: "Ⓢ"}}},
|
||||
0x13: {
|
||||
0x9D: {0xFF: {0x25: "▲"}},
|
||||
0x9E: {0xFF: {0x25: "▼"}},
|
||||
0x9F: {0xFF: {0x25: "◀"}},
|
||||
0xA0: {0xFF: {0x25: "▶"}},
|
||||
},
|
||||
0x14: {0x9C: {0xFF: {0x25: "Ⓩ"}}},
|
||||
}}},
|
||||
0x07: "[inputOff]\n",
|
||||
0x08: "[inputOn]\n",
|
||||
0x09: "[delayOff]\n",
|
||||
0x0A: "[delayOn]\n",
|
||||
0x0B: {None: lambda d: (f"[kerning:{d[0]}]", 1)},
|
||||
0x0C: {None: lambda d: (f"[scroll:{d[0]}]", 1)},
|
||||
0x0D: {None: lambda d: (f"[size:{d[0]}:{d[0]}]\n", 2)},
|
||||
0x0E: "[sizeReset]\n",
|
||||
0x0F: {None: lambda d: (f"[speed:{d[0]}:{d[1]}]", 2)},
|
||||
0x10: {None: lambda d: (f"[setPrintPos:{d[0]}:{d[1]}]", 2)},
|
||||
0x11: {None: lambda d: (f"[setPrintY:{d[0]}]", 1)},
|
||||
0x12: {None: lambda d: (f"[indent:{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"[image1:{d[0]}]\n", 1)},
|
||||
0x16: {None: lambda d: (f"[sprite:{d[0]}:{d[1]}:{d[2]}]\n", 3)},
|
||||
0x17: {None: lambda d: (f"[item:{d[0]}:{d[1]}]\n", 2)},
|
||||
0x18: {None: lambda d: (f"[image7:{d[0]}:{d[1]}:{d[2]}:{d[3]}:{d[4]}:{d[5]}:{d[6]}]\n", 7)},
|
||||
0x1A: {None: lambda d: (f"[func_1A:{d[0]}:{d[1]}:{d[2]}]", 3)},
|
||||
0x1B: {None: lambda d: (f"[func_1B:{d[0]}:{d[1]}]", 2)},
|
||||
0x1C: {None: lambda d: (f"[func_1C:{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: "[startAnim]",
|
||||
0x23: "[endAnim]",
|
||||
# 0x24: {0xFF: {0x05: {
|
||||
# 0x10: {0x98: {0xFF: {0x25: "Ⓐ"}}},
|
||||
# 0x11: {0x99: {0xFF: {0x25: "Ⓑ"}}},
|
||||
# 0x12: {0xA1: {0xFF: {0x25: "Ⓢ"}}},
|
||||
# 0x13: {
|
||||
# 0x9D: {0xFF: {0x25: "▲"}},
|
||||
# 0x9E: {0xFF: {0x25: "▼"}},
|
||||
# 0x9F: {0xFF: {0x25: "◀"}},
|
||||
# 0xA0: {0xFF: {0x25: "▶"}},
|
||||
# },
|
||||
# 0x14: {0x9C: {0xFF: {0x25: "Ⓩ"}}},
|
||||
# }}},
|
||||
0x24: "[pushColor]",
|
||||
0x25: "[popColor]",
|
||||
0x26: {
|
||||
0x00: "[shaky]",
|
||||
0x01: "[wavy]",
|
||||
0x03: {None: lambda d: (f"[noise fade={d[0]}]", 1)},
|
||||
0x05: {None: lambda d: (f"[faded-shaky fade={d[0]}]", 1)},
|
||||
0x07: {None: lambda d: (f"[fade={d[0]}]", 1)},
|
||||
0x0A: "[shout]",
|
||||
0x0B: "[whisper]",
|
||||
0x0C: "[scream]",
|
||||
0x0D: "[chortle]",
|
||||
0x0E: "[shadow]",
|
||||
0x00: "[startFX:jitter]",
|
||||
0x01: "[startFX:wavy]",
|
||||
0x03: {None: lambda d: (f"[startFX:fadedNoise:{d[0]}]", 1)},
|
||||
0x05: {None: lambda d: (f"[startFX:fadedJitter:{d[0]}]", 1)},
|
||||
0x07: {None: lambda d: (f"[startFX:faded:{d[0]}]", 1)},
|
||||
0x0A: "[startFX:shrinking]",
|
||||
0x0B: "[startFX:growing]",
|
||||
0x0C: "[startFX:sizeJitter]",
|
||||
0x0D: "[startFX:sizeWave]",
|
||||
0x0E: "[startFX:dropShadow]",
|
||||
},
|
||||
0x27: {
|
||||
0x00: "[/shaky]",
|
||||
0x01: "[/wavy]",
|
||||
0x03: "[/noise]",
|
||||
0x05: "[/faded-shaky]",
|
||||
0x07: "[/fade]",
|
||||
0x0A: "[/shout]",
|
||||
0x0B: "[/whisper]",
|
||||
0x0C: "[/scream]",
|
||||
0x0D: "[/chortle]",
|
||||
0x0E: "[/shadow]",
|
||||
0x00: "[endFX:jitter]",
|
||||
0x01: "[endFX:wavy]",
|
||||
0x03: "[endFX:fadedNoise]",
|
||||
0x05: "[endFX:fadedJitter]",
|
||||
0x07: "[endFX:faded]",
|
||||
0x0A: "[endFX:shrinking]",
|
||||
0x0B: "[endFX:growing]",
|
||||
0x0C: "[endFX:sizeJitter]",
|
||||
0x0D: "[endFX:sizeWave]",
|
||||
0x0E: "[endFX:dropShadow]",
|
||||
},
|
||||
0x28: {None: lambda d: (f"[var {d[0]}]", 1)},
|
||||
0x29: {None: lambda d: (f"[center {d[0]}]", 1)},
|
||||
0x2E: {None: lambda d: (f"[volume={d[0]}]", 1)},
|
||||
0x28: {None: lambda d: (f"[var:{d[0]}]", 1)},
|
||||
0x29: {None: lambda d: (f"[func_29:{d[0]}]", 1)},
|
||||
0x2B: "[func_2B]",
|
||||
0x2E: {None: lambda d: (f"[volume:{d[0]}]", 1)},
|
||||
0x2F: {
|
||||
1: "[sound=bowser]\n",
|
||||
2: "[sound=spirit]\n",
|
||||
None: lambda d: (f"[sound={d[0]}]\n", 1),
|
||||
#1: "[speechSound:bowser]\n",
|
||||
#2: "[speechSound:star]\n",
|
||||
None: lambda d: (f"[speechSound:{d[0]}]\n", 1),
|
||||
},
|
||||
None: lambda d: (f"[func 0x{d[0]:X}]", 1),
|
||||
#None: lambda d: (f"[func_{d[0]:02X}]", 1),
|
||||
},
|
||||
None: lambda d: (f"[raw 0x{d[0]:02X}]", 1),
|
||||
None: lambda d: (f"[raw:0x{d[0]:02X}]", 1),
|
||||
}
|
||||
|
||||
CHARSET_CREDITS = {
|
||||
@ -334,6 +356,7 @@ class N64SegPaperMarioMessages(N64Segment):
|
||||
def __init__(self, segment, next_segment, options):
|
||||
super().__init__(segment, next_segment, options)
|
||||
self.files = segment.get("files", []) if type(segment) is dict else []
|
||||
self.ids = segment["ids"]
|
||||
|
||||
def split(self, rom_bytes, base_path):
|
||||
data = rom_bytes[self.rom_start: self.rom_end]
|
||||
@ -349,6 +372,12 @@ class N64SegPaperMarioMessages(N64Segment):
|
||||
section_offsets.append(offset)
|
||||
pos += 4
|
||||
|
||||
msg_dir = Path(base_path, self.options["assets_dir"], self.name)
|
||||
msg_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# delete existing files
|
||||
self.delete_dir_childs(msg_dir)
|
||||
|
||||
for i, section_offset in enumerate(section_offsets):
|
||||
name = f"{i:02X}"
|
||||
if len(self.files) >= i:
|
||||
@ -367,15 +396,34 @@ class N64SegPaperMarioMessages(N64Segment):
|
||||
|
||||
self.log(f"Reading {len(msg_offsets)} messages in section {name} (0x{i:02X})")
|
||||
|
||||
path = Path(base_path, self.options["assets_dir"], self.name, name + ".msg")
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
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")
|
||||
self.f.write(f"[message section=0x{i:02X} index={j}]\n")
|
||||
|
||||
msg_name = None
|
||||
for section, index, goodname in self.ids:
|
||||
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[/message]\n")
|
||||
self.f.write("\n}\n")
|
||||
|
||||
@staticmethod
|
||||
def delete_dir_childs(path):
|
||||
for f in path.iterdir():
|
||||
if f.is_dir():
|
||||
N64SegPaperMarioMessages.delete_dir_childs(f)
|
||||
f.rmdir()
|
||||
else:
|
||||
f.unlink()
|
||||
|
||||
def get_ld_files(self):
|
||||
return [(self.options["assets_dir"], self.name, ".data", self.rom_start)]
|
||||
@ -419,10 +467,12 @@ class N64SegPaperMarioMessages(N64Segment):
|
||||
else:
|
||||
raise ValueError(value)
|
||||
|
||||
def write_markup(self, markup):
|
||||
self.f.write(markup)
|
||||
self.write_markup("[end]")
|
||||
|
||||
if markup == "[font=title]\n" or markup == "[font=subtitle]\n":
|
||||
def write_markup(self, markup):
|
||||
self.f.write(re.sub("\n", "\n\t", markup))
|
||||
|
||||
if markup == "[font:title]\n" or markup == "[font:subtitle]\n":
|
||||
self.root_charset = CHARSET_CREDITS
|
||||
elif markup == "[font=normal]":
|
||||
elif markup == "[font:normal]":
|
||||
self.root_charset = CHARSET
|
||||
|
Loading…
Reference in New Issue
Block a user