code wiki / _hdl_build / nx_anim_gate.nx
nx_anim_gate.nx source
↩ module page · 93 lines · 3064 B
1// nx_anim_gate.nx -- proves the per-frame render LOOP (basis of real-time): render the world at 4 yaw angles
2// (a 90deg sweep) by varying the spec's camera, composite into one 2x2 contact sheet. Same render_world, just a
3// loop over frames -> motion. Reuses nx_voxel_world (no new render code). exit 0 = rendered. license_tier: ORIGINAL
4import "nx_syscalls.nx"
5import "nx_voxel_world.nx"
6
7const SW: i64 = 640
8const SH: i64 = 480
9
10func mk(seed: i64, n: i64, water: i64, maxh: i64, latsp: i64,
11 psin: i64, pcos: i64, ysin: i64, ycos: i64, push: i64, focal: i64, style: i64) -> *i64 {
12 let s: *i64 = sys_mmap(12 * 8) as *i64
13 s[0] = seed; s[1] = n; s[2] = water; s[3] = maxh; s[4] = latsp
14 s[5] = psin; s[6] = pcos; s[7] = ysin; s[8] = ycos; s[9] = push; s[10] = focal; s[11] = style
15 return s
16}
17func put_u32le(b: *u8, o: i64, v: i64) -> i64 {
18 b[o] = (v & 0xff) as u8
19 b[o + 1] = ((v >> 8) & 0xff) as u8
20 b[o + 2] = ((v >> 16) & 0xff) as u8
21 b[o + 3] = ((v >> 24) & 0xff) as u8
22 return 0
23}
24func write_sheet(fb: *i64, path: *u8) -> i64 {
25 let pix: i64 = SW * SH * 3
26 let total: i64 = 54 + pix
27 let b: *u8 = sys_mmap(total) as *u8
28 b[0] = 66 as u8
29 b[1] = 77 as u8
30 put_u32le(b, 2, total)
31 put_u32le(b, 10, 54)
32 put_u32le(b, 14, 40)
33 put_u32le(b, 18, SW)
34 put_u32le(b, 22, SH)
35 b[26] = 1 as u8
36 b[28] = 24 as u8
37 put_u32le(b, 34, pix)
38 var o: i64 = 54
39 var ry: i64 = 0
40 while ry < SH {
41 let syrow: i64 = SH - 1 - ry
42 var x: i64 = 0
43 while x < SW {
44 let c: i64 = fb[syrow * SW + x]
45 b[o] = ((c >> 16) & 0xff) as u8
46 b[o + 1] = ((c >> 8) & 0xff) as u8
47 b[o + 2] = (c & 0xff) as u8
48 o = o + 3
49 x = x + 1
50 }
51 ry = ry + 1
52 }
53 let fd: i64 = sys_openat_wr(path, 0x1a4)
54 if fd < 0 { return 0 - 1 }
55 sys_write(fd, b, total)
56 sys_close(fd)
57 return 0
58}
59
60func main() -> i64 {
61 let fb: *i64 = sys_mmap(world_fb_bytes()) as *i64
62 let zb: *i64 = sys_mmap(world_fb_bytes()) as *i64
63 let sheet: *i64 = sys_mmap(SW * SH * 8) as *i64
64 var i: i64 = 0
65 while i < SW * SH { sheet[i] = world_sky(); i = i + 1 }
66
67 let ycos: *i64 = sys_mmap(4 * 8) as *i64
68 let ysin: *i64 = sys_mmap(4 * 8) as *i64
69 ycos[0] = 1000; ysin[0] = 0
70 ycos[1] = 866; ysin[1] = 500
71 ycos[2] = 500; ysin[2] = 866
72 ycos[3] = 0; ysin[3] = 1000
73
74 var f: i64 = 0
75 while f < 4 {
76 render_world(mk(7, 14, 1, 6, 4, 574, 819, ysin[f], ycos[f], 24, 300, 0), fb, zb)
77 // composite the 320x240 frame into quadrant (col=f%2, row=f/2) of the sheet.
78 let qx: i64 = (f % 2) * 320
79 let qy: i64 = (f / 2) * 240
80 var y: i64 = 0
81 while y < 240 {
82 var x: i64 = 0
83 while x < 320 {
84 sheet[(qy + y) * SW + (qx + x)] = fb[y * 320 + x]
85 x = x + 1
86 }
87 y = y + 1
88 }
89 f = f + 1
90 }
91 write_sheet(sheet, "web_assets/_game_build/world_anim.bmp" as *u8)
92 return 0
93}