71 lines
2.8 KiB
TypeScript
71 lines
2.8 KiB
TypeScript
import Endian from '/endian';
|
|
import {MIN_WIDTH, MIN_HEIGHT, PACKET_ID_HELLO, PACKET_ID_SEND_FRAME, PACKET_ID_KEY_DOWN} from '/constants';
|
|
|
|
function concatU8Array(array1: Uint8Array, array2: Uint8Array) {
|
|
const final_array = new Uint8Array(array1.length + array2.length);
|
|
final_array.set(array1);
|
|
final_array.set(array2, array1.length);
|
|
return final_array;
|
|
}
|
|
|
|
export function sendHello(websocket: WebSocket, rom_array: Uint8Array, savestate_array: Uint8Array) {
|
|
console.log('Sending hello.');
|
|
const length_rom = BigInt(rom_array.length);
|
|
const length_savestate = BigInt(savestate_array.length);
|
|
const raw_data =
|
|
concatU8Array(
|
|
concatU8Array(
|
|
concatU8Array(Endian.u64ToByteArrayBigEndian(length_rom), rom_array),
|
|
Endian.u64ToByteArrayBigEndian(length_savestate)
|
|
),
|
|
savestate_array
|
|
);
|
|
sendPacket(websocket, PACKET_ID_HELLO, raw_data);
|
|
}
|
|
|
|
export function sendKeyDown(websocket: WebSocket, isDown: boolean, key: number) {
|
|
console.log('Sending keyDown.', isDown);
|
|
const isDownArray = new Uint8Array(1);
|
|
isDownArray[0] = isDown ? 1: 0;
|
|
const rawData = concatU8Array(isDownArray, Endian.u32ToByteArrayBigEndian(key));
|
|
sendPacket(websocket, PACKET_ID_KEY_DOWN, rawData);
|
|
}
|
|
|
|
export function sendPacket(websocket: WebSocket, id: bigint, raw_data: Uint8Array) {
|
|
const packet_u8 = concatU8Array(
|
|
concatU8Array(Endian.u64ToByteArrayBigEndian(id), Endian.u64ToByteArrayBigEndian(BigInt(raw_data.length))),
|
|
raw_data
|
|
);
|
|
const packet_buffer = packet_u8.buffer;
|
|
console.log('Sending packet');
|
|
websocket.send(packet_buffer);
|
|
}
|
|
|
|
export function handleSendFrame(raw_data: Uint8Array, canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, printingFrame: boolean, setPrintingFrame: (c: boolean) => void) {
|
|
if (printingFrame) {
|
|
return;
|
|
}
|
|
setPrintingFrame(true);
|
|
let data: Uint8Array | null = raw_data;
|
|
const stride = Endian.byteArrayToU32BigEndian(data.slice(0, 4));
|
|
data = data.slice(4, data.length);
|
|
const output_buffer_size = Endian.byteArrayToU64BigEndian(data.slice(0, 8));
|
|
data = data.slice(8, data.length);
|
|
const img_data = ctx.createImageData(MIN_WIDTH, MIN_HEIGHT);
|
|
const img_data_u8 = new Uint8Array(img_data.data.buffer);
|
|
for (let i = 0; i<data.length; i++) {
|
|
if (i % 4 == 3) {
|
|
img_data_u8[i] = 255;
|
|
continue;
|
|
}
|
|
img_data_u8[i] = data[i];
|
|
}
|
|
data = null;
|
|
createImageBitmap(img_data).then((bitmap) => drawBitmap(bitmap, canvas, ctx, printingFrame));
|
|
}
|
|
|
|
function drawBitmap(bitmap: ImageBitmap, canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, printingFrame: boolean) {
|
|
ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
|
|
printingFrame = false;
|
|
}
|