refactor(runtime,packages,examples): named constants, package enums, idiom sweep

- runtime: HEADLESS_FRAME_PATH, STICK_DEADZONE / STICK_LEFT_X/Y, key and
  byte codes as char literals throughout (`k == 'w'`, `fill(rt_map, ' ', …)`)
- ludic.gameplay/stats: drop the duplicate `stat_field` (it answered "atk"
  for every build stat); Stats.base uses stats_field_name
- ludic.shooter: compare aim modes and fire patterns with AimMode.* and
  WeaponPattern.* instead of raw ints; STICK_RIGHT_X/Y
- ludic.npcai: DecisionMade / brain_set_state use AiState.*
- examples/games/menu.ludic uses Font.load / Ui.* with FONT_PATH and
  BACKDROP named; strings.ludic header says what it prints
- whole tree: `x = x + 1` → `x += 1` (single-term right-hand sides only),
  `0 - x` → `-x`, ASCII codes → char literals; every .ludic and every
  ```ludic fence reformatted with the fixed formatter (whitespace only)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-05 01:12:26 +03:00
parent e3e1bc7784
commit bf36bc8a8f
103 changed files with 1256 additions and 1252 deletions

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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]

View file

@ -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]
}
}

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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 <char> <rrggbb>"
if c0 == 'p' { # 'p' — "pal <char> <rrggbb>"
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
}
}
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -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 {

View file

@ -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
}

View file

@ -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<name> (captured, name ignored for now)
else if d == 60 { rx_skip_name() } # (?<name>
if d == ':' { rx_adv() } # (?: non-capturing
else if d == 'P' { rx_adv(); rx_skip_name() } # (?P<name> (captured, name ignored for now)
else if d == '<' { rx_skip_name() } # (?<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
}

View file

@ -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
}

View file

@ -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) --------------------------

View file

@ -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)

View file

@ -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) }

View file

@ -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 {

View file

@ -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

View file

@ -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)
}

View file

@ -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 <imagelayer> 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 {

View file

@ -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
}

View file

@ -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

View file

@ -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 }

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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

View file

@ -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
}

View file

@ -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 `<!DOCTYPE ...>` 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 { # '<!'
if p.i + 3 < p.n and p.s[p.i + 2] == 45 and p.s[p.i + 3] == 45 { # '<!--' comment
p.i = p.i + 4
while p.i + 2 < p.n and not (p.s[p.i] == 45 and p.s[p.i + 1] == 45 and p.s[p.i + 2] == 62) { p.i = p.i + 1 }
p.i = p.i + 3
if c == '!' { # '<!'
if p.i + 3 < p.n and p.s[p.i + 2] == '-' and p.s[p.i + 3] == '-' { # '<!--' comment
p.i += 4
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 }
p.i += 3
return true
}
# '<!DOCTYPE ...>' 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 { # '</' close
p.i = p.i + 2
if p.s[p.i] == '<' { # '<'
if p.i + 1 < p.n and p.s[p.i + 1] == '/' { # '</' close
p.i += 2
let cn = xp_name(p)
while p.i < p.n and p.s[p.i] != 62 { p.i = p.i + 1 }
p.i = p.i + 1 # skip '>'
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 { # '<![' CDATA
if p.i + 3 < p.n and p.s[p.i + 1] == '!' and p.s[p.i + 2] == '[' { # '<![' CDATA
# <![CDATA[ ... ]]>
p.i = p.i + 9 # past "<![CDATA["
p.i += 9 # past "<![CDATA["
let start = p.i
while p.i + 2 < p.n and not (p.s[p.i] == 93 and p.s[p.i + 1] == 93 and p.s[p.i + 2] == 62) { p.i = p.i + 1 }
node.text = node.text + p.s[start..p.i]
p.i = p.i + 3 # 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("")
}

View file

@ -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
}