Common::SeekableReadStream *PEFile::getResource(uint32 index) const { // Convert from the PE cursor group/cursor format to the standalone // cursor format. Common::MemoryWriteStreamDynamic out; Common::SeekableReadStream *cursorGroup = _peFile->getResource(Common::kPEGroupCursor, index); if (!cursorGroup) return 0; // Cursor Group Header out.writeUint16LE(cursorGroup->readUint16LE()); out.writeUint16LE(cursorGroup->readUint16LE()); uint16 cursorCount = cursorGroup->readUint16LE(); out.writeUint16LE(cursorCount); std::vector<Common::SeekableReadStream *> cursorStreams; cursorStreams.resize(cursorCount); uint32 startOffset = 6 + cursorCount * 16; for (uint16 i = 0; i < cursorCount; i++) { out.writeByte(cursorGroup->readUint16LE()); // width out.writeByte(cursorGroup->readUint16LE() / 2); // height cursorGroup->readUint16LE(); // planes out.writeByte(cursorGroup->readUint16LE()); // bits per pixel out.writeByte(0); // reserved cursorGroup->readUint32LE(); // data size uint16 id = cursorGroup->readUint16LE(); Common::SeekableReadStream *cursor = _peFile->getResource(Common::kPECursor, id); if (!cursor) { warning("Could not get cursor resource %d", id); return 0; } out.writeUint16LE(cursor->readUint16LE()); // hotspot X out.writeUint16LE(cursor->readUint16LE()); // hotspot Y out.writeUint32LE(cursor->size() - 4); // size out.writeUint32LE(startOffset); // offset startOffset += cursor->size() - 4; cursorStreams[i] = cursor; } for (uint32 i = 0; i < cursorStreams.size(); i++) { byte *data = new byte[cursorStreams[i]->size() - 4]; cursorStreams[i]->read(data, cursorStreams[i]->size() - 4); out.write(data, cursorStreams[i]->size() - 4); delete cursorStreams[i]; } return new Common::MemoryReadStream(out.getData(), out.size()); }
void ComposerEngine::loadAnimation(Animation *&anim, uint16 animId, int16 x, int16 y, int16 eventParam, int32 size) { Common::SeekableReadStream *stream = NULL; Pipe *newPipe = NULL; // First, check the existing pipes. for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) { Pipe *pipe = *j; if (!pipe->hasResource(ID_ANIM, animId)) continue; stream = pipe->getResource(ID_ANIM, animId, false); // When loading from savegame, make sure we have the correct stream if ((!size) || (stream->size() >= size)) break; stream = NULL; } // If we didn't find it, try the libraries. if (!stream) { if (!hasResource(ID_ANIM, animId)) { warning("ignoring attempt to play invalid anim %d", animId); return; } Common::List<Library>::iterator j; for (j = _libraries.begin(); j != _libraries.end(); j++) { if (!j->_archive->hasResource(ID_ANIM, animId)) continue; stream = j->_archive->getResource(ID_ANIM, animId); // When loading from savegame, make sure we have the correct stream if ((!size) || (stream->size() >= size)) break; stream = NULL; } uint32 type = j->_archive->getResourceFlags(ID_ANIM, animId); // If the resource is a pipe itself, then load the pipe // and then fish the requested animation out of it. if (type != 1) { _pipeStreams.push_back(stream); newPipe = new Pipe(stream, animId); _pipes.push_front(newPipe); newPipe->nextFrame(); stream = newPipe->getResource(ID_ANIM, animId, false); } } anim = new Animation(stream, animId, Common::Point(x, y), eventParam); if (newPipe) newPipe->_anim = anim; }
ExpressCursorMan::ExpressCursorMan(OSystem *system, Common::Archive *arc) : _syst(system), _current(255), _data(NULL) { Common::SeekableReadStream *cursorFile; cursorFile = arc->createReadStreamForMember("CURSORS.TBM"); if (cursorFile) { _data = new byte[cursorFile->size()]; if (_data) { cursorFile->read(_data, cursorFile->size()); } } }
bool Debugger::Cmd_DumpFile(int argc, const char **argv) { if (argc < 2) { debugPrintf("Usage: %s <resource> <unpack>\n", argv[0]); debugPrintf(" resource: the resource name\n"); debugPrintf(" unpack: optional, when specified, the FAB/MADSPACK compressed resource is unpacked\n"); } else { Common::DumpFile outFile; Common::File inFile; if (!inFile.open(argv[1])) { debugPrintf("Specified resource does not exist\n"); } else { outFile.open(argv[1]); bool unpack = ((argc >= 3) && !scumm_stricmp(argv[2], "unpack")); byte *data; int totalSize = 0; if (!unpack) { totalSize = inFile.size(); data = new byte[totalSize]; inFile.read(data, totalSize); } else { MadsPack dataPack(&inFile); int count = dataPack.getCount(); for (int i = 0; i < count; i++) { totalSize += dataPack.getItem(i)._size; } data = new byte[totalSize]; byte *ptr = data; for (int i = 0; i < count; i++) { Common::SeekableReadStream *readStream = dataPack.getItemStream(i); readStream->read(ptr, readStream->size()); ptr += readStream->size(); } } outFile.write(data, totalSize); outFile.flush(); delete[] data; inFile.close(); outFile.close(); debugPrintf("File written successfully.\n"); } } return true; }
bool ADLPlayer::readHeader(Common::SeekableReadStream &adl, int &timbreCount) { // Sanity check if (adl.size() < 60) { warning("ADLPlayer::readHeader(): File too small (%d)", adl.size()); return false; } _soundMode = adl.readByte(); timbreCount = adl.readByte() + 1; adl.skip(1); return true; }
void VPXDecoder::decodeFrame(Graphics::Surface &surface, Common::SeekableReadStream &dataStream) { if (!_initialized) return; // Read all the data from the stream Common::ScopedArray<byte> data(new byte[dataStream.size()]); dataStream.read(data.get(), dataStream.size()); // Perform the actual decode vpx_codec_err_t result = vpx_codec_decode(&_context, data.get(), dataStream.size(), 0, 0); if (result != VPX_CODEC_OK) return; // Try to get the image vpx_codec_iter_t iter = 0; vpx_image_t *image = vpx_codec_get_frame(&_context, &iter); if (!image) return; // Figure out the color range Graphics::YUVToRGBManager::LuminanceScale scale; switch (image->range) { case VPX_CR_STUDIO_RANGE: scale = Graphics::YUVToRGBManager::kScaleITU; break; case VPX_CR_FULL_RANGE: scale = Graphics::YUVToRGBManager::kScaleFull; break; default: return; } // If we don't have it already, create our local surface if (!_surface) _surface.reset(new Graphics::Surface(image->w, image->h)); // Do the conversion based on the color space switch (image->fmt) { case VPX_IMG_FMT_I420: YUVToRGBMan.convert420(scale, _surface->getData(), _surface->getPitch(), image->planes[0], image->planes[1], image->planes[2], image->w, image->h, image->stride[0], image->stride[1]); break; default: return; } // Copy the subarea into the surface for (int y = 0; y < surface.getHeight(); y++) memcpy(surface.getData() + y * surface.getPitch(), _surface->getData() + (y * image->d_h) * image->d_w * 4, image->d_w * 4); }
void SBM::readData(Common::SeekableReadStream &sbm, bool deswizzle) { if ((sbm.size() % 1024) != 0) throw Common::Exception("Invalid SBM (%u)", (uint)sbm.size()); const size_t rowCount = (sbm.size() / 1024); _mipMaps.push_back(new MipMap); _mipMaps[0]->width = 4 * 32; _mipMaps[0]->height = NEXTPOWER2((uint32) rowCount * 32); _mipMaps[0]->size = _mipMaps[0]->width * _mipMaps[0]->height * 4; _mipMaps[0]->data.reset(new byte[_mipMaps[0]->size]); // SBM data consists of character sized 32 * 32 pixels, with 2 bits per pixel. // 4 characters each are on top of each other, occupying the same x/y // coordinates but different planes. // We'll unpack them and draw them next to each other instead. static const int masks [4] = { 0x03, 0x0C, 0x30, 0xC0 }; static const int shifts[4] = { 0, 2, 4, 6 }; byte *data = _mipMaps[0]->data.get(); byte buffer[1024]; for (size_t c = 0; c < rowCount; c++) { if (sbm.read(buffer, 1024) != 1024) throw Common::Exception(Common::kReadError); for (int y = 0; y < 32; y++) { for (int plane = 0; plane < 4; plane++) { for (int x = 0; x < 32; x++) { const uint32 offset = deswizzle ? deSwizzleOffset(x, y, 32, rowCount) : (y * 32 + x); const byte a = ((buffer[offset] & masks[plane]) >> shifts[plane]) * 0x55; *data++ = 0xFF; // B *data++ = 0xFF; // G *data++ = 0xFF; // R *data++ = a; // A } } } } byte *dataEnd = _mipMaps[0]->data.get() + _mipMaps[0]->size; std::memset(data, 0, dataEnd - data); }
static void io_appendto() { Common::String s = Common::lastPathComponent(luaL_check_string(FIRSTARG), '\\'); Common::SeekableReadStream *inFile = NULL; Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); inFile = saveFileMan->openForLoading(s); if (!inFile) { pushresult(0); return; } int size = inFile->size(); byte *buf = new byte[size]; inFile->read(buf, size); delete inFile; Common::WriteStream *outFile = NULL; outFile = saveFileMan->openForSaving(s); if (!outFile) pushresult(0); else { outFile->write(buf, size); LuaFile *current = new LuaFile(); current->_out = outFile; current->_filename = s; setreturn(addfile(current), FOUTPUT); } delete[] buf; }
int32 AudioManager::playSFX(int32 id, int volume , bool genericSFX) { debugC(4, kDebugAudio, "playSFX(%d, %d)", id, (genericSFX) ? 1 : 0); // find a free SFX channel Common::SeekableReadStream *stream; if (genericSFX) stream = _audioPacks[2]->getStream(id, true); else stream = _audioPacks[3]->getStream(id, true); if (stream->size() == 0) return -1; for (int32 i = 3; i < 16; i++) { if (!_channels[i]) { _channels[i] = new AudioStreamInstance(this, _mixer, stream, false, true); _channels[i]->play(false, Audio::Mixer::kSFXSoundType); _channels[i]->setVolume(_sfxMuted ? 0 : volume); return i; } } return -1; }
Common::String Resource::getMessage(uint16 id, uint16 message) { Common::SeekableReadStream *lookup = _text->createReadStreamForIndex(id + 6); Common::SeekableReadStream *strings = _text->createReadStreamForIndex(id + 7); char buff[1024]; int j = 0; int size = lookup->size()/2; for (int i = 0; i < size; ++i) { uint16 val = lookup->readUint16LE(); if (val == message) { strings->seek(i*2); uint16 offset = strings->readUint16LE(); char c = 0; strings->seek(offset); do { c = strings->readByte(); buff[j++] = c; } while (c != 0); return buff; } } return ""; }
bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) { uint32 headerSize = stream.readUint32LE(); if (headerSize != 40) return false; uint32 width = stream.readUint32LE(); uint32 height = stream.readUint32LE(); stream.readUint16LE(); // planes uint16 bitsPerPixel = stream.readUint16LE(); uint32 compression = stream.readUint32BE(); /* uint32 imageSize = */ stream.readUint32LE(); /* uint32 pixelsPerMeterX = */ stream.readUint32LE(); /* uint32 pixelsPerMeterY = */ stream.readUint32LE(); _paletteColorCount = stream.readUint32LE(); /* uint32 colorsImportant = */ stream.readUint32LE(); _paletteColorCount = (_paletteColorCount == 0) ? 255: _paletteColorCount; Common::SeekableSubReadStream subStream(&stream, 40, stream.size()); _codec = Image::createBitmapCodec(compression, width, height, bitsPerPixel); if (!_codec) return false; _surface = _codec->decodeFrame(subStream); return true; }
void DrasculaEngine::playFile(const char *fname) { Common::SeekableReadStream *stream = _archives.open(fname); if (stream) { int startOffset = 0; int soundSize = stream->size() - startOffset; if (!strcmp(fname, "3.als") && soundSize == 145166 && _lang != kSpanish) { // WORKAROUND: File 3.als with English speech files has a big silence at // its beginning and end. We seek past the silence at the beginning, // and ignore the silence at the end // Fixes bug #2111815 - "DRASCULA: Voice delayed" startOffset = 73959; soundSize = soundSize - startOffset - 26306; } Common::SeekableReadStream *subStream = new Common::SeekableSubReadStream( stream, startOffset, startOffset + soundSize, DisposeAfterUse::YES); if (!subStream) { warning("playFile: Out of memory"); delete stream; return; } Audio::AudioStream *sound = Audio::makeRawStream(subStream, 11025, Audio::FLAG_UNSIGNED); _mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle, sound); } else warning("playFile: Could not open %s", fname); }
Common::WriteStream *ScummEngine_v60he::openSaveFileForAppending(const byte *fileName) { Common::SeekableReadStream *initialFile = openSaveFileForReading(fileName); byte *initialData = 0; uint32 initialDataSize = 0; if (initialFile) { initialDataSize = initialFile->size(); if (initialDataSize > 0) { initialData = new byte[initialDataSize]; initialFile->read(initialData, initialDataSize); } delete initialFile; } Common::WriteStream *output = openSaveFileForWriting(fileName); if (!output) { delete[] initialData; return nullptr; } if (initialData) { output->write(initialData, initialDataSize); delete[] initialData; } return output; }
int MadsSpriteSlots::addSprites(const char *resName, bool suppressErrors, int flags) { // If errors are suppressed, first check if the resource exists if (suppressErrors) { if (!_vm->res()->resourceExists(resName)) return -1; } // Append on a '.SS' suffix if the resource doesn't already have an extension char buffer[100]; strncpy(buffer, resName, 95); buffer[95] = '\0'; if (!strchr(buffer, '.')) strcat(buffer, ".SS"); // Get the sprite set Common::SeekableReadStream *data = _vm->res()->get(buffer); SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), buffer, false, flags); spriteSet->translate(_madsVm->_palette); assert(spriteSet != NULL); _sprites.push_back(spriteSet); _vm->res()->toss(buffer); return _sprites.size() - 1; }
void DrasculaEngine::playFile(const char *fname) { Common::SeekableReadStream *stream = _archives.open(fname); if (stream) { int soundSize = stream->size(); byte *soundData = (byte *)malloc(soundSize); if (!(!strcmp(fname, "3.als") && soundSize == 145166 && _lang != kSpanish)) { stream->seek(32); } else { // WORKAROUND: File 3.als with English speech files has a big silence at // its beginning and end. We seek past the silence at the beginning, // and ignore the silence at the end // Fixes bug #2111815 - "DRASCULA: Voice delayed" stream->seek(73959, SEEK_SET); soundSize = 117158 - 73959; } stream->read(soundData, soundSize); delete stream; _subtitlesDisabled = !ConfMan.getBool("subtitles"); if (ConfMan.getBool("speech_mute")) memset(soundData, 0x80, soundSize); // Mute speech but keep the pause Audio::AudioStream *sound = Audio::makeRawStream(soundData, soundSize - 64, 11025, Audio::FLAG_UNSIGNED); _mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle, sound); } else warning("playFile: Could not open %s", fname); }
void DrasculaEngine::loadPic(const char *NamePcc, byte *targetSurface, int colorCount) { debug(5, "loadPic(%s)", NamePcc); uint dataSize = 0; byte *pcxData; Common::SeekableReadStream *stream = _archives.open(NamePcc); if (!stream) error("missing game data %s %c", NamePcc, 7); dataSize = stream->size() - 128 - (256 * 3); pcxData = (byte *)malloc(dataSize); stream->seek(128, SEEK_SET); stream->read(pcxData, dataSize); decodeRLE(pcxData, targetSurface); free(pcxData); for (int i = 0; i < 256; i++) { cPal[i * 3 + 0] = stream->readByte(); cPal[i * 3 + 1] = stream->readByte(); cPal[i * 3 + 2] = stream->readByte(); } delete stream; setRGB((byte *)cPal, colorCount); }
void Font::setFontMads(const char *filename) { MadsPack fontData(filename, _vm); Common::SeekableReadStream *fontFile = fontData.getItemStream(0); _maxHeight = fontFile->readByte(); _maxWidth = fontFile->readByte(); _charWidths = new uint8[128]; // Char data is shifted by 1 _charWidths[0] = 0; fontFile->read(_charWidths + 1, 127); fontFile->readByte(); // remainder _charOffs = new uint16[128]; uint32 startOffs = 2 + 128 + 256; uint32 fontSize = fontFile->size() - startOffs; // Char data is shifted by 1 _charOffs[0] = 0; for (int i = 1; i < 128; i++) _charOffs[i] = fontFile->readUint16LE() - startOffs; fontFile->readUint16LE(); // remainder _charData = new uint8[fontSize]; fontFile->read(_charData, fontSize); delete fontFile; }
void Surface::load(Common::SeekableReadStream &stream, Type type) { //debug(0, "load()"); free(); x = y = 0; uint16 w_ = stream.readUint16LE(); uint16 h_ = stream.readUint16LE(); if (type != kTypeLan) { uint16 pos = stream.readUint16LE(); x = pos % 320; y = pos / 320; } //debug(0, "declared info: %ux%u (%04xx%04x) -> %u,%u", w_, h_, w_, h_, x, y); if (stream.eos() || w_ == 0) return; if (w_ * h_ > stream.size()) { debug(0, "invalid surface %ux%u -> %u,%u", w_, h_, x, y); return; } //debug(0, "creating surface %ux%u -> %u,%u", w_, h_, x, y); create(w_, h_, Graphics::PixelFormat::createFormatCLUT8()); stream.read(pixels, w_ * h_); }
Common::SeekableReadStream *HERFFile::getResource(uint32 index) const { const IResource &res = getIResource(index); if (res.size == 0) return new Common::MemoryReadStream(0, 0); Common::SeekableReadStream *herf = ResMan.getResource(TypeMan.setFileType(_fileName, kFileTypeNone), kFileTypeHERF); if (!herf) throw Common::Exception(Common::kOpenError); if (!herf->seek(res.offset)) { delete herf; throw Common::Exception(Common::kSeekError); } Common::SeekableReadStream *resStream = herf->readStream(res.size); if (!resStream || (((uint32) resStream->size()) != res.size)) { delete herf; delete resStream; throw Common::Exception(Common::kReadError); } delete herf; return resStream; }
void SSFFile::load(Common::SeekableReadStream &ssf) { readHeader(ssf); if (_id != kSSFID) throw Common::Exception("Not a SSF file"); if ((_version != kVersion1) && (_version != kVersion11)) throw Common::Exception("Unsupported SSF file version %08X", _version); uint32 entryCount = 0; if (_version == kVersion1) entryCount = ssf.readUint32LE(); uint32 offEntryTable = ssf.readUint32LE(); if (_version == kVersion11) entryCount = (ssf.size() - offEntryTable) / 4; _sounds.resize(entryCount); try { readEntries(ssf, offEntryTable); if (ssf.err()) throw Common::Exception(Common::kReadError); } catch (Common::Exception &e) { e.add("Failed reading SSF file"); throw e; } }
void HERFFile::getDictionary(std::list<uint32> &hashes, std::list<Common::UString> &names) const { hashes.clear(); names.clear(); if (_dictIndex == 0xFFFFFFFF) return; Common::SeekableReadStream *dict = getResource(_dictIndex); dict->skip(8); // unknown while (dict->pos() < dict->size()) { uint32 hash = dict->readUint32LE(); if (hash == 0) break; hashes.push_back(hash); names.push_back(""); names.back().readFixedASCII(*dict, 128); names.back().tolower(); } delete dict; }
bool Sprite::loadFromSaturnCursor(Common::SeekableReadStream &cursor) { if (cursor.size() != 260) return false; _fromCursor = true; create(16, 16); cursor.seek(0); _feetX = cursor.readUint16BE(); _feetY = cursor.readUint16BE(); byte *img = (byte *) _surfaceTrueColor.pixels; for (int32 y = 0; y < 16; y++) { for (int32 x = 0; x < 16; x++) { const uint8 p = cursor.readByte(); const uint32 c = (p == 0) ? ImgConv.getColor(0, 0, 255) : ImgConv.getColor(255 - p, 255 - p, 255 - p); ImgConv.writeColor(img, c); img += _surfaceTrueColor.bytesPerPixel; } } return true; }
void MadsM4Engine::dumpFile(const char* filename, bool uncompress) { Common::DumpFile f; byte buffer[DUMP_BUFFER_SIZE]; Common::SeekableReadStream *fileS = res()->get(filename); if (!f.open(filename)) error("Could not open '%s' for writing", filename); int bytesRead = 0; warning("Dumping %s, size: %i\n", filename, fileS->size()); if (!uncompress) { while (!fileS->eos()) { bytesRead = fileS->read(buffer, DUMP_BUFFER_SIZE); f.write(buffer, bytesRead); } } else { MadsPack packData(fileS); Common::SeekableReadStream *sourceUnc; for (int i = 0; i < packData.getCount(); i++) { sourceUnc = packData.getItemStream(i); debugCN(kDebugCore, "Dumping compressed chunk %i of %i, size is %i\n", i + 1, packData.getCount(), sourceUnc->size()); while (!sourceUnc->eos()) { bytesRead = sourceUnc->read(buffer, DUMP_BUFFER_SIZE); f.write(buffer, bytesRead); } delete sourceUnc; } } f.close(); res()->toss(filename); res()->purge(); }
GameInterfaceView::GameInterfaceView(M4Engine *vm): View(vm, Common::Rect(0, vm->_screen->height() - INTERFACE_HEIGHT, vm->_screen->width(), vm->_screen->height())), _statusText(GUITextField(this, Common::Rect(200, 1, 450, 21))), _inventory(GUIInventory(this, vm, Common::Rect(188, 22, 539, 97), 9, 1, 39, 75, 3)) { _screenType = VIEWID_INTERFACE; _screenFlags.layer = LAYER_INTERFACE; _screenFlags.visible = false; _screenFlags.get = SCREVENT_MOUSE; _highlightedIndex = -1; _selected = false; Common::SeekableReadStream *data = _vm->res()->get(INTERFACE_SERIES); RGB8 *palette; _sprites = new SpriteAsset(_vm, data, data->size(), INTERFACE_SERIES); palette = _sprites->getPalette(); //Palette.setPalette(palette, 0, _sprites->getColorCount()); _vm->res()->toss(INTERFACE_SERIES); // Setup the interface buttons _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(15, 35, 47, 66), 0, SPR(0), SPR(1), SPR(2)))); // look _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(60, 35, 92, 66), 1, SPR(3), SPR(4), SPR(5)))); // take _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(105, 35, 137, 66), 2, SPR(6), SPR(7), SPR(8)))); // manipulate _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(580, 10, 620, 69), 3, SPR(69), SPR(70), SPR(71)))); // abduction _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(582, 70, 619, 105), 4, SPR(76), SPR(77), SPR(78)))); // menu _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(168, 22, 188, 97), 5, SPR(60), SPR(61), SPR(62)))); // Scroll left _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(539, 22, 559, 97), 6, SPR(64), SPR(65), SPR(66)))); // Scroll right }
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; }
bool Script::loadScript(Common::String filename) { Common::SeekableReadStream *scriptfile = 0; if (_vm->_macResFork) { // Try to open the script file from the resource fork scriptfile = _vm->_macResFork->getResource(filename); } else { // Try to open the script file scriptfile = SearchMan.createReadStreamForMember(filename); } if (!scriptfile) return false; // Save the script filename _scriptFile = filename; // Load the code _codeSize = scriptfile->size(); _code = new byte[_codeSize]; if (!_code) return false; scriptfile->read(_code, _codeSize); delete scriptfile; // Patch the loaded code for known script bugs if (filename.equals("dr.grv")) { // WORKAROUND for the cake puzzle glitch (bug #2458322): Lowering the // piece on the first column and second row updates the wrong script // variable assert(_codeSize == 5546); _code[0x03C2] = 0x38; } else if (filename.equals("maze.grv")) { // GRAPHICS ENHANCEMENT - Leave a skeleton in the maze. // Replaces one normal T intersection with the unused(?) // skeleton T intersection graphics. assert(_codeSize == 3652); // Terminating T branch _code[0x0769] = 0x46; _code[0x0774] = 0x3E; _code[0x077A] = 0x42; // T with branch on right _code[0x08E2] = 0x43; _code[0x08D7] = 0x44; _code[0x08E8] = 0x45; // T with branch on left _code[0x0795] = 0x41; _code[0x078A] = 0x40; _code[0x079B] = 0x3F; } // Initialize the script _currentInstruction = 0; return true; }
byte *PackageManager::getFile(const Common::String &fileName, uint *fileSizePtr) { const Common::String B25S_EXTENSION(".b25s"); Common::SeekableReadStream *in; if (fileName.hasSuffix(B25S_EXTENSION)) { // Savegame loading logic Common::SaveFileManager *sfm = g_system->getSavefileManager(); Common::InSaveFile *file = sfm->openForLoading( FileSystemUtil::getPathFilename(fileName)); if (!file) { BS_LOG_ERRORLN("Could not load savegame \"%s\".", fileName.c_str()); return 0; } if (fileSizePtr) *fileSizePtr = file->size(); byte *buffer = new byte[file->size()]; file->read(buffer, file->size()); delete file; return buffer; } Common::ArchiveMemberPtr fileNode = getArchiveMember(normalizePath(fileName, _currentDirectory)); if (!fileNode) return 0; if (!(in = fileNode->createReadStream())) return 0; // If the filesize is desired, then output the size if (fileSizePtr) *fileSizePtr = in->size(); // Read the file byte *buffer = new byte[in->size()]; int bytesRead = in->read(buffer, in->size()); delete in; if (!bytesRead) { delete[] buffer; return NULL; } return buffer; }
void MainWindow::exportBMUMP3Impl(Common::SeekableReadStream &bmu, Common::WriteStream &mp3) { if ((bmu.size() <= 8) || (bmu.readUint32BE() != MKTAG('B', 'M', 'U', ' ')) || (bmu.readUint32BE() != MKTAG('V', '1', '.', '0'))) throw Common::Exception("Not a valid BMU file"); mp3.writeStream(bmu); }
void TitanicEngine::setItemNames() { Common::SeekableReadStream *r; r = g_vm->_filesManager->getResource("TEXT/ITEM_NAMES"); while (r->pos() < r->size()) _itemNames.push_back(readStringFromStream(r)); delete r; r = g_vm->_filesManager->getResource("TEXT/ITEM_DESCRIPTIONS"); while (r->pos() < r->size()) _itemDescriptions.push_back(readStringFromStream(r)); delete r; r = g_vm->_filesManager->getResource("TEXT/ITEM_IDS"); while (r->pos() < r->size()) _itemIds.push_back(readStringFromStream(r)); delete r; }
void TRXFile::loadDirectory(Common::SeekableReadStream &trx, std::vector<Packet> &packets) { for (std::vector<Packet>::iterator p = packets.begin(); p != packets.end(); ++p) { p->type = trx.readUint32BE(); p->offset = trx.readUint32LE(); if (p->offset >= (uint)trx.size()) throw Common::Exception("Offset of 0x%08X packet too big (%d)", p->type, p->offset); } }