Example #1
0
/**
 * Started up for scene script and entrance script.
 */
static void SceneTinselProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		INT_CONTEXT *pic;
		const TP_INIT *pInit;
		int myEscape;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// The following myEscape value setting is used for enabling title screen skipping in DW1
	if (TinselV1 && (sceneCtr == 1)) initialMyEscape = GetEscEvents();
	_ctx->myEscape = (TinselV1 && (sceneCtr < 4)) ? initialMyEscape : 0;

	// get the stuff copied to process when it was created
	_ctx->pInit = (const TP_INIT *)param;
	assert(_ctx->pInit);
	assert(_ctx->pInit->hTinselCode);		// Must have some code to run

	_ctx->pic = InitInterpretContext(GS_SCENE,
		READ_LE_UINT32(&_ctx->pInit->hTinselCode),
		TinselV2 ? _ctx->pInit->event : NOEVENT,
		NOPOLY,			// No polygon
		0,				// No actor
		NULL,			// No object
		_ctx->myEscape);
	CORO_INVOKE_1(Interpret, _ctx->pic);

	if (_ctx->pInit->event == CLOSEDOWN || _ctx->pInit->event == LEAVE_T2)
		bWatchingOut = false;

	CORO_END_CODE;
}
Example #2
0
static void ActorRestoredProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		INT_CONTEXT *pic;
	CORO_END_CONTEXT(_ctx);

	// get the stuff copied to process when it was created
	const RATP_INIT *r = (const RATP_INIT *)param;
	bool isSavegame = r->pic->resumeState == RES_SAVEGAME;

	CORO_BEGIN_CODE(_ctx);

	_ctx->pic = RestoreInterpretContext(r->pic);

	// The newly added check here specially sets the process to RES_NOT when loading a savegame.
	// This is needed particularly for the Psychiatrist scene in Discworld 1 - otherwise Rincewind
	// can't go upstairs without leaving the building and returning.  If this patch causes problems
	// in other scenes, an added check for the hCode == 1174490602 could be added.
	if (isSavegame && TinselV1)
		_ctx->pic->resumeState = RES_NOT;

	CORO_INVOKE_1(Interpret, _ctx->pic);

	// If it gets here, actor's code has run to completion
	actorInfo[r->id - 1].completed = true;

	CORO_END_CODE;
}
Example #3
0
/**
 * Runs actor's glitter code.
 */
static void ActorTinselProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		INT_CONTEXT *pic;
		bool bTookControl;
	CORO_END_CONTEXT(_ctx);

	// get the stuff copied to process when it was created
	const ATP_INIT *atp = (const ATP_INIT *)param;

	CORO_BEGIN_CODE(_ctx);

	if (TinselV2) {
		// Take control for CONVERSE events
		if (atp->event == CONVERSE) {
			_ctx->bTookControl = GetControl();
			HideConversation(true);
		} else
			_ctx->bTookControl = false;

		// Run the Glitter code
		CORO_INVOKE_1(Interpret, atp->pic);

		// Restore conv window if applicable
		if (atp->event == CONVERSE) {
			// Free control if we took it
			if (_ctx->bTookControl)
				ControlOn();

			HideConversation(false);
		}
	} else {
		CORO_INVOKE_1(AllowDclick, atp->bev);		// May kill us if single click

		// Run the Glitter code
		assert(actorInfo[atp->id - 1].actorCode); // no code to run

		_ctx->pic = InitInterpretContext(GS_ACTOR, actorInfo[atp->id - 1].actorCode,
			atp->event, NOPOLY, atp->id, NULL);
		CORO_INVOKE_1(Interpret, _ctx->pic);

		// If it gets here, actor's code has run to completion
		actorInfo[atp->id - 1].completed = true;
	}

	CORO_END_CODE;
}
Example #4
0
/**
 * Main process for playing the game.
 *
 * @remarks     This needs to be in a separate process, since there are some things that can briefly
 * block the execution of process. For now, all ScummVm event handling is dispatched to within the context of this
 * process. If it ever proves a problem, we may have to look into whether it's feasible to have it still remain
 * in the outer 'main' process.
 */
