fix(screenshot): send GxEPD2 rotation in header; full rot 0-3 decode in Python

Firmware (7-byte header):
  Byte 7 = display->screenshotRotation() — GxEPD2/GFX rotation value (0-3).
  DisplayDriver::screenshotRotation() defaults to 0 (OLED).
  GxEPDDisplay::screenshotRotation() returns display.getRotation(), the
  live GxEPD2 value (reflects runtime setDisplayRotation() calls, not just
  the compile-time DISPLAY_ROTATION macro).

Python decoder:
  - Parse 7-byte header; pass rotation to eink_buffer_to_image().
  - Implement all four GxEPD2 drawPixel coordinate transforms:
      rot 0: phys_x=lx,            phys_y=ly
      rot 1: phys_x=vis_w-1-ly,    phys_y=lx
      rot 2: phys_x=vis_w-1-lx,    phys_y=vis_h-1-ly  (180° flip)
      rot 3: phys_x=ly,            phys_y=vis_h-1-lx
  - vis_w/vis_h derived from log dimensions + rotation parity (no constants).
  - Print rot= in the status line so the user sees which rotation was used.

This fixes the 180° rotated image seen with rotation=2 (portrait inverted)
without hardcoding a flip — correct for any rotation value.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-28 08:10:16 +02:00
parent 37432491dd
commit d1a88c8277
4 changed files with 55 additions and 34 deletions

View File

@@ -2098,9 +2098,11 @@ void MyMesh::handleScreenshotRequest() {
}
void MyMesh::sendScreenshotResponse(DisplayDriver* display, const uint8_t* buffer, uint16_t bufferSize) {
// Frame format: RESP_CODE_SCREENSHOT, width, height, chunk_idx, total_chunks, display_type, [data]
// Frame format: RESP_CODE_SCREENSHOT, width, height, chunk_idx, total_chunks,
// display_type, rotation, [data]
// display_type: 0=OLED (page-based), 1=e-ink (row-major, MSB-first, 1=white/0=black)
const int HEADER_SIZE = 6;
// rotation: 0-3, Adafruit_GFX/GxEPD2 rotation value (only meaningful for e-ink)
const int HEADER_SIZE = 7;
const int MAX_DATA_PER_FRAME = MAX_FRAME_SIZE - HEADER_SIZE;
int totalChunks = (bufferSize + MAX_DATA_PER_FRAME - 1) / MAX_DATA_PER_FRAME;
@@ -2112,6 +2114,7 @@ void MyMesh::sendScreenshotResponse(DisplayDriver* display, const uint8_t* buffe
out_frame[i++] = (uint8_t)chunkIdx;
out_frame[i++] = (uint8_t)totalChunks;
out_frame[i++] = display->getDisplayType();
out_frame[i++] = display->screenshotRotation();
int chunkSize = min(MAX_DATA_PER_FRAME, (int)bufferSize - chunkIdx * MAX_DATA_PER_FRAME);
memcpy(&out_frame[i], buffer + chunkIdx * MAX_DATA_PER_FRAME, chunkSize);