예제 #1
0
bool createIDMap(PAKFile &out, const Game *g, const int *needList) {
	int dataEntries = 0;
	// Count entries in the need list and check whether the resources are
	// present
	for (const int *n = needList; *n != -1; ++n) {
		char filename[12];
		if (!getFilename(filename, g, *n) || !out.getFileList()->findEntry(filename)) {
			fprintf(stderr, "ERROR: Could not find need %d for game %04X", *n, createGameDef(g));
			return false;
		}
		++dataEntries;
	}

	const int mapSize = 2 + dataEntries * (2 + 1 + 4);
	uint8 *map = new uint8[mapSize];
	uint8 *dst = map;

	WRITE_BE_UINT16(dst, dataEntries); dst += 2;
	for (const int *id = needList; *id != -1; ++id) {
		WRITE_BE_UINT16(dst, *id); dst += 2;
		const ExtractFilename *fDesc = getFilenameDesc(*id);
		if (!fDesc) {
			delete[] map;
			return false;
		}
		*dst++ = fDesc->type;
		WRITE_BE_UINT32(dst, getFilename(g, *id)); dst += 4;
	}

	char filename[12];
	if (!getFilename(filename, g, 0)) {
		fprintf(stderr, "ERROR: Could not create ID map for game\n");
		delete[] map;
		return false;
	}

	if (!out.addFile(filename, map, mapSize)) {
		fprintf(stderr, "ERROR: Could not add ID map \"%s\" to kyra.dat\n", filename);
		delete[] map;
		return false;
	}

	return true;
}
예제 #2
0
bool process(PAKFile &out, const Game *g, const byte *data, const uint32 size) {
	char filename[128];

	Search search(data, size);
	ExtractMap ids;

	if (!getExtractionData(g, search, ids))
		return false;

	const int *needList = getNeedList(g);
	if (!needList) {
		fprintf(stderr, "ERROR: No entry need list available\n");
		return false;
	}

	ExtractInformation extractInfo;
	extractInfo.game = g->game;
	extractInfo.platform = g->platform;
	extractInfo.special = g->special;

	for (ExtractMap::const_iterator i = ids.begin(); i != ids.end(); ++i) {
		const int id = i->first;
		extractInfo.lang = i->second.desc.lang;

		const ExtractFilename *fDesc = getFilenameDesc(id);

		if (!fDesc) {
			fprintf(stderr, "ERROR: couldn't find file description for id %d/%s\n", id, getIdString(id));
			return false;
		}

		filename[0] = 0;
		if (!getFilename(filename, &extractInfo, id)) {
			fprintf(stderr, "ERROR: couldn't get filename for id %d/%s\n", id, getIdString(id));
			return false;
		}

		const ExtractType *tDesc = findExtractType(fDesc->type);

		if (!tDesc) {
			fprintf(stderr, "ERROR: couldn't find type description for id %d/%s (%d)\n", id, getIdString(id), fDesc->type);
			return false;
		}

		PAKFile::cFileList *list = out.getFileList();
		if (list && list->findEntry(filename) != 0)
			continue;

		if (!tDesc->extract(out, &extractInfo, data + i->second.offset, i->second.desc.hint.size, filename, id)) {
			fprintf(stderr, "ERROR: couldn't extract id %d/%s\n", id, getIdString(id));
			return false;
		}
	}

	for (int i = 0; i < 3; ++i) {
		if (g->lang[i] == -1)
			continue;

		extractInfo.lang = g->lang[i];
		if (!createIDMap(out, &extractInfo, needList))
			return false;

		if (!updateIndex(out, &extractInfo)) {
			error("couldn't update INDEX file, stop processing of all files");
			return false;
		}
	}

	return true;
}