uint SoundChannel::play(uint soundNum, uint repeats, uint notify) { stop(); if (repeats == 0) return 1; // Find a sound of the given name Audio::AudioStream *stream; Common::File f; Common::String nameSnd = Common::String::format("sound%u.snd", soundNum); Common::String nameWav = Common::String::format("sound%u.wav", soundNum); Common::String nameAiff = Common::String::format("sound%u.aiff", soundNum); #ifdef USE_MAD Common::String nameMp3 = Common::String::format("sound%u.mp3", soundNum); #endif if (f.exists(nameSnd) && f.open(nameSnd)) { if (f.readUint16BE() != (f.size() - 2)) error("Invalid sound filesize"); repeats = f.readByte(); f.skip(1); uint freq = f.readUint16BE(); f.skip(2); uint size = f.readUint16BE(); Common::SeekableReadStream *s = f.readStream(size); stream = Audio::makeRawStream(s, freq, Audio::FLAG_UNSIGNED); #ifdef USE_MAD } else if (f.exists(nameMp3) && f.open(nameMp3)) { Common::SeekableReadStream *s = f.readStream(f.size()); stream = Audio::makeMP3Stream(s, DisposeAfterUse::YES); #endif } else if (f.exists(nameWav) && f.open(nameWav)) { Common::SeekableReadStream *s = f.readStream(f.size()); stream = Audio::makeWAVStream(s, DisposeAfterUse::YES); } else if (f.exists(nameAiff) && f.open(nameAiff)) { Common::SeekableReadStream *s = f.readStream(f.size()); stream = Audio::makeAIFFStream(s, DisposeAfterUse::YES); } else { warning("Could not find sound %u", soundNum); return 1; } _soundNum = soundNum; _notify = notify; // Set up a repeat if multiple repeats are specified if (repeats > 1) { Audio::RewindableAudioStream *rwStream = dynamic_cast<Audio::RewindableAudioStream *>(stream); assert(rwStream); stream = new Audio::LoopingAudioStream(rwStream, repeats, DisposeAfterUse::YES); } // Start playing the audio g_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, stream); return 0; }
int AgiEngine::loadWords(const char *fname) { Common::File fp; if (!fp.open(fname)) { warning("loadWords: can't open %s", fname); return errOK; // err_BadFileOpen } debug(0, "Loading dictionary: %s", fname); // Loop through alphabet, as words in the dictionary file are sorted by // first character for (int i = 0; i < 26; i++) { fp.seek(i * 2, SEEK_SET); int offset = fp.readUint16BE(); if (offset == 0) continue; fp.seek(offset, SEEK_SET); int k = fp.readByte(); while (!fp.eos() && !fp.err()) { // Read next word char c, str[64]; do { c = fp.readByte(); str[k++] = (c ^ 0x7F) & 0x7F; } while (!(c & 0x80) && k < (int)sizeof(str) - 1); str[k] = 0; // WORKAROUND: // The SQ0 fan game stores words starting with numbers (like '7up') // in its dictionary under the 'a' entry. We skip these. // See bug #3615061 if (str[0] == 'a' + i) { // And store it in our internal dictionary AgiWord *w = new AgiWord; w->word = myStrndup(str, k); w->id = fp.readUint16BE(); _game.words[i].push_back(w); } k = fp.readByte(); // Are there more words with an already known prefix? // WORKAROUND: We only break after already seeing words with the // right prefix, for the SQ0 words starting with digits filed under // 'a'. See above comment and bug #3615061. if (k == 0 && str[0] >= 'a' + i) break; } } return errOK; }
void ExtractCine::unpackFile(Common::File &file) { char fileName[15]; unsigned int entryCount = file.readUint16BE(); // How many entries? unsigned int entrySize = file.readUint16BE(); // How many bytes per entry? assert(entrySize == 0x1e); while (entryCount--) { file.read_throwsOnError(fileName, 14); fileName[14] = '\0'; Common::Filename outPath(_outputPath); outPath.setFullName(fileName); uint32 offset = file.readUint32BE(); unsigned int packedSize = file.readUint32BE(); unsigned int unpackedSize = file.readUint32BE(); // Skip one file.readUint32BE(); unsigned int savedPos = file.pos(); print("unpacking '%s' ... ", outPath.getFullName().c_str()); Common::File fpOut(outPath, "wb"); file.seek(offset, SEEK_SET); assert(unpackedSize >= packedSize); uint8 *data = (uint8 *)calloc(unpackedSize, 1); uint8 *packedData = (uint8 *)calloc(packedSize, 1); assert(data); assert(packedData); file.read_throwsOnError(packedData, packedSize); bool status = true; if (packedSize != unpackedSize) { CineUnpacker cineUnpacker; status = cineUnpacker.unpack(packedData, packedSize, data, unpackedSize); } else { memcpy(data, packedData, packedSize); } free(packedData); fpOut.write(data, unpackedSize); free(data); if (!status) { print("CRC ERROR"); } else { print("ok"); } print(", packedSize %u unpackedSize %u", packedSize, unpackedSize); file.seek(savedPos, SEEK_SET); } }
void SoundHandler::loadIntroSong(Common::File &in) { for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { uint16 numBuf = in.readUint16BE(); if (varnt == _vm->_gameVariant) DOSIntroSong = _vm->_text->getTextData(numBuf); } }
void Sound::loadVoiceFile(const GameSpecificSettings *gss) { // Game versions which use separate voice files if (_vm->getGameType() == GType_FF || _vm->getGameId() == GID_SIMON1CD32) return; char filename[16]; Common::File *file = new Common::File(); if (!_hasVoiceFile) { _voice = makeCompressedSound(_mixer, file, gss->speech_filename); _hasVoiceFile = (_voice != 0); } if (!_hasVoiceFile && _vm->getGameType() == GType_SIMON2) { // for simon2 mac/amiga, only read index file file->open("voices.idx"); if (file->isOpen() == true) { int end = file->size(); _filenums = (uint16 *)malloc((end / 6 + 1) * 2); _offsets = (uint32 *)malloc((end / 6 + 1) * 4); for (int i = 1; i <= end / 6; i++) { _filenums[i] = file->readUint16BE(); _offsets[i] = file->readUint32BE(); } _hasVoiceFile = true; } } if (!_hasVoiceFile) { sprintf(filename, "%s.wav", gss->speech_filename); file->open(filename); if (file->isOpen()) { _hasVoiceFile = true; _voice = new WavSound(_mixer, file); } } const bool dataIsUnsigned = true; if (!_hasVoiceFile) { sprintf(filename, "%s.voc", gss->speech_filename); file->open(filename); if (file->isOpen()) { _hasVoiceFile = true; _voice = new VocSound(_mixer, file, dataIsUnsigned); } } if (!_hasVoiceFile) { sprintf(filename, "%s", gss->speech_filename); file->open(filename); if (file->isOpen()) { _hasVoiceFile = true; if (_vm->getGameType() == GType_PP) _voice = new WavSound(_mixer, file); else _voice = new VocSound(_mixer, file, dataIsUnsigned); } } }
/** * Load _numObj from Hugo.dat */ void ObjectHandler::loadNumObj(Common::File &in) { int numElem; for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { numElem = in.readUint16BE(); if (varnt == _vm->_gameVariant) _numObj = numElem; } }
void loadTextData(const char *pFileName, byte *pDestinationBuffer) { Common::File pFileHandle; uint16 entrySize; uint16 numEntry; uint16 i; byte *tempBuffer; uint16 dataSize; assert(pFileName); assert(pDestinationBuffer); pFileHandle.open(pFileName); assert(pFileHandle.isOpen()); entrySize = pFileHandle.readUint16BE(); numEntry = pFileHandle.readUint16BE(); dataSize = numEntry * entrySize; pFileHandle.read(pDestinationBuffer, numEntry * entrySize); tempBuffer = pDestinationBuffer; if (gameType == Cine::GID_FW) { dataSize = dataSize / 0x4E; loadRelatedPalette(pFileName); for (i = 0; i < 0x4E; i++) { gfxConvertSpriteToRaw(textTable[i][0], tempBuffer, 16, 8); generateMask(textTable[i][0], textTable[i][1], 16 * 8, 0); tempBuffer += dataSize; } } else { for (i = 0; i < 90; i++) { gfxConvertSpriteToRaw(textTable[i][0], tempBuffer, 8, 8); generateMask(textTable[i][0], textTable[i][1], 8 * 8, 0); tempBuffer += 0x40; } } pFileHandle.close(); }
/** * Load phoneme sound file * @remarks Originally called 'charge_phbruit' */ void SpeechManager::loadPhonemeSounds() { Common::File f; if (!f.open("phbrui.mor")) error("Missing file - phbrui.mor"); for (int i = 1; i <= f.size() / 2; ++i) _cfiphBuffer[i] = f.readUint16BE(); f.close(); }
void TopMenu::loadBmpArr(Common::File &in) { arraySize = in.readUint16BE(); delete arrayBmp; arrayBmp = new Graphics::Surface *[arraySize * 2]; for (int i = 0; i < arraySize; i++) { uint16 bmpSize = in.readUint16BE(); uint32 filPos = in.pos(); Common::SeekableSubReadStream stream(&in, filPos, filPos + bmpSize); arrayBmp[i * 2] = Graphics::ImageDecoder::loadFile(stream, g_system->getOverlayFormat()); arrayBmp[i * 2 + 1] = new Graphics::Surface(); arrayBmp[i * 2 + 1]->create(arrayBmp[i * 2]->w * 2, arrayBmp[i * 2]->h * 2, arrayBmp[i * 2]->bytesPerPixel); byte *src = (byte *)arrayBmp[i * 2]->pixels; byte *dst = (byte *)arrayBmp[i * 2 + 1]->pixels; for (int j = 0; j < arrayBmp[i * 2]->h; j++) { src = (byte *)arrayBmp[i * 2]->getBasePtr(0, j); dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); for (int k = arrayBmp[i * 2]->w; k > 0; k--) { for (int m = arrayBmp[i * 2]->bytesPerPixel; m > 0; m--) { *dst++ = *src++; } src -= arrayBmp[i * 2]->bytesPerPixel; for (int m = arrayBmp[i * 2]->bytesPerPixel; m > 0; m--) { *dst++ = *src++; } } src = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2 + 1); for (int k = arrayBmp[i * 2 + 1]->pitch; k > 0; k--) { *dst++ = *src++; } } in.skip(bmpSize); } }
void Sound::loadVoiceFile(const GameSpecificSettings *gss) { // Game versions which use separate voice files if (_hasVoiceFile || _vm->getGameType() == GType_FF || _vm->getGameId() == GID_SIMON1CD32) return; _voice = makeSound(_mixer, gss->speech_filename); _hasVoiceFile = (_voice != 0); if (_hasVoiceFile) return; if (_vm->getGameType() == GType_SIMON2) { // for simon2 mac/amiga, only read index file Common::File file; if (file.open("voices.idx")) { int end = file.size(); _filenums = (uint16 *)malloc((end / 6 + 1) * 2); _offsets = (uint32 *)malloc((end / 6 + 1 + 1) * 4); for (int i = 1; i <= end / 6; i++) { _filenums[i] = file.readUint16BE(); _offsets[i] = file.readUint32BE(); } // We need to add a terminator entry otherwise we get an out of // bounds read when the offset table is accessed in // BaseSound::getSoundStream. _offsets[end / 6 + 1] = 0; _hasVoiceFile = true; return; } } const bool dataIsUnsigned = true; if (Common::File::exists(gss->speech_filename)) { _hasVoiceFile = true; if (_vm->getGameType() == GType_PP) _voice = new WavSound(_mixer, gss->speech_filename); else _voice = new VocSound(_mixer, gss->speech_filename, dataIsUnsigned); } }
/** * Loads Hugo.dat file, which contains all the hardcoded data in the original executables */ bool HugoEngine::loadHugoDat() { Common::File in; in.open("hugo.dat"); if (!in.isOpen()) { Common::String errorMessage = "You're missing the 'hugo.dat' file. Get it from the ScummVM website"; GUIErrorMessage(errorMessage); warning("%s", errorMessage.c_str()); return false; } // Read header char buf[4]; in.read(buf, 4); if (memcmp(buf, "HUGO", 4)) { Common::String errorMessage = "File 'hugo.dat' is corrupt. Get it from the ScummVM website"; GUIErrorMessage(errorMessage); return false; } int majVer = in.readByte(); int minVer = in.readByte(); if ((majVer != HUGO_DAT_VER_MAJ) || (minVer != HUGO_DAT_VER_MIN)) { Common::String errorMessage = Common::String::format("File 'hugo.dat' is wrong version. Expected %d.%d but got %d.%d. Get it from the ScummVM website", HUGO_DAT_VER_MAJ, HUGO_DAT_VER_MIN, majVer, minVer); GUIErrorMessage(errorMessage); return false; } _numVariant = in.readUint16BE(); _screen->loadPalette(in); _screen->loadFontArr(in); _text->loadAllTexts(in); _intro->loadIntroData(in); _parser->loadArrayReqs(in); _parser->loadCatchallList(in); _parser->loadBackgroundObjects(in); _parser->loadCmdList(in); _mouse->loadHotspots(in); _inventory->loadInvent(in); _object->loadObjectUses(in); _object->loadObjectArr(in); _object->loadNumObj(in); _scheduler->loadPoints(in); _scheduler->loadScreenAct(in); _scheduler->loadActListArr(in); _scheduler->loadAlNewscrIndex(in); _hero = &_object->_objects[kHeroIndex]; // This always points to hero _screenPtr = &(_object->_objects[kHeroIndex]._screenIndex); // Current screen is hero's _heroImage = kHeroIndex; // Current in use hero image for (int varnt = 0; varnt < _numVariant; varnt++) { if (varnt == _gameVariant) { _tunesNbr = in.readSByte(); _soundSilence = in.readSByte(); _soundTest = in.readSByte(); } else { in.readSByte(); in.readSByte(); in.readSByte(); } } int numElem; //Read _defltTunes for (int varnt = 0; varnt < _numVariant; varnt++) { numElem = in.readUint16BE(); if (varnt == _gameVariant) { _defltTunes = (int16 *)malloc(sizeof(int16) * numElem); for (int i = 0; i < numElem; i++) _defltTunes[i] = in.readSint16BE(); } else { for (int i = 0; i < numElem; i++) in.readSint16BE(); } } //Read _screenStates size for (int varnt = 0; varnt < _numVariant; varnt++) { numElem = in.readUint16BE(); if (varnt == _gameVariant) { _numStates = numElem; _screenStates = (byte *)malloc(sizeof(byte) * numElem); memset(_screenStates, 0, sizeof(byte) * numElem); } } //Read look, take and drop special verbs indexes for (int varnt = 0; varnt < _numVariant; varnt++) { if (varnt == _gameVariant) { _look = in.readUint16BE(); _take = in.readUint16BE(); _drop = in.readUint16BE(); } else { in.readUint16BE(); in.readUint16BE(); in.readUint16BE(); } } _sound->loadIntroSong(in); _topMenu->loadBmpArr(in); return true; }
bool TonyEngine::loadTonyDat() { Common::String msg; Common::File in; in.open("tony.dat"); if (!in.isOpen()) { msg = "You're missing the 'tony.dat' file. Get it from the ScummVM website"; GUIErrorMessage(msg); warning("%s", msg.c_str()); return false; } // Read header char buf[4+1]; in.read(buf, 4); buf[4] = '\0'; if (strcmp(buf, "TONY")) { msg = "File 'tony.dat' is corrupt. Get it from the ScummVM website"; GUIErrorMessage(msg); warning("%s", msg.c_str()); return false; } int majVer = in.readByte(); int minVer = in.readByte(); if ((majVer != TONY_DAT_VER_MAJ) || (minVer != TONY_DAT_VER_MIN)) { msg = Common::String::format("File 'tony.dat' is wrong version. Expected %d.%d but got %d.%d. Get it from the ScummVM website", TONY_DAT_VER_MAJ, TONY_DAT_VER_MIN, majVer, minVer); GUIErrorMessage(msg); warning("%s", msg.c_str()); return false; } int expectedLangVariant = -1; switch (g_vm->getLanguage()) { case Common::IT_ITA: case Common::EN_ANY: expectedLangVariant = 0; break; case Common::PL_POL: expectedLangVariant = 1; break; case Common::RU_RUS: expectedLangVariant = 2; break; case Common::CZ_CZE: expectedLangVariant = 3; break; case Common::FR_FRA: expectedLangVariant = 4; break; case Common::DE_DEU: expectedLangVariant = 5; break; default: warning("Unhandled language, falling back to English/Italian fonts."); expectedLangVariant = 0; break; } int numVariant = in.readUint16BE(); if (expectedLangVariant > numVariant - 1) { msg = Common::String::format("Font variant not present in 'tony.dat'. Get it from the ScummVM website"); GUIErrorMessage(msg); warning("%s", msg.c_str()); return false; } in.seek(in.pos() + (2 * 256 * 8 * expectedLangVariant)); for (int i = 0; i < 256; i++) { _cTableDialog[i] = in.readSint16BE(); _lTableDialog[i] = in.readSint16BE(); _cTableMacc[i] = in.readSint16BE(); _lTableMacc[i] = in.readSint16BE(); _cTableCred[i] = in.readSint16BE(); _lTableCred[i] = in.readSint16BE(); _cTableObj[i] = in.readSint16BE(); _lTableObj[i] = in.readSint16BE(); } return true; }
bool DrasculaEngine::loadDrasculaDat() { Common::File in; int i; in.open("drascula.dat"); if (!in.isOpen()) { Common::String errorMessage = "You're missing the 'drascula.dat' file. Get it from the ScummVM website"; GUIErrorMessage(errorMessage); warning("%s", errorMessage.c_str()); return false; } char buf[256]; int ver; in.read(buf, 8); buf[8] = '\0'; if (strcmp(buf, "DRASCULA")) { Common::String errorMessage = "File 'drascula.dat' is corrupt. Get it from the ScummVM website"; GUIErrorMessage(errorMessage); warning("%s", errorMessage.c_str()); return false; } ver = in.readByte(); if (ver != DRASCULA_DAT_VER) { snprintf(buf, 256, "File 'drascula.dat' is wrong version. Expected %d but got %d. Get it from the ScummVM website", DRASCULA_DAT_VER, ver); GUIErrorMessage(buf); warning("%s", buf); return false; } _charMapSize = in.readUint16BE(); _charMap = (CharInfo *)malloc(sizeof(CharInfo) * _charMapSize); for (i = 0; i < _charMapSize; i++) { _charMap[i].inChar = in.readByte(); _charMap[i].mappedChar = in.readSint16BE(); _charMap[i].charType = in.readByte(); } _itemLocationsSize = in.readUint16BE(); _itemLocations = (ItemLocation *)malloc(sizeof(ItemLocation) * _itemLocationsSize); for (i = 0; i < _itemLocationsSize; i++) { _itemLocations[i].x = in.readSint16BE(); _itemLocations[i].y = in.readSint16BE(); } _polXSize = in.readUint16BE(); _polX = (int *)malloc(sizeof(int) * _polXSize); _polY = (int *)malloc(sizeof(int) * _polXSize); for (i = 0; i < _polXSize; i++) { _polX[i] = in.readSint16BE(); _polY[i] = in.readSint16BE(); } _verbBarXSize = in.readUint16BE(); _verbBarX = (int *)malloc(sizeof(int) * _verbBarXSize); for (i = 0; i < _verbBarXSize; i++) { _verbBarX[i] = in.readSint16BE(); } _x1dMenuSize = in.readUint16BE(); _x1d_menu = (int *)malloc(sizeof(int) * _x1dMenuSize); _y1d_menu = (int *)malloc(sizeof(int) * _x1dMenuSize); for (i = 0; i < _x1dMenuSize; i++) { _x1d_menu[i] = in.readSint16BE(); _y1d_menu[i] = in.readSint16BE(); } _frameXSize = in.readUint16BE(); _frameX = (int *)malloc(sizeof(int) * _frameXSize); for (i = 0; i < _frameXSize; i++) { _frameX[i] = in.readSint16BE(); } _candleXSize = in.readUint16BE(); _candleX = (int *)malloc(sizeof(int) * _candleXSize); _candleY = (int *)malloc(sizeof(int) * _candleXSize); for (i = 0; i < _candleXSize; i++) { _candleX[i] = in.readSint16BE(); _candleY[i] = in.readSint16BE(); } _pianistXSize = in.readUint16BE(); _pianistX = (int *)malloc(sizeof(int) * _pianistXSize); for (i = 0; i < _pianistXSize; i++) { _pianistX[i] = in.readSint16BE(); } _drunkXSize = in.readUint16BE(); _drunkX = (int *)malloc(sizeof(int) * _drunkXSize); for (i = 0; i < _drunkXSize; i++) { _drunkX[i] = in.readSint16BE(); } _roomPreUpdatesSize = in.readUint16BE(); _roomPreUpdates = (RoomUpdate *)malloc(sizeof(RoomUpdate) * _roomPreUpdatesSize); for (i = 0; i < _roomPreUpdatesSize; i++) { _roomPreUpdates[i].roomNum = in.readSint16BE(); _roomPreUpdates[i].flag = in.readSint16BE(); _roomPreUpdates[i].flagValue = in.readSint16BE(); _roomPreUpdates[i].sourceX = in.readSint16BE(); _roomPreUpdates[i].sourceY = in.readSint16BE(); _roomPreUpdates[i].destX = in.readSint16BE(); _roomPreUpdates[i].destY = in.readSint16BE(); _roomPreUpdates[i].width = in.readSint16BE(); _roomPreUpdates[i].height = in.readSint16BE(); _roomPreUpdates[i].type = in.readSint16BE(); } _roomUpdatesSize = in.readUint16BE(); _roomUpdates = (RoomUpdate *)malloc(sizeof(RoomUpdate) * _roomUpdatesSize); for (i = 0; i < _roomUpdatesSize; i++) { _roomUpdates[i].roomNum = in.readSint16BE(); _roomUpdates[i].flag = in.readSint16BE(); _roomUpdates[i].flagValue = in.readSint16BE(); _roomUpdates[i].sourceX = in.readSint16BE(); _roomUpdates[i].sourceY = in.readSint16BE(); _roomUpdates[i].destX = in.readSint16BE(); _roomUpdates[i].destY = in.readSint16BE(); _roomUpdates[i].width = in.readSint16BE(); _roomUpdates[i].height = in.readSint16BE(); _roomUpdates[i].type = in.readSint16BE(); } _roomActionsSize = in.readUint16BE(); _roomActions = (RoomTalkAction *)malloc(sizeof(RoomTalkAction) * _roomActionsSize); for (i = 0; i < _roomActionsSize; i++) { _roomActions[i].room = in.readSint16BE(); _roomActions[i].chapter = in.readSint16BE(); _roomActions[i].action = in.readSint16BE(); _roomActions[i].objectID = in.readSint16BE(); _roomActions[i].speechID = in.readSint16BE(); } _talkSequencesSize = in.readUint16BE(); _talkSequences = (TalkSequenceCommand *)malloc(sizeof(TalkSequenceCommand) * _talkSequencesSize); for (i = 0; i < _talkSequencesSize; i++) { _talkSequences[i].chapter = in.readSint16BE(); _talkSequences[i].sequence = in.readSint16BE(); _talkSequences[i].commandType = in.readSint16BE(); _talkSequences[i].action = in.readSint16BE(); } _numLangs = in.readUint16BE(); _text = loadTexts(in); _textd = loadTexts(in); _textb = loadTexts(in); _textbj = loadTexts(in); _texte = loadTexts(in); _texti = loadTexts(in); _textl = loadTexts(in); _textp = loadTexts(in); _textt = loadTexts(in); _textvb = loadTexts(in); _textsys = loadTexts(in); _texthis = loadTexts(in); _textverbs = loadTexts(in); _textmisc = loadTexts(in); _textd1 = loadTexts(in); return true; }
void AGOSEngine::loadGamePcFile() { Common::File in; int fileSize; if (getFileName(GAME_BASEFILE) != NULL) { /* Read main gamexx file */ in.open(getFileName(GAME_BASEFILE)); if (in.isOpen() == false) { error("loadGamePcFile: Can't load gamexx file '%s'", getFileName(GAME_BASEFILE)); } if (getFeatures() & GF_CRUNCHED_GAMEPC) { uint srcSize = in.size(); byte *srcBuf = (byte *)malloc(srcSize); in.read(srcBuf, srcSize); uint dstSize = READ_BE_UINT32(srcBuf + srcSize - 4); byte *dstBuf = (byte *)malloc(dstSize); decrunchFile(srcBuf, dstBuf, srcSize); free(srcBuf); Common::MemoryReadStream stream(dstBuf, dstSize); readGamePcFile(&stream); free(dstBuf); } else { readGamePcFile(&in); } in.close(); } if (getFileName(GAME_TBLFILE) != NULL) { /* Read list of TABLE resources */ in.open(getFileName(GAME_TBLFILE)); if (in.isOpen() == false) { error("loadGamePcFile: Can't load table resources file '%s'", getFileName(GAME_TBLFILE)); } fileSize = in.size(); _tblList = (byte *)malloc(fileSize); if (_tblList == NULL) error("loadGamePcFile: Out of memory for strip table list"); in.read(_tblList, fileSize); in.close(); /* Remember the current state */ _subroutineListOrg = _subroutineList; _tablesHeapPtrOrg = _tablesHeapPtr; _tablesHeapCurPosOrg = _tablesHeapCurPos; } if (getFileName(GAME_STRFILE) != NULL) { /* Read list of TEXT resources */ in.open(getFileName(GAME_STRFILE)); if (in.isOpen() == false) error("loadGamePcFile: Can't load text resources file '%s'", getFileName(GAME_STRFILE)); fileSize = in.size(); _strippedTxtMem = (byte *)malloc(fileSize); if (_strippedTxtMem == NULL) error("loadGamePcFile: Out of memory for strip text list"); in.read(_strippedTxtMem, fileSize); in.close(); } if (getFileName(GAME_STATFILE) != NULL) { /* Read list of ROOM STATE resources */ in.open(getFileName(GAME_STATFILE)); if (in.isOpen() == false) { error("loadGamePcFile: Can't load state resources file '%s'", getFileName(GAME_STATFILE)); } _numRoomStates = in.size() / 8; _roomStates = (RoomState *)calloc(_numRoomStates, sizeof(RoomState)); if (_roomStates == NULL) error("loadGamePcFile: Out of memory for room state list"); for (uint s = 0; s < _numRoomStates; s++) { uint16 num = in.readUint16BE() - (_itemArrayInited - 2); _roomStates[num].state = in.readUint16BE(); _roomStates[num].classFlags = in.readUint16BE(); _roomStates[num].roomExitStates = in.readUint16BE(); } in.close(); } if (getFileName(GAME_RMSLFILE) != NULL) { /* Read list of ROOM ITEMS resources */ in.open(getFileName(GAME_RMSLFILE)); if (in.isOpen() == false) { error("loadGamePcFile: Can't load room resources file '%s'", getFileName(GAME_RMSLFILE)); } fileSize = in.size(); _roomsList = (byte *)malloc(fileSize); if (_roomsList == NULL) error("loadGamePcFile: Out of memory for room items list"); in.read(_roomsList, fileSize); in.close(); } if (getFileName(GAME_XTBLFILE) != NULL) { /* Read list of XTABLE resources */ in.open(getFileName(GAME_XTBLFILE)); if (in.isOpen() == false) { error("loadGamePcFile: Can't load xtable resources file '%s'", getFileName(GAME_XTBLFILE)); } fileSize = in.size(); _xtblList = (byte *)malloc(fileSize); if (_xtblList == NULL) error("loadGamePcFile: Out of memory for strip xtable list"); in.read(_xtblList, fileSize); in.close(); /* Remember the current state */ _xsubroutineListOrg = _subroutineList; _xtablesHeapPtrOrg = _tablesHeapPtr; _xtablesHeapCurPosOrg = _tablesHeapCurPos; } }
/** * Load ObjectArr from Hugo.dat */ void ObjectHandler::loadObjectArr(Common::File &in) { debugC(6, kDebugObject, "loadObject(&in)"); for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { uint16 numElem = in.readUint16BE(); if (varnt == _vm->_gameVariant) { _objCount = numElem; _objects = (object_t *)malloc(sizeof(object_t) * numElem); for (int i = 0; i < numElem; i++) { _objects[i].nounIndex = in.readUint16BE(); _objects[i].dataIndex = in.readUint16BE(); uint16 numSubElem = in.readUint16BE(); if (numSubElem == 0) _objects[i].stateDataIndex = 0; else _objects[i].stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem); for (int j = 0; j < numSubElem; j++) _objects[i].stateDataIndex[j] = in.readUint16BE(); _objects[i].pathType = (path_t) in.readSint16BE(); _objects[i].vxPath = in.readSint16BE(); _objects[i].vyPath = in.readSint16BE(); _objects[i].actIndex = in.readUint16BE(); _objects[i].seqNumb = in.readByte(); _objects[i].currImagePtr = 0; if (_objects[i].seqNumb == 0) { _objects[i].seqList[0].imageNbr = 0; _objects[i].seqList[0].seqPtr = 0; } for (int j = 0; j < _objects[i].seqNumb; j++) { _objects[i].seqList[j].imageNbr = in.readUint16BE(); _objects[i].seqList[j].seqPtr = 0; } _objects[i].cycling = (cycle_t)in.readByte(); _objects[i].cycleNumb = in.readByte(); _objects[i].frameInterval = in.readByte(); _objects[i].frameTimer = in.readByte(); _objects[i].radius = in.readByte(); _objects[i].screenIndex = in.readByte(); _objects[i].x = in.readSint16BE(); _objects[i].y = in.readSint16BE(); _objects[i].oldx = in.readSint16BE(); _objects[i].oldy = in.readSint16BE(); _objects[i].vx = in.readByte(); _objects[i].vy = in.readByte(); _objects[i].objValue = in.readByte(); _objects[i].genericCmd = in.readSint16BE(); _objects[i].cmdIndex = in.readUint16BE(); _objects[i].carriedFl = (in.readByte() != 0); _objects[i].state = in.readByte(); _objects[i].verbOnlyFl = (in.readByte() != 0); _objects[i].priority = in.readByte(); _objects[i].viewx = in.readSint16BE(); _objects[i].viewy = in.readSint16BE(); _objects[i].direction = in.readSint16BE(); _objects[i].curSeqNum = in.readByte(); _objects[i].curImageNum = in.readByte(); _objects[i].oldvx = in.readByte(); _objects[i].oldvy = in.readByte(); } } else { for (int i = 0; i < numElem; i++) { in.readUint16BE(); in.readUint16BE(); uint16 numSubElem = in.readUint16BE(); for (int j = 0; j < numSubElem; j++) in.readUint16BE(); in.readSint16BE(); in.readSint16BE(); in.readSint16BE(); in.readUint16BE(); numSubElem = in.readByte(); for (int j = 0; j < numSubElem; j++) in.readUint16BE(); in.readByte(); in.readByte(); in.readByte(); in.readByte(); in.readByte(); in.readByte(); in.readSint16BE(); in.readSint16BE(); in.readSint16BE(); in.readSint16BE(); in.readByte(); in.readByte(); in.readByte(); in.readSint16BE(); in.readUint16BE(); in.readByte(); in.readByte(); in.readByte(); in.readByte(); in.readSint16BE(); in.readSint16BE(); in.readUint16BE(); in.readByte(); in.readByte(); in.readByte(); in.readByte(); } } } }
void MidiMusicPlayer::playSEQ(uint32 size, bool loop) { // MIDI.DAT holds the file names in DW1 PSX Common::String baseName((char *)g_midiBuffer.pDat, size); Common::String seqName = baseName + ".SEQ"; // TODO: Load the instrument bank (<baseName>.VB and <baseName>.VH) Common::File seqFile; if (!seqFile.open(seqName)) error("Failed to open SEQ file '%s'", seqName.c_str()); if (seqFile.readUint32LE() != MKTAG('S', 'E', 'Q', 'p')) error("Failed to find SEQp tag"); // Make sure we don't have a SEP file (with multiple SEQ's inside) if (seqFile.readUint32BE() != 1) error("Can only play SEQ files, not SEP"); uint16 ppqn = seqFile.readUint16BE(); uint32 tempo = seqFile.readUint16BE() << 8; tempo |= seqFile.readByte(); /* uint16 beat = */ seqFile.readUint16BE(); // SEQ is directly based on SMF and we'll use that to our advantage here // and convert to SMF and then use the SMF MidiParser. // Calculate the SMF size we'll need uint32 dataSize = seqFile.size() - 15; uint32 actualSize = dataSize + 7 + 22; // Resize the buffer if necessary if (g_midiBuffer.size < actualSize) { g_midiBuffer.pDat = (byte *)realloc(g_midiBuffer.pDat, actualSize); assert(g_midiBuffer.pDat); } // Now construct the header WRITE_BE_UINT32(g_midiBuffer.pDat, MKTAG('M', 'T', 'h', 'd')); WRITE_BE_UINT32(g_midiBuffer.pDat + 4, 6); // header size WRITE_BE_UINT16(g_midiBuffer.pDat + 8, 0); // type 0 WRITE_BE_UINT16(g_midiBuffer.pDat + 10, 1); // one track WRITE_BE_UINT16(g_midiBuffer.pDat + 12, ppqn); WRITE_BE_UINT32(g_midiBuffer.pDat + 14, MKTAG('M', 'T', 'r', 'k')); WRITE_BE_UINT32(g_midiBuffer.pDat + 18, dataSize + 7); // SEQ data size + tempo change event size // Add in a fake tempo change event WRITE_BE_UINT32(g_midiBuffer.pDat + 22, 0x00FF5103); // no delta, meta event, tempo change, param size = 3 WRITE_BE_UINT16(g_midiBuffer.pDat + 26, tempo >> 8); g_midiBuffer.pDat[28] = tempo & 0xFF; // Now copy in the rest of the events seqFile.read(g_midiBuffer.pDat + 29, dataSize); seqFile.close(); MidiParser *parser = MidiParser::createParser_SMF(); if (parser->loadMusic(g_midiBuffer.pDat, actualSize)) { parser->setTrack(0); parser->setMidiDriver(this); parser->setTimerRate(getBaseTempo()); parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1); parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1); _parser = parser; _isLooping = loop; _isPlaying = true; } else { delete parser; } }