/*

Colors: a closer look at Color32 - named colors, HSL, and blending between two colors.
@description A deep dive into Color32: named colors, HSL, and interpolating between two colors.

Part of the BLIT386 demo series.

Prerequisites:
  - Basics: https://demos.blit386.dev/basics
  - Primitives: https://demos.blit386.dev/primitives

Live version: https://demos.blit386.dev/colors

Guides:
  - Palette: https://blit386.dev/docs/guides/palette#draw-using-absolute-palette-indices
  - Overlay: https://blit386.dev/docs/guides/overlay#colors-and-hud-palette-slots

Reference:
  - Core types: https://blit386.dev/docs/api/core-types#color32

---

WHAT YOU WILL SEE
-----------------

Three numbered sections stacked on a dark gray-blue screen:

  1. NAMED COLORS: a row of seven labeled swatches - red, green, blue, yellow, cyan,
     white, and black.
  2. HSL RAINBOW: a strip across the full screen width that cycles through every hue, and
     keeps scrolling sideways.
  3. LERP: a purple "A" square on the left, a teal "B" square on the right, a gradient
     bar between them that slides along, and a thin strip below it that pulses from A to
     B and back.

The engine overlay is open from the start, with the palette grid showing 4 rows at a time
so you can watch the animated slots change color.

WHAT YOU WILL LEARN
-------------------

- Named shortcut colors: Color32.red, Color32.green, and friends are static properties,
  not function calls - ready-made Color32 objects you can copy into a palette.
- HSL: Color32.fromHSL(hue, saturation, lightness) picks a color by its angle on the
  color wheel (0-360) instead of mixing red, green, and blue by hand.
- Lerp: colorA.lerp(colorB, t) returns the color a fraction t of the way from A to B,
  like a dimmer between two lamps.
- The fourth Color32 argument is alpha: 255 is fully solid, 0 fully invisible.
- Palette animation: static colors go into the palette once in init(); animated colors
  are recalculated every tick in update() and written back into reserved slots. render()
  only ever uses slot numbers.
- Counting time in seconds with BT.deltaSeconds, the length of one update tick.

HOW THE PALETTE IS LAID OUT
---------------------------

- Slots 1-9: the static basics - white, background, black, and the six named colors.
- Slot 15: the overlay text color. Slots 18-19: the lerp endpoints A and B. Slot 20: the
  overlay bar color.
- Slots 30-93: the 64 rainbow hues. Slots 94-125: the 32 gradient steps. Slot 126: the
  pulse color. These are rewritten every tick.
- Slots 240-251: the shared UI kit's own twelve colors, used for the numbered
  section headers. The swatches and their small labels are hand-drawn on purpose:
  they ARE the lesson.

UPDATE VS RENDER
----------------

- update() runs at a fixed rate, 60 times per second (the engine default). Each call is
  one "tick", and animTime grows by BT.deltaSeconds (1/60 of a second) per tick, so after
  60 ticks it is about 1.0.
- render() may run a different number of times per second on a high-refresh monitor, but
  animTime only changes inside update(), so the animation speed is the same everywhere.

TRY THIS
--------

- The overlay is already open. Watch its palette grid at the bottom: slots 30-93 scroll
  through the rainbow, 94-125 slide, and 126 pulses, in step with the strips above.
- Press the backquote key (`) or click/tap the symbol in the bottom-left corner to hide
  the overlay and see the whole screen.

*/

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;
    ... 124 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').Palette} Palette */ /** @typedef {import('blit386').Color32} Color32 */ // These numbers are the palette "addresses". We name them so the code reads well. Slot 0 // is always transparent and reserved - never write to it. // Basic colors: set once in init(), never changed. const const C_WHITE: 1C_WHITE = 1; // pure white: the WHITE 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: the BLACK swatch and labels on light 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 slot that holds still. const const C_OVERLAY_BAR: 20C_OVERLAY_BAR = 20; // soft blue-gray strip behind the engine overlay text // Animated slots: recalculated every tick in update(). // HSL rainbow strip: 64 hue slots covering the whole 0-360 degree color wheel. Slot // C_HSL_BASE + i holds the color for the i-th group of columns. const const C_HSL_BASE: 30C_HSL_BASE = 30; const const HSL_SLOTS: 64HSL_SLOTS = 64; // 64 slots, each 5 pixels wide, cover the 320-pixel 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, an HSL rainbow, and lerp. All animated colors // are computed in update() and stored in palette slots; render() uses only slot numbers. class class DemoDemo { // 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 a box of 256 // numbered paint cans. /** @type {Palette | null} */ Demo.palette: Palette | null
