diff --git a/specs/t27f/reel.t27 b/specs/t27f/reel.t27 index 55b86c7752..760cebf7c8 100644 --- a/specs/t27f/reel.t27 +++ b/specs/t27f/reel.t27 @@ -24,7 +24,7 @@ ; answer reaches the user everywhere; the desktop Code tab opens it in its Browser pane. CHANNEL_* below. ; Host: gHashTag/t27-mcp t27f_view draws stills of the demo reel from a wasm build of this file's ; Zig output (bodies) and its gen-js output (constants); see "host entry points" below. -; Not claimed: no video has been rendered, and no host but t27f_view imports this file. +; Not claimed: no video has been rendered. Importers: t27f_view (above) and T27fDeck (specs/t27f/deck.t27). ; phi^2 + 1/phi^2 = 3 | TRINITY module T27fReel; @@ -514,6 +514,36 @@ pub fn demo_r(f: i32, preset: u8) -> i32 { return screen_r(camera_hw(DEMO_COUNT, DEMO_KIND, DEMO_CELL, DEMO_FRAMES, f), preset); } +/// The demo camera itself at base frame f, for a host that places the map somewhere other than the +/// full frame (T27fDeck slide_x / slide_y / slide_r take exactly these three). +pub fn demo_cx(f: i32) -> i32 { + return camera_cx(DEMO_COUNT, DEMO_KIND, DEMO_CELL, DEMO_FRAMES, f); +} + +pub fn demo_cy(f: i32) -> i32 { + return camera_cy(DEMO_COUNT, DEMO_KIND, DEMO_CELL, DEMO_LENS, DEMO_FRAMES, f); +} + +pub fn demo_hw(f: i32) -> i32 { + return camera_hw(DEMO_COUNT, DEMO_KIND, DEMO_CELL, DEMO_FRAMES, f); +} + +/// The kind of a demo scene, or SCENE_KIND_COUNT (no kind) for a scene the demo does not have. +pub fn demo_kind(scene: i32) -> u8 { + if (scene < 0 or scene >= DEMO_COUNT) { + return SCENE_KIND_COUNT; + } + return DEMO_KIND[@intCast(scene)]; +} + +/// The first base frame of a demo scene, or END_OF_REEL. +pub fn demo_scene_start(scene: i32) -> i32 { + if (scene < 0 or scene >= DEMO_COUNT) { + return END_OF_REEL; + } + return scene_start(DEMO_FRAMES, scene); +} + /// Corner i of a cell on screen: what a host draws as the cell's polygon. pub fn demo_corner_sx(f: i32, preset: u8, cell: i32, i: i32) -> i32 { return demo_sx(f, preset, cell_x(cell) + corner_dx(i)); @@ -750,6 +780,32 @@ test demo_entry_points_match_the_reel { assert demo_sy(demo_still(1), PRESET_WIDE, lens_cy(0)) == 360; } +test demo_camera_is_the_reel_camera { + // the camera a host reads is the one demo_sx / demo_sy / demo_r already use + assert demo_cx(224) == cell_x(10); + assert demo_cy(224) == cell_y(10); + assert demo_hw(224) == FOCUS_HW; + assert demo_cy(demo_still(1)) == lens_cy(0); + var s : i32 = 0; + while (s < DEMO_COUNT) { + const f : i32 = demo_still(s); + assert demo_sx(f, PRESET_TALL, 0) == screen_x(demo_cx(f), demo_hw(f), PRESET_TALL, 0); + assert demo_sy(f, PRESET_TALL, 0) == screen_y(demo_cy(f), demo_hw(f), PRESET_TALL, 0); + assert demo_scene_at(demo_scene_start(s)) == s; + assert demo_scene_start(s) <= f; + s = s + 1; + } + // the demo has no title scene: scene 0 is the overview, scene 4 the call + assert demo_kind(0) == SCENE_OVERVIEW; + assert demo_kind(2) == SCENE_FOCUS; + assert demo_kind(4) == SCENE_CALL; + assert demo_kind(5) == SCENE_KIND_COUNT; + assert demo_kind(-1) == SCENE_KIND_COUNT; + assert demo_scene_start(0) == 0; + assert demo_scene_start(2) == 135; + assert demo_scene_start(5) == END_OF_REEL; +} + test overview_still_fits_every_frame { // every corner of every cell of the first still lands inside the picture on every preset var p : u8 = 0;