void QuickTimeDecoder::queueNextAudioChunk() { AudioSampleDesc *entry = (AudioSampleDesc *)_tracks[_audioTrackIndex]->sampleDescs[0]; Common::MemoryWriteStreamDynamic *wStream = new Common::MemoryWriteStreamDynamic(); _fd->seek(_tracks[_audioTrackIndex]->chunkOffsets[_curAudioChunk]); // First, we have to get the sample count uint32 sampleCount = entry->getAudioChunkSampleCount(_curAudioChunk); assert(sampleCount); if (isOldDemuxing()) { // Old-style audio demuxing // Then calculate the right sizes while (sampleCount > 0) { uint32 samples = 0, size = 0; if (entry->_samplesPerFrame >= 160) { samples = entry->_samplesPerFrame; size = entry->_bytesPerFrame; } else if (entry->_samplesPerFrame > 1) { samples = MIN<uint32>((1024 / entry->_samplesPerFrame) * entry->_samplesPerFrame, sampleCount); size = (samples / entry->_samplesPerFrame) * entry->_bytesPerFrame; } else { samples = MIN<uint32>(1024, sampleCount); size = samples * _tracks[_audioTrackIndex]->sampleSize; } // Now, we read in the data for this data and output it byte *data = (byte *)malloc(size); _fd->read(data, size); wStream->write(data, size); free(data); sampleCount -= samples; } } else { // New-style audio demuxing // Find our starting sample uint32 startSample = 0; for (uint32 i = 0; i < _curAudioChunk; i++) startSample += entry->getAudioChunkSampleCount(i); for (uint32 i = 0; i < sampleCount; i++) { uint32 size = (_tracks[_audioTrackIndex]->sampleSize != 0) ? _tracks[_audioTrackIndex]->sampleSize : _tracks[_audioTrackIndex]->sampleSizes[i + startSample]; // Now, we read in the data for this data and output it byte *data = (byte *)malloc(size); _fd->read(data, size); wStream->write(data, size); free(data); } } // Now queue the buffer queueSound(entry->createAudioStream(new Common::MemoryReadStream(wStream->getData(), wStream->size(), true))); delete wStream; _curAudioChunk++; }
void MystScriptParser::o_changeBackgroundSound(uint16 var, const ArgumentsArray &args) { soundWaitStop(); // Used on Stoneship Card 2080 // Used on Channelwood Card 3225 with argc = 8 i.e. Conditional Sound List Common::MemoryWriteStreamDynamic writeStream = Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES); for (uint i = 0; i < args.size(); i++) { writeStream.writeUint16LE(args[i]); } Common::MemoryReadStream readStream = Common::MemoryReadStream(writeStream.getData(), writeStream.size()); MystSoundBlock soundBlock = _vm->readSoundBlock(&readStream); _vm->applySoundBlock(soundBlock); }
RivenScriptPtr RivenScriptManager::createScriptFromData(uint16 commandCount, ...) { va_list args; va_start(args, commandCount); // Build a script from the variadic arguments Common::MemoryWriteStreamDynamic writeStream = Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES); writeStream.writeUint16BE(commandCount); for (uint i = 0; i < commandCount; i++) { uint16 command = va_arg(args, int); writeStream.writeUint16BE(command); if (command == kRivenCommandSwitch) { // The switch command has a different format that is not implemented error("Cannot create a Switch command from data"); } uint16 argumentCount = va_arg(args, int); writeStream.writeUint16BE(argumentCount); for (uint j = 0; j < commandCount; j++) { uint16 argument = va_arg(args, int); writeStream.writeUint16BE(argument); } } va_end(args); Common::MemoryReadStream readStream = Common::MemoryReadStream(writeStream.getData(), writeStream.size()); return readScript(&readStream); }
GTEST_TEST_F(LocString, write) { Aurora::LocString locString; locString.setString(Aurora::kLanguageEnglish, Aurora::kLanguageGenderMale, "String to test"); locString.setString(Aurora::kLanguageFrench, Aurora::kLanguageGenderMale, "String pour tester"); Common::MemoryWriteStreamDynamic *writeStream = new Common::MemoryWriteStreamDynamic(true); locString.writeLocString(*writeStream); Aurora::LocString locString2; Common::MemoryReadStream readStream(writeStream->getData(), writeStream->size()); EXPECT_EQ(readStream.readUint32LE(), 0); EXPECT_EQ(readStream.readUint32LE(), 14); Common::UString englishString = Common::readStringFixed(readStream, Common::kEncodingASCII, 14); EXPECT_STREQ(englishString.c_str(), "String to test"); EXPECT_EQ(readStream.readUint32LE(), 2); EXPECT_EQ(readStream.readUint32LE(), 18); Common::UString frenchString = Common::readStringFixed(readStream, Common::kEncodingASCII, 18); EXPECT_STREQ(frenchString.c_str(), "String pour tester"); delete writeStream; }
static uint32 convertSND2MIDI(byte *snddata, byte **data) { int32 lp, ep; int n; double ll; Common::MemoryWriteStreamDynamic st; ll = log10(pow(2.0, 1.0 / 12.0)); /* Header */ st.write("MThd", 4); st.writeUint32BE(6); st.writeUint16BE(1); /* mode */ st.writeUint16BE(3); /* number of tracks */ st.writeUint16BE(192); /* ticks / quarter */ fprintf(_fd, "window.sound%d = [\n", _index); for (n = 0; n < 3; n++) { uint16 start, end, pos; st.write("MTrk", 4); lp = st.pos(); st.writeUint32BE(0); /* chunklength */ writeDelta(&st, 0); /* set instrument */ st.writeByte(0xc0 + n); st.writeByte(instr[n]); start = snddata[n * 2 + 0] | (snddata[n * 2 + 1] << 8); end = ((snddata[n * 2 + 2] | (snddata[n * 2 + 3] << 8))) - 5; fprintf(_fd, " ["); bool first = true; for (pos = start; pos < end; pos += 5) { uint16 freq, dur; dur = (snddata[pos + 0] | (snddata[pos + 1] << 8)) * SPEED_FACTOR; freq = ((snddata[pos + 2] & 0x3F) << 4) + (snddata[pos + 3] & 0x0F); if (snddata[pos + 2] > 0) { double fr; int note; /* I don't know, what frequency equals midi note 0 ... */ /* This moves the song 4 octaves down: */ fr = (log10(111860.0 / (double)freq) / ll) - 48; note = (int)floor(fr + 0.5); if (note < 0) note = 0; if (note > 127) note = 127; /* note on */ writeDelta(&st, 0); st.writeByte(144 + n); st.writeByte(note); st.writeByte(100); /* note off */ writeDelta(&st, dur); st.writeByte(128 + n); st.writeByte(note); st.writeByte(0); if ( first ) first = false; else fprintf(_fd, ","); fprintf(_fd, "%d,%d", note, dur/SPEED_FACTOR); } else { /* note on */ writeDelta(&st, 0); st.writeByte(144 + n); st.writeByte(0); st.writeByte(0); /* note off */ writeDelta(&st, dur); st.writeByte(128 + n); st.writeByte(0); st.writeByte(0); if ( first ) first = false; else fprintf(_fd, ","); fprintf(_fd, "%d,%d", -1, dur/SPEED_FACTOR); } } fprintf(_fd, n<2 ? "],\n" : "]\n"); writeDelta(&st, 0); st.writeByte(0xff); st.writeByte(0x2f); st.writeByte(0x0); ep = st.pos(); st.seek(lp, SEEK_SET); st.writeUint32BE((ep - lp) - 4); st.seek(ep, SEEK_SET); } fprintf(_fd, "];\n"); // *data = st.getData(); return st.pos(); }
static void compareStream(Common::MemoryWriteStreamDynamic &stream, const char *data) { ASSERT_EQ(stream.size(), strlen(data)); for (size_t i = 0; i < strlen(data); i++) EXPECT_EQ(stream.getData()[i], data[i]) << "At index " << i; }
Common::MemoryReadStream *LanguageManager::preParseColorCodes(Common::SeekableReadStream &stream) { Common::MemoryWriteStreamDynamic output; output.reserve(stream.size()); int state = 0; std::vector<byte> collect; collect.reserve(6); byte color[3]; byte b; while (stream.read(&b, 1) == 1) { if (state == 0) { if (b == '<') { collect.push_back(b); state = 1; } else output.writeByte(b); continue; } if (state == 1) { if (b == 'c') { collect.push_back(b); state = 2; } else { output.write(&collect[0], collect.size()); output.writeByte(b); collect.clear(); state = 0; } continue; } if ((state == 2) || (state == 3) || (state == 4)) { collect.push_back(b); color[state - 2] = b; state++; continue; } if (state == 5) { if (b == '>') { Common::UString c = Common::UString::format("<c%02X%02X%02X%02X>", (uint8) color[0], (uint8) color[1], (uint8) color[2], (uint8) 0xFF); output.writeString(c); collect.clear(); state = 0; } else { output.write(&collect[0], collect.size()); output.writeByte(b); collect.clear(); state = 0; } continue; } } return new Common::MemoryReadStream(output.getData(), output.size(), true); }
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[] data; delete cursorStreams[i]; } return new Common::MemoryReadStream(out.getData(), out.size()); }
bool GameLoader::writeSavegame(Scene *sc, const char *fname) { GameVar *v = _gameVar->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME"); if (!v) { v = _gameVar->getSubVarByName("OBJSTATES")->addSubVarAsInt("SAVEGAME", 0); if (!v) { warning("No state to save"); return false; } } SaveHeader header; v->setSubVarAsInt("Scene", sc->_sceneId); saveScenePicAniInfos(sc->_sceneId); memset(&header, 0, sizeof(header)); header.version = 48; // '0' strcpy(header.magic, "FullPipe Savegame"); header.updateCounter = _updateCounter; header.unkField = 1; Common::MemoryWriteStreamDynamic stream; MfcArchive *archive = new MfcArchive(&stream); v = _gameVar->getSubVarByName("OBJSTATES"); GameVar *nxt = 0; GameVar *prv = 0; GameVar *par; if (v) { nxt = v->_nextVarObj; prv = v->_prevVarObj; par = v->_parentVarObj; v->_parentVarObj = 0; v->_nextVarObj = 0; v->_prevVarObj = 0; } archive->writeObject(v); if (v) { v->_parentVarObj = par; v->_nextVarObj = nxt; v->_prevVarObj = prv; } getGameLoaderInventory()->savePartial(*archive); archive->writeUint32LE(_sc2array.size()); debugC(3, kDebugLoading, "Saving %d infos", _sc2array.size()); for (uint i = 0; i < _sc2array.size(); i++) { archive->writeUint32LE(_sc2array[i]._picAniInfosCount); if (_sc2array[i]._picAniInfosCount) debugC(3, kDebugLoading, "Count %d: %d", i, _sc2array[i]._picAniInfosCount); for (uint j = 0; j < _sc2array[i]._picAniInfosCount; j++) { _sc2array[i]._picAniInfos[j]->save(*archive); } } header.encSize = stream.size(); // Now obfuscate the data for (uint i = 0; i < header.encSize; i++) stream.getData()[i] += i & 0x7f; if (_savegameCallback) _savegameCallback(archive, true); // Now dump it into save file Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(fname); if (!saveFile) { warning("Cannot open file for writing: %s", fname); return false; } saveFile->writeUint32LE(header.version); saveFile->write(header.magic, 32); saveFile->writeUint32LE(header.updateCounter); saveFile->writeUint32LE(header.unkField); saveFile->writeUint32LE(header.encSize); debugC(3, kDebugLoading, "version: %d magic: %s updateCounter: %d unkField: %d encSize: %d, pos: %d", header.version, header.magic, header.updateCounter, header.unkField, header.encSize, saveFile->pos()); saveFile->write(stream.getData(), stream.size()); uint headerPos = saveFile->pos(); FullpipeSavegameHeader header2; strcpy(header2.id, "SVMCR"); header2.version = FULLPIPE_SAVEGAME_VERSION; TimeDate curTime; g_system->getTimeAndDate(curTime); header2.date = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF); header2.time = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF); header2.playtime = g_fp->getTotalPlayTime() / 1000; saveFile->write(header2.id, 6); saveFile->writeByte(header2.version); saveFile->writeUint32LE(header2.date); saveFile->writeUint16LE(header2.time); saveFile->writeUint32LE(header2.playtime); g_fp->_currentScene->draw(); Graphics::saveThumbnail(*saveFile); // FIXME. Render proper screen saveFile->writeUint32LE(headerPos); // Store where the header starts saveFile->finalize(); delete saveFile; delete archive; return true; }