aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-08-31 15:00:30 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-08-31 15:00:30 +0200
commit59b4df9a0aa5e7a4a98c8730858e3c2bbcfc98fc (patch)
tree9cd3141321d0669d274f5fdfbf13e6a95f45b2f2
parent2a643308faf4262b938f9c32ab49fd56a95f04a0 (diff)
successfully convert pictochat data capture to png
-rw-r--r--assets/first-decode-pictochat.pngbin0 -> 4117 bytes
-rw-r--r--assets/first-decode-ws.pngbin0 -> 160244 bytes
-rw-r--r--assets/first-decode.pngbin0 -> 528 bytes
-rw-r--r--docs/notes.md16
-rw-r--r--experiments/conv/.gitignore4
-rw-r--r--experiments/conv/consts.py18
-rwxr-xr-xexperiments/conv/pc2png70
-rw-r--r--experiments/conv/requirements.txt1
8 files changed, 109 insertions, 0 deletions
diff --git a/assets/first-decode-pictochat.png b/assets/first-decode-pictochat.png
new file mode 100644
index 0000000..cede905
--- /dev/null
+++ b/assets/first-decode-pictochat.png
Binary files differ
diff --git a/assets/first-decode-ws.png b/assets/first-decode-ws.png
new file mode 100644
index 0000000..0370ee2
--- /dev/null
+++ b/assets/first-decode-ws.png
Binary files differ
diff --git a/assets/first-decode.png b/assets/first-decode.png
new file mode 100644
index 0000000..387aa50
--- /dev/null
+++ b/assets/first-decode.png
Binary files differ
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