nx_cast_projection_contract_t234.nx source
↩ module page · 91 lines · 3717 B
1// Projection contract for the existing character shader producer. Values retain its current scene-unit policy.
2const CSP_I64_MAX:i64=9223372036854775807
3const CSP_I64_DECIMAL_DIGITS:i64=19
4const CSP_LITERAL_CAP:i64=CSP_I64_DECIMAL_DIGITS*2+3
5static csp_near:i64
6static csp_far:i64
7static csp_guard:i64
8static csp_scale:i64
9// Zero means untouched legacy API; a rejected explicit configuration must never reset.
10static csp_configured:i64
11func csp_valid(n:i64,f:i64,g:i64,s:i64)->i64{
12 if n<=0||f<=n||g<n||g>=f||s<=0{return 0}
13 var t:i64=s
14 while t>1 {if t%10!=0{return 0};t=t/10}
15 if s>CSP_I64_MAX/s||s*s>CSP_I64_MAX/10{return 0}
16 if f>CSP_I64_MAX-n||f>CSP_I64_MAX/n/2||n>CSP_I64_MAX/256{return 0}
17 return 1
18}
19func csp_configure(n:i64,f:i64,g:i64,s:i64)->i64{
20 csp_configured=1
21 if csp_valid(n,f,g,s)!=1{csp_scale=0;return 0}
22 csp_near=n;csp_far=f;csp_guard=g;csp_scale=s;return 1
23}
24func csp_decimal(n:i64,d:i64)->*u8{
25 if n<0||d<=0||d>CSP_I64_MAX/10{return 0 as *u8}
26 var t:i64=d
27 while t>1{if t%10!=0{return 0 as *u8};t=t/10}
28 let out:*u8=sys_mmap_try(CSP_LITERAL_CAP)
29 if (out as i64)<=0{return 0 as *u8}
30 var p:i64=eb_num(out,0,CSP_LITERAL_CAP,n/d)
31 out[p]=46 as u8;p=p+1
32 var r:i64=n%d
33 if r==0{out[p]=48 as u8;p=p+1}
34 while r>0{
35 r=r*10
36 out[p]=(48+r/d) as u8;p=p+1;r=r%d
37 }
38 out[p]=0 as u8;return out
39}
40func csp_literal(k:i64)->*u8{
41 if csp_valid(csp_near,csp_far,csp_guard,csp_scale)!=1{return 0 as *u8}
42 if k==0{return csp_decimal(csp_guard,csp_scale)}
43 if k==1{return csp_decimal(csp_far+csp_near,csp_scale)}
44 if k==2{return csp_decimal(csp_far-csp_near,csp_scale)}
45 if k==3{return csp_decimal(2*csp_near*csp_far,csp_scale*csp_scale)}
46 return 0 as *u8
47}
48func csp_near_q8_for(near:i64,den:i64)->i64{
49 if near<=0||den<=0{return 0-1}
50 if near>CSP_I64_MAX/256{return 0-1}
51 let n:i64=near*256;var q:i64=n/den;if n%den>0{q=q+1};return q
52}
53func csp_near_q8()->i64{
54 if csp_valid(csp_near,csp_far,csp_guard,csp_scale)!=1{return 0-1}
55 return csp_near_q8_for(csp_near,csp_scale)
56}
57func csp_record(out:*u8,cap:i64)->i64{
58 if csp_valid(csp_near,csp_far,csp_guard,csp_scale)!=1{return 0-1}
59 // Metadata capacity is derived from keys plus five signed-i64 decimal fields, checked before writes.
60 let keys:*u8="cast_projection_version=1\ncast_projection_near_num=\ncast_projection_far_num=\ncast_projection_guard_num=\ncast_projection_den=\ncast_projection_near_q8=\n"
61 let need:i64=sir_slen(keys)+5*(CSP_I64_DECIMAL_DIGITS+1)+1
62 if cap<need{return 0-2}
63 var p:i64=eb_put(out,0,cap,"cast_projection_version=1\ncast_projection_near_num=")
64 p=eb_num(out,p,cap,csp_near);p=eb_put(out,p,cap,"\ncast_projection_far_num=")
65 p=eb_num(out,p,cap,csp_far);p=eb_put(out,p,cap,"\ncast_projection_guard_num=")
66 p=eb_num(out,p,cap,csp_guard);p=eb_put(out,p,cap,"\ncast_projection_den=")
67 p=eb_num(out,p,cap,csp_scale);p=eb_put(out,p,cap,"\ncast_projection_near_q8=")
68 p=eb_num(out,p,cap,csp_near_q8());p=eb_put(out,p,cap,"\n");out[p]=0 as u8;return p
69}
70
71func csp_release(text:*u8)->i64{if (text as i64)>0{return sys_munmap_direct(text,CSP_LITERAL_CAP)};return 0}
72
73// Compatibility recipe preserves the existing Beach projection policy in scene-unit thousandths.
74func csp_legacy_beach()->i64{return csp_configure(80,300000,81,1000)}
75func csp_ready()->i64{
76 if csp_configured==0{return csp_legacy_beach()}
77 return csp_valid(csp_near,csp_far,csp_guard,csp_scale)
78}
79// Strict positive decimal CLI admission; overflow refused before multiplication.
80func csp_positive_arg(s:*u8)->i64{
81 if (s as i64)<=0{return 0-1}
82 var n:i64=0;var i:i64=0
83 if s[0]==(0 as u8){return 0-1}
84 while s[i]!=(0 as u8){
85 let d:i64=(s[i] as i64)-48
86 if d<0||d>9{return 0-1}
87 if n>(CSP_I64_MAX-d)/10{return 0-1}
88 n=n*10+d;i=i+1
89 }
90 if n<=0{return 0-1};return n
91}