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



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

ha yes, totally makes sense. thanks cheepicus!


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]