Skip to main content

ScanScratch

Struct ScanScratch 

Source
pub struct ScanScratch {
Show 22 fields pub radar: Vec<CastDat>, pub angstart: Vec<isize>, pub gscanptr: usize, pub sky_cur_lng: i32, pub sky_cur_dir: i32, pub sky_off: i32, pub lastx: Vec<i32>, pub uurend: Vec<i32>, pub uurend_half_stride: usize, pub cf: Vec<CfType>, pub gpz: [i32; 2], pub gdz: [i32; 2], pub gixy: [i32; 2], pub gxmax: i32, pub gi0: i32, pub gi1: i32, pub skycast: CastDat, pub fog_col: i32, pub foglut: Vec<i32>, pub gcsub: [i64; 9], pub sideshademode: bool, pub treat_z_max_as_air: bool,
}
Expand description

Scratch state the scan loops share between gline (the ray caster, R4.3) and hrend / vrend (the scanline rasterizers, in roxlap-core’s R5 SSE-recover companion).

In voxlap C this is several globals: a static radar buffer, castdat *angstart[MAXXDIM*4] pointers, gscanptr cursor, and the skycurlng / skycurdir sky-radar bookkeeping. The Rust port keeps them on a stack-allocatable struct so each render call owns its own scratch and the engine doesn’t have hidden mutable global state.

Fields§

§radar: Vec<CastDat>

All ray-cast hit records, written by gline calls and read indirectly by hrend / vrend via Self::angstart.

§angstart: Vec<isize>

Per-ray offset into Self::radar — voxlap stores this as a castdat* array and computes entries via gscanptr ± p0/p1, which can land before radar[0] (negative offset). The scanline rasterizers add a per-pixel plc value on top before the actual deref, and that combination is always in-range. We keep the raw signed offset here to mirror voxlap’s pointer arithmetic exactly.

§gscanptr: usize

Cursor into Self::radar for the next-to-be-written hit record. Reset to 0 at the start of each quadrant scan.

§sky_cur_lng: i32

Sky-radar bookkeeping cursor (skycurlng in voxlap). -1 when no sky pixel has been emitted yet.

§sky_cur_dir: i32

+1 or -1 — the sign of -giforzsgn that voxlap stamps on each new quadrant entry. The scan loops will set this; for now ScanScratch::new_for_size just initialises to 0.

§sky_off: i32

Voxlap’s skyoff — current row’s pixel-index offset into the sky texture (= sky_cur_lng * (sky.xsiz + 1), computed in gline’s per-ray frustum prep). 0 means the textured-sky path is inactive — phase_startsky falls back to solid-fill skycast. Set by gline when an crate::sky::Sky is loaded; reset to 0 each quadrant.

§lastx: Vec<i32>

Per-screen-row x-boundary, voxlap’s int32_t lastx[max(MAXYDIM, VSID)]. The right / left quadrants populate this during their pass-2 column walk; the vrend dispatch pass then reads lastx[sy] per row to know where each vertical slice begins.

§uurend: Vec<i32>

Per-screen-column ray-index pair, voxlap’s int32_t uurendmem[MAXXDIM*2 + 9] viewed as [uurend[sx], uurend[sx + MAXXDIM]]. The right / left quadrants stamp uurend[sx] = u and uurend[sx + MAXXDIM] = ui per column for the vertical rasterizer to consume.

§uurend_half_stride: usize

Stride between the uurend[sx] half and the uurend[sx + half_stride] half. Equals MAXXDIM in voxlap; our port sizes the buffer exactly to the framebuffer width rounded up.

§cf: Vec<CfType>

cf[129] — voxlap’s cfasm scratch. The seed slot at index CF_SEED_INDEX (= 128) is filled by gline before each ray; grouscan pops / pushes from there.

§gpz: [i32; 2]

gpz[2] — distance to next voxel-grid line per axis, PREC-scaled. Set by gline per ray; grouscan walks it.

§gdz: [i32; 2]

gdz[2] — per-column-step delta added to gpz after a column advance. Constant per ray. Set by gline.

§gixy: [i32; 2]

gixy[2] — voxel-column step in the ray’s direction (±1 along x, ±vsid along y). Set by gline.

§gxmax: i32

gxmax — scan-distance ceiling, PREC-scaled. Set by gline per ray (clipped against viewport edges and gmaxscandist).

§gi0: i32

gi0 — voxlap’s per-pixel x step coefficient written by gline; consumed by grouscan’s column advance.

§gi1: i32

gi1 — voxlap’s per-pixel y step coefficient.

§skycast: CastDat

