Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions apps/cafe/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// phase guards, no input blocking needed for this demo's script.

import { createMemo, createSignal, For, Show, onMount } from "solid-js";
import { Text, View, type NodeMirror } from "@pocketjs/framework/components";
import { Focusable, Text, View, type NodeMirror } from "@pocketjs/framework/components";
import { onButtonPress } from "@pocketjs/framework/lifecycle";
import { BTN, pushFocusScope } from "@pocketjs/framework/input";
import { runEffect } from "@pocketjs/framework/effects";
Expand Down Expand Up @@ -57,7 +57,7 @@ export default function Cafe() {
setQty((q) => q.map((n, j) => (j === i ? n + 1 : n)));
};

onButtonPress(BTN.START, () => {
const placeOrder = () => {
if (phase() !== "menu" || total() === 0) return;
setPhase("placing");
const order = items()
Expand All @@ -73,7 +73,8 @@ export default function Cafe() {
setPhase("menu");
});
});
});
};
onButtonPress(BTN.START, placeOrder);

return (
<View class="w-full h-full flex-col" style={{ bgColor: "#05080c" }}>
Expand Down Expand Up @@ -116,9 +117,15 @@ export default function Cafe() {
<Show
when={phase() === "placing"}
fallback={
<Text class="text-xs tracking-wide" style={{ textColor: DIM }}>
↕ BROWSE · ○ ADD · START = PLACE ORDER
</Text>
/* Tapping the hint places the order too — the touch twin of
START (menu rows already add on tap via activation). The
active: wash is the only visual, so untouched frames stay
byte-identical. */
<Focusable onPress={placeOrder} class="active:bg-[#12202c]">
<Text class="text-xs tracking-wide" style={{ textColor: DIM }}>
↕ BROWSE · ○ ADD · START = PLACE ORDER
</Text>
</Focusable>
}
>
<Text class="text-xs tracking-wide animate-pulse" style={{ textColor: AMBER }}>
Expand Down
7 changes: 7 additions & 0 deletions apps/cafe/psp/Psp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# XMB metadata for the PocketJS Cafe EBOOT. tools/psp.ts copies this to
# hosts/psp/Psp.toml when building this demo (any framework); cargo-psp packs
# it into PARAM.SFO / ICON0 / PIC1.
# Regenerate the art with: bun tools/gen-demo-covers.ts cafe
title = "PocketJS Cafe"
xmb_icon_png = "icon0.png"
xmb_background_png = "pic1.png"
Binary file added apps/cafe/psp/icon0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/cafe/psp/pic1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/cafe/vita/sce_sys/livearea/contents/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/cards/vita/sce_sys/livearea/contents/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions apps/chrome/psp/Psp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# XMB metadata for the PocketJS Chrome EBOOT. tools/psp.ts copies this to
# hosts/psp/Psp.toml when building this demo (any framework); cargo-psp packs
# it into PARAM.SFO / ICON0 / PIC1.
# Regenerate the art with: bun tools/gen-demo-covers.ts chrome
title = "PocketJS Chrome"
xmb_icon_png = "icon0.png"
xmb_background_png = "pic1.png"
Binary file added apps/chrome/psp/icon0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/chrome/psp/pic1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/chrome/vita/sce_sys/livearea/contents/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions apps/cursor/psp/Psp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# XMB metadata for the PocketJS Cursor EBOOT. tools/psp.ts copies this to
# hosts/psp/Psp.toml when building this demo (any framework); cargo-psp packs
# it into PARAM.SFO / ICON0 / PIC1.
# Regenerate the art with: bun tools/gen-demo-covers.ts cursor
title = "PocketJS Cursor"
xmb_icon_png = "icon0.png"
xmb_background_png = "pic1.png"
Binary file added apps/cursor/psp/icon0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/cursor/psp/pic1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/cursor/vita/sce_sys/livearea/contents/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/hero/psp/pic1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/hero/vita/sce_sys/livearea/contents/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/im/vita/sce_sys/livearea/contents/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions apps/motions/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Show, createSignal } from "solid-js";
import type { JSX } from "solid-js";
import { Image, Text, View } from "@pocketjs/framework/components";
import { onButtonPress } from "@pocketjs/framework/lifecycle";
import { createGesture } from "@pocketjs/framework/gesture";
import { BTN } from "@pocketjs/framework/input";

// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -654,8 +655,19 @@ const PAGES: PageDef[] = [
export default function Motions() {
const [index, setIndex] = createSignal(0);
const page = () => PAGES[index()];
onButtonPress(BTN.RIGHT | BTN.RTRIGGER, () => setIndex((i) => (i + 1) % PAGES.length));
onButtonPress(BTN.LEFT | BTN.LTRIGGER, () => setIndex((i) => (i + PAGES.length - 1) % PAGES.length));
const next = () => setIndex((i) => (i + 1) % PAGES.length);
const prev = () => setIndex((i) => (i + PAGES.length - 1) % PAGES.length);
onButtonPress(BTN.RIGHT | BTN.RTRIGGER, next);
onButtonPress(BTN.LEFT | BTN.LTRIGGER, prev);
// Touch: the paging idiom is a horizontal swipe anywhere on the deck —
// swipe left = forward, matching the L/R buttons (docs/TOUCH.md §3).
createGesture({
axis: "x",
onPanEnd: (c) => {
if (c.dx <= -40 || c.vx <= -300) next();
else if (c.dx >= 40 || c.vx >= 300) prev();
},
});
return (
<View debugName="MotionsScreen" class="w-full h-full bg-[#191919]">
<View debugName="Header" class="absolute left-0 top-[1] w-full flex-row justify-between px-[8]">
Expand Down
7 changes: 7 additions & 0 deletions apps/motions/psp/Psp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# XMB metadata for the PocketJS Motions EBOOT. tools/psp.ts copies this to
# hosts/psp/Psp.toml when building this demo (any framework); cargo-psp packs
# it into PARAM.SFO / ICON0 / PIC1.
# Regenerate the art with: bun tools/gen-demo-covers.ts motions
title = "PocketJS Motions"
xmb_icon_png = "icon0.png"
xmb_background_png = "pic1.png"
Binary file added apps/motions/psp/icon0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/motions/psp/pic1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/music/vita/sce_sys/livearea/contents/bg.png
14 changes: 12 additions & 2 deletions apps/stats/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { createMemo, createSignal, onMount, Show } from "solid-js";
import { Text, View, type NodeMirror } from "@pocketjs/framework/components";
import { animate } from "@pocketjs/framework/animation";
import { onButtonPress, onFrame } from "@pocketjs/framework/lifecycle";
import { createGesture } from "@pocketjs/framework/gesture";
import { BTN } from "@pocketjs/framework/input";

const COUNT_FRAMES = 75;
Expand Down Expand Up @@ -161,11 +162,20 @@ export default function Stats() {
const [tab, setTab] = createSignal(0);
const [systemsFrame, setSystemsFrame] = createSignal(0);

onButtonPress(BTN.RIGHT, () => {
const toSystems = () => {
setTab(1);
setSystemsFrame(0);
});
};
onButtonPress(BTN.RIGHT, toSystems);
onButtonPress(BTN.LEFT, () => setTab(0));
// Touch: swipe between the two boards, mirroring LEFT/RIGHT.
createGesture({
axis: "x",
onPanEnd: (c) => {
if (c.dx <= -40 || c.vx <= -300) toSystems();
else if (c.dx >= 40 || c.vx >= 300) setTab(0);
},
});
onFrame(() => {
if (frameN() < COUNT_FRAMES) setFrameN(frameN() + 1);
if (tab() === 1 && systemsFrame() < SYSTEMS_MAX_FRAMES) {
Expand Down
Binary file added apps/stats/vita/sce_sys/livearea/contents/bg.png
7 changes: 7 additions & 0 deletions apps/zoomlab/psp/Psp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# XMB metadata for the PocketJS ZoomLab EBOOT. tools/psp.ts copies this to
# hosts/psp/Psp.toml when building this demo (any framework); cargo-psp packs
# it into PARAM.SFO / ICON0 / PIC1.
# Regenerate the art with: bun tools/gen-demo-covers.ts zoomlab
title = "PocketJS ZoomLab"
xmb_icon_png = "icon0.png"
xmb_background_png = "pic1.png"
Binary file added apps/zoomlab/psp/icon0.png
Binary file added apps/zoomlab/psp/pic1.png
24 changes: 24 additions & 0 deletions tests/golden-specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,30 @@ export const GOLDEN_SPECS: GoldenSpec[] = [
return [];
},
},
{
// The motions pager swipe with a REAL THUMB's profile: the landing
// wobbles vertically before the horizontal sweep builds — the exact
// arc that exposed the single-shot axis verdict on hardware (a pure
// scripted line passed everywhere while devices never paged). f40 =
// page 1; f100 = page 2 reached through the deferred-dominance claim.
name: "motions-swipe",
app: "motions-main",
frames: 110,
capture: [40, 100],
input: () => 0,
touch: (f) => {
if (f >= 60 && f < 68) {
const i = f - 60;
// Frame 1 after the down moves 8px DOWN and only 2 across — the
// wrong axis crosses slop first, exactly like a landing thumb.
// The horizontal sweep takes over from frame 2.
const x = i <= 1 ? 360 - i * 2 : 358 - (i - 1) * 34;
const y = i <= 1 ? 140 + i * 8 : 148 + i;
return [{ id: 0, x, y }];
}
return [];
},
},
];

export function encodeThresholdInput(spec: GoldenSpec): string {
Expand Down
15 changes: 15 additions & 0 deletions tests/sim.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ describe("the virtual clock", () => {
});
});

describe("touch activation reaches the demo fleet", () => {
test("hero: taps on the button increment the count", async () => {
// The button is a bare Focusable with onPress — no touch code in the
// app. Each tap rides its hit fact into the default activation
// recognizer (docs/TOUCH.md §0) exactly like CIRCLE does. Four taps
// cross the count>3 gate, mounting an unambiguous beacon line.
const taps = [0.5, 0.7, 0.9, 1.1].flatMap((at, i) => [
{ at, touch: [{ id: i + 1, x: 70, y: 234 }] },
{ at: at + 0.1, touch: [] },
]);
const t = await runScenario({ app: "hero-main", hz: 60, seconds: 2, script: taps });
expect(treeHasText(t.tree, "Reactive on real hardware.")).toBe(true);
});
});

describe("the journey actually happened", () => {
test("order placed, cart reset, world settled", () => {
// The trace's tree probe (a DevTools getTree after the final frame) is
Expand Down
Loading