Add native Crystal exploration port and reference tooling
Checks / web (push) Canceled after 0s

This commit is contained in:
Sébastien QUEROL committed 2026-09-23 09:23:29 +02:00
1 parent 2127f5f459
commit 8b80d05ca2
56 files changed
+6910 -1

No files matched your search

+55
View File
@@ -0,0 +1,55 @@
const key = (name: string, label: string, className = "") =>
`<button class="game-key ${className}" data-game-button="${name}" aria-label="${name === "a" || name === "b" ? name.toUpperCase() : name}" aria-pressed="false" disabled>${label}</button>`;
export function renderShell(root: HTMLElement) {
root.innerHTML = `
<header class="site-header">
<a class="brand" href="./" aria-label="Crystal home"><img src="${import.meta.env.BASE_URL}icon.svg" alt="" width="36" height="36">crystal<span>NATIVE WEB PORT</span></a>
<button id="help" class="text-button">How to play <span aria-hidden="true">↗</span></button>
</header>
<main>
<section class="intro" aria-labelledby="page-title">
<p class="eyebrow"><span class="small-star">✧</span> YOUR CARTRIDGE. A NEW HOME.</p>
<h1 id="page-title">A little adventure.<br><em>Anywhere.</em></h1>
<p class="intro-copy">Crystal, rebuilt for the web.<br> Start exploring New Bark Town in the first native milestone.</p>
<div class="load-card">
<div class="card-heading"><span class="step-number">01</span><h2>Bring your cartridge</h2></div>
<p>Pokémon Crystal<br><strong>English US/Europe · Revision 1.1</strong></p>
<div class="player-setup"><label>Name <input id="player-name" value="CHRIS" maxlength="7" pattern="[A-Za-z0-9 -]{1,7}" autocomplete="off"></label><label>Character <select id="player-avatar"><option value="chris">Chris</option><option value="kris">Kris</option></select></label><small>Used for your first session. Saved sessions keep their character.</small></div>
<label class="primary-button file-button" id="rom-label" for="rom-file"><span aria-hidden="true">+</span> Choose ROM <span aria-hidden="true">→</span></label>
<input id="rom-file" class="file-input" type="file" accept=".gbc,.gb,.rom,application/octet-stream" />
<p class="privacy-note"><span aria-hidden="true">◇</span> Opened locally. Never uploaded.</p>
</div>
<div class="project-note"><span class="note-line"></span><p>An exploration build, not the full game yet.<br><span>Move, enter buildings, read signs and try interactions. Story progression, battles and audio are next.</span></p></div>
</section>
<section class="play-area" aria-label="Game player">
<div class="console">
<div class="console-top"><span>NATIVE / EXPLORATION</span><span class="power"><i id="power-light"></i><span id="power-label">STANDBY</span></span></div>
<div class="screen-bezel">
<div class="screen">
<canvas id="game-screen" width="160" height="144" tabindex="0" aria-label="Game screen. Arrow keys move, X is A, Z is B, Enter is Start, Shift is Select."></canvas>
<div id="native-dialogue" class="native-dialogue" aria-label="Dialogue" hidden><p id="dialogue-text" aria-live="polite"></p><div><span id="dialogue-page"></span><button id="dialogue-next">Continue <span aria-hidden="true">▸</span></button></div></div>
<div id="screen-empty" class="screen-empty"><div class="crystal-mark" aria-hidden="true">◇</div><h2>Your next chapter<br>starts here.</h2><p>Load your Crystal ROM to begin.</p><span class="screen-dots" aria-hidden="true">· · ·</span></div>
<div id="pause-overlay" class="pause-overlay" hidden><span>PAUSED</span><button id="screen-resume">Continue playing →</button></div>
</div>
<div class="screen-caption"><span id="location">YOUR WORLD, REBUILT</span><span>160 × 144</span></div>
</div>
<div class="controls">
<div class="dpad" aria-label="Directional controls">${key("up", "▲")}${key("left", "◀")}<span class="dpad-center" aria-hidden="true"></span>${key("right", "▶")}${key("down", "▼")}</div>
<div class="action-keys">${key("b", "B")}${key("a", "A")}</div>
<div class="system-keys">${key("select", "SELECT")}${key("start", "START")}</div>
<div class="speaker" aria-hidden="true"><i></i><i></i><i></i><i></i></div>
</div>
<div class="console-bottom"><span>MADE FOR THE WAY YOU PLAY</span><span>✧</span></div>
</div>
<div class="player-toolbar" aria-label="Player actions"><button id="play" disabled>Play</button><button id="save" disabled>Save session</button><button id="backup" disabled>Export backup</button></div>
<p class="world-status"><span id="tiles-walked">0 tiles walked</span><span>Exploration build · Audio pending</span></p>
<p id="game-notice" role="status" class="game-notice"></p>
<p id="status" class="status" role="status" aria-live="polite">Ready when you are. Choose your ROM to get started.</p>
<p id="save-status" class="save-status">Session backups stay in this browser.</p>
<details class="save-tools"><summary>Save files & compatibility</summary><div><button id="import-save" disabled>Import native backup</button><input id="save-file" class="file-input" type="file" accept=".json" /><p>Native saves keep your character, position and completed interactions. They are separate from emulator snapshots and cartridge .sav files, which cannot be imported yet.</p><p>Time-of-day colors follow your device clock. The tile counter measures in-game movement, not real-world steps. Export a backup before clearing browser data.</p></div></details>
</section>
</main>
<footer><span>A personal cartridge, a pocket-sized world.</span><span>Independent project · No game assets included</span></footer>
<dialog id="help-dialog"><button id="close-help" class="dialog-close" aria-label="Close help">×</button><p class="eyebrow">NATIVE PORT · FIRST MILESTONE</p><h2>Make yourself at home.</h2><p>Choose your own English US/Europe revision 1.1 ROM, then press Play. Graphics, maps, sprites and dialogue are read locally from your ROM. Select it again after a reload to resume.</p><p>Explore your bedroom, downstairs, New Bark Town and its buildings. Use A to read signs, the radio and supported conversations. An unfinished interaction shows a message and leaves progress unchanged.</p><dl><dt>Move</dt><dd>Arrow keys</dd><dt>Interact / Continue</dt><dd>X / Z or A / B</dd></dl><p>Sessions save every 10 seconds and when paused. Download a backup before clearing browser data. Switching apps pauses play.</p><p>This is an exploration milestone. Opening scenes, story progression, battles, NPC movement, room decorations, audio and routes beyond town are not ported yet. Online Link and real-world steps come after the original game systems.</p></dialog>`;
}