Exemplo n.º 1
0
/**
 * Save current scene.
 * @param sd			Pointer to the scene data
 */
void DoSaveScene(SAVED_DATA *sd) {
	sd->SavedSceneHandle = GetSceneHandle();
	sd->SavedBgroundHandle = GetBgroundHandle();
	SaveMovers(sd->SavedMoverInfo);
	sd->NumSavedActors = SaveActors(sd->SavedActorInfo);
	PlayfieldGetPos(FIELD_WORLD, &sd->SavedLoffset, &sd->SavedToffset);
	SaveInterpretContexts(sd->SavedICInfo);
	sd->SavedControl = ControlIsOn();
	sd->SavedNoBlocking = GetNoBlocking();
	GetNoScrollData(&sd->SavedNoScrollData);

	if (TinselV2) {
		// Tinsel 2 specific data save
		SaveActorZ(sd->savedActorZ);
		SaveZpositions(sd->zPositions);
		SavePolygonStuff(sd->SavedPolygonStuff);
		_vm->_pcmMusic->getTunePlaying(sd->SavedTune, sizeof(sd->SavedTune));
		sd->bTinselDim = _vm->_pcmMusic->getMusicTinselDimmed();
		sd->SavedScrollFocus = GetScrollFocus();
		SaveSysVars(sd->SavedSystemVars);
		SaveSoundReels(sd->SavedSoundReels);

	} else {
		// Tinsel 1 specific data save
		SaveDeadPolys(sd->SavedDeadPolys);
		CurrentMidiFacts(&sd->SavedMidi, &sd->SavedLoop);
	}

	ASceneIsSaved = true;
}
Exemplo n.º 2
0
/**
 * Process to handle changes in the mouse buttons.
 */
static void MouseProcess(CORO_PARAM, const void *) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		bool lastLWasDouble;
		bool lastRWasDouble;
		uint32 lastLeftClick, lastRightClick;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	_ctx->lastLWasDouble = false;
	_ctx->lastRWasDouble = false;
	_ctx->lastLeftClick = _ctx->lastRightClick = DwGetCurrentTime();

	while (true) {

		if (mouseButtons.empty()) {
			// allow scheduling
			CORO_SLEEP(1);
			continue;
		}

		// get next mouse button event
		Common::EventType type = *mouseButtons.begin();
		mouseButtons.erase(mouseButtons.begin());

		int xp, yp;
		GetCursorXYNoWait(&xp, &yp, true);
		const Common::Point mousePos(xp, yp);

		switch (type) {
		case Common::EVENT_LBUTTONDOWN:
			// left button press
			if (DwGetCurrentTime() - _ctx->lastLeftClick < (uint32)dclickSpeed) {
				// Left button double-click

				if (TinselV2) {
					// Kill off the button process and fire off the action command
					g_scheduler->killMatchingProcess(PID_BTN_CLICK, -1);
					PlayerEvent(PLR_ACTION, clickPos);
				} else {
					// signal left drag start
					ProcessButEvent(PLR_DRAG1_START);

					// signal left double click event
					ProcessButEvent(PLR_DLEFT);
				}

				_ctx->lastLWasDouble = true;
			} else {
				// Initial mouse down - either for a single click, or potentially
				// the start of a double-click action

				if (TinselV2) {
					PlayerEvent(PLR_DRAG1_START, mousePos);

					ProvNotProcessed();
					PlayerEvent(PLR_PROV_WALKTO, mousePos);

				} else {
					// signal left drag start
					ProcessButEvent(PLR_DRAG1_START);

					// signal left single click event
					ProcessButEvent(PLR_SLEFT);
				}

				_ctx->lastLWasDouble = false;
			}
			break;

		case Common::EVENT_LBUTTONUP:
			// left button release

			// update click timer
			if (_ctx->lastLWasDouble == false) {
				_ctx->lastLeftClick = DwGetCurrentTime();

				// If player control is enabled, start a process which, if it times out,
				// will activate a single button click
				if (TinselV2 && ControlIsOn()) {
					clickPos = mousePos;
					g_scheduler->createProcess(PID_BTN_CLICK, SingleLeftProcess, NULL, 0);
				}
			} else
				_ctx->lastLeftClick -= dclickSpeed;

			if (TinselV2)
				// Signal left drag end
				PlayerEvent(PLR_DRAG1_END, mousePos);
			else
				// signal left drag end
				ProcessButEvent(PLR_DRAG1_END);
			break;

		case Common::EVENT_RBUTTONDOWN:
			// right button press

			if (DwGetCurrentTime() - _ctx->lastRightClick < (uint32)dclickSpeed) {
				// Right button double-click
				if (TinselV2) {
					PlayerEvent(PLR_NOEVENT, clickPos);
				} else {
					// signal right drag start
					ProcessButEvent(PLR_DRAG2_START);

					// signal right double click event
					ProcessButEvent(PLR_DRIGHT);
				}

				_ctx->lastRWasDouble = true;
			} else {
				if (TinselV2) {
					PlayerEvent(PLR_DRAG2_START, mousePos);
					PlayerEvent(PLR_LOOK, mousePos);
				} else {
					// signal right drag start
					ProcessButEvent(PLR_DRAG2_START);

					// signal right single click event
					ProcessButEvent(PLR_SRIGHT);
				}

				_ctx->lastRWasDouble = false;
			}
			break;

		case Common::EVENT_RBUTTONUP:
			// right button release

			// update click timer
			if (_ctx->lastRWasDouble == false)
				_ctx->lastRightClick = DwGetCurrentTime();
			else
				_ctx->lastRightClick -= dclickSpeed;

			if (TinselV2)
				// Signal left drag end
				PlayerEvent(PLR_DRAG2_END, mousePos);
			else
				// signal right drag end
				ProcessButEvent(PLR_DRAG2_END);
			break;

		default:
			break;
		}
	}
	CORO_END_CODE;
}
Exemplo n.º 3
0
/**
 * Main interface point for specifying player atcions
 */
