diff --git a/examples/ecs/hello.ludic b/examples/ecs/hello.ludic index c4935292..2a845ffe 100644 --- a/examples/ecs/hello.ludic +++ b/examples/ecs/hello.ludic @@ -19,8 +19,8 @@ program Hello { # runs once per match, each property bound by name and self() giving that entity. @Queries(these: [Pos, Vel]) handler Move phase FixedUpdate { - Pos.x = Pos.x + Vel.dx - Pos.y = Pos.y + Vel.dy + Pos.x += Vel.dx + Pos.y += Vel.dy } handler Report phase Update { diff --git a/examples/ecs/world_query.ludic b/examples/ecs/world_query.ludic index 33cf843b..c41f5f5d 100644 --- a/examples/ecs/world_query.ludic +++ b/examples/ecs/world_query.ludic @@ -16,8 +16,8 @@ program WorldQuery { var sum = 0 var e = world_query_next(H, 0) while e >= 0 { - count = count + 1 - sum = sum + world_get(e, H, hp) + count += 1 + sum += world_get(e, H, hp) e = world_query_next(H, e + 1) } print(count) # 2 diff --git a/examples/ecs/world_scan.ludic b/examples/ecs/world_scan.ludic index e82bde5c..8b56af20 100644 --- a/examples/ecs/world_scan.ludic +++ b/examples/ecs/world_scan.ludic @@ -19,10 +19,10 @@ program WorldScan { var e = 0 while e < n { if world_kind(e) == Um { - count = count + 1 - sum = sum + world_get(e, H, hp) + count += 1 + sum += world_get(e, H, hp) } - e = e + 1 + e += 1 } print(count) # 2 print(sum) # 110 diff --git a/examples/events/cancel.ludic b/examples/events/cancel.ludic index 65e1f163..f59de919 100644 --- a/examples/events/cancel.ludic +++ b/examples/events/cancel.ludic @@ -20,8 +20,8 @@ program Cancel { # the realistic shape: only apply the effect when the decision isn't vetoed var hp = 100 - if emit BeforeHurt(amount: 8) == 0 { hp = hp - 8 } # allowed -> 92 - if emit BeforeHurt(amount: 50) == 0 { hp = hp - 50 } # vetoed -> unchanged + if emit BeforeHurt(amount: 8) == 0 { hp -= 8 } # allowed -> 92 + if emit BeforeHurt(amount: 50) == 0 { hp -= 50 } # vetoed -> unchanged print(hp) # 92 } } diff --git a/examples/events/layer_events.ludic b/examples/events/layer_events.ludic index 61246356..ab99630c 100644 --- a/examples/events/layer_events.ludic +++ b/examples/events/layer_events.ludic @@ -17,7 +17,7 @@ program LayerEvents { } layer Ctrl { handler Drive phase LateUpdate { - step = step + 1 + step += 1 if step == 1 { disable layer Hud } # frame 1: hide -> Hidden 2, Draw stops if step == 2 { enable layer Hud } # frame 2: show -> Shown 1, Draw resumes if step == 3 { quit() } # frame 3: after Draw ran again diff --git a/examples/events/mod_events.ludic b/examples/events/mod_events.ludic index 92bd19e1..f1b3dc23 100644 --- a/examples/events/mod_events.ludic +++ b/examples/events/mod_events.ludic @@ -6,7 +6,7 @@ program ModEvents { var total: int = 0 event Damage { amount: int = 0 } @On(Damage) handler Native { print(amount) } # prints each hit - @On(Damage) handler Accum { total = total + amount } # sums them + @On(Damage) handler Accum { total += amount } # sums them entry { emit Damage(amount: 10) # Native prints 10 diff --git a/examples/events/program_events.ludic b/examples/events/program_events.ludic index 4a7b49c2..db0b4127 100644 --- a/examples/events/program_events.ludic +++ b/examples/events/program_events.ludic @@ -11,8 +11,8 @@ program ProgramEvents { @Public @OnStart handler Boot { print(1) } # -> program_start @Public @OnQuit handler Bye { print(2) } # -> program_quit - @On(program_start) handler ModInit { print(100) } # mod boots after the game - @On(program_quit) handler ModDone { print(200) } # mod tears down as the game exits + @On(program_start) handler ModInit { print(100) } # mod boots after the game + @On(program_quit) handler ModDone { print(200) } # mod tears down as the game exits handler Run phase Update { quit() } } diff --git a/examples/events/recurse.ludic b/examples/events/recurse.ludic index 45cb0295..e1f8be69 100644 --- a/examples/events/recurse.ludic +++ b/examples/events/recurse.ludic @@ -11,7 +11,7 @@ program Recurse { event Ping { } event Pong { } - @On(Ping) handler A { n = n + 1; emit Pong() } # each Ping deepens by one Pong + @On(Ping) handler A { n += 1; emit Pong() } # each Ping deepens by one Pong @On(Pong) handler B { emit Ping() } # ...and each Pong by one Ping entry { diff --git a/examples/events/scoped.ludic b/examples/events/scoped.ludic index c3a405ce..6d54bfe5 100644 --- a/examples/events/scoped.ludic +++ b/examples/events/scoped.ludic @@ -8,7 +8,7 @@ program Scoped { model Unit { Health } var fires: int = 0 event Tick { } - @On(Tick) handler OnTick { for (Health) in query [Health, {Unit}] { fires = fires + 1 } } + @On(Tick) handler OnTick { for (Health) in query [Health, {Unit}] { fires += 1 } } entry { spawn Unit { Health { hp: 1 } } diff --git a/examples/games/chronorift/combat.ludic b/examples/games/chronorift/combat.ludic index e716a6e8..b5bb0e4e 100644 --- a/examples/games/chronorift/combat.ludic +++ b/examples/games/chronorift/combat.ludic @@ -27,13 +27,13 @@ handler Battle phase Update { match menu_cursor { KnightAct.Attack => { let d = max(1, st.atk - e.def + Random.range(0, 4)) - e.hp = e.hp - d + e.hp -= d player_hit = d } KnightAct.Guard => { st.guard = 1; player_hit = 0 } KnightAct.Item => { if potions > 0 { - potions = potions - 1 + potions -= 1 st.hp = min(st.maxhp, st.hp + 24) player_hit = 24 } else { player_hit = 0 } @@ -55,7 +55,7 @@ handler Battle phase Update { if k != 0 { if e.hp <= 0 { grant_xp(e.xp) - gold = gold + e.xp + gold += e.xp if enemy_type == 2 { boss_down = 1; game_mode = 3; ack = 0 } else { game_mode = 0 } become KnightMenu @@ -78,12 +78,12 @@ handler Battle phase Update { match menu_cursor { MageAct.Attack => { let d = max(1, st.atk + 5 - e.def + Random.range(0, 5)) - e.hp = e.hp - d + e.hp -= d player_hit = d } MageAct.Heal => { if st.mp >= 4 { - st.mp = st.mp - 4 + st.mp -= 4 for (t2, p2) in query [Stats, Party] { if p2.slot == 0 { t2.hp = min(t2.maxhp, t2.hp + 16) } } @@ -104,7 +104,7 @@ handler Battle phase Update { if k != 0 { if e.hp <= 0 { grant_xp(e.xp) - gold = gold + e.xp + gold += e.xp if enemy_type == 2 { boss_down = 1; game_mode = 3; ack = 0 } else { game_mode = 0 } become KnightMenu @@ -121,8 +121,8 @@ handler Battle phase Update { if done == 0 { if t3.hp > 0 { var ed = max(1, e.atk - t3.def + Random.range(0, 4)) - if t3.guard == 1 { ed = ed / 2; t3.guard = 0 } - t3.hp = t3.hp - ed + if t3.guard == 1 { ed /= 2; t3.guard = 0 } + t3.hp -= ed enemy_hit = ed done = 1 } @@ -130,7 +130,7 @@ handler Battle phase Update { } var alive = 0 for (t4) in query [Stats, {Party}] { - if t4.hp > 0 { alive = alive + 1 } + if t4.hp > 0 { alive += 1 } } if alive == 0 { game_mode = 2; ack = 0 } else { diff --git a/examples/games/chronorift/overworld.ludic b/examples/games/chronorift/overworld.ludic index 5b82a2e1..87cb851b 100644 --- a/examples/games/chronorift/overworld.ludic +++ b/examples/games/chronorift/overworld.ludic @@ -84,33 +84,33 @@ handler Control phase Input { if tc != 'D' { if tc != 'S' { if tc != 'B' { - if tc != 'h' { - encounter = encounter - 1 - if encounter <= 0 { - encounter = Random.range(4, 9) - var et = 0 - if world_map == 1 { et = 1 } - if world_map == 0 { - if Random.chance(40) { et = 1 } - } - enemy_type = et - if et == 0 { - spawn Enemy { - Actor { kind: 6 } - Stats { hp: 18, maxhp: 18, mp: 0, maxmp: 0, atk: 8, def: 2, lvl: 1, xp: 7, guard: 0 } + if tc != 'h' { + encounter -= 1 + if encounter <= 0 { + encounter = Random.range(4, 9) + var et = 0 + if world_map == 1 { et = 1 } + if world_map == 0 { + if Random.chance(40) { et = 1 } } - } - if et == 1 { - spawn Enemy { - Actor { kind: 7 } - Stats { hp: 30, maxhp: 30, mp: 0, maxmp: 0, atk: 11, def: 5, lvl: 1, xp: 15, guard: 0 } + enemy_type = et + if et == 0 { + spawn Enemy { + Actor { kind: 6 } + Stats { hp: 18, maxhp: 18, mp: 0, maxmp: 0, atk: 8, def: 2, lvl: 1, xp: 7, guard: 0 } + } } + if et == 1 { + spawn Enemy { + Actor { kind: 7 } + Stats { hp: 30, maxhp: 30, mp: 0, maxmp: 0, atk: 11, def: 5, lvl: 1, xp: 15, guard: 0 } + } + } + game_mode = 1 + turn_phase = 0 + menu_cursor = 0 } - game_mode = 1 - turn_phase = 0 - menu_cursor = 0 } - } } } } @@ -130,8 +130,8 @@ handler Shop phase Update { if is_confirm(k) { if menu_cursor == 0 { if gold >= 10 { - gold = gold - 10 - potions = potions + 1 + gold -= 10 + potions += 1 } } if menu_cursor == 1 { game_mode = 0 } diff --git a/examples/games/chronorift/rules.ludic b/examples/games/chronorift/rules.ludic index 685409b8..2dadaeab 100644 --- a/examples/games/chronorift/rules.ludic +++ b/examples/games/chronorift/rules.ludic @@ -15,7 +15,7 @@ function walkable(x: int, y: int) -> bool { let c = Map.tile(x, y) return c == '.' or c == 'D' or c == 'r' or c == ',' or c == 'S' or c == 'B' or c == 'h' } -function is_confirm(k: int) -> bool { return k == 32 or k == 10 or k == 13 } +function is_confirm(k: int) -> bool { return k == ' ' or k == '\n' or k == '\r' } function enemy_name(et: int) -> string { if et == 0 { return "SLIME" } if et == 1 { return "SKELETON" } @@ -70,15 +70,15 @@ function build_dungeon(x: int) -> int { function grant_xp(amount: int) -> int { for (t) in query [Stats, {Party}] { if t.hp > 0 { - t.xp = t.xp + amount + t.xp += amount while t.xp >= t.lvl * 20 { t.xp = t.xp - t.lvl * 20 - t.lvl = t.lvl + 1 - t.maxhp = t.maxhp + 8 + t.lvl += 1 + t.maxhp += 8 t.hp = t.maxhp - t.maxmp = t.maxmp + 2 - t.atk = t.atk + 2 - t.def = t.def + 1 + t.maxmp += 2 + t.atk += 2 + t.def += 1 } } } diff --git a/examples/games/menu.ludic b/examples/games/menu.ludic index eac3d8ee..8a841778 100644 --- a/examples/games/menu.ludic +++ b/examples/games/menu.ludic @@ -4,6 +4,11 @@ # and activation. The game only loads a font, opens the UI, and reads clicks. program Menu { + # the macOS system font: the toolchain targets macOS today, and the sample keeps + # the repo free of a bundled font + const FONT_PATH: string = "/System/Library/Fonts/Supplemental/Arial.ttf" + const BACKDROP: int = 0x0e0e16 + var title_font: int = 0 ui MainMenu { @@ -19,22 +24,22 @@ program Menu { } handler Boot phase Start { - title_font = font_load("/System/Library/Fonts/Supplemental/Arial.ttf") - ui_build() - ui_open(UI_MainMenu) + title_font = Font.load(FONT_PATH) + Ui.build() + Ui.open(UI_MainMenu) } handler Nav phase Update { - ui_tick(Input.key()) - if ui_clicked(UI_NewGame) { ui_set_text(UI_NewGame, "Starting...") } - if ui_clicked(UI_Continue) { ui_set_text(UI_Continue, "No save") } - if ui_clicked(UI_Options) { ui_set_text(UI_Options, "Soon (TM)") } - if ui_clicked(UI_Quit) { quit() } + Ui.tick(Input.key()) + if Ui.clicked(UI_NewGame) { Ui.set_text(UI_NewGame, "Starting...") } + if Ui.clicked(UI_Continue) { Ui.set_text(UI_Continue, "No save") } + if Ui.clicked(UI_Options) { Ui.set_text(UI_Options, "Soon (TM)") } + if Ui.clicked(UI_Quit) { quit() } } handler Draw phase Render { - Screen.clear(0x0e0e16) - ui_render() + Screen.clear(BACKDROP) + Ui.render() Screen.show() } } diff --git a/examples/games/npcai_demo.ludic b/examples/games/npcai_demo.ludic index 5d7d96c0..5fc48687 100644 --- a/examples/games/npcai_demo.ludic +++ b/examples/games/npcai_demo.ludic @@ -34,9 +34,9 @@ program NpcAiDemo { @OnSpawn(Dummy) handler DInit { } var spotted: int = 0 - @On(TargetSpotted) handler OnSpot { spotted = spotted + 1 } + @On(TargetSpotted) handler OnSpot { spotted += 1 } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } function gx(e: int) -> int { let P = World.prop_id("Position"); return World.get(e, P, World.field_id(P, "x")) } function gy(e: int) -> int { let P = World.prop_id("Position"); return World.get(e, P, World.field_id(P, "y")) } @@ -52,7 +52,7 @@ program NpcAiDemo { let PBr = World.prop_id("Brain") var e = World.query_next(PS, 0) while e >= 0 { if World.has(e, PBr) == 0 { return e }; e = World.query_next(PS, e + 1) } - return 0 - 1 + return -1 } entry { @@ -102,7 +102,7 @@ program NpcAiDemo { # ---- E. companion follower advances toward its leader ------------------ spawn Ally { Position { x: 40, y: 40 }, Collider { w: 12, h: 12 }, TopDown { move_speed: 3 }, Faction { id: 2 }, Stats { hp: 30, max_hp: 30 }, - Brain { model: 0 }, Follower { leader: 0 - 1, distance: 24 } } + Brain { model: 0 }, Follower { leader: -1, distance: 24 } } # the ally is the Brain+Follower entity that isn't the enemy var ally = World.query_next(PBr, 0) while (ally >= 0) and (World.has(ally, World.prop_id("Follower")) == 0) { ally = World.query_next(PBr, ally + 1) } diff --git a/examples/games/platformer_demo.ludic b/examples/games/platformer_demo.ludic index 506a30f4..d6768a47 100644 --- a/examples/games/platformer_demo.ludic +++ b/examples/games/platformer_demo.ludic @@ -33,14 +33,14 @@ program PlatformerDemo { @OnSpawn(Wall) handler WallInit { } var jumps: int = 0 - @On(JumpPerformed) handler CountJumps { jumps = jumps + 1 } + @On(JumpPerformed) handler CountJumps { jumps += 1 } # a game rule: forbid the air (double) jump unless a "power" flag is set — pure # lever-4 veto, no controller edit. var have_power: int = 0 var vetoed_air: int = 0 @On(JumpRequested) handler GateAir { if (kind == 2) and (have_power == 0) { vetoed_air = 1; cancel } } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } function pf_coyote(e: int) -> int { let P = World.prop_id("Platformer") @@ -78,7 +78,7 @@ program PlatformerDemo { Platformer.jump(h) var top = World.get(h, PP, fy) var i = 0 - while i < 20 { tick_fixed(); let y = World.get(h, PP, fy); if y < top { top = y }; i = i + 1 } + while i < 20 { tick_fixed(); let y = World.get(h, PP, fy); if y < top { top = y }; i += 1 } let rise = floor_y - top # px risen at apex (target 64 = 4 tiles) print(bi((rise >= 56) and (rise <= 72))) # 1 Platformer.hold(h, 0) diff --git a/examples/games/platformer_scaffolding.ludic b/examples/games/platformer_scaffolding.ludic index 3e83ad59..5f1b9743 100644 --- a/examples/games/platformer_scaffolding.ludic +++ b/examples/games/platformer_scaffolding.ludic @@ -34,13 +34,13 @@ program PlatformerScaffolding { @OnSpawn(Spike) handler SI { } var picked: int = 0 - @On(ItemPickedUp) handler OnPick { picked = picked + 1 } + @On(ItemPickedUp) handler OnPick { picked += 1 } var sprang: int = 0 - @On(Sprang) handler OnSpring { sprang = sprang + 1 } + @On(Sprang) handler OnSpring { sprang += 1 } var hurt: int = 0 - @On(Hurt) handler OnHurt { hurt = hurt + 1 } + @On(Hurt) handler OnHurt { hurt += 1 } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } entry { diff --git a/examples/games/rpg_demo.ludic b/examples/games/rpg_demo.ludic index 92555aa9..45c9a5ab 100644 --- a/examples/games/rpg_demo.ludic +++ b/examples/games/rpg_demo.ludic @@ -41,13 +41,13 @@ program RpgDemo { var locked: int = 0 @On(MoveRequested) handler LockDoor { if (locked == 1) and (dx == 1) { cancel } } var entered: int = 0 - @On(TileEntered) handler CountEnter { entered = entered + 1 } + @On(TileEntered) handler CountEnter { entered += 1 } var talked: int = 0 - @On(Interacted) handler OnTalk { if target >= 0 { talked = talked + 1 } } + @On(Interacted) handler OnTalk { if target >= 0 { talked += 1 } } var quest_done: int = 0 - @On(QuestCompleted) handler OnQuestDone { quest_done = quest_done + 1 } + @On(QuestCompleted) handler OnQuestDone { quest_done += 1 } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } function px(e: int) -> int { let P = World.prop_id("Position"); return World.get(e, P, World.field_id(P, "x")) } function py(e: int) -> int { let P = World.prop_id("Position"); return World.get(e, P, World.field_id(P, "y")) } @@ -112,7 +112,7 @@ program RpgDemo { let before = Inventory.count(h, "herb") print(bi(Craft.can(h, "potion") == 1)) # 1 print(bi(Craft.make(h, "potion") == 1)) # 1 — consumed 2, produced 1 - print(bi(Inventory.count(h, "herb") == before - 1)) # 1 — net -2 + 1 + print(bi(Inventory.count(h, "herb") == before - 1)) # 1 — net -2 + 1 # ================= Module D: quests ================= Quest.define("hunt") @@ -126,7 +126,7 @@ program RpgDemo { let dn0 = Dialog.node("elder", "hello") let dn1 = Dialog.node("elder", "farewell") Dialog.choice(dn0, "greet", dn1) - Dialog.choice(dn1, "leave", 0 - 1) + Dialog.choice(dn1, "leave", -1) Dialog.start(h, "elder") print(bi(Dialog.line(h) == "hello")) # 1 — entry node text Dialog.choose(h, 0) diff --git a/examples/games/shooter_demo.ludic b/examples/games/shooter_demo.ludic index e7ad67eb..297133a6 100644 --- a/examples/games/shooter_demo.ludic +++ b/examples/games/shooter_demo.ludic @@ -31,20 +31,20 @@ program ShooterDemo { @OnSpawn(Nest) handler NInit { } var spawn_reqs: int = 0 - @On(SpawnRequested) handler OnSpawnReq { spawn_reqs = spawn_reqs + 1 } + @On(SpawnRequested) handler OnSpawnReq { spawn_reqs += 1 } var waves_cleared: int = 0 - @On(WaveCleared) handler OnWaveClear { waves_cleared = waves_cleared + 1 } + @On(WaveCleared) handler OnWaveClear { waves_cleared += 1 } var spawned: int = 0 - @On(ProjectileSpawned) handler CountSpawn { spawned = spawned + 1 } + @On(ProjectileSpawned) handler CountSpawn { spawned += 1 } var hits: int = 0 - @On(ProjectileHit) handler CountHit { hits = hits + 1 } + @On(ProjectileHit) handler CountHit { hits += 1 } # reap the dead (the realistic policy: a Died body leaves the world) so stale # corpses do not sit in the faction/targeting scans. var deaths: int = 0 - @On(Died) handler Reap { deaths = deaths + 1; despawn e } + @On(Died) handler Reap { deaths += 1; despawn e } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } function hp_of(e: int) -> int { let P = World.prop_id("Stats") @@ -57,7 +57,7 @@ program ShooterDemo { let PT = World.prop_id("TopDown") var e = World.query_next(PS, 0) while e >= 0 { if World.has(e, PT) == 0 { return e }; e = World.query_next(PS, e + 1) } - return 0 - 1 + return -1 } # a mob still alive (hp > 0) — the dead one from an earlier test stays in the world. function find_live_mob() -> int { @@ -69,7 +69,7 @@ program ShooterDemo { if (World.has(e, PT) == 0) and (World.get(e, PS, fhp) > 0) { return e } e = World.query_next(PS, e + 1) } - return 0 - 1 + return -1 } entry { @@ -138,7 +138,7 @@ program ShooterDemo { var f = 0 while (deaths == d0) and (f < 400) { TopDown.fire(g, 1); tick_fixed(); TopDown.fire(g, 0); tick_fixed() - f = f + 1 + f += 1 } print(bi(deaths == d0 + 1)) # 1 — enemy destroyed (Died fired) diff --git a/examples/games/snake.ludic b/examples/games/snake.ludic index 10f491c7..0032bc72 100644 --- a/examples/games/snake.ludic +++ b/examples/games/snake.ludic @@ -79,7 +79,7 @@ program Snake { handler Move phase Update { if mode == MODE_PLAY { - tick = tick + 1 + tick += 1 if tick >= 6 { tick = 0 # remember the tail cell, then drag every segment onto the one ahead of it @@ -102,10 +102,10 @@ program Snake { ate = 0 for (ph, sh) in query [Pos, Seg] { if sh.order == 0 { - if direction == DIR_UP { ph.y = ph.y - 1 } - if direction == DIR_DOWN { ph.y = ph.y + 1 } - if direction == DIR_LEFT { ph.x = ph.x - 1 } - if direction == DIR_RIGHT { ph.x = ph.x + 1 } + if direction == DIR_UP { ph.y -= 1 } + if direction == DIR_DOWN { ph.y += 1 } + if direction == DIR_LEFT { ph.x -= 1 } + if direction == DIR_RIGHT { ph.x += 1 } if ph.x < 0 { mode = MODE_OVER } if ph.x >= GRID_W { mode = MODE_OVER } if ph.y < 0 { mode = MODE_OVER } @@ -124,9 +124,9 @@ program Snake { } } if ate == 1 { - score = score + 1 + score += 1 spawn Body { Seg { order: length }; Pos { x: tail_x, y: tail_y } } - length = length + 1 + length += 1 food_x = Random.range(low: 0, high: GRID_W - 1) food_y = Random.range(low: 0, high: GRID_H - 1) } diff --git a/examples/library/anim_ecs.ludic b/examples/library/anim_ecs.ludic index 473070e2..5e3b0fa4 100644 --- a/examples/library/anim_ecs.ludic +++ b/examples/library/anim_ecs.ludic @@ -59,6 +59,6 @@ program AnimEcs { # run the Update phase n times; the engine systems advance one tick each call. function tick_n(n: int) -> void { var i = 0 - while i < n { tick_fixed(); i = i + 1 } + while i < n { tick_fixed(); i += 1 } } } diff --git a/examples/library/anim_sugar.ludic b/examples/library/anim_sugar.ludic index 4ea74f51..ef02b82b 100644 --- a/examples/library/anim_sugar.ludic +++ b/examples/library/anim_sugar.ludic @@ -16,7 +16,7 @@ program AnimSugar { model Sprite { SpriteAnim } model Mover { Motion } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } entry { diff --git a/examples/library/atlas.ludic b/examples/library/atlas.ludic index af3b7bf2..8f1321f7 100644 --- a/examples/library/atlas.ludic +++ b/examples/library/atlas.ludic @@ -25,7 +25,7 @@ program AtlasDemo { let d = Sprite.define("hero", sheet, 2, 3) # name a cell print(bi(Sprite.named("hero") == d)) # 1 — looked up by name print(bi(Assets.get("hero") == d)) # 1 — Assets.get is the same lookup - print(bi(Sprite.named("nope") == (0 - 1))) # 1 — an unknown name is -1 + print(bi(Sprite.named("nope") == (-1))) # 1 — an unknown name is -1 let whole = Assets.image("assets/kenney/tiny-dungeon/Tiles/tile_0096.png") print(Sprite.width(whole)) # 16 — a whole tile as one sprite @@ -34,7 +34,7 @@ program AtlasDemo { Screen.clear(0) Sprite.draw(whole, 10, 10) var n = 0 - for yy in 10 .. 26 { for xx in 10 .. 26 { if Screen.pixel(xx, yy) != 0 { n = n + 1 } } } + for yy in 10 .. 26 { for xx in 10 .. 26 { if Screen.pixel(xx, yy) != 0 { n += 1 } } } print(bi(n > 0)) # 1 — the sprite drew content } } diff --git a/examples/library/combat.ludic b/examples/library/combat.ludic index 8d8e8cd0..fbf2959f 100644 --- a/examples/library/combat.ludic +++ b/examples/library/combat.ludic @@ -19,7 +19,7 @@ program Combat { @export function damage(attack: int, armour: int, roll: int) -> int { var raw = attack - armour if raw < 1 { raw = 1 } - if roll == 20 { raw = raw * CRIT_MULT } + if roll == 20 { raw *= CRIT_MULT } return raw } @@ -29,8 +29,8 @@ program Combat { var left = hp var n = 0 while left > 0 { - left = left - damage(attack, armour, 0) - n = n + 1 + left -= damage(attack, armour, 0) + n += 1 } return n } diff --git a/examples/library/component_access.ludic b/examples/library/component_access.ludic index 9bfa956f..e07a302d 100644 --- a/examples/library/component_access.ludic +++ b/examples/library/component_access.ludic @@ -30,7 +30,7 @@ program ComponentAccess { Hero.of(player).iframes -= 5 print(Hero.of(player).iframes) # 15 let hero = Hero.of(player) - hero.roll_frames = hero.roll_frames + 1 + hero.roll_frames += 1 print(Hero.of(player).roll_frames) # 10 print(Position.of(player).x + Position.of(1).x) # 33 print(Hero.has(player)) # 1 diff --git a/examples/library/containers.ludic b/examples/library/containers.ludic index 9dc21c6d..90542e47 100644 --- a/examples/library/containers.ludic +++ b/examples/library/containers.ludic @@ -12,7 +12,7 @@ program Containers { if Dict.get(bank, "gold") == 150 { print(1) } if Dict.get(bank, "wood") == 50 { print(2) } if Dict.get(bank, "stone") == 0 { print(3) } # absent -> 0 - if Dict.get_or(bank, "stone", 0 - 1) == 0 - 1 { print(4) } + if Dict.get_or(bank, "stone", -1) == -1 { print(4) } if Dict.has(bank, "wood") { print(5) } if Dict.size(bank) == 2 { print(6) } Dict.remove(bank, "wood") @@ -21,7 +21,7 @@ program Containers { # grow past the initial capacity, then read back var i = 0 - while i < 100 { Dict.set(bank, "k" + string(i), i * 2); i = i + 1 } + while i < 100 { Dict.set(bank, "k" + string(i), i * 2); i += 1 } if Dict.get(bank, "k42") == 84 { print(9) } if Dict.size(bank) == 101 { print(10) } # gold + k0..k99 if len(Dict.keys(bank)) == 101 { print(11) } diff --git a/examples/library/core_components.ludic b/examples/library/core_components.ludic index 20d1c01b..9256d689 100644 --- a/examples/library/core_components.ludic +++ b/examples/library/core_components.ludic @@ -14,7 +14,7 @@ program CoreComponents { # subclassing, just another property on the same model. property Health { hp: int = 0 } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } entry { let pp = World.prop_id("Position") diff --git a/examples/library/coverage.ludic b/examples/library/coverage.ludic index 99605843..da9a933b 100644 --- a/examples/library/coverage.ludic +++ b/examples/library/coverage.ludic @@ -16,7 +16,7 @@ program CoverageSpec { return 1 } if n < 0 { - return 0 - 1 + return -1 } return 0 } @@ -35,7 +35,7 @@ program CoverageSpec { test "sign covers every branch" { expect_eq(sign(7), 1) - expect_eq(sign(0 - 3), 0 - 1) + expect_eq(sign(-3), -1) expect_eq(sign(0), 0) } diff --git a/examples/library/errors.ludic b/examples/library/errors.ludic index 278043cf..e3a2faa6 100644 --- a/examples/library/errors.ludic +++ b/examples/library/errors.ludic @@ -21,7 +21,7 @@ program Errors { entry { print(checked_div(10, 2)) # 5 print(clampi(15, 0, 10)) # 10 (above hi) - print(clampi(0 - 3, 0, 10)) # 0 (below lo) + print(clampi(-3, 0, 10)) # 0 (below lo) print(clampi(7, 0, 10)) # 7 (in range) print(1) # reached: every assertion held } diff --git a/examples/library/gameplay_foundation.ludic b/examples/library/gameplay_foundation.ludic index 021fe7f9..3d840b19 100644 --- a/examples/library/gameplay_foundation.ludic +++ b/examples/library/gameplay_foundation.ludic @@ -24,9 +24,9 @@ program GameplayFoundation { } var deaths: int = 0 - @On(Died) handler Tally { deaths = deaths + 1 } + @On(Died) handler Tally { deaths += 1 } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } entry { @@ -74,7 +74,7 @@ program GameplayFoundation { # finish it off with sub-100 hits so the veto never blocks the kill var guard = 0 - while (World.get(t, PS, fhp) > 0) and (guard < 100) { Combat.damage(t, a, 90); guard = guard + 1 } + while (World.get(t, PS, fhp) > 0) and (guard < 100) { Combat.damage(t, a, 90); guard += 1 } print(deaths) # 1 quit() diff --git a/examples/library/grid.ludic b/examples/library/grid.ludic index 6cf33b4c..537e7e06 100644 --- a/examples/library/grid.ludic +++ b/examples/library/grid.ludic @@ -45,12 +45,12 @@ program Grid { let dx = p[i].x - p[i - 1].x let dy = p[i].y - p[i - 1].y var ad = dx - if ad < 0 { ad = 0 - ad } + if ad < 0 { ad = -ad } var ay = dy - if ay < 0 { ay = 0 - ay } + if ay < 0 { ay = -ay } if ad + ay != 1 { ok = false } if Grid.blocked(p[i].x, p[i].y, '#') { ok = false } - i = i + 1 + i += 1 } if ok { print(9) } @@ -58,7 +58,7 @@ program Grid { if len(Grid.a_star(1, 1, 3, 2, '#')) == 0 { print(10) } # (3,2) is a wall if Grid.blocked(3, 2, '#') { print(11) } if not Grid.blocked(1, 1, '#') { print(12) } - if Grid.blocked(0 - 1, 0, '#') { print(13) } # out of bounds + if Grid.blocked(-1, 0, '#') { print(13) } # out of bounds } handler Run phase Update { quit() } diff --git a/examples/library/input_auto.ludic b/examples/library/input_auto.ludic index 25457007..74bcaca2 100644 --- a/examples/library/input_auto.ludic +++ b/examples/library/input_auto.ludic @@ -15,6 +15,6 @@ program InputAuto { var hits: int = 0 @OnStart handler Boot { Input.action("go", 'l') } # 'l' == 108 - handler Sense phase Update { if Input.active("go") { hits = hits + 1 } } + handler Sense phase Update { if Input.active("go") { hits += 1 } } @OnQuit handler Report { print(hits) } } diff --git a/examples/library/input_edge.ludic b/examples/library/input_edge.ludic index fddb1b58..84d2b13f 100644 --- a/examples/library/input_edge.ludic +++ b/examples/library/input_edge.ludic @@ -19,9 +19,9 @@ program InputEdge { handler In phase Update { var v = 0 - if Input.key_down('k') { v = v + 1 } # held - if Input.key_pressed('k') { v = v + 10 } # went down this frame - if Input.key_released('k') { v = v + 100 } # went up this frame + if Input.key_down('k') { v += 1 } # held + if Input.key_pressed('k') { v += 10 } # went down this frame + if Input.key_released('k') { v += 100 } # went up this frame print(v) } } diff --git a/examples/library/light_tiers.ludic b/examples/library/light_tiers.ludic index 7a7a67da..a94f1704 100644 --- a/examples/library/light_tiers.ludic +++ b/examples/library/light_tiers.ludic @@ -69,7 +69,7 @@ program LightTiers { dark() Light.clear_normals() Light.normal(18, 30, 8, 8, 0.7, 0.0) # this patch faces right (toward the light) - Light.normal(46, 30, 8, 8, 0.0 - 0.7, 0.0) # this patch faces left (away) + Light.normal(46, 30, 8, 8, 0.0 - 0.7, 0.0) # this patch faces left (away) Light.point(32, 34, 44, 16777215, 1.0) # a light centred between the patches let toward = lum(22, 34) # patch facing the light let away = lum(48, 34) # patch facing away diff --git a/examples/library/numeric.ludic b/examples/library/numeric.ludic index 2e202aca..0368b805 100644 --- a/examples/library/numeric.ludic +++ b/examples/library/numeric.ludic @@ -14,7 +14,7 @@ program Numeric { if Huge.str(Huge.add(Huge.from(1000000000), Huge.from(1))) == "1.00e9" { print(6) } # +1 negligible if Huge.cmp(Huge.from(1000000000), Huge.from(1000000)) == 1 { print(7) } if Huge.exp(Huge.mul(Huge.from(1000000), Huge.from(1000000))) == 12 { print(8) } - if Huge.str(Huge.from(0 - 42)) == "-4.20e1" { print(9) } + if Huge.str(Huge.from(-42)) == "-4.20e1" { print(9) } if Huge.str(Huge.from(0)) == "0" { print(10) } # --- Angle: wrapping radians (built on the deterministic Math.*) --- diff --git a/examples/library/optionresult.ludic b/examples/library/optionresult.ludic index b5ba9ef0..4198e9f8 100644 --- a/examples/library/optionresult.ludic +++ b/examples/library/optionresult.ludic @@ -12,7 +12,7 @@ program OptionResult { } # a fallible parse — a value or a message function to_digit(c: int) -> result { - if c >= 48 and c <= 57 { return ok(c - 48) } # '0'..'9' + if c >= '0' and c <= '9' { return ok(c - 48) } # '0'..'9' return err("not a digit") } entry { @@ -20,20 +20,20 @@ program OptionResult { let a = some(42) if is_some(a) { print(1) } if not is_none(a) { print(2) } - if unwrap_or(a, 0 - 1) == 42 { print(3) } + if unwrap_or(a, -1) == 42 { print(3) } let b = none() if is_none(b) { print(4) } - if unwrap_or(b, 0 - 1) == 0 - 1 { print(5) } + if unwrap_or(b, -1) == -1 { print(5) } if unwrap_or(slot_of(5), 0) == 50 { print(6) } - if is_none(slot_of(0 - 1)) { print(7) } + if is_none(slot_of(-1)) { print(7) } # --- result + try/else --- if is_ok(to_digit(55)) { print(8) } if is_err(to_digit(120)) { print(9) } let d = try to_digit(55) else { 0 } # '7' -> 7 if d == 7 { print(10) } - let bad = try to_digit(120) else { 0 - 1 } # not a digit -> fallback - if bad == 0 - 1 { print(11) } + let bad = try to_digit(120) else { -1 } # not a digit -> fallback + if bad == -1 { print(11) } let msg = try to_digit(120) else { print(12); 0 } # else binds `error` } } diff --git a/examples/library/physics.ludic b/examples/library/physics.ludic index ec9a2749..c27fc149 100644 --- a/examples/library/physics.ludic +++ b/examples/library/physics.ludic @@ -20,7 +20,7 @@ program Physics { hit: int = 0, entered: int = 0, exited: int = 0 } - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } # despawn every live entity carrying a property, so each scenario starts clean. @@ -65,7 +65,7 @@ program Physics { # re-apply the run velocity each frame, the way a controller drives it from # held input — so hit_wall stays asserted while pressed against the wall. var bi2 = 0 - while bi2 < 80 { World.set(a, pb, f_vx, fixed(4)); tick_fixed(); bi2 = bi2 + 1 } + while bi2 < 80 { World.set(a, pb, f_vx, fixed(4)); tick_fixed(); bi2 += 1 } print(World.get(a, pp, f_x)) # 284 — right edge stops at the wall (300) print(World.get(a, pb, f_hw)) # 1 — hit_wall while pressed print(bi(World.get(a, pb, f_vx) == 0)) # 1 — the sweep zeroed it this frame @@ -93,7 +93,7 @@ program Physics { spawn Plat { Position { x: 400, y: 150 }, Collider { w: 64, h: 8, one_way: 1 } } spawn Runner { Position { x: 405, y: 60 }, Body { gravity: fixed(1), max_fall: fixed(6) }, Collider { w: 16, h: 16 } } let e1 = World.query_next(pb, 0) - spawn Riser { Position { x: 430, y: 200 }, Body { vy: fixed(0 - 4), policy: 1 }, Collider { w: 16, h: 16 } } + spawn Riser { Position { x: 430, y: 200 }, Body { vy: fixed(-4), policy: 1 }, Collider { w: 16, h: 16 } } var e2 = World.query_next(pb, 0) if e2 == e1 { e2 = World.query_next(pb, e1 + 1) } tick_n(20) diff --git a/examples/library/physics_tiles.ludic b/examples/library/physics_tiles.ludic index 27e0e3a0..71ee651b 100644 --- a/examples/library/physics_tiles.ludic +++ b/examples/library/physics_tiles.ludic @@ -49,7 +49,7 @@ program PhysicsTiles { spawn Runner { Position { x: 32, y: 16 }, Body { gravity: fixed(1), max_fall: fixed(6) }, Collider { w: 16, h: 16 } } var a = World.query_next(pb, 0) var i = 0 - while i < 80 { tick_fixed(); i = i + 1 } + while i < 80 { tick_fixed(); i += 1 } print(World.get(a, pp, f_y)) # 112 — feet rest on the tile floor top (128) print(World.get(a, pb, f_grd)) # 1 @@ -58,7 +58,7 @@ program PhysicsTiles { spawn Runner { Position { x: 16, y: 112 }, Body { gravity: fixed(1), max_fall: fixed(6) }, Collider { w: 16, h: 16 } } a = World.query_next(pb, 0) i = 0 - while i < 60 { World.set(a, pb, f_vx, fixed(4)); tick_fixed(); i = i + 1 } + while i < 60 { World.set(a, pb, f_vx, fixed(4)); tick_fixed(); i += 1 } print(World.get(a, pp, f_x)) # 80 — right edge stops at the wall column (96) print(World.get(a, pb, f_hw)) # 1 @@ -67,16 +67,16 @@ program PhysicsTiles { spawn Runner { Position { x: 176, y: 16 }, Body { gravity: fixed(1), max_fall: fixed(6) }, Collider { w: 16, h: 16 } } a = World.query_next(pb, 0) i = 0 - while i < 40 { tick_fixed(); i = i + 1 } + while i < 40 { tick_fixed(); i += 1 } print(World.get(a, pp, f_y)) # 48 — feet on the one-way top (64) print(World.get(a, pb, f_grd)) # 1 # ---- T3b. rise straight up through the one-way tile -------------------- clear() - spawn Riser { Position { x: 176, y: 120 }, Body { vy: fixed(0 - 4), policy: 1 }, Collider { w: 16, h: 16 } } + spawn Riser { Position { x: 176, y: 120 }, Body { vy: fixed(-4), policy: 1 }, Collider { w: 16, h: 16 } } a = World.query_next(pb, 0) i = 0 - while i < 15 { tick_fixed(); i = i + 1 } + while i < 15 { tick_fixed(); i += 1 } print(World.get(a, pp, f_y)) # 60 — passed through (120 - 4*15), above the platform quit() diff --git a/examples/library/query.ludic b/examples/library/query.ludic index b96ab2de..b44faa66 100644 --- a/examples/library/query.ludic +++ b/examples/library/query.ludic @@ -52,7 +52,7 @@ program Query { let near0 = Query.within(P, P, 0, 0, 0, cx, cy) if len(near0) == 1 { print(14) } # only e0 at (0,0) if World.get(near0[0], P, cx) == 0 { print(15) } # and it is e0 - if len(Query.within(G, P, 0, 0, 100, cx, cy)) == 0 { print(16) } # empty + if len(Query.within(G, P, 0, 0, 100, cx, cy)) == 0 { print(16) } # empty if len(Query.within(K, P, 0, 0, 6, cx, cy)) == 2 { print(17) } # Mobs e0, e2 (filter K, pos P) if World.get(Query.nearest(P, P, cx, cy, 20, 20), P, cx) == 20 { print(18) } # e4 diff --git a/examples/library/reflect.ludic b/examples/library/reflect.ludic index 18fc193f..8e3b2a23 100644 --- a/examples/library/reflect.ludic +++ b/examples/library/reflect.ludic @@ -52,11 +52,11 @@ program Reflect { let fc = Reflect.field_count(p) var f = 0 while f < fc { - total = total + Reflect.get(e, p, f) - f = f + 1 + total += Reflect.get(e, p, f) + f += 1 } } - p = p + 1 + p += 1 } if total == 327697 { print(17) } # 7 + 10 + 131072 + 196608 diff --git a/examples/library/regex.ludic b/examples/library/regex.ludic index a8c0c14c..718162de 100644 --- a/examples/library/regex.ludic +++ b/examples/library/regex.ludic @@ -42,7 +42,7 @@ program Regex { var tags = "" var cur = Regex.exec("#a #bb #ccc", re) while Regex.ok(cur) { - tags = tags + Regex.group(cur, 1) + tags += Regex.group(cur, 1) cur = Regex.next("#a #bb #ccc", re, Regex.end(cur, 0)) } if tags == "abbccc" { print(16) } diff --git a/examples/library/testing.ludic b/examples/library/testing.ludic index 9b7f8f2c..8684dc5e 100644 --- a/examples/library/testing.ludic +++ b/examples/library/testing.ludic @@ -32,7 +32,7 @@ program TestingSpec { test "loops and locals work in a test" { var sum = 0 - for i in 0 .. 5 { sum = sum + i } # 0+1+2+3+4 = 10 + for i in 0 .. 5 { sum += i } # 0+1+2+3+4 = 10 expect_eq(sum, 10) } diff --git a/examples/library/tiled_p05.ludic b/examples/library/tiled_p05.ludic index 36de69a4..250b7ae2 100644 --- a/examples/library/tiled_p05.ludic +++ b/examples/library/tiled_p05.ludic @@ -26,7 +26,7 @@ program TiledP05 { # --- four layers, every encoding decodes to the SAME 16-GID array --- let layers = Value.get(m, "layers") if Value.count(layers) == 4 { print(8) } - let FLIP = 0 - 2147483647 # 0x80000001 as i32 + let FLIP = -2147483647 # 0x80000001 as i32 var same = 1 var li = 0 while li < 4 { @@ -35,7 +35,7 @@ program TiledP05 { if Value.as_int(Value.at(data, 0)) != 1 { same = 0 } if Value.as_int(Value.at(data, 14)) != 15 { same = 0 } if Value.as_int(Value.at(data, 15)) != FLIP { same = 0 } - li = li + 1 + li += 1 } if same == 1 { print(9) } # the CSV path and the gzip path agree on the flip-flagged GID @@ -61,9 +61,9 @@ program TiledP05 { var gi = 0 while gi < 16 { if Value.as_int(Value.at(jdata, gi)) != Value.as_int(Value.at(csvdata, gi)) { jsame = 0 } - gi = gi + 1 + gi += 1 } - jli = jli + 1 + jli += 1 } if jsame == 1 { print(16) } diff --git a/examples/library/tiled_p1.ludic b/examples/library/tiled_p1.ludic index c1c9da3c..1616d77b 100644 --- a/examples/library/tiled_p1.ludic +++ b/examples/library/tiled_p1.ludic @@ -18,9 +18,9 @@ program TiledP1 { var x = 0 while x < 320 { h = h * 31 + rt_get_px(x, y) - x = x + 4 + x += 4 } - y = y + 4 + y += 4 } return h } @@ -56,7 +56,7 @@ program TiledP1 { # --- flips draw with the correct orientation --- # find a horizontally-asymmetric tile so the mirror test is meaningful - var chosen = 0 - 1 + var chosen = -1 var t = 0 while t < 132 { rt_clear(0) @@ -67,12 +67,12 @@ program TiledP1 { var xx = 0 while xx < 8 { if rt_get_px(xx, yy) != rt_get_px(15 - xx, yy) { asym = 1 } - xx = xx + 1 + xx += 1 } - yy = yy + 1 + yy += 1 } if asym == 1 and chosen < 0 { chosen = t } - t = t + 1 + t += 1 } if chosen >= 0 { print(12) } @@ -88,9 +88,9 @@ program TiledP1 { while xx2 < 16 { if rt_get_px(xx2, yy2) != rt_get_px(31 - xx2, yy2) { mirror = 0 } # H-flip mirrors if rt_get_px(xx2, yy2) != rt_get_px(15 - xx2, yy2) { diff = 1 } # the tile isn't symmetric - xx2 = xx2 + 1 + xx2 += 1 } - yy2 = yy2 + 1 + yy2 += 1 } if mirror == 1 { print(13) } if diff == 1 { print(14) } diff --git a/examples/library/tiled_p2.ludic b/examples/library/tiled_p2.ludic index 6771c633..37d7e0d6 100644 --- a/examples/library/tiled_p2.ludic +++ b/examples/library/tiled_p2.ludic @@ -23,16 +23,16 @@ program TiledP2 { var n = 0 var y = 0 while y < 10 { var x = 0 - while x < 16 { if rt_tile(x, y) == 35 { n = n + 1 }; x = x + 1 } - y = y + 1 } + while x < 16 { if rt_tile(x, y) == 35 { n += 1 }; x += 1 } + y += 1 } return n } function grid_hash() -> int { var h = 0 var y = 0 while y < 10 { var x = 0 - while x < 16 { h = h * 31 + rt_tile(x, y); x = x + 1 } - y = y + 1 } + while x < 16 { h = h * 31 + rt_tile(x, y); x += 1 } + y += 1 } return h } @@ -75,7 +75,7 @@ program TiledP2 { let f_grd = World.field_id(pb, "on_ground") let a = World.query_next(pb, 0) var i = 0 - while i < 80 { tick_fixed(); i = i + 1 } + while i < 80 { tick_fixed(); i += 1 } if World.get(a, pp, f_y) == 112 { print(13) } # feet rest on the tile floor top (128) if World.get(a, pb, f_grd) == 1 { print(14) } } diff --git a/examples/library/tiled_p3.ludic b/examples/library/tiled_p3.ludic index b2503f0b..c7300c07 100644 --- a/examples/library/tiled_p3.ludic +++ b/examples/library/tiled_p3.ludic @@ -13,8 +13,8 @@ program TiledP3 { var h = 0 var y = 0 while y < 64 { var x = 0 - while x < 64 { h = h * 31 + rt_get_px(x, y); x = x + 2 } - y = y + 2 } + while x < 64 { h = h * 31 + rt_get_px(x, y); x += 2 } + y += 2 } return h } @@ -38,13 +38,13 @@ program TiledP3 { # --- tile object parsed from the object layer --- let tree = Tiled.tree(m) - var oglayer = Value.null() + var oglayer = Value.null () let layers = Value.get(tree, "layers") var li = 0 while li < Value.count(layers) { let L = Value.at(layers, li) if Value.as_str(Value.get(L, "type")) == "objectgroup" { oglayer = L } - li = li + 1 + li += 1 } let objs = Value.get(oglayer, "objects") if Value.count(objs) == 1 { print(8) } @@ -62,7 +62,7 @@ program TiledP3 { # --- tile objects draw with correct GID flips (mirror test) --- # find an asymmetric tile, draw it normal vs H-flipped as a tile object - var chosen = 0 - 1 + var chosen = -1 var t = 0 while t < 132 { rt_clear(0) @@ -70,10 +70,10 @@ program TiledP3 { var asym = 0 var yy = 0 while yy < 16 { var xx = 0 - while xx < 8 { if rt_get_px(xx, yy) != rt_get_px(15 - xx, yy) { asym = 1 }; xx = xx + 1 } - yy = yy + 1 } + while xx < 8 { if rt_get_px(xx, yy) != rt_get_px(15 - xx, yy) { asym = 1 }; xx += 1 } + yy += 1 } if asym == 1 and chosen < 0 { chosen = t } - t = t + 1 + t += 1 } rt_clear(0) tmap_draw_gid(m, 1 + chosen, 0, 0) @@ -81,8 +81,8 @@ program TiledP3 { var mirror = 1 var yy2 = 0 while yy2 < 16 { var xx2 = 0 - while xx2 < 16 { if rt_get_px(xx2, yy2) != rt_get_px(31 - xx2, yy2) { mirror = 0 }; xx2 = xx2 + 1 } - yy2 = yy2 + 1 } + while xx2 < 16 { if rt_get_px(xx2, yy2) != rt_get_px(31 - xx2, yy2) { mirror = 0 }; xx2 += 1 } + yy2 += 1 } if mirror == 1 and chosen >= 0 { print(12) } # --- the design's named fixture: rpg/beach_tileset.tsx (33 animations) --- @@ -94,8 +94,8 @@ program TiledP3 { while ti < Value.count(tiles) { let tt = Value.at(tiles, ti) let an = Value.get(tt, "animation") - if Value.count(an) > 0 { nanim = nanim + 1; nframes = nframes + Value.count(an) } - ti = ti + 1 + if Value.count(an) > 0 { nanim += 1; nframes += Value.count(an) } + ti += 1 } if nanim == 33 { print(13) } if nframes == 131 { print(14) } diff --git a/examples/library/tiled_p4.ludic b/examples/library/tiled_p4.ludic index 8ccc4de6..4c58903c 100644 --- a/examples/library/tiled_p4.ludic +++ b/examples/library/tiled_p4.ludic @@ -51,11 +51,11 @@ program TiledP4 { # --- the design's named fixture: orthogonal-outside.tmx object shapes --- let og = Tiled.load("assets/tiled-fixtures/orthogonal-outside.tmx") - var olayer = 0 - 1 + var olayer = -1 var oli = 0 while oli < Tiled.layer_count(og) { if Tiled.object_count(og, oli) > 0 { olayer = oli } - oli = oli + 1 + oli += 1 } var nell = 0 var npt = 0 @@ -64,11 +64,11 @@ program TiledP4 { var oi = 0 while oi < Tiled.object_count(og, olayer) { let sh = Tiled.object_shape(Tiled.object(og, olayer, oi)) - if sh == "ellipse" { nell = nell + 1 } - if sh == "point" { npt = npt + 1 } - if sh == "polygon" { npg = npg + 1 } - if sh == "polyline" { npl = npl + 1 } - oi = oi + 1 + if sh == "ellipse" { nell += 1 } + if sh == "point" { npt += 1 } + if sh == "polygon" { npg += 1 } + if sh == "polyline" { npl += 1 } + oi += 1 } if nell == 1 and npt == 1 and npg == 1 { print(17) } if npl == 2 { print(18) } diff --git a/examples/library/tiled_p5.ludic b/examples/library/tiled_p5.ludic index b46efa27..580e150a 100644 --- a/examples/library/tiled_p5.ludic +++ b/examples/library/tiled_p5.ludic @@ -13,7 +13,7 @@ program TiledP5 { let iso = Tiled.load("assets/tiled-fixtures/isometric_grass_and_water.tmx") if Value.as_str(Value.get(Tiled.tree(iso), "orientation")) == "isometric" { print(1) } if Tiled.cell_x(iso, 1, 0) == 32 { print(2) } # (1-0)*64/2 - if Tiled.cell_x(iso, 0, 1) == 0 - 32 { print(3) } # (0-1)*64/2 + if Tiled.cell_x(iso, 0, 1) == -32 { print(3) } # (0-1)*64/2 if Tiled.cell_y(iso, 1, 1) == 32 { print(4) } # (1+1)*32/2 if Tiled.cell_y(iso, 2, 0) == 32 { print(5) } # (2+0)*32/2 @@ -23,8 +23,8 @@ program TiledP5 { var cy = 0 while cy < Tiled.height(iso) and g == 0 { var cx = 0 - while cx < Tiled.width(iso) and g == 0 { g = Tiled.gid(iso, 0, cx, cy); cx = cx + 1 } - cy = cy + 1 + while cx < Tiled.width(iso) and g == 0 { g = Tiled.gid(iso, 0, cx, cy); cx += 1 } + cy += 1 } let r = Tiled.resolve(iso, g) if r.tileset == 0 and r.local >= 0 { print(6) } @@ -48,8 +48,8 @@ program TiledP5 { var yy = 0 while yy < 32 and painted == 0 { var xx = 0 - while xx < 32 and painted == 0 { if rt_get_px(xx, yy) != 0 { painted = 1 }; xx = xx + 1 } - yy = yy + 1 + while xx < 32 and painted == 0 { if rt_get_px(xx, yy) != 0 { painted = 1 }; xx += 1 } + yy += 1 } if painted == 1 { print(14) } } diff --git a/examples/library/tiled_p6.ludic b/examples/library/tiled_p6.ludic index b8d64baf..76d48a46 100644 --- a/examples/library/tiled_p6.ludic +++ b/examples/library/tiled_p6.ludic @@ -40,7 +40,7 @@ program TiledP6 { var i = 0 while i < Value.count(csv) { if Value.as_int(Value.at(csv, i)) != Value.as_int(Value.at(zstd, i)) { same = 0 } - i = i + 1 + i += 1 } if same == 1 { print(12) } } diff --git a/examples/library/world_bounds.ludic b/examples/library/world_bounds.ludic index dc5639d0..711ce07a 100644 --- a/examples/library/world_bounds.ludic +++ b/examples/library/world_bounds.ludic @@ -8,7 +8,7 @@ program WorldBounds { import "ludic.core/components.ludic" - function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i = i + 1 } } + function tick_n(n: int) -> void { var i = 0; while i < n { tick_fixed(); i += 1 } } function bi(b: bool) -> int { if b { return 1 }; return 0 } function clear_all() -> void { @@ -57,7 +57,7 @@ program WorldBounds { tick_n(1) var live = 0 var q = World.query_next(PBody, 0) - while q >= 0 { live = live + 1; q = World.query_next(PBody, q + 1) } + while q >= 0 { live += 1; q = World.query_next(PBody, q + 1) } print(live) # 0 — the out-of-bounds body was killed } } diff --git a/examples/networking/net_demo.ludic b/examples/networking/net_demo.ludic index 9bcc87d9..f84974f2 100644 --- a/examples/networking/net_demo.ludic +++ b/examples/networking/net_demo.ludic @@ -23,7 +23,7 @@ program NetDemo { @ToServer event Move { dx: int = 0 } # client → server RPC @On(Move) handler DoMove { # the authority applies input - for (Pos) in query [Pos, {Ship}] { Pos.x = Pos.x + dx } + for (Pos) in query [Pos, {Ship}] { Pos.x += dx } } entry { diff --git a/examples/networking/net_echo.ludic b/examples/networking/net_echo.ludic index 952a948a..f4013788 100644 --- a/examples/networking/net_echo.ludic +++ b/examples/networking/net_echo.ludic @@ -9,16 +9,16 @@ program NetEcho { entry { let out = bytes(4) - out[0] = 10 + out[0] = '\n' out[1] = 20 out[2] = 30 - out[3] = 42 + out[3] = '*' net_send(0, out, 4) # onto the wire (the built-in loopback) let inb = bytes(64) let n = net_poll(inb, 64) # take the next datagram back off print(n) # 4 var i = 0 - while i < n { print(inb[i]); i = i + 1 } # 10 20 30 42 + while i < n { print(inb[i]); i += 1 } # 10 20 30 42 } } diff --git a/examples/networking/net_roles.ludic b/examples/networking/net_roles.ludic index 9279de96..aa333cdc 100644 --- a/examples/networking/net_roles.ludic +++ b/examples/networking/net_roles.ludic @@ -16,8 +16,8 @@ program NetRoles { property Score { n: int = 0 } model Board { Score } - handler Both phase Update { for (Score) in query [Score] { Score.n = Score.n + 1 } } # runs everywhere - @Server handler ServerOnly phase Update { for (Score) in query [Score] { Score.n = Score.n + 100 } } # authority only + handler Both phase Update { for (Score) in query [Score] { Score.n += 1 } } # runs everywhere + @Server handler ServerOnly phase Update { for (Score) in query [Score] { Score.n += 100 } } # authority only entry { spawn Board { Score { n: 0 } } diff --git a/examples/networking/net_rpc.ludic b/examples/networking/net_rpc.ludic index 2bdbf442..c215afcc 100644 --- a/examples/networking/net_rpc.ludic +++ b/examples/networking/net_rpc.ludic @@ -15,7 +15,7 @@ program NetRpc { @ToServer event Fire { dir: int = 0 } @On(Fire) handler OnFire { - for (Log) in query [Log] { Log.hits = Log.hits + dir } + for (Log) in query [Log] { Log.hits += dir } } entry { diff --git a/packages/ludic.gameplay/combat.ludic b/packages/ludic.gameplay/combat.ludic index 31551a34..bb27d7ea 100644 --- a/packages/ludic.gameplay/combat.ludic +++ b/packages/ludic.gameplay/combat.ludic @@ -53,7 +53,7 @@ var combat_pending: int = 0 # the attacker's build: damage_pct, then a crit_pct chance to double var raw = amount * stats_field(src, "damage_pct", 100) / 100 let crit = stats_field(src, "crit_pct", 0) - if (crit > 0) and Random.chance(percent: crit) { raw = raw * 2; emit Crit(target: target, src: src) } + if (crit > 0) and Random.chance(percent: crit) { raw *= 2; emit Crit(target: target, src: src) } combat_pending = combat_mitigate(target, raw) if emit DamageAboutToApply(target: target, src: src, amount: combat_pending) != 0 { return 0 } var dmg = combat_pending diff --git a/packages/ludic.gameplay/faction.ludic b/packages/ludic.gameplay/faction.ludic index 29778034..7078ef92 100644 --- a/packages/ludic.gameplay/faction.ludic +++ b/packages/ludic.gameplay/faction.ludic @@ -55,10 +55,10 @@ function fac_ensure() -> void { # Faction.id_of(e) — the faction id an entity carries (-1 if it has no Faction). @Namespace(Faction) function faction_id_of(e: int) -> int { let P = World.prop_id("Faction") - if P < 0 { return 0 - 1 } - if World.has(e, P) == 0 { return 0 - 1 } + if P < 0 { return -1 } + if World.has(e, P) == 0 { return -1 } let f = World.field_id(P, "id") - if f < 0 { return 0 - 1 } + if f < 0 { return -1 } return World.get(e, P, f) } diff --git a/packages/ludic.gameplay/stats.ludic b/packages/ludic.gameplay/stats.ludic index 49ca3a3a..a469bc4e 100644 --- a/packages/ludic.gameplay/stats.ludic +++ b/packages/ludic.gameplay/stats.ludic @@ -89,21 +89,11 @@ model ModifierFx { Modifier } } } -# map a stat code to the matching Stats field name. -function stat_field(stat: int) -> pointer { - if stat == 0 { return "max_hp" } - if stat == 1 { return "atk" } - if stat == 2 { return "def" } - if stat == 3 { return "spd" } - if stat == 4 { return "max_mp" } - return "atk" -} - # Stats.base(e, stat) — the raw stored field, no modifiers. @Namespace(Stats) function stats_base(e: int, stat: int) -> int { let P = World.prop_id("Stats") if P < 0 { return 0 } - let f = World.field_id(P, stat_field(stat)) + let f = World.field_id(P, stats_field_name(stat)) if f < 0 { return 0 } return World.get(e, P, f) } @@ -123,7 +113,7 @@ function stat_field(stat: int) -> pointer { while m >= 0 { if (World.get(m, P, ft) == e) and (World.get(m, P, fs) == stat) { let amt = World.get(m, P, fa) - if World.get(m, P, fo) == 1 { pct = pct + amt } else { flat = flat + amt } + if World.get(m, P, fo) == 1 { pct += amt } else { flat += amt } } m = World.query_next(P, m + 1) } @@ -133,7 +123,7 @@ function stat_field(stat: int) -> pointer { # Stats.modify(target, stat, op, amount, ttl) — push a modifier onto the stack. @Namespace(Stats) function stats_modify(target: int, stat: int, op: int, amount: int, ttl: int) -> int { let m = World.model_id("ModifierFx") - if m < 0 { return 0 - 1 } + if m < 0 { return -1 } let e = World.spawn(m) let P = World.prop_id("Modifier") World.set(e, P, World.field_id(P, "target"), target) diff --git a/packages/ludic.npcai/npcai.ludic b/packages/ludic.npcai/npcai.ludic index 5648db77..2bfa2c44 100644 --- a/packages/ludic.npcai/npcai.ludic +++ b/packages/ludic.npcai/npcai.ludic @@ -32,7 +32,7 @@ property Brain { home_x: int = 0, home_y: int = 0, seed: int = 1, hunt_blind: int = 0 # 1 = with no target in sight, seek the nearest hostile anyway (no idle patrol) } -property Follower { leader: int = 0 - 1, distance: int = 40, mode: int = 0 } # mode 0 follow,1 guard,2 aggressive +property Follower { leader: int = -1, distance: int = 40, mode: int = 0 } # mode 0 follow,1 guard,2 aggressive property Steering { separate: int = 0, cohere: int = 0, align: int = 0, radius: int = 48 } # --------------------------------------------------------------------------- @@ -59,7 +59,7 @@ function ai_has(prop: pointer, e: int) -> int { let P = World.prop_id(prop); if P < 0 { return 0 } return World.has(e, P) } -function sign_i(a: int) -> int { if a > 0 { return 1 }; if a < 0 { return 0 - 1 }; return 0 } +function sign_i(a: int) -> int { if a > 0 { return 1 }; if a < 0 { return -1 }; return 0 } # optional line-of-sight over the tilemap (only when a Solids config exists); # without a tilemap the field is open, so LOS is always clear. @@ -104,7 +104,7 @@ function ai_los(px: int, py: int, tx: int, ty: int) -> int { let fac = Faction.id_of(e) # nearest hostile in range + LOS let PF = World.prop_id("Faction") - var best = 0 - 1 + var best = -1 var bestd = 0 var o = World.query_next(PF, 0) while o >= 0 { @@ -196,8 +196,8 @@ function brain_seek(e: int, tx: int, ty: int) -> void { function brain_flee(e: int, tx: int, ty: int) -> void { let px = ai_get("Position", e, "x") let py = ai_get("Position", e, "y") - ai_set("Brain", e, "intent_x", 0 - sign_i(tx - px)) - ai_set("Brain", e, "intent_y", 0 - sign_i(ty - py)) + ai_set("Brain", e, "intent_x", -sign_i(tx - px)) + ai_set("Brain", e, "intent_y", -sign_i(ty - py)) } function brain_stop(e: int) -> void { ai_set("Brain", e, "intent_x", 0); ai_set("Brain", e, "intent_y", 0) } @@ -257,20 +257,20 @@ function ai_decide_fsm(e: int) -> void { let tx = ai_get("Memory", e, "last_x") let ty = ai_get("Memory", e, "last_y") if brain_low_hp(e, ai_get("Brain", e, "flee_pct")) == 1 { - if emit DecisionMade(e: e, action: 3) == 0 { brain_set_state(e, 3); brain_flee(e, tx, ty) } + if emit DecisionMade(e: e, action: AiState.Flee) == 0 { brain_set_state(e, AiState.Flee); brain_flee(e, tx, ty) } } else { if d2 <= ar * ar { - if emit DecisionMade(e: e, action: 2) == 0 { brain_set_state(e, 2); brain_stop(e); ai_set("Brain", e, "want_fire", 1) } + if emit DecisionMade(e: e, action: AiState.Attack) == 0 { brain_set_state(e, AiState.Attack); brain_stop(e); ai_set("Brain", e, "want_fire", 1) } } else { - if emit DecisionMade(e: e, action: 1) == 0 { brain_set_state(e, 1); brain_seek(e, tx, ty) } + if emit DecisionMade(e: e, action: AiState.Chase) == 0 { brain_set_state(e, AiState.Chase); brain_seek(e, tx, ty) } } } } else { let prey = brain_nearest_hostile(e) if (ai_get("Brain", e, "hunt_blind") == 1) and (prey >= 0) { - if emit DecisionMade(e: e, action: 1) == 0 { brain_set_state(e, 1); brain_seek(e, ai_get("Position", prey, "x"), ai_get("Position", prey, "y")) } + if emit DecisionMade(e: e, action: AiState.Chase) == 0 { brain_set_state(e, AiState.Chase); brain_seek(e, ai_get("Position", prey, "x"), ai_get("Position", prey, "y")) } } else { - if emit DecisionMade(e: e, action: 0) == 0 { brain_set_state(e, 0); brain_wander(e) } + if emit DecisionMade(e: e, action: AiState.Patrol) == 0 { brain_set_state(e, AiState.Patrol); brain_wander(e) } } } } @@ -278,11 +278,11 @@ function ai_decide_fsm(e: int) -> void { function brain_nearest_hostile(e: int) -> int { let PF = World.prop_id("Faction") let PP = World.prop_id("Position") - if (PF < 0) or (PP < 0) { return 0 - 1 } + if (PF < 0) or (PP < 0) { return -1 } let fac = Faction.id_of(e) let px = ai_get("Position", e, "x") let py = ai_get("Position", e, "y") - var best = 0 - 1 + var best = -1 var bestd = 0 var o = World.query_next(PF, 0) while o >= 0 { @@ -338,11 +338,11 @@ function ai_decide_bt(e: int) -> void { let ar = ai_get("Brain", e, "attack_range") if ai_get("Memory", e, "has_target") == 1 { # leaf: see_target if brain_target_d2(e) <= ar * ar { # leaf: in_range - if emit DecisionMade(e: e, action: 2) == 0 { brain_set_state(e, 2); brain_stop(e); ai_set("Brain", e, "want_fire", 1); return } + if emit DecisionMade(e: e, action: AiState.Attack) == 0 { brain_set_state(e, AiState.Attack); brain_stop(e); ai_set("Brain", e, "want_fire", 1); return } } - if emit DecisionMade(e: e, action: 1) == 0 { brain_set_state(e, 1); brain_seek(e, tx, ty); return } + if emit DecisionMade(e: e, action: AiState.Chase) == 0 { brain_set_state(e, AiState.Chase); brain_seek(e, tx, ty); return } } - if emit DecisionMade(e: e, action: 0) == 0 { brain_set_state(e, 0); brain_wander(e) } + if emit DecisionMade(e: e, action: AiState.Patrol) == 0 { brain_set_state(e, AiState.Patrol); brain_wander(e) } } # =========================================================================== @@ -404,8 +404,8 @@ function ai_decide_bt(e: int) -> void { let dx = ox - px; let dy = oy - py let d2 = dx * dx + dy * dy if d2 <= radius * radius { - sepx = sepx - sign_i(dx); sepy = sepy - sign_i(dy) - cx = cx + ox; cy = cy + oy; n = n + 1 + sepx -= sign_i(dx); sepy -= sign_i(dy) + cx += ox; cy += oy; n += 1 } } o = World.query_next(PS, o + 1) @@ -413,8 +413,8 @@ function ai_decide_bt(e: int) -> void { if n > 0 { var ix = ai_get("Brain", e, "intent_x") var iy = ai_get("Brain", e, "intent_y") - if wsep > 0 { ix = ix + sign_i(sepx); iy = iy + sign_i(sepy) } - if wcoh > 0 { ix = ix + sign_i(cx / n - px); iy = iy + sign_i(cy / n - py) } + if wsep > 0 { ix += sign_i(sepx); iy += sign_i(sepy) } + if wcoh > 0 { ix += sign_i(cx / n - px); iy += sign_i(cy / n - py) } ai_set("Brain", e, "intent_x", sign_i(ix)) ai_set("Brain", e, "intent_y", sign_i(iy)) } @@ -457,7 +457,7 @@ function ai_decide_bt(e: int) -> void { @Namespace(Ai) function ai_state(e: int) -> int { return ai_get("Brain", e, "state") } @Namespace(Ai) function ai_target(e: int) -> int { if ai_get("Memory", e, "has_target") == 1 { return ai_get("Memory", e, "target") } - return 0 - 1 + return -1 } @Namespace(Follower) function follower_set(e: int, leader: int, distance: int, mode: int) -> void { ai_set("Follower", e, "leader", leader) diff --git a/packages/ludic.platformer/platformer.ludic b/packages/ludic.platformer/platformer.ludic index d394bc2d..4c6d837f 100644 --- a/packages/ludic.platformer/platformer.ludic +++ b/packages/ludic.platformer/platformer.ludic @@ -39,9 +39,9 @@ property Platformer { friction: int = 50, # ground stopping, % of speed shed / frame when idle jump_height: int = 4, # tiles; gravity + impulse are derived from this + apex apex_frames: int = 14, # frames to the top of the jump (defines gravity — feel) - fall_gravity_mul: int = 160, # 100 = symmetric; >100 = snappier fall (Celeste) + fall_gravity_mul: int = 160, # 100 = symmetric; >100 = snappier fall (Celeste) coyote_frames: int = 6, # grace frames to still jump after leaving a ledge - jump_buffer_frames: int = 6, # grace frames to buffer a jump pressed before landing + jump_buffer_frames: int = 6, # grace frames to buffer a jump pressed before landing max_fall: int = 8, # terminal fall speed, px/frame air_jumps: int = 0, # extra mid-air jumps (1 = double jump, N = multi) policy: int = 0, # gravity profile (lever 6): 0 asymmetric, 1 symmetric, 2 floaty @@ -129,8 +129,8 @@ function bd_set(e: int, name: pointer, v: int) -> void { var e = World.query_next(P, 0) while e >= 0 { var wx = 0 - if Input.down("move_right") { wx = wx + 1 } - if Input.down("move_left") { wx = wx - 1 } + if Input.down("move_right") { wx += 1 } + if Input.down("move_left") { wx -= 1 } pf_set(e, "want_x", wx) var wj = 0; if Input.pressed("jump") { wj = 1 } pf_set(e, "want_jump", wj) @@ -185,14 +185,14 @@ function bd_set(e: int, name: pointer, v: int) -> void { let apex = pf_get(e, "apex_frames") var g = plat_g(jh, apex, tile) let pol = pf_get(e, "policy") - if pol == 2 { g = g / 2 } # floaty + if pol == 2 { g /= 2 } # floaty let vy = bd_get(e, "vy") if vy > 0 { # falling var fm = pf_get(e, "fall_gravity_mul") if pol == 1 { fm = 100 } # symmetric profile ignores the fall multiplier g = g * fm / 100 } else { - if pf_get(e, "hold_jump") == 0 { g = g * 2 } # released while rising -> short hop + if pf_get(e, "hold_jump") == 0 { g *= 2 } # released while rising -> short hop } bd_set(e, "gravity", g) bd_set(e, "max_fall", pf_get(e, "max_fall") * PLAT_Q) @@ -205,7 +205,7 @@ function plat_do_jump(e: int, kind: int) -> bool { if emit JumpRequested(e: e, kind: kind) != 0 { return false } let tile = plat_tile() let v0 = plat_v0(pf_get(e, "jump_height"), pf_get(e, "apex_frames"), tile) - bd_set(e, "vy", 0 - v0) + bd_set(e, "vy", -v0) pf_set(e, "buffer_t", 0) pf_set(e, "coyote_t", 0) emit JumpPerformed(e: e, kind: kind) @@ -280,7 +280,7 @@ function plat_do_jump(e: int, kind: int) -> bool { # state var st = 0 if grounded == 1 { - var ax = vx; if ax < 0 { ax = 0 - ax } + var ax = vx; if ax < 0 { ax = -ax } if ax > (PLAT_Q / 4) { st = 1 } else { st = 0 } # running vs idle (>0.25 px/frame) } else { if vy < 0 { st = 2 } else { st = 3 } # rise vs fall diff --git a/packages/ludic.platformer/scaffolding.ludic b/packages/ludic.platformer/scaffolding.ludic index 58354bab..0ec64fba 100644 --- a/packages/ludic.platformer/scaffolding.ludic +++ b/packages/ludic.platformer/scaffolding.ludic @@ -58,7 +58,7 @@ event PlatformCrumbled { e: int = 0 } # platform's top edge within the horizontal span. function plat_rider_on(p: int) -> int { let PB = World.prop_id("Body") - if PB < 0 { return 0 - 1 } + if PB < 0 { return -1 } let px = sc_pos(p, "x") + sc_col(p, "offx") let py = sc_pos(p, "y") + sc_col(p, "offy") let pw = sc_col(p, "w") @@ -79,7 +79,7 @@ function plat_rider_on(p: int) -> int { } b = World.query_next(PB, b + 1) } - return 0 - 1 + return -1 } @EngineSystem(Platform, FixedUpdate) function esys_platform() -> void { @@ -103,8 +103,8 @@ function plat_rider_on(p: int) -> int { var tx = bx; var ty = by if dir < 0 { tx = ax; ty = ay } var dx = 0; var dy = 0 - if ox < tx { dx = speed } else { if ox > tx { dx = 0 - speed } } - if oy < ty { dy = speed } else { if oy > ty { dy = 0 - speed } } + if ox < tx { dx = speed } else { if ox > tx { dx = -speed } } + if oy < ty { dy = speed } else { if oy > ty { dy = -speed } } # clamp the step so we do not overshoot the endpoint if dx > 0 { if ox + dx > tx { dx = tx - ox } } if dx < 0 { if ox + dx < tx { dx = tx - ox } } @@ -120,7 +120,7 @@ function plat_rider_on(p: int) -> int { } # flip direction at an endpoint if (sc_pos(e, "x") == tx) and (sc_pos(e, "y") == ty) { - World.set(e, P, World.field_id(P, "dir"), 0 - dir) + World.set(e, P, World.field_id(P, "dir"), -dir) } } if kind == 3 { # crumble @@ -222,7 +222,7 @@ event Sprang { body: int = 0, spring: int = 0, power: int = 0 } let body = World.get(e, PC, fhit) if body >= 0 { let power = World.get(e, P, fpow) - sc_body_set(body, "vy", 0 - power * SCAF_Q) + sc_body_set(body, "vy", -power * SCAF_Q) sc_body_set(body, "ry", 0) emit Sprang(body: body, spring: e, power: power) } @@ -269,7 +269,7 @@ property Hazard { dmg: int = 1, knockback: int = 6 } let dmg = World.get(e, P, fdmg) if life_hurt(body, e, dmg) > 0 { let kb = World.get(e, P, fkb) - sc_body_set(body, "vy", 0 - kb * SCAF_Q) # pop up on hit + sc_body_set(body, "vy", -kb * SCAF_Q) # pop up on hit } } e = World.query_next(P, e + 1) diff --git a/packages/ludic.prefs/prefs.ludic b/packages/ludic.prefs/prefs.ludic index 7c12d670..cdffe581 100644 --- a/packages/ludic.prefs/prefs.ludic +++ b/packages/ludic.prefs/prefs.ludic @@ -24,8 +24,8 @@ namespace Prefs { internal function find(key: pointer) -> int { var i = 0 - while i < prefs_n { if prefs_names[i] == key { return i }; i = i + 1 } - return 0 - 1 + while i < prefs_n { if prefs_names[i] == key { return i }; i += 1 } + return -1 } export function get(key: pointer, fallback: int) -> int { @@ -49,7 +49,7 @@ namespace Prefs { if prefs_n >= PREFS_MAX { return } i = prefs_n prefs_names[i] = key - prefs_n = prefs_n + 1 + prefs_n += 1 } prefs_vals[i] = value } @@ -71,18 +71,18 @@ namespace Prefs { # digits after `=` on one line -> an int (a leading '-' negates) internal function parse_line(buf: pointer, from: int, to: int) -> void { var eq = from - while (eq < to) and (buf[eq] != 61) { eq = eq + 1 } # '=' + while (eq < to) and (buf[eq] != '=') { eq += 1 } # '=' if eq >= to { return } let key = bytes(eq - from + 1) var k = 0 - while k < eq - from { key[k] = buf[from + k]; k = k + 1 } + while k < eq - from { key[k] = buf[from + k]; k += 1 } key[eq - from] = 0 var v = 0 var neg = false var p = eq + 1 - if (p < to) and (buf[p] == 45) { neg = true; p = p + 1 } # '-' - while (p < to) and (buf[p] >= 48) and (buf[p] <= 57) { v = v * 10 + (buf[p] - 48); p = p + 1 } - if neg { v = 0 - v } + if (p < to) and (buf[p] == '-') { neg = true; p += 1 } # '-' + while (p < to) and (buf[p] >= '0') and (buf[p] <= '9') { v = v * 10 + (buf[p] - 48); p += 1 } + if neg { v = -v } set(key, v) } @@ -94,15 +94,15 @@ namespace Prefs { var start = 0 var i = 0 while buf[i] != 0 { - if buf[i] == 10 { parse_line(buf, start, i); start = i + 1 } # newline - i = i + 1 + if buf[i] == '\n' { parse_line(buf, start, i); start = i + 1 } # newline + i += 1 } if i > start { parse_line(buf, start, i) } } internal function write_text(f: pointer, s: pointer) -> void { var n = 0 - while s[n] != 0 { n = n + 1 } + while s[n] != 0 { n += 1 } file_write(f, s, n) } @@ -114,7 +114,7 @@ namespace Prefs { var i = 0 while i < prefs_n { write_text(f, `{prefs_names[i]}={string(prefs_vals[i])}\n`) - i = i + 1 + i += 1 } file_close(f) } diff --git a/packages/ludic.rpg/crafting.ludic b/packages/ludic.rpg/crafting.ludic index 57f42fb5..ca24fcec 100644 --- a/packages/ludic.rpg/crafting.ludic +++ b/packages/ludic.rpg/crafting.ludic @@ -32,14 +32,14 @@ event CraftCompleted { e: int = 0, recipe: int = 0 } # Craft.recipe(name, out_item, out_qty) — declare a recipe; returns its id. @Namespace(Craft) function craft_recipe(name: pointer, out_item: pointer, out_qty: int) -> int { craft_ensure() - if recipe_n >= CRAFT_MAX { return 0 - 1 } + if recipe_n >= CRAFT_MAX { return -1 } let id = recipe_n recipe_out[id] = out_item; recipe_outqty[id] = out_qty - recipe_n = recipe_n + 1 + recipe_n += 1 Dict.set(recipe_reg, name, id) return id } -@Namespace(Craft) function craft_id(name: pointer) -> int { craft_ensure(); return Dict.get_or(recipe_reg, name, 0 - 1) } +@Namespace(Craft) function craft_id(name: pointer) -> int { craft_ensure(); return Dict.get_or(recipe_reg, name, -1) } # Craft.ingredient(recipe_name, item, qty) — add an ingredient requirement. @Namespace(Craft) function craft_ingredient(recipe_name: pointer, item: pointer, qty: int) -> void { craft_ensure() @@ -47,7 +47,7 @@ event CraftCompleted { e: int = 0, recipe: int = 0 } if rid < 0 { return } if ing_n >= CRAFT_ING_MAX { return } ing_rid[ing_n] = rid; ing_name[ing_n] = item; ing_qty[ing_n] = qty - ing_n = ing_n + 1 + ing_n += 1 } # Craft.can(e, recipe_name) — does the owner hold every ingredient? @@ -60,7 +60,7 @@ event CraftCompleted { e: int = 0, recipe: int = 0 } if ing_rid[i] == rid { if Inventory.count(e, ing_name[i]) < ing_qty[i] { return 0 } } - i = i + 1 + i += 1 } return 1 } @@ -75,7 +75,7 @@ event CraftCompleted { e: int = 0, recipe: int = 0 } var i = 0 while i < ing_n { if ing_rid[i] == rid { Inventory.remove(e, ing_name[i], ing_qty[i]) } - i = i + 1 + i += 1 } Inventory.add(e, recipe_out[rid], recipe_outqty[rid]) emit CraftCompleted(e: e, recipe: rid) diff --git a/packages/ludic.rpg/dialog.ludic b/packages/ludic.rpg/dialog.ludic index 1e47decc..e2d19e36 100644 --- a/packages/ludic.rpg/dialog.ludic +++ b/packages/ludic.rpg/dialog.ludic @@ -38,12 +38,12 @@ event DialogEnded { e: int = 0 } # Dialog.tree(name) — register (or fetch) a tree id. @Namespace(Dialog) function dialog_tree(name: pointer) -> int { dlg_ensure() - let ex = Dict.get_or(dlg_reg, name, 0 - 1) + let ex = Dict.get_or(dlg_reg, name, -1) if ex >= 0 { return ex } - if dlg_tree_n >= DLG_TREE_MAX { return 0 - 1 } + if dlg_tree_n >= DLG_TREE_MAX { return -1 } let id = dlg_tree_n - dlg_tree_start[id] = 0 - 1 - dlg_tree_n = dlg_tree_n + 1 + dlg_tree_start[id] = -1 + dlg_tree_n += 1 Dict.set(dlg_reg, name, id) return id } @@ -52,21 +52,21 @@ event DialogEnded { e: int = 0 } @Namespace(Dialog) function dialog_node(tree_name: pointer, text: pointer) -> int { dlg_ensure() let tid = dialog_tree(tree_name) - if tid < 0 { return 0 - 1 } - if dlg_node_n >= DLG_NODE_MAX { return 0 - 1 } + if tid < 0 { return -1 } + if dlg_node_n >= DLG_NODE_MAX { return -1 } let id = dlg_node_n dlg_node_tree[id] = tid; dlg_node_text[id] = text - dlg_node_n = dlg_node_n + 1 + dlg_node_n += 1 if dlg_tree_start[tid] < 0 { dlg_tree_start[tid] = id } return id } # Dialog.choice(node, label, next_node) — add a branch (next_node -1 ends). @Namespace(Dialog) function dialog_choice(node: int, label: pointer, next_node: int) -> int { dlg_ensure() - if dlg_choice_n >= DLG_CHOICE_MAX { return 0 - 1 } + if dlg_choice_n >= DLG_CHOICE_MAX { return -1 } let id = dlg_choice_n dlg_choice_node[id] = node; dlg_choice_label[id] = label; dlg_choice_next[id] = next_node - dlg_choice_n = dlg_choice_n + 1 + dlg_choice_n += 1 return id } @@ -101,7 +101,7 @@ function dlg_set(e: int, name: pointer, v: int) -> void { if dlg_get(e, "active") == 0 { return 0 } let node = dlg_get(e, "node") var n = 0; var i = 0 - while i < dlg_choice_n { if dlg_choice_node[i] == node { n = n + 1 }; i = i + 1 } + while i < dlg_choice_n { if dlg_choice_node[i] == node { n += 1 }; i += 1 } return n } # Dialog.choose(e, i) — take the i-th choice (veto-able); advance or end. @@ -109,12 +109,12 @@ function dlg_set(e: int, name: pointer, v: int) -> void { dlg_ensure() if dlg_get(e, "active") == 0 { return 0 } let node = dlg_get(e, "node") - var seen = 0; var i = 0; var pick = 0 - 1 + var seen = 0; var i = 0; var pick = -1 while i < dlg_choice_n { if dlg_choice_node[i] == node { - if seen == idx { pick = i; i = dlg_choice_n } else { seen = seen + 1 } + if seen == idx { pick = i; i = dlg_choice_n } else { seen += 1 } } - i = i + 1 + i += 1 } if pick < 0 { return 0 } if emit DialogChoice(e: e, node: node, choice: idx) != 0 { return 0 } diff --git a/packages/ludic.rpg/inventory.ludic b/packages/ludic.rpg/inventory.ludic index 9e133c54..fbb193f2 100644 --- a/packages/ludic.rpg/inventory.ludic +++ b/packages/ludic.rpg/inventory.ludic @@ -26,14 +26,14 @@ function item_ensure() -> void { # Item.def(name, stack_max, weight, value) — register an item template. Returns id. @Namespace(Item) function item_def(name: pointer, stack_max: int, weight: int, value: int) -> int { item_ensure() - if item_n >= INV_MAX { return 0 - 1 } + if item_n >= INV_MAX { return -1 } let id = item_n item_stackmax[id] = stack_max; item_weight[id] = weight; item_value[id] = value - item_n = item_n + 1 + item_n += 1 Dict.set(item_reg, name, id) return id } -@Namespace(Item) function item_id(name: pointer) -> int { item_ensure(); return Dict.get_or(item_reg, name, 0 - 1) } +@Namespace(Item) function item_id(name: pointer) -> int { item_ensure(); return Dict.get_or(item_reg, name, -1) } @Namespace(Item) function item_value_of(name: pointer) -> int { let id = item_id(name); if id < 0 { return 0 } return item_value[id] @@ -97,7 +97,7 @@ event cancellable ItemUse { e: int = 0, item: int = 0 } # veto a use ( @Namespace(Inventory) function inventory_spend_gold(e: int, n: int) -> int { let g = inventory_gold(e) if g < n { return 0 } - inventory_add_gold(e, 0 - n) + inventory_add_gold(e, -n) return 1 } diff --git a/packages/ludic.rpg/mover.ludic b/packages/ludic.rpg/mover.ludic index 69daf74e..63011d2b 100644 --- a/packages/ludic.rpg/mover.ludic +++ b/packages/ludic.rpg/mover.ludic @@ -48,7 +48,7 @@ function mv_body_set(e: int, name: pointer, v: int) -> void { let P = World.prop_id("Body"); if P < 0 { return } let f = World.field_id(P, name); if f >= 0 { World.set(e, P, f, v) } } -function mv_sign(a: int) -> int { if a > 0 { return 1 }; if a < 0 { return 0 - 1 }; return 0 } +function mv_sign(a: int) -> int { if a > 0 { return 1 }; if a < 0 { return -1 }; return 0 } # is the destination cell walkable? Uses the Solids tilemap when configured, # otherwise the whole field is open. @@ -159,19 +159,19 @@ function mover_free(e: int) -> void { let ax = mv_pos(e, "x") + mv_get(e, "facing_x") * step let ay = mv_pos(e, "y") + mv_get(e, "facing_y") * step let PP = World.prop_id("Position") - if PP < 0 { return 0 - 1 } + if PP < 0 { return -1 } var o = World.query_next(PP, 0) while o >= 0 { if o != e { let ox = World.get(o, PP, World.field_id(PP, "x")) let oy = World.get(o, PP, World.field_id(PP, "y")) let dx = ox - ax; let dy = oy - ay - var adx = dx; if adx < 0 { adx = 0 - adx } - var ady = dy; if ady < 0 { ady = 0 - ady } + var adx = dx; if adx < 0 { adx = -adx } + var ady = dy; if ady < 0 { ady = -ady } if (adx < step) and (ady < step) { emit Interacted(e: e, target: o); return o } } o = World.query_next(PP, o + 1) } - emit Interacted(e: e, target: 0 - 1) - return 0 - 1 + emit Interacted(e: e, target: -1) + return -1 } diff --git a/packages/ludic.rpg/puzzles.ludic b/packages/ludic.rpg/puzzles.ludic index 67662225..a5c6d98d 100644 --- a/packages/ludic.rpg/puzzles.ludic +++ b/packages/ludic.rpg/puzzles.ludic @@ -9,7 +9,7 @@ const PZ_Q: int = 65536 property Pushable { } property Switch { on: int = 0 } property Pressure { on: int = 0, step: int = 16 } -property Gate { open: int = 0, src: int = 0 - 1 } +property Gate { open: int = 0, src: int = -1 } event BlockPushed { block: int = 0, dx: int = 0, dy: int = 0 } event cancellable PushBlocked { block: int = 0 } @@ -27,13 +27,13 @@ function pz_pos_set(e: int, name: pointer, v: int) -> void { # the pushable whose cell is exactly (x, y), or -1. function pz_block_at(x: int, y: int) -> int { let P = World.prop_id("Pushable") - if P < 0 { return 0 - 1 } + if P < 0 { return -1 } var e = World.query_next(P, 0) while e >= 0 { if (pz_pos(e, "x") == x) and (pz_pos(e, "y") == y) { return e } e = World.query_next(P, e + 1) } - return 0 - 1 + return -1 } # reuse the Mover module's tilemap walkability check when present. @@ -120,9 +120,9 @@ function pz_source_on(src: int) -> int { if (o != e) and (World.has(o, P) == 0) { let ox = World.get(o, PP, World.field_id(PP, "x")) let oy = World.get(o, PP, World.field_id(PP, "y")) - var adx = ox - px; if adx < 0 { adx = 0 - adx } - var ady = oy - py; if ady < 0 { ady = 0 - ady } - if (adx < step) and (ady < step) { on = 1; o = 0 - 1 } + var adx = ox - px; if adx < 0 { adx = -adx } + var ady = oy - py; if ady < 0 { ady = -ady } + if (adx < step) and (ady < step) { on = 1; o = -1 } } if o >= 0 { o = World.query_next(PP, o + 1) } } diff --git a/packages/ludic.rpg/quests.ludic b/packages/ludic.rpg/quests.ludic index 5403eab9..3e6105e7 100644 --- a/packages/ludic.rpg/quests.ludic +++ b/packages/ludic.rpg/quests.ludic @@ -41,24 +41,24 @@ event ObjectiveProgressed { quest: int = 0, objective: int = 0, have: int = 0, n # Quest.define(name) — register a quest (state hidden). Returns id. @Namespace(Quest) function quest_define(name: pointer) -> int { quest_ensure() - if quest_n >= QUEST_MAX { return 0 - 1 } + if quest_n >= QUEST_MAX { return -1 } let id = quest_n quest_state[id] = 0 - quest_n = quest_n + 1 + quest_n += 1 Dict.set(quest_reg, name, id) return id } -@Namespace(Quest) function quest_id(name: pointer) -> int { quest_ensure(); return Dict.get_or(quest_reg, name, 0 - 1) } +@Namespace(Quest) function quest_id(name: pointer) -> int { quest_ensure(); return Dict.get_or(quest_reg, name, -1) } # Quest.objective(quest_name, kind, target, need) — add an objective. @Namespace(Quest) function quest_objective(quest_name: pointer, kind: int, target: int, need: int) -> int { quest_ensure() let qid = quest_id(quest_name) - if qid < 0 { return 0 - 1 } - if obj_n >= OBJ_MAX { return 0 - 1 } + if qid < 0 { return -1 } + if obj_n >= OBJ_MAX { return -1 } let id = obj_n obj_qid[id] = qid; obj_kind[id] = kind; obj_target[id] = target obj_need[id] = need; obj_have[id] = 0 - obj_n = obj_n + 1 + obj_n += 1 return id } # Quest.start(name) — activate a quest (emits QuestStarted). @@ -72,7 +72,7 @@ event ObjectiveProgressed { quest: int = 0, objective: int = 0, have: int = 0, n @Namespace(Quest) function quest_state_of(name: pointer) -> int { quest_ensure() let qid = quest_id(name) - if qid < 0 { return 0 - 1 } + if qid < 0 { return -1 } return quest_state[qid] } @@ -81,7 +81,7 @@ function quest_all_done(qid: int) -> int { var i = 0 while i < obj_n { if obj_qid[i] == qid { if obj_have[i] < obj_need[i] { return 0 } } - i = i + 1 + i += 1 } return 1 } @@ -98,7 +98,7 @@ function quest_all_done(qid: int) -> int { if obj_kind[i] == kind { if (obj_target[i] == 0) or (obj_target[i] == target) { if obj_have[i] < obj_need[i] { - obj_have[i] = obj_have[i] + amount + obj_have[i] += amount if obj_have[i] > obj_need[i] { obj_have[i] = obj_need[i] } emit ObjectiveProgressed(quest: qid, objective: i, have: obj_have[i], need: obj_need[i]) if quest_all_done(qid) == 1 { @@ -109,7 +109,7 @@ function quest_all_done(qid: int) -> int { } } } - i = i + 1 + i += 1 } } diff --git a/packages/ludic.rpg/status.ludic b/packages/ludic.rpg/status.ludic index 157f8673..2378bd68 100644 --- a/packages/ludic.rpg/status.ludic +++ b/packages/ludic.rpg/status.ludic @@ -22,7 +22,7 @@ event StatusExpired { target: int = 0, kind: int = 0 } # Status.apply(target, kind, amount, interval, ttl) — attach a timed effect. @Namespace(Status) function status_apply(target: int, kind: int, amount: int, interval: int, ttl: int) -> int { let m = World.model_id("StatusFx") - if m < 0 { return 0 - 1 } + if m < 0 { return -1 } let e = World.spawn(m) let P = World.prop_id("Status") World.set(e, P, World.field_id(P, "target"), target) diff --git a/packages/ludic.shooter/shooter.ludic b/packages/ludic.shooter/shooter.ludic index 7cc03e61..061a59ee 100644 --- a/packages/ludic.shooter/shooter.ludic +++ b/packages/ludic.shooter/shooter.ludic @@ -23,6 +23,10 @@ const WPN_MAX: int = 64 # --------------------------------------------------------------------------- enum AimMode { Mouse, RightStick, MoveDirection, NearestEnemy, Manual, Auto } # TopDown.aim_mode; Auto = mouse, or the right stick while a pad is connected enum WeaponPattern { Single, Cone, Ring, Spiral } # Weapon.def pattern + +# gamepad axis indices as Input.pad_axis numbers them: left stick 0/1, right stick 2/3 +const STICK_RIGHT_X: int = 2 +const STICK_RIGHT_Y: int = 3 property TopDown { move_speed: int = 4, # px/frame accel: int = 80, # responsiveness %, gap closed / frame @@ -41,7 +45,7 @@ property TopDown { # a Weapon instance points at a registry entry (def_id). cooldown counts down to # the next allowed shot; ammo -1 = infinite; phase drives spiral emitters. -property Weapon { def_id: int = 0, ammo: int = 0 - 1, cooldown: int = 0, phase: int = 0 } +property Weapon { def_id: int = 0, ammo: int = -1, cooldown: int = 0, phase: int = 0 } property Projectile { color: int = 0xffffff, # drawn by the engine as a 3x3 square (Weapon.set_color) @@ -92,20 +96,20 @@ function wpn_ensure() -> void { # gun. pattern: 0 single/aimed, 1 spread cone, 2 ring, 3 spiral. Returns the def id. @Namespace(Weapon) function weapon_def(name: pointer, fire_rate: int, damage: int, speed: int, spread: int, pellets: int, pattern: int) -> int { wpn_ensure() - if wpn_n >= WPN_MAX { return 0 - 1 } + if wpn_n >= WPN_MAX { return -1 } let id = wpn_n wpn_rate[id] = fire_rate; wpn_dmg[id] = damage; wpn_speed[id] = speed wpn_spread[id] = spread; wpn_pellets[id] = pellets; wpn_pattern[id] = pattern wpn_ttl[id] = 120 wpn_color[id] = 0xffffff wpn_rate_base[id] = fire_rate - wpn_n = wpn_n + 1 + wpn_n += 1 Dict.set(wpn_reg, name, id) return id } @Namespace(Weapon) function weapon_id(name: pointer) -> int { wpn_ensure() - return Dict.get_or(wpn_reg, name, 0 - 1) + return Dict.get_or(wpn_reg, name, -1) } # Weapon.set_rate(id, frames) — frames between shots (a fire-rate upgrade changes it in place). @Namespace(Weapon) function weapon_set_rate(id: int, frames: int) -> void { @@ -180,10 +184,10 @@ function pr_set(e: int, name: pointer, v: int) -> void { # nearest entity with a Faction hostile to `fac`, by centre distance. -1 if none. function sh_nearest_enemy(self_e: int, fac: int, px: int, py: int) -> int { let PF = World.prop_id("Faction") - if PF < 0 { return 0 - 1 } + if PF < 0 { return -1 } let PP = World.prop_id("Position") - if PP < 0 { return 0 - 1 } - var best = 0 - 1 + if PP < 0 { return -1 } + var best = -1 var bestd = 0 var e = World.query_next(PF, 0) while e >= 0 { @@ -292,7 +296,7 @@ function melee_get(e: int, name: pointer) -> int { return sh_get("Melee", e, nam @Namespace(Melee) function melee_ready(e: int) -> bool { return melee_get(e, "cooldown") == 0 } @Namespace(Melee) function melee_active(e: int) -> bool { return melee_get(e, "frames_left") > 0 } @Namespace(Melee) function melee_swing(e: int) -> int { - if melee_get(e, "cooldown") > 0 { return 0 - 1 } + if melee_get(e, "cooldown") > 0 { return -1 } sh_set("Melee", e, "frames_left", melee_get(e, "frames")) sh_set("Melee", e, "cooldown", melee_get(e, "cooldown_frames")) let PF = World.prop_id("Faction") @@ -316,7 +320,7 @@ function melee_get(e: int, name: pointer) -> int { return sh_get("Melee", e, nam let ny = pos_get(o, "y") + push.y if not Map.is_solid_at(nx, ny) { pos_set(o, "x", nx); pos_set(o, "y", ny) } emit MeleeHit(attacker: e, target: o) - hits = hits + 1 + hits += 1 } } } @@ -405,23 +409,23 @@ function sh_half_w(e: int) -> int { let py = sh_cy(e) var target = td_get(e, "aim_angle") # default: keep current var have = 0 - if mode == 0 { # mouse / point + if mode == AimMode.Mouse { let mx = Input.mouse_x() let my = Input.mouse_y() target = sh_angle_to(px, py, mx, my); have = 1 } - if mode == 1 { # right stick - let ax = Input.pad_axis(0, 2) - let ay = Input.pad_axis(0, 3) + if mode == AimMode.RightStick { + let ax = Input.pad_axis(0, STICK_RIGHT_X) + let ay = Input.pad_axis(0, STICK_RIGHT_Y) if (ax != 0) or (ay != 0) { target = sh_dir_angle(ax, ay); have = 1 } } - if mode == 2 { # move direction (from the intent) + if mode == AimMode.MoveDirection { # from the movement intent let wx = td_get(e, "want_x") let wy = td_get(e, "want_y") if (wx != 0) or (wy != 0) { target = sh_dir_angle(wx, wy); have = 1 } } - # mode 4 = manual: the game/AI owns aim_angle; the aim system leaves it alone. - if mode == 3 { # nearest enemy (auto-aim) + # AimMode.Manual: the game/AI owns aim_angle; the aim system leaves it alone. + if mode == AimMode.NearestEnemy { # auto-aim let fac = Faction.id_of(e) let t = sh_nearest_enemy(e, fac, px, py) if t >= 0 { target = sh_angle_to(px, py, sh_cx(t), sh_cy(t)); have = 1 } @@ -433,7 +437,7 @@ function sh_half_w(e: int) -> int { } else { let cur = td_get(e, "aim_angle") let d = sh_angle_diff(cur, target) # shortest signed arc, degrees - if (d >= 0 - tr) and (d <= tr) { td_set(e, "aim_angle", target) } + if (d >= -tr) and (d <= tr) { td_set(e, "aim_angle", target) } else { if d > 0 { td_set(e, "aim_angle", sh_wrap_deg(cur + tr)) } else { td_set(e, "aim_angle", sh_wrap_deg(cur - tr)) } } } } @@ -471,21 +475,21 @@ function sh_dir_angle(dx: int, dy: int) -> int { } function sh_wrap_deg(d: int) -> int { var a = d - while a < 0 { a = a + 360 } - while a >= 360 { a = a - 360 } + while a < 0 { a += 360 } + while a >= 360 { a -= 360 } return a } function sh_angle_diff(from: int, to: int) -> int { var d = sh_wrap_deg(to) - sh_wrap_deg(from) - while d > 180 { d = d - 360 } - while d < 0 - 180 { d = d + 360 } + while d > 180 { d -= 360 } + while d < -180 { d += 360 } return d } # spawn one projectile travelling at `deg` degrees from (px,py). function sh_spawn_bullet(owner: int, fac: int, px: int, py: int, deg: int, speed: int, dmg: int, ttl: int, pierce: int, homing: int) -> int { let m = World.model_id("Bullet") - if m < 0 { return 0 - 1 } + if m < 0 { return -1 } let b = World.spawn(m) pos_set(b, "x", px) pos_set(b, "y", py) @@ -508,7 +512,7 @@ function sh_spawn_bullet(owner: int, fac: int, px: int, py: int, deg: int, speed } # announce it: a listener may veto (cancel -> despawn) or tweak the Projectile. pr_set(b, "color", wpn_fire_color) - if emit ProjectileSpawned(proj: b, owner: owner, damage: dmg) != 0 { despawn b; return 0 - 1 } + if emit ProjectileSpawned(proj: b, owner: owner, damage: dmg) != 0 { despawn b; return -1 } return b } var wpn_fire_color: int = 0xffffff # the colour of the weapon being fired (sh_fire) @@ -554,17 +558,17 @@ function sh_fire(owner: int, id: int) -> void { wpn_fire_color = wpn_color[id] var pellets = pellets0; if pellets < 1 { pellets = 1 } emit WeaponFired(owner: owner, def_id: id) - if pattern == 2 { # ring: pellets around 360 + if pattern == WeaponPattern.Ring { # pellets around 360 var i = 0 - while i < pellets { sh_spawn_bullet(owner, fac, px, py, sh_wrap_deg(base + i * 360 / pellets), speed, dmg, ttl, pierce, homing); i = i + 1 } + while i < pellets { sh_spawn_bullet(owner, fac, px, py, sh_wrap_deg(base + i * 360 / pellets), speed, dmg, ttl, pierce, homing); i += 1 } return } - if pattern == 3 { # spiral: ring + a rotating phase + if pattern == WeaponPattern.Spiral { # ring + a rotating phase let PW = World.prop_id("Weapon") let fph = World.field_id(PW, "phase") var ph = 0; if fph >= 0 { ph = World.get(owner, PW, fph) } var i = 0 - while i < pellets { sh_spawn_bullet(owner, fac, px, py, sh_wrap_deg(base + ph + i * 360 / pellets), speed, dmg, ttl, pierce, homing); i = i + 1 } + while i < pellets { sh_spawn_bullet(owner, fac, px, py, sh_wrap_deg(base + ph + i * 360 / pellets), speed, dmg, ttl, pierce, homing); i += 1 } if fph >= 0 { World.set(owner, PW, fph, sh_wrap_deg(ph + 15)) } return } @@ -574,9 +578,9 @@ function sh_fire(owner: int, id: int) -> void { } else { var i = 0 while i < pellets { - let off = 0 - (spread / 2) + i * spread / (pellets - 1) + let off = -(spread / 2) + i * spread / (pellets - 1) sh_spawn_bullet(owner, fac, px, py, sh_wrap_deg(base + off), speed, dmg, ttl, pierce, homing) - i = i + 1 + i += 1 } } } @@ -610,7 +614,7 @@ function sh_fire(owner: int, id: int) -> void { let cur = pr_get(e, "dir") let d = sh_angle_diff(cur, want) var na = cur - if (d >= 0 - hom) and (d <= hom) { na = want } + if (d >= -hom) and (d <= hom) { na = want } else { if d > 0 { na = sh_wrap_deg(cur + hom) } else { na = sh_wrap_deg(cur - hom) } } pr_set(e, "dir", na) let sp = pr_get(e, "speed") @@ -688,7 +692,7 @@ event WaveCleared { spawner: int = 0, wave: int = 0 } var t = World.get(e, P, ft) - 1 if t <= 0 { emit SpawnRequested(spawner: e, wave: World.get(e, P, fwave), index: spawned) - spawned = spawned + 1 + spawned += 1 World.set(e, P, fsp, spawned) World.set(e, P, ft, World.get(e, P, frate)) if spawned >= budget { emit WaveCleared(spawner: e, wave: World.get(e, P, fwave)) } diff --git a/runtime/native/atlas.ludic b/runtime/native/atlas.ludic index 3ff744bc..b352fc47 100644 --- a/runtime/native/atlas.ludic +++ b/runtime/native/atlas.ludic @@ -77,40 +77,40 @@ function atlas_register_name(name: pointer, id: int) -> void { if at_nname >= ATLAS_MAX_NAME { return } at_name_str[at_nname] = name at_name_id[at_nname] = id - at_nname = at_nname + 1 + at_nname += 1 } # load a spritesheet PNG whose cells are cw x ch px; returns a sheet handle (>= 0). function atlas_sheet(path: pointer, cw: int, ch: int) -> int { atlas_init() - if at_nsheet >= ATLAS_MAX_SHEET { return 0 - 1 } + if at_nsheet >= ATLAS_MAX_SHEET { return -1 } let img = rt_image_load(path) - if img < 0 { return 0 - 1 } + if img < 0 { return -1 } let h = at_nsheet at_sheet_img[h] = img at_sheet_cw[h] = cw at_sheet_ch[h] = ch - at_nsheet = at_nsheet + 1 + at_nsheet += 1 return h } # register an atlas sprite for a sub-rect (px) of a sheet's image. function atlas_make(sheet: int, sx: int, sy: int, w: int, h: int) -> int { atlas_init() - if at_nspr >= ATLAS_MAX_SPR { return 0 - 1 } + if at_nspr >= ATLAS_MAX_SPR { return -1 } let id = at_nspr at_spr_sheet[id] = sheet at_spr_sx[id] = sx at_spr_sy[id] = sy at_spr_w[id] = w at_spr_h[id] = h - at_nspr = at_nspr + 1 + at_nspr += 1 return id } # one cell (col, row) of a sheet, addressed by grid coords. function atlas_cell(sheet: int, col: int, row: int) -> int { - if (sheet < 0) or (sheet >= at_nsheet) { return 0 - 1 } + if (sheet < 0) or (sheet >= at_nsheet) { return -1 } let cw = at_sheet_cw[sheet] let ch = at_sheet_ch[sheet] return atlas_make(sheet, col * cw, row * ch, cw, ch) @@ -119,7 +119,7 @@ function atlas_cell(sheet: int, col: int, row: int) -> int { # a sprite spanning cols x rows cells from (col, row) — some sprites cover more # than one cell (a tall character, a wide object). function atlas_cell_span(sheet: int, col: int, row: int, cols: int, rows: int) -> int { - if (sheet < 0) or (sheet >= at_nsheet) { return 0 - 1 } + if (sheet < 0) or (sheet >= at_nsheet) { return -1 } let cw = at_sheet_cw[sheet] let ch = at_sheet_ch[sheet] return atlas_make(sheet, col * cw, row * ch, cols * cw, rows * ch) @@ -129,11 +129,11 @@ function atlas_cell_span(sheet: int, col: int, row: int, cols: int, rows: int) - function atlas_define(name: pointer, sheet: int, col: int, row: int) -> int { atlas_init() let id = atlas_cell(sheet, col, row) - if id < 0 { return 0 - 1 } + if id < 0 { return -1 } if at_nname < ATLAS_MAX_NAME { at_name_str[at_nname] = name at_name_id[at_nname] = id - at_nname = at_nname + 1 + at_nname += 1 } return id } @@ -144,24 +144,24 @@ function atlas_named(name: pointer) -> int { var i = 0 while i < at_nname { if at_name_str[i] == name { return at_name_id[i] } - i = i + 1 + i += 1 } - return 0 - 1 + return -1 } # load a whole image file as one atlas sprite (a 1x1 sheet the size of the image). function atlas_image(path: pointer) -> int { atlas_init() - if at_nsheet >= ATLAS_MAX_SHEET { return 0 - 1 } + if at_nsheet >= ATLAS_MAX_SHEET { return -1 } let img = rt_image_load(path) - if img < 0 { return 0 - 1 } + if img < 0 { return -1 } let w = img_w[img] let h = img_h[img] let sh = at_nsheet at_sheet_img[sh] = img at_sheet_cw[sh] = w at_sheet_ch[sh] = h - at_nsheet = at_nsheet + 1 + at_nsheet += 1 return atlas_make(sh, 0, 0, w, h) } @@ -191,10 +191,10 @@ function atlas_draw(id: int, dx: int, dy: int) -> void { let px = s[srcy * iw + srcx] if ((px >> 24) & 255) >= 128 { rt_put_px(dx + x, dy + y, px & 16777215) } } - x = x + 1 + x += 1 } } - y = y + 1 + y += 1 } } @@ -223,10 +223,10 @@ function atlas_draw_scaled(id: int, dx: int, dy: int, sc: int) -> void { let px = s[srcy * iw + srcx] if ((px >> 24) & 255) >= 128 { rt_fill_rect(dx + x * sc, dy + y * sc, sc, sc, px & 16777215) } } - x = x + 1 + x += 1 } } - y = y + 1 + y += 1 } } @@ -265,22 +265,22 @@ function atlas_draw_ex(id: int, dx: int, dy: int, sc0: int, flip: int, tint: int else { rt_fill_rect(dx + x * sc, dy + y * sc, sc, sc, col) } } } - x = x + 1 + x += 1 } } - y = y + 1 + y += 1 } } # a strip of `count` frames starting at (col,row), each `rows` cells tall, registered # as consecutive ids so `first + SpriteAnim.frame` addresses the current frame. function atlas_strip(sheet: int, col: int, row: int, count: int, rows: int) -> int { - var first = 0 - 1 + var first = -1 var i = 0 while i < count { let id = atlas_cell_span(sheet, col + i, row, 1, rows) if first < 0 { first = id } - i = i + 1 + i += 1 } return first } @@ -299,7 +299,7 @@ function atlas_draw_meter(x: int, y: int, value: int, max: int, per_icon: int, s if value >= i * per_icon + per_icon / 2 { id = half } if value >= (i + 1) * per_icon { id = full } atlas_draw(id, x + i * spacing, y) - i = i + 1 + i += 1 } } @@ -312,9 +312,9 @@ function assets_enqueue_dir(dir: pointer) -> void { while i < len(names) { let file = names[i] var dot = len(file) - 1 - while (dot > 0) and (file[dot] != 46) { dot = dot - 1 } + while (dot > 0) and (file[dot] != '.') { dot -= 1 } if dot > 0 { assets_enqueue(file[0..dot], dir + ("/") + file) } - i = i + 1 + i += 1 } } @@ -325,7 +325,7 @@ function assets_enqueue(name: pointer, path: pointer) -> void { if at_q_n >= ATLAS_MAX_QUEUE { return } at_q_name[at_q_n] = name at_q_path[at_q_n] = path - at_q_n = at_q_n + 1 + at_q_n += 1 } # Load up to `max` queued assets this frame, registering each under its name, and @@ -338,8 +338,8 @@ function assets_pump(max: int) -> int { var done = 0 while (done < max) and (at_q_pos < at_q_n) { assets_load_one(at_q_name[at_q_pos], at_q_path[at_q_pos]) - at_q_pos = at_q_pos + 1 - done = done + 1 + at_q_pos += 1 + done += 1 } if (at_q_pos >= at_q_n) and (not at_q_announced) { at_q_announced = true; emit AssetsReady() } return done @@ -362,7 +362,7 @@ function path_has_suffix(path: pointer, suffix: pointer) -> bool { var i = 0 while i < m { if path[n - m + i] != suffix[i] { return false } - i = i + 1 + i += 1 } return true } @@ -380,7 +380,7 @@ function assets_load_one(name: pointer, path: pointer) -> void { if at_font_n < ATLAS_MAX_FONT { at_font_name[at_font_n] = name at_font_id[at_font_n] = rt_font_load(path) - at_font_n = at_font_n + 1 + at_font_n += 1 } return } @@ -391,7 +391,7 @@ function assets_font(name: pointer) -> int { var i = 0 while i < at_font_n { if at_font_name[i] == name { return at_font_id[i] } - i = i + 1 + i += 1 } return 0 } diff --git a/runtime/native/audio.ludic b/runtime/native/audio.ludic index 7f30a7ce..32c30ba2 100644 --- a/runtime/native/audio.ludic +++ b/runtime/native/audio.ludic @@ -46,7 +46,7 @@ function audio_define(name: pointer, path: pointer) -> int { if snd_bank_n < AUDIO_CAP { snd_bank_name[snd_bank_n] = name snd_bank_id[snd_bank_n] = id - snd_bank_n = snd_bank_n + 1 + snd_bank_n += 1 } return id } @@ -56,7 +56,7 @@ function audio_named(name: pointer) -> int { var i = 0 while i < snd_bank_n { if snd_bank_name[i] == name { return snd_bank_id[i] } - i = i + 1 + i += 1 } return 0 } @@ -82,7 +82,7 @@ function audio_load(path: pointer) -> int { snd_tab[i] = p return i + 1 } - i = i + 1 + i += 1 } return 0 } @@ -132,7 +132,7 @@ function audio_stop_all() -> void { var i = 0 while i < AUDIO_CAP { if snd_tab[i] != null { snd_stop(snd_tab[i]) } - i = i + 1 + i += 1 } snd_music = 0 } @@ -146,7 +146,7 @@ function audio_volume(v: fixed) -> void { var i = 0 while i < AUDIO_CAP { if snd_tab[i] != null { snd_set_volume(snd_tab[i], v) } - i = i + 1 + i += 1 } } @@ -158,7 +158,7 @@ function audio_pitch(v: fixed) -> void { var i = 0 while i < AUDIO_CAP { if snd_tab[i] != null { snd_set_rate(snd_tab[i], v) } - i = i + 1 + i += 1 } } diff --git a/runtime/native/base64.ludic b/runtime/native/base64.ludic index 92c8dd01..f752198c 100644 --- a/runtime/native/base64.ludic +++ b/runtime/native/base64.ludic @@ -15,12 +15,12 @@ # the standard alphabet value of a base64 character, or -1 for anything else # (whitespace, '=', stray bytes — the decoder skips them / stops on '='). function b64_val(c: int) -> int { - if c >= 65 and c <= 90 { return c - 65 } # 'A'..'Z' -> 0..25 - if c >= 97 and c <= 122 { return c - 71 } # 'a'..'z' -> 26..51 - if c >= 48 and c <= 57 { return c + 4 } # '0'..'9' -> 52..61 - if c == 43 { return 62 } # '+' - if c == 47 { return 63 } # '/' - return 0 - 1 + if c >= 'A' and c <= 'Z' { return c - 65 } # 'A'..'Z' -> 0..25 + if c >= 'a' and c <= 'z' { return c - 71 } # 'a'..'z' -> 26..51 + if c >= '0' and c <= '9' { return c + 4 } # '0'..'9' -> 52..61 + if c == '+' { return 62 } # '+' + if c == '/' { return 63 } # '/' + return -1 } # decode NUL-terminated base64 `src` into the caller's `out` buffer; returns the @@ -33,18 +33,18 @@ function b64_decode(src: pointer, out: pointer) -> int { var i = 0 var c = src[i] while c != 0 { - if c == 61 { return w } # '=' -> done + if c == '=' { return w } # '=' -> done let v = b64_val(c) if v >= 0 { acc = (acc << 6) | v - nbits = nbits + 6 + nbits += 6 if nbits >= 8 { - nbits = nbits - 8 + nbits -= 8 out[w] = (acc >> nbits) & 255 - w = w + 1 + w += 1 } } - i = i + 1 + i += 1 c = src[i] } return w @@ -79,9 +79,9 @@ function base64_encode(src: pointer) -> pointer { let e2 = ((b1 & 15) << 2) | (b2 >> 6) let e3 = b2 & 63 out = out + tab[e0..e0 + 1] + tab[e1..e1 + 1] - if have >= 2 { out = out + tab[e2..e2 + 1] } else { out = out + "=" } - if have >= 3 { out = out + tab[e3..e3 + 1] } else { out = out + "=" } - i = i + 3 + if have >= 2 { out += tab[e2..e2 + 1] } else { out += "=" } + if have >= 3 { out += tab[e3..e3 + 1] } else { out += "=" } + i += 3 } return out } diff --git a/runtime/native/bignum.ludic b/runtime/native/bignum.ludic index cc911f42..7eee58f8 100644 --- a/runtime/native/bignum.ludic +++ b/runtime/native/bignum.ludic @@ -38,14 +38,14 @@ function bn_alloc(cap: int) -> BigNum { let b = new BigNum b.sign = 0; b.n = 0; b.limbs = words(c) var i = 0 - while i < c { b.limbs[i] = 0; i = i + 1 } + while i < c { b.limbs[i] = 0; i += 1 } return b } # drop high zero limbs; a magnitude of zero forces sign 0 function bn_norm(b: BigNum) -> BigNum { var k = b.n - while k > 0 and b.limbs[k - 1] == 0 { k = k - 1 } + while k > 0 and b.limbs[k - 1] == 0 { k -= 1 } b.n = k if k == 0 { b.sign = 0 } return b @@ -58,7 +58,7 @@ function bigint_from(value: int) -> BigNum { if value == 0 { return bigint_zero() } var sign = 1 var v: long = value - if v < 0 { sign = -1; v = 0 - v } + if v < 0 { sign = -1; v = -v } let b = bn_alloc(3) var i = 0 while v > 0 { @@ -66,7 +66,7 @@ function bigint_from(value: int) -> BigNum { let lo: int = v - q * BN_BASE b.limbs[i] = lo v = q - i = i + 1 + i += 1 } b.n = i; b.sign = sign return bn_norm(b) @@ -77,9 +77,9 @@ function bigint_from_str(text: pointer) -> BigNum { let e = len(text) var i = 0 var sign = 1 - if e > 0 and text[0] == 45 { sign = -1; i = 1 } # '-' - if e > 0 and text[0] == 43 { i = 1 } # '+' - while i < e - 1 and text[i] == 48 { i = i + 1 } # skip leading zeros + if e > 0 and text[0] == '-' { sign = -1; i = 1 } # '-' + if e > 0 and text[0] == '+' { i = 1 } # '+' + while i < e - 1 and text[i] == '0' { i += 1 } # skip leading zeros let ndig = e - i if ndig <= 0 { return bigint_zero() } let nlimb = (ndig + 8) / 9 @@ -91,8 +91,8 @@ function bigint_from_str(text: pointer) -> BigNum { if start < i { start = i } var v = 0 var k = start - while k < pos { v = v * 10 + (text[k] - 48); k = k + 1 } - b.limbs[li] = v; li = li + 1 + while k < pos { v = v * 10 + (text[k] - 48); k += 1 } + b.limbs[li] = v; li += 1 pos = start } b.n = nlimb; b.sign = sign @@ -105,7 +105,7 @@ function bn_ucmp(a: BigNum, b: BigNum) -> int { var i = a.n - 1 while i >= 0 { if a.limbs[i] != b.limbs[i] { if a.limbs[i] > b.limbs[i] { return 1 }; return -1 } - i = i - 1 + i -= 1 } return 0 } @@ -119,10 +119,10 @@ function bn_uadd(a: BigNum, b: BigNum) -> BigNum { var i = 0 while i < m { var s = carry - if i < a.n { s = s + a.limbs[i] } - if i < b.n { s = s + b.limbs[i] } + if i < a.n { s += a.limbs[i] } + if i < b.n { s += b.limbs[i] } if s >= BN_BASE { r.limbs[i] = s - BN_BASE; carry = 1 } else { r.limbs[i] = s; carry = 0 } - i = i + 1 + i += 1 } r.limbs[m] = carry r.n = m + 1 @@ -136,10 +136,10 @@ function bn_usub(a: BigNum, b: BigNum) -> BigNum { var i = 0 while i < a.n { var s = a.limbs[i] - borrow - if i < b.n { s = s - b.limbs[i] } - if s < 0 { s = s + BN_BASE; borrow = 1 } else { borrow = 0 } + if i < b.n { s -= b.limbs[i] } + if s < 0 { s += BN_BASE; borrow = 1 } else { borrow = 0 } r.limbs[i] = s - i = i + 1 + i += 1 } r.n = a.n return bn_norm(r) @@ -148,8 +148,8 @@ function bn_usub(a: BigNum, b: BigNum) -> BigNum { function bigint_neg(a: BigNum) -> BigNum { let r = bn_alloc(a.n) var i = 0 - while i < a.n { r.limbs[i] = a.limbs[i]; i = i + 1 } - r.n = a.n; r.sign = 0 - a.sign + while i < a.n { r.limbs[i] = a.limbs[i]; i += 1 } + r.n = a.n; r.sign = -a.sign return r } @@ -185,7 +185,7 @@ function bigint_mul(a: BigNum, b: BigNum) -> BigNum { let lo: int = t - q * BN_BASE r.limbs[i + j] = lo carry = q - j = j + 1 + j += 1 } var k = i + b.n while carry > 0 { @@ -195,9 +195,9 @@ function bigint_mul(a: BigNum, b: BigNum) -> BigNum { let lo2: int = t2 - q2 * BN_BASE r.limbs[k] = lo2 carry = q2 - k = k + 1 + k += 1 } - i = i + 1 + i += 1 } r.n = a.n + b.n; r.sign = a.sign * b.sign return bn_norm(r) @@ -211,7 +211,7 @@ function bigint_pow(a: BigNum, exp: int) -> BigNum { while e > 0 { if e - (e / 2) * 2 == 1 { result = bigint_mul(result, base) } base = bigint_mul(base, base) - e = e / 2 + e /= 2 } return result } @@ -220,7 +220,7 @@ function bigint_pow(a: BigNum, exp: int) -> BigNum { function bigint_div_int(a: BigNum, d: int) -> BigNum { var dd = d var dsign = 1 - if d < 0 { dsign = -1; dd = 0 - d } + if d < 0 { dsign = -1; dd = -d } let r = bn_alloc(a.n) var rem: long = 0 let ddl: long = dd @@ -230,7 +230,7 @@ function bigint_div_int(a: BigNum, d: int) -> BigNum { let q: long = cur / ddl rem = cur - q * ddl r.limbs[i] = q - i = i - 1 + i -= 1 } r.n = a.n; r.sign = a.sign * dsign return bn_norm(r) @@ -239,14 +239,14 @@ function bigint_div_int(a: BigNum, d: int) -> BigNum { # remainder of dividing by a nonzero int; carries the sign of `a` function bigint_mod_int(a: BigNum, d: int) -> int { var dd = d - if d < 0 { dd = 0 - d } + if d < 0 { dd = -d } let ddl: long = dd var rem: long = 0 var i = a.n - 1 while i >= 0 { let cur: long = rem * BN_BASE + a.limbs[i] rem = cur - (cur / ddl) * ddl - i = i - 1 + i -= 1 } let r: int = rem return r * a.sign @@ -257,7 +257,7 @@ function bigint_cmp(a: BigNum, b: BigNum) -> int { if a.sign == 0 { return 0 } let c = bn_ucmp(a, b) if a.sign > 0 { return c } - return 0 - c + return -c } function bigint_eq(a: BigNum, b: BigNum) -> bool { return bigint_cmp(a, b) == 0 } @@ -268,12 +268,12 @@ function bigint_to_int(a: BigNum) -> int { if a.sign == 0 { return 0 } var v: long = 0 var i = a.n - 1 - while i >= 0 { v = v * BN_BASE + a.limbs[i]; i = i - 1 } - if a.sign < 0 { v = 0 - v } + while i >= 0 { v = v * BN_BASE + a.limbs[i]; i -= 1 } + if a.sign < 0 { v = -v } let hi: long = 2147483647 - let lo: long = 0 - hi - 1 + let lo: long = -hi - 1 if v > hi { let r: int = hi; return r } - if v < lo { return 0 - 2147483647 - 1 } + if v < lo { return -2147483647 - 1 } let r: int = v return r } @@ -283,7 +283,7 @@ function bn_pad9(x: int) -> pointer { var s = string(x) var pad = 9 - len(s) var out = "" - while pad > 0 { out = out + "0"; pad = pad - 1 } + while pad > 0 { out += "0"; pad -= 1 } return out + s } @@ -291,9 +291,9 @@ function bigint_str(a: BigNum) -> pointer { if a.sign == 0 { return "0" } var out = "" if a.sign < 0 { out = "-" } - out = out + string(a.limbs[a.n - 1]) + out += string(a.limbs[a.n - 1]) var i = a.n - 2 - while i >= 0 { out = out + bn_pad9(a.limbs[i]); i = i - 1 } + while i >= 0 { out += bn_pad9(a.limbs[i]); i -= 1 } return out } @@ -312,12 +312,12 @@ function decimal_from(value: int) -> Dec { return dec_make(bigint_from(value), 0 # "[-]int[.frac]" -> Dec, scale = number of fractional digits function decimal_from_str(text: pointer) -> Dec { let e = len(text) - var dot = 0 - 1 + var dot = -1 var i = 0 - while i < e { if text[i] == 46 { dot = i }; i = i + 1 } # '.' + while i < e { if text[i] == '.' { dot = i }; i += 1 } # '.' if dot < 0 { return dec_make(bigint_from_str(text), 0) } let intp = text[0..dot] - let fracp = text[dot + 1 .. e] + let fracp = text[dot + 1..e] let scale = len(fracp) return dec_make(bigint_from_str(intp + fracp), scale) } @@ -360,7 +360,7 @@ function decimal_rescale(d: Dec, places: int) -> Dec { var diff = d.scale - places var m = d.m var i = 0 - while i < diff { m = bigint_div_int(m, 10); i = i + 1 } + while i < diff { m = bigint_div_int(m, 10); i += 1 } return dec_make(m, places) } @@ -372,7 +372,7 @@ function decimal_str(d: Dec) -> pointer { if d.scale == 0 { return neg + digits } var nd = len(digits) var pad = d.scale + 1 - nd - while pad > 0 { digits = "0" + digits; pad = pad - 1; nd = nd + 1 } + while pad > 0 { digits = "0" + digits; pad -= 1; nd += 1 } let cut = nd - d.scale let ip = digits[0..cut] let fp = digits[cut..nd] diff --git a/runtime/native/core.ludic b/runtime/native/core.ludic index 4c3b88c7..e271ae34 100644 --- a/runtime/native/core.ludic +++ b/runtime/native/core.ludic @@ -20,6 +20,9 @@ # ============================================================================ # ---- state ---------------------------------------------------------------- +# where a headless build leaves its last frame (relative to the working directory) +const HEADLESS_FRAME_PATH: string = "build/out.ppm" + var rt_fb: words = null # framebuffer, one i32 (0x00RRGGBB) per pixel var rt_fbw: int = 320 var rt_fbh: int = 240 @@ -63,7 +66,7 @@ function rt_init() -> void { rt_regs = words(64) fill(rt_regs, 0, 64 * 4) rt_map = bytes(96 * 64) - fill(rt_map, 32, 96 * 64) + fill(rt_map, ' ', 96 * 64) rt_clip_x1 = rt_fbw rt_clip_y1 = rt_fbh rt_statusbuf = bytes(96) @@ -82,7 +85,7 @@ function rt_shutdown() -> void { win_close() return } - rt_dump_ppm("build/out.ppm") + rt_dump_ppm(HEADLESS_FRAME_PATH) } # ---- framebuffer ---------------------------------------------------------- @@ -153,9 +156,9 @@ function rt_fill_rect(x: int, y: int, w: int, h: int, c: int) -> void { while i < x1 { if rt_blend == 1 { rt_fb[row + i] = rt_blend_add(rt_fb[row + i], c) } else { rt_fb[row + i] = c } - i = i + 1 + i += 1 } - j = j + 1 + j += 1 } } @@ -169,16 +172,16 @@ function rt_frame_rect(x: int, y: int, w: int, h: int, c: int) -> void { # A straight line by Bresenham's algorithm — integer only, any direction. function rt_line(x0: int, y0: int, x1: int, y1: int, c: int) -> void { var x = x0; var y = y0 - let dx = abs(x1 - x0); let dy = 0 - abs(y1 - y0) - var sx = 0 - 1; if x0 < x1 { sx = 1 } - var sy = 0 - 1; if y0 < y1 { sy = 1 } + let dx = abs(x1 - x0); let dy = -abs(y1 - y0) + var sx = -1; if x0 < x1 { sx = 1 } + var sy = -1; if y0 < y1 { sy = 1 } var err = dx + dy while true { rt_put_px(x, y, c) if (x == x1) and (y == y1) { return } let e2 = 2 * err - if e2 >= dy { err = err + dy; x = x + sx } - if e2 <= dx { err = err + dx; y = y + sy } + if e2 >= dy { err += dy; x += sx } + if e2 <= dx { err += dx; y += sy } } } @@ -191,9 +194,9 @@ function rt_circle(cx: int, cy: int, r: int, c: int) -> void { rt_put_px(cx - y, cy + x, c); rt_put_px(cx - x, cy + y, c) rt_put_px(cx - x, cy - y, c); rt_put_px(cx - y, cy - x, c) rt_put_px(cx + y, cy - x, c); rt_put_px(cx + x, cy - y, c) - y = y + 1 + y += 1 if err < 0 { err = err + 2 * y + 1 } - else { x = x - 1; err = err + 2 * (y - x) + 1 } + else { x -= 1; err = err + 2 * (y - x) + 1 } } } @@ -201,12 +204,12 @@ function rt_circle(cx: int, cy: int, r: int, c: int) -> void { function rt_fill_circle(cx: int, cy: int, r: int, c: int) -> void { if r < 0 { return } let r2 = r * r - var dy = 0 - r + var dy = -r while dy <= r { var dx = 0 - while (dx + 1) * (dx + 1) + dy * dy <= r2 { dx = dx + 1 } + while (dx + 1) * (dx + 1) + dy * dy <= r2 { dx += 1 } rt_fill_rect(cx - dx, cy + dy, 2 * dx + 1, 1, c) - dy = dy + 1 + dy += 1 } } @@ -231,9 +234,9 @@ function rt_fill_triangle(x0: int, y0: int, x1: int, y1: int, x2: int, y2: int, let neg = (d0 < 0) or (d1 < 0) or (d2 < 0) let pos = (d0 > 0) or (d1 > 0) or (d2 > 0) if not (neg and pos) { rt_put_px(px, py, c) } - px = px + 1 + px += 1 } - py = py + 1 + py += 1 } } @@ -261,18 +264,18 @@ function rt_oval(x: int, y: int, rx: int, ry: int, c: int) -> void { rt_oval_pts(x, y, ex, ey, c) var p = ry2 - rx2 * ry + rx2 / 4 # region 1 while px < py { - ex = ex + 1 - px = px + two_ry2 + ex += 1 + px += two_ry2 if p < 0 { p = p + ry2 + px } - else { ey = ey - 1; py = py - two_rx2; p = p + ry2 + px - py } + else { ey -= 1; py -= two_rx2; p = p + ry2 + px - py } rt_oval_pts(x, y, ex, ey, c) } p = ry2 * (ex * 2 + 1) * (ex * 2 + 1) / 4 + rx2 * (ey - 1) * (ey - 1) - rx2 * ry2 # region 2 while ey > 0 { - ey = ey - 1 - py = py - two_rx2 + ey -= 1 + py -= two_rx2 if p > 0 { p = p + rx2 - py } - else { ex = ex + 1; px = px + two_ry2; p = p + rx2 - py + px } + else { ex += 1; px += two_ry2; p = p + rx2 - py + px } rt_oval_pts(x, y, ex, ey, c) } } @@ -291,7 +294,7 @@ function rt_get_px(x: int, y: int) -> int { # glyph (5 wide + 1 gap), matching rt_text's cursor step. function rt_measure_text(text: string) -> int { var i = 0 - while text[i] != 0 { i = i + 1 } + while text[i] != 0 { i += 1 } return i * 6 } @@ -316,8 +319,8 @@ function rt_camera_follow(x: int, y: int, lerp: fixed) -> void { let ty = y - rt_fbh / 2 let sx = fixed(tx - rt_cam_x) * lerp # fixed * fixed, then floor to whole pixels let sy = fixed(ty - rt_cam_y) * lerp - rt_cam_x = rt_cam_x + floor(sx) - rt_cam_y = rt_cam_y + floor(sy) + rt_cam_x += floor(sx) + rt_cam_y += floor(sy) } # Add a random screen shake of up to +/- amount pixels, drawn from the seeded @@ -325,8 +328,8 @@ function rt_camera_follow(x: int, y: int, lerp: fixed) -> void { # amount <= 0 clears it. function rt_camera_shake(amount: int) -> void { if amount <= 0 { rt_shake_x = 0; rt_shake_y = 0; return } - rt_shake_x = rt_rng_range(0 - amount, amount) - rt_shake_y = rt_rng_range(0 - amount, amount) + rt_shake_x = rt_rng_range(-amount, amount) + rt_shake_y = rt_rng_range(-amount, amount) } # Camera.shake_for(amount, frames): shake by up to +/- amount pixels for `frames` @@ -340,7 +343,7 @@ function rt_camera_shake_for(amount: int, frames: int) -> void { } function rt_camera_tick() -> void { if rt_shake_left > 0 { - rt_shake_left = rt_shake_left - 1 + rt_shake_left -= 1 rt_camera_shake(rt_shake_amount) return } @@ -377,11 +380,11 @@ function rt_present() -> void { # ---- text ----------------------------------------------------------------- function rt_glyph(x: int, y: int, ch: int, colour: int, sc: int) -> void { var c = ch - if c >= 97 { - if c <= 122 { c = c - 32 } + if c >= 'a' { + if c <= 'z' { c -= 32 } } - if c < 32 { return } - if c > 90 { return } + if c < ' ' { return } + if c > 'Z' { return } let base = (c - 32) * 7 let font = rt_font() for row in 0 .. 7 { @@ -404,38 +407,38 @@ function rt_text(x: int, y: int, s: string, colour: int, sc: int) -> void { while ch != 0 { rt_glyph(cx, y, ch, colour, sc) cx = cx + 6 * sc - i = i + 1 + i += 1 ch = s[i] } } function rt_text_int(x: int, y: int, n: int, colour: int, sc: int) -> void { if n == 0 { - rt_glyph(x, y, 48, colour, sc) + rt_glyph(x, y, '0', colour, sc) return } var v = n var cx = x if v < 0 { - rt_glyph(cx, y, 45, colour, sc) + rt_glyph(cx, y, '-', colour, sc) cx = cx + 6 * sc - v = 0 - v + v = -v } var digits = 0 var t = v while t > 0 { - digits = digits + 1 - t = t / 10 + digits += 1 + t /= 10 } var p = digits while p > 0 { var div = 1 for k in 1 .. p { - div = div * 10 + div *= 10 } rt_glyph(cx, y, 48 + (v / div) % 10, colour, sc) cx = cx + 6 * sc - p = p - 1 + p -= 1 } } @@ -496,7 +499,7 @@ function rt_rng_int(max: int) -> int { # a deterministic +1 or -1 function rt_rng_sign() -> int { if rt_rng_chance(50) { return 1 } - return 0 - 1 + return -1 } # ---- platform: input ------------------------------------------------------ @@ -509,7 +512,7 @@ function rt_poll() -> int { rt_alive = 0 return 0 } - if c == 113 { # 'q' quits, as in the headless C platform + if c == 'q' { # 'q' quits, as in the headless C platform rt_alive = 0 } return c @@ -529,8 +532,8 @@ function rt_put_str(buf: pointer, at: int, s: string) -> int { var ch = s[0] while ch != 0 { buf[n] = ch - n = n + 1 - i = i + 1 + n += 1 + i += 1 ch = s[i] } return n @@ -538,25 +541,25 @@ function rt_put_str(buf: pointer, at: int, s: string) -> int { function rt_put_int(buf: pointer, at: int, v: int) -> int { if v == 0 { - buf[at] = 48 + buf[at] = '0' return at + 1 } var digits = 0 var t = v while t > 0 { - digits = digits + 1 - t = t / 10 + digits += 1 + t /= 10 } var n = at var p = digits while p > 0 { var div = 1 for k in 1 .. p { - div = div * 10 + div *= 10 } buf[n] = 48 + (v / div) % 10 - n = n + 1 - p = p - 1 + n += 1 + p -= 1 } return n } @@ -604,7 +607,7 @@ var rt_maph: int = 0 function rt_map_size(w: int, h: int) -> void { rt_mapw = clamp(w, 0, 96) rt_maph = clamp(h, 0, 64) - fill(rt_map, 32, 96 * 64) + fill(rt_map, ' ', 96 * 64) } function rt_map_row(y: int, s: string) -> void { @@ -615,7 +618,7 @@ function rt_map_row(y: int, s: string) -> void { while ch != 0 { if x >= 96 { return } rt_map[y * 96 + x] = ch - x = x + 1 + x += 1 ch = s[x] } } @@ -627,12 +630,12 @@ function rt_map_set(x: int, y: int, glyph: int) -> void { } function rt_map_fill(glyph: int) -> void { var y = 0 - while y < rt_maph { var x = 0; while x < rt_mapw { rt_map[y * 96 + x] = glyph; x = x + 1 }; y = y + 1 } + while y < rt_maph { var x = 0; while x < rt_mapw { rt_map[y * 96 + x] = glyph; x += 1 }; y += 1 } } # every cell of the rectangle (x, y, w, h) function rt_map_rect(x: int, y: int, w: int, h: int, glyph: int) -> void { var yy = y - while yy < y + h { var xx = x; while xx < x + w { rt_map_set(xx, yy, glyph); xx = xx + 1 }; yy = yy + 1 } + while yy < y + h { var xx = x; while xx < x + w { rt_map_set(xx, yy, glyph); xx += 1 }; yy += 1 } } # the outermost ring of cells function rt_map_border(glyph: int) -> void { @@ -648,11 +651,11 @@ function rt_map_random_cell(glyph: int) -> IVec2 { let x = rt_rng_range(0, rt_mapw - 1) let y = rt_rng_range(0, rt_maph - 1) if rt_tile(x, y) == glyph { return IVec2.make(x, y) } - tries = tries + 1 + tries += 1 } var y2 = 0 - while y2 < rt_maph { var x2 = 0; while x2 < rt_mapw { if rt_tile(x2, y2) == glyph { return IVec2.make(x2, y2) }; x2 = x2 + 1 }; y2 = y2 + 1 } - return IVec2.make(0 - 1, 0 - 1) + while y2 < rt_maph { var x2 = 0; while x2 < rt_mapw { if rt_tile(x2, y2) == glyph { return IVec2.make(x2, y2) }; x2 += 1 }; y2 += 1 } + return IVec2.make(-1, -1) } # a random cell holding `glyph` at least `min_tiles` from `from` (tiles); falls back to any such cell function rt_map_random_cell_far(glyph: int, from: IVec2, min_tiles: int) -> IVec2 { @@ -661,7 +664,7 @@ function rt_map_random_cell_far(glyph: int, from: IVec2, min_tiles: int) -> IVec while tries < 40 { if not IVec2.within(tile, from, min_tiles - 1) { return tile } tile = rt_map_random_cell(glyph) - tries = tries + 1 + tries += 1 } return tile } @@ -696,8 +699,8 @@ function rt_ivec_step(degrees: int) -> IVec2 { } function rt_angle_diff_degrees(a: int, b: int) -> int { var d = (b - a) % 360 - if d > 180 { d = d - 360 } - if d <= 0 - 180 { d = d + 360 } + if d > 180 { d -= 360 } + if d <= -180 { d += 360 } return d } @@ -714,18 +717,18 @@ function rt_bar(x: int, y: int, w: int, h: int, value: int, max: int, color: int function rt_rng_weighted(weights: []int) -> int { var total = 0 var i = 0 - while i < len(weights) { if weights[i] > 0 { total = total + weights[i] }; i = i + 1 } - if total <= 0 { return 0 - 1 } + while i < len(weights) { if weights[i] > 0 { total += weights[i] }; i += 1 } + if total <= 0 { return -1 } var roll = rt_rng_range(0, total - 1) i = 0 while i < len(weights) { if weights[i] > 0 { if roll < weights[i] { return i } - roll = roll - weights[i] + roll -= weights[i] } - i = i + 1 + i += 1 } - return 0 - 1 + return -1 } # List.sample(pool, count): `count` picks from an int slice, distinct while the @@ -735,20 +738,20 @@ function rt_list_sample(pool: []int, count: int) -> []int { let n = len(pool) var i = 0 while i < count { - if n == 0 { push(out, 0); i = i + 1; continue } + if n == 0 { push(out, 0); i += 1; continue } var pick = rt_rng_range(0, n - 1) var distinct = n > i var tries = 0 while distinct and (tries < 64) { var seen = false var j = 0 - while j < len(out) { if out[j] == pool[pick] { seen = true }; j = j + 1 } + while j < len(out) { if out[j] == pool[pick] { seen = true }; j += 1 } if not seen { break } pick = rt_rng_range(0, n - 1) - tries = tries + 1 + tries += 1 } push(out, pool[pick]) - i = i + 1 + i += 1 } return out } @@ -773,7 +776,7 @@ function rt_status(s: string) -> void { if i >= 95 { ch = 0 } if ch != 0 { rt_statusbuf[i] = ch - i = i + 1 + i += 1 ch = s[i] } } diff --git a/runtime/native/dict.ludic b/runtime/native/dict.ludic index ec9992c5..4543654f 100644 --- a/runtime/native/dict.ludic +++ b/runtime/native/dict.ludic @@ -40,27 +40,27 @@ function dict_new() -> Dict { # FNV-1a over the key's bytes -> a non-negative slot index in [0, cap) function dict_slot(key: pointer, cap: int) -> int { - var h = 0 - 2128831035 # FNV-1a offset basis, as a signed i32 + var h = -2128831035 # FNV-1a offset basis, as a signed i32 var i = 0 - while key[i] != 0 { h = (h ^ key[i]) * 16777619; i = i + 1 } + while key[i] != 0 { h = (h ^ key[i]) * 16777619; i += 1 } h = h & 2147483647 # clear the sign bit -> non-negative return h - (h / cap) * cap # h % cap } # slot index of `key`, or -1 if absent function dict_find(d: Dict, key: pointer) -> int { - if d.cap == 0 { return 0 - 1 } + if d.cap == 0 { return -1 } var idx = dict_slot(key, d.cap) var probes = 0 while probes < d.cap { let u = d.used[idx] - if u == DICT_EMPTY { return 0 - 1 } + if u == DICT_EMPTY { return -1 } if u == DICT_USED and d.keys[idx] == key { return idx } - idx = idx + 1 + idx += 1 if idx >= d.cap { idx = 0 } - probes = probes + 1 + probes += 1 } - return 0 - 1 + return -1 } # grow to double capacity and reinsert every live key @@ -75,7 +75,7 @@ function dict_grow(d: Dict) -> void { var i = 0 while i < oldcap { if oldused[i] == DICT_USED { dict_set(d, oldkeys[i], oldvals[i]) } - i = i + 1 + i += 1 } } @@ -84,7 +84,7 @@ function dict_set(d: Dict, key: pointer, value: int) -> void { if d.cap == 0 { dict_init(d, 16) } if (d.count + 1) * 10 >= d.cap * 7 { dict_grow(d) } # load factor 0.7 var idx = dict_slot(key, d.cap) - var tomb = 0 - 1 + var tomb = -1 var probes = 0 while probes < d.cap { let u = d.used[idx] @@ -92,18 +92,18 @@ function dict_set(d: Dict, key: pointer, value: int) -> void { var slot = idx if tomb >= 0 { slot = tomb } d.keys[slot] = key; d.vals[slot] = value; d.used[slot] = DICT_USED - d.count = d.count + 1 + d.count += 1 return } if u == DICT_TOMB { if tomb < 0 { tomb = idx } } if u == DICT_USED and d.keys[idx] == key { d.vals[idx] = value; return } - idx = idx + 1 + idx += 1 if idx >= d.cap { idx = 0 } - probes = probes + 1 + probes += 1 } if tomb >= 0 { d.keys[tomb] = key; d.vals[tomb] = value; d.used[tomb] = DICT_USED - d.count = d.count + 1 + d.count += 1 } } @@ -128,7 +128,7 @@ function dict_remove(d: Dict, key: pointer) -> void { if i < 0 { return } d.used[i] = DICT_TOMB d.keys[i] = null - d.count = d.count - 1 + d.count -= 1 } function dict_size(d: Dict) -> int { return d.count } @@ -146,7 +146,7 @@ function dict_keys(d: Dict) -> []pointer { var i = 0 while i < d.cap { if d.used[i] == DICT_USED { push(out, d.keys[i]) } - i = i + 1 + i += 1 } return out } diff --git a/runtime/native/fx.ludic b/runtime/native/fx.ludic index 17bb9604..2f8b5b3d 100644 --- a/runtime/native/fx.ludic +++ b/runtime/native/fx.ludic @@ -52,13 +52,13 @@ function fx_sparks(x: int, y: int, color: int, count: int) -> void { if fx_sn >= FX_MAX_SPARKS { return } fx_sx[fx_sn] = x fx_sy[fx_sn] = y - fx_svx[fx_sn] = rt_rng_range(0 - FX_SPARK_SPEED, FX_SPARK_SPEED) - fx_svy[fx_sn] = rt_rng_range(0 - FX_SPARK_SPEED, FX_SPARK_SPEED) + fx_svx[fx_sn] = rt_rng_range(-FX_SPARK_SPEED, FX_SPARK_SPEED) + fx_svy[fx_sn] = rt_rng_range(-FX_SPARK_SPEED, FX_SPARK_SPEED) fx_slife[fx_sn] = FX_SPARK_LIFE + rt_rng_range(0, FX_SPARK_LIFE_JITTER) fx_scolor[fx_sn] = color fx_ssize[fx_sn] = 1 + rt_rng_range(0, 2) - fx_sn = fx_sn + 1 - i = i + 1 + fx_sn += 1 + i += 1 } } @@ -70,7 +70,7 @@ function fx_number(x: int, y: int, value: int, color: int) -> void { fx_nvalue[fx_nn] = value fx_nlife[fx_nn] = FX_NUMBER_LIFE fx_ncolor[fx_nn] = color - fx_nn = fx_nn + 1 + fx_nn += 1 } function fx_clear() -> void { fx_sn = 0; fx_nn = 0 } @@ -95,16 +95,16 @@ function fx_tick() -> void { if not fx_ready { return } var i = 0 while i < fx_sn { - fx_sx[i] = fx_sx[i] + fx_svx[i] - fx_sy[i] = fx_sy[i] + fx_svy[i] - fx_slife[i] = fx_slife[i] - 1 - if fx_slife[i] <= 0 { fx_drop_spark(i) } else { i = i + 1 } + fx_sx[i] += fx_svx[i] + fx_sy[i] += fx_svy[i] + fx_slife[i] -= 1 + if fx_slife[i] <= 0 { fx_drop_spark(i) } else { i += 1 } } i = 0 while i < fx_nn { - fx_nlife[i] = fx_nlife[i] - 1 - if fx_nlife[i] % 2 == 0 { fx_ny[i] = fx_ny[i] - 1 } - if fx_nlife[i] <= 0 { fx_drop_number(i) } else { i = i + 1 } + fx_nlife[i] -= 1 + if fx_nlife[i] % 2 == 0 { fx_ny[i] -= 1 } + if fx_nlife[i] <= 0 { fx_drop_number(i) } else { i += 1 } } } @@ -114,11 +114,11 @@ function fx_draw() -> void { var i = 0 while i < fx_sn { rt_fill_rect(fx_sx[i], fx_sy[i], fx_ssize[i], fx_ssize[i], fx_scolor[i]) - i = i + 1 + i += 1 } i = 0 while i < fx_nn { rt_text_int(fx_nx[i] - 4, fx_ny[i] - 10, fx_nvalue[i], fx_ncolor[i], 1) - i = i + 1 + i += 1 } } diff --git a/runtime/native/grid.ludic b/runtime/native/grid.ludic index 9583227c..95986e35 100644 --- a/runtime/native/grid.ludic +++ b/runtime/native/grid.ludic @@ -15,7 +15,7 @@ property Cell { x: int = 0, y: int = 0 } -function grid_abs(v: int) -> int { if v < 0 { return 0 - v }; return v } +function grid_abs(v: int) -> int { if v < 0 { return -v }; return v } function grid_in_bounds(x: int, y: int) -> bool { return x >= 0 and y >= 0 and x < rt_mapw and y < rt_maph } # a cell blocks movement if it is out of bounds or holds the `wall` tile. function grid_blocked(x: int, y: int, wall: int) -> bool { @@ -30,9 +30,9 @@ function grid_line(x0: int, y0: int, x1: int, y1: int) -> []Cell { var y = y0 let dx = grid_abs(x1 - x0) let dy = grid_abs(y1 - y0) - var sx = 0 - 1 + var sx = -1 if x0 < x1 { sx = 1 } - var sy = 0 - 1 + var sy = -1 if y0 < y1 { sy = 1 } var err = dx - dy while true { @@ -41,8 +41,8 @@ function grid_line(x0: int, y0: int, x1: int, y1: int) -> []Cell { push(out, c) if x == x1 and y == y1 { break } let e2 = 2 * err - if e2 > 0 - dy { err = err - dy; x = x + sx } - if e2 < dx { err = err + dx; y = y + sy } + if e2 > -dy { err -= dy; x += sx } + if e2 < dx { err += dx; y += sy } } return out } @@ -53,7 +53,7 @@ function grid_line_of_sight(x0: int, y0: int, x1: int, y1: int, wall: int) -> bo var i = 0 while i < len(cells) { if grid_blocked(cells[i].x, cells[i].y, wall) { return false } - i = i + 1 + i += 1 } return true } @@ -66,17 +66,17 @@ function grid_flood(sx: int, sy: int, wall: int) -> []Cell { let n = w * rt_maph let seen = bytes(n) var i = 0 - while i < n { seen[i] = 0; i = i + 1 } + while i < n { seen[i] = 0; i += 1 } let qx = words(n) let qy = words(n) var head = 0 var tail = 0 - qx[tail] = sx; qy[tail] = sy; tail = tail + 1 + qx[tail] = sx; qy[tail] = sy; tail += 1 seen[sy * w + sx] = 1 while head < tail { let cx = qx[head] let cy = qy[head] - head = head + 1 + head += 1 let c = new Cell c.x = cx; c.y = cy push(out, c) @@ -90,9 +90,9 @@ function grid_flood(sx: int, sy: int, wall: int) -> []Cell { if dir == 3 { ny = cy - 1 } if grid_in_bounds(nx, ny) and seen[ny * w + nx] == 0 and not grid_blocked(nx, ny, wall) { seen[ny * w + nx] = 1 - qx[tail] = nx; qy[tail] = ny; tail = tail + 1 + qx[tail] = nx; qy[tail] = ny; tail += 1 } - dir = dir + 1 + dir += 1 } } return out @@ -113,14 +113,14 @@ function path_a_star(x0: int, y0: int, x1: int, y1: int, wall: int) -> []Cell { let inopen = bytes(n) let closed = bytes(n) var i = 0 - while i < n { g[i] = INF; came[i] = 0 - 1; inopen[i] = 0; closed[i] = 0; i = i + 1 } + while i < n { g[i] = INF; came[i] = -1; inopen[i] = 0; closed[i] = 0; i += 1 } let start = y0 * w + x0 let goal = y1 * w + x1 g[start] = 0 inopen[start] = 1 var found = false while true { - var best = 0 - 1 + var best = -1 var bestf = INF i = 0 while i < n { @@ -130,7 +130,7 @@ function path_a_star(x0: int, y0: int, x1: int, y1: int, wall: int) -> []Cell { let f = g[i] + grid_abs(cx - x1) + grid_abs(cy - y1) if f < bestf { bestf = f; best = i } } - i = i + 1 + i += 1 } if best < 0 { break } if best == goal { found = true; break } @@ -153,7 +153,7 @@ function path_a_star(x0: int, y0: int, x1: int, y1: int, wall: int) -> []Cell { if ng < g[ni] { g[ni] = ng; came[ni] = best; inopen[ni] = 1 } } } - dir = dir + 1 + dir += 1 } } if not found { return out } @@ -169,6 +169,6 @@ function path_a_star(x0: int, y0: int, x1: int, y1: int, wall: int) -> []Cell { cur = came[cur] } var k = len(rev) - 1 - while k >= 0 { push(out, rev[k]); k = k - 1 } + while k >= 0 { push(out, rev[k]); k -= 1 } return out } diff --git a/runtime/native/http.ludic b/runtime/native/http.ludic index df6a41c2..9023086a 100644 --- a/runtime/native/http.ludic +++ b/runtime/native/http.ludic @@ -47,7 +47,7 @@ function http_init() -> void { h_used[i] = 0; h_native[i] = 0; h_sent[i] = 0; h_res[i] = 0 h_status[i] = 0; h_blen[i] = 0 h_req[i] = null; h_body[i] = null; h_hdr[i] = null - i = i + 1 + i += 1 } h_ready = true } @@ -62,9 +62,9 @@ function http_slot_alloc() -> int { h_req[i] = null; h_body[i] = null; h_hdr[i] = null return i } - i = i + 1 + i += 1 } - return 0 - 1 + return -1 } function http_valid(h: int) -> bool { @@ -77,7 +77,7 @@ function http_valid(h: int) -> bool { function http_cstr_len(p: pointer) -> int { if p == null { return 0 } var n = 0 - while p[n] != 0 { n = n + 1 } + while p[n] != 0 { n += 1 } return n } @@ -147,9 +147,9 @@ function http_poll(h: int) -> int { if not http_valid(h) { return 0 } let s = h - 1 if h_native[s] == 0 { return h_status[s] } # a parsed handle is ready immediately - if h_sent[s] == 0 { return 0 - 1 } + if h_sent[s] == 0 { return -1 } if h_res[s] == 1 { return h_status[s] } - if hs_done(s) == 0 { return 0 - 1 } + if hs_done(s) == 0 { return -1 } # first time we see it finished: cache the fields off the worker. h_status[s] = hs_status(s) h_body[s] = hs_body(s) @@ -204,13 +204,13 @@ function http_slice_dup(src: pointer, a: int, b: int) -> pointer { if n < 0 { n = 0 } let out = bytes(n + 1) var i = 0 - while i < n { out[i] = src[a + i]; i = i + 1 } + while i < n { out[i] = src[a + i]; i += 1 } out[n] = 0 return out } -function http_is_digit(c: int) -> bool { return (c >= 48) and (c <= 57) } -function http_lower(c: int) -> int { if (c >= 65) and (c <= 90) { return c + 32 }; return c } +function http_is_digit(c: int) -> bool { return (c >= '0') and (c <= '9') } +function http_lower(c: int) -> int { if (c >= 'A') and (c <= 'Z') { return c + 32 }; return c } # Parse a raw HTTP/1.1 response (status line + headers + blank line + body) into # a ready handle. Useful for cached/custom transports and offline tests. @@ -221,20 +221,20 @@ function http_parse(resp: pointer, len: int) -> int { # status: the token after the first space on the status line. var i = 0 - while (i < len) and (resp[i] != 32) { i = i + 1 } # skip "HTTP/1.1" - while (i < len) and (resp[i] == 32) { i = i + 1 } # skip the space(s) + while (i < len) and (resp[i] != ' ') { i += 1 } # skip "HTTP/1.1" + while (i < len) and (resp[i] == ' ') { i += 1 } # skip the space(s) var st = 0 - while (i < len) and http_is_digit(resp[i]) { st = (st * 10) + (resp[i] - 48); i = i + 1 } + while (i < len) and http_is_digit(resp[i]) { st = (st * 10) + (resp[i] - 48); i += 1 } h_status[s] = st # header/body split at the first CRLFCRLF. - var split = 0 - 1 + var split = -1 var j = 0 while (j + 3) < len { - if (resp[j] == 13) and (resp[j + 1] == 10) and (resp[j + 2] == 13) and (resp[j + 3] == 10) { + if (resp[j] == '\r') and (resp[j + 1] == '\n') and (resp[j + 2] == '\r') and (resp[j + 3] == '\n') { split = j j = len - } else { j = j + 1 } + } else { j += 1 } } var hdr_end = split var body_start = split + 4 @@ -243,8 +243,8 @@ function http_parse(resp: pointer, len: int) -> int { # header block starts after the status line's CRLF. var hs = 0 while (hs + 1) < len { - if (resp[hs] == 13) and (resp[hs + 1] == 10) { hs = hs + 2; break } - hs = hs + 1 + if (resp[hs] == '\r') and (resp[hs + 1] == '\n') { hs += 2; break } + hs += 1 } if hs > hdr_end { hs = hdr_end } h_hdr[s] = http_slice_dup(resp, hs, hdr_end) @@ -264,17 +264,17 @@ function http_find_header(hdr: pointer, name: pointer) -> pointer { while i < hlen { # match name at the start of a line, followed by ':'. var k = 0 - while (k < nlen) and ((i + k) < hlen) and (http_lower(hdr[i + k]) == http_lower(name[k])) { k = k + 1 } - if (k == nlen) and ((i + k) < hlen) and (hdr[i + k] == 58) { + while (k < nlen) and ((i + k) < hlen) and (http_lower(hdr[i + k]) == http_lower(name[k])) { k += 1 } + if (k == nlen) and ((i + k) < hlen) and (hdr[i + k] == ':') { var v = i + k + 1 - while (v < hlen) and (hdr[v] == 32) { v = v + 1 } # skip spaces after ':' + while (v < hlen) and (hdr[v] == ' ') { v += 1 } # skip spaces after ':' var e = v - while (e < hlen) and (hdr[e] != 13) and (hdr[e] != 10) { e = e + 1 } + while (e < hlen) and (hdr[e] != '\r') and (hdr[e] != '\n') { e += 1 } return http_slice_dup(hdr, v, e) } # advance to the next line. - while (i < hlen) and (hdr[i] != 10) { i = i + 1 } - i = i + 1 + while (i < hlen) and (hdr[i] != '\n') { i += 1 } + i += 1 } return null } diff --git a/runtime/native/image.ludic b/runtime/native/image.ludic index b90e5711..39ee0a6e 100644 --- a/runtime/native/image.ludic +++ b/runtime/native/image.ludic @@ -71,7 +71,7 @@ function rt_decode_png(path: string) -> bool { let size = rt_file_len if size < 8 { free(d); return false } if d[0] != 137 { free(d); return false } - if d[1] != 80 { free(d); return false } + if d[1] != 'P' { free(d); return false } var w = 0 var h = 0 @@ -110,7 +110,7 @@ function rt_decode_png(path: string) -> bool { } if png_tag(d, typ, 73, 68, 65, 84) { # IDAT for k in 0 .. ln { idat[idlen + k] = d[body + k] } - idlen = idlen + ln + idlen += ln } if png_tag(d, typ, 73, 69, 78, 68) { done = 1 } # IEND i = i + 12 + ln @@ -150,8 +150,8 @@ function rt_decode_png(path: string) -> bool { if y > 0 { b = raw[prev + x] } if x >= fbpp { if y > 0 { c = raw[prev + x - fbpp] } } var v = raw[cur + x] - if ft == 1 { v = v + a } - if ft == 2 { v = v + b } + if ft == 1 { v += a } + if ft == 2 { v += b } if ft == 3 { v = v + (a + b) / 2 } if ft == 4 { let p = a + b - c @@ -161,7 +161,7 @@ function rt_decode_png(path: string) -> bool { var pick = c if pb <= pc { pick = b } if pa <= pb { if pa <= pc { pick = a } } - v = v + pick + v += pick } raw[cur + x] = (v & 255) } @@ -228,10 +228,10 @@ function rt_decode_png(path: string) -> bool { # ---- images --------------------------------------------------------------- function rt_image_load(path: string) -> int { - if img_n >= IMG_MAX { return 0 - 1 } - if rt_decode_png(path) == false { return 0 - 1 } + if img_n >= IMG_MAX { return -1 } + if rt_decode_png(path) == false { return -1 } let id = img_n - img_n = img_n + 1 + img_n += 1 img_px[id] = png_px img_w[id] = png_w img_h[id] = png_h @@ -316,10 +316,10 @@ function rt_draw_9slice(id: int, dx: int, dy: int, dw: int, dh: int, inset: int) # ---- sprites (16x16 art) -------------------------------------------------- function rt_png_load(path: string) -> int { - if spr_n >= SPR_MAX { return 0 - 1 } - if rt_decode_png(path) == false { return 0 - 1 } + if spr_n >= SPR_MAX { return -1 } + if rt_decode_png(path) == false { return -1 } let id = spr_n - spr_n = spr_n + 1 + spr_n += 1 let base = id * SPR_SZ * SPR_SZ for y in 0 .. SPR_SZ { for x in 0 .. SPR_SZ { @@ -395,10 +395,10 @@ function rt_draw_sprite_ex(id: int, px: int, py: int, sc: int, flip: int, tint: # ---- .lspr sprite sheets (palette + ASCII rows) --------------------------- function rt_hexval(c: int) -> int { - if c >= 48 { if c <= 57 { return c - 48 } } - if c >= 97 { if c <= 102 { return c - 87 } } - if c >= 65 { if c <= 70 { return c - 55 } } - return 0 - 1 + if c >= '0' { if c <= '9' { return c - 48 } } + if c >= 'a' { if c <= 'f' { return c - 87 } } + if c >= 'A' { if c <= 'F' { return c - 55 } } + return -1 } function rt_sprites_load(path: string) -> void { @@ -407,7 +407,7 @@ function rt_sprites_load(path: string) -> void { let size = rt_file_len let pal: words = words(128) fill(pal, 0, 128 * 4) - var cur = 0 - 1 + var cur = -1 var row = 0 var i = 0 while i < size { @@ -416,10 +416,10 @@ function rt_sprites_load(path: string) -> void { var j = start while j < size { let ch = d[j] - if ch == 10 { j = size } else { len = len + 1; j = j + 1 } + if ch == '\n' { j = size } else { len += 1; j += 1 } } let c0 = d[start] - if c0 == 112 { # 'p' — "pal " + if c0 == 'p' { # 'p' — "pal " let ch = d[start + 4] var v = 0 for k in 0 .. 6 { @@ -428,18 +428,18 @@ function rt_sprites_load(path: string) -> void { } if ch < 128 { pal[ch] = ((255 << 24) | v) } } - if c0 == 115 { # 's' — "spr" starts a new sprite - cur = 0 - 1 + if c0 == 's' { # 's' — "spr" starts a new sprite + cur = -1 if spr_n < SPR_MAX { cur = spr_n - spr_n = spr_n + 1 + spr_n += 1 fill(offset(spr_px, cur * SPR_SZ * SPR_SZ * 4), 0, SPR_SZ * SPR_SZ * 4) } row = 0 } - if c0 != 112 { - if c0 != 115 { - if c0 != 35 { # '#' comment + if c0 != 'p' { + if c0 != 's' { + if c0 != '#' { # '#' comment if cur >= 0 { if row < SPR_SZ { for x in 0 .. SPR_SZ { @@ -447,7 +447,7 @@ function rt_sprites_load(path: string) -> void { spr_px[cur * SPR_SZ * SPR_SZ + row * SPR_SZ + x] = pal[(d[start + x] & 127)] } } - row = row + 1 + row += 1 } } } diff --git a/runtime/native/inflate.ludic b/runtime/native/inflate.ludic index 0d71cc9f..1164d258 100644 --- a/runtime/native/inflate.ludic +++ b/runtime/native/inflate.ludic @@ -37,11 +37,11 @@ function z_bits(need: int) -> int { return 0 } val = (val | (z_src[z_pos] << z_bitcnt)) - z_pos = z_pos + 1 - z_bitcnt = z_bitcnt + 8 + z_pos += 1 + z_bitcnt += 8 } z_bitbuf = (val >> need) - z_bitcnt = z_bitcnt - need + z_bitcnt -= need return (val & ((1 << need) - 1)) } @@ -59,7 +59,7 @@ function z_table_build(table: words, lengths: words, n: int) -> void { } for s in 0 .. n { let l = lengths[s] - table[l] = table[l] + 1 + table[l] += 1 } table[0] = 0 # length 0 means "not present" # offset of each length's first symbol @@ -72,7 +72,7 @@ function z_table_build(table: words, lengths: words, n: int) -> void { let l = lengths[s] if l != 0 { table[16 + offs[l]] = s - offs[l] = offs[l] + 1 + offs[l] += 1 } } free(offs) @@ -88,7 +88,7 @@ function z_decode(table: words) -> int { if code - first < count { return table[16 + index + (code - first)] } - index = index + count + index += count first = ((first + count) << 1) code = (code << 1) } @@ -130,14 +130,14 @@ function z_stored(out: pointer, at: int, cap: int) -> int { z_bitcnt = 0 # stored blocks are byte-aligned if z_pos + 4 > z_len { return -1 } let n = z_src[z_pos] + (z_src[z_pos + 1] << 8) - z_pos = z_pos + 4 # LEN then its one's complement + z_pos += 4 # LEN then its one's complement var w = at for i in 0 .. n { if z_pos >= z_len { return -1 } if w >= cap { return -1 } out[w] = z_src[z_pos] - w = w + 1 - z_pos = z_pos + 1 + w += 1 + z_pos += 1 } return w } @@ -151,7 +151,7 @@ function z_codes(out: pointer, at: int, cap: int, lit: pointer, dist: pointer) - if sym < 256 { if w >= cap { return -1 } out[w] = sym - w = w + 1 + w += 1 } if sym > 256 { let s = sym - 257 @@ -164,7 +164,7 @@ function z_codes(out: pointer, at: int, cap: int, lit: pointer, dist: pointer) - for k in 0 .. length { if w >= cap { return -1 } out[w] = out[w - distance] - w = w + 1 + w += 1 } } sym = z_decode(lit) @@ -208,7 +208,7 @@ function z_dynamic_tables(lit: pointer, dist: pointer) -> int { if sym < 0 { return 0 } if sym < 16 { lengths[n] = sym - n = n + 1 + n += 1 } if sym >= 16 { var prev = 0 @@ -223,7 +223,7 @@ function z_dynamic_tables(lit: pointer, dist: pointer) -> int { for k in 0 .. rep { if n < 320 { lengths[n] = prev - n = n + 1 + n += 1 } } } @@ -294,14 +294,14 @@ function z_gunzip(src: pointer, len: int, out: pointer, cap: int) -> int { pos = pos + 2 + xlen } if (flg & 8) != 0 { # FNAME: NUL-terminated - while pos < len and src[pos] != 0 { pos = pos + 1 } - pos = pos + 1 + while pos < len and src[pos] != 0 { pos += 1 } + pos += 1 } if (flg & 16) != 0 { # FCOMMENT: NUL-terminated - while pos < len and src[pos] != 0 { pos = pos + 1 } - pos = pos + 1 + while pos < len and src[pos] != 0 { pos += 1 } + pos += 1 } - if (flg & 2) != 0 { pos = pos + 2 } # FHCRC: 2-byte header CRC + if (flg & 2) != 0 { pos += 2 } # FHCRC: 2-byte header CRC if pos + 8 > len { return -1 } return z_inflate(offset(src, pos), len - pos - 8, out, cap) } diff --git a/runtime/native/input.ludic b/runtime/native/input.ludic index 4fdd428d..2baec649 100644 --- a/runtime/native/input.ludic +++ b/runtime/native/input.ludic @@ -51,9 +51,9 @@ function input_find(name: pointer) -> int { var i = 0 while i < input_nact { if input_names[i] == name { return i } - i = i + 1 + i += 1 } - return 0 - 1 + return -1 } # get-or-create the slot for `name`. @@ -63,7 +63,7 @@ function input_slot(name: pointer) -> int { if input_nact >= INPUT_MAX_ACT { return INPUT_MAX_ACT - 1 } # silently reuse the last slot when full let s = input_nact input_names[s] = name - input_nact = input_nact + 1 + input_nact += 1 return s } @@ -75,12 +75,12 @@ function input_bind(name: pointer, key: int) -> void { var i = 0 while i < INPUT_MAX_KEYS { if input_keys[base + i] == key { return } # already bound - i = i + 1 + i += 1 } i = 0 while i < INPUT_MAX_KEYS { if input_keys[base + i] == 0 { input_keys[base + i] = key; return } - i = i + 1 + i += 1 } } @@ -93,7 +93,7 @@ function input_default(name: pointer, key: int) -> void { var i = 0 while i < INPUT_MAX_KEYS { if input_keys[base + i] != 0 { return } # already has a binding — keep it - i = i + 1 + i += 1 } input_keys[base] = key } @@ -107,12 +107,12 @@ function input_bind_pad(name: pointer, button: int) -> void { var i = 0 while i < INPUT_MAX_KEYS { if input_pads[base + i] == (button + 1) { return } # already bound - i = i + 1 + i += 1 } i = 0 while i < INPUT_MAX_KEYS { if input_pads[base + i] == 0 { input_pads[base + i] = button + 1; return } - i = i + 1 + i += 1 } } @@ -125,7 +125,7 @@ function input_rebind(name: pointer, oldkey: int, newkey: int) -> void { var i = 0 while i < INPUT_MAX_KEYS { if input_keys[base + i] == oldkey { input_keys[base + i] = newkey; return } - i = i + 1 + i += 1 } } @@ -137,7 +137,7 @@ function input_slot_has(s: int, k: int) -> bool { var i = 0 while i < INPUT_MAX_KEYS { if input_keys[base + i] == k { return true } - i = i + 1 + i += 1 } return false } @@ -158,7 +158,7 @@ function input_commit() -> int { input_last = input_frame if input_mode == 2 { # replay var k = 0 - if input_pos < input_recn { k = input_rec[input_pos]; input_pos = input_pos + 1 } + if input_pos < input_recn { k = input_rec[input_pos]; input_pos += 1 } input_frame = k input_device_commit(k, 1) # rebuild the device state from the tape return k @@ -166,7 +166,7 @@ function input_commit() -> int { let k = rt_poll() if input_mode == 1 { # record if input_rec == null { input_rec = words(INPUT_REC_CAP) } - if input_recn < INPUT_REC_CAP { input_rec[input_recn] = k; input_recn = input_recn + 1 } + if input_recn < INPUT_REC_CAP { input_rec[input_recn] = k; input_recn += 1 } } input_frame = k input_device_commit(k, 0) @@ -264,9 +264,9 @@ function in_bit_set(set: words, k: int, on: bool) -> void { let m = 1 << (k & 31) if on { set[w] = set[w] | m } else { set[w] = set[w] & (~m) } } -function in_set_clear(set: words) -> void { var i = 0; while i < IN_WORDS { set[i] = 0; i = i + 1 } } -function in_set_copy(dst: words, src: words) -> void { var i = 0; while i < IN_WORDS { dst[i] = src[i]; i = i + 1 } } -function in_set_or(dst: words, a: words, b: words) -> void { var i = 0; while i < IN_WORDS { dst[i] = a[i] | b[i]; i = i + 1 } } +function in_set_clear(set: words) -> void { var i = 0; while i < IN_WORDS { set[i] = 0; i += 1 } } +function in_set_copy(dst: words, src: words) -> void { var i = 0; while i < IN_WORDS { dst[i] = src[i]; i += 1 } } +function in_set_or(dst: words, a: words, b: words) -> void { var i = 0; while i < IN_WORDS { dst[i] = a[i] | b[i]; i += 1 } } # ---- the per-frame device commit (called by input_poll) -------------------- # Snapshot the committed set into prev (for edges), refresh the platform set (or @@ -278,7 +278,7 @@ function input_device_commit(k: int, replaying: int) -> void { # Taken before the platform refresh (win_pad, below, runs after this), so it holds # the previous frame's committed value against which this frame's edge is measured. var pj = 0 - while pj < IN_PADS { in_pad_btn0[pj] = in_pad_btn[pj]; pj = pj + 1 } + while pj < IN_PADS { in_pad_btn0[pj] = in_pad_btn[pj]; pj += 1 } if replaying == 1 { # rebuild the platform set + mouse from the tape; sim/injection is ignored so @@ -286,7 +286,7 @@ function input_device_commit(k: int, replaying: int) -> void { let base = (input_pos - 1) * IN_STRIDE if (in_tape != null) and (base >= 0) { var i = 0 - while i < IN_WORDS { in_dev[i] = in_tape[base + i]; i = i + 1 } + while i < IN_WORDS { in_dev[i] = in_tape[base + i]; i += 1 } in_mx = in_tape[base + 8] in_my = in_tape[base + 9] in_mbtn = in_tape[base + 10] @@ -312,7 +312,7 @@ function input_device_commit(k: int, replaying: int) -> void { input_set_pad(pi, pbuf[pb] != 0, pbuf[pb + 1], as_fixed(pbuf[pb + 2]), as_fixed(pbuf[pb + 3]), as_fixed(pbuf[pb + 4]), as_fixed(pbuf[pb + 5])) - pi = pi + 1 + pi += 1 } let tbuf = words(IN_TOUCH * 3) # [active, x, y]/point win_touch(tbuf) @@ -320,7 +320,7 @@ function input_device_commit(k: int, replaying: int) -> void { while ti < IN_TOUCH { let tb = ti * 3 input_set_touch(ti, tbuf[tb + 1], tbuf[tb + 2], tbuf[tb] != 0) - ti = ti + 1 + ti += 1 } } else { in_set_clear(in_dev) @@ -345,7 +345,7 @@ function input_device_record() -> void { if (f < 0) or (f >= INPUT_REC_CAP) { return } let base = f * IN_STRIDE var i = 0 - while i < IN_WORDS { in_tape[base + i] = in_held[i]; i = i + 1 } + while i < IN_WORDS { in_tape[base + i] = in_held[i]; i += 1 } in_tape[base + 8] = in_mx in_tape[base + 9] = in_my in_tape[base + 10] = in_mbtn @@ -366,8 +366,8 @@ function input_release(k: int) -> void { in_init(); in_bit_set(in_sim, k, false function input_axis(neg: int, pos: int) -> fixed { in_init() var v = fixed(0) - if in_bit_get(in_held, pos) { v = v + fixed(1) } - if in_bit_get(in_held, neg) { v = v - fixed(1) } + if in_bit_get(in_held, pos) { v += fixed(1) } + if in_bit_get(in_held, neg) { v -= fixed(1) } return v } # #79 — a directional intent as a plain int: +1 if the positive key is held, -1 if @@ -377,38 +377,44 @@ function input_axis(neg: int, pos: int) -> fixed { function input_axis_i(neg: int, pos: int) -> int { in_init() var v = 0 - if in_bit_get(in_held, pos) { v = v + 1 } - if in_bit_get(in_held, neg) { v = v - 1 } + if in_bit_get(in_held, pos) { v += 1 } + if in_bit_get(in_held, neg) { v -= 1 } return v } +# a stick has to leave its centre by this much before it counts as a direction +const STICK_DEADZONE: fixed = 0.35 +# gamepad axis indices as input_pad_axis numbers them +const STICK_LEFT_X: int = 0 +const STICK_LEFT_Y: int = 1 + # The standard top-down movement intent as -1/0/1 per axis: WASD or the arrow -# keys, and the left stick of pad 0 (past a 0.35 deadzone) when one is connected. +# keys, and the left stick of pad 0 (past the deadzone) when one is connected. function input_move_i() -> IVec2 { in_init() var x = input_axis_i(Key.A, Key.D) + input_axis_i(Key.Left, Key.Right) var y = input_axis_i(Key.W, Key.S) + input_axis_i(Key.Up, Key.Down) if input_pad_connected(0) { - let sx = input_pad_axis(0, 0) - let sy = input_pad_axis(0, 1) - if sx > 0.35 { x = 1 } - if sx < -0.35 { x = 0 - 1 } - if sy > 0.35 { y = 1 } - if sy < -0.35 { y = 0 - 1 } + let sx = input_pad_axis(0, STICK_LEFT_X) + let sy = input_pad_axis(0, STICK_LEFT_Y) + if sx > STICK_DEADZONE { x = 1 } + if sx < -STICK_DEADZONE { x = -1 } + if sy > STICK_DEADZONE { y = 1 } + if sy < -STICK_DEADZONE { y = -1 } } - return IVec2.make(clamp(x, 0 - 1, 1), clamp(y, 0 - 1, 1)) + return IVec2.make(clamp(x, -1, 1), clamp(y, -1, 1)) } # A 2D vector from four direction keys, normalized so a diagonal is not faster. function input_vector(left: int, right: int, up: int, down: int) -> Vector { in_init() var x = fixed(0) var y = fixed(0) - if in_bit_get(in_held, right) { x = x + fixed(1) } - if in_bit_get(in_held, left) { x = x - fixed(1) } - if in_bit_get(in_held, down) { y = y + fixed(1) } - if in_bit_get(in_held, up) { y = y - fixed(1) } + if in_bit_get(in_held, right) { x += fixed(1) } + if in_bit_get(in_held, left) { x -= fixed(1) } + if in_bit_get(in_held, down) { y += fixed(1) } + if in_bit_get(in_held, up) { y -= fixed(1) } if (x != 0) and (y != 0) { # diagonal: scale by 1/sqrt(2) - x = x * 0.7071 # fixed multiply (64-bit intermediate) - y = y * 0.7071 + x *= 0.7071 # fixed multiply (64-bit intermediate) + y *= 0.7071 } return Vector.make(x, y) } @@ -486,7 +492,7 @@ function input_touch_count() -> int { in_init() var n = 0 var i = 0 - while i < IN_TOUCH { if in_touch_on[i] != 0 { n = n + 1 }; i = i + 1 } + while i < IN_TOUCH { if in_touch_on[i] != 0 { n += 1 }; i += 1 } return n } function input_touch_x(i: int) -> int { in_init(); if (i < 0) or (i >= IN_TOUCH) { return 0 }; return in_touch_x[i] } @@ -523,7 +529,7 @@ function input_active_in(name: pointer, held: words, padmask: int) -> bool { if (k != 0) and in_bit_get(held, k) { return true } let pb = input_pads[base + i] if (pb != 0) and ((padmask & (1 << (pb - 1))) != 0) { return true } - i = i + 1 + i += 1 } return false } diff --git a/runtime/native/jobs.ludic b/runtime/native/jobs.ludic index b432b947..6da3a0f2 100644 --- a/runtime/native/jobs.ludic +++ b/runtime/native/jobs.ludic @@ -90,7 +90,7 @@ function jb_alloc(kind: int) -> int { jb_nmem[i] = 0 return i + 1 } - i = i + 1 + i += 1 } return 0 } @@ -161,16 +161,16 @@ function jb_refresh_group(s: int) -> void { let ms = mh - 1 let mst = jb_state[ms] if mst != J_PENDING { - settled = settled + 1 + settled += 1 if mst == J_DONE { - ok = ok + 1 + ok += 1 if first_ok == 0 { first_ok = mh } } } } else { - settled = settled + 1 # a freed/invalid member counts as settled-failed + settled += 1 # a freed/invalid member counts as settled-failed } - i = i + 1 + i += 1 } if k == JK_ALL { if ok == n { jb_state[s] = J_DONE; jb_result[s] = n } @@ -227,8 +227,8 @@ function job_pending() -> int { var n = 0 var i = 0 while i < JOB_SLOTS { - if jb_state[i] == J_PENDING { n = n + 1 } - i = i + 1 + if jb_state[i] == J_PENDING { n += 1 } + i += 1 } return n } @@ -246,7 +246,7 @@ function jb_step(s: int) -> int { var i = jb_i[s] if k == JK_SUM { jb_acc[s] = jb_acc[s] + (i + 1) - i = i + 1 + i += 1 jb_i[s] = i if i >= n { jb_state[s] = J_DONE; jb_result[s] = jb_acc[s]; return 1 } return 0 @@ -256,14 +256,14 @@ function jb_step(s: int) -> int { let t = jb_acc[s] + jb_acc2[s] jb_acc[s] = jb_acc2[s] jb_acc2[s] = t - i = i + 1 + i += 1 jb_i[s] = i if i >= n { jb_state[s] = J_DONE; jb_result[s] = jb_acc[s]; return 1 } return 0 } if k == JK_PRIMES { - if jb_is_prime(i) { jb_acc[s] = jb_acc[s] + 1 } - i = i + 1 + if jb_is_prime(i) { jb_acc[s] += 1 } + i += 1 jb_i[s] = i if i > n { jb_state[s] = J_DONE; jb_result[s] = jb_acc[s]; return 1 } return 0 @@ -276,7 +276,7 @@ function jb_is_prime(v: int) -> bool { var d = 2 while d * d <= v { if v - (v / d) * d == 0 { return false } - d = d + 1 + d += 1 } return true } @@ -296,10 +296,10 @@ function job_pump(budget: int) -> int { while (jb_state[s] == J_PENDING) and compute { if (budget > 0) and (spent >= budget) { s = JOB_SLOTS + 1; break } let fin = jb_step(s) - spent = spent + 1 - if fin == 1 { completed = completed + 1 } + spent += 1 + if fin == 1 { completed += 1 } } - s = s + 1 + s += 1 } # settle groups after the compute jobs advanced this frame. s = 0 @@ -308,10 +308,10 @@ function job_pump(budget: int) -> int { let k = jb_kind[s] if (k == JK_ALL) or (k == JK_RACE) { jb_refresh_group(s) - if jb_state[s] != J_PENDING { completed = completed + 1 } + if jb_state[s] != J_PENDING { completed += 1 } } } - s = s + 1 + s += 1 } return completed } @@ -324,7 +324,7 @@ function jb_set_members(s: int, handles: []int) -> void { if n > JOB_MAXMEM { n = JOB_MAXMEM } let base = s * JOB_MAXMEM var i = 0 - while i < n { jb_mem[base + i] = handles[i]; i = i + 1 } + while i < n { jb_mem[base + i] = handles[i]; i += 1 } jb_nmem[s] = n } @@ -354,8 +354,8 @@ function prom_count_done(handles: []int) -> int { var n = 0 var i = 0 while i < len(handles) { - if job_done(handles[i]) { n = n + 1 } - i = i + 1 + if job_done(handles[i]) { n += 1 } + i += 1 } return n } @@ -364,7 +364,7 @@ function prom_all_done(handles: []int) -> bool { var i = 0 while i < len(handles) { if not job_done(handles[i]) { return false } - i = i + 1 + i += 1 } return true } @@ -415,7 +415,7 @@ function sync_mutex() -> int { var i = 0 while i < SYNC_MUTEX { if mx_used[i] == 0 { mx_used[i] = 1; mx_held[i] = 0; return i + 1 } - i = i + 1 + i += 1 } return 0 } @@ -447,7 +447,7 @@ function sync_atomic() -> int { var i = 0 while i < SYNC_ATOMIC { if at_used[i] == 0 { at_used[i] = 1; at_val[i] = 0; return i + 1 } - i = i + 1 + i += 1 } return 0 } @@ -468,7 +468,7 @@ function sync_set(a: int, v: int) -> void { function sync_add(a: int, delta: int) -> int { sy_init() if (a < 1) or (a > SYNC_ATOMIC) { return 0 } - at_val[a - 1] = at_val[a - 1] + delta + at_val[a - 1] += delta return at_val[a - 1] } @@ -487,7 +487,7 @@ function sync_channel() -> int { var i = 0 while i < SYNC_CHAN { if ch_used[i] == 0 { ch_used[i] = 1; ch_head[i] = 0; ch_count[i] = 0; return i + 1 } - i = i + 1 + i += 1 } return 0 } @@ -500,9 +500,9 @@ function sync_send(c: int, v: int) -> bool { if ch_count[s] >= CHAN_CAP { return false } let pos = ch_head[s] + ch_count[s] var idx = pos - if idx >= CHAN_CAP { idx = idx - CHAN_CAP } + if idx >= CHAN_CAP { idx -= CHAN_CAP } ch_buf[s * CHAN_CAP + idx] = v - ch_count[s] = ch_count[s] + 1 + ch_count[s] += 1 return true } @@ -516,7 +516,7 @@ function sync_recv(c: int) -> int { var nh = ch_head[s] + 1 if nh >= CHAN_CAP { nh = 0 } ch_head[s] = nh - ch_count[s] = ch_count[s] - 1 + ch_count[s] -= 1 return v } diff --git a/runtime/native/light.ludic b/runtime/native/light.ludic index b5cea0a3..a30be0be 100644 --- a/runtime/native/light.ludic +++ b/runtime/native/light.ludic @@ -53,7 +53,7 @@ function light_occlude(x: int, y: int, w: int, h: int) -> void { rt_light_occ[i + 1] = y rt_light_occ[i + 2] = w rt_light_occ[i + 3] = h - rt_light_occ_n = rt_light_occ_n + 1 + rt_light_occ_n += 1 } # ---- shadow geometry ------------------------------------------------------ @@ -63,7 +63,7 @@ function light_occlude(x: int, y: int, w: int, h: int) -> void { function light_orient(ax: int, ay: int, bx: int, by: int, cx: int, cy: int) -> int { let v = (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) if v > 0 { return 1 } - if v < 0 { return 0 - 1 } + if v < 0 { return -1 } return 0 } @@ -102,7 +102,7 @@ function light_blocked(lx: int, ly: int, px: int, py: int) -> bool { if light_seg_cross(lx, ly, px, py, x1, y0, x1, y1) { return true } # right if light_seg_cross(lx, ly, px, py, x1, y1, x0, y1) { return true } # bottom if light_seg_cross(lx, ly, px, py, x0, y1, x0, y0) { return true } # left - k = k + 1 + k += 1 } return false } @@ -135,7 +135,7 @@ function light_fsqrt(v: fixed) -> fixed { var rt_light_falloff: int = 1 # brightness ramp exponent: 1 linear, 2 quadratic, 3 cubic… var rt_light_soft: int = 0 # penumbra radius in px (0 = hard single-sample shadow) var rt_light_gel: int = 0 # outer gel colour 0x00RRGGBB (used only when rt_light_gel_on) -var rt_light_gel_on: bool = false # gel active? off = a flat single-colour light +var rt_light_gel_on: bool = false # gel active? off = a flat single-colour light var rt_light_h: int = 64 # virtual light height above the surface, for normal-map N·L function light_set_falloff(exp: int) -> void { @@ -163,7 +163,7 @@ function light_clear_normals() -> void { if rt_light_nrm == null { return } let n = rt_fbw * rt_fbh var i = 0 - while i < n { rt_light_nrm[i] = 0; i = i + 1 } + while i < n { rt_light_nrm[i] = 0; i += 1 } } # stamp a rectangular region's surface normal. nx, ny are the normal's x/y as a @@ -182,10 +182,10 @@ function light_normal_rect(x: int, y: int, w: int, h: int, nx: fixed, ny: fixed) var px = x while px < x + w { if (px >= 0) and (px < rt_fbw) { rt_light_nrm[py * rt_fbw + px] = packed } - px = px + 1 + px += 1 } } - py = py + 1 + py += 1 } } @@ -220,7 +220,7 @@ function light_atan2_deg(y: int, x: int) -> int { # smallest absolute difference between two whole-degree angles, 0..180. function light_ang_diff(a: int, b: int) -> int { var d = a - b - if d < 0 { d = 0 - d } + if d < 0 { d = -d } if d > 180 { d = 360 - d } return d } @@ -231,7 +231,7 @@ function light_pow_t(t: fixed, exp: int) -> fixed { if exp <= 1 { return t } var r = t var i = 1 - while i < exp { r = r * t; i = i + 1 } + while i < exp { r *= t; i += 1 } return r } @@ -246,11 +246,11 @@ function light_vis(cx: int, cy: int, px: int, py: int) -> fixed { } let s = rt_light_soft var hit = 0 - if not light_blocked(cx, cy, px, py) { hit = hit + 1 } - if not light_blocked(cx + s, cy, px, py) { hit = hit + 1 } - if not light_blocked(cx - s, cy, px, py) { hit = hit + 1 } - if not light_blocked(cx, cy + s, px, py) { hit = hit + 1 } - if not light_blocked(cx, cy - s, px, py) { hit = hit + 1 } + if not light_blocked(cx, cy, px, py) { hit += 1 } + if not light_blocked(cx + s, cy, px, py) { hit += 1 } + if not light_blocked(cx - s, cy, px, py) { hit += 1 } + if not light_blocked(cx, cy + s, px, py) { hit += 1 } + if not light_blocked(cx, cy - s, px, py) { hit += 1 } return fixed(hit) / fixed(5) } @@ -297,7 +297,7 @@ function light_ambient(color: int) -> void { let ng = (((cur >> 8) & 255) * ag) / 255 let nb = ((cur & 255) * ab) / 255 rt_fb[i] = (nr << 16) | (ng << 8) | nb - i = i + 1 + i += 1 } } @@ -368,17 +368,17 @@ function light_emit(cx: int, cy: int, radius: int, color: int, energy: fixed, di } } } - px = px + 1 + px += 1 } } - py = py + 1 + py += 1 } } # a radial (omnidirectional) point light — the original short-signature call, # now a thin wrapper over light_emit with the cone disabled. function light_point(cx: int, cy: int, radius: int, color: int, energy: fixed) -> void { - light_emit(cx, cy, radius, color, energy, 0, 0 - 1) + light_emit(cx, cy, radius, color, energy, 0, -1) } # a cone / spot light aimed at `direction` degrees (0 = +x, CCW) with a half-angle @@ -396,7 +396,7 @@ function light_spot(cx: int, cy: int, radius: int, color: int, energy: fixed, di function light_time_of_day(t: fixed) -> void { # day factor 0..1: 0 at midnight, 1 at noon (triangle over the day). var day = t * fixed(2) # 0..2 across the day - if day > fixed(1) { day = fixed(2) - day } # fold 0.5..1 back down: peak at noon + if day > fixed(1) { day = fixed(2) - day } # fold 0.5..1 back down: peak at noon if day < 0 { day = fixed(0) } # night tint 0x14142a (deep blue) -> day 0xffffff, per channel. let nr = 20; let ng = 20; let nb = 42 diff --git a/runtime/native/numeric.ludic b/runtime/native/numeric.ludic index 553e4b51..060ff3a4 100644 --- a/runtime/native/numeric.ludic +++ b/runtime/native/numeric.ludic @@ -33,8 +33,8 @@ function huge_make(m: fixed, e: int) -> Huge { var mm = m if mm < 0.0 { neg = true; mm = 0.0 - mm } var ee = e - while mm >= HUGE_TEN { mm = mm / HUGE_TEN; ee = ee + 1 } - while mm < HUGE_ONE { mm = mm * HUGE_TEN; ee = ee - 1 } + while mm >= HUGE_TEN { mm /= HUGE_TEN; ee += 1 } + while mm < HUGE_ONE { mm *= HUGE_TEN; ee -= 1 } if neg { mm = 0.0 - mm } h.m = mm; h.e = ee return h @@ -45,10 +45,10 @@ function huge_from(value: int) -> Huge { if value == 0 { return huge_make(0.0, 0) } var neg = false var v: long = value - if v < 0 { neg = true; v = 0 - v } + if v < 0 { neg = true; v = -v } var e = 0 var p: long = 1 - while p * 10 <= v { p = p * 10; e = e + 1 } + while p * 10 <= v { p *= 10; e += 1 } let raw: long = (v * 65536) / p # v / 10^e in Q16.16 (in [1,10)) let rawi: int = raw var m: fixed = as_fixed(rawi) @@ -78,7 +78,7 @@ function huge_add(a: Huge, b: Huge) -> Huge { if diff > 8 { return big } # negligible at display precision var sm = small.m var k = 0 - while k < diff { sm = sm / HUGE_TEN; k = k + 1 } + while k < diff { sm /= HUGE_TEN; k += 1 } return huge_make(big.m + sm, big.e) } @@ -90,9 +90,9 @@ function huge_cmp(a: Huge, b: Huge) -> int { if sa != sb { if sa > sb { return 1 }; return -1 } if sa == 0 { return 0 } var c = 0 - if a.e != b.e { if a.e > b.e { c = 1 } else { c = 0 - 1 } } - else { if a.m > b.m { c = 1 } else { if a.m < b.m { c = 0 - 1 } else { c = 0 } } } - if sa < 0 { c = 0 - c } + if a.e != b.e { if a.e > b.e { c = 1 } else { c = -1 } } + else { if a.m > b.m { c = 1 } else { if a.m < b.m { c = -1 } else { c = 0 } } } + if sa < 0 { c = -c } return c } @@ -109,8 +109,8 @@ function huge_str(a: Huge) -> pointer { let frac: fixed = m - fixed(ip) var dd: int = floor(frac * 100.0 + 0.5) # round the two decimals to nearest var ex = a.e - if dd >= 100 { dd = 0; ip = ip + 1 } # rounding carried into the ones place - if ip >= 10 { ip = 1; ex = ex + 1 } # ...and on into the exponent + if dd >= 100 { dd = 0; ip += 1 } # rounding carried into the ones place + if ip >= 10 { ip = 1; ex += 1 } # ...and on into the exponent var ds = string(dd) if dd < 10 { ds = "0" + ds } return neg + string(ip) + "." + ds + "e" + string(ex) @@ -124,8 +124,8 @@ const ANGLE_TAU: fixed = 6.28318531 # wrap any radian value into the half-open range [-pi, pi) function angle_wrap(a: fixed) -> fixed { var x = a - while x >= ANGLE_PI { x = x - ANGLE_TAU } - while x < 0.0 - ANGLE_PI { x = x + ANGLE_TAU } + while x >= ANGLE_PI { x -= ANGLE_TAU } + while x < 0.0 - ANGLE_PI { x += ANGLE_TAU } return x } diff --git a/runtime/native/query.ludic b/runtime/native/query.ludic index e4b78a45..ac52ea15 100644 --- a/runtime/native/query.ludic +++ b/runtime/native/query.ludic @@ -23,7 +23,7 @@ function query_count(prop: int) -> int { var n = 0 var e = world_query_next(prop, 0) while e >= 0 { - n = n + 1 + n += 1 e = world_query_next(prop, e + 1) } return n @@ -40,7 +40,7 @@ function query_first(prop: int) -> int { # y_field); pass the same id for `prop` and `pos` to query by the position # component itself, or a separate tag for `prop` (e.g. "nearest Enemy"). function query_nearest(prop: int, pos: int, x_field: int, y_field: int, px: int, py: int) -> int { - var best = 0 - 1 + var best = -1 var bestd = 0 var e = world_query_next(prop, 0) while e >= 0 { diff --git a/runtime/native/reflect_io.ludic b/runtime/native/reflect_io.ludic index 439570cf..2af7f775 100644 --- a/runtime/native/reflect_io.ludic +++ b/runtime/native/reflect_io.ludic @@ -32,11 +32,11 @@ function reflect_serialize(e: int) -> Val { var node = value_int(raw) if world_field_type(p, f) == "fixed" { node = value_fixed(raw) } value_put(comp, fname, node) - f = f + 1 + f += 1 } value_put(obj, world_prop_name(p), comp) } - p = p + 1 + p += 1 } return obj } @@ -49,7 +49,7 @@ function reflect_apply(e: int, v: Val) -> int { var i = 0 while i < value_count(v) { let pname = value_key_at(v, i) - if pname[0] != 64 { # skip reserved "@…" keys + if pname[0] != '@' { # skip reserved "@…" keys let p = world_prop_id(pname) if p >= 0 and world_has(e, p) != 0 { let comp = value_at(v, i) @@ -59,13 +59,13 @@ function reflect_apply(e: int, v: Val) -> int { let f = world_field_id(p, fname) if f >= 0 { world_set(e, p, f, value_as_int(value_at(comp, j))) - set = set + 1 + set += 1 } - j = j + 1 + j += 1 } } } - i = i + 1 + i += 1 } return set } diff --git a/runtime/native/regex.ludic b/runtime/native/regex.ludic index 8c3d65b5..3b1ac555 100644 --- a/runtime/native/regex.ludic +++ b/runtime/native/regex.ludic @@ -25,7 +25,7 @@ # ============================================================================ # ---- small helpers ---------------------------------------------------------- -function rx_slen(s: pointer) -> int { var n = 0; while s[n] != 0 { n = n + 1 }; return n } +function rx_slen(s: pointer) -> int { var n = 0; while s[n] != 0 { n += 1 }; return n } # ---- growable int vector ---------------------------------------------------- property IVec { d: words, n: int, cap: int } @@ -37,17 +37,17 @@ function iv_new() -> IVec { function iv_grow(v: IVec, need: int) -> void { if v.n + need <= v.cap { return } var nc = v.cap * 2 - while nc < v.n + need { nc = nc * 2 } + while nc < v.n + need { nc *= 2 } let nd = words(nc) var i = 0 - while i < v.n { nd[i] = v.d[i]; i = i + 1 } + while i < v.n { nd[i] = v.d[i]; i += 1 } v.d = nd; v.cap = nc } function iv_push(v: IVec, x: int) -> int { iv_grow(v, 1) let idx = v.n v.d[v.n] = x - v.n = v.n + 1 + v.n += 1 return idx } @@ -80,13 +80,13 @@ const N_EMPTY: int = 13 property RNode { op: int = 0, ch: int = 0, cls: int = 0, lo: int = 0, hi: int = 0, - greedy: int = 1, gidx: int = 0 - 1, kids: []RNode + greedy: int = 1, gidx: int = -1, kids: []RNode } function rx_node(op: int) -> RNode { let n = new RNode n.op = op n.greedy = 1 - n.gidx = 0 - 1 + n.gidx = -1 n.kids = new []RNode return n } @@ -101,16 +101,16 @@ var rx_err: int = 0 var rx_ngroup: int = 0 var rx_prog: Prog = null -function rx_peek() -> int { if rx_pos < rx_len { return rx_pat[rx_pos] & 255 }; return 0 - 1 } -function rx_peek2() -> int { if rx_pos + 1 < rx_len { return rx_pat[rx_pos + 1] & 255 }; return 0 - 1 } -function rx_adv() -> int { let c = rx_peek(); rx_pos = rx_pos + 1; return c } +function rx_peek() -> int { if rx_pos < rx_len { return rx_pat[rx_pos] & 255 }; return -1 } +function rx_peek2() -> int { if rx_pos + 1 < rx_len { return rx_pat[rx_pos + 1] & 255 }; return -1 } +function rx_adv() -> int { let c = rx_peek(); rx_pos += 1; return c } # ---- character classes ------------------------------------------------------ # a class is 8 i32 words (256 bits) in prog.cls; class k occupies cls[8k .. 8k+8) function rx_class_new() -> int { let idx = rx_prog.cls.n / 8 var i = 0 - while i < 8 { iv_push(rx_prog.cls, 0); i = i + 1 } + while i < 8 { iv_push(rx_prog.cls, 0); i += 1 } return idx } function rx_class_set(idx: int, c: int) -> void { @@ -119,11 +119,11 @@ function rx_class_set(idx: int, c: int) -> void { } function rx_class_set_range(idx: int, a: int, b: int) -> void { var c = a - while c <= b { rx_class_set(idx, c); c = c + 1 } + while c <= b { rx_class_set(idx, c); c += 1 } } function rx_class_negate(idx: int) -> void { var i = 0 - while i < 8 { let w = idx * 8 + i; rx_prog.cls.d[w] = ~rx_prog.cls.d[w]; i = i + 1 } + while i < 8 { let w = idx * 8 + i; rx_prog.cls.d[w] = ~rx_prog.cls.d[w]; i += 1 } } function rx_class_unset(idx: int, c: int) -> void { let w = idx * 8 + (c >> 5) @@ -131,11 +131,11 @@ function rx_class_unset(idx: int, c: int) -> void { } function rx_class_unset_range(idx: int, a: int, b: int) -> void { var c = a - while c <= b { rx_class_unset(idx, c); c = c + 1 } + while c <= b { rx_class_unset(idx, c); c += 1 } } function rx_class_set_all(idx: int) -> void { var i = 0 - while i < 8 { rx_prog.cls.d[idx * 8 + i] = 0 - 1; i = i + 1 } + while i < 8 { rx_prog.cls.d[idx * 8 + i] = -1; i += 1 } } function rx_class_set_word(idx: int) -> void { rx_class_set_range(idx, 48, 57) @@ -151,12 +151,12 @@ function rx_class_has(prog: Prog, idx: int, c: int) -> bool { let w = prog.cls.d[idx * 8 + (c >> 5)] return (w & (1 << (c & 31))) != 0 } -function rx_is_digit(c: int) -> bool { return c >= 48 and c <= 57 } +function rx_is_digit(c: int) -> bool { return c >= '0' and c <= '9' } function rx_is_word(c: int) -> bool { - return (c >= 48 and c <= 57) or (c >= 65 and c <= 90) or (c >= 97 and c <= 122) or c == 95 + return (c >= '0' and c <= '9') or (c >= 'A' and c <= 'Z') or (c >= 'a' and c <= 'z') or c == '_' } function rx_is_ws(c: int) -> bool { - return c == 32 or c == 9 or c == 10 or c == 13 or c == 12 or c == 11 + return c == ' ' or c == '\t' or c == '\n' or c == '\r' or c == 12 or c == 11 } # OR the set named by \d \D \w \W \s \S into class idx. The negated forms OR in # the complement set bit-by-bit (never via set-all+unset, which would clobber a @@ -170,7 +170,7 @@ function rx_class_add_pre(idx: int, kind: int) -> void { if kind == 68 { if not rx_is_digit(c) { rx_class_set(idx, c) } } # \D else if kind == 87 { if not rx_is_word(c) { rx_class_set(idx, c) } } # \W else if kind == 83 { if not rx_is_ws(c) { rx_class_set(idx, c) } } # \S - c = c + 1 + c += 1 } } @@ -186,7 +186,7 @@ function rx_parse_class() -> RNode { var lo = rx_adv() if lo == 92 { # escape inside class let e = rx_adv() - if e == 100 or e == 68 or e == 119 or e == 87 or e == 115 or e == 83 { + if e == 'd' or e == 'D' or e == 'w' or e == 'W' or e == 's' or e == 'S' { rx_class_add_pre(idx, e) continue } @@ -210,12 +210,12 @@ function rx_parse_class() -> RNode { } # map an escaped char inside a class to its byte function rx_class_escape_char(e: int) -> int { - if e == 110 { return 10 } - if e == 116 { return 9 } - if e == 114 { return 13 } - if e == 102 { return 12 } - if e == 118 { return 11 } - if e == 48 { return 0 } + if e == 'n' { return 10 } + if e == 't' { return 9 } + if e == 'r' { return 13 } + if e == 'f' { return 12 } + if e == 'v' { return 11 } + if e == '0' { return 0 } return e } @@ -223,21 +223,21 @@ function rx_class_escape_char(e: int) -> int { function rx_parse_escape() -> RNode { rx_adv() # consume '\' let e = rx_adv() - if e == 100 or e == 68 or e == 119 or e == 87 or e == 115 or e == 83 { + if e == 'd' or e == 'D' or e == 'w' or e == 'W' or e == 's' or e == 'S' { let idx = rx_class_new() rx_class_add_pre(idx, e) let node = rx_node(N_CLASS) node.cls = idx return node } - if e >= 49 and e <= 57 { rx_err = 1; return rx_node(N_EMPTY) } # backrefs unsupported + if e >= '1' and e <= '9' { rx_err = 1; return rx_node(N_EMPTY) } # backrefs unsupported var ch = e - if e == 110 { ch = 10 } - else if e == 116 { ch = 9 } - else if e == 114 { ch = 13 } - else if e == 102 { ch = 12 } - else if e == 118 { ch = 11 } - else if e == 48 { ch = 0 } + if e == 'n' { ch = 10 } + else if e == 't' { ch = 9 } + else if e == 'r' { ch = 13 } + else if e == 'f' { ch = 12 } + else if e == 'v' { ch = 11 } + else if e == '0' { ch = 0 } else if e < 0 { rx_err = 1; return rx_node(N_EMPTY) } let node = rx_node(N_LIT) node.ch = ch @@ -261,7 +261,7 @@ function rx_parse_concat() -> RNode { let cat = rx_node(N_CONCAT) while true { let c = rx_peek() - if c < 0 or c == 124 or c == 41 { break } + if c < 0 or c == '|' or c == ')' { break } push(cat.kids, rx_parse_repeat()) if rx_err == 1 { break } } @@ -278,17 +278,17 @@ function rx_parse_repeat() -> RNode { let atom = rx_parse_atom() if rx_err == 1 { return atom } let c = rx_peek() - if c == 42 or c == 43 or c == 63 { + if c == '*' or c == '+' or c == '?' { rx_adv() var op = N_STAR - if c == 43 { op = N_PLUS } - if c == 63 { op = N_QUEST } + if c == '+' { op = N_PLUS } + if c == '?' { op = N_QUEST } let r = rx_node(op) r.greedy = rx_lazy() push(r.kids, atom) return r } - if c == 123 { return rx_parse_brace(atom) } + if c == '{' { return rx_parse_brace(atom) } return atom } # {n} {n,} {n,m} @@ -300,7 +300,7 @@ function rx_parse_brace(atom: RNode) -> RNode { while rx_peek() >= 48 and rx_peek() <= 57 { lo = lo * 10 + (rx_adv() - 48); haslo = true } var hi = lo var hasComma = false - if rx_peek() == 44 { hasComma = true; rx_adv(); hi = 0 - 1 + if rx_peek() == 44 { hasComma = true; rx_adv(); hi = -1 var hashi = false while rx_peek() >= 48 and rx_peek() <= 57 { if not hashi { hi = 0 }; hi = hi * 10 + (rx_adv() - 48); hashi = true } } @@ -319,18 +319,18 @@ function rx_parse_brace(atom: RNode) -> RNode { } function rx_parse_atom() -> RNode { let c = rx_peek() - if c == 40 { # '(' + if c == '(' { # '(' rx_adv() - var gidx = 0 - 1 + var gidx = -1 if rx_peek() == 63 { # (? ... rx_adv() let d = rx_peek() - if d == 58 { rx_adv() } # (?: non-capturing - else if d == 80 { rx_adv(); rx_skip_name() } # (?P (captured, name ignored for now) - else if d == 60 { rx_skip_name() } # (? + if d == ':' { rx_adv() } # (?: non-capturing + else if d == 'P' { rx_adv(); rx_skip_name() } # (?P (captured, name ignored for now) + else if d == '<' { rx_skip_name() } # (? else { rx_err = 1; return rx_node(N_EMPTY) } } else { - rx_ngroup = rx_ngroup + 1 + rx_ngroup += 1 gidx = rx_ngroup } let inner = rx_parse_alt() @@ -341,12 +341,12 @@ function rx_parse_atom() -> RNode { push(g.kids, inner) return g } - if c == 91 { return rx_parse_class() } - if c == 46 { rx_adv(); return rx_node(N_ANY) } - if c == 94 { rx_adv(); return rx_node(N_BOL) } - if c == 36 { rx_adv(); return rx_node(N_EOL) } - if c == 92 { return rx_parse_escape() } - if c == 42 or c == 43 or c == 63 or c == 41 { rx_err = 1; return rx_node(N_EMPTY) } + if c == '[' { return rx_parse_class() } + if c == '.' { rx_adv(); return rx_node(N_ANY) } + if c == '^' { rx_adv(); return rx_node(N_BOL) } + if c == '$' { rx_adv(); return rx_node(N_EOL) } + if c == '\\' { return rx_parse_escape() } + if c == '*' or c == '+' or c == '?' or c == ')' { rx_err = 1; return rx_node(N_EMPTY) } if c < 0 { rx_err = 1; return rx_node(N_EMPTY) } rx_adv() let n = rx_node(N_LIT) @@ -359,7 +359,7 @@ function rx_skip_name() -> void { if rx_peek() == 60 { rx_adv() } # consume '<' while rx_peek() != 62 and rx_peek() >= 0 { rx_adv() } if rx_peek() == 62 { rx_adv() } # consume '>' - rx_ngroup = rx_ngroup + 1 + rx_ngroup += 1 # note: the caller set gidx = -1; fix it up to a real capture index rx_named_gidx = rx_ngroup } @@ -387,7 +387,7 @@ function rx_compile(node: RNode) -> void { if op == N_EOL { pg_emit(OP_EOL, 0, 0); return } if op == N_CONCAT { var i = 0 - while i < len(node.kids) { rx_compile(node.kids[i]); i = i + 1 } + while i < len(node.kids) { rx_compile(node.kids[i]); i += 1 } return } if op == N_GROUP { @@ -414,11 +414,11 @@ function rx_compile(node: RNode) -> void { } else { rx_compile(node.kids[i]) } - i = i + 1 + i += 1 } let end = pg_pc() i = 0 - while i < jmps.n { pg_set_a(jmps.d[i], end); i = i + 1 } + while i < jmps.n { pg_set_a(jmps.d[i], end); i += 1 } return } if op == N_STAR { @@ -453,7 +453,7 @@ function rx_compile(node: RNode) -> void { if op == N_REP { let kid = node.kids[0] var i = 0 - while i < node.lo { rx_compile(kid); i = i + 1 } + while i < node.lo { rx_compile(kid); i += 1 } if node.hi < 0 { let st = rx_node(N_STAR) st.greedy = node.greedy @@ -466,7 +466,7 @@ function rx_compile(node: RNode) -> void { q.greedy = node.greedy push(q.kids, kid) rx_compile(q) - i = i + 1 + i += 1 } } return @@ -503,4 +503,3 @@ function regex_compile(pattern: pointer) -> Prog { pg_emit(OP_MATCH, 0, 0) return p } - diff --git a/runtime/native/regex_vm.ludic b/runtime/native/regex_vm.ludic index 29d0a38b..e64d2277 100644 --- a/runtime/native/regex_vm.ludic +++ b/runtime/native/regex_vm.ludic @@ -43,8 +43,8 @@ function rx_add(list: TList, pc: int, caps: words, sp: int, s: pointer, slen: in let t = list.n list.pc[t] = pc var i = 0 - while i < rx_nc { list.caps[t * rx_nc + i] = caps[i]; i = i + 1 } - list.n = list.n + 1 + while i < rx_nc { list.caps[t * rx_nc + i] = caps[i]; i += 1 } + list.n += 1 } # run prog over s (length slen) from startpos; returns caps words or null @@ -54,7 +54,7 @@ function rx_run(prog: Prog, s: pointer, slen: int, startpos: int) -> words { let ncode = prog.code.n / 3 rx_seen = words(ncode) var i = 0 - while i < ncode { rx_seen[i] = 0; i = i + 1 } + while i < ncode { rx_seen[i] = 0; i += 1 } rx_gen = 0 var clist = new TList clist.pc = words(ncode); clist.caps = words(ncode * rx_nc); clist.n = 0 @@ -63,29 +63,29 @@ function rx_run(prog: Prog, s: pointer, slen: int, startpos: int) -> words { let wcaps = words(rx_nc) var matched: words = null - rx_gen = rx_gen + 1 + rx_gen += 1 i = 0 - while i < rx_nc { wcaps[i] = 0 - 1; i = i + 1 } + while i < rx_nc { wcaps[i] = -1; i += 1 } rx_add(clist, 0, wcaps, startpos, s, slen) var sp = startpos while true { if clist.n == 0 { break } - var c = 0 - 1 + var c = -1 if sp < slen { c = s[sp] & 255 } nlist.n = 0 - rx_gen = rx_gen + 1 + rx_gen += 1 var ti = 0 var stop = false while ti < clist.n and not stop { let pc = clist.pc[ti] var k = 0 - while k < rx_nc { wcaps[k] = clist.caps[ti * rx_nc + k]; k = k + 1 } + while k < rx_nc { wcaps[k] = clist.caps[ti * rx_nc + k]; k += 1 } let op = rx_code[3 * pc] if op == OP_CHAR { if c >= 0 and c == rx_code[3 * pc + 1] { rx_add(nlist, pc + 1, wcaps, sp + 1, s, slen) } } else if op == OP_ANY { - if c >= 0 and c != 10 { rx_add(nlist, pc + 1, wcaps, sp + 1, s, slen) } + if c >= 0 and c != '\n' { rx_add(nlist, pc + 1, wcaps, sp + 1, s, slen) } } else if op == OP_ANYNL { if c >= 0 { rx_add(nlist, pc + 1, wcaps, sp + 1, s, slen) } } else if op == OP_CLASS { @@ -93,14 +93,14 @@ function rx_run(prog: Prog, s: pointer, slen: int, startpos: int) -> words { } else if op == OP_MATCH { if matched == null { matched = words(rx_nc) } k = 0 - while k < rx_nc { matched[k] = wcaps[k]; k = k + 1 } + while k < rx_nc { matched[k] = wcaps[k]; k += 1 } stop = true } - ti = ti + 1 + ti += 1 } let tmp = clist; clist = nlist; nlist = tmp if sp >= slen { break } - sp = sp + 1 + sp += 1 } return matched } @@ -143,11 +143,11 @@ function regex_next(str: pointer, re: Prog, from: int) -> Match { function regex_ok(m: Match) -> bool { return m != null } function regex_group_count(m: Match) -> int { if m == null { return 0 }; return m.ng } function regex_start(m: Match, n: int) -> int { - if m == null or n < 0 or n > m.ng { return 0 - 1 } + if m == null or n < 0 or n > m.ng { return -1 } return m.caps[2 * n] } function regex_end(m: Match, n: int) -> int { - if m == null or n < 0 or n > m.ng { return 0 - 1 } + if m == null or n < 0 or n > m.ng { return -1 } return m.caps[2 * n + 1] } function regex_group(m: Match, n: int) -> pointer { @@ -157,7 +157,7 @@ function regex_group(m: Match, n: int) -> pointer { if a < 0 or b < 0 { return "" } let out = bytes(b - a + 1) var i = 0 - while i < b - a { out[i] = m.str[a + i]; i = i + 1 } + while i < b - a { out[i] = m.str[a + i]; i += 1 } out[b - a] = 0 return out } @@ -167,7 +167,7 @@ function regex_valid(pattern: pointer) -> bool { return regex_compile(pattern) ! # repl expands \0..\9 (groups; \0 = whole match) and \\ (a literal backslash). function rx_append(out: IVec, s: pointer, a: int, b: int) -> void { var i = a - while i < b { iv_push(out, s[i] & 255); i = i + 1 } + while i < b { iv_push(out, s[i] & 255); i += 1 } } function regex_replace(str: pointer, pattern: pointer, repl: pointer) -> pointer { let p = regex_compile(pattern) @@ -186,16 +186,16 @@ function regex_replace(str: pointer, pattern: pointer, repl: pointer) -> pointer # expand replacement var i = 0 while i < rn { - if repl[i] == 92 and i + 1 < rn { + if repl[i] == '\\' and i + 1 < rn { let d = repl[i + 1] & 255 - if d >= 48 and d <= 57 { + if d >= '0' and d <= '9' { let g = d - 48 if g <= p.ngroups { let a = caps[2 * g]; let b = caps[2 * g + 1]; if a >= 0 and b >= 0 { rx_append(out, str, a, b) } } - i = i + 2 - } else if d == 92 { iv_push(out, 92); i = i + 2 } - else { iv_push(out, d); i = i + 2 } + i += 2 + } else if d == '\\' { iv_push(out, 92); i += 2 } + else { iv_push(out, d); i += 2 } } else { - iv_push(out, repl[i] & 255); i = i + 1 + iv_push(out, repl[i] & 255); i += 1 } } prev = me @@ -204,8 +204,7 @@ function regex_replace(str: pointer, pattern: pointer, repl: pointer) -> pointer rx_append(out, str, prev, n) # trailing text let res = bytes(out.n + 1) var i = 0 - while i < out.n { res[i] = out.d[i]; i = i + 1 } + while i < out.n { res[i] = out.d[i]; i += 1 } res[out.n] = 0 return res } - diff --git a/runtime/native/systems.ludic b/runtime/native/systems.ludic index 7c39a256..5d16aab3 100644 --- a/runtime/native/systems.ludic +++ b/runtime/native/systems.ludic @@ -60,7 +60,7 @@ function anim_clip(name: pointer, frames: int, fps: int, mode: int) -> void { anim_clip_frames[i] = frames; anim_clip_fps[i] = fps; anim_clip_mode[i] = mode return } - i = i + 1 + i += 1 } if anim_nclips >= ANIM_MAX_CLIPS { return } # silently ignore past capacity let s = anim_nclips @@ -68,7 +68,7 @@ function anim_clip(name: pointer, frames: int, fps: int, mode: int) -> void { anim_clip_frames[s] = frames anim_clip_fps[s] = fps anim_clip_mode[s] = mode - anim_nclips = anim_nclips + 1 + anim_nclips += 1 } function anim_clip_find(name: pointer) -> int { @@ -76,9 +76,9 @@ function anim_clip_find(name: pointer) -> int { var i = 0 while i < anim_nclips { if anim_clip_names[i] == name { return i } - i = i + 1 + i += 1 } - return 0 - 1 + return -1 } # ---- Anim.play / Anim.on_frame / Anim.fired (#48) -------------------------- diff --git a/runtime/native/systems_bounds.ludic b/runtime/native/systems_bounds.ludic index 784ab997..4b9f08d5 100644 --- a/runtime/native/systems_bounds.ludic +++ b/runtime/native/systems_bounds.ludic @@ -93,8 +93,8 @@ function esys_bounds() -> void { if y < by { y = by; hity = 1 } if y + h > y1 { y = y1 - h; hity = 1 } if pol == BND_BOUNCE { - if (hitx == 1) and (f_vx >= 0) { World.set(e, PBody, f_vx, 0 - World.get(e, PBody, f_vx)) } - if (hity == 1) and (f_vy >= 0) { World.set(e, PBody, f_vy, 0 - World.get(e, PBody, f_vy)) } + if (hitx == 1) and (f_vx >= 0) { World.set(e, PBody, f_vx, -World.get(e, PBody, f_vx)) } + if (hity == 1) and (f_vy >= 0) { World.set(e, PBody, f_vy, -World.get(e, PBody, f_vy)) } } } World.set(e, PP, fx, x) diff --git a/runtime/native/systems_light.ludic b/runtime/native/systems_light.ludic index bad2037b..705245b0 100644 --- a/runtime/native/systems_light.ludic +++ b/runtime/native/systems_light.ludic @@ -126,7 +126,7 @@ function esys_light2d() -> void { light_set_soft(soft) if lgf >= 0 { light_set_gel(World.get(e, pl, lgf)) } else { light_clear_gel() } - var spread = 0 - 1 + var spread = -1 if lsf >= 0 { spread = World.get(e, pl, lsf) } var direction = 0 if ldf >= 0 { direction = World.get(e, pl, ldf) } diff --git a/runtime/native/systems_move.ludic b/runtime/native/systems_move.ludic index 0fd4ce8b..95a2755b 100644 --- a/runtime/native/systems_move.ludic +++ b/runtime/native/systems_move.ludic @@ -60,18 +60,18 @@ const PHYS_ONE: int = 65536 # Q16.16 one whole pixel # ---- per-frame config + reflected ids (filled at the top of esys_move) ------- -var pm_pos: int = 0 - 1 # Position prop id -var pm_pos_x: int = 0 - 1 -var pm_pos_y: int = 0 - 1 -var pm_col: int = 0 - 1 # Collider prop id -var pm_c_w: int = 0 - 1 -var pm_c_h: int = 0 - 1 -var pm_c_offx: int = 0 - 1 -var pm_c_offy: int = 0 - 1 -var pm_c_trig: int = 0 - 1 -var pm_c_oneway: int = 0 - 1 -var pm_c_layer: int = 0 - 1 -var pm_c_mask: int = 0 - 1 +var pm_pos: int = -1 # Position prop id +var pm_pos_x: int = -1 +var pm_pos_y: int = -1 +var pm_col: int = -1 # Collider prop id +var pm_c_w: int = -1 +var pm_c_h: int = -1 +var pm_c_offx: int = -1 +var pm_c_offy: int = -1 +var pm_c_trig: int = -1 +var pm_c_oneway: int = -1 +var pm_c_layer: int = -1 +var pm_c_mask: int = -1 var phys_ts: int = 0 # tile size px (0 = grid off) var phys_wall: int = 0 # solid glyph var phys_wall2: int = 0 # optional second solid glyph (Solids.solid2), e.g. a closed door @@ -96,7 +96,7 @@ var phys_trig_prev: words = null function phys_floordiv(a: int, b: int) -> int { var q = a / b let r = a - q * b - if (r != 0) and ((a < 0) != (b < 0)) { q = q - 1 } + if (r != 0) and ((a < 0) != (b < 0)) { q -= 1 } return q } @@ -123,13 +123,13 @@ function phys_tile_oneway(c: int, r: int) -> bool { # is any full-solid tile present in column c over the row span [r0, r1]? function phys_col_solid(c: int, r0: int, r1: int) -> bool { var r = r0 - while r <= r1 { if phys_tile_solid(c, r) { return true }; r = r + 1 } + while r <= r1 { if phys_tile_solid(c, r) { return true }; r += 1 } return false } # is any full-solid tile present in row r over the column span [c0, c1]? function phys_row_solid(r: int, c0: int, c1: int) -> bool { var c = c0 - while c <= c1 { if phys_tile_solid(c, r) { return true }; c = c + 1 } + while c <= c1 { if phys_tile_solid(c, r) { return true }; c += 1 } return false } # is any full-OR-one-way tile present in row r over [c0, c1]? (downward landings) @@ -138,7 +138,7 @@ function phys_row_land(r: int, c0: int, c1: int) -> bool { while c <= c1 { if phys_tile_solid(c, r) { return true } if phys_tile_oneway(c, r) { return true } - c = c + 1 + c += 1 } return false } @@ -147,10 +147,10 @@ function phys_row_land(r: int, c0: int, c1: int) -> bool { # 0 mask reads as "all" (all-ones), so default-0 components still collide. function phys_match(la: int, ma: int, lb: int, mb: int) -> bool { var al = la; var bl = lb; var am = ma; var bm = mb - if al == 0 { al = 0 - 1 } - if bl == 0 { bl = 0 - 1 } - if am == 0 { am = 0 - 1 } - if bm == 0 { bm = 0 - 1 } + if al == 0 { al = -1 } + if bl == 0 { bl = -1 } + if am == 0 { am = -1 } + if bm == 0 { bm = -1 } if (am & bl) == 0 { return false } if (bm & al) == 0 { return false } return true @@ -223,7 +223,7 @@ function phys_clamp_x(self_e: int, px: int, py: int, w: int, h: int, dx: int) -> let allow = c * ts - (px + w) if allow < best { best = allow } c = endc + 1 # nearest wins; stop - } else { c = c + 1 } + } else { c += 1 } } } else { let startc = phys_floordiv(px, ts) @@ -234,7 +234,7 @@ function phys_clamp_x(self_e: int, px: int, py: int, w: int, h: int, dx: int) -> let allow = (c + 1) * ts - px if allow > best { best = allow } c = endc - 1 # nearest wins; stop - } else { c = c - 1 } + } else { c -= 1 } } } } @@ -305,7 +305,7 @@ function phys_clamp_y(self_e: int, px: int, py: int, w: int, h: int, dy: int) -> let allow = r * ts - (py + h) if allow < best { best = allow } r = endr + 1 - } else { r = r + 1 } + } else { r += 1 } } } else { let startr = phys_floordiv(py, ts) @@ -316,7 +316,7 @@ function phys_clamp_y(self_e: int, px: int, py: int, w: int, h: int, dy: int) -> let allow = (r + 1) * ts - py if allow > best { best = allow } r = endr - 1 - } else { r = r - 1 } + } else { r -= 1 } } } } @@ -429,7 +429,7 @@ function esys_move() -> void { var vy = 0; if f_vy >= 0 { vy = World.get(e, pb, f_vy) } var policy = 0; if f_pol >= 0 { policy = World.get(e, pb, f_pol) } if policy != 1 { - if f_grav >= 0 { vy = vy + World.get(e, pb, f_grav) } + if f_grav >= 0 { vy += World.get(e, pb, f_grav) } if f_maxf >= 0 { let mf = World.get(e, pb, f_maxf) if (mf > 0) and (vy > mf) { vy = mf } @@ -476,9 +476,9 @@ function esys_move() -> void { phys_set_y(e, phys_pos_y(e) + cdy) # derived flags + contact normal - if phys_hit_x == 1 { hit_wall = 1; vx = 0; if dx > 0 { nx = 0 - 1 } else { nx = 1 } } + if phys_hit_x == 1 { hit_wall = 1; vx = 0; if dx > 0 { nx = -1 } else { nx = 1 } } if phys_hit_up == 1 { hit_ceiling = 1; vy = 0; ny = 1 } - if phys_hit_down == 1 { vy = 0; ny = 0 - 1 } + if phys_hit_down == 1 { vy = 0; ny = -1 } let gy = phys_aabb_y(e) if phys_grounded(e, px, gy, w, h) { on_ground = 1 } # a body pressed onto the ground carries no downward velocity, whatever @@ -531,7 +531,7 @@ function esys_triggers() -> void { let tx = phys_aabb_x(t); let ty = phys_aabb_y(t) let tw = phys_c_int(t, pm_c_w); let th = phys_c_int(t, pm_c_h) let tl = phys_c_int(t, pm_c_layer); let tm = phys_c_int(t, pm_c_mask) - var cur = 0 - 1 + var cur = -1 var b = World.query_next(pm_col, 0) while b >= 0 { if b != t { diff --git a/runtime/native/systems_sprite.ludic b/runtime/native/systems_sprite.ludic index 932762e2..d8aa7ea5 100644 --- a/runtime/native/systems_sprite.ludic +++ b/runtime/native/systems_sprite.ludic @@ -57,17 +57,17 @@ function esys_sprite() -> void { let f_atlas = World.field_id(P, "atlas") let SA = World.prop_id("SpriteAnim") - var f_frame = 0 - 1 + var f_frame = -1 if SA >= 0 { f_frame = World.field_id(SA, "frame") } let f_move = World.field_id(P, "move_id") let f_face = World.field_id(P, "face") let f_flash = World.field_id(P, "flash") let f_blink = World.field_id(P, "blink") let TD = World.prop_id("TopDown") - var f_wx = 0 - 1; var f_wy = 0 - 1 + var f_wx = -1; var f_wy = -1 if TD >= 0 { f_wx = World.field_id(TD, "want_x"); f_wy = World.field_id(TD, "want_y") } let PB = World.prop_id("Body") - var f_vx = 0 - 1; var f_vy = 0 - 1 + var f_vx = -1; var f_vy = -1 if PB >= 0 { f_vx = World.field_id(PB, "vx"); f_vy = World.field_id(PB, "vy") } var e = World.query_next(P, 0) @@ -94,12 +94,12 @@ function esys_sprite() -> void { } # add the current animation frame when the entity also carries SpriteAnim. if (SA >= 0) and (f_frame >= 0) { - if World.has(e, SA) != 0 { id = id + World.get(e, SA, f_frame) } + if World.has(e, SA) != 0 { id += World.get(e, SA, f_frame) } } var x = spr_pos(e, 0) var y = spr_pos(e, 1) - if f_offx >= 0 { x = x + World.get(e, P, f_offx) } - if f_offy >= 0 { y = y + World.get(e, P, f_offy) } + if f_offx >= 0 { x += World.get(e, P, f_offx) } + if f_offy >= 0 { y += World.get(e, P, f_offy) } var sc = 1 if f_scale >= 0 { let sv = World.get(e, P, f_scale); if sv > 1 { sc = sv } } var flip = 0 diff --git a/runtime/native/systems_tileskin.ludic b/runtime/native/systems_tileskin.ludic index d79f37f8..f36c4d56 100644 --- a/runtime/native/systems_tileskin.ludic +++ b/runtime/native/systems_tileskin.ludic @@ -43,9 +43,9 @@ function esys_tileskin() -> void { if is_atlas != 0 { atlas_draw_ex(sprite, tx * size, ty * size, sc, 0, 0) } else { rt_draw_sprite_ex(sprite, tx * size, ty * size, sc, 0, 0) } } - tx = tx + 1 + tx += 1 } - ty = ty + 1 + ty += 1 } e = World.query_next(P, e + 1) } diff --git a/runtime/native/tiled.ludic b/runtime/native/tiled.ludic index 1d964790..1b0f481f 100644 --- a/runtime/native/tiled.ludic +++ b/runtime/native/tiled.ludic @@ -27,13 +27,13 @@ function tiled_csv_list(text: pointer) -> Val { var have = 0 while i < n { let c = text[i] - if c >= 48 and c <= 57 { cur = cur * 10 + (c - 48); have = 1 } + if c >= '0' and c <= '9' { cur = cur * 10 + (c - 48); have = 1 } else { - if c == 44 or c == 32 or c == 9 or c == 10 or c == 13 { + if c == ',' or c == ' ' or c == '\t' or c == '\n' or c == '\r' { if have == 1 { push(out.kids, value_int(cur)); cur = 0; have = 0 } } } - i = i + 1 + i += 1 } if have == 1 { push(out.kids, value_int(cur)) } return out @@ -59,7 +59,7 @@ function tiled_b64_list(text: pointer, compression: pointer, count: int) -> Val while i + 3 < rawlen { let g = raw[i] | (raw[i + 1] << 8) | (raw[i + 2] << 16) | (raw[i + 3] << 24) push(out.kids, value_int(g)) - i = i + 4 + i += 4 } return out } @@ -83,8 +83,8 @@ function tiled_chunked_layer(data: Xml, o: Val) -> void { # pass 1: bounds over every chunk (tile coordinates) var minx = 1000000000 var miny = 1000000000 - var maxx = 0 - 1000000000 - var maxy = 0 - 1000000000 + var maxx = -1000000000 + var maxy = -1000000000 var i = 0 while i < xml_child_count(data) { let ch = xml_child(data, i) @@ -96,13 +96,13 @@ function tiled_chunked_layer(data: Xml, o: Val) -> void { if cx + xml_attr_int(ch, "width", 0) > maxx { maxx = cx + xml_attr_int(ch, "width", 0) } if cy + xml_attr_int(ch, "height", 0) > maxy { maxy = cy + xml_attr_int(ch, "height", 0) } } - i = i + 1 + i += 1 } let W = maxx - minx let H = maxy - miny let gids = value_list() var k = 0 - while k < W * H { push(gids.kids, value_int(0)); k = k + 1 } + while k < W * H { push(gids.kids, value_int(0)); k += 1 } # pass 2: place each chunk's decoded data at its offset i = 0 while i < xml_child_count(data) { @@ -118,12 +118,12 @@ function tiled_chunked_layer(data: Xml, o: Val) -> void { var xx = 0 while xx < cw { gids.kids[(cy + yy) * W + (cx + xx)] = value_at(cdata, yy * cw + xx) - xx = xx + 1 + xx += 1 } - yy = yy + 1 + yy += 1 } } - i = i + 1 + i += 1 } value_put(o, "width", value_int(W)) value_put(o, "height", value_int(H)) @@ -152,7 +152,7 @@ function tmx_props_list(parent: Xml) -> Val { value_put(o, "value", value_str(v)) push(out.kids, o) } - i = i + 1 + i += 1 } return out } @@ -201,18 +201,18 @@ function tmx_points_list(s: pointer) -> Val { let n = len(s) var i = 0 while i < n { - while i < n and (s[i] == 32 or s[i] == 9) { i = i + 1 } + while i < n and (s[i] == ' ' or s[i] == '\t') { i += 1 } if i >= n { break } # read "x,y" var xv = 0; var xn = 0; var xs = 0 - if s[i] == 45 { xs = 1; i = i + 1 } - while i < n and s[i] >= 48 and s[i] <= 57 { xv = xv * 10 + (s[i] - 48); xn = 1; i = i + 1 } - if xs == 1 { xv = 0 - xv } - if i < n and s[i] == 44 { i = i + 1 } + if s[i] == '-' { xs = 1; i += 1 } + while i < n and s[i] >= '0' and s[i] <= '9' { xv = xv * 10 + (s[i] - 48); xn = 1; i += 1 } + if xs == 1 { xv = -xv } + if i < n and s[i] == ',' { i += 1 } var yv = 0; var ys = 0 - if i < n and s[i] == 45 { ys = 1; i = i + 1 } - while i < n and s[i] >= 48 and s[i] <= 57 { yv = yv * 10 + (s[i] - 48); i = i + 1 } - if ys == 1 { yv = 0 - yv } + if i < n and s[i] == '-' { ys = 1; i += 1 } + while i < n and s[i] >= '0' and s[i] <= '9' { yv = yv * 10 + (s[i] - 48); i += 1 } + if ys == 1 { yv = -yv } if xn == 1 { let o = value_object() value_put(o, "x", value_int(xv)) @@ -252,7 +252,7 @@ function tmx_tile_to_value(t: Xml) -> Val { value_put(f, "duration", value_int(xml_attr_int(fr, "duration", 0))) push(frames.kids, f) } - i = i + 1 + i += 1 } value_put(o, "animation", frames) } @@ -264,7 +264,7 @@ function tmx_tile_to_value(t: Xml) -> Val { while j < xml_child_count(og) { let ch = xml_child(og, j) if xml_tag(ch) == "object" { push(objs.kids, tmx_object_to_value(ch)) } - j = j + 1 + j += 1 } let ogo = value_object() value_put(ogo, "objects", objs) @@ -296,7 +296,7 @@ function tmx_fill_tileset(o: Val, ts: Xml) -> void { while i < xml_child_count(ts) { let ch = xml_child(ts, i) if xml_tag(ch) == "tile" { push(tiles.kids, tmx_tile_to_value(ch)) } - i = i + 1 + i += 1 } if len(tiles.kids) > 0 { value_put(o, "tiles", tiles) } } @@ -366,7 +366,7 @@ function tmx_objectlayer_to_value(el: Xml) -> Val { while i < xml_child_count(el) { let ch = xml_child(el, i) if xml_tag(ch) == "object" { push(objs.kids, tmx_object_to_value(ch)) } - i = i + 1 + i += 1 } value_put(o, "objects", objs) return o @@ -402,7 +402,7 @@ function tmx_to_value(root: Xml) -> Val { else { if tag == "objectgroup" { push(layers.kids, tmx_objectlayer_to_value(ch)) } else { if tag == "imagelayer" { push(layers.kids, tmx_imagelayer_to_value(ch)) } else { if tag == "group" { push(layers.kids, tmx_group_to_value(ch, mapw, maph)) } } } } } - i = i + 1 + i += 1 } let props = tmx_props_list(root) if len(props.kids) > 0 { value_put(m, "properties", props) } @@ -437,7 +437,7 @@ function tmx_group_to_value(el: Xml, mapw: int, maph: int) -> Val { else { if tag == "objectgroup" { push(layers.kids, tmx_objectlayer_to_value(ch)) } else { if tag == "imagelayer" { push(layers.kids, tmx_imagelayer_to_value(ch)) } else { if tag == "group" { push(layers.kids, tmx_group_to_value(ch, mapw, maph)) } } } } - i = i + 1 + i += 1 } value_put(o, "layers", layers) return o @@ -453,7 +453,7 @@ function tmj_normalize_layer(layer: Val) -> void { if ty == "group" { let ls = value_get(layer, "layers") var i = 0 - while i < value_count(ls) { tmj_normalize_layer(value_at(ls, i)); i = i + 1 } + while i < value_count(ls) { tmj_normalize_layer(value_at(ls, i)); i += 1 } return } if ty != "tilelayer" { return } @@ -484,8 +484,8 @@ function tmj_chunk_gids(chunk: Val, enc: pointer, comp: pointer, count: int) -> function tmj_flatten_chunks(layer: Val, chunks: Val, enc: pointer, comp: pointer) -> void { var minx = 1000000000 var miny = 1000000000 - var maxx = 0 - 1000000000 - var maxy = 0 - 1000000000 + var maxx = -1000000000 + var maxy = -1000000000 var i = 0 while i < value_count(chunks) { let c = value_at(chunks, i) @@ -495,13 +495,13 @@ function tmj_flatten_chunks(layer: Val, chunks: Val, enc: pointer, comp: pointer if cy < miny { miny = cy } if cx + value_as_int(value_get(c, "width")) > maxx { maxx = cx + value_as_int(value_get(c, "width")) } if cy + value_as_int(value_get(c, "height")) > maxy { maxy = cy + value_as_int(value_get(c, "height")) } - i = i + 1 + i += 1 } let W = maxx - minx let H = maxy - miny let gids = value_list() var k = 0 - while k < W * H { push(gids.kids, value_int(0)); k = k + 1 } + while k < W * H { push(gids.kids, value_int(0)); k += 1 } i = 0 while i < value_count(chunks) { let c = value_at(chunks, i) @@ -515,11 +515,11 @@ function tmj_flatten_chunks(layer: Val, chunks: Val, enc: pointer, comp: pointer var xx = 0 while xx < cw { gids.kids[(cy + yy) * W + (cx + xx)] = value_at(cdata, yy * cw + xx) - xx = xx + 1 + xx += 1 } - yy = yy + 1 + yy += 1 } - i = i + 1 + i += 1 } value_put(layer, "width", value_int(W)) value_put(layer, "height", value_int(H)) @@ -529,7 +529,7 @@ function tmj_flatten_chunks(layer: Val, chunks: Val, enc: pointer, comp: pointer function tmj_normalize(m: Val) -> Val { let ls = value_get(m, "layers") var i = 0 - while i < value_count(ls) { tmj_normalize_layer(value_at(ls, i)); i = i + 1 } + while i < value_count(ls) { tmj_normalize_layer(value_at(ls, i)); i += 1 } return m } @@ -540,7 +540,7 @@ function tiled_first_byte(s: pointer) -> int { let n = len(s) while i < n { let c = s[i] - if c == 32 or c == 9 or c == 10 or c == 13 { i = i + 1 } else { return c } + if c == ' ' or c == '\t' or c == '\n' or c == '\r' { i += 1 } else { return c } } return 0 } @@ -580,7 +580,7 @@ property TmTileset { spacing: int = 0 margin: int = 0 tilecount: int = 0 - imgid: int = 0 - 1 # loaded image handle (rt_image_load), -1 = none + imgid: int = -1 # loaded image handle (rt_image_load), -1 = none meta: Val # the tileset Value object (per-tile metadata) } @@ -590,7 +590,7 @@ property TmLayer { w: int = 0 h: int = 0 visible: int = 1 - imgid: int = 0 - 1 # loaded image handle (imagelayer only), -1 = none + imgid: int = -1 # loaded image handle (imagelayer only), -1 = none gids: []int # dense w*h GID array (tilelayer only) data: Val # the layer Value object (objects, image, …) } @@ -604,12 +604,12 @@ property Tmap { layers: []TmLayer tilesets: []TmTileset tree: Val # the source intermediate tree - coll: int = 0 - 1 # designated collision layer index, or -1 + coll: int = -1 # designated collision layer index, or -1 } # ---- GID resolver ---------------------------------------------------------- property GidInfo { - tileset: int = 0 - 1 # index into Tmap.tilesets (-1 = none/empty) + tileset: int = -1 # index into Tmap.tilesets (-1 = none/empty) local: int = 0 # local tile id within that tileset fh: int = 0 # horizontal flip fv: int = 0 # vertical flip @@ -622,7 +622,7 @@ property GidInfo { # whose firstgid is the greatest not exceeding it. gid == 0 is the empty cell. function tmap_resolve(m: Tmap, gid: int) -> GidInfo { let r = new GidInfo - if gid == 0 { r.empty = 1; r.tileset = 0 - 1; return r } + if gid == 0 { r.empty = 1; r.tileset = -1; return r } let H = 1 << 31 let V = 1 << 30 let D = 1 << 29 @@ -630,13 +630,13 @@ function tmap_resolve(m: Tmap, gid: int) -> GidInfo { if (gid & V) != 0 { r.fv = 1 } if (gid & D) != 0 { r.fd = 1 } let id = gid & 536870911 # low 29 bits = global tile id - var best = 0 - 1 + var best = -1 var bestfg = 0 var i = 0 while i < len(m.tilesets) { let fg = m.tilesets[i].firstgid if fg <= id and fg >= bestfg { bestfg = fg; best = i } - i = i + 1 + i += 1 } r.tileset = best if best >= 0 { r.local = id - m.tilesets[best].firstgid } @@ -678,7 +678,7 @@ function tmap_tile_meta(m: Tmap, gid: int) -> Val { while i < value_count(tiles) { let t = value_at(tiles, i) if value_as_int(value_get(t, "id")) == r.local { return t } - i = i + 1 + i += 1 } return value_null() } @@ -696,7 +696,7 @@ function tmap_tile_prop(m: Tmap, gid: int, name: pointer) -> int { if value_as_str(value_get(p, "value")) == "true" { return 1 } return 0 } - j = j + 1 + j += 1 } return 0 } @@ -750,14 +750,14 @@ function tmap_project_layer(m: Tmap, layer: int, whole_layer_solid: int) -> void if gid != 0 { var k = tmap_collision_kind(m, gid) if k == 0 and whole_layer_solid != 0 { k = 1 } # collision-layer fallback - if k == 1 { rt_map[y * 96 + x] = 35 } # '#' - if k == 2 { rt_map[y * 96 + x] = 61 } # '=' + if k == 1 { rt_map[y * 96 + x] = '#' } # '#' + if k == 2 { rt_map[y * 96 + x] = '=' } # '=' } } - x = x + 1 + x += 1 } } - y = y + 1 + y += 1 } } @@ -775,9 +775,9 @@ function tmap_find_collision(m: Tmap) -> int { while i < len(m.layers) { let n = m.layers[i].name if m.layers[i].kind == 0 and (n == "collision" or n == "solids" or n == "walls" or n == "Collision" or n == "Solids") { return i } - i = i + 1 + i += 1 } - return 0 - 1 + return -1 } # ---- rendering ------------------------------------------------------------- @@ -799,9 +799,9 @@ function tmap_blit_tile(imgid: int, sx: int, sy: int, tw: int, th: int, dx: int, if fv == 1 { v = th - 1 - v } let argb = s[(sy + v) * iw + (sx + u)] rt_blend_px(dx + i, dy + j, argb) - i = i + 1 + i += 1 } - j = j + 1 + j += 1 } } @@ -832,7 +832,7 @@ function tmap_gids_from_layer(lv: Val) -> []int { let out = new []int let data = value_get(lv, "data") var i = 0 - while i < value_count(data) { push(out, value_as_int(value_at(data, i))); i = i + 1 } + while i < value_count(data) { push(out, value_as_int(value_at(data, i))); i += 1 } return out } @@ -887,12 +887,12 @@ function tmap_build(tree: Val, basedir: pointer) -> Tmap { let img = value_as_str(value_get(tv, "image")) if img != "" { ts.imgid = rt_image_load(tiled_join(imgdir, img)) } push(m.tilesets, ts) - i = i + 1 + i += 1 } # layers (flat; groups' children are lifted so tile layers render/resolve) let ls = value_get(tree, "layers") i = 0 - while i < value_count(ls) { tmap_add_layer(m, value_at(ls, i)); i = i + 1 } + while i < value_count(ls) { tmap_add_layer(m, value_at(ls, i)); i += 1 } # image layers (#73): load each image relative to the map file i = 0 while i < len(m.layers) { @@ -900,7 +900,7 @@ function tmap_build(tree: Val, basedir: pointer) -> Tmap { let img = value_as_str(value_get(m.layers[i].data, "image")) if img != "" { m.layers[i].imgid = rt_image_load(tiled_join(basedir, img)) } } - i = i + 1 + i += 1 } # infinite map (#74): the header w/h are 0 — take the flattened layer bounds. if m.w <= 0 or m.h <= 0 { @@ -912,7 +912,7 @@ function tmap_build(tree: Val, basedir: pointer) -> Tmap { if m.layers[i].w > mw { mw = m.layers[i].w } if m.layers[i].h > mh { mh = m.layers[i].h } } - i = i + 1 + i += 1 } m.w = mw m.h = mh @@ -954,7 +954,7 @@ function tmap_add_layer(m: Tmap, lv: Val) -> void { l.kind = 3; push(m.layers, l) let sub = value_get(lv, "layers") var i = 0 - while i < value_count(sub) { tmap_add_layer(m, value_at(sub, i)); i = i + 1 } + while i < value_count(sub) { tmap_add_layer(m, value_at(sub, i)); i += 1 } return } push(m.layers, l) @@ -1005,7 +1005,7 @@ function tmap_frame_gid(m: Tmap, gid: int, frame: int) -> int { if nfr == 0 { return gid } var total = 0 var i = 0 - while i < nfr { total = total + value_as_int(value_get(value_at(anim, i), "duration")); i = i + 1 } + while i < nfr { total = total + value_as_int(value_get(value_at(anim, i), "duration")); i += 1 } if total <= 0 { return gid } let t_ms = (frame * 1000 / 60) % total var cur = value_as_int(value_get(value_at(anim, 0), "tileid")) @@ -1015,7 +1015,7 @@ function tmap_frame_gid(m: Tmap, gid: int, frame: int) -> int { let fr = value_at(anim, i) acc = acc + value_as_int(value_get(fr, "duration")) if t_ms < acc { cur = value_as_int(value_get(fr, "tileid")); i = nfr } - else { i = i + 1 } + else { i += 1 } } let ts = m.tilesets[r.tileset] return (ts.firstgid + cur) | tmap_flag_bits(gid) @@ -1049,9 +1049,9 @@ function tmap_draw_full(m: Tmap, camx: int, camy: int, frame: int, animate: int) # orientation transform places the cell (orthogonal / iso / hex / staggered) tmap_draw_gid(m, gid, tmap_cell_sx(m, x, y) + lox - camx, tmap_cell_sy(m, x, y) + loy - camy) } - x = x + 1 + x += 1 } - y = y + 1 + y += 1 } } if l.kind == 2 and l.visible != 0 { # image layer (parallax / repeat) @@ -1070,10 +1070,10 @@ function tmap_draw_full(m: Tmap, camx: int, camy: int, frame: int, animate: int) # Tiled anchors a tile object by its bottom-left corner tmap_draw_gid(m, g, ox - camx, oy - m.tileh - camy) } - oi = oi + 1 + oi += 1 } } - li = li + 1 + li += 1 } } @@ -1125,7 +1125,7 @@ function tiled_prop_node(container: Val, name: pointer) -> Val { while i < value_count(props) { let p = value_at(props, i) if value_as_str(value_get(p, "name")) == name { return p } - i = i + 1 + i += 1 } return value_null() } @@ -1201,12 +1201,12 @@ function tiled_load_types(path: pointer) -> int { value_put(o, "value", value_str(xml_attr(pr, "default"))) push(props.kids, o) } - j = j + 1 + j += 1 } value_put(tbl, xml_attr(ot, "name"), props) - n = n + 1 + n += 1 } - i = i + 1 + i += 1 } return n } @@ -1220,7 +1220,7 @@ function tiled_type_default(typename: pointer, propname: pointer) -> Val { while i < value_count(props) { let p = value_at(props, i) if value_as_str(value_get(p, "name")) == propname { return p } - i = i + 1 + i += 1 } return value_null() } @@ -1251,7 +1251,7 @@ function tiled_merge_template(inst: Val, tmpl: Val) -> void { while i < value_count(tmpl) { let k = value_key_at(tmpl, i) if value_has(inst, k) == 0 { value_put(inst, k, value_at(tmpl, i)) } - i = i + 1 + i += 1 } } @@ -1268,10 +1268,10 @@ function tmap_resolve_templates(m: Tmap, basedir: pointer) -> void { let ob = value_at(objs, oi) let tp = value_as_str(value_get(ob, "template")) if tp != "" { tiled_merge_template(ob, tiled_read_template(tiled_join(basedir, tp))) } - oi = oi + 1 + oi += 1 } } - li = li + 1 + li += 1 } } @@ -1330,9 +1330,9 @@ function tmap_draw_imagelayer(m: Tmap, l: TmLayer, camx: int, camy: int) -> void let repy = value_as_int(value_get(l.data, "repeaty")) # starting origin: for a repeating axis, back up to before the screen var sx0 = px - if repx != 0 { while sx0 > 0 { sx0 = sx0 - iw }; } + if repx != 0 { while sx0 > 0 { sx0 -= iw }; } var sy0 = py - if repy != 0 { while sy0 > 0 { sy0 = sy0 - ih }; } + if repy != 0 { while sy0 > 0 { sy0 -= ih }; } var yy = sy0 var first_y = 1 while (yy < rt_screen_h()) and (first_y == 1 or repy != 0) { @@ -1341,16 +1341,16 @@ function tmap_draw_imagelayer(m: Tmap, l: TmLayer, camx: int, camy: int) -> void while (xx < rt_screen_w()) and (first_x == 1 or repx != 0) { rt_draw_image(l.imgid, xx, yy) first_x = 0 - if repx == 0 { xx = rt_screen_w() } else { xx = xx + iw } + if repx == 0 { xx = rt_screen_w() } else { xx += iw } } first_y = 0 - if repy == 0 { yy = rt_screen_h() } else { yy = yy + ih } + if repy == 0 { yy = rt_screen_h() } else { yy += ih } } } # ---- image/group-layer accessors ------------------------------------------- function tmap_layer_kind(m: Tmap, layer: int) -> int { - if layer < 0 or layer >= len(m.layers) { return 0 - 1 } + if layer < 0 or layer >= len(m.layers) { return -1 } return m.layers[layer].kind } function tmap_layer_opacity(m: Tmap, layer: int) -> pointer { diff --git a/runtime/native/tiled_spawn.ludic b/runtime/native/tiled_spawn.ludic index a7da0d0b..cf100cbf 100644 --- a/runtime/native/tiled_spawn.ludic +++ b/runtime/native/tiled_spawn.ludic @@ -16,7 +16,7 @@ function tiled_apply_field(e: int, fname: pointer, v: int) -> void { let fid = world_field_id(pi, fname) if fid >= 0 { world_set(e, pi, fid, v) } } - pi = pi + 1 + pi += 1 } } @@ -26,7 +26,7 @@ function tiled_apply_field(e: int, fname: pointer, v: int) -> void { # unknown. Opt-in — the core load never calls this. function tiled_spawn_object(m: Tmap, obj: Val, model_name: pointer) -> int { let mid = world_model_id(model_name) - if mid < 0 { return 0 - 1 } + if mid < 0 { return -1 } let e = world_spawn(mid) let pp = world_prop_id("Position") if pp >= 0 and world_has(e, pp) == 1 { @@ -40,7 +40,7 @@ function tiled_spawn_object(m: Tmap, obj: Val, model_name: pointer) -> int { while i < value_count(props) { let p = value_at(props, i) tiled_apply_field(e, value_as_str(value_get(p, "name")), tiled_prop_int(obj, value_as_str(value_get(p, "name")))) - i = i + 1 + i += 1 } return e } @@ -50,6 +50,6 @@ function tiled_spawn_layer(m: Tmap, layer: int, model_name: pointer) -> int { var n = 0 let c = tmap_object_count(m, layer) var i = 0 - while i < c { if tiled_spawn_object(m, tmap_object(m, layer, i), model_name) >= 0 { n = n + 1 }; i = i + 1 } + while i < c { if tiled_spawn_object(m, tmap_object(m, layer, i), model_name) >= 0 { n += 1 }; i += 1 } return n } diff --git a/runtime/native/truetype.ludic b/runtime/native/truetype.ludic index bd732d90..2ac4c6f0 100644 --- a/runtime/native/truetype.ludic +++ b/runtime/native/truetype.ludic @@ -134,23 +134,23 @@ function tt_find_table(d: pointer, base: int, a: int, b: int, c: int, e: int) -> } } } - return 0 - 1 + return -1 } # pick the most capable Unicode subtable, as the C loader did function tt_pick_cmap(id: int, d: pointer, co: int) -> void { - tt_cmap[id] = 0 - 1 + tt_cmap[id] = -1 tt_cfmt[id] = 0 if co < 0 { return } let n = tt_u16(d, co + 2) - var best = 0 - 1 - var bestscore = 0 - 1 + var best = -1 + var bestscore = -1 for i in 0 .. n { let rec = co + 4 + i * 8 let plat = tt_u16(d, rec) let enc = tt_u16(d, rec + 2) let off = tt_u32(d, rec + 4) - var score = 0 - 1 + var score = -1 if plat == 0 { score = 2 } if plat == 0 { if enc == 4 { score = 4 } } if plat == 0 { if enc == 6 { score = 4 } } @@ -167,14 +167,14 @@ function tt_pick_cmap(id: int, d: pointer, co: int) -> void { } function rt_font_load(path: string) -> int { - if tt_n >= TT_MAX { return 0 - 1 } + if tt_n >= TT_MAX { return -1 } let d = rt_read_file(path) - if (d == null) { return 0 - 1 } + if (d == null) { return -1 } let size = rt_file_len var base = 0 # a .ttc collection points at its first font if size >= 16 { - if d[0] == 116 { if d[1] == 116 { if d[2] == 99 { if d[3] == 102 { + if d[0] == 't' { if d[1] == 't' { if d[2] == 'c' { if d[3] == 'f' { base = tt_u32(d, 12) } } } } } @@ -184,15 +184,15 @@ function rt_font_load(path: string) -> int { let loca = tt_find_table(d, base, 108, 111, 99, 97) let glyf = tt_find_table(d, base, 103, 108, 121, 102) let hmtx = tt_find_table(d, base, 104, 109, 116, 120) - if head < 0 { return 0 - 1 } - if maxp < 0 { return 0 - 1 } - if hhea < 0 { return 0 - 1 } - if loca < 0 { return 0 - 1 } - if glyf < 0 { return 0 - 1 } - if hmtx < 0 { return 0 - 1 } + if head < 0 { return -1 } + if maxp < 0 { return -1 } + if hhea < 0 { return -1 } + if loca < 0 { return -1 } + if glyf < 0 { return -1 } + if hmtx < 0 { return -1 } let id = tt_n - tt_n = tt_n + 1 + tt_n += 1 tt_data[id] = d tt_size[id] = size var upem = tt_u16(d, head + 18) @@ -275,7 +275,7 @@ function ol_pt(x: fixed, y: fixed, on: int) -> void { ol_x[ol_n] = x ol_y[ol_n] = y ol_on[ol_n] = on - ol_n = ol_n + 1 + ol_n += 1 } function tt_glyph_start(id: int, gid: int) -> int { @@ -314,15 +314,15 @@ function tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fix var i = 0 while i < npts { let fl = d[p] - p = p + 1 + p += 1 flags[i] = fl - i = i + 1 + i += 1 if (fl & 8) != 0 { # REPEAT var r = d[p] - p = p + 1 + p += 1 while r > 0 { - if i < npts { flags[i] = fl; i = i + 1 } - r = r - 1 + if i < npts { flags[i] = fl; i += 1 } + r -= 1 } } } @@ -334,10 +334,10 @@ function tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fix let fl = flags[k] if (fl & 2) != 0 { let dxv = d[p] - p = p + 1 - if (fl & 16) != 0 { xv = xv + dxv } else { xv = xv - dxv } + p += 1 + if (fl & 16) != 0 { xv += dxv } else { xv -= dxv } } else { - if (fl & 16) == 0 { xv = xv + tt_i16(d, p); p = p + 2 } + if (fl & 16) == 0 { xv += tt_i16(d, p); p += 2 } } xs[k] = xv } @@ -346,10 +346,10 @@ function tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fix let fl = flags[k] if (fl & 4) != 0 { let dyv = d[p] - p = p + 1 - if (fl & 32) != 0 { yv = yv + dyv } else { yv = yv - dyv } + p += 1 + if (fl & 32) != 0 { yv += dyv } else { yv -= dyv } } else { - if (fl & 32) == 0 { yv = yv + tt_i16(d, p); p = p + 2 } + if (fl & 32) == 0 { yv += tt_i16(d, p); p += 2 } } ys[k] = yv } @@ -364,7 +364,7 @@ function tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fix } if ol_ne < 256 { ol_ends[ol_ne] = ol_n - ol_ne = ol_ne + 1 + ol_ne += 1 } start = last + 1 } @@ -378,17 +378,17 @@ function tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fix while more == 1 { let flags = tt_u16(d, p) let cgid = tt_u16(d, p + 2) - p = p + 4 + p += 4 var arg1 = 0 var arg2 = 0 if (flags & 1) != 0 { arg1 = tt_i16(d, p) arg2 = tt_i16(d, p + 2) - p = p + 4 + p += 4 } else { arg1 = tt_i8(d, p) arg2 = tt_i8(d, p + 1) - p = p + 2 + p += 2 } var ca = 1.0 var cb = 0.0 @@ -397,19 +397,19 @@ function tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fix if (flags & 8) != 0 { ca = as_fixed((tt_i16(d, p) << 2)) # F2Dot14 -> Q16.16 ce = ca - p = p + 2 + p += 2 } if (flags & 64) != 0 { ca = as_fixed((tt_i16(d, p) << 2)) ce = as_fixed((tt_i16(d, p + 2) << 2)) - p = p + 4 + p += 4 } if (flags & 128) != 0 { ca = as_fixed((tt_i16(d, p) << 2)) cb = as_fixed((tt_i16(d, p + 2) << 2)) cc = as_fixed((tt_i16(d, p + 4) << 2)) ce = as_fixed((tt_i16(d, p + 6) << 2)) - p = p + 8 + p += 8 } var odx = dx var ody = dy diff --git a/runtime/native/truetype_raster.ludic b/runtime/native/truetype_raster.ludic index dbaaf943..cc5ffc39 100644 --- a/runtime/native/truetype_raster.ludic +++ b/runtime/native/truetype_raster.ludic @@ -8,7 +8,7 @@ function ed_add(x0: fixed, y0: fixed, x1: fixed, y1: fixed) -> void { ed_y0[ed_n] = y0 ed_x1[ed_n] = x1 ed_y1[ed_n] = y1 - ed_n = ed_n + 1 + ed_n += 1 } function tt_isqrt(v: int) -> int { @@ -18,7 +18,7 @@ function tt_isqrt(v: int) -> int { while b > 0 { let t = r + b if t * t <= v { r = t } - b = b / 2 + b /= 2 } return r } @@ -98,7 +98,7 @@ function tt_raster(id: int, gid: int, px: int) -> pointer { let end = ol_ends[ci] let cnt = end - start if cnt >= 2 { - var first_on = 0 - 1 + var first_on = -1 for i in 0 .. cnt { if first_on < 0 { if ol_on[start + i] == 1 { first_on = i } } } @@ -133,7 +133,7 @@ function tt_raster(id: int, gid: int, px: int) -> pointer { var ex = jx var ey = jy if ol_on[start + j] == 1 { - step = step + 1 + step += 1 } else { ex = (ix + jx) / 2 # implied on-curve midpoint ey = (iy + jy) / 2 @@ -142,7 +142,7 @@ function tt_raster(id: int, gid: int, px: int) -> pointer { curx = ex cury = ey } - step = step + 1 + step += 1 } ed_add(curx, cury, sx, sy) } @@ -167,8 +167,8 @@ function tt_raster(id: int, gid: int, px: int) -> pointer { if hit == 1 { let t = (yc - ya) / (yb - ya) sc_x[m] = ed_x0[i] + t * (ed_x1[i] - ed_x0[i]) - if yb > ya { sc_d[m] = 1 } else { sc_d[m] = 0 - 1 } - m = m + 1 + if yb > ya { sc_d[m] = 1 } else { sc_d[m] = -1 } + m += 1 } } # insertion sort the crossings by x @@ -181,12 +181,12 @@ function tt_raster(id: int, gid: int, px: int) -> pointer { if sc_x[j] > kx { sc_x[j + 1] = sc_x[j] sc_d[j + 1] = sc_d[j] - j = j - 1 + j -= 1 } else { sc_x[j + 1] = kx sc_d[j + 1] = kd placed = 1 - j = 0 - 1 + j = -1 } } if placed == 0 { @@ -197,7 +197,7 @@ function tt_raster(id: int, gid: int, px: int) -> pointer { var wind = 0 let oy = sy / TT_SS for i in 0 .. m - 1 { - wind = wind + sc_d[i] + wind += sc_d[i] if wind != 0 { var xa = sc_x[i] var xb = sc_x[i + 1] @@ -271,7 +271,7 @@ var u8_next: int = 0 # byte index just past the codepoint last decoded function tt_utf8(s: string, at: int) -> int { let c = s[at] - var extra = 0 - 1 + var extra = -1 if c < 128 { extra = 0 } if (c >> 5) == 6 { extra = 1 } if (c >> 4) == 14 { extra = 2 } @@ -342,11 +342,11 @@ function rt_text_ttf(font: int, x: int, y: int, s: string, colour: int, px: int) i = u8_next if cp == 10 { penx = x - baseline = baseline + lineh + baseline += lineh } else { let g = tt_glyph_get(font, cp, px) tt_blit(gc_bmp[g], gc_w[g], gc_h[g], penx + gc_ox[g], baseline - gc_oy[g], colour) - penx = penx + gc_adv[g] + penx += gc_adv[g] } } } @@ -365,7 +365,7 @@ function rt_text_w(font: int, s: string, px: int) -> int { if w > best { best = w } w = 0 } else { - w = w + gc_adv[tt_glyph_get(font, cp, px)] + w += gc_adv[tt_glyph_get(font, cp, px)] } } if w > best { best = w } diff --git a/runtime/native/tween.ludic b/runtime/native/tween.ludic index e4491a9f..2675ef78 100644 --- a/runtime/native/tween.ludic +++ b/runtime/native/tween.ludic @@ -60,15 +60,15 @@ function tw_alloc() -> int { var i = 0 while i < TW_MAX { if tw_used[i] == 0 { return i } - i = i + 1 + i += 1 } # none free: reuse the first finished handle so long-lived games don't leak. i = 0 while i < TW_MAX { if tw_done[i] != 0 { return i } - i = i + 1 + i += 1 } - return 0 - 1 + return -1 } # append one segment to a handle (internal). Silently ignored past TW_SEGS. @@ -88,7 +88,7 @@ function tw_push(h: int, kind: int, from: int, to: int, dur: int, ease: int) -> # start a new tween handle: from -> to over `dur` ticks with easing `ease`. function tween_to(from: int, to: int, dur: int, ease: int) -> int { let h = tw_alloc() - if h < 0 { return 0 - 1 } + if h < 0 { return -1 } tw_used[h] = 1 tw_seg[h] = 0 tw_nseg[h] = 0 @@ -187,7 +187,7 @@ function tw_advance_one(h: int) -> void { # (a delay segment holds tw_value unchanged.) if tick >= dur { # this segment finished: advance if kind == 0 { tw_value[h] = tw_to[s] } # rest exactly on the target - seg = seg + 1 + seg += 1 tw_seg[h] = seg tw_tick[h] = 0 if seg >= n { tw_done[h] = 1 } @@ -203,6 +203,6 @@ function esys_tween() -> void { var i = 0 while i < TW_MAX { if (tw_used[i] != 0) and (tw_done[i] == 0) { tw_advance_one(i) } - i = i + 1 + i += 1 } } diff --git a/runtime/native/ui.ludic b/runtime/native/ui.ludic index 97b16ebe..cf02fbdb 100644 --- a/runtime/native/ui.ludic +++ b/runtime/native/ui.ludic @@ -116,7 +116,7 @@ function rt_ui_reset(n: int) -> void { ui_n = n for i in 0 .. n { ui_type[i] = 0 - ui_parent[i] = 0 - 1 + ui_parent[i] = -1 ui_w[i] = 0 ui_h[i] = 0 ui_x[i] = 0 @@ -124,16 +124,16 @@ function rt_ui_reset(n: int) -> void { ui_haspos[i] = 0 ui_pad[i] = 0 ui_gap[i] = 0 - ui_bg[i] = 0 - 1 - ui_fg[i] = 0 - 1 - ui_border[i] = 0 - 1 - ui_align[i] = 0 - 1 + ui_bg[i] = -1 + ui_fg[i] = -1 + ui_border[i] = -1 + ui_align[i] = -1 ui_grow[i] = 0 - ui_font[i] = 0 - 1 + ui_font[i] = -1 ui_size[i] = 8 - ui_skin[i] = 0 - 1 + ui_skin[i] = -1 ui_inset[i] = 6 - ui_img[i] = 0 - 1 + ui_img[i] = -1 ui_focusable[i] = 0 ui_visible[i] = 1 ui_fired[i] = 0 @@ -197,7 +197,7 @@ function ui_tw(font: int, s: pointer, size: int) -> int { if font < tt_n { return rt_text_w(font, s, size) } } var n = 0 - while s[n] != 0 { n = n + 1 } + while s[n] != 0 { n += 1 } return n * 6 * max(size / 8, 1) } @@ -239,15 +239,15 @@ function ui_measure() -> void { let pad = ui_pad[i] var cw = 0 var ch = 0 - if t == WT_LABEL { cw = 0 - 1 } - if t == WT_BUTTON { cw = 0 - 1 } - if cw == 0 - 1 { + if t == WT_LABEL { cw = -1 } + if t == WT_BUTTON { cw = -1 } + if cw == -1 { let s = ui_str(i) cw = ui_tw(ui_font[i], s, ui_size[i]) + 2 * pad ch = ui_th(ui_font[i], ui_size[i]) + 2 * pad if t == WT_BUTTON { - cw = cw + 10 - ch = ch + 6 + cw += 10 + ch += 6 } } else { if t == WT_IMAGE { @@ -269,13 +269,13 @@ function ui_measure() -> void { if ui_parent[c] == i { if ui_visible[c] == 1 { if dir == 1 { - mainsz = mainsz + ui_rh[c] + mainsz += ui_rh[c] cross = max(cross, ui_rw[c]) } else { - mainsz = mainsz + ui_rw[c] + mainsz += ui_rw[c] cross = max(cross, ui_rh[c]) } - nc = nc + 1 + nc += 1 } } } @@ -299,7 +299,7 @@ function ui_measure() -> void { ui_rw[i] = rw ui_rh[i] = rh } - i = i - 1 + i -= 1 } } diff --git a/runtime/native/ui_draw.ludic b/runtime/native/ui_draw.ludic index a9242ea3..a4f84d3f 100644 --- a/runtime/native/ui_draw.ludic +++ b/runtime/native/ui_draw.ludic @@ -18,9 +18,9 @@ function ui_arrange(i: int, x: int, y: int) -> void { for c in 0 .. ui_n { if ui_parent[c] == i { if ui_visible[c] == 1 { - if dir == 1 { total = total + ui_rh[c] } else { total = total + ui_rw[c] } - ng = ng + 1 - grows = grows + ui_grow[c] + if dir == 1 { total += ui_rh[c] } else { total += ui_rw[c] } + ng += 1 + grows += ui_grow[c] } } } @@ -156,7 +156,7 @@ function ui_focusables() -> int { if ui_visible[i] == 1 { if ui_under(i, ui_active) { ui_fl[n] = i - n = n + 1 + n += 1 } } } @@ -169,12 +169,12 @@ function ui_focusables() -> int { event UiClicked { id: int = 0 } # Ui.close(): no menu is active (the same as opening root -1) -function rt_ui_close() -> void { rt_ui_open(0 - 1) } +function rt_ui_close() -> void { rt_ui_open(-1) } function rt_ui_open(root: int) -> void { ui_active = root let n = ui_focusables() - ui_focus = 0 - 1 + ui_focus = -1 if n > 0 { ui_focus = ui_fl[0] } } @@ -184,10 +184,10 @@ function rt_ui_tick(k: int) -> void { ui_layout() let n = ui_focusables() if n == 0 { - ui_focus = 0 - 1 + ui_focus = -1 return } - var cur = 0 - 1 + var cur = -1 for i in 0 .. n { if ui_fl[i] == ui_focus { cur = i } } @@ -195,18 +195,18 @@ function rt_ui_tick(k: int) -> void { cur = 0 ui_focus = ui_fl[0] } - if k == 119 { # 'w' + if k == 'w' { # 'w' cur = (cur - 1 + n) % n ui_focus = ui_fl[cur] } - if k == 115 { # 's' + if k == 's' { # 's' cur = (cur + 1) % n ui_focus = ui_fl[cur] } var fire = 0 - if k == 32 { fire = 1 } - if k == 10 { fire = 1 } - if k == 13 { fire = 1 } + if k == ' ' { fire = 1 } + if k == '\n' { fire = 1 } + if k == '\r' { fire = 1 } if fire == 1 { ui_fired[ui_focus] = 1; emit UiClicked(id: ui_focus) } } @@ -233,7 +233,7 @@ function rt_ui_set_text(id: int, s: string) -> void { if i >= 95 { ch = 0 } if ch != 0 { ui_dyn[base + i] = ch - i = i + 1 + i += 1 ch = s[i] } } @@ -248,27 +248,27 @@ function rt_ui_set_int(id: int, n: int) -> void { var at = 0 var v = n if v < 0 { - ui_dyn[base] = 45 + ui_dyn[base] = '-' at = 1 - v = 0 - v + v = -v } if v == 0 { - ui_dyn[base + at] = 48 - at = at + 1 + ui_dyn[base + at] = '0' + at += 1 } else { var digits = 0 var t = v while t > 0 { - digits = digits + 1 - t = t / 10 + digits += 1 + t /= 10 } var p = digits while p > 0 { var div = 1 - for k in 1 .. p { div = div * 10 } + for k in 1 .. p { div *= 10 } ui_dyn[base + at] = 48 + (v / div) % 10 - at = at + 1 - p = p - 1 + at += 1 + p -= 1 } } ui_dyn[base + at] = 0 diff --git a/runtime/native/value.ludic b/runtime/native/value.ludic index 057f59d9..879f045e 100644 --- a/runtime/native/value.ludic +++ b/runtime/native/value.ludic @@ -45,7 +45,7 @@ function value_object() -> Val { return value_new(6) } function value_add(list: Val, item: Val) -> Val { push(list.kids, item); return list } function value_put(obj: Val, key: pointer, item: Val) -> Val { var i = 0 - while i < len(obj.keys) { if obj.keys[i] == key { obj.kids[i] = item; return obj }; i = i + 1 } + while i < len(obj.keys) { if obj.keys[i] == key { obj.kids[i] = item; return obj }; i += 1 } push(obj.keys, key); push(obj.kids, item) return obj } @@ -65,12 +65,12 @@ function value_key_at(obj: Val, i: int) -> pointer { } function value_get(obj: Val, key: pointer) -> Val { var i = 0 - while i < len(obj.keys) { if obj.keys[i] == key { return obj.kids[i] }; i = i + 1 } + while i < len(obj.keys) { if obj.keys[i] == key { return obj.kids[i] }; i += 1 } return value_null() } function value_has(obj: Val, key: pointer) -> int { var i = 0 - while i < len(obj.keys) { if obj.keys[i] == key { return 1 }; i = i + 1 } + while i < len(obj.keys) { if obj.keys[i] == key { return 1 }; i += 1 } return 0 } @@ -82,11 +82,11 @@ function json_quote(s: pointer) -> pointer { let n = len(s) while i < n { let c = s[i] - if c == 34 { out = out + "\\\"" } - else { if c == 92 { out = out + "\\\\" } - else { if c == 10 { out = out + "\\n" } - else { out = out + s[i..i + 1] } } } - i = i + 1 + if c == '"' { out += "\\\"" } + else { if c == '\\' { out += "\\\\" } + else { if c == '\n' { out += "\\n" } + else { out += s[i..i + 1] } } } + i += 1 } return out + "\"" } @@ -99,14 +99,14 @@ function json_quote(s: pointer) -> pointer { function json_fixed_str(raw: int) -> pointer { var a = raw var sign = "" - if a < 0 { sign = "-"; a = 0 - a } + if a < 0 { sign = "-"; a = -a } let ip = a / 65536 var frac = a % 65536 if frac == 0 { return sign + string(ip) + ".0" } var fs = "" while frac != 0 { - frac = frac * 10 - fs = fs + string(frac / 65536) + frac *= 10 + fs += string(frac / 65536) frac = frac % 65536 } return sign + string(ip) + "." + fs @@ -122,18 +122,18 @@ function json_encode(v: Val) -> pointer { var out = "[" var i = 0 while i < len(v.kids) { - if i > 0 { out = out + "," } - out = out + json_encode(v.kids[i]) - i = i + 1 + if i > 0 { out += "," } + out += json_encode(v.kids[i]) + i += 1 } return out + "]" } var out = "{" var i = 0 while i < len(v.keys) { - if i > 0 { out = out + "," } + if i > 0 { out += "," } out = out + json_quote(v.keys[i]) + ":" + json_encode(v.kids[i]) - i = i + 1 + i += 1 } return out + "}" } @@ -147,7 +147,7 @@ property JP { s: pointer = null, i: int = 0, n: int = 0 } function jp_skip_ws(p: JP) -> void { while p.i < p.n { let c = p.s[p.i] - if c == 32 or c == 9 or c == 10 or c == 13 { p.i = p.i + 1 } + if c == ' ' or c == '\t' or c == '\n' or c == '\r' { p.i += 1 } else { return } } } @@ -162,33 +162,33 @@ function jp_value(p: JP) -> Val { jp_skip_ws(p) if p.i >= p.n { return value_null() } let c = p.s[p.i] - if c == 123 { return jp_object(p) } # '{' - if c == 91 { return jp_list(p) } # '[' - if c == 34 { return value_str(jp_string(p)) } # '"' - if c == 116 { p.i = p.i + 4; return value_bool(1) } # true - if c == 102 { p.i = p.i + 5; return value_bool(0) } # false - if c == 110 { p.i = p.i + 4; return value_null() } # null + if c == '{' { return jp_object(p) } # '{' + if c == '[' { return jp_list(p) } # '[' + if c == '"' { return value_str(jp_string(p)) } # '"' + if c == 't' { p.i += 4; return value_bool(1) } # true + if c == 'f' { p.i += 5; return value_bool(0) } # false + if c == 'n' { p.i += 4; return value_null() } # null return jp_number(p) } # read a quoted string (cursor on the opening quote) -> the unescaped contents. function jp_string(p: JP) -> pointer { - p.i = p.i + 1 # skip opening quote + p.i += 1 # skip opening quote var out = "" while p.i < p.n { let c = p.s[p.i] - if c == 34 { p.i = p.i + 1; return out } # closing quote - if c == 92 { # escape - p.i = p.i + 1 + if c == '"' { p.i += 1; return out } # closing quote + if c == '\\' { # escape + p.i += 1 if p.i < p.n { let e = p.s[p.i] - if e == 110 { out = out + "\n" } - else { out = out + p.s[p.i..p.i + 1] } # \" \\ \/ -> the literal char - p.i = p.i + 1 + if e == 'n' { out += "\n" } + else { out += p.s[p.i..p.i + 1] } # \" \\ \/ -> the literal char + p.i += 1 } } else { - out = out + p.s[p.i..p.i + 1] - p.i = p.i + 1 + out += p.s[p.i..p.i + 1] + p.i += 1 } } return out @@ -197,18 +197,18 @@ function jp_string(p: JP) -> pointer { # read a number; a '.' makes it a fixed node, otherwise an int node. function jp_number(p: JP) -> Val { var neg = 0 - if p.i < p.n and p.s[p.i] == 45 { neg = 1; p.i = p.i + 1 } # '-' + if p.i < p.n and p.s[p.i] == '-' { neg = 1; p.i += 1 } # '-' var ip = 0 - while p.i < p.n and p.s[p.i] >= 48 and p.s[p.i] <= 57 { + while p.i < p.n and p.s[p.i] >= '0' and p.s[p.i] <= '9' { ip = ip * 10 + (p.s[p.i] - 48) - p.i = p.i + 1 + p.i += 1 } - if p.i < p.n and p.s[p.i] == 46 { # '.', a fixed - p.i = p.i + 1 + if p.i < p.n and p.s[p.i] == '.' { # '.', a fixed + p.i += 1 let digits = new []int - while p.i < p.n and p.s[p.i] >= 48 and p.s[p.i] <= 57 { + while p.i < p.n and p.s[p.i] >= '0' and p.s[p.i] <= '9' { push(digits, p.s[p.i] - 48) - p.i = p.i + 1 + p.i += 1 } # exact inverse of json_fixed_str's generation: fold the digits back from the # last, frac_{i-1} = (d_i*65536 + frac_i)/10. Every intermediate stays < 2^16*10, @@ -218,49 +218,49 @@ function jp_number(p: JP) -> Val { var di = len(digits) - 1 while di >= 0 { frac = (digits[di] * 65536 + frac) / 10 - di = di - 1 + di -= 1 } var raw = ip * 65536 + frac - if neg != 0 { raw = 0 - raw } + if neg != 0 { raw = -raw } return value_fixed(raw) } - if neg != 0 { ip = 0 - ip } + if neg != 0 { ip = -ip } return value_int(ip) } function jp_list(p: JP) -> Val { let out = value_list() - p.i = p.i + 1 # '[' + p.i += 1 # '[' jp_skip_ws(p) - if p.i < p.n and p.s[p.i] == 93 { p.i = p.i + 1; return out } # empty ']' + if p.i < p.n and p.s[p.i] == ']' { p.i += 1; return out } # empty ']' while p.i < p.n { push(out.kids, jp_value(p)) jp_skip_ws(p) - if p.i < p.n and p.s[p.i] == 44 { p.i = p.i + 1; continue } # ',' + if p.i < p.n and p.s[p.i] == ',' { p.i += 1; continue } # ',' break } jp_skip_ws(p) - if p.i < p.n and p.s[p.i] == 93 { p.i = p.i + 1 } + if p.i < p.n and p.s[p.i] == ']' { p.i += 1 } return out } function jp_object(p: JP) -> Val { let out = value_object() - p.i = p.i + 1 # '{' + p.i += 1 # '{' jp_skip_ws(p) - if p.i < p.n and p.s[p.i] == 125 { p.i = p.i + 1; return out } # empty '}' + if p.i < p.n and p.s[p.i] == '}' { p.i += 1; return out } # empty '}' while p.i < p.n { jp_skip_ws(p) let key = jp_string(p) jp_skip_ws(p) - if p.i < p.n and p.s[p.i] == 58 { p.i = p.i + 1 } # ':' + if p.i < p.n and p.s[p.i] == ':' { p.i += 1 } # ':' push(out.keys, key) push(out.kids, jp_value(p)) jp_skip_ws(p) - if p.i < p.n and p.s[p.i] == 44 { p.i = p.i + 1; continue } # ',' + if p.i < p.n and p.s[p.i] == ',' { p.i += 1; continue } # ',' break } jp_skip_ws(p) - if p.i < p.n and p.s[p.i] == 125 { p.i = p.i + 1 } + if p.i < p.n and p.s[p.i] == '}' { p.i += 1 } return out } diff --git a/runtime/native/xml.ludic b/runtime/native/xml.ludic index a9c4810a..6b6886c3 100644 --- a/runtime/native/xml.ludic +++ b/runtime/native/xml.ludic @@ -44,12 +44,12 @@ function xml_child(n: Xml, i: int) -> Xml { function xml_attr_count(n: Xml) -> int { return len(n.akeys) } function xml_has(n: Xml, key: pointer) -> int { var i = 0 - while i < len(n.akeys) { if n.akeys[i] == key { return 1 }; i = i + 1 } + while i < len(n.akeys) { if n.akeys[i] == key { return 1 }; i += 1 } return 0 } function xml_attr(n: Xml, key: pointer) -> pointer { var i = 0 - while i < len(n.akeys) { if n.akeys[i] == key { return n.avals[i] }; i = i + 1 } + while i < len(n.akeys) { if n.akeys[i] == key { return n.avals[i] }; i += 1 } return "" } # attribute as an integer (decimal, optional leading '-'); `dflt` when absent. @@ -61,14 +61,14 @@ function xml_attr_int(n: Xml, key: pointer, dflt: int) -> int { # the first direct child named `tag`, or the synthetic empty node if none. function xml_find(n: Xml, tag: pointer) -> Xml { var i = 0 - while i < len(n.kids) { if n.kids[i].tag == tag { return n.kids[i] }; i = i + 1 } + while i < len(n.kids) { if n.kids[i].tag == tag { return n.kids[i] }; i += 1 } return xml_new("") } # count direct children named `tag`. function xml_count(n: Xml, tag: pointer) -> int { var c = 0 var i = 0 - while i < len(n.kids) { if n.kids[i].tag == tag { c = c + 1 }; i = i + 1 } + while i < len(n.kids) { if n.kids[i].tag == tag { c += 1 }; i += 1 } return c } @@ -77,13 +77,13 @@ function xml_atoi(s: pointer) -> int { var i = 0 let n = len(s) var neg = 0 - if i < n and s[i] == 45 { neg = 1; i = i + 1 } # '-' + if i < n and s[i] == '-' { neg = 1; i += 1 } # '-' var v = 0 - while i < n and s[i] >= 48 and s[i] <= 57 { + while i < n and s[i] >= '0' and s[i] <= '9' { v = v * 10 + (s[i] - 48) - i = i + 1 + i += 1 } - if neg != 0 { return 0 - v } + if neg != 0 { return -v } return v } @@ -97,41 +97,41 @@ function xml_unescape(s: pointer) -> pointer { var k = 0 let m = len(s) var amp = 0 - while k < m { if s[k] == 38 { amp = 1; k = m } else { k = k + 1 } } + while k < m { if s[k] == '&' { amp = 1; k = m } else { k += 1 } } if amp == 0 { return s } var out = "" var i = 0 while i < m { let c = s[i] - if c != 38 { # not '&' + if c != '&' { # not '&' # copy the run up to the next '&' in one slice var j = i - while j < m and s[j] != 38 { j = j + 1 } - out = out + s[i..j] + while j < m and s[j] != '&' { j += 1 } + out += s[i..j] i = j } else { # find the ';' var j = i + 1 - while j < m and s[j] != 59 { j = j + 1 } # ';' - if j >= m { out = out + s[i..m]; i = m } + while j < m and s[j] != ';' { j += 1 } # ';' + if j >= m { out += s[i..m]; i = m } else { let ent = s[i + 1..j] - if ent == "amp" { out = out + "&" } - else { if ent == "lt" { out = out + "<" } - else { if ent == "gt" { out = out + ">" } - else { if ent == "quot" { out = out + "\"" } - else { if ent == "apos" { out = out + "'" } + if ent == "amp" { out += "&" } + else { if ent == "lt" { out += "<" } + else { if ent == "gt" { out += ">" } + else { if ent == "quot" { out += "\"" } + else { if ent == "apos" { out += "'" } else { - if len(ent) >= 2 and ent[0] == 35 { # '#' numeric reference + if len(ent) >= 2 and ent[0] == '#' { # '#' numeric reference var code = 0 - if ent[1] == 120 or ent[1] == 88 { # '#x' hex + if ent[1] == 'x' or ent[1] == 'X' { # '#x' hex var h = 2 - while h < len(ent) { code = code * 16 + xml_hexval(ent[h]); h = h + 1 } + while h < len(ent) { code = code * 16 + xml_hexval(ent[h]); h += 1 } } else { var d = 1 - while d < len(ent) { code = code * 10 + (ent[d] - 48); d = d + 1 } + while d < len(ent) { code = code * 10 + (ent[d] - 48); d += 1 } } - out = out + xml_byte(code & 255) + out += xml_byte(code & 255) } else { out = out + "&" + ent + ";" # unknown entity, keep literal } @@ -144,9 +144,9 @@ function xml_unescape(s: pointer) -> pointer { } function xml_hexval(c: int) -> int { - if c >= 48 and c <= 57 { return c - 48 } - if c >= 97 and c <= 102 { return c - 87 } - if c >= 65 and c <= 70 { return c - 55 } + if c >= '0' and c <= '9' { return c - 48 } + if c >= 'a' and c <= 'f' { return c - 87 } + if c >= 'A' and c <= 'F' { return c - 55 } return 0 } @@ -158,7 +158,7 @@ function xml_byte(b: int) -> pointer { if xml_bytetab == null { let t = bytes(257) var i = 0 - while i < 256 { t[i] = i + 1; i = i + 1 } # table[i] = byte (i+1), so 0 never appears + while i < 256 { t[i] = i + 1; i += 1 } # table[i] = byte (i+1), so 0 never appears t[256] = 0 xml_bytetab = t } @@ -168,34 +168,34 @@ function xml_byte(b: int) -> pointer { # --- parser ----------------------------------------------------------------- property XP { s: pointer = null, i: int = 0, n: int = 0 } -function xp_ws(c: int) -> bool { return c == 32 or c == 9 or c == 10 or c == 13 } +function xp_ws(c: int) -> bool { return c == ' ' or c == '\t' or c == '\n' or c == '\r' } function xp_skip_ws(p: XP) -> void { - while p.i < p.n and xp_ws(p.s[p.i]) { p.i = p.i + 1 } + while p.i < p.n and xp_ws(p.s[p.i]) { p.i += 1 } } # skip a ``, `` or `` at the cursor. Returns true # if it consumed one (cursor on '<'). function xp_skip_misc(p: XP) -> bool { - if p.i + 1 >= p.n or p.s[p.i] != 60 { return false } # '<' + if p.i + 1 >= p.n or p.s[p.i] != '<' { return false } # '<' let c = p.s[p.i + 1] - if c == 63 { # '' - p.i = p.i + 2 - while p.i + 1 < p.n and not (p.s[p.i] == 63 and p.s[p.i + 1] == 62) { p.i = p.i + 1 } - p.i = p.i + 2 + if c == '?' { # '' + p.i += 2 + while p.i + 1 < p.n and not (p.s[p.i] == '?' and p.s[p.i + 1] == '>') { p.i += 1 } + p.i += 2 return true } - if c == 33 { # '') { p.i += 1 } + p.i += 3 return true } # '' or other declaration — skip to the matching '>' - p.i = p.i + 2 - while p.i < p.n and p.s[p.i] != 62 { p.i = p.i + 1 } - p.i = p.i + 1 + p.i += 2 + while p.i < p.n and p.s[p.i] != '>' { p.i += 1 } + p.i += 1 return true } return false @@ -206,8 +206,8 @@ function xp_name(p: XP) -> pointer { let start = p.i while p.i < p.n { let c = p.s[p.i] - let ok = (c >= 65 and c <= 90) or (c >= 97 and c <= 122) or (c >= 48 and c <= 57) - if ok or c == 95 or c == 45 or c == 58 or c == 46 { p.i = p.i + 1 } + let ok = (c >= 'A' and c <= 'Z') or (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') + if ok or c == '_' or c == '-' or c == ':' or c == '.' { p.i += 1 } else { break } } return p.s[start..p.i] @@ -219,21 +219,21 @@ function xp_attrs(p: XP, node: Xml) -> void { xp_skip_ws(p) if p.i >= p.n { return } let c = p.s[p.i] - if c == 62 or c == 47 or c == 63 { return } # '>' '/' '?' + if c == '>' or c == '/' or c == '?' { return } # '>' '/' '?' let key = xp_name(p) - if len(key) == 0 { p.i = p.i + 1; continue } # stray char, don't stall + if len(key) == 0 { p.i += 1; continue } # stray char, don't stall xp_skip_ws(p) var val = "" - if p.i < p.n and p.s[p.i] == 61 { # '=' - p.i = p.i + 1 + if p.i < p.n and p.s[p.i] == '=' { # '=' + p.i += 1 xp_skip_ws(p) - if p.i < p.n and (p.s[p.i] == 34 or p.s[p.i] == 39) { + if p.i < p.n and (p.s[p.i] == '"' or p.s[p.i] == '\'') { let q = p.s[p.i] - p.i = p.i + 1 + p.i += 1 let start = p.i - while p.i < p.n and p.s[p.i] != q { p.i = p.i + 1 } + while p.i < p.n and p.s[p.i] != q { p.i += 1 } val = xml_unescape(p.s[start..p.i]) - p.i = p.i + 1 # skip closing quote + p.i += 1 # skip closing quote } } push(node.akeys, key) @@ -243,34 +243,34 @@ function xp_attrs(p: XP, node: Xml) -> void { # parse one element (cursor on its opening '<'). Recurses for children. function xp_element(p: XP) -> Xml { - p.i = p.i + 1 # skip '<' + p.i += 1 # skip '<' let name = xp_name(p) let node = xml_new(name) xp_attrs(p, node) # self-closing '/>' - if p.i < p.n and p.s[p.i] == 47 { # '/' - p.i = p.i + 1 - if p.i < p.n and p.s[p.i] == 62 { p.i = p.i + 1 } # '>' + if p.i < p.n and p.s[p.i] == '/' { # '/' + p.i += 1 + if p.i < p.n and p.s[p.i] == '>' { p.i += 1 } # '>' return node } - if p.i < p.n and p.s[p.i] == 62 { p.i = p.i + 1 } # '>' + if p.i < p.n and p.s[p.i] == '>' { p.i += 1 } # '>' # content until the matching close tag while p.i < p.n { - if p.s[p.i] == 60 { # '<' - if p.i + 1 < p.n and p.s[p.i + 1] == 47 { # '' + while p.i < p.n and p.s[p.i] != '>' { p.i += 1 } + p.i += 1 # skip '>' return node } - if p.i + 3 < p.n and p.s[p.i + 1] == 33 and p.s[p.i + 2] == 91 { # ' - p.i = p.i + 9 # past "" + while p.i + 2 < p.n and not (p.s[p.i] == ']' and p.s[p.i + 1] == ']' and p.s[p.i + 2] == '>') { p.i += 1 } + node.text += p.s[start..p.i] + p.i += 3 # past "]]>" } else { if xp_skip_misc(p) { } # comment / PI inside content else { push(node.kids, xp_element(p)) } @@ -278,8 +278,8 @@ function xp_element(p: XP) -> Xml { } else { # character data run up to the next '<' let start = p.i - while p.i < p.n and p.s[p.i] != 60 { p.i = p.i + 1 } - node.text = node.text + xml_unescape(p.s[start..p.i]) + while p.i < p.n and p.s[p.i] != '<' { p.i += 1 } + node.text += xml_unescape(p.s[start..p.i]) } } return node @@ -292,10 +292,10 @@ function xml_parse(s: pointer) -> Xml { while p.i < p.n { xp_skip_ws(p) if p.i >= p.n { break } - if p.s[p.i] == 60 { # '<' + if p.s[p.i] == '<' { # '<' if xp_skip_misc(p) { } # prolog / comment / doctype else { return xp_element(p) } - } else { p.i = p.i + 1 } + } else { p.i += 1 } } return xml_new("") } diff --git a/runtime/native/zstd.ludic b/runtime/native/zstd.ludic index a0827c14..051075b7 100644 --- a/runtime/native/zstd.ludic +++ b/runtime/native/zstd.ludic @@ -28,9 +28,9 @@ function zf_read(n: int) -> int { while k < n { let b = (zf_src[zf_pos] >> zf_bit) & 1 v = v | (b << k) - zf_bit = zf_bit + 1 - if zf_bit == 8 { zf_bit = 0; zf_pos = zf_pos + 1 } - k = k + 1 + zf_bit += 1 + if zf_bit == 8 { zf_bit = 0; zf_pos += 1 } + k += 1 } return v } @@ -45,18 +45,18 @@ var zb_skip: int = 0 # padding bits above the sentinel in the last byt var zb_cur: int = 0 # data-bit index consumed so far function zstd_highbit(v: int) -> int { - var r = 0 - 1 + var r = -1 var x = v & 255 - while x > 0 { r = r + 1; x = x >> 1 } + while x > 0 { r += 1; x = x >> 1 } return r # position of the most-significant set bit (-1 if 0) } # init over stream bytes [s, s+L); the sentinel is the top set bit of the last. function zb_init(src: pointer, s: int, L: int) -> int { zb_src = src; zb_s = s; zb_L = L; zb_cur = 0 - if L <= 0 { return 0 - 1 } + if L <= 0 { return -1 } let hb = zstd_highbit(src[s + L - 1]) - if hb < 0 { return 0 - 1 } # a zero last byte is invalid + if hb < 0 { return -1 } # a zero last byte is invalid zb_skip = 8 - hb # the sentinel bit + anything above it is padding return 0 } @@ -65,7 +65,7 @@ function zb_bit() -> int { let j = zb_skip + zb_cur let byteidx = (zb_L - 1) - (j >> 3) let bit = 7 - (j & 7) - zb_cur = zb_cur + 1 + zb_cur += 1 if byteidx < 0 { return 0 } return (zb_src[zb_s + byteidx] >> bit) & 1 } @@ -73,7 +73,7 @@ function zb_bit() -> int { function zb_read(n: int) -> int { var v = 0 var k = 0 - while k < n { v = (v << 1) | zb_bit(); k = k + 1 } + while k < n { v = (v << 1) | zb_bit(); k += 1 } return v } function zb_total() -> int { return 8 * (zb_L - 1) + (8 - zb_skip) } # usable data bits @@ -101,14 +101,14 @@ function fse_build(norm: words, nsym: int, tableLog: int) -> FseDT { var highThreshold = size - 1 var s = 0 while s < nsym { - if norm[s] == (0 - 1) { + if norm[s] == (-1) { dt.sym[highThreshold] = s - highThreshold = highThreshold - 1 + highThreshold -= 1 symnext[s] = 1 } else { symnext[s] = norm[s] } - s = s + 1 + s += 1 } # spread the remaining symbols with the standard step let step = (size >> 1) + (size >> 3) + 3 @@ -122,21 +122,21 @@ function fse_build(norm: words, nsym: int, tableLog: int) -> FseDT { dt.sym[pos] = s pos = (pos + step) & mask while pos > highThreshold { pos = (pos + step) & mask } # skip the low-prob zone - i = i + 1 + i += 1 } } - s = s + 1 + s += 1 } # assign nbBits + newState for each cell var u = 0 while u < size { let sy = dt.sym[u] let nextState = symnext[sy] - symnext[sy] = symnext[sy] + 1 + symnext[sy] += 1 let nbits = tableLog - zstd_highbit32(nextState) dt.nb[u] = nbits dt.ns[u] = (nextState << nbits) - size - u = u + 1 + u += 1 } free(symnext) return dt @@ -144,9 +144,9 @@ function fse_build(norm: words, nsym: int, tableLog: int) -> FseDT { # highbit for a full 32-bit-ish value (nextState < size <= 2^tableLog) function zstd_highbit32(v: int) -> int { - var r = 0 - 1 + var r = -1 var x = v - while x > 0 { r = r + 1; x = x >> 1 } + while x > 0 { r += 1; x = x >> 1 } return r } @@ -167,11 +167,11 @@ function fse_read_ncount(norm: words, maxsym: int) -> int { var n0 = sym var rep = zf_read(2) while rep == 3 { - n0 = n0 + 3 + n0 += 3 rep = zf_read(2) } - n0 = n0 + rep - while sym < n0 { norm[sym] = 0; sym = sym + 1 } + n0 += rep + while sym < n0 { norm[sym] = 0; sym += 1 } prev0 = 0 } else { let maxv = (2 * threshold - 1) - remaining @@ -183,22 +183,22 @@ function fse_read_ncount(norm: words, maxsym: int) -> int { zf_skip(bitsLeft - 1) } else { count = zf_read(bitsLeft) - if count >= threshold { count = count - maxv } + if count >= threshold { count -= maxv } } let val = count - 1 # -1 means low-prob (stored as -1) norm[sym] = val - if val == (0 - 1) { remaining = remaining - 1 } - else { remaining = remaining - val } - sym = sym + 1 + if val == (-1) { remaining -= 1 } + else { remaining -= val } + sym += 1 if val == 0 { prev0 = 1 } # shrink the threshold as `remaining` falls while remaining < threshold { - bitsLeft = bitsLeft - 1 + bitsLeft -= 1 threshold = threshold >> 1 } } } - while sym <= maxsym { norm[sym] = 0; sym = sym + 1 } + while sym <= maxsym { norm[sym] = 0; sym += 1 } fse_ncount_n = sym return accLog } @@ -222,13 +222,13 @@ function fse_decompress(dt: FseDT, out: words, cap: int) -> int { # two states alternate; when a state-advance read overruns the stream, the # other state's residual symbol is the final one (FSE_decompress tail). while true { - out[n] = dt.sym[s1]; n = n + 1 + out[n] = dt.sym[s1]; n += 1 s1 = dt.ns[s1] + zb_read(dt.nb[s1]) - if zb_cur > zb_total() { out[n] = dt.sym[s2]; n = n + 1; return n } + if zb_cur > zb_total() { out[n] = dt.sym[s2]; n += 1; return n } if n >= cap { return n } - out[n] = dt.sym[s2]; n = n + 1 + out[n] = dt.sym[s2]; n += 1 s2 = dt.ns[s2] + zb_read(dt.nb[s2]) - if zb_cur > zb_total() { out[n] = dt.sym[s1]; n = n + 1; return n } + if zb_cur > zb_total() { out[n] = dt.sym[s1]; n += 1; return n } if n >= cap { return n } } return n @@ -245,7 +245,7 @@ property SeqDT { log: int = 0, base: words, addbits: words, nb: words, ns: words function zstd_lits(s: pointer) -> words { var n = 1 var i = 0 - while i < len(s) { if s[i] == 59 { n = n + 1 }; i = i + 1 } + while i < len(s) { if s[i] == ';' { n += 1 }; i += 1 } let a = words(n) var idx = 0 var cur = 0 @@ -253,11 +253,11 @@ function zstd_lits(s: pointer) -> words { i = 0 while i < len(s) { let c = s[i] - if c == 59 { if neg == 1 { cur = 0 - cur }; a[idx] = cur; idx = idx + 1; cur = 0; neg = 0 } - else { if c == 45 { neg = 1 } else { cur = cur * 10 + (c - 48) } } - i = i + 1 + if c == ';' { if neg == 1 { cur = -cur }; a[idx] = cur; idx += 1; cur = 0; neg = 0 } + else { if c == '-' { neg = 1 } else { cur = cur * 10 + (c - 48) } } + i += 1 } - if neg == 1 { cur = 0 - cur } + if neg == 1 { cur = -cur } a[idx] = cur return a } @@ -309,36 +309,35 @@ function zstd_seq_tables_init() -> void { if zstd_ll_base != null { return } let llb = words(36) var i = 0 - while i < 16 { llb[i] = i; i = i + 1 } - llb[16]=16; llb[17]=18; llb[18]=20; llb[19]=22; llb[20]=24; llb[21]=28 - llb[22]=32; llb[23]=40; llb[24]=48; llb[25]=64; llb[26]=128; llb[27]=256 - llb[28]=512; llb[29]=1024; llb[30]=2048; llb[31]=4096; llb[32]=8192 - llb[33]=16384; llb[34]=32768; llb[35]=65536 + while i < 16 { llb[i] = i; i += 1 } + llb[16] = 16; llb[17] = 18; llb[18] = 20; llb[19] = 22; llb[20] = 24; llb[21] = 28 + llb[22] = 32; llb[23] = 40; llb[24] = 48; llb[25] = 64; llb[26] = 128; llb[27] = 256 + llb[28] = 512; llb[29] = 1024; llb[30] = 2048; llb[31] = 4096; llb[32] = 8192 + llb[33] = 16384; llb[34] = 32768; llb[35] = 65536 let llx = words(36) i = 0 - while i < 16 { llx[i] = 0; i = i + 1 } - llx[16]=1; llx[17]=1; llx[18]=1; llx[19]=1; llx[20]=2; llx[21]=2 - llx[22]=3; llx[23]=3; llx[24]=4; llx[25]=6; llx[26]=7; llx[27]=8 - llx[28]=9; llx[29]=10; llx[30]=11; llx[31]=12; llx[32]=13; llx[33]=14 - llx[34]=15; llx[35]=16 + while i < 16 { llx[i] = 0; i += 1 } + llx[16] = 1; llx[17] = 1; llx[18] = 1; llx[19] = 1; llx[20] = 2; llx[21] = 2 + llx[22] = 3; llx[23] = 3; llx[24] = 4; llx[25] = 6; llx[26] = 7; llx[27] = 8 + llx[28] = 9; llx[29] = 10; llx[30] = 11; llx[31] = 12; llx[32] = 13; llx[33] = 14 + llx[34] = 15; llx[35] = 16 let mlb = words(53) i = 0 - while i < 32 { mlb[i] = i + 3; i = i + 1 } - mlb[32]=35; mlb[33]=37; mlb[34]=39; mlb[35]=41; mlb[36]=43; mlb[37]=47 - mlb[38]=51; mlb[39]=59; mlb[40]=67; mlb[41]=83; mlb[42]=99; mlb[43]=131 - mlb[44]=259; mlb[45]=515; mlb[46]=1027; mlb[47]=2051; mlb[48]=4099 - mlb[49]=8195; mlb[50]=16387; mlb[51]=32771; mlb[52]=65539 + while i < 32 { mlb[i] = i + 3; i += 1 } + mlb[32] = 35; mlb[33] = 37; mlb[34] = 39; mlb[35] = 41; mlb[36] = 43; mlb[37] = 47 + mlb[38] = 51; mlb[39] = 59; mlb[40] = 67; mlb[41] = 83; mlb[42] = 99; mlb[43] = 131 + mlb[44] = 259; mlb[45] = 515; mlb[46] = 1027; mlb[47] = 2051; mlb[48] = 4099 + mlb[49] = 8195; mlb[50] = 16387; mlb[51] = 32771; mlb[52] = 65539 let mlx = words(53) i = 0 - while i < 32 { mlx[i] = 0; i = i + 1 } - mlx[32]=1; mlx[33]=1; mlx[34]=1; mlx[35]=1; mlx[36]=2; mlx[37]=2 - mlx[38]=3; mlx[39]=3; mlx[40]=4; mlx[41]=4; mlx[42]=5; mlx[43]=7 - mlx[44]=8; mlx[45]=9; mlx[46]=10; mlx[47]=11; mlx[48]=12; mlx[49]=13 - mlx[50]=14; mlx[51]=15; mlx[52]=16 + while i < 32 { mlx[i] = 0; i += 1 } + mlx[32] = 1; mlx[33] = 1; mlx[34] = 1; mlx[35] = 1; mlx[36] = 2; mlx[37] = 2 + mlx[38] = 3; mlx[39] = 3; mlx[40] = 4; mlx[41] = 4; mlx[42] = 5; mlx[43] = 7 + mlx[44] = 8; mlx[45] = 9; mlx[46] = 10; mlx[47] = 11; mlx[48] = 12; mlx[49] = 13 + mlx[50] = 14; mlx[51] = 15; mlx[52] = 16 zstd_ll_base = llb; zstd_ll_bits = llx; zstd_ml_base = mlb; zstd_ml_bits = mlx } - # ---- Huffman literal decode ------------------------------------------------ property HufDT { maxbits: int = 0, sym: words, nb: words } @@ -347,7 +346,7 @@ property HufDT { maxbits: int = 0, sym: words, nb: words } function huf_build(weight: words, nweights: int) -> HufDT { var total = 0 var i = 0 - while i < nweights { if weight[i] > 0 { total = total + (1 << (weight[i] - 1)) }; i = i + 1 } + while i < nweights { if weight[i] > 0 { total = total + (1 << (weight[i] - 1)) }; i += 1 } let maxbits = zstd_highbit32(total) + 1 let left = (1 << maxbits) - total weight[nweights] = zstd_highbit32(left) + 1 # last symbol's weight @@ -360,13 +359,13 @@ function huf_build(weight: words, nweights: int) -> HufDT { # rank start positions: weight w occupies rankCount[w] << (w-1) cells, low weights first let rankcount = words(maxbits + 2) var w = 0 - while w <= maxbits { rankcount[w] = 0; w = w + 1 } + while w <= maxbits { rankcount[w] = 0; w += 1 } i = 0 - while i < nsym { rankcount[weight[i]] = rankcount[weight[i]] + 1; i = i + 1 } + while i < nsym { rankcount[weight[i]] = rankcount[weight[i]] + 1; i += 1 } let rankval = words(maxbits + 2) var next = 0 w = 1 - while w <= maxbits { rankval[w] = next; next = next + (rankcount[w] << (w - 1)); w = w + 1 } + while w <= maxbits { rankval[w] = next; next = next + (rankcount[w] << (w - 1)); w += 1 } i = 0 while i < nsym { let ww = weight[i] @@ -374,10 +373,10 @@ function huf_build(weight: words, nweights: int) -> HufDT { let len = 1 << (ww - 1) let nb = maxbits + 1 - ww var k = 0 - while k < len { dt.sym[rankval[ww] + k] = i; dt.nb[rankval[ww] + k] = nb; k = k + 1 } - rankval[ww] = rankval[ww] + len + while k < len { dt.sym[rankval[ww] + k] = i; dt.nb[rankval[ww] + k] = nb; k += 1 } + rankval[ww] += len } - i = i + 1 + i += 1 } free(rankcount); free(rankval) return dt @@ -387,7 +386,7 @@ function huf_build(weight: words, nweights: int) -> HufDT { # leaves zf_pos just past the description. function huf_read_tree() -> HufDT { let header = zf_src[zf_pos] - zf_pos = zf_pos + 1 + zf_pos += 1 let weight = words(256) if header >= 128 { # direct: (header-127) 4-bit weights let n = header - 127 @@ -397,7 +396,7 @@ function huf_read_tree() -> HufDT { var w = 0 if (i & 1) == 0 { w = zf_src[bpos] >> 4 } else { w = zf_src[bpos] & 15 } weight[i] = w - i = i + 1 + i += 1 } zf_pos = zf_pos + ((n + 1) >> 1) return huf_build(weight, n) @@ -423,8 +422,8 @@ function huf_decode_stream(dt: HufDT, out: pointer, at: int, n: int) -> void { while i < n { let bits = zstd_peek_rev(dt.maxbits) out[at + i] = dt.sym[bits] - zb_cur = zb_cur + dt.nb[bits] - i = i + 1 + zb_cur += dt.nb[bits] + i += 1 } } # peek maxbits bits (MSB-first) without consuming — for the Huffman table index. @@ -466,7 +465,7 @@ function zstd_lit_decode(src: pointer, pos: int, blockend: int) -> int { let buf = bytes(regen + 1) let b = src[pos + hdr] var i = 0 - while i < regen { buf[i] = b; i = i + 1 } + while i < regen { buf[i] = b; i += 1 } zstd_lit = buf zstd_litn = regen return pos + hdr + 1 @@ -507,7 +506,7 @@ function zstd_lit_huff(src: pointer, pos: int, ltype: int, sf: int) -> int { zf_init(src, hs) dt = huf_read_tree() let treesize = zf_bytepos() - hs - hs = hs + treesize + hs += treesize payn = comp - treesize zstd_huf_prev = dt } @@ -523,11 +522,11 @@ function zstd_lit_huff(src: pointer, pos: int, ltype: int, sf: int) -> int { let seg = (regen + 3) / 4 var o = hs + 6 zb_init(src, o, s1); huf_decode_stream(dt, buf, 0, seg) - o = o + s1 + o += s1 zb_init(src, o, s2); huf_decode_stream(dt, buf, seg, seg) - o = o + s2 + o += s2 zb_init(src, o, s3); huf_decode_stream(dt, buf, 2 * seg, seg) - o = o + s3 + o += s3 zb_init(src, o, s4); huf_decode_stream(dt, buf, 3 * seg, regen - 3 * seg) } return pos + hdr + comp @@ -572,7 +571,7 @@ function zstd_seq_table(src: pointer, sp: int, mode: int, kind: int, prev: SeqDT while u < size { dt.base[u] = zstd_seq_base(kind, ft.sym[u]) dt.addbits[u] = zstd_seq_bits(kind, ft.sym[u]) - u = u + 1 + u += 1 } return dt } @@ -595,17 +594,17 @@ function zstd_decomp_block(src: pointer, bstart: int, bsize: int, out: pointer, let blockend = bstart + bsize var sp = zstd_lit_decode(src, bstart, blockend) var nseq = src[sp] - if nseq < 128 { sp = sp + 1 } - else { if nseq < 255 { nseq = ((nseq - 128) << 8) + src[sp + 1]; sp = sp + 2 } - else { nseq = src[sp + 1] + (src[sp + 2] << 8) + 32512; sp = sp + 3 } } + if nseq < 128 { sp += 1 } + else { if nseq < 255 { nseq = ((nseq - 128) << 8) + src[sp + 1]; sp += 2 } + else { nseq = src[sp + 1] + (src[sp + 2] << 8) + 32512; sp += 3 } } var op = opos var litpos = 0 if nseq == 0 { var i = 0 - while i < zstd_litn { out[op] = zstd_lit[i]; op = op + 1; i = i + 1 } + while i < zstd_litn { out[op] = zstd_lit[i]; op += 1; i += 1 } return op } - let modes = src[sp]; sp = sp + 1 + let modes = src[sp]; sp += 1 let llmode = (modes >> 6) & 3 let ofmode = (modes >> 4) & 3 let mlmode = (modes >> 2) & 3 @@ -641,53 +640,52 @@ function zstd_decomp_block(src: pointer, bstart: int, bsize: int, out: pointer, if ov == 1 { temp = zstd_rep1 } else { if ov == 3 { temp = zstd_rep0 - 1 } else { if ov >= 2 { temp = zstd_rep2 } else { temp = zstd_rep0 } } } - if temp == 0 { temp = 0 - 1 } + if temp == 0 { temp = -1 } if ov == 1 { } else { zstd_rep2 = zstd_rep1 } zstd_rep1 = zstd_rep0 zstd_rep0 = temp offset = temp } } - if mlBits > 0 { matchLen = matchLen + zb_read(mlBits) } - if llBits > 0 { litLen = litLen + zb_read(llBits) } + if mlBits > 0 { matchLen += zb_read(mlBits) } + if llBits > 0 { litLen += zb_read(llBits) } var i = 0 - while i < litLen { out[op] = zstd_lit[litpos]; op = op + 1; litpos = litpos + 1; i = i + 1 } + while i < litLen { out[op] = zstd_lit[litpos]; op += 1; litpos += 1; i += 1 } var k = 0 - while k < matchLen { out[op] = out[op - offset]; op = op + 1; k = k + 1 } - q = q + 1 + while k < matchLen { out[op] = out[op - offset]; op += 1; k += 1 } + q += 1 if q < nseq { llstate = llt.ns[llstate] + zb_read(llt.nb[llstate]) mlstate = mlt.ns[mlstate] + zb_read(mlt.nb[mlstate]) ofstate = oft.ns[ofstate] + zb_read(oft.nb[ofstate]) } } - while litpos < zstd_litn { out[op] = zstd_lit[litpos]; op = op + 1; litpos = litpos + 1 } + while litpos < zstd_litn { out[op] = zstd_lit[litpos]; op += 1; litpos += 1 } return op } - # ---- frame / block loop ---------------------------------------------------- var zstd_err: int = 0 # decompress a single zstd frame. Returns bytes written, or -1. function z_zstd(src: pointer, len: int, out: pointer, cap: int) -> int { - if len < 6 { return 0 - 1 } - if src[0] != 40 { return 0 - 1 } # 0x28 - if src[1] != 181 { return 0 - 1 } # 0xB5 - if src[2] != 47 { return 0 - 1 } # 0x2F - if src[3] != 253 { return 0 - 1 } # 0xFD + if len < 6 { return -1 } + if src[0] != '(' { return -1 } # 0x28 + if src[1] != 181 { return -1 } # 0xB5 + if src[2] != '/' { return -1 } # 0x2F + if src[3] != 253 { return -1 } # 0xFD let fhd = src[4] let fcsFlag = (fhd >> 6) & 3 let single = (fhd >> 5) & 1 let dictFlag = fhd & 3 var pos = 5 - if single == 0 { pos = pos + 1 } # window descriptor - if dictFlag == 1 { pos = pos + 1 } - if dictFlag == 2 { pos = pos + 2 } - if dictFlag == 3 { pos = pos + 4 } - if fcsFlag == 0 { if single == 1 { pos = pos + 1 } } - if fcsFlag == 1 { pos = pos + 2 } - if fcsFlag == 2 { pos = pos + 4 } - if fcsFlag == 3 { pos = pos + 8 } + if single == 0 { pos += 1 } # window descriptor + if dictFlag == 1 { pos += 1 } + if dictFlag == 2 { pos += 2 } + if dictFlag == 3 { pos += 4 } + if fcsFlag == 0 { if single == 1 { pos += 1 } } + if fcsFlag == 1 { pos += 2 } + if fcsFlag == 2 { pos += 4 } + if fcsFlag == 3 { pos += 8 } # reset the repeat offsets per frame zstd_rep0 = 1; zstd_rep1 = 4; zstd_rep2 = 8 zstd_huf_prev = null @@ -695,27 +693,27 @@ function z_zstd(src: pointer, len: int, out: pointer, cap: int) -> int { var op = 0 var last = 0 while last == 0 { - if pos + 3 > len { return 0 - 1 } + if pos + 3 > len { return -1 } let bh = src[pos] | (src[pos + 1] << 8) | (src[pos + 2] << 16) - pos = pos + 3 + pos += 3 last = bh & 1 let btype = (bh >> 1) & 3 let bsize = bh >> 3 if btype == 0 { # raw block var i = 0 - while i < bsize { out[op] = src[pos + i]; op = op + 1; i = i + 1 } - pos = pos + bsize + while i < bsize { out[op] = src[pos + i]; op += 1; i += 1 } + pos += bsize } else { if btype == 1 { # RLE block: one byte * bsize let b = src[pos] var i = 0 - while i < bsize { out[op] = b; op = op + 1; i = i + 1 } - pos = pos + 1 + while i < bsize { out[op] = b; op += 1; i += 1 } + pos += 1 } else { if btype == 2 { # compressed block op = zstd_decomp_block(src, pos, bsize, out, op, cap) - pos = pos + bsize - } else { return 0 - 1 } } } # reserved - if op > cap { return 0 - 1 } - if zstd_err != 0 { return 0 - 1 } + pos += bsize + } else { return -1 } } } # reserved + if op > cap { return -1 } + if zstd_err != 0 { return -1 } } return op }