diff options
-rw-r--r-- | bedrock.js | 64 |
1 files changed, 36 insertions, 28 deletions
@@ -909,11 +909,17 @@ function Bedrock(emulatorElement, wasm=defaultToWasm) { } } + // Reveal and resize the canvas. + this.showScreen = () => { + this.e.showScreenPanel(); + // HACK: The screen panel isn't given a size until the next render tick, + // so we have to queue this function call for when Bedrock next yields + // control back to the browser. + setTimeout(() => { this.e.updateScreenSize() }, 0); + } + this.render = () => { if (this.e) { - if (this.dev.input.accessed || this.dev.screen.accessed) { - this.e.showScreenPanel(); - } let scr = this.dev.screen; if (scr.dirty()) { scr.render(); @@ -1426,7 +1432,6 @@ function InputDevice(br) { this.accessed = false; } this.read = function(p) { - this.accessed = true; switch (p) { case 0x0: this.xR = this.x; return getH(this.xR); case 0x1: return getL(this.xR); @@ -1445,10 +1450,12 @@ function InputDevice(br) { } } this.write = function(p,v) { - this.accessed = true; + // HACK: Interrupt the emulator loop to give canvas a chance to resize. + let s = 0; + if (!this.accessed) { br.showScreen(); s = -1; this.accessed = true; } switch (p) { - case 0xA: this.characterBytes.clear(); return; - default: return; + case 0xA: this.characterBytes.clear(); return s; + default: return s; } } this.wake = function() { @@ -1580,13 +1587,12 @@ function ScreenDevice(br) { this.sprite = new SpriteBuffer(); let initialWidth = Math.trunc(br.e.el.clientWidth / initialScreenScale); let initialHeight = Math.trunc(initialWidth * 9/16); - this.width = -1; // screen won't resize if dimensions aren't different + this.width = -1; // screen won't resize if dimensions haven't changed this.resize(initialWidth, initialHeight, initialScreenScale); this.wakeFlag = false; this.accessed = false; } this.read = function(p) { - this.accessed = true; switch (p) { case 0x0: return getH(this.x); case 0x1: return getL(this.x); @@ -1600,25 +1606,27 @@ function ScreenDevice(br) { } } this.write = function(p,v) { - this.accessed = true; + // HACK: Interrupt the emulator loop to give canvas a chance to resize. + let s = 0; + if (!this.accessed) { br.showScreen(); s = -1; this.accessed = true; } switch (p) { - case 0x0: this.x = setH(this.x, v); return; - case 0x1: this.x = setL(this.x, v); return; - case 0x2: this.y = setH(this.y, v); return; - case 0x3: this.y = setL(this.y, v); return; - case 0x4: this.widthW = setH(this.widthW, v); return; - case 0x5: this.widthW = setL(this.widthW, v); this.commitWidth(); return; - case 0x6: this.heightW = setH(this.heightW, v); return; - case 0x7: this.heightW = setL(this.heightW, v); this.commitHeight(); return; - case 0x8: this.paletteW = setH(this.paletteW, v); return; - case 0x9: this.paletteW = setL(this.paletteW, v); this.commitPalette(); return; - case 0xA: this.selection[0] = v >> 4; this.selection[1] = v & 0xF; return; - case 0xB: this.selection[2] = v >> 4; this.selection[3] = v & 0xF; return; + case 0x0: this.x = setH(this.x, v); return s; + case 0x1: this.x = setL(this.x, v); return s; + case 0x2: this.y = setH(this.y, v); return s; + case 0x3: this.y = setL(this.y, v); return s; + case 0x4: this.widthW = setH(this.widthW, v); return s; + case 0x5: this.widthW = setL(this.widthW, v); this.commitWidth(); return s; + case 0x6: this.heightW = setH(this.heightW, v); return s; + case 0x7: this.heightW = setL(this.heightW, v); this.commitHeight(); return s; + case 0x8: this.paletteW = setH(this.paletteW, v); return s; + case 0x9: this.paletteW = setL(this.paletteW, v); this.commitPalette(); return s; + case 0xA: this.selection[0] = v >> 4; this.selection[1] = v & 0xF; return s; + case 0xB: this.selection[2] = v >> 4; this.selection[3] = v & 0xF; return s; case 0xC: - case 0xD: this.sprite.push(v); return; - case 0xE: this.draw(v); return; - case 0xF: this.move(v); return; - default: return; + case 0xD: this.sprite.push(v); return s; + case 0xE: this.draw(v); return s; + case 0xF: this.move(v); return s; + default: return s; } } this.wake = function() { @@ -1642,14 +1650,14 @@ function ScreenDevice(br) { } // Check if the screen has a visible dirty region. this.dirty = function() { - // TODO: Does clamp pull a distant dirty region into the viewport? + // TODO: Does clamp pull distant dirty regions into the viewport? this.dx0 = clamp(this.dx0, 0, this.width); this.dx1 = clamp(this.dx1, 0, this.width); this.dy0 = clamp(this.dy0, 0, this.height); this.dy1 = clamp(this.dy1, 0, this.height); return this.dx1 > this.dx0 && this.dy1 > this.dy0; } - // Update the dirty region of this.pixels from fg and bg. + // Update the dirty region of this.pixels using fg and bg. this.render = function() { let dw = this.dx1 - this.dx0; for (let y=this.dy0; y<this.dy1; y++) { |