void PlayerEvent(PLR_EVENT pEvent, const Common::Point &coOrds) {
	// Logging of player actions
	const char *actionList[] = {
		"PLR_PROV_WALKTO", "PLR_WALKTO", "PLR_LOOK", "PLR_ACTION", "PLR_ESCAPE",
		"PLR_MENU", "PLR_QUIT", "PLR_PGUP", "PLR_PGDN", "PLR_HOME", "PLR_END",
		"PLR_DRAG1_START", "PLR_DRAG1_END", "PLR_DRAG2_START", "PLR_DRAG2_END",
		"PLR_JUMP", "PLR_NOEVENT", "PLR_SAVE", "PLR_LOAD", "PLR_WHEEL_UP",
		"PLR_WHEEL_DOWN"};
	debugC(DEBUG_BASIC, kTinselDebugActions, "%s - (%d,%d)",
		actionList[pEvent], coOrds.x, coOrds.y);
	static uint32 lastRealAction = 0;	// FIXME: Avoid non-const global vars

	// This stuff to allow F1 key during startup.
	if (g_bEnableMenu && pEvent == PLR_MENU)
		Control(CONTROL_ON);
	else
		IncUserEvents();

	if (pEvent == PLR_ESCAPE) {
		++g_escEvents;
		++g_leftEvents;		// Yes, I do mean this
	} else if ((pEvent == PLR_PROV_WALKTO)
			|| (pEvent == PLR_WALKTO)
			|| (pEvent == PLR_LOOK)
			|| (pEvent == PLR_ACTION)) {
		++g_leftEvents;
	}

	// Only allow events if player control is on
	if (!ControlIsOn() && (pEvent != PLR_DRAG1_END))
		return;

	if (TinselV2 && InventoryActive()) {
		int x, y;
		PlayfieldGetPos(FIELD_WORLD, &x, &y);
		EventToInventory(pEvent, Common::Point(coOrds.x - x, coOrds.y - y));
		return;
	}

	switch (pEvent) {
	case PLR_QUIT:
		OpenMenu(QUIT_MENU);
		break;

	case PLR_MENU:
		OpenMenu(MAIN_MENU);
		break;

	case PLR_JUMP:
		OpenMenu(HOPPER_MENU1);
		break;

	case PLR_SAVE:
		OpenMenu(SAVE_MENU);
		break;

	case PLR_LOAD:
		OpenMenu(LOAD_MENU);
		break;

	case PLR_PROV_WALKTO:		// Provisional WALKTO !
		ProcessUserEvent(PROV_WALKTO, coOrds);
		break;

	case PLR_WALKTO:
		REAL_ACTION_CHECK;

		if (TinselV2 || !InventoryActive())
			ProcessUserEvent(WALKTO, coOrds, PLR_SLEFT);
		else
			EventToInventory(PLR_SLEFT, coOrds);
		break;

	case PLR_ACTION:
		REAL_ACTION_CHECK;

		if (TinselV2 || !InventoryActive())
			ProcessUserEvent(ACTION, coOrds, PLR_DLEFT);
		else
			EventToInventory(PLR_DLEFT, coOrds);
		break;

	case PLR_LOOK:
		REAL_ACTION_CHECK;

		if (TinselV2 || !InventoryActive())
			ProcessUserEvent(LOOK, coOrds, PLR_SRIGHT);
		else
			EventToInventory(PLR_SRIGHT, coOrds);
		break;

	default:
		if (InventoryActive())
			EventToInventory(pEvent, coOrds);
		break;
	}
}