// Colors Demo - a deep dive into Color32 and palettes in BLIT386.
// @description A deep dive into Color32: named colors, HSL, and interpolating between two colors.
//
// Part of the BLIT386 demo series, written for young learners (around 12)
// who are getting comfortable with code. You will see:
//
//   - Named shortcut colors (Color32.red and friends - static properties, not function calls)
//   - HSL: another way to pick colors (hue, saturation, lightness) and a scrolling rainbow
//   - Lerp: smoothly sliding between two colors (like a dimmer between two lights)
//
// We learned about the demo lifecycle, Vector2i, Rect2i, and clearing the screen in the Basics demo:
// https://demos.blit386.dev/basics
//
// Live version: https://demos.blit386.dev/colors
// Guide: https://blit386.dev/docs/api/core-types#color32
//
// IMPORTANT - palettes and how they changed from older demos:
//
//   The engine now uses a "palette" - a table of up to 256 numbered colors.
//   Instead of passing a Color32 to every draw call, you pick a number (an "index")
//   from the palette. Think of it like numbered paint cans: you choose which can to use,
//   not the exact mix of paint every time you pick up the brush.
//
//   Static colors (named swatches, overlay text) go into the palette once during init().
//   Animated colors (HSL rainbow, lerp gradient, pulse) are recalculated every tick
//   inside update() and written back into their reserved palette slots.
//   render() only ever uses palette index numbers - no Color32 objects there.
//
//   The numbered section headers are drawn with the shared UI kit (src/shared/ui.js),
//   which parks its own twelve colors in high slots 240-251 - far away from every slot
//   this lesson uses. The swatches and their little labels stay hand-drawn on purpose:
//   they ARE the lesson.
//
// IMPORTANT - update() ticks vs render() frames:
//   update() runs at a fixed rate (here, 60 times per second when the tab is active).
//   Each call to update() is one "tick". Our animTime adds 1/60 on every tick, so after
//   60 ticks (about one second), animTime is about 1.0. That is time measured in ticks,
//   not in how often the monitor redraws. render() can run a different number of times
//   per second on high-refresh screens, but animTime still only changes inside update().

