isn't pico8 supposed to drop to 30fps when your cpu load exceeds 100%?
that's not what I am seeing:
text="dlfkjhglskdhj shlksgjhlksjhslk sdhlkjshgk" scx=128 stlim=1 function _update60() scx-=1 if (scx<-#text*4) scx=128 if (btnp(0)) stlim -= (btn(4) and 0.1 or 0.001) if (btnp(1)) stlim += (btn(4) and 0.1 or 0.001) end function _draw() local st=0 cls() print(text, scx,64, 7) repeat st=stat(1) until(st>=stlim) print('target: '..stlim..'\nstat(1): '..st,0,44,7) end |
that's a scroll text, one pixel per frame. use c, left & right to change cpu load.
the scrolling is smooth at 60 pixels per second until stat(1)==1.012
beyond that, pico should drop to 30fps, and you should see the text scroll at half-speed, right?
something else happens: the scrolling only gets kind of jerky, but stays at full speed until stat(1)==2.121
it seems _update60() still runs at 60hz with 200% cpu, only video sync gets wonky.
that would mean you can get double cpu power if you don't mind losing synchro.
isn't there a mismatch between code throttling and video syncing ?
edit: same thing with _update(), doesn't really drop to 15fps



When stat(1) gets over 100% it starts running _update() twice per _draw(), so game logic is still happening at the same speed, but drawing FPS is halved, resulting in jerkiness.
If you go up to 200% CPU then you still only get 2 updates per draw, so that's where you start to get real slowdown.
You can test this out by adding code like:
ucount=0 function _update() ucount+=1 ... end function _draw() ... print("ucount: " .. ucount) ucount=0 end |



although that happens when _draw() is heavier than _update(). when it's the other way around, _update() only gets called once and everything is slowed down. clever.



found a way to "disable" this feature by redefining _mainloop():
frames=0 -- #frames to account for ustat=0 -- cpu usage in _update60() dstat=0 -- cpu usage in _draw() function _mainloop() _set_mainloop_exists(2)--for buttons (?) local s1,s2 while (true) do frames=1+_get_frames_skipped() _update_buttons() holdframe() s1=stat(1) _update60() s2=stat(1) _draw() dstat=stat(1)-s2 ustat=s2-s1 flip() end end |
(I'm using this for profiling)
too bad _get_frames_skipped() doesn't really do what its name says:
- won't return more than 1 even after 200% cpu.
- resets something after being called (returns 0 afterwards).
- seems to only work with holdframe() and flip()
so its sole purpose seems to decide whether _update60() should be called twice (no more).
here's the original mainloop (as of 0.1.9b) for reference:
if (_mainloop == nil and (_draw ~= nil or _update ~= nil or _update60 ~= nil)) then _set_mainloop_exists(2) _mainloop = function() while (true) do local num=min(1, _get_frames_skipped()) while (num >= 0) do _update_buttons() if (_update60 ~= nil) then _update60() elseif (_update ~= nil) then _update() end num = num - 1 end holdframe() if (_draw ~= nil) then _draw() end flip() for i=1,5 do if (_get_menu_item_selected(i)) then _pausemenu[i].callback() end end end end end |
[Please log in to post a comment]