Simulator 2.4.0: playdate.keyPressed(key) - content of key parameter has changed

playdate.keyPressed(key) no longer seems to be called behave differently in Simulator 2.4.0?

  • Simulator 2.3.1 doesn't have this issue

I'm on a 2021 MBP with M1 Pro running Sonoma 14.3.1. My unchanged Super ICARUS code runs fine on Simulator 2.3.1 but not on 2.4.0.

I second this.

I'm on Mac Sonoma M1 using the simulator, the keyboard presses seem to not be functioning.

playdate.keyPressed(key) is working on Simulator Version 2.4.0 for me. I'm on a 2020 M1 Mac Mini with Sonoma 14.2.1 using a Logitech MX Keys Mini keyboard.

1 Like

You're right, it does fire.

Getting closer to the heart of the issue: conditionals inside it no longer work as expected/previously.

Testing key == "m", even though both are strings, returns false.

This is because in 2.4.0 the string value passed to playdate.keyPressed(key) is length 2. :thinking:

Repro

import "CoreLibs/graphics"

function playdate.keyPressed(key)
	print("|m|", type("m"), string.len("m"), "|"..key.."|", type(key), string.len(key), "==", key == "m")
	if key == "m" then
		print("test", "OK")
	else
		print("test", "bad")
	end
end

function playdate.update()
	playdate.graphics.drawText("*PRESS m KEY*",150,110)
end

Expected output

|m|	string	1	|m|	string	1	==	true
test	OK

Actual output

|m|	string	1	|m	string	2	==	false
test	bad

...is there an extra null byte at the end? that's what I could think of -- maybe pushBytes is pushing both the key value and the null byte ending it.

I didn't have much time to investigate further.

I did try trimming everything but alphanumerics using a regex but it didn't make any difference. But I was so short on time and tired I can't say for sure that I did it correctly.

It's interesting that the trailing pipe character is also discarded in the actual output. Maybe that implies there's a null byte in-between.

Yes. It is a null byte.

Repro: keyPressed_null.lua
import "CoreLibs/graphics"
function playdate.keyPressed(key)
    print("keyPressed:", #key, "characters long.")
    for i = 1, #key do
        print(string.format("  0x%02x", string.byte(string.sub(key, i)) .. " "))
    end
end
function playdate.update() end
playdate.graphics.drawText("*PRESS A KEY*",150,110)

Ouput

keyPressed:	2	characters long.
  0x6d
  0x00
3 Likes

When I added the serial message handler I refactored the keyPressed/Released code to handle arbitrary strings, naively assumed I needed to give it a null terminated string and didn't think to test it. :person_facepalming:

A fix is in, will get 2.4.1 out asap!

5 Likes

Thanks Dave, always with the speedy fixes.

Is there a use case for keyPressed working with arbitrary strings (ie: not single key presses)?

Here's the relevant bit from the release notes about why the arbitrary strings:

  • Added callbacks for receiving messages via the serial port msg command
    Lua: playdate.serialMessageReceived(message)
    C: playdate->system->setSerialMessageCallback(void (*callback)(const char* data));
    As a convenient way to get data into the Playdate runtime I've added a msg command that takes a string at a time and sends it to a callback. This is much easier than sending it one character at a time with btn or using eval which takes compiled Lua bytecode.

They go to the playdate.serialMessageReceived() callback instead of keyPressed/Released, but work the same. Or maybe I misunderstood your question?

1 Like