nx_wasm_adventure.nx source
↩ module page · 99 lines · 4931 B
1// nx_wasm_adventure.nx -- BROWSER-PLAYABLE sovereign Adventure: BASE-RELATIVE integer core, runs native (-> PNG)
2// AND in the browser (base = 0). NO float, NO JS logic, NO canvas drawing. A grid maze: move 4-directionally
3// (a step-cooldown keeps held keys at a sane pace), walls block, collect the key, then the locked door opens
4// (win). init()/tick(input)/render()/score()/ww()/hh()/fb_off() = the wasm interface; input 1=up 2=down 4=left
5// 8=right. license_tier: ORIGINAL
6import "nx_nishi_font_core.nx"
7const GW: i64 = 10
8const GH: i64 = 10
9const CELL: i64 = 16
10const W: i64 = 160 // GW*CELL
11const H: i64 = 160
12const STEP_CD: i64 = 6
13const O_FB: i64 = 0 // framebuffer W*H i64
14const O_MAP: i64 = 204800 // map[GW*GH] (W*H*8)
15const O_ST: i64 = 205600 // scalars[16]: 0=gx 1=gy 2=has_key 3=won 4=cooldown
16const O_MSK: i64 = 205728
17const O_STR: i64 = 213920
18
19func rgb(r: i64, g: i64, b: i64) -> i64 { return (r & 255) | ((g & 255) << 8) | ((b & 255) << 16) }
20
21func fillr(base: i64, x0: i64, y0: i64, x1: i64, y1: i64, c: i64) -> i64 {
22 let fb: *i64 = (base + O_FB) as *i64
23 var yy: i64 = y0; if yy < 0 { yy = 0 }
24 var ye: i64 = y1; if ye > H { ye = H }
25 while yy < ye {
26 var xx: i64 = x0; if xx < 0 { xx = 0 }
27 var xe: i64 = x1; if xe > W { xe = W }
28 while xx < xe { fb[yy*W + xx] = c; xx = xx + 1 }
29 yy = yy + 1
30 }
31 return 0
32}
33func wall(base: i64, mp: *i64, x: i64, y: i64) -> i64 { mp[y*GW + x] = 1; return 0 }
34
35func init_impl(base: i64) -> i64 {
36 let mp: *i64 = (base + O_MAP) as *i64
37 let st: *i64 = (base + O_ST) as *i64
38 var i: i64 = 0; while i < GW*GH { mp[i] = 0; i = i + 1 }
39 var x: i64 = 0; while x < GW { wall(base, mp, x, 0); wall(base, mp, x, GH-1); x = x + 1 }
40 var y: i64 = 0; while y < GH { wall(base, mp, 0, y); wall(base, mp, GW-1, y); y = y + 1 }
41 // interior walls (none on row 1 or column 8 -> the key/door path stays clear)
42 wall(base, mp, 2, 3); wall(base, mp, 3, 3); wall(base, mp, 4, 3); wall(base, mp, 5, 3)
43 wall(base, mp, 4, 5); wall(base, mp, 5, 5); wall(base, mp, 6, 5); wall(base, mp, 7, 5)
44 wall(base, mp, 2, 7); wall(base, mp, 3, 7); wall(base, mp, 4, 7); wall(base, mp, 5, 7)
45 mp[1*GW + 8] = 2 // key at (8,1)
46 mp[8*GW + 8] = 3 // door at (8,8)
47 st[0] = 1; st[1] = 1; st[2] = 0; st[3] = 0; st[4] = 0
48 return 0
49}
50
51func tick_impl(base: i64, input: i64) -> i64 {
52 let mp: *i64 = (base + O_MAP) as *i64
53 let st: *i64 = (base + O_ST) as *i64
54 if st[3] == 1 { return 0 } // win: frozen (reload to replay)
55 if st[4] > 0 { st[4] = st[4] - 1; return 0 }
56 var dx: i64 = 0; var dy: i64 = 0
57 if (input & 1) != 0 { dy = 0 - 1 } else { if (input & 2) != 0 { dy = 1 } else { if (input & 4) != 0 { dx = 0 - 1 } else { if (input & 8) != 0 { dx = 1 } } } }
58 if dx == 0 { if dy == 0 { return 0 } }
59 let nx: i64 = st[0] + dx; let ny: i64 = st[1] + dy
60 if nx < 0 { return 0 } if ny < 0 { return 0 } if nx >= GW { return 0 } if ny >= GH { return 0 }
61 let cell: i64 = mp[ny*GW + nx]
62 if cell == 1 { return 0 } // wall
63 if cell == 3 { if st[2] == 0 { return 0 } st[0] = nx; st[1] = ny; st[3] = 1; st[4] = STEP_CD; return 0 } // locked door / win
64 st[0] = nx; st[1] = ny
65 if cell == 2 { st[2] = 1; mp[ny*GW + nx] = 0 } // pick up key
66 st[4] = STEP_CD
67 return 0
68}
69
70func render_impl(base: i64) -> i64 {
71 let fb: *i64 = (base + O_FB) as *i64
72 let mp: *i64 = (base + O_MAP) as *i64
73 let st: *i64 = (base + O_ST) as *i64
74 var p: i64 = 0; while p < W*H { fb[p] = rgb(18, 18, 26); p = p + 1 }
75 var y: i64 = 0
76 while y < GH {
77 var x: i64 = 0
78 while x < GW {
79 let c: i64 = mp[y*GW + x]
80 if c == 1 { fillr(base, x*CELL, y*CELL, x*CELL+CELL, y*CELL+CELL, rgb(96, 96, 112)) }
81 if c == 2 { fillr(base, x*CELL+5, y*CELL+5, x*CELL+CELL-5, y*CELL+CELL-5, rgb(245, 210, 70)) }
82 if c == 3 { fillr(base, x*CELL+2, y*CELL+1, x*CELL+CELL-2, y*CELL+CELL-1, rgb(160, 90, 50)) }
83 x = x + 1
84 }
85 y = y + 1
86 }
87 fillr(base, st[0]*CELL+3, st[1]*CELL+3, st[0]*CELL+CELL-3, st[1]*CELL+CELL-3, rgb(90, 210, 122)) // player
88 if st[2] == 1 { fillr(base, W-12, 4, W-4, 12, rgb(245, 210, 70)) } // key-held icon
89 if st[3] == 1 { fillr(base, 0,0,W,3, rgb(90,220,120)); fillr(base, 0,H-3,W,H, rgb(90,220,120)); fillr(base, 0,0,3,H, rgb(90,220,120)); fillr(base, W-3,0,W,H, rgb(90,220,120)) }
90 return 0
91}
92
93func init() -> i64 { return init_impl(0) }
94func tick(input: i64) -> i64 { return tick_impl(0, input) }
95func render() -> i64 { return render_impl(0) }
96func score() -> i64 { let st: *i64 = (0 + O_ST) as *i64; return st[2] }
97func fb_off() -> i64 { return O_FB }
98func ww() -> i64 { return W }
99func hh() -> i64 { return H }