Add hires preview (#146)
This commit is contained in:
parent
5170738ddc
commit
bf789eb2fd
14
js/canvas.ts
14
js/canvas.ts
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue