bool Console::Cmd_DumpArchive(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Extract all the files from a game archive.\n"); DebugPrintf("The destination folder, named 'dump', must exist.\n"); DebugPrintf("Usage :\n"); DebugPrintf("dumpArchive [file name]\n"); return true; } // Is the archive multi-room Common::String temp = Common::String(argv[1]); temp.toUppercase(); bool multiRoom = !temp.hasSuffix(".M3A"); if (!multiRoom) { temp = Common::String(argv[1], 4); temp.toUppercase(); } Archive archive; if (!archive.open(argv[1], multiRoom ? 0 : temp.c_str())) { DebugPrintf("Can't open archive with name '%s'\n", argv[1]); return true; } archive.dumpToFiles(); archive.close(); return true; }
bool PackageSet::hasFile(const Common::String &name) const { Common::String upcName = name; upcName.toUppercase(); Common::HashMap<Common::String, Common::ArchiveMemberPtr>::const_iterator it; it = _files.find(upcName.c_str()); return (it != _files.end()); }
void Menu::handleInput(const Common::KeyState &e) { uint16 node = _vm->_state->getLocationNode(); uint16 room = _vm->_state->getLocationRoom(); uint16 item = _vm->_state->getMenuSaveLoadSelectedItem(); if (room != 901 || node != 300 || item != 7) return; Common::String display = prepareSaveNameForDisplay(_saveName); if (e.keycode == Common::KEYCODE_BACKSPACE || e.keycode == Common::KEYCODE_DELETE) { display.deleteLastChar(); _saveName = display; return; } else if (e.keycode == Common::KEYCODE_RETURN || e.keycode == Common::KEYCODE_KP_ENTER) { saveMenuSave(); return; } if (((e.ascii >= 'a' && e.ascii <= 'z') || (e.ascii >= 'A' && e.ascii <= 'Z') || (e.ascii >= '0' && e.ascii <= '9') || e.ascii == ' ') && (display.size() < 17)) { display += e.ascii; display.toUppercase(); _saveName = display; } }
const Common::ArchiveMemberPtr PackageSet::getMember(const Common::String &name) const { Common::String upcName = name; upcName.toUppercase(); Common::HashMap<Common::String, Common::ArchiveMemberPtr>::const_iterator it; it = _files.find(upcName.c_str()); return Common::ArchiveMemberPtr(it->_value); }
const uint32 *TlkArchive::findFile(const Common::String &name) const { Common::String uppercaseName = name; uppercaseName.toUppercase(); if (!uppercaseName.hasSuffix(".AUD")) return 0; uint32 id; if (sscanf(uppercaseName.c_str(), "%08u.AUD", &id) != 1) return 0; // Binary search for the file entry int leftIndex = 0; int rightIndex = _entryCount - 1; while (leftIndex <= rightIndex) { int mid = (leftIndex + rightIndex) / 2; const uint32 key = _fileEntries[mid * 2]; if (key == id) { // Found return &_fileEntries[mid * 2]; } else if (key > id) { // Take the left sub-tree rightIndex = mid - 1; } else { // Take the right sub-tree leftIndex = mid + 1; } } return 0; }
bool Debugger::Cmd_DumpItems(int argc, const char **argv) { InventoryObjects &objects = _vm->_game->_objects; Common::DumpFile outFile; outFile.open("items.txt"); for (uint32 i = 0; i < objects.size(); i++) { Common::String curId = Common::String::format("%d", i); Common::String desc = _vm->_game->_scene.getVocab(objects[i]._descId); desc.toUppercase(); for (uint j = 0; j < desc.size(); j++) { if (desc[j] == ' ' || desc[j] == '-') desc.setChar('_', j); } Common::String cur = "\tOBJ_" + desc + " = " + curId + ",\n"; outFile.writeString(cur.c_str()); } outFile.flush(); outFile.close(); debugPrintf("Game items dumped\n"); return true; }
bool Debugger::Cmd_DumpVocab(int argc, const char **argv) { Common::DumpFile outFile; outFile.open("vocab.txt"); for (uint32 i = 0; i < _vm->_game->_scene.getVocabStringsCount(); i++) { Common::String curId = Common::String::format("%x", i + 1); Common::String curVocab = _vm->_game->_scene.getVocab(i + 1); curVocab.toUppercase(); for (uint j = 0; j < curVocab.size(); j++) { if (curVocab[j] == ' ' || curVocab[j] == '-') curVocab.setChar('_', j); } Common::String cur = "\tNOUN_" + curVocab + " = 0x" + curId + ",\n"; outFile.writeString(cur.c_str()); } outFile.flush(); outFile.close(); debugPrintf("Game vocab dumped\n"); return true; }
bool Resource::loadPakFile(Common::String filename) { filename.toUppercase(); Common::ArchiveMemberPtr file = _files.getMember(filename); if (!file) return false; return loadPakFile(filename, file); }
Common::SeekableReadStream *PackageSet::createReadStreamForMember(const Common::String &name) const { Common::String upcName = name; upcName.toUppercase(); Common::HashMap<Common::String, Common::ArchiveMemberPtr>::const_iterator it; it = _files.find(upcName.c_str()); if (it != _files.end()) { return it->_value->createReadStream(); } return nullptr; }
SaveStateList AvalancheMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::StringArray filenames; Common::String pattern = target; pattern.toUppercase(); pattern += ".???"; filenames = saveFileMan->listSavefiles(pattern); sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) SaveStateList saveList; for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) { const Common::String &fname = *filename; int slotNum = atoi(fname.c_str() + fname.size() - 3); if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) { Common::InSaveFile *file = saveFileMan->openForLoading(fname); if (file) { // Check for our signature. uint32 signature = file->readUint32LE(); if (signature != MKTAG('A', 'V', 'A', 'L')) { warning("Savegame of incompatible type!"); delete file; continue; } // Check version. byte saveVersion = file->readByte(); if (saveVersion != kSavegameVersion) { warning("Savegame of incompatible version!"); delete file; continue; } // Read name. uint32 nameSize = file->readUint32LE(); if (nameSize >= 255) { delete file; continue; } char *name = new char[nameSize + 1]; file->read(name, nameSize); name[nameSize] = 0; saveList.push_back(SaveStateDescriptor(slotNum, name)); delete[] name; delete file; } } } return saveList; }
int MacFontManager::parseFontSlant(Common::String slant) { slant.toUppercase(); int slantVal = 0; if (slant == "I") slantVal |= kMacFontItalic; if (slant == "B") slantVal |= kMacFontBold; if (slant == "R") slantVal |= kMacFontRegular; return slantVal; }
bool Resource::loadPakFile(Common::String name, Common::ArchiveMemberPtr file) { name.toUppercase(); if (_archiveFiles.hasArchive(name) || _protectedFiles.hasArchive(name)) return true; Common::Archive *archive = loadArchive(name, file); if (!archive) return false; _archiveFiles.add(name, archive, 0, false); return true; }
SaveStateList SkyMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); SaveStateList saveList; // Load the descriptions Common::StringArray savenames; savenames.resize(MAX_SAVE_GAMES+1); Common::InSaveFile *inf; inf = saveFileMan->openForLoading("SKY-VM.SAV"); if (inf != NULL) { char *tmpBuf = new char[MAX_SAVE_GAMES * MAX_TEXT_LEN]; char *tmpPtr = tmpBuf; inf->read(tmpBuf, MAX_SAVE_GAMES * MAX_TEXT_LEN); for (int i = 0; i < MAX_SAVE_GAMES; ++i) { savenames[i] = tmpPtr; tmpPtr += savenames[i].size() + 1; } delete inf; delete[] tmpBuf; } // Find all saves Common::StringArray filenames; filenames = saveFileMan->listSavefiles("SKY-VM.???"); sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) // Slot 0 is the autosave, if it exists. // TODO: Check for the existence of the autosave -- but this require us // to know which SKY variant we are looking at. saveList.insert_at(0, SaveStateDescriptor(0, "*AUTOSAVE*")); // Prepare the list of savestates by looping over all matching savefiles for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { // Extract the extension Common::String ext = file->c_str() + file->size() - 3; ext.toUppercase(); if (Common::isDigit(ext[0]) && Common::isDigit(ext[1]) && Common::isDigit(ext[2])) { int slotNum = atoi(ext.c_str()); Common::InSaveFile *in = saveFileMan->openForLoading(*file); if (in) { saveList.push_back(SaveStateDescriptor(slotNum+1, savenames[slotNum])); delete in; } } } return saveList; }
ActionCursor::ActionCursor(ZVision *engine, int32 slotkey, const Common::String &line) : ResultAction(engine, slotkey) { Common::String up = line; up.toUppercase(); _action = 0; if (up[0] == 'B') _action = 2; else if (up[0] == 'I') _action = 3; else if (up[0] == 'U') _action = 0; else if (up[0] == 'H') _action = 1; }
Common::String Menu::prepareSaveNameForDisplay(const Common::String &name) { Common::String display = name; display.toUppercase(); if (display.hasSuffix(".M3S")) { display.deleteLastChar(); display.deleteLastChar(); display.deleteLastChar(); display.deleteLastChar(); } while (display.size() > 17) display.deleteLastChar(); return display; }
void Resource::unloadPakFile(Common::String filename, bool remFromCache) { filename.toUppercase(); // We do not remove files from '_protectedFiles' here, since // those are protected against unloading. if (_archiveFiles.hasArchive(filename)) { _archiveFiles.remove(filename); if (remFromCache) { ArchiveMap::iterator iter = _archiveCache.find(filename); if (iter != _archiveCache.end()) { delete iter->_value; _archiveCache.erase(filename); } } } }
Common::String Menu::getAgeLabel(GameState *gameState) { uint32 age = 0; uint32 room = gameState->getLocationRoom(); if (room == 901) age = gameState->getMenuSavedAge(); else age = gameState->getLocationAge(); // Look for the age name const DirectorySubEntry *desc = _vm->getFileDescription("AGES", 1000, 0, DirectorySubEntry::kTextMetadata); Common::String label = desc->getTextData(_vm->_db->getAgeLabelId(age)); label.toUppercase(); return label; }
void OpenGLRenderer::draw2DText(const Common::String &text, const Common::Point &position) { OpenGLTexture *glFont = static_cast<OpenGLTexture *>(_font); // The font only has uppercase letters Common::String textToDraw = text; textToDraw.toUppercase(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); glDepthMask(GL_FALSE); glColor3f(1.0f, 1.0f, 1.0f); glBindTexture(GL_TEXTURE_2D, glFont->id); int x = position.x; int y = position.y; for (uint i = 0; i < textToDraw.size(); i++) { Common::Rect textureRect = getFontCharacterRect(textToDraw[i]); int w = textureRect.width(); int h = textureRect.height(); float cw = textureRect.width() / (float)glFont->internalWidth; float ch = textureRect.height() / (float)glFont->internalHeight; float cx = textureRect.left / (float)glFont->internalWidth; float cy = textureRect.top / (float)glFont->internalHeight; glBegin(GL_QUADS); glTexCoord2f(cx, cy + ch); glVertex3f(x, y, 1.0f); glTexCoord2f(cx + cw, cy + ch); glVertex3f(x + w, y, 1.0f); glTexCoord2f(cx + cw, cy); glVertex3f(x + w, y + h, 1.0f); glTexCoord2f(cx, cy); glVertex3f(x, y + h, 1.0f); glEnd(); x += textureRect.width() - 3; } glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDepthMask(GL_TRUE); }
void ComputerScreen::draw() { MRGFile mrg; _vm->_gfx->loadMRG("compute1.pic", &mrg); // draw title list for (uint i = 0; i < 15; i++) { uint toDraw = i; uint entryId; Common::String text; byte color = 3; uint indent = 0; if (toDraw < _sectionStack.size()) { // parents entryId = _sectionStack[toDraw]; color = 2; indent = toDraw; } else { // children uint subentry = toDraw - _sectionStack.size(); uint parentId = _sectionStack[_sectionStack.size() - 1]; const Common::Array<uint> &subentries = _vm->data._computerEntries[parentId].subentries; if (subentry >= subentries.size()) continue; entryId = subentries[subentry]; indent = _sectionStack.size(); } text = _vm->data._computerEntries[entryId].title; text.toUppercase(); // 0/1: normal/full section background _vm->_gfx->drawMRG(&mrg, (toDraw == _selection) ? 1 : 0, 1, 47 + (i * 23)); Common::Rect rect(15 + ((indent + 1) * 10), 61 + (i * 23), 167, 76 + (i * 23)); _vm->_gfx->drawString(rect.left, rect.top, /*rect.right, rect.bottom,*/ text, color); } // draw UI controls for (uint i = 0; i < _controls.size(); i++) { UIControl *control = _controls[i]; if (control->_sprite == 0xffffffff) continue; _vm->_gfx->drawMRG(&mrg, control->_sprite + control->_state, control->_bounds.left, control->_bounds.top); } }
Common::SeekableReadStream *BaseFileManager::openPkgFile(const Common::String &filename) { Common::String upcName = filename; upcName.toUppercase(); Common::SeekableReadStream *file = nullptr; // correct slashes for (uint32 i = 0; i < upcName.size(); i++) { if (upcName[(int32)i] == '/') { upcName.setChar('\\', (uint32)i); } } Common::ArchiveMemberPtr entry = _packages.getMember(upcName); if (!entry) { return nullptr; } file = entry->createReadStream(); return file; }
bool Console::Cmd_Extract(int argc, const char **argv) { if (argc != 5) { DebugPrintf("Extract a file from the game's archives\n"); DebugPrintf("Usage :\n"); DebugPrintf("extract [room] [node id] [face number] [object type]\n"); return true; } // Room names are uppercase Common::String room = Common::String(argv[1]); room.toUppercase(); uint16 id = atoi(argv[2]); uint16 face = atoi(argv[3]); DirectorySubEntry::ResourceType type = (DirectorySubEntry::ResourceType) atoi(argv[4]); const DirectorySubEntry *desc = _vm->getFileDescription(room.c_str(), id, face, type); if (!desc) { DebugPrintf("File with room %s, id %d, face %d and type %d does not exist\n", room.c_str(), id, face, type); return true; } Common::MemoryReadStream *s = desc->getData(); Common::String filename = Common::String::format("node%s_%d_face%d.%d", room.c_str(), id, face, type); Common::DumpFile f; f.open(filename); uint8 *buf = new uint8[s->size()]; s->read(buf, s->size()); f.write(buf, s->size()); delete[] buf; f.close(); delete s; DebugPrintf("File '%s' successfully written\n", filename.c_str()); return true; }
Common::SeekableReadStream *BaseFileManager::openPkgFile(const Common::String &filename) { Common::String upcName = filename; upcName.toUppercase(); Common::SeekableReadStream *file = NULL; char fileName[MAX_PATH_LENGTH]; strcpy(fileName, upcName.c_str()); // correct slashes for (uint32 i = 0; i < upcName.size(); i++) { if (upcName[(int32)i] == '/') { upcName.setChar('\\', (uint32)i); } } Common::ArchiveMemberPtr entry = _packages.getMember(upcName); if (!entry) { return NULL; } file = entry->createReadStream(); return file; }
Common::String Resource::translateFileName(const Common::String filename) { Common::String upperFilename = filename; upperFilename.toUppercase(); Common::String fileNameStrFinal; if (upperFilename.hasPrefix("P:") || upperFilename.hasPrefix("F:")) { if (_vm->_isHiRes) fileNameStrFinal = "SPICT/"; else fileNameStrFinal = "PICT/"; if (_vm->getPlatform() == Common::kPlatformAmiga) { if (upperFilename.hasPrefix("P:")) { fileNameStrFinal = "PICT/"; } else { fileNameStrFinal = "LABFONTS/"; upperFilename += "T"; // all the Amiga fonts have a ".FONT" suffix } } } else if (upperFilename.hasPrefix("LAB:")) { // Look inside the game folder } else if (upperFilename.hasPrefix("MUSIC:")) { fileNameStrFinal = "MUSIC/"; } if (upperFilename.contains(':')) { while (upperFilename[0] != ':') { upperFilename.deleteChar(0); } upperFilename.deleteChar(0); } fileNameStrFinal += upperFilename; return fileNameStrFinal; }
bool Resource::loadFileList(const Common::String &filedata) { Common::SeekableReadStream *f = createReadStream(filedata); if (!f) return false; uint32 filenameOffset = 0; while ((filenameOffset = f->readUint32LE()) != 0) { uint32 offset = f->pos(); f->seek(filenameOffset, SEEK_SET); uint8 buffer[13]; f->read(buffer, sizeof(buffer)-1); buffer[12] = 0; f->seek(offset + 16, SEEK_SET); Common::String filename = Common::String((char *)buffer); filename.toUppercase(); if (filename.hasSuffix(".PAK")) { if (!exists(filename.c_str()) && _vm->gameFlags().isDemo) { // the demo version supplied with Kyra3 does not // contain all pak files listed in filedata.fdt // so we don't do anything here if they are non // existant. } else if (!loadPakFile(filename)) { delete f; error("couldn't load file '%s'", filename.c_str()); return false; // for compilers that don't support NORETURN } } } delete f; return true; }
void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point &position) { TinyGLTexture *glFont = static_cast<TinyGLTexture *>(_font); // The font only has uppercase letters Common::String textToDraw = text; textToDraw.toUppercase(); tglEnable(TGL_BLEND); tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA); tglEnable(TGL_TEXTURE_2D); tglDepthMask(TGL_FALSE); tglColor3f(1.0f, 1.0f, 1.0f); tglBindTexture(TGL_TEXTURE_2D, glFont->id); int x = position.x; int y = position.y; for (uint i = 0; i < textToDraw.size(); i++) { Common::Rect textureRect = getFontCharacterRect(textToDraw[i]); int w = textureRect.width(); int h = textureRect.height(); Graphics::BlitTransform transform(x, y); transform.sourceRectangle(textureRect.left, textureRect.top, w, h); transform.flip(true, false); Graphics::tglBlit(glFont->getBlitTexture(), transform); x += textureRect.width() - 3; } tglDisable(TGL_TEXTURE_2D); tglDisable(TGL_BLEND); tglDepthMask(TGL_TRUE); }
TestExitStatus FStests::testReadFile() { const Common::String &path = ConfMan.get("path"); Common::FSDirectory gameRoot(path); int numFailed = 0; if (!gameRoot.getFSNode().exists() || !gameRoot.getFSNode().isDirectory()) { Testsuite::logDetailedPrintf("game Path should be an existing directory"); return kTestFailed; } const char *dirList[] = {"test1" ,"Test2", "TEST3" , "tEST4", "test5"}; const char *file[] = {"file.txt", "File.txt", "FILE.txt", "fILe.txt", "file"}; for (unsigned int i = 0; i < ARRAYSIZE(dirList); i++) { Common::String dirName = dirList[i]; Common::String fileName = file[i]; Common::FSDirectory *directory = gameRoot.getSubDirectory(dirName); if (!directory) { Testsuite::logDetailedPrintf("Failed to open directory %s during FS tests\n", dirName.c_str()); return kTestFailed; } if (!readDataFromFile(directory, fileName.c_str())) { Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str()); numFailed++; } dirName.toLowercase(); fileName.toLowercase(); delete directory; directory = gameRoot.getSubDirectory(dirName); if (!directory) { Testsuite::logDetailedPrintf("Failed to open directory %s during FS tests\n", dirName.c_str()); return kTestFailed; } if (!readDataFromFile(directory, fileName.c_str())) { Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str()); numFailed++; } dirName.toUppercase(); fileName.toUppercase(); delete directory; directory = gameRoot.getSubDirectory(dirName); if (!directory) { Testsuite::logDetailedPrintf("Failed to open directory %s during FS tests\n", dirName.c_str()); return kTestFailed; } if (!readDataFromFile(directory, fileName.c_str())) { Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str()); numFailed++; } delete directory; } Testsuite::logDetailedPrintf("Failed %d out of 15\n", numFailed); if (numFailed) { return kTestFailed; } else { return kTestPassed; } }
Common::Error EoBCoreEngine::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) { Common::String saveNameTmp; const char *fileName = 0; // Special slot id -1 to create final save for party transfer if (slot == -1) { _savegameFilename = _targetName + Common::String(".fin"); fileName = _savegameFilename.c_str(); saveNameTmp = _targetName + Common::String(" final"); saveNameTmp.toUppercase(); saveName = saveNameTmp.c_str(); } else { fileName = getSavegameFilename(slot); } Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumbnail); if (!out) return _saveFileMan->getError(); completeDoorOperations(); generateTempData(); advanceTimers(_restPartyElapsedTime); _restPartyElapsedTime = 0; for (int i = 0; i < 6; i++) timerSpecialCharacterUpdate(0x30 + i); for (int i = 0; i < 6; i++) { EoBCharacter *c = &_characters[i]; out->writeByte(c->id); out->writeByte(c->flags); out->write(c->name, 11); out->writeSByte(c->strengthCur); out->writeSByte(c->strengthMax); out->writeSByte(c->strengthExtCur); out->writeSByte(c->strengthExtMax); out->writeSByte(c->intelligenceCur); out->writeSByte(c->intelligenceMax); out->writeSByte(c->wisdomCur); out->writeSByte(c->wisdomMax); out->writeSByte(c->dexterityCur); out->writeSByte(c->dexterityMax); out->writeSByte(c->constitutionCur); out->writeSByte(c->constitutionMax); out->writeSByte(c->charismaCur); out->writeSByte(c->charismaMax); out->writeSint16BE(c->hitPointsCur); out->writeSint16BE(c->hitPointsMax); out->writeSByte(c->armorClass); out->writeByte(c->disabledSlots); out->writeByte(c->raceSex); out->writeByte(c->cClass); out->writeByte(c->alignment); out->writeByte(c->portrait); out->writeByte(c->food); out->write(c->level, 3); for (int ii = 0; ii < 3; ii++) out->writeUint32BE(c->experience[ii]); out->write(c->mageSpells, 80); out->write(c->clericSpells, 80); out->writeUint32BE(c->mageSpellsAvailableFlags); for (int ii = 0; ii < 27; ii++) out->writeSint16BE(c->inventory[ii]); uint32 ct = _system->getMillis(); for (int ii = 0; ii < 10; ii++) out->writeUint32BE((c->timers[ii] && c->timers[ii] > ct) ? c->timers[ii] - ct : 0); out->write(c->events, 10); out->write(c->effectsRemainder, 4); out->writeUint32BE(c->effectFlags); out->writeByte(c->damageTaken); out->write(c->slotStatus, 5); } out->writeByte(_currentLevel); out->writeSByte(_currentSub); out->writeUint16BE(_currentBlock); out->writeUint16BE(_currentDirection); out->writeSint16BE(_itemInHand); out->writeUint32BE(_hasTempDataFlags); out->writeUint32BE(_partyEffectFlags); out->writeUint16BE(_updateFlags); out->writeUint16BE(_compassDirection); out->writeUint16BE(_currentControlMode); out->writeUint16BE(_updateCharNum); out->writeSByte(_openBookSpellLevel); out->writeSByte(_openBookSpellSelectedItem); out->writeSByte(_openBookSpellListOffset); out->writeByte(_openBookChar); out->writeByte(_openBookType); out->writeByte(_openBookCharBackup); out->writeByte(_openBookTypeBackup); out->writeByte(_activeSpellCharId); out->writeByte(_activeSpellCharacterPos); out->writeByte(_activeSpell); out->writeByte(_returnAfterSpellCallback ? 1 : 0); _inf->saveState(out); for (int i = 0; i < 600; i++) { EoBItem *t = &_items[i]; out->writeByte(t->nameUnid); out->writeByte(t->nameId); out->writeByte(t->flags); out->writeSByte(t->icon); out->writeSByte(t->type); out->writeSByte(t->pos); out->writeSint16BE(t->block); out->writeSint16BE(t->next); out->writeSint16BE(t->prev); out->writeByte(t->level); out->writeSByte(t->value); } for (int i = 51; i < 65; i++) { EoBItemType *t = &_itemTypes[i]; out->writeUint16BE(t->invFlags); out->writeUint16BE(t->handFlags); out->writeSByte(t->armorClass); out->writeSByte(t->allowedClasses); out->writeSByte(t->requiredHands); out->writeSByte(t->dmgNumDiceS); out->writeSByte(t->dmgNumPipsS); out->writeSByte(t->dmgIncS); out->writeSByte(t->dmgNumDiceL); out->writeSByte(t->dmgNumPipsL); out->writeSByte(t->dmgIncL); out->writeByte(t->unk1); out->writeUint16BE(t->extraProperties); } for (int i = 0; i < 18; i++) { LevelTempData *l = _lvlTempData[i]; if (!l || !(_hasTempDataFlags & (1 << i))) continue; out->write(l->wallsXorData, 4096); for (int ii = 0; ii < 1024; ii++) out->writeByte(l->flags[ii] & 0xff); EoBMonsterInPlay *lm = (EoBMonsterInPlay *)_lvlTempData[i]->monsters; EoBFlyingObject *lf = (EoBFlyingObject *)_lvlTempData[i]->flyingObjects; WallOfForce *lw = (WallOfForce *)_lvlTempData[i]->wallsOfForce; for (int ii = 0; ii < 30; ii++) { EoBMonsterInPlay *m = &lm[ii]; out->writeByte(m->type); out->writeByte(m->unit); out->writeUint16BE(m->block); out->writeByte(m->pos); out->writeSByte(m->dir); out->writeByte(m->animStep); out->writeByte(m->shpIndex); out->writeSByte(m->mode); out->writeSByte(m->f_9); out->writeSByte(m->curAttackFrame); out->writeSByte(m->spellStatusLeft); out->writeSint16BE(m->hitPointsMax); out->writeSint16BE(m->hitPointsCur); out->writeUint16BE(m->dest); out->writeUint16BE(m->randItem); out->writeUint16BE(m->fixedItem); out->writeByte(m->flags); out->writeByte(m->idleAnimState); out->writeByte(m->curRemoteWeapon); out->writeByte(m->numRemoteAttacks); out->writeSByte(m->palette); out->writeByte(m->directionChanged); out->writeByte(m->stepsTillRemoteAttack); out->writeByte(m->sub); } for (int ii = 0; ii < _numFlyingObjects; ii++) { EoBFlyingObject *m = &lf[ii]; out->writeByte(m->enable); out->writeByte(m->objectType); out->writeSint16BE(m->attackerId); out->writeSint16BE(m->item); out->writeUint16BE(m->curBlock); out->writeUint16BE(m->u2); out->writeByte(m->u1); out->writeByte(m->direction); out->writeByte(m->distance); out->writeSByte(m->callBackIndex); out->writeByte(m->curPos); out->writeByte(m->flags); out->writeByte(m->unused); } for (int ii = 0; ii < 5; ii++) { WallOfForce *w = &lw[ii]; out->writeUint16BE(w->block); out->writeUint32BE(w->duration); } } out->finalize(); // check for errors if (out->err()) { warning("Can't write file '%s'. (Disk full?)", fileName); return Common::kUnknownError; } else { debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName); } delete out; _gui->notifyUpdateSaveSlotsList(); return Common::kNoError; }
void ShaderRenderer::draw2DText(const Common::String &text, const Common::Point &position) { OpenGLTexture *glFont = static_cast<OpenGLTexture *>(_font); // The font only has uppercase letters Common::String textToDraw = text; textToDraw.toUppercase(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); if (_prevText != textToDraw || _prevTextPosition != position) { _prevText = textToDraw; _prevTextPosition = position; float x = position.x / (float) _currentViewport.width(); float y = position.y / (float) _currentViewport.height(); float *bufData = new float[16 * textToDraw.size()]; float *cur = bufData; for (uint i = 0; i < textToDraw.size(); i++) { Common::Rect textureRect = getFontCharacterRect(textToDraw[i]); float w = textureRect.width() / (float) _currentViewport.width(); float h = textureRect.height() / (float) _currentViewport.height(); float cw = textureRect.width() / (float)glFont->internalWidth; float ch = textureRect.height() / (float)glFont->internalHeight; float cx = textureRect.left / (float)glFont->internalWidth; float cy = textureRect.top / (float)glFont->internalHeight; const float charData[] = { cx, cy + ch, x, y, cx + cw, cy + ch, x + w, y, cx + cw, cy, x + w, y + h, cx, cy, x, y + h, }; memcpy(cur, charData, 16 * sizeof(float)); cur += 16; x += (textureRect.width() - 3) / (float) _currentViewport.width(); } glBindBuffer(GL_ARRAY_BUFFER, _textVBO); glBufferSubData(GL_ARRAY_BUFFER, 0, textToDraw.size() * 16 * sizeof(float), bufData); delete[] bufData; } _textShader->use(); glBindTexture(GL_TEXTURE_2D, glFont->id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quadEBO); glDrawElements(GL_TRIANGLES, 6 * textToDraw.size(), GL_UNSIGNED_SHORT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); }
/** * 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; }
PackageSet::PackageSet(Common::FSNode file, const Common::String &filename, bool searchSignature) { uint32 absoluteOffset = 0; _priority = 0; bool boundToExe = false; Common::SeekableReadStream *stream = file.createReadStream(); if (!stream) { return; } if (searchSignature) { uint32 offset; if (!findPackageSignature(stream, &offset)) { delete stream; return; } else { stream->seek(offset, SEEK_SET); absoluteOffset = offset; boundToExe = true; } } TPackageHeader hdr; hdr.readFromStream(stream); if (hdr._magic1 != PACKAGE_MAGIC_1 || hdr._magic2 != PACKAGE_MAGIC_2 || hdr._packageVersion > PACKAGE_VERSION) { debugC(kWintermuteDebugFileAccess | kWintermuteDebugLog, " Invalid header in package file '%s'. Ignoring.", filename.c_str()); delete stream; return; } if (hdr._packageVersion != PACKAGE_VERSION) { debugC(kWintermuteDebugFileAccess | kWintermuteDebugLog, " Warning: package file '%s' is outdated.", filename.c_str()); } _priority = hdr._priority; // new in v2 if (hdr._packageVersion == PACKAGE_VERSION) { uint32 dirOffset; dirOffset = stream->readUint32LE(); dirOffset += absoluteOffset; stream->seek(dirOffset, SEEK_SET); } assert(hdr._numDirs == 1); for (uint32 i = 0; i < hdr._numDirs; i++) { BasePackage *pkg = new BasePackage(); if (!pkg) { return; } pkg->_fsnode = file; pkg->_boundToExe = boundToExe; // read package info byte nameLength = stream->readByte(); char *pkgName = new char[nameLength]; stream->read(pkgName, nameLength); pkg->_name = pkgName; pkg->_cd = stream->readByte(); pkg->_priority = hdr._priority; delete[] pkgName; pkgName = nullptr; if (!hdr._masterIndex) { pkg->_cd = 0; // override CD to fixed disk } _packages.push_back(pkg); // read file entries uint32 numFiles = stream->readUint32LE(); for (uint32 j = 0; j < numFiles; j++) { char *name; uint32 offset, length, compLength, flags;/*, timeDate1, timeDate2;*/ nameLength = stream->readByte(); name = new char[nameLength]; stream->read(name, nameLength); // v2 - xor name if (hdr._packageVersion == PACKAGE_VERSION) { for (int k = 0; k < nameLength; k++) { ((byte *)name)[k] ^= 'D'; } } debugC(kWintermuteDebugFileAccess, "Package contains %s", name); Common::String upcName = name; upcName.toUppercase(); delete[] name; name = nullptr; offset = stream->readUint32LE(); offset += absoluteOffset; length = stream->readUint32LE(); compLength = stream->readUint32LE(); flags = stream->readUint32LE(); if (hdr._packageVersion == PACKAGE_VERSION) { /* timeDate1 = */ stream->readUint32LE(); /* timeDate2 = */ stream->readUint32LE(); } _filesIter = _files.find(upcName); if (_filesIter == _files.end()) { BaseFileEntry *fileEntry = new BaseFileEntry(); fileEntry->_package = pkg; fileEntry->_offset = offset; fileEntry->_length = length; fileEntry->_compressedLength = compLength; fileEntry->_flags = flags; _files[upcName] = Common::ArchiveMemberPtr(fileEntry); } else { // current package has higher priority than the registered // TODO: This cast might be a bit ugly. BaseFileEntry *filePtr = (BaseFileEntry *) &*(_filesIter->_value); if (pkg->_priority > filePtr->_package->_priority) { filePtr->_package = pkg; filePtr->_offset = offset; filePtr->_length = length; filePtr->_compressedLength = compLength; filePtr->_flags = flags; } } } } debugC(kWintermuteDebugFileAccess, " Registered %d files in %d package(s)", _files.size(), _packages.size()); delete stream; }