mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: dds stream
This commit is contained in:
1 parent
2f650af0f7
commit
cd546b274f
10 files changed
+170
-146
No files matched your search
@@ -54,7 +54,6 @@
|
|||||||
"markdown-escape": "^2.0.0",
|
"markdown-escape": "^2.0.0",
|
||||||
"next": "^14.0.3",
|
"next": "^14.0.3",
|
||||||
"parse-dds": "^1.2.1",
|
"parse-dds": "^1.2.1",
|
||||||
"pngjs": "^7.0.0",
|
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-fuzzysort": "^1.0.1",
|
"react-fuzzysort": "^1.0.1",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { NodeIO } from '@gltf-transform/core';
|
import { NodeIO } from '@gltf-transform/core';
|
||||||
import { config } from 'dotenv';
|
import { config } from 'dotenv';
|
||||||
import { writeFileSync } from 'fs';
|
|
||||||
import { mkdir, readdir } from 'fs/promises';
|
import { mkdir, readdir } from 'fs/promises';
|
||||||
import { argv } from 'process';
|
import { argv } from 'process';
|
||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
@@ -25,24 +24,7 @@ import {
|
|||||||
Tier,
|
Tier,
|
||||||
TurretDefinition,
|
TurretDefinition,
|
||||||
} from '../src/core/blitzkrieg/tankDefinitions';
|
} from '../src/core/blitzkrieg/tankDefinitions';
|
||||||
import { VertexAttribute } from '../src/core/streams/scpg';
|
|
||||||
|
|
||||||
const vertexAttributeGLTFName: Partial<Record<VertexAttribute, string>> = {
|
|
||||||
[VertexAttribute.VERTEX]: 'POSITION',
|
|
||||||
[VertexAttribute.NORMAL]: 'NORMAL',
|
|
||||||
[VertexAttribute.COLOR]: 'COLOR_0',
|
|
||||||
[VertexAttribute.TEXCOORD0]: 'TEXCOORD_0',
|
|
||||||
[VertexAttribute.TEXCOORD1]: 'TEXCOORD_0',
|
|
||||||
[VertexAttribute.TEXCOORD2]: 'TEXCOORD_0',
|
|
||||||
[VertexAttribute.TEXCOORD3]: 'TEXCOORD_0',
|
|
||||||
[VertexAttribute.TANGENT]: 'TANGENT',
|
|
||||||
[VertexAttribute.JOINTINDEX]: 'JOINT_0',
|
|
||||||
[VertexAttribute.JOINTWEIGHT]: 'WEIGHT_0',
|
|
||||||
};
|
|
||||||
|
|
||||||
(BigInt.prototype as any).toJSON = function () {
|
|
||||||
return this.toString();
|
|
||||||
};
|
|
||||||
config();
|
config();
|
||||||
|
|
||||||
// WARNING! MOST OF THESE TYPES ARE NOT EXHAUSTIVE!
|
// WARNING! MOST OF THESE TYPES ARE NOT EXHAUSTIVE!
|
||||||
@@ -339,7 +321,6 @@ if (allTargets || targets?.includes('definitions')) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('Committing tank definitions...');
|
console.log('Committing tank definitions...');
|
||||||
writeFileSync('test.json', JSON.stringify(definitions, null, 2));
|
|
||||||
// await commitMultipleFiles(
|
// await commitMultipleFiles(
|
||||||
// 'tresabhi',
|
// 'tresabhi',
|
||||||
// 'blitzkrieg-assets',
|
// 'blitzkrieg-assets',
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { Document, Material, Node, Scene } from '@gltf-transform/core';
|
import { Document, Material, Node, Scene } from '@gltf-transform/core';
|
||||||
import { writeFileSync } from 'fs';
|
|
||||||
import { range, times } from 'lodash';
|
import { range, times } from 'lodash';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
import sharp from 'sharp';
|
|
||||||
import { Matrix4, Quaternion, Vector3, Vector4Tuple } from 'three';
|
import { Matrix4, Quaternion, Vector3, Vector4Tuple } from 'three';
|
||||||
import { readTexture } from '../blitzkrieg/readTexture';
|
import { readTexture } from '../blitzkrieg/readTexture';
|
||||||
import { Hierarchy, Sc2Stream, Textures } from '../streams/sc2';
|
import { Hierarchy, Sc2Stream, Textures } from '../streams/sc2';
|
||||||
@@ -35,8 +33,6 @@ export async function extractModel(data: string, path: string) {
|
|||||||
const buffer = document.createBuffer();
|
const buffer = document.createBuffer();
|
||||||
const materials = new Map<bigint, Material | bigint>();
|
const materials = new Map<bigint, Material | bigint>();
|
||||||
|
|
||||||
writeFileSync('test.sc2.json', JSON.stringify(sc2, null, 2));
|
|
||||||
|
|
||||||
// create materials
|
// create materials
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
sc2['#dataNodes'].map(async (node) => {
|
sc2['#dataNodes'].map(async (node) => {
|
||||||
@@ -64,7 +60,7 @@ export async function extractModel(data: string, path: string) {
|
|||||||
material.setBaseColorTexture(
|
material.setBaseColorTexture(
|
||||||
document
|
document
|
||||||
.createTexture(node.materialName)
|
.createTexture(node.materialName)
|
||||||
.setMimeType('image/jpg')
|
.setMimeType('image/png')
|
||||||
.setImage(
|
.setImage(
|
||||||
await readTexture(
|
await readTexture(
|
||||||
`${data}/3d/${dirname(path)}/${textures.albedo}`,
|
`${data}/3d/${dirname(path)}/${textures.albedo}`,
|
||||||
@@ -76,24 +72,29 @@ export async function extractModel(data: string, path: string) {
|
|||||||
material.setMetallicRoughnessTexture(
|
material.setMetallicRoughnessTexture(
|
||||||
document
|
document
|
||||||
.createTexture(node.materialName)
|
.createTexture(node.materialName)
|
||||||
.setMimeType('image/jpg')
|
.setMimeType('image/png')
|
||||||
.setImage(
|
.setImage(
|
||||||
await sharp(
|
|
||||||
await readTexture(
|
await readTexture(
|
||||||
`${data}/3d/${dirname(path)}/${textures.baseRMMap}`,
|
`${data}/3d/${dirname(path)}/${textures.baseRMMap}`,
|
||||||
),
|
),
|
||||||
)
|
|
||||||
.raw()
|
|
||||||
.toBuffer({ resolveWithObject: true })
|
|
||||||
.then(({ data, info }) => {
|
|
||||||
// fake it till you make it
|
|
||||||
for (let index = 0; index < data.length; index++) {
|
|
||||||
data[index] = 255 - data[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
return sharp(data, { raw: info }).jpeg().toBuffer();
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
|
// .setImage(
|
||||||
|
// await sharp(
|
||||||
|
// await readTexture(
|
||||||
|
// `${data}/3d/${dirname(path)}/${textures.baseRMMap}`,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
|
// .raw()
|
||||||
|
// .toBuffer({ resolveWithObject: true })
|
||||||
|
// .then(({ data, info }) => {
|
||||||
|
// // fake it till you make it
|
||||||
|
// for (let index = 0; index < data.length; index++) {
|
||||||
|
// data[index] = 255 - data[index];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return sharp(data, { raw: info }).jpeg().toBuffer();
|
||||||
|
// }),
|
||||||
|
// ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,24 +102,29 @@ export async function extractModel(data: string, path: string) {
|
|||||||
material.setNormalTexture(
|
material.setNormalTexture(
|
||||||
document
|
document
|
||||||
.createTexture(node.materialName)
|
.createTexture(node.materialName)
|
||||||
.setMimeType('image/jpg')
|
.setMimeType('image/png')
|
||||||
.setImage(
|
.setImage(
|
||||||
await sharp(
|
|
||||||
await readTexture(
|
await readTexture(
|
||||||
`${data}/3d/${dirname(path)}/${textures.baseNormalMap}`,
|
`${data}/3d/${dirname(path)}/${textures.baseNormalMap}`,
|
||||||
),
|
),
|
||||||
)
|
|
||||||
.raw()
|
|
||||||
.toBuffer({ resolveWithObject: true })
|
|
||||||
.then(({ data, info }) => {
|
|
||||||
// https://www.youtube.com/watch?v=CGys6CnnYSg
|
|
||||||
for (let index = 0; index < data.length; index += 3) {
|
|
||||||
data[index + 2] = 255 - data[index + 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
return sharp(data, { raw: info }).jpeg().toBuffer();
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
|
// .setImage(
|
||||||
|
// await sharp(
|
||||||
|
// await readTexture(
|
||||||
|
// `${data}/3d/${dirname(path)}/${textures.baseNormalMap}`,
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
|
// .raw()
|
||||||
|
// .toBuffer({ resolveWithObject: true })
|
||||||
|
// .then(({ data, info }) => {
|
||||||
|
// // https://www.youtube.com/watch?v=CGys6CnnYSg
|
||||||
|
// for (let index = 0; index < data.length; index += 3) {
|
||||||
|
// data[index + 2] = 255 - data[index + 2];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return sharp(data, { raw: info }).jpeg().toBuffer();
|
||||||
|
// }),
|
||||||
|
// ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,8 +152,6 @@ export async function extractModel(data: string, path: string) {
|
|||||||
materials.set(id, resolvedMaterial);
|
materials.set(id, resolvedMaterial);
|
||||||
});
|
});
|
||||||
|
|
||||||
writeFileSync('test.sc2.json', JSON.stringify(sc2, null, 2));
|
|
||||||
|
|
||||||
function parseHierarchies(hierarchies: Hierarchy[], parent: Scene | Node) {
|
function parseHierarchies(hierarchies: Hierarchy[], parent: Scene | Node) {
|
||||||
hierarchies.forEach((hierarchy) => {
|
hierarchies.forEach((hierarchy) => {
|
||||||
const node = document.createNode(hierarchy.name);
|
const node = document.createNode(hierarchy.name);
|
||||||
|
|||||||
@@ -1,21 +1,29 @@
|
|||||||
import { existsSync } from 'fs';
|
import sharp from 'sharp';
|
||||||
import { readDVPLFile } from '../blitz/readDVPLFile';
|
import { readDVPLFile } from '../blitz/readDVPLFile';
|
||||||
import { ToJpgOptions, toJpg } from './toJpg';
|
import { DdsStream } from '../streams/dds';
|
||||||
|
import { ToJpgOptions } from './toJpg';
|
||||||
|
|
||||||
export async function readTexture(
|
export async function readTexture(
|
||||||
path: string,
|
path: string,
|
||||||
options?: Partial<Omit<ToJpgOptions, 'format'>>,
|
options?: Partial<Omit<ToJpgOptions, 'format'>>,
|
||||||
) {
|
) {
|
||||||
const ddsTexturePath = path.replace('.tex', '.dx11.dds.dvpl');
|
const ddsTexturePath = path.replace('.tex', '.dx11.dds.dvpl');
|
||||||
const isDds = existsSync(ddsTexturePath);
|
const decompressedDvpl = await readDVPLFile(ddsTexturePath);
|
||||||
const resolvedTexturePath = isDds
|
const stream = new DdsStream(decompressedDvpl);
|
||||||
? ddsTexturePath
|
const ddsRaw = await stream.dds();
|
||||||
: ddsTexturePath.replace('.dds', '.pvr');
|
const png = await sharp(ddsRaw.data, { raw: ddsRaw }).png().toBuffer();
|
||||||
const decompressedTexture = await readDVPLFile(resolvedTexturePath);
|
|
||||||
const jpg = await toJpg(decompressedTexture, {
|
|
||||||
...options,
|
|
||||||
format: isDds ? 'dds' : 'pvr',
|
|
||||||
});
|
|
||||||
|
|
||||||
return jpg;
|
return png;
|
||||||
|
|
||||||
|
// const isDds = existsSync(ddsTexturePath);
|
||||||
|
// const resolvedTexturePath = isDds
|
||||||
|
// ? ddsTexturePath
|
||||||
|
// : ddsTexturePath.replace('.dds', '.pvr');
|
||||||
|
// const decompressedTexture = await readDVPLFile(resolvedTexturePath);
|
||||||
|
// const jpg = await toJpg(decompressedTexture, {
|
||||||
|
// ...options,
|
||||||
|
// format: isDds ? 'dds' : 'pvr',
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return jpg;
|
||||||
}
|
}
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import { times } from 'lodash';
|
|
||||||
|
|
||||||
type Bit = 0 | 1;
|
|
||||||
|
|
||||||
export class BitStream {
|
|
||||||
public index = 0;
|
|
||||||
bits: Bit[] = [];
|
|
||||||
|
|
||||||
constructor(buffer: Buffer) {
|
|
||||||
for (let bufferIndex = 0; bufferIndex < buffer.length; bufferIndex++) {
|
|
||||||
const byte = buffer[bufferIndex];
|
|
||||||
|
|
||||||
for (let byteIndex = 7; byteIndex >= 0; byteIndex--) {
|
|
||||||
this.bits.push(((byte >> byteIndex) & 1) as Bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
skip(size: number) {
|
|
||||||
this.index += size;
|
|
||||||
}
|
|
||||||
read(size: number) {
|
|
||||||
if (size > 32) {
|
|
||||||
throw new RangeError('Cannot read more than 32 bits at a time');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.index + size > this.bits.length) {
|
|
||||||
throw new RangeError('Cannot read beyond end of stream');
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.bits
|
|
||||||
.slice(this.index, this.index + size)
|
|
||||||
.reduce((accumulator, bit) => (accumulator << 1) | bit, 0 as number);
|
|
||||||
}
|
|
||||||
readBytes(size: number) {
|
|
||||||
const buffer = Buffer.from(times(size, () => this.consume(8)));
|
|
||||||
this.skip(-8 * size);
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
consume(size: number) {
|
|
||||||
const value = this.read(size);
|
|
||||||
this.skip(size);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export class ByteStream {
|
export class BufferStream {
|
||||||
public index = 0;
|
public index = 0;
|
||||||
constructor(public stream: Buffer) {}
|
constructor(public stream: Buffer) {}
|
||||||
|
|
||||||
+108
-24
@@ -1,10 +1,9 @@
|
|||||||
import { writeFileSync } from 'fs';
|
|
||||||
import { times } from 'lodash';
|
import { times } from 'lodash';
|
||||||
import sharp from 'sharp';
|
|
||||||
import { readDVPLFile } from '../blitz/readDVPLFile';
|
import { readDVPLFile } from '../blitz/readDVPLFile';
|
||||||
import { Bc1Stream } from './bc1';
|
|
||||||
import { WindowsStream } from './windows';
|
import { WindowsStream } from './windows';
|
||||||
|
|
||||||
|
type Bits2 = 0b00 | 0b01 | 0b10 | 0b11;
|
||||||
|
|
||||||
enum DxgiFormat {
|
enum DxgiFormat {
|
||||||
UNKNOWN = 0,
|
UNKNOWN = 0,
|
||||||
R32G32B32A32_TYPELESS = 1,
|
R32G32B32A32_TYPELESS = 1,
|
||||||
@@ -180,10 +179,7 @@ export class DdsStream extends WindowsStream {
|
|||||||
|
|
||||||
const header = this.header();
|
const header = this.header();
|
||||||
|
|
||||||
if (
|
if (header.pf.flags !== DdpfFlags.FOURCC || header.pf.fourCC !== 'DX10') {
|
||||||
header.pf.flags !== DdpfFlags.FOURCC ||
|
|
||||||
header.pf.fourCC !== 0x30315844 // "DX10"
|
|
||||||
) {
|
|
||||||
throw new RangeError('No other formats other than DX10 are supported');
|
throw new RangeError('No other formats other than DX10 are supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,25 +187,57 @@ export class DdsStream extends WindowsStream {
|
|||||||
|
|
||||||
switch (headerDxt10.dxgiFormat) {
|
switch (headerDxt10.dxgiFormat) {
|
||||||
case DxgiFormat.BC1_UNORM_SRGB: {
|
case DxgiFormat.BC1_UNORM_SRGB: {
|
||||||
this.skip(1);
|
if (header.width % 4 !== 0 || header.height % 4 !== 0) {
|
||||||
|
throw new RangeError('Width and height must be divisible by 4');
|
||||||
|
}
|
||||||
|
|
||||||
const image = new Bc1Stream(
|
const data = Buffer.alloc(header.width * header.height * 4);
|
||||||
// this.consume((header.width / 4) * (header.height / 4) * 8),
|
const blocksX = header.width / 4;
|
||||||
this.consumeRemaining(),
|
const blocksY = header.height / 4;
|
||||||
).bc1(header.width, header.height);
|
|
||||||
|
|
||||||
writeFileSync(
|
times(blocksX * blocksY, (blockIndex) => {
|
||||||
'test.png',
|
const blockPosX = (blockIndex % blocksX) * 4;
|
||||||
await sharp(image, {
|
const blockPosY = Math.floor(blockIndex / blocksX) * 4;
|
||||||
raw: {
|
const interpolations = this.interpolations();
|
||||||
channels: 4,
|
const indices = this.indices();
|
||||||
|
|
||||||
|
indices.forEach((index, indexIndex) => {
|
||||||
|
let pixelPosX = 4 - (indexIndex % 4);
|
||||||
|
let pixelPosY = Math.floor(indexIndex / 4);
|
||||||
|
let x = blockPosX + pixelPosX;
|
||||||
|
let y = blockPosY + pixelPosY;
|
||||||
|
|
||||||
|
const bufferIndex = 4 * (y * header.width + x);
|
||||||
|
const color = interpolations[index].map((standard) =>
|
||||||
|
Math.round(255 * standard),
|
||||||
|
);
|
||||||
|
|
||||||
|
data[bufferIndex] = color[0];
|
||||||
|
data[bufferIndex + 1] = color[1];
|
||||||
|
data[bufferIndex + 2] = color[2];
|
||||||
|
data[bufferIndex + 3] = color[3];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// writeFileSync(
|
||||||
|
// 'dist/assets/models/15697/baseColor_1.jpg',
|
||||||
|
// await sharp(image, {
|
||||||
|
// raw: {
|
||||||
|
// width: header.width,
|
||||||
|
// height: header.height,
|
||||||
|
// channels: 4,
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
// .jpeg()
|
||||||
|
// .toBuffer(),
|
||||||
|
// );
|
||||||
|
|
||||||
|
return {
|
||||||
width: header.width,
|
width: header.width,
|
||||||
height: header.height,
|
height: header.height,
|
||||||
},
|
channels: 4 as const,
|
||||||
})
|
data,
|
||||||
.png()
|
};
|
||||||
.toBuffer(),
|
|
||||||
);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -223,8 +251,64 @@ export class DdsStream extends WindowsStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interpolations() {
|
||||||
|
const buffer0 = this.consume(2);
|
||||||
|
const buffer1 = this.consume(2);
|
||||||
|
const int0 = buffer0.readUInt16LE();
|
||||||
|
const int1 = buffer1.readUInt16LE();
|
||||||
|
const alpha = int0 < int1;
|
||||||
|
const color0 = [
|
||||||
|
((buffer0[1] & 0b11111000) >>> 3) / 0x1f,
|
||||||
|
(((buffer0[1] & 0b111) << 3) + ((buffer0[0] & 0b11100000) >>> 5)) / 0x3f,
|
||||||
|
(buffer0[0] & 0b11111) / 0x1f,
|
||||||
|
1,
|
||||||
|
];
|
||||||
|
const color1 = [
|
||||||
|
((buffer1[1] & 0b11111000) >>> 3) / 0x1f,
|
||||||
|
(((buffer1[1] & 0b111) << 3) + ((buffer1[0] & 0b11100000) >>> 5)) / 0x3f,
|
||||||
|
(buffer1[0] & 0b11111) / 0x1f,
|
||||||
|
1,
|
||||||
|
];
|
||||||
|
const color2 = alpha
|
||||||
|
? color0.map((channel0, index) => (channel0 + color1[index]) / 2)
|
||||||
|
: color0.map((channel0, index) => (2 * channel0 + color1[index]) / 3);
|
||||||
|
const color3 = alpha
|
||||||
|
? [0, 0, 0, 0]
|
||||||
|
: color0.map((channel0, index) => (channel0 + 2 * color1[index]) / 3);
|
||||||
|
|
||||||
|
return {
|
||||||
|
[0b00]: color0,
|
||||||
|
[0b01]: color1,
|
||||||
|
[0b10]: color2,
|
||||||
|
[0b11]: color3,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
indices() {
|
||||||
|
const indicesBuffer = this.consume(4);
|
||||||
|
const indices = times(16, (index) => {
|
||||||
|
const bufferIndex = Math.floor(index / 4);
|
||||||
|
const maskShift = 2 * (index % 4);
|
||||||
|
const valueShift = 2 * (3 - (index % 4));
|
||||||
|
const buffer = indicesBuffer[bufferIndex];
|
||||||
|
const mask = 0b11000000 >>> maskShift;
|
||||||
|
const masked = buffer & mask;
|
||||||
|
const value = masked >>> valueShift;
|
||||||
|
|
||||||
|
return value as Bits2;
|
||||||
|
});
|
||||||
|
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
magicNumber() {
|
magicNumber() {
|
||||||
return this.dword();
|
const magic = this.dword();
|
||||||
|
|
||||||
|
if (magic !== 0x20534444) {
|
||||||
|
throw new Error(`Invalid DDS magic number: 0x${magic.toString(16)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return magic;
|
||||||
}
|
}
|
||||||
|
|
||||||
header() {
|
header() {
|
||||||
@@ -250,7 +334,7 @@ export class DdsStream extends WindowsStream {
|
|||||||
return {
|
return {
|
||||||
size: this.dword(),
|
size: this.dword(),
|
||||||
flags: this.dword() as DdpfFlags,
|
flags: this.dword() as DdpfFlags,
|
||||||
fourCC: this.dword(),
|
fourCC: this.ascii(4),
|
||||||
rgbBitCount: this.dword(),
|
rgbBitCount: this.dword(),
|
||||||
rBitMask: this.dword(),
|
rBitMask: this.dword(),
|
||||||
gBitMask: this.dword(),
|
gBitMask: this.dword(),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { times } from 'lodash';
|
import { times } from 'lodash';
|
||||||
import { ByteStream } from './byte';
|
import { BufferStream } from './buffer';
|
||||||
|
|
||||||
enum KAType {
|
enum KAType {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
@@ -55,7 +55,7 @@ export enum VertexAttribute {
|
|||||||
CUBETEXCOORD3 = 19,
|
CUBETEXCOORD3 = 19,
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ScpgStream extends ByteStream {
|
export class ScpgStream extends BufferStream {
|
||||||
vectorN(size: number) {
|
vectorN(size: number) {
|
||||||
return times(size, () => this.float());
|
return times(size, () => this.float());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ByteStream } from './byte';
|
import { BufferStream } from './buffer';
|
||||||
|
|
||||||
export class WindowsStream extends ByteStream {
|
export class WindowsStream extends BufferStream {
|
||||||
dword() {
|
dword() {
|
||||||
return this.uint32();
|
return this.uint32();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5049,11 +5049,6 @@ pkg-types@^1.0.3:
|
|||||||
mlly "^1.2.0"
|
mlly "^1.2.0"
|
||||||
pathe "^1.1.0"
|
pathe "^1.1.0"
|
||||||
|
|
||||||
pngjs@^7.0.0:
|
|
||||||
version "7.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26"
|
|
||||||
integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==
|
|
||||||
|
|
||||||
postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0:
|
postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
||||||
|
|||||||
Reference in new issue
Block a user