Exemple #1
0
AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) {
	ENTER();

	int offset = p.size();

	//assert(offset > 0);

	if (offset <= 0) {
		debug(6, "Bad offset");
		return;
	}

	_sPath = p;
	_sDisplayName = ::lastPathComponent(_sPath);
	_pFileLock = 0;
	_bIsDirectory = false;
	_bIsValid = false;

	// Check whether the node exists and if it's a directory
	struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_StringNameInput,_sPath.c_str(),TAG_END);
	if (pExd) {
		_nProt = pExd->Protection;
		if (EXD_IS_DIRECTORY(pExd)) {
			_bIsDirectory = true;
			_pFileLock = IDOS->Lock((CONST_STRPTR)_sPath.c_str(), SHARED_LOCK);
			_bIsValid = (_pFileLock != 0);

			// Add a trailing slash if needed
			const char c = _sPath.lastChar();
			if (c != '/' && c != ':')
				_sPath += '/';
		} else {
			//_bIsDirectory = false;
			_bIsValid = true;
		}

		IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd);
	}

	LEAVE();
}
void IdCreateDirectoryRequest::start() {
	//cleanup
	_ignoreCallback = true;
	if (_workingRequest)
		_workingRequest->finish();
	_workingRequest = nullptr;
	_ignoreCallback = false;

	//the only exception when we create parent folder - is when it's ScummVM/ base folder
	Common::String prefix = _requestedParentPath;
	if (prefix.size() > 7)
		prefix.erase(7);
	if (prefix.equalsIgnoreCase("ScummVM")) {
		Storage::BoolCallback callback = new Common::Callback<IdCreateDirectoryRequest, Storage::BoolResponse>(this, &IdCreateDirectoryRequest::createdBaseDirectoryCallback);
		Networking::ErrorCallback failureCallback = new Common::Callback<IdCreateDirectoryRequest, Networking::ErrorResponse>(this, &IdCreateDirectoryRequest::createdBaseDirectoryErrorCallback);
		_workingRequest = _storage->createDirectory("ScummVM", callback, failureCallback);
		return;
	}

	resolveId();
}
Exemple #3
0
bool MessageState::stringHex(Common::String &outStr, const Common::String &inStr, uint &index) {
	// Hex escape sequences of the form \nn, where n is a hex digit
	if (inStr[index] != '\\')
		return false;

	// Check for enough room for a hex escape sequence
	if (index + 2 >= inStr.size())
		return false;

	int digit1 = hexDigitToInt(inStr[index + 1]);
	int digit2 = hexDigitToInt(inStr[index + 2]);

	// Check for hex
	if ((digit1 == -1) || (digit2 == -1))
		return false;

	outStr += digit1 * 16 + digit2;
	index += 3;

	return true;
}
Exemple #4
0
AbstractFSNode *WindowsFilesystemNode::getParent() const {
	assert(_isValid || _isPseudoRoot);

	if (_isPseudoRoot)
		return 0;

	WindowsFilesystemNode *p = new WindowsFilesystemNode();
	if (_path.size() > 3) {
		const char *start = _path.c_str();
		const char *end = lastPathComponent(_path, '\\');

		p = new WindowsFilesystemNode();
		p->_path = Common::String(start, end - start);
		p->_isValid = true;
		p->_isDirectory = true;
		p->_displayName = lastPathComponent(p->_path, '\\');
		p->_isPseudoRoot = false;
	}

	return p;
}
Exemple #5
0
void BoxStorage::loadKeyAndSecret() {
#ifdef ENABLE_RELEASE
	KEY = RELEASE_BOX_KEY;
	SECRET = RELEASE_BOX_SECRET;
#else
	Common::String k = ConfMan.get("BOX_KEY", ConfMan.kCloudDomain);
	KEY = new char[k.size() + 1];
	memcpy(KEY, k.c_str(), k.size());
	KEY[k.size()] = 0;

	k = ConfMan.get("BOX_SECRET", ConfMan.kCloudDomain);
	SECRET = new char[k.size() + 1];
	memcpy(SECRET, k.c_str(), k.size());
	SECRET[k.size()] = 0;
#endif
}
Exemple #6
0
void MessageState::outputString(reg_t buf, const Common::String &str) {
#ifdef ENABLE_SCI32
	if (getSciVersion() >= SCI_VERSION_2) {
		if (_segMan->getSegmentType(buf.getSegment()) == SEG_TYPE_STRING) {
			SciString *sciString = _segMan->lookupString(buf);
			sciString->setSize(str.size() + 1);
			for (uint32 i = 0; i < str.size(); i++)
				sciString->setValue(i, str.c_str()[i]);
			sciString->setValue(str.size(), 0);
		} else if (_segMan->getSegmentType(buf.getSegment()) == SEG_TYPE_ARRAY) {
			// Happens in the intro of LSL6, we are asked to write the string
			// into an array
			SciArray<reg_t> *sciString = _segMan->lookupArray(buf);
			sciString->setSize(str.size() + 1);
			for (uint32 i = 0; i < str.size(); i++)
				sciString->setValue(i, make_reg(0, str.c_str()[i]));
			sciString->setValue(str.size(), NULL_REG);
		}
	} else {
#endif
		SegmentRef buffer_r = _segMan->dereference(buf);

		if ((unsigned)buffer_r.maxSize >= str.size() + 1) {
			_segMan->strcpy(buf, str.c_str());
		} else {
			// LSL6 sets an exit text here, but the buffer size allocated
			// is too small. Don't display a warning in this case, as we
			// don't use the exit text anyway - bug report #3035533
			if (g_sci->getGameId() == GID_LSL6 && str.hasPrefix("\r\n(c) 1993 Sierra On-Line, Inc")) {
				// LSL6 buggy exit text, don't show warning
			} else {
				warning("Message: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(buf), str.size() + 1, str.c_str());
			}

			// Set buffer to empty string if possible
			if (buffer_r.maxSize > 0)
				_segMan->strcpy(buf, "");
		}
#ifdef ENABLE_SCI32
	}
#endif
}
Exemple #7
0
Common::String lastPathComponent(const Common::String &path, const char sep) {
	const char *str = path.c_str();
	const char *last = str + path.size();

	// Skip over trailing slashes
	while (last > str && *(last-1) == sep)
		--last;

	// Path consisted of only slashes -> return empty string
	if (last == str)
		return Common::String();

	// Now scan the whole component
	const char *first = last - 1;
	while (first >= str && *first != sep)
		--first;

	if (*first == sep)
		first++;

	return Common::String(first, last);
}
void GoogleDriveUploadRequest::idResolveFailedCallback(Networking::ErrorResponse error) {
	_workingRequest = nullptr;
	if (_ignoreCallback)
		return;

	//not resolved => error or no such file
	if (error.response.contains("no such file found in its parent directory")) {
		//parent's id after the '\n'
		Common::String parentId = error.response;
		for (uint32 i = 0; i < parentId.size(); ++i)
			if (parentId[i] == '\n') {
				parentId.erase(0, i + 1);
				break;
			}

		_parentId = parentId;
		startUpload();
		return;
	}

	finishError(error);
}
Exemple #9
0
DSFileSystemNode::DSFileSystemNode(const Common::String& path) {
//	consolePrintf("--%s ",path.c_str());

	int lastSlash = 3;
	for (int r = 0; r < (int) path.size() - 1; r++) {
		if (path[r] == '\\') {
			lastSlash = r;
		}
	}

	_displayName = Common::String(path.c_str() + lastSlash + 1);
	_path = path;
//	_isValid = true;
//	_isDirectory = false;

	const char *pathStr = path.c_str();

	if (path.hasPrefix("ds:/")) {
		pathStr += 4;
	}

	if (*pathStr == '\0') {
		_isValid = true;
		_isDirectory = true;
		return;
	}

	_zipFile->setAllFilesVisible(true);
	if (_zipFile->findFile(pathStr)) {
		_isValid = true;
		_isDirectory = _zipFile->isDirectory();
	} else {
		_isValid = false;
		_isDirectory = false;
	}
	_zipFile->setAllFilesVisible(false);

//	consolePrintf("%s - Found: %d, Dir: %d\n", pathStr, _isValid, _isDirectory);
}
Exemple #10
0
int16 Text::count() {
	EncryptedStream tf(_vm, _fileName);
	if (tf.err())
		return -1;

	Common::String line;
	char tmpStr[kLineMax + 1];

	int counter = 0;

	for (line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
		char *s;
		assert(line.size() <= 513);
		strcpy(tmpStr, line.c_str());
		if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
			continue;
		if (!Common::isDigit(*s))
			continue;

		counter++;
	}
	return counter;
}
Exemple #11
0
void LabEngine::doWestPaper() {
	TextFont *paperFont = _resource->getFont("F:News22.fon");
	Common::String paperText = _resource->getText("Lab:Rooms/Date");

	Common::Rect textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(77) + _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(91));
	_graphics->flowText(paperFont, 0, 0, 0, false, true, false, true, textRect, paperText.c_str());
	_graphics->freeFont(&paperFont);

	paperFont = _resource->getFont("F:News32.fon");
	paperText = _resource->getText("Lab:Rooms/Headline");

	int fileLen = paperText.size() - 1;
	textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(86) - _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(118));
	int charsPrinted = _graphics->flowText(paperFont, -8, 0, 0, false, true, false, true, textRect, paperText.c_str());

	uint16 y;

	if (charsPrinted < fileLen) {
		y = 130 - _utils->svgaCord(5);
		textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(86) - _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(132));
		_graphics->flowText(paperFont, -8 - _utils->svgaCord(1), 0, 0, false, true, false, true, textRect, paperText.c_str());
	} else
		y = 115 - _utils->svgaCord(5);

	_graphics->freeFont(&paperFont);

	paperFont = _resource->getFont("F:Note.fon");
	paperText = _resource->getText("Lab:Rooms/Col1");
	_graphics->flowText(paperFont, -4, 0, 0, false, false, false, true, _utils->vgaRectScale(45, y, 158, 148), paperText.c_str());

	paperText = _resource->getText("Lab:Rooms/Col2");
	_graphics->flowText(paperFont, -4, 0, 0, false, false, false, true, _utils->vgaRectScale(162, y, 275, 148), paperText.c_str());

	_graphics->freeFont(&paperFont);
	_graphics->setPalette(_anim->_diffPalette, 256);
}
Exemple #12
0
bool SaveManager::scummVMSaveLoadDialog(bool isSave) {
	GUI::SaveLoadChooser *dialog;
	Common::String desc;
	int slot;

	if (isSave) {
		dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);

		slot = dialog->runModalWithCurrentTarget();
		desc = dialog->getResultString();

		if (desc.empty()) {
			// create our own description for the saved game, the user didnt enter it
			desc = dialog->createDefaultSaveDescription(slot);
		}

		if (desc.size() > 28)
			desc = Common::String(desc.c_str(), 28);
	} else {
		dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
		slot = dialog->runModalWithCurrentTarget();
	}

	delete dialog;

	if (slot < 0)
		return false;

	if (isSave) {
		saveGame(slot, desc, false);
		return true;
	} else {
		Common::ErrorCode result = loadGame(slot).getCode();
		return (result == Common::kNoError);
	}
}
Exemple #13
0
// we need to have a separate status drawing code
//  In KQ4 the IV char is actually 0xA, which would otherwise get considered as linebreak and not printed
void GfxText16::DrawStatus(const Common::String &str) {
	uint16 curChar, charWidth;
	const byte *text = (const byte *)str.c_str();
	uint16 textLen = str.size();
	Common::Rect rect;

	GetFont();
	if (!_font)
		return;

	rect.top = _ports->_curPort->curTop;
	rect.bottom = rect.top + _ports->_curPort->fontHeight;
	while (textLen--) {
		curChar = *text++;
		switch (curChar) {
		case 0:
			break;
		default:
			charWidth = _font->getCharWidth(curChar);
			_font->draw(curChar, _ports->_curPort->top + _ports->_curPort->curTop, _ports->_curPort->left + _ports->_curPort->curLeft, _ports->_curPort->penClr, _ports->_curPort->greyedOutput);
			_ports->_curPort->curLeft += charWidth;
		}
	}
}
Exemple #14
0
Common::String DefinitionRegistry::stringToCamelCase(const Common::String &input) {
	Common::String clean = input;

	// First replace all non alphanumerical characters with spaces
	for (uint i = 0; i < clean.size(); i++) {
		if (!Common::isAlnum(clean[i])) {
			clean.setChar(' ', i);
		}
	}

	// Then turn the string into camel case
	Common::String output;
	Common::StringTokenizer tokens = Common::StringTokenizer(clean);
	while (!tokens.empty()) {
		Common::String token = tokens.nextToken();

		char upperFirstLetter = toupper(token[0]);
		token.setChar(upperFirstLetter, 0);

		output += token;
	}

	return output;
}
void GoogleDriveUploadRequest::startUpload() {
	Common::String name = _savePath;
	for (uint32 i = name.size(); i > 0; --i) {
		if (name[i - 1] == '/' || name[i - 1] == '\\') {
			name.erase(0, i);
			break;
		}
	}

	Common::String url = GOOGLEDRIVE_API_FILES;
	if (_resolvedId != "")
		url += "/" + ConnMan.urlEncode(_resolvedId);
	url += "?uploadType=resumable&fields=id,mimeType,modifiedTime,name,size";
	Networking::JsonCallback callback = new Common::Callback<GoogleDriveUploadRequest, Networking::JsonResponse>(this, &GoogleDriveUploadRequest::startUploadCallback);
	Networking::ErrorCallback failureCallback = new Common::Callback<GoogleDriveUploadRequest, Networking::ErrorResponse>(this, &GoogleDriveUploadRequest::startUploadErrorCallback);
	Networking::CurlJsonRequest *request = new GoogleDriveTokenRefresher(_storage, callback, failureCallback, url.c_str());
	request->addHeader("Authorization: Bearer " + _storage->accessToken());
	request->addHeader("Content-Type: application/json");
	if (_resolvedId != "")
		request->usePatch();

	Common::JSONObject jsonRequestParameters;
	if (_resolvedId != "") {
		jsonRequestParameters.setVal("id", new Common::JSONValue(_resolvedId));
	} else {
		Common::JSONArray parentsArray;
		parentsArray.push_back(new Common::JSONValue(_parentId));
		jsonRequestParameters.setVal("parents", new Common::JSONValue(parentsArray));
	}
	jsonRequestParameters.setVal("name", new Common::JSONValue(name));

	Common::JSONValue value(jsonRequestParameters);
	request->addPostField(Common::JSON::stringify(&value));

	_workingRequest = ConnMan.addRequest(request);
}
Exemple #16
0
void Inter_Geisha::oGeisha_checkData(OpFuncParams &params) {
	Common::String file = _vm->_game->_script->evalString();
	int16 varOff = _vm->_game->_script->readVarIndex();

	file.toLowercase();
	if (file.hasSuffix(".0ot"))
		file.setChar('t', file.size() - 3);

	bool exists = false;

	SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file.c_str());
	if (mode == SaveLoad::kSaveModeNone) {

		exists = _vm->_dataIO->hasFile(file);
		if (!exists)
			warning("File \"%s\" not found", file.c_str());

	} else if (mode == SaveLoad::kSaveModeSave)
		exists = _vm->_saveLoad->getSize(file.c_str()) >= 0;
	else if (mode == SaveLoad::kSaveModeExists)
		exists = true;

	WRITE_VAR_OFFSET(varOff, exists ? 50 : (uint32)-1);
}
void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point &position) {
	TinyGLTexture *glFont = static_cast<TinyGLTexture *>(_font);

	// The font only has uppercase letters
	Common::String textToDraw = text;
	textToDraw.toUppercase();

	tglEnable(TGL_BLEND);
	tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);

	tglEnable(TGL_TEXTURE_2D);
	tglDepthMask(TGL_FALSE);

	tglColor3f(1.0f, 1.0f, 1.0f);
	tglBindTexture(TGL_TEXTURE_2D, glFont->id);

	int x = position.x;
	int y = position.y;

	for (uint i = 0; i < textToDraw.size(); i++) {
		Common::Rect textureRect = getFontCharacterRect(textToDraw[i]);
		int w = textureRect.width();
		int h = textureRect.height();

		Graphics::BlitTransform transform(x, y);
		transform.sourceRectangle(textureRect.left, textureRect.top, w, h);
		transform.flip(true, false);
		Graphics::tglBlit(glFont->getBlitTexture(), transform);

		x += textureRect.width() - 3;
	}

	tglDisable(TGL_TEXTURE_2D);
	tglDisable(TGL_BLEND);
	tglDepthMask(TGL_TRUE);
}
Exemple #18
0
Common::String SciEngine::unwrapFilename(const Common::String &name) const {
	Common::String prefix = getFilePrefix() + "-";
	if (name.hasPrefix(prefix.c_str()))
		return Common::String(name.c_str() + prefix.size());
	return name;
}
Exemple #19
0
bool Quetzal::save(Common::WriteStream *svf, Processor *proc, const Common::String &desc) {
	Processor &p = *proc;
	uint ifzslen = 0, cmemlen = 0, stkslen = 0, descLen = 0;
	uint pc;
	zword i, j, n;
	zword nvars, nargs, nstk;
	zbyte var;
	long cmempos, stkspos;
	int c;

	// Set a temporary memory stream for writing out the data. This is needed, since we need to
	// do some seeking within it at the end to fill out totals before properly writing it all out
	Common::MemoryWriteStreamDynamic saveData(DisposeAfterUse::YES);
	_out = &saveData;

	// Write `IFZS' header.
	write_chnk(ID_FORM, 0);
	write_long(ID_IFZS);

	// Write `IFhd' chunk
	pc = p.getPC();
	write_chnk(ID_IFhd, 13);
	write_word(p.h_release);
	for (i = H_SERIAL; i<H_SERIAL + 6; ++i)
		write_byte(p[i]);

	write_word(p.h_checksum);
	write_long(pc << 8);		// Includes pad

	// Write 'ANNO' chunk
	descLen = desc.size() + 1;
	write_chnk(ID_ANNO, descLen);
	saveData.write(desc.c_str(), desc.size());
	write_byte(0);
	if ((desc.size() % 2) == 0) {
		write_byte(0);
		++descLen;
	}

	// Write `CMem' chunk.
	cmempos = saveData.pos();
	write_chnk(ID_CMem, 0);
	_storyFile->seek(0);

	// j holds current run length.
	for (i = 0, j = 0, cmemlen = 0; i < p.h_dynamic_size; ++i) {
		c = _storyFile->readByte();
		c ^= p[i];

		if (c == 0) {
			// It's a run of equal bytes
			++j;
		} else {
			// Write out any run there may be.
			if (j > 0) {
				for (; j > 0x100; j -= 0x100) {
					write_run(0xFF);
					cmemlen += 2;
				}
				write_run(j - 1);
				cmemlen += 2;
				j = 0;
			}

			// Any runs are now written. Write this (nonzero) byte
			write_byte((zbyte)c);
			++cmemlen;
		}
	}

	// Reached end of dynamic memory. We ignore any unwritten run there may be at this point.
	if (cmemlen & 1)
		// Chunk length must be even.
		write_byte(0);

	// Write `Stks' chunk. You are not expected to understand this. ;)
	stkspos = saveData.pos();
	write_chnk(ID_Stks, 0);

	// We construct a list of frame indices, most recent first, in `frames'.
	// These indices are the offsets into the `stack' array of the word before
	// the first word pushed in each frame.
	frames[0] = p._sp - p._stack;	// The frame we'd get by doing a call now.
	for (i = p._fp - p._stack + 4, n = 0; i < STACK_SIZE + 4; i = p._stack[i - 3] + 5)
		frames[++n] = i;

	// All versions other than V6 can use evaluation stack outside a function
	// context. We write a faked stack frame (most fields zero) to cater for this.
	if (p.h_version != V6) {
		for (i = 0; i < 6; ++i)
			write_byte(0);
		nstk = STACK_SIZE - frames[n];
		write_word(nstk);
		for (j = STACK_SIZE - 1; j >= frames[n]; --j)
			write_word(p._stack[j]);
		stkslen = 8 + 2 * nstk;
	}

	// Write out the rest of the stack frames.
	for (i = n; i > 0; --i) {
		zword *pf = p._stack + frames[i] - 4;	// Points to call frame
		nvars = (pf[0] & 0x0F00) >> 8;
		nargs = pf[0] & 0x00FF;
		nstk = frames[i] - frames[i - 1] - nvars - 4;
		pc = ((uint)pf[3] << 9) | pf[2];

		// Check type of call
		switch (pf[0] & 0xF000)	{
		case 0x0000:
			// Function
			var = p[pc];
			pc = ((pc + 1) << 8) | nvars;
			break;

		case 0x1000:
			// Procedure
			var = 0;
			pc = (pc << 8) | 0x10 | nvars;	// Set procedure flag
			break;

		default:
			p.runtimeError(ERR_SAVE_IN_INTER);
			return 0;
		}
		if (nargs != 0)
			nargs = (1 << nargs) - 1;	// Make args into bitmap

		// Write the main part of the frame...
		write_long(pc);
		write_byte(var);
		write_byte(nargs);
		write_word(nstk);

		// Write the variables and eval stack
		for (j = 0, --pf; j<nvars + nstk; ++j, --pf)
			write_word(*pf);

		// Calculate length written thus far
		stkslen += 8 + 2 * (nvars + nstk);
	}

	// Fill in variable chunk lengths
	ifzslen = 4 * 8 + 4 + 14 + cmemlen + stkslen + descLen;
	if (cmemlen & 1)
		++ifzslen;

	saveData.seek(4);
	saveData.writeUint32BE(ifzslen);
	saveData.seek(cmempos + 4);
	saveData.writeUint32BE(cmemlen);
	saveData.seek(stkspos + 4);
	saveData.writeUint32BE(stkslen);

	// Write the save data out
	svf->write(saveData.getData(), saveData.size());

	// After all that, still nothing went wrong!
	return true;
}
Exemple #20
0
/**
 * Save game to supplied slot
 */
bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
	debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip.c_str());

	int16 savegameId;
	Common::String savegameDescription;

	if (slot == -1) {
		GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true);
		savegameId = dialog->runModalWithCurrentTarget();
		savegameDescription = dialog->getResultString();
		delete dialog;
	} else {
		savegameId = slot;
		if (!descrip.empty()) {
			savegameDescription = descrip;
		} else {
			savegameDescription = Common::String::format("Quick save #%d", slot);
		}
	}

	if (savegameId < 0)                             // dialog aborted
		return false;

	Common::String savegameFile = _vm->getSavegameFilename(savegameId);
	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
	Common::OutSaveFile *out = saveMan->openForSaving(savegameFile);

	if (!out) {
		warning("Can't create file '%s', game not saved", savegameFile.c_str());
		return false;
	}

	// Write version.  We can't restore from obsolete versions
	out->writeByte(kSavegameVersion);

	if (savegameDescription == "") {
		savegameDescription = "Untitled savegame";
	}

	out->writeSint16BE(savegameDescription.size() + 1);
	out->write(savegameDescription.c_str(), savegameDescription.size() + 1);

	Graphics::saveThumbnail(*out);

	TimeDate curTime;
	_vm->_system->getTimeAndDate(curTime);

	uint32 saveDate = (curTime.tm_mday & 0xFF) << 24 | ((curTime.tm_mon + 1) & 0xFF) << 16 | ((curTime.tm_year + 1900) & 0xFFFF);
	uint16 saveTime = (curTime.tm_hour & 0xFF) << 8 | ((curTime.tm_min) & 0xFF);

	out->writeUint32BE(saveDate);
	out->writeUint16BE(saveTime);

	_vm->_object->saveObjects(out);

	const Status &gameStatus = _vm->getGameStatus();

	// Save whether hero image is swapped
	out->writeByte(_vm->_heroImage);

	// Save score
	out->writeSint16BE(_vm->getScore());

	// Save story mode
	out->writeByte((gameStatus._storyModeFl) ? 1 : 0);

	// Save jumpexit mode
	out->writeByte((_vm->_mouse->getJumpExitFl()) ? 1 : 0);

	// Save gameover status
	out->writeByte((gameStatus._gameOverFl) ? 1 : 0);

	// Save screen states
	for (int i = 0; i < _vm->_numStates; i++)
		out->writeByte(_vm->_screenStates[i]);

	_vm->_scheduler->saveSchedulerData(out);
	// Save palette table
	_vm->_screen->savePal(out);

	// Save maze status
	out->writeByte((_vm->_maze._enabledFl) ? 1 : 0);
	out->writeByte(_vm->_maze._size);
	out->writeSint16BE(_vm->_maze._x1);
	out->writeSint16BE(_vm->_maze._y1);
	out->writeSint16BE(_vm->_maze._x2);
	out->writeSint16BE(_vm->_maze._y2);
	out->writeSint16BE(_vm->_maze._x3);
	out->writeSint16BE(_vm->_maze._x4);
	out->writeByte(_vm->_maze._firstScreenIndex);

	out->writeByte((byte)_vm->getGameStatus()._viewState);

	out->finalize();

	delete out;

	return true;
}
Exemple #21
0
reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
	reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text));

	// The object in the text selector of the item can be either a raw string
	// or a Str object. In the latter case, we need to access the object's data
	// selector to get the raw string.
	if (_segMan->isHeapObject(stringObject))
		stringObject = readSelector(_segMan, stringObject, SELECTOR(data));

	Common::String text = _segMan->getString(stringObject);
	// HACK: The character offsets of the up and down arrow buttons are off by one
	// in GK1, for some unknown reason. Fix them here.
	if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) {
		text.setChar(text[0] + 1, 0);
	}
	GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font));
	GfxFont *font = _cache->getFont(fontId);
	bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed));
	int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode));
	uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore));
	uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));

	Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject);
	uint16 width = nsRect.width() + 1;
	uint16 height = nsRect.height() + 1;

	// Limit rectangle dimensions, if requested
	if (maxWidth > 0)
		width = maxWidth;
	if (maxHeight > 0)
		height = maxHeight;

	// Upscale the coordinates/width if the fonts are already upscaled
	if (_screen->fontIsUpscaled()) {
		width = width * _screen->getDisplayWidth() / _screen->getWidth();
		height = height * _screen->getDisplayHeight() / _screen->getHeight();
	}

	int entrySize = width * height + BITMAP_HEADER_SIZE;
	reg_t memoryId = NULL_REG;
	if (prevHunk.isNull()) {
		memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
		writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
	} else {
		memoryId = prevHunk;
	}
	byte *memoryPtr = _segMan->getHunkPointer(memoryId);

	if (prevHunk.isNull())
		memset(memoryPtr, 0, BITMAP_HEADER_SIZE);

	byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
	memset(bitmap, backColor, width * height);

	// Save totalWidth, totalHeight
	WRITE_LE_UINT16(memoryPtr, width);
	WRITE_LE_UINT16(memoryPtr + 2, height);

	int16 charCount = 0;
	uint16 curX = 0, curY = 0;
	const char *txt = text.c_str();
	int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0;
	uint16 start = 0;

	// Calculate total text height
	while (*txt) {
		charCount = GetLongest(txt, width, font);
		if (charCount == 0)
			break;

		Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true);

		totalHeight += textHeight;
		txt += charCount;
		while (*txt == ' ')
			txt++; // skip over breaking spaces
	}

	txt = text.c_str();

	// Draw text in buffer
	while (*txt) {
		charCount = GetLongest(txt, width, font);
		if (charCount == 0)
			break;
		Width(txt, start, charCount, fontId, textWidth, textHeight, true);

		switch (alignment) {
		case SCI_TEXT32_ALIGNMENT_RIGHT:
			offsetX = width - textWidth;
			break;
		case SCI_TEXT32_ALIGNMENT_CENTER:
			// Center text both horizontally and vertically
			offsetX = (width - textWidth) / 2;
			offsetY = (height - totalHeight) / 2;
			break;
		case SCI_TEXT32_ALIGNMENT_LEFT:
			offsetX = 0;
			break;

		default:
			warning("Invalid alignment %d used in TextBox()", alignment);
		}

		for (int i = 0; i < charCount; i++) {
			unsigned char curChar = txt[i];
			font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height);
			curX += font->getCharWidth(curChar);
		}

		curX = 0;
		curY += font->getHeight();
		txt += charCount;
		while (*txt == ' ')
			txt++; // skip over breaking spaces
	}

	return memoryId;
}
Exemple #22
0
/**
 * Loads and draws the chosen page of the help.
 * @remarks Originally called 'getme'
 */
