diff --git a/src/runner.c b/src/runner.c index f0fd443b9..7d3ac55f1 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2296,6 +2296,11 @@ Runner* Runner_create(DataWin* dataWin, VMContext* vm, Renderer* renderer, FileS runner->fileSystem = fileSystem; runner->audioSystem = audioSystem; runner->frameCount = 0; + double initialFps = (double)dataWin->gen8.gms2FPS; + runner->fps = initialFps; + runner->fpsReal = initialFps; + runner->fpsWindowStartFrame = 0; + runner->fpsWindowStartNanos = nowNanos(); runner->osType = OS_WINDOWS; runner->keyboard = RunnerKeyboard_create(); runner->gamepads = RunnerGamepad_create(); @@ -3833,7 +3838,7 @@ void Runner_step(Runner* runner) { if (entry->units == 1) { entry->elapsed += (double)1.0; } else { - entry->elapsed += runner->deltaTime / (double)1000000.0; + entry->elapsed += (double)runner->deltaTime / (double)1000000.0; } if (entry->elapsed >= entry->period) { @@ -4094,6 +4099,18 @@ void Runner_step(Runner* runner) { Runner_cleanupDestroyedInstances(runner); Runner_sweepDeadStructs(runner); + // Measure fps builtin + if (nowNanos() - runner->fpsWindowStartNanos >= (uint64_t)1000000000) { + runner->fps = (double)(runner->frameCount - runner->fpsWindowStartFrame); + runner->fpsWindowStartFrame = runner->frameCount; + runner->fpsWindowStartNanos = nowNanos(); + } + + // Measure fps_real builtin + if (runner->deltaTime > 0.0) { + runner->fpsReal = (double)(1000000.0 / runner->deltaTime); + } + runner->frameCount++; } diff --git a/src/runner.h b/src/runner.h index 9efb1d4e4..81ff2a243 100644 --- a/src/runner.h +++ b/src/runner.h @@ -549,7 +549,13 @@ struct Runner { Instance** structInstances; int32_t forcedDepth; // The time between the last frame and the current frame, stored in microseconds. - double deltaTime; + GMLReal deltaTime; + // Current frame rate (capped at room speed) + double fps; // last measured frames-per-second value returned to GML + uint64_t fpsWindowStartNanos; // nowNanos() at the start of the measurement window + int fpsWindowStartFrame; // runner->frameCount at the start of the measurement window + // Real-time measured frame rate for the "fps_real" builtin, computed from deltaTime. + double fpsReal; char* windowTitle; // ===[ Builtin function state ]=== diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 51241c919..246013437 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -323,6 +323,7 @@ static const BuiltinVarEntry BUILTIN_VAR_TABLE[] = { { "direction", BUILTIN_VAR_DIRECTION }, { "false", BUILTIN_VAR_FALSE }, { "fps", BUILTIN_VAR_FPS }, + { "fps_real", BUILTIN_VAR_FPS_REAL }, { "friction", BUILTIN_VAR_FRICTION }, { "gp_axislh", BUILTIN_VAR_GP_AXIS_LH }, { "gp_axislv", BUILTIN_VAR_GP_AXIS_LV }, @@ -1283,7 +1284,9 @@ RValue VMBuiltins_getVariable(VMContext* ctx, Instance* inst, int16_t builtinVar return RValue_makeReal((GMLReal) INSTANCE_NOONE); } case BUILTIN_VAR_FPS: - return RValue_makeReal(ctx->dataWin->gen8.gms2FPS); + return RValue_makeReal(runner->fps); + case BUILTIN_VAR_FPS_REAL: + return RValue_makeReal(runner->fpsReal); case BUILTIN_VAR_DEBUG_MODE: return RValue_makeBool(false); case BUILTIN_VAR_DELTA_TIME: @@ -5674,7 +5677,7 @@ static RValue builtin_ds_queue_read(VMContext* ctx, RValue* args, MAYBE_UNUSED i if (s.error || 0 > last) { free(bytes); return RValue_makeBool(false); } // Replace queue contents. - { + { repeat(arrlen(q->items), i) { RValue_free(&q->items[i]); } @@ -18221,7 +18224,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "tile_set_empty", builtin_tile_set_empty); VM_registerBuiltin(ctx, "tile_set_mirror", builtin_tile_set_mirror); VM_registerBuiltin(ctx, "tile_set_flip", builtin_tile_set_flip); - VM_registerBuiltin(ctx, "tile_set_rotate", builtin_tile_set_rotate); + VM_registerBuiltin(ctx, "tile_set_rotate", builtin_tile_set_rotate); VM_registerBuiltin(ctx, "tilemap_set", builtin_tilemap_set); VM_registerBuiltin(ctx, "tilemap_set_at_pixel", builtin_tilemap_set_at_pixel); #endif diff --git a/src/vm_builtins.h b/src/vm_builtins.h index b8cd35674..bdc57002f 100644 --- a/src/vm_builtins.h +++ b/src/vm_builtins.h @@ -238,6 +238,7 @@ typedef enum { BUILTIN_VAR_INSTANCE_COUNT, BUILTIN_VAR_INSTANCE_ID, BUILTIN_VAR_FPS, + BUILTIN_VAR_FPS_REAL, BUILTIN_VAR_DEBUG_MODE, BUILTIN_VAR_DELTA_TIME,