HydraIssues

kioskoverlay backdrop distorts on portrait displays (no aspect-ratio or rotation handling)
open bug Project: hydrabody Reporter: 22 Apr 2026 17:56

Description

## Context

`cmd/kioskoverlay/main.go:467-472` renders the backdrop with a single `StretchBlt` that scales the source image to `screenWidth × screenHeight`:

```go
procStretchBlt.Call(
hdc, 0, 0, uintptr(screenWidth), uintptr(screenHeight),
backdropDC, 0, 0, uintptr(backdropWidth), uintptr(backdropHeight),
srcCopy,
)
```

No aspect-ratio preservation, no rotation handling. On a portrait-rotated display (1080×1920), a landscape-composed backdrop (1920×1080) gets squished to fill — the Hydra logo and any branded composition come out distorted.

We have portrait bodies in the fleet (per `project_portrait_streaming.md` — VDD + Sunshine config for portrait). On those bodies, visitors see a stretched/distorted backdrop during idle or post-experience-close.

## Proposal

Detect orientation at `prepareBackdropBitmap` time and pick the right rendering strategy. Two options:

### Option A (simplest): rotate the source image 90° when screen is portrait
If `screenHeight > screenWidth`, rotate the source bitmap 90° at load time (GDI `Plg` blit or `GdipRotateImage`). Keeps a single backdrop asset per body.

### Option B: ship two backdrop files and pick at runtime
`defaultbackdrop-landscape.png` + `defaultbackdrop-portrait.png` in hydrabody's embedded assets. Cleaner for bodies where the portrait composition isn't just a rotation of the landscape one.

### Option C: letterbox with black bars to preserve aspect
Render backdrop centered at its native aspect, fill the rest with the black stock brush. Simplest fallback but visually weaker than A or B for branded idle screens.

Recommend A for v1 (single asset, auto-rotate), B only if we need distinct portrait branding.

## Impact

Cosmetic — distorted idle screen on portrait bodies. Doesn't affect streams (Sunshine captures the game, not the overlay).

## References

- `project_portrait_streaming.md` — portrait streaming context (VDD + Sunshine config).
- Code: `hydrabody/cmd/kioskoverlay/main.go:340-402` (bitmap prep) + `:464-474` (paint).