Пример #1
0
TextEntryList *Text::getDialog(uint dialogNum, uint entryNum) {
	if (dialogNum >= kADSTextMax)
		error("getDialog(): Invalid entry number requested, %d (max %d)", dialogNum, kADSTextMax - 1);

	TextEntryList *l = new TextEntryList();

	byte *data = getChunkData(dialogNum);
	byte *ptr = data;

	ptr += 2;	// entry number
	ptr += 2;	// number of persons
	ptr += 2;	// automove count
	ptr += 2;	// cursor number
	ptr += 13;	// misc data

	for (uint i = 0; i <= entryNum; i++) {
		do {
			TextEntry curDialog;
			ptr++;	// current entry
			ptr += 2;
			curDialog.speechId = READ_LE_UINT16(ptr) - VOICE_OFFSET;	ptr += 2;

			do {
				curDialog.text += *ptr++;

				if (*ptr == 0 && *(ptr + 1) != kEndText) {
					// TODO: Split lines
					*ptr = ' ';
				}
			} while (*ptr != kEndText);

			if (i == entryNum)
				l->push_back(curDialog);

		} while (*(ptr + 1) != kEndEntry);

		ptr += 2;	// kEndText, kEndEntry

		if (*ptr == kEndBlock)	// not found
			break;
	}

	delete[] data;

	return l;
}
Пример #2
0
void Script::load(ResourceManager *resMan) {
	Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, _nr), 0);
	assert(script != 0);

	_buf = (byte *)malloc(_bufSize);
	assert(_buf);

	assert(_bufSize >= script->size);
	memcpy(_buf, script->data, script->size);

	// Check scripts for matching signatures and patch those, if found
	matchSignatureAndPatch(_nr, _buf, script->size);

	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) {
		Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, _nr), 0);
		assert(heap != 0);

		_heapStart = _buf + _scriptSize;

		assert(_bufSize - _scriptSize <= heap->size);
		memcpy(_heapStart, heap->data, heap->size);
	}

	_exportTable = 0;
	_numExports = 0;
	_synonyms = 0;
	_numSynonyms = 0;
	
	if (getSciVersion() <= SCI_VERSION_1_LATE) {
		_exportTable = (const uint16 *)findBlockSCI0(SCI_OBJ_EXPORTS);
		if (_exportTable) {
			_numExports = READ_SCI11ENDIAN_UINT16(_exportTable + 1);
			_exportTable += 3;	// skip header plus 2 bytes (_exportTable is a uint16 pointer)
		}
		_synonyms = findBlockSCI0(SCI_OBJ_SYNONYMS);
		if (_synonyms) {
			_numSynonyms = READ_SCI11ENDIAN_UINT16(_synonyms + 2) / 4;
			_synonyms += 4;	// skip header
		}
		const byte* localsBlock = findBlockSCI0(SCI_OBJ_LOCALVARS);
		if (localsBlock) {
			_localsOffset = localsBlock - _buf + 4;
			_localsCount = (READ_LE_UINT16(_buf + _localsOffset - 2) - 4) >> 1;	// half block size
		}
	} else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) {
Пример #3
0
void RlfAnimation::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
	uint32 sourceOffset = 0;
	uint32 destOffset = 0;

	while (sourceOffset < sourceSize) {
		int8 numberOfSamples = source[sourceOffset];
		sourceOffset++;

		// If numberOfSamples is negative, the next abs(numberOfSamples) samples should
		// be copied directly from source to dest
		if (numberOfSamples < 0) {
			numberOfSamples = ABS(numberOfSamples);

			while (numberOfSamples > 0) {
				if (sourceOffset + 1 >= sourceSize) {
					return;
				} else if (destOffset + 1 >= destSize) {
					debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
					return;
				}

				byte r, g, b;
				Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
				uint16 destColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
				WRITE_UINT16(dest + destOffset, destColor);

				sourceOffset += 2;
				destOffset += 2;
				numberOfSamples--;
			}

		// If numberOfSamples is >= 0, move destOffset forward ((numberOfSamples * 2) + 2)
		// This function assumes the dest buffer has been memset with 0's.
		} else {
			if (sourceOffset + 1 >= sourceSize) {
				return;
			} else if (destOffset + 1 >= destSize) {
				debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize);
				return;
			}

			destOffset += (numberOfSamples * 2) + 2;
		}
	}
}
Пример #4
0
void TeenAgentEngine::init() {
	_mark_delay = 80;
	_game_delay = 110;

	Resources * res = Resources::instance();
	use_hotspots.resize(42);
	byte *scene_hotspots = res->dseg.ptr(0xbb87);
	for (byte i = 0; i < 42; ++i) {
		Common::Array<UseHotspot> & hotspots = use_hotspots[i];
		byte * hotspots_ptr = res->dseg.ptr(READ_LE_UINT16(scene_hotspots + i * 2));
		while (*hotspots_ptr) {
			UseHotspot h;
			h.load(hotspots_ptr);
			hotspots_ptr += 9;
			hotspots.push_back(h);
		}
	}
}
Пример #5
0
Common::Error LureEngine::init() {
	int_engine = this;
	_initialised = false;
	_saveLoadAllowed = false;

	initGraphics(FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT, false);

	// Check the version of the lure.dat file
	Common::File f;
	VersionStructure version;
	if (!f.open(SUPPORT_FILENAME)) {
		GUIError("Could not locate Lure support file");
		return Common::kUnknownError;
	}

	f.seek(0xbf * 8);
	f.read(&version, sizeof(VersionStructure));
	f.close();

	if (READ_LE_UINT16(&version.id) != 0xffff) {
		GUIError("Error validating %s - file is invalid or out of date", SUPPORT_FILENAME);
		return Common::kUnknownError;
	} else if ((version.vMajor != LURE_DAT_MAJOR) || (version.vMinor != LURE_DAT_MINOR)) {
		GUIError("Incorrect version of %s file - expected %d.%d but got %d.%d",
			SUPPORT_FILENAME, LURE_DAT_MAJOR, LURE_DAT_MINOR,
			version.vMajor, version.vMinor);
		return Common::kUnknownError;
	}

	_disk = new Disk();
	_resources = new Resources();
	_strings = new StringData();
	_screen = new Screen(*_system);
	_mouse = new Mouse();
	_events = new Events();
	_menu = new Menu();
	Surface::initialise();
	_room = new Room();
	_fights = new FightsManager();

	_gameToLoad = -1;
	_initialised = true;
	return Common::kNoError;
}
Пример #6
0
bool Intro::floppyScrollFlirt(void) {

	uint8 *scrollScreen = (uint8*)malloc(FRAME_SIZE * 2);
	memset(scrollScreen, 0, FRAME_SIZE);
	memcpy(scrollScreen + FRAME_SIZE, _skyScreen->giveCurrent(), FRAME_SIZE);
	uint8 *scrollPos = scrollScreen + FRAME_SIZE;
	uint8 *vgaData = _skyDisk->loadFile(60100);
	uint8 *diffData = _skyDisk->loadFile(60101);
	uint16 frameNum = READ_LE_UINT16(diffData);
	uint8 *diffPtr = diffData + 2;
	uint8 *vgaPtr = vgaData;
	bool doContinue = true;

	for (uint16 frameCnt = 1; (frameCnt < frameNum) && doContinue; frameCnt++) {
		uint8 scrollVal = *diffPtr++;
		if (scrollVal)
			scrollPos -= scrollVal * GAME_SCREEN_WIDTH;

		uint16 scrPos = 0;
		while (scrPos < FRAME_SIZE) {
			uint8 nrToDo, nrToSkip;
			do {
				nrToSkip = *diffPtr++;
				scrPos += nrToSkip;
			} while (nrToSkip == 255);
			do {
				nrToDo = *diffPtr++;
				memcpy(scrollPos + scrPos, vgaPtr, nrToDo);
				scrPos += nrToDo;
				vgaPtr += nrToDo;
			} while (nrToDo == 255);
		}
		_system->copyRectToScreen(scrollPos, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT);
		_system->updateScreen();
		if (!escDelay(60))
			doContinue = false;
	}
	memcpy(_skyScreen->giveCurrent(), scrollPos, FRAME_SIZE);
	free(diffData);
	free(vgaData);
	free(scrollScreen);
	return doContinue;
}
Пример #7
0
int TextDisplayer::getCharLength(const char *str, int len) {
	int charsCount = 0;
	if (*str) {
		_screen->_charWidth = -2;
		int i = 0;
		while (i <= len && *str) {
			uint c = *str++;
			c &= 0xFF;
			if (c >= 0x7F && _vm->gameFlags().lang == Common::JA_JPN) {
				c = READ_LE_UINT16(str - 1);
				++str;
			}
			i += _screen->getCharWidth(c);
			++charsCount;
		}
		_screen->_charWidth = 0;
	}
	return charsCount;
}
Пример #8
0
Font::Font(const char *filename, const char *data, int len) : Object() {
	_fname = filename;

	_filename = filename;
	_numChars = READ_LE_UINT32(data);
	_dataSize = READ_LE_UINT32(data + 4);
	_height = READ_LE_UINT32(data + 8);
	_baseOffsetY = READ_LE_UINT32(data + 12);
	_firstChar = READ_LE_UINT32(data + 24);
	_lastChar = READ_LE_UINT32(data + 28);

	data += 32;

	// Read character indexes - are the key/value reversed?
	_charIndex = new uint16[_numChars];
	if (!_charIndex)
		error("Could not load font %s. Out of memory", filename);
	for (uint i = 0; i < _numChars; ++i) {
		_charIndex[i] = READ_LE_UINT16(data + 2 * i);
	}

	data += _numChars * 2;

	// Read character headers
	_charHeaders = new CharHeader[_numChars];
	if (!_charHeaders)
		error("Could not load font %s. Out of memory", filename);
	for (uint i = 0; i < _numChars; ++i) {
		_charHeaders[i].offset = READ_LE_UINT32(data);
		_charHeaders[i].width = *(int8 *)(data + 4);
		_charHeaders[i].startingCol = *(int8 *)(data + 5);
		_charHeaders[i].startingLine = *(int8 *)(data + 6);
		_charHeaders[i].dataWidth = READ_LE_UINT32(data + 8);
		_charHeaders[i].dataHeight = READ_LE_UINT32(data + 12);
		data += 16;
	}
	// Read font data
	_fontData = new byte[_dataSize];
	if (!_fontData)
		error("Could not load font %s. Out of memory", filename);

	memcpy(_fontData, data, _dataSize);
}
Пример #9
0
void MoviePlayer::openTextObject(uint32 index) {
	MovieText *text = &_movieTexts[index];

	// Pull out the text line to get the official text number (for WAV id)

	uint32 res = text->_textNumber / SIZE;
	uint32 localText = text->_textNumber & 0xffff;

	// Open text resource and get the line

	byte *textData = _vm->fetchTextLine(_vm->_resman->openResource(res), localText);

	text->_speechId = READ_LE_UINT16(textData);

	// Is it speech or subtitles, or both?

	// If we want subtitles, or there was no sound

	if (_vm->getSubtitles() || !text->_speechId) {
		text->_textMem = _vm->_fontRenderer->makeTextSprite(textData + 2, 600, 255, _vm->_speechFontId, 1);
	}

	_vm->_resman->closeResource(res);

	if (text->_textMem) {
		FrameHeader frame;

		frame.read(text->_textMem);

		text->_textSprite.x = 320 - frame.width / 2;
		text->_textSprite.y = 440 - frame.height;
		text->_textSprite.w = frame.width;
		text->_textSprite.h = frame.height;
		text->_textSprite.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION;
		text->_textSprite.data = text->_textMem + FrameHeader::size();
		text->_textSprite.isText = true;
		_vm->_screen->createSurface(&text->_textSprite, &_textSurface);

		_textX = 320 - text->_textSprite.w / 2;
		_textY = 420 - text->_textSprite.h;
	}
}
Пример #10
0
void Player_Towns_v1::startSound(int sound) {
    uint8 *ptr = _vm->getResourceAddress(rtSound, sound);
    if (_vm->_game.version != 3)
        ptr += 2;

    int type = ptr[13];

    if (type == 0) {
        uint8 velocity = 0;
        uint8 note = 0;

        if (_vm->_game.version == 3) {
            velocity = (_soundOverride[sound].vLeft + _soundOverride[sound].vRight);
            note = _soundOverride[sound].note;
        }

        velocity = velocity ? velocity >> 2 : ptr[14] >> 1;
        playPcmTrack(sound, ptr + 6, velocity, 64, note ? note : ptr[50], READ_LE_UINT16(ptr + 10));

    } else if (type == 1) {
Пример #11
0
void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY, byte oldColor, byte newColor) {

	const bool replaceColors = oldColor != newColor;

	int16 rows, chunks;
	int16 skip, copy;

	if (flipY) {
		dest += destPitch * (height - 1);
		destPitch = -destPitch;
	}

	rows = READ_LE_UINT16(source);
	chunks = READ_LE_UINT16(source + 2);
	source += 4;

	do {
		if (chunks == 0) {
			dest += rows * destPitch;
		} else {
			while (rows-- > 0) {
				uint16 rowChunks = chunks;
				while (rowChunks-- > 0) {
					skip = READ_LE_UINT16(source);
					copy = READ_LE_UINT16(source + 2);
					source += 4;
					if (!flipX) {
						memcpy(dest + skip, source, copy);
					} else {
						byte *flipDest = dest + width - skip - 1;
						for (int xc = 0; xc < copy; xc++) {
							*flipDest-- = source[xc];
						}
					}
					source += copy;
				}
				if (replaceColors)
					for (int xc = 0; xc < width; xc++)
						if (dest[xc] == oldColor)
							dest[xc] = newColor;
				dest += destPitch;
			}
		}
		rows = READ_LE_UINT16(source);
		chunks = READ_LE_UINT16(source + 2);
		source += 4;
	} while (rows > 0);

}
Пример #12
0
/**
 * Fetches up to 4 bytes from the code script
 */
static int32 GetBytes(const byte *scriptCode, const WorkaroundEntry* &wkEntry, int &ip, uint numBytes) {
	assert(numBytes <= 4 && numBytes != 3);
	const byte *code = scriptCode;

	if (wkEntry != NULL) {
		if (ip >= wkEntry->numBytes) {
			// Finished the workaround
			ip = wkEntry->ip;
			wkEntry = NULL;
		} else {
			code = wkEntry->script;
		}
	}

	uint32 tmp;
	switch (numBytes) {
	case 0:
		// Instruction byte
		tmp = code[ip++ * (TinselV0 ? 4 : 1)];
		break;
	case 1:
		// Fetch and sign extend a 8 bit value to 32 bits.
		tmp = (int8)code[ip++];
		break;
	case 2:
		// Fetch and sign extend a 16 bit value to 32 bits.
		tmp = (int16)READ_LE_UINT16(code + ip);
		ip += 2;
		break;
	default:
		if (TinselV0)
			tmp = (int32)READ_LE_UINT32(code + ip++ * 4);
		else {
			tmp = (int32)READ_LE_UINT32(code + ip);
			ip += 4;
		}
		break;
	}

	return tmp;
}
Пример #13
0
/**
 * Search Animation
 */
void AnimationManager::searchAnim(const byte *data, int animIndex, int bufSize) {
	for (int dataIdx = 0; dataIdx <= bufSize; dataIdx++) {
		if (READ_BE_UINT32(&data[dataIdx]) == MKTAG('A', 'N', 'I', 'M')) {
			int entryIndex = data[dataIdx + 4];
			if (animIndex == entryIndex) {
				int curBufferPos = dataIdx + 5;
				int count = 0;
				bool innerLoopCond = false;
				do {
					if (READ_BE_UINT32(&data[curBufferPos]) == MKTAG('A', 'N', 'I', 'M') || READ_BE_UINT24(&data[curBufferPos]) == MKTAG24('F', 'I', 'N'))
						innerLoopCond = true;
					if (bufSize < curBufferPos) {
						_animBqe[animIndex]._enabledFl = false;
						_animBqe[animIndex]._data = NULL;
						return;
					}
					++curBufferPos;
					++count;
				} while (!innerLoopCond);
				_animBqe[animIndex]._data = _vm->_globals->allocMemory(count + 50);
				_animBqe[animIndex]._enabledFl = true;
				memcpy(_animBqe[animIndex]._data, data + dataIdx + 5, 20);

				byte *dataP = _animBqe[animIndex]._data;
				int curDestDataIndx = 20;
				int curSrcDataIndx = dataIdx + 25;

				for (int i = 0; i <= 4999; i++) {
					memcpy(dataP + curDestDataIndx, data + curSrcDataIndx, 10);
					if (!READ_LE_UINT16(data + curSrcDataIndx + 4))
						break;
					curDestDataIndx += 10;
					curSrcDataIndx += 10;
				}
				break;
			}
		}
		if (READ_BE_UINT24(&data[dataIdx]) == MKTAG24('F', 'I', 'N'))
			break;
	}
}
Пример #14
0
void DreamGenContext::deallocatemem() {
	uint16 id = (uint16)es;
	debug(1, "deallocating segment %04x", id);
	deallocateSegment(id);

	//fixing invalid entries in the sprite table
	es = data;
	uint tsize = 16 * 32;
	uint16 bseg = data.word(kBuffers);
	if (!bseg)
		return;
	SegmentRef buffers(this);
	buffers = bseg;
	uint8 *ptr = buffers.ptr(kSpritetable, tsize);
	for(uint i = 0; i < tsize; i += 32) {
		uint16 seg = READ_LE_UINT16(ptr + i + 6);
		//debug(1, "sprite segment = %04x", seg);
		if (seg == id)
			memset(ptr + i, 0xff, 32);
	}
}
Пример #15
0
uint32 CdfArchive::BlockDecode(uint8 *dst, uint32 a_dst_size, const uint8 *a_src, uint32 a_src_size) const
{
	uint32 dst_size = 0;

	uint16 data_type = READ_LE_UINT16(a_src);

	const uint8 *src = a_src + sizeof(uint16);
	uint32 src_size = a_src_size - sizeof(uint16);

	// data uncompressed, just copy contents
	if(data_type == 0)
	{
		memcpy(dst, src, src_size);
		dst_size = src_size;
	}
	// deflate compression used
	else if(data_type == 8)
		dst_size = inflateZlibHeaderless((byte *)dst, a_dst_size, src, src_size);

	return dst_size;
}
Пример #16
0
void CharsetRendererCommon::setCurID(int32 id) {
	if (id == -1)
		return;

	assertRange(0, id, _vm->_numCharsets - 1, "charset");

	_curId = id;

	_fontPtr = _vm->getResourceAddress(rtCharset, id);
	if (_fontPtr == 0)
		error("CharsetRendererCommon::setCurID: charset %d not found", id);

	if (_vm->_game.version == 4)
		_fontPtr += 17;
	else
		_fontPtr += 29;

	_bytesPerPixel = _fontPtr[0];
	_fontHeight = _fontPtr[1];
	_numChars = READ_LE_UINT16(_fontPtr + 2);
}
Пример #17
0
void KyraRpgEngine::restoreBlockTempData(int levelIndex) {
	int l = levelIndex - 1;
	const uint8 *p = getBlockFileData(levelIndex);
	uint16 len = READ_LE_UINT16(p + 4);
	p += 6;

	memset(_levelBlockProperties, 0, 1024 * sizeof(LevelBlockProperty));

	uint8 *t = _lvlTempData[l]->wallsXorData;
	uint16 *t2 = _lvlTempData[l]->flags;

	for (int i = 0; i < 1024; i++) {
		for (int ii = 0; ii < 4; ii++)
			_levelBlockProperties[i].walls[ii] = p[i * len + ii] ^ *t++;
		_levelBlockProperties[i].flags = *t2++;
	}

	restoreMonsterTempData(_lvlTempData[l]);
	restoreFlyingObjectTempData(_lvlTempData[l]);
	restoreWallOfForceTempData(_lvlTempData[l]);
}
Пример #18
0
Surface *Animation::currentFrame(int dt) {
	if (paused)
		return firstFrame();

	if (frames == NULL || frames_count == 0)
		return NULL;

	Surface *r;

	if (data != NULL) {
		uint32 frame = 3 * index;
		//debug(0, "%u/%u", index, data_size / 3);
		index += dt;

		if (!loop && index >= data_size / 3) {
			return NULL;
		}

		if (data[frame] - 1 >= frames_count) {
			warning("invalid frame %u(0x%x) (max %u) index %u, mod %u", frame, frame, frames_count, index - 1, data_size / 3);
			return NULL;
		}

		r = frames + data[frame] - 1;
		uint16 pos = READ_LE_UINT16(data + frame + 1);
		index %= (data_size / 3);

		if (pos != 0) {
			x = r->x = pos % 320;
			y = r->y = pos / 320;
		}
	} else {
		//debug(0, "index %u", index);
		r = frames + index;
		index += dt;
		index %= frames_count;
	}

	return r;
}
Пример #19
0
uint8_t *decode_bitmap(const uint8_t *src, bool alpha, int colorKey, int *w, int *h) {
	if (memcmp(src, "BM", 2) != 0) {
		return 0;
	}
	const uint32_t imageOffset = READ_LE_UINT32(src + 0xA);
	const int width = READ_LE_UINT32(src + 0x12);
	const int height = READ_LE_UINT32(src + 0x16);
	const int depth = READ_LE_UINT16(src + 0x1C);
	const int compression = READ_LE_UINT32(src + 0x1E);
	if ((depth != 8 && depth != 32) || compression != 0) {
		warning("Unhandled bitmap depth %d compression %d", depth, compression);
		return 0;
	}
	const int bpp = (!alpha && colorKey < 0) ? 3 : 4;
	uint8_t *dst = (uint8_t *)malloc(width * height * bpp);
	if (!dst) {
		warning("Failed to allocate bitmap buffer, width %d height %d bpp %d", width, height, bpp);
		return 0;
	}
	if (depth == 8) {
		const uint8_t *palette = src + 14 /* BITMAPFILEHEADER */ + 40 /* BITMAPINFOHEADER */;
		const bool flipY = true;
		clut(src + imageOffset, palette, (width + 3) & ~3, width, height, bpp, flipY, colorKey, dst);
	} else {
		assert(depth == 32 && bpp == 3);
		const uint8_t *p = src + imageOffset;
		for (int y = height - 1; y >= 0; --y) {
			uint8_t *q = dst + y * width * bpp;
			for (int x = 0; x < width; ++x) {
				const uint32_t color = READ_LE_UINT32(p); p += 4;
				*q++ = (color >> 16) & 255;
				*q++ = (color >>  8) & 255;
				*q++ =  color        & 255;
			}
		}
	}
	*w = width;
	*h = height;
	return dst;
}
Пример #20
0
void SoundTowns_Darkmoon::loadSoundFile(Common::String name) {
	Common::SeekableReadStream *s = _vm->resource()->createReadStream(Common::String::format("%s.SDT", name.c_str()));
	if (!s)
		error("Failed to load sound file '%s.SDT'", name.c_str());

	for (int i = 0; i < 120; i++) {
		_soundTable[i].type = s->readSByte();
		_soundTable[i].para1 = s->readSint32LE();
		_soundTable[i].para2 = s->readSint16LE();
	}

	delete s;

	uint32 bytesLeft;
	uint8 *pmb = _vm->resource()->fileData(Common::String::format("%s.PMB", name.c_str()).c_str(), &bytesLeft);

	_vm->delay(300);

	if (pmb) {
		uint8 *src = pmb + 8;
		for (int i = 0; i < 32; i++)
			_intf->callback(5, 0x40, i, &src[i << 7]);
		
		_intf->callback(35, -1);
		src += 0x1000;
		bytesLeft -= 0x1008;

		while (bytesLeft) {
			_intf->callback(34, src);
			uint32 len = READ_LE_UINT16(&src[12]) + 32;
			src = src + len;
			bytesLeft -= len;
		}

		delete[] pmb;
	} else {
		warning("Sound file '%s.PMB' not found.", name.c_str());
		// TODO
	}
}
Пример #21
0
void DSP_Play(const uint8 *data)
{
	uint32 len;
	uint32 freq;
	uint32 sampleLen;

	/* skip Create Voice File header */
	data += READ_LE_UINT16(data + 20);

	/* first byte is Block Type :
	 * 0x00: Terminator
	 * 0x01: Sound data
	 * 0x02: Sound data continuation
	 * 0x03: Silence
	 * 0x04: Marker
	 * 0x05: Text
	 * 0x06: Repeat start
	 * 0x07: Repeat end
	 * 0x08: Extra info
	 * 0x09: Sound data (New format) */
	if (*data != 1) return;

	/* next 3 bytes are block size (not including the 1 block type and
	 * size 4 bytes) */
	len = data[1] | (data[2] << 8) | (data[3] << 16);
	len -= 2;
	data += 4;
	/* byte  0    frequency divisor
	 * byte  1    codec id : 0 is "8bits unsigned PCM"
	 * bytes 2..n audio data */
	freq = 1000000 / (256 - data[0]);
	if (data[1] != 0) Warning("Unsupported VOC codec 0x%02x\n", (int)data[1]);
	sampleLen = DSP_ConvertAudio(freq, data + 2, len);

	if(sampleLen > 0) {
		set_dma_sound(s_stRamBuffer, sampleLen);
	}
}
Пример #22
0
int16 *CompressSword1::uncompressSpeech(Common::File &clu, uint32 idx, uint32 cSize, uint32 *returnSize) {
	uint32 resSize, srcPos;
	int16 *srcData, *dstData, *dstPos;
	uint32 headerPos = 0;
	int16 length, cnt;
	uint8 *fBuf = (uint8 *)malloc(cSize);
	clu.seek(idx, SEEK_SET);
	clu.read_throwsOnError(fBuf, cSize);

	while ((READ_BE_UINT32(fBuf + headerPos) != 'data') && (headerPos < 100))
		headerPos++;
	if (headerPos < 100) {
		resSize = READ_LE_UINT32(fBuf + headerPos + 4) >> 1;
		srcData = (int16 *)(fBuf + headerPos + 8);
		dstData = (int16 *)malloc(resSize * 2);
		srcPos = 0;
		dstPos = dstData;
		cSize = (cSize - (headerPos + 8)) / 2;
		while (srcPos < cSize) {
			length = (int16)READ_LE_UINT16(srcData + srcPos);
			srcPos++;
			if (length < 0) {
				length = -length;
				for (cnt = 0; cnt < (uint16)length; cnt++)
					*dstPos++ = srcData[srcPos];
				srcPos++;
			} else {
				memcpy(dstPos, srcData + srcPos, length * 2);
				dstPos += length;
				srcPos += length;
			}
		}
		free(fBuf);
		*returnSize = resSize * 2;
		if (_speechEndianness == UnknownEndian)
			guessEndianness(dstData, length);
		return dstData;
	} else {
Пример #23
0
void MoviePlayer::copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint pitch) {
	uint h = getHeight();
	uint w = getWidth();

	const Graphics::Surface *surface = decodeNextFrame();
	byte *src = (byte *)surface->pixels;

	if (hasDirtyPalette())
		_vm->setPaletteFromPtr(getPalette(), 256);

	if (_vm->_game.features & GF_16BIT_COLOR) {
		dst += y * pitch + x * 2;
		do {
			for (uint i = 0; i < w; i++) {
				uint16 color = READ_LE_UINT16(_vm->_hePalettes + _vm->_hePaletteSlot + 768 + src[i] * 2);
				switch (dstType) {
				case kDstScreen:
					WRITE_UINT16(dst + i * 2, color);
					break;
				case kDstResource:
					WRITE_LE_UINT16(dst + i * 2, color);
					break;
				default:
					error("copyFrameToBuffer: Unknown dstType %d", dstType);
				}
			}
			dst += pitch;
			src += w;
		} while (--h);
	} else {
		dst += y * pitch + x;
		do {
			memcpy(dst, src, w);
			dst += pitch;
			src += w;
		} while (--h);
	}
}
Пример #24
0
byte *TLib::getSubResource(int resNum, int rlbNum, int index, uint *size, bool suppressErrors) {
	// Get the specified image set
	byte *dataIn = getResource(RES_VISAGE, resNum, rlbNum);
	if (!dataIn) {
		if (suppressErrors)
			return NULL;

		error("Unknown sub resource %d/%d index %d", resNum, rlbNum, index);
	}

	int numEntries = READ_LE_UINT16(dataIn);
	uint32 entryOffset = READ_LE_UINT32(dataIn + 2 + (index - 1) * 4);
	uint32 nextOffset = (index == numEntries) ?
			_memoryManager.getSize(dataIn) : READ_LE_UINT32(dataIn + 2 + index * 4);
	*size = nextOffset - entryOffset;
	assert(*size < (1024 * 1024));

	byte *entry = _memoryManager.allocate2(*size);
	Common::copy(&dataIn[entryOffset], &dataIn[nextOffset], entry);

	_memoryManager.deallocate(dataIn);
	return entry;
}
Пример #25
0
static uint32 readFakeChar(SeekableReadStream &stream, 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:
			if (stream.read(data, 1) != 1)
				return 0;

			return data[0];

		case kEncodingUTF16LE:
			if (stream.read(data, 2) != 2)
				return 0;

			return READ_LE_UINT16(data);

		case kEncodingUTF16BE:
			if (stream.read(data, 2) != 2)
				return 0;

			return READ_BE_UINT16(data);

		default:
			break;
	}

	return 0;
}
Пример #26
0
void CLUInputStream::refill() {
	byte *in = _inbuf;
	int16 *out = _outbuf;

	_file->seek(_file_pos, SEEK_SET);

	uint len_left = _file->read(in, MIN((uint32)BUFFER_SIZE, _end_pos - _file->pos()));

	_file_pos = _file->pos();

	while (len_left > 0) {
		uint16 sample;

		if (_firstTime) {
			_firstTime = false;
			_prev = READ_LE_UINT16(in);
			sample = _prev;
			len_left -= 2;
			in += 2;
		} else {
			uint16 delta = GetCompressedAmplitude(*in) << GetCompressedShift(*in);
			if (GetCompressedSign(*in))
				sample = _prev - delta;
			else
				sample = _prev + delta;

			_prev = sample;
			len_left--;
			in++;
		}

		*out++ = (int16)sample;
	}

	_pos = _outbuf;
	_bufferEnd = out;
}
Пример #27
0
static void decompress_codec3(const char *compressed, char *result) {
	int bitstr_value = READ_LE_UINT16(compressed);
	int bitstr_len = 16;
	compressed += 2;
	bool bit;

	for (;;) {
		GET_BIT;
		if (bit == 1)
			*result++ = *compressed++;
		else {
			GET_BIT;
			int copy_len, copy_offset;
			if (bit == 0) {
				GET_BIT;
				copy_len = 2 * bit;
				GET_BIT;
				copy_len += bit + 3;
				copy_offset = *(uint8 *)(compressed++) - 0x100;
			} else {
				copy_offset = (*(uint8 *)(compressed) | (*(uint8 *)(compressed + 1) & 0xf0) << 4) - 0x1000;
				copy_len = (*(uint8 *)(compressed + 1) & 0xf) + 3;
				compressed += 2;
				if (copy_len == 3) {
					copy_len = *(uint8 *)(compressed++) + 1;
					if (copy_len == 1)
						return;
				}
			}
			while (copy_len > 0) {
				*result = result[copy_offset];
				result++;
				copy_len--;
			}
		}
	}
}
Пример #28
0
void KyraRpgEngine::generateTempData() {
	int l = _currentLevel - 1;
	if (_lvlTempData[l]) {
		delete[] _lvlTempData[l]->wallsXorData;
		delete[] _lvlTempData[l]->flags;
		releaseMonsterTempData(_lvlTempData[l]);
		releaseFlyingObjectTempData(_lvlTempData[l]);
		releaseWallOfForceTempData(_lvlTempData[l]);
		delete _lvlTempData[l];
	}

	_lvlTempData[l] = new LevelTempData;

	_lvlTempData[l]->wallsXorData = new uint8[4096];
	_lvlTempData[l]->flags = new uint16[1024];

	const uint8 *p = getBlockFileData(_currentLevel);
	uint16 len = READ_LE_UINT16(p + 4);
	p += 6;

	memset(_lvlTempData[l]->wallsXorData, 0, 4096);
	memset(_lvlTempData[l]->flags, 0, 1024 * sizeof(uint16));
	uint8 *d = _lvlTempData[l]->wallsXorData;
	uint16 *df = _lvlTempData[l]->flags;

	for (int i = 0; i < 1024; i++) {
		for (int ii = 0; ii < 4; ii++)
			*d++ = p[i * len + ii] ^ _levelBlockProperties[i].walls[ii];
		*df++ = _levelBlockProperties[i].flags;
	}

	_lvlTempData[l]->monsters = generateMonsterTempData(_lvlTempData[l]);
	_lvlTempData[l]->flyingObjects = generateFlyingObjectTempData(_lvlTempData[l]);
	_lvlTempData[l]->wallsOfForce = generateWallOfForceTempData(_lvlTempData[l]);

	_hasTempDataFlags |= (1 << l);
}
Пример #29
0
void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
	byte *scanData = _script->getSlotData(slotIndex) + slotOffset;

	// If there's another talk text at the requested slot and it's still
	// active, don't overwrite it. Fixes bug #3600166.
	if (_screen->isTalkTextActive(slotIndex))
		return;

	while (*scanData < 0xF0) {
		if (*scanData == 0x19) {
			scanData++;
		} else if (*scanData == 0x14) {
			scanData++;
		} else if (*scanData == 0x0A) {
			scanData += 4;
		} else if (*scanData < 0x0A) {
			scanData++;
		}
		scanData++;
	}

	if (*scanData == 0xFE) {
		if (_doSpeech) {
			int16 resIndex = READ_LE_UINT16(scanData + 1);
			debug(0, "ToltecsEngine::talk() playSound(resIndex: %d)", resIndex);
			_sound->playSpeech(resIndex);
		}

		if (_doText) {
			_screen->updateTalkText(slotIndex, slotOffset, false);
		} else {
			_screen->keepTalkTextItemsAlive();
		}
	} else {
		_screen->updateTalkText(slotIndex, slotOffset, true);
	}
}
Пример #30
0
void Player_AD::startMusic() {
	memset(_instrumentOffset, 0, sizeof(_instrumentOffset));

	bool hasRhythmData = false;
	uint instruments = _musicData[10];
	for (uint i = 0; i < instruments; ++i) {
		const int instrIndex = _musicData[11 + i] - 1;
		if (0 <= instrIndex && instrIndex < 16) {
			_instrumentOffset[instrIndex] = i * 16 + 16 + 3;
			hasRhythmData |= (_musicData[_instrumentOffset[instrIndex] + 13] != 0);
		}
	}

	if (hasRhythmData) {
		_mdvdrState = 0x20;
		limitHWChannels(6);
	} else {
		_mdvdrState = 0;
		limitHWChannels(9);
	}

	_curOffset = 0x93;
	// TODO: is this the same for Loom?
	_nextEventTimer = 40;
	_engineMusicTimer = 0;
	_internalMusicTimer = 0;
	_musicTimer = 0;

	writeReg(0xBD, _mdvdrState);

	const bool isLoom = (_vm->_game.id == GID_LOOM);
	_timerLimit = isLoom ? 473 : 256;
	_musicTicks = _musicData[3] * (isLoom ? 2 : 1);
	_loopFlag = (_musicData[4] == 0);
	_musicLoopStart = _curOffset + READ_LE_UINT16(_musicData + 5);
}