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; }
void Sound::playSpeech(const Common::String &name) { Resources &res = *_vm->_res; Scene &scene = *_vm->_scene; stopSpeech(); // TODO: Technically Scalpel has an sfx command which I've set to call this method because it sets the // _voice variable as if it were speech. Need to do a play-through of Scalpel and see if it's ever called. // If so, will need to enhance this method to handle the Serrated Scalpel voice resources assert(IS_ROSE_TATTOO); // Figure out which speech library to use Common::String libraryName = Common::String::format("speech%02d.lib", scene._currentScene); if ((!scumm_strnicmp(name.c_str(), "SLVE12S", 7)) || (!scumm_strnicmp(name.c_str(), "WATS12X", 7)) || (!scumm_strnicmp(name.c_str(), "HOLM12X", 7))) libraryName = "SPEECH12.LIB"; // If the speech library file doesn't even exist, then we can't play anything Common::File f; if (!f.exists(libraryName)) return; // Ensure the given library is in the cache res.addToCache(libraryName); if (playSoundResource(name, libraryName, Audio::Mixer::kSpeechSoundType, _speechHandle)) _speechPlaying = true; }
bool TeenAgentEngine::showCDLogo() { Common::File cdlogo; if (!cdlogo.exists("cdlogo.res") || !cdlogo.open("cdlogo.res")) return true; byte bg[0xfa00]; byte palette[3*256]; cdlogo.read(bg, sizeof(bg)); cdlogo.read(palette, sizeof(palette)); for (uint c = 0; c < 3*256; ++c) palette[c] *= 4; _system->getPaletteManager()->setPalette(palette, 0, 0x100); _system->copyRectToScreen(bg, 320, 0, 0, 320, 200); _system->updateScreen(); for(uint i = 0; i < 20; ++i) { int r = skipEvents(); if (r != 0) return r > 0? true: false; _system->delayMillis(100); } cdlogo.close(); return true; }
bool TeenAgentEngine::showCDLogo() { Common::File cdlogo; if (!cdlogo.exists("cdlogo.res") || !cdlogo.open("cdlogo.res")) return true; byte bg[0xfa00]; byte palette[0x400]; cdlogo.read(bg, sizeof(bg)); memset(palette, 0, sizeof(palette)); for(uint c = 0; c < 0x100; ++c) { uint idx = c * 4; cdlogo.read(palette + idx, 3); palette[idx] *= 4; palette[idx + 1] *= 4; palette[idx + 2] *= 4; } _system->setPalette(palette, 0, 0x100); _system->copyRectToScreen(bg, 320, 0, 0, 320, 200); _system->updateScreen(); for(uint i = 0; i < 20; ++i) { int r = skipEvents(); if (r != 0) return r > 0? true: false; _system->delayMillis(100); } cdlogo.close(); return true; }
bool FileSystemUtil::fileExists(const Common::String &filename) { Common::File f; if (f.exists(filename)) return true; // Check if the file exists in the save folder Common::FSNode folder(PersistenceService::getSavegameDirectory()); Common::FSNode fileNode = folder.getChild(getPathFilename(filename)); return fileNode.exists(); }
bool Debugger::Cmd_PlayText(int argc, const char **argv) { if (argc != 2) { debugPrintf("Usage: %s <text name>\n", argv[0]); return true; } else { Common::String resName = argv[1]; if (resName.hasPrefix("@")) resName.deleteChar(0); Common::File f; if (f.exists(resName) || f.exists(resName + ".txr")) { TextView::execute(_vm, resName); return false; } else { debugPrintf("Could not find resource file\n"); return true; } } }
/** * Load Animation */ void AnimationManager::loadAnim(const Common::String &animName) { clearAnim(); Common::String filename = animName + ".ANI"; Common::File f; if (!f.open(filename)) error("Failed to open %s", filename.c_str()); int filesize = f.size(); int nbytes = filesize - 115; char header[10]; char dummyBuf[15]; char filename1[15]; char filename2[15]; char filename3[15]; char filename4[15]; char filename5[15]; char filename6[15]; f.read(header, 10); f.read(dummyBuf, 15); f.read(filename1, 15); f.read(filename2, 15); f.read(filename3, 15); f.read(filename4, 15); f.read(filename5, 15); f.read(filename6, 15); if (READ_BE_UINT32(header) != MKTAG('A', 'N', 'I', 'S')) error("Invalid animation File: %s", filename.c_str()); const char *files[6] = { &filename1[0], &filename2[0], &filename3[0], &filename4[0], &filename5[0], &filename6[0] }; for (int idx = 0; idx <= 5; ++idx) { if (files[idx][0]) { if (!f.exists(files[idx])) error("Missing file %s in animation File: %s", files[idx], filename.c_str()); if (loadSpriteBank(idx + 1, files[idx])) error("Invalid sprite bank in animation File: %s", filename.c_str()); } } byte *data = _vm->_globals->allocMemory(nbytes + 1); f.read(data, nbytes); f.close(); for (int idx = 1; idx <= 20; ++idx) searchAnim(data, idx, nbytes); _vm->_globals->freeMemory(data); }
CString CResourceKey::exists() const { CString name = _key; // Check for a resource being specified within an ST container int idx = name.indexOf('#'); if (idx >= 0) { name = name.left(idx); name += ".st"; } // The original did tests for the file in the different // asset paths, which aren't needed in ScummVM Common::File f; return f.exists(name) ? name : CString(); }
void SherlockEngine::initialize() { DebugMan.addDebugChannel(kDebugLevelScript, "scripts", "Script debug level"); DebugMan.addDebugChannel(kDebugLevelAdLibDriver, "AdLib", "AdLib driver debugging"); DebugMan.addDebugChannel(kDebugLevelMT32Driver, "MT32", "MT32 driver debugging"); DebugMan.addDebugChannel(kDebugLevelMusic, "Music", "Music debugging"); Fonts::setVm(this); ImageFile::setVm(this); ImageFile3DO::setVm(this); BaseObject::setVm(this); if (isDemo()) { Common::File f; // The interactive demo doesn't have an intro thus doesn't include TITLE.SND // At the opposite, the non-interactive demo is only the intro. if (f.exists("TITLE.SND")) _interactiveFl = false; } _res = new Resources(this); _animation = new Animation(this); _debugger = Debugger::init(this); _events = new Events(this); _fixedText = FixedText::init(this); _inventory = Inventory::init(this); _map = Map::init(this); _music = new Music(this, _mixer); _journal = Journal::init(this); _people = People::init(this); _saves = SaveManager::init(this, _targetName); _scene = Scene::init(this); _screen = Screen::init(this); _sound = new Sound(this, _mixer); _talk = Talk::init(this); _ui = UserInterface::init(this); // Load game settings loadConfig(); if (getPlatform() == Common::kPlatform3DO) { // Disable portraits on 3DO // 3DO does not include portrait data _people->_portraitsOn = false; } }
FileManager::FileManager(XeenEngine *vm) { Common::File f; int sideNum = 0; File::_currentArchive = ANY_ARCHIVE; _isDarkCc = vm->getGameID() == GType_DarkSide; _archives[0] = _archives[1] = _archives[2] = nullptr; if (vm->getGameID() != GType_DarkSide) { _archives[0] = new CCArchive("xeen.cc", "xeen", true); SearchMan.add("xeen", _archives[0]); sideNum = 1; } if (vm->getGameID() == GType_DarkSide || vm->getGameID() == GType_WorldOfXeen) { _archives[sideNum] = new CCArchive("dark.cc", "dark", true); SearchMan.add("dark", _archives[sideNum]); } if (f.exists("intro.cc")) { _archives[2] = new CCArchive("intro.cc", "intro", true); SearchMan.add("intro", _archives[2]); } }
bool CFilesManager::fileExists(const CString &name) { Common::File f; return f.exists(name); }
bool Resources::exists(const Common::String &filename) const { Common::File f; return f.exists(filename) || _cache.isCached(filename); }
bool FileManager::existFile(const Common::String &filename) { Common::File f; return f.exists(filename); }
/** * Load Sprite Bank */ int AnimationManager::loadSpriteBank(int idx, const Common::String &filename) { int result = 0; Bank[idx]._loadedFl = true; Bank[idx]._filename = filename; byte *fileDataPtr = _vm->_fileIO->loadFile(filename); Bank[idx]._fileHeader = 0; if (fileDataPtr[1] == 'L' && fileDataPtr[2] == 'E') Bank[idx]._fileHeader = 1; else if (fileDataPtr[1] == 'O' && fileDataPtr[2] == 'R') Bank[idx]._fileHeader = 2; if (!Bank[idx]._fileHeader) { _vm->_globals->freeMemory(fileDataPtr); Bank[idx]._loadedFl = false; result = -1; } Bank[idx]._data = fileDataPtr; int objectDataIdx = 0; for(objectDataIdx = 0; objectDataIdx <= 249; objectDataIdx++) { int width = _vm->_objectsMan->getWidth(fileDataPtr, objectDataIdx); int height = _vm->_objectsMan->getHeight(fileDataPtr, objectDataIdx); if (!width && !height) break; } if (objectDataIdx > 249) { _vm->_globals->freeMemory(fileDataPtr); Bank[idx]._loadedFl = false; result = -2; } Bank[idx]._objDataIdx = objectDataIdx; Common::String ofsFilename = Bank[idx]._filename; char ch; do { ch = ofsFilename.lastChar(); ofsFilename.deleteLastChar(); } while (ch != '.'); ofsFilename += ".OFS"; Common::File f; if (f.exists(ofsFilename)) { byte *ofsData = _vm->_fileIO->loadFile(ofsFilename); byte *curOfsData = ofsData; for (int objIdx = 0; objIdx < Bank[idx]._objDataIdx; ++objIdx, curOfsData += 8) { int x1 = READ_LE_INT16(curOfsData); int y1 = READ_LE_INT16(curOfsData + 2); int x2 = READ_LE_INT16(curOfsData + 4); int y2 = READ_LE_INT16(curOfsData + 6); _vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x1, y1, 0); if (Bank[idx]._fileHeader == 2) _vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x2, y2, 1); } _vm->_globals->freeMemory(ofsData); result = 0; } return result; }
/** * Check if a file is present */ bool FileManager::fileExists(const Common::String &file) { Common::File f; return f.exists(file); }
/** * Search file in Cat file */ byte *FileManager::searchCat(const Common::String &file, CatMode mode, bool &fileFoundFl) { byte *ptr = NULL; fileFoundFl = true; Common::File f; Common::String filename = file; Common::String secondaryFilename = ""; filename.toUppercase(); switch (mode) { case RES_INI: if (!f.exists("RES_INI.CAT")) { fileFoundFl = false; return NULL; } ptr = loadFile("RES_INI.CAT"); secondaryFilename = "RES_INI.RES"; break; case RES_REP: if (!f.exists("RES_REP.CAT")) { fileFoundFl = false; return NULL; } ptr = loadFile("RES_REP.CAT"); secondaryFilename = "RES_REP.RES"; break; case RES_LIN: if (!f.exists("RES_LIN.CAT")) { fileFoundFl = false; return NULL; } ptr = loadFile("RES_LIN.CAT"); secondaryFilename = "RES_LIN.RES"; break; case RES_PER: if (!f.exists("RES_PER.CAT")) { fileFoundFl = false; return NULL; } ptr = loadFile("RES_PER.CAT"); secondaryFilename = "RES_PER.RES"; break; case RES_PIC: if (!f.exists("PIC.CAT")) { fileFoundFl = false; return NULL; } ptr = loadFile("PIC.CAT"); break; case RES_SAN: if (!f.exists("RES_SAN.CAT")) { fileFoundFl = false; return NULL; } ptr = loadFile("RES_SAN.CAT"); break; case RES_SLI: if (!f.exists("RES_SLI.CAT")) { fileFoundFl = false; return NULL; } ptr = loadFile("RES_SLI.CAT"); break; case RES_VOI: { Common::String tmpFilename; if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS) tmpFilename = "ENG_VOI.CAT"; // Win95 and Linux versions uses another set of names else { switch (_vm->_globals->_language) { case LANG_EN: tmpFilename = "RES_VAN.CAT"; break; case LANG_FR: tmpFilename = "RES_VFR.CAT"; break; case LANG_SP: tmpFilename = "RES_VES.CAT"; break; } } if (!f.exists(tmpFilename)) { fileFoundFl = false; return NULL; } ptr = loadFile(tmpFilename); break; } default: break; } // Scan for an entry in the catalogue byte *result; bool matchFlag = false; int offsetVal = 0; while (!matchFlag) { Common::String name = (const char *)ptr + offsetVal; if (name == filename) { // Found entry for file, so get it's details from the catalogue entry const byte *pData = ptr + offsetVal; _catalogPos = READ_LE_UINT32(pData + 15); _catalogSize = READ_LE_UINT32(pData + 19); matchFlag = true; } if (name == "FINIS") { _vm->_globals->freeMemory(ptr); fileFoundFl = false; return NULL; } offsetVal += 23; } _vm->_globals->freeMemory(ptr); if (secondaryFilename != "") { if (!f.open(secondaryFilename)) error("CHARGE_FICHIER"); f.seek(_catalogPos); byte *catData = _vm->_globals->allocMemory(_catalogSize); if (catData == g_PTRNUL) error("CHARGE_FICHIER"); readStream(f, catData, _catalogSize); f.close(); result = catData; } else { result = NULL; } return result; }
MidiMusicPlayer::MidiMusicPlayer(TinselEngine *vm) { _driver = NULL; _milesAudioMode = false; bool milesAudioEnabled = false; if (vm->getPlatform() == Common::kPlatformDOS) { // Enable Miles Audio for DOS platform only... switch (vm->getGameID()) { case GID_DW1: if (!vm->getIsADGFDemo()) { // ...for Discworld 1 milesAudioEnabled = true; } else { if (vm->isV1CD()) { // ...and for Discworld 1 CD Demo milesAudioEnabled = true; } } break; default: break; } } if (milesAudioEnabled) { // Discworld 1 (DOS) uses Miles Audio 3 // use our own Miles Audio drivers // // It seems that there are multiple versions of Discworld 1 // // Version 1: // Has SAMPLE.AD for AdLib and SAMPLE.OPL for OPL-3 // Timbre files are inside a subdirectory of the CD called "/drivers". Main game files are in // another subdirectory, which means the user has to copy those files over. // Installer script copies all drivers directly to harddrive without name changes // // Version 2: // Has FAT.OPL only (gets copied by the installer into MIDPAK.AD or MIDPAK.OPL) // Timbre file is inside subdirectory "drivers" right in the main game directory. // Installer copies FAT.OPL to MIDPAK.AD all the time, even when user selected AWE32 // // Neither have timbre data for MT32 ::MidiDriver::DeviceHandle dev = ::MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM); ::MusicType musicType = ::MidiDriver::getMusicType(dev); Common::File fileClass; switch (musicType) { case MT_ADLIB: if (fileClass.exists("FAT.OPL")) { // Version 2: fat.opl, may be in drivers-subdirectory _driver = Audio::MidiDriver_Miles_AdLib_create("", "FAT.OPL"); } else { if (fileClass.exists("MIDPAK.AD")) { // Version 2: drivers got installed and fat.opl got copied over by the user _driver = Audio::MidiDriver_Miles_AdLib_create("MIDPAK.AD", ""); } else { if ((fileClass.exists("SAMPLE.AD")) || (fileClass.exists("SAMPLE.OPL"))) { // Version 1: sample.ad / sample.opl, have to be copied over by the user for this version _driver = Audio::MidiDriver_Miles_AdLib_create("SAMPLE.AD", "SAMPLE.OPL"); } else { error("MILES-ADLIB: timbre file not found (may be called FAT.OPL, MIDPAK.AD, SAMPLE.AD or SAMPLE.OPL, may be in a subdirectory)"); } } } break; case MT_MT32: // Discworld 1 doesn't have a MT32 timbre file _driver = Audio::MidiDriver_Miles_MT32_create(""); break; case MT_GM: if (ConfMan.getBool("native_mt32")) { _driver = Audio::MidiDriver_Miles_MT32_create(""); musicType = MT_MT32; } break; default: break; } if (!_driver) { // nothing got created yet? -> create default driver MidiPlayer::createDriver(); } else { _milesAudioMode = true; } } else { MidiPlayer::createDriver(); } int ret = _driver->open(); if (ret == 0) { if (_nativeMT32) _driver->sendMT32Reset(); else _driver->sendGMReset(); _driver->setTimerCallback(this, &timerCallback); } }