aboutsummaryrefslogtreecommitdiff
path: root/tools/img2sprite.py
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2021-05-03 08:21:10 +0100
committerJuan J. Martinez <jjm@usebox.net>2021-05-03 10:00:00 +0100
commitc3b0fa04a663fe233765b83d3be41a42aa08c25d (patch)
tree0befda349001ef6ce306b39378f9c70ad917363e /tools/img2sprite.py
downloadreturn-of-traxtor-cpc-main.tar.gz
return-of-traxtor-cpc-main.zip
Initial import for public releaseHEADmain
Diffstat (limited to 'tools/img2sprite.py')
-rwxr-xr-xtools/img2sprite.py115
1 files changed, 115 insertions, 0 deletions
diff --git a/tools/img2sprite.py b/tools/img2sprite.py
new file mode 100755
index 0000000..6463e0c
--- /dev/null
+++ b/tools/img2sprite.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+
+__version__ = "1.0"
+
+import sys
+from argparse import ArgumentParser
+from PIL import Image
+
+DEF_W = 8
+DEF_H = 16
+
+def encode_byte(a, b):
+ return (a & 1) << 7 | (b & 1) << 6 \
+ | (a & 4) << 3 | (b & 4) << 2 \
+ | (a & 2) << 2 | (b & 2) << 1 \
+ | (a & 8) >> 2 | (b & 8) >> 3
+
+def main():
+
+ parser = ArgumentParser(description="Image cpcrslib sprite",
+ epilog="Copyright (C) 2015 Juan J Martinez <jjm@usebox.net>",
+ )
+
+ parser.add_argument("--version", action="version", version="%(prog)s " + __version__)
+ parser.add_argument("-i", "--id", dest="id", default="sprite", type=str,
+ help="variable name (default: sprite)")
+ parser.add_argument("--width", dest="w", default=DEF_W, type=int,
+ help="sprite width (default: %s)" % DEF_W)
+ parser.add_argument("--height", dest="h", default=DEF_H, type=int,
+ help="sprite height (default: %s)" % DEF_H)
+ parser.add_argument("--transparent-color", dest="tc", default=None, type=int,
+ help="palette index for the transparent color (default: None)")
+ parser.add_argument("-d", "--dimension", dest="dim", action="store_true",
+ help="include the sprite dimensions in the output")
+ parser.add_argument("-b", "--binary", dest="binary", action="store_true",
+ help="output binary instead of C code")
+
+
+ parser.add_argument("image", help="image to convert", nargs="?")
+
+ args = parser.parse_args()
+
+ if not args.image:
+ parser.error("required parameter: image")
+
+ if args.tc:
+ try:
+ args.tc = int(args.tc)
+ if args.tc < 0 or args.tc > 15:
+ raise ValueError()
+ except ValueError:
+ parser.error("--transparent-color expects an integer in [0, 15]")
+
+ try:
+ image = Image.open(args.image)
+ except IOError:
+ parser.error("failed to open the image")
+
+ if image.mode != "P":
+ parser.error("not an indexed image (no palette)")
+
+ (w, h) = image.size
+
+ if w % args.w or h % args.h:
+ parser.error("%s size is not multiple of the image size" % args.image)
+
+ data = image.getdata()
+
+ out = []
+ for x in range(0, w, args.w):
+ frame = []
+ for y in range(h): # FIXME: different heights!
+ if args.dim:
+ out.extend([args.w // 2, args.h])
+ for i in range(0, args.w, 2):
+ a = data[x + i + (y * w)]
+ b = data[x + i + 1 + (y * w)]
+
+ if args.tc is not None:
+ mask_a = mask_b = 0
+ if a == args.tc:
+ mask_a = 0xf
+ a = 0
+ if b == args.tc:
+ mask_b = 0xf
+ b = 0
+ frame.append(encode_byte(mask_a, mask_b))
+
+ frame.append(encode_byte(a, b))
+ out.append(frame)
+
+ if args.binary:
+ for frame in out:
+ sys.stdout.write(bytearray(frame))
+ return
+
+ frames = len(out)
+
+ data_out = ""
+ for block in out:
+ if data_out:
+ data_out += ",\n"
+ data_out += "{"
+ for part in range(0, len(block), 4):
+ if data_out and data_out[-1] != "{":
+ data_out += ",\n"
+ data_out += ', '.join(["0x%02x" % b for b in block[part: part + 4]])
+ data_out += "}"
+
+ print("/* %sx%s (frames: %s, mask: %s, dim: %s) */" % (args.w, args.h, frames, args.tc is not None, args.dim))
+ print("const unsigned char %s[%d][%d] = {\n%s\n};\n" % (args.id, len(out), len(out[0]), data_out))
+
+if __name__ == "__main__":
+ main()
+