Closed Isotarge closed 3 years ago
Can confirm this. Furthermore, nothing in gui
works with event.onframeend
. Here's a script to repro:
local function main()
print("output every frame")
gui.pixelText(20, 20, "draw every frame")
end
event.onframeend(main)
When run, this script prints to the console every frame, but it doesn't draw the text.
I think there are some events that will still have this problem. If drawing in a callback still isn't working for you, but you believe your use-case is reasonable, let me know.
Thanks for taking a look at this, I just downloaded the dev build of 643d7b12dd8a69e3318e10bbdc6e64a0a622e3b7 and unfortunately the script I posted up the top of this issue report still doesn't draw a rectangle when the emulator is unpaused.
That's working as intended. If I refactor the script and include the implied DrawNew
/DrawFinish
, it's clear what's actually happening:
local drawRect = function()
gui.drawText(32, 32, "Rect");
gui.drawRectangle(32, 32, 32, 16);
end
event.onframeend(function()
-- gui.DrawNew("emu", true);
if not client.ispaused() then
drawRect();
end
-- gui.DrawFinish();
end);
while true do
-- gui.DrawNew("emu", true); -- not guarded by `if client.ispaused()` so will always clear scripts' drawing when the Lua Console updates
if client.ispaused() then
drawRect();
end
-- gui.DrawFinish();
emu.yield();
end
With blessings from @adelikat I have an idea for making the automatic locking (DrawNew
) less aggressive, so nothing will be cleared until the next gui
lib call.
I see what you mean, and I like the idea of making the automatic locking less aggressive. If it helps I can explain why we've set it up this way for ScriptHawk. We're using the onframeend hook to read memory and redraw everything exactly once per frame while the emulator is running, but the while true emu.yield() hook reads & redraws as fast as possible while emulation is paused to make sure the OSD doesn't desync from RAM if you poke & prod stuff while paused. It's been a long time, but if I recall correctly, doing everything in the while true loop (even while emulation is unpaused) caused performance issues. Perhaps a reasonable compromise could be something like this (eliminating the onframeend hook altogether)?
while true do
-- gui.DrawNew("emu", true); -- not guarded by `if client.ispaused()` so will always clear scripts' drawing when the Lua Console updates
drawRect();
if client.ispaused() then
emu.yield();
else
emu.frameadvance();
end
-- gui.DrawFinish();
end
Tried this and no luck sadly :( It never prints paused for me, on screen or in the console.
while true do
gui.drawRectangle(32, 32, 32, 16);
if client.ispaused() then
print("Paused");
gui.text(32, 32, "PAUSED");
gui.drawText(32, 32, "PAUSED");
emu.yield();
else
print("Running");
gui.text(32, 40, "RUNNING");
gui.drawText(32, 40, "RUNNING");
emu.frameadvance();
end
end
Looking at the script in OP again (using 2.5.2), the rectangle isn't actually drawn every frame while paused, even though the draw calls are every frame. Only when unpausing do the draw calls from the while loop take effect, before the draw calls from the event clear them on the next frame. What I mean by that is if you make them draw in red and blue, as below, you'll see a flash of red when unpausing. While paused, you see the stale blue rect from the last frame before you paused.
local drawRect = function(b)
local y = b and 32 or 64;
local c = b and 0xFF0000FF or 0xFFFF0000;
console.write(b and "B" or "A");
gui.drawText(32, y, "Rect", c);
gui.drawRectangle(32, y, 32, 16, c);
end
event.onframeend(function()
if not client.ispaused() then
drawRect(true);
end
end);
while true do
if client.ispaused() then
drawRect(false);
end
emu.yield();
end
I've committed a8b1e06e4 with my suggested change from above. Though it doesn't restore the old behaviour, your script will now work as you originally intended.
Summary
On 2.6 (and the dev build of adca19c30a816c1627a7c436cc8776a918ba5f36) the following Lua script no longer draws the rectangle when the emulator is unpaused. On 2.5.2 and before it draws a rectangle every frame when the emulator is unpaused as expected.
Repro
Host env.