59 lines
2.8 KiB
Text
59 lines
2.8 KiB
Text
# terrain_height_file.ludic — the file scratch the terrain's questions read a tile through when it is not
|
|
# resident (ter_h, ter_o), so a question never takes a slot: who asks and in what order leaves the cache
|
|
# as the loaders put it. terrain_height_file stays as the name callers wrote against; it is terrain_height.
|
|
const TF_KEEP: int = 4 # tiles the scratch keeps: a texel square at a corner spans four
|
|
|
|
export function terrain_height_file(render3d_st: mut Render3dState, x: float, z: float) -> float { return terrain_height(render3d_st, x, z) }
|
|
|
|
# the scratch entry holding tile t's heights, read from the file (as tt_decode reads them) when none does
|
|
function tf_entry(render3d_st: mut Render3dState, t: int) -> int {
|
|
for e in 0 .. TF_KEEP { if render3d_st.tf_tile[e] == t + 1 { return e } }
|
|
let e = render3d_st.tf_next
|
|
render3d_st.tf_next = (e + 1) % TF_KEEP
|
|
let n2 = TT_TEX * TT_TEX
|
|
let raw = render3d_st.tf_raw
|
|
file_seek(render3d_st.tt_file, render3d_st.tt_hoff + t * n2 * 2, 0)
|
|
file_read(render3d_st.tt_file, data_of(raw), n2 * 2)
|
|
let lo = render3d_st.tt_tab[t * 2]
|
|
let step = render3d_st.tt_tab[t * 2 + 1]
|
|
for i in 0 .. n2 { render3d_st.tf_h[e * n2 + i] = lo + float(raw[i * 2] | (raw[i * 2 + 1] << 8)) * step }
|
|
render3d_st.tf_tile[e] = t + 1
|
|
return e
|
|
}
|
|
|
|
# ... and of its photograph (the scratch sized to the map's tiles when they were opened, tf_size)
|
|
function tfo_entry(render3d_st: mut Render3dState, t: int) -> int {
|
|
for e in 0 .. TF_KEEP { if render3d_st.tfo_tile[e] == t + 1 { return e } }
|
|
let e = render3d_st.tfo_next
|
|
render3d_st.tfo_next = (e + 1) % TF_KEEP
|
|
let o2 = render3d_st.tt_oside * render3d_st.tt_oside
|
|
let raw = render3d_st.tf_raw
|
|
file_seek(render3d_st.tt_file, render3d_st.tt_ooff + t * o2 * 3, 0)
|
|
file_read(render3d_st.tt_file, data_of(raw), o2 * 3)
|
|
for i in 0 .. o2 { render3d_st.tfo_px[e * o2 + i] = (raw[i * 3] << 16) | (raw[i * 3 + 1] << 8) | raw[i * 3 + 2] }
|
|
render3d_st.tfo_tile[e] = t + 1
|
|
return e
|
|
}
|
|
|
|
# the photograph's scratch and the read buffer made for `side` texels a tile, once a size
|
|
@alloc_ok("a map being loaded: the questions' photograph scratch, once a size")
|
|
function tf_size(render3d_st: mut Render3dState, side: int) -> void {
|
|
if len(render3d_st.tfo_px) < TF_KEEP * side * side {
|
|
free(render3d_st.tfo_px)
|
|
render3d_st.tfo_px = words(TF_KEEP * side * side)
|
|
}
|
|
if len(render3d_st.tf_raw) < side * side * 3 {
|
|
free(render3d_st.tf_raw)
|
|
render3d_st.tf_raw = buffer(side * side * 3)
|
|
}
|
|
}
|
|
|
|
# the scratch forgotten: the tiles' file closed or replaced (another map's tile t is another tile)
|
|
function tf_forget(render3d_st: mut Render3dState) -> void {
|
|
for e in 0 .. TF_KEEP {
|
|
render3d_st.tf_tile[e] = 0
|
|
render3d_st.tfo_tile[e] = 0
|
|
}
|
|
render3d_st.tf_next = 0
|
|
render3d_st.tfo_next = 0
|
|
}
|