Beispiel #1
0
bool Debugger::cmdDumpFile(int argc, const char **argv) {
	if (argc != 2) {
		debugPrintf("Format: dumpfile <resource name>\n");
		return true;
	}

	Common::SeekableReadStream *s = _vm->_res->load(argv[1]);
	if (!s) {
		debugPrintf("Invalid resource.\n");
		return true;
	}

	byte *buffer = new byte[s->size()];
	s->read(buffer, s->size());

	Common::DumpFile dumpFile;
	dumpFile.open(argv[1]);

	dumpFile.write(buffer, s->size());
	dumpFile.flush();
	dumpFile.close();

	delete[] buffer;

	debugPrintf("Resource %s has been dumped to disk.\n", argv[1]);

	return true;
}
Beispiel #2
0
void ResourceManager::dumpResourcesList(const Common::UString &fileName) const {
	Common::DumpFile file;

	if (!file.open(fileName))
		throw Common::Exception(Common::kOpenError);

	file.writeString("                Name                 |     Size    \n");
	file.writeString("-------------------------------------|-------------\n");

	for (ResourceMap::const_iterator itName = _resources.begin(); itName != _resources.end(); ++itName) {
		for (ResourceTypeMap::const_iterator itType = itName->second.begin(); itType != itName->second.end(); ++itType) {
			if (itType->second.empty())
				continue;

			const Resource &resource = itType->second.back();

			const Common::UString &name = itName->first;
			const Common::UString  ext  = setFileType("", resource.type);
			const uint32           size = getResourceSize(resource);

			const Common::UString line =
				Common::UString::sprintf("%32s%4s | %12d\n", name.c_str(), ext.c_str(), size);

			file.writeString(line);
		}
	}

	file.flush();

	if (file.err())
		throw Common::Exception("Write error");

	file.close();
}
Beispiel #3
0
bool Console::Cmd_DumpFile(int argc, const char **argv) {
	if (argc != 3) {
		debugPrintf("Usage: %s <file path> <output file name>\n", argv[0]);
		return true;
	}

	Common::String filePath = argv[1];
	Common::String outFileName = argv[2];

	BaseFileManager *fileManager = BaseEngine::instance().getFileManager();
	Common::SeekableReadStream *inFile = fileManager->openFile(filePath);
	if (!inFile) {
		debugPrintf("File '%s' not found\n", argv[1]);
		return true;
	}

	Common::DumpFile *outFile = new Common::DumpFile();
	outFile->open(outFileName);

	byte *data = new byte[inFile->size()];
	inFile->read(data, inFile->size());
	outFile->write(data, inFile->size());
	outFile->finalize();
	outFile->close();
	delete[] data;

	delete outFile;
	delete inFile;

	debugPrintf("Resource file '%s' dumped to file '%s'\n", argv[1], argv[2]);
	return true;
}
Beispiel #4
0
// Dumps all of the game's music in external XMIDI *.xmi files
void dumpMusic() {
	Common::File midiFile;
	Common::DumpFile outFile;
	char outName[20];
	midiFile.open(MIDI_FILE);
	int outFileSize = 0;
	char buffer[20000];

	const int total = 155;	// maximum (SCN version)

	for (int i = 0; i < total; i++) {
		if (midiOffsets[i] == 0)
			break;

		sprintf(outName, "track%03d.xmi", i + 1);
		outFile.open(outName);

		if (i < total - 1)
			outFileSize = midiOffsets[i + 1] - midiOffsets[i] - 4;
		else
			outFileSize = midiFile.size() - midiOffsets[i] - 4;

		midiFile.seek(midiOffsets[i] + 4, SEEK_SET);

		assert(outFileSize < 20000);
		midiFile.read(buffer, outFileSize);
		outFile.write(buffer, outFileSize);

		outFile.close();
	}

	midiFile.close();
}
Beispiel #5
0
void MadsM4Engine::dumpFile(const char* filename, bool uncompress) {
	Common::DumpFile f;
	byte buffer[DUMP_BUFFER_SIZE];
	Common::SeekableReadStream *fileS = res()->get(filename);
	
	if (!f.open(filename))
		error("Could not open '%s' for writing", filename);

	int bytesRead = 0;
	warning("Dumping %s, size: %i\n", filename, fileS->size());

	if (!uncompress) {
		while (!fileS->eos()) {
			bytesRead = fileS->read(buffer, DUMP_BUFFER_SIZE);
			f.write(buffer, bytesRead);
		}
	} else {
		MadsPack packData(fileS);
		Common::SeekableReadStream *sourceUnc;
		for (int i = 0; i < packData.getCount(); i++) {
			sourceUnc = packData.getItemStream(i);
			debugCN(kDebugCore, "Dumping compressed chunk %i of %i, size is %i\n", i + 1, packData.getCount(), sourceUnc->size());
			while (!sourceUnc->eos()) {
				bytesRead = sourceUnc->read(buffer, DUMP_BUFFER_SIZE);
				f.write(buffer, bytesRead);
			}
			delete sourceUnc;
		}
	}

	f.close();
	res()->toss(filename);
	res()->purge();
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
0
bool Debugger::Cmd_DumpFile(int argc, const char **argv) {
    if (argc != 2) {
        debugPrintf("Usage: %s <resource>\n", argv[0]);
    } else {
        Common::DumpFile outFile;
        Common::File inFile;

        if (!inFile.open(argv[1])) {
            debugPrintf("Specified resource does not exist\n");
        } else {
            outFile.open(argv[1]);
            byte *data = new byte[inFile.size()];

            inFile.read(data, inFile.size());
            outFile.write(data, inFile.size());
            outFile.flush();

            delete[] data;
            inFile.close();
            outFile.close();

            debugPrintf("File written successfully.\n");
        }
    }

    return true;
}
Beispiel #9
0
void ResourceManager::dumpResourcesList(const Common::UString &fileName) const {
	Common::DumpFile file;

	if (!file.open(fileName))
		throw Common::Exception(Common::kOpenError);

	file.writeString("                Name                 |        Hash        |     Size    \n");
	file.writeString("-------------------------------------|--------------------|-------------\n");

	for (ResourceMap::const_iterator r = _resources.begin(); r != _resources.end(); ++r) {
		if (r->second.empty())
			continue;

		const Resource &res = r->second.back();

		const Common::UString &name = res.name;
		const Common::UString   ext = TypeMan.setFileType("", res.type);
		const uint64           hash = r->first;
		const uint32           size = getResourceSize(res);

		const Common::UString line =
			Common::UString::sprintf("%32s%4s | 0x%016llX | %12d\n", name.c_str(), ext.c_str(),
                               (unsigned long long) hash, size);

		file.writeString(line);
	}

	file.flush();

	if (file.err())
		throw Common::Exception("Write error");

	file.close();
}
Beispiel #10
0
static bool writeBMP(const Common::UString &filename, const byte *data,
		int width, int height) {

	if ((width <= 0) || (height <= 0) || !data)
		return false;

	Common::DumpFile file;

	if (!file.open(filename))
		return false;

	// The pitch of the output has to be divisible by 4, so
	// we output zeroes to make the pitch that far.
	int extraDataSize = width & 3;
	int imageSize = height * (width + extraDataSize) * 3;

	// Main bitmap header
	file.writeByte('B');
	file.writeByte('M');
	file.writeUint32LE(14 + 40 + imageSize); // Size
	file.writeUint32LE(0); // reserved
	file.writeUint32LE(14 + 40); // Image offset after both headers

	// v3 header
	file.writeUint32LE(40);
	file.writeUint32LE(width);
	file.writeUint32LE(height);
	file.writeUint16LE(1);
	file.writeUint16LE(24);
	file.writeUint32LE(0);
	file.writeUint32LE(imageSize);
	file.writeUint32LE(72);
	file.writeUint32LE(72);
	file.writeUint32LE(0);
	file.writeUint32LE(0);

	if (extraDataSize != 0) {
		// Dump, making sure the pitch is correct
		while (height--) {
			file.write(data, width * 3);

			// Ensure we're on a 4-byte boundary
			for (int i = 0; i < extraDataSize; i++)
				file.writeByte(0);

			data += width * 3;
		}
	} else {
		// Dump directly (can do all at once here because the data
		// is already good for BMP output)
		file.write(data, width * height * 3);
	}

	if (!file.flush() || file.err())
		return false;

	file.close();
	return true;
}
Beispiel #11
0
bool Console::cmdDumpImage(int argc, const char **argv) {
	if (argc != 2) {
		debugPrintf("Use %s <TGA/TGZ name> to dump a Z-Vision TGA/TGZ image into a regular BMP image\n", argv[0]);
		return true;
	}

	Common::String fileName = argv[1];
	if (!fileName.hasSuffix(".tga")) {
		debugPrintf("%s is not an image file", argv[1]);
	}

	Common::File f;
	if (!_engine->getSearchManager()->openFile(f, argv[1])) {
		warning("File not found: %s", argv[1]);
		return true;
	}

	Graphics::Surface surface;
	_engine->getRenderManager()->readImageToSurface(argv[1], surface, false);

	// Open file
	Common::DumpFile out;

	fileName.setChar('b', fileName.size() - 3);
	fileName.setChar('m', fileName.size() - 2);
	fileName.setChar('p', fileName.size() - 1);

	out.open(fileName);

	// Write BMP header
	out.writeByte('B');
	out.writeByte('M');
	out.writeUint32LE(surface.h * surface.pitch + 54);
	out.writeUint32LE(0);
	out.writeUint32LE(54);
	out.writeUint32LE(40);
	out.writeUint32LE(surface.w);
	out.writeUint32LE(surface.h);
	out.writeUint16LE(1);
	out.writeUint16LE(16);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);

	// Write pixel data to BMP
	out.write(surface.getPixels(), surface.pitch * surface.h);

	out.flush();
	out.close();

	surface.free();

	return true;
}
Beispiel #12
0
bool Node::dumpFaceMask(uint16 index, int face, DirectorySubEntry::ResourceType type) {
	static const int32 kMaskSize = 640 * 640;

	byte *mask = new byte[kMaskSize];
	memset(mask, 0, kMaskSize);
	uint32 headerOffset = 0;
	uint32 dataOffset = 0;

	const DirectorySubEntry *maskDesc = _vm->getFileDescription(0, index, face, type);

	if (!maskDesc) {
		delete[] mask;
		return false;
	}

	Common::MemoryReadStream *maskStream = maskDesc->getData();

	while (headerOffset < 400) {
		int blockX = (headerOffset / sizeof(dataOffset)) % 10;
		int blockY = (headerOffset / sizeof(dataOffset)) / 10;

		maskStream->seek(headerOffset, SEEK_SET);
		dataOffset = maskStream->readUint32LE();
		headerOffset = maskStream->pos();

		if (dataOffset != 0) {
			maskStream->seek(dataOffset, SEEK_SET);

			for(int i = 63; i >= 0; i--) {
				int x = 0;
				byte numValues = maskStream->readByte();
				for (int j = 0; j < numValues; j++) {
					byte repeat = maskStream->readByte();
					byte value = maskStream->readByte();
					for (int k = 0; k < repeat; k++) {
						mask[((blockY * 64) + i) * 640 + blockX * 64 + x] = value;
						x++;
					}
				}
			}
		}
	}

	delete maskStream;

	Common::DumpFile outFile;
	outFile.open(Common::String::format("dump/%d-%d.masku_%d", index, face, type));
	outFile.write(mask, kMaskSize);
	outFile.close();
	delete[] mask;

	return true;
}
Beispiel #13
0
void dumpStream(Common::SeekableReadStream &stream, const Common::UString &fileName) {
	Common::DumpFile file;
	if (!file.open(fileName))
		throw Common::Exception(Common::kOpenError);

	file.writeStream(stream);
	file.flush();
	if (file.err())
		throw Common::Exception(Common::kWriteError);

	file.close();
}
Beispiel #14
0
void dumpFile(Common::SeekableReadStream *s, const char *outName) {
	byte *buffer = new byte[s->size()];
	s->read(buffer, s->size());

	Common::DumpFile dumpFile;
	dumpFile.open(outName);

	dumpFile.write(buffer, s->size());
	dumpFile.flush();
	dumpFile.close();

	delete[] buffer;
}
Beispiel #15
0
bool Debugger::Cmd_DumpFile(int argc, const char **argv) {
	if (argc < 2) {
		debugPrintf("Usage: %s <resource> <unpack>\n", argv[0]);
		debugPrintf("  resource: the resource name\n");
		debugPrintf("  unpack: optional, when specified, the FAB/MADSPACK compressed resource is unpacked\n");
	} else {
		Common::DumpFile outFile;
		Common::File inFile;

		if (!inFile.open(argv[1])) {
			debugPrintf("Specified resource does not exist\n");
		} else {
			outFile.open(argv[1]);
			bool unpack = ((argc >= 3) && !scumm_stricmp(argv[2], "unpack"));

			byte *data;
			int totalSize = 0;

			if (!unpack) {
				totalSize = inFile.size();
				data = new byte[totalSize];
				inFile.read(data, totalSize);
			} else {
				MadsPack dataPack(&inFile);
				int count = dataPack.getCount();
				for (int i = 0; i < count; i++) {
					totalSize += dataPack.getItem(i)._size;
				}
				data = new byte[totalSize];
				byte *ptr = data;

				for (int i = 0; i < count; i++) {
					Common::SeekableReadStream *readStream = dataPack.getItemStream(i);
					readStream->read(ptr, readStream->size());
					ptr += readStream->size();
				}
			}

			outFile.write(data, totalSize);
			outFile.flush();

			delete[] data;
			inFile.close();
			outFile.close();

			debugPrintf("File written successfully.\n");
		}
	}

	return true;
}
Beispiel #16
0
bool TwoDAFile::dumpASCII(const Common::UString &fileName) const {
	Common::DumpFile file;
	if (!file.open(fileName))
		return false;

	// Write header

	file.writeString("2DA V2.0\n");
	file.writeString(_defaultString); file.writeByte('\n');

	// Calculate column lengths

	std::vector<uint32> colLength;
	colLength.resize(_headers.size() + 1);

	const Common::UString maxRow = Common::UString::sprintf("%d", (int)_rows.size() - 1);
	colLength[0] = maxRow.size();

	for (uint32 i = 0; i < _headers.size(); i++)
		colLength[i + 1] = _headers[i].size();

	for (uint32 i = 0; i < _rows.size(); i++)
		for (uint32 j = 0; j < _rows[i]->_data.size(); j++)
			colLength[j + 1] = MAX<uint32>(colLength[j + 1], _rows[i]->_data[j].size());

	// Write column headers

	file.writeString(Common::UString::sprintf("%-*s", colLength[0], ""));

	for (uint32 i = 0; i < _headers.size(); i++)
		file.writeString(Common::UString::sprintf(" %-*s", colLength[i + 1], _headers[i].c_str()));

	file.writeByte('\n');

	// Write array

	for (uint32 i = 0; i < _rows.size(); i++) {
		file.writeString(Common::UString::sprintf("%*d", colLength[0], i));

		for (uint32 j = 0; j < _rows[i]->_data.size(); j++)
			file.writeString(Common::UString::sprintf(" %-*s", colLength[j + 1], _rows[i]->_data[j].c_str()));

		file.writeByte('\n');
	}

	file.flush();
	file.close();

	return true;
}
Beispiel #17
0
void ResMan::dumpRes(uint32 id) {
	char outn[30];
	sprintf(outn, "DUMP%08X.BIN", id);
	Common::DumpFile outf;
	if (outf.open(outn)) {
		resOpen(id);
		MemHandle *memHandle = resHandle(id);
		if (memHandle) {
			outf.write(memHandle->data, memHandle->size);
			outf.close();
		}
		resClose(id);
	}
}
Beispiel #18
0
void DirectorySubEntry::dumpToFile(Common::SeekableReadStream &inStream, const char* room, uint32 index) {
    char fileName[255];

    switch (_type) {
    case kNumMetadata:
    case kTextMetadata:
        return; // These types are pure metadata and can't be extracted
    case kCubeFace:
    case kSpotItem:
    case kLocalizedSpotItem:
    case kFrame:
        sprintf(fileName, "dump/%s-%d-%d.jpg", room, index, _face);
        break;
    case kWaterEffectMask:
        sprintf(fileName, "dump/%s-%d-%d.mask", room, index, _face);
        break;
    case kMovie:
    case kStillMovie:
    case kDialogMovie:
    case kMultitrackMovie:
        sprintf(fileName, "dump/%s-%d.bik", room, index);
        break;
    default:
        sprintf(fileName, "dump/%s-%d-%d.%d", room, index, _face, _type);
        break;
    }


    debug("Extracted %s", fileName);

    Common::DumpFile outFile;
    if (!outFile.open(fileName))
        error("Unable to open file '%s' for writing", fileName);

    inStream.seek(_offset);

    uint8 *buf = new uint8[_size];

    inStream.read(buf, _size);
    outFile.write(buf, _size);

    delete[] buf;

    outFile.close();
}
Beispiel #19
0
void ArchiveReader::dump(uint resIndex) {
	int32 resourceSize = getResourceSize(resIndex);
	byte *data = new byte[resourceSize];

	Common::String fn = Common::String::format("toltecs_res.%03d", resIndex);

	openResource(resIndex);
	read(data, resourceSize);
	closeResource();

	Common::DumpFile o;
	o.open(fn);
	o.write(data, resourceSize);
	o.finalize();
	o.close();

	delete[] data;
}
Beispiel #20
0
void writeFileContentsToFile(const Common::String &sourceFile, const Common::String &destFile) {
	Common::File f;
	if (!f.open(sourceFile)) {
		return;
	}

	byte* buffer = new byte[f.size()];
	f.read(buffer, f.size());

	Common::DumpFile dumpFile;
	dumpFile.open(destFile);

	dumpFile.write(buffer, f.size());
	dumpFile.flush();
	dumpFile.close();

	delete[] buffer;
}
Beispiel #21
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 [archive name]\n");
		return true;
	}

	Formats::XARCArchive xarc;
	if (!xarc.open(argv[1])) {
		debugPrintf("Can't open archive with name '%s'\n", argv[1]);
		return true;
	}

	Common::ArchiveMemberList members;
	xarc.listMembers(members);

	for (Common::ArchiveMemberList::const_iterator it = members.begin(); it != members.end(); it++) {
		Common::String fileName = Common::String::format("dump/%s", it->get()->getName().c_str());

		// Open the output file
		Common::DumpFile outFile;
		if (!outFile.open(fileName)) {
			debugPrintf("Unable to open file '%s' for writing\n", fileName.c_str());
			return true;
		}

		// Copy the archive content to the output file using a temporary buffer
		Common::SeekableReadStream *inStream = it->get()->createReadStream();
		uint8 *buf = new uint8[inStream->size()];

		inStream->read(buf, inStream->size());
		outFile.write(buf, inStream->size());

		delete[] buf;
		delete inStream;
		outFile.close();

		debugPrintf("Extracted '%s'\n", it->get()->getName().c_str());
	}

	return true;
}
Beispiel #22
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;
}
Beispiel #23
0
bool dumpStream(Common::SeekableReadStream &stream, const Common::UString &fileName) {
	Common::DumpFile file;
	if (!file.open(fileName))
		return false;

	uint32 pos = stream.pos();

	stream.seek(0);

	file.writeStream(stream);
	file.flush();

	bool error = file.err();

	stream.seek(pos);
	file.close();

	return !error;
}
Beispiel #24
0
void DefaultSaveFileManager::saveTimestamps(Common::HashMap<Common::String, uint32> &timestamps) {
	Common::DumpFile f;
	Common::String filename = concatWithSavesPath(TIMESTAMPS_FILENAME);
	if (!f.open(filename, true)) {
		warning("DefaultSaveFileManager: failed to open '%s' file to save timestamps", filename.c_str());
		return;
	}

	for (Common::HashMap<Common::String, uint32>::iterator i = timestamps.begin(); i != timestamps.end(); ++i) {
		Common::String data = i->_key + Common::String::format(" %u\n", i->_value);
		if (f.write(data.c_str(), data.size()) != data.size()) {
			warning("DefaultSaveFileManager: failed to write timestamps data into '%s'", filename.c_str());
			return;
		}
	}

	f.flush();
	f.finalize();
	f.close();
}
Beispiel #25
0
bool Console::dumpFaceMask(uint16 index, int face, DirectorySubEntry::ResourceType type) {
	const DirectorySubEntry *maskDesc = _vm->getFileDescription("", index, face, type);

	if (!maskDesc)
		return false;

	Common::MemoryReadStream *maskStream = maskDesc->getData();

	Effect::FaceMask *mask = Effect::loadMask(maskStream);

	delete maskStream;

	Common::DumpFile outFile;
	outFile.open(Common::String::format("dump/%d-%d.masku_%d", index, face, type));
	outFile.write(mask->surface->getPixels(), mask->surface->pitch * mask->surface->h);
	outFile.close();

	delete mask;

	return true;
}
Beispiel #26
0
void ArchiveReader::dump(uint resIndex, const char *prefix) {
	int32 resourceSize = getResourceSize(resIndex);
	byte *data = new byte[resourceSize];

	Common::String fn;
	
	if (prefix)
		fn = Common::String::format("%s_%04X.0", prefix, resIndex);
	else
		fn = Common::String::format("%04X.0", resIndex);

	openResource(resIndex);
	read(data, resourceSize);
	closeResource();

	Common::DumpFile o;
	o.open(fn);
	o.write(data, resourceSize);
	o.finalize();
	o.close();

	delete[] data;
}
Beispiel #27
0
void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint16 verb, uint16 cond, uint16 seq) {
	_position = position;

	// Now init audio and sync resource
	uint32 audioNumber = ((noun & 0xff) << 24) | ((verb & 0xff) << 16) | ((cond & 0xff) << 8) | (seq & 0xff);
#ifndef DEBUG_PORTRAIT_USE_SYNC_RESOURCES
	ResourceId raveResourceId = ResourceId(kResourceTypeRave, resourceId, noun, verb, cond, seq);
	Resource *raveResource = _resMan->findResource(raveResourceId, true);
	uint raveOffset = 0;
#else
	ResourceId syncResourceId = ResourceId(kResourceTypeSync36, resourceId, noun, verb, cond, seq);
	Resource *syncResource = _resMan->findResource(syncResourceId, true);
	uint syncOffset = 0;
#endif

#ifdef DEBUG_PORTRAIT
	// prints out the current lip sync ASCII data
	char debugPrint[4000];
	if (raveResource->size < 4000) {
		memcpy(debugPrint, raveResource->data, raveResource->size);
		debugPrint[raveResource->size] = 0; // set terminating NUL
		debug("kPortrait: using actor %s", _resourceName.c_str());
		debug("kPortrait (noun %d, verb %d, cond %d, seq %d)", noun, verb, cond, seq);
		debug("kPortrait: rave data is '%s'", debugPrint);
	}
#endif

	// TODO: maybe try to create the missing sync resources for low-res KQ6 out of the rave resources

#ifdef DEBUG_PORTRAIT_USE_SYNC_RESOURCES
		// Dump the sync resources to disk
		Common::DumpFile *outFile = new Common::DumpFile();
		Common::String outName = syncResourceId.toPatchNameBase36() + ".sync36";
		outFile->open(outName);
		syncResource->writeToStream(outFile);
		outFile->finalize();
		outFile->close();

		ResourceId raveResourceId = ResourceId(kResourceTypeRave, resourceId, noun, verb, cond, seq);
		Resource *raveResource = _resMan->findResource(raveResourceId, true);
		outName = raveResourceId.toPatchNameBase36() + ".rave";
		outFile->open(outName);
		raveResource->writeToStream(outFile);
		outFile->finalize();
		outFile->close();
		_resMan->unlockResource(raveResource);

		delete outFile;
#endif

	// Set the portrait palette
	_palette->set(&_portraitPalette, false, true);

	// Draw base bitmap
	drawBitmap(0);
	bitsShow();

	// Start playing audio...
	_audio->stopAudio();
	_audio->startAudio(resourceId, audioNumber);

#ifndef DEBUG_PORTRAIT_USE_SYNC_RESOURCES
	if (!raveResource) {
		warning("kPortrait: no rave resource %d %X", resourceId, audioNumber);
		return;
	}

	// Do animation depending on rave resource till audio is done playing
	int16 raveTicks;
	uint16 raveID;
	byte *raveLipSyncData;
	byte raveLipSyncTicks;
	byte raveLipSyncBitmapNr;
	int timerPosition = 0;
	int timerPositionWithin = 0;
	int curPosition;
	SciEvent curEvent;
	bool userAbort = false;

	while ((raveOffset < raveResource->size) && (!userAbort)) {
		// rave string starts with tick count, followed by lipSyncID, tick count and so on
		raveTicks = raveGetTicks(raveResource, &raveOffset);
		if (raveTicks < 0)
			break;

		// get lipSyncID
		raveID = raveGetID(raveResource, &raveOffset);
		if (raveID) {
			raveLipSyncData = raveGetLipSyncData(raveID);
		} else {
			raveLipSyncData = NULL;
		}

#ifdef DEBUG_PORTRAIT
		if (raveID & 0x0ff) {
			debug("kPortrait: rave '%c%c' after %d ticks", raveID >> 8, raveID & 0x0ff, raveTicks);
		} else if (raveID) {
Beispiel #28
0
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;
}
Beispiel #29
0
	void close() {
		_in.close();
		_out.close();
	}
Beispiel #30
0
void dumpEveryResultAction(const Common::String &destFile) {
	Common::HashMap<Common::String, byte> count;
	Common::HashMap<Common::String, bool> fileAlreadyUsed;

	Common::DumpFile output;
	output.open(destFile);

	// Find scr files
	Common::ArchiveMemberList list;
	SearchMan.listMatchingMembers(list, "*.scr");

	for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
		Common::SeekableReadStream *stream = (*iter)->createReadStream();

		Common::String line = stream->readLine();
		trimCommentsAndWhiteSpace(&line);

		while (!stream->eos()) {
			if (line.matchString("*:add*", true)) {
				tryToDumpLine("add", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animplay*", true)) {
				tryToDumpLine("animplay", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animpreload*", true)) {
				tryToDumpLine("animpreload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animunload*", true)) {
				tryToDumpLine("animunload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:attenuate*", true)) {
				tryToDumpLine("attenuate", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:assign*", true)) {
				tryToDumpLine("assign", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:change_location*", true)) {
				tryToDumpLine("change_location", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:crossfade*", true) && !fileAlreadyUsed["add"]) {
				tryToDumpLine("crossfade", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:debug*", true)) {
				tryToDumpLine("debug", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:delay_render*", true)) {
				tryToDumpLine("delay_render", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:disable_control*", true)) {
				tryToDumpLine("disable_control", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:disable_venus*", true)) {
				tryToDumpLine("disable_venus", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:display_message*", true)) {
				tryToDumpLine("display_message", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:dissolve*", true)) {
				tryToDumpLine("dissolve", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:distort*", true)) {
				tryToDumpLine("distort", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:enable_control*", true)) {
				tryToDumpLine("enable_control", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:flush_mouse_events*", true)) {
				tryToDumpLine("flush_mouse_events", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:inventory*", true)) {
				tryToDumpLine("inventory", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:kill*", true)) {
				tryToDumpLine("kill", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:menu_bar_enable*", true)) {
				tryToDumpLine("menu_bar_enable", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:music*", true)) {
				tryToDumpLine("music", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:pan_track*", true)) {
				tryToDumpLine("pan_track", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:playpreload*", true)) {
				tryToDumpLine("playpreload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:preferences*", true)) {
				tryToDumpLine("preferences", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:quit*", true)) {
				tryToDumpLine("quit", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:random*", true)) {
				tryToDumpLine("random", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:region*", true)) {
				tryToDumpLine("region", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:restore_game*", true)) {
				tryToDumpLine("restore_game", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:rotate_to*", true)) {
				tryToDumpLine("rotate_to", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:save_game*", true)) {
				tryToDumpLine("save_game", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_partial_screen*", true)) {
				tryToDumpLine("set_partial_screen", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_screen*", true)) {
				tryToDumpLine("set_screen", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_venus*", true)) {
				tryToDumpLine("set_venus", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:stop*", true)) {
				tryToDumpLine("stop", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:streamvideo*", true)) {
				tryToDumpLine("streamvideo", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:syncsound*", true)) {
				tryToDumpLine("syncsound", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:timer*", true)) {
				tryToDumpLine("timer", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:ttytext*", true)) {
				tryToDumpLine("ttytext", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:universe_music*", true)) {
				tryToDumpLine("universe_music", line, &count, &fileAlreadyUsed, output);
			}

			line = stream->readLine();
			trimCommentsAndWhiteSpace(&line);
		}

		for (Common::HashMap<Common::String, bool>::iterator fileUsedIter = fileAlreadyUsed.begin(); fileUsedIter != fileAlreadyUsed.end(); ++fileUsedIter) {
			fileUsedIter->_value = false;
		}
	}

	output.close();
}