// Auto-capture root script for EVEngine examples. // // Mirrors the engine's standard src/scripts/load.nut startup sequence (bind // modules, create window, load config.nut + main.nut, call eve_init) and then // runs the frame loop. After `capture_frame` frames it saves the actual // presented frame via gfx.saveFramePng(capture_path) and exits — the PNG is // written by the engine from the swapchain readback, so it is exactly what the // engine rendered. // // The game directory may contain an optional `capture_settings.nut`: // capture_path <- "C:/path/out.png"; // absolute or game-relative // capture_frame <- 180; // frame index to capture at // capture_tries <- 15; // max extra frames to retry // Without it the defaults below apply (capture.png after 180 frames). function file_exists(path) { try { file(path, "r").close(); return true; } catch (e) { return false; } } function format_script_error(e) { if ("lastScriptError" in eve) { local stacked = eve.lastScriptError(); if (typeof stacked == "string" && stacked.len() > 0) return stacked; } return "" + e; } function has_module(slot) { return slot in getroottable() && getroottable()[slot] != null; } config <- { width = 800 height = 600 title = "EVEngine" debug = false hotReload = false }; if (file_exists("config.nut")) dofile("config.nut"); // Bind the modules this build actually contains. foreach (m in eve.moduleList) { try { getroottable()[m.slot] <- eve[m.cls](); } catch (e) { print("module " + m.cls + " failed to initialize: " + e + "\n"); } } if (!has_module("win") || !has_module("gfx")) { print("engine build is missing the window or graphics module\n"); return; } local s = eve.WindowSettings(); s.width = config.width; s.height = config.height; s.centered = true; if (!win.setWindowSettings(s)) { print("setWindowSettings failed\n"); return; } config.width = win.getWidth(); config.height = win.getHeight(); // Node-style async (Promise / nextTick / setTimeout), same as load.nut. if ("asyncScript" in eve && eve.asyncScript != null && eve.asyncScript != "") { try { compilestring(eve.asyncScript)(); } catch (e) { print("async runtime failed to load: " + e + "\n"); } } else if (file_exists("async.nut")) { try { dofile("async.nut"); } catch (e) { print("async.nut failed to load: " + e + "\n"); } } eve_init <- function() {}; eve_update <- function(dt) { if (has_module("scene")) scene.updateTransformsAll(); }; eve_render <- function() { gfx.clear(); }; eve_quit <- function() {}; // Capture configuration (overridable by capture_settings.nut in the game dir). capture_path <- "capture.png"; capture_frame <- 180; capture_tries <- 15; if (file_exists("capture_settings.nut")) { try { dofile("capture_settings.nut"); } catch (e) { print("capture_settings.nut failed: " + e + "\n"); } } if (file_exists("main.nut")) { try { dofile("main.nut"); } catch (e) { print("main.nut failed: " + e + "\n"); return; } } try { eve_init(); } catch (e) { print("eve_init failed: " + e + "\n"); } startup_frames <- 45; frame <- 0; left_to_try <- capture_tries + 1; captured <- false; while (true) { platform_event.pump(); local running = true; while (true) { local name = platform_event.poll(); if (name == "") break; local data = platform_event.getLastData(); if ("async_dispatch_event" in getroottable()) async_dispatch_event(name, data); if (name == "quit") { if (startup_frames <= 0) running = false; } } if (startup_frames > 0) startup_frames -= 1; if (!running) break; local dt = has_module("timer") ? timer.step() : 0.016; try { if ("async_pump" in getroottable()) async_pump(); eve_update(dt); if ("async_pump" in getroottable()) async_pump(); eve_render(); } catch (e) { print("frame error: " + format_script_error(e) + "\n"); } try { gfx.present(); if (has_module("ui")) ui.dispatchEvents(); } catch (e) { print("present error: " + format_script_error(e) + "\n"); } frame++; if (frame >= capture_frame && !captured && left_to_try > 0) { left_to_try -= 1; if (gfx.saveFramePng(capture_path)) { print("CAPTURED " + capture_path + "\n"); captured = true; break; } // First call only enables readback; the next presented frame lands in // the buffer, so keep retrying on following frames. } } try { eve_quit(); } catch (e) { } win.close(); if (!captured) print("CAPTURE_FAILED\n");