pub struct ScanScratch {Show 21 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,
}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: usizeCursor into Self::radar for the next-to-be-written hit
record. Reset to 0 at the start of each quadrant scan.
sky_cur_lng: i32Sky-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: i32Voxlap’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: usizeStride 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: i32gxmax — scan-distance ceiling, PREC-scaled. Set by gline
per ray (clipped against viewport edges and gmaxscandist).
gi0: i32gi0 — voxlap’s per-pixel x step coefficient written by
gline; consumed by grouscan’s column advance.
gi1: i32gi1 — voxlap’s per-pixel y step coefficient.
skycast: CastDatVoxlap’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: i32Fog 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: boolVoxlap’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).
Implementations§
Source§impl ScanScratch
impl ScanScratch
Sourcepub fn new_for_size(xres: u32, yres: u32, vsid: u32) -> Self
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).
Sourcepub fn set_side_shades(
&mut self,
top: i8,
bot: i8,
left: i8,
right: i8,
up: i8,
down: i8,
)
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.
Sourcepub fn set_skycast(&mut self, col: i32, dist: i32)
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.
Sourcepub fn set_fog(&mut self, col: i32, max_scan_dist: i32)
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).
Sourcepub fn reset_for_quadrant(&mut self, sky_cur_dir: i32)
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
impl Clone for ScanScratch
Source§fn clone(&self) -> ScanScratch
fn clone(&self) -> ScanScratch
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for ScanScratch
impl RefUnwindSafe for ScanScratch
impl Send for ScanScratch
impl Sync for ScanScratch
impl Unpin for ScanScratch
impl UnsafeUnpin for ScanScratch
impl UnwindSafe for ScanScratch
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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