feat: improve RenPy conversion and support MIST runtime
This commit is contained in:
1 parent
f7f7f5b1b3
commit
f9eb5c1212
44 files changed
+2822
-174
No files matched your search
@@ -0,0 +1,51 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { test } from "node:test";
|
||||
import ts from "typescript";
|
||||
import { parseHTML } from "linkedom";
|
||||
|
||||
const source = readFileSync(new URL("../src/player/movie.ts", import.meta.url), "utf8");
|
||||
const { outputText } = ts.transpileModule(source, { compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext } });
|
||||
const { applyMovieMask, movieDisplayable } = await import(`data:text/javascript;base64,${Buffer.from(outputText).toString("base64")}`);
|
||||
|
||||
test("video opacity uses the mask's red channel and retains existing transparency", () => {
|
||||
const pixels = new Uint8ClampedArray([200, 10, 20, 255, 30, 40, 50, 128]);
|
||||
applyMovieMask(pixels, new Uint8ClampedArray([0, 255, 255, 255, 128, 0, 0, 255]));
|
||||
assert.deepEqual([...pixels], [200, 10, 20, 0, 30, 40, 50, 64]);
|
||||
});
|
||||
|
||||
test("masked movie composites frames, synchronizes the mask and stops when removed", () => {
|
||||
const { document } = parseHTML("<!doctype html><html><body></body></html>");
|
||||
globalThis.document = document;
|
||||
const create = document.createElement.bind(document);
|
||||
const videos = [], frames = [], painted = [];
|
||||
let canvases = 0;
|
||||
globalThis.requestAnimationFrame = (callback) => frames.push(callback);
|
||||
document.createElement = (name) => {
|
||||
const element = create(name);
|
||||
if (name === "video") {
|
||||
Object.assign(element, { readyState: 2, videoWidth: 2, videoHeight: 1, currentTime: 0, ended: false,
|
||||
play: () => Promise.resolve(), pause: () => { element.paused = true; } });
|
||||
videos.push(element);
|
||||
}
|
||||
if (name === "canvas") {
|
||||
const mask = canvases++ > 0;
|
||||
element.getContext = () => ({ clearRect() {}, drawImage() {},
|
||||
getImageData: () => ({ data: new Uint8ClampedArray(mask
|
||||
? [0, 0, 0, 255, 128, 128, 128, 255] : [200, 10, 20, 255, 30, 40, 50, 255]) }),
|
||||
putImageData: (image) => painted.push([...image.data]),
|
||||
});
|
||||
}
|
||||
return element;
|
||||
};
|
||||
const canvas = movieDisplayable("/movie.webm", "/mask.webm", false);
|
||||
document.body.append(canvas);
|
||||
videos[1].currentTime = 2;
|
||||
frames.shift()();
|
||||
assert.deepEqual(painted[0], [200, 10, 20, 0, 30, 40, 50, 128]);
|
||||
assert.equal(videos[1].currentTime, 0);
|
||||
canvas.remove();
|
||||
frames.shift()();
|
||||
assert.ok(videos.every((video) => video.paused));
|
||||
assert.equal(frames.length, 0);
|
||||
});
|
||||
Reference in new issue
Block a user