wasm4 icon indicating copy to clipboard operation
wasm4 copied to clipboard

api to skip frames

Open yamt opened this issue 1 year ago • 5 comments

for games, it's often more important to provide a constant game speed than drawing every single frames. it would be nicer for wasm4 to provide a mechanism for skipping frames. especially for graphics-heavy games on slow hardware.

eg. a simple timestamp (maybe in fps) on the shared memory area.

static unsigned int n = 0;

update()
{
  if (TIMESTAMP > n++) {
    /* somehow reduce computation for this frame */
  }
}

yamt avatar Oct 01 '24 11:10 yamt

You could set the SYSTEM_PRESERVE_FRAMEBUFFER flag in SYSTEM_FLAGS and then skip drawing depending on frame number.

Example drawing at 30fps:

#include "wasm4.h"

const size_t FRAME_SKIP = 2; // Draw every 2nd frame

void start() {
    *SYSTEM_FLAGS |= SYSTEM_PRESERVE_FRAMEBUFFER;
}

size_t frame = 0;
void update() {
    frame++;
    if ((frame % FRAME_SKIP) == 0) {
        // Regular processing here
        rect(10, 10, 32, 32);
    }
}

JerwuQu avatar Dec 03 '24 20:12 JerwuQu

if you know the system is fast enough to handle 30 fps, maybe it works. otherwise, maybe not.

also, i prefer an api to allow 60 fps on the first machine.

btw, i think it can be useful to provide a way for the update callback to tell wasm4 that it made no user-visible changes to the frame buffer/palette/etc. so that wasm4 can skip its entire graphic processing for the frame.

yamt avatar Dec 05 '24 14:12 yamt

I suppose in addition to SYSTEM_PRESERVE_FRAMEBUFFER there could be SYSTEM_SKIP_RENDERING for skipping the screen-blit completely. 🤔 There could also be a SYSTEM_REQUEST_LOW_FRAMERATE that is set by the runtime rather than the game, letting the game detect it and then use the SYSTEM_SKIP_RENDERING flag however often it wants. Games that don't support it would simply ignore it. Though... I'm not sure if devices that can't even blit the framebuffer to screen at 60fps are in scope for WASM-4, since that's part of its design, and working around it introduces this kind of complexity.

Instead, I would suggest looking into transpiling the WASM to your hardware and running games natively instead. There this cool project called wasm4-aot specifically for that you could take a look at!

JerwuQu avatar Dec 05 '24 18:12 JerwuQu

I suppose in addition to SYSTEM_PRESERVE_FRAMEBUFFER there could be SYSTEM_SKIP_RENDERING for skipping the screen-blit completely. 🤔 There could also be a SYSTEM_REQUEST_LOW_FRAMERATE that is set by the runtime rather than the game, letting the game detect it and then use the SYSTEM_SKIP_RENDERING flag however often it wants. Games that don't support it would simply ignore it. Though... I'm not sure if devices that can't even blit the framebuffer to screen at 60fps are in scope for WASM-4, since that's part of its design, and working around it introduces this kind of complexity.

Instead, I would suggest looking into transpiling the WASM to your hardware and running games natively instead. There this cool project called wasm4-aot specifically for that you could take a look at!

well, i also want to reduce power consumption eg. when playing non-realtime games like puzzles on a phone.

yamt avatar Dec 07 '24 14:12 yamt

I like the idea of SYSTEM_SKIP_RENDERING being settable by the game. We could also have it be settable by the runtime for frames that it knows won't be rendered anyways, such as during a netplay rollback fast-forward.

We could also have a system flag settable by the game to skip the entire update next frame, basically opting into 30hz update mode?

I also agree with @JerwuQu though that we probably shouldn't go crazy with supporting devices that can't run at 60hz. Not sure!

aduros avatar Dec 07 '24 20:12 aduros