Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 38x 20x 20x 263x 263x 263x 263x 263x 358x 358x 358x 358x 48x 29x 29x 29x 29x 29x 54x 12x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 8x 8x 8x 8x 40x 10x 7x 7x 54x 6x 44x 10x 10x 24x 24x 7x 3x 3x 44x | import { Fifo } from "./binary.js";
const PollHz = 8; // Made up
function doScale(val, scale, margin) {
val = (val - margin) / (1 - 2 * margin);
return val * scale;
}
export class TouchScreen {
constructor(scheduler, cyclesPerSecond) {
this.scheduler = scheduler;
this.pollCycles = cyclesPerSecond / PollHz;
this.outBuffer = new Fifo(16);
this.pollTask = this.scheduler.newTask(() => this.poll());
this.reset();
}
reset() {
this.mouse = { x: 0, y: 0, button: 0 };
this.mode = 0;
this.outBuffer.clear();
this.pollTask.cancel();
}
snapshotState() {
return {
mode: this.mode,
outBuffer: this.outBuffer.toArray(),
pollTaskOffset: this.pollTask.scheduled() ? this.pollTask.expireEpoch - this.scheduler.epoch : null,
};
}
restoreState(state) {
this.mode = state.mode;
this.outBuffer.clear();
for (const byte of state.outBuffer) this.store(byte);
this.pollTask.cancel();
if (state.pollTaskOffset !== null) this.pollTask.schedule(state.pollTaskOffset);
}
tryReceive(rts) {
if (this.outBuffer.size && rts) return this.outBuffer.get();
return -1;
}
doRead() {
const scaleX = 120,
marginX = 0.13;
const scaleY = 100,
marginY = 0.03;
const scaledX = doScale(this.mouse.x, scaleX, marginX);
const scaledY = doScale(1 - this.mouse.y, scaleY, marginY);
const toSend = [0x4f, 0x4f, 0x4f, 0x4f];
const x = Math.min(255, Math.max(0, scaledX)) | 0;
const y = Math.min(255, Math.max(0, scaledY)) | 0;
if (this.mouse.button) {
toSend[0] = 0x40 | ((x & 0xf0) >>> 4);
toSend[1] = 0x40 | (x & 0x0f);
toSend[2] = 0x40 | ((y & 0xf0) >>> 4);
toSend[3] = 0x40 | (y & 0x0f);
}
for (let i = 0; i < 4; ++i) this.store(toSend[i]);
this.store(".".charCodeAt(0));
}
poll() {
this.doRead();
this.pollTask.reschedule(this.pollCycles);
}
store(byte) {
this.outBuffer.put(byte);
}
onMouse(x, y, button) {
this.mouse = { x: x, y: y, button: button };
}
onTransmit(val) {
switch (String.fromCharCode(val)) {
case "M":
this.mode = 0;
break;
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
this.mode = 10 * this.mode + val - "0".charCodeAt(0);
break;
case ".":
break;
case "?":
Eif (this.mode === 1) this.doRead();
break;
}
this.pollTask.ensureScheduled(this.mode === 129 || this.mode === 130, this.pollCycles);
}
}
|