void TonyEngine::playProcess(CORO_PARAM, const void *param) {
	CORO_BEGIN_CONTEXT;
	Common::String fn;
	CORO_END_CONTEXT(_ctx);


	CORO_BEGIN_CODE(_ctx);

	// Game loop. We rely on the outer main process to detect if a shutdown is required,
	// and kill the scheudler and all the processes, including this one
	for (;;) {
		// If a savegame needs to be loaded, then do so
		if (g_vm->_loadSlotNumber != -1 && GLOBALS._gfxEngine != NULL) {
			_ctx->fn = getSaveStateFileName(g_vm->_loadSlotNumber);
			CORO_INVOKE_1(GLOBALS._gfxEngine->loadState, _ctx->fn);
			g_vm->_loadSlotNumber = -1;
		}

		// Wait for the next frame
		CORO_INVOKE_1(CoroScheduler.sleep, 50);

		// Call the engine to handle the next frame
		CORO_INVOKE_1(g_vm->_theEngine.doFrame, g_vm->_bDrawLocation);

		// Warns that a frame is finished
		CoroScheduler.pulseEvent(g_vm->_hEndOfFrame);

		// Handle drawing the frame
		if (!g_vm->_bPaused) {
			if (!g_vm->_theEngine._bWiping)
				g_vm->_window.getNewFrame(g_vm->_theEngine, NULL);
			else
				g_vm->_window.getNewFrame(g_vm->_theEngine, &g_vm->_theEngine._rcWipeEllipse);
		}

		// Paint the frame onto the screen
		g_vm->_window.repaint();

		// Signal the ScummVM debugger
		g_vm->_debugger->onFrame();
	}

	CORO_END_CODE;
}
Example #5
0
/**
 * Run the master script.
 * Continues between scenes, or until Interpret() returns.
 */
static void MasterScriptProcess(CORO_PARAM, const void *) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		INT_CONTEXT *pic;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);
	_ctx->pic = InitInterpretContext(GS_MASTER, 0, NOEVENT, NOPOLY, 0, NULL);
	CORO_INVOKE_1(Interpret, _ctx->pic);
	CORO_END_CODE;
}
Example #6
0
void TonyEngine::loadState(CORO_PARAM, int n) {
	CORO_BEGIN_CONTEXT;
	Common::String buf;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	_ctx->buf = getSaveStateFileName(n);
	CORO_INVOKE_1(_theEngine.loadState, _ctx->buf.c_str());

	CORO_END_CODE;
}
Example #7
0
void RMDialogChoice::doFrame(CORO_PARAM, RMPoint ptMousePos) {
	CORO_BEGIN_CONTEXT;
	int i;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	if (ptMousePos._y > _ptDrawPos._y) {
		for (_ctx->i = 0; _ctx->i < _numChoices; _ctx->i++) {
			if ((ptMousePos._y >= _ptDrawPos._y + _ptDrawStrings[_ctx->i]._y) && (ptMousePos._y < _ptDrawPos._y + _ptDrawStrings[_ctx->i]._y + _drawedStrings[_ctx->i].getDimy())) {
				CORO_INVOKE_1(setSelected, _ctx->i);
				break;
			}
		}

		if (_ctx->i == _numChoices)
			CORO_INVOKE_1(setSelected, -1);
	}

	CORO_END_CODE;
}
Example #8
0
/**
 * Process Tinsel Process
 */
static void ProcessTinselProcess(CORO_PARAM, const void *param) {
	const PINT_CONTEXT *pPic = (const PINT_CONTEXT *)param;

	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// get the stuff copied to process when it was created
	CORO_INVOKE_1(Interpret, *pPic);

	CORO_KILL_SELF();
	CORO_END_CODE;
}
Example #9
0
/**
 * The code for for restored scene processes.
 */
