示例#1
0
bool Sword2Engine::initStartMenu() {
	// Print out a list of all the start points available.
	// There should be a linc produced file called startup.txt.
	// This file should contain ascii numbers of all the resource game
	// objects that are screen managers.
	// We query each in turn and setup an array of start structures.
	// If the file doesn't exist then we say so and return a 0.

	Common::File fp;

	// ok, load in the master screen manager file

	_totalStartups = 0;
	_totalScreenManagers = 0;

	if (!fp.open("startup.inf")) {
		warning("Cannot open startup.inf - the debugger won't have a start menu");
		return false;
	}

	// The startup.inf file which contains a list of all the files. Now
	// extract the filenames

	int start_ids[MAX_starts];
	int lineno = 0;

	while (!fp.eos() && !fp.ioFailed()) {
		Common::String line = fp.readLine();

		// Skip empty lines or, more likely, the end of the stream.
		if (line.size() == 0)
			continue;

		char *errptr;
		int id;

		lineno++;
		id = strtol(line.c_str(), &errptr, 10);

		if (*errptr) {
			warning("startup.inf:%d: Invalid string '%s'", lineno, line.c_str());
			continue;
		}

		if (!_resman->checkValid(id)) {
			warning("startup.inf:%d: Invalid resource %d", lineno, id);
			continue;
		}

		if (_resman->fetchType(id) != SCREEN_MANAGER) {
			warning("startup.inf:%d: '%s' (%d) is not a screen manager", lineno, _resman->fetchName(id), id);
			continue;
		}

		start_ids[_totalScreenManagers] = id;

		if (++_totalScreenManagers >= MAX_starts) {
			warning("Too many entries in startup.inf");
			break;
		}
	}

	// An I/O error before EOS? That's bad, but this is not a vital file.
	if (fp.ioFailed() && !fp.eos())
		warning("I/O error while reading startup.inf");

	fp.close();

	// Using this method the Gode generated resource.inf must have #0d0a
	// on the last entry

	debug(1, "%d screen manager objects", _totalScreenManagers);

	// Open each object and make a query call. The object must fill in a
	// startup structure. It may fill in several if it wishes - for
	// instance a startup could be set for later in the game where
	// specific vars are set

	for (uint i = 0; i < _totalScreenManagers; i++) {
		_startRes = start_ids[i];

		debug(2, "Querying screen manager %d", _startRes);

		// Open each one and run through the interpreter. Script 0 is
		// the query request script. We have already made reasonably
		// sure the resource is ok.

		_logic->runResScript(_startRes, 0);
	}

	return 1;
}
示例#2
0
bool ResourceManager::init() {
	uint32 i, j;

	// Until proven differently, assume we're on CD 1. This is so the start
	// dialog will be able to play any music at all.

	setCD(1);

	// We read in the resource info which tells us the names of the
	// resource cluster files ultimately, although there might be groups
	// within the clusters at this point it makes no difference. We only
	// wish to know what resource files there are and what is in each

	Common::File file;

	if (!file.open("resource.inf")) {
		_vm->GUIErrorMessage("Broken Sword 2: Cannot open resource.inf");
		return false;
	}

	// The resource.inf file is a simple text file containing the names of
	// all the resource files.

	while (file.readLine(_resFiles[_totalClusters].fileName, sizeof(_resFiles[_totalClusters].fileName))) {
		_resFiles[_totalClusters].numEntries = -1;
		_resFiles[_totalClusters].entryTab = NULL;
		if (++_totalClusters >= MAX_res_files) {
			_vm->GUIErrorMessage("Broken Sword 2: Too many entries in resource.inf");
			return false;
		}
	}

	file.close();

	// Now load in the binary id to res conversion table
	if (!file.open("resource.tab")) {
		_vm->GUIErrorMessage("Broken Sword 2: Cannot open resource.tab");
		return false;
	}

	// Find how many resources
	uint32 size = file.size();

	_totalResFiles = size / 4;

	// Table seems ok so malloc some space
	_resConvTable = (uint16 *)malloc(size);

	for (i = 0; i < size / 2; i++)
		_resConvTable[i] = file.readUint16LE();

	if (file.ioFailed()) {
		file.close();
		_vm->GUIErrorMessage("Broken Sword 2: Cannot read resource.tab");
		return false;
	}

	file.close();

	if (!file.open("cd.inf")) {
		_vm->GUIErrorMessage("Broken Sword 2: Cannot open cd.inf");
		return false;
	}

	CdInf *cdInf = new CdInf[_totalClusters];

	for (i = 0; i < _totalClusters; i++) {
		file.read(cdInf[i].clusterName, sizeof(cdInf[i].clusterName));

		cdInf[i].cd = file.readByte();

		if (file.ioFailed()) {
			delete cdInf;
			file.close();
			_vm->GUIErrorMessage("Broken Sword 2: Cannot read cd.inf");
			return false;
		}

		// It has been reported that there are two different versions
		// of the cd.inf file: One where all clusters on CD also have
		// the LOCAL_CACHE bit set. This bit is no longer used. To
		// avoid future problems, let's normalize the flag once and for
		// all here.

		if (cdInf[i].cd & LOCAL_PERM)
			cdInf[i].cd = 0;
		else if (cdInf[i].cd & CD1)
			cdInf[i].cd = 1;
		else if (cdInf[i].cd & CD2)
			cdInf[i].cd = 2;
		else
			cdInf[i].cd = 0;

		// Any file on "CD 0" may be needed at all times. Verify that
		// it exists. Any other missing cluster will be requested with
		// an "insert CD" message. Of course, the file may still vanish
		// during game-play (oh, that wascally wabbit!) in which case
		// the resource manager will print a fatal error.

		if (cdInf[i].cd == 0 && !Common::File::exists((char *)cdInf[i].clusterName)) {
			_vm->GUIErrorMessage("Broken Sword 2: Cannot find " + Common::String((char *)cdInf[i].clusterName));
			delete [] cdInf;
			return false;
		}
	}

	file.close();

	for (i = 0; i < _totalClusters; i++) {
		for (j = 0; j < _totalClusters; j++) {
			if (scumm_stricmp((char *)cdInf[j].clusterName, _resFiles[i].fileName) == 0)
				break;
		}

		if (j == _totalClusters) {
			delete [] cdInf;
			_vm->GUIErrorMessage(Common::String(_resFiles[i].fileName) + " is not in cd.inf");
			return false;
		}

		_resFiles[i].cd = cdInf[j].cd;
	}

	delete [] cdInf;

	debug(1, "%d resources in %d cluster files", _totalResFiles, _totalClusters);
	for (i = 0; i < _totalClusters; i++)
		debug(2, "filename of cluster %d: -%s (%d)", i, _resFiles[i].fileName, _resFiles[i].cd);

	_resList = (Resource *)malloc(_totalResFiles * sizeof(Resource));

	for (i = 0; i < _totalResFiles; i++) {
		_resList[i].ptr = NULL;
		_resList[i].size = 0;
		_resList[i].refCount = 0;
		_resList[i].prev = _resList[i].next = NULL;
	}

	return true;
}