void Map_v2::loadGoblinStates(Common::SeekableReadStream &data, int index) { Mult::Mult_GobState *statesPtr; Mult::Mult_GobState *gobState; int8 indices[102]; uint8 statesCount; uint8 dataCount; int16 state; uint32 tmpPos; memset(indices, -1, 101); _vm->_mult->_objects[index].goblinStates = new Mult::Mult_GobState*[101]; memset(_vm->_mult->_objects[index].goblinStates, 0, 101 * sizeof(Mult::Mult_GobState *)); data.read(indices, 100); tmpPos = data.pos(); statesCount = 0; for (int i = 0; i < 100; i++) { if (indices[i] != -1) { statesCount++; data.skip(4); dataCount = data.readByte(); statesCount += dataCount; data.skip(dataCount * 9); } } data.seek(tmpPos); statesPtr = new Mult::Mult_GobState[statesCount]; _vm->_mult->_objects[index].goblinStates[0] = statesPtr; for (int i = 0; i < 100; i++) { state = indices[i]; if (state != -1) { _vm->_mult->_objects[index].goblinStates[state] = statesPtr++; gobState = _vm->_mult->_objects[index].goblinStates[state]; gobState[0].animation = data.readSint16LE(); gobState[0].layer = data.readSint16LE(); dataCount = data.readByte(); gobState[0].dataCount = dataCount; for (uint8 j = 1; j <= dataCount; j++) { data.skip(1); gobState[j].sndItem = data.readSByte(); data.skip(1); gobState[j].sndFrame = data.readByte(); data.skip(1); gobState[j].freq = data.readSint16LE(); gobState[j].repCount = data.readSByte(); gobState[j].speaker = data.readByte(); statesPtr++; } } } }
int64 GFF4Struct::getSint(Common::SeekableReadStream &data, IFieldType type) const { switch (type) { case kIFieldTypeUint8: return (int64) ((uint64) data.readByte()); case kIFieldTypeSint8: return (int64) data.readSByte(); case kIFieldTypeUint16: return (int64) ((uint64) data.readUint16LE()); case kIFieldTypeSint16: return (int64) data.readSint16LE(); case kIFieldTypeUint32: return (int64) ((uint64) data.readUint32LE()); case kIFieldTypeSint32: return (int64) data.readSint32LE(); case kIFieldTypeUint64: return (int64) ((uint64) data.readUint64LE()); case kIFieldTypeSint64: return (int64) data.readSint64LE(); default: break; } throw Common::Exception("GFF4: Field is not an int type"); }
bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) { int x = 0, y = 0; // If the stream has exactly the required number of bits for this image, // we assume it is uncompressed. if (stream.size() * 8 == _surface->pitch * _surface->h) { debugC(3, kDebugImages, "Skipping compression"); for (y = 0; y < _surface->h; y++) { for (x = 0; x < _surface->pitch; ) { byte color = stream.readByte(); for (int c = 0; c < 8; c++) *((byte *)_surface->getBasePtr(x++, y)) = (color & (1 << (7 - c))) ? 0 : 0xff; } } return true; } while (y < _surface->h) { int n = stream.readSByte(); int count; int b = 0; int state = 0; if (stream.eos()) break; if ((n >= 0) && (n <= 127)) { // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. count = n + 1; state = 1; } else if ((n >= -127) && (n <= -1)) { // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. b = stream.readByte(); count = -n + 1; state = 2; } else { // Else if n is -128, noop. count = 0; } for (int i = 0; i < count && y < _surface->h; i++) { byte color = 0; if (state == 1) { color = stream.readByte(); } else if (state == 2) color = b; for (int c = 0; c < 8; c++) { *((byte *)_surface->getBasePtr(x, y)) = (color & (1 << (7 - c))) ? 0 : 0xff; x++; if (x == _surface->pitch) { y++; x = 0; break; } } } } return true; }
void SmushPlayer::handleSoundFrame(int32 subSize, Common::SeekableReadStream &b) { debugC(DEBUG_SMUSH, "SmushPlayer::handleSoundFrame()"); int32 track_id = b.readUint16LE(); int32 index = b.readUint16LE(); int32 max_frames = b.readUint16LE(); int32 flags = b.readUint16LE(); int32 vol = b.readByte(); int32 pan = b.readSByte(); if (index == 0) { debugC(DEBUG_SMUSH, "track_id:%d, max_frames:%d, flags:%d, vol:%d, pan:%d", track_id, max_frames, flags, vol, pan); } int32 size = subSize - 10; handleSoundBuffer(track_id, index, max_frames, flags, vol, pan, b, size); }
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 } }
Common::String readPascalString(Common::SeekableReadStream &in) { Common::String s; char *buf; int len; int i; len = in.readSByte(); if (len < 0) len += 256; buf = (char *)malloc(len + 1); for (i = 0; i < len; i++) { buf[i] = in.readByte(); if (buf[i] == 0x0d) buf[i] = '\n'; } buf[i] = 0; s = buf; free(buf); return s; }
void Design::drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadStream &in) { int numBytes = in.readSint16BE(); int y1 = in.readSint16BE(); int x1 = in.readSint16BE(); int y2 = in.readSint16BE(); int x2 = in.readSint16BE(); int w = x2 - x1; int h = y2 - y1; Graphics::ManagedSurface tmp; tmp.create(w, h, Graphics::PixelFormat::createFormatCLUT8()); numBytes -= 10; int x = 0, y = 0; while (numBytes > 0 && y < h) { int n = in.readSByte(); int count; int b = 0; int state = 0; numBytes--; if ((n >= 0) && (n <= 127)) { // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. count = n + 1; state = 1; } else if ((n >= -127) && (n <= -1)) { // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. b = in.readByte(); numBytes--; count = -n + 1; state = 2; } else { // Else if n is -128, noop. count = 0; } for (int i = 0; i < count && y < h; i++) { byte color = 0; if (state == 1) { color = in.readByte(); numBytes--; } else if (state == 2) color = b; for (int c = 0; c < 8; c++) { if (_boundsCalculationMode) { adjustBounds(x1 + x, y1 + y); } else if (x1 + x >= 0 && x1 + x < surface->w && y1 + y >= 0 && y1 + y < surface->h) *((byte *)tmp.getBasePtr(x, y)) = (color & (1 << (7 - c % 8))) ? kColorBlack : kColorWhite; x++; if (x == w) { y++; x = 0; break; } } } } in.skip(numBytes); if (_boundsCalculationMode) return; FloodFill ff(&tmp, kColorWhite, kColorGreen); for (int yy = 0; yy < h; yy++) { ff.addSeed(0, yy); ff.addSeed(w - 1, yy); } for (int xx = 0; xx < w; xx++) { ff.addSeed(xx, 0); ff.addSeed(xx, h - 1); } ff.fill(); for (y = 0; y < h && y1 + y < surface->h; y++) { byte *src = (byte *)tmp.getBasePtr(0, y); byte *dst = (byte *)surface->getBasePtr(x1, y1 + y); for (x = 0; x < w; x++) { if (*src != kColorGreen) *dst = *src; src++; dst++; } } tmp.free(); }
/** * Initialises and loads the data of an animation */ void MadsAnimation::initialise(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface) { MadsPack anim(filename.c_str(), _vm); bool madsRes = filename[0] == '*'; char buffer[20]; int streamIndex = 1; // Chunk 1: header // header Common::SeekableReadStream *animStream = anim.getItemStream(0); int spriteListCount = animStream->readUint16LE(); int miscEntriesCount = animStream->readUint16LE(); int frameEntryCount = animStream->readUint16LE(); int messagesCount = animStream->readUint16LE(); animStream->skip(1); _flags = animStream->readByte(); animStream->skip(2); _animMode = animStream->readUint16LE(); _roomNumber = animStream->readUint16LE(); animStream->skip(2); _field12 = animStream->readUint16LE() != 0; _spriteListIndex = animStream->readUint16LE(); _scrollX = animStream->readSint16LE(); _scrollY = animStream->readSint16LE(); _scrollTicks = animStream->readUint16LE(); animStream->skip(8); animStream->read(buffer, FILENAME_SIZE); buffer[FILENAME_SIZE] = '\0'; _interfaceFile = Common::String(buffer); for (int i = 0; i < 10; ++i) { animStream->read(buffer, FILENAME_SIZE); buffer[FILENAME_SIZE] = '\0'; _spriteSetNames[i] = Common::String(buffer); } animStream->skip(81); animStream->read(buffer, FILENAME_SIZE); buffer[FILENAME_SIZE] = '\0'; _lbmFilename = Common::String(buffer); animStream->skip(365); animStream->read(buffer, FILENAME_SIZE); buffer[FILENAME_SIZE] = '\0'; _spritesFilename = Common::String(buffer); animStream->skip(48); animStream->read(buffer, FILENAME_SIZE); buffer[FILENAME_SIZE] = '\0'; _soundName = Common::String(buffer); animStream->skip(13); animStream->read(buffer, FILENAME_SIZE); buffer[FILENAME_SIZE] = '\0'; _dsrName = Common::String(buffer); animStream->read(buffer, FILENAME_SIZE); buffer[FILENAME_SIZE] = '\0'; Common::String fontResource(buffer); if (_animMode == 4) flags |= 0x4000; if (flags & 0x100) loadInterface(surface, depthSurface); // Initialise the reference list for (int i = 0; i < spriteListCount; ++i) _spriteListIndexes.push_back(-1); delete animStream; if (messagesCount > 0) { // Chunk 2 // Following is a list of any messages for the animation animStream = anim.getItemStream(streamIndex++); for (int i = 0; i < messagesCount; ++i) { AnimMessage rec; rec.soundId = animStream->readSint16LE(); animStream->read(rec.msg, 64); animStream->skip(4); rec.pos.x = animStream->readSint16LE(); rec.pos.y = animStream->readSint16LE(); rec.flags = animStream->readUint16LE(); rec.rgb1.r = animStream->readByte() << 2; rec.rgb1.g = animStream->readByte() << 2; rec.rgb1.b = animStream->readByte() << 2; rec.rgb2.r = animStream->readByte() << 2; rec.rgb2.g = animStream->readByte() << 2; rec.rgb2.b = animStream->readByte() << 2; animStream->skip(2); // Space for kernelMsgIndex rec.kernelMsgIndex = -1; animStream->skip(6); rec.startFrame = animStream->readUint16LE(); rec.endFrame = animStream->readUint16LE(); animStream->skip(2); _messages.push_back(rec); } delete animStream; } if (frameEntryCount > 0) { // Chunk 3: animation frame info animStream = anim.getItemStream(streamIndex++); for (int i = 0; i < frameEntryCount; i++) { AnimFrameEntry rec; rec.frameNumber = animStream->readUint16LE(); rec.seqIndex = animStream->readByte(); rec.spriteSlot.spriteListIndex = animStream->readByte(); rec.spriteSlot.frameNumber = animStream->readUint16LE(); rec.spriteSlot.xp = animStream->readSint16LE(); rec.spriteSlot.yp = animStream->readSint16LE(); rec.spriteSlot.depth = animStream->readSByte(); rec.spriteSlot.scale = (int8)animStream->readByte(); _frameEntries.push_back(rec); } delete animStream; } if (miscEntriesCount > 0) { // Chunk 4: Misc Data animStream = anim.getItemStream(streamIndex); for (int i = 0; i < miscEntriesCount; ++i) { AnimMiscEntry rec; rec.soundNum = animStream->readByte(); rec.msgIndex = animStream->readSByte(); rec.numTicks = animStream->readUint16LE(); rec.posAdjust.x = animStream->readUint16LE(); rec.posAdjust.y = animStream->readUint16LE(); animStream->readUint16LE(); _miscEntries.push_back(rec); } delete animStream; } // If the animation specifies a font, then load it for access if (_flags & ANIM_CUSTOM_FONT) { Common::String fontName; if (madsRes) fontName += "*"; fontName += fontResource; if (fontName != "") _font = _vm->_font->getFont(fontName.c_str()); else warning("Attempted to set a font with an empty name"); } // If a speech file is specified, then load it if (!_dsrName.empty()) _vm->_sound->loadDSRFile(_dsrName.c_str()); // Load all the sprite sets for the animation for (int i = 0; i < spriteListCount; ++i) { if (_field12 && (i == _spriteListIndex)) // Skip over field, since it's manually loaded continue; _spriteListIndexes[i] = _view->_spriteSlots.addSprites(_spriteSetNames[i].c_str()); } if (_field12) { Common::String resName; if (madsRes) resName += "*"; resName += _spriteSetNames[_spriteListIndex]; _spriteListIndexes[_spriteListIndex] = _view->_spriteSlots.addSprites(resName.c_str()); } // TODO: Unknown section about handling sprite set list combined with messages size // TODO: The original has two separate loops for the loop below based on _animMode == 4. Is it // perhaps that in that mode the sprite frames has a different format..? // Remap the sprite list index fields from the initial value to the indexes of the loaded // sprite sets for the animation for (uint i = 0; i < _frameEntries.size(); ++i) { int idx = _frameEntries[i].spriteSlot.spriteListIndex; _frameEntries[i].spriteSlot.spriteListIndex = _spriteListIndexes[idx]; } if (hasScroll()) _nextScrollTimer = _madsVm->_currentTimer + _scrollTicks; }