all repos — mgba @ 20353fa19533f68d89b168ea5f32a47e2e9d7b89

mGBA Game Boy Advance Emulator

tools/make-dotcode.py (view raw)

 1import numpy as np
 2import PIL.Image
 3import PIL.ImageChops
 4import sys
 5
 6with open(sys.argv[1], 'rb') as f:
 7    data = f.read()
 8size = len(data)
 9
10blocksize = 104
11blocks = size // blocksize
12height = 36
13width = 35
14margin = 2
15
16dots = np.zeros((width * blocks + margin * 2 + 1, height + margin * 2), dtype=np.bool)
17anchor = np.array([[0, 1, 1, 1, 0],
18                   [1, 1, 1, 1, 1],
19                   [1, 1, 1, 1, 1],
20                   [1, 1, 1, 1, 1],
21                   [0, 1, 1, 1, 0]], dtype=np.bool)
22alignment = np.array([1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0], dtype=np.bool)
23nybbles = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [1, 0, 0, 1, 0],
24           [0, 0, 1, 0, 0], [0, 0, 1, 0, 1], [0, 0, 1, 1, 0], [1, 0, 1, 1, 0],
25           [0, 1, 0, 0, 0], [0, 1, 0, 0, 1], [0, 1, 0, 1, 0], [1, 0, 1, 0, 0],
26           [0, 1, 1, 0, 0], [0, 1, 1, 0, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 0]]
27addr = [0x03FF]
28for i in range(1, 54):
29    addr.append(addr[i - 1] ^ ((i & -i) * 0x769))
30    if (i & 0x07) == 0:
31        addr[i] ^= 0x769
32    if (i & 0x0F) == 0:
33        addr[i] ^= 0x769 << 1
34    if (i & 0x1F) == 0:
35        addr[i] ^= (0x769 << 2) ^ 0x769
36
37base = 1 if blocks == 18 else 25
38for i in range(blocks + 1):
39    dots[i * width:i * width + 5, 0:5] = anchor
40    dots[i * width:i * width + 5, height + margin * 2 - 5:height + margin * 2] = anchor
41    dots[i * width + margin, margin + 5] = 1
42    a = addr[base + i]
43    for j in range(16):
44        dots[i * width + margin, margin + 14 + j] = a & (1 << (15 - j))
45for i in range(blocks):
46    dots[i * width:(i + 1) * width, margin] = alignment
47    dots[i * width:(i + 1) * width, height + margin - 1] = alignment
48    block = []
49    for byte in data[i * blocksize:(i + 1) * blocksize]:
50        block.extend(nybbles[byte >> 4])
51        block.extend(nybbles[byte & 0xF])
52    j = 0
53    for y in range(3):
54        dots[i * width + margin + 5:i * width + margin + 31, margin + 2 + y] = block[j:j + 26]
55        j += 26
56    for y in range(26):
57        dots[i * width + margin + 1:i * width + margin + 35, margin + 5 + y] = block[j:j + 34]
58        j += 34
59    for y in range(3):
60        dots[i * width + margin + 5:i * width + margin + 31, margin + 31 + y] = block[j:j + 26]
61        j += 26
62im = PIL.Image.fromarray(dots.T)
63im = PIL.ImageChops.invert(im)
64im.save('dotcode.png')