Exemple #1
0
/**
 * Loads the contents of the mort.dat data file
 */
Common::ErrorCode MortevielleEngine::loadMortDat() {
	Common::File f;

	// Open the mort.dat file
	if (!f.open(MORT_DAT)) {
		Common::String msg = Common::String::format(_("Unable to locate the '%s' engine data file."), MORT_DAT);
		GUIErrorMessage(msg);
		return Common::kReadingFailed;
	}

	// Validate the data file header
	char fileId[4];
	f.read(fileId, 4);
	if (strncmp(fileId, "MORT", 4) != 0) {
		Common::String msg = Common::String::format(_("The '%s' engine data file is corrupt."), MORT_DAT);
		GUIErrorMessage(msg);
		return Common::kReadingFailed;
	}

	// Check the version
	int majVer = f.readByte();
	int minVer = f.readByte();

	if (majVer < MORT_DAT_REQUIRED_VERSION) {
		Common::String msg = Common::String::format(
			_("Incorrect version of the '%s' engine data file found. Expected %d.%d but got %d.%d."),
			MORT_DAT, MORT_DAT_REQUIRED_VERSION, 0, majVer, minVer);
		GUIErrorMessage(msg);
		return Common::kReadingFailed;
	}

	// Loop to load resources from the data file
	while (f.pos() < f.size()) {
		// Get the Id and size of the next resource
		char dataType[4];
		int dataSize;
		f.read(dataType, 4);
		dataSize = f.readUint16LE();

		if (!strncmp(dataType, "FONT", 4)) {
			// Font resource
			_screenSurface->readFontData(f, dataSize);
		} else if (!strncmp(dataType, "SSTR", 4)) {
			readStaticStrings(f, dataSize, kStaticStrings);
		} else if ((!strncmp(dataType, "GSTR", 4)) && (!_txxFileFl)) {
			readStaticStrings(f, dataSize, kGameStrings);
		} else if (!strncmp(dataType, "VERB", 4)) {
			_menu->readVerbNums(f, dataSize);
		} else {
			// Unknown section
			f.skip(dataSize);
		}
	}

	// Close the file
	f.close();

	assert(_engineStrings.size() > 0);
	return Common::kNoError;
}
Exemple #2
0
bool Resources::loadArchives(const ADGameDescription *gd) {
	Common::File *dat_file = new Common::File();
	Common::String filename = "teenagent.dat";
	if (!dat_file->open(filename.c_str())) {
		delete dat_file;
		Common::String errorMessage = Common::String::format(_("Unable to locate the '%s' engine data file."), filename.c_str());
		warning("%s", errorMessage.c_str());
		GUIErrorMessage(errorMessage);
		return false;
	}

	// teenagent.dat used to be compressed with zlib compression. The usage of
	// zlib here is no longer needed, and it's maintained only for backwards
	// compatibility.
	Common::SeekableReadStream *dat = Common::wrapCompressedReadStream(dat_file);

#if !defined(USE_ZLIB)
	uint16 header = dat->readUint16BE();
	bool isCompressed = (header == 0x1F8B ||
				     ((header & 0x0F00) == 0x0800 &&
				      header % 31 == 0));
	dat->seek(-2, SEEK_CUR);

	if (isCompressed) {
		// teenagent.dat is compressed, but zlib hasn't been compiled in
		delete dat;
		Common::String errorMessage = _("The teenagent.dat file is compressed and zlib hasn't been included in this executable. Please decompress it");
		warning("%s", errorMessage.c_str());
		GUIErrorMessage(errorMessage);
		return false;
	}
#endif

	dat->skip(CSEG_SIZE);
	dseg.read(dat, DSEG_SIZE);
	eseg.read(dat, ESEG_SIZE);
	delete dat;

	precomputeDialogOffsets();

	FilePack varia;
	varia.open("varia.res");
	font7.load(varia, 7, 11, 1);
	font8.load(varia, 8, 31, 0);
	varia.close();

	off.open("off.res");
	on.open("on.res");
	ons.open("ons.res");
	lan000.open("lan_000.res");
	lan500.open("lan_500.res");
	mmm.open("mmm.res");
	sam_mmm.open("sam_mmm.res");
	sam_sam.open("sam_sam.res");
	voices.open("voices.res");

	return true;
}
Exemple #3
0
/**
 * Loads the contents of the mort.dat data file
 */
