Exemple #1
0
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;
}
Exemple #2
0
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());
}
Exemple #3
0
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;
	}
}
Exemple #4
0
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;
}
Exemple #6
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;
}
Exemple #7
0
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;
}
Exemple #8
0
bool Resource::loadPakFile(Common::String filename) {
	filename.toUppercase();

	Common::ArchiveMemberPtr file = _files.getMember(filename);
	if (!file)
		return false;

	return loadPakFile(filename, file);
}
Exemple #9
0
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;
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
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);
			}
		}
	}
}
Exemple #17
0
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;
}
Exemple #18
0
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);
}
Exemple #19
0
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;
}
Exemple #21
0
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;
}
Exemple #23
0
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;
}
Exemple #24
0
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);
}
Exemple #26
0
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;
	}
}
Exemple #27
0
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);
}
Exemple #29
0
/**
 * 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;
}
Exemple #30
0
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;
}