From a362301515f1ffb23527ad342675901700831dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sat, 20 Jan 2024 13:27:56 -0600 Subject: [PATCH] feat: r5g6b5a0 format compatibility --- scripts/buildAssets/tankArmors.ts | 2 +- scripts/buildAssets/tankModels.ts | 2 +- .../{TankDisplay.tsx => TankSandbox.tsx} | 4 +- src/app/tools/tankopedia/[id]/page.tsx | 4 +- src/core/streams/pvr.ts | 41 +++++++++++++++++-- 5 files changed, 43 insertions(+), 10 deletions(-) rename src/app/tools/tankopedia/[id]/components/Model/{TankDisplay.tsx => TankSandbox.tsx} (98%) diff --git a/scripts/buildAssets/tankArmors.ts b/scripts/buildAssets/tankArmors.ts index 3ffc091f4..25735a9fb 100644 --- a/scripts/buildAssets/tankArmors.ts +++ b/scripts/buildAssets/tankArmors.ts @@ -20,7 +20,7 @@ export async function buildTankArmors() { await Promise.all( nations.map(async (nation) => { - if (nation !== 'usa') return; + if (nation !== 'germany') return; const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>( `${DATA}/${POI.vehicleDefinitions}/${nation}/list.xml.dvpl`, diff --git a/scripts/buildAssets/tankModels.ts b/scripts/buildAssets/tankModels.ts index 69a878cf6..7ac38875f 100644 --- a/scripts/buildAssets/tankModels.ts +++ b/scripts/buildAssets/tankModels.ts @@ -27,7 +27,7 @@ export async function buildTankModels() { await Promise.all( nations.map(async (nation) => { - if (nation !== 'usa') return; + if (nation !== 'germany') return; const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>( `${DATA}/${POI.vehicleDefinitions}/${nation}/list.xml.dvpl`, diff --git a/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx similarity index 98% rename from src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx rename to src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx index 7beb25254..27c192f57 100644 --- a/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx +++ b/src/app/tools/tankopedia/[id]/components/Model/TankSandbox.tsx @@ -21,11 +21,11 @@ import { Options } from './components/Options'; import { TankArmor } from './components/TankArmor'; import { TankModel } from './components/TankModel'; -interface TankDisplayProps { +interface TankSandboxProps { duel: Duel; } -export function TankDisplay({ duel }: TankDisplayProps) { +export function TankSandbox({ duel }: TankSandboxProps) { const canvas = useRef(null); const awaitedModelDefinitions = use(modelDefinitions); const canvasWrapper = useRef(null); diff --git a/src/app/tools/tankopedia/[id]/page.tsx b/src/app/tools/tankopedia/[id]/page.tsx index 0c7786f36..b6bf87f56 100644 --- a/src/app/tools/tankopedia/[id]/page.tsx +++ b/src/app/tools/tankopedia/[id]/page.tsx @@ -8,7 +8,7 @@ import { tankDefinitions } from '../../../../core/blitzkrieg/tankDefinitions'; import mutateTankopedia, { DuelMember } from '../../../../stores/tankopedia'; import { AntagonistBar } from './components/AntagonistBar'; import { Configure } from './components/Configure'; -import { TankDisplay } from './components/Model/TankDisplay'; +import { TankSandbox } from './components/Model/TankSandbox'; import { Title } from './components/Title'; export interface Duel { @@ -81,7 +81,7 @@ export default function Page({ params }: { params: { id: string } }) { - <TankDisplay duel={duel} /> + <TankSandbox duel={duel} /> <AntagonistBar duel={duel} setDuel={setDuel} /> </Flex> diff --git a/src/core/streams/pvr.ts b/src/core/streams/pvr.ts index 847c38e4d..b9f13f2a5 100644 --- a/src/core/streams/pvr.ts +++ b/src/core/streams/pvr.ts @@ -1,5 +1,4 @@ import { clamp, isEqual, times } from 'lodash'; -import { Vector4Tuple } from 'three'; import { BufferStream } from './buffer'; export enum PvrFlags { @@ -89,12 +88,13 @@ enum PvrChannelType { enum ResolvedBitRatePixelFormat { R4G4B4A4, + R5G6B5A0, } export class PvrStream extends BufferStream { pvr() { const header = this.header(); - const metadata = this.metadata(); + this.metadata(); if (typeof header.pixelFormat === 'number') { switch (header.pixelFormat) { @@ -114,7 +114,6 @@ export class PvrStream extends BufferStream { switch (resolvedPixelFormat) { case ResolvedBitRatePixelFormat.R4G4B4A4: { const data = Buffer.alloc(pixelCount * 4); - let lastPixel: Vector4Tuple; times(pixelCount, (index) => { const buffer = this.consume(2); @@ -138,6 +137,31 @@ export class PvrStream extends BufferStream { }; } + case ResolvedBitRatePixelFormat.R5G6B5A0: { + const data = Buffer.alloc(pixelCount * 3); + + times(pixelCount, (index) => { + const buffer = this.consume(2); + const bufferIndex = index * 4; + const r = ((buffer[1] & 0b11111000) >>> 3) / 31; + const g = + ((buffer[1] & 0b111) << 3) | + (((buffer[0] & 0b11100000) >>> 5) / 31); + const b = buffer[0] & 0b11111; + + data[bufferIndex] = Math.round(clamp(r * 255, 0, 255)); + data[bufferIndex + 1] = Math.round(clamp(g * 255, 0, 255)); + data[bufferIndex + 2] = Math.round(clamp(b * 255, 0, 255)); + }); + + return { + data, + width: header.width, + height: header.height, + channels: 3 as const, + }; + } + default: throw new TypeError( `Unhandled resolved pixel format ${resolvedPixelFormat} (${header.pixelFormat})`, @@ -188,7 +212,16 @@ export class PvrStream extends BufferStream { throw new TypeError( `Unhandled rgba bit rate ${pixelFormat.bitRates.join(', ')}`, ); - } else throw new TypeError(`Unhandled pixel order ${pixelFormat.order}`); + } else if (pixelFormat.order === 'rgb\0') { + if (isEqual(pixelFormat.bitRates, [5, 6, 5, 0])) { + return ResolvedBitRatePixelFormat.R5G6B5A0; + } else + throw new TypeError( + `Unhandled rgb bit rate ${pixelFormat.bitRates.join(', ')}`, + ); + } else { + throw new TypeError(`Unhandled pixel order ${pixelFormat.order}`); + } } metadata() { const fourCC = this.ascii(4);