Example #1
0
/**
 * Formats AGI string.
 * This function turns a AGI string into a real string expanding values
 * according to the AGI format specifiers.
 * @param s  string containing the format specifier
 * @param n  logic number
 */
char *AgiEngine::agiSprintf(const char *s) {
	static char agiSprintf_buf[768];
	Common::String p;
	char z[16];

	debugC(3, kDebugLevelText, "logic %d, '%s'", _game.lognum, s);

	while (*s) {
		switch (*s) {
		case '%':
			s++;
			switch (*s++) {
				int i;
			case 'v':
				i = strtoul(s, NULL, 10);
				while (*s >= '0' && *s <= '9')
					s++;
				sprintf(z, "%015i", getvar(i));

				i = 99;
				if (*s == '|') {
					s++;
					i = strtoul(s, NULL, 10);
					while (*s >= '0' && *s <= '9')
						s++;
				}

				if (i == 99) {
					// remove all leading 0
					// don't remove the 3rd zero if 000
					for (i = 0; z[i] == '0' && i < 14; i++)
						;
				} else {
					i = 15 - i;
				}
				safeStrcat(p, z + i);
				break;
			case '0':
				i = strtoul(s, NULL, 10) - 1;
				safeStrcat(p, objectName(i));
				break;
			case 'g':
				i = strtoul(s, NULL, 10) - 1;
				safeStrcat(p, _game.logics[0].texts[i]);
				break;
			case 'w':
				i = strtoul(s, NULL, 10) - 1;
				safeStrcat(p, _game.egoWords[i].word);
				break;
			case 's':
				i = strtoul(s, NULL, 10);
				safeStrcat(p, agiSprintf(_game.strings[i]));
				break;
			case 'm':
				i = strtoul(s, NULL, 10) - 1;
				if (_game.logics[_game.lognum].numTexts > i)
					safeStrcat(p, agiSprintf(_game.logics[_game.lognum].texts[i]));
				break;
			}

			while (*s >= '0' && *s <= '9')
				s++;
			break;

		case '\\':
			s++;
			// FALL THROUGH

		default:
			p += *s++;
			break;
		}
	}

	assert(p.size() < sizeof(agiSprintf_buf));
	strcpy(agiSprintf_buf, p.c_str());
	return agiSprintf_buf;
}
void OneDriveListDirectoryRequest::makeRequest(Common::String url) {
	Networking::JsonCallback callback = new Common::Callback<OneDriveListDirectoryRequest, Networking::JsonResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryCallback);
	Networking::ErrorCallback failureCallback = new Common::Callback<OneDriveListDirectoryRequest, Networking::ErrorResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryErrorCallback);
	Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(_storage, callback, failureCallback, url.c_str());
	request->addHeader("Authorization: Bearer " + _storage->accessToken());
	_workingRequest = ConnMan.addRequest(request);
}
Example #3
0
void Lingo::call(Common::String &name, int nargs) {
	bool drop = false;

	Symbol *sym;

	if (!g_lingo->_handlers.contains(name)) {
		Symbol *s = g_lingo->lookupVar(name.c_str(), false);
		if (s && s->type == OBJECT) {
			debugC(3, kDebugLingoExec,  "Dereferencing object reference: %s to %s", name.c_str(), s->u.s->c_str());
			name = *s->u.s;
		}
	}

	if (!g_lingo->_handlers.contains(name)) {
		warning("Call to undefined handler '%s'. Dropping %d stack items", name.c_str(), nargs);
		drop = true;
	} else {
		sym = g_lingo->_handlers[name];

		if (sym->type == BLTIN && sym->nargs != -1 && sym->nargs != nargs && sym->maxArgs != nargs) {
			if (sym->nargs == sym->maxArgs)
				warning("Incorrect number of arguments to handler '%s', expecting %d. Dropping %d stack items", name.c_str(), sym->nargs, nargs);
			else
				warning("Incorrect number of arguments to handler '%s', expecting %d or %d. Dropping %d stack items", name.c_str(), sym->nargs, sym->maxArgs, nargs);

			drop = true;
		}
	}

	if (drop) {
		for (int i = 0; i < nargs; i++)
			g_lingo->pop();

		// Push dummy value
		g_lingo->pushVoid();

		return;
	}

	if (sym->nargs != -1 && sym->nargs < nargs) {
		warning("Incorrect number of arguments for function %s. Dropping extra %d", name.c_str(), nargs - sym->nargs);
		for (int i = 0; i < nargs - sym->nargs; i++)
			g_lingo->pop();
	}

	if (sym->type == BLTIN) {
		if (sym->u.bltin == b_factory)
			g_lingo->factoryCall(name, nargs);
		else
			(*sym->u.bltin)(nargs);

		return;
	}

	for (int i = nargs; i < sym->nargs; i++) {
		Datum d;

		d.u.s = NULL;
		d.type = VOID;
		g_lingo->push(d);
	}

	debugC(5, kDebugLingoExec, "Pushing frame %d", g_lingo->_callstack.size() + 1);
	CFrame *fp = new CFrame;

	fp->sp = sym;
	fp->retpc = g_lingo->_pc;
	fp->retscript = g_lingo->_currentScript;
	fp->localvars = g_lingo->_localvars;

	// Create new set of local variables
	g_lingo->_localvars = new SymbolHash;

	g_lingo->_callstack.push_back(fp);

	g_lingo->_currentScript = sym->u.defn;
	g_lingo->execute(0);

	g_lingo->_returning = false;
}
Example #4
0
void OSpit::xbookclick(const ArgumentArray &args) {
	// Let's hook onto our video
	RivenVideo *video = _vm->_video->getSlot(args[0]);

	// Convert from the standard QuickTime base time to milliseconds
	// The values are in terms of 1/600 of a second.
	// Have I said how much I just *love* QuickTime? </sarcasm>
	uint32 startTime = args[1] * 1000 / 600;
	uint32 endTime = args[2] * 1000 / 600;

	// Track down our hotspot
	Common::String hotspotName = Common::String::format("touchBook%d", args[3]);
	RivenHotspot *hotspot = _vm->getCard()->getHotspotByName(hotspotName);
	Common::Rect hotspotRect = hotspot->getRect();

	debug(0, "xbookclick:");
	debug(0, "\tVideo Code = %d", args[0]);
	debug(0, "\tStart Time = %dms", startTime);
	debug(0, "\tEnd Time   = %dms", endTime);
	debug(0, "\tHotspot    = %d -> %s", args[3], hotspotName.c_str());

	// Just let the video play while we wait until Gehn opens the trap book for us
	while (video->getTime() < startTime && !_vm->hasGameEnded()) {
		_vm->doFrame();
	}

	// Break out if we're quitting
	if (_vm->hasGameEnded())
		return;

	// OK, Gehn has opened the trap book and has asked us to go in. Let's watch
	// and see what the player will do...
	while (video->getTime() < endTime && !_vm->hasGameEnded()) {
		if (hotspotRect.contains(getMousePosition()))
			_vm->_cursor->setCursor(kRivenOpenHandCursor);
		else
			_vm->_cursor->setCursor(kRivenMainCursor);

		if (mouseIsDown()) {
			if (hotspotRect.contains(getMousePosition())) {
				// OK, we've used the trap book! We go for ride lady!
				_vm->_video->closeVideos();                          // Stop all videos
				_vm->_cursor->setCursor(kRivenHideCursor);          // Hide the cursor
				_vm->_gfx->scheduleTransition(kRivenTransitionBlend);
				_vm->getCard()->drawPicture(3);                  // Black out the screen
				_vm->_sound->playSound(0);                          // Play the link sound
				_vm->delay(12000);
				_vm->getCard()->playMovie(7);    // Activate Gehn Link Video
				RivenVideo *linkVideo = _vm->_video->openSlot(1);             // Play Gehn Link Video
				linkVideo->playBlocking();
				_vm->_vars["ocage"] = 1;
				_vm->_vars["agehn"] = 4;                            // Set Gehn to the trapped state
				_vm->_vars["atrapbook"] = 1;                        // We've got the trap book again
				_vm->_sound->playSound(0);                          // Play the link sound again
				_vm->_gfx->scheduleTransition(kRivenTransitionBlend);
				_vm->changeToCard(_vm->getStack()->getCardStackId(0x2885));    // Link out!
				_vm->_inventory->forceVisible(true);
				_vm->delay(2000);
				_vm->_inventory->forceVisible(false);
				_vm->_scriptMan->stopAllScripts();                  // Stop all running scripts (so we don't remain in the cage)
				return;
			}
		}

		_vm->doFrame();
	}

	// Break out if we're quitting
	if (_vm->hasGameEnded())
		return;

	// If there was no click and this is the third time Gehn asks us to
	// use the trap book, he will shoot the player. Dead on arrival.
	// Run the credits from here.
	if (_vm->_vars["agehn"] == 3) {
		_vm->_scriptMan->stopAllScripts();
		runCredits(args[0], 5000);
		return;
	}

	// There was no click, so just play the rest of the video.
	video->playBlocking();
}
Example #5
0
void MinigameBbAnt::loadSounds() {
	for (uint i = 0; i < kSoundFilenamesCount; ++i) {
		Common::String filename = Common::String::format("bbant/%s", kSoundFilenames[i]);
		_vm->_sound->loadSound(filename.c_str());
	}
}
Example #6
0
	const char *slide() const {
		return _slide.c_str();
	}