static void RestoredProcessProcess(CORO_PARAM, const void *param) {
	CORO_BEGIN_CONTEXT;
		INT_CONTEXT *pic;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// get the stuff copied to process when it was created
	_ctx->pic = *(const PINT_CONTEXT *)param;

	_ctx->pic = RestoreInterpretContext(_ctx->pic);
	AttachInterpret(_ctx->pic, g_scheduler->getCurrentProcess());

	CORO_INVOKE_1(Interpret, _ctx->pic);

	CORO_END_CODE;
}
Example #10
0
static void ActorRestoredProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		INT_CONTEXT *pic;
	CORO_END_CONTEXT(_ctx);

	// get the stuff copied to process when it was created
	const RATP_INIT *r = (const RATP_INIT *)param;

	CORO_BEGIN_CODE(_ctx);

	_ctx->pic = RestoreInterpretContext(r->pic);
	CORO_INVOKE_1(Interpret, _ctx->pic);

	// If it gets here, actor's code has run to completion
	actorInfo[r->id - 1].completed = true;

	CORO_END_CODE;
}
Example #11
0
/**
 * Continually checks to see if active sounds have finished playing
 * Sets the event signalling the sound has ended
 */
void FPSfx::soundCheckProcess(CORO_PARAM, const void *param) {
	CORO_BEGIN_CONTEXT;
		Common::List<FPSfx *>::iterator i;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	for (;;) {
		// Check each active sound
		for (_ctx->i = g_vm->_activeSfx.begin(); _ctx->i != g_vm->_activeSfx.end(); ++_ctx->i) {
			FPSfx *sfx = *_ctx->i;
			if (sfx->endOfBuffer())
				CoroScheduler.setEvent(sfx->_hEndOfBuffer);
		}

		// Delay until the next check is done
		CORO_INVOKE_1(CoroScheduler.sleep, 50);
	}

	CORO_END_CODE;
}
Example #12
0
static void RestoredProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		INT_CONTEXT *pic;
		bool bConverse;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// get the stuff copied to process when it was created
	_ctx->pic = *((INT_CONTEXT * const *)param);

	_ctx->pic = RestoreInterpretContext(_ctx->pic);
	_ctx->bConverse = TinselV2 && (_ctx->pic->event == CONVERSE);

	CORO_INVOKE_1(Interpret, _ctx->pic);

	// Restore control after CallScene() from a conversation icon
	if (_ctx->bConverse)
		ControlOn();

	CORO_END_CODE;
}
Example #13
0
void RMGfxEngine::doFrame(CORO_PARAM, bool bDrawLocation) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// Poll of input devices
	_input.poll();

	if (_bMustEnterMenu && GLOBALS._bIdleExited) {
		_bOption = true;
		_bMustEnterMenu = false;
		GLOBALS._bIdleExited = false;
	}

	if (_bOption) {
		CORO_INVOKE_1(_opt.doFrame, &_input);
		_bOption = !_opt.isClosing();
		if (!_bOption) {
			disableMouse();
			enableInput();
			mpalStartIdlePoll(_nCurLoc);
			g_vm->pauseSound(false);
		}
	}

	if (bDrawLocation && _bLocationLoaded) {
		// Location and objects
		_loc.doFrame(&_bigBuf);

		// Check the mouse input
		if (_bInput && !_tony.inAction()) {
			// If we are on the inventory, it is it who controls all input
			if (_inv.haveFocus(_input.mousePos()) && !_inter.active()) {
				// Left Click
				// **********
				if (_input.mouseLeftClicked()/* && m_itemName.IsItemSelected()*/) {
					// Left click activates the combine, if we are on an object
					if (_inv.leftClick(_input.mousePos(), _curActionObj)) {
						_curAction = TA_COMBINE;
						_point.setAction(_curAction);
					}
				} else

					// Right Click
					// ***********
					if (_input.mouseRightClicked()) {
						if (_itemName.isItemSelected()) {
							_curActionObj = 0;
							_inv.rightClick(_input.mousePos());
						} else
							_inv.rightClick(_input.mousePos());
					} else

						// Right Release
						// *************
						if (_input.mouseRightReleased()) {
							if (_inv.rightRelease(_input.mousePos(), _curAction)) {
								CORO_INVOKE_3(_tony.moveAndDoAction, _itemName.getHotspot(), _itemName.getSelectedItem(), _curAction);

								_curAction = TA_GOTO;
								_point.setAction(_curAction);
							}
						}
			} else {
				// Options Menu
				// ************
				if (_bGUIOption) {
					if (!_tony.inAction() && _bInput) {
						if ((_input.mouseLeftClicked() && _input.mousePos()._x < 3 && _input.mousePos()._y < 3)) {
							CORO_INVOKE_1(openOptionScreen, 0);
							goto SKIPCLICKSINISTRO;
						} else if (_input.getAsyncKeyState(Common::KEYCODE_ESCAPE))
							CORO_INVOKE_1(openOptionScreen, 0);
						else if (!g_vm->getIsDemo()) {
							if (_input.getAsyncKeyState(Common::KEYCODE_F3) || _input.getAsyncKeyState(Common::KEYCODE_F5))
								// Save game screen
								CORO_INVOKE_1(openOptionScreen, 4);
							else if (_input.getAsyncKeyState(Common::KEYCODE_F2) || _input.getAsyncKeyState(Common::KEYCODE_F7))
								// Load game screen
								CORO_INVOKE_1(openOptionScreen, 3);
						}
					}
				}

				// Left Click
				// **************
				if (_input.mouseLeftClicked() && !_inter.active()) {

					if (_curAction != TA_COMBINE)
						CORO_INVOKE_3(_tony.moveAndDoAction, _itemName.getHotspot(), _itemName.getSelectedItem(), _point.curAction());
					else if (_itemName.getSelectedItem() != NULL)
						CORO_INVOKE_4(_tony.moveAndDoAction, _itemName.getHotspot(), _itemName.getSelectedItem(), TA_COMBINE, _curActionObj);

					if (_curAction == TA_COMBINE) {
						_inv.endCombine();
						_point.setSpecialPointer(RMPointer::PTR_NONE);
					}

					_curAction = TA_GOTO;
					_point.setAction(_curAction);
				}

SKIPCLICKSINISTRO:
				// Right Click
				// ************
				if (_curAction == TA_COMBINE) {
					// During a combine, it cancels it
					if (_input.mouseRightClicked()) {
						_inv.endCombine();
						_curActionObj = 0;
						_curAction = TA_GOTO;
						_point.setAction(_curAction);
						_point.setSpecialPointer(RMPointer::PTR_NONE);
					}
				} else if (_input.mouseRightClicked() && _itemName.isItemSelected() && _point.getSpecialPointer() == RMPointer::PTR_NONE) {
					if (_bGUIInterface) {
						// Before opening the interface, replaces GOTO
						_curAction = TA_GOTO;
						_curActionObj = 0;
						_point.setAction(_curAction);
						_inter.clicked(_input.mousePos());
					}
				}


				// Right Release
				// *************
				if (_input.mouseRightReleased()) {
					if (_bGUIInterface) {
						if (_inter.released(_input.mousePos(), _curAction)) {
							_point.setAction(_curAction);
							CORO_INVOKE_3(_tony.moveAndDoAction, _itemName.getHotspot(), _itemName.getSelectedItem(), _curAction);

							_curAction = TA_GOTO;
							_point.setAction(_curAction);
						}
					}
				}
			}

			// Update the name under the mouse pointer
			_itemName.setMouseCoord(_input.mousePos());
			if (!_inter.active() && !_inv.miniActive())
				CORO_INVOKE_4(_itemName.doFrame, _bigBuf, _loc, _point, _inv);
		}

		// Interface & Inventory
		_inter.doFrame(_bigBuf, _input.mousePos());
		_inv.doFrame(_bigBuf, _point, _input.mousePos(), (!_tony.inAction() && !_inter.active() && _bGUIInventory));
	}

	// Animate Tony
	CORO_INVOKE_2(_tony.doFrame, &_bigBuf, _nCurLoc);

	// Update screen scrolling to keep Tony in focus
	if (_tony.mustUpdateScrolling() && _bLocationLoaded) {
		RMPoint showThis = _tony.position();
		showThis._y -= 60;
		_loc.updateScrolling(showThis);
	}

	if (_bLocationLoaded)
		_tony.setScrollPosition(_loc.scrollPosition());

	if ((!_tony.inAction() && _bInput) || _bAlwaysDrawMouse) {
		_point.showCursor();
	} else {
		_point.hideCursor();
	}
	_point.doFrame();

	// **********************
	// Draw the list in the OT
	// **********************
	CORO_INVOKE_0(_bigBuf.drawOT);

