code wiki / (root) / nx_pets_wasm.nx

nx_pets_wasm.nx source

↩ module page · 614 lines · 19714 B

1// nx_pets_wasm.nx -- Generates a procedurally created 16x12 grid world with terrain and structures for a turn-based pet capture game. 2const K_MAGIC_1103515245: i64 = 1103515245 3const K_MAGIC_12345: i64 = 12345 4const K_MAGIC_32767: i64 = 32767 5const K_MAGIC_4096: i64 = 4096 6const K_MAGIC_147456: i64 = 147456 7const K_MAGIC_8000: i64 = 8000 8const K_MAGIC_1100: i64 = 1100 9const K_MAGIC_1047: i64 = 1047 10const K_MAGIC_1200: i64 = 1200 11const K_MAGIC_8192: i64 = 8192 12const K_MAGIC_1024: i64 = 1024 13const K_MAGIC_65536: i64 = 65536 14const K_MAGIC_20260613: i64 = 20260613 15// nx_pets_wasm.nx -- PIXELMON-LITE pets game, wasm-friendly (compiles via the SOVEREIGN 16// pipeline: nx -> wat (nxc2 --target wat, NO --opt) -> wasm (Nishi nx_wat_compiler) -> 17// served by nx_arcade_serve at /pets). Pokemon-x-Minecraft loop: walk a procgen overworld, 18// wild creatures in tall grass, STRATEGIC turn-based battle (type triangle fire>grass>water> 19// fire; neutral Strike + typed Special; PARTY-SWITCH to a type-advantaged captured pet), 20// weaken then CAPTURE, build a party/collection of up to 6. NO syscalls (fixed linear-memory 21// offsets + exported funcs); the JS canvas shim blits the framebuffer. HONEST: tutor-authored 22// PLAYABLE ALPHA of the core loop, NOT a measured pixelmon/minecraft exceed. license_tier: ORIGINAL 23// 24// memory: gs[] i64 at 1024 ; world 16x12 u8 at 4096 ; party roster i64 at 8192 ; fb 320x240 at 65536 25// gs: 0 px 1 py 2 mode 3 rng 4 party_count 5 msg 6 my_hp 7 my_max 8 my_lvl 9 my_species 26// 10 captured 11 wild_hp 12 wild_max 13 wild_lvl 14 wild_species 15 xp 16 seen_mask 27// 17 last_eff(0 none 1 super 2 weak 3 normal) 18 last_dmg 19 active_idx 28// roster[i] stride 4: +0 species +1 level +2 hp +3 max (max 6 members) 29// types: 0 fire 1 water 2 grass. species->type: 0 grass 1 fire 2 water 3 grass 30 31func g_rng(gs: *i64) -> i64 { 32 var s: i64 = gs[3] 33 s = s * K_MAGIC_1103515245 + K_MAGIC_12345 34 gs[3] = s 35 return (s >> 16) & K_MAGIC_32767 36} 37func g_cell(x: i64, y: i64) -> i64 { 38 if x < 0 { return 1 } 39 if y < 0 { return 1 } 40 if x >= 16 { return 1 } 41 if y >= 12 { return 1 } 42 let w: *u8 = (K_MAGIC_4096 as i64) as *u8 43 return w[y * 16 + x] as i64 44} 45func g_set(x: i64, y: i64, v: i64) -> i64 { 46 let w: *u8 = (K_MAGIC_4096 as i64) as *u8 47 w[y * 16 + x] = v as u8 48 return 0 49} 50func g_build(gs: *i64) -> i64 { 51 var y: i64 = 0 52 while y < 12 { 53 var x: i64 = 0 54 while x < 16 { 55 var c: i64 = 0 56 if x == 0 { c = 1 } 57 if y == 0 { c = 1 } 58 if x == 15 { c = 1 } 59 if y == 11 { c = 1 } 60 g_set(x, y, c) 61 x = x + 1 62 } 63 y = y + 1 64 } 65 var i: i64 = 0 66 while i < 26 { 67 let rx: i64 = 1 + (g_rng(gs) % 14) 68 let ry: i64 = 1 + (g_rng(gs) % 10) 69 var ok: i64 = 1 70 if rx < 3 { if ry < 3 { ok = 0 } } 71 if ok == 1 { g_set(rx, ry, 2) } 72 i = i + 1 73 } 74 var j: i64 = 0 75 while j < 10 { 76 let rx: i64 = 1 + (g_rng(gs) % 14) 77 let ry: i64 = 1 + (g_rng(gs) % 10) 78 var ok2: i64 = 1 79 if rx < 3 { if ry < 3 { ok2 = 0 } } 80 if ok2 == 1 { g_set(rx, ry, 1) } 81 j = j + 1 82 } 83 g_set(1, 1, 0) 84 g_set(2, 1, 0) 85 g_set(1, 2, 0) 86 gs[0] = 1 87 gs[1] = 1 88 return 0 89} 90func g_max_for(lvl: i64) -> i64 { return 16 + lvl * 4 } 91func g_base(sp: i64) -> i64 { if sp >= 10 { return sp - 10 } return sp } 92func g_type_of(sp: i64) -> i64 { 93 let b: i64 = g_base(sp) 94 if b == 1 { return 0 } 95 if b == 2 { return 1 } 96 return 2 97} 98func g_effect(at: i64, df: i64) -> i64 { 99 if at == 0 { if df == 2 { return 20 } if df == 1 { return 5 } return 10 } 100 if at == 1 { if df == 0 { return 20 } if df == 2 { return 5 } return 10 } 101 if df == 1 { return 20 } 102 if df == 0 { return 5 } 103 return 10 104} 105// --- SFX: the organ SYNTHESIZES 8-bit PCM into linear memory (128 = silence); the JS shim is 106// a pure DAC sink that copies samples into a Web Audio buffer and plays them -- exactly the 107// role canvas plays for the framebuffer. NO oscillator/synth in JS. audio buf u8 at 147456, 108// 8000 Hz; gs[30] = pending sfx id (the team owns BOTH the waveform and the event->sound map). 109// amp <= 90 keeps 128+/-amp inside [38,218] (no clip). sfx: 1 hit 2 super 3 catch 4 faint 110// 5 level/evolve/dex 6 mine 7 encounter. 111func g_tone(start: i64, len: i64, freq: i64, amp0: i64) -> i64 { 112 let buf: *u8 = (K_MAGIC_147456 as i64) as *u8 113 var period: i64 = 0 114 if freq > 0 { period = K_MAGIC_8000 / freq } 115 var i: i64 = 0 116 while i < len { 117 var s: i64 = 128 118 if period > 0 { 119 let amp: i64 = amp0 * (len - i) / len 120 if (i % period) * 2 < period { s = 128 + amp } else { s = 128 - amp } 121 } 122 buf[start + i] = s as u8 123 i = i + 1 124 } 125 return start + len 126} 127func g_synth(sfx: i64) -> i64 { 128 var n: i64 = 0 129 if sfx == 1 { n = g_tone(0, 900, 220, 78) } 130 if sfx == 2 { n = g_tone(0, 1000, 660, 88); n = g_tone(n, 700, 990, 70) } 131 if sfx == 3 { n = g_tone(0, 520, 523, 82); n = g_tone(n, 520, 659, 82); n = g_tone(n, 1000, 784, 86) } 132 if sfx == 4 { n = g_tone(0, 700, 392, 80); n = g_tone(n, 1000, 196, 78) } 133 if sfx == 5 { n = g_tone(0, 420, 523, 84); n = g_tone(n, 420, 659, 84); n = g_tone(n, 420, 784, 84); n = g_tone(n, K_MAGIC_1100, K_MAGIC_1047, 90) } 134 if sfx == 6 { n = g_tone(0, 260, K_MAGIC_1200, 66) } 135 if sfx == 7 { n = g_tone(0, 380, 440, 72); n = g_tone(n, 520, 880, 80) } 136 return n 137} 138// --- party roster accessors (source of truth for non-active members) --- 139func g_party_sp(i: i64) -> i64 { let r: *i64 = (K_MAGIC_8192 as i64) as *i64; return r[i * 4 + 0] } 140func g_party_lvl(i: i64) -> i64 { let r: *i64 = (K_MAGIC_8192 as i64) as *i64; return r[i * 4 + 1] } 141func g_party_hp(i: i64) -> i64 { let r: *i64 = (K_MAGIC_8192 as i64) as *i64; return r[i * 4 + 2] } 142func g_party_max(i: i64) -> i64 { let r: *i64 = (K_MAGIC_8192 as i64) as *i64; return r[i * 4 + 3] } 143func g_sync_active(gs: *i64) -> i64 { 144 let r: *i64 = (K_MAGIC_8192 as i64) as *i64 145 let a: i64 = gs[19] 146 gs[9] = r[a * 4 + 0] 147 gs[8] = r[a * 4 + 1] 148 gs[6] = r[a * 4 + 2] 149 gs[7] = r[a * 4 + 3] 150 return 0 151} 152func g_save_active(gs: *i64) -> i64 { 153 let r: *i64 = (K_MAGIC_8192 as i64) as *i64 154 let a: i64 = gs[19] 155 r[a * 4 + 0] = gs[9] 156 r[a * 4 + 1] = gs[8] 157 r[a * 4 + 2] = gs[6] 158 r[a * 4 + 3] = gs[7] 159 return 0 160} 161func g_add_party(gs: *i64, sp: i64, lvl: i64) -> i64 { 162 let r: *i64 = (K_MAGIC_8192 as i64) as *i64 163 let c: i64 = gs[4] 164 if c >= 6 { return 0 } 165 let mx: i64 = g_max_for(lvl) 166 r[c * 4 + 0] = sp 167 r[c * 4 + 1] = lvl 168 r[c * 4 + 2] = mx 169 r[c * 4 + 3] = mx 170 gs[4] = c + 1 171 return 0 172} 173func g_count_alive(gs: *i64) -> i64 { 174 let r: *i64 = (K_MAGIC_8192 as i64) as *i64 175 let c: i64 = gs[4] 176 var n: i64 = 0 177 var i: i64 = 0 178 while i < c { if r[i * 4 + 2] > 0 { n = n + 1 } i = i + 1 } 179 return n 180} 181func g_switch_next(gs: *i64) -> i64 { 182 let r: *i64 = (K_MAGIC_8192 as i64) as *i64 183 let c: i64 = gs[4] 184 let a: i64 = gs[19] 185 var k: i64 = 1 186 while k < c { 187 let idx: i64 = (a + k) % c 188 if r[idx * 4 + 2] > 0 { gs[19] = idx; g_sync_active(gs); return 1 } 189 k = k + 1 190 } 191 return 0 192} 193func g_heal_all(gs: *i64) -> i64 { 194 let r: *i64 = (K_MAGIC_8192 as i64) as *i64 195 let c: i64 = gs[4] 196 var i: i64 = 0 197 while i < c { r[i * 4 + 2] = r[i * 4 + 3] i = i + 1 } 198 gs[19] = 0 199 g_sync_active(gs) 200 return 0 201} 202func gi_init(seed: i64) -> i64 { 203 let gs: *i64 = (K_MAGIC_1024 as i64) as *i64 204 let r: *i64 = (K_MAGIC_8192 as i64) as *i64 205 gs[3] = seed 206 gs[2] = 0 207 gs[5] = 0 208 gs[10] = 0 209 gs[15] = 0 210 gs[16] = 1 211 gs[17] = 0 212 gs[18] = 0 213 gs[19] = 0 214 gs[20] = 0 215 gs[21] = 0 216 gs[22] = 0 217 gs[23] = 1 218 gs[24] = 0 219 gs[25] = 0 220 gs[26] = 0 221 gs[27] = 0 222 gs[28] = 1 223 gs[29] = 0 224 gs[30] = 0 225 var i: i64 = 0 226 while i < 24 { r[i] = 0 i = i + 1 } 227 r[0] = 0 228 r[1] = 5 229 r[2] = g_max_for(5) 230 r[3] = g_max_for(5) 231 gs[4] = 1 232 g_sync_active(gs) 233 g_build(gs) 234 return 0 235} 236func g_encounter(gs: *i64) -> i64 { 237 gs[2] = 1 238 gs[14] = 1 + (g_rng(gs) % 3) 239 gs[13] = 2 + (g_rng(gs) % 5) 240 gs[12] = g_max_for(gs[13]) 241 gs[11] = gs[12] 242 gs[5] = 1 243 gs[17] = 0 244 let bit: i64 = 1 << gs[14] 245 gs[16] = gs[16] | bit 246 gs[30] = 7 247 return 0 248} 249func g_move(gs: *i64, dx: i64, dy: i64) -> i64 { 250 let nx: i64 = gs[0] + dx 251 let ny: i64 = gs[1] + dy 252 let c: i64 = g_cell(nx, ny) 253 if c == 1 { return 0 } 254 gs[0] = nx 255 gs[1] = ny 256 if c == 2 { if (g_rng(gs) % 5) == 0 { g_encounter(gs) } } 257 return 0 258} 259// the cell the player faces; clamped to the interior so the border stays intact 260func g_facex(gs: *i64) -> i64 { 261 let f: i64 = gs[23] 262 if f == 2 { return gs[0] - 1 } 263 if f == 3 { return gs[0] + 1 } 264 return gs[0] 265} 266func g_facey(gs: *i64) -> i64 { 267 let f: i64 = gs[23] 268 if f == 0 { return gs[1] - 1 } 269 if f == 1 { return gs[1] + 1 } 270 return gs[1] 271} 272func g_interior(x: i64, y: i64) -> i64 { 273 if x < 1 { return 0 } 274 if x > 14 { return 0 } 275 if y < 1 { return 0 } 276 if y > 10 { return 0 } 277 return 1 278} 279// MINE the block in front: tree/placed -> +wood, grass -> +fiber; clears to path 280func g_break(gs: *i64) -> i64 { 281 let fx: i64 = g_facex(gs) 282 let fy: i64 = g_facey(gs) 283 if g_interior(fx, fy) == 0 { return 0 } 284 let c: i64 = g_cell(fx, fy) 285 if c == 1 { g_set(fx, fy, 0); gs[24] = gs[24] + 1; gs[5] = 13; gs[30] = 6 } 286 if c == 2 { g_set(fx, fy, 0); gs[25] = gs[25] + 1; gs[5] = 14; gs[30] = 6 } 287 if c == 4 { g_set(fx, fy, 0); gs[24] = gs[24] + 1; gs[5] = 13; gs[30] = 6 } 288 return 0 289} 290// PLACE a wood block in front (costs 1 wood) onto an empty path cell 291func g_place(gs: *i64) -> i64 { 292 let fx: i64 = g_facex(gs) 293 let fy: i64 = g_facey(gs) 294 if g_interior(fx, fy) == 0 { gs[5] = 16; return 0 } 295 let c: i64 = g_cell(fx, fy) 296 if c == 0 { 297 if gs[24] > 0 { g_set(fx, fy, 4); gs[24] = gs[24] - 1; gs[5] = 15 } else { gs[5] = 16 } 298 } else { gs[5] = 16 } 299 return 0 300} 301func g_my_base(gs: *i64) -> i64 { 302 var d: i64 = 4 + gs[8] + (g_rng(gs) % 4) 303 if gs[9] >= 10 { d = d + 3 } 304 return d 305} 306func g_wild_base(gs: *i64) -> i64 { return 2 + gs[13] + (g_rng(gs) % 3) } 307func g_wild_turn(gs: *i64) -> i64 { 308 let wt: i64 = g_type_of(gs[14]) 309 let mt: i64 = g_type_of(gs[9]) 310 let eff: i64 = g_effect(wt, mt) 311 let d: i64 = g_wild_base(gs) * eff / 10 312 gs[6] = gs[6] - d 313 if gs[6] <= 0 { 314 gs[6] = 0 315 g_save_active(gs) 316 if g_switch_next(gs) == 1 { 317 gs[5] = 11 318 } else { 319 g_heal_all(gs) 320 gs[2] = 0 321 gs[5] = 5 322 } 323 } 324 return 0 325} 326func g_wild_faint(gs: *i64) -> i64 { 327 gs[30] = 4 328 gs[15] = gs[15] + gs[13] * 2 329 if gs[15] >= gs[8] * 10 { 330 gs[8] = gs[8] + 1 331 gs[15] = 0 332 gs[7] = g_max_for(gs[8]) 333 gs[6] = gs[7] 334 gs[5] = 6 335 gs[30] = 5 336 if gs[8] >= 8 { if gs[9] < 10 { gs[9] = gs[9] + 10; gs[7] = g_max_for(gs[8]) + 20; gs[6] = gs[7]; gs[5] = 22 } } 337 } else { 338 gs[5] = 3 339 } 340 g_save_active(gs) 341 gs[2] = 0 342 return 0 343} 344func g_strike(gs: *i64) -> i64 { 345 if gs[2] != 1 { return 0 } 346 gs[21] = 10 347 gs[22] = 1 348 let d: i64 = g_my_base(gs) 349 gs[18] = d 350 gs[17] = 3 351 gs[30] = 1 352 gs[11] = gs[11] - d 353 if gs[11] <= 0 { g_wild_faint(gs); return 0 } 354 g_wild_turn(gs) 355 return 0 356} 357func g_element(gs: *i64) -> i64 { 358 if gs[2] != 1 { return 0 } 359 gs[21] = 10 360 gs[22] = 1 361 let mt: i64 = g_type_of(gs[9]) 362 let wt: i64 = g_type_of(gs[14]) 363 let eff: i64 = g_effect(mt, wt) 364 let d: i64 = g_my_base(gs) * eff / 10 365 gs[18] = d 366 if eff == 20 { gs[17] = 1 } else { if eff == 5 { gs[17] = 2 } else { gs[17] = 3 } } 367 if eff == 20 { gs[30] = 2 } else { gs[30] = 1 } 368 gs[11] = gs[11] - d 369 if gs[11] <= 0 { g_wild_faint(gs); return 0 } 370 g_wild_turn(gs) 371 return 0 372} 373func g_switch_action(gs: *i64) -> i64 { 374 if gs[2] != 1 { return 0 } 375 g_save_active(gs) 376 if g_count_alive(gs) <= 1 { gs[5] = 12; return 0 } 377 g_switch_next(gs) 378 gs[5] = 10 379 gs[17] = 0 380 g_wild_turn(gs) 381 return 1 382} 383func g_do_capture(gs: *i64, bonus: i64) -> i64 { 384 if gs[2] != 1 { return 0 } 385 gs[17] = 0 386 var chance: i64 = 250 + bonus 387 if gs[12] > 0 { chance = chance + (gs[12] - gs[11]) * 650 / gs[12] } 388 if (g_rng(gs) % 1000) < chance { 389 g_save_active(gs) 390 g_add_party(gs, gs[14], gs[13]) 391 gs[10] = gs[10] + 1 392 gs[28] = gs[28] | (1 << g_base(gs[14])) 393 gs[2] = 0 394 gs[5] = 4 395 gs[30] = 3 396 if (gs[28] & 15) == 15 { gs[29] = 1; gs[5] = 21; gs[30] = 5 } 397 } else { 398 gs[5] = 7 399 gs[30] = 1 400 g_wild_turn(gs) 401 } 402 return 0 403} 404func g_capture(gs: *i64) -> i64 { return g_do_capture(gs, 0) } 405// craft items fuse the mine-half into the catch-half: better odds + healing 406func g_throw_ball(gs: *i64) -> i64 { 407 if gs[2] != 1 { return 0 } 408 if gs[27] > 0 { gs[27] = gs[27] - 1; g_do_capture(gs, 300) } else { gs[5] = 18 } 409 return 0 410} 411func g_use_potion(gs: *i64) -> i64 { 412 if gs[2] != 1 { return 0 } 413 if gs[26] > 0 { 414 gs[26] = gs[26] - 1 415 gs[6] = gs[6] + 25 416 if gs[6] > gs[7] { gs[6] = gs[7] } 417 g_save_active(gs) 418 gs[5] = 20 419 g_wild_turn(gs) 420 } else { gs[5] = 18 } 421 return 0 422} 423func g_craft_potion(gs: *i64) -> i64 { 424 if gs[25] >= 2 { gs[25] = gs[25] - 2; gs[26] = gs[26] + 1; gs[5] = 17 } else { gs[5] = 18 } 425 return 0 426} 427func g_craft_ball(gs: *i64) -> i64 { 428 if gs[24] >= 1 { if gs[25] >= 1 { gs[24] = gs[24] - 1; gs[25] = gs[25] - 1; gs[27] = gs[27] + 1; gs[5] = 19; return 0 } } 429 gs[5] = 18 430 return 0 431} 432// key: 0 up 1 down 2 left 3 right 4 strike 5 restart 6 capture 7 flee 8 special 9 switch 433func gi_input(key: i64) -> i64 { 434 let gs: *i64 = (K_MAGIC_1024 as i64) as *i64 435 if gs[2] == 1 { 436 if key == 4 { g_strike(gs) } 437 if key == 8 { g_element(gs) } 438 if key == 9 { g_switch_action(gs) } 439 if key == 6 { g_capture(gs) } 440 if key == 10 { g_use_potion(gs) } 441 if key == 11 { g_throw_ball(gs) } 442 if key == 7 { gs[2] = 0; gs[5] = 8; gs[17] = 0 } 443 g_save_active(gs) 444 return 0 445 } 446 if key == 0 { gs[23] = 0 g_move(gs, 0, 0 - 1) } 447 if key == 1 { gs[23] = 1 g_move(gs, 0, 1) } 448 if key == 2 { gs[23] = 2 g_move(gs, 0 - 1, 0) } 449 if key == 3 { gs[23] = 3 g_move(gs, 1, 0) } 450 if key == 4 { g_break(gs) } 451 if key == 8 { g_place(gs) } 452 if key == 12 { g_craft_potion(gs) } 453 if key == 13 { g_craft_ball(gs) } 454 if key == 5 { gi_init(gs[3] + 9) } 455 return 0 456} 457func g_fill(x0: i64, y0: i64, ww: i64, hh: i64, col: i64) -> i64 { 458 let fb: *u8 = (K_MAGIC_65536 as i64) as *u8 459 var y: i64 = y0 460 while y < y0 + hh { 461 if y >= 0 { if y < 240 { 462 var x: i64 = x0 463 while x < x0 + ww { 464 if x >= 0 { if x < 320 { fb[y * 320 + x] = col as u8 } } 465 x = x + 1 466 } 467 } } 468 y = y + 1 469 } 470 return 0 471} 472func g_species_col(sp: i64) -> i64 { 473 let b: i64 = g_base(sp) 474 if b == 0 { return 6 } 475 if b == 1 { return 7 } 476 if b == 2 { return 8 } 477 return 9 478} 479// distinct per-species creature sprite (composed rects) + vertical bob offset. 480// sp 0 Leafling=leaf ears, 1 Emberpup=pointy ears+tail, 2 Aquafin=dorsal fin, 3 Sprout=stem. 481func g_draw_pet(sp: i64, x: i64, y: i64, w: i64, h: i64, bob: i64) -> i64 { 482 let b: i64 = g_base(sp) 483 let col: i64 = g_species_col(sp) 484 let yy: i64 = y + bob 485 if b == 0 { 486 g_fill(x + 6, yy - 8, 12, 10, 9) 487 g_fill(x + w - 18, yy - 8, 12, 10, 9) 488 } 489 if b == 1 { 490 g_fill(x + 8, yy - 10, 8, 12, col) 491 g_fill(x + w - 16, yy - 10, 8, 12, col) 492 } 493 if b == 2 { g_fill(x + w / 2 - 6, yy - 12, 12, 14, col) } 494 if b == 3 { 495 g_fill(x + w / 2 - 3, yy - 12, 6, 12, 1) 496 g_fill(x + w / 2 - 8, yy - 16, 16, 7, 9) 497 } 498 g_fill(x + 4, yy, w - 8, h, col) 499 g_fill(x, yy + 6, w, h - 12, col) 500 g_fill(x + 10, yy + 16, 16, 16, 4) 501 g_fill(x + w - 26, yy + 16, 16, 16, 4) 502 g_fill(x + 16, yy + 22, 7, 7, 12) 503 g_fill(x + w - 20, yy + 22, 7, 7, 12) 504 g_fill(x + w / 2 - 8, yy + h - 18, 16, 7, 12) 505 if b == 1 { g_fill(x - 6, yy + h - 20, 10, 8, col) } 506 if sp >= 10 { g_fill(x + w / 2 - 12, yy - 22, 24, 7, 14) } 507 return 0 508} 509func g_render_overworld(gs: *i64) -> i64 { 510 var cy: i64 = 0 511 while cy < 12 { 512 var cx: i64 = 0 513 while cx < 16 { 514 let c: i64 = g_cell(cx, cy) 515 var col: i64 = 0 516 if c == 1 { col = 1 } 517 if c == 2 { col = 2 } 518 if c == 3 { col = 3 } 519 if c == 4 { col = 13 } 520 g_fill(cx * 20, cy * 20, 20, 20, col) 521 cx = cx + 1 522 } 523 cy = cy + 1 524 } 525 g_fill(gs[0] * 20 + 4, gs[1] * 20 + 4, 12, 12, 4) 526 var tx: i64 = gs[0] * 20 + 8 527 var ty: i64 = gs[1] * 20 + 8 528 if gs[23] == 0 { ty = gs[1] * 20 } 529 if gs[23] == 1 { ty = gs[1] * 20 + 16 } 530 if gs[23] == 2 { tx = gs[0] * 20 } 531 if gs[23] == 3 { tx = gs[0] * 20 + 16 } 532 g_fill(tx, ty, 4, 4, 12) 533 return 0 534} 535func g_bar(x0: i64, y0: i64, val: i64, max: i64, col: i64) -> i64 { 536 var n: i64 = 0 537 if max > 0 { n = val * 120 / max } 538 if n < 0 { n = 0 } 539 if n > 120 { n = 120 } 540 g_fill(x0, y0, 120, 12, 12) 541 g_fill(x0, y0, n, 12, col) 542 return 0 543} 544// party dots: one small square per member, dim if fainted, white ring on active 545func g_render_party(gs: *i64) -> i64 { 546 let c: i64 = gs[4] 547 var i: i64 = 0 548 while i < c { 549 let px: i64 = 8 + i * 22 550 if i == gs[19] { g_fill(px - 2, 44, 20, 20, 4) } 551 var col: i64 = g_species_col(g_party_sp(i)) 552 if g_party_hp(i) <= 0 { col = 1 } 553 g_fill(px, 46, 16, 16, col) 554 i = i + 1 555 } 556 return 0 557} 558func g_render_battle(gs: *i64) -> i64 { 559 g_fill(0, 0, 320, 240, 5) 560 g_fill(20, 150, 110, 60, 2) 561 g_fill(200, 60, 100, 50, 2) 562 let fr: i64 = gs[20] 563 var bob: i64 = (fr / 6) % 4 564 if bob == 3 { bob = 1 } 565 let fx: i64 = gs[21] 566 let kind: i64 = gs[22] 567 var myx: i64 = 36 568 if fx > 0 { if kind == 1 { 569 var l: i64 = fx 570 if l > 5 { l = 10 - l } 571 myx = 36 + l * 6 572 } } 573 g_draw_pet(gs[14], 216, 64, 70, 84, bob) 574 if fx > 0 { if kind == 1 { if fx >= 4 { if fx <= 7 { g_fill(216, 64, 70, 84, 4) } } } } 575 g_draw_pet(gs[9], myx, 96, 70, 84, bob) 576 g_bar(20, 24, gs[11], gs[12], 11) 577 g_bar(180, 214, gs[6], gs[7], 10) 578 g_render_party(gs) 579 return 0 580} 581func gi_tick() -> i64 { 582 let gs: *i64 = (K_MAGIC_1024 as i64) as *i64 583 gs[20] = gs[20] + 1 584 if gs[21] > 0 { gs[21] = gs[21] - 1 } 585 return gs[21] 586} 587func gi_render() -> i64 { 588 let gs: *i64 = (K_MAGIC_1024 as i64) as *i64 589 if gs[2] == 1 { g_render_battle(gs); return 0 } 590 g_render_overworld(gs) 591 return 0 592} 593func gi_get(field: i64) -> i64 { 594 let gs: *i64 = (K_MAGIC_1024 as i64) as *i64 595 if field >= 0 { if field < 30 { return gs[field] } } 596 return 0 597} 598func gi_fb_offset() -> i64 { return K_MAGIC_65536 } 599func gi_fb_w() -> i64 { return 320 } 600func gi_fb_h() -> i64 { return 240 } 601func gi_synth(sfx: i64) -> i64 { return g_synth(sfx) } 602func gi_audio_offset() -> i64 { return K_MAGIC_147456 } 603func gi_audio_rate() -> i64 { return K_MAGIC_8000 } 604func gi_take_sfx() -> i64 { 605 let gs: *i64 = (K_MAGIC_1024 as i64) as *i64 606 let v: i64 = gs[30] 607 gs[30] = 0 608 return v 609} 610func main() -> i64 { 611 gi_init(K_MAGIC_20260613) 612 gi_render() 613 return gi_get(4) 614}