Example #7
0
// TODO: specify the possible return values here
static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const Common::String &edebuglevels) {
	// Determine the game data path, for validation and error messages
	Common::FSNode dir(ConfMan.get("path"));
	Common::Error err = Common::kNoError;
	Engine *engine = 0;

	// Verify that the game path refers to an actual directory
	if (!(dir.exists() && dir.isDirectory()))
		err = Common::kPathNotDirectory;

	// Create the game engine
	if (err.getCode() == Common::kNoError)
		err = (*plugin)->createInstance(&system, &engine);

	// Check for errors
	if (!engine || err.getCode() != Common::kNoError) {

		// Print a warning; note that scummvm_main will also
		// display an error dialog, so we don't have to do this here.
		warning("%s failed to instantiate engine: %s (target '%s', path '%s')",
			plugin->getName(),
			err.getDesc().c_str(),
			ConfMan.getActiveDomainName().c_str(),
			dir.getPath().c_str()
			);

		// Autoadded is set only when no path was provided and
		// the game is run from command line.
		//
		// Thus, we remove this garbage entry
		//
		// Fixes bug #1544799
		if (ConfMan.hasKey("autoadded")) {
			ConfMan.removeGameDomain(ConfMan.getActiveDomainName().c_str());
		}

		return err;
	}

	// Set the window caption to the game name
	Common::String caption(ConfMan.get("description"));

	if (caption.empty()) {
		caption = EngineMan.findGame(ConfMan.get("gameid")).description();
	}
	if (caption.empty())
		caption = ConfMan.getActiveDomainName();	// Use the domain (=target) name
	if (!caption.empty())	{
		system.setWindowCaption(caption.c_str());
	}

	//
	// Setup various paths in the SearchManager
	//

	// Add the game path to the directory search list
	SearchMan.addDirectory(dir.getPath(), dir, 0, 4);

	// Add extrapath (if any) to the directory search list
	if (ConfMan.hasKey("extrapath")) {
		dir = Common::FSNode(ConfMan.get("extrapath"));
		SearchMan.addDirectory(dir.getPath(), dir);
	}

	// If a second extrapath is specified on the app domain level, add that as well.
	if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain)) {
		dir = Common::FSNode(ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain));
		SearchMan.addDirectory(dir.getPath(), dir);
	}

	// On creation the engine should have set up all debug levels so we can use
	// the command line arugments here
	Common::StringTokenizer tokenizer(edebuglevels, " ,");
	while (!tokenizer.empty()) {
		Common::String token = tokenizer.nextToken();
		if (!DebugMan.enableDebugChannel(token))
			warning(_("Engine does not support debug level '%s'"), token.c_str());
	}

	// Inform backend that the engine is about to be run
	system.engineInit();

	// Run the engine
	Common::Error result = engine->run();

	// Inform backend that the engine finished
	system.engineDone();

	// Free up memory
	delete engine;

	// We clear all debug levels again even though the engine should do it
	DebugMan.clearAllDebugChannels();

	// Reset the file/directory mappings
	SearchMan.clear();

	// Return result (== 0 means no error)
	return result;
}
Example #8
0
Common::Error Saver::restore(int slot) {
	assert(!getMacroRestoreFlag());
	Common::StackLock slock1(g_globals->_soundManager._serverDisabledMutex);

	// Signal any objects registered for notification
	_loadNotifiers.notify(false);

	// Set fields
	_macroRestoreFlag = true;
	_saveSlot = slot;
	_unresolvedPtrs.clear();

	// Set up the serializer
	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(g_vm->generateSaveName(slot));
	if (!saveFile)
		return Common::kReadingFailed;

	Serializer serializer(saveFile, NULL);

	// Read in the savegame header
	tSageSavegameHeader header;
	readSavegameHeader(saveFile, header);
	if (header.thumbnail)
		header.thumbnail->free();
	delete header.thumbnail;

	serializer.setSaveVersion(header.version);

	// Load in data for objects that need to come at the start of the savegame
	for (Common::List<SaveListener *>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) {
		(*i)->listenerSynchronize(serializer);
	}

	// Loop through each registered object to load in the data
	for (SynchronizedList<SavedObject *>::iterator i = _objList.begin(); i != _objList.end(); ++i) {
		serializer.validate((*i)->getClassName());
		(*i)->synchronize(serializer);
	}

	// Loop through the remaining data of the file, instantiating new objects.
	// Note: I don't store pointers to instantiated objects here, because it's not necessary - the mere act
	// of instantiating a saved object registers it with the saver, and will then be resolved to whatever
	// object originally had a pointer to it as part of the post-processing step
	Common::String className;
	serializer.syncString(className);
	while (className != "END") {
		SavedObject *savedObject;
		if (!_factoryPtr || ((savedObject = _factoryPtr(className)) == NULL))
			error("Unknown class name '%s' encountered trying to restore savegame", className.c_str());

		// Populate the contents of the object
		savedObject->synchronize(serializer);

		// Move to next object
		serializer.syncString(className);
	}

	// Post-process any unresolved pointers to get the correct pointer
	resolveLoadPointers();

	delete saveFile;

	// Final post-restore notifications
	_macroRestoreFlag = false;
	_loadNotifiers.notify(true);

	return Common::kNoError;
}
Example #9
0
Common::String SciEngine::getSciLanguageString(const Common::String &str, kLanguage requestedLanguage, kLanguage *secondaryLanguage, uint16 *languageSplitter) const {
	kLanguage foundLanguage = K_LANG_NONE;
	const byte *textPtr = (const byte *)str.c_str();
	byte curChar = 0;
	byte curChar2 = 0;
	
	while (1) {
		curChar = *textPtr;
		if (!curChar)
			break;
		
		if ((curChar == '%') || (curChar == '#')) {
			curChar2 = *(textPtr + 1);
			foundLanguage = charToLanguage(curChar2);

			if (foundLanguage != K_LANG_NONE) {
				// Return language splitter
				if (languageSplitter)
					*languageSplitter = curChar | ( curChar2 << 8 );
				// Return the secondary language found in the string
				if (secondaryLanguage)
					*secondaryLanguage = foundLanguage;
				break;
			}
		}
		textPtr++;
	}

	if (foundLanguage == requestedLanguage) {
		if (curChar2 == 'J') {
			// Japanese including Kanji, displayed with system font
			// Convert half-width characters to full-width equivalents
			Common::String fullWidth;
			uint16 mappedChar;

			textPtr += 2; // skip over language splitter

			while (1) {
				curChar = *textPtr;
				
				switch (curChar) {
				case 0: // Terminator NUL
					return fullWidth;
				case '\\':
					// "\n", "\N", "\r" and "\R" were overwritten with SPACE + 0x0D in PC-9801 SSCI
					//  inside GetLongest() (text16). We do it here, because it's much cleaner and
					//  we have to process the text here anyway.
					//  Occurs for example in Police Quest 2 intro
					curChar2 = *(textPtr + 1);
					switch (curChar2) {
					case 'n':
					case 'N':
					case 'r':
					case 'R':
						fullWidth += ' ';
						fullWidth += 0x0D; // CR
						textPtr += 2;
						continue;
					}
				}
				
				textPtr++;

				mappedChar = s_halfWidthSJISMap[curChar];
				if (mappedChar) {
					fullWidth += mappedChar >> 8;
					fullWidth += mappedChar & 0xFF;
				} else {
					// Copy double-byte character
					curChar2 = *(textPtr++);
					if (!curChar) {
						error("SJIS character %02X is missing second byte", curChar);
						break;
					}
					fullWidth += curChar;
					fullWidth += curChar2;
				}
			}

		} else {
Example #10
0
static bool isValidDomainName(const Common::String &domName) {
	const char *p = domName.c_str();
	while (*p && (Common::isAlnum(*p) || *p == '-' || *p == '_'))
		p++;
	return *p == 0;
}
Example #11
0
void MohawkEngine_CSTime::loadResourceFile(Common::String name) {
	MohawkArchive *archive = new MohawkArchive();
	if (!archive->open(name + ".mhk"))
		error("failed to open %s.mhk", name.c_str());
	_mhk.push_back(archive);
}
Example #12
0
void ScriptLifeV1::SAY_MESSAGE_OBJ() {
	byte actor = getParamByte();
	uint16 id = getParamUint16();
	Common::String str = g_resource->getMessage(0, id);
	warning("STUB: SAY_MESSAGE_OBJ(%d): %s", id, str.c_str());
}
Example #13
0
const char *ToltecsEngine::getSavegameFilename(int num) {
	static Common::String filename;
	filename = getSavegameFilename(_targetName, num);
	return filename.c_str();
}
Example #14
0
Common::Error ToltecsEngine::saveGameState(int slot, const Common::String &description) {
	const char *fileName = getSavegameFilename(slot);
	savegame(fileName, description.c_str());
	return Common::kNoError;
}
Example #15
0
	const char *location() const {
		return _location.c_str();
	}
Example #16
0
bool NSArchive::hasFile(const Common::String &name) const {
	if (name.empty())
		return false;
	return lookup(name.c_str()) != _numFiles;
}
Example #17
0
	const char *character() const {
		return _character.c_str();
	}
Example #18
0
void ConsoleDialog::handleKeyDown(Common::KeyState state) {
	int i;

	if (_slideMode != kNoSlideMode)
		return;

	switch (state.keycode) {
	case Common::KEYCODE_RETURN:
	case Common::KEYCODE_KP_ENTER: {
		if (_caretVisible)
			drawCaret(true);

		nextLine();

		assert(_promptEndPos >= _promptStartPos);
		int len = _promptEndPos - _promptStartPos;
		bool keepRunning = true;


		if (len > 0) {

			// We have to allocate the string buffer with new, since VC++ sadly does not
			// comply to the C++ standard, so we can't use a dynamic sized stack array.
			char *str = new char[len + 1];

			// Copy the user input to str
			for (i = 0; i < len; i++)
				str[i] = buffer(_promptStartPos + i);
			str[len] = '\0';

			// Add the input to the history
			addToHistory(str);

			// Pass it to the input callback, if any
			if (_callbackProc)
				keepRunning = (*_callbackProc)(this, str, _callbackRefCon);

				// Get rid of the string buffer
			delete[] str;
		}

		print(PROMPT);
		_promptStartPos = _promptEndPos = _currentPos;

		draw();
		if (!keepRunning)
			slideUpAndClose();
		break;
		}

	case Common::KEYCODE_ESCAPE:
		slideUpAndClose();
		break;

	case Common::KEYCODE_BACKSPACE:
		if (_caretVisible)
			drawCaret(true);

		if (_currentPos > _promptStartPos) {
			_currentPos--;
			killChar();
		}
		scrollToCurrent();
		drawLine(pos2line(_currentPos));
		break;

	case Common::KEYCODE_TAB: {
		if (_completionCallbackProc) {
			int len = _currentPos - _promptStartPos;
			assert(len >= 0);
			char *str = new char[len + 1];

			// Copy the user input to str
			for (i = 0; i < len; i++)
				str[i] = buffer(_promptStartPos + i);
			str[len] = '\0';

			Common::String completion;
			if ((*_completionCallbackProc)(this, str, completion, _callbackRefCon)) {
				if (_caretVisible)
					drawCaret(true);
				insertIntoPrompt(completion.c_str());
				scrollToCurrent();
				drawLine(pos2line(_currentPos));
			}
			delete[] str;
		}
		break;
		}

	// Keypad & special keys
	//   - if num lock is set, we always go to the default case
	//   - if num lock is not set, we either fall down to the special key case
	//     or ignore the key press in case of 0 (INSERT) or 5

	case Common::KEYCODE_KP0:
	case Common::KEYCODE_KP5:
		if (state.flags & Common::KBD_NUM)
			defaultKeyDownHandler(state);
		break;

	case Common::KEYCODE_KP_PERIOD:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_DELETE:
		if (_currentPos < _promptEndPos) {
			killChar();
			drawLine(pos2line(_currentPos));
		}
		break;

	case Common::KEYCODE_KP1:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_END:
		if (state.hasFlags(Common::KBD_SHIFT)) {
			_scrollLine = _promptEndPos / kCharsPerLine;
			if (_scrollLine < _linesPerPage - 1)
				_scrollLine = _linesPerPage - 1;
			updateScrollBuffer();
		} else {
			_currentPos = _promptEndPos;
		}
		draw();
		break;

	case Common::KEYCODE_KP2:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_DOWN:
		historyScroll(-1);
		break;

	case Common::KEYCODE_KP3:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_PAGEDOWN:
		if (state.hasFlags(Common::KBD_SHIFT)) {
			_scrollLine += _linesPerPage - 1;
			if (_scrollLine > _promptEndPos / kCharsPerLine) {
				_scrollLine = _promptEndPos / kCharsPerLine;
				if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1)
					_scrollLine = _firstLineInBuffer + _linesPerPage - 1;
			}
			updateScrollBuffer();
			draw();
		}
		break;

	case Common::KEYCODE_KP4:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_LEFT:
		if (_currentPos > _promptStartPos)
			_currentPos--;
		drawLine(pos2line(_currentPos));
		break;

	case Common::KEYCODE_KP6:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_RIGHT:
		if (_currentPos < _promptEndPos)
			_currentPos++;
		drawLine(pos2line(_currentPos));
		break;

	case Common::KEYCODE_KP7:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_HOME:
		if (state.hasFlags(Common::KBD_SHIFT)) {
			_scrollLine = _firstLineInBuffer + _linesPerPage - 1;
			updateScrollBuffer();
		} else {
			_currentPos = _promptStartPos;
		}
		draw();
		break;

	case Common::KEYCODE_KP8:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_UP:
		historyScroll(+1);
		break;

	case Common::KEYCODE_KP9:
		if (state.flags & Common::KBD_NUM) {
			defaultKeyDownHandler(state);
			break;
		}
	case Common::KEYCODE_PAGEUP:
		if (state.hasFlags(Common::KBD_SHIFT)) {
			_scrollLine -= _linesPerPage - 1;
			if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1)
				_scrollLine = _firstLineInBuffer + _linesPerPage - 1;
			updateScrollBuffer();
			draw();
		}
		break;

	default:
		defaultKeyDownHandler(state);
	}
}
Example #19
0
// TODO: specify the possible return values here
static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const Common::String &edebuglevels) {
	// Determine the game data path, for validation and error messages
	Common::FSNode dir(ConfMan.get("path"));
	Common::Error err = Common::kNoError;
	Engine *engine = 0;

#if defined(SDL_BACKEND) && defined(USE_OPENGL) && defined(USE_RGB_COLOR)
	// HACK: We set up the requested graphics mode setting here to allow the
	// backend to switch from Surface SDL to OpenGL if necessary. This is
	// needed because otherwise the g_system->getSupportedFormats might return
	// bad values.
	g_system->beginGFXTransaction();
		g_system->setGraphicsMode(ConfMan.get("gfx_mode").c_str());
	if (g_system->endGFXTransaction() != OSystem::kTransactionSuccess) {
		warning("Switching graphics mode to '%s' failed", ConfMan.get("gfx_mode").c_str());
		return Common::kUnknownError;
	}
#endif

	// Verify that the game path refers to an actual directory
        if (!dir.exists()) {
		err = Common::kPathDoesNotExist;
        } else if (!dir.isDirectory()) {
		err = Common::kPathNotDirectory;
        }

	// Create the game engine
	if (err.getCode() == Common::kNoError) {
		// Set default values for all of the custom engine options
		// Appareantly some engines query them in their constructor, thus we
		// need to set this up before instance creation.
		const ExtraGuiOptions engineOptions = (*plugin)->getExtraGuiOptions(Common::String());
		for (uint i = 0; i < engineOptions.size(); i++) {
			ConfMan.registerDefault(engineOptions[i].configOption, engineOptions[i].defaultState);
		}

		err = (*plugin)->createInstance(&system, &engine);
	}

	// Check for errors
	if (!engine || err.getCode() != Common::kNoError) {

		// Print a warning; note that scummvm_main will also
		// display an error dialog, so we don't have to do this here.
		warning("%s failed to instantiate engine: %s (target '%s', path '%s')",
			plugin->getName(),
			err.getDesc().c_str(),
			ConfMan.getActiveDomainName().c_str(),
			dir.getPath().c_str()
			);

		// Autoadded is set only when no path was provided and
		// the game is run from command line.
		//
		// Thus, we remove this garbage entry
		//
		// Fixes bug #1544799
		if (ConfMan.hasKey("autoadded")) {
			ConfMan.removeGameDomain(ConfMan.getActiveDomainName().c_str());
		}

		return err;
	}

	// Set the window caption to the game name
	Common::String caption(ConfMan.get("description"));

	if (caption.empty()) {
		caption = EngineMan.findGame(ConfMan.get("gameid")).description();
	}
	if (caption.empty())
		caption = ConfMan.getActiveDomainName();	// Use the domain (=target) name
	if (!caption.empty())	{
		system.setWindowCaption(caption.c_str());
	}

	//
	// Setup various paths in the SearchManager
	//

	// Add the game path to the directory search list
	engine->initializePath(dir);

	// Add extrapath (if any) to the directory search list
	if (ConfMan.hasKey("extrapath")) {
		dir = Common::FSNode(ConfMan.get("extrapath"));
		SearchMan.addDirectory(dir.getPath(), dir);
	}

	// If a second extrapath is specified on the app domain level, add that as well.
	// However, since the default hasKey() and get() check the app domain level,
	// verify that it's not already there before adding it. The search manager will
	// check for that too, so this check is mostly to avoid a warning message.
	if (ConfMan.hasKey("extrapath", Common::ConfigManager::kApplicationDomain)) {
		Common::String extraPath = ConfMan.get("extrapath", Common::ConfigManager::kApplicationDomain);
		if (!SearchMan.hasArchive(extraPath)) {
			dir = Common::FSNode(extraPath);
			SearchMan.addDirectory(dir.getPath(), dir);
		}
	}

	// On creation the engine should have set up all debug levels so we can use
	// the command line arguments here
	Common::StringTokenizer tokenizer(edebuglevels, " ,");
	while (!tokenizer.empty()) {
		Common::String token = tokenizer.nextToken();
		if (token.equalsIgnoreCase("all"))
			DebugMan.enableAllDebugChannels();
		else if (!DebugMan.enableDebugChannel(token))
			warning(_("Engine does not support debug level '%s'"), token.c_str());
	}

	// Initialize any game-specific keymaps
	engine->initKeymap();

	// Inform backend that the engine is about to be run
	system.engineInit();

	// Run the engine
	Common::Error result = engine->run();

	// Inform backend that the engine finished
	system.engineDone();

	// Clean up any game-specific keymaps
	engine->deinitKeymap();

	// Free up memory
	delete engine;

	// We clear all debug levels again even though the engine should do it
	DebugMan.clearAllDebugChannels();

	// Reset the file/directory mappings
	SearchMan.clear();

	// Return result (== 0 means no error)
	return result;
}
Example #20
0
bool Console::Cmd_Infos(int argc, const char **argv) {
	uint16 nodeId = _vm->_state->getLocationNode();
	uint32 roomId = _vm->_state->getLocationRoom();

	if (argc >= 2) {
		nodeId = atoi(argv[1]);
	}

	if (argc >= 3) {
		roomId = _vm->_db->getRoomId(argv[2]);

		if (roomId == 0) {
			debugPrintf("Unknown room name %s\n", argv[2]);
			return true;
		}
	}

	NodePtr nodeData = _vm->_db->getNodeData(nodeId, roomId);

	if (!nodeData) {
		debugPrintf("No node with id %d\n", nodeId);
		return true;
	}

	Common::String roomName = _vm->_db->getRoomName(roomId);

	debugPrintf("node: %s %d    ", roomName.c_str(), nodeId);

	for (uint i = 0; i < nodeData->scripts.size(); i++) {
		debugPrintf("\ninit %d > %s (%s)\n", i,
				_vm->_state->describeCondition(nodeData->scripts[i].condition).c_str(),
				_vm->_state->evaluate(nodeData->scripts[i].condition) ? "true" : "false");

		describeScript(nodeData->scripts[i].script);
	}

	for (uint i = 0; i < nodeData->hotspots.size(); i++) {
		debugPrintf("\nhotspot %d > %s (%s)\n", i,
				_vm->_state->describeCondition(nodeData->hotspots[i].condition).c_str(),
				_vm->_state->evaluate(nodeData->hotspots[i].condition) ? "true" : "false");

		for(uint j = 0; j < nodeData->hotspots[i].rects.size(); j++) {
			PolarRect &rect = nodeData->hotspots[i].rects[j];

			debugPrintf("    rect > pitch: %d heading: %d width: %d height: %d\n",
					rect.centerPitch, rect.centerHeading, rect.width, rect.height);
		}

		describeScript(nodeData->hotspots[i].script);
	}

	for (uint i = 0; i < nodeData->soundScripts.size(); i++) {
		debugPrintf("\nsound %d > %s (%s)\n", i,
				_vm->_state->describeCondition(nodeData->soundScripts[i].condition).c_str(),
				_vm->_state->evaluate(nodeData->soundScripts[i].condition) ? "true" : "false");

		describeScript(nodeData->soundScripts[i].script);
	}

	for (uint i = 0; i < nodeData->backgroundSoundScripts.size(); i++) {
		debugPrintf("\nbackground sound %d > %s (%s)\n", i,
				_vm->_state->describeCondition(nodeData->backgroundSoundScripts[i].condition).c_str(),
				_vm->_state->evaluate(nodeData->backgroundSoundScripts[i].condition) ? "true" : "false");

		describeScript(nodeData->backgroundSoundScripts[i].script);
	}

	return true;
}
Example #21
0
extern "C" int scummvm_main(int argc, const char * const argv[]) {
	Common::String specialDebug;
	Common::String command;

	// Verify that the backend has been initialized (i.e. g_system has been set).
	assert(g_system);
	OSystem &system = *g_system;

	// Register config manager defaults
	Base::registerDefaults();

	// Parse the command line
	Common::StringMap settings;
	command = Base::parseCommandLine(settings, argc, argv);

	// Load the config file (possibly overridden via command line):
	if (settings.contains("config")) {
		ConfMan.loadConfigFile(settings["config"]);
		settings.erase("config");
	} else {
		ConfMan.loadDefaultConfigFile();
	}

	// Update the config file
	ConfMan.set("versioninfo", gScummVMVersion, Common::ConfigManager::kApplicationDomain);

	// Load and setup the debuglevel and the debug flags. We do this at the
	// soonest possible moment to ensure debug output starts early on, if
	// requested.
	if (settings.contains("debuglevel")) {
		gDebugLevel = (int)strtol(settings["debuglevel"].c_str(), 0, 10);
		printf("Debuglevel (from command line): %d\n", gDebugLevel);
		settings.erase("debuglevel");	// This option should not be passed to ConfMan.
	} else if (ConfMan.hasKey("debuglevel"))
		gDebugLevel = ConfMan.getInt("debuglevel");

	if (settings.contains("debugflags")) {
		specialDebug = settings["debugflags"];
		settings.erase("debugflags");
	}

	PluginManager::instance().init();
 	PluginManager::instance().loadAllPlugins(); // load plugins for cached plugin manager
	
	// If we received an invalid music parameter via command line we check this here.
	// We can't check this before loading the music plugins.
	// On the other hand we cannot load the plugins before we know the file paths (in case of external plugins).
	if (settings.contains("music-driver")) {
		if (MidiDriver::getMusicType(MidiDriver::getDeviceHandle(settings["music-driver"])) == MT_INVALID) {
			warning("Unrecognized music driver '%s'. Switching to default device", settings["music-driver"].c_str());
			settings["music-driver"] = "auto";
		}
	}

	// Process the remaining command line settings. Must be done after the
	// config file and the plugins have been loaded.
	Common::Error res;

	// TODO: deal with settings that require plugins to be loaded
	res = Base::processSettings(command, settings);
	if (res.getCode() != Common::kArgumentNotProcessed) {
		warning("%s", res.getDesc().c_str());
		return res.getCode();
	}

	// Init the backend. Must take place after all config data (including
	// the command line params) was read.
	system.initBackend();

	// If we received an invalid graphics mode parameter via command line
	// we check this here. We can't do it until after the backend is inited,
	// or there won't be a graphics manager to ask for the supported modes.

	if (settings.contains("gfx-mode")) {
		const OSystem::GraphicsMode *gm = g_system->getSupportedGraphicsModes();
		Common::String option = settings["gfx-mode"];
		bool isValid = false;

		while (gm->name && !isValid) {
			isValid = !scumm_stricmp(gm->name, option.c_str());
			gm++;
		}
		if (!isValid) {
			warning("Unrecognized graphics mode '%s'. Switching to default mode", option.c_str());
			settings["gfx-mode"] = "default";
		}
	}

	setupGraphics(system);

	// Init the different managers that are used by the engines.
	// Do it here to prevent fragmentation later
	system.getAudioCDManager();
	MusicManager::instance();
	Common::DebugManager::instance();
	
	// Init the event manager. As the virtual keyboard is loaded here, it must
	// take place after the backend is initiated and the screen has been setup
	system.getEventManager()->init();

	// Directly after initializing the event manager, we will initialize our
	// event recorder.
	//
	// TODO: This is just to match the current behavior, when we further extend
	// our event recorder, we might do this at another place. Or even change
	// the whole API for that ;-).
	g_eventRec.init();

	// Now as the event manager is created, setup the keymapper
	setupKeymapper(system);

	// Unless a game was specified, show the launcher dialog
	if (0 == ConfMan.getActiveDomain())
		launcherDialog();

	// FIXME: We're now looping the launcher. This, of course, doesn't
	// work as well as it should. In theory everything should be destroyed
	// cleanly, so this is now enabled to encourage people to fix bits :)
	while (0 != ConfMan.getActiveDomain()) {
		// Try to find a plugin which feels responsible for the specified game.
		const EnginePlugin *plugin = detectPlugin();
		if (plugin) {
			// Unload all plugins not needed for this game,
			// to save memory
			PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, plugin);

			// Try to run the game
			Common::Error result = runGame(plugin, system, specialDebug);

		#if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES)
			// do our best to prevent fragmentation by unloading as soon as we can
			PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false);
			// reallocate the config manager to get rid of any fragmentation
			ConfMan.defragment();
		#endif	
			
			// Did an error occur ?
			if (result.getCode() != Common::kNoError) {
				// Shows an informative error dialog if starting the selected game failed.
				GUI::displayErrorDialog(result, _("Error running game:"));
			}

			// Quit unless an error occurred, or Return to launcher was requested
			#ifndef FORCE_RTL
			if (result.getCode() == Common::kNoError && !g_system->getEventManager()->shouldRTL())
				break;
			#endif
			// Reset RTL flag in case we want to load another engine
			g_system->getEventManager()->resetRTL();
			#ifdef FORCE_RTL
			g_system->getEventManager()->resetQuit();
			#endif

			// Discard any command line options. It's unlikely that the user
			// wanted to apply them to *all* games ever launched.
			ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();

			// Clear the active config domain
			ConfMan.setActiveDomain("");

			PluginManager::instance().loadAllPlugins(); // only for cached manager

		} else {
			GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game"));
		}

		// reset the graphics to default
		setupGraphics(system);
		launcherDialog();
	}
	PluginManager::instance().unloadAllPlugins();
	PluginManager::destroy();
	GUI::GuiManager::destroy();
	Common::ConfigManager::destroy();
	Common::SearchManager::destroy();
