Пример #1
0
void RMGfxEngine::unloadLocation(CORO_PARAM, bool bDoOnExit, uint32 *result) {
	CORO_BEGIN_CONTEXT;
	uint32 h;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// Release the location
	CORO_INVOKE_2(mpalEndIdlePoll, _nCurLoc, NULL);

	// On Exit?
	if (bDoOnExit) {
		_ctx->h = mpalQueryDoAction(1, _nCurLoc, 0);
		if (_ctx->h != CORO_INVALID_PID_VALUE)
			CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
	}

	_bLocationLoaded = false;

	_bigBuf.clearOT();
	_loc.unload();

	if (result != NULL)
		*result = CORO_INVALID_PID_VALUE;

	CORO_END_CODE;
}
Пример #2
0
void RMTony::stop(CORO_PARAM) {
	CORO_BEGIN_CONTEXT;
	uint32 pid;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	if (_actionItem != NULL) {
		// Call MPAL to choose the direction
		_ctx->pid = mpalQueryDoAction(21, _actionItem->mpalCode(), 0);

		if (_ctx->pid == CORO_INVALID_PID_VALUE)
			CORO_INVOKE_0(RMCharacter::stop);
		else {
			_bNeedToStop = false;    // If we make the OnWhichDirection, we don't need at least after the Stop().
			_bMoving = false;
			CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->pid, CORO_INFINITE); // @@@ Put an assert after 10 seconds
		}
	} else {
		CORO_INVOKE_0(RMCharacter::stop);
	}

	if (!_bActionPending)
		return;

	_bActionPending = false;

	executeAction(_action, _actionItem->mpalCode(), _actionParm);

	_actionItem = NULL;

	CORO_END_CODE;
}
Пример #3
0
void RMTony::executeAction(int nAction, int nActionItem, int nParm) {
	uint32 pid;

	if (nAction == TA_COMBINE) {
		pid = mpalQueryDoAction(TA_COMBINE, nParm, nActionItem);

		// If you failed the combine, we have RECEIVECOMBINE as a fallback
		if (pid == CORO_INVALID_PID_VALUE) {
			pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, nParm);

			// If you failed with that, go with the generic
			// @@@ CombineGive!
			if (pid == CORO_INVALID_PID_VALUE) {
				pid = mpalQueryDoAction(TA_COMBINE, nParm, 0);

				if (pid == CORO_INVALID_PID_VALUE) {
					pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, 0);
				}
			}
		}
	} else {
		// Perform the action
		pid = mpalQueryDoAction(nAction, nActionItem, 0);
	}

	if (pid != CORO_INVALID_PID_VALUE) {
		_bAction = true;
		CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
		_hActionThread = pid;
	} else if (nAction != TA_GOTO) {
		if (nAction == TA_TALK) {
			pid = mpalQueryDoAction(6, 1, 0);
			_bAction = true;
			CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
			_hActionThread = pid;
		} else if (nAction == TA_PERORATE) {
			pid = mpalQueryDoAction(7, 1, 0);
			_bAction = true;
			CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
			_hActionThread = pid;
		} else {
			pid = mpalQueryDoAction(5, 1, 0);
			_bAction = true;
			CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
			_hActionThread = pid;
		}
	}
}
Пример #4
0
void RMTextItemName::doFrame(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMLocation &loc, RMPointer &ptr, RMInventory &inv) {
	CORO_BEGIN_CONTEXT;
	RMItem *lastItem;
	uint32 hThread;
	CORO_END_CONTEXT(_ctx);

	Common::String itemName;

	CORO_BEGIN_CODE(_ctx);

	_ctx->lastItem = _item;

	// Adds to the list if there is need
	if (!_nInList)
		bigBuf.addPrim(new RMGfxPrimitive(this));

	// Update the scrolling co-ordinates
	_curscroll = loc.scrollPosition();

	// Check if we are on the inventory
	if (inv.itemInFocus(_mpos))
		_item = inv.whichItemIsIn(_mpos);
	else
		_item = loc.whichItemIsIn(_mpos);

	// If there an item, get its name
	if (_item != NULL)
		_item->getName(itemName);

	// Write it
	writeText(itemName, 1);

	// Handle the change If the selected item is different from the previous one
	if (_ctx->lastItem != _item) {
		if (_item == NULL)
			ptr.setSpecialPointer(RMPointer::PTR_NONE);
		else {
			_ctx->hThread = mpalQueryDoAction(20, _item->mpalCode(), 0);
			if (_ctx->hThread == CORO_INVALID_PID_VALUE)
				ptr.setSpecialPointer(RMPointer::PTR_NONE);
			else
				CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->hThread, CORO_INFINITE);
		}
	}

	CORO_END_CODE;
}
Пример #5
0
void RMGfxEngine::loadState(CORO_PARAM, const Common::String &fn) {
	// PROBLEM: You should change the location in a separate process to do the OnEnter
	CORO_BEGIN_CONTEXT;
	Common::InSaveFile *f;
	byte *state, *statecmp;
	uint32 size, sizecmp;
	char buf[4];
	RMPoint tp;
	int loc;
	int ver;
	int i;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	_ctx->f = g_system->getSavefileManager()->openForLoading(fn);
	if (_ctx->f == NULL)
		return;
	_ctx->f->read(_ctx->buf, 4);

	if (_ctx->buf[0] != 'R' || _ctx->buf[1] != 'M' || _ctx->buf[2] != 'S') {
		delete _ctx->f;
		return;
	}

	_ctx->ver = _ctx->buf[3];

	if (_ctx->ver == 0 || _ctx->ver > TONY_SAVEGAME_VERSION) {
		delete _ctx->f;
		return;
	}

	if (_ctx->ver >= 0x3) {
		// There is a thumbnail. If the version is between 5 and 7, it's compressed
		if ((_ctx->ver >= 0x5) && (_ctx->ver <= 0x7)) {
			_ctx->i = 0;
			_ctx->i = _ctx->f->readUint32LE();
			_ctx->f->seek(_ctx->i);
		} else {
			if (_ctx->ver >= 8)
				// Skip thumbnail size
				_ctx->f->skip(4);

			_ctx->f->seek(160 * 120 * 2, SEEK_CUR);
		}
	}

	if (_ctx->ver >= 0x5) {
		// Skip the difficulty level
		_ctx->f->seek(1, SEEK_CUR);
	}

	if (_ctx->ver >= 0x4) { // Skip the savegame name, which serves no purpose
		_ctx->i = _ctx->f->readByte();
		_ctx->f->seek(_ctx->i, SEEK_CUR);
	}

	_ctx->loc = _ctx->f->readUint32LE();
	_ctx->tp._x = _ctx->f->readUint32LE();
	_ctx->tp._y = _ctx->f->readUint32LE();
	_ctx->size = _ctx->f->readUint32LE();

	if ((_ctx->ver >= 0x5) && (_ctx->ver <= 7)) {
		// MPAL was packed!
		_ctx->sizecmp = _ctx->f->readUint32LE();
		_ctx->state = new byte[_ctx->size];
		_ctx->statecmp = new byte[_ctx->sizecmp];
		_ctx->f->read(_ctx->statecmp, _ctx->sizecmp);
		lzo1x_decompress(_ctx->statecmp, _ctx->sizecmp, _ctx->state, &_ctx->size);
		delete[] _ctx->statecmp;
	} else {
		// Read uncompressed MPAL data
		_ctx->state = new byte[_ctx->size];
		_ctx->f->read(_ctx->state, _ctx->size);
	}

	mpalLoadState(_ctx->state);
	delete[] _ctx->state;

	// Inventory
	_ctx->size = _ctx->f->readUint32LE();
	_ctx->state = new byte[_ctx->size];
	_ctx->f->read(_ctx->state, _ctx->size);
	_inv.loadState(_ctx->state);
	delete[] _ctx->state;

	if (_ctx->ver >= 0x2) {   // Version 2: box please
		_ctx->size = _ctx->f->readUint32LE();
		_ctx->state = new byte[_ctx->size];
		_ctx->f->read(_ctx->state, _ctx->size);
		g_vm->_theBoxes.loadState(_ctx->state);
		delete[] _ctx->state;
	}

	if (_ctx->ver >= 5) {
		// Version 5
		bool bStat = false;

		bStat = _ctx->f->readByte();
		_tony.setShepherdess(bStat);
		bStat = _ctx->f->readByte();
		_inter.setPerorate(bStat);

		charsLoadAll(_ctx->f);
	}

	if (_ctx->ver >= 6) {
		// Load options
		GLOBALS._bCfgInvLocked = _ctx->f->readByte();
		GLOBALS._bCfgInvNoScroll = _ctx->f->readByte();
		GLOBALS._bCfgTimerizedText = _ctx->f->readByte();
		GLOBALS._bCfgInvUp = _ctx->f->readByte();
		GLOBALS._bCfgAnni30 = _ctx->f->readByte();
		GLOBALS._bCfgAntiAlias = _ctx->f->readByte();
		GLOBALS._bShowSubtitles = _ctx->f->readByte();
		GLOBALS._bCfgTransparence = _ctx->f->readByte();
		GLOBALS._bCfgInterTips = _ctx->f->readByte();
		GLOBALS._bCfgDubbing = _ctx->f->readByte();
		GLOBALS._bCfgMusic = _ctx->f->readByte();
		GLOBALS._bCfgSFX = _ctx->f->readByte();
		GLOBALS._nCfgTonySpeed = _ctx->f->readByte();
		GLOBALS._nCfgTextSpeed = _ctx->f->readByte();
		GLOBALS._nCfgDubbingVolume = _ctx->f->readByte();
		GLOBALS._nCfgMusicVolume = _ctx->f->readByte();
		GLOBALS._nCfgSFXVolume = _ctx->f->readByte();

		// Load hotspots
		loadChangedHotspot(_ctx->f);
	}

	if (_ctx->ver >= 7) {
		loadMusic(_ctx->f);
	}

	delete _ctx->f;

	CORO_INVOKE_2(unloadLocation, false, NULL);
	loadLocation(_ctx->loc, _ctx->tp, RMPoint(-1, -1));
	_tony.setPattern(RMTony::PAT_STANDRIGHT);

	// On older versions, need to an enter action
	if (_ctx->ver < 5)
		mpalQueryDoAction(0, _ctx->loc, 0);
	else {
		// In the new ones, we just reset the mcode
		mCharResetCodes();
	}

	if (_ctx->ver >= 6)
		reapplyChangedHotspot();

	CORO_INVOKE_0(restoreMusic);

	_bGUIInterface = true;
	_bGUIInventory = true;
	_bGUIOption = true;

	CORO_END_CODE;
}