Basic tests
30
js/canvas.ts
|
@ -328,24 +328,20 @@ export class LoresPage2D implements LoresPage {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (!this.vm._80colMode && bank == 1) {
|
||||
return;
|
||||
}
|
||||
if (this.vm._80colMode && !this.vm.an3State) {
|
||||
let offset = (col * 14 + (bank ? 0 : 1) * 7 + row * 560 * 8) * 4;
|
||||
if (this.vm._monoMode) {
|
||||
fore = whiteCol;
|
||||
back = blackCol;
|
||||
for (let jdx = 0; jdx < 8; jdx++) {
|
||||
let b = (jdx < 8) ? (val & 0x0f) : (val >> 4);
|
||||
let b = (jdx < 4) ? (val & 0x0f) : (val >> 4);
|
||||
b |= (b << 4);
|
||||
if (bank & 0x1) {
|
||||
b <<= 1;
|
||||
b |= (b << 8);
|
||||
if (col & 0x1) {
|
||||
b >>= 2;
|
||||
}
|
||||
for (let idx = 0; idx < 7; idx++) {
|
||||
const color = (b & 0x80) ? fore : back;
|
||||
const color = (b & 0x01) ? whiteCol : blackCol;
|
||||
this._drawHalfPixel(data, offset, color);
|
||||
b <<= 1;
|
||||
b >>= 1;
|
||||
offset += 4;
|
||||
}
|
||||
offset += 553 * 4;
|
||||
|
@ -359,28 +355,26 @@ export class LoresPage2D implements LoresPage {
|
|||
(val & 0x0f) : (val >> 4)];
|
||||
for (let idx = 0; idx < 7; idx++) {
|
||||
this._drawHalfPixel(data, offset, color);
|
||||
off += 4;
|
||||
offset += 4;
|
||||
}
|
||||
offset += 553 * 4;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (bank === 0) {
|
||||
let offset = (col * 14 + row * 560 * 8) * 4;
|
||||
|
||||
if (this.vm._monoMode) {
|
||||
fore = whiteCol;
|
||||
back = blackCol;
|
||||
for (let jdx = 0; jdx < 8; jdx++) {
|
||||
let b = (jdx < 4) ? (val & 0x0f) : (val >> 4);
|
||||
b |= (b << 4);
|
||||
b |= (b << 8);
|
||||
if (col & 0x1) {
|
||||
b <<= 2;
|
||||
b >>= 2;
|
||||
}
|
||||
for (let idx = 0; idx < 14; idx++) {
|
||||
const color = (b & 0x8000) ? fore : back;
|
||||
const color = (b & 0x0001) ? whiteCol : blackCol;
|
||||
this._drawHalfPixel(data, offset, color);
|
||||
b <<= 1;
|
||||
b >>= 1;
|
||||
offset += 4;
|
||||
}
|
||||
offset += 546 * 4;
|
||||
|
@ -906,6 +900,7 @@ export class VideoModes2D implements VideoModes {
|
|||
refresh() {
|
||||
this._refresh();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.textMode = true;
|
||||
this.mixedMode = false;
|
||||
|
@ -1153,6 +1148,7 @@ export class VideoModes2D implements VideoModes {
|
|||
} else {
|
||||
this.canvas.classList.remove('mono');
|
||||
}
|
||||
this._monoMode = on;
|
||||
this._refresh();
|
||||
}
|
||||
|
||||
|
|
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
@ -1,90 +1,260 @@
|
|||
/** @fileoverview Test for gl.ts. */
|
||||
|
||||
import { generateImage } from 'jsdom-screenshot';
|
||||
import { LoresPage2D, VideoModes2D } from 'js/canvas';
|
||||
import { VideoPage } from 'js/videomodes';
|
||||
import { LoresPage2D, HiresPage2D, VideoModes2D } from 'js/canvas';
|
||||
import apple2enh_char from 'js/roms/apple2enh_char';
|
||||
import { createImageFromImageData } from 'test/util/image';
|
||||
|
||||
describe('LoresPage', () => {
|
||||
let canvas: HTMLCanvasElement;
|
||||
let lores1: LoresPage2D;
|
||||
let vm: VideoModes2D;
|
||||
async function checkImageData(page: VideoPage) {
|
||||
const img = createImageFromImageData(page.imageData);
|
||||
document.body.appendChild(img);
|
||||
const screen = await generateImage();
|
||||
img.remove();
|
||||
|
||||
beforeEach(() => {
|
||||
canvas = document.createElement('canvas');
|
||||
vm = new VideoModes2D(canvas, true);
|
||||
lores1 = new LoresPage2D(vm, 1, apple2enh_char, true);
|
||||
vm.reset();
|
||||
});
|
||||
expect(screen).toMatchImageSnapshot();
|
||||
}
|
||||
|
||||
describe('text mode', () => {
|
||||
describe('40 column', () => {
|
||||
it('renders', async () => {
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
lores1.write(page, off, off);
|
||||
describe('canvas', () => {
|
||||
describe('LoresPage', () => {
|
||||
let canvas: HTMLCanvasElement;
|
||||
let lores1: LoresPage2D;
|
||||
let vm: VideoModes2D;
|
||||
|
||||
beforeEach(() => {
|
||||
canvas = document.createElement('canvas');
|
||||
vm = new VideoModes2D(canvas, true);
|
||||
lores1 = new LoresPage2D(vm, 1, apple2enh_char, true);
|
||||
vm.reset();
|
||||
vm.hires(false);
|
||||
});
|
||||
|
||||
describe('text mode', () => {
|
||||
describe('40 column', () => {
|
||||
it('renders', async () => {
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
lores1.write(page, off, off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const img = createImageFromImageData(lores1.imageData);
|
||||
document.body.appendChild(img);
|
||||
const screen = await generateImage();
|
||||
expect(screen).toMatchImageSnapshot();
|
||||
img.remove();
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
|
||||
it('renders alt chars', async () => {
|
||||
vm.altChar(true);
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
lores1.write(page, off, off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders alt chars', async () => {
|
||||
vm.altChar(true);
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
lores1.write(page, off, off);
|
||||
describe('80 column', () => {
|
||||
it('renders', async () => {
|
||||
vm._80col(true);
|
||||
const bank0 = lores1.bank0();
|
||||
const bank1 = lores1.bank1();
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
bank0.write(page, off, off);
|
||||
bank1.write(page, off, 255 - off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const img = createImageFromImageData(lores1.imageData);
|
||||
document.body.appendChild(img);
|
||||
const screen = await generateImage();
|
||||
expect(screen).toMatchImageSnapshot();
|
||||
img.remove();
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
|
||||
it('renders alt chars', async () => {
|
||||
vm.altChar(true);
|
||||
vm._80col(true);
|
||||
const bank0 = lores1.bank0();
|
||||
const bank1 = lores1.bank1();
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
bank0.write(page, off, off);
|
||||
bank1.write(page, off, 255 - off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('80 column', () => {
|
||||
it('renders', async () => {
|
||||
vm._80col(true);
|
||||
const bank0 = lores1.bank0();
|
||||
const bank1 = lores1.bank1();
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
bank0.write(page, off, off);
|
||||
bank1.write(page, off, 255 - off);
|
||||
describe('graphics mode', () => {
|
||||
describe('lores', () => {
|
||||
it('renders', async () => {
|
||||
vm.text(false);
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
lores1.write(page, off, off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const img = createImageFromImageData(lores1.imageData);
|
||||
document.body.appendChild(img);
|
||||
const screen = await generateImage();
|
||||
expect(screen).toMatchImageSnapshot();
|
||||
img.remove();
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
|
||||
it('renders mixed', async () => {
|
||||
vm.text(false);
|
||||
vm.mixed(true);
|
||||
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
lores1.write(page, off, off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
|
||||
it('renders mono', async () => {
|
||||
vm.text(false);
|
||||
vm.mono(true);
|
||||
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
lores1.write(page, off, off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders alt chars', async () => {
|
||||
vm.altChar(true);
|
||||
describe('double lores', () => {
|
||||
it('renders', async () => {
|
||||
vm.text(false);
|
||||
vm._80col(true);
|
||||
vm.an3(false);
|
||||
|
||||
const bank0 = lores1.bank0();
|
||||
const bank1 = lores1.bank1();
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
bank0.write(page, off, off);
|
||||
bank1.write(page, off, 255 - off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
|
||||
it('renders mixed', async () => {
|
||||
vm.text(false);
|
||||
vm.mixed(true);
|
||||
vm._80col(true);
|
||||
vm.an3(false);
|
||||
|
||||
const bank0 = lores1.bank0();
|
||||
const bank1 = lores1.bank1();
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
bank0.write(page, off, off);
|
||||
bank1.write(page, off, 255 - off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
|
||||
it('renders mono', async () => {
|
||||
vm.text(false);
|
||||
vm._80col(true);
|
||||
vm.an3(false);
|
||||
vm.mono(true);
|
||||
|
||||
const bank0 = lores1.bank0();
|
||||
const bank1 = lores1.bank1();
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
bank0.write(page, off, off);
|
||||
bank1.write(page, off, 255 - off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(lores1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('HiresPage', () => {
|
||||
let canvas: HTMLCanvasElement;
|
||||
let hires1: HiresPage2D;
|
||||
let vm: VideoModes2D;
|
||||
|
||||
beforeEach(() => {
|
||||
canvas = document.createElement('canvas');
|
||||
vm = new VideoModes2D(canvas, true);
|
||||
hires1 = new HiresPage2D(vm, 1);
|
||||
vm.reset();
|
||||
vm.hires(true);
|
||||
});
|
||||
|
||||
describe('hires', () => {
|
||||
it('renders', async () => {
|
||||
vm.text(false);
|
||||
for (let page = 0x20; page < 0x40; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
hires1.write(page, off, off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(hires1);
|
||||
});
|
||||
|
||||
it('renders mono', async () => {
|
||||
vm.text(false);
|
||||
vm.mono(true);
|
||||
|
||||
for (let page = 0x20; page < 0x40; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
hires1.write(page, off, off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(hires1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('double lores', () => {
|
||||
it('renders', async () => {
|
||||
vm.text(false);
|
||||
vm._80col(true);
|
||||
const bank0 = lores1.bank0();
|
||||
const bank1 = lores1.bank1();
|
||||
for (let page = 0x4; page < 0x8; page++) {
|
||||
vm.an3(false);
|
||||
|
||||
const bank0 = hires1.bank0();
|
||||
const bank1 = hires1.bank1();
|
||||
for (let page = 0x20; page < 0x40; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
bank0.write(page, off, off);
|
||||
bank1.write(page, off, 255 - off);
|
||||
}
|
||||
}
|
||||
|
||||
const img = createImageFromImageData(lores1.imageData);
|
||||
document.body.appendChild(img);
|
||||
const screen = await generateImage();
|
||||
expect(screen).toMatchImageSnapshot();
|
||||
img.remove();
|
||||
await checkImageData(hires1);
|
||||
});
|
||||
|
||||
it('renders mono', async () => {
|
||||
vm.text(false);
|
||||
vm._80col(true);
|
||||
vm.an3(false);
|
||||
vm.mono(true);
|
||||
|
||||
const bank0 = hires1.bank0();
|
||||
const bank1 = hires1.bank1();
|
||||
for (let page = 0x20; page < 0x40; page++) {
|
||||
for (let off = 0; off < 0x100; off++) {
|
||||
bank0.write(page, off, off);
|
||||
bank1.write(page, off, 255 - off);
|
||||
}
|
||||
}
|
||||
|
||||
await checkImageData(hires1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|