code wiki / _hdl_build / nx_scene3d_gate.nx

nx_scene3d_gate.nx source

↩ module page · 78 lines · 4016 B

1// nx_scene3d_gate.nx -- gates the reusable nx_scene3d module AND renders the EXACT frame the live native window 2// (nishi_game.exe) blits: same sc_cube_draw, same 640x480 canvas + params (S=95, focal=460, dist=660, centre 3// 320,264). Screen-capturing the live window is blocked in this headless session (whole desktop reads black), so 4// this proves the window's CONTENT via the working PNG path while the window creation/launch is proven separately. 5// license_tier: ORIGINAL expect_exit: 0 6import "nx_syscalls.nx" 7import "nx_image.nx" 8import "nx_scene3d.nx" 9import "nx_png_write.nx" 10 11func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 12func pn(v: i64) -> i64 { let t: *u8=sys_mmap(24); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let b: *u8=sys_mmap(24); var j: i64=0; while j<k{b[j]=t[k-1-j];j=j+1} sys_write(1,b,k); return 0 } 13 14func main() -> i64 { 15 hw("=== nx_scene3d_gate -- the exact frame nishi_game.exe renders (640x480, sc_cube_draw) ===\n" as *u8) 16 var fails: i64 = 0 17 let W: i64 = 640 18 let H: i64 = 480 19 let npix: i64 = W * H 20 21 let cube: *Cube3D = sc_cube_new(95, 460, 660) 22 let fb: *Image = nx_image_alloc(W, H, 3) 23 let p: *u8 = fb.pixels 24 // window background (12,14,24) + top HUD bar (22,26,40) -- matches the exe 25 var y: i64 = 0 26 while y < H { 27 var x: i64 = 0 28 while x < W { 29 let o: i64 = y * fb.stride + x * 3 30 if y < 40 { p[o]=22 as u8; p[o+1]=26 as u8; p[o+2]=40 as u8 } else { p[o]=12 as u8; p[o+1]=14 as u8; p[o+2]=24 as u8 } 31 x = x + 1 32 } 33 y = y + 1 34 } 35 let zb: *i64 = sys_mmap(npix * 8) as *i64 36 depth_clear(zb, npix, 1000000000) 37 sc_cube_draw(cube, fb, zb, W / 2, H / 2 + 24, 40, 0 - 24) // frame ~ t*3=40 deg (the exe spins t*3) 38 39 // T1: the cube covers a solid region (present, on-canvas) 40 var cover: i64 = 0 41 var maxb: i64 = 0 42 var minb: i64 = 100000 43 var k: i64 = 0 44 while k < npix { 45 let r: i64 = p[k*3] as i64 46 let g: i64 = p[k*3+1] as i64 47 let b: i64 = p[k*3+2] as i64 48 let s: i64 = r + g + b 49 if s > 120 { // brighter than the (12,14,24)=50 / (22,26,40)=88 backgrounds 50 cover = cover + 1 51 if s > maxb { maxb = s } 52 if s < minb { minb = s } 53 } 54 k = k + 1 55 } 56 hw(" cube-cover px=" as *u8); pn(cover); hw(" brightness min=" as *u8); pn(minb); hw(" max=" as *u8); pn(maxb); hw(" spread=" as *u8); pn(maxb-minb); hw("\n" as *u8) 57 var t1: i64 = 0 58 if cover > 8000 { t1 = 1 } // a ~180px cube ~ 20k+ px 59 if t1 == 1 { hw("T1 PASS the lit cube renders a solid on-canvas region (the exe's scene is real)\n" as *u8) } else { fails=fails+1; hw("T1 FAIL cube missing/tiny\n" as *u8) } 60 61 // T2: directional lighting -> brightness spread across faces 62 var t2: i64 = 0 63 if maxb - minb > 120 { t2 = 1 } 64 if t2 == 1 { hw("T2 PASS directional Lambert lighting present (bright face vs shadowed face)\n" as *u8) } else { fails=fails+1; hw("T2 FAIL flat\n" as *u8) } 65 66 // T3: center pixel is on the cube (non-background) 67 let co: i64 = (H/2+24) * fb.stride + (W/2) * 3 68 var t3: i64 = 0 69 if (p[co] as i64) + (p[co+1] as i64) + (p[co+2] as i64) > 120 { t3 = 1 } 70 if t3 == 1 { hw("T3 PASS cube on the canvas center\n" as *u8) } else { fails=fails+1; hw("T3 FAIL center is background\n" as *u8) } 71 72 nx_png_write_rgb("knowledge/nishi_3d_window_frame.png\x00" as *u8, fb.pixels, W, H) 73 hw("artifact -> knowledge/nishi_3d_window_frame.png (the EXACT frame nishi_game.exe blits, sans text HUD)\n" as *u8) 74 75 if fails == 0 { hw("NX-SCENE3D GREEN -- nx_scene3d module verified; the native-window 3D frame is real (lit, depth-sorted, 640x480)\n" as *u8); sys_exit(0); return 0 } 76 hw("NX-SCENE3D RED fails=" as *u8); pn(fails); hw("\n" as *u8) 77 sys_exit(1); return 1 78}