bool Player_V5M::loadMusic(const byte *ptr) { Common::MacResManager resource; bool found = false; uint i; for (i = 0; i < ARRAYSIZE(monkeyIslandFileNames); i++) { if (resource.open(monkeyIslandFileNames[i])) { found = true; break; } } if (!found) { return false; } ptr += 8; // TODO: Decipher the unknown bytes in the header. For now, skip 'em ptr += 28; Common::MacResIDArray idArray = resource.getResIDArray(RES_SND); // Load the three channels and their instruments for (i = 0; i < 3; i++) { assert(READ_BE_UINT32(ptr) == MKTAG('C', 'h', 'a', 'n')); uint32 len = READ_BE_UINT32(ptr + 4); uint32 instrument = READ_BE_UINT32(ptr + 8); _channel[i]._length = len - 20; _channel[i]._data = ptr + 12; _channel[i]._looped = (READ_BE_UINT32(ptr + len - 8) == MKTAG('L', 'o', 'o', 'p')); _channel[i]._pos = 0; _channel[i]._pitchModifier = 0; _channel[i]._velocity = 0; _channel[i]._remaining = 0; _channel[i]._notesLeft = true; for (uint j = 0; j < idArray.size(); j++) { Common::String name = resource.getResName(RES_SND, idArray[j]); if (instrument == READ_BE_UINT32(name.c_str())) { debug(6, "Player_V5M::loadMusic: Channel %d: Loading instrument '%s'", i, name.c_str()); Common::SeekableReadStream *stream = resource.getResource(RES_SND, idArray[j]); if (!_channel[i].loadInstrument(stream)) { resource.close(); return false; } break; } } ptr += len; } resource.close(); // The last note of each channel is just zeroes. We will adjust this // note so that all the channels end at the same time. uint32 samples[3]; uint32 maxSamples = 0; for (i = 0; i < 3; i++) { samples[i] = 0; for (uint j = 0; j < _channel[i]._length; j += 4) { samples[i] += durationToSamples(READ_BE_UINT16(&_channel[i]._data[j])); } if (samples[i] > maxSamples) { maxSamples = samples[i]; } } for (i = 0; i < 3; i++) { _lastNoteSamples[i] = maxSamples - samples[i]; } return true; }
bool World::loadWorld(Common::MacResManager *resMan) { Common::MacResIDArray resArray; Common::SeekableReadStream *res; Common::MacResIDArray::const_iterator iter; // Dumping interpreter code #if 1 res = resMan->getResource(MKTAG('C','O','D','E'), 1); warning("code size: %d", res->size()); byte *buf = (byte *)malloc(res->size()); res->read(buf, res->size()); Common::DumpFile out; out.open("code.bin"); out.write(buf, res->size()); out.close(); free(buf); delete res; #endif if ((resArray = resMan->getResIDArray(MKTAG('G','C','O','D'))).size() == 0) return false; // Load global script res = resMan->getResource(MKTAG('G','C','O','D'), resArray[0]); _globalScript = new Script(res); // TODO: read creator // Load main configuration if ((resArray = resMan->getResIDArray(MKTAG('V','E','R','S'))).size() == 0) return false; _name = resMan->getBaseFileName(); if (resArray.size() > 1) warning("Too many VERS resources"); if (!resArray.empty()) { debug(3, "Loading version info"); res = resMan->getResource(MKTAG('V','E','R','S'), resArray[0]); res->skip(10); byte b = res->readByte(); _weaponMenuDisabled = (b != 0); if (b != 0 && b != 1) error("Unexpected value for weapons menu"); res->skip(3); _aboutMessage = readPascalString(res); if (!scumm_stricmp(resMan->getBaseFileName().c_str(), "Scepters")) res->skip(1); // ???? _soundLibrary1 = readPascalString(res); _soundLibrary2 = readPascalString(res); delete res; } Common::String *message; if ((message = loadStringFromDITL(resMan, 2910, 1)) != NULL) { message->trim(); debug(2, "_gameOverMessage: %s", message->c_str()); _gameOverMessage = message; } if ((message = loadStringFromDITL(resMan, 2480, 3)) != NULL) { message->trim(); debug(2, "_saveBeforeQuitMessage: %s", message->c_str()); _saveBeforeQuitMessage = message; } if ((message = loadStringFromDITL(resMan, 2490, 3)) != NULL) { message->trim(); debug(2, "_saveBeforeCloseMessage: %s", message->c_str()); _saveBeforeCloseMessage = message; } if ((message = loadStringFromDITL(resMan, 2940, 2)) != NULL) { message->trim(); debug(2, "_revertMessage: %s", message->c_str()); _revertMessage = message; } // Load scenes resArray = resMan->getResIDArray(MKTAG('A','S','C','N')); debug(3, "Loading %d scenes", resArray.size()); for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource(MKTAG('A','S','C','N'), *iter); Scene *scene = new Scene(resMan->getResName(MKTAG('A','S','C','N'), *iter), res); res = resMan->getResource(MKTAG('A','C','O','D'), *iter); if (res != NULL) scene->_script = new Script(res); res = resMan->getResource(MKTAG('A','T','X','T'), *iter); if (res != NULL) { scene->_textBounds = readRect(res); scene->_fontType = res->readUint16BE(); scene->_fontSize = res->readUint16BE(); Common::String text; while (res->pos() < res->size()) { char c = res->readByte(); if (c == 0x0d) c = '\n'; text += c; } scene->_text = text; delete res; } addScene(scene); } // Load Objects resArray = resMan->getResIDArray(MKTAG('A','O','B','J')); debug(3, "Loading %d objects", resArray.size()); for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource(MKTAG('A','O','B','J'), *iter); addObj(new Obj(resMan->getResName(MKTAG('A','O','B','J'), *iter), res)); } // Load Characters resArray = resMan->getResIDArray(MKTAG('A','C','H','R')); debug(3, "Loading %d characters", resArray.size()); for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource(MKTAG('A','C','H','R'), *iter); Chr *chr = new Chr(resMan->getResName(MKTAG('A','C','H','R'), *iter), res); addChr(chr); // TODO: What if there's more than one player character? if (chr->_playerCharacter) _player = chr; } // Load Sounds resArray = resMan->getResIDArray(MKTAG('A','S','N','D')); debug(3, "Loading %d sounds", resArray.size()); for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource(MKTAG('A','S','N','D'), *iter); addSound(new Sound(resMan->getResName(MKTAG('A','S','N','D'), *iter), res)); } if (!_soundLibrary1.empty()) { loadExternalSounds(_soundLibrary1); } if (!_soundLibrary2.empty()) { loadExternalSounds(_soundLibrary2); } // Load Patterns res = resMan->getResource(MKTAG('P','A','T','#'), 900); if (res != NULL) { int count = res->readUint16BE(); debug(3, "Loading %d patterns", count); for (int i = 0; i < count; i++) { byte *pattern = (byte *)malloc(8); res->read(pattern, 8); _patterns->push_back(pattern); } delete res; } else { /* Enchanted Scepters did not use the PAT# resource for the textures. */ res = resMan->getResource(MKTAG('C','O','D','E'), 1); if (res != NULL) { res->skip(0x55ac); for (int i = 0; i < 29; i++) { byte *pattern = (byte *)malloc(8); res->read(pattern, 8); _patterns->push_back(pattern); } } delete res; } res = resMan->getResource(MKTAG('M','E','N','U'), 2001); if (res != NULL) { Common::StringArray *menu = readMenu(res); _aboutMenuItemName.clear(); Common::String string = menu->operator[](1); for (uint i = 0; i < string.size() && string[i] != ';'; i++) // Read token _aboutMenuItemName += string[i]; delete menu; delete res; } res = resMan->getResource(MKTAG('M','E','N','U'), 2004); if (res != NULL) { Common::StringArray *menu = readMenu(res); _commandsMenuName = menu->operator[](0); _commandsMenu = menu->operator[](1); delete menu; delete res; } res = resMan->getResource(MKTAG('M','E','N','U'), 2005); if (res != NULL) { Common::StringArray *menu = readMenu(res); _weaponsMenuName = menu->operator[](0); delete menu; delete res; } // TODO: Read Apple menu and get the name of that menu item.. // store global info in state object for use with save/load actions //world.setCurrentState(initialState); // pass off the state object to the world return true; }
void MacFontManager::loadFonts() { Common::Archive *dat; dat = Common::makeZipArchive("classicmacfonts.dat"); if (!dat) { warning("Could not find classicmacfonts.dat. Falling back to built-in fonts"); _builtInFonts = true; return; } Common::ArchiveMemberList list; dat->listMembers(list); for (Common::ArchiveMemberList::iterator it = list.begin(); it != list.end(); ++it) { Common::SeekableReadStream *stream = dat->createReadStreamForMember((*it)->getName()); Common::MacResManager *fontFile = new Common::MacResManager(); if (!fontFile->loadFromMacBinary(*stream)) continue; Common::MacResIDArray fonds = fontFile->getResIDArray(MKTAG('F','O','N','D')); if (fonds.size() > 0) { for (Common::Array<uint16>::iterator iterator = fonds.begin(); iterator != fonds.end(); ++iterator) { Common::SeekableReadStream *fond = fontFile->getResource(MKTAG('F', 'O', 'N', 'D'), *iterator); Common::String familyName = fontFile->getResName(MKTAG('F', 'O', 'N', 'D'), *iterator); Graphics::MacFontFamily *fontFamily = new MacFontFamily(); fontFamily->load(*fond); Common::Array<Graphics::MacFontFamily::AsscEntry> *assoc = fontFamily->getAssocTable(); for (uint i = 0; i < assoc->size(); i++) { debug("size: %d style: %d id: %d", (*assoc)[i]._fontSize, (*assoc)[i]._fontStyle, (*assoc)[i]._fontID); Common::SeekableReadStream *fontstream; MacFont *macfont; Graphics::MacFONTFont *font; fontstream = fontFile->getResource(MKTAG('N', 'F', 'N', 'T'), (*assoc)[i]._fontID); if (!fontstream) fontstream = fontFile->getResource(MKTAG('F', 'O', 'N', 'T'), (*assoc)[i]._fontID); if (!fontstream) { warning("Unknown FontId: %d", (*assoc)[i]._fontID); continue; } font = new Graphics::MacFONTFont; font->loadFont(*fontstream, fontFamily, (*assoc)[i]._fontSize, (*assoc)[i]._fontStyle); delete fontstream; Common::String fontName = Common::String::format("%s-%d-%d", familyName.c_str(), (*assoc)[i]._fontStyle, (*assoc)[i]._fontSize); macfont = new MacFont(_fontNames.getVal(familyName, kMacFontNonStandard), (*assoc)[i]._fontSize, (*assoc)[i]._fontStyle); FontMan.assignFontToName(fontName, font); macfont->setFont(font); _fontRegistry.setVal(fontName, macfont); debug(2, " %s", fontName.c_str()); } delete fond; } } delete fontFile; } _builtInFonts = false; delete dat; }