Cleanup: parallel fetching, error recovery, dead code removal

- Fetch .tex files in parallel with Promise.all instead of sequentially
- Clear cached IndexedDB promise on rejection so subsequent calls retry
- Remove unused textureOrder array from Act1State parser
- Unify selectDefault/applyCustom into single applyTexture function
- Remove redundant squareTexture call on already-squared wdbTexture
This commit is contained in:
Christian Semmler 2026-02-07 14:08:34 -08:00
parent 8adeb9fed6
commit 4f9740619b
4 changed files with 21 additions and 27 deletions

View File

@ -325,19 +325,18 @@ export class SaveGameParser {
// Conditional textures based on which planes have names // Conditional textures based on which planes have names
const textures = new Map(); const textures = new Map();
const textureOrder = [];
if (planes[3].nameLength > 0) { if (planes[3].nameLength > 0) {
for (let i = 0; i < 3; i++) textureOrder.push(this.readAct1Texture(textures)); for (let i = 0; i < 3; i++) this.readAct1Texture(textures);
} }
if (planes[4].nameLength > 0) { if (planes[4].nameLength > 0) {
for (let i = 0; i < 2; i++) textureOrder.push(this.readAct1Texture(textures)); for (let i = 0; i < 2; i++) this.readAct1Texture(textures);
} }
if (planes[5].nameLength > 0) { if (planes[5].nameLength > 0) {
textureOrder.push(this.readAct1Texture(textures)); this.readAct1Texture(textures);
} }
if (planes[6].nameLength > 0) { if (planes[6].nameLength > 0) {
for (let i = 0; i < 3; i++) textureOrder.push(this.readAct1Texture(textures)); for (let i = 0; i < 3; i++) this.readAct1Texture(textures);
} }
// Final fields // Final fields
@ -347,7 +346,6 @@ export class SaveGameParser {
this.parsed.act1State = { this.parsed.act1State = {
planes, planes,
textures, textures,
textureOrder,
startOffset, startOffset,
endOffset: this.reader.tell(), endOffset: this.reader.tell(),
cptClickDialogueNextIndex, cptClickDialogueNextIndex,

View File

@ -21,6 +21,9 @@ function openDB() {
request.onsuccess = () => resolve(request.result); request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error); request.onerror = () => reject(request.error);
}).catch((err) => {
dbPromise = null;
throw err;
}); });
return dbPromise; return dbPromise;

View File

@ -70,13 +70,13 @@
return canvas.toDataURL(); return canvas.toDataURL();
} }
function selectDefault(tex) { function applyTexture(tex) {
onSelect({ onSelect({
width: tex.width, width: tex.width,
height: tex.height, height: tex.height,
palette: tex.palette, palette: tex.palette,
pixels: tex.pixels, pixels: tex.pixels,
paletteSize: tex.palette.length paletteSize: tex.paletteSize || tex.palette.length
}); });
} }
@ -86,14 +86,7 @@
function applyCustom() { function applyCustom() {
const tex = customTextures.find(t => t.id === selectedCustomId); const tex = customTextures.find(t => t.id === selectedCustomId);
if (!tex) return; if (tex) applyTexture(tex);
onSelect({
width: tex.width,
height: tex.height,
palette: tex.palette,
pixels: tex.pixels,
paletteSize: tex.paletteSize
});
} }
function handleUploadClick() { function handleUploadClick() {
@ -194,7 +187,7 @@
<button <button
type="button" type="button"
class="texture-thumb" class="texture-thumb"
onclick={() => selectDefault(tex)} onclick={() => applyTexture(tex)}
title={tex.name} title={tex.name}
> >
<img src={tex.dataUrl} alt={tex.name} /> <img src={tex.dataUrl} alt={tex.name} />

View File

@ -223,19 +223,19 @@
} }
async function preloadDefaultTextures(info) { async function preloadDefaultTextures(info) {
const loaded = []; const results = await Promise.all(info.texFiles.map(async (texFile) => {
for (const texFile of info.texFiles) {
const response = await fetch(`/${texFile}.tex`); const response = await fetch(`/${texFile}.tex`);
if (!response.ok) continue; if (!response.ok) return null;
const buffer = await response.arrayBuffer(); const buffer = await response.arrayBuffer();
const parsed = parseTex(buffer); const parsed = parseTex(buffer);
if (parsed.textures.length > 0) { if (parsed.textures.length > 0) {
loaded.push({ name: texFile, ...parsed.textures[0] }); return { name: texFile, ...parsed.textures[0] };
}
} }
return null;
}));
// Only apply if textureInfo hasn't changed since we started // Only apply if textureInfo hasn't changed since we started
if (textureInfo === info) { if (textureInfo === info) {
preloadedDefaults = loaded; preloadedDefaults = results.filter(Boolean);
} }
} }
@ -275,16 +275,16 @@
} }
}; };
// Reset texture to WDB default (equivalent to WriteDefaultTexture in the game) // Reset texture to WDB default (equivalent to WriteDefaultTexture in the game).
// wdbTexture is already squared when cached in loadCurrentPart().
if (canEditTexture && wdbTexture && renderer) { if (canEditTexture && wdbTexture && renderer) {
const texKey = textureInfo.textureName.toLowerCase(); const texKey = textureInfo.textureName.toLowerCase();
const saveData = squareTexture(wdbTexture);
renderer.updateTexture(texKey, saveData); renderer.updateTexture(texKey, wdbTexture);
update.texture = { update.texture = {
textureName: textureInfo.textureName, textureName: textureInfo.textureName,
textureData: saveData textureData: wdbTexture
}; };
} }