exl100

Émulateur Exelvision EXL 100 (1984) dans le navigateur : dsp-cpp en WebAssembly, cartouches et cassettes BASIC
git clone https://git.schurger.org/exl100.git
Log | Files | Refs | README

commit 83ae722193a12c86417efa52775fa090e15feb11
parent 3f982c043647492b54833ee96aded3b320eb558f
Author: Jean Schurger <jean@schurger.org>
Date:   Thu,  5 Nov 2026 16:50:49 -0500

Faces : la barre nomme la face en place (📂 Titre — Face A) et le bouton d'Ă©change dit « ⏏ InsĂ©rer Face B »

Le bouton đŸ“Œ Face B se lisait comme un Ă©tat (« la face B est chargĂ©e ») alors qu'il proposait l'insertion.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyJB9yqUAYm3wRQi4uytj9

Diffstat:
Mtest/tape-sides.mjs | 2+-
Mweb/shell.html.in | 17++++++++++++++---
2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/test/tape-sides.mjs b/test/tape-sides.mjs @@ -23,5 +23,5 @@ await page.evaluate("document.querySelector('#tape-sides button').click()"); await sleep(500); const after = await page.evaluate("({ status: document.getElementById('status').textContent, pick: document.getElementById('pick').textContent, buttons: [...document.querySelectorAll('#tape-sides button')].map((b) => b.textContent) })"); console.log('aprĂšs insertion :', JSON.stringify(after)); -console.log(buttons.length && /insĂ©rĂ©e/.test(after.status) && after.buttons.join() !== buttons.join() ? 'OK' : 'PROBLÈME'); +console.log(buttons.length && /dans le lecteur/.test(after.status) && after.buttons.join() !== buttons.join() ? 'OK' : 'PROBLÈME'); page.close(); diff --git a/web/shell.html.in b/web/shell.html.in @@ -64,6 +64,7 @@ .pg-b { color: var(--accent); font-size: .78rem; margin-left: 8px; } .pg-side { margin-left: 6px; background: #1f3f3f; color: var(--accent); border: 1px solid #2b5c5c; border-radius: 6px; font-size: .75rem; padding: 1px 7px; cursor: pointer; } .pg-side:hover { background: #2a5555; color: #fff; } + .pg-side.on { background: var(--accent); color: #000; border-color: var(--accent); } .pg-ins { margin-left: 8px; background: #2b2d35; color: #ddd; border: 1px solid #40434e; border-radius: 6px; font-size: .75rem; padding: 1px 6px; cursor: pointer; } .pg-ins:hover { background: #3a3d48; } #tape-sides { display: inline; } @@ -500,7 +501,15 @@ for (const el of programsEl.querySelectorAll('.pg')) { const on = el.dataset.value === value || (!!value && (el.dataset.sides || '').split(' ').includes(value)); el.classList.toggle('active', on); - if (on && value) title = el.dataset.title; + if (on && value) { + title = el.dataset.title; + // Programme Ă  plusieurs cassettes : la face lancĂ©e est surlignĂ©e et nommĂ©e dans la barre. + for (const sb of el.querySelectorAll('.pg-side')) { + const cur = sb.dataset.value === value; + sb.classList.toggle('on', cur); + if (cur) title += ' — ' + sb.textContent; + } + } } $('pick').textContent = title ? '📂 ' + title : '📂 Choisir un programme
'; } @@ -594,7 +603,7 @@ for (const sd of sides) { if (sd.f === file) continue; const b = document.createElement('button'); b.type = 'button'; b.className = 'pick-btn'; - b.textContent = 'đŸ“Œ ' + sd.l; + b.textContent = '⏏ InsĂ©rer ' + sd.l; // action, pas un Ă©tat : la face en place est dans le bouton 📂 b.title = 'InsĂ©rer « ' + sd.l + ' » sans redĂ©marrer, quand le programme la demande'; b.onclick = () => tapeInsert(sd.f, sd.l); box.appendChild(b); @@ -606,7 +615,8 @@ let ok = 0; try { ok = Module.ccall('dsp_web_tape_load', 'number', ['string'], ['/roms/tapes/' + file]); } catch (e) { ok = 0; } if (!ok) { statusEl.textContent = 'Impossible d’insĂ©rer « ' + label + ' » : lancez d’abord un programme sur cassette.'; return; } - statusEl.textContent = 'đŸ“Œ « ' + label + ' » insĂ©rĂ©e — reprenez le chargement quand le programme le demande (sinon LOAD"1" ⏎ puis Échap).'; + statusEl.textContent = 'đŸ“Œ « ' + label + ' » maintenant dans le lecteur — reprenez le chargement quand le programme le demande (sinon LOAD"1" ⏎ puis Échap).'; + markActive('tape:' + file); const sides = currentTape && currentTape.sides.some((x) => x.f === file) ? currentTape.sides : undefined; setTape(file, sides); } @@ -685,6 +695,7 @@ for (const sd of m.sides) { const sb = document.createElement('button'); sb.type = 'button'; sb.className = 'pg-side'; sb.textContent = sd.l; + sb.dataset.value = 'tape:' + sd.f; sb.title = 'DĂ©marrer sur « ' + sd.l + ' » (en cours de programme, insĂ©rez-la plutĂŽt avec le bouton đŸ“Œ de la barre)'; sb.onclick = (e) => { e.stopPropagation(); bootProgram('tape:' + sd.f); }; t.appendChild(sb);