import { function bootstrap(DemoClass: DemoConstructor, options?: BootstrapOptions): Promise<boolean>
One-liner bootstrap function for BLIT386 demos. Handles canvas retrieval and engine initialization. Backend selection (WebGPU or software fallback) is managed internally by BTAPI. This function provides a streamlined way to start a demo with sensible defaults while allowing customization through options.
@since0.2.0@changed1.4.0 Calling `bootstrap()` again while already initialized now routes to a hot swap (via {@link registerHotReload}) when a Vite HMR context is registered, or logs a double-bootstrap guard and returns `false` otherwise - previously it silently started a second, unstoppable `GameLoop`.@changed1.7.0 Exposes `BT` on `window.BT` after bootstrap finishes, gated by {@link BootstrapOptions.exposeGlobal} (default: {@link BT.isDevMode}).@paramDemoClass - Demo class constructor implementing `IBTDemo` (optional `configure()` for hardware settings).@paramoptions - Optional configuration for IDs and callbacks.@returns`true` when the demo boots successfully; otherwise `false`.@example// Simplest usage - uses default IDs. bootstrap(MyDemo);@example// With custom options. bootstrap(MyDemo, { canvasID: 'custom-canvas', containerID: 'custom-container', onSuccess: () => console.log('Demo started!'), onError: (err) => analytics.trackError(err), });@example// Await the result. const success = await bootstrap(MyDemo); if (success) { console.log('Demo is running'); }
bootstrap
,
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
,
type Color32 = Color32
class Color32
Mutable 32-bit RGBA color value with 8-bit channels.
@since0.1.0
Color32
, class Rect2i
Integer rectangle for pixel-perfect bounds and regions. Used throughout the engine for sprite regions, display-space bounds, and zero-allocation geometry helpers. Both convenience getters and allocation-free `*To()` helpers are provided so callers can choose between readability and hot-path efficiency.
@since0.1.0
Rect2i
, class Vector2i
Integer 2D vector for pixel-perfect positioning. Used for points, sizes, directions, and camera offsets throughout the engine. The API includes both allocation-free `*To()` / `*InPlace()` variants and convenience methods that return new vectors.
@since0.1.0
Vector2i
} from 'blit386';
// The shared demo UI kit: applyTheme() installs the series' standard UI colors into the // palette, and ui.caption() prints the section headers with them. We met the kit in the // Basics demo: https://demos.blit386.dev/basics import { import applyThemeapplyTheme, import uiui } from './shared/ui.js'; /** @typedef {import('blit386').IBTDemo} IBTDemo */ /** @typedef {import('blit386').HardwareSettings} HardwareSettings */ /** @typedef {import('blit386').Palette} Palette */ /** @typedef {import('blit386').Color32} Color32 */ // // These numbers are the palette "addresses". We name them so the code is readable. // Index 0 is always transparent and reserved - never assign to it. // Basic colors (set once in init, never change). const const C_WHITE: 1C_WHITE = 1; // Pure white - the WHT swatch and labels on dark swatches. const const C_BG: 2C_BG = 2; // Dark gray-blue background. const const C_BLACK: 3C_BLACK = 3; // Pure black - labels on light-colored swatches. const const C_RED: 4C_RED = 4; // Color32.red - (255, 0, 0). const const C_GREEN_N: 5C_GREEN_N = 5; // Color32.green - (0, 255, 0). const const C_BLUE_N: 6C_BLUE_N = 6; // Color32.blue - (0, 0, 255). const const C_YELLOW_N: 7C_YELLOW_N = 7; // Color32.yellow - (255, 255, 0). const const C_CYAN_N: 8C_CYAN_N = 8; // Color32.cyan - (0, 255, 255). const const C_MAGENTA_N: 9C_MAGENTA_N = 9; // Color32.magenta - (255, 0, 255). // Overlay text color: a muted purple, set once in init() like the basic colors above. const const C_OVERLAY_TEXT: 15C_OVERLAY_TEXT = 15; // (200, 80, 200, 140) - semi-transparent purple. // Lerp endpoints (the two colors being blended). const const C_LERP_A: 18C_LERP_A = 18; // (180, 40, 220) - purple. const const C_LERP_B: 19C_LERP_B = 19; // (40, 220, 160) - teal. // Static overlay bar color - never animated (configure() needs a fixed slot). const const C_OVERLAY_BAR: 20C_OVERLAY_BAR = 20; // Soft blue-gray for the engine overlay background strip. // Dynamic slots - recalculated every tick in update(). // HSL rainbow strip: 64 hue slots covering the full 0..360 degree color wheel. // Slot C_HSL_BASE+i represents the color for column group i. const const C_HSL_BASE: 30C_HSL_BASE = 30; const const HSL_SLOTS: 64HSL_SLOTS = 64; // 64 slots * (320/64 ≈ 5 pixels wide each) covers the screen. // Lerp gradient bar: 32 color steps blending from C_LERP_A to C_LERP_B. const const C_LERP_BASE: 94C_LERP_BASE = 94; const const LERP_SLOTS: 32LERP_SLOTS = 32; // Pulse slot: a single color that breathes back and forth between A and B. const const C_PULSE: 126C_PULSE = 126; /** * Shows how Color32 works: named colors, HSL rainbow, and lerp. * All animated colors are computed in update() and stored in palette slots. * render() uses only palette index numbers - no Color32 objects there. * * @implements {IBTDemo} */ class class Demo
Shows how Color32 works: named colors, HSL rainbow, and lerp. All animated colors are computed in update() and stored in palette slots. render() uses only palette index numbers - no Color32 objects there.
@implementsIBTDemo
Demo
{
// animTime is "how many seconds of game time have passed". // We only change it in update(), so it follows logical time, not drawing time. Demo.animTime: numberanimTime = 0; // The palette holds all the colors we are allowed to draw with. // Imagine it as a box of 256 numbered paint cans. /** @type {Palette | null} */ Demo.palette: Palette | null
@type{Palette | null}
palette
= null;
// theme remembers which palette slots the shared UI kit colors landed in. // applyTheme() in init() fills it with a map like { bg, text, dim, header, ... }. Demo.theme: nulltheme = null; // The two Color32 objects used to compute the lerp gradient. // We store them here so update() can call colorA.lerp(colorB, t) every tick. /** @type {Color32 | null} */ Demo.lerpColorA: Color32 | null
@type{Color32 | null}
lerpColorA
= null;
/** @type {Color32 | null} */ Demo.lerpColorB: Color32 | null
@type{Color32 | null}
lerpColorB
= null;
/** * Optional engine settings. We keep the default 320x240 screen and show the * palette grid in the overlay with 4 visible rows (scroll for the rest). * * @returns {Partial<HardwareSettings>} */ Demo.configure(): Partial<HardwareSettings>
Optional engine settings. We keep the default 320x240 screen and show the palette grid in the overlay with 4 visible rows (scroll for the rest).
@returns
configure
() {
return { isOverlayPaletteEnabled: booleanisOverlayPaletteEnabled: true, overlayPaletteRowsVisible: numberoverlayPaletteRowsVisible: 4,
overlayStyle: {
    barPaletteIndex: number;
    textPaletteIndex: number;
    gapPaletteIndex: number;
}
overlayStyle
: {
// Dedicated static slot - not C_LERP_BASE, which update() rewrites every tick. barPaletteIndex: numberbarPaletteIndex: const C_OVERLAY_BAR: 20C_OVERLAY_BAR, textPaletteIndex: numbertextPaletteIndex: const C_OVERLAY_TEXT: 15C_OVERLAY_TEXT, gapPaletteIndex: numbergapPaletteIndex: const C_BLACK: 3C_BLACK, }, }; } /** * Sets up the palette and prepares lerp color objects. * * @returns {Promise<boolean>} */ async Demo.init(): Promise<boolean>
Sets up the palette and prepares lerp color objects.
@returns
init
() {
// Step 1: Create the palette this.Demo.palette: Palette | null
@type{Palette | null}
palette
=
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.paletteCreate: (size?: number) => Palette
Creates a standalone palette instance.
@since1.0.3@paramsize - Palette size. Defaults to 256 colors.@returnsNew mutable palette.
paletteCreate
(256);
// Step 2: Fill in static colors // Basic colors. this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_WHITE: 1C_WHITE, new new Color32(r?: number, g?: number, b?: number, a?: number): Color32
Creates a clamped 8-bit RGBA color.
@paramr - Red channel (0-255, defaults to 255).@paramg - Green channel (0-255, defaults to 255).@paramb - Blue channel (0-255, defaults to 255).@parama - Alpha channel (0-255, defaults to 255 = opaque).
Color32
(255, 255, 255));
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_BG: 2C_BG, new new Color32(r?: number, g?: number, b?: number, a?: number): Color32
Creates a clamped 8-bit RGBA color.
@paramr - Red channel (0-255, defaults to 255).@paramg - Green channel (0-255, defaults to 255).@paramb - Blue channel (0-255, defaults to 255).@parama - Alpha channel (0-255, defaults to 255 = opaque).
Color32
(24, 28, 40));
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_BLACK: 3C_BLACK, new new Color32(r?: number, g?: number, b?: number, a?: number): Color32
Creates a clamped 8-bit RGBA color.
@paramr - Red channel (0-255, defaults to 255).@paramg - Green channel (0-255, defaults to 255).@paramb - Blue channel (0-255, defaults to 255).@parama - Alpha channel (0-255, defaults to 255 = opaque).
Color32
(0, 0, 0));
// Named shortcut colors: Color32.red, Color32.green, etc. are static properties // on the Color32 class (ready-made Color32 objects). Copy them into the palette // so render() can draw with index numbers instead of passing Color32 each time. this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_RED: 4C_RED, class Color32
Mutable 32-bit RGBA color value with 8-bit channels.
@since0.1.0
Color32
.Color32.red: Color32
Pure red color (255, 0, 0, 255). Cached frozen singleton - do not modify.
@returnsThe shared red Color32 instance.
red
);
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_GREEN_N: 5C_GREEN_N, class Color32
Mutable 32-bit RGBA color value with 8-bit channels.
@since0.1.0
Color32
.Color32.green: Color32
Pure green color (0, 255, 0, 255). Cached frozen singleton - do not modify.
@returnsThe shared green Color32 instance.
green
);
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_BLUE_N: 6C_BLUE_N, class Color32
Mutable 32-bit RGBA color value with 8-bit channels.
@since0.1.0
Color32
.Color32.blue: Color32
Pure blue color (0, 0, 255, 255). Cached frozen singleton - do not modify.
@returnsThe shared blue Color32 instance.
blue
);
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_YELLOW_N: 7C_YELLOW_N, class Color32
Mutable 32-bit RGBA color value with 8-bit channels.
@since0.1.0
Color32
.Color32.yellow: Color32
Yellow color (255, 255, 0, 255). Cached frozen singleton - do not modify.
@returnsThe shared yellow Color32 instance.
yellow
);
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_CYAN_N: 8C_CYAN_N, class Color32
Mutable 32-bit RGBA color value with 8-bit channels.
@since0.1.0
Color32
.Color32.cyan: Color32
Cyan color (0, 255, 255, 255). Cached frozen singleton - do not modify.
@returnsThe shared cyan Color32 instance.
cyan
);
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_MAGENTA_N: 9C_MAGENTA_N, class Color32
Mutable 32-bit RGBA color value with 8-bit channels.
@since0.1.0
Color32
.Color32.magenta: Color32
Magenta color (255, 0, 255, 255). Cached frozen singleton - do not modify.
@returnsThe shared magenta Color32 instance.
magenta
);
// Overlay text color. The fourth argument to Color32 is alpha: 255 = fully // solid, 0 = fully invisible. this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_OVERLAY_TEXT: 15C_OVERLAY_TEXT, new new Color32(r?: number, g?: number, b?: number, a?: number): Color32
Creates a clamped 8-bit RGBA color.
@paramr - Red channel (0-255, defaults to 255).@paramg - Green channel (0-255, defaults to 255).@paramb - Blue channel (0-255, defaults to 255).@parama - Alpha channel (0-255, defaults to 255 = opaque).
Color32
(200, 80, 200, 140));
// Lerp endpoints - the two colors the gradient blends between. this.Demo.lerpColorA: Color32 | null
@type{Color32 | null}
lerpColorA
= new new Color32(r?: number, g?: number, b?: number, a?: number): Color32
Creates a clamped 8-bit RGBA color.
@paramr - Red channel (0-255, defaults to 255).@paramg - Green channel (0-255, defaults to 255).@paramb - Blue channel (0-255, defaults to 255).@parama - Alpha channel (0-255, defaults to 255 = opaque).
Color32
(180, 40, 220); // Purple.
this.Demo.lerpColorB: Color32 | null
@type{Color32 | null}
lerpColorB
= new new Color32(r?: number, g?: number, b?: number, a?: number): Color32
Creates a clamped 8-bit RGBA color.
@paramr - Red channel (0-255, defaults to 255).@paramg - Green channel (0-255, defaults to 255).@paramb - Blue channel (0-255, defaults to 255).@parama - Alpha channel (0-255, defaults to 255 = opaque).
Color32
(40, 220, 160); // Teal.
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_LERP_A: 18C_LERP_A, this.Demo.lerpColorA: Color32
@type{Color32 | null}
lerpColorA
);
this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_LERP_B: 19C_LERP_B, this.Demo.lerpColorB: Color32
@type{Color32 | null}
lerpColorB
);
// Overlay bar: a calm static color so the HUD strip does not pulse with the lerp demo. this.Demo.palette: Palette
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_OVERLAY_BAR: 20C_OVERLAY_BAR, new new Color32(r?: number, g?: number, b?: number, a?: number): Color32
Creates a clamped 8-bit RGBA color.
@paramr - Red channel (0-255, defaults to 255).@paramg - Green channel (0-255, defaults to 255).@paramb - Blue channel (0-255, defaults to 255).@parama - Alpha channel (0-255, defaults to 255 = opaque).
Color32
(40, 48, 64));
// HSL, lerp gradient, and pulse slots are left empty here. // update() will fill them before the first frame is drawn. // Step 3: Install the shared UI theme // applyTheme() writes the series' twelve standard UI colors into slots 240-251, // safely above every slot this lesson uses (the static colors in 1-20 and the // animated ranges 30-93, 94-125, and 126). The section headers draw with them. // This must happen BEFORE BT.paletteSet() below so the colors are included. this.Demo.theme: nulltheme = import applyThemeapplyTheme(this.Demo.palette: Palette
@type{Palette | null}
palette
);
// Step 4: Activate the palette
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.paletteSet: (palette: Palette) => void
Stores the active engine palette. Use this to swap the **entire palette** (e.g. switch between a day and night theme). After this call the renderer uploads the new palette uniform on the next frame. **Palette-value swap (change what a slot looks like):** mutate the live {@link BT.palette } in place with `palette.set(slot, newColor)`. The renderer uploads dirty slots on the next frame; no `paletteSet()` or {@link BT.spritesRefresh } needed. **Palette-layout swap (same colors, different slot positions):** build a new palette with the same colors at new indices, call `paletteSet()`, then call {@link BT.spritesRefresh } so every sprite sheet re-maps its original RGBA pixels against the new slot layout.
@since1.0.3@parampalette - Palette to make active.
paletteSet
(this.Demo.palette: Palette
@type{Palette | null}
palette
);
return true; } /** * Advances logical time and recalculates all animated palette entries. * * - HSL rainbow: 64 hue slots scroll with animTime. * - Lerp gradient: 32 slots blend from colorA to colorB with a sliding phase. * - Pulse: 1 slot breathes between colorA and colorB using a sine wave. */ Demo.update(): void
Advances logical time and recalculates all animated palette entries. - HSL rainbow: 64 hue slots scroll with animTime. - Lerp gradient: 32 slots blend from colorA to colorB with a sliding phase. - Pulse: 1 slot breathes between colorA and colorB using a sine wave.
update
() {
// Add one tick's worth of seconds. At 60 ticks per second, each tick is 1/60 of a second. this.Demo.animTime: numberanimTime +=
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.deltaSeconds: number
Fixed-step seconds per update tick. Equivalent to `1 / BT.targetFPS` when `BT.targetFPS` is finite and positive. Falls back to `1 / 60` when target FPS is non-finite or non-positive.
@since1.0.4@returnsSeconds advanced by one fixed update tick.
deltaSeconds
;
// HSL rainbow: 64 animated hue slots // Each slot gets a hue based on its position on the color wheel PLUS // a time-based scroll offset so the whole rainbow moves over time. const const scroll: numberscroll = this.Demo.animTime: numberanimTime * 90; // 90 degrees per second. for (let let i: numberi = 0; let i: numberi < const HSL_SLOTS: 64HSL_SLOTS; let i: numberi++) { // Spread the base hue evenly: slot 0 is hue 0, slot 63 is hue 337.5. const const baseHue: numberbaseHue = (let i: numberi / const HSL_SLOTS: 64HSL_SLOTS) * 360; // Add scroll and wrap into 0..360 range. // % can give negative values in JS if the input is negative, so we add 360 first. const const hue: numberhue = (((const baseHue: numberbaseHue + const scroll: numberscroll) % 360) + 360) % 360; // fromHSL(hue, saturation, lightness): vivid rainbow needs 100% saturation, 50% lightness. this.Demo.palette: Palette | null
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_HSL_BASE: 30C_HSL_BASE + let i: numberi, class Color32
Mutable 32-bit RGBA color value with 8-bit channels.
@since0.1.0
Color32
.Color32.fromHSL(h: number, s: number, l: number, a?: number): Color32
Creates a color from HSL values.
@paramh - Hue in degrees (0-360).@params - Saturation as percentage (0-100).@paraml - Lightness as percentage (0-100).@parama - Alpha channel (0-255, defaults to 255).@returnsNew color converted from HSL values.
fromHSL
(const hue: numberhue, 100, 50));
} // Lerp gradient: 32 sliding color steps // phase01 cycles from 0 to 1 repeatedly, making the gradient appear to travel. const const phase: numberphase = this.Demo.animTime: numberanimTime * 0.35; // Speed of the scroll. const const phase01: numberphase01 = const phase: numberphase - Math.floor(const phase: numberphase); // Only the fractional part (0..1). for (let let j: numberj = 0; let j: numberj < const LERP_SLOTS: 32LERP_SLOTS; let j: numberj++) { // u is this slot's position along the bar (0 = left, 1 = right). const const u: numberu = let j: numberj / (const LERP_SLOTS: 32LERP_SLOTS - 1); // Combine the bar position with the animated phase so the pattern moves. const const t: numbert = (const u: numberu + const phase01: numberphase01) % 1; // Wraps at 1 to keep cycling. // lerp returns a new Color32 blended between A and B at position t. this.Demo.palette: Palette | null
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_LERP_BASE: 94C_LERP_BASE + let j: numberj, this.Demo.lerpColorA: Color32 | null
@type{Color32 | null}
lerpColorA
.Color32.lerp(other: Color32, t: number): Color32
Linearly interpolates between this color and another. Useful for color transitions and gradients.
@paramother - Target color to blend toward.@paramt - Interpolation factor (0.0 = this color, 1.0 = other color).@returnsNew color blended between this and other.
lerp
(this.Demo.lerpColorB: Color32 | null
@type{Color32 | null}
lerpColorB
, const t: numbert));
} // Pulse: one color that breathes back and forth // Math.sin() returns a wave between -1 and 1. // We shift it to 0..1 by adding 1 and dividing by 2. const const sinVal: anysinVal = Math.sin(this.Demo.animTime: numberanimTime * 2.5); const const pulseT: numberpulseT = (const sinVal: anysinVal + 1) / 2; // 0 when all colorA, 1 when all colorB. this.Demo.palette: Palette | null
@type{Palette | null}
palette
.Palette.set(index: number, color: Color32): void
Writes a color into a palette slot.
@paramindex - Palette index to overwrite.@paramcolor - Color to store.@throwsError if the index is invalid or if index `0` is set opaque.
set
(const C_PULSE: 126C_PULSE, this.Demo.lerpColorA: Color32 | null
@type{Color32 | null}
lerpColorA
.Color32.lerp(other: Color32, t: number): Color32
Linearly interpolates between this color and another. Useful for color transitions and gradients.
@paramother - Target color to blend toward.@paramt - Interpolation factor (0.0 = this color, 1.0 = other color).@returnsNew color blended between this and other.
lerp
(this.Demo.lerpColorB: Color32 | null
@type{Color32 | null}
lerpColorB
, const pulseT: numberpulseT));
} /** * Draws every section each frame. Always clear first, then paint from back to front. * * Notice: NO Color32 objects appear here. Every draw call uses a palette index. */ Demo.render(): void
Draws every section each frame. Always clear first, then paint from back to front. Notice: NO Color32 objects appear here. Every draw call uses a palette index.
render
() {
// Dark gray-blue background so bright color samples pop.
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.clear: (paletteIndex: number) => void
Sets the frame clear color using a palette index. The renderer uses this color when clearing the full display at the start of the next frame.
@since0.1.0@parampaletteIndex - Palette index for the full-screen clear pass.
clear
(const C_BG: 2C_BG);
// Section 1: ready-made named colors in a row with short labels. this.Demo.drawNamedColorsSection(): void
Paints the top row of preset Color32 colors (red(), green(), and so on). Each block is a filled rectangle; the label sits above it in small text.
drawNamedColorsSection
();
// Section 2: HSL rainbow strip with hue that scrolls over time. this.Demo.drawHslRainbowSection(): void
Draws one horizontal strip where each column group uses a palette slot from C_HSL_BASE. The HSL slots are updated in update() so the rainbow scrolls over time. This function only maps each x column to the right slot - no Color32 objects needed. Hue is an angle 0..360 on a color wheel. 64 slots cover the whole wheel in steps.
drawHslRainbowSection
();
// Section 3: sliding blend between two colors using colorA.lerp(colorB, t). this.Demo.drawLerpSection(): void
Section 3: lerp (linear interpolation) between two colors. Think of t like a dimmer switch between two lamps: t = 0 is only lamp A (purple), t = 1 is only lamp B (teal), and t = 0.5 is an even mix halfway between them. colorA.lerp(colorB, t) returns a new Color32 at that blend point. The wide bar uses 32 palette slots that slide over time (a moving gradient). The thin strip below uses one slot that breathes A <-> B with a sine wave.
drawLerpSection
();
} /** * Paints the top row of preset Color32 colors (red(), green(), and so on). * Each block is a filled rectangle; the label sits above it in small text. */ Demo.drawNamedColorsSection(): void
Paints the top row of preset Color32 colors (red(), green(), and so on). Each block is a filled rectangle; the label sits above it in small text.
drawNamedColorsSection
() {
// Section header, drawn with ui.caption() from the shared UI kit. Every demo in // the series uses this same widget, so all headers look identical everywhere. import uiui.caption(6, 3, '1: NAMED COLORS (shortcuts)'); const const rowY: 16rowY = 16; const const swatchH: 11swatchH = 11; // Each entry: a short label and the palette index for that named color. const const entries: {}entries = [ { label: stringlabel: 'RED', index: numberindex: const C_RED: 4C_RED }, { label: stringlabel: 'GREEN', index: numberindex: const C_GREEN_N: 5C_GREEN_N }, { label: stringlabel: 'BLUE', index: numberindex: const C_BLUE_N: 6C_BLUE_N }, { label: stringlabel: 'YELLOW', index: numberindex: const C_YELLOW_N: 7C_YELLOW_N }, { label: stringlabel: 'CYAN', index: numberindex: const C_CYAN_N: 8C_CYAN_N }, { label: stringlabel: 'WHITE', index: numberindex: const C_WHITE: 1C_WHITE }, { label: stringlabel: 'BLACK', index: numberindex: const C_BLACK: 3C_BLACK }, ]; // Shared horizontal padding so the row does not touch the screen edge. const const margin: 6margin = 6; // How many pixels wide each swatch can be if we split the row evenly. const const slotW: anyslotW = Math.floor((320 - const margin: 6margin * 2) / const entries: {}entries.length); for (let let slotIndex: numberslotIndex = 0; let slotIndex: numberslotIndex < const entries: {}entries.length; let slotIndex: numberslotIndex++) { const const entry: anyentry = const entries: {}entries[let slotIndex: numberslotIndex]; const const x: numberx = const margin: 6margin + let slotIndex: numberslotIndex * const slotW: anyslotW; const const swatchW: numberswatchW = const slotW: anyslotW - 4; // Light swatches (white, yellow, green, cyan) need black labels so you can read them. // Dark swatches get white labels. const const isLight: booleanisLight = const entry: anyentry.index === const C_WHITE: 1C_WHITE || const entry: anyentry.index === const C_YELLOW_N: 7C_YELLOW_N || const entry: anyentry.index === const C_GREEN_N: 5C_GREEN_N || const entry: anyentry.index === const C_CYAN_N: 8C_CYAN_N; const const labelColor: 1 | 3labelColor = const isLight: booleanisLight ? const C_BLACK: 3C_BLACK : const C_WHITE: 1C_WHITE; // Fill a rectangle with that named color.
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.drawRectFill: (rect: Rect2i, paletteIndex: number) => void
Draws a filled rectangle.
@since0.1.0@paramrect - Rectangle bounds in display coordinates.@parampaletteIndex - Palette color index.
drawRectFill
(new new Rect2i(x?: number, y?: number, width?: number, height?: number): Rect2i
Creates an integer rectangle, truncating all inputs toward zero.
@paramx - Left-edge X coordinate (defaults to 0).@paramy - Top-edge Y coordinate (defaults to 0).@paramwidth - Width in pixels (defaults to 0).@paramheight - Height in pixels (defaults to 0).
Rect2i
(const x: numberx, const rowY: 16rowY, const swatchW: numberswatchW, const swatchH: 11swatchH), const entry: anyentry.index);
// Print the label into the swatch.
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.systemPrint: (pos: Vector2i, paletteIndex: number, text: string) => void
Draws text using the built-in 6x14 system font. The system font covers printable ASCII (characters 32-126). For custom bitmap fonts with proportional glyphs, use {@link BT.printFont } instead.
@since1.0.3@parampos - Text origin in display coordinates.@parampaletteIndex - Palette color index for the text.@paramtext - String to render.
systemPrint
(new new Vector2i(x?: number, y?: number): Vector2i
Creates an integer 2D vector, truncating inputs toward zero.
@paramx - Horizontal component (defaults to 0).@paramy - Vertical component (defaults to 0).
Vector2i
(const x: numberx + 2, const rowY: 16rowY - 1), const labelColor: 1 | 3labelColor, const entry: anyentry.label);
} } /** * Draws one horizontal strip where each column group uses a palette slot from C_HSL_BASE. * * The HSL slots are updated in update() so the rainbow scrolls over time. * This function only maps each x column to the right slot - no Color32 objects needed. * * Hue is an angle 0..360 on a color wheel. 64 slots cover the whole wheel in steps. */ Demo.drawHslRainbowSection(): void
Draws one horizontal strip where each column group uses a palette slot from C_HSL_BASE. The HSL slots are updated in update() so the rainbow scrolls over time. This function only maps each x column to the right slot - no Color32 objects needed. Hue is an angle 0..360 on a color wheel. 64 slots cover the whole wheel in steps.
drawHslRainbowSection
() {
import uiui.caption(6, 30, '2: HSL RAINBOW (fromHSL, scrolling hue)'); const const stripY: 43stripY = 43; const const stripH: 11stripH = 11; // Walk every x column on the screen from left to right. // Each column maps to one of the 64 HSL palette slots. for (let let x: numberx = 0; let x: numberx < 320; let x: numberx++) { // Which slot does this column belong to? There are 64 slots covering 320 pixels. // Math.floor(...) rounds down to get an integer slot index. const const slot: anyslot = Math.min(Math.floor((let x: numberx / 320) * const HSL_SLOTS: 64HSL_SLOTS), const HSL_SLOTS: 64HSL_SLOTS - 1);
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.drawRectFill: (rect: Rect2i, paletteIndex: number) => void
Draws a filled rectangle.
@since0.1.0@paramrect - Rectangle bounds in display coordinates.@parampaletteIndex - Palette color index.
drawRectFill
(new new Rect2i(x?: number, y?: number, width?: number, height?: number): Rect2i
Creates an integer rectangle, truncating all inputs toward zero.
@paramx - Left-edge X coordinate (defaults to 0).@paramy - Top-edge Y coordinate (defaults to 0).@paramwidth - Width in pixels (defaults to 0).@paramheight - Height in pixels (defaults to 0).
Rect2i
(let x: numberx, const stripY: 43stripY, 1, const stripH: 11stripH), const C_HSL_BASE: 30C_HSL_BASE + const slot: anyslot);
} } /** * Section 3: lerp (linear interpolation) between two colors. * * Think of t like a dimmer switch between two lamps: t = 0 is only lamp A (purple), * t = 1 is only lamp B (teal), and t = 0.5 is an even mix halfway between them. * colorA.lerp(colorB, t) returns a new Color32 at that blend point. * * The wide bar uses 32 palette slots that slide over time (a moving gradient). * The thin strip below uses one slot that breathes A <-> B with a sine wave. */ Demo.drawLerpSection(): void
Section 3: lerp (linear interpolation) between two colors. Think of t like a dimmer switch between two lamps: t = 0 is only lamp A (purple), t = 1 is only lamp B (teal), and t = 0.5 is an even mix halfway between them. colorA.lerp(colorB, t) returns a new Color32 at that blend point. The wide bar uses 32 palette slots that slide over time (a moving gradient). The thin strip below uses one slot that breathes A <-> B with a sine wave.
drawLerpSection
() {
import uiui.caption(6, 57, '3: LERP: slide + pulse (see comments)'); const const barY: 70barY = 70; // Dimmer analogy: these end squares are the two "lamps" at full brightness (pure A and B).
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.drawRectFill: (rect: Rect2i, paletteIndex: number) => void
Draws a filled rectangle.
@since0.1.0@paramrect - Rectangle bounds in display coordinates.@parampaletteIndex - Palette color index.
drawRectFill
(new new Rect2i(x?: number, y?: number, width?: number, height?: number): Rect2i
Creates an integer rectangle, truncating all inputs toward zero.
@paramx - Left-edge X coordinate (defaults to 0).@paramy - Top-edge Y coordinate (defaults to 0).@paramwidth - Width in pixels (defaults to 0).@paramheight - Height in pixels (defaults to 0).
Rect2i
(6, const barY: 70barY, 11, 11), const C_LERP_A: 18C_LERP_A);
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.systemPrint: (pos: Vector2i, paletteIndex: number, text: string) => void
Draws text using the built-in 6x14 system font. The system font covers printable ASCII (characters 32-126). For custom bitmap fonts with proportional glyphs, use {@link BT.printFont } instead.
@since1.0.3@parampos - Text origin in display coordinates.@parampaletteIndex - Palette color index for the text.@paramtext - String to render.
systemPrint
(new new Vector2i(x?: number, y?: number): Vector2i
Creates an integer 2D vector, truncating inputs toward zero.
@paramx - Horizontal component (defaults to 0).@paramy - Vertical component (defaults to 0).
Vector2i
(8, const barY: 70barY - 1), const C_BLACK: 3C_BLACK, 'A');
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.drawRectFill: (rect: Rect2i, paletteIndex: number) => void
Draws a filled rectangle.
@since0.1.0@paramrect - Rectangle bounds in display coordinates.@parampaletteIndex - Palette color index.
drawRectFill
(new new Rect2i(x?: number, y?: number, width?: number, height?: number): Rect2i
Creates an integer rectangle, truncating all inputs toward zero.
@paramx - Left-edge X coordinate (defaults to 0).@paramy - Top-edge Y coordinate (defaults to 0).@paramwidth - Width in pixels (defaults to 0).@paramheight - Height in pixels (defaults to 0).
Rect2i
(300, const barY: 70barY, 11, 11), const C_LERP_B: 19C_LERP_B);
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.systemPrint: (pos: Vector2i, paletteIndex: number, text: string) => void
Draws text using the built-in 6x14 system font. The system font covers printable ASCII (characters 32-126). For custom bitmap fonts with proportional glyphs, use {@link BT.printFont } instead.
@since1.0.3@parampos - Text origin in display coordinates.@parampaletteIndex - Palette color index for the text.@paramtext - String to render.
systemPrint
(new new Vector2i(x?: number, y?: number): Vector2i
Creates an integer 2D vector, truncating inputs toward zero.
@paramx - Horizontal component (defaults to 0).@paramy - Vertical component (defaults to 0).
Vector2i
(302, const barY: 70barY - 1), const C_BLACK: 3C_BLACK, 'B');
// Middle gradient bar: each column is another step on the dimmer between A and B. // update() already wrote 32 blended colors into palette slots C_LERP_BASE.. . const const barX: 24barX = 24; const const barW: 268barW = 268; const const barH: 11barH = 11; for (let let i: numberi = 0; let i: numberi < const barW: 268barW; let i: numberi++) { // Pick which of the 32 pre-blended "dimmer steps" this pixel column uses. const const slot: anyslot = Math.min(Math.floor((let i: numberi / const barW: 268barW) * const LERP_SLOTS: 32LERP_SLOTS), const LERP_SLOTS: 32LERP_SLOTS - 1);
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.drawRectFill: (rect: Rect2i, paletteIndex: number) => void
Draws a filled rectangle.
@since0.1.0@paramrect - Rectangle bounds in display coordinates.@parampaletteIndex - Palette color index.
drawRectFill
(new new Rect2i(x?: number, y?: number, width?: number, height?: number): Rect2i
Creates an integer rectangle, truncating all inputs toward zero.
@paramx - Left-edge X coordinate (defaults to 0).@paramy - Top-edge Y coordinate (defaults to 0).@paramwidth - Width in pixels (defaults to 0).@paramheight - Height in pixels (defaults to 0).
Rect2i
(const barX: 24barX + let i: numberi, const barY: 70barY, 1, const barH: 11barH), const C_LERP_BASE: 94C_LERP_BASE + const slot: anyslot);
} // Thin strip: one color slot whose t value waves back and forth (whole bar pulses). // In update(), pulseT follows a sine wave so the dimmer slides A -> B -> A smoothly.
const BT: {
    FLIP_H: number;
    FLIP_V: number;
    ROT_90_CW: number;
    ROT_180_CW: number;
    ROT_270_CW: number;
    BTN_UP: number;
    BTN_DOWN: number;
    BTN_LEFT: number;
    BTN_RIGHT: number;
    BTN_A: number;
    BTN_B: number;
    BTN_X: number;
    BTN_Y: number;
    BTN_L: number;
    BTN_R: number;
    BTN_START: number;
    BTN_SELECT: number;
    BTN_POINTER_A: number;
    BTN_POINTER_B: number;
    BTN_POINTER_C: number;
    BTN_POINTER_D: number;
    PLAYER_ONE: number;
    PLAYER_TWO: number;
    PLAYER_THREE: number;
    PLAYER_FOUR: number;
    AXIS_LEFT_X: number;
    AXIS_LEFT_Y: number;
    AXIS_RIGHT_X: number;
    AXIS_RIGHT_Y: number;
    AXIS_TRIGGER_L: number;
    ... 106 more ...;
    spritesRefresh: () => void;
}
Main BLIT386 API namespace used by runtime demos.
BT
.drawRectFill: (rect: Rect2i, paletteIndex: number) => void
Draws a filled rectangle.
@since0.1.0@paramrect - Rectangle bounds in display coordinates.@parampaletteIndex - Palette color index.
drawRectFill
(new new Rect2i(x?: number, y?: number, width?: number, height?: number): Rect2i
Creates an integer rectangle, truncating all inputs toward zero.
@paramx - Left-edge X coordinate (defaults to 0).@paramy - Top-edge Y coordinate (defaults to 0).@paramwidth - Width in pixels (defaults to 0).@paramheight - Height in pixels (defaults to 0).
Rect2i
(24, 82, 268, 11), const C_PULSE: 126C_PULSE);
} } function bootstrap(DemoClass: DemoConstructor, options?: BootstrapOptions): Promise<boolean>
One-liner bootstrap function for BLIT386 demos. Handles canvas retrieval and engine initialization. Backend selection (WebGPU or software fallback) is managed internally by BTAPI. This function provides a streamlined way to start a demo with sensible defaults while allowing customization through options.
@since0.2.0@changed1.4.0 Calling `bootstrap()` again while already initialized now routes to a hot swap (via {@link registerHotReload}) when a Vite HMR context is registered, or logs a double-bootstrap guard and returns `false` otherwise - previously it silently started a second, unstoppable `GameLoop`.@changed1.7.0 Exposes `BT` on `window.BT` after bootstrap finishes, gated by {@link BootstrapOptions.exposeGlobal} (default: {@link BT.isDevMode}).@paramDemoClass - Demo class constructor implementing `IBTDemo` (optional `configure()` for hardware settings).@paramoptions - Optional configuration for IDs and callbacks.@returns`true` when the demo boots successfully; otherwise `false`.@example// Simplest usage - uses default IDs. bootstrap(MyDemo);@example// With custom options. bootstrap(MyDemo, { canvasID: 'custom-canvas', containerID: 'custom-container', onSuccess: () => console.log('Demo started!'), onError: (err) => analytics.trackError(err), });@example// Await the result. const success = await bootstrap(MyDemo); if (success) { console.log('Demo is running'); }
bootstrap
(class Demo
Shows how Color32 works: named colors, HSL rainbow, and lerp. All animated colors are computed in update() and stored in palette slots. render() uses only palette index numbers - no Color32 objects there.
@implementsIBTDemo
Demo
);