diff options
| -rw-r--r-- | engines/sci/engine/kfile.cpp | 162 | ||||
| -rw-r--r-- | engines/sci/engine/kgraphics.cpp | 1 | ||||
| -rw-r--r-- | engines/sci/engine/selector.cpp | 3 | ||||
| -rw-r--r-- | engines/sci/engine/selector.h | 4 | ||||
| -rw-r--r-- | engines/sci/engine/state.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/state.h | 12 | ||||
| -rw-r--r-- | engines/sci/sci.cpp | 21 | ||||
| -rw-r--r-- | engines/sci/sci.h | 6 | 
8 files changed, 131 insertions, 80 deletions
| diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index a76c96cfea..2eb4580f4f 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -101,13 +101,9 @@ enum { -reg_t file_open(EngineState *s, const char *filename, int mode) { -	// QfG3 character import prepends /\ to the filenames. -	if (filename[0] == '/' && filename[1] == '\\') -		filename += 2; - +reg_t file_open(EngineState *s, const char *filename, int mode, bool unwrapFilename) {  	Common::String englishName = g_sci->getSciLanguageString(filename, K_LANG_ENGLISH); -	const Common::String wrappedName = g_sci->wrapFilename(englishName); +	Common::String wrappedName = unwrapFilename ? g_sci->wrapFilename(englishName) : englishName;  	Common::SeekableReadStream *inFile = 0;  	Common::WriteStream *outFile = 0;  	Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); @@ -183,7 +179,7 @@ reg_t kFOpen(EngineState *s, int argc, reg_t *argv) {  	int mode = argv[1].toUint16();  	debugC(2, kDebugLevelFile, "kFOpen(%s,0x%x)", name.c_str(), mode); -	return file_open(s, name.c_str(), mode); +	return file_open(s, name.c_str(), mode, true);  }  static FileHandle *getFileFromHandle(EngineState *s, uint handle) { @@ -739,45 +735,6 @@ reg_t kValidPath(EngineState *s, int argc, reg_t *argv) {  	return make_reg(0, 1);  } -reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) { -	// Verify that we are given a valid buffer -	if (!buffer.segment) { -		error("DirSeeker::firstFile('%s') invoked with invalid buffer", mask.c_str()); -		return NULL_REG; -	} -	_outbuffer = buffer; - -	// Prefix the mask -	const Common::String wrappedMask = g_sci->wrapFilename(mask); - -	// Obtain a list of all savefiles matching the given mask -	Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); -	_savefiles = saveFileMan->listSavefiles(wrappedMask); - -	// Reset the list iterator and write the first match to the output buffer, -	// if any. -	_iter = _savefiles.begin(); -	return nextFile(segMan); -} - -reg_t DirSeeker::nextFile(SegManager *segMan) { -	if (_iter == _savefiles.end()) { -		return NULL_REG; -	} - -	const Common::String wrappedString = *_iter; - -	// Strip the prefix -	Common::String string = g_sci->unwrapFilename(wrappedString); -	if (string.size() > 12) -		string = Common::String(string.c_str(), 12); -	segMan->strcpy(_outbuffer, string.c_str()); - -	// Return the result and advance the list iterator :) -	++_iter; -	return _outbuffer; -} -  reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {  	if (!s)  		return make_reg(0, getSciVersion()); @@ -790,6 +747,7 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {  	// SCI32 can call K_FILEIO_OPEN with only one argument. It seems to  	// just be checking if it exists.  	int mode = (argc < 2) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[1].toUint16(); +	bool unwrapFilename = true;  	// SQ4 floppy prepends /\ to the filenames  	if (name.hasPrefix("/\\")) { @@ -813,6 +771,12 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {  	}  	debugC(2, kDebugLevelFile, "kFileIO(open): %s, 0x%x", name.c_str(), mode); +	// QFG import rooms get a virtual filelisting instead of an actual one +	if (g_sci->inQfGImportRoom()) { +		// we need to find out what the user actually selected, "savedHeroes" is already destroyed +		//  when we get here. That's why we need to remember selection via kDrawControl +		name = s->_dirseeker.getVirtualFilename(s->_chosenQfGImportItem); +		unwrapFilename = false;  	// Since we're not wrapping/unwrapping save files for QFG import screens,  	// the name of the save file will almost certainly be over 12 characters in  	// length. Compensate for that fact here, by cutting off the last character @@ -835,7 +799,7 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {  		}  	} -	return file_open(s, name.c_str(), mode); +	return file_open(s, name.c_str(), mode, unwrapFilename);  }  reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { @@ -962,24 +926,104 @@ reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) {  	return SIGNAL_REG;  } +void DirSeeker::addAsVirtualFiles(Common::String title, Common::String fileMask) { +	Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); +	Common::StringArray foundFiles = saveFileMan->listSavefiles(fileMask); +	if (!foundFiles.empty()) { +		_files.push_back(title); +		_virtualFiles.push_back(""); +		Common::StringArray::iterator it; +		Common::StringArray::iterator it_end = foundFiles.end(); +		for (it = foundFiles.begin(); it != it_end; it++) { +			Common::String regularFilename = *it; +			Common::String wrappedFilename = Common::String(regularFilename.c_str() + fileMask.size() - 1); +			// We need to remove the prefix for display purposes +			_files.push_back(wrappedFilename); +			// but remember the actual name as well +			_virtualFiles.push_back(regularFilename); +		} +	} +} + +Common::String DirSeeker::getVirtualFilename(uint fileNumber) { +	if (fileNumber >= _virtualFiles.size()) +		error("invalid virtual filename access"); +	return _virtualFiles[fileNumber]; +} + +reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) { +	// Verify that we are given a valid buffer +	if (!buffer.segment) { +		error("DirSeeker::firstFile('%s') invoked with invalid buffer", mask.c_str()); +		return NULL_REG; +	} +	_outbuffer = buffer; +	_files.clear(); +	_virtualFiles.clear(); + +	int QfGImport = g_sci->inQfGImportRoom(); +	if (QfGImport) { +		_files.clear(); +		addAsVirtualFiles("-QfG1-", "qfg1-*"); +		addAsVirtualFiles("-QfG1VGA-", "qfg1vga-*"); +		if (QfGImport > 2) +			addAsVirtualFiles("-QfG2-", "qfg2-*"); +		if (QfGImport > 3) +			addAsVirtualFiles("-QfG3-", "qfg3-*"); + +		if (QfGImport == 3) { +			// QfG3 sorts the filelisting itself, we can't let that happen otherwise our +			//  virtual list would go out-of-sync +			SegManager *segMan = g_sci->getEngineState()->_segMan; +			reg_t savedHeros = segMan->findObjectByName("savedHeros"); +			if (!savedHeros.isNull()) +				writeSelectorValue(segMan, savedHeros, SELECTOR(sort), 0); +		} + +	} else { +		// Prefix the mask +		const Common::String wrappedMask = g_sci->wrapFilename(mask); + +		// Obtain a list of all files matching the given mask +		Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); +		_files = saveFileMan->listSavefiles(wrappedMask); +	} + +	// Reset the list iterator and write the first match to the output buffer, +	// if any. +	_iter = _files.begin(); +	return nextFile(segMan); +} + +reg_t DirSeeker::nextFile(SegManager *segMan) { +	if (_iter == _files.end()) { +		return NULL_REG; +	} + +	Common::String string; + +	if (_virtualFiles.empty()) { +		// Strip the prefix, if we don't got a virtual filelisting +		const Common::String wrappedString = *_iter; +		string = g_sci->unwrapFilename(wrappedString); +	} else { +		string = *_iter; +	} +	if (string.size() > 12) +		string = Common::String(string.c_str(), 12); +	segMan->strcpy(_outbuffer, string.c_str()); + +	// Return the result and advance the list iterator :) +	++_iter; +	return _outbuffer; +} +  reg_t kFileIOFindFirst(EngineState *s, int argc, reg_t *argv) {  	Common::String mask = s->_segMan->getString(argv[0]);  	reg_t buf = argv[1];  	int attr = argv[2].toUint16(); // We won't use this, Win32 might, though...  	debugC(2, kDebugLevelFile, "kFileIO(findFirst): %s, 0x%x", mask.c_str(), attr); -	// Change the file mask in QFG character import screens. The game -	// is looking for *.*, but that may well include other files as well, -	// thus limit the file mask to only include exported characters. -	if (g_sci->isQFGImportScreen()) -		mask = "qfg*.sav"; - -	// QfG3 uses "/\*.*" for the character import, QfG4 uses "/\*" -	if (mask.hasPrefix("/\\")) { -		mask.deleteChar(0); -		mask.deleteChar(0); -	} -  	// We remove ".*". mask will get prefixed, so we will return all additional files for that gameid  	if (mask == "*.*")  		mask = "*"; diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 4e0306106b..e19a51b525 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -944,6 +944,7 @@ reg_t kDrawControl(EngineState *s, int argc, reg_t *argv) {  						"for Quest for Glory 2. Example: 'qfg2-thief.sav'.");  			}  		} +		s->_chosenQfGImportItem = readSelectorValue(s->_segMan, controlObject, SELECTOR(mark));  	}  	_k_GenericDrawControl(s, controlObject, false); diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index f5eb9eb73a..436a4b98ff 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -86,7 +86,8 @@ void Kernel::mapSelectors() {  	// window  	FIND_SELECTOR(cursor);  	FIND_SELECTOR(max); -	// mark +	FIND_SELECTOR(mark); +	FIND_SELECTOR(sort);  	// who  	FIND_SELECTOR(message);  	// edit diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index 661290f58c..63ec11fab1 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -58,7 +58,9 @@ struct SelectorCache {  	Selector state, font, type;///< Used by controls  	// window  	Selector cursor, max; ///< Used by EditControl -	// mark, who +	Selector mark; //< Used by list controls +	Selector sort; //< Used by list controls (script internal, is needed by us for QfG3 import room) +	// who  	Selector message; ///< Used by GetEvent  	// edit  	Selector play; ///< Play function (first function to be called) diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 5e0e7e21d5..bbdab6f7f0 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -110,6 +110,8 @@ void EngineState::reset(bool isRestoring) {  	_lastSaveVirtualId = SAVEGAMEID_OFFICIALRANGE_START;  	_lastSaveNewId = 0; +	_chosenQfGImportItem = 0; +  	scriptStepCounter = 0;  	scriptGCInterval = GC_INTERVAL;  } diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index ca5232022e..42294fa08c 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -59,17 +59,23 @@ enum AbortGameState {  class DirSeeker {  protected:  	reg_t _outbuffer; -	Common::StringArray _savefiles; +	Common::StringArray _files; +	Common::StringArray _virtualFiles;  	Common::StringArray::const_iterator _iter;  public:  	DirSeeker() {  		_outbuffer = NULL_REG; -		_iter = _savefiles.begin(); +		_iter = _files.begin();  	}  	reg_t firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan);  	reg_t nextFile(SegManager *segMan); + +	Common::String getVirtualFilename(uint fileNumber); + +private: +	void addAsVirtualFiles(Common::String title, Common::String fileMask);  };  enum { @@ -139,6 +145,8 @@ public:  	int16 _lastSaveVirtualId; // last virtual id fed to kSaveGame, if no kGetSaveFiles was called inbetween  	int16 _lastSaveNewId;    // last newly created filename-id by kSaveGame +	uint _chosenQfGImportItem; // Remembers the item selected in QfG import rooms +  public:  	/* VM Information */ diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index cb36ebd0f5..f9f89ea1ae 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -641,34 +641,27 @@ Common::String SciEngine::getFilePrefix() const {  }  Common::String SciEngine::wrapFilename(const Common::String &name) const { -	// Do not wrap the game prefix when reading files in QFG import screens. -	// That way, we can read exported characters from all QFG games, as -	// intended. -	return !isQFGImportScreen() ? getFilePrefix() + "-" + name : name; +	return getFilePrefix() + "-" + name;  }  Common::String SciEngine::unwrapFilename(const Common::String &name) const {  	Common::String prefix = getFilePrefix() + "-"; -	// Do not unwrap the file name when reading files in QFG import screens. -	// We don't wrap the game ID prefix in these screens in order to read -	// save states from all QFG games. -	if (name.hasPrefix(prefix.c_str()) && !isQFGImportScreen()) +	if (name.hasPrefix(prefix.c_str()))  		return Common::String(name.c_str() + prefix.size());  	return name;  } -bool SciEngine::isQFGImportScreen() const { +int SciEngine::inQfGImportRoom() const {  	if (_gameId == GID_QFG2 && _gamestate->currentRoomNumber() == 805) {  		// QFG2 character import screen -		return true; +		return 2;  	} else if (_gameId == GID_QFG3 && _gamestate->currentRoomNumber() == 54) {  		// QFG3 character import screen -		return true; +		return 3;  	} else if (_gameId == GID_QFG4 && _gamestate->currentRoomNumber() == 54) { -		return true; -	} else { -		return false; +		return 4;  	} +	return 0;  }  void SciEngine::pauseEngineIntern(bool pause) { diff --git a/engines/sci/sci.h b/engines/sci/sci.h index aaa53367a7..a620f6cd09 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -251,10 +251,10 @@ public:  	Common::String unwrapFilename(const Common::String &name) const;  	/** -	 * Checks if we are in a QFG import screen, where special handling -	 * of save states is performed. +	 * Checks if we are in a QfG import screen, where special handling +	 * of file-listings is performed.  	 */ -	bool isQFGImportScreen() const; +	int inQfGImportRoom() const;  	void sleep(uint32 msecs); | 
