mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
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;
|
private highColorTextMode = false;
|
||||||
|
|
||||||
dirty: Region = {...notDirty};
|
dirty: Region = { ...notDirty };
|
||||||
imageData: ImageData;
|
imageData: ImageData;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -485,7 +485,7 @@ export class LoresPage2D implements LoresPage {
|
||||||
|
|
||||||
export class HiresPage2D implements HiresPage {
|
export class HiresPage2D implements HiresPage {
|
||||||
public imageData: ImageData;
|
public imageData: ImageData;
|
||||||
dirty: Region = {...notDirty};
|
dirty: Region = { ...notDirty };
|
||||||
|
|
||||||
private _buffer: memory[] = [];
|
private _buffer: memory[] = [];
|
||||||
private _refreshing = false;
|
private _refreshing = false;
|
||||||
|
@ -604,7 +604,7 @@ export class HiresPage2D implements HiresPage {
|
||||||
if (x > this.dirty.right) { this.dirty.right = x; }
|
if (x > this.dirty.right) { this.dirty.right = x; }
|
||||||
|
|
||||||
dy = rowa << 4 | rowb << 1;
|
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) {
|
if (this.oneSixtyMode && !this.vm.monoMode) {
|
||||||
// 1 byte = two pixels, but 3:4 ratio
|
// 1 byte = two pixels, but 3:4 ratio
|
||||||
const c3 = val & 0xf;
|
const c3 = val & 0xf;
|
||||||
|
@ -643,8 +643,8 @@ export class HiresPage2D implements HiresPage {
|
||||||
((b2 & 0x40) >> 6) | ((b3 & 0x07) << 1), // 5
|
((b2 & 0x40) >> 6) | ((b3 & 0x07) << 1), // 5
|
||||||
((b3 & 0x78) >> 3), // 6
|
((b3 & 0x78) >> 3), // 6
|
||||||
0
|
0
|
||||||
], // 7
|
]; // 7
|
||||||
hb = [
|
const hb = [
|
||||||
0,
|
0,
|
||||||
b0 & 0x80, // 0
|
b0 & 0x80, // 0
|
||||||
b0 & 0x80, // 1
|
b0 & 0x80, // 1
|
||||||
|
@ -1092,8 +1092,8 @@ export class VideoModes2D implements VideoModes {
|
||||||
gr.imageData, gr.dirty
|
gr.imageData, gr.dirty
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
hgr.dirty = {...notDirty};
|
hgr.dirty = { ...notDirty };
|
||||||
gr.dirty = {...notDirty};
|
gr.dirty = { ...notDirty };
|
||||||
|
|
||||||
return blitted;
|
return blitted;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
import { HiresPage2D, LoresPage2D, VideoModes2D } from 'js/canvas';
|
||||||
import { h, Fragment } from 'preact';
|
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 { Modal, ModalContent, ModalFooter } from '../Modal';
|
||||||
|
|
||||||
import styles from './css/FileViewer.module.css';
|
import styles from './css/FileViewer.module.css';
|
||||||
|
@ -15,6 +16,35 @@ export interface FileViewerProps {
|
||||||
onClose: () => void;
|
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) => {
|
export const FileViewer = ({ fileData, onClose }: FileViewerProps) => {
|
||||||
const [binaryHref, setBinaryHref] = useState('');
|
const [binaryHref, setBinaryHref] = useState('');
|
||||||
const [textHref, setTextHref] = useState('');
|
const [textHref, setTextHref] = useState('');
|
||||||
|
@ -41,15 +71,18 @@ export const FileViewer = ({ fileData, onClose }: FileViewerProps) => {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { fileName, text } = fileData;
|
const { fileName, text, binary } = fileData;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal isOpen={true} onClose={onClose} title={fileName}>
|
<Modal isOpen={true} onClose={onClose} title={fileName}>
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
<pre className={styles.fileViewer} tabIndex={-1} >
|
<div className={styles.fileViewer}>
|
||||||
{text}
|
<HiresPreview binary={binary} />
|
||||||
</pre>
|
<pre className={styles.textViewer} tabIndex={-1} >
|
||||||
|
{text}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<a
|
<a
|
||||||
|
|
|
@ -1,10 +1,28 @@
|
||||||
.fileViewer {
|
.fileViewer {
|
||||||
background: white;
|
|
||||||
font: monospace;
|
|
||||||
width: 60em;
|
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;
|
padding: 1em;
|
||||||
height: 60vh;
|
height: 60vh;
|
||||||
|
line-height: 1em;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
border: 2px inset #f0edd0;
|
border: 2px inset #f0edd0;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hiresPreview {
|
||||||
|
border: 2px inset #f0edd0;
|
||||||
|
width: 560px;
|
||||||
|
height: 384px;
|
||||||
|
min-width: 560px;
|
||||||
|
min-height: 384px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user