Back to Supersonic RC Revive
SOURCE / PINNED RELEASE

Made of little things.

Supersonic RC Revive

Release
1ba42f1ca1d6…
Author-recorded commit
baecad10b1cd…
License
LICENSE
Author’s source reference
nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.napplet.soy%2F/n-143146b0d6f

Archive hash verified: 90d22b206672eba4…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/napplet-keys.ts
import { KEYS_DOMAIN, keys } from '@napplet/sdk';
import { runtimeHasDomain } from './domain-availability.js';
import type { DirectorKey } from './game/input.js';

const DRIVING_ACTIONS: ReadonlyArray<{
  action: { id: string; label: string; defaultKey: string };
  key: DirectorKey;
}> = [
  { action: { id: 'game.drive.forward', label: 'Accelerate', defaultKey: 'ArrowUp' }, key: 126 },
  { action: { id: 'game.drive.reverse', label: 'Reverse', defaultKey: 'ArrowDown' }, key: 125 },
  { action: { id: 'game.drive.left', label: 'Steer left', defaultKey: 'ArrowLeft' }, key: 123 },
  { action: { id: 'game.drive.right', label: 'Steer right', defaultKey: 'ArrowRight' }, key: 124 },
];

/**
 * Advertise the game's primary keyboard controls to a NAP-KEYS-capable shell.
 *
 * The runtime-owned keys shim forwards all other keydown events automatically.
 * These registrations let the shell reserve/rebind the arrow controls while the
 * game's native keydown/keyup listeners continue to provide held-key input.
 */
export function registerDrivingKeyActions(trigger: (key: DirectorKey) => void): () => void {
  if (!runtimeHasDomain(KEYS_DOMAIN)) return () => {};

  const handles = new Set<{ close(): void }>();
  let closed = false;

  for (const { action, key } of DRIVING_ACTIONS) {
    void (async () => {
      try {
        const handle = await keys.register(action, () => trigger(key));
        if (closed) handle.close();
        else handles.add(handle);
      } catch {
        // NAP-KEYS is optional. A partial/denied registration must not stop play.
      }
    })();
  }

  return () => {
    closed = true;
    for (const handle of handles) handle.close();
    handles.clear();
  };
}