Log In  

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

P#32658 2016-11-20 20:46 ( Edited 2016-11-23 17:13)

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
P#32659 2016-11-20 21:34 ( Edited 2016-11-21 02:34)

ha yes, totally makes sense. thanks cheepicus!

P#32660 2016-11-20 22:43 ( Edited 2016-11-21 03:43)

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.

P#32662 2016-11-20 23:03 ( Edited 2016-11-21 04:03)

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 
P#32714 2016-11-23 12:13 ( Edited 2016-11-23 17:13)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-29 11:03:50 | 0.009s | Q:15