Arduino 에뮬레이터: OLED 2x 렌더링으로 교체 — CSS 스케일링 의존 제거
aspect-ratio:2/1 미지원 브라우저에서 캔버스가 64px 자연 높이로 렌더링되어 가로로만 늘어나 '줄만 몇 개'로 보이는 버그 수정. - canvas 128×64 → 256×128 (물리 픽셀 2배) - JS 렌더러: 논리 픽셀 1개 → 2×2 물리 픽셀로 직접 기록 - CSS: image-rendering:pixelated + aspect-ratio 제거 → max-width:100%; height:auto 로 브라우저 자연 스케일링 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -58,7 +58,7 @@
|
||||
.oled-dot { width:6px; height:6px; border-radius:50%; background:#333; flex-shrink:0; }
|
||||
.oled-dot.on { background:#60a5fa; box-shadow:0 0 4px #60a5fa; }
|
||||
.oled-wrap { background:#000; border:2px solid #222; border-radius:4px; padding:4px; position:relative; }
|
||||
#oled-canvas { display:block; image-rendering:pixelated; width:100%; aspect-ratio:2/1; }
|
||||
#oled-canvas { display:block; max-width:100%; height:auto; }
|
||||
.oled-placeholder { position:absolute; inset:4px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px; pointer-events:none; }
|
||||
.oled-placeholder span { font-size:10px; color:#333; letter-spacing:.05em; }
|
||||
.oled-placeholder .oled-ph-grid { width:100%; height:2px; background:repeating-linear-gradient(90deg,#1a1a1a 0,#1a1a1a 4px,transparent 4px,transparent 8px); }
|
||||
@@ -179,7 +179,7 @@
|
||||
SSD1306 OLED 128×64
|
||||
</div>
|
||||
<div class="oled-wrap">
|
||||
<canvas id="oled-canvas" width="128" height="64"></canvas>
|
||||
<canvas id="oled-canvas" width="256" height="128"></canvas>
|
||||
<div class="oled-placeholder" id="oled-placeholder">
|
||||
<div class="oled-ph-grid"></div>
|
||||
<span>OLED 연결 대기</span>
|
||||
@@ -455,20 +455,26 @@ function oledReset() {
|
||||
function oledFlushCanvas() {
|
||||
if (!oledCtx || !oledDirty) return;
|
||||
oledDirty = false;
|
||||
const img = oledCtx.createImageData(128, 64);
|
||||
const fg = oled.inverse ? 0 : 255;
|
||||
const bg = oled.inverse ? 255 : 0;
|
||||
// 2x 렌더링: 캔버스 256×128, 논리 픽셀 1개 = 2×2 물리 픽셀
|
||||
const img = oledCtx.createImageData(256, 128);
|
||||
for (let page = 0; page < 8; page++) {
|
||||
for (let col = 0; col < 128; col++) {
|
||||
const byte = oled.gddram[page * 128 + col];
|
||||
for (let bit = 0; bit < 8; bit++) {
|
||||
const row = page * 8 + bit;
|
||||
const idx = (row * 128 + col) * 4;
|
||||
const on = (byte >> bit) & 1;
|
||||
img.data[idx] = on ? fg : bg;
|
||||
img.data[idx + 1] = on ? (oled.inverse ? 0 : 0x62) : bg; // slight blue tint when on
|
||||
img.data[idx + 2] = on ? (oled.inverse ? 0 : 0xff) : bg;
|
||||
img.data[idx + 3] = 255;
|
||||
const row = page * 8 + bit;
|
||||
const pr = on ? (oled.inverse ? 0 : 0xff) : 0;
|
||||
const pg = on ? (oled.inverse ? 0 : 0x5a) : 0;
|
||||
const pb = on ? 0xff : 0;
|
||||
for (let dy = 0; dy < 2; dy++) {
|
||||
for (let dx = 0; dx < 2; dx++) {
|
||||
const idx = ((row * 2 + dy) * 256 + (col * 2 + dx)) * 4;
|
||||
img.data[idx] = pr;
|
||||
img.data[idx + 1] = pg;
|
||||
img.data[idx + 2] = pb;
|
||||
img.data[idx + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -726,7 +732,9 @@ function initEmulator(hex) {
|
||||
totalCycles = 0;
|
||||
lcdReset();
|
||||
oledReset();
|
||||
oledCtx = document.getElementById('oled-canvas').getContext('2d');
|
||||
const oledCanvas = document.getElementById('oled-canvas');
|
||||
oledCtx = oledCanvas.getContext('2d');
|
||||
oledCtx.clearRect(0, 0, 256, 128);
|
||||
buildPinUI();
|
||||
|
||||
let lastD13 = -1;
|
||||
|
||||
Reference in New Issue
Block a user