@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
74 lines (67 loc) • 1.93 kB
JavaScript
/**
* 32-bit modular sequence arithmetic.
*
* Mirrors {@link ./seq16.js} but in a 32-bit modular space (wraps at 2^32).
* Use this when 16 bits are not enough headroom — e.g. for frame counters that
* tick at 60+ Hz over many hours, where 16 bits (~18 minutes) wraps too quickly
* for safe comparison even with the half-range rule.
*
* All functions are pure.
*
* @author Alex Goldring
* @copyright Company Named Limited (c) 2025
*/
/**
* @type {number}
*/
export const SEQ32_MAX = 0xFFFFFFFF;
/**
* Modular range as a Number. 2^32 is exactly representable as a Number.
* @type {number}
*/
export const SEQ32_RANGE = 0x100000000;
/**
* @type {number}
*/
export const SEQ32_HALF_RANGE = 0x80000000;
/**
* True if `a` is strictly newer than `b` accounting for 32-bit wraparound.
*
* Inputs must be unsigned 32-bit integers (0..2^32-1). Use Number arithmetic,
* not bitwise comparison, because JS bitwise operators sign-extend at bit 31.
*
* @param {number} a
* @param {number} b
* @returns {boolean}
*/
export function seq32_greater_than(a, b) {
return ((a > b) && (a - b < SEQ32_HALF_RANGE)) ||
((a < b) && (b - a > SEQ32_HALF_RANGE));
}
/**
* Signed forward distance from `from` to `to` accounting for 32-bit wraparound.
* Result range: -2^31..2^31-1.
*
* @param {number} from
* @param {number} to
* @returns {number}
*/
export function seq32_distance(from, to) {
let d = to - from;
// Normalize to 0..2^32-1 first, then collapse the upper half.
if (d < 0) d += SEQ32_RANGE;
if (d >= SEQ32_HALF_RANGE) d -= SEQ32_RANGE;
return d;
}
/**
* Advance a sequence by `delta` (which may be negative) with 32-bit wraparound.
*
* @param {number} seq
* @param {number} [delta=1]
* @returns {number}
*/
export function seq32_advance(seq, delta = 1) {
let next = (seq + delta) % SEQ32_RANGE;
if (next < 0) next += SEQ32_RANGE;
return next;
}