Example #1
0
void AGOSEngine::dumpVgaFile(const byte *vga) {
	const byte *pp;
	const byte *p;
	int16 count;

	pp = vga;
	p = pp + READ_BE_UINT16(pp + 10) + 20;
	count = READ_BE_UINT16(&((const VgaFile1Header_Common *) p)->animationCount);
	p = pp + READ_BE_UINT16(&((const VgaFile1Header_Common *) p)->animationTable);

	while (--count >= 0) {
		uint16 id = READ_BE_UINT16(&((const AnimationHeader_WW *) p)->id);

		dumpVgaScriptAlways(vga + READ_BE_UINT16(&((const AnimationHeader_WW *) p)->scriptOffs), id / 100, id);
		p += sizeof(AnimationHeader_WW);
	}

	pp = vga;
	p = pp + READ_BE_UINT16(pp + 10) + 20;
	count = READ_BE_UINT16(&((const VgaFile1Header_Common *) p)->imageCount);
	p = pp + READ_BE_UINT16(&((const VgaFile1Header_Common *) p)->imageTable);

	while (--count >= 0) {
		uint16 id = READ_BE_UINT16(&((const ImageHeader_WW *) p)->id);

		dumpVgaScriptAlways(vga + READ_BE_UINT16(&((const ImageHeader_WW *) p)->scriptOffs), id / 100, id);
		p += sizeof(ImageHeader_WW);
	}
}
Example #2
0
void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height) {
	int32 sync_size;
	byte *sync_ptr;

	msPos /= 16;
	if (msPos < 65536) {
		Common::StackLock lock(_mutex, "IMuseDigital::getLipSync()");
		for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
			Track *track = _track[l];
			if (track->used && !track->toBeRemoved && (track->soundId == soundId)) {
				_sound->getSyncSizeAndPtrById(track->soundDesc, syncId, sync_size, &sync_ptr);
				if ((sync_size != 0) && (sync_ptr != NULL)) {
					sync_size /= 4;
					while (sync_size--) {
						if (READ_BE_UINT16(sync_ptr) >= msPos)
							break;
						sync_ptr += 4;
					}
					if (sync_size < 0)
						sync_ptr -= 4;
					else
						if (READ_BE_UINT16(sync_ptr) > msPos)
							sync_ptr -= 4;

					width = sync_ptr[2];
					height = sync_ptr[3];
					return;
				}
			}
		}
	}
}
void SfxPlayer::loadSfxModule(uint16_t resNum, uint16_t delay, uint8_t pos) {

	debug(DBG_SND, "SfxPlayer::loadSfxModule(0x%X, %d, %d)", resNum, delay, pos);
	MutexStack(sys, _mutex);


	MemEntry *me = &res->_memList[resNum];

	if (me->state == 1 && me->type == Resource::RT_MUSIC) {
		_resNum = resNum;
		memset(&_sfxMod, 0, sizeof(SfxModule));
		_sfxMod.curOrder = pos;
		_sfxMod.numOrder = READ_BE_UINT16(me->bufPtr + 0x3E);
		debug(DBG_SND, "SfxPlayer::loadSfxModule() curOrder = 0x%X numOrder = 0x%X", _sfxMod.curOrder, _sfxMod.numOrder);
		for (int i = 0; i < 0x80; ++i) {
			_sfxMod.orderTable[i] = *(me->bufPtr + 0x40 + i);
		}
		if (delay == 0) {
			_delay = READ_BE_UINT16(me->bufPtr);
		} else {
			_delay = delay;
		}
		_delay = _delay * 60 / 7050;
		_sfxMod.data = me->bufPtr + 0xC0;
		debug(DBG_SND, "SfxPlayer::loadSfxModule() eventDelay = %d ms", _delay);
		prepareInstruments(me->bufPtr + 2);
	} else {
		warning("SfxPlayer::loadSfxModule() ec=0x%X", 0xF8);
	}
}
Example #4
0
void loadRel(char *pRelName) {
	uint16 numEntry;
	uint16 i;
	byte *ptr;

	checkDataDisk(-1);

	for (i = 0; i < NUM_MAX_REL; i++) {
		if (relTable[i].data) {
			free(relTable[i].data);
			relTable[i].data = NULL;
			relTable[i].size = 0;
		}
	}

	ptr = readBundleFile(findFileInBundle(pRelName));

	setMouseCursor(MOUSE_CURSOR_DISK);

	numEntry = READ_BE_UINT16(ptr); ptr += 2;

	assert(numEntry <= NUM_MAX_REL);

	for (i = 0; i < numEntry; i++) {
		relTable[i].size = READ_BE_UINT16(ptr); ptr += 2;
		relTable[i].obj1Param1 = READ_BE_UINT16(ptr); ptr += 2;
		relTable[i].obj1Param2 = READ_BE_UINT16(ptr); ptr += 2;
		relTable[i].obj2Param = READ_BE_UINT16(ptr); ptr += 2;
	}

	for (i = 0; i < numEntry; i++) {
		if (relTable[i].size) {
			relTable[i].data = (byte *)malloc(relTable[i].size);

			assert(relTable[i].data);

			memcpy(relTable[i].data, ptr, relTable[i].size);
			ptr += relTable[i].size;
		}
	}

#ifdef DUMP_SCRIPTS

	{
		uint16 s;
		char buffer[256];

		for (s = 0; s < numEntry; s++) {
			if (relTable[s].size) {
				sprintf(buffer, "%s_%03d.txt", pRelName, s);

				decompileScript(relTable[s].data, NULL, relTable[s].size, s);
				dumpScript(buffer);
			}
		}
	}
#endif
}
Example #5
0
/*! \todo Is script size of 0 valid?
 * \todo Fix script dump code
 */