Voxlap’s skycast — the (col, dist) pair grouscan’s startsky writes into every remaining radar slot when the solid-sky branch fires (textured sky is R4.4 work). The engine sets it via Self::set_skycast before invoking the rasterizer; default is opaque black at far depth.

§fog_col: i32

Fog colour (packed ARGB; the alpha byte isn’t used by the per-channel blend). Set by Self::set_fog.

§foglut: Vec<i32>

Fog distance falloff table. Empty = fog disabled (voxlap’s ofogdist < 0). Otherwise foglut[dist >> 20] & 32767 gives the per-pixel blend factor (0 = no fog applied, 32767 = full fog colour). Built by Self::set_fog.

§gcsub: [i64; 9]

Voxlap’s gcsub[9] per-side shading table. Default pattern is 0x00ff00ff00ff00ff per entry — that’s voxlap’s setsideshades(0,0,0,0,0,0) baseline (no per-side darkening). The high byte of entries 2..7 is the per-side intensity (top, bottom, left, right, up, down). Set via Self::set_side_shades; rasterizers read it on every gline call.

§sideshademode: bool

Voxlap’s vx5.sideshademode flag — derived by Self::set_side_shades: false when all six args are zero (oracle baseline, swap is dead), true otherwise. When true, the per-ray gline body picks gcsub[0]/gcsub[1] from gcsub[4..7] based on the sign of gixy[0]/gixy[1] so wall faces get directional darkening (voxlap5.c:1230-1234).

§treat_z_max_as_air: bool

S1.W: when true, draw phases that are about to read a voxel at z=MAXZDIM-1 (=255, voxlap’s bedrock z) bail to AfterDelete instead of writing it to the radar. The ray then column-steps past the bedrock until either an in-bounds slab fires or gxmax triggers Startsky — which in turn fills the radar with skycast (solid OR textured sky, depending on the SkyRef binding).

Why this exists: voxlap’s delslab clamps every carve’s y1 to MAXZDIM-1, so z=255 is ALWAYS solid post-pack regardless of what the dense grid says. For typical voxlap scenes that’s fine — terrain reaches the bottom and the “bedrock” voxel is hidden inside a multi-voxel slab. For thin-floor / sparse scenes (and ANY scene viewed from outside the XY footprint), the bedrock voxel is exposed and renders as whatever color it carries. Without an explicit color assignment that’s colfunc(x, y, 255) = 0 → BLACK pentagon under the world.

Default false to keep the 12 oracle hashes byte-identical; host enables it when the scene’s “below-the-world” expected to look like sky.

Implementations§

Source§

impl ScanScratch

Source

pub fn new_for_size(xres: u32, yres: u32, vsid: u32) -> Self

Allocate a scratch buffer sized for an xres × yres framebuffer. Voxlap’s per-frame radar buffer is MAXXDIM * 6 * 256 castdat entries (voxlap5.c:206-area declaration). Sized as xres * max(6*256, yres*2) — the yres*2 branch activates on HiDPI screens where per-quadrant radar consumption exceeds the classic 6*256 per-column budget due to corner-cut fan expansion at steep camera angles. uurend / lastx are sized to fit xres / max(yres, vsid) entries respectively (R4.1f4b consumers).

Source

pub fn set_side_shades( &mut self, top: i8, bot: i8, left: i8, right: i8, up: i8, down: i8, )

Engine-side setter for per-side shading intensities, mirror of voxlap’s setsideshades(top, bot, left, right, up, down) (voxlap5.c). Each i8 parameter is the high byte stamped onto gcsub[2..7]; the low 7 bytes keep the 0x00ff00ff00ff00ff saturate-zero pattern. Pass (0,…,0) to disable shading (the default), or moderate positive values (15..31) for visible side darkening like voxlap’s classic games use.

Source

pub fn set_skycast(&mut self, col: i32, dist: i32)

Engine-side setter for the sky (col, dist) pair. Engine owns Engine::sky_color; this is the wire it writes to so grouscan’s startsky has the right value at fill time.

Source

pub fn set_fog(&mut self, col: i32, max_scan_dist: i32)

Engine-side setter for fog. Voxlap5.c:11151-11185. max_scan_dist <= 0 disables fog (clears the table). Otherwise builds the 2048-entry fog falloff table: foglut[k] = (acc >> 16) & 32767 where acc accumulates step = i32::MAX / max_scan_dist per entry. After the accumulation overflows, remaining entries pad with 32767 (full fog).

Source

pub fn reset_for_quadrant(&mut self, sky_cur_dir: i32)

Reset cursors at the start of a new quadrant scan.

Trait Implementations§

Source§

impl Clone for ScanScratch

Source§

fn clone(&self) -> ScanScratch

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ScanScratch

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.