Common::ErrorCode MortevielleEngine::loadMortDat() {
	Common::File f;

	// Open the mort.dat file
	if (!f.open(MORT_DAT)) {
		GUIErrorMessage("Could not locate 'mort.dat'.");
		return Common::kReadingFailed;
	}

	// Validate the data file header
	char fileId[4];
	f.read(fileId, 4);
	if (strncmp(fileId, "MORT", 4) != 0) {
		GUIErrorMessage("The located mort.dat data file is invalid");
		return Common::kReadingFailed;
	}

	// Check the version
	if (f.readByte() < MORT_DAT_REQUIRED_VERSION) {
		GUIErrorMessage("The located mort.dat data file is too old, please download an updated version on scummvm.org");
		return Common::kReadingFailed;
	}
	f.readByte();		// Minor version

	// Loop to load resources from the data file
	while (f.pos() < f.size()) {
		// Get the Id and size of the next resource
		char dataType[4];
		int dataSize;
		f.read(dataType, 4);
		dataSize = f.readUint16LE();

		if (!strncmp(dataType, "FONT", 4)) {
			// Font resource
			_screenSurface.readFontData(f, dataSize);
		} else if (!strncmp(dataType, "SSTR", 4)) {
			readStaticStrings(f, dataSize, kStaticStrings);
		} else if ((!strncmp(dataType, "GSTR", 4)) && (!_txxFileFl)) {
			readStaticStrings(f, dataSize, kGameStrings);
		} else if (!strncmp(dataType, "VERB", 4)) {
			_menu.readVerbNums(f, dataSize);
		} else {
			// Unknown section
			f.skip(dataSize);
		}
	}

	// Close the file
	f.close();

	assert(_engineStrings.size() > 0);
	return Common::kNoError;
}
Exemple #4
0
bool MohawkEngine_Riven::checkDatafiles() {
	Common::String missingFiles;

	const char **datafiles = listExpectedDatafiles();
	for (int i = 0; datafiles[i] != nullptr; i++) {
		if (!SearchMan.hasFile(datafiles[i])) {
			if (strcmp(datafiles[i], "j_Data3.mhk") == 0
					|| strcmp(datafiles[i], "b_Data1.mhk") == 0) {
				// j_Data3.mhk and b_Data1.mhk come from the 1.02 patch. They are not required to play.
				continue;
			}

			if (!missingFiles.empty()) {
				missingFiles += ", ";
			}
			missingFiles += datafiles[i];
		}
	}

	if (missingFiles.empty()) {
		return true;
	}

	Common::String message = _("You are missing the following required Riven data files:\n") + missingFiles;
	warning("%s", message.c_str());
	GUIErrorMessage(message);

	return false;
}
void GUIErrorMessageFormat(const char *fmt, ...) {
	Common::String msg;

	va_list va;
	va_start(va, fmt);
	msg = Common::String::vformat(fmt, va);
	va_end(va);

	GUIErrorMessage(msg);
}
Exemple #6
0
void LureEngine::GUIError(const char *msg, ...) {
	char buffer[STRINGBUFLEN];
	va_list va;

	// Generate the full error message
	va_start(va, msg);
	vsnprintf(buffer, STRINGBUFLEN, msg, va);
	va_end(va);

	GUIErrorMessage(buffer);
}
Exemple #7
0
void KyraEngine_v1::loadGameStateCheck(int slot) {
	if (loadGameState(slot) != Common::kNoError) {
		const char *filename = getSavegameFilename(slot);
		Common::String errorMessage = "Could not load savegame: '";
		errorMessage += filename;
		errorMessage += "'";

		GUIErrorMessage(errorMessage);
		error("%s", errorMessage.c_str());
	}
}
Exemple #8
0
void KyraEngine_v1::loadGameStateCheck(int slot) {
	// FIXME: Instead of throwing away the error returned by
	// loadGameState, we should use it / augment it.
	if (loadGameState(slot).getCode() != Common::kNoError) {
		const char *filename = getSavegameFilename(slot);
		Common::String errorMessage = "Could not load savegame: '";
		errorMessage += filename;
		errorMessage += "'";

		GUIErrorMessage(errorMessage);
		error("%s", errorMessage.c_str());
	}
}
Exemple #9
0
byte *Sword2Engine::fetchPsxBackground(uint32 location) {
	Common::File file;
	PSXScreensEntry header;
	uint32 screenOffset, dataOffset;
	uint32 totSize; // Total size of background, counting data, offset table and additional header
	byte *buffer;

	if (!file.open("screens.clu")) {
		GUIErrorMessage("Broken Sword 2: Cannot open screens.clu");
		return NULL;
	}

	file.seek(location * 4, SEEK_SET);
	screenOffset = file.readUint32LE();

	if (screenOffset == 0) { // We don't have screen data for this location number.
		file.close();
		return NULL;
	}

	// Get to the beginning of PSXScreensEntry
	file.seek(screenOffset + ResHeader::size(), SEEK_SET);

	buffer = (byte *)malloc(PSXScreensEntry::size());
	file.read(buffer, PSXScreensEntry::size());

	// Prepare the header
	header.read(buffer);
	free(buffer);

	file.seek(screenOffset + header.bgOffset + 4, SEEK_SET);
	dataOffset = file.readUint32LE();

	file.seek(screenOffset + header.bgOffset, SEEK_SET);

	totSize = header.bgSize + (dataOffset - header.bgOffset) + 8;
	buffer = (byte *)malloc(totSize);

	// Write some informations before background data
	WRITE_LE_UINT16(buffer, header.bgXres);
	WRITE_LE_UINT16(buffer + 2, header.bgYres);
	WRITE_LE_UINT32(buffer + 4, header.bgOffset);

	file.read(buffer + 8, totSize - 8); // Do not write on the header
	file.close();

	return buffer;
}
Exemple #10
0
Common::Error MohawkEngine_Riven::run() {
	MohawkEngine::run();

	// Let's try to open the installer file (it holds extras.mhk)
	// Though, we set a low priority to prefer the extracted version
	if (_installerArchive.open("arcriven.z"))
		SearchMan.add("arcriven.z", &_installerArchive, 0, false);

	_gfx = new RivenGraphics(this);
	_console = new RivenConsole(this);
	_saveLoad = new RivenSaveLoad(this, _saveFileMan);
	_externalScriptHandler = new RivenExternal(this);
	_optionsDialog = new RivenOptionsDialog(this);
	_scriptMan = new RivenScriptManager(this);

	_rnd = new Common::RandomSource("riven");

	// Create the cursor manager
	if (Common::File::exists("rivendmo.exe"))
		_cursor = new PECursorManager("rivendmo.exe");
	else if (Common::File::exists("riven.exe"))
		_cursor = new PECursorManager("riven.exe");
	else // last resort: try the Mac executable
		_cursor = new MacCursorManager("Riven");

	initVars();

	// We need to have a cursor source, or the game won't work
	if (!_cursor->hasSource()) {
		Common::String message = "You're missing a Riven executable. The Windows executable is 'riven.exe' or 'rivendmo.exe'. ";
		message += "Using the 'arcriven.z' installer file also works. In addition, you can use the Mac 'Riven' executable.";
		GUIErrorMessage(message);
		warning("%s", message.c_str());
		return Common::kNoGameDataFoundError;
	}

	// Open extras.mhk for common images
	_extrasFile = new MohawkArchive();

	// We need extras.mhk for inventory images, marble images, and credits images
	if (!_extrasFile->openFile("extras.mhk")) {
		Common::String message = "You're missing 'extras.mhk'. Using the 'arcriven.z' installer file also works.";
		GUIErrorMessage(message);
		warning("%s", message.c_str());
		return Common::kNoGameDataFoundError;
	}

	// Set the transition speed
	_gfx->setTransitionSpeed(_vars["transitionmode"]);

	// Start at main cursor
	_cursor->setCursor(kRivenMainCursor);
	_cursor->showCursor();
	_system->updateScreen();

	// Let's begin, shall we?
	if (getFeatures() & GF_DEMO) {
		// Start the demo off with the videos
		changeToStack(kStackAspit);
		changeToCard(6);
	} else if (ConfMan.hasKey("save_slot")) {
		// Load game from launcher/command line if requested
		uint32 gameToLoad = ConfMan.getInt("save_slot");
		Common::StringArray savedGamesList = _saveLoad->generateSaveGameList();
		if (gameToLoad > savedGamesList.size())
			error ("Could not find saved game");

		// Attempt to load the game. On failure, just send us to the main menu.
		if (_saveLoad->loadGame(savedGamesList[gameToLoad]).getCode() != Common::kNoError) {
			changeToStack(kStackAspit);
			changeToCard(1);
		}
	} else {
		// Otherwise, start us off at aspit's card 1 (the main menu)
		changeToStack(kStackAspit);
		changeToCard(1);
	}


	while (!_gameOver && !shouldQuit())
		handleEvents();

	return Common::kNoError;
}
Exemple #11
0
Common::Error SagaEngine::run() {
	setTotalPlayTime(0);

	// Assign default values to the config manager, in case settings are missing
	ConfMan.registerDefault("talkspeed", "255");
	ConfMan.registerDefault("subtitles", "true");

	_musicVolume = ConfMan.getInt("music_volume");
	_subtitlesEnabled = ConfMan.getBool("subtitles");
	_readingSpeed = getTalkspeed();
	_copyProtection = ConfMan.getBool("copy_protection");
	_musicWasPlaying = false;
	_isIHNMDemo = Common::File::exists("music.res");
	_hasITESceneSubstitutes = Common::File::exists("boarhall.bbm");

	if (_readingSpeed > 3)
		_readingSpeed = 0;

	switch (getGameId()) {
		case GID_ITE:
			_resource = new Resource_RSC(this);
			break;
#ifdef ENABLE_IHNM
		case GID_IHNM:
			_resource = new Resource_RES(this);
			break;
#endif
#ifdef ENABLE_SAGA2
		case GID_DINO:
		case GID_FTA2:
			_resource = new Resource_HRS(this);
			break;
#endif
	}

	// Detect game and open resource files
	if (!initGame()) {
		GUIErrorMessage("Error loading game resources.");
		return Common::kUnknownError;
	}

	// Initialize engine modules
	// TODO: implement differences for SAGA2
	_sndRes = new SndRes(this);
	_events = new Events(this);

	if (!isSaga2()) {
		_font = new Font(this);
		_sprite = new Sprite(this);
		_script = new SAGA1Script(this);
	} else {
		_script = new SAGA2Script(this);
	}

	_anim = new Anim(this);
	_interface = new Interface(this); // requires script module
	_scene = new Scene(this);
	_actor = new Actor(this);
	_palanim = new PalAnim(this);

	if (getGameId() == GID_ITE) {
		_isoMap = new IsoMap(this);
		_puzzle = new Puzzle(this);
	}

	// System initialization

	_previousTicks = _system->getMillis();

	// Initialize graphics
	_gfx = new Gfx(this, _system, getDisplayInfo().width, getDisplayInfo().height);

	// Graphics driver should be initialized before console
	_console = new Console(this);

	// Graphics should be initialized before music
	_music = new Music(this, _mixer);
	_render = new Render(this, _system);
	if (!_render->initialized()) {
		return Common::kUnknownError;
	}

	// Initialize system specific sound
	_sound = new Sound(this, _mixer);

	if (!isSaga2()) {
		_interface->converseClear();
		_script->setVerb(_script->getVerbType(kVerbWalkTo));
	}

	_music->setVolume(_musicVolume, 1);

	if (!isSaga2()) {
		_gfx->initPalette();
	}

	if (_voiceFilesExist) {
		if (getGameId() == GID_IHNM) {
			if (!ConfMan.hasKey("voices")) {
				_voicesEnabled = true;
				ConfMan.setBool("voices", true);
			} else {
				_voicesEnabled = ConfMan.getBool("voices");
			}
		} else {
			_voicesEnabled = true;
		}
	}

	syncSoundSettings();

	int msec = 0;

	_previousTicks = _system->getMillis();

	if (ConfMan.hasKey("start_scene")) {
		_scene->changeScene(ConfMan.getInt("start_scene"), 0, kTransitionNoFade);
	} else if (ConfMan.hasKey("boot_param")) {
		if (getGameId() == GID_ITE)
			_interface->addToInventory(_actor->objIndexToId(0));	// Magic hat
		_scene->changeScene(ConfMan.getInt("boot_param"), 0, kTransitionNoFade);
	} else if (ConfMan.hasKey("save_slot")) {
		// Init the current chapter to 8 (character selection) for IHNM
		if (getGameId() == GID_IHNM)
			_scene->changeScene(-2, 0, kTransitionFade, 8);

		// First scene sets up palette
		_scene->changeScene(getStartSceneNumber(), 0, kTransitionNoFade);
		_events->handleEvents(0); // Process immediate events

		if (getGameId() == GID_ITE)
			_interface->setMode(kPanelMain);
		else
			_interface->setMode(kPanelChapterSelection);

		char *fileName = calcSaveFileName(ConfMan.getInt("save_slot"));
		load(fileName);
		syncSoundSettings();
	} else {
		_framesEsc = 0;
		_scene->startScene();
	}

	uint32 currentTicks;

	while (!shouldQuit()) {
		_console->onFrame();

		if (_render->getFlags() & RF_RENDERPAUSE) {
			// Freeze time while paused
			_previousTicks = _system->getMillis();
		} else {
			currentTicks = _system->getMillis();
			// Timer has rolled over after 49 days
			if (currentTicks < _previousTicks)
				msec = 0;
			else {
				msec = currentTicks - _previousTicks;
				_previousTicks = currentTicks;
			}
			if (msec > MAX_TIME_DELTA) {
				msec = MAX_TIME_DELTA;
			}

			// Since Puzzle and forced text are actorless, we do them here
			if ((getGameId() == GID_ITE && _puzzle->isActive()) || _actor->isForcedTextShown()) {
				_actor->handleSpeech(msec);
			} else if (!_scene->isInIntro()) {
				if (_interface->getMode() == kPanelMain ||
						_interface->getMode() == kPanelConverse ||
						_interface->getMode() == kPanelCutaway ||
						_interface->getMode() == kPanelNull ||
						_interface->getMode() == kPanelChapterSelection)
					_actor->direct(msec);
			}

			_events->handleEvents(msec);
			_script->executeThreads(msec);
		}
		// Per frame processing
		_render->drawScene();
		_system->delayMillis(10);
	}

	return Common::kNoError;
}
Exemple #12
0
/**
 * Display an error message
 */
