summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bedrock.js64
1 files changed, 36 insertions, 28 deletions
diff --git a/bedrock.js b/bedrock.js
index d9811c1..aae3977 100644
--- a/bedrock.js
+++ b/bedrock.js
@@ -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++) {