コード例 #1
0
Common::Error TeenAgentEngine::run() {
	Resources *res = Resources::instance();
	if (!res->loadArchives(_gameDescription))
		return Common::kUnknownError;

	Common::EventManager *_event = _system->getEventManager();

	initGraphics(320, 200, false);

	scene = new Scene;
	inventory = new Inventory;
	console = new Console(this);

	scene->init(this, _system);
	inventory->init(this);

	init();

	CursorMan.pushCursor(res->dseg.ptr(0x00da), 8, 12, 0, 0, 1);

	syncSoundSettings();

	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, music, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, false);
	setMusic(1);
	music->start();

	int load_slot = Common::ConfigManager::instance().getInt("save_slot");
	if (load_slot >= 0) {
		loadGameState(load_slot);
	} else {
		if (!showCDLogo())
			return Common::kNoError;
		if (!showLogo())
			return Common::kNoError;
		if (!showMetropolis())
			return Common::kNoError;
		scene->intro = true;
		scene_busy = true;
		processCallback(0x24c);
	}

	CursorMan.showMouse(true);

	uint32 game_timer = 0;
	uint32 mark_timer = 0;

	Common::Event event;
	Common::Point mouse;
	uint32 timer = _system->getMillis();

	do {
		Object *current_object = scene->findObject(mouse);

		while (_event->pollEvent(event)) {
			if (event.type == Common::EVENT_RTL) {
				deinit();
				return Common::kNoError;
			}

			if ((!scene_busy && inventory->processEvent(event)) || scene->processEvent(event))
				continue;

			//debug(0, "event");
			switch (event.type) {
			case Common::EVENT_KEYDOWN:
				if ((event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) ||
					event.kbd.ascii == '~' || event.kbd.ascii == '#') {
					console->attach();
				} else if (event.kbd.hasFlags(0) && event.kbd.keycode == Common::KEYCODE_F5) {
					openMainMenuDialog();
				} if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_f) {
					_mark_delay = _mark_delay == 80? 40: 80;
					debug(0, "mark_delay = %u", _mark_delay);
				}
				break;
			case Common::EVENT_LBUTTONDOWN:
				if (scene->getId() < 0)
					break;
				examine(event.mouse, current_object);
				break;
			case Common::EVENT_RBUTTONDOWN:
				//if (current_object)
				//	debug(0, "%d, %s", current_object->id, current_object->name.c_str());
				if (scene->getId() < 0)
					break;

				if (current_object == NULL)
					break;

				if (res->dseg.get_byte(0) == 3 && current_object->id == 1) {
					processCallback(0x5189); //boo!
					break;
				}
				if (res->dseg.get_byte(0) == 4 && current_object->id == 5) {
					processCallback(0x99e0); //getting an anchor
					break;
				}
				use(current_object);
				break;
			case Common::EVENT_MOUSEMOVE:
				mouse = event.mouse;
				break;
			default:
				;
			}
		}

		//game delays: slow 16, normal 11, fast 5, crazy 1
		//mark delays: 4 * (3 - hero_speed), normal == 1
		//game delays in 1/100th of seconds
		uint32 new_timer = _system->getMillis();
		uint32 delta = new_timer - timer;
		timer = new_timer;

		bool tick_game = game_timer <= delta;
		if (tick_game)
			game_timer = _game_delay - ((delta - game_timer) % _game_delay);
		else
			game_timer -= delta;

		bool tick_mark = mark_timer <= delta;
		if (tick_mark)
			mark_timer = _mark_delay - ((delta - mark_timer) % _mark_delay);
		else
			mark_timer -= delta;

		if (tick_game || tick_mark) {
			bool b = scene->render(tick_game, tick_mark, delta);
			if (!inventory->active() && !b && action != kActionNone) {
				processObject();
				action = kActionNone;
				dst_object = NULL;
			}
			scene_busy = b;
		}
		_system->showMouse(scene->getMessage().empty() && !scene_busy);

		bool busy = inventory->active() || scene_busy;

		Graphics::Surface *surface = _system->lockScreen();

		if (!busy) {
			InventoryObject *selected_object = inventory->selectedObject();
			if (current_object || selected_object) {
				Common::String name;
				if (selected_object) {
					name += selected_object->name;
					name += " & ";
				}
				if (current_object)
					name += current_object->name;

				uint w = res->font7.render(NULL, 0, 0, name, 0xd1);
				res->font7.render(surface, (320 - w) / 2, 180, name, 0xd1, true);
#if 0
				if (current_object) {
					current_object->rect.render(surface, 0x80);
					current_object->actor_rect.render(surface, 0x81);
				}
#endif
			}
		}

		inventory->render(surface, tick_game? 1: 0);

		_system->unlockScreen();

		_system->updateScreen();

		console->onFrame();

		uint32 next_tick = MIN(game_timer, mark_timer);
		if (next_tick > 0) {
			_system->delayMillis(next_tick > 40? 40: next_tick);
		}
	} while (!shouldQuit());

	deinit();
	return Common::kNoError;
}