11 line_number_mapping
= {}
13 def raise_error(filename
, lineindex
, msg
):
14 raise SyntaxError("Error in " + filename
+ ":" + str(line_number_mapping
[lineindex
] + 1) + ": " + msg
)
16 def parse_struct(filename
, lines
, lineindex
, name
):
17 global items
, order_mapping
19 if lineindex
+ 9 >= len(lines
):
20 raise_error(filename
, lineindex
, "struct Animation must be 11 lines")
21 v1
= int(lines
[lineindex
+ 0].rstrip(","), 0)
22 v2
= int(lines
[lineindex
+ 1].rstrip(","), 0)
23 v3
= int(lines
[lineindex
+ 2].rstrip(","), 0)
24 v4
= int(lines
[lineindex
+ 3].rstrip(","), 0)
25 v5
= int(lines
[lineindex
+ 4].rstrip(","), 0)
26 values
= lines
[lineindex
+ 6].rstrip(",")
27 indices
= lines
[lineindex
+ 7].rstrip(",")
28 items
.append(("header", name
, (v1
, v2
, v3
, v4
, v5
, values
, indices
)))
29 if lines
[lineindex
+ 9] != "};":
30 raise_error(filename
, lineindex
+ 9, "Expected \"};\" but got " + lines
[lineindex
+ 9])
31 order_mapping
[name
] = len(items
)
35 def parse_array(filename
, lines
, lineindex
, name
, is_indices
):
36 global items
, len_mapping
, order_mapping
39 while lineindex
< len(lines
) and lines
[lineindex
] != "};":
40 line
= lines
[lineindex
].rstrip(",")
42 values
.extend(line
.split(","))
44 if lineindex
>= len(lines
):
45 raise_error(filename
, lineindex
, "Expected \"};\" but reached end of file")
46 items
.append(("array", name
, (is_indices
, values
)))
47 len_mapping
[name
] = len(values
)
48 order_mapping
[name
] = len(items
)
52 def parse_file(filename
, lines
):
55 while lineindex
< len(lines
):
56 line
= lines
[lineindex
]
57 for prefix
in ["static ", "const "]:
58 if line
.startswith(prefix
):
59 line
= line
[len(prefix
):]
60 lines
[lineindex
] = line
62 is_struct
= line
.startswith("struct Animation ") and line
.endswith("[] = {")
63 is_indices
= line
.startswith("u16 ") and line
.endswith("[] = {")
64 is_values
= line
.startswith("s16 ") and line
.endswith("[] = {")
65 if not is_struct
and not is_indices
and not is_values
:
66 raise_error(filename
, lineindex
, "\"" + line
+ "\" does not follow the pattern \"static const struct Animation anim_x[] = {\", \"static const u16 anim_x_indices[] = {\" or \"static const s16 anim_x_values[] = {\"")
69 name
= lines
[lineindex
][len("struct Animation "):-6]
70 lineindex
= parse_struct(filename
, lines
, lineindex
, name
)
73 name
= lines
[lineindex
][len("s16 "):-6]
74 lineindex
= parse_array(filename
, lines
, lineindex
, name
, is_indices
)
77 files
= os
.listdir("assets/anims")
80 for filename
in files
:
81 if filename
.endswith(".inc.c"):
83 with
open("assets/anims/" + filename
) as f
:
84 for i
, line
in enumerate(f
):
85 line
= re
.sub(r
"/\*.*?\*/", "", line
)
87 line_number_mapping
[-1] = i
88 raise_error(filename
, -1, "Multiline comments are not supported")
89 line
= line
.split("//", 1)[0].strip()
91 line_number_mapping
[len(lines
)] = i
94 parse_file(filename
, lines
)
96 structdef
= ["u32 numEntries;", "const struct Animation *addrPlaceholder;", "struct OffsetSizePair entries[" + str(num_headers
) + "];"]
97 structobj
= [str(num_headers
) + ",", "NULL,","{"]
100 type, name
, obj
= item
102 v1
, v2
, v3
, v4
, v5
, values
, indices
= obj
103 if order_mapping
[indices
] < order_mapping
[name
]:
104 raise SyntaxError("Error: Animation struct must be written before indices array for " + name
)
105 if order_mapping
[values
] < order_mapping
[indices
]:
106 raise SyntaxError("Error: values array must be written after indices array for " + name
)
107 values_num_values
= len_mapping
[values
]
108 offset_to_struct
= "offsetof(struct MarioAnimsObj, " + name
+ ")"
109 offset_to_end
= "offsetof(struct MarioAnimsObj, " + values
+ ") + sizeof(gMarioAnims." + values
+ ")"
110 structobj
.append("{" + offset_to_struct
+ ", " + offset_to_end
+ " - " + offset_to_struct
+ "},")
111 structobj
.append("},")
114 type, name
, obj
= item
116 v1
, v2
, v3
, v4
, v5
, values
, indices
= obj
117 indices_len
= len_mapping
[indices
] // 6 - 1
118 values_num_values
= len_mapping
[values
]
119 offset_to_struct
= "offsetof(struct MarioAnimsObj, " + name
+ ")"
120 offset_to_end
= "offsetof(struct MarioAnimsObj, " + values
+ ") + sizeof(gMarioAnims." + values
+ ")"
121 structdef
.append("struct Animation " + name
+ ";")
122 structobj
.append("{" + ", ".join([
129 "(const s16 *)(offsetof(struct MarioAnimsObj, " + values
+ ") - " + offset_to_struct
+ ")",
130 "(const u16 *)(offsetof(struct MarioAnimsObj, " + indices
+ ") - " + offset_to_struct
+ ")",
131 offset_to_end
+ " - " + offset_to_struct
134 is_indices
, arr
= obj
135 type = "u16" if is_indices
else "s16"
136 structdef
.append("{} {}[{}];".format(type, name
, len(arr
)))
137 structobj
.append("{" + ",".join(arr
) + "},")
139 print("#include \"types.h\"")
140 print("#include <stddef.h>")
143 print("const struct MarioAnimsObj {")
146 print("} gMarioAnims = {")
151 except Exception as e
:
152 note
= "NOTE! The mario animation C files are not processed by a normal C compiler, but by the script in tools/mario_anims_converter.py. The format is much more strict than normal C, so please follow the syntax of existing files.\n"
156 print(note
, file=sys
.stderr
)
157 traceback
.print_exc()