@type{Palette | null}
palette
= null;
// Palette slot map for the shared UI kit theme, filled in init() by applyTheme(): a // map like { bg, text, dim, header, ... } of slot numbers. Demo.theme: nulltheme = null; // The two Color32 objects the lerp gradient blends between. We keep them here so // update() can call lerpColorA.lerp(lerpColorB, 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, open the overlay from // the start, and show its palette grid with 4 visible rows (scroll for the rest).
Demo.configure(): {
    isOverlayPaletteEnabled: boolean;
    overlayPaletteRowsVisible: number;
    isOverlayVisibleAtStart: boolean;
    overlayStyle: {
        barPaletteIndex: number;
        textPaletteIndex: number;
        gapPaletteIndex: number;
    };
}
configure
() {
return { isOverlayPaletteEnabled: booleanisOverlayPaletteEnabled: true, overlayPaletteRowsVisible: numberoverlayPaletteRowsVisible: 4, isOverlayVisibleAtStart: booleanisOverlayVisibleAtStart: true,
overlayStyle: {
    barPaletteIndex: number;
    textPaletteIndex: number;
    gapPaletteIndex: number;
}
overlayStyle
: {
// A dedicated static slot - not one of the lerp slots update() rewrites. 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 the two lerp colors. async Demo.init(): unknowninit() { // 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;
    ... 124 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 the static colors, starting with the basics. 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, and so on are static // properties on the Color32 class - ready-made Color32 objects. Copy them into // the palette so render() can draw with slot numbers instead of passing a // 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 is fully // solid, 0 is 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. 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));
// The HSL, gradient, and pulse slots stay empty here. update() fills 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 go live with the palette. 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;
    ... 124 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 every animated palette slot: // - HSL rainbow: 64 hue slots that scroll with animTime. // - Lerp gradient: 32 slots blending from A to B with a sliding phase. // - Pulse: 1 slot breathing between A and B on a sine wave. Demo.update(): voidupdate() { // Add one tick's worth of seconds. BT.deltaSeconds is 1/60 at 60 // ticks per 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;
    ... 124 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: each slot gets a hue from its position on the color wheel PLUS a // time-based offset, so the whole rainbow scrolls 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 hues 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 the scroll and wrap into 0-360. % (remainder) can give a negative // result in JavaScript when its input is negative, so we add 360 first // and wrap again. const const hue: numberhue = (((const baseHue: numberbaseHue + const scroll: numberscroll) % 360) + 360) % 360; // fromHSL(hue, saturation, lightness): a vivid rainbow needs saturation 100 // and lightness 50. 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: phase01 cycles from 0 to 1 over and over, which makes the // gradient appear to travel along the bar. const const phase: numberphase = this.Demo.animTime: numberanimTime * 0.35; // speed of the slide 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 at the left, 1 at the 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; adding 1 and dividing by 2 shifts it into 0-1. const const sinVal: anysinVal = Math.sin(this.Demo.animTime: numberanimTime * 2.5); const const pulseT: numberpulseT = (const sinVal: anysinVal + 1) / 2; // 0 is all A, 1 is all B 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 slot. Demo.render(): voidrender() { // Dark gray-blue background so the 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;
    ... 124 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(): voiddrawNamedColorsSection(); // Section 2: the HSL rainbow strip with a hue that scrolls over time. this.Demo.drawHslRainbowSection(): voiddrawHslRainbowSection(); // Section 3: a sliding blend between two colors, made with lerp. this.Demo.drawLerpSection(): voiddrawLerpSection(); } // Paints the row of swatches: red, green, blue, yellow, cyan, white, black. Each is a // filled rectangle with its label printed over the top edge. Demo.drawNamedColorsSection(): voiddrawNamedColorsSection() { // 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, 50, '1: NAMED COLORS (shortcuts)'); const const rowY: 61rowY = 61; const const swatchH: 11swatchH = 11; // Each entry: a short label and the palette slot for that 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 }, ]; // Horizontal padding so the row does not touch the screen edge. const const margin: 6margin = 6; // How many pixels wide each swatch may 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 to stay // readable. 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 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;
    ... 124 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: 61rowY, 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;
    ... 124 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: 61rowY - 1), const labelColor: 1 | 3labelColor, const entry: anyentry.label);
} } // Draws one horizontal strip where each group of columns uses a slot from C_HSL_BASE. // The slots are rewritten in update(), so the rainbow scrolls over time; this method // only maps each x column to the right slot - no Color32 objects needed. // // Hue is an angle from 0 to 360 on a color wheel. 64 slots cover the whole // wheel in steps. Demo.drawHslRainbowSection(): voiddrawHslRainbowSection() { import uiui.caption(6, 84, '2: HSL RAINBOW (fromHSL, scrolling hue)'); const const stripY: 95stripY = 95; 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 slots. for (let let x: numberx = 0; let x: numberx < 320; let x: numberx++) { // Which slot does this column belong to? 64 slots cover 320 pixels, so each // slot is 5 columns wide. Math.floor rounds down to a whole slot index, and // Math.min keeps it inside the range. 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;
    ... 124 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: 95stripY, 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 as 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. // lerpColorA.lerp(lerpColorB, 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 from A to B and back on a sine wave. Demo.drawLerpSection(): voiddrawLerpSection() { import uiui.caption(6, 118, '3: LERP: slide + pulse (see comments)'); const const barY: 129barY = 129; // The two end squares are the "lamps" at full brightness: pure A and pure 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;
    ... 124 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: 129barY, 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;
    ... 124 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: 129barY - 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;
    ... 124 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: 129barY, 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;
    ... 124 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: 129barY - 1), const C_BLACK: 3C_BLACK, 'B');
// The gradient bar: each column is another step on the dimmer between A and B. // update() already wrote 32 blended colors into slots C_LERP_BASE and up. 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;
    ... 124 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: 129barY, 1, const barH: 11barH), const C_LERP_BASE: 94C_LERP_BASE + const slot: anyslot);
} // The thin strip: one slot whose t value waves back and forth, so the whole // strip pulses. In update(), pulseT follows a sine wave, so the dimmer slides A // to B to 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;
    ... 124 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, const barY: 129barY + 15, 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 DemoDemo);