Add hires preview (#146)

This commit is contained in:
Will Scullin 2022-07-23 15:51:12 -07:00 committed by GitHub
parent 5170738ddc
commit bf789eb2fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 14 deletions

View File

@ -113,7 +113,7 @@ export class LoresPage2D implements LoresPage {
private highColorTextMode = false;
dirty: Region = {...notDirty};
dirty: Region = { ...notDirty };
imageData: ImageData;
constructor(
@ -485,7 +485,7 @@ export class LoresPage2D implements LoresPage {
export class HiresPage2D implements HiresPage {
public imageData: ImageData;
dirty: Region = {...notDirty};
dirty: Region = { ...notDirty };
private _buffer: memory[] = [];
private _refreshing = false;
@ -604,7 +604,7 @@ export class HiresPage2D implements HiresPage {
if (x > this.dirty.right) { this.dirty.right = x; }
dy = rowa << 4 | rowb << 1;
let bz, b0, b1, b2, b3, b4, c, hb;
let bz, b0, b1, b2, b3, b4, c;
if (this.oneSixtyMode && !this.vm.monoMode) {
// 1 byte = two pixels, but 3:4 ratio
const c3 = val & 0xf;
@ -643,8 +643,8 @@ export class HiresPage2D implements HiresPage {
((b2 & 0x40) >> 6) | ((b3 & 0x07) << 1), // 5
((b3 & 0x78) >> 3), // 6
0
], // 7
hb = [
]; // 7
const hb = [
0,
b0 & 0x80, // 0
b0 & 0x80, // 1
@ -1092,8 +1092,8 @@ export class VideoModes2D implements VideoModes {
gr.imageData, gr.dirty
);
}
hgr.dirty = {...notDirty};
gr.dirty = {...notDirty};
hgr.dirty = { ...notDirty };
gr.dirty = { ...notDirty };
return blitted;
}

View File

@ -1,5 +1,6 @@
import { HiresPage2D, LoresPage2D, VideoModes2D } from 'js/canvas';
import { h, Fragment } from 'preact';
import { useEffect, useState } from 'preact/hooks';
import { useEffect, useRef, useState } from 'preact/hooks';
import { Modal, ModalContent, ModalFooter } from '../Modal';
import styles from './css/FileViewer.module.css';
@ -15,6 +16,35 @@ export interface FileViewerProps {
onClose: () => void;
}
const HiresPreview = ({ binary }: { binary: Uint8Array }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
if (binary.byteLength < 8187 || binary.byteLength > 8192) {
return null;
}
if (canvasRef.current) {
const vm = new VideoModes2D(canvasRef.current, true);
const lores = new LoresPage2D(vm, 1, new Uint8Array(), false);
const hires = new HiresPage2D(vm, 1);
vm.setLoresPage(1, lores);
vm.setHiresPage(1, hires);
vm.text(false);
vm.hires(true);
vm.doubleHires(false);
vm.page(1);
for (let idx = 0; idx < 0x20; idx++) {
for (let jdx = 0; jdx < 0x100; jdx++) {
hires.write(idx + 0x20, jdx, binary[idx * 0x100 + jdx]);
}
}
vm.blit();
}
return <canvas ref={canvasRef} width={560} height={192} className={styles.hiresPreview} />;
};
export const FileViewer = ({ fileData, onClose }: FileViewerProps) => {
const [binaryHref, setBinaryHref] = useState('');
const [textHref, setTextHref] = useState('');
@ -41,15 +71,18 @@ export const FileViewer = ({ fileData, onClose }: FileViewerProps) => {
return null;
}
const { fileName, text } = fileData;
const { fileName, text, binary } = fileData;
return (
<>
<Modal isOpen={true} onClose={onClose} title={fileName}>
<ModalContent>
<pre className={styles.fileViewer} tabIndex={-1} >
{text}
</pre>
<div className={styles.fileViewer}>
<HiresPreview binary={binary} />
<pre className={styles.textViewer} tabIndex={-1} >
{text}
</pre>
</div>
</ModalContent>
<ModalFooter>
<a

View File

@ -1,10 +1,28 @@
.fileViewer {
background: white;
font: monospace;
width: 60em;
max-height: 60vh;
overflow-y: auto;
display: flex;
flex-direction: column;
align-items: center;
}
.textViewer {
background: white;
font-family: monospace;
width: 57em;
padding: 1em;
height: 60vh;
line-height: 1em;
overflow-y: auto;
border: 2px inset #f0edd0;
white-space: pre-wrap;
}
.hiresPreview {
border: 2px inset #f0edd0;
width: 560px;
height: 384px;
min-width: 560px;
min-height: 384px;
}