import { h } from 'preact'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; import cs from 'classnames'; import { Apple2 as Apple2Impl } from 'js/apple2'; import { VideoPage } from 'js/videomodes'; import styles from './css/VideoModes.module.scss'; import debuggerStyles from './css/Debugger.module.scss'; export interface VideoModesProps { apple2: Apple2Impl | undefined; } const blit = (page: VideoPage, canvas: HTMLCanvasElement | null) => { if (canvas) { const context = canvas.getContext('2d'); if (context) { context.putImageData(page.imageData, 0, 0); } } }; export const VideoModes = ({ apple2 }: VideoModesProps) => { const [text, setText] = useState(false); const [hires, setHires] = useState(false); const [page2, setPage2] = useState(false); const canvas1 = useRef(null); const canvas2 = useRef(null); const canvas3 = useRef(null); const canvas4 = useRef(null); const animationRef = useRef(0); const animate = useCallback(() => { if (apple2) { const vm = apple2.getVideoModes(); const text = vm.isText(); const hires = vm.isHires(); const page2 = vm.isPage2(); vm.getLoresPage(1).refresh(); vm.getLoresPage(2).refresh(); vm.getHiresPage(1).refresh(); vm.getHiresPage(2).refresh(); blit(vm.getLoresPage(1), canvas1.current); blit(vm.getLoresPage(2), canvas2.current); blit(vm.getHiresPage(1), canvas3.current); blit(vm.getHiresPage(2), canvas4.current); setText(text); setHires(hires); setPage2(page2); } animationRef.current = requestAnimationFrame(animate); }, [apple2]); useEffect(() => { animationRef.current = requestAnimationFrame(animate); return () => cancelAnimationFrame(animationRef.current); }, [animate]); return (
Text/Lores Page 1
Text/Lores Page 2
Hires Page 1
Hires Page 2
); };