Example #1
0
void TalkTable_GFF::readString05(Common::SeekableSubReadStreamEndian &huffTree,
                                 Common::SeekableSubReadStreamEndian &bitStream, Entry &entry) const {

	/* Read a string encoded in a Huffman'd bitstream.
	 *
	 * The Huffman tree itself is made up of signed 32bit nodes:
	 *  - Positive values are internal nodes, encoding a child index
	 *  - Negative values are leaf nodes, encoding an UTF-16 character value
	 *
	 * Kudos to Rick (gibbed) (<http://gib.me/>).
	 */

	std::vector<uint16> utf16Str;

	const uint32 startOffset = entry.strct->getUint(kGFF4HuffTalkStringBitOffset);

	uint32 index = startOffset >> 5;
	uint32 shift = startOffset & 0x1F;

	do {
		ptrdiff_t e = (huffTree.size() / 8) - 1;

		while (e >= 0) {
			bitStream.seek(index * 4);
			const ptrdiff_t offset = (bitStream.readUint32() >> shift) & 1;

			huffTree.seek(((e * 2) + offset) * 4);
			e = huffTree.readSint32();

			shift++;
			index += (shift >> 5);

			shift %= 32;
		}

		utf16Str.push_back(TO_LE_16(0xFFFF - e));

	} while (utf16Str.back() != 0);

	const byte  *data = reinterpret_cast<const byte *>(&utf16Str[0]);
	const size_t size = utf16Str.size() * 2;

	entry.text = Common::readString(data, size, Common::kEncodingUTF16LE);
}