void loadRel(char *pRelName) {
	uint16 numEntry;
	uint16 i;
	uint16 size, p1, p2, p3;
	byte *ptr, *dataPtr;

	checkDataDisk(-1);

	objectScripts.clear();
	relTable.clear();

	ptr = dataPtr = readBundleFile(findFileInBundle(pRelName));

	setMouseCursor(MOUSE_CURSOR_DISK);

	numEntry = READ_BE_UINT16(ptr); ptr += 2;

	for (i = 0; i < numEntry; i++) {
		size = READ_BE_UINT16(ptr); ptr += 2;
		p1 = READ_BE_UINT16(ptr); ptr += 2;
		p2 = READ_BE_UINT16(ptr); ptr += 2;
		p3 = READ_BE_UINT16(ptr); ptr += 2;
		RawObjectScriptPtr tmp(new RawObjectScript(size, p1, p2, p3));
		assert(tmp);
		relTable.push_back(tmp);
	}

	for (i = 0; i < numEntry; i++) {
		size = relTable[i]->_size;
		// TODO: delete the test?
		if (size) {
			relTable[i]->setData(*scriptInfo, ptr);
			ptr += size;
		}
	}

	free(dataPtr);

#ifdef DUMP_SCRIPTS

	{
		uint16 s;
		char buffer[256];

		for (s = 0; s < numEntry; s++) {
			if (relTable[s]->_size) {
				sprintf(buffer, "%s_%03d.txt", pRelName, s);

				decompileScript((const byte *)relTable[s]->getString(0), relTable[s]->_size, s);
				dumpScript(buffer);
			}
		}
	}
#endif
}
Example #6
0
bool Player_V3M::loadMusic(const byte *ptr) {
	Common::MacResManager resource;
	bool found = false;

	for (int i = 0; i < ARRAYSIZE(loomFileNames); i++) {
		if (resource.open(loomFileNames[i])) {
			found = true;
			break;
		}
	}

	if (!found) {
		return false;
	}

	if (ptr[4] != 's' || ptr[5] != 'o') {
		// Like the original we ignore all sound resources which do not have
		// a 'so' tag in them.
		// See bug #3602239 ("Mac Loom crashes using opening spell on
		// gravestone") for a case where this is required. Loom Mac tries to
		// play resource 11 here. This resource is no Mac sound resource
		// though, it is a PC Speaker resource. A test with the original
		// interpreter also has shown that no sound is played while the
		// screen is shaking.
		debug(5, "Player_V3M::loadMusic: Skipping unknown music type %02X%02X", ptr[4], ptr[5]);
		resource.close();
		return false;
	}

	uint i;
	for (i = 0; i < 5; i++) {
		int instrument = READ_BE_UINT16(ptr + 20 + 2 * i);
		int offset = READ_BE_UINT16(ptr + 30 + 2 * i);

		_channel[i]._looped = false;
		_channel[i]._length = READ_BE_UINT16(ptr + offset + 4) * 3;
		_channel[i]._data = ptr + offset + 6;
		_channel[i]._pos = 0;
		_channel[i]._pitchModifier = 0;
		_channel[i]._velocity = 0;
		_channel[i]._remaining = 0;
		_channel[i]._notesLeft = true;

		Common::SeekableReadStream *stream = resource.getResource(RES_SND, instrument);
		if (_channel[i].loadInstrument(stream)) {
			debug(6, "Player_V3M::loadMusic: Channel %d - Loaded Instrument %d (%s)", i, instrument, resource.getResName(RES_SND, instrument).c_str());
		} else {
			resource.close();
			return false;
		}
	}

	resource.close();
	return true;
}
Example #7
0
	void playSoundRaw(uint8_t channel, const uint8_t *data, uint16_t freq, uint8_t volume) {
		int len = READ_BE_UINT16(data) * 2;
		const int loopLen = READ_BE_UINT16(data + 2) * 2;
		if (loopLen != 0) {
			len = loopLen;
		}
		uint8_t *sample = convertToWav(data + 8, freq, len);
		if (sample) {
			playSoundWav(channel, sample, volume, (loopLen != 0) ? -1 : 0);
			free(sample);
		}
	}
Example #8
0
/**
 * Find a word in the dictionary
 * Uses an algorithm hopefully like the one Sierra used. Returns the ID
 * of the word and the length in flen. Returns -1 if not found.
 *
 * Thomas Akesson, November 2001
 */
