Beispiel #1
0
uint32_t File::readUint32BE(uint8_t *ptr) {
	read(ptr, 4);

	return READ_BE_UINT32(ptr);
}
Beispiel #2
0
int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
#ifndef ENABLE_SCI32
	// SCI32 support is not built in. Check if this is a SCI32 game
	// and if it is abort here.
	if (_volVersion >= kResVersionSci2)
		return SCI_ERROR_RESMAP_NOT_FOUND;
#endif

	uint32 offset = 0;
	Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->_volumeNumber), false);

	if (!mapRes) {
		warning("Failed to open %i.MAP", map->_volumeNumber);
		return SCI_ERROR_RESMAP_NOT_FOUND;
	}

	ResourceSource *src = findVolume(map, 0);

	if (!src)
		return SCI_ERROR_NO_RESOURCE_FILES_FOUND;

	byte *ptr = mapRes->data;

	// Heuristic to detect entry size
	uint32 entrySize = 0;
	for (int i = mapRes->size - 1; i >= 0; --i) {
		if (ptr[i] == 0xff)
			entrySize++;
		else
			break;
	}

	if (map->_volumeNumber == 65535) {
		while (ptr < mapRes->data + mapRes->size) {
			uint16 n = READ_LE_UINT16(ptr);
			ptr += 2;

			if (n == 0xffff)
				break;

			if (entrySize == 6) {
				offset = READ_LE_UINT32(ptr);
				ptr += 4;
			} else {
				offset += READ_LE_UINT24(ptr);
				ptr += 3;
			}

			addResource(ResourceId(kResourceTypeAudio, n), src, offset);
		}
	} else if (map->_volumeNumber == 0 && entrySize == 10 && ptr[3] == 0) {
		// QFG3 demo format
		// ptr[3] would be 'seq' in the normal format and cannot possibly be 0
		while (ptr < mapRes->data + mapRes->size) {
			uint16 n = READ_BE_UINT16(ptr);
			ptr += 2;

			if (n == 0xffff)
				break;

			offset = READ_LE_UINT32(ptr);
			ptr += 4;
			uint32 size = READ_LE_UINT32(ptr);
			ptr += 4;

			addResource(ResourceId(kResourceTypeAudio, n), src, offset, size);
		}
	} else if (map->_volumeNumber == 0 && entrySize == 8 && READ_LE_UINT16(ptr + 2) == 0xffff) {
		// LB2 Floppy/Mother Goose SCI1.1 format
		Common::SeekableReadStream *stream = getVolumeFile(src);

		while (ptr < mapRes->data + mapRes->size) {
			uint16 n = READ_LE_UINT16(ptr);
			ptr += 4;

			if (n == 0xffff)
				break;

			offset = READ_LE_UINT32(ptr);
			ptr += 4;

			// The size is not stored in the map and the entries have no order.
			// We need to dig into the audio resource in the volume to get the size.
			stream->seek(offset + 1);
			byte headerSize = stream->readByte();
			assert(headerSize == 11 || headerSize == 12);
			
			stream->skip(5);
			uint32 size = stream->readUint32LE() + headerSize + 2;

			addResource(ResourceId(kResourceTypeAudio, n), src, offset, size);
		}
	} else {
		bool isEarly = (entrySize != 11); 

		if (!isEarly) {
			offset = READ_LE_UINT32(ptr);
			ptr += 4;
		}

		while (ptr < mapRes->data + mapRes->size) {
			uint32 n = READ_BE_UINT32(ptr);
			int syncSize = 0;
			ptr += 4;

			if (n == 0xffffffff)
				break;

			if (isEarly) {
				offset = READ_LE_UINT32(ptr);
				ptr += 4;
			} else {
				offset += READ_LE_UINT24(ptr);
				ptr += 3;
			}

			if (isEarly || (n & 0x80)) {
				syncSize = READ_LE_UINT16(ptr);
				ptr += 2;

				if (syncSize > 0)
					addResource(ResourceId(kResourceTypeSync36, map->_volumeNumber, n & 0xffffff3f), src, offset, syncSize);
			}

			if (n & 0x40) {
				// This seems to define the size of raw lipsync data (at least
				// in kq6), may also just be general appended data.
				syncSize += READ_LE_UINT16(ptr);
				ptr += 2;
			}

			addResource(ResourceId(kResourceTypeAudio36, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize);
		}
	}

	return 0;
}
Beispiel #3
0
void AGOSEngine::loadGamePcFile() {
	Common::SeekableReadStream *in;
	int fileSize;

	if (getFileName(GAME_BASEFILE) != NULL) {
		/* Read main gamexx file */
		in = _archives.open(getFileName(GAME_BASEFILE));
		if (!in) {
			error("loadGamePcFile: Can't load gamexx file '%s'", getFileName(GAME_BASEFILE));
		}

		if (getFeatures() & GF_CRUNCHED_GAMEPC) {
			uint srcSize = in->size();
			byte *srcBuf = (byte *)malloc(srcSize);
			in->read(srcBuf, srcSize);

			uint dstSize = READ_BE_UINT32(srcBuf + srcSize - 4);
			byte *dstBuf = (byte *)malloc(dstSize);
			decrunchFile(srcBuf, dstBuf, srcSize);
			free(srcBuf);

			Common::MemoryReadStream stream(dstBuf, dstSize);
			readGamePcFile(&stream);
			free(dstBuf);
		} else {
			readGamePcFile(in);
		}
		delete in;
	}

	if (getFileName(GAME_TBLFILE) != NULL) {
		/* Read list of TABLE resources */
		in = _archives.open(getFileName(GAME_TBLFILE));
		if (!in) {
			error("loadGamePcFile: Can't load table resources file '%s'", getFileName(GAME_TBLFILE));
		}

		fileSize = in->size();

		_tblList = (byte *)malloc(fileSize);
		if (_tblList == NULL)
			error("loadGamePcFile: Out of memory for strip table list");
		in->read(_tblList, fileSize);
		delete in;

		/* Remember the current state */
		_subroutineListOrg = _subroutineList;
		_tablesHeapPtrOrg = _tablesHeapPtr;
		_tablesHeapCurPosOrg = _tablesHeapCurPos;
	}

	if (getFileName(GAME_STRFILE) != NULL) {
		/* Read list of TEXT resources */
		in = _archives.open(getFileName(GAME_STRFILE));
		if (!in)
			error("loadGamePcFile: Can't load text resources file '%s'", getFileName(GAME_STRFILE));

		fileSize = in->size();
		_strippedTxtMem = (byte *)malloc(fileSize);
		if (_strippedTxtMem == NULL)
			error("loadGamePcFile: Out of memory for strip text list");
		in->read(_strippedTxtMem, fileSize);
		delete in;
	}

	if (getFileName(GAME_STATFILE) != NULL) {
		/* Read list of ROOM STATE resources */
		in = _archives.open(getFileName(GAME_STATFILE));
		if (!in) {
			error("loadGamePcFile: Can't load state resources file '%s'", getFileName(GAME_STATFILE));
		}

		_numRoomStates = in->size() / 8;

		_roomStates = (RoomState *)calloc(_numRoomStates, sizeof(RoomState));
		if (_roomStates == NULL)
			error("loadGamePcFile: Out of memory for room state list");

		for (uint s = 0; s < _numRoomStates; s++) {
			uint16 num = in->readUint16BE() - (_itemArrayInited - 2);

			_roomStates[num].state = in->readUint16BE();
			_roomStates[num].classFlags = in->readUint16BE();
			_roomStates[num].roomExitStates = in->readUint16BE();
		}
		delete in;
	}

	if (getFileName(GAME_RMSLFILE) != NULL) {
		/* Read list of ROOM ITEMS resources */
		in = _archives.open(getFileName(GAME_RMSLFILE));
		if (!in) {
			error("loadGamePcFile: Can't load room resources file '%s'", getFileName(GAME_RMSLFILE));
		}

		fileSize = in->size();

		_roomsList = (byte *)malloc(fileSize);
		if (_roomsList == NULL)
			error("loadGamePcFile: Out of memory for room items list");
		in->read(_roomsList, fileSize);
		delete in;
	}

	if (getFileName(GAME_XTBLFILE) != NULL) {
		/* Read list of XTABLE resources */
		in = _archives.open(getFileName(GAME_XTBLFILE));
		if (!in) {
			error("loadGamePcFile: Can't load xtable resources file '%s'", getFileName(GAME_XTBLFILE));
		}

		fileSize = in->size();

		_xtblList = (byte *)malloc(fileSize);
		if (_xtblList == NULL)
			error("loadGamePcFile: Out of memory for strip xtable list");
		in->read(_xtblList, fileSize);
		delete in;

		/* Remember the current state */
		_xsubroutineListOrg = _subroutineList;
		_xtablesHeapPtrOrg = _tablesHeapPtr;
		_xtablesHeapCurPosOrg = _tablesHeapCurPos;
	}
}
Beispiel #4
0
uint32 AGOSEngine::readUint32Wrapper(const void *src) {
	return READ_BE_UINT32(src);
}
Beispiel #5
0
void DXADecoder::DXAVideoTrack::decode13(int size) {
#ifdef USE_ZLIB
	uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;

	if (!_decompBuffer) {
		_decompBuffer = new byte[_decompBufferSize];
		memset(_decompBuffer, 0, _decompBufferSize);
	}

	/* decompress the input data */
	decodeZlib(_decompBuffer, size, _decompBufferSize);

	memcpy(_frameBuffer2, _frameBuffer1, _frameSize);

	int codeSize = _width * _curHeight / 16;
	int dataSize, motSize;

	dataSize = READ_BE_UINT32(&_decompBuffer[0]);
	motSize  = READ_BE_UINT32(&_decompBuffer[4]);
	//maskSize = READ_BE_UINT32(&_decompBuffer[8]);

	codeBuf = &_decompBuffer[12];
	dataBuf = &codeBuf[codeSize];
	motBuf = &dataBuf[dataSize];
	maskBuf = &motBuf[motSize];

	for (uint32 by = 0; by < _curHeight; by += BLOCKH) {
		for (uint32 bx = 0; bx < _width; bx += BLOCKW) {
			uint8 type = *codeBuf++;
			uint8 *b2 = (uint8 *)_frameBuffer1 + bx + by * _width;

			switch (type) {
			case 0:
				break;

			case 1: {
				uint16 diffMap = READ_BE_UINT16(maskBuf);
				maskBuf += 2;

				for (int yc = 0; yc < BLOCKH; yc++) {
					for (int xc = 0; xc < BLOCKW; xc++) {
						if (diffMap & 0x8000) {
							b2[xc] = *dataBuf++;
						}
						diffMap <<= 1;
					}
					b2 += _width;
				}
				break;
			}
			case 2: {
				uint8 color = *dataBuf++;

				for (int yc = 0; yc < BLOCKH; yc++) {
					for (int xc = 0; xc < BLOCKW; xc++) {
						b2[xc] = color;
					}
					b2 += _width;
				}
				break;
			}
			case 3: {
				for (int yc = 0; yc < BLOCKH; yc++) {
					for (int xc = 0; xc < BLOCKW; xc++) {
						b2[xc] = *dataBuf++;
					}
					b2 += _width;
				}
				break;
			}
			case 4: {
				uint8 mbyte = *motBuf++;

				int mx = (mbyte >> 4) & 0x07;
				if (mbyte & 0x80)
					mx = -mx;
				int my = mbyte & 0x07;
				if (mbyte & 0x08)
					my = -my;

				uint8 *b1 = (uint8 *)_frameBuffer2 + (bx+mx) + (by+my) * _width;
				for (int yc = 0; yc < BLOCKH; yc++) {
					memcpy(b2, b1, BLOCKW);
					b1 += _width;
					b2 += _width;
				}
				break;
			}
			case 8: {
				static const int subX[4] = {0, 2, 0, 2};
				static const int subY[4] = {0, 0, 2, 2};

				uint8 subMask = *maskBuf++;

				for (int subBlock = 0; subBlock < 4; subBlock++) {
					int sx = bx + subX[subBlock], sy = by + subY[subBlock];
					b2 = (uint8 *)_frameBuffer1 + sx + sy * _width;
					switch (subMask & 0xC0) {
					// 00: skip
					case 0x00:
						break;
					// 01: solid color
					case 0x40: {
						uint8 subColor = *dataBuf++;
						for (int yc = 0; yc < BLOCKH / 2; yc++) {
							for (int xc = 0; xc < BLOCKW / 2; xc++) {
								b2[xc] = subColor;
							}
							b2 += _width;
						}
						break;
					}
					// 02: motion vector
					case 0x80: {
						uint8 mbyte = *motBuf++;

						int mx = (mbyte >> 4) & 0x07;
						if (mbyte & 0x80)
							mx = -mx;

						int my = mbyte & 0x07;
						if (mbyte & 0x08)
							my = -my;

						uint8 *b1 = (uint8 *)_frameBuffer2 + (sx+mx) + (sy+my) * _width;
						for (int yc = 0; yc < BLOCKH / 2; yc++) {
							memcpy(b2, b1, BLOCKW / 2);
							b1 += _width;
							b2 += _width;
						}
						break;
					}
					// 03: raw
					case 0xC0:
						for (int yc = 0; yc < BLOCKH / 2; yc++) {
							for (int xc = 0; xc < BLOCKW / 2; xc++) {
								b2[xc] = *dataBuf++;
							}
							b2 += _width;
						}
						break;
					}
					subMask <<= 2;
				}
				break;
			}
			case 32:
			case 33:
			case 34: {
				int count = type - 30;
				uint8 pixels[4];

				memcpy(pixels, dataBuf, count);
				dataBuf += count;

				if (count == 2) {
					uint16 code = READ_BE_UINT16(maskBuf);
					maskBuf += 2;
					for (int yc = 0; yc < BLOCKH; yc++) {
						for (int xc = 0; xc < BLOCKW; xc++) {
							b2[xc] = pixels[code & 1];
							code >>= 1;
						}
						b2 += _width;
					}
				} else {
					uint32 code = READ_BE_UINT32(maskBuf);
					maskBuf += 4;
					for (int yc = 0; yc < BLOCKH; yc++) {
						for (int xc = 0; xc < BLOCKW; xc++) {
							b2[xc] = pixels[code & 3];
							code >>= 2;
						}
						b2 += _width;
					}
				}
				break;
			}
			default:
				error("decode13: Unknown type %d", type);
			}
		}