Esempio n. 1
0
void MADSEngine::initialize() {
	// Set up debug channels
	DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level");
	DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts");
	DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling");

	// Initial sub-system engine references
	MSurface::setVm(this);
	MSprite::setVm(this);

	Resources::init(this);
	Conversation::init(this);
	_debugger = new Debugger(this);
	_dialogs = Dialogs::init(this);
	_events = new EventsManager(this);
	_palette = new Palette(this);
	Font::init(this);
	_font = new Font();
	_screen.init();
	_sound = new SoundManager(this, _mixer);
	_audio = new AudioPlayer(_mixer, getGameID());
	_game = Game::init(this);

	switch (getGameID()) {
	case GType_RexNebular:
		_gameConv = nullptr;
		break;
	default:
		_gameConv = new GameConversation(this);
	}

	loadOptions();

	_screen.empty();
}
Esempio n. 2
0
MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {

	const GameSettings *g;

	const char *gameid = ConfMan.get("gameid").c_str();
	for (g = madeSettings; g->gameid; ++g)
		if (!scumm_stricmp(g->gameid, gameid))
			_gameId = g->id;

	_rnd = new Common::RandomSource();
	syst->getEventManager()->registerRandomSource(*_rnd, "made");

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

	_pmvPlayer = new PmvPlayer(this, _mixer);
	_res = new ResourceReader();
	_screen = new Screen(this);

	if (getGameID() == GID_LGOP2 || getGameID() == GID_MANHOLE || getGameID() == GID_RODNEY) {
		_dat = new GameDatabaseV2(this);
	} else if (getGameID() == GID_RTZ) {
		_dat = new GameDatabaseV3(this);
	} else {
		error("Unknown GameID");
	}

	_script = new ScriptInterpreter(this);

	int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
	bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
	//bool adlib = (midiDriver == MD_ADLIB);

	MidiDriver *driver = MidiDriver::createMidi(midiDriver);
	if (native_mt32)
		driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);

	_music = new MusicPlayer(driver);
	_music->setNativeMT32(native_mt32);
	//_music->setAdlib(adlib);

	// Set default sound frequency
	switch (getGameID()) {
	case GID_RODNEY:
		_soundRate = 11025;
		break;
	case GID_MANHOLE:
		_soundRate = 11025;
		break;
	case GID_LGOP2:
		_soundRate = 8000;
		break;
	case GID_RTZ:
		// Return to Zork sets it itself via a script funtion
		break;
	}

	syncSoundSettings();
}
Esempio n. 3
0
void AgiEngine::setupOpcodes() {
	if (getVersion() >= 0x2000) {
		for (int i = 0; i < ARRAYSIZE(insV2Test); ++i)
			_agiCondCommands[i] = insV2Test[i].func;
		for (int i = 0; i < ARRAYSIZE(insV2); ++i)
			_agiCommands[i] = insV2[i].func;

		logicNamesTest = insV2Test;
		logicNamesCmd = insV2;

		// Alter opcode parameters for specific games
		// TODO: This could be either turned into a game feature, or a version
		// specific check, instead of a game version check

		// The Apple IIGS versions of MH1 and Goldrush both have a parameter for
		// show.mouse and hide.mouse. Fixes bugs #3577754 and #3426946.
		if ((getGameID() == GID_MH1 || getGameID() == GID_GOLDRUSH) &&
			getPlatform() == Common::kPlatformApple2GS) {
			logicNamesCmd[176].args = "n";	// hide.mouse
			logicNamesCmd[178].args = "n";	// show.mouse
		}
	} else {
		for (int i = 0; i < ARRAYSIZE(insV1Test); ++i)
			_agiCondCommands[i] = insV1Test[i].func;
		for (int i = 0; i < ARRAYSIZE(insV1); ++i)
			_agiCommands[i] = insV1[i].func;

		logicNamesTest = insV1Test;
		logicNamesCmd = insV1;
	}
}
Esempio n. 4
0
Common::Error MadeEngine::run() {
	_music = new MusicPlayer(getGameID() == GID_RTZ);
	syncSoundSettings();

	// Initialize backend
	initGraphics(320, 200, false);

	resetAllTimers();

	if (getGameID() == GID_RTZ) {
		if (getFeatures() & GF_DEMO) {
			_dat->open("demo.dat");
			_res->open("demo.prj");
		} else if (getFeatures() & GF_CD) {
			_dat->open("rtzcd.dat");
			_res->open("rtzcd.prj");
		} else if (getFeatures() & GF_CD_COMPRESSED) {
			_dat->openFromRed("rtzcd.red", "rtzcd.dat");
			_res->open("rtzcd.prj");
		} else if (getFeatures() & GF_FLOPPY) {
			_dat->open("rtz.dat");
			_res->open("rtz.prj");
		} else {
			error("Unknown RTZ game features");
		}
	} else if (getGameID() == GID_MANHOLE) {
		_dat->open("manhole.dat");

		if (getVersion() == 2) {
			_res->open("manhole.prj");
		} else {
			_res->openResourceBlocks();
		}
	} else if (getGameID() == GID_LGOP2) {
		_dat->open("lgop2.dat");
		_res->open("lgop2.prj");
	} else if (getGameID() == GID_RODNEY) {
		_dat->open("rodneys.dat");
		_res->open("rodneys.prj");
	} else {
		error ("Unknown MADE game");
	}

	if ((getFeatures() & GF_CD) || (getFeatures() & GF_CD_COMPRESSED))
		checkCD();

	_autoStopSound = false;
	_eventNum = _eventKey = _eventMouseX = _eventMouseY = 0;

#ifdef DUMP_SCRIPTS
	_script->dumpAllScripts();
#else
	_screen->setDefaultMouseCursor();
	_script->runScript(_dat->getMainCodeObjectIndex());
#endif

	return Common::kNoError;
}
Esempio n. 5
0
void SherlockEngine::loadConfig() {
	// Load sound settings
	syncSoundSettings();

	ConfMan.registerDefault("font", getGameID() == GType_SerratedScalpel ? 1 : 4);

	_screen->setFont(ConfMan.getInt("font"));
	if (getGameID() == GType_SerratedScalpel)
		_screen->_fadeStyle = ConfMan.getBool("fade_style");

	_ui->_helpStyle = ConfMan.getBool("help_style");
	_ui->_slideWindows = ConfMan.getBool("window_style");
	_people->_portraitsOn = ConfMan.getBool("portraits_on");
}
Esempio n. 6
0
MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {

	const GameSettings *g;

	const char *gameid = ConfMan.get("gameid").c_str();
	for (g = madeSettings; g->gameid; ++g)
		if (!scumm_stricmp(g->gameid, gameid))
			_gameId = g->id;

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

	_console = new MadeConsole(this);

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

	_pmvPlayer = new PmvPlayer(this, _mixer);
	_res = new ResourceReader();
	_screen = new Screen(this);

	if (getGameID() == GID_LGOP2 || getGameID() == GID_MANHOLE || getGameID() == GID_RODNEY) {
		_dat = new GameDatabaseV2(this);
	} else if (getGameID() == GID_RTZ) {
		_dat = new GameDatabaseV3(this);
	} else {
		error("Unknown GameID");
	}

	_script = new ScriptInterpreter(this);

	_music = nullptr;

	// Set default sound frequency
	switch (getGameID()) {
	case GID_RODNEY:
		_soundRate = 11025;
		break;
	case GID_MANHOLE:
		_soundRate = 11025;
		break;
	case GID_LGOP2:
		_soundRate = 8000;
		break;
	case GID_RTZ:
		// Return to Zork sets it itself via a script funtion
		break;
	}
}
Esempio n. 7
0
void MADSEngine::loadOptions() {
	if (ConfMan.hasKey("EasyMouse"))
		_easyMouse = ConfMan.getBool("EasyMouse");

	if (ConfMan.hasKey("mute") && ConfMan.getBool("mute")) {
		_soundFlag = false;
		_musicFlag = false;
	} else {
		_soundFlag = !ConfMan.hasKey("sfx_mute") || !ConfMan.getBool("sfx_mute");
		_musicFlag = !ConfMan.hasGameDomain("music_mute") || !ConfMan.getBool("music_mute");
	}

	if (ConfMan.hasKey("ScreenFade"))
		_screenFade = (ScreenFade)ConfMan.getInt("ScreenFade");
	//if (ConfMan.hasKey("GraphicsDithering"))
	//	_dithering = ConfMan.getBool("GraphicsDithering");

	if (getGameID() == GType_RexNebular) {
		if (ConfMan.hasKey("InvObjectsAnimated"))
			_invObjectsAnimated = ConfMan.getBool("InvObjectsAnimated");
		if (ConfMan.hasKey("TextWindowStill"))
			_textWindowStill = !ConfMan.getBool("TextWindowAnimated");
		if (ConfMan.hasKey("NaughtyMode"))
			_game->setNaughtyMode(ConfMan.getBool("NaughtyMode"));
	}

	// Note: MADS is weird in that sfx and music are handled by the same driver,
	// and the game scripts themselves check for music being enabled before playing
	// a "music" sound. Which means we can independantly mute music in ScummVM, but
	// otherwise all sound, music and sfx, is controlled by the SFX volume slider.
	int soundVolume = MIN(255, ConfMan.getInt("sfx_volume"));
	_sound->setVolume(soundVolume);
}
Esempio n. 8
0
void cmdDrawPic(AgiGame *state, uint8 *p) {
	debugC(6, kDebugLevelScripts, "=== draw pic %d ===", _v[p0]);
	state->_vm->_sprites->eraseBoth();
	state->_vm->_picture->decodePicture(_v[p0], true);
	state->_vm->_sprites->blitBoth();
	state->_vm->_sprites->commitBoth();
	state->pictureShown = 0;
	debugC(6, kDebugLevelScripts, "--- end of draw pic %d ---", _v[p0]);

	// WORKAROUND for a script bug which exists in SQ1, logic scripts
	// 20 and 110. Flag 103 is not reset correctly, which leads to erroneous
	// behavior from view 46 (the spider droid). View 46 is supposed to
	// follow ego and explode when it comes in contact with him. However, as
	// flag 103 is not reset correctly, when the player goes down the path
	// and back up, the spider is always at the base of the path (since it
	// can't go up) and kills the player when he goes down at ground level
	// (although the spider droid sprite itself seems to be correctly positioned).
	// With this workaround, when the player goes back to picture 20 (1 screen
	// above the ground), flag 103 is reset, thereby fixing this issue. Note
	// that this is a script bug and occurs in the original interpreter as well.
	// Fixes bug #1658514: AGI: SQ1 (2.2 DOS ENG) bizzare exploding roger
	if (getGameID() == GID_SQ1 && _v[p0] == 20)
		setflag(103, false);

	// Simulate slowww computer. Many effects rely on this
	state->_vm->pause(kPausePicture);
}
Esempio n. 9
0
GameDef createGameDef(const Game *g) {
	return ((getGameID(g->game) & 0xF) << 12) |
	       ((getPlatformID(g->platform) & 0xF) << 8) |
	       ((getSpecialID(g->special) & 0xF) << 4) |
	       ((getLanguageID(g->lang) & 0xF) << 0);
	return 0;
}
Esempio n. 10
0
File: id.cpp Progetto: Cruel/scummvm
int AgiEngine::setupV3Game(int ver) {
	int ec = errOK;

	debug(0, "Setting up for version 0x%04X", ver);

	// 'unknown176' takes 1 arg for 3.002.086, not 0 args.
	// 'unknown173' also takes 1 arg for 3.002.068, not 0 args.
	// Is this actually used anywhere? -- dsymonds
	if (ver == 0x3086) {
//		logicNamesCmd[0xb0].numArgs = 1;
//		logicNamesCmd[0xad].numArgs = 1;
		logicNamesCmd[0xb0].args = "n";
		logicNamesCmd[0xad].args = "n";
	}

	// FIXME: Apply this fix to other games also that use 2 arguments for command 182.
	// 'adj.ego.move.to.x.y' (i.e. command 182) takes 2 arguments for at least the
	// Amiga Gold Rush! (v2.05 1989-03-09) using Amiga AGI 2.316. Amiga's Gold Rush
	// has been set to use AGI 3.149 in ScummVM so that's why this initialization is
	// here and not in setupV2Game.
	if (getGameID() == GID_GOLDRUSH && getPlatform() == Common::kPlatformAmiga)
//		logicNamesCmd[182].numArgs = 2;
		logicNamesCmd[182].args = "vv";

	return ec;
}
Esempio n. 11
0
uint32 getFilename(int game, int plat, int spec, int lang, const ExtractFilename *fDesc) {
	// GAME, PLATFORM, SPECIAL, ID, LANG
	return ((getGameID(game) & 0xF) << 24) |
	       ((getPlatformID(plat) & 0xF) << 20) |
	       ((getSpecialID(spec) & 0xF) << 16) |
	       ((fDesc->id & 0xFFF) << 4) |
	       ((getLanguageID(fDesc->langSpecific ? lang : UNK_LANG) & 0xF) << 0);
}
Esempio n. 12
0
void PreAgiEngine::clearTextArea() {
	int start = IDI_MAX_ROW_PIC;

	if (getGameID() == GID_TROLL)
		start = 21;

	for (int row = start; row < 200 / 8; row++) {
		clearRow(row);
	}
}
Esempio n. 13
0
uint32 getFilename(const ExtractInformation *info, const int id) {
	const ExtractFilename *fDesc = getFilenameDesc(id);

	if (!fDesc)
		return 0;

	// GAME, PLATFORM, SPECIAL, ID, LANG
	return ((getGameID(info->game) & 0xF) << 24) |
	       ((getPlatformID(info->platform) & 0xF) << 20) |
	       ((getSpecialID(info->special) & 0xF) << 16) |
	       ((id & 0xFFF) << 4) |
	       ((getLanguageID(fDesc->langSpecific ? info->lang : UNK_LANG) & 0xF) << 0);
}
Esempio n. 14
0
void cmdDistance(AgiGame *state, uint8 *p) {
	int16 x1, y1, x2, y2, d;
	VtEntry *v0 = &state->viewTable[p0];
	VtEntry *v1 = &state->viewTable[p1];

	if (v0->flags & fDrawn && v1->flags & fDrawn) {
		x1 = v0->xPos + v0->xSize / 2;
		y1 = v0->yPos;
		x2 = v1->xPos + v1->xSize / 2;
		y2 = v1->yPos;
		d = ABS(x1 - x2) + ABS(y1 - y2);
		if (d > 0xfe)
			d = 0xfe;
	} else {
		d = 0xff;
	}

	// WORKAROUND: Fixes King's Quest IV's script bug #1660424 (KQ4: Zombie bug).
	// In the graveyard (Rooms 16 and 18) at night if you had the Obsidian Scarab (Item 4)
	// and you were very close to a spot where a zombie was going to rise up from the
	// ground you could reproduce the bug. Just standing there and letting the zombie
	// try to rise up the Obsidian Scarab would repel the zombie immediately and that
	// would make the script bug so that the zombie would still come up but it just
	// wouldn't chase Rosella around anymore. If it had worked correctly the zombie
	// wouldn't have come up at all or it would have come up and gone back down
	// immediately. The latter approach is the one implemented here.
	if (getGameID() == GID_KQ4 && (_v[vCurRoom] == 16 || _v[vCurRoom] == 18) && p2 >= 221 && p2 <= 223) {
		// Rooms 16 and 18 are graveyards where three zombies come up at night. They use logics 16 and 18.
		// Variables 221-223 are used to save the distance between each zombie and Rosella.
		// Variables 155, 156 and 162 are used to save the state of each zombie in room 16.
		// Variables 155, 156 and 158 are used to save the state of each zombie in room 18.
		// Rosella gets turned to a zombie only if any of the zombies is under 10 units away
		// from her and she doesn't have the Obsidian Scarab (Item 4). Likewise Rosella makes
		// a zombie go back into the ground if the zombie comes under 15 units away from her
		// and she has the Obsidian Scarab. To ensure a zombie always first rises up before
		// checking for either of the aforementioned conditions (Rosella getting turned to
		// a zombie or the zombie getting turned away by the scarab) we make it appear the
		// zombie is far away from Rosella if the zombie is not already up and chasing her.
		enum zombieStates {ZOMBIE_SET_TO_RISE_UP, ZOMBIE_RISING_UP, ZOMBIE_CHASING_EGO};
		uint8 zombieStateVarNumList[] = {155, 156, (_v[vCurRoom] == 16) ? 162 : 158};
		uint8 zombieNum         = p2 - 221;                         // Zombie's number (In range 0-2)
		uint8 zombieStateVarNum = zombieStateVarNumList[zombieNum]; // Number of the variable containing zombie's state
		uint8 zombieState       = _v[zombieStateVarNum];            // Zombie's state
		// If zombie is not chasing Rosella then set its distance from Rosella to the maximum
		if (zombieState != ZOMBIE_CHASING_EGO)
			d = 0xff;
	}

	_v[p2] = (unsigned char)d;
}
Esempio n. 15
0
void cmdNewRoom(AgiGame *state, uint8 *p) {
	state->_vm->newRoom(p0);

	// WORKAROUND: Works around intro skipping bug (#1737343) in Gold Rush.
	// Intro was skipped because the enter-keypress finalizing the entering
	// of the copy protection string (Copy protection is in logic.128) was
	// left over to the intro scene (Starts with room 73 i.e. logic.073).
	// The intro scene checks for any keys pressed and if it finds any it
	// jumps to the game's start (Room 1 i.e. logic.001). We clear the
	// keyboard buffer when the intro sequence's first room (Room 73) is
	// loaded so that no keys from the copy protection scene can be left
	// over to cause the intro to skip to the game's start.
	if (getGameID() == GID_GOLDRUSH && p0 == 73)
		state->keypress = 0;
}
Esempio n. 16
0
void XeenEngine::play() {
	_interface->setup();
	_screen->loadBackground("back.raw");
	_screen->loadPalette("mm4.pal");

	if (getGameID() == GType_DarkSide && !_map->_loadCcNum) {
		_map->_loadCcNum = 1;
		_party->_mazeId = 29;
		_party->_mazeDirection = DIR_NORTH;
		_party->_mazePosition.x = 25;
		_party->_mazePosition.y = 21;
	}

	_map->clearMaze();
	if (_loadSaveSlot >= 0) {
		_saves->newGame();
		_saves->loadGameState(_loadSaveSlot);
		_loadSaveSlot = -1;
	} else {
		_map->load(_party->_mazeId);
	}

	_interface->startup();
	if (_mode == MODE_STARTUP) {
//		_screen->fadeOut();
	}

	(*_windows)[0].update();
	_interface->mainIconsPrint();
	(*_windows)[0].update();
	_events->setCursor(0);

	_combat->_moveMonsters = true;
	if (_mode == MODE_STARTUP) {
		_mode = MODE_INTERACTIVE;
		_screen->fadeIn();
	}

	_combat->_moveMonsters = true;

	gameLoop();

	if (_party->_dead)
		death();

	_mode = MODE_STARTUP;
	_gameMode = GMODE_MENU;
}
Esempio n. 17
0
void MADSEngine::saveOptions() {
	ConfMan.setBool("EasyMouse", _easyMouse);
	ConfMan.setInt("ScreenFade", (int)_screenFade);
	//ConfMan.setBool("GraphicsDithering", _dithering);

	ConfMan.setBool("mute", !_soundFlag && !_musicFlag);
	ConfMan.setBool("sfx_mute", !_soundFlag && _musicFlag);
	ConfMan.setBool("music_mute", _soundFlag && !_musicFlag);

	if (getGameID() == GType_RexNebular) {
		ConfMan.setBool("InvObjectsAnimated", _invObjectsAnimated);
		ConfMan.setBool("TextWindowAnimated", !_textWindowStill);
		ConfMan.setBool("NaughtyMode", _game->getNaughtyMode());
	}

	ConfMan.flushToDisk();
}
Esempio n. 18
0
Common::Error DirectorEngine::run() {
    debug("Starting v%d Director game", getVersion());

    _currentPalette = nullptr;

    _macBinary = nullptr;
    _soundManager = nullptr;

    _wm = new Graphics::MacWindowManager;

    _lingo = new Lingo(this);
    _soundManager = new DirectorSound();

    if (getGameID() == GID_TEST) {
        _mainArchive = nullptr;
        _currentScore = nullptr;

        _lingo->runTests();

        return Common::kNoError;
    }

    //FIXME
    //_mainArchive = new RIFFArchive();
    //_mainArchive->openFile("bookshelf_example.mmm");

    //testFont();

    if (getPlatform() == Common::kPlatformWindows)
        _sharedCastFile = "SHARDCST.MMM";
    else
        _sharedCastFile = "Shared Cast*";

    loadSharedCastsFrom(_sharedCastFile);

    loadMainArchive();

    _currentScore = new Score(this, _mainArchive);
    debug(0, "Score name %s", _currentScore->getMacName().c_str());

    _currentScore->loadArchive();
    _currentScore->startLoop();

    return Common::kNoError;
}
Esempio n. 19
0
void PreAgiEngine::initialize() {
	initRenderMode();

	_gfx = new GfxMgr(this);
	_picture = new PictureMgr(this, _gfx);

	if (getGameID() == GID_MICKEY) {
		_fontData = fontData_Mickey;
	} else {
		_fontData = fontData_IBM;
	}

	_gfx->initMachine();

	_game.gameFlags = 0;

	_game.colorFg = 15;
	_game.colorBg = 0;

	_defaultColor = 0xF;

	_game.name[0] = '\0';

	_game.sbufOrig = (uint8 *)calloc(_WIDTH, _HEIGHT * 2); // Allocate space for two AGI screens vertically
	_game.sbuf16c  = _game.sbufOrig + SBUF16_OFFSET; // Make sbuf16c point to the 16 color (+control line & priority info) AGI screen
	_game.sbuf     = _game.sbuf16c; // Make sbuf point to the 16 color (+control line & priority info) AGI screen by default

	_game.lineMinPrint = 0; // hardcoded

	_gfx->initVideo();

	_speakerStream = new Audio::PCSpeaker();
	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
							_speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);

	debugC(2, kDebugLevelMain, "Detect game");

	// clear all resources and events
	for (int i = 0; i < MAX_DIRS; i++) {
		memset(&_game.pictures[i], 0, sizeof(struct AgiPicture));
		memset(&_game.sounds[i], 0, sizeof(class AgiSound *)); // _game.sounds contains pointers now
		memset(&_game.dirPic[i], 0, sizeof(struct AgiDir));
		memset(&_game.dirSound[i], 0, sizeof(struct AgiDir));
	}
}
Esempio n. 20
0
Common::Error DirectorEngine::run() {
	debug("Starting v%d Director game", getVersion());

	_sharedCasts = nullptr;
	_sharedSound = nullptr;
	_sharedBMP = nullptr;
	_sharedSTXT = nullptr;
	_sharedDIB = nullptr;

	_movies = nullptr;
	_currentPalette = nullptr;

	_macBinary = nullptr;
	_soundManager = nullptr;

	_lingo = new Lingo(this);
	_soundManager = new DirectorSound();

	if (getGameID() == GID_TEST) {
		_mainArchive = nullptr;
		_currentScore = nullptr;

		_lingo->runTests();

		return Common::kNoError;
	}

	//FIXME
	_mainArchive = new RIFFArchive();
	_mainArchive->openFile("bookshelf_example.mmm");
	_currentScore = new Score(this);
	debug(0, "Score name %s", _currentScore->getMacName().c_str());

	_currentScore->loadArchive();
	_currentScore->startLoop();

	if (getPlatform() == Common::kPlatformWindows)
		loadEXE();
	else
		loadMac();

	return Common::kNoError;
}
Esempio n. 21
0
uint16 AgiEngine::artificialDelay_SearchTable(AgiArtificialDelayTriggerType triggerType, int16 orgNr, int16 newNr) {
	if (getPlatform() != Common::kPlatformApple2GS) {
		return 0;
	}

	const AgiArtificialDelayEntry *delayEntry = artificialDelayTable;

	while (delayEntry->triggerType != ARTIFICIALDELAYTYPE_END) {
		if (triggerType == delayEntry->triggerType) {
			if ((orgNr == delayEntry->orgNr) && (newNr == delayEntry->newNr)) {
				if ((getGameID() == delayEntry->gameId) && (getPlatform() == delayEntry->platform)) {
					warning("artificial delay forced");
					return delayEntry->millisecondsDelay;
				}
			}
		}

		delayEntry++;
	}
	return 0;
}
Esempio n. 22
0
Common::Error PreAgiEngine::go() {
	setflag(fSoundOn, true);	// enable sound

//
// FIXME (Fingolfin asks): Why are Mickey, Winnie and Troll standalone classes
// instead of being subclasses of PreAgiEngine ?
//

	// run preagi engine main loop
	switch (getGameID()) {
	case GID_MICKEY:
		{
			Mickey *mickey = new Mickey(this);
			mickey->init();
			mickey->run();
			delete mickey;
		}
		break;
	case GID_WINNIE:
		{
			Winnie *winnie = new Winnie(this);
			winnie->init();
			winnie->run();
			delete winnie;
		}
		break;
	case GID_TROLL:
		{
			Troll *troll = new Troll(this);
			troll->init();
			troll->run();
			delete troll;
		}
		break;
	default:
		error("Unknown preagi engine");
		break;
	}
	return Common::kNoError;
}
Esempio n. 23
0
void cmdSetPriority(AgiGame *state, uint8 *p) {
	vt.flags |= fFixedPriority;
	vt.priority = p1;

	// WORKAROUND: this fixes bug #1712585 in KQ4 (dwarf sprite priority)
	// For this scene, ego (Rosella) hasn't got a fixed priority till script 54
	// explicitly sets priority 8 for her, so that she can walk back to the table
	// without being drawn over the other dwarfs
	// It seems that in this scene, ego's priority is set to 8, but the priority of
	// the last dwarf with the soup bowls (view 152) is also set to 8, which causes
	// the dwarf to be drawn behind ego
	// With this workaround, when the game scripts set the priority of view 152
	// (seventh dwarf with soup bowls), ego's priority is set to 7
	// The game script itself sets priotity 8 for ego before she starts walking,
	// and then releases the fixed priority set on ego after ego is seated
	// Therefore, this workaround only affects that specific part of this scene
	// Ego is set to object 19 by script 54
	if (getGameID() == GID_KQ4 && vt.currentView == 152) {
		state->viewTable[19].flags |= fFixedPriority;
		state->viewTable[19].priority = 7;
	}
}
Esempio n. 24
0
void XeenEngine::play() {
	// TODO: Init variables
	_quitMode = 0;

	_interface->setup();
	_screen->loadBackground("back.raw");
	_screen->loadPalette("mm4.pal");

	if (getGameID() != GType_WorldOfXeen && !_map->_loadDarkSide) {
		_map->_loadDarkSide = true;
		_party->_mazeId = 29;
		_party->_mazeDirection = DIR_NORTH;
		_party->_mazePosition.x = 25;
		_party->_mazePosition.y = 21;
	}

	_map->load(_party->_mazeId);

	_interface->startup();
	if (_mode == MODE_0) {
//		_screen->fadeOut();
	}

	_screen->_windows[0].update();
	_interface->mainIconsPrint();
	_screen->_windows[0].update();
	_events->setCursor(0);

	_combat->_moveMonsters = true;
	if (_mode == MODE_0) {
		_mode = MODE_1;
		_screen->fadeIn();
	}

	_combat->_moveMonsters = true;

	gameLoop();
}
Esempio n. 25
0
int AgiEngine::agiLoadResource(int r, int n) {
    int i;

    i = _loader->loadResource(r, n);

    // WORKAROUND: Patches broken picture 147 in a corrupted Amiga version of Gold Rush! (v2.05 1989-03-09).
    // The picture can be seen in room 147 after dropping through the outhouse's hole in room 146.
    if (i == errOK && getGameID() == GID_GOLDRUSH && r == rPICTURE && n == 147 && _game.dirPic[n].len == 1982) {
        uint8 *pic = _game.pictures[n].rdata;
        Common::MemoryReadStream picStream(pic, _game.dirPic[n].len);
        Common::String md5str = Common::computeStreamMD5AsString(picStream, _game.dirPic[n].len);
        if (md5str == "1c685eb048656cedcee4eb6eca2cecea") {
            pic[0x042] = 0x4B; // 0x49 -> 0x4B
            pic[0x043] = 0x66; // 0x26 -> 0x66
            pic[0x204] = 0x68; // 0x28 -> 0x68
            pic[0x6C0] = 0x2D; // 0x25 -> 0x2D
            pic[0x6F0] = 0xF0; // 0x70 -> 0xF0
            pic[0x734] = 0x6F; // 0x2F -> 0x6F
        }
    }

    return i;
}
Esempio n. 26
0
void MADSEngine::initialize() {
	// Initial sub-system engine references
	MSurface::setVm(this);
	MSprite::setVm(this);

	Resources::init(this);
	Conversation::init(this);
	_debugger = new Debugger(this);
	_dialogs = Dialogs::init(this);
	_events = new EventsManager(this);
	_palette = new Palette(this);
	Font::init(this);
	_font = new Font();
	_screen = new Screen();
	_sound = new SoundManager(this, _mixer);
	_audio = new AudioPlayer(_mixer, getGameID());
	_game = Game::init(this);
	_gameConv = new GameConversations(this);

	loadOptions();

	_screen->clear();
}
Esempio n. 27
0
bool AgiEngine::handleController(uint16 key) {
	ScreenObjEntry *screenObjEgo = &_game.screenObjTable[SCREENOBJECTS_EGO_ENTRY];

	if (key == 0) // nothing pressed
		return false;

	// This previously skipped processing, when ESC was pressed and called menu directly.
	// This original approach was bad, because games check different flags before actually allowing the
	//  user to enter the menu. We checked a few common flags, like for example the availability of the prompt.
	//  But this stopped the user being able to enter the menu, when the original interpreter actually allowed it.
	//  We now instead implement this feature using another way for those platforms.
	if (key == AGI_KEY_ESCAPE) {
		// Escape pressed, user probably wants to trigger the menu
		// For PC, just passing ASCII code for ESC will normally trigger a controller
		//  and the scripts will then trigger the menu
		switch (getPlatform()) {
		case Common::kPlatformAmiga:
		case Common::kPlatformApple2GS:
		case Common::kPlatformAtariST:
			// For these platforms, the button ESC normally triggered "pause"
			// But users could at the same time trigger the menu by clicking on the status line
			// We check, if menu is currently available and supposed to be accessible.
			// If yes, we do a delayed trigger now, otherwise we continue processing the key just like normal.
			//
			// This is probably the solution with the highest compatibility.
			// Several games also look for special keys see AGI_MENU_TRIGGER_*
			// And then there's also Mixed Up Mother Goose, which actually hooks the ESC key for the regular menu
			//
			// We risk in here of course, that we let the user access the menu, when it shouldn't be possible.
			// I'm not 100% sure if those other interpreters really only check VM_FLAG_MENUS_ACCESSIBLE
			// Needs further investigation.
			if (getFlag(VM_FLAG_MENUS_ACCESSIBLE) && _menu->isAvailable()) {
				// menu is supposed to be accessible and is also available
				_menu->delayedExecuteViaKeyboard();
				return true;
			}
		default:
			break;
		}
		// Otherwise go on and look for the ESC controller
	}

	// AGI 3.149 games, The Black Cauldron and King's Quest 4 need KEY_ESCAPE to use menus
	// Games with the GF_ESCPAUSE flag need KEY_ESCAPE to pause the game
	//		(key == KEY_ESCAPE && getVersion() != 0x3149 && getGameID() != GID_BC && getGameID() != GID_KQ4 && !(getFeatures() & GF_ESCPAUSE)) )
	//		return false;

	if ((getGameID() == GID_MH1 || getGameID() == GID_MH2) && (key == AGI_KEY_ENTER) &&
	        (!_text->promptIsEnabled())) {
		key = 0x20; // Set Enter key to Space in Manhunter when prompt is disabled
	}

	debugC(3, kDebugLevelInput, "key = %04x", key);

	for (uint16 curMapping = 0; curMapping < MAX_CONTROLLER_KEYMAPPINGS; curMapping++) {
		if (_game.controllerKeyMapping[curMapping].keycode == key) {
			debugC(3, kDebugLevelInput, "event %d: key press", _game.controllerKeyMapping[curMapping].controllerSlot);
			_game.controllerOccured[_game.controllerKeyMapping[curMapping].controllerSlot] = true;
			return true;
		}
	}

	int16 newDirection = 0;

	switch (key) {
	case AGI_KEY_UP:
		newDirection = 1;
		break;
	case AGI_KEY_DOWN:
		newDirection = 5;
		break;
	case AGI_KEY_LEFT:
		newDirection = 7;
		break;
	case AGI_KEY_RIGHT:
		newDirection = 3;
		break;
	case AGI_KEY_UP_RIGHT:
		newDirection = 2;
		break;
	case AGI_KEY_DOWN_RIGHT:
		newDirection = 4;
		break;
	case AGI_KEY_UP_LEFT:
		newDirection = 8;
		break;
	case AGI_KEY_DOWN_LEFT:
		newDirection = 6;
		break;
	default:
		break;
	}

	if (_game.playerControl) {
		if (!(getFeatures() & GF_AGIMOUSE)) {
			// Handle mouse button events
			if (!_game.mouseHidden) {
				if (key == AGI_MOUSE_BUTTON_LEFT) {
					if (getGameID() == GID_PQ1 && getVar(VM_VAR_CURRENT_ROOM) == 116) {
						// WORKAROUND: Special handling for mouse clicks in the newspaper
						// screen of PQ1. Fixes bug #3018770.
						newDirection = 3;   // fake a right arrow key (next page)

					} else {
						// Click-to-walk mouse interface
						//v->flags |= fAdjEgoXY;
						// setting fAdjEgoXY here will at least break "climbing the log" in SQ2
						// in case you walked to the log by using the mouse, so don't!!!
						int16 egoDestinationX = _mouse.pos.x;
						int16 egoDestinationY = _mouse.pos.y;
						_gfx->translateDisplayPosToGameScreen(egoDestinationX, egoDestinationY);

						screenObjEgo->motionType = kMotionEgo;
						if (egoDestinationX < (screenObjEgo->xSize / 2)) {
							screenObjEgo->move_x = -1;
						} else {
							screenObjEgo->move_x = egoDestinationX - (screenObjEgo->xSize / 2);
						}
						screenObjEgo->move_y        = egoDestinationY;
						screenObjEgo->move_stepSize = screenObjEgo->stepSize;
						return true;
					}
				}
			}
		}
	}

	if (newDirection || key == AGI_KEY_STATIONARY) {
		// TODO: not sure, what original AGI did with AdjEgoXY
		screenObjEgo->flags &= ~fAdjEgoXY;
		if (screenObjEgo->direction == newDirection) {
			setVar(VM_VAR_EGO_DIRECTION, 0);
		} else {
			setVar(VM_VAR_EGO_DIRECTION, newDirection);
		}
		if (_game.playerControl) {
			screenObjEgo->motionType = kMotionNormal;
		}
		return true;
	}

	return false;
}
Esempio n. 28
0
GameDef createGameDef(const ExtractInformation *eI) {
	return ((getGameID(eI->game) & 0xF) << 12) |
	       ((getPlatformID(eI->platform) & 0xF) << 8) |
	       ((getSpecialID(eI->special) & 0xF) << 4) |
	       ((getLanguageID(eI->lang) & 0xF) << 0);
}
Esempio n. 29
0
Common::Error TinselEngine::run() {
	// Initialize backend
	if (getGameID() == GID_DW2) {
#ifndef DW2_EXACT_SIZE
		initGraphics(640, 480, true);
#else
		initGraphics(640, 432, true);
#endif
		_screenSurface.create(640, 432, 1);
	} else {
		initGraphics(320, 200, false);
		_screenSurface.create(320, 200, 1);
	}

	g_system->getEventManager()->registerRandomSource(_random, "tinsel");

	_console = new Console();

	_scheduler = new Scheduler();

	InitSysVars();

	// init memory manager
	MemoryInit();

	// load user configuration
	ReadConfig();

#if 1
	// FIXME: The following is taken from RestartGame().
	// It may have to be adjusted a bit
	CountOut = 1;

	RebootCursor();
	RebootDeadTags();
	RebootMovers();
	resetUserEventTime();
	RebootTimers();
	RebootScalingReels();

	DelayedScene.scene = HookScene.scene = 0;
#endif

	// Load in text strings
	ChangeLanguage(g_language);

	// Init palette and object managers, scheduler, keyboard and mouse
	RestartDrivers();

	// load in graphics info
	SetupHandleTable();

	// Actors, globals and inventory icons
	LoadBasicChunks();

	// Continuous game processes
	CreateConstProcesses();

	// allow game to run in the background
	//RestartBackgroundProcess();	// FIXME: is this still needed?

	//dumpMusic();	// dumps all of the game's music in external XMIDI files

	// Load game from specified slot, if any
	//
	// TODO: We might want to think about properly taking care of possible
	// errors when loading the save state.

	if (ConfMan.hasKey("save_slot")) {
		if (loadGameState(ConfMan.getInt("save_slot")) == Common::kNoError)
			loadingFromGMM = true;
	}

	// Foreground loop
	uint32 timerVal = 0;
	while (!shouldQuit()) {
		assert(_console);
		if (_console->isAttached())
			_console->onFrame();

		// Check for time to do next game cycle
		if ((g_system->getMillis() > timerVal + GAME_FRAME_DELAY)) {
			timerVal = g_system->getMillis();
			AudioCD.updateCD();
			NextGameCycle();
		}

		if (bRestart) {
			RestartGame();
			bRestart = false;
			bHasRestarted = true;	// Set restarted flag
		}

		// Save/Restore scene file transfers
		ProcessSRQueue();

		// Handle any playing movie
		FettleBMV();

#ifdef DEBUG
		if (bFast)
			continue;		// run flat-out
#endif
		// Loop processing events while there are any pending
		while (pollEvent())
			;

		DoCdChange();

		if (MoviePlaying() && NextMovieTime())
			g_system->delayMillis(MAX<int>(NextMovieTime() - g_system->getMillis() + MovieAudioLag(), 0));
		else
			g_system->delayMillis(10);
	}

	// Write configuration
	WriteConfig();

	return Common::kNoError;
}
Esempio n. 30
0
void PreAgiEngine::drawStr(int row, int col, int attr, const char *buffer) {
	int code;

	if (attr == kColorDefault)
		attr = _defaultColor;

	for (int iChar = 0; iChar < (int)strlen(buffer); iChar++) {
		code = buffer[iChar];

		switch (code) {
		case '\n':
		case 0x8D:
			if (++row == 200 / 8) return;
			col = 0;
			break;

		case '|':
			// swap attribute nibbles
			break;

		default:
			_gfx->putTextCharacter(1, col * 8 , row * 8, static_cast<char>(code), attr & 0x0f, (attr & 0xf0) / 0x10, false, getGameID() == GID_MICKEY ? mickey_fontdata : ibm_fontdata);

			if (++col == 320 / 8) {
				col = 0;
				if (++row == 200 / 8) return;
			}
		}
	}
}