legacy-puyo-tools 0.0.1__py3-none-any.whl → 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- legacy_puyo_tools/cli.py +114 -134
- legacy_puyo_tools/exceptions.py +4 -0
- legacy_puyo_tools/fpd.py +29 -35
- legacy_puyo_tools/mtx.py +5 -12
- legacy_puyo_tools-0.1.0.dist-info/METADATA +119 -0
- legacy_puyo_tools-0.1.0.dist-info/RECORD +11 -0
- {legacy_puyo_tools-0.0.1.dist-info → legacy_puyo_tools-0.1.0.dist-info}/licenses/LICENSE +1 -1
- legacy_puyo_tools-0.0.1.dist-info/METADATA +0 -34
- legacy_puyo_tools-0.0.1.dist-info/RECORD +0 -11
- {legacy_puyo_tools-0.0.1.dist-info → legacy_puyo_tools-0.1.0.dist-info}/WHEEL +0 -0
- {legacy_puyo_tools-0.0.1.dist-info → legacy_puyo_tools-0.1.0.dist-info}/entry_points.txt +0 -0
legacy_puyo_tools/cli.py
CHANGED
@@ -1,176 +1,156 @@
|
|
1
|
-
"""A commandline
|
1
|
+
"""A commandline interface for the conversion tools.
|
2
2
|
|
3
3
|
SPDX-FileCopyrightText: 2025 Samuel Wu
|
4
4
|
SPDX-License-Identifier: MIT
|
5
5
|
"""
|
6
6
|
|
7
|
-
from __future__ import annotations
|
8
|
-
|
9
|
-
import argparse
|
10
|
-
import sys
|
11
7
|
from codecs import BOM_UTF16_LE
|
12
|
-
from collections.abc import Callable
|
13
|
-
from importlib import metadata
|
14
8
|
from pathlib import Path
|
15
9
|
from typing import BinaryIO
|
16
10
|
|
17
|
-
|
11
|
+
import cloup
|
12
|
+
from cloup import option, option_group
|
13
|
+
from cloup.constraints import require_one
|
18
14
|
|
19
|
-
from legacy_puyo_tools.exceptions import FileFormatError
|
15
|
+
from legacy_puyo_tools.exceptions import ArgumentError, FileFormatError
|
20
16
|
from legacy_puyo_tools.fpd import Fpd
|
21
17
|
from legacy_puyo_tools.mtx import Mtx
|
22
18
|
|
19
|
+
output_option = option(
|
20
|
+
"--output",
|
21
|
+
"-o",
|
22
|
+
help="Output file. Defaults to an appropriate filename and extension.",
|
23
|
+
type=cloup.File("wb"),
|
24
|
+
)
|
25
|
+
|
26
|
+
mtx_options = option_group(
|
27
|
+
"Character table options",
|
28
|
+
option(
|
29
|
+
"--fpd",
|
30
|
+
help="Use a fpd file as the character table.",
|
31
|
+
type=cloup.Path(exists=True, dir_okay=False, path_type=Path),
|
32
|
+
),
|
33
|
+
option(
|
34
|
+
"--unicode",
|
35
|
+
help="Use a unicode text file as the character table.",
|
36
|
+
type=cloup.Path(exists=True, dir_okay=False, path_type=Path),
|
37
|
+
),
|
38
|
+
constraint=require_one.rephrased(
|
39
|
+
"exactly 1 character table required for mtx files",
|
40
|
+
"exactly 1 character table must be specified",
|
41
|
+
),
|
42
|
+
)
|
43
|
+
|
44
|
+
|
45
|
+
@cloup.group()
|
46
|
+
@cloup.version_option()
|
47
|
+
def main() -> None:
|
48
|
+
"""A conversion tool for files used by older Puyo games."""
|
49
|
+
|
23
50
|
|
24
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
input: BinaryIO
|
28
|
-
output: BinaryIO
|
29
|
-
unicode: BinaryIO
|
30
|
-
fpd: BinaryIO
|
31
|
-
version: bool
|
51
|
+
@main.group()
|
52
|
+
def create() -> None:
|
53
|
+
"""Create files to used by older Puyo games."""
|
32
54
|
|
33
55
|
|
34
|
-
|
35
|
-
|
56
|
+
@create.command(name="fpd")
|
57
|
+
@cloup.argument(
|
58
|
+
"input_file",
|
59
|
+
help="Unicode text file encoded in UTF-16 little-endian.",
|
60
|
+
type=cloup.File("rb"),
|
61
|
+
)
|
62
|
+
@output_option
|
63
|
+
def create_fpd(input_file: BinaryIO, output: BinaryIO | None) -> None:
|
64
|
+
"""Create a fpd file from a unicode text file."""
|
65
|
+
if input_file.read(2) != BOM_UTF16_LE:
|
36
66
|
raise FileFormatError(
|
37
|
-
f"{
|
38
|
-
"file."
|
67
|
+
f"{input_file.name} is not a UTF-16 little-endian encoded text file."
|
39
68
|
)
|
40
69
|
|
41
|
-
if
|
42
|
-
Fpd.read_unicode(
|
70
|
+
if output:
|
71
|
+
Fpd.read_unicode(input_file).write_fpd(output)
|
43
72
|
return
|
44
73
|
|
45
|
-
path = Path(
|
74
|
+
path = Path(input_file.name).with_suffix("")
|
46
75
|
|
47
76
|
if path.suffix != ".fpd":
|
48
77
|
path = path.with_suffix(".fpd")
|
49
78
|
|
50
|
-
Fpd.read_unicode(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
79
|
+
Fpd.read_unicode(input_file).write_fpd_to_path(path)
|
80
|
+
|
81
|
+
|
82
|
+
@create.command(name="mtx", show_constraints=True)
|
83
|
+
@cloup.argument(
|
84
|
+
"input_file",
|
85
|
+
help="XML file that contains markup text or dialog.",
|
86
|
+
type=cloup.File("rb"),
|
87
|
+
)
|
88
|
+
@output_option
|
89
|
+
@mtx_options
|
90
|
+
def create_mtx(
|
91
|
+
input_file: BinaryIO, output: BinaryIO, fpd: Path | None, unicode: Path | None
|
92
|
+
) -> None:
|
93
|
+
"""Create a mtx file from a XML file."""
|
94
|
+
raise NotImplementedError("Creating MTX files is currently not implemented yet.")
|
95
|
+
|
96
|
+
|
97
|
+
@main.group()
|
98
|
+
def convert() -> None:
|
99
|
+
"""Convert files used by older Puyo games to an editable format."""
|
100
|
+
|
101
|
+
|
102
|
+
@convert.command(name="fpd")
|
103
|
+
@cloup.argument(
|
104
|
+
"input_file", help="Fpd file containing character data.", type=cloup.File("rb")
|
105
|
+
)
|
106
|
+
@output_option
|
107
|
+
def convert_fpd(input_file: BinaryIO, output_file: BinaryIO | None) -> None:
|
108
|
+
"""Convert a fpd file to a UTF-16 little-endian unicode text file."""
|
109
|
+
if output_file:
|
110
|
+
output_file.write(BOM_UTF16_LE)
|
111
|
+
Fpd.read_fpd(input_file).write_fpd(output_file)
|
61
112
|
return
|
62
113
|
|
63
|
-
path = Path(
|
114
|
+
path = Path(input_file.name).with_suffix("")
|
64
115
|
|
65
116
|
if path.suffix != ".fpd":
|
66
117
|
path = path.with_suffix(".fpd")
|
67
118
|
|
68
|
-
Fpd.read_fpd(
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
119
|
+
Fpd.read_fpd(input_file).write_unicode_to_path(path)
|
120
|
+
|
121
|
+
|
122
|
+
@convert.command(name="mtx", show_constraints=True)
|
123
|
+
@cloup.argument(
|
124
|
+
"input_file", help="Mtx file containing Manzai text.", type=cloup.File("rb")
|
125
|
+
)
|
126
|
+
@output_option
|
127
|
+
@mtx_options
|
128
|
+
def convert_mtx(
|
129
|
+
input_file: BinaryIO,
|
130
|
+
output: BinaryIO | None,
|
131
|
+
fpd: Path | None,
|
132
|
+
unicode: Path | None,
|
133
|
+
) -> None:
|
134
|
+
"""Convert a mtx file to a XML file."""
|
135
|
+
if fpd:
|
136
|
+
fpd_data = Fpd.read_fpd_from_path(fpd)
|
137
|
+
elif unicode:
|
138
|
+
fpd_data = Fpd.read_unicode_from_path(unicode)
|
74
139
|
else:
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
"file."
|
79
|
-
)
|
80
|
-
|
81
|
-
fpd_data = Fpd.read_unicode(args.unicode)
|
140
|
+
raise ArgumentError(
|
141
|
+
"You must specify a character table using --fpd or --unicode."
|
142
|
+
)
|
82
143
|
|
83
|
-
if
|
84
|
-
Mtx.read_mtx(
|
144
|
+
if output:
|
145
|
+
Mtx.read_mtx(input_file).write_xml(output, fpd_data)
|
85
146
|
return
|
86
147
|
|
87
|
-
path = Path(
|
148
|
+
path = Path(input_file.name).with_suffix("")
|
88
149
|
|
89
150
|
if path.suffix != ".xml":
|
90
151
|
path = path.with_suffix(".xml")
|
91
152
|
|
92
|
-
Mtx.read_mtx(
|
93
|
-
|
94
|
-
|
95
|
-
def _create_parsers(main_parser: argparse.ArgumentParser) -> None:
|
96
|
-
shared_options = argparse.ArgumentParser(add_help=False)
|
97
|
-
shared_options.add_argument(
|
98
|
-
"input", type=argparse.FileType("rb"), help="input file"
|
99
|
-
)
|
100
|
-
shared_options.add_argument(
|
101
|
-
"-o", "--output", type=argparse.FileType("wb"), help="output file"
|
102
|
-
)
|
103
|
-
|
104
|
-
mtx_options = argparse.ArgumentParser(
|
105
|
-
add_help=False, parents=[shared_options]
|
106
|
-
)
|
107
|
-
mtx_options_group = mtx_options.add_mutually_exclusive_group(required=True)
|
108
|
-
mtx_options_group.add_argument(
|
109
|
-
"--fpd", type=argparse.FileType("rb"), help="fpd file"
|
110
|
-
)
|
111
|
-
mtx_options_group.add_argument(
|
112
|
-
"--unicode", type=argparse.FileType("rb"), help="unicode text file"
|
113
|
-
)
|
114
|
-
|
115
|
-
sub_parser = main_parser.add_subparsers()
|
116
|
-
|
117
|
-
create_parser = sub_parser.add_parser("create")
|
118
|
-
create_sub_parser = create_parser.add_subparsers(required=True)
|
119
|
-
|
120
|
-
create_fpd_parser = create_sub_parser.add_parser(
|
121
|
-
"fpd",
|
122
|
-
help="create a fpd file from a unicode text file",
|
123
|
-
parents=[shared_options],
|
124
|
-
)
|
125
|
-
create_fpd_parser.set_defaults(func=_create_fpd)
|
126
|
-
|
127
|
-
create_mtx_parser = create_sub_parser.add_parser(
|
128
|
-
"mtx", help="create a mtx file from a XML file", parents=[mtx_options]
|
129
|
-
)
|
130
|
-
create_mtx_parser.set_defaults(func=_create_mtx)
|
131
|
-
|
132
|
-
convert_parser = sub_parser.add_parser("convert")
|
133
|
-
convert_sub_parser = convert_parser.add_subparsers(required=True)
|
134
|
-
|
135
|
-
convert_fpd_parser = convert_sub_parser.add_parser(
|
136
|
-
"fpd",
|
137
|
-
help="convert a fpd file to a unicode file",
|
138
|
-
parents=[shared_options],
|
139
|
-
)
|
140
|
-
convert_fpd_parser.set_defaults(func=_convert_fpd)
|
141
|
-
|
142
|
-
convert_mtx_parser = convert_sub_parser.add_parser(
|
143
|
-
"mtx", help="convert a mtx file to XML file", parents=[mtx_options]
|
144
|
-
)
|
145
|
-
convert_mtx_parser.set_defaults(func=_convert_mtx)
|
146
|
-
|
147
|
-
|
148
|
-
def main() -> None:
|
149
|
-
"""Entry point for the commandline application."""
|
150
|
-
main_parser = argparse.ArgumentParser(
|
151
|
-
description="A conversion tool for files used by older Puyo games."
|
152
|
-
)
|
153
|
-
main_parser.add_argument(
|
154
|
-
"-v", "--version", help="show version", action="store_true"
|
155
|
-
)
|
156
|
-
|
157
|
-
_create_parsers(main_parser)
|
158
|
-
|
159
|
-
args = main_parser.parse_args(namespace=_CliNamespace)
|
160
|
-
|
161
|
-
if args.version is True:
|
162
|
-
package_name = "legacy-puyo-tools"
|
163
|
-
version = metadata.version(package_name)
|
164
|
-
|
165
|
-
print(f"{package_name} {version}")
|
166
|
-
|
167
|
-
sys.exit(0)
|
168
|
-
|
169
|
-
if not hasattr(args, "func"):
|
170
|
-
main_parser.print_help(sys.stderr)
|
171
|
-
sys.exit(1)
|
172
|
-
|
173
|
-
args.func(args)
|
153
|
+
Mtx.read_mtx(input_file).write_xml_to_file(path, fpd_data)
|
174
154
|
|
175
155
|
|
176
156
|
if __name__ == "__main__":
|
legacy_puyo_tools/exceptions.py
CHANGED
legacy_puyo_tools/fpd.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
"""
|
1
|
+
"""Fpd conversion tool for older Puyo games.
|
2
2
|
|
3
|
-
This module supports the encoding and decoding of the fpd format used by
|
4
|
-
|
3
|
+
This module supports the encoding and decoding of the fpd format used by Puyo Puyo! 15th
|
4
|
+
Anniversary and Puyo Puyo 7.
|
5
5
|
|
6
6
|
SPDX-FileCopyrightText: 2025 Samuel Wu
|
7
7
|
SPDX-License-Identifier: MIT
|
@@ -26,16 +26,16 @@ WIDTH_ENTRY_OFFSET = 2
|
|
26
26
|
class FpdCharacter:
|
27
27
|
"""A fpd character entry.
|
28
28
|
|
29
|
-
A fpd character is a binary entry that is 3 bytes long and formatted
|
30
|
-
|
31
|
-
|
29
|
+
A fpd character is a binary entry that is 3 bytes long and formatted as follows:
|
30
|
+
`XX XX YY`. Where `XX XX` is the character encoded in UTF-16 little-endian and `YY`
|
31
|
+
is the width of the character.
|
32
32
|
|
33
33
|
Attributes:
|
34
34
|
code_point:
|
35
35
|
A string that stores a single character.
|
36
36
|
width:
|
37
|
-
How wide should the character be, only used in the Nintendo
|
38
|
-
|
37
|
+
How wide should the character be, only used in the Nintendo DS versions of
|
38
|
+
the games.
|
39
39
|
"""
|
40
40
|
|
41
41
|
code_point: str
|
@@ -71,16 +71,13 @@ class FpdCharacter:
|
|
71
71
|
|
72
72
|
Raises:
|
73
73
|
FormatError:
|
74
|
-
The entry given does not conform to the fpd character
|
75
|
-
format.
|
74
|
+
The entry given does not conform to the fpd character format.
|
76
75
|
|
77
76
|
Returns:
|
78
77
|
A fpd character entry containing its code point and width.
|
79
78
|
"""
|
80
79
|
if len(fpd_entry) != FPD_ENTRY_LENGTH:
|
81
|
-
raise FormatError(
|
82
|
-
f"{fpd_entry} does not matches size {FPD_ENTRY_LENGTH}"
|
83
|
-
)
|
80
|
+
raise FormatError(f"{fpd_entry} does not matches size {FPD_ENTRY_LENGTH}")
|
84
81
|
|
85
82
|
return cls(fpd_entry[:UTF16_LENGTH], fpd_entry[WIDTH_ENTRY_OFFSET])
|
86
83
|
|
@@ -89,10 +86,10 @@ class FpdCharacter:
|
|
89
86
|
class Fpd:
|
90
87
|
"""A fpd character table.
|
91
88
|
|
92
|
-
The fpd stores character table in which each entry is placed right
|
93
|
-
|
94
|
-
|
95
|
-
|
89
|
+
The fpd stores character table in which each entry is placed right next to each
|
90
|
+
other and the indices is offset by multiples of `0x03`. I.e. The 1st character is at
|
91
|
+
index `0x00`, the 2nd character is at index `0x03`, the 3rd character is at index
|
92
|
+
`0x06`, etc.
|
96
93
|
|
97
94
|
Attributes:
|
98
95
|
entries:
|
@@ -119,13 +116,12 @@ class Fpd:
|
|
119
116
|
|
120
117
|
Args:
|
121
118
|
path:
|
122
|
-
A path to a fpd encoded file that contains a fpd
|
123
|
-
character table.
|
119
|
+
A path to a fpd encoded file that contains a fpd character table.
|
124
120
|
|
125
121
|
Raises:
|
126
122
|
FileFormatError:
|
127
|
-
The fpd file contain a entry that does not conform
|
128
|
-
|
123
|
+
The fpd file contain a entry that does not conform to the fpd character
|
124
|
+
format.
|
129
125
|
|
130
126
|
Returns:
|
131
127
|
A fpd character table.
|
@@ -155,8 +151,7 @@ class Fpd:
|
|
155
151
|
|
156
152
|
Args:
|
157
153
|
data:
|
158
|
-
A fpd encoded stream that contains a fpd character
|
159
|
-
table.
|
154
|
+
A fpd encoded stream that contains a fpd character table.
|
160
155
|
|
161
156
|
Returns:
|
162
157
|
A fpd character table.
|
@@ -199,25 +194,26 @@ class Fpd:
|
|
199
194
|
|
200
195
|
@classmethod
|
201
196
|
def read_unicode_from_path(cls, path: Path) -> Self:
|
202
|
-
"""Reads and convert characters from a UTF-16
|
197
|
+
"""Reads and convert characters from a UTF-16 little-endian text file.
|
203
198
|
|
204
199
|
Arguments:
|
205
|
-
path:
|
206
|
-
A path to a UTF-16 LE text file.
|
200
|
+
path: A path to a UTF-16 LE text file.
|
207
201
|
|
208
202
|
Raises:
|
209
203
|
FileFormatError:
|
210
|
-
The file is not a UTF-16
|
211
|
-
|
204
|
+
The file is not a UTF-16 little-endian encoded text file or is missing
|
205
|
+
the Byte Order Mark for UTF-16 little-endian.
|
212
206
|
|
213
207
|
Returns:
|
214
208
|
A fpd character table.
|
215
209
|
"""
|
216
210
|
with Path(path).open("rb") as fp:
|
217
|
-
# Check the Byte Order Mark (BOM) to see if it is really a
|
218
|
-
#
|
211
|
+
# Check the Byte Order Mark (BOM) to see if it is really a UTF-16 LE text
|
212
|
+
# file
|
219
213
|
if fp.read(2) != BOM_UTF16_LE:
|
220
|
-
raise FileFormatError(
|
214
|
+
raise FileFormatError(
|
215
|
+
f"{path} is not a UTF-16 little-endian text file."
|
216
|
+
)
|
221
217
|
|
222
218
|
return cls.read_unicode(fp)
|
223
219
|
|
@@ -234,8 +230,7 @@ class Fpd:
|
|
234
230
|
"""
|
235
231
|
return cls.decode_unicode(fp.read())
|
236
232
|
|
237
|
-
# TODO: Somehow allow people to specify the width of the character
|
238
|
-
# during decoding
|
233
|
+
# TODO: Somehow allow people to specify the width of the character during decoding
|
239
234
|
@classmethod
|
240
235
|
def decode_unicode(cls, unicode: bytes) -> Self:
|
241
236
|
"""Converts a UTF-16 LE stream into a fpd character table.
|
@@ -278,8 +273,7 @@ class Fpd:
|
|
278
273
|
"""Encodes the fpd character table into a UTF-16 LE text stream.
|
279
274
|
|
280
275
|
Returns:
|
281
|
-
A UTF-16 LE encoded text stream with characters from the
|
282
|
-
fpd.
|
276
|
+
A UTF-16 LE encoded text stream with characters from the fpd.
|
283
277
|
"""
|
284
278
|
with BytesIO() as bytes_buffer:
|
285
279
|
for character in self.entries:
|
legacy_puyo_tools/mtx.py
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
"""Manzai text conversion tool for older Puyo Puyo games.
|
2
2
|
|
3
|
-
This module converts
|
4
|
-
|
5
|
-
Anniversary.
|
3
|
+
This module converts mtx files to and from XML for modding Puyo games. Currently
|
4
|
+
supports Puyo Puyo 7 and might support Puyo Puyo! 15th Anniversary.
|
6
5
|
|
7
6
|
SPDX-FileCopyrightText: 2025 Samuel Wu
|
8
7
|
SPDX-License-Identifier: MIT
|
@@ -62,9 +61,7 @@ class Mtx:
|
|
62
61
|
try:
|
63
62
|
return cls.read_mtx(fp)
|
64
63
|
except FormatError as e:
|
65
|
-
raise FileFormatError(
|
66
|
-
f"{path} is not a valid `mtx` file"
|
67
|
-
) from e
|
64
|
+
raise FileFormatError(f"{path} is not a valid `mtx` file") from e
|
68
65
|
|
69
66
|
@classmethod
|
70
67
|
def read_mtx(cls, fp: BinaryIO) -> Self:
|
@@ -85,9 +82,7 @@ class Mtx:
|
|
85
82
|
|
86
83
|
sections = [
|
87
84
|
read_offset(data, section_table_offset + (i * int_width))
|
88
|
-
for i in range(
|
89
|
-
(string_table_offset - section_table_offset) // int_width
|
90
|
-
)
|
85
|
+
for i in range((string_table_offset - section_table_offset) // int_width)
|
91
86
|
]
|
92
87
|
|
93
88
|
# Add the length to the sections so we can read to end of stream
|
@@ -97,9 +92,7 @@ class Mtx:
|
|
97
92
|
|
98
93
|
for current_string_offset, next_string_offset in pairwise(sections):
|
99
94
|
strings.append([
|
100
|
-
_read_character(
|
101
|
-
data, current_string_offset + (i * CHARACTER_WIDTH)
|
102
|
-
)
|
95
|
+
_read_character(data, current_string_offset + (i * CHARACTER_WIDTH))
|
103
96
|
for i in range(next_string_offset - current_string_offset)
|
104
97
|
])
|
105
98
|
|
@@ -0,0 +1,119 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: legacy-puyo-tools
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: A tool to edit text for older Puyo Puyo games.
|
5
|
+
Project-URL: changelog, https://github.com/wushenrong/legacy-puyo-tools/blob/main/CHANGELOG.md
|
6
|
+
Project-URL: homepage, https://github.com/wushenrong/legacy-puyo-tools
|
7
|
+
Project-URL: issues, https://github.com/wushenrong/legacy-puyo-tools/issues
|
8
|
+
Project-URL: source, https://github.com/wushenrong/legacy-puyo-tools.git
|
9
|
+
Author-email: Samuel Wu <twopizza9621536@gmail.com>
|
10
|
+
License-Expression: MIT
|
11
|
+
License-File: LICENSE
|
12
|
+
Keywords: puyopuyo
|
13
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
14
|
+
Classifier: Environment :: Console
|
15
|
+
Classifier: Intended Audience :: Other Audience
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
19
|
+
Classifier: Topic :: File Formats
|
20
|
+
Classifier: Topic :: Games/Entertainment :: Puzzle Games
|
21
|
+
Classifier: Topic :: Utilities
|
22
|
+
Requires-Python: >=3.13
|
23
|
+
Requires-Dist: attrs>=25.3.0
|
24
|
+
Requires-Dist: click>=8.2.1
|
25
|
+
Requires-Dist: cloup>=3.0.7
|
26
|
+
Requires-Dist: lxml>=6.0.0
|
27
|
+
Description-Content-Type: text/markdown
|
28
|
+
|
29
|
+
# Legacy Puyo Tools
|
30
|
+
|
31
|
+
A command line tool for modding older Puyo Puyo games. (Yes, the name is using a
|
32
|
+
[reversed naming scheme](https://github.com/microsoft/WSL).)
|
33
|
+
|
34
|
+
## Installation
|
35
|
+
|
36
|
+
Install the latest version [Python](https://www.python.org/).
|
37
|
+
|
38
|
+
`legacy-python-tools` is published to
|
39
|
+
[PyPI](https://pypi.org/project/legacy-puyo-tools/). It is recommended to
|
40
|
+
install tools from PyPI into an isolated Python environment.
|
41
|
+
|
42
|
+
You can use [`pipx`](https://pipx.pypa.io):
|
43
|
+
|
44
|
+
```bash
|
45
|
+
pipx install legacy-python-tools
|
46
|
+
# Or to run the cli without installing legacy-python-tools
|
47
|
+
pipx run legacy-python-tools
|
48
|
+
```
|
49
|
+
|
50
|
+
Or [`uv`](https://docs.astral.sh/uv):
|
51
|
+
|
52
|
+
```bash
|
53
|
+
uv tool install legacy-python-tools
|
54
|
+
# Or to run the cli without installing legacy-python-tools
|
55
|
+
uv tool run legacy-python-tools
|
56
|
+
# Or the shorter uvx
|
57
|
+
uvx legacy-python-tools
|
58
|
+
```
|
59
|
+
|
60
|
+
And of course, you can use good old pip in a virtual Python environment using
|
61
|
+
[`virualenv`](https://virtualenv.pypa.io) or the built-in `venv` library:
|
62
|
+
|
63
|
+
```bash
|
64
|
+
# Create a virtual python environment
|
65
|
+
virualenv .venv
|
66
|
+
# Or with the venv library
|
67
|
+
python -m venv .venv
|
68
|
+
# Activate the virtual environment
|
69
|
+
./.venv/Scripts/activate
|
70
|
+
# Install legacy-python-tools
|
71
|
+
pip install legacy-python-tools
|
72
|
+
# Or using the pip module
|
73
|
+
python -m pip install legacy-python-tools
|
74
|
+
```
|
75
|
+
|
76
|
+
## Usage
|
77
|
+
|
78
|
+
Create a `fpd` file from a UTF-16 little-endian encoded text file.
|
79
|
+
|
80
|
+
```bash
|
81
|
+
legacy-puyo-tools create fpd puyo14.txt
|
82
|
+
```
|
83
|
+
|
84
|
+
Or convert a `mtx` file to an editable XML file using a `fpd` file.
|
85
|
+
|
86
|
+
```bash
|
87
|
+
legacy-puyo-tools convert mtx --output custom_als.mtx --fpd puyo14.fpd als.xml
|
88
|
+
```
|
89
|
+
|
90
|
+
You can use the `--help` flag to see what sub-commands and options are
|
91
|
+
available.
|
92
|
+
|
93
|
+
## Supported Games
|
94
|
+
|
95
|
+
This tool will try to support formats from the following Puyo games:
|
96
|
+
|
97
|
+
- Puyo Puyo! 15th Annversivery
|
98
|
+
- Puyo Puyo 7
|
99
|
+
- Puyo Puyo!! 20th Annversivery (If there is demand)
|
100
|
+
|
101
|
+
See [Formats](formats.md) for detailed information about those formats, and the
|
102
|
+
current progress on creating and converting them.
|
103
|
+
|
104
|
+
## Why
|
105
|
+
|
106
|
+
The [Puyo Text Editor][puyo-text-editor] can already do what `legacy-puyo-tools`
|
107
|
+
does and is the inspiration of this tool, but there are advantages to rewriting
|
108
|
+
it in Python:
|
109
|
+
|
110
|
+
[puyo-text-editor]: https://github.com/nickworonekin/puyo-text-editor
|
111
|
+
|
112
|
+
- Better cross compatibility with Linux.
|
113
|
+
- Don't have to update the language version every time it becomes End of Life.
|
114
|
+
- Avoids the rigidness of using a pure object-oriented design.
|
115
|
+
|
116
|
+
## License
|
117
|
+
|
118
|
+
Under the MIT License. Based on [Puyo Text Editor][puyo-text-editor] which is
|
119
|
+
also under the MIT License.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
legacy_puyo_tools/__init__.py,sha256=tTzyNju0CFsXWki9ttjO6qnNx4Dlmur-1zgJ-n9toB0,277
|
2
|
+
legacy_puyo_tools/cli.py,sha256=qYBGmjO2LU5afTcwcGw3WJK-csDbaJF9lr_7mxlDkeA,4207
|
3
|
+
legacy_puyo_tools/exceptions.py,sha256=o0iH8s9qtt6ra8qaRW470amMszwUofsOMJr0mkCnVjM,428
|
4
|
+
legacy_puyo_tools/fpd.py,sha256=7pWdfREmNFRiIMsncwUF4h5yFV3TkIPenEagfx_8Hxc,8287
|
5
|
+
legacy_puyo_tools/mtx.py,sha256=fIRQJzx3UXv5q95k05eH99Ouh56CwpNRfP5uiI5S91k,4145
|
6
|
+
legacy_puyo_tools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
legacy_puyo_tools-0.1.0.dist-info/METADATA,sha256=j1yyrc2f-lA-IJCv9EPUlbTPVy7DGqKmzoMnLXO-bwE,3660
|
8
|
+
legacy_puyo_tools-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
9
|
+
legacy_puyo_tools-0.1.0.dist-info/entry_points.txt,sha256=SWkgMVVrmWMKaFJXbb0vx-qAjqMWnxm3_0AVwYCdZLs,65
|
10
|
+
legacy_puyo_tools-0.1.0.dist-info/licenses/LICENSE,sha256=C-K9I-yQXfd_K7nB9-9HgmhXprEcMcObZsRTv02ZWP8,1083
|
11
|
+
legacy_puyo_tools-0.1.0.dist-info/RECORD,,
|
@@ -1,34 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: legacy-puyo-tools
|
3
|
-
Version: 0.0.1
|
4
|
-
Summary: A tool to edit text for older Puyo Puyo games.
|
5
|
-
Author-email: Samuel Wu <twopizza9621536@gmail.com>
|
6
|
-
License-Expression: MIT
|
7
|
-
License-File: LICENSE
|
8
|
-
Requires-Python: >=3.13
|
9
|
-
Requires-Dist: attrs>=25.3.0
|
10
|
-
Requires-Dist: lxml>=6.0.0
|
11
|
-
Description-Content-Type: text/markdown
|
12
|
-
|
13
|
-
# Legacy Puyo Tools
|
14
|
-
|
15
|
-
Supports Puyo Puyo 7 and possibly Puyo Puyo! 15th Anniversary `mtx` and `fpd`
|
16
|
-
files. Puyo Puyo!! 20th Anniversary is still not supported yet. (Create an issue
|
17
|
-
or pull request to support `fnt` and additional `mtx` controls). Also, legacy as
|
18
|
-
in older Puyo Puyo games, not that this tool is decapitated.
|
19
|
-
|
20
|
-
## Why
|
21
|
-
|
22
|
-
The [Puyo Text Editor][1] can already do what Legacy Puyo Tools does and is the
|
23
|
-
inspiration of this tool, but there are advantages to rewrite it in Python:
|
24
|
-
|
25
|
-
- Better cross compatibility with Linux.
|
26
|
-
- Don't have to update the language version every time it becomes End of Life.
|
27
|
-
- Avoids the rigidness of using a pure object-oriented design.
|
28
|
-
|
29
|
-
## License
|
30
|
-
|
31
|
-
Under the MIT License. Based on [Puyo Text Editor][1] which is also under the
|
32
|
-
MIT License.
|
33
|
-
|
34
|
-
[1]: https://github.com/nickworonekin/puyo-text-editor
|
@@ -1,11 +0,0 @@
|
|
1
|
-
legacy_puyo_tools/__init__.py,sha256=tTzyNju0CFsXWki9ttjO6qnNx4Dlmur-1zgJ-n9toB0,277
|
2
|
-
legacy_puyo_tools/cli.py,sha256=gqwjiuSqAzuJRc_Tei1WRxRWGMC0AycWhf940oY-UrY,4934
|
3
|
-
legacy_puyo_tools/exceptions.py,sha256=vqoMG7VjUddzWGMIvzWtE18U6fnmMW7VcpwdOIoOiBc,341
|
4
|
-
legacy_puyo_tools/fpd.py,sha256=XXVCMlYD_eJAhmIQzDlRFvqm-FG9imm68bLooM2-mi4,8306
|
5
|
-
legacy_puyo_tools/mtx.py,sha256=8dGHE719LuOZ9fi8uEgAKh5YIdCuvo9bXAEbcwxaC8Q,4253
|
6
|
-
legacy_puyo_tools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
-
legacy_puyo_tools-0.0.1.dist-info/METADATA,sha256=PCxhnsrQHopcml8PQbgEuBGBP4z_4rPbZWHMkFftFxc,1167
|
8
|
-
legacy_puyo_tools-0.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
9
|
-
legacy_puyo_tools-0.0.1.dist-info/entry_points.txt,sha256=SWkgMVVrmWMKaFJXbb0vx-qAjqMWnxm3_0AVwYCdZLs,65
|
10
|
-
legacy_puyo_tools-0.0.1.dist-info/licenses/LICENSE,sha256=hu6L3ztT5uuc-EMaEgsjrhAHSTh56efyD-tVaEpc7Rw,1066
|
11
|
-
legacy_puyo_tools-0.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|