Support splitting texturemaps into individual sprites.
This commit is contained in:
parent
31ad2856fd
commit
0c4cb8df5c
@ -1676,6 +1676,12 @@ def main() -> int:
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Generate overlay images showing mappings",
|
help="Generate overlay images showing mappings",
|
||||||
)
|
)
|
||||||
|
extract_parser.add_argument(
|
||||||
|
"-s",
|
||||||
|
"--split-textures",
|
||||||
|
action="store_true",
|
||||||
|
help="Split textures into individual sprites",
|
||||||
|
)
|
||||||
|
|
||||||
update_parser = subparsers.add_parser('update', help='Update relevant textures in a file from a directory')
|
update_parser = subparsers.add_parser('update', help='Update relevant textures in a file from a directory')
|
||||||
update_parser.add_argument(
|
update_parser.add_argument(
|
||||||
@ -1711,67 +1717,75 @@ def main() -> int:
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.action == "extract":
|
if args.action == "extract":
|
||||||
|
if args.split_textures:
|
||||||
|
if args.write_raw:
|
||||||
|
raise Exception("Cannot write raw textures when splitting sprites!")
|
||||||
|
if args.generate_mapping_overlays:
|
||||||
|
raise Exception("Cannot generate mapping overlays when splitting sprites!")
|
||||||
|
|
||||||
with open(args.file, "rb") as bfp:
|
with open(args.file, "rb") as bfp:
|
||||||
afpfile = AFPFile(bfp.read(), verbose=args.verbose)
|
afpfile = AFPFile(bfp.read(), verbose=args.verbose)
|
||||||
|
|
||||||
# Actually place the files down.
|
# Actually place the files down.
|
||||||
os.makedirs(args.dir, exist_ok=True)
|
os.makedirs(args.dir, exist_ok=True)
|
||||||
|
|
||||||
for texture in afpfile.textures:
|
if not args.split_textures:
|
||||||
filename = os.path.join(args.dir, texture.name)
|
for texture in afpfile.textures:
|
||||||
|
filename = os.path.join(args.dir, texture.name)
|
||||||
|
|
||||||
if texture.img:
|
if texture.img:
|
||||||
if args.pretend:
|
if args.pretend:
|
||||||
print(f"Would write {filename}.png texture...")
|
print(f"Would write {filename}.png texture...")
|
||||||
else:
|
else:
|
||||||
print(f"Writing {filename}.png texture...")
|
print(f"Writing {filename}.png texture...")
|
||||||
with open(f"{filename}.png", "wb") as bfp:
|
with open(f"{filename}.png", "wb") as bfp:
|
||||||
texture.img.save(bfp, format='PNG')
|
texture.img.save(bfp, format='PNG')
|
||||||
|
|
||||||
if not texture.img or args.write_raw:
|
if not texture.img or args.write_raw:
|
||||||
if args.pretend:
|
if args.pretend:
|
||||||
print(f"Would write {filename}.raw texture...")
|
print(f"Would write {filename}.raw texture...")
|
||||||
else:
|
else:
|
||||||
print(f"Writing {filename}.raw texture...")
|
print(f"Writing {filename}.raw texture...")
|
||||||
with open(f"{filename}.raw", "wb") as bfp:
|
with open(f"{filename}.raw", "wb") as bfp:
|
||||||
bfp.write(texture.raw)
|
bfp.write(texture.raw)
|
||||||
|
|
||||||
if args.pretend:
|
if args.pretend:
|
||||||
print(f"Would write {filename}.xml texture info...")
|
print(f"Would write {filename}.xml texture info...")
|
||||||
else:
|
else:
|
||||||
print(f"Writing {filename}.xml texture info...")
|
print(f"Writing {filename}.xml texture info...")
|
||||||
with open(f"{filename}.xml", "w") as sfp:
|
with open(f"{filename}.xml", "w") as sfp:
|
||||||
sfp.write(textwrap.dedent(f"""
|
sfp.write(textwrap.dedent(f"""
|
||||||
<info>
|
<info>
|
||||||
<width>{texture.width}</width>
|
<width>{texture.width}</width>
|
||||||
<height>{texture.height}</height>
|
<height>{texture.height}</height>
|
||||||
<type>{hex(texture.fmt)}</type>
|
<type>{hex(texture.fmt)}</type>
|
||||||
<raw>{filename}.raw</raw>
|
<raw>{filename}.raw</raw>
|
||||||
</info>
|
</info>
|
||||||
""").strip())
|
""").strip())
|
||||||
|
|
||||||
if args.write_mappings:
|
if args.write_mappings:
|
||||||
for i, name in enumerate(afpfile.regionmap.entries):
|
if not args.split_textures:
|
||||||
if i < 0 or i >= len(afpfile.texture_to_region):
|
for i, name in enumerate(afpfile.regionmap.entries):
|
||||||
raise Exception(f"Out of bounds region {i}")
|
if i < 0 or i >= len(afpfile.texture_to_region):
|
||||||
region = afpfile.texture_to_region[i]
|
raise Exception(f"Out of bounds region {i}")
|
||||||
texturename = afpfile.texturemap.entries[region.textureno]
|
region = afpfile.texture_to_region[i]
|
||||||
filename = os.path.join(args.dir, name)
|
texturename = afpfile.texturemap.entries[region.textureno]
|
||||||
|
filename = os.path.join(args.dir, name)
|
||||||
|
|
||||||
if args.pretend:
|
if args.pretend:
|
||||||
print(f"Would write {filename}.xml region information...")
|
print(f"Would write {filename}.xml region information...")
|
||||||
else:
|
else:
|
||||||
print(f"Writing {filename}.xml region information...")
|
print(f"Writing {filename}.xml region information...")
|
||||||
with open(f"{filename}.xml", "w") as sfp:
|
with open(f"{filename}.xml", "w") as sfp:
|
||||||
sfp.write(textwrap.dedent(f"""
|
sfp.write(textwrap.dedent(f"""
|
||||||
<info>
|
<info>
|
||||||
<left>{region.left}</left>
|
<left>{region.left}</left>
|
||||||
<top>{region.top}</top>
|
<top>{region.top}</top>
|
||||||
<right>{region.right}</right>
|
<right>{region.right}</right>
|
||||||
<bottom>{region.bottom}</bottom>
|
<bottom>{region.bottom}</bottom>
|
||||||
<texture>{texturename}</texture>
|
<texture>{texturename}</texture>
|
||||||
</info>
|
</info>
|
||||||
""").strip())
|
""").strip())
|
||||||
|
|
||||||
if afpfile.fontdata is not None:
|
if afpfile.fontdata is not None:
|
||||||
filename = os.path.join(args.dir, "fontinfo.xml")
|
filename = os.path.join(args.dir, "fontinfo.xml")
|
||||||
@ -1826,6 +1840,43 @@ def main() -> int:
|
|||||||
with open(filename, "wb") as bfp:
|
with open(filename, "wb") as bfp:
|
||||||
img.save(bfp, format='PNG')
|
img.save(bfp, format='PNG')
|
||||||
|
|
||||||
|
if args.split_textures:
|
||||||
|
textures: Dict[str, Any] = {}
|
||||||
|
announced: Dict[str, bool] = {}
|
||||||
|
|
||||||
|
for i, name in enumerate(afpfile.regionmap.entries):
|
||||||
|
if i < 0 or i >= len(afpfile.texture_to_region):
|
||||||
|
raise Exception(f"Out of bounds region {i}")
|
||||||
|
region = afpfile.texture_to_region[i]
|
||||||
|
texturename = afpfile.texturemap.entries[region.textureno]
|
||||||
|
|
||||||
|
if texturename not in textures:
|
||||||
|
for tex in afpfile.textures:
|
||||||
|
if tex.name == texturename:
|
||||||
|
textures[texturename] = tex
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise Exception("Could not find texture {texturename} to split!")
|
||||||
|
|
||||||
|
if textures[texturename].img:
|
||||||
|
# Grab the location in the image, save it out to a new file.
|
||||||
|
filename = f"{texturename}_{name}.png"
|
||||||
|
filename = os.path.join(args.dir, filename)
|
||||||
|
|
||||||
|
if args.pretend:
|
||||||
|
print(f"Would write {filename} sprite...")
|
||||||
|
else:
|
||||||
|
print(f"Writing {filename} sprite...")
|
||||||
|
sprite = textures[texturename].img.crop(
|
||||||
|
(region.left // 2, region.top // 2, region.right // 2, region.bottom // 2),
|
||||||
|
)
|
||||||
|
with open(filename, "wb") as bfp:
|
||||||
|
sprite.save(bfp, format='PNG')
|
||||||
|
else:
|
||||||
|
if not announced.get(texturename, False):
|
||||||
|
print(f"Cannot extract sprites from {texturename} because it is not a supported format!")
|
||||||
|
announced[texturename] = True
|
||||||
|
|
||||||
if args.action == "update":
|
if args.action == "update":
|
||||||
# First, parse the file out
|
# First, parse the file out
|
||||||
with open(args.file, "rb") as bfp:
|
with open(args.file, "rb") as bfp:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user