mirror of
https://github.com/pmret/papermario.git
synced 2024-11-09 12:32:38 +01:00
add message naming to splat.yaml
This commit is contained in:
parent
46d7a144e7
commit
87652e8abb
16
configure.py
16
configure.py
@ -315,9 +315,8 @@ async def main():
|
|||||||
description="ld_addrs_h $in")
|
description="ld_addrs_h $in")
|
||||||
n.newline()
|
n.newline()
|
||||||
|
|
||||||
# $msg_combine_headers
|
|
||||||
n.rule("msg_combine",
|
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")
|
description="combine messages")
|
||||||
n.rule("msg",
|
n.rule("msg",
|
||||||
command="$python tools/msg/parse_compile.py $in $out",
|
command="$python tools/msg/parse_compile.py $in $out",
|
||||||
@ -386,10 +385,11 @@ async def main():
|
|||||||
n.build(add_generated_header("$builddir/include/ld_addrs.h"), "ld_addrs_h", "$builddir/$target.ld")
|
n.build(add_generated_header("$builddir/include/ld_addrs.h"), "ld_addrs_h", "$builddir/$target.ld")
|
||||||
|
|
||||||
# messages
|
# messages
|
||||||
msg_files = []
|
msg_files = set()
|
||||||
for d in ASSET_DIRS:
|
for d in ASSET_DIRS:
|
||||||
msg_files.extend(glob(d + "/**/*.msg", recursive=True))
|
for f in glob(d + "/**/*.msg", recursive=True):
|
||||||
msg_files = list(set(msg_files)) # dedup
|
msg_files.add(find_asset(f[len(d)+1:]))
|
||||||
|
msg_files = list(msg_files)
|
||||||
for msg_file in msg_files:
|
for msg_file in msg_files:
|
||||||
n.build(
|
n.build(
|
||||||
f"$builddir/{msg_file.split('/', 1)[1]}.bin",
|
f"$builddir/{msg_file.split('/', 1)[1]}.bin",
|
||||||
@ -397,15 +397,13 @@ async def main():
|
|||||||
msg_file,
|
msg_file,
|
||||||
implicit="tools/msg/parse_compile.py",
|
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_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]
|
msg_bins = [f"$builddir/{msg_file.split('/', 1)[1]}.bin" for msg_file in msg_files]
|
||||||
n.build(
|
n.build(
|
||||||
"$builddir/msg.bin",
|
["$builddir/msg.bin", add_generated_header(f"$builddir/include/message_ids.h")],
|
||||||
"msg_combine",
|
"msg_combine",
|
||||||
msg_bins,
|
msg_bins,
|
||||||
implicit="tools/msg/combine.py",
|
implicit="tools/msg/combine.py",
|
||||||
implicit_outputs=msg_headers,
|
|
||||||
variables={ "msg_combine_headers": msg_headers }
|
|
||||||
)
|
)
|
||||||
n.build("$builddir/msg.o", "bin", "$builddir/msg.bin")
|
n.build("$builddir/msg.o", "bin", "$builddir/msg.bin")
|
||||||
|
|
||||||
|
@ -5,12 +5,7 @@
|
|||||||
|
|
||||||
typedef s32 MessageID;
|
typedef s32 MessageID;
|
||||||
|
|
||||||
|
// Prefer editing splat.yaml's msg ids section than using this directly!
|
||||||
#define MESSAGE_ID(section, index) (((section << 0x10) + index))
|
#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)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "kmr_03.h"
|
#include "kmr_03.h"
|
||||||
|
#include "message_ids.h"
|
||||||
#include "../../partners.h"
|
#include "../../partners.h"
|
||||||
|
|
||||||
Script N(Main);
|
Script N(Main);
|
||||||
@ -61,7 +62,7 @@ MapConfig N(config) = {
|
|||||||
.entryList = N(entryList),
|
.entryList = N(entryList),
|
||||||
.entryCount = ENTRY_COUNT(N(entryList)),
|
.entryCount = ENTRY_COUNT(N(entryList)),
|
||||||
.background = &gBackgroundImage,
|
.background = &gBackgroundImage,
|
||||||
.tattle = MessageID_TATTLE_KMR_03,
|
.tattle = MSG_kmr_03_tattle,
|
||||||
};
|
};
|
||||||
|
|
||||||
Script N(Script_802406C0) = SCRIPT({
|
Script N(Script_802406C0) = SCRIPT({
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "kmr_12.h"
|
#include "kmr_12.h"
|
||||||
|
#include "message_ids.h"
|
||||||
#include "sprite/npc/goomba.h"
|
#include "sprite/npc/goomba.h"
|
||||||
|
|
||||||
Script N(ExitWest) = EXIT_WALK_SCRIPT(60, 0, "kmr_07", 1);
|
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!"
|
// "Eat a Mushroom to regain your energy!"
|
||||||
suspend group 1;
|
suspend group 1;
|
||||||
DisablePlayerInput(TRUE);
|
DisablePlayerInput(TRUE);
|
||||||
ShowMessageAtScreenPos(MessageID_SIGN_MUSHROOM_GOOMBA_TRAP, 160, 40);
|
ShowMessageAtScreenPos(MSG_kmr_12_sign_trap, 160, 40);
|
||||||
resume group 1;
|
resume group 1;
|
||||||
|
|
||||||
SI_FLAG(0) = FALSE;
|
SI_FLAG(0) = FALSE;
|
||||||
@ -201,7 +202,7 @@ Script N(ReadEastSign) = SCRIPT({
|
|||||||
|
|
||||||
func_802D5830(1);
|
func_802D5830(1);
|
||||||
DisablePlayerInput(1);
|
DisablePlayerInput(1);
|
||||||
ShowMessageAtScreenPos(MessageID_SIGN_GOOMBA_KINGS_FORTRESS_AHEAD, 160, 40);
|
ShowMessageAtScreenPos(MSG_kmr_12_sign_to_fortress, 160, 40);
|
||||||
DisablePlayerInput(0);
|
DisablePlayerInput(0);
|
||||||
func_802D5830(0);
|
func_802D5830(0);
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "kmr_12.h"
|
#include "kmr_12.h"
|
||||||
|
#include "message_ids.h"
|
||||||
|
|
||||||
Vec4f N(entryList)[] = {
|
Vec4f N(entryList)[] = {
|
||||||
{ -126.0f, 0.0f, 12.0f, 90.0f }, // west, towards Red/Blue Goomba miniboss room
|
{ -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),
|
.entryList = N(entryList),
|
||||||
.entryCount = ENTRY_COUNT(N(entryList)),
|
.entryCount = ENTRY_COUNT(N(entryList)),
|
||||||
.background = &gBackgroundImage,
|
.background = &gBackgroundImage,
|
||||||
.tattle = MessageID_TATTLE_KMR_12,
|
.tattle = MSG_kmr_12_tattle,
|
||||||
};
|
};
|
||||||
|
|
||||||
Script N(PlayMusic) = SCRIPT({
|
Script N(PlayMusic) = SCRIPT({
|
||||||
|
@ -16,30 +16,38 @@ class Message:
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(argv) < 3:
|
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)
|
exit(1)
|
||||||
|
|
||||||
_, outfile, *infiles = argv
|
_, outfile, header_file, *infiles = argv
|
||||||
|
|
||||||
messages = []
|
messages = []
|
||||||
header_files = []
|
#header_files = []
|
||||||
|
|
||||||
for i, infile in enumerate(infiles):
|
for i, infile in enumerate(infiles):
|
||||||
if infile == "--headers":
|
# if infile == "--headers":
|
||||||
header_files = infiles[i+1:]
|
# header_files = infiles[i+1:]
|
||||||
break
|
# break
|
||||||
|
|
||||||
with open(infile, "rb") as f:
|
with open(infile, "rb") as f:
|
||||||
messages.extend(Message(msg, i) for msg in msgpack.unpack(f))
|
messages.extend(Message(msg, i) for msg in msgpack.unpack(f))
|
||||||
|
|
||||||
with open(outfile, "wb") as f:
|
with open(outfile, "wb") as f:
|
||||||
# sectioned+indexed, followed by just sectioned, followed by just indexed, followed by named (unsectioned & unindexed)
|
# 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()
|
names = set()
|
||||||
|
|
||||||
sections = [] * 0x2E
|
sections = []
|
||||||
messages_by_file = {}
|
#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:
|
for message in messages:
|
||||||
if message.section is None:
|
if message.section is None:
|
||||||
@ -47,35 +55,45 @@ if __name__ == "__main__":
|
|||||||
for section_idx, section in enumerate(sections):
|
for section_idx, section in enumerate(sections):
|
||||||
if len(section) < 0xFFF:
|
if len(section) < 0xFFF:
|
||||||
break
|
break
|
||||||
|
message.section = section_idx
|
||||||
else:
|
else:
|
||||||
section_idx = message.section
|
section_idx = message.section
|
||||||
while len(sections) <= section_idx:
|
while len(sections) <= section_idx:
|
||||||
sections.append([])
|
sections.append({})
|
||||||
section = sections[section_idx]
|
section = sections[section_idx]
|
||||||
|
|
||||||
message.index = 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:
|
||||||
if message.name in names:
|
if message.name in names:
|
||||||
print(f"warning: multiple messages with name '{message.name}'")
|
print(f"error: multiple messages with name '{message.name}'")
|
||||||
|
exit(1)
|
||||||
else:
|
else:
|
||||||
names.add(message.name)
|
names.add(message.name)
|
||||||
|
|
||||||
if message.header_file_index in messages_by_file:
|
# if message.header_file_index in messages_by_file:
|
||||||
messages_by_file[message.header_file_index].add(message)
|
# messages_by_file[message.header_file_index].add(message)
|
||||||
else:
|
# else:
|
||||||
messages_by_file[message.header_file_index] = set([message])
|
# messages_by_file[message.header_file_index] = set([message])
|
||||||
|
|
||||||
section.append(message.bytes)
|
if message.index in section:
|
||||||
|
print(f"error: multiple messages allocated to id {section_idx:02X}:{message.index:03X}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
section[message.index] = message
|
||||||
|
|
||||||
f.seek((len(sections) + 1) * 4) # skip past table of contents
|
f.seek((len(sections) + 1) * 4) # skip past table of contents
|
||||||
|
|
||||||
section_offsets = []
|
section_offsets = []
|
||||||
for section in sections:
|
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 = []
|
message_offsets = []
|
||||||
for message in section:
|
for message in section:
|
||||||
message_offsets.append(f.tell())
|
message_offsets.append(f.tell())
|
||||||
f.write(message)
|
f.write(message.bytes)
|
||||||
|
|
||||||
section_offset = f.tell()
|
section_offset = f.tell()
|
||||||
section_offsets.append(section_offset)
|
section_offsets.append(section_offset)
|
||||||
@ -92,34 +110,17 @@ if __name__ == "__main__":
|
|||||||
f.write(offset.to_bytes(4, byteorder="big"))
|
f.write(offset.to_bytes(4, byteorder="big"))
|
||||||
f.write(b'\0\0\0\0')
|
f.write(b'\0\0\0\0')
|
||||||
|
|
||||||
for i, header_file in enumerate(header_files):
|
with open(header_file, "w") as f:
|
||||||
messages = messages_by_file.get(i, [])
|
f.write(
|
||||||
|
f"#ifndef _MESSAGE_IDS_H_\n"
|
||||||
h = (
|
f"#define _MESSAGE_IDS_H_\n"
|
||||||
f"#ifndef _MESSAGE_IDS_{i}_H_\n"
|
|
||||||
f"#define _MESSAGE_IDS_{i}_H_\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
'#include "messages.h"\n'
|
'#include "messages.h"\n'
|
||||||
"\n"
|
"\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
for message in messages:
|
for message in messages:
|
||||||
h += f"#define MSG_{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"
|
f.write("\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)
|
|
||||||
|
@ -9467,7 +9467,7 @@ segments:
|
|||||||
- 20_party_letters_luigi_diary
|
- 20_party_letters_luigi_diary
|
||||||
- 21_advice_fortunes
|
- 21_advice_fortunes
|
||||||
- 22_treasure_fortunes
|
- 22_treasure_fortunes
|
||||||
- 23_item_descriptions # TODO: difference between 23,24,25
|
- 23_item_descriptions # TODO: difference between 23,24,25 (shops, menus, pickups?)
|
||||||
- 24_item_descriptions
|
- 24_item_descriptions
|
||||||
- 25_item_descriptions
|
- 25_item_descriptions
|
||||||
- 26_item_names
|
- 26_item_names
|
||||||
@ -9479,6 +9479,11 @@ segments:
|
|||||||
- 2C_quiz_questions
|
- 2C_quiz_questions
|
||||||
- 2D_quiz_options
|
- 2D_quiz_options
|
||||||
- 2E_credits
|
- 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(?)
|
- [0x1C84D30, bin] # junk(?)
|
||||||
- [0x1E00000, bin] # junk (player sprite data; can be zeroed out with no effect)
|
- [0x1E00000, bin] # junk (player sprite data; can be zeroed out with no effect)
|
||||||
- [0x1E40000, PaperMarioMapFS]
|
- [0x1E40000, PaperMarioMapFS]
|
||||||
|
@ -356,6 +356,7 @@ class N64SegPaperMarioMessages(N64Segment):
|
|||||||
def __init__(self, segment, next_segment, options):
|
def __init__(self, segment, next_segment, options):
|
||||||
super().__init__(segment, next_segment, options)
|
super().__init__(segment, next_segment, options)
|
||||||
self.files = segment.get("files", []) if type(segment) is dict else []
|
self.files = segment.get("files", []) if type(segment) is dict else []
|
||||||
|
self.ids = segment["ids"]
|
||||||
|
|
||||||
def split(self, rom_bytes, base_path):
|
def split(self, rom_bytes, base_path):
|
||||||
data = rom_bytes[self.rom_start: self.rom_end]
|
data = rom_bytes[self.rom_start: self.rom_end]
|
||||||
@ -401,7 +402,17 @@ class N64SegPaperMarioMessages(N64Segment):
|
|||||||
for j, msg_offset in enumerate(msg_offsets):
|
for j, msg_offset in enumerate(msg_offsets):
|
||||||
if j != 0:
|
if j != 0:
|
||||||
self.f.write("\n")
|
self.f.write("\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 ")
|
self.f.write(f"#message:{i:02X}:{j:03X} {{\n ")
|
||||||
|
else:
|
||||||
|
self.f.write(f"#message:{i:02X}:({msg_name}) {{\n ")
|
||||||
self.write_message_markup(data[msg_offset:])
|
self.write_message_markup(data[msg_offset:])
|
||||||
self.f.write("\n}\n")
|
self.f.write("\n}\n")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user