#define FSTEP (480/32)

	// Wipe
	if (_bWiping) {
		switch (_nWipeType) {
		case 1:
			if (!(_rcWipeEllipse.bottom - _rcWipeEllipse.top >= FSTEP * 2)) {
				CoroScheduler.setEvent(_hWipeEvent);
				_nWipeType = 3;
				break;
			}

			_rcWipeEllipse.top += FSTEP;
			_rcWipeEllipse.left += FSTEP;
			_rcWipeEllipse.right -= FSTEP;
			_rcWipeEllipse.bottom -= FSTEP;
			break;

		case 2:
			if (!(_rcWipeEllipse.bottom - _rcWipeEllipse.top < 480 - FSTEP)) {
				CoroScheduler.setEvent(_hWipeEvent);
				_nWipeType = 3;
				break;
			}

			_rcWipeEllipse.top -= FSTEP;
			_rcWipeEllipse.left -= FSTEP;
			_rcWipeEllipse.right += FSTEP;
			_rcWipeEllipse.bottom += FSTEP;
			break;
		}
	}

	CORO_END_CODE;
}
Example #14
0
/**
 * Runs glitter code associated with a polygon.
 */
void PolyTinselProcess(CORO_PARAM, const void *param) {
	// COROUTINE
	CORO_BEGIN_CONTEXT;
		INT_CONTEXT *pic;
		bool bTookControl;	// Set if this function takes control

	CORO_END_CONTEXT(_ctx);

	const PTP_INIT *to = (const PTP_INIT *)param;	// get the stuff copied to process when it was created

	CORO_BEGIN_CODE(_ctx);

	if (TinselV2) {

		// Take control for CONVERSE events
		if (to->event == CONVERSE) {
			_ctx->bTookControl = GetControl();
			HideConversation(true);
		} else
			_ctx->bTookControl = false;

		CORO_INVOKE_1(Interpret, to->pic);

		// Restore conv window if applicable
		if (to->event == CONVERSE) {
			// Free control if we took it
			if (_ctx->bTookControl)
				ControlOn();

			HideConversation(false);
		}

	} else {

		CORO_INVOKE_1(AllowDclick, to->bev);	// May kill us if single click

		// Control may have gone off during AllowDclick()
		if (!TestToken(TOKEN_CONTROL)
			&& (to->event == WALKTO || to->event == ACTION || to->event == LOOK))
			CORO_KILL_SELF();

		// Take control, if requested
		if (to->take_control)
			_ctx->bTookControl = GetControl(CONTROL_OFF);
		else
			_ctx->bTookControl = false;

		// Hide conversation if appropriate
		if (to->event == CONVERSE)
			HideConversation(true);

		// Run the code
		_ctx->pic = InitInterpretContext(GS_POLYGON, GetPolyScript(to->hPoly), to->event, to->hPoly, to->actor, NULL);
		CORO_INVOKE_1(Interpret, _ctx->pic);

		// Free control if we took it
		if (_ctx->bTookControl)
			Control(CONTROL_ON);

		// Restore conv window if applicable
		if (to->event == CONVERSE)
			HideConversation(false);
	}

	CORO_END_CODE;
}