#ifdef USE_TRANSLATION
	Common::TranslationManager::destroy();
#endif

	return 0;
}
Example #22
0
bool OSystem_Android::openUrl(const Common::String &url) {
	return JNI::openUrl(url.c_str());
}
Example #23
0
/**
 * DoSave
 */
static void DoSave() {
	Common::OutSaveFile *f;
	char tmpName[FNAMELEN];

	// Next getList() must do its stuff again
	NeedLoad = true;

	if (SaveSceneName == NULL) {
		// Generate a new unique save name	
		int	i;
		int	ano = 1;	// Allocated number

		while (1) {
			Common::String fname = _vm->getSavegameFilename(ano);
			strcpy(tmpName, fname.c_str());

			for (i = 0; i < numSfiles; i++)
				if (!strcmp(savedFiles[i].name, tmpName))
					break;

			if (i == numSfiles)
				break;
			ano++;
		}

		SaveSceneName = tmpName;
	}


	if (SaveSceneDesc[0] == 0)
		SaveSceneDesc = "unnamed";

	f = _vm->getSaveFileMan()->openForSaving(SaveSceneName);
	Common::Serializer s(0, f);

	if (f == NULL)
		goto save_failure;

	// Write out a savegame header
	SaveGameHeader hdr;
	hdr.id = SAVEGAME_ID;
	hdr.size = SAVEGAME_HEADER_SIZE;
	hdr.ver = CURRENT_VER;
	memcpy(hdr.desc, SaveSceneDesc, SG_DESC_LEN);
	hdr.desc[SG_DESC_LEN - 1] = 0;
	g_system->getTimeAndDate(hdr.dateTime);
	if (!syncSaveGameHeader(s, hdr) || f->err()) {
		goto save_failure;
	}

	DoSync(s);

	// Write out the special Id for Discworld savegames
	f->writeUint32LE(0xFEEDFACE);
	if (f->err())
		goto save_failure;

	f->finalize();
	delete f;
	SaveSceneName = NULL;	// Invalidate save name
	return;

save_failure:
	if (f) {
		delete f;
		_vm->getSaveFileMan()->removeSavefile(SaveSceneName);
		SaveSceneName = NULL;	// Invalidate save name
	}
	GUI::MessageDialog dialog("Failed to save game state to file.");
	dialog.runModal();
}
Example #24
0
void SaveFileManager::remove(const Common::String &target, int slot) {
	Common::String filename = Common::String::format("%s.%03d", target.c_str(), slot);
	g_system->getSavefileManager()->removeSavefile(filename);
}
Example #25
0
void BladeRunnerEngine::ISez(const Common::String &str) {
	debug("\t%s", str.c_str());
}
Example #26
0
Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) const {
	assert(engine);

	const ADGameDescription *agdDesc = 0;
	Common::Language language = Common::UNK_LANG;
	Common::Platform platform = Common::kPlatformUnknown;
	Common::String extra;

	if (ConfMan.hasKey("language"))
		language = Common::parseLanguage(ConfMan.get("language"));
	if (ConfMan.hasKey("platform"))
		platform = Common::parsePlatform(ConfMan.get("platform"));
	if (_flags & kADFlagUseExtraAsHint) {
		if (ConfMan.hasKey("extra"))
			extra = ConfMan.get("extra");
	}

	Common::String gameid = ConfMan.get("gameid");

	Common::String path;
	if (ConfMan.hasKey("path")) {
		path = ConfMan.get("path");
	} else {
		path = ".";

		// This situation may happen only when game was
		// launched from a command line with wrong target and
		// no path was provided.
		//
		// A dummy entry will get created and will keep game path
		// We mark this entry, so it will not be added to the
		// config file.
		//
		// Fixes bug #1544799
		ConfMan.setBool("autoadded", true);

		warning("No path was provided. Assuming the data files are in the current directory");
	}
	Common::FSNode dir(path);
	Common::FSList files;
	if (!dir.isDirectory() || !dir.getChildren(files, Common::FSNode::kListAll, true)) {
		warning("Game data path does not exist or is not a directory (%s)", path.c_str());
		return Common::kNoGameDataFoundError;
	}

	if (files.empty())
		return Common::kNoGameDataFoundError;

	// Compose a hashmap of all files in fslist.
	FileMap allFiles;
	composeFileHashMap(allFiles, files, (_maxScanDepth == 0 ? 1 : _maxScanDepth));

	// Run the detector on this
	ADGameDescList matches = detectGame(files.begin()->getParent(), allFiles, language, platform, extra);

	if (cleanupPirated(matches))
		return Common::kNoGameDataFoundError;

	if (_singleId == NULL) {
		// Find the first match with correct gameid.
		for (uint i = 0; i < matches.size(); i++) {
			if (matches[i]->gameId == gameid) {
				agdDesc = matches[i];
				break;
			}
		}
	} else if (matches.size() > 0) {
		agdDesc = matches[0];
	}

	if (agdDesc == 0) {
		// Use fallback detector if there were no matches by other means
		agdDesc = fallbackDetect(allFiles, files);
		if (agdDesc != 0) {
			// Seems we found a fallback match. But first perform a basic
			// sanity check: the gameid must match.
			if (_singleId == NULL && agdDesc->gameId != gameid)
				agdDesc = 0;
		}
	}

	if (agdDesc == 0)
		return Common::kNoGameDataFoundError;

	// If the GUI options were updated, we catch this here and update them in the users config
	// file transparently.
	Common::String lang = getGameGUIOptionsDescriptionLanguage(agdDesc->language);
	if (agdDesc->flags & ADGF_ADDENGLISH)
		lang += " " + getGameGUIOptionsDescriptionLanguage(Common::EN_ANY);

	Common::updateGameGUIOptions(agdDesc->guiOptions + _guiOptions, lang);

	GameDescriptor gameDescriptor = toGameDescriptor(*agdDesc, _gameIds);

	bool showTestingWarning = false;

#ifdef RELEASE_BUILD
	showTestingWarning = true;
#endif

	if (((gameDescriptor.getSupportLevel() == kUnstableGame
			|| (gameDescriptor.getSupportLevel() == kTestingGame
					&& showTestingWarning)))
			&& !Engine::warnUserAboutUnsupportedGame())
		return Common::kUserCanceled;

	debug(2, "Running %s", gameDescriptor.description().c_str());
	initSubSystems(agdDesc);
	if (!createInstance(syst, engine, agdDesc))
		return Common::kNoGameDataFoundError;
	else
		return Common::kNoError;
}
Example #27
0
bool Character::loadTalkAnimation(Common::String animName) {
	debugC(1, kDebugCharacter, "loadTalkAnimation(%s)", animName.c_str());
	delete _talkAnim;
	_talkAnim = new Animation(_vm);
	return _talkAnim->loadAnimation(animName);
}
Example #28
0
ADGameDescList AdvancedMetaEngine::detectGame(const Common::FSNode &parent, const FileMap &allFiles, Common::Language language, Common::Platform platform, const Common::String &extra) const {
	ADFilePropertiesMap filesProps;

	const ADGameFileDescription *fileDesc;
	const ADGameDescription *g;
	const byte *descPtr;

	debug(3, "Starting detection in dir '%s'", parent.getPath().c_str());

	// Check which files are included in some ADGameDescription *and* are present.
	// Compute MD5s and file sizes for these files.
	for (descPtr = _gameDescriptors; ((const ADGameDescription *)descPtr)->gameId != 0; descPtr += _descItemSize) {
		g = (const ADGameDescription *)descPtr;

		for (fileDesc = g->filesDescriptions; fileDesc->fileName; fileDesc++) {
			Common::String fname = fileDesc->fileName;
			ADFileProperties tmp;

			if (filesProps.contains(fname))
				continue;

			if (getFileProperties(parent, allFiles, *g, fname, tmp)) {
				debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str());
				filesProps[fname] = tmp;
			}
		}
	}

	ADGameDescList matched;
	int maxFilesMatched = 0;
	bool gotAnyMatchesWithAllFiles = false;

	// MD5 based matching
	uint i;
	for (i = 0, descPtr = _gameDescriptors; ((const ADGameDescription *)descPtr)->gameId != 0; descPtr += _descItemSize, ++i) {
		g = (const ADGameDescription *)descPtr;
		bool fileMissing = false;

		// Do not even bother to look at entries which do not have matching
		// language and platform (if specified).
		if ((language != Common::UNK_LANG && g->language != Common::UNK_LANG && g->language != language
			 && !(language == Common::EN_ANY && (g->flags & ADGF_ADDENGLISH))) ||
			(platform != Common::kPlatformUnknown && g->platform != Common::kPlatformUnknown && g->platform != platform)) {
			continue;
		}

		if ((_flags & kADFlagUseExtraAsHint) && !extra.empty() && g->extra != extra)
			continue;

		bool allFilesPresent = true;
		int curFilesMatched = 0;

		// Try to match all files for this game
		for (fileDesc = g->filesDescriptions; fileDesc->fileName; fileDesc++) {
			Common::String tstr = fileDesc->fileName;

			if (!filesProps.contains(tstr)) {
				fileMissing = true;
				allFilesPresent = false;
				break;
			}

			if (fileDesc->md5 != NULL && fileDesc->md5 != filesProps[tstr].md5) {
				debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesProps[tstr].md5.c_str());
				fileMissing = true;
				break;
			}

			if (fileDesc->fileSize != -1 && fileDesc->fileSize != filesProps[tstr].size) {
				debug(3, "Size Mismatch. Skipping");
				fileMissing = true;
				break;
			}

			debug(3, "Matched file: %s", tstr.c_str());
			curFilesMatched++;
		}

		// We found at least one entry with all required files present.
		// That means that we got new variant of the game.
		//
		// Without this check we would have erroneous checksum display
		// where only located files will be enlisted.
		//
		// Potentially this could rule out variants where some particular file
		// is really missing, but the developers should better know about such
		// cases.
		if (allFilesPresent)
			gotAnyMatchesWithAllFiles = true;

		if (!fileMissing) {
			debug(2, "Found game: %s (%s %s/%s) (%d)", g->gameId, g->extra,
			 getPlatformDescription(g->platform), getLanguageDescription(g->language), i);

			if (curFilesMatched > maxFilesMatched) {
				debug(2, " ... new best match, removing all previous candidates");
				maxFilesMatched = curFilesMatched;

				matched.clear();	// Remove any prior, lower ranked matches.
				matched.push_back(g);
			} else if (curFilesMatched == maxFilesMatched) {
				matched.push_back(g);
			} else {
				debug(2, " ... skipped");
			}

		} else {
			debug(5, "Skipping game: %s (%s %s/%s) (%d)", g->gameId, g->extra,
			 getPlatformDescription(g->platform), getLanguageDescription(g->language), i);
		}
	}

	// We didn't find a match
	if (matched.empty()) {
		if (!filesProps.empty() && gotAnyMatchesWithAllFiles) {
			reportUnknown(parent, filesProps);
		}

		// Filename based fallback
	}

	return matched;
}
Example #29
0
void LabEngine::processMonitor(const Common::String &ntext, TextFont *monitorFont, bool isInteractive, Common::Rect textRect) {
	Common::String startFileName = _monitorTextFilename;
	const CloseData *startClosePtr = _closeDataPtr, *lastClosePtr[10];
	uint16 depth = 0;
	Common::String text = ntext;

	lastClosePtr[0] = _closeDataPtr;

	while (1) {
		if (isInteractive) {
			if (!_closeDataPtr)
				_closeDataPtr = startClosePtr;

			Common::String filename;
			if (_closeDataPtr == startClosePtr)
				filename = startFileName;
			else
				filename = _closeDataPtr->_graphicName;

			if (filename != _monitorTextFilename) {
				_monitorPage = 0;
				_monitorTextFilename = filename;

				text = _resource->getText(_monitorTextFilename);
				_graphics->fade(false);
				drawMonText(text.c_str(), monitorFont, textRect, isInteractive);
				_graphics->fade(true);
			}
		}

		IntuiMessage *msg = _event->getMsg();
		if (shouldQuit()) {
			_quitLab = true;
			return;
		}

		updateEvents();
		_graphics->screenUpdate();
		_system->delayMillis(10);

		if (!msg)
			continue;

		MessageClass msgClass  = msg->_msgClass;

		if ((msgClass == kMessageRightClick) ||
				((msgClass == kMessageRawKey) && (msg->_code == Common::KEYCODE_ESCAPE)))
			return;

		if (msgClass == kMessageLeftClick) {
			int16 mouseX = msg->_mouse.x;
			int16 mouseY = msg->_mouse.y;

			// Check if mouse was in button bar
			if ((mouseY >= _utils->vgaScaleY(171)) && (mouseY <= _utils->vgaScaleY(200))) {
				if (mouseX <= _utils->vgaScaleX(31)) {
					// Exit button
					return;
				}

				if (mouseX <= _utils->vgaScaleX(59)) {
					// Back button
					if (isInteractive) {
						_monitorPage = 0;

						if (depth) {
							depth--;
							_closeDataPtr = lastClosePtr[depth];
						}
					} else if (_monitorPage > 0) {
						_monitorPage = 0;
						drawMonText(text.c_str(), monitorFont, textRect, isInteractive);
					}
				} else if (mouseX < _utils->vgaScaleX(259)) {
					// empty region; ignore
				} else if (mouseX <= _utils->vgaScaleX(289)) {
					// Page down button
					if (!_lastPage) {
						_monitorPage += 1;
						drawMonText(text.c_str(), monitorFont, textRect, isInteractive);
					}
				} else if (_monitorPage >= 1) {
					// Page up button
					_monitorPage -= 1;
					drawMonText(text.c_str(), monitorFont, textRect, isInteractive);
				}
			} else if (isInteractive) {
				const CloseData *tmpClosePtr = _closeDataPtr;
				mouseY = 64 + (mouseY / _monitorButtonHeight) * 42;
				mouseX = 101;
				setCurrentClose(Common::Point(mouseX, mouseY), &_closeDataPtr, false);

				if (tmpClosePtr != _closeDataPtr) {
					lastClosePtr[depth] = tmpClosePtr;
					depth++;
				}
			}
		}
	}	// while
}
Example #30
0
void BArchive::openArchive(const Common::String &path) {
	byte buf[4];
	byte *footer;
	uint32 footerOffset, footerSize;

	// Close previously opened archive (if any)
	closeArchive();

	debugCN(2, kDraciArchiverDebugLevel, "Loading archive %s: ", path.c_str());

	_f.open(path);
	if (_f.isOpen()) {
		debugC(2, kDraciArchiverDebugLevel, "Success");
	} else {
		debugC(2, kDraciArchiverDebugLevel, "Error");
		return;
	}

	// Save path for reading in files later on
	_path = path;

	// Read archive header
	debugCN(2, kDraciArchiverDebugLevel, "Checking for BAR magic number: ");

	_f.read(buf, 4);
	if (memcmp(buf, _magicNumber, 4) == 0) {
		debugC(2, kDraciArchiverDebugLevel, "Success");

		// Indicate this archive is a BAR
		_isDFW = false;
	} else {
		debugC(2, kDraciArchiverDebugLevel, "Not a BAR archive");
		debugCN(2, kDraciArchiverDebugLevel, "Retrying as DFW: ");
		_f.close();

		// Try to open as DFW
		openDFW(_path);

		return;
	}

	_fileCount = _f.readUint16LE();
	footerOffset = _f.readUint32LE();
	footerSize = _f.size() - footerOffset;

	debugC(2, kDraciArchiverDebugLevel, "Archive info: %d files, %d data bytes",
		_fileCount, footerOffset - _archiveHeaderSize);

	// Read in footer
	footer = new byte[footerSize];
	_f.seek(footerOffset);
	_f.read(footer, footerSize);
	Common::MemoryReadStream reader(footer, footerSize);

	// Read in file headers, but do not read the actual data yet
	// The data will be read on demand to save memory
	_files = new BAFile[_fileCount];

	for (uint i = 0; i < _fileCount; i++) {
		uint32 fileOffset;

		fileOffset = reader.readUint32LE();
		_f.seek(fileOffset); 						// Seek to next file in archive

		_files[i]._compLength = _f.readUint16LE(); 	// Compressed size
													// should be the same as uncompressed

		_files[i]._length = _f.readUint16LE(); 		// Original size

		_files[i]._offset = fileOffset;				// Offset of file from start

		assert(_f.readByte() == 0 &&
			"Compression type flag is non-zero (file is compressed)");

		_files[i]._crc = _f.readByte(); 	// CRC checksum of the file
		_files[i]._data = NULL; 		// File data will be read in on demand
		_files[i]._stopper = 0; 		// Dummy value; not used in BAR files, needed in DFW
	}

	// Last footer item should be equal to footerOffset
	assert(reader.readUint32LE() == footerOffset && "Footer offset mismatch");

	// Indicate that the archive has been successfully opened
	_opened = true;

	delete[] footer;
}