예제 #1
0
파일: pck.cpp 프로젝트: idshibanov/OpenApoc
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;
}
예제 #2
0
파일: pck.cpp 프로젝트: JonnyH/OpenApoc
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;
}
예제 #3
0
파일: pck.cpp 프로젝트: JonnyH/OpenApoc
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;
	}
}