/** * 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; }
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; }
/** * 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; }
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); }
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); }
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()); } }
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()); } }
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; }
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; }
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; }
/** * Display an error message */ void TonyEngine::GUIError(const Common::String &msg) { GUIErrorMessage(msg); }
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; }
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; }
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; }
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; }
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; }
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(); } }
/** * 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; }
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; }