-
Notifications
You must be signed in to change notification settings - Fork 0
/
assets.ts
87 lines (78 loc) · 3.07 KB
/
assets.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { asyncReplace } from "../util/async-replace";
import { Buffer, imgProm } from "../util/dutil";
import { grab } from "../util/util";
export type ShaderProgramText = {
name: string, // for debugging
vert: string,
frag: string,
};
type Assets = {
dictionary: Record<string, boolean>,
spritesBuf: Buffer,
largeSpritesBuf: Buffer,
fontSheetBuf: Buffer,
worldShaders: ShaderProgramText,
tileShaders: ShaderProgramText,
spriteShaders: ShaderProgramText,
debugQuadShaders: ShaderProgramText,
canvasShaders: ShaderProgramText,
bonusShaders: ShaderProgramText,
};
// Any data that goes here is effectively test data for consumption by
// unit tests. initAssets, which will be called early in
// initialization in actual execution, will overwrite it.
let assets: Assets = {
dictionary: { 'foo': true, 'bar': true, 'baz': true },
// We assume tests don't exercise any of the below data:
spritesBuf: undefined as any,
largeSpritesBuf: undefined as any,
fontSheetBuf: undefined as any,
worldShaders: { name: '', frag: '', vert: '' },
tileShaders: { name: '', frag: '', vert: '' },
spriteShaders: { name: '', frag: '', vert: '' },
debugQuadShaders: { name: '', frag: '', vert: '' },
canvasShaders: { name: '', frag: '', vert: '' },
bonusShaders: { name: '', frag: '', vert: '' },
}
async function preprocess(shaderText: string): Promise<string> {
return await asyncReplace(shaderText, /^#include "(.*?)"/mg, async (ms) => {
const file = ms[1];
// XXX recursively preprocess?
// XXX cache fetches?
return await grab(`assets/shaders/${file}`);
});
}
async function getShaders(prefix: string): Promise<ShaderProgramText> {
const vert = await preprocess(await grab(`assets/shaders/${prefix}.vert`));
const frag = await preprocess(await grab(`assets/shaders/${prefix}.frag`));
return { name: prefix, vert, frag };
}
export type Prerenderers = {
prerenderSpriteSheet(im: HTMLImageElement): Buffer;
prerenderToolbar(im: HTMLImageElement): Buffer;
prerenderFontSheet(im: HTMLImageElement): Buffer;
}
export async function initAssets(prerenderers: Prerenderers) {
const { prerenderSpriteSheet, prerenderFontSheet, prerenderToolbar } = prerenderers;
const spritesImg = await imgProm('assets/sprites.png');
const fontSheetImg = await imgProm('assets/font-sheet.png');
const largeSpritesImg = await imgProm('assets/sprites-large.png');
const wordlist = (await (await fetch('assets/dictionary.txt')).text())
.split('\n').filter(x => x);
const dictionary = Object.fromEntries(wordlist.map(word => [word, true]));
assets = {
dictionary,
spritesBuf: prerenderSpriteSheet(spritesImg),
largeSpritesBuf: prerenderToolbar(largeSpritesImg),
fontSheetBuf: prerenderFontSheet(fontSheetImg),
worldShaders: await getShaders('world'),
tileShaders: await getShaders('tile'),
spriteShaders: await getShaders('sprite'),
debugQuadShaders: await getShaders('debug-quad'),
canvasShaders: await getShaders('canvas'),
bonusShaders: await getShaders('bonus'),
};
}
export function getAssets(): Assets {
return assets as Assets;
}