diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-08-31 15:00:30 +0200 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-08-31 15:00:30 +0200 |
commit | 59b4df9a0aa5e7a4a98c8730858e3c2bbcfc98fc (patch) | |
tree | 9cd3141321d0669d274f5fdfbf13e6a95f45b2f2 | |
parent | 2a643308faf4262b938f9c32ab49fd56a95f04a0 (diff) |
successfully convert pictochat data capture to png
-rw-r--r-- | assets/first-decode-pictochat.png | bin | 0 -> 4117 bytes | |||
-rw-r--r-- | assets/first-decode-ws.png | bin | 0 -> 160244 bytes | |||
-rw-r--r-- | assets/first-decode.png | bin | 0 -> 528 bytes | |||
-rw-r--r-- | docs/notes.md | 16 | ||||
-rw-r--r-- | experiments/conv/.gitignore | 4 | ||||
-rw-r--r-- | experiments/conv/consts.py | 18 | ||||
-rwxr-xr-x | experiments/conv/pc2png | 70 | ||||
-rw-r--r-- | experiments/conv/requirements.txt | 1 |
8 files changed, 109 insertions, 0 deletions
diff --git a/assets/first-decode-pictochat.png b/assets/first-decode-pictochat.png Binary files differnew file mode 100644 index 0000000..cede905 --- /dev/null +++ b/assets/first-decode-pictochat.png diff --git a/assets/first-decode-ws.png b/assets/first-decode-ws.png Binary files differnew file mode 100644 index 0000000..0370ee2 --- /dev/null +++ b/assets/first-decode-ws.png diff --git a/assets/first-decode.png b/assets/first-decode.png Binary files differnew file mode 100644 index 0000000..387aa50 --- /dev/null +++ b/assets/first-decode.png diff --git a/docs/notes.md b/docs/notes.md index c4a72ab..9965544 100644 --- a/docs/notes.md +++ b/docs/notes.md @@ -324,6 +324,22 @@ code to reassemble these chunks, the following observations were made: drawings. These bytes appear to be some kind of padding as changing them appears to have no effect and does not show up in the drawing. +Using the reassembled message data, the following message was decoded as an +experiment: + +![](../assets/first-decode-pictochat.png) + +Wireshark allows you to easily save the binary content of a dissection field to +a file: + +![](../assets/first-decode-ws.png) + +Resulting decoded image: + +<div style="background-color: black; padding: 4px; font-size: 0px; display: inline-block;"> +<img src="../assets/first-decode.png"/> +</div> + ## Unsure/notes - Is the endianness of the DS properly emulated? diff --git a/experiments/conv/.gitignore b/experiments/conv/.gitignore new file mode 100644 index 0000000..3b4db56 --- /dev/null +++ b/experiments/conv/.gitignore @@ -0,0 +1,4 @@ +venv +__pycache__ +*.bin +*.png diff --git a/experiments/conv/consts.py b/experiments/conv/consts.py new file mode 100644 index 0000000..898bd3d --- /dev/null +++ b/experiments/conv/consts.py @@ -0,0 +1,18 @@ +PICTOCHAT_PALETTE = ( + (0xff, 0xff, 0xff), + (0x00, 0x00, 0x00), + (0xd3, 0xcb, 0xc3), + (0xeb, 0x00, 0xeb), + (0xfb, 0x00, 0x8a), + (0xfb, 0x00, 0x28), + (0xfb, 0x49, 0x00), + (0xfb, 0xa2, 0x00), + (0xe3, 0xf3, 0x00), + (0x82, 0xfb, 0x00), + (0x10, 0xfb, 0x20), + (0x00, 0xfb, 0xba), + (0x00, 0xc3, 0xfb), + (0x00, 0x79, 0xfb), + (0x00, 0x30, 0xfb), + (0x28, 0x00, 0xfb), +) diff --git a/experiments/conv/pc2png b/experiments/conv/pc2png new file mode 100755 index 0000000..4fa7a1a --- /dev/null +++ b/experiments/conv/pc2png @@ -0,0 +1,70 @@ +#!/bin/python3 + +import sys +import re +import math +import io + +from PIL import Image + +from consts import PICTOCHAT_PALETTE + +DS_TILE_SIZE = 8 +TILE_BYTES = 32 # tiles are stored in 32 bytes chunks + +TILES_HORIZONTAL = 32 + +# convert a single DS tile (8x8) from packed palette index format to RGB colors +def convert_chunk(img, chunk, offset): + palette_indices = [] + for byte in chunk: + palette_indices += [ + (byte >> 0) & 0x0f, + (byte >> 4) & 0x0f, + ] + + for i, palette_idx in enumerate(palette_indices): + color = PICTOCHAT_PALETTE[palette_idx] + location = ( + i % DS_TILE_SIZE + offset[0], + i // DS_TILE_SIZE + offset[1], + ) + img.putpixel(location, color) + +# convert a string of tiles into a PNG image +def pc2png(data): + tile_count = math.floor(len(data) / TILE_BYTES) + size = ( + TILES_HORIZONTAL * DS_TILE_SIZE, + math.ceil(tile_count / TILES_HORIZONTAL) * DS_TILE_SIZE, + ) + img = Image.new(mode="RGB", size=size) + + for tile in range(tile_count): + chunk_idx = tile * TILE_BYTES + chunk = data[chunk_idx:chunk_idx+TILE_BYTES] + tile_offset = ( + tile % TILES_HORIZONTAL, + tile // TILES_HORIZONTAL, + ) + convert_chunk(img, chunk, [x * DS_TILE_SIZE for x in tile_offset]) + + output = io.BytesIO() + img.save(output, format='PNG') + return output.getvalue() + +def convert_file(input_filename, output_filename): + with open(input_filename, 'rb') as input_file: + content = input_file.read() + output = pc2png(content) + with open(output_filename, 'wb+') as output_file: + output_file.write(output) + +if __name__ == "__main__": + del sys.argv[0] + for input_filename in sys.argv: + output_filename = re.sub('.bin$', '.png', input_filename) + if not output_filename.endswith('.png'): + output_filename += '.png' + convert_file(input_filename, output_filename) + diff --git a/experiments/conv/requirements.txt b/experiments/conv/requirements.txt new file mode 100644 index 0000000..4efc8c7 --- /dev/null +++ b/experiments/conv/requirements.txt @@ -0,0 +1 @@ +pillow==10.4.0 |