void TonyEngine::GUIError(const Common::String &msg) {
	GUIErrorMessage(msg);
}
Exemple #13
0
bool TonyEngine::loadTonyDat() {
	Common::String msg;
	Common::File in;

	in.open("tony.dat");

	if (!in.isOpen()) {
		msg = "You're missing the 'tony.dat' file. Get it from the ScummVM website";
		GUIErrorMessage(msg);
		warning("%s", msg.c_str());
		return false;
	}

	// Read header
	char buf[4+1];
	in.read(buf, 4);
	buf[4] = '\0';

	if (strcmp(buf, "TONY")) {
		msg = "File 'tony.dat' is corrupt. Get it from the ScummVM website";
		GUIErrorMessage(msg);
		warning("%s", msg.c_str());
		return false;
	}

	int majVer = in.readByte();
	int minVer = in.readByte();

	if ((majVer != TONY_DAT_VER_MAJ) || (minVer != TONY_DAT_VER_MIN)) {
		msg = Common::String::format("File 'tony.dat' is wrong version. Expected %d.%d but got %d.%d. Get it from the ScummVM website", TONY_DAT_VER_MAJ, TONY_DAT_VER_MIN, majVer, minVer);
		GUIErrorMessage(msg);
		warning("%s", msg.c_str());

		return false;
	}

	int expectedLangVariant = -1;
	switch (g_vm->getLanguage()) {
	case Common::IT_ITA:
	case Common::EN_ANY:
		expectedLangVariant = 0;
		break;
	case Common::PL_POL:
		expectedLangVariant = 1;
		break;
	case Common::RU_RUS:
		expectedLangVariant = 2;
		break;
	case Common::CZ_CZE:
		expectedLangVariant = 3;
		break;
	case Common::FR_FRA:
		expectedLangVariant = 4;
		break;
	case Common::DE_DEU:
		expectedLangVariant = 5;
		break;
	default:
		warning("Unhandled language, falling back to English/Italian fonts.");
		expectedLangVariant = 0;
		break;
	}

	int numVariant = in.readUint16BE();
	if (expectedLangVariant > numVariant - 1) {
		msg = Common::String::format("Font variant not present in 'tony.dat'. Get it from the ScummVM website");
		GUIErrorMessage(msg);
		warning("%s", msg.c_str());

		return false;
	}

	in.seek(in.pos() + (2 * 256 * 8 * expectedLangVariant));
	for (int i = 0; i < 256; i++) {
		_cTableDialog[i] = in.readSint16BE();
		_lTableDialog[i] = in.readSint16BE();
		_cTableMacc[i] = in.readSint16BE();
		_lTableMacc[i] = in.readSint16BE();
		_cTableCred[i] = in.readSint16BE();
		_lTableCred[i] = in.readSint16BE();
		_cTableObj[i] = in.readSint16BE();
		_lTableObj[i] = in.readSint16BE();
	}

	return true;
}
Exemple #14
0
bool DrasculaEngine::loadDrasculaDat() {
	Common::File in;
	int i;

	in.open("drascula.dat");

	if (!in.isOpen()) {
		Common::String errorMessage = "You're missing the 'drascula.dat' file. Get it from the ScummVM website";
		GUIErrorMessage(errorMessage);
		warning("%s", errorMessage.c_str());

		return false;
	}

	char buf[256];
	int ver;

	in.read(buf, 8);
	buf[8] = '\0';

	if (strcmp(buf, "DRASCULA")) {
		Common::String errorMessage = "File 'drascula.dat' is corrupt. Get it from the ScummVM website";
		GUIErrorMessage(errorMessage);
		warning("%s", errorMessage.c_str());

		return false;
	}

	ver = in.readByte();

	if (ver != DRASCULA_DAT_VER) {
		snprintf(buf, 256, "File 'drascula.dat' is wrong version. Expected %d but got %d. Get it from the ScummVM website", DRASCULA_DAT_VER, ver);
		GUIErrorMessage(buf);
		warning("%s", buf);

		return false;
	}

	_charMapSize = in.readUint16BE();
	_charMap = (CharInfo *)malloc(sizeof(CharInfo) * _charMapSize);
	for (i = 0; i < _charMapSize; i++) {
		_charMap[i].inChar = in.readByte();
		_charMap[i].mappedChar = in.readSint16BE();
		_charMap[i].charType = in.readByte();
	}

	_itemLocationsSize = in.readUint16BE();
	_itemLocations = (ItemLocation *)malloc(sizeof(ItemLocation) * _itemLocationsSize);
	for (i = 0; i < _itemLocationsSize; i++) {
		_itemLocations[i].x = in.readSint16BE();
		_itemLocations[i].y = in.readSint16BE();
	}

	_polXSize = in.readUint16BE();
	_polX = (int *)malloc(sizeof(int) * _polXSize);
	_polY = (int *)malloc(sizeof(int) * _polXSize);
	for (i = 0; i < _polXSize; i++) {
		_polX[i] = in.readSint16BE();
		_polY[i] = in.readSint16BE();
	}

	_verbBarXSize = in.readUint16BE();
	_verbBarX = (int *)malloc(sizeof(int) * _verbBarXSize);
	for (i = 0; i < _verbBarXSize; i++) {
		_verbBarX[i] = in.readSint16BE();
	}

	_x1dMenuSize = in.readUint16BE();
	_x1d_menu = (int *)malloc(sizeof(int) * _x1dMenuSize);
	_y1d_menu = (int *)malloc(sizeof(int) * _x1dMenuSize);
	for (i = 0; i < _x1dMenuSize; i++) {
		_x1d_menu[i] = in.readSint16BE();
		_y1d_menu[i] = in.readSint16BE();
	}

	_frameXSize = in.readUint16BE();
	_frameX = (int *)malloc(sizeof(int) * _frameXSize);
	for (i = 0; i < _frameXSize; i++) {
		_frameX[i] = in.readSint16BE();
	}

	_candleXSize = in.readUint16BE();
	_candleX = (int *)malloc(sizeof(int) * _candleXSize);
	_candleY = (int *)malloc(sizeof(int) * _candleXSize);
	for (i = 0; i < _candleXSize; i++) {
		_candleX[i] = in.readSint16BE();
		_candleY[i] = in.readSint16BE();
	}

	_pianistXSize = in.readUint16BE();
	_pianistX = (int *)malloc(sizeof(int) * _pianistXSize);
	for (i = 0; i < _pianistXSize; i++) {
		_pianistX[i] = in.readSint16BE();
	}

	_drunkXSize = in.readUint16BE();
	_drunkX = (int *)malloc(sizeof(int) * _drunkXSize);
	for (i = 0; i < _drunkXSize; i++) {
		_drunkX[i] = in.readSint16BE();
	}

	_roomPreUpdatesSize = in.readUint16BE();
	_roomPreUpdates = (RoomUpdate *)malloc(sizeof(RoomUpdate) * _roomPreUpdatesSize);
	for (i = 0; i < _roomPreUpdatesSize; i++) {
		_roomPreUpdates[i].roomNum = in.readSint16BE();
		_roomPreUpdates[i].flag = in.readSint16BE();
		_roomPreUpdates[i].flagValue = in.readSint16BE();
		_roomPreUpdates[i].sourceX = in.readSint16BE();
		_roomPreUpdates[i].sourceY = in.readSint16BE();
		_roomPreUpdates[i].destX = in.readSint16BE();
		_roomPreUpdates[i].destY = in.readSint16BE();
		_roomPreUpdates[i].width = in.readSint16BE();
		_roomPreUpdates[i].height = in.readSint16BE();
		_roomPreUpdates[i].type = in.readSint16BE();
	}

	_roomUpdatesSize = in.readUint16BE();
	_roomUpdates = (RoomUpdate *)malloc(sizeof(RoomUpdate) * _roomUpdatesSize);
	for (i = 0; i < _roomUpdatesSize; i++) {
		_roomUpdates[i].roomNum = in.readSint16BE();
		_roomUpdates[i].flag = in.readSint16BE();
		_roomUpdates[i].flagValue = in.readSint16BE();
		_roomUpdates[i].sourceX = in.readSint16BE();
		_roomUpdates[i].sourceY = in.readSint16BE();
		_roomUpdates[i].destX = in.readSint16BE();
		_roomUpdates[i].destY = in.readSint16BE();
		_roomUpdates[i].width = in.readSint16BE();
		_roomUpdates[i].height = in.readSint16BE();
		_roomUpdates[i].type = in.readSint16BE();
	}

	_roomActionsSize = in.readUint16BE();
	_roomActions = (RoomTalkAction *)malloc(sizeof(RoomTalkAction) * _roomActionsSize);
	for (i = 0; i < _roomActionsSize; i++) {
		_roomActions[i].room = in.readSint16BE();
		_roomActions[i].chapter = in.readSint16BE();
		_roomActions[i].action = in.readSint16BE();
		_roomActions[i].objectID = in.readSint16BE();
		_roomActions[i].speechID = in.readSint16BE();
	}

	_talkSequencesSize = in.readUint16BE();
	_talkSequences = (TalkSequenceCommand *)malloc(sizeof(TalkSequenceCommand) * _talkSequencesSize);
	for (i = 0; i < _talkSequencesSize; i++) {
		_talkSequences[i].chapter = in.readSint16BE();
		_talkSequences[i].sequence = in.readSint16BE();
		_talkSequences[i].commandType = in.readSint16BE();
		_talkSequences[i].action = in.readSint16BE();
	}

	_numLangs = in.readUint16BE();

	_text = loadTexts(in);
	_textd = loadTexts(in);
	_textb = loadTexts(in);
	_textbj = loadTexts(in);
	_texte = loadTexts(in);
	_texti = loadTexts(in);
	_textl = loadTexts(in);
	_textp = loadTexts(in);
	_textt = loadTexts(in);
	_textvb = loadTexts(in);
	_textsys = loadTexts(in);
	_texthis = loadTexts(in);
	_textverbs = loadTexts(in);
	_textmisc = loadTexts(in);
	_textd1 = loadTexts(in);

	return true;
}
Exemple #15
0
Common::Error GobEngine::run() {
	if (!initGameParts()) {
		GUIErrorMessage("GobEngine::init(): Unknown version of game engine");
		return Common::kUnknownError;
	}

	if (!initGraphics()) {
		GUIErrorMessage("GobEngine::init(): Failed to set up graphics");
		return Common::kUnknownError;
	}

	// On some systems it's not safe to run CD audio games from the CD.
	if (isCD())
		checkCD();

	int cd_num = ConfMan.getInt("cdrom");
	if (cd_num >= 0)
		_system->getAudioCDManager()->openCD(cd_num);

	_global->_debugFlag = 1;
	_video->_doRangeClamp = true;

	// WORKAROUND: Some versions check the video mode to detect the system
	if (_platform == Common::kPlatformAmiga)
		_global->_fakeVideoMode = 0x11;
	else if (_platform == Common::kPlatformAtariST)
		_global->_fakeVideoMode = 0x10;
	else
		_global->_fakeVideoMode = 0x13;

	_global->_videoMode = 0x13;
	_global->_useMouse = 1;
	_global->_soundFlags = MIDI_FLAG | SPEAKER_FLAG | BLASTER_FLAG | ADLIB_FLAG;

	if (ConfMan.hasKey("language"))
		_language = Common::parseLanguage(ConfMan.get("language"));

	switch (_language) {
	case Common::FR_FRA:
	case Common::RU_RUS:
		_global->_language = kLanguageFrench;
		break;
	case Common::DE_DEU:
		_global->_language = kLanguageGerman;
		break;
	case Common::EN_ANY:
	case Common::EN_GRB:
	case Common::HU_HUN:
		_global->_language = kLanguageBritish;
		break;
	case Common::ES_ESP:
		_global->_language = kLanguageSpanish;
		break;
	case Common::IT_ITA:
		_global->_language = kLanguageItalian;
		break;
	case Common::EN_USA:
		_global->_language = kLanguageAmerican;
		break;
	case Common::NL_NLD:
		_global->_language = kLanguageDutch;
		break;
	case Common::KO_KOR:
		_global->_language = kLanguageKorean;
		break;
	case Common::HE_ISR:
		_global->_language = kLanguageHebrew;
		break;
	case Common::PT_BRA:
		_global->_language = kLanguagePortuguese;
		break;
	case Common::JA_JPN:
		_global->_language = kLanguageJapanese;
		break;
	default:
		_global->_language = kLanguageBritish;
		break;
	}
	_global->_languageWanted = _global->_language;

	_init->initGame();

	return Common::kNoError;
}
Exemple #16
0
bool ResourceManager::init() {
    uint32 i, j;

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

    setCD(1);

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

    Common::File file;

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

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

    while (1) {
        char *buf = _resFiles[_totalClusters].fileName;
        uint len = sizeof(_resFiles[_totalClusters].fileName);

        if (!file.readLine(buf, len))
            break;

        int pos = strlen(buf);
        if (buf[pos - 1] == 0x0A)
            buf[pos - 1] = 0;

        _resFiles[_totalClusters].numEntries = -1;
        _resFiles[_totalClusters].entryTab = NULL;
        if (++_totalClusters >= MAX_res_files) {
            GUIErrorMessage("Broken Sword II: Too many entries in resource.inf");
            return false;
        }
    }

    file.close();

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

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

    _totalResFiles = size / 4;

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

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

    if (file.eos() || file.err()) {
        file.close();
        GUIErrorMessage("Broken Sword II: Cannot read resource.tab");
        return false;
    }

    file.close();

    // Check that we have cd.inf file, unless we are running PSX
    // version, which has all files on one disc.

    if (!file.open("cd.inf") && !Sword2Engine::isPsx()) {
        GUIErrorMessage("Broken Sword II: Cannot open cd.inf");
        return false;
    }

    CdInf *cdInf = new CdInf[_totalClusters];

    for (i = 0; i < _totalClusters; i++) {

        if (Sword2Engine::isPsx()) { // We are running PSX version, artificially fill CdInf structure
            cdInf[i].cd = CD1;
        } else { // We are running PC version, read cd.inf file
            file.read(cdInf[i].clusterName, sizeof(cdInf[i].clusterName));

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

            if (file.eos() || file.err()) {
                delete[] cdInf;
                file.close();
                GUIErrorMessage("Broken Sword II: Cannot read cd.inf");
                return false;
            }

        }

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

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

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

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

    file.close();

    // We check the presence of resource files in cd.inf
    // This is ok in PC version, but in PSX version we don't
    // have cd.inf so we'll have to skip this.
    if (!Sword2Engine::isPsx()) {
        for (i = 0; i < _totalClusters; i++) {
            for (j = 0; j < _totalClusters; j++) {
                if (scumm_stricmp((char *)cdInf[j].clusterName, _resFiles[i].fileName) == 0)
                    break;
            }

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

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

    delete[] cdInf;

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

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

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

    return true;
}
Exemple #17
0
byte *Sword2Engine::fetchPsxParallax(uint32 location, uint8 level) {
	Common::File file;
	PSXScreensEntry header;
	uint32 screenOffset;
	uint16 horTiles; // Number of horizontal tiles in the parallax grid
	uint16 verTiles; // Number of vertical tiles in parallax grid
	uint32 totSize; // Total size of parallax, counting data, grid, and additional header
	byte *buffer;

	uint16 plxXres;
	uint16 plxYres;
	uint32 plxOffset;
	uint32 plxSize;

	if (level > 1)
		return NULL;

	if (!file.open("screens.clu")) {
		GUIErrorMessage("Broken Sword 2: Cannot open screens.clu");
		return NULL;
	}

	file.seek(location * 4, SEEK_SET);
	screenOffset = file.readUint32LE();

	if (screenOffset == 0) // There is no screen here
		return NULL;

	// Get to the beginning of PSXScreensEntry
	file.seek(screenOffset + ResHeader::size(), SEEK_SET);

	buffer = (byte *)malloc(PSXScreensEntry::size());
	file.read(buffer, PSXScreensEntry::size());

	// Initialize the header
	header.read(buffer);
	free(buffer);

	// We are fetching...
	if (level == 0) { // a background parallax
		plxXres = header.bgPlxXres;
		plxYres = header.bgPlxYres;
		plxOffset = header.bgPlxOffset;
		plxSize = header.bgPlxSize;
	} else {  // a foreground parallax
		plxXres = header.fgPlxXres;
		plxYres = header.fgPlxYres;
		plxOffset = header.fgPlxOffset;
		plxSize = header.fgPlxSize;
	}

	if (plxXres == 0 || plxYres == 0 || plxSize == 0) // This screen has no parallax data.
		return NULL;

	debug(2, "fetchPsxParallax() -> %s parallax, xRes: %u, yRes: %u", (level == 0) ? "Background" : "Foreground", plxXres, plxYres);

	// Calculate the number of tiles which compose the parallax grid.
	horTiles = plxXres % 64 ? (plxXres / 64) + 1 : plxXres / 64;
	verTiles = plxYres % 16 ? (plxYres / 16) + 1 : plxYres / 16;

	totSize = plxSize + horTiles * verTiles * 4 + 8;

	file.seek(screenOffset + plxOffset, SEEK_SET);
	buffer = (byte *)malloc(totSize);

	// Insert parallax resolution information in the buffer,
	// preceding parallax data.
	WRITE_LE_UINT16(buffer, plxXres);
	WRITE_LE_UINT16(buffer + 2, plxYres);
	WRITE_LE_UINT16(buffer + 4, horTiles);
	WRITE_LE_UINT16(buffer + 6, verTiles);

	// Read parallax data from file and store it inside the buffer,
	// skipping the generated header.
	file.read(buffer + 8, totSize - 8);
	file.close();

	return buffer;
}
Exemple #18
0
void initGraphics(int width, int height, const Graphics::PixelFormat *format) {

	g_system->beginGFXTransaction();

		initCommonGFX();
#ifdef USE_RGB_COLOR
		if (format)
			g_system->initSize(width, height, format);
		else {
			Graphics::PixelFormat bestFormat = g_system->getSupportedFormats().front();
			g_system->initSize(width, height, &bestFormat);
		}
#else
		g_system->initSize(width, height);
#endif

	OSystem::TransactionError gfxError = g_system->endGFXTransaction();

	if (!splash && !GUI::GuiManager::instance()._launched)
		splashScreen();

	if (gfxError == OSystem::kTransactionSuccess)
		return;

	// Error out on size switch failure
	if (gfxError & OSystem::kTransactionSizeChangeFailed) {
		Common::String message;
		message = Common::String::format("Could not switch to resolution: '%dx%d'.", width, height);

		GUIErrorMessage(message);
		error("%s", message.c_str());
	}

	// Just show warnings then these occur:
#ifdef USE_RGB_COLOR
	if (gfxError & OSystem::kTransactionFormatNotSupported) {
		Common::String message = _("Could not initialize color format.");

		GUI::MessageDialog dialog(message);
		dialog.runModal();
	}
#endif

	if (gfxError & OSystem::kTransactionModeSwitchFailed) {
		Common::String message = _("Could not switch to video mode: '");
		message += ConfMan.get("gfx_mode");
		message += "'.";

		GUI::MessageDialog dialog(message);
		dialog.runModal();
	}

	if (gfxError & OSystem::kTransactionStretchModeSwitchFailed) {
		Common::String message = _("Could not switch to stretch mode: '");
		message += ConfMan.get("stretch_mode");
		message += "'.";

		GUI::MessageDialog dialog(message);
		dialog.runModal();
	}

	if (gfxError & OSystem::kTransactionAspectRatioFailed) {
		GUI::MessageDialog dialog(_("Could not apply aspect ratio setting."));
		dialog.runModal();
	}

	if (gfxError & OSystem::kTransactionFullscreenFailed) {
		GUI::MessageDialog dialog(_("Could not apply fullscreen setting."));
		dialog.runModal();
	}

	if (gfxError & OSystem::kTransactionFilteringFailed) {
		GUI::MessageDialog dialog(_("Could not apply filtering setting."));
		dialog.runModal();
	}
}
Exemple #19
0
/**
 * Loads Hugo.dat file, which contains all the hardcoded data in the original executables
 */
bool HugoEngine::loadHugoDat() {
	Common::File in;
	in.open("hugo.dat");

	if (!in.isOpen()) {
		Common::String errorMessage = "You're missing the 'hugo.dat' file. Get it from the ScummVM website";
		GUIErrorMessage(errorMessage);
		warning("%s", errorMessage.c_str());
		return false;
	}

	// Read header
	char buf[4];
	in.read(buf, 4);

	if (memcmp(buf, "HUGO", 4)) {
		Common::String errorMessage = "File 'hugo.dat' is corrupt. Get it from the ScummVM website";
		GUIErrorMessage(errorMessage);
		return false;
	}

	int majVer = in.readByte();
	int minVer = in.readByte();

	if ((majVer != HUGO_DAT_VER_MAJ) || (minVer != HUGO_DAT_VER_MIN)) {
		Common::String errorMessage = Common::String::format("File 'hugo.dat' is wrong version. Expected %d.%d but got %d.%d. Get it from the ScummVM website", HUGO_DAT_VER_MAJ, HUGO_DAT_VER_MIN, majVer, minVer);
		GUIErrorMessage(errorMessage);
		return false;
	}

	_numVariant = in.readUint16BE();

	_screen->loadPalette(in);
	_screen->loadFontArr(in);
	_text->loadAllTexts(in);
	_intro->loadIntroData(in);
	_parser->loadArrayReqs(in);
	_parser->loadCatchallList(in);
	_parser->loadBackgroundObjects(in);
	_parser->loadCmdList(in);
	_mouse->loadHotspots(in);
	_inventory->loadInvent(in);
	_object->loadObjectUses(in);
	_object->loadObjectArr(in);
	_object->loadNumObj(in);
	_scheduler->loadPoints(in);
	_scheduler->loadScreenAct(in);
	_scheduler->loadActListArr(in);
	_scheduler->loadAlNewscrIndex(in);
	_hero = &_object->_objects[kHeroIndex];         // This always points to hero
	_screenPtr = &(_object->_objects[kHeroIndex]._screenIndex); // Current screen is hero's
	_heroImage = kHeroIndex;                        // Current in use hero image

	for (int varnt = 0; varnt < _numVariant; varnt++) {
		if (varnt == _gameVariant) {
			_tunesNbr     = in.readSByte();
			_soundSilence = in.readSByte();
			_soundTest    = in.readSByte();
		} else {
			in.readSByte();
			in.readSByte();
			in.readSByte();
		}
	}

	int numElem;

	//Read _defltTunes
	for (int varnt = 0; varnt < _numVariant; varnt++) {
		numElem = in.readUint16BE();
		if (varnt == _gameVariant) {
			_defltTunes = (int16 *)malloc(sizeof(int16) * numElem);
			for (int i = 0; i < numElem; i++)
				_defltTunes[i] = in.readSint16BE();
		} else {
			for (int i = 0; i < numElem; i++)
				in.readSint16BE();
		}
	}

	//Read _screenStates size
	for (int varnt = 0; varnt < _numVariant; varnt++) {
		numElem = in.readUint16BE();
		if (varnt == _gameVariant) {
			_numStates = numElem;
			_screenStates = (byte *)malloc(sizeof(byte) * numElem);
			memset(_screenStates, 0, sizeof(byte) * numElem);
		}
	}

	//Read look, take and drop special verbs indexes
	for (int varnt = 0; varnt < _numVariant; varnt++) {
		if (varnt == _gameVariant) {
			_look = in.readUint16BE();
			_take = in.readUint16BE();
			_drop = in.readUint16BE();
		} else {
			in.readUint16BE();
			in.readUint16BE();
			in.readUint16BE();
		}
	}

	_sound->loadIntroSong(in);
	_topMenu->loadBmpArr(in);

	return true;
}
Exemple #20
0
Common::Error MohawkEngine_Riven::run() {
	MohawkEngine::run();

	// Let's try to open the installer file (it holds extras.mhk)
	// Though, we set a low priority to prefer the extracted version
	if (_installerArchive.open("arcriven.z"))
		SearchMan.add("arcriven.z", &_installerArchive, 0, false);

	_gfx = new RivenGraphics(this);
	_video = new RivenVideoManager(this);
	_sound = new RivenSoundManager(this);
	_console = new RivenConsole(this);
	_saveLoad = new RivenSaveLoad(this, _saveFileMan);
	_optionsDialog = new RivenOptionsDialog(this);
	_scriptMan = new RivenScriptManager(this);
	_inventory = new RivenInventory(this);

	_rnd = new Common::RandomSource("riven");

	// Create the cursor manager
	if (Common::File::exists("rivendmo.exe"))
		_cursor = new PECursorManager("rivendmo.exe");
	else if (Common::File::exists("riven.exe"))
		_cursor = new PECursorManager("riven.exe");
	else // last resort: try the Mac executable
		_cursor = new MacCursorManager("Riven");

	initVars();

	// Check the user has copied all the required datafiles
	if (!checkDatafiles()) {
		return Common::kNoGameDataFoundError;
	}

	// We need to have a cursor source, or the game won't work
	if (!_cursor->hasSource()) {
		Common::String message = _("You're missing a Riven executable. The Windows executable is 'riven.exe' or 'rivendmo.exe'. ");
		message += _("Using the 'arcriven.z' installer file also works. In addition, you can use the Mac 'Riven' executable.");
		GUIErrorMessage(message);
		warning("%s", message.c_str());
		return Common::kNoGameDataFoundError;
	}

	// Open extras.mhk for common images
	_extrasFile = new MohawkArchive();

	// We need extras.mhk for inventory images, marble images, and credits images
	if (!_extrasFile->openFile("extras.mhk")) {
		Common::String message = _("You're missing 'extras.mhk'. Using the 'arcriven.z' installer file also works.");
		GUIErrorMessage(message);
		warning("%s", message.c_str());
		return Common::kNoGameDataFoundError;
	}

	// Set the transition speed
	_gfx->setTransitionMode((RivenTransitionMode) _vars["transitionmode"]);

	// Start at main cursor
	_cursor->setCursor(kRivenMainCursor);
	_cursor->showCursor();

	// Let's begin, shall we?
	if (getFeatures() & GF_DEMO) {
		// Start the demo off with the videos
		changeToStack(kStackAspit);
		changeToCard(6);
	} else if (ConfMan.hasKey("save_slot")) {
		// Load game from launcher/command line if requested
		int gameToLoad = ConfMan.getInt("save_slot");

		// Attempt to load the game.
		Common::Error loadError = _saveLoad->loadGame(gameToLoad);
		if (loadError.getCode() != Common::kNoError) {
			return loadError;
		}
	} else {
		// Otherwise, start us off at aspit's card 1 (the main menu)
		changeToStack(kStackAspit);
		changeToCard(1);
	}


	while (!hasGameEnded())
		doFrame();

	return Common::kNoError;
}