How to rotate all video output?

I see that the Simulator has controls for rotating the display. Cool! I'd like to use that in some way.

What's the recommended way of transforming graphics to output at either 90- or 270-degree rotated? I'm hoping there's a way to do it with very little code?

Feels like one day I'll be posting this sort of question on Stackoverflow?

I am not sure I understand the question. You want to do it on device and rotate what is on screen? For example if the player is holding the console with the crank at the bottom?

The little code solution would be probably to take the working frame buffer after everything was rendered and do a drawRotated() on it. But I am not sure how you plan to deal with the aspect ratio.

But the better solution is most likely that the game has to handle it because that really depend of each games.

Ideally I would be able to toggle portrait somehow, which would set the framebuffer to portrait and do a rotation without me caring. Then I'd draw all graphics as usual to the taller buffer without any rotations needed.

But I can't see that's possible right now.

That would be the little code solution. Good for very simple cases but performance wise not ideal.

With a demo
screenOrientation.zip (14.9 KB)

Would be fun to set the orientation based on the accelerator but right now is just two orientation only.

screen = {}

local _mode = "landscape"
local _new_mode = nil

local _render_portrait = playdate.graphics.image.new(240, 400)

function screen.toLandscape()
	_new_mode = "landscape"
end

function screen.toPortrait()
	_new_mode = "portrait"
end

function screen.toggleOrientation()
	if _mode == "portrait" then
		_new_mode = "landscape"
	else
		_new_mode = "portrait"
	end
end

function screen.getSize()
	if _mode == "portrait" then
		return 240, 400
	end
	return 400, 240
end

function screen.beforeDrawing()
	if _new_mode then
		_mode = _new_mode
		_new_mode = nil
	end

	if _mode == "portrait" then
		playdate.graphics.lockFocus(_render_portrait)
	end
end

function screen.afterDrawing()
	if _mode == "portrait" then
		playdate.graphics.unlockFocus()
		_render_portrait:drawRotated(200, 120, -90)
	end
end
1 Like

Cool, Nic! Thanks. Food for thought.

@matt I have a game in-progress where you rotate the Playdate, so the crank is at the bottom. (It's a car racing game.) I didn't do anything elegant for it, programming-wise: I just pre-rotated my graphics and drew them as if the game is happening at landscape-orientation.

It would be cool to have something more elegant!

1 Like

Nic your solution works, but as you mention performance on hardware is not great 4fps (on the simulator it can do up to 50fps, full framerate)

It's the rotation that kills the framerate, but I would expect special case (coordinate swap) rotations like 90-degree or flips to be basically free? I cannot see the code in CoreLibs so I assume the rotations are done in C code?

I added a little code to set portrait orientation on startup using the gyro, and then immediately turn off the gyro.

A bottom-crank for driving is wonderful
Now I want to 3d print a tiny steering wheel in anticipation.

2 Likes