cmd/kioskoverlay/main.go:467-472 renders the backdrop with a single StretchBlt that scales the source image to screenWidth × screenHeight:
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.
Detect orientation at prepareBackdropBitmap time and pick the right rendering strategy. Two options:
If screenHeight > screenWidth, rotate the source bitmap 90° at load time (GDI Plg blit or GdipRotateImage). Keeps a single backdrop asset per body.
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.
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.
Cosmetic — distorted idle screen on portrait bodies. Doesn't affect streams (Sunshine captures the game, not the overlay).
project_portrait_streaming.md — portrait streaming context (VDD + Sunshine config).hydrabody/cmd/kioskoverlay/main.go:340-402 (bitmap prep) + :464-474 (paint).