int AgiEngine::findWord(char *word, int *flen) {
	int mchr = 0;		// matched chars
	int len, fchr, id = -1;
	uint8 *p = words;
	uint8 *q = words + wordsFlen;
	*flen = 0;

	debugC(2, kDebugLevelScripts, "find_word(%s)", word);

	if (word[0] >= 'a' && word[0] <= 'z')
		fchr = word[0] - 'a';
	else
		return -1;

	len = strlen(word);

	// Get the offset to the first word beginning with the
	// right character
	p += READ_BE_UINT16(p + 2 * fchr);

	while (p[0] >= mchr) {
		if (p[0] == mchr) {
			p++;
			// Loop through all matching characters
			while ((p[0] ^ word[mchr]) == 0x7F && mchr < len) {
				mchr++;
				p++;
			}
			// Check if this is the last character of the word
			// and if it matches
			if ((p[0] ^ word[mchr]) == 0xFF && mchr < len) {
				mchr++;
				if (word[mchr] == 0 || word[mchr] == 0x20) {
					id = READ_BE_UINT16(p + 1);
					*flen = mchr;
				}
			}
		}
		if (p >= q)
			return -1;

		// Step to the next word
		while (p[0] < 0x80)
			p++;

		p += 3;
	}

	return id;
}
Example #9
0
void Sound::playSound(uint16 sound, uint16 volume, uint8 channel) {
	if (channel == 0)
		_mixer->stopID(SOUND_CH0);
	else
		_mixer->stopID(SOUND_CH1);

	if (!_soundData) {
		warning("Sound::playSound(%04X, %04X) called with a section having been loaded", sound, volume);
		return;
	}

	if (sound > _soundsTotal) {
		debug(5, "Sound::playSound %d ignored, only %d sfx in file", sound, _soundsTotal);
		return;
	}

	volume = (volume & 0x7F) << 1;
	sound &= 0xFF;

	// Note: All those tables are big endian. Don't ask me why. *sigh*

	// Use the sample rate from game data, see bug #1507757.
	uint16 sampleRate = READ_BE_UINT16(_sampleRates + (sound << 2));
	if (sampleRate > 11025)
		sampleRate = 11025;
	uint32 dataOfs  = READ_BE_UINT16(_sfxInfo + (sound << 3) + 0) << 4;
	uint32 dataSize = READ_BE_UINT16(_sfxInfo + (sound << 3) + 2);
	uint32 dataLoop = READ_BE_UINT16(_sfxInfo + (sound << 3) + 6);
	dataOfs += _sfxBaseOfs;

	Audio::SeekableAudioStream *stream = Audio::makeRawStream(_soundData + dataOfs, dataSize, sampleRate,
	                                                                Audio::FLAG_UNSIGNED, DisposeAfterUse::NO);

	Audio::AudioStream *output = 0;
	if (dataLoop) {
		uint32 loopSta = dataSize - dataLoop;
		uint32 loopEnd = dataSize;

		output = Audio::makeLoopingAudioStream(stream, Audio::Timestamp(0, loopSta, sampleRate),
		                                       Audio::Timestamp(0, loopEnd, sampleRate), 0);
	} else {
		output = stream;
	}

	if (channel == 0)
		_mixer->playStream(Audio::Mixer::kSFXSoundType, &_ingameSound0, output, SOUND_CH0, volume, 0);
	else
		_mixer->playStream(Audio::Mixer::kSFXSoundType, &_ingameSound1, output, SOUND_CH1, volume, 0);
}
Example #10
0
static void convertCompressedImage(const byte *src, byte *dst, uint8 colorDepth, int height, int width, bool horizontal = true) {
	const byte *plane[kMaxColorDepth];
	byte *uncptr[kMaxColorDepth];
	int length, i, j;

	byte *uncbfrout = (byte *)malloc(width * height);

	length = (width + 15) / 16 * height;

	for (i = 0; i < colorDepth; ++i) {
		plane[i] = src + READ_BE_UINT16(src + i * 4) + READ_BE_UINT16(src + i * 4 + 2);
		uncptr[i] = (uint8 *)malloc(length * 2);
		uncompressPlane(plane[i], uncptr[i], length);
		plane[i] = uncptr[i];
	}

	byte *uncbfroutptr = uncbfrout;
	for (i = 0; i < length; ++i) {
		uint16 w[kMaxColorDepth];
		for (j = 0; j < colorDepth; ++j) {
			w[j] = READ_BE_UINT16(plane[j]); plane[j] += 2;
		}
		bitplaneToChunky(w, colorDepth, uncbfroutptr);
	}

	uncbfroutptr = uncbfrout;
	const int chunkSize = colorDepth > 4 ? 16 : 8;
	if (horizontal) {
		for (j = 0; j < height; ++j) {
			for (i = 0; i < width / 16; ++i) {
				memcpy(dst + width * chunkSize / 16 * j + chunkSize * i, uncbfroutptr, chunkSize);
				uncbfroutptr += chunkSize;
			}
		}
	} else {
		for (i = 0; i < width / 16; ++i) {
			for (j = 0; j < height; ++j) {
				memcpy(dst + width * chunkSize / 16 * j + chunkSize * i, uncbfroutptr, chunkSize);
				uncbfroutptr += chunkSize;
			}
		}
	}

	free(uncbfrout);
	for (i = 0; i < colorDepth; ++i) {
		free(uncptr[i]);
	}
}
Example #11
0
byte loadCtOS(const char *ctName) {
	debugC(1, kCineDebugCollision, "loadCtOS(\"%s\")", ctName);
	byte *ptr, *dataPtr;

	int16 foundFileIdx = findFileInBundle(ctName);
	if (foundFileIdx == -1) {
		warning("loadCtOS: Unable to find collision data file '%s'", ctName);
		// FIXME: Rework this function's return value policy and return an appropriate value here.
		// The return value isn't yet used for anything so currently it doesn't really matter.
		return 0;
	}

	if (currentCtName != ctName)
		strcpy(currentCtName, ctName);

	ptr = dataPtr = readBundleFile(foundFileIdx);

	uint16 bpp = READ_BE_UINT16(ptr);
	ptr += 2;

	if (bpp == 8) {
		renderer->loadCt256(ptr, ctName);
	} else {
		gfxConvertSpriteToRaw(collisionPage, ptr + 32, 160, 200);
		renderer->loadCt16(ptr, ctName);
	}

	free(dataPtr);
	return 0;
}
Example #12
0
byte loadCt(const char *ctName) {
	uint16 header[32];

	strcpy(currentCtName, ctName);

	byte *ptr = readBundleFile(findFileInBundle(ctName));

	if (gameType == Cine::GID_OS) {
		uint16 bpp = READ_BE_UINT16(ptr); ptr += 2;
		if (bpp == 8) {
			ptr += 3 * 256;
			loadCtHigh(ptr);
		} else {
			ptr += 32;
			gfxResetRawPage(page3Raw);
			gfxConvertSpriteToRaw(page3Raw, ptr, 160, 200);
		}
	} else {
		loadRelatedPalette(ctName);

		assert(strstr(ctName, ".NEO"));

		Common::MemoryReadStream readS(ptr, 32);

		for (int i = 0; i < 16; i++) {
			header[i] = readS.readUint16BE();
		}

		gfxConvertSpriteToRaw(page3Raw, ptr + 0x80, 160, 200);
	}

	return 0;
}
Example #13
0
void SoundManager::regenbruit() {
	int i = 69876;
	for (int j = 0; j < 100; j++) {
		_cfiphBuffer[j] = READ_BE_UINT16(&_noiseBuf[i]);
		i += 2;
	}
}
Example #14
0
/**
 * This function does noting but load a raw resource into memory,
 * if further decoding is required, it must be done by another
 * routine. NULL is returned if unsucsessfull.
 */
