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