static sp<PaletteImage> loadStrategy(IFile &file) { auto img = mksp<PaletteImage>(Vec2<int>{8, 8}); // All strategy map tiles are 8x8 unsigned int offset = 0; struct strat_header header; file.read(reinterpret_cast<char *>(&header), sizeof(header)); PaletteImageLock region(img); while (file && header.pixel_skip != 0xffff) { unsigned int count = header.count; offset = header.pixel_skip; while (file && count--) { uint8_t idx = 0; #define STRIDE 640 unsigned int x = offset % STRIDE; unsigned int y = offset / STRIDE; #undef STRIDE if (x >= 8 || y >= 8) { LogError("Writing to {%d,%d} in 8x8 stratmap image", x, y); return img; } file.read(reinterpret_cast<char *>(&idx), 1); region.set(Vec2<int>{x, y}, idx); offset++; } file.read(reinterpret_cast<char *>(&header), sizeof(header)); } return img; }
static sp<PaletteImage> loadShadowImage(IFile &file, uint8_t shadedIdx) { struct ShadowHeader header; file.read(reinterpret_cast<char *>(&header), sizeof(header)); if (!file) { LogError("Unexpected EOF reading shadow PCK header\n"); return nullptr; } auto img = mksp<PaletteImage>(Vec2<int>{header.width, header.height}); PaletteImageLock region(img); uint8_t b = 0; file.read(reinterpret_cast<char *>(&b), 1); int pos = 0; while (b != 0xff) { uint8_t count = b; file.read(reinterpret_cast<char *>(&b), 1); if (!file) { LogError("Unexpected EOF reading shadow data\n"); return nullptr; } uint8_t idx = b; if (idx == 0) pos += count * 4; else { LogAssert(idx < 7); while (count--) { for (int i = 0; i < 4; i++) { const int STRIDE = 640; int x = pos % STRIDE; int y = pos / STRIDE; if (x < header.width && y < header.height) { if (ditherLut[idx][i]) region.set({x, y}, shadedIdx); else region.set({x, y}, 0); } pos++; } } } file.read(reinterpret_cast<char *>(&b), 1); if (!file) { LogError("Unexpected EOF reading shadow data\n"); return nullptr; } } return img; }
static unsigned int guessTabMultiplier(IFile &pckFile, IFile &tabFile) { // This tries to guess if the tab file contains (offset) or (offset/4) based on the last entry, // if multiplying it by 4 is greater than the pck file size it's (offset), otherwise (offset/4) auto pckSize = pckFile.size(); auto tabSize = tabFile.size(); if (tabSize < 4) { LogWarning("Tab size %zu too small for a single entry?", tabSize); return 0; } // Store the tab offset so we can restore the file state auto tabOffset = tabFile.tellg(); tabFile.seekg(tabSize - 4); uint32_t lastOffset; tabFile.read(reinterpret_cast<char *>(&lastOffset), sizeof(lastOffset)); if (!tabFile) { LogWarning("Failed to read last tab offset"); return 0; } tabFile.seekg(tabOffset); if (lastOffset * 4 >= pckSize) { return 1; } else { return 4; } }