1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "bladerunner/vqa_decoder.h"
24 
25 #include "bladerunner/bladerunner.h"
26 #include "bladerunner/decompress_lcw.h"
27 #include "bladerunner/decompress_lzo.h"
28 #include "bladerunner/game_info.h"
29 #include "bladerunner/lights.h"
30 #include "bladerunner/screen_effects.h"
31 #include "bladerunner/view.h"
32 #include "bladerunner/zbuffer.h"
33 
34 #include "audio/decoders/raw.h"
35 
36 #include "common/array.h"
37 #include "common/util.h"
38 #include "common/memstream.h"
39 
40 namespace BladeRunner {
41 
42 #define kAESC 0x41455343
43 #define kCBFZ 0x4342465A
44 #define kCBPZ 0x4342505A
45 #define kCIND 0x43494E44
46 #define kCINF 0x43494E46
47 #define kCINH 0x43494E48
48 #define kCLIP 0x434C4950
49 #define kFINF 0x46494E46
50 #define kFORM 0x464f524d
51 #define kLIND 0x4C494E44
52 #define kLINF 0x4C494E46
53 #define kLINH 0x4C494E48
54 #define kLITE 0x4C495445
55 #define kLNID 0x4C4E4944
56 #define kLNIH 0x4C4E4948
57 #define kLNIN 0x4C4E494E
58 #define kLNIO 0x4C4E494F
59 #define kMFCD 0x4D464344
60 #define kMFCH 0x4D464348
61 #define kMFCI 0x4D464349
62 #define kMFCT 0x4D464354
63 #define kMSCH 0x4D534348
64 #define kMSCI 0x4D534349
65 #define kMSCT 0x4D534354
66 #define kSN2J 0x534e324a
67 #define kSND2 0x534e4432
68 #define kVIEW 0x56494557
69 #define kVPTR 0x56505452
70 #define kVQFL 0x5651464C
71 #define kVQFR 0x56514652
72 #define kVQHD 0x56514844
73 #define kWVQA 0x57565141
74 #define kZBUF 0x5A425546
75 
remain(Common::SeekableReadStream * s)76 int32 remain(Common::SeekableReadStream *s) {
77 	int32 pos = s->pos();
78 	if (pos == -1) return -1;
79 
80 	int32 size = s->size();
81 	if (size == -1) return -1;
82 
83 	return size - pos;
84 }
85 
86 struct IFFChunkHeader {
IFFChunkHeaderBladeRunner::IFFChunkHeader87 	IFFChunkHeader()
88 		: id(0), size(0)
89 	{}
90 
91 	uint32 id;
92 	uint32 size;
93 };
94 
readIFFChunkHeader(Common::SeekableReadStream * s,IFFChunkHeader * ts)95 static bool readIFFChunkHeader(Common::SeekableReadStream *s, IFFChunkHeader *ts) {
96 	if (remain(s) < 8)
97 		return false;
98 
99 	ts->id   = s->readUint32BE();
100 	ts->size = s->readUint32BE();
101 
102 	return true;
103 }
104 
roundup(uint32 v)105 static inline uint32 roundup(uint32 v) {
106 	return (v + 1) & ~1u;
107 }
108 
VQADecoder()109 VQADecoder::VQADecoder() {
110 	_s                   = nullptr;
111 	_frameInfo           = nullptr;
112 	_videoTrack          = nullptr;
113 	_audioTrack          = nullptr;
114 	_maxVIEWChunkSize    = 0;
115 	_maxZBUFChunkSize    = 0;
116 	_maxAESCChunkSize    = 0;
117 	_header.version      = 0;
118 	_header.flags        = 0;
119 	_header.numFrames    = 0;
120 	_header.width        = 0;
121 	_header.height       = 0;
122 	_header.blockW       = 0;
123 	_header.blockH       = 0;
124 	_header.frameRate    = 0;
125 	_header.cbParts      = 0;
126 	_header.colors       = 0;
127 	_header.maxBlocks    = 0;
128 	_header.offsetX      = 0;
129 	_header.offsetY      = 0;
130 	_header.maxVPTRSize  = 0;
131 	_header.freq         = 0;
132 	_header.channels     = 0;
133 	_header.bits         = 0;
134 	_header.unk3         = 0;
135 	_header.unk4         = 0;
136 	_header.maxCBFZSize  = 0;
137 	_header.unk5         = 0;
138 	_readingFrame        = -1;
139 	_decodingFrame       = -1;
140 }
141 
~VQADecoder()142 VQADecoder::~VQADecoder() {
143 	for (uint i = _codebooks.size(); i != 0; --i) {
144 		delete[] _codebooks[i - 1].data;
145 	}
146 	delete _audioTrack;
147 	delete _videoTrack;
148 	delete[] _frameInfo;
149 }
150 
loadStream(Common::SeekableReadStream * s)151 bool VQADecoder::loadStream(Common::SeekableReadStream *s) {
152 	// close();
153 	_s = s;
154 
155 	IFFChunkHeader chd;
156 	uint32 type;
157 
158 	readIFFChunkHeader(s, &chd);
159 	if (chd.id != kFORM || !chd.size)
160 		return false;
161 
162 	type = s->readUint32BE();
163 
164 	if (type != kWVQA)
165 		return false;
166 
167 	do {
168 		if (!readIFFChunkHeader(_s, &chd))
169 			return false;
170 
171 		bool rc = false;
172 		switch (chd.id) {
173 		case kCINF: rc = readCINF(s, chd.size); break;
174 		case kCLIP: rc = readCLIP(s, chd.size); break;
175 		case kFINF: rc = readFINF(s, chd.size); break;
176 		case kLINF: rc = readLINF(s, chd.size); break;
177 		case kLNIN: rc = readLNIN(s, chd.size); break;
178 		case kMFCI: rc = readMFCI(s, chd.size); break;
179 		case kMSCI: rc = readMSCI(s, chd.size); break;
180 		case kVQHD: rc = readVQHD(s, chd.size); break;
181 		default:
182 			warning("Unhandled chunk '%s'", tag2str(chd.id));
183 			s->skip(roundup(chd.size));
184 			rc = true;
185 		}
186 
187 		if (!rc) {
188 			warning("failed to handle chunk %s", tag2str(chd.id));
189 			return false;
190 		}
191 	} while (chd.id != kFINF);
192 
193 	_videoTrack = new VQAVideoTrack(this);
194 	_audioTrack = new VQAAudioTrack(this);
195 
196 	return true;
197 }
198 
decodeVideoFrame(Graphics::Surface * surface,int frame,bool forceDraw)199 void VQADecoder::decodeVideoFrame(Graphics::Surface *surface, int frame, bool forceDraw) {
200 	_decodingFrame = frame;
201 	_videoTrack->decodeVideoFrame(surface, forceDraw);
202 }
203 
decodeZBuffer(ZBuffer * zbuffer)204 void VQADecoder::decodeZBuffer(ZBuffer *zbuffer) {
205 	_videoTrack->decodeZBuffer(zbuffer);
206 }
207 
decodeAudioFrame()208 Audio::SeekableAudioStream *VQADecoder::decodeAudioFrame() {
209 	return _audioTrack->decodeAudioFrame();
210 }
211 
decodeView(View * view)212 void VQADecoder::decodeView(View *view) {
213 	_videoTrack->decodeView(view);
214 }
215 
decodeScreenEffects(ScreenEffects * screenEffects)216 void VQADecoder::decodeScreenEffects(ScreenEffects *screenEffects) {
217 	_videoTrack->decodeScreenEffects(screenEffects);
218 }
219 
decodeLights(Lights * lights)220 void VQADecoder::decodeLights(Lights *lights) {
221 	_videoTrack->decodeLights(lights);
222 }
223 
readPacket(uint readFlags)224 void VQADecoder::readPacket(uint readFlags) {
225 	IFFChunkHeader chd;
226 
227 	if (remain(_s) < 8) {
228 		warning("VQADecoder::readPacket(): remain: %d", remain(_s));
229 		assert(remain(_s) < 8);
230 	}
231 
232 	do {
233 		if (!readIFFChunkHeader(_s, &chd)) {
234 			error("VQADecoder::readPacket(): Error reading chunk header");
235 		}
236 
237 		bool rc = false;
238 		// Video track
239 		switch (chd.id) {
240 		case kAESC: rc = ((readFlags & kVQAReadCustom) == 0) ? _s->skip(roundup(chd.size)) : _videoTrack->readAESC(_s, chd.size); break;
241 		case kLITE: rc = ((readFlags & kVQAReadCustom) == 0) ? _s->skip(roundup(chd.size)) : _videoTrack->readLITE(_s, chd.size); break;
242 		case kVIEW: rc = ((readFlags & kVQAReadCustom) == 0) ? _s->skip(roundup(chd.size)) : _videoTrack->readVIEW(_s, chd.size); break;
243 		case kVQFL: rc = ((readFlags & kVQAReadVideo ) == 0) ? _s->skip(roundup(chd.size)) : _videoTrack->readVQFL(_s, chd.size, readFlags); break;
244 		case kVQFR: rc = ((readFlags & kVQAReadVideo ) == 0) ? _s->skip(roundup(chd.size)) : _videoTrack->readVQFR(_s, chd.size, readFlags); break;
245 		case kZBUF: rc = ((readFlags & kVQAReadCustom) == 0) ? _s->skip(roundup(chd.size)) : _videoTrack->readZBUF(_s, chd.size); break;
246 		// Sound track
247 		case kSN2J: rc = ((readFlags & kVQAReadAudio) == 0) ? _s->skip(roundup(chd.size)) : _audioTrack->readSN2J(_s, chd.size); break;
248 		case kSND2: rc = ((readFlags & kVQAReadAudio) == 0) ? _s->skip(roundup(chd.size)) : _audioTrack->readSND2(_s, chd.size); break;
249 		default:
250 			rc = false;
251 			_s->skip(roundup(chd.size));
252 		}
253 
254 		if (!rc) {
255 			warning("VQADecoder::readPacket(): Error handling chunk %s", tag2str(chd.id));
256 			return;
257 		}
258 	} while (chd.id != kVQFR);
259 }
260 
readFrame(int frame,uint readFlags)261 void VQADecoder::readFrame(int frame, uint readFlags) {
262 	if (frame < 0 || frame >= numFrames()) {
263 		error("VQADecoder::readFrame(): frame %d out of bounds, frame count is %d", frame, numFrames());
264 	}
265 
266 	uint32 frameOffset = 2 * (_frameInfo[frame] & 0x0FFFFFFF);
267 	_s->seek(frameOffset);
268 
269 	_readingFrame = frame;
270 	readPacket(readFlags);
271 }
272 
readVQHD(Common::SeekableReadStream * s,uint32 size)273 bool VQADecoder::readVQHD(Common::SeekableReadStream *s, uint32 size) {
274 	if (size != 42)
275 		return false;
276 
277 	_header.version     = s->readUint16LE();
278 	_header.flags       = s->readUint16LE();
279 	_header.numFrames   = s->readUint16LE();
280 	_header.width       = s->readUint16LE();
281 	_header.height      = s->readUint16LE();
282 	_header.blockW      = s->readByte();
283 	_header.blockH      = s->readByte();
284 	_header.frameRate   = s->readByte();
285 	_header.cbParts     = s->readByte();
286 	_header.colors      = s->readUint16LE();
287 	_header.maxBlocks   = s->readUint16LE();
288 	_header.offsetX     = s->readUint16LE();
289 	_header.offsetY     = s->readUint16LE();
290 	_header.maxVPTRSize = s->readUint16LE();
291 	_header.freq        = s->readUint16LE();
292 	_header.channels    = s->readByte();
293 	_header.bits        = s->readByte();
294 	_header.unk3        = s->readUint32LE();
295 	_header.unk4        = s->readUint16LE();
296 	_header.maxCBFZSize = s->readUint32LE();
297 	_header.unk5        = s->readUint32LE();
298 
299 	// if (_header.unk3 || _header.unk4 != 4 || _header.unk5 || _header.flags != 0x0014) {
300 	// 	debug("_header.version      %d", _header.version);
301 	// 	debug("_header.flags        %04x", _header.flags);
302 	// 	debug("_header.numFrames    %d", _header.numFrames);
303 	// 	debug("_header.width        %d", _header.width);
304 	// 	debug("_header.height       %d", _header.height);
305 	// 	debug("_header.blockW       %d", _header.blockW);
306 	// 	debug("_header.blockH       %d", _header.blockH);
307 	// 	debug("_header.frameRate    %d", _header.frameRate);
308 	// 	debug("_header.cbParts      %d", _header.cbParts);
309 	// 	debug("_header.colors       %d", _header.colors);
310 	// 	debug("_header.maxBlocks    %d", _header.maxBlocks);
311 	// 	debug("_header.offsetX      %d", _header.offsetX);
312 	// 	debug("_header.offsetY      %d", _header.offsetY);
313 	// 	debug("_header.maxVPTRSize  %d", _header.maxVPTRSize);
314 	// 	debug("_header.freq         %d", _header.freq);
315 	// 	debug("_header.channels     %d", _header.channels);
316 	// 	debug("_header.bits         %d", _header.bits);
317 	// 	debug("_header.unk3         %d", _header.unk3);
318 	// 	debug("_header.unk4         %d", _header.unk4);
319 	// 	debug("_header.maxCBFZSize  %d", _header.maxCBFZSize);
320 	// 	debug("_header.unk5         %d", _header.unk5);
321 	// 	debug("\n");
322 	// }
323 
324 	assert(_header.version == 2);
325 	if (_header.channels != 0) {
326 		assert(_header.freq == 22050);
327 		assert(_header.channels == 1);
328 		assert(_header.bits == 16);
329 	}
330 	assert(_header.colors == 0);
331 
332 	return true;
333 }
334 
readVQFR(Common::SeekableReadStream * s,uint32 size,uint readFlags)335 bool VQADecoder::VQAVideoTrack::readVQFR(Common::SeekableReadStream *s, uint32 size, uint readFlags) {
336 	IFFChunkHeader chd;
337 
338 	signed int sizeLeft = size; // we have to use signed int to avoid underflow
339 
340 	while (sizeLeft >= 8) {
341 		if (!readIFFChunkHeader(s, &chd))
342 			return false;
343 		sizeLeft -= roundup(chd.size) + 8;
344 
345 		bool rc = false;
346 		switch (chd.id) {
347 		case kCBFZ: rc = ((readFlags & kVQAReadCodebook          ) == 0) ? s->skip(roundup(chd.size)) : readCBFZ(s, chd.size); break;
348 		case kCBPZ: rc = ((readFlags & kVQAReadCodebook          ) == 0) ? s->skip(roundup(chd.size)) : readCBFZ(s, chd.size); break;
349 		case kVPTR: rc = ((readFlags & kVQAReadVectorPointerTable) == 0) ? s->skip(roundup(chd.size)) : readVPTR(s, chd.size); break;
350 		default:
351 			s->skip(roundup(chd.size));
352 		}
353 
354 		if (!rc) {
355 			error("VQADecoder::VQAVideoTrack::readVQFR(): error handling chunk %s", tag2str(chd.id));
356 			return false;
357 		}
358 	}
359 
360 	return true;
361 }
362 
readMSCI(Common::SeekableReadStream * s,uint32 size)363 bool VQADecoder::readMSCI(Common::SeekableReadStream *s, uint32 size) {
364 	IFFChunkHeader chd;
365 	readIFFChunkHeader(_s, &chd);
366 
367 	if (chd.id != kMSCH)
368 		return false;
369 
370 	uint32 count, unk0;
371 	count = s->readUint32LE();
372 	unk0  = s->readUint32LE();
373 	assert(unk0 == 0);
374 
375 	readIFFChunkHeader(_s, &chd);
376 	if (chd.id != kMSCT || chd.size != count * 0x10)
377 		return false;
378 
379 	for (uint32 i = count; i != 0; --i) {
380 		uint32 tag, max_size;
381 		tag  = s->readUint32BE();
382 		max_size = s->readUint32LE();
383 
384 		switch (tag) {
385 		case kVIEW:
386 			_maxVIEWChunkSize = max_size;
387 			break;
388 		case kZBUF:
389 			_maxZBUFChunkSize = max_size;
390 			break;
391 		case kAESC:
392 			_maxAESCChunkSize = max_size;
393 			break;
394 		default:
395 			warning("Unknown tag in MSCT: %s", tag2str(tag));
396 		}
397 
398 		uint32 zero;
399 		zero = s->readUint32LE(); assert(zero == 0);
400 		zero = s->readUint32LE(); assert(zero == 0);
401 	}
402 
403 	return true;
404 }
405 
readLINF(Common::SeekableReadStream * s,uint32 size)406 bool VQADecoder::readLINF(Common::SeekableReadStream *s, uint32 size) {
407 	IFFChunkHeader chd;
408 	readIFFChunkHeader(_s, &chd);
409 
410 	if (chd.id != kLINH || chd.size != 6)
411 		return false;
412 
413 	_loopInfo.loopCount = s->readUint16LE();
414 	_loopInfo.flags = s->readUint32LE();
415 
416 	if ((_loopInfo.flags & 3) == 0)
417 		return false;
418 
419 	readIFFChunkHeader(_s, &chd);
420 	if (chd.id != kLIND || chd.size != 4u * _loopInfo.loopCount)
421 		return false;
422 
423 	_loopInfo.loops = new Loop[_loopInfo.loopCount];
424 	for (uint16 i = _loopInfo.loopCount; i != 0; --i) {
425 		_loopInfo.loops[_loopInfo.loopCount - i].begin = s->readUint16LE();
426 		_loopInfo.loops[_loopInfo.loopCount - i].end   = s->readUint16LE();
427 
428 		// debug("Loop %d: %04x %04x", _loopInfo.loopCount - i, _loopInfo.loops[_loopInfo.loopCount - i].begin, _loopInfo.loops[_loopInfo.loopCount - i].end);
429 	}
430 
431 	return true;
432 }
433 
codebookInfoForFrame(int frame)434 VQADecoder::CodebookInfo &VQADecoder::codebookInfoForFrame(int frame) {
435 	assert(frame < numFrames());
436 	assert(!_codebooks.empty());
437 
438 	CodebookInfo *ci = nullptr;
439 	uint count = _codebooks.size();
440 
441 	for (uint i = count; i != 0; --i) {
442 		if (frame >= _codebooks[i - 1].frame) {
443 			return _codebooks[i - 1];
444 		}
445 	}
446 
447 	assert(ci && "No codebook found");
448 	return _codebooks[0];
449 }
450 
readCINF(Common::SeekableReadStream * s,uint32 size)451 bool VQADecoder::readCINF(Common::SeekableReadStream *s, uint32 size) {
452 	IFFChunkHeader chd;
453 
454 	readIFFChunkHeader(_s, &chd);
455 	if (chd.id != kCINH || chd.size != 8u)
456 		return false;
457 
458 	uint16 codebookCount = s->readUint16LE();
459 	_codebooks.resize(codebookCount);
460 
461 	s->skip(6);
462 
463 	readIFFChunkHeader(_s, &chd);
464 	if (chd.id != kCIND || chd.size != 6u * codebookCount)
465 		return false;
466 
467 	for (uint16 i = codebookCount; i != 0; --i) {
468 		_codebooks[codebookCount - i].frame = s->readUint16LE();
469 		_codebooks[codebookCount - i].size  = s->readUint32LE();
470 		_codebooks[codebookCount - i].data  = nullptr;
471 
472 		// debug("Codebook %2u: %4d %8d", codebookCount - i, _codebooks[codebookCount - i].frame, _codebooks[codebookCount - i].size);
473 
474 		assert(_codebooks[codebookCount - i].frame < numFrames());
475 	}
476 
477 	return true;
478 }
479 
readFINF(Common::SeekableReadStream * s,uint32 size)480 bool VQADecoder::readFINF(Common::SeekableReadStream *s, uint32 size) {
481 	if (size != 4u * _header.numFrames)
482 		return false;
483 
484 	_frameInfo = new uint32[_header.numFrames];
485 
486 	for (uint16 i =  _header.numFrames; i != 0; --i)
487 		_frameInfo[ _header.numFrames - i] = s->readUint32LE();
488 
489 	// if (false) {
490 	// 	uint32 last = 0;
491 	// 	for (uint32 i = 0; i != _header.numFrames; ++i) {
492 	// 		uint32 diff = _frameInfo[i] - last;
493 	// 		debug("_frameInfo[%4d] = 0x%08x   - %08x", i, _frameInfo[i], diff);
494 	// 		last = _frameInfo[i];
495 	// 	}
496 	// }
497 
498 	return true;
499 }
500 
readLNIN(Common::SeekableReadStream * s,uint32 size)501 bool VQADecoder::readLNIN(Common::SeekableReadStream *s, uint32 size) {
502 	IFFChunkHeader chd;
503 
504 	readIFFChunkHeader(_s, &chd);
505 	if (chd.id != kLNIH || chd.size != 10)
506 		return false;
507 
508 	uint16 loopNamesCount = s->readUint16LE();
509 	uint16 loopUnk1       = s->readUint16LE();
510 	uint16 loopUnk2       = s->readUint16LE();
511 	uint16 loopUnk3       = s->readUint16LE();
512 	uint16 loopUnk4       = s->readUint16LE();
513 
514 #if BLADERUNNER_DEBUG_CONSOLE
515 	debug("VQADecoder::readLNIN() Unknown Values: 0x%04x 0x%04x 0x%04x 0x%04x", loopUnk1, loopUnk2, loopUnk3, loopUnk4);
516 #else
517 	(void)loopUnk1;
518 	(void)loopUnk2;
519 	(void)loopUnk3;
520 	(void)loopUnk4;
521 #endif
522 
523 	if (loopNamesCount != _loopInfo.loopCount)
524 		return false;
525 
526 	readIFFChunkHeader(_s, &chd);
527 	if (chd.id != kLNIO || chd.size != 4u * loopNamesCount)
528 		return false;
529 
530 	uint32 *loopNameOffsets = (uint32 *)malloc(loopNamesCount * sizeof(uint32));
531 	for (uint16 i = loopNamesCount; i != 0; --i) {
532 		loopNameOffsets[loopNamesCount - i] = s->readUint32LE();
533 	}
534 
535 	readIFFChunkHeader(_s, &chd);
536 	if (chd.id != kLNID) {
537 		free(loopNameOffsets);
538 		return false;
539 	}
540 
541 	char *names = (char *)malloc(roundup(chd.size));
542 	s->read(names, roundup(chd.size));
543 
544 	for (uint16 i = loopNamesCount; i != 0; --i) {
545 		char   *begin = names + loopNameOffsets[loopNamesCount - i];
546 		uint32  len   = ((i == 1) ? chd.size : loopNameOffsets[loopNamesCount - i + 1]) - loopNameOffsets[loopNamesCount - i];
547 
548 		_loopInfo.loops[loopNamesCount - i].name = Common::String(begin, len);
549 
550 		// debug("%2u: %s", loopNamesCount - i, _loopInfo.loops[loopNamesCount - i].name.c_str());
551 	}
552 
553 	free(loopNameOffsets);
554 	free(names);
555 	return true;
556 }
557 
getLoopBeginAndEndFrame(int loop,int * begin,int * end)558 bool VQADecoder::getLoopBeginAndEndFrame(int loop, int *begin, int *end) {
559 	assert(begin && end);
560 
561 	if (loop < 0 || loop >= _loopInfo.loopCount)
562 		return false;
563 
564 	*begin = _loopInfo.loops[loop].begin;
565 	*end   = _loopInfo.loops[loop].end;
566 
567 	return true;
568 }
569 
getLoopIdFromFrame(int frame)570 int VQADecoder::getLoopIdFromFrame(int frame) {
571 	if (frame >= 0) {
572 		for (int loopId = 0; loopId < _loopInfo.loopCount; ++loopId) {
573 			if (frame >= _loopInfo.loops[loopId].begin && frame <= _loopInfo.loops[loopId].end) {
574 				return loopId;
575 			}
576 		}
577 	}
578 	return -1;
579 }
580 
readCLIP(Common::SeekableReadStream * s,uint32 size)581 bool VQADecoder::readCLIP(Common::SeekableReadStream *s, uint32 size) {
582 	s->skip(roundup(size));
583 	return true;
584 }
585 
readMFCI(Common::SeekableReadStream * s,uint32 size)586 bool VQADecoder::readMFCI(Common::SeekableReadStream *s, uint32 size) {
587 	s->skip(roundup(size));
588 	return true;
589 }
590 
VQAVideoTrack(VQADecoder * vqaDecoder)591 VQADecoder::VQAVideoTrack::VQAVideoTrack(VQADecoder *vqaDecoder) {
592 	_vqaDecoder = vqaDecoder;
593 	_hasNewFrame = false;
594 
595 	VQADecoder::Header *header = &vqaDecoder->_header;
596 	_numFrames = header->numFrames;
597 	_width     = header->width;
598 	_height    = header->height;
599 	_blockW    = header->blockW;
600 	_blockH    = header->blockH;
601 	_frameRate = header->frameRate;
602 	_maxBlocks = header->maxBlocks;
603 	_offsetX   = header->offsetX;
604 	_offsetY   = header->offsetY;
605 
606 	_maxVPTRSize = header->maxVPTRSize;
607 	_maxCBFZSize = header->maxCBFZSize;
608 	_maxZBUFChunkSize = vqaDecoder->_maxZBUFChunkSize;
609 
610 	_codebook = nullptr;
611 	_cbfz     = nullptr;
612 
613 	_vpointerSize = 0;
614 	_vpointer = nullptr;
615 
616 	_curFrame = -1;
617 
618 	_zbufChunkSize = 0;
619 	_zbufChunk     = new uint8[roundup(_maxZBUFChunkSize)];
620 
621 	_viewDataSize = 0;
622 	_viewData     = nullptr;
623 
624 	_screenEffectsDataSize = 0;
625 	_screenEffectsData     = nullptr;
626 
627 	_lightsDataSize = 0;
628 	_lightsData     = nullptr;
629 }
630 
~VQAVideoTrack()631 VQADecoder::VQAVideoTrack::~VQAVideoTrack() {
632 	delete[] _cbfz;
633 	delete[] _zbufChunk;
634 	delete[] _vpointer;
635 
636 	delete[] _viewData;
637 	delete[] _screenEffectsData;
638 	delete[] _lightsData;
639 }
640 
getWidth() const641 uint16 VQADecoder::VQAVideoTrack::getWidth() const {
642 	return _width;
643 }
644 
getHeight() const645 uint16 VQADecoder::VQAVideoTrack::getHeight() const {
646 	return _height;
647 }
648 
getFrameCount() const649 int VQADecoder::VQAVideoTrack::getFrameCount() const {
650 	return _numFrames;
651 }
652 
getFrameRate() const653 Common::Rational VQADecoder::VQAVideoTrack::getFrameRate() const {
654 	return _frameRate;
655 }
656 
decodeVideoFrame(Graphics::Surface * surface,bool forceDraw)657 void VQADecoder::VQAVideoTrack::decodeVideoFrame(Graphics::Surface *surface, bool forceDraw) {
658 	if (_hasNewFrame || forceDraw) {
659 		assert(surface);
660 		decodeFrame(surface);
661 		_hasNewFrame = false;
662 	}
663 }
664 
readVQFL(Common::SeekableReadStream * s,uint32 size,uint readFlags)665 bool VQADecoder::VQAVideoTrack::readVQFL(Common::SeekableReadStream *s, uint32 size, uint readFlags) {
666 	IFFChunkHeader chd;
667 
668 	signed int sizeLeft = size; // we have to use signed int to avoid underflow
669 
670 	while (sizeLeft >= 8) {
671 		if (!readIFFChunkHeader(s, &chd))
672 			return false;
673 		sizeLeft -= roundup(chd.size) + 8;
674 
675 		bool rc = false;
676 		switch (chd.id) {
677 			case kCBFZ: rc = readCBFZ(s, chd.size); break;
678 			default:
679 				s->skip(roundup(chd.size));
680 		}
681 
682 		if (!rc) {
683 			warning("VQFL: error handling chunk %s", tag2str(chd.id));
684 			return false;
685 		}
686 	}
687 
688 	return true;
689 }
690 
readCBFZ(Common::SeekableReadStream * s,uint32 size)691 bool VQADecoder::VQAVideoTrack::readCBFZ(Common::SeekableReadStream *s, uint32 size) {
692 	if (size > _maxCBFZSize) {
693 		warning("readCBFZ: chunk too large: %d > %d", size, _maxCBFZSize);
694 		return false;
695 	}
696 
697 	CodebookInfo &codebookInfo = _vqaDecoder->codebookInfoForFrame(_vqaDecoder->_readingFrame);
698 	if (codebookInfo.data) {
699 		s->skip(roundup(size));
700 		return true;
701 	}
702 
703 	uint32 codebookSize = 2 * _maxBlocks * _blockW * _blockH;
704 	codebookInfo.data = new uint8[codebookSize];
705 
706 	if (!_cbfz) {
707 		_cbfz = new uint8[roundup(_maxCBFZSize)];
708 	}
709 
710 	s->read(_cbfz, roundup(size));
711 
712 	decompress_lcw(_cbfz, size, codebookInfo.data, codebookSize);
713 
714 	return true;
715 }
716 
readZBUF(Common::SeekableReadStream * s,uint32 size)717 bool VQADecoder::VQAVideoTrack::readZBUF(Common::SeekableReadStream *s, uint32 size) {
718 	if (size > _maxZBUFChunkSize) {
719 		warning("VQA ERROR: ZBUF chunk size: %08x > %08x", size, _maxZBUFChunkSize);
720 		s->skip(roundup(size));
721 		return false;
722 	}
723 
724 	_zbufChunkSize = size;
725 	s->read(_zbufChunk, roundup(size));
726 
727 	return true;
728 }
729 
decodeZBuffer(ZBuffer * zbuffer)730 void VQADecoder::VQAVideoTrack::decodeZBuffer(ZBuffer *zbuffer) {
731 	if (_zbufChunkSize == 0) {
732 		return;
733 	}
734 
735 	zbuffer->decodeData(_zbufChunk, _zbufChunkSize);
736 }
737 
readVIEW(Common::SeekableReadStream * s,uint32 size)738 bool VQADecoder::VQAVideoTrack::readVIEW(Common::SeekableReadStream *s, uint32 size) {
739 	if (size != 56) {
740 		return false;
741 	}
742 
743 	if (_viewData) {
744 		delete[] _viewData;
745 	}
746 
747 	_viewDataSize = roundup(size);
748 	_viewData = new uint8[_viewDataSize];
749 	s->read(_viewData, _viewDataSize);
750 
751 	return true;
752 }
753 
decodeView(View * view)754 void VQADecoder::VQAVideoTrack::decodeView(View *view) {
755 	if (!view || !_viewData) {
756 		return;
757 	}
758 
759 	Common::MemoryReadStream s(_viewData, _viewDataSize);
760 	view->readVqa(&s);
761 
762 	delete[] _viewData;
763 	_viewData = nullptr;
764 }
765 
readAESC(Common::SeekableReadStream * s,uint32 size)766 bool VQADecoder::VQAVideoTrack::readAESC(Common::SeekableReadStream *s, uint32 size) {
767 	if (_screenEffectsData) {
768 		delete[] _screenEffectsData;
769 	}
770 
771 	_screenEffectsDataSize = roundup(size);
772 	_screenEffectsData = new uint8[_screenEffectsDataSize];
773 	s->read(_screenEffectsData, _screenEffectsDataSize);
774 
775 	return true;
776 }
777 
decodeScreenEffects(ScreenEffects * aesc)778 void VQADecoder::VQAVideoTrack::decodeScreenEffects(ScreenEffects *aesc) {
779 	if (!aesc || !_screenEffectsData) {
780 		return;
781 	}
782 
783 	Common::MemoryReadStream s(_screenEffectsData, _screenEffectsDataSize);
784 	aesc->readVqa(&s);
785 
786 	delete[] _screenEffectsData;
787 	_screenEffectsData = nullptr;
788 }
789 
readLITE(Common::SeekableReadStream * s,uint32 size)790 bool VQADecoder::VQAVideoTrack::readLITE(Common::SeekableReadStream *s, uint32 size) {
791 	if (_lightsData) {
792 		delete[] _lightsData;
793 	}
794 
795 	_lightsDataSize = roundup(size);
796 	_lightsData = new uint8[_lightsDataSize];
797 	s->read(_lightsData, _lightsDataSize);
798 
799 	return true;
800 }
801 
802 
decodeLights(Lights * lights)803 void VQADecoder::VQAVideoTrack::decodeLights(Lights *lights) {
804 	if (!lights || !_lightsData) {
805 		return;
806 	}
807 
808 	Common::MemoryReadStream s(_lightsData, _lightsDataSize);
809 	lights->readVqa(&s);
810 
811 	delete[] _lightsData;
812 	_lightsData = nullptr;
813 }
814 
815 
readVPTR(Common::SeekableReadStream * s,uint32 size)816 bool VQADecoder::VQAVideoTrack::readVPTR(Common::SeekableReadStream *s, uint32 size) {
817 	if (size > _maxVPTRSize)
818 		return false;
819 
820 	if (!_vpointer) {
821 		_vpointer = new uint8[roundup(_maxVPTRSize)];
822 	}
823 
824 	_vpointerSize = size;
825 	s->read(_vpointer, roundup(size));
826 
827 	_hasNewFrame = true;
828 
829 	return true;
830 }
831 
VPTRWriteBlock(Graphics::Surface * surface,unsigned int dstBlock,unsigned int srcBlock,int count,bool alpha)832 void VQADecoder::VQAVideoTrack::VPTRWriteBlock(Graphics::Surface *surface, unsigned int dstBlock, unsigned int srcBlock, int count, bool alpha) {
833 	const uint8 *const block_src = &_codebook[2 * srcBlock * _blockW * _blockH];
834 
835 	uint16 blocks_per_line = _width / _blockW;
836 
837 	uint32 intermDiv = 0;
838 	uint32 dst_x = 0;
839 	uint32 dst_y = 0;
840 	uint16 vqaColor = 0;
841 	uint8 a, r, g, b;
842 
843 	for (uint i = count; i != 0; --i) {
844 		intermDiv = (dstBlock + count - i) / blocks_per_line;
845 		dst_x = ((dstBlock + count - i) - intermDiv * blocks_per_line) * _blockW + _offsetX;
846 		dst_y = intermDiv * _blockH + _offsetY;
847 
848 		const uint8 *src_p = block_src;
849 
850 		for (uint y = _blockH; y != 0; --y) {
851 			for (uint x = _blockW; x != 0; --x) {
852 				vqaColor = READ_LE_UINT16(src_p);
853 				src_p += 2;
854 
855 				getGameDataColor(vqaColor, a, r, g, b);
856 
857 				if (!(alpha && a)) {
858 					// clip is too slow and it is not needed
859 					// void* dstPtr = surface->getBasePtr(CLIP(dst_x + x, (uint32)0, (uint32)(surface->w - 1)), CLIP(dst_y + y, (uint32)0, (uint32)(surface->h - 1)));
860 					void* dstPtr = surface->getBasePtr(dst_x + _blockW - x, dst_y + _blockH - y);
861 					// Ignore the alpha in the output as it is inversed in the input
862 					drawPixel(*surface, dstPtr, surface->format.RGBToColor(r, g, b));
863 				}
864 			}
865 		}
866 	}
867 }
868 
decodeFrame(Graphics::Surface * surface)869 bool VQADecoder::VQAVideoTrack::decodeFrame(Graphics::Surface *surface) {
870 	CodebookInfo &codebookInfo = _vqaDecoder->codebookInfoForFrame(_vqaDecoder->_decodingFrame);
871 
872 	if (!codebookInfo.data) {
873 		_vqaDecoder->readFrame(codebookInfo.frame, kVQAReadCodebook);
874 	}
875 
876 	_codebook = codebookInfo.data;
877 	if (!_codebook || !_vpointer)
878 		return false;
879 
880 	uint8 *src = _vpointer;
881 	uint8 *end = _vpointer + _vpointerSize;
882 
883 	uint16 count, srcBlock, dstBlock = 0;
884 	(void)srcBlock;
885 
886 	while (end - src >= 2) {
887 		uint16 command = src[0] | (src[1] << 8);
888 		uint8  prefix = command >> 13;
889 		src += 2;
890 
891 		switch (prefix) {
892 		case 0:
893 			count = command & 0x1fff;
894 			dstBlock += count;
895 			break;
896 		case 1:
897 			count = 2 * (((command >> 8) & 0x1f) + 1);
898 			srcBlock = command & 0x00ff;
899 
900 			VPTRWriteBlock(surface, dstBlock, srcBlock, count);
901 			dstBlock += count;
902 			break;
903 		case 2:
904 			count = 2 * (((command >> 8) & 0x1f) + 1);
905 			srcBlock = command & 0x00ff;
906 
907 			VPTRWriteBlock(surface, dstBlock, srcBlock, 1);
908 			++dstBlock;
909 
910 			for (uint16 i = count; i != 0; --i) {
911 				srcBlock = *src++;
912 				VPTRWriteBlock(surface, dstBlock, srcBlock, 1);
913 				++dstBlock;
914 			}
915 			break;
916 		case 3:
917 		case 4:
918 			count = 1;
919 			srcBlock = command & 0x1fff;
920 
921 			VPTRWriteBlock(surface, dstBlock, srcBlock, count, prefix == 4);
922 			++dstBlock;
923 			break;
924 		case 5:
925 		case 6:
926 			count = *src++;
927 			srcBlock = command & 0x1fff;
928 
929 			VPTRWriteBlock(surface, dstBlock, srcBlock, count, prefix == 6);
930 			dstBlock += count;
931 			break;
932 		default:
933 			warning("VQAVideoTrack::decodeFrame: Undefined case %d", command >> 13);
934 		}
935 	}
936 
937 	return true;
938 }
939 
VQAAudioTrack(VQADecoder * vqaDecoder)940 VQADecoder::VQAAudioTrack::VQAAudioTrack(VQADecoder *vqaDecoder) {
941 	if (vqaDecoder != nullptr) {
942 		_frequency = vqaDecoder->_header.freq;
943 	} else {
944 		warning("VQADecoder::VQAAudioTrack::VQAAudioTrack: null pointer for vqaDecoder parameter");
945 		// TODO use some typical value?
946 		_frequency = 0;
947 	}
948 	memset(_compressedAudioFrame, 0, sizeof(uint8));
949 }
950 
~VQAAudioTrack()951 VQADecoder::VQAAudioTrack::~VQAAudioTrack() {
952 }
953 
decodeAudioFrame()954 Audio::SeekableAudioStream *VQADecoder::VQAAudioTrack::decodeAudioFrame() {
955 	int16 *audioFrame = (int16 *)malloc(kSizeInShortsAllocatedToAudioFrame);
956 	if (audioFrame != nullptr) {
957 		memset(audioFrame, 0, kSizeInShortsAllocatedToAudioFrame);
958 
959 		_adpcmDecoder.decode(_compressedAudioFrame, kSizeInBytesOfCompressedAudioFrame, audioFrame, true);
960 
961 		uint flags = Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN;
962 
963 		return Audio::makeRawStream((byte *)audioFrame, kSizeInShortsAllocatedToAudioFrame, _frequency, flags, DisposeAfterUse::YES);
964 	} else {
965 		warning("VQADecoder::VQAAudioTrack::decodeAudioFrame: Insufficient memory to allocate for audio frame");
966 		return nullptr;
967 	}
968 }
969 
readSND2(Common::SeekableReadStream * s,uint32 size)970 bool VQADecoder::VQAAudioTrack::readSND2(Common::SeekableReadStream *s, uint32 size) {
971 	if (size != kSizeInBytesOfCompressedAudioFrame) {
972 		warning("audio frame size: %d", size);
973 		return false;
974 	}
975 
976 	s->read(_compressedAudioFrame, roundup(size));
977 
978 	return true;
979 }
980 
readSN2J(Common::SeekableReadStream * s,uint32 size)981 bool VQADecoder::VQAAudioTrack::readSN2J(Common::SeekableReadStream *s, uint32 size) {
982 	if (size != 6)
983 		return false;
984 
985 	uint16 stepIndex = s->readUint16LE();
986 	uint32 predictor = s->readUint32LE();
987 
988 	_adpcmDecoder.setParameters(stepIndex >> 5, predictor);
989 
990 	return true;
991 }
992 
993 } // End of namespace BladeRunner
994