aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-05-22 12:53:03 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-05-22 12:53:03 +0100
commitcf000407b8d2d4e75a6f56b5d111f3e55e7400e5 (patch)
tree9ed14ce5c38213acfad0994018dbfe0c807197ab /tools
parentf89c327501a841d5bdcb5d26be065819e0e13229 (diff)
downloadtr8vm-cf000407b8d2d4e75a6f56b5d111f3e55e7400e5.tar.gz
tr8vm-cf000407b8d2d4e75a6f56b5d111f3e55e7400e5.zip
Added rotate tiles tool
Diffstat (limited to 'tools')
-rw-r--r--tools/rotate.md40
-rwxr-xr-xtools/rotate.py83
2 files changed, 123 insertions, 0 deletions
diff --git a/tools/rotate.md b/tools/rotate.md
new file mode 100644
index 0000000..ab95c07
--- /dev/null
+++ b/tools/rotate.md
@@ -0,0 +1,40 @@
+# Rotate tiles
+
+This tool can be used to transform an image containing a tileset into a new
+one with a single column of tiles, so can be loaded with ".incpng" and the
+result is easy to index.
+
+For example, given 6 tiles of 8x8 pixels in `origin.ong`:
+
+```
+012345
+```
+
+The command `./rotate.py origin.png 8 8 dest.png` will generate an image with
+the tiles rearranged like this:
+
+```
+0
+1
+2
+3
+4
+5
+```
+
+In this way tile 0 is in `addr`, tile 1 in `addr + 64`, tile 2 in `addr + 128`, etc.
+
+## Requirements
+
+The tool requires:
+
+- Python 3
+- PIL (or Pillow)
+
+For example, you can install Pillow with:
+
+```
+python3 -m pip install --upgrade pip
+python3 -m pip install --upgrade Pillow
+```
+
diff --git a/tools/rotate.py b/tools/rotate.py
new file mode 100755
index 0000000..1fcc2c9
--- /dev/null
+++ b/tools/rotate.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+#
+# Rotate tiles
+# Copyright (C) 2023 by Juan J. Martinez <jjm@usebox.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+__version__ = "1.0"
+
+import sys
+from argparse import ArgumentParser
+from itertools import chain
+
+try:
+ from PIL import Image
+except ImportError:
+ sys.exit("Please install PIP (or pillow)")
+
+
+def main():
+
+ parser = ArgumentParser(
+ description="Rotate tiles",
+ epilog="Copyright (C) 2023 Juan J Martinez <jjm@usebox.net>",
+ )
+
+ parser.add_argument(
+ "--version", action="version", version="%(prog)s " + __version__
+ )
+
+ parser.add_argument("image", help="image to convert")
+ parser.add_argument("width", help="witdth of the tiles", type=int)
+ parser.add_argument("height", help="height of the tiles", type=int)
+ parser.add_argument("dest", help="destination image")
+
+ args = parser.parse_args()
+
+ try:
+ image = Image.open(args.image)
+ except IOError:
+ parser.error("failed to open the image")
+
+ (w, h) = image.size
+
+ if w % args.width or h % args.height:
+ parser.error("%s size is not multiple of the tile size" % args.image)
+
+ data = list(image.convert("RGB").getdata())
+
+ ntiles = 0
+ out = []
+ for base_y in range(0, h, args.height):
+ for x in range(0, w, args.width):
+ tile = []
+ for y in range(base_y, base_y + args.height):
+ tile.extend(data[x + y * w : x + y * w + args.width])
+ out.extend(tile)
+ ntiles += 1
+
+ out_data = list(chain.from_iterable(out))
+ result = Image.frombytes("RGB", (args.width, args.height * ntiles), bytes(out_data))
+ with open(args.dest, "wb") as fd:
+ result.save(fd)
+
+
+if __name__ == "__main__":
+ main()