From 7f5accf79002b5b4ed5951fbefd22a2e4e14b2ed Mon Sep 17 00:00:00 2001 From: Daan Vanden Bosch Date: Mon, 6 Jan 2020 14:04:05 +0100 Subject: [PATCH] AFS archives with compressed XVM texture archives are now supported. --- src/core/data_formats/parsing/afs.ts | 2 +- .../data_formats/parsing/ninja/texture.ts | 6 +++++- src/core/files.ts | 2 +- src/quest_editor/loading/EntityAssetLoader.ts | 2 +- src/viewer/controllers/TextureController.ts | 19 ++++++++++++++++--- .../model/ModelToolBarController.ts | 5 +++-- .../loading/CharacterClassAssetLoader.ts | 5 ++++- src/viewer/rendering/TextureRenderer.ts | 1 - 8 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/core/data_formats/parsing/afs.ts b/src/core/data_formats/parsing/afs.ts index d009a1f5..24433e87 100644 --- a/src/core/data_formats/parsing/afs.ts +++ b/src/core/data_formats/parsing/afs.ts @@ -26,7 +26,7 @@ export function parse_afs(cursor: Cursor): ArrayBuffer[] { const file_count = cursor.u16(); - // Skip two unused bytes. + // Skip two unused bytes (are these just part of the file count field?). cursor.seek(2); const file_entries: AfsFileEntry[] = []; diff --git a/src/core/data_formats/parsing/ninja/texture.ts b/src/core/data_formats/parsing/ninja/texture.ts index 12703f23..f2b32c0e 100644 --- a/src/core/data_formats/parsing/ninja/texture.ts +++ b/src/core/data_formats/parsing/ninja/texture.ts @@ -43,7 +43,7 @@ export function parse_xvr(cursor: Cursor): XvrTexture { }; } -export function parse_xvm(cursor: Cursor): Xvm { +export function parse_xvm(cursor: Cursor): Xvm | undefined { const chunks = parse_iff(cursor); const header_chunk = chunks.find(chunk => chunk.type === XVMH); const header = header_chunk && parse_header(header_chunk.data); @@ -52,6 +52,10 @@ export function parse_xvm(cursor: Cursor): Xvm { .filter(chunk => chunk.type === XVRT) .map(chunk => parse_xvr(chunk.data)); + if (!header && textures.length === 0) { + return undefined; + } + if (header && header.texture_count !== textures.length) { logger.warn( `Found ${textures.length} textures instead of ${header.texture_count} as defined in the header.`, diff --git a/src/core/files.ts b/src/core/files.ts index 70f0d786..ad9515a6 100644 --- a/src/core/files.ts +++ b/src/core/files.ts @@ -1,7 +1,7 @@ import { input } from "./gui/dom"; export function open_files(options?: { accept?: string; multiple?: boolean }): Promise { - return new Promise((resolve) => { + return new Promise(resolve => { const el = input({ type: "file" }); el.accept = options?.accept ?? ""; el.multiple = options?.multiple ?? false; diff --git a/src/quest_editor/loading/EntityAssetLoader.ts b/src/quest_editor/loading/EntityAssetLoader.ts index b993d330..efda6922 100644 --- a/src/quest_editor/loading/EntityAssetLoader.ts +++ b/src/quest_editor/loading/EntityAssetLoader.ts @@ -79,7 +79,7 @@ export class EntityAssetLoader implements Disposable { .then(({ data }) => { const cursor = new ArrayBufferCursor(data, Endianness.Little); const xvm = parse_xvm(cursor); - return xvm_to_textures(xvm); + return xvm === undefined ? [] : xvm_to_textures(xvm); }) .catch(e => { logger.warn( diff --git a/src/viewer/controllers/TextureController.ts b/src/viewer/controllers/TextureController.ts index 0a8ce4df..dcf03f9d 100644 --- a/src/viewer/controllers/TextureController.ts +++ b/src/viewer/controllers/TextureController.ts @@ -9,6 +9,7 @@ import { LogManager } from "../../core/Logger"; import { WritableListProperty } from "../../core/observable/property/list/WritableListProperty"; import { list_property } from "../../core/observable"; import { ListProperty } from "../../core/observable/property/list/ListProperty"; +import { prs_decompress } from "../../core/data_formats/compression/prs/decompress"; const logger = LogManager.get("viewer/controllers/TextureController"); @@ -24,14 +25,26 @@ export class TextureController extends Controller { if (ext === "xvm") { const xvm = parse_xvm(new ArrayBufferCursor(buffer, Endianness.Little)); - this._textures.splice(0, Infinity, ...xvm.textures); + if (xvm) { + this._textures.splice(0, Infinity, ...xvm.textures); + } } else if (ext === "afs") { const afs = parse_afs(new ArrayBufferCursor(buffer, Endianness.Little)); const textures: XvrTexture[] = []; for (const buffer of afs) { - const xvm = parse_xvm(new ArrayBufferCursor(buffer, Endianness.Little)); - textures.push(...xvm.textures); + const cursor = new ArrayBufferCursor(buffer, Endianness.Little); + const xvm = parse_xvm(cursor); + + if (xvm) { + textures.push(...xvm.textures); + } else { + const xvm = parse_xvm(prs_decompress(cursor.seek_start(0))); + + if (xvm) { + textures.push(...xvm.textures); + } + } } this._textures.val = textures; diff --git a/src/viewer/controllers/model/ModelToolBarController.ts b/src/viewer/controllers/model/ModelToolBarController.ts index 67431abb..9f448565 100644 --- a/src/viewer/controllers/model/ModelToolBarController.ts +++ b/src/viewer/controllers/model/ModelToolBarController.ts @@ -70,11 +70,12 @@ export class ModelToolBarController extends Controller { this.store.set_current_nj_motion(parse_njm(cursor, nj_object.bone_count())); } } else if (file.name.endsWith(".xvm")) { - this.store.set_current_textures(parse_xvm(cursor).textures); + this.store.set_current_textures(parse_xvm(cursor)?.textures ?? []); } else if (file.name.endsWith(".afs")) { const files = parse_afs(cursor); const textures: XvrTexture[] = files.flatMap( - file => parse_xvm(new ArrayBufferCursor(file, Endianness.Little)).textures, + file => + parse_xvm(new ArrayBufferCursor(file, Endianness.Little))?.textures ?? [], ); this.store.set_current_textures(textures); diff --git a/src/viewer/loading/CharacterClassAssetLoader.ts b/src/viewer/loading/CharacterClassAssetLoader.ts index 5c7d6359..a04b6bf0 100644 --- a/src/viewer/loading/CharacterClassAssetLoader.ts +++ b/src/viewer/loading/CharacterClassAssetLoader.ts @@ -173,7 +173,10 @@ export class CharacterClassAssetLoader implements Disposable { for (const file of afs) { const xvm = parse_xvm(new ArrayBufferCursor(file, Endianness.Little)); - textures.push(...xvm.textures); + + if (xvm) { + textures.push(...xvm.textures); + } } return textures; diff --git a/src/viewer/rendering/TextureRenderer.ts b/src/viewer/rendering/TextureRenderer.ts index ad79cc5d..4279ccc1 100644 --- a/src/viewer/rendering/TextureRenderer.ts +++ b/src/viewer/rendering/TextureRenderer.ts @@ -38,7 +38,6 @@ export class TextureRenderer extends Renderer implements Disposable { ); this.init_camera_controls(); - this.controls.dollySpeed = -1; this.controls.azimuthRotateSpeed = 0; this.controls.polarRotateSpeed = 0; }