void Help::switchPage(byte which) {
	// Help icons are 80x20.

	_highlightWas = 177; // Forget where the highlight was.

	Common::File file;

	if (!file.open("help.avd"))
		error("AVALANCHE: Help: File not found: help.avd");

	file.seek(which * 2);
	uint16 offset = file.readUint16LE();
	file.seek(offset);

	Common::String title = getLine(file);

	_vm->_graphics->drawFilledRectangle(Common::Rect(0, 0, 640, 200), kColorBlue);
	_vm->_graphics->drawFilledRectangle(Common::Rect(8, 40, 450, 200), kColorWhite);

	byte index = file.readByte();
	_vm->_graphics->helpDrawButton(-177, index);

	// Plot the title:
	_vm->_graphics->drawNormalText(title, _vm->_font, 8, 629 - 8 * title.size(), 26, kColorBlack);
	_vm->_graphics->drawNormalText(title, _vm->_font, 8, 630 - 8 * title.size(), 25, kColorCyan);

	_vm->_graphics->helpDrawBigText("help!", 549, 1, kColorBlack);
	_vm->_graphics->helpDrawBigText("help!", 550, 0, kColorCyan);

	byte y = 0;
	do {
		Common::String line = getLine(file);
		if (!line.empty()) {
			if (line.compareTo(Common::String('!')) == 0)  // End of the help text is signalled with a '!'.
				break;
			if (line[0] == '\\') {
				line.deleteChar(0);
				_vm->_graphics->drawNormalText(line, _vm->_font, 8, 16, 41 + y * 10, kColorRed);
			}
			else
				_vm->_graphics->drawNormalText(line, _vm->_font, 8, 16, 41 + y * 10, kColorBlack);
		}
		y++;
	} while (true);

	// We are now at the end of the text. Next we must read the icons:
	y = 0;
	_buttonNum = 0;
	while (!file.eos()) {
		int trigger = file.readByte();

		if (trigger == 177)
			break;
		switch (trigger) {
		case 254: // Escape
			trigger = 27;
			break;
		case 214: // PageUp
			trigger = 280;
			break;
		case 216: // PageDown
			trigger = 281;
			break;
		default: // A - Z
			// The characters are stored in the file in uppercase, but we need the lowercase versions for KeyCode:
			trigger = tolower(trigger);
			break;
		}

		_buttons[y]._trigger = Common::KeyCode(trigger);
		index = file.readByte();
		if (_buttons[y]._trigger != Common::KEYCODE_INVALID)
			_vm->_graphics->helpDrawButton(13 + (y + 1) * 27, index);
		_buttons[y]._whither = file.readByte(); // This is the position to jump to.

		Common::String text = "";
		switch (_buttons[y]._trigger) {
		case Common::KEYCODE_ESCAPE:
			text = Common::String("Esc");
			break;
		case Common::KEYCODE_PAGEUP:
			text = Common::String(24);
			break;
		case Common::KEYCODE_PAGEDOWN:
			text = Common::String(25);
			break;
		default:
			text = Common::String(toupper(_buttons[y]._trigger));
			break;
		}

		_vm->_graphics->helpDrawBigText(text, 589 - (text.size() * 8), 18 + (y + 1) * 27, kColorBlack);
		_vm->_graphics->helpDrawBigText(text, 590 - (text.size() * 8), 17 + (y + 1) * 27, kColorCyan);

		y++;
		_buttonNum++;
	}

	_vm->_graphics->refreshScreen();

	file.close();
}
Exemple #23
0
void GfxControls32::kernelTexteditChange(reg_t controlObject) {
	SciEvent curEvent;
	uint16 maxChars = 40;	//readSelectorValue(_segMan, controlObject, SELECTOR(max));	// TODO
	reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text));
	GfxFont *font = _cache->getFont(readSelectorValue(_segMan, controlObject, SELECTOR(font)));
	Common::String text;
	uint16 textSize;
	bool textChanged = false;
	bool textAddChar = false;
	Common::Rect rect;

	if (textReference.isNull())
		error("kEditControl called on object that doesn't have a text reference");
	text = _segMan->getString(textReference);

	// TODO: Finish this
	warning("kEditText ('%s')", text.c_str());
	return;

	uint16 cursorPos = 0;
	//uint16 oldCursorPos = cursorPos;
	bool captureEvents = true;
	EventManager* eventMan = g_sci->getEventManager();

	while (captureEvents) {
		curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK);

		if (curEvent.type == SCI_EVENT_NONE) {
			eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
		} else {
			textSize = text.size();

			switch (curEvent.type) {
			case SCI_EVENT_MOUSE_PRESS:
				// TODO: Implement mouse support for cursor change
				break;
			case SCI_EVENT_KEYBOARD:
				switch (curEvent.character) {
				case SCI_KEY_BACKSPACE:
					if (cursorPos > 0) {
						cursorPos--; text.deleteChar(cursorPos);
						textChanged = true;
					}
					eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
					break;
				case SCI_KEY_DELETE:
					if (cursorPos < textSize) {
						text.deleteChar(cursorPos);
						textChanged = true;
					}
					eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
					break;
				case SCI_KEY_HOME: // HOME
					cursorPos = 0; textChanged = true;
					eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
					break;
				case SCI_KEY_END: // END
					cursorPos = textSize; textChanged = true;
					eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
					break;
				case SCI_KEY_LEFT: // LEFT
					if (cursorPos > 0) {
						cursorPos--; textChanged = true;
					}
					eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
					break;
				case SCI_KEY_RIGHT: // RIGHT
					if (cursorPos + 1 <= textSize) {
						cursorPos++; textChanged = true;
					}
					eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
					break;
				case 3:	// returned in SCI1 late and newer when Control - C is pressed
					if (curEvent.modifiers & SCI_KEYMOD_CTRL) {
						// Control-C erases the whole line
						cursorPos = 0; text.clear();
						textChanged = true;
					}
					eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
					break;
				case SCI_KEY_UP:
				case SCI_KEY_DOWN:
				case SCI_KEY_ENTER:
				case SCI_KEY_ESC:
				case SCI_KEY_TAB:
				case SCI_KEY_SHIFT_TAB:
					captureEvents = false;
					break;
				default:
					if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.character == 'c') {
						// Control-C in earlier SCI games (SCI0 - SCI1 middle)
						// Control-C erases the whole line
						cursorPos = 0; text.clear();
						textChanged = true;
					} else if (curEvent.character > 31 && curEvent.character < 256 && textSize < maxChars) {
						// insert pressed character
						textAddChar = true;
						textChanged = true;
					}
					eventMan->getSciEvent(SCI_EVENT_KEYBOARD);	// consume the event
					break;
				}
				break;
			}
		}

		if (textChanged) {
			rect = g_sci->_gfxCompare->getNSRect(controlObject);

			if (textAddChar) {
				const char *textPtr = text.c_str();

				// We check if we are really able to add the new char
				uint16 textWidth = 0;
				while (*textPtr)
					textWidth += font->getCharWidth((byte)*textPtr++);
				textWidth += font->getCharWidth(curEvent.character);

				// Does it fit?
				if (textWidth >= rect.width()) {
					return;
				}

				text.insertChar(curEvent.character, cursorPos++);

				// Note: the following checkAltInput call might make the text
				// too wide to fit, but SSCI fails to check that too.
			}

			reg_t hunkId = readSelector(_segMan, controlObject, SELECTOR(bitmap));
			Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(controlObject);
			//texteditCursorErase();	// TODO: Cursor

			// Write back string
			_segMan->strcpy(textReference, text.c_str());
			// Modify the buffer and show it
			warning("kernelTexteditChange");
#if 0
			_text->createTextBitmap(controlObject, 0, 0, hunkId);

			_text->drawTextBitmap(0, 0, nsRect, controlObject);
			//texteditCursorDraw(rect, text.c_str(), cursorPos);	// TODO: Cursor
			g_system->updateScreen();
#endif
		} else {
			// TODO: Cursor
			/*
			if (g_system->getMillis() >= _texteditBlinkTime) {
				_paint16->invertRect(_texteditCursorRect);
				_paint16->bitsShow(_texteditCursorRect);
				_texteditCursorVisible = !_texteditCursorVisible;
				texteditSetBlinkTime();
			}
			*/
		}

		textAddChar = false;
		textChanged = false;
		g_sci->sleep(10);
	}	// while
}
Exemple #24
0
Common::String HiRes4Engine_Atari::formatVerbError(const Common::String &verb) const {
	Common::String err = _strings.verbError;
	for (uint i = 0; i < verb.size(); ++i)
		err.setChar(verb[i], i + 8);
	return err;
}
Exemple #25
0
static uint find_in_str(const Common::String &str, char c, uint pos = 0) {
	while (pos < str.size() && str[pos] != c) ++pos;
	return pos;
}
Exemple #26
0
void SystemClass::dump(Common::WriteStream *stream) {
	Common::String str;
	str = Common::String::format("%03d %c %-20s instances: %d\n", _iD, _persistent ? 'p' : ' ', _name.c_str(), getNumInstances());
	stream->write(str.c_str(), str.size());
}
Exemple #27
0
void ComposerEngine::loadLibrary(uint id) {
	if (getGameType() == GType_ComposerV1 && !_libraries.empty()) {
		// kill the previous page, starting with any scripts running on it

		for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++)
			delete *i;
		_oldScripts.clear();

		Library *library = &_libraries.front();
		unloadLibrary(library->_id);
	}

	Common::String filename;

	if (getGameType() == GType_ComposerV1) {
		if (!id || _bookGroup.empty())
			filename = getStringFromConfig("Common", "StartPage");
		else
			filename = getStringFromConfig(_bookGroup, Common::String::format("%d", id));
		filename = mangleFilename(filename);

		// bookGroup is the basename of the path.
		// TODO: tidy this up.
		_bookGroup.clear();
		for (uint i = 0; i < filename.size(); i++) {
			if (filename[i] == '~' || filename[i] == '/' || filename[i] == ':')
				continue;
			for (uint j = 0; j < filename.size(); j++) {
				if (filename[j] == '/') {
					_bookGroup.clear();
					continue;
				}
				if (filename[j] == '.')
					break;
				_bookGroup += filename[j];
			}
			break;
		}
	} else {
		if (!id)
			id = atoi(getStringFromConfig("Common", "StartUp").c_str());
		filename = getFilename("Libs", id);
	}

	Library library;

	library._id = id;
	library._archive = new ComposerArchive();
	if (!library._archive->openFile(filename))
		error("failed to open '%s'", filename.c_str());
	_libraries.push_front(library);

	Library &newLib = _libraries.front();

	Common::Array<uint16> buttonResources = library._archive->getResourceIDList(ID_BUTN);
	for (uint i = 0; i < buttonResources.size(); i++) {
		uint16 buttonId = buttonResources[i];
		Common::SeekableReadStream *stream = library._archive->getResource(ID_BUTN, buttonId);
		Button button(stream, buttonId, getGameType());

		bool inserted = false;
		for (Common::List<Button>::iterator b = newLib._buttons.begin(); b != newLib._buttons.end(); b++) {
			if (button._zorder < b->_zorder)
				continue;
			newLib._buttons.insert(b, button);
			inserted = true;
			break;
		}
		if (!inserted)
			newLib._buttons.push_back(button);
	}

	Common::Array<uint16> ambientResources = library._archive->getResourceIDList(ID_AMBI);
	for (uint i = 0; i < ambientResources.size(); i++) {
		Common::SeekableReadStream *stream = library._archive->getResource(ID_AMBI, ambientResources[i]);
		Button button(stream);
		newLib._buttons.insert(newLib._buttons.begin(), button);
	}

	Common::Array<uint16> accelResources = library._archive->getResourceIDList(ID_ACEL);
	for (uint i = 0; i < accelResources.size(); i++) {
		Common::SeekableReadStream *stream = library._archive->getResource(ID_ACEL, accelResources[i]);
		KeyboardHandler handler;
		handler.keyId = stream->readUint16LE();
		handler.modifierId = stream->readUint16LE();
		handler.scriptId = stream->readUint16LE();
		newLib._keyboardHandlers.push_back(handler);
	}

	Common::Array<uint16> randResources = library._archive->getResourceIDList(ID_RAND);
	for (uint i = 0; i < randResources.size(); i++) {
		Common::SeekableReadStream *stream = library._archive->getResource(ID_RAND, randResources[i]);
		Common::Array<RandomEvent> &events = _randomEvents[randResources[i]];
		uint16 count = stream->readUint16LE();
		for (uint j = 0; j < count; j++) {
			RandomEvent random;
			random.scriptId = stream->readUint16LE();
			random.weight = stream->readUint16LE();
			events.push_back(random);
		}
		delete stream;
	}

	// add background sprite, if it exists
	if (hasResource(ID_BMAP, 1000))
		setBackground(1000);

	// TODO: better CTBL logic
	loadCTBL(1000, 100);

	// Run the startup script.
	runScript(1000, 0, 0, 0);

	_mouseEnabled = true;
	onMouseMove(_lastMousePos);

	runEvent(kEventLoad, id, 0, 0);
}
Exemple #28
0
void CGEEngine::loadSprite(const char *fname, int ref, int scene, int col = 0, int row = 0, int pos = 0) {
	static const char *Comd[] = { "Name", "Type", "Phase", "East",
	                              "Left", "Right", "Top", "Bottom",
	                              "Seq", "Near", "Take",
	                              "Portable", "Transparent",
	                              NULL
	                            };
	static const char *Type[] = { "DEAD", "AUTO", "WALK", "NEWTON", "LISSAJOUS",
	                              "FLY", NULL
	                            };

	int shpcnt = 0;
	int type = 0; // DEAD
	bool east = false;
	bool port = false;
	bool tran = false;
	int i, lcnt = 0;

	char tmpStr[kLineMax + 1];
	Common::String line;
	mergeExt(tmpStr, fname, kSprExt);

	if (_resman->exist(tmpStr)) {      // sprite description file exist
		EncryptedStream sprf(this, tmpStr);
		if (sprf.err())
			error("Bad SPR [%s]", tmpStr);

		uint16 len;
		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
			len = line.size();
			lcnt++;
			strcpy(tmpStr, line.c_str());
			if (len == 0 || *tmpStr == '.')
				continue;

			if ((i = takeEnum(Comd, strtok(tmpStr, " =\t"))) < 0)
				error("Bad line %d [%s]", lcnt, fname);


			switch (i) {
			case  0 : // Name - will be taken in Expand routine
				break;
			case  1 : // Type
				if ((type = takeEnum(Type, strtok(NULL, " \t,;/"))) < 0)
					error("Bad line %d [%s]", lcnt, fname);
				break;
			case  2 : // Phase
				shpcnt++;
				break;
			case  3 : // East
				east = (atoi(strtok(NULL, " \t,;/")) != 0);
				break;
			case 11 : // Portable
				port = (atoi(strtok(NULL, " \t,;/")) != 0);
				break;
			case 12 : // Transparent
				tran = (atoi(strtok(NULL, " \t,;/")) != 0);
				break;
			}
		}
		if (! shpcnt)
			error("No shapes [%s]", fname);
	} else {
		// no sprite description: mono-shaped sprite with only .BMP file
		++shpcnt;
	}

	// make sprite of choosen type
	switch (type) {
	case 1:
		// AUTO
		_sprite = new Sprite(this, NULL);
		if (_sprite) {
			_sprite->gotoxy(col, row);
		}
		break;
	case 2:
		{ // WALK
		Walk *w = new Walk(this, NULL);
		if (w && ref == 1) {
			w->gotoxy(col, row);
			if (_hero)
				error("2nd HERO [%s]", fname);
			_hero = w;
		}
		_sprite = w;
		break;
		}
	case 3:  // NEWTON
	case 4:  // LISSAJOUS
		error("Bad type [%s]", fname);
		break;
	case 5:
		{ // FLY
		Fly *f = new Fly(this, NULL);
		_sprite = f;
		break;
		}
	default:
		// DEAD
		_sprite = new Sprite(this, NULL);
		if (_sprite)
			_sprite->gotoxy(col, row);
		break;
	}

	if (_sprite) {
		_sprite->_ref = ref;
		_sprite->_scene = scene;
		_sprite->_z = pos;
		_sprite->_flags._east = east;
		_sprite->_flags._port = port;
		_sprite->_flags._tran = tran;
		_sprite->_flags._kill = true;
		_sprite->_flags._bDel = true;

		// Extract the filename, without the extension
		strcpy(_sprite->_file, fname);
		char *p = strchr(_sprite->_file, '.');
		if (p)
			*p = '\0';

		_sprite->_shpCnt = shpcnt;
		_vga->_spareQ->append(_sprite);
	}
}
Exemple #29
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.err()) {
		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.err() && !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;
}
Exemple #30
0
void CGEEngine::loadScript(const char *fname) {
	EncryptedStream scrf(this, fname);

	if (scrf.err())
		return;

	bool ok = true;
	int lcnt = 0;

	char tmpStr[kLineMax+1];
	Common::String line;

	for (line = scrf.readLine(); !scrf.eos(); line = scrf.readLine()) {
		char *p;

		lcnt++;
		strcpy(tmpStr, line.c_str());
		if ((line.size() == 0) || (*tmpStr == '.'))
			continue;

		ok = false;   // not OK if break

		// sprite ident number
		if ((p = strtok(tmpStr, " \t\n")) == NULL)
			break;
		int SpI = atoi(p);

		// sprite file name
		char *SpN;
		if ((SpN = strtok(NULL, " ,;/\t\n")) == NULL)
			break;

		// sprite scene
		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
			break;
		int SpA = atoi(p);

		// sprite column
		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
			break;
		int SpX = atoi(p);

		// sprite row
		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
			break;
		int SpY = atoi(p);

		// sprite Z pos
		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
			break;
		int SpZ = atoi(p);

		// sprite life
		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
			break;
		bool BkG = atoi(p) == 0;

		ok = true;    // no break: OK

		_sprite = NULL;
		loadSprite(SpN, SpI, SpA, SpX, SpY, SpZ);
		if (_sprite && BkG)
			_sprite->_flags._back = true;
	}

	if (!ok)
		error("Bad INI line %d [%s]", lcnt, fname);
}