uint8 *AgiLoader_v2::loadVolRes(struct AgiDir *agid) {
	uint8 *data = NULL;
	char x[MAXPATHLEN], *path;
	Common::File fp;
	unsigned int sig;

	sprintf(x, "vol.%i", agid->volume);
	path = x;
	debugC(3, kDebugLevelResources, "Vol res: path = %s", path);

	if (agid->offset != _EMPTY && fp.open(path)) {
		debugC(3, kDebugLevelResources, "loading resource at offset %d", agid->offset);
		fp.seek(agid->offset, SEEK_SET);
		fp.read(&x, 5);
		if ((sig = READ_BE_UINT16((uint8 *) x)) == 0x1234) {
			agid->len = READ_LE_UINT16((uint8 *) x + 3);
			data = (uint8 *) calloc(1, agid->len + 32);
			if (data != NULL) {
				fp.read(data, agid->len);
			} else {
				exit(1);
			}
		} else {
			warning("AgiLoader_v2::loadVolRes: bad signature %04x", sig);
			return 0;
		}
		fp.close();
	} else {
		// we have a bad volume resource
		// set that resource to NA
		agid->offset = _EMPTY;
	}

	return data;
}
Example #15
0
int Graphics::drawChar16(uint8 *dst, int dstPitch, uint8 chr, int x, int y, uint16 color) {
	dst += y * dstPitch + x;
	uint8 color1 = color & 0xFF;
	uint8 color2 = color >> 8;
	assert(chr >= 32 && chr < 32 + _fontSize);
	const uint8 *chrData = _fontData + _fontOffs[chr - 32];
	int chrHeight = chrData[1];
	int chrWidth = chrData[2];
	chrData += 3;
	while (chrHeight--) {
		int shiftCount = 0;
		int mask = 0;
		for (int i = 0; i < chrWidth; ++i) {
			if (shiftCount == 0) {
				mask = READ_BE_UINT16(chrData); chrData += 2;
				shiftCount = 8;
			}
			int b = (mask & 0xC000) >> 14;
			mask <<= 2;
			--shiftCount;
			if (b) {
				if (b & 2) {
					dst[i] = color2;
				} else {
					dst[i] = color1;
				}
			}
		}
		dst += dstPitch;
	}
	return chrWidth;
}
Example #16
0
byte *AGOSEngine::convertImage(VC10_state *state, bool compressed) {
	int length, i, j;

	uint8 colorDepth = 4;
	if (getGameType() == GType_SIMON1) {
		if (((_videoLockOut & 0x20) && !state->palette) || ((getFeatures() & GF_32COLOR) &&
			state->palette != 0xC0)) {
			colorDepth = 5;
		}
	}

	const byte *src = state->srcPtr;
	int width = state->width * 16;
	int height = state->height;

	free(_planarBuf);
	_planarBuf = (byte *)malloc(width * height);
	byte *dst = _planarBuf;

	if (compressed) {
		convertCompressedImage(src, dst, colorDepth, height, width, (getGameType() == GType_PN));
	} else {
		length = (width + 15) / 16 * height;
		for (i = 0; i < length; i++) {
			uint16 w[kMaxColorDepth];
			if (getGameType() == GType_SIMON1 && colorDepth == 4) {
				for (j = 0; j < colorDepth; ++j) {
					w[j] = READ_BE_UINT16(src + j * length * 2);
				}
				if (state->palette == 0xC0) {
					bitplaneToChunkyText(w, colorDepth, dst);
				} else {
					bitplaneToChunky(w, colorDepth, dst);
				}
				src += 2;
			} else {
				for (j = 0; j < colorDepth; ++j) {
					w[j] = READ_BE_UINT16(src); src += 2;
				}
				bitplaneToChunky(w, colorDepth, dst);
			}
		}
	}

	return _planarBuf;
}
Example #17
0
File: main.cpp Project: cyxx/rawgl
void Player::handlePattern(uint8_t channel, uint8_t *&data, Pattern *pat) {
	pat->note_1 = READ_BE_UINT16(data + 0);
	pat->note_2 = READ_BE_UINT16(data + 2);
	data += 4;
	if (pat->note_1 != 0xFFFD) {
		uint16_t sample = (pat->note_2 & 0xF000) >> 12;
		if (sample != 0) {
			uint8_t *ptr = _sfxMod.samples[sample - 1].buf.buf;
			fprintf(stdout, "Preparing sample %d ptr = %p\n", sample, ptr);
			if (ptr != 0) {
				pat->sample_volume = _sfxMod.samples[sample - 1].volume;
				pat->sample_start = 8;
				pat->sample_buffer = ptr;
				pat->period_value = READ_BE_UINT16(ptr) * 2;
				uint16_t loopLen = READ_BE_UINT16(ptr + 2) * 2;
				if (loopLen != 0) {
					pat->loopPos = pat->period_value;
					pat->loopData = ptr;
					pat->loopLen = loopLen;
				} else {
					pat->loopPos = 0;
					pat->loopData = 0;
					pat->loopLen = 0;
				}
				int16_t m = pat->sample_volume;
				uint8_t effect = pat->note_2 & 0x0F00;
				fprintf(stdout, "effect = %d\n", effect);
				if (effect == 5) { // volume up
					uint8_t volume = (pat->note_2 & 0xFF);
					m += volume;
					if (m > 0x3F) {
						m = 0x3F;
					}
				} else if (effect == 6) { // volume down
					uint8_t volume = (pat->note_2 & 0xFF);
					m -= volume;
					if (m < 0) {
						m = 0;
					}	
				}
				Mix_setChannelVolume(channel, m);
				pat->sample_volume = m;
			}
		}
	}
Example #18
0
void SfxPlayer::prepareInstruments(const uint8_t *p) {
	memset(_sfxMod.samples, 0, sizeof(_sfxMod.samples));
	for (int i = 0; i < 15; ++i) {
		SfxInstrument *ins = &_sfxMod.samples[i];
		uint16_t resNum = READ_BE_UINT16(p); p += 2;
		if (resNum != 0) {
			ins->volume = READ_BE_UINT16(p);
			MemEntry *me = &_res->_memList[resNum];
			if (me->status == Resource::STATUS_LOADED && me->type == 0) {
				ins->data = me->bufPtr;
				debug(DBG_SND, "Loaded instrument 0x%X n=%d volume=%d", resNum, i, ins->volume);
			} else {
				error("Error loading instrument 0x%X", resNum);
			}
		}
		p += 2; // skip volume
	}
}
Example #19
0
void SpeechManager::regenbruit() {
	int i = kOffsetB3 + 8590;
	int j = 0;
	do {
		_cfiphBuffer[j] = READ_BE_UINT16(&_vm->_mem[(kAdrNoise3 * 16) + i]);
		i += 2;
		++j;
	} while (i < kOffsetB3 + 8790);
}
Example #20
0
void Kernel::loadSelectorNames() {
	Resource *r = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS), 0);
	bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);

	// Starting with KQ7, Mac versions have a BE name table. GK1 Mac and earlier (and all
	// other platforms) always use LE.
	bool isBE = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2_1
			&& g_sci->getGameId() != GID_GK1);

	if (!r) { // No such resource?
		// Check if we have a table for this game
		// Some demos do not have a selector table
		Common::StringArray staticSelectorTable = checkStaticSelectorNames();

		if (staticSelectorTable.empty())
			error("Kernel: Could not retrieve selector names");
		else
			warning("No selector vocabulary found, using a static one");

		for (uint32 i = 0; i < staticSelectorTable.size(); i++) {
			_selectorNames.push_back(staticSelectorTable[i]);
			if (oldScriptHeader)
				_selectorNames.push_back(staticSelectorTable[i]);
		}

		return;
	}

	int count = (isBE ? READ_BE_UINT16(r->data) : READ_LE_UINT16(r->data)) + 1; // Counter is slightly off

	for (int i = 0; i < count; i++) {
		int offset = isBE ? READ_BE_UINT16(r->data + 2 + i * 2) : READ_LE_UINT16(r->data + 2 + i * 2);
		int len = isBE ? READ_BE_UINT16(r->data + offset) : READ_LE_UINT16(r->data + offset);

		Common::String tmp((const char *)r->data + offset + 2, len);
		_selectorNames.push_back(tmp);
		//debug("%s", tmp.c_str());

		// Early SCI versions used the LSB in the selector ID as a read/write
		// toggle. To compensate for that, we add every selector name twice.
		if (oldScriptHeader)
			_selectorNames.push_back(tmp);
	}
}
Example #21
0
void SmushDecoder::handleIACT(const byte *src, int32 size) {
	int32 bsize = size - 18;
	const byte *d_src = src + 18;

	while (bsize > 0) {
		if (_IACTpos >= 2) {
			int32 len = READ_BE_UINT16(_IACToutput) + 2;
			len -= _IACTpos;
			if (len > bsize) {
				memcpy(_IACToutput + _IACTpos, d_src, bsize);
				_IACTpos += bsize;
				bsize = 0;
			} else {
				byte *output_data = new byte[4096];
				memcpy(_IACToutput + _IACTpos, d_src, len);
				byte *dst = output_data;
				byte *d_src2 = _IACToutput;
				d_src2 += 2;
				int32 count = 1024;
				byte variable1 = *d_src2++;
				byte variable2 = variable1 / 16;
				variable1 &= 0x0f;
				do {
					byte value;
					value = *(d_src2++);
					if (value == 0x80) {
						*dst++ = *d_src2++;
						*dst++ = *d_src2++;
					} else {
						int16 val = (int8)value << variable2;
						*dst++ = val >> 8;
						*dst++ = (byte)(val);
					}
					value = *(d_src2++);
					if (value == 0x80) {
						*dst++ = *d_src2++;
						*dst++ = *d_src2++;
					} else {
						int16 val = (int8)value << variable1;
						*dst++ = val >> 8;
						*dst++ = (byte)(val);
					}
				} while (--count);

				if (!_stream) {
					_stream = Audio::makeQueuingAudioStream(22050, true);
					g_system->getMixer()->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _stream);
				}
				_stream->queueBuffer(output_data, 0x1000, DisposeAfterUse::YES, Audio::FLAG_STEREO | Audio::FLAG_16BITS);

				bsize -= len;
				d_src += len;
				_IACTpos = 0;
			}
		} else {
			if (bsize > 1 && _IACTpos == 0) {
void SfxPlayer::handlePattern(uint8_t channel, const uint8_t *data) {
	SfxPattern pat;
	memset(&pat, 0, sizeof(SfxPattern));
	pat.note_1 = READ_BE_UINT16(data + 0);
	pat.note_2 = READ_BE_UINT16(data + 2);
	if (pat.note_1 != 0xFFFD) {
		uint16_t sample = (pat.note_2 & 0xF000) >> 12;
		if (sample != 0) {
			uint8_t *ptr = _sfxMod.samples[sample - 1].data;
			if (ptr != 0) {
				debug(DBG_SND, "SfxPlayer::handlePattern() preparing sample %d", sample);
				pat.sampleVolume = _sfxMod.samples[sample - 1].volume;
				pat.sampleStart = 8;
				pat.sampleBuffer = ptr;
				pat.sampleLen = READ_BE_UINT16(ptr) * 2;
				uint16_t loopLen = READ_BE_UINT16(ptr + 2) * 2;
				if (loopLen != 0) {
					pat.loopPos = pat.sampleLen;
					pat.loopData = ptr;
					pat.loopLen = loopLen;
				} else {
					pat.loopPos = 0;
					pat.loopData = 0;
					pat.loopLen = 0;
				}
				int16_t m = pat.sampleVolume;
				uint8_t effect = (pat.note_2 & 0x0F00) >> 8;
				if (effect == 5) { // volume up
					uint8_t volume = (pat.note_2 & 0xFF);
					m += volume;
					if (m > 0x3F) {
						m = 0x3F;
					}
				} else if (effect == 6) { // volume down
					uint8_t volume = (pat.note_2 & 0xFF);
					m -= volume;
					if (m < 0) {
						m = 0;
					}	
				}
				mixer->setChannelVolume(channel, m);
				pat.sampleVolume = m;
			}
void ExtractCine::unpackAllResourceFiles(const Common::Filename &filename) {
	Common::File f(filename, "rb");

	uint32 unpackedSize, packedSize;
	{
		char header[8];
		f.read_throwsOnError(header, 8);
		if (memcmp(header, "ABASECP", 7) == 0) {
			unpackedSize = f.readUint32BE();
			packedSize = f.readUint32BE();
		} else {
			unpackedSize = packedSize = f.pos(); /* Get file size */
			f.seek(0, SEEK_SET);
		}
	}

	assert(unpackedSize >= packedSize);
	uint8 *buf = (uint8 *)calloc(unpackedSize, 1);
	assert(buf);
	f.read_throwsOnError(buf, packedSize);

	if (packedSize != unpackedSize) {
		CineUnpacker cineUnpacker;
		if (!cineUnpacker.unpack(buf, packedSize, buf, unpackedSize)) {
			error("Failed to unpack 'vol.cnf' data");
		}
	}

	unsigned int resourceFilesCount = READ_BE_UINT16(&buf[0]);
	unsigned int entrySize = READ_BE_UINT16(&buf[2]);
	print("--- Unpacking all %d resource files from 'vol.cnf' (entrySize = %d):", resourceFilesCount, entrySize);
	char resourceFileName[9];
	for (unsigned int i = 0; i < resourceFilesCount; ++i) {
		memcpy(resourceFileName, &buf[4 + i * entrySize], 8);
		resourceFileName[8] = 0;

		Common::File fpResFile(resourceFileName, "rb");
		print("--- Unpacking resource file %s:", resourceFileName);
		unpackFile(fpResFile);
	}

	free(buf);
}
Example #24
0
void loadObject(char *pObjectName) {
	debug(5, "loadObject(\"%s\")", pObjectName);
	uint16 numEntry;
	uint16 entrySize;
	uint16 i;
	byte *ptr, *dataPtr;

	checkDataDisk(-1);

	ptr = dataPtr = readBundleFile(findFileInBundle(pObjectName));

	setMouseCursor(MOUSE_CURSOR_DISK);

	numEntry = READ_BE_UINT16(ptr); ptr += 2;

	entrySize = READ_BE_UINT16(ptr); ptr += 2;

	assert(numEntry <= NUM_MAX_OBJECT);

	for (i = 0; i < numEntry; i++) {
		if (g_cine->_objectTable[i].costume != -2 && g_cine->_objectTable[i].costume != -3) { // flag is keep?
			Common::MemoryReadStream readS(ptr, entrySize);

			g_cine->_objectTable[i].x = readS.readSint16BE();
			g_cine->_objectTable[i].y = readS.readSint16BE();
			g_cine->_objectTable[i].mask = readS.readUint16BE();
			g_cine->_objectTable[i].frame = readS.readSint16BE();
			g_cine->_objectTable[i].costume = readS.readSint16BE();
			readS.read(g_cine->_objectTable[i].name, 20);
			g_cine->_objectTable[i].part = readS.readUint16BE();
		}
		ptr += entrySize;
	}

	if (!strcmp(pObjectName, "INTRO.OBJ")) {
		for (i = 0; i < 10; i++) {
			g_cine->_objectTable[i].costume = 0;
		}
	}

	free(dataPtr);
}
Example #25
0
// Elvira 2 and Waxworks specific
void AGOSEngine::doMenuStrip(uint menuNum) {
    uint i;
    const uint var = (getGameType() == GType_WW) ? 11 : 1;

    for (i = 111; i != 115; i++)
        disableBox(i);

    for (i = var; i != (var + 5); i++)
        _variableArray[i] = 0;

    byte *srcPtr = _menuBase;
    while (menuNum--) {
        while (READ_BE_UINT16(srcPtr) != 0)
            srcPtr += 2;
        srcPtr += 2;
    }

    uint id = 111;
    uint v = var;

    while (READ_BE_UINT16(srcPtr) != 0) {
        uint verb = READ_BE_UINT16(srcPtr);
        _variableArray[v] = verb;

        HitArea *ha = findBox(id);
        if (ha != NULL) {
            ha->flags &= ~kBFBoxDead;
            ha->verb = verb;
        }

        id++;
        srcPtr += 2;
        v++;
    }

    _variableArray[var + 4] = id - 111;
    if (getGameType() == GType_WW) {
        setWindowImageEx(2, 102);
    } else {
        setWindowImageEx(2, 103);
    }
}
Example #26
0
File: main.cpp Project: cyxx/rawgl
void Player::loadInstruments(const uint8_t *p) {
	memset(_sfxMod.samples, 0, sizeof(_sfxMod.samples));
	for (int i = 0; i < 0xF; ++i) {
		SfxInstrument *ins = &_sfxMod.samples[i];
		ins->resId = READ_BE_UINT16(p); p += 2;
		if (ins->resId != 0) {
			ins->volume = READ_BE_UINT16(p);
			char path[MAXPATHLEN];
			snprintf(path, sizeof(path), kSndFilePath, ins->resId);
			ins->buf = readFile(path);
			if (ins->buf.buf) {
				memset(ins->buf.buf + 8, 0, 4);
				fprintf(stdout, "Loaded instrument '%s' n=%d volume=%d\n", path, i, ins->volume);
			} else {
				fprintf(stderr, "Error loading instrument '%s'\n", path);
			}
		}
		p += 2; // volume
	}
}
Example #27
0
bool Player_V5M::getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) {
	if (_channel[ch]._pos >= _channel[ch]._length) {
		if (!_channel[ch]._looped) {
			_channel[ch]._notesLeft = false;
			return false;
		}
		// FIXME: Jamieson630: The jump seems to be happening
		// too quickly! There should maybe be a pause after
		// the last Note Off? But I couldn't find one in the
		// MI1 Lookout music, where I was hearing problems.
		_channel[ch]._pos = 0;
	}
	uint16 duration = READ_BE_UINT16(&_channel[ch]._data[_channel[ch]._pos]);
	byte note = _channel[ch]._data[_channel[ch]._pos + 2];
	samples = durationToSamples(duration);

	if (note != 1) {
		_channel[ch]._instrument.newNote();
	}

	if (note > 1) {
		pitchModifier = noteToPitchModifier(note, &_channel[ch]._instrument);
		velocity = _channel[ch]._data[_channel[ch]._pos + 3];
	} else if (note == 1) {
		// This is guesswork, but Monkey Island uses two different
		// "special" note values: 0, which is clearly a rest, and 1
		// which is... I thought at first it was a "soft" key off, to
		// fade out the note, but listening to the music in a Mac
		// emulator (which unfortunately doesn't work all that well),
		// I hear no trace of fading out.
		//
		// It could mean "change the volume on the current note", but
		// I can't hear that either, and it always seems to use the
		// exact same velocity on this note.
		//
		// So it appears it really just is a "hold the current note",
		// but why? Couldn't they just have made the original note
		// longer?

		pitchModifier = _channel[ch]._pitchModifier;
		velocity = _channel[ch]._velocity;
	} else {
		pitchModifier = 0;
		velocity = 0;
	}

	_channel[ch]._pos += 4;

	if (_channel[ch]._pos >= _channel[ch]._length) {
		samples = _lastNoteSamples[ch];
	}
	return true;
}
Example #28
0
bool SoundDesc::loadSND(byte *data, uint32 dSize) {
	assert(dSize > 6);

	_type = SOUND_SND;
	_data = data;
	_dataPtr = data + 6;
	_frequency = MAX((int16) READ_BE_UINT16(data + 4), (int16) 4700);
	_flag = data[0] ? (data[0] & 0x7F) : 8;
	data[0] = 0;
	_size = MIN(READ_BE_UINT32(data), dSize - 6);

	return true;
}
Example #29
0
File: main.cpp Project: cyxx/rawgl
void Player::loadSfxModule(int num) {
	char path[MAXPATHLEN];
	snprintf(path, sizeof(path), kSfxFilePath, num);
	_sfxMod.buf = readFile(path);
	if (_sfxMod.buf.buf) {
		uint8_t *p = _sfxMod.buf.buf;
		_sfxMod.curOrder = 0;
		_sfxMod.numOrder = READ_BE_UINT16(p + 0x3E);
		fprintf(stdout, "curOrder = 0x%X numOrder = 0x%X\n", _sfxMod.curOrder, _sfxMod.numOrder);
		for (int i = 0; i < 0x80; ++i) {
			_sfxMod.orderTable[i] = *(p + 0x40 + i);
		}
		_delay = READ_BE_UINT16(p);
//		_delay = 15700;
		_delay = _delay * 60 / 7050;
		_bufData = p + 0xC0;
		fprintf(stdout, "eventDelay = %d\n", _delay);
		loadInstruments(p + 2);
		stop();
		start();
	}
}
Example #30
0
File: msg.cpp Project: 33d/scummvm
void loadMsg(char *pMsgName) {
	uint32 sourceSize;

	checkDataDisk(-1);
	g_cine->_messageTable.clear();
	byte *dataPtr = readBundleFile(findFileInBundle(pMsgName), &sourceSize);

	setMouseCursor(MOUSE_CURSOR_DISK);

	uint count = READ_BE_UINT16(dataPtr);
	uint messageLenPos = 2;
	uint messageDataPos = messageLenPos + 2 * count;

	// Read in the messages
	for (uint i = 0; i < count; i++) {
		// Read message's length
		uint messageLen = READ_BE_UINT16(dataPtr + messageLenPos);
		messageLenPos += 2;

		// Store the read message.
		// This code works around input data that has empty strings residing outside the input
		// buffer (e.g. message indexes 58-254 in BATEAU.MSG in PROCS08 in Operation Stealth).
		if (messageDataPos < sourceSize) {
			g_cine->_messageTable.push_back((const char *)(dataPtr + messageDataPos));
		} else {
			if (messageLen > 0) { // Only warn about overflowing non-empty strings
				warning("loadMsg(%s): message (%d. / %d) is overflowing the input buffer. Replacing it with an empty string", pMsgName, i + 1, count);
			} else {
				debugC(5, kCineDebugPart, "loadMsg(%s): empty message (%d. / %d) resides outside input buffer", pMsgName, i + 1, count);
			}
			// Message resides outside the input buffer so we replace it with an empty string
			g_cine->_messageTable.push_back("");
		}
		// Jump to the next message
		messageDataPos += messageLen;
	}

	free(dataPtr);
}