Esempio n. 1
0
bool createIDMap(PAKFile &out, const ExtractInformation *eI, const int *needList) {
	int dataEntries = 0;
	// Count entries in the need list
	for (const int *n = needList; *n != -1; ++n)
		++dataEntries;

	const int mapSize = 2 + dataEntries * (2 + 1 + 4);
	uint8 *map = new uint8[mapSize];
	uint8 *dst = map;

	WRITE_BE_UINT16(dst, dataEntries); dst += 2;
	for (const int *id = needList; *id != -1; ++id) {
		WRITE_BE_UINT16(dst, *id); dst += 2;
		const ExtractFilename *fDesc = getFilenameDesc(*id);
		if (!fDesc)
			return false;
		*dst++ = getTypeID(fDesc->type);
		WRITE_BE_UINT32(dst, getFilename(eI, *id)); dst += 4;
	}

	char filename[12];
	if (!getFilename(filename, eI, 0)) {
		fprintf(stderr, "ERROR: Could not create ID map for game\n");
		return false;
	}

	out.removeFile(filename);
	if (!out.addFile(filename, map, mapSize)) {
		fprintf(stderr, "ERROR: Could not add ID map \"%s\" to kyra.dat\n", filename);
		return false;
	}

	return true;
}
Esempio n. 2
0
static void writeFakeChar(std::vector<byte> &output, uint32 c, Encoding encoding) {
	byte data[2];

	switch (encoding) {
		case kEncodingASCII:
		case kEncodingLatin9:
		case kEncodingUTF8:
		case kEncodingCP1250:
		case kEncodingCP1251:
		case kEncodingCP1252:
		case kEncodingCP932:
		case kEncodingCP936:
		case kEncodingCP949:
		case kEncodingCP950:
			output.push_back(c);
			break;

		case kEncodingUTF16LE:
			WRITE_LE_UINT16(data, c);
			output.push_back(data[0]);
			output.push_back(data[1]);
			break;

		case kEncodingUTF16BE:
			WRITE_BE_UINT16(data, c);
			output.push_back(data[0]);
			output.push_back(data[1]);
			break;

		default:
			break;
	}
}
Esempio n. 3
0
void Glyph::convertChar16x16(uint8 *dst) const {
	const uint8 *src = plainData;
	dst += yOffset * 2;

	for (int y = 0; y < height; ++y) {
		uint16 mask = 1 << (15 - xOffset);

		const uint8 *curSrc = src;

		uint16 line = 0;
		uint8 d = 0;
		for (int x = 0; x < width; ++x) {
			if (x == 0 || x == 8)
				d = *curSrc++;

			if (d & 0x80)
				line |= mask;

			d <<= 1;
			mask >>= 1;
		}

		WRITE_BE_UINT16(dst, line); dst += 2;
		src += pitch;
	}
}
Esempio n. 4
0
/**
 * Handle a phoneme
 * @remarks	Originally called 'trait_ph'
 */
void SpeechManager::handlePhoneme() {
	const uint16 deca[3] = {300, 30, 40};

	uint16 startPos = _cfiphBuffer[_phonemeNumb - 1] + deca[_typlec];
	uint16 endPos = _cfiphBuffer[_phonemeNumb] + deca[_typlec];
	int wordCount = endPos - startPos;
	
	startPos /= 2;
	endPos /= 2;
	for (int i = startPos, currWord = 0; i < endPos; i++, currWord += 2)
		WRITE_BE_UINT16(&_vm->_mem[(kAdrWord * 16) + currWord], _cfiphBuffer[i]);

	_ptr_oct = 0;
	int currWord = 0;
	initQueue();

	do {
		moveQueue();
		charg_car(currWord);
		trait_car();
	} while (currWord < wordCount);

	moveQueue();
	trait_car();
	entroct((int)'#');
}
Esempio n. 5
0
bool createIDMap(PAKFile &out, const Game *g, const int *needList) {
	int dataEntries = 0;
	// Count entries in the need list and check whether the resources are
	// present
	for (const int *n = needList; *n != -1; ++n) {
		char filename[12];
		if (!getFilename(filename, g, *n) || !out.getFileList()->findEntry(filename)) {
			fprintf(stderr, "ERROR: Could not find need %d for game %04X", *n, createGameDef(g));
			return false;
		}
		++dataEntries;
	}

	const int mapSize = 2 + dataEntries * (2 + 1 + 4);
	uint8 *map = new uint8[mapSize];
	uint8 *dst = map;

	WRITE_BE_UINT16(dst, dataEntries); dst += 2;
	for (const int *id = needList; *id != -1; ++id) {
		WRITE_BE_UINT16(dst, *id); dst += 2;
		const ExtractFilename *fDesc = getFilenameDesc(*id);
		if (!fDesc) {
			delete[] map;
			return false;
		}
		*dst++ = fDesc->type;
		WRITE_BE_UINT32(dst, getFilename(g, *id)); dst += 4;
	}

	char filename[12];
	if (!getFilename(filename, g, 0)) {
		fprintf(stderr, "ERROR: Could not create ID map for game\n");
		delete[] map;
		return false;
	}

	if (!out.addFile(filename, map, mapSize)) {
		fprintf(stderr, "ERROR: Could not add ID map \"%s\" to kyra.dat\n", filename);
		delete[] map;
		return false;
	}

	return true;
}
Esempio n. 6
0
int main(int argc, char *argv[]) {
	if (argc != 2) {
		printHelp(argv[0]);
		return -1;
	}

	PAKFile out;

	// First step: Write out all resources.
	outputAllResources(out);

	// Second step: Write all game version information
	std::vector<GameDef> games;
	outputAllGames(out, games);

	// Third step: Write index file
	byte *const indexBuffer = new byte[8 + 2 * games.size()];
	byte *dst = indexBuffer;
	WRITE_BE_UINT32(dst, kKyraDatVersion); dst += 4;
	WRITE_BE_UINT32(dst, games.size()); dst += 4;
	for (std::vector<GameDef>::const_iterator i = games.begin(), end = games.end(); i != end; ++i) {
		WRITE_BE_UINT16(dst, *i); dst += 2;
	}
	if (!out.addFile("INDEX", indexBuffer, 8 + 2 * games.size())) {
		error("couldn't write INDEX file");
	}

	if (!out.saveFile(argv[1])) {
		error("couldn't save changes to '%s'", argv[1]);
	}

	uint8 digest[16];
	if (!md5_file(argv[1], digest, 0))
		error("couldn't calc. md5 for file '%s'", argv[1]);
	FILE *f = fopen(argv[1], "ab");
	if (!f)
		error("couldn't open file '%s'", argv[1]);
	if (fwrite(digest, 1, 16, f) != 16)
		error("couldn't write md5sum to file '%s'", argv[1]);
	fclose(f);

	return 0;
}
Esempio n. 7
0
bool updateIndex(PAKFile &out, const ExtractInformation *eI) {
	uint32 size = 0;
	const uint8 *data = out.getFileData("INDEX", &size);

	Index index;
	if (data)
		index = parseIndex(data, size);

	GameDef gameDef = createGameDef(eI);
	if (index.version == kKyraDatVersion) {
		if (std::find(index.gameList.begin(), index.gameList.end(), gameDef) == index.gameList.end()) {
			++index.includedGames;
			index.gameList.push_back(gameDef);
		} else {
			// Already included in the game list, thus we do not need any further processing here.
			return true;
		}
	} else {
		index.version = kKyraDatVersion;
		index.includedGames = 1;
		index.gameList.push_back(gameDef);
	}

	const uint32 indexBufferSize = 8 + index.includedGames * 2;
	uint8 *indexBuffer = new uint8[indexBufferSize];
	assert(indexBuffer);
	uint8 *dst = indexBuffer;
	WRITE_BE_UINT32(dst, index.version); dst += 4;
	WRITE_BE_UINT32(dst, index.includedGames); dst += 4;
	for (Index::GameList::const_iterator i = index.gameList.begin(); i != index.gameList.end(); ++i) {
		WRITE_BE_UINT16(dst, *i); dst += 2;
	}

	out.removeFile("INDEX");
	if (!out.addFile("INDEX", indexBuffer, indexBufferSize)) {
		fprintf(stderr, "ERROR: couldn't update kyra.dat INDEX\n");
		delete[] indexBuffer;
		return false;
	}

	return true;
}
Esempio n. 8
0
int16 Op_Exec() {
	int scriptIdx;
	int ovlIdx;
	uint8 *ptr;
	uint8 *ptr2;
	int16 popTable[200];

	int numOfArgToPop = popVar();

	int i = 0;

	for (i = 0; i < numOfArgToPop; i++) {
		popTable[numOfArgToPop - i - 1] = popVar();
	}

	scriptIdx = popVar();
	ovlIdx = popVar();

	if (!ovlIdx) {
		ovlIdx = currentScriptPtr->overlayNumber;
	}

	ptr = attacheNewScriptToTail(&procHead, ovlIdx, scriptIdx, currentScriptPtr->type, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, scriptType_MinusPROC);

	if (!ptr)
		return (0);

	if (numOfArgToPop <= 0) {
		return (0);
	}

	ptr2 = ptr;

	for (i = 0; i < numOfArgToPop; i++) {
		WRITE_BE_UINT16(ptr2, popTable[i]);
		ptr2 += 2;
	}

	return (0);
}
Esempio n. 9
0
void Sound::saveState(byte *&ptr) {
	WRITE_BE_UINT16(ptr, _lastOverride); ptr += 2;
}
Esempio n. 10
0
void WRITE_SCI11ENDIAN_UINT16(void *ptr, uint16 val) {
	if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1)
		WRITE_BE_UINT16(ptr, val);
	else
		WRITE_LE_UINT16(ptr, val);
}
Esempio n. 11
0
void WRITE_SCIENDIAN_UINT16(void *ptr, uint16 val) {
	if (g_sci->isBE())
		WRITE_BE_UINT16(ptr, val);
	else
		WRITE_LE_UINT16(ptr, val);
}
Esempio n. 12
0
void MidiMusicPlayer::playSEQ(uint32 size, bool loop) {
	// MIDI.DAT holds the file names in DW1 PSX
	Common::String baseName((char *)g_midiBuffer.pDat, size);
	Common::String seqName = baseName + ".SEQ";

	// TODO: Load the instrument bank (<baseName>.VB and <baseName>.VH)

	Common::File seqFile;
	if (!seqFile.open(seqName))
		error("Failed to open SEQ file '%s'", seqName.c_str());

	if (seqFile.readUint32LE() != MKTAG('S', 'E', 'Q', 'p'))
		error("Failed to find SEQp tag");

	// Make sure we don't have a SEP file (with multiple SEQ's inside)
	if (seqFile.readUint32BE() != 1)
		error("Can only play SEQ files, not SEP");

	uint16 ppqn = seqFile.readUint16BE();
	uint32 tempo = seqFile.readUint16BE() << 8;
	tempo |= seqFile.readByte();
	/* uint16 beat = */ seqFile.readUint16BE();

	// SEQ is directly based on SMF and we'll use that to our advantage here
	// and convert to SMF and then use the SMF MidiParser.

	// Calculate the SMF size we'll need
	uint32 dataSize = seqFile.size() - 15;
	uint32 actualSize = dataSize + 7 + 22;

	// Resize the buffer if necessary
	if (g_midiBuffer.size < actualSize) {
		g_midiBuffer.pDat = (byte *)realloc(g_midiBuffer.pDat, actualSize);
		assert(g_midiBuffer.pDat);
	}

	// Now construct the header
	WRITE_BE_UINT32(g_midiBuffer.pDat, MKTAG('M', 'T', 'h', 'd'));
	WRITE_BE_UINT32(g_midiBuffer.pDat + 4, 6); // header size
	WRITE_BE_UINT16(g_midiBuffer.pDat + 8, 0); // type 0
	WRITE_BE_UINT16(g_midiBuffer.pDat + 10, 1); // one track
	WRITE_BE_UINT16(g_midiBuffer.pDat + 12, ppqn);
	WRITE_BE_UINT32(g_midiBuffer.pDat + 14, MKTAG('M', 'T', 'r', 'k'));
	WRITE_BE_UINT32(g_midiBuffer.pDat + 18, dataSize + 7); // SEQ data size + tempo change event size

	// Add in a fake tempo change event
	WRITE_BE_UINT32(g_midiBuffer.pDat + 22, 0x00FF5103); // no delta, meta event, tempo change, param size = 3
	WRITE_BE_UINT16(g_midiBuffer.pDat + 26, tempo >> 8);
	g_midiBuffer.pDat[28] = tempo & 0xFF;

	// Now copy in the rest of the events
	seqFile.read(g_midiBuffer.pDat + 29, dataSize);
	seqFile.close();

	MidiParser *parser = MidiParser::createParser_SMF();
	if (parser->loadMusic(g_midiBuffer.pDat, actualSize)) {
		parser->setTrack(0);
		parser->setMidiDriver(this);
		parser->setTimerRate(getBaseTempo());
		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
		parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);

		_parser = parser;

		_isLooping = loop;
		_isPlaying = true;
	} else {
		delete parser;
	}
}
Esempio n. 13
0
void SmackerDecoder::SmackerAudioTrack::queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize) {
	Common::BitStream8LSB audioBS(new Common::MemoryReadStream(buffer, bufferSize), true);
	bool dataPresent = audioBS.getBit();

	if (!dataPresent)
		return;

	bool isStereo = audioBS.getBit();
	assert(isStereo == _audioInfo.isStereo);
	bool is16Bits = audioBS.getBit();
	assert(is16Bits == _audioInfo.is16Bits);

	int numBytes = 1 * (isStereo ? 2 : 1) * (is16Bits ? 2 : 1);

	byte *unpackedBuffer = (byte *)malloc(unpackedSize);
	byte *curPointer = unpackedBuffer;
	uint32 curPos = 0;

	SmallHuffmanTree *audioTrees[4];
	for (int k = 0; k < numBytes; k++)
		audioTrees[k] = new SmallHuffmanTree(audioBS);

	// Base values, stored as big endian

	int32 bases[2];

	if (isStereo) {
		if (is16Bits) {
			bases[1] = SWAP_BYTES_16(audioBS.getBits(16));
		} else {
			bases[1] = audioBS.getBits(8);
		}
	}

	if (is16Bits) {
		bases[0] = SWAP_BYTES_16(audioBS.getBits(16));
	} else {
		bases[0] = audioBS.getBits(8);
	}

	// The bases are the first samples, too
	for (int i = 0; i < (isStereo ? 2 : 1); i++, curPointer += (is16Bits ? 2 : 1), curPos += (is16Bits ? 2 : 1)) {
		if (is16Bits)
			WRITE_BE_UINT16(curPointer, bases[i]);
		else
			*curPointer = (bases[i] & 0xFF) ^ 0x80;
	}

	// Next follow the deltas, which are added to the corresponding base values and
	// are stored as little endian
	// We store the unpacked bytes in big endian format

	while (curPos < unpackedSize) {
		// If the sample is stereo, the data is stored for the left and right channel, respectively
		// (the exact opposite to the base values)
		if (!is16Bits) {
			for (int k = 0; k < (isStereo ? 2 : 1); k++) {
				bases[k] += (int8) ((int16) audioTrees[k]->getCode(audioBS));
				*curPointer++ = CLIP<int>(bases[k], 0, 255) ^ 0x80;
				curPos++;
			}
		} else {
			for (int k = 0; k < (isStereo ? 2 : 1); k++) {
				byte lo = audioTrees[k * 2]->getCode(audioBS);
				byte hi = audioTrees[k * 2 + 1]->getCode(audioBS);
				bases[k] += (int16) (lo | (hi << 8));

				WRITE_BE_UINT16(curPointer, bases[k]);
				curPointer += 2;
				curPos += 2;
			}
		}

	}

	for (int k = 0; k < numBytes; k++)
		delete audioTrees[k];

	queuePCM(unpackedBuffer, unpackedSize);
}
Esempio n. 14
0
void decompressVima(const byte *src, int16 *dest, int destLen, uint16 *destTable) {
	int numChannels = 1;
	byte sBytes[2];
	int16 sWords[2];

	sBytes[0] = *src++;
	if (sBytes[0] & 0x80) {
		sBytes[0] = ~sBytes[0];
		numChannels = 2;
	}
	sWords[0] = READ_BE_UINT16(src);
	src += 2;
	if (numChannels > 1) {
		sBytes[1] = *src++;
		sWords[1] = READ_BE_UINT16(src);
		src += 2;
	}

	int numSamples = destLen / (numChannels * 2);
	int bits = READ_BE_UINT16(src);
	int bitPtr = 0;
	src += 2;

	for (int channel = 0; channel < numChannels; channel++) {
		int16 *destPos = dest + channel;
		int currTablePos = sBytes[channel];
		int outputWord = sWords[channel];

		for (int sample = 0; sample < numSamples; sample++) {
			int numBits = imcTable2[currTablePos];
			bitPtr += numBits;
			int highBit = 1 << (numBits - 1);
			int lowBits = highBit - 1;
			int val = (bits >> (16 - bitPtr)) & (highBit | lowBits);

			if (bitPtr > 7) {
				bits = ((bits & 0xff) << 8) | *src++;
				bitPtr -= 8;
			}

			if (val & highBit)
				val ^= highBit;
			else
				highBit = 0;

			if (val == lowBits) {
				outputWord = ((int16)(bits << bitPtr) & 0xffffff00);
				bits = ((bits & 0xff) << 8) | *src++;
				outputWord |= ((bits >> (8 - bitPtr)) & 0xff);
				bits = ((bits & 0xff) << 8) | *src++;
			} else {
				int index = (val << (7 - numBits)) | (currTablePos << 6);
				int delta = destTable[index];

				if (val)
					delta += (imcTable1[currTablePos] >> (numBits - 1));
				if (highBit)
					delta = -delta;

				outputWord += delta;
				if (outputWord < -0x8000)
					outputWord = -0x8000;
				else if (outputWord > 0x7fff)
					outputWord = 0x7fff;
			}

			WRITE_BE_UINT16(destPos, outputWord);
			destPos += numChannels;

			currTablePos += offsets[numBits - 2][val];

			if (currTablePos < 0)
				currTablePos = 0;
			else if (currTablePos > 88)
				currTablePos = 88;
		}
Esempio n. 15
0
static void DumpWord(int i, FILE* D) {
 byte out[2];
 WRITE_BE_UINT16(out, i);
 DumpBlock(out,2,D);
}
Esempio n. 16
0
void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
		uint32 unpackedSize, int streamNum) {

	BitStream audioBS(buffer, bufferSize);
	bool dataPresent = audioBS.getBit();

	if (!dataPresent)
		return;

	bool isStereo = audioBS.getBit();
	assert(isStereo == _header.audioInfo[streamNum].isStereo);
	bool is16Bits = audioBS.getBit();
	assert(is16Bits == _header.audioInfo[streamNum].is16Bits);

	int numBytes = 1 * (isStereo ? 2 : 1) * (is16Bits ? 2 : 1);

	byte *unpackedBuffer = (byte *)malloc(unpackedSize);
	byte *curPointer = unpackedBuffer;
	uint32 curPos = 0;

	SmallHuffmanTree *audioTrees[4];
	for (int k = 0; k < numBytes; k++)
		audioTrees[k] = new SmallHuffmanTree(audioBS);

	// Base values, stored as big endian

	int32 bases[2];

	if (isStereo) {
		if (is16Bits) {
			byte hi = audioBS.getBits8();
			byte lo = audioBS.getBits8();
			bases[1] = (int16) ((hi << 8) | lo);
		} else {
			bases[1] = audioBS.getBits8();
		}
	}

	if (is16Bits) {
		byte hi = audioBS.getBits8();
		byte lo = audioBS.getBits8();
		bases[0] = (int16) ((hi << 8) | lo);
	} else {
		bases[0] = audioBS.getBits8();
	}

	// The bases are the first samples, too
	for (int i = 0; i < (isStereo ? 2 : 1); i++, curPointer += (is16Bits ? 2 : 1), curPos += (is16Bits ? 2 : 1)) {
		if (is16Bits)
			WRITE_BE_UINT16(curPointer, bases[i]);
		else
			*curPointer = (bases[i] & 0xFF) ^ 0x80;
	}

	// Next follow the deltas, which are added to the corresponding base values and
	// are stored as little endian
	// We store the unpacked bytes in big endian format

	while (curPos < unpackedSize) {
		// If the sample is stereo, the data is stored for the left and right channel, respectively
		// (the exact opposite to the base values)
		if (!is16Bits) {
			for (int k = 0; k < (isStereo ? 2 : 1); k++) {
				bases[k] += (int8) ((int16) audioTrees[k]->getCode(audioBS));
				*curPointer++ = CLIP<int>(bases[k], 0, 255) ^ 0x80;
				curPos++;
			}
		} else {
			for (int k = 0; k < (isStereo ? 2 : 1); k++) {
				byte lo = audioTrees[k * 2]->getCode(audioBS);
				byte hi = audioTrees[k * 2 + 1]->getCode(audioBS);
				bases[k] += (int16) (lo | (hi << 8));

				WRITE_BE_UINT16(curPointer, bases[k]);
				curPointer += 2;
				curPos += 2;
			}
		}

	}

	for (int k = 0; k < numBytes; k++)
		delete audioTrees[k];

	byte flags = 0;
	if (_header.audioInfo[0].is16Bits)
		flags = flags | Audio::FLAG_16BITS;
	if (_header.audioInfo[0].isStereo)
		flags = flags | Audio::FLAG_STEREO;
	_audioStream->queueBuffer(unpackedBuffer, unpackedSize, DisposeAfterUse::YES, flags);
	// unpackedBuffer will be deleted by QueuingAudioStream
}
Esempio n. 17
0
int updateScriptImport(int ovlIdx) {
	char buffer[256];
	ovlDataStruct *ovlData;
	int numData3;
	int size5;
	int numRelocGlob;
	int param;
	int var_32;
	ovlData3Struct *pScript;
//  char* arrayRelocGlob;
//  char* namePtr;
//  char* arrayMsgRelHeader;

	if (!overlayTable[ovlIdx].ovlData)
		return (-4);

	ovlData = overlayTable[ovlIdx].ovlData;

	numData3 = ovlData->numProc;
	size5 = ovlData->numRel;
	numRelocGlob = ovlData->numRelocGlob;
	param = 0;

	// do it for the 2 first string types
	do {

		int i = 0;

		if (param == 0) {
			var_32 = numData3;
		} else {
			var_32 = size5;
		}

		if (var_32) {
			do {
				importScriptStruct *ptrImportData;
				const char *ptrImportName;
				uint8 *ptrData;

				int var_22 = 0;

				if (param == 0) {
					pScript = getOvlData3Entry(ovlIdx, i);
				} else {
					pScript = scriptFunc1Sub2(ovlIdx, i);
				}

				ptrImportData = (importScriptStruct *)(pScript->dataPtr + pScript->offsetToImportData);	// import data
				ptrImportName = (const char*)(pScript->dataPtr + pScript->offsetToImportName);	// import name
				ptrData = pScript->dataPtr;

				var_22 = 0;

				if (pScript->numRelocGlob > 0) {
					int counter = pScript->numRelocGlob;

					do {
						int param2 = ptrImportData->type;

						if (param2 != 70) {
							exportEntryStruct * ptrDest2;
							int out1;
							int out2;

							strcpy(buffer, ptrImportName + ptrImportData->offsetToName);
							ptrDest2 = parseExport(&out1, &out2, buffer);

							if (ptrDest2 && out2) {
								int temp =
								    ptrImportData->
								    offset;
								if (out1) {	//is sub function... (ie  'invent.livre:s')
									uint8 *ptr = ptrData + temp;

									*(ptr + 1) = out2;
									WRITE_BE_UINT16(ptr + 2, ptrDest2->idx);
								} else {
									if (param2 == 20 || param2 == 30 || param2 == 40 || param2 == 50) {	// this patch a double push
										uint8 *ptr = ptrData + temp;

										*(ptr + 1) = 0;
										*(ptr + 2) = out2;	// update the overlay number

										WRITE_BE_UINT16(ptr + 4, ptrDest2->idx);
									} else {
										int var_4 = ptrDest2->var4;

										if (var_4 & 1) {
											param2 = 8;
										} else {
											param2 = 16;
										}

										if (var_4 >= 0 && var_4 <= 3) {
											param2 |= 5;
										} else {
											param2 |= 6;
										}

										*(ptrData + temp) = param2;
										*(ptrData + temp + 1) = out2;

										WRITE_BE_UINT16(ptrData + temp + 2, ptrDest2->idx);
									}
								}
							}
						}

						ptrImportData++;
					} while (--counter);
				}

			} while (++i < var_32);

		}

	} while (++param < 2);

	if (ovlData->arrayRelocGlob && ovlData->arrayNameRelocGlob && numRelocGlob) {
		int numImport2 = numRelocGlob;
		int i;

		for (i = 0; i < numImport2; i++) {
			int out1;
			int foundExportIdx;
			exportEntryStruct *pFoundExport;
			int linkType;
			int linkEntryIdx;

			strcpy(buffer, ovlData->arrayNameRelocGlob + ovlData->arrayRelocGlob[i].nameOffset);

			pFoundExport = parseExport(&out1, &foundExportIdx, buffer);

			linkType = ovlData->arrayRelocGlob[i].linkType;
			linkEntryIdx = ovlData->arrayRelocGlob[i].linkIdx;

			if (pFoundExport && foundExportIdx) {
				switch (linkType) {
				case 0: {	// verb
					ovlData->arrayMsgRelHeader[linkEntryIdx].verbOverlay = foundExportIdx;
					ovlData->arrayMsgRelHeader[linkEntryIdx].verbNumber = pFoundExport->idx;
					break;
				}
				case 1: {	// obj1
					ovlData->arrayMsgRelHeader[linkEntryIdx].obj1Overlay = foundExportIdx;
					ovlData->arrayMsgRelHeader[linkEntryIdx].obj1Number = pFoundExport->idx;
					break;
				}
				case 2: {	// obj2
					ovlData->arrayMsgRelHeader[linkEntryIdx].obj2Overlay = foundExportIdx;
					ovlData->arrayMsgRelHeader[linkEntryIdx].obj2Number = pFoundExport->idx;
					break;
				}
				}
			}
		}
	}

	return (0);
}