diff --git a/changes/baked-textures.md b/changes/baked-textures.md new file mode 100644 index 00000000..7f7fcb4b --- /dev/null +++ b/changes/baked-textures.md @@ -0,0 +1,8 @@ +bump: minor +type: feature +**Textures a game baked at build time are read before the PNG.** `png_decode` first takes +`assets/baked/png/.tex` (a game's `ludic bake` output: the samples, ready to upload), and a cut-out +load (`tex_load_ex` with dilate) first takes `assets/baked/cutouts/.bc7` (padded as `tex_dilate` +pads, then BC7 with its mips) - so a boot decodes, pads and converts nothing it can take ready-made. Both +are ludic.base's baked form, read by hand (baked_tex.ludic: the "LBAK" header, the key and version); a +missing or stale one falls back to the PNG as before. `tex_load_dds_at` reads a .dds at an offset. diff --git a/changes/dilate-parallel.md b/changes/dilate-parallel.md new file mode 100644 index 00000000..345109c2 --- /dev/null +++ b/changes/dilate-parallel.md @@ -0,0 +1,8 @@ +bump: patch +type: performance +**Cut-out edge padding runs on every core.** `tex_dilate`'s passes hand their rows, sixteen at a time, to +`Job.parallel_for`: within a pass a row writes only its own still-masked texels and reads only +neighbours the mask already let go, so the bytes are the ones the single-threaded loop made. The worker +is handed plain buffers in a `DilateJob` and makes nothing. `tex_dilate_bytes` is the slice-taking +form (safe_api.ludic), and `examples/rendering/dilate.ludic` holds the result against the old loop +(prints DILATE OK). It was 206 ms of the main thread in a Maroon Lake boot. diff --git a/changes/inflate-context.md b/changes/inflate-context.md new file mode 100644 index 00000000..56c292c0 --- /dev/null +++ b/changes/inflate-context.md @@ -0,0 +1,8 @@ +bump: minor +type: feature +**Inflate in a caller-owned context.** `ZInflate` holds everything one inflate works in - the bit reader, +the RFC's length and distance tables, and every Huffman table and scratch list a block builds - made once +by `z_inflate_new()` and rebuilt in place, so an inflate allocates nothing and each thread that inflates +holds a context of its own. `z_inflate_in(z, src, len, out, cap)`, `z_uncompress_in` (zlib) and +`z_gunzip_in` (gzip) take the context; `z_inflate` / `z_uncompress` / `z_gunzip` keep their signatures, +working in the one context `RtInflateState` holds, so no caller changes. diff --git a/changes/zones.md b/changes/zones.md new file mode 100644 index 00000000..558be25a --- /dev/null +++ b/changes/zones.md @@ -0,0 +1,10 @@ +bump: minor +type: feature +**`ludic.zones`: where a world is simulated.** A disc per player, `(x, z, r)` with `r = zones_radius(fog)` +(the fog distance plus 40 m, never under 150 m, 900 m with no fog), overlapping discs merged into +clusters with a bounding circle, and `zones_contains` / `zones_nearest` for everything that asks; fixed +arrays, nothing made per frame. The packages that simulate now ask their world port whether a place is +simulated, with a default of everywhere: `WildlifeWorld.active` (an animal outside is frozen - its +state kept, no dice drawn), `NpcWorld.active` (a walker outside is frozen, and nobody is born outside), +`VehicleWorld.active` (a moored boat outside is left where it lies) and `ThingsWorld.restocks` (a +morning restocks only inside). diff --git a/examples/library/ui_first_show.ludic b/examples/library/ui_first_show.ludic new file mode 100644 index 00000000..c3aeb648 --- /dev/null +++ b/examples/library/ui_first_show.ludic @@ -0,0 +1,27 @@ +# ui_first_show.ludic - a component shown for the first time once the fence is judging (a prompt's key +# hint mid-walk) makes its instance's props and model: declared, once per instance, and the failing +# fence lets it through; hidden and shown again, the instance is reused and nothing more is made: +# bad 0 shown 3 +import "ludic.ui" +import "ui_first_show_parts/Cell.ludic" +import "ui_first_show_parts/Host.ludic" +program UiFirstShow { + numbers float + function frame(ui_st: mut UiState) -> UiNode { + let root: UiNode = ui_nodes(ui_st, "Host", null) + ui_place(ui_st, root, 0.0, 0.0, 400.0, 400.0) + return root + } + entry (ui_st: mut UiState) { + var shown = 0 + for f in 0 .. 1400 { + let root = frame(ui_st) + if f == 700 or f == 900 or f == 1000 or f == 1100 or f == 1200 { + ui_press(ui_st, root.children[0].children[0]) + if f != 900 and f != 1100 { shown += 1 } + } + Mem.frame() + } + print(`bad {Mem.bad_frames()} shown {shown}`) + } +} diff --git a/examples/library/ui_first_show_parts/Cell.lss b/examples/library/ui_first_show_parts/Cell.lss new file mode 100644 index 00000000..b8c03a5a --- /dev/null +++ b/examples/library/ui_first_show_parts/Cell.lss @@ -0,0 +1 @@ +.cell { width: 100px; height: 40px } diff --git a/examples/library/ui_first_show_parts/Cell.ludic b/examples/library/ui_first_show_parts/Cell.ludic new file mode 100644 index 00000000..0ed005d7 --- /dev/null +++ b/examples/library/ui_first_show_parts/Cell.ludic @@ -0,0 +1,3 @@ +component Cell { + prop caption: string = "" +} diff --git a/examples/library/ui_first_show_parts/Cell.xml b/examples/library/ui_first_show_parts/Cell.xml new file mode 100644 index 00000000..a88076ab --- /dev/null +++ b/examples/library/ui_first_show_parts/Cell.xml @@ -0,0 +1,3 @@ +
+ +
diff --git a/examples/library/ui_first_show_parts/Host.lss b/examples/library/ui_first_show_parts/Host.lss new file mode 100644 index 00000000..1bac0ccf --- /dev/null +++ b/examples/library/ui_first_show_parts/Host.lss @@ -0,0 +1 @@ +.t { width: 60px; height: 30px } diff --git a/examples/library/ui_first_show_parts/Host.ludic b/examples/library/ui_first_show_parts/Host.ludic new file mode 100644 index 00000000..a8e1b5ba --- /dev/null +++ b/examples/library/ui_first_show_parts/Host.ludic @@ -0,0 +1,4 @@ +component Host { + state on: bool = false + on flip() { on = not on } +} diff --git a/examples/library/ui_first_show_parts/Host.xml b/examples/library/ui_first_show_parts/Host.xml new file mode 100644 index 00000000..29140558 --- /dev/null +++ b/examples/library/ui_first_show_parts/Host.xml @@ -0,0 +1,4 @@ +
+ + +
diff --git a/examples/library/ui_select_disabled.ludic b/examples/library/ui_select_disabled.ludic new file mode 100644 index 00000000..2adba55d --- /dev/null +++ b/examples/library/ui_select_disabled.ludic @@ -0,0 +1,55 @@ +# ui_select_disabled.ludic -