コード例 #1
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
void RMDialogChoice::hide(CORO_PARAM) {
	CORO_BEGIN_CONTEXT;
	int deltay;
	int starttime;
	int elaps;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	if (1) {
		_ctx->starttime = g_vm->getTime();

		_ctx->deltay = 480 - _ptDrawPos._y;
		_ctx->elaps = 0;
		while (_ctx->elaps < 700) {
			CORO_INVOKE_2(CoroScheduler.waitForSingleObject, g_vm->_hEndOfFrame, CORO_INFINITE);
			_ctx->elaps = g_vm->getTime() - _ctx->starttime;
			_ptDrawPos._y = 480 - ((_ctx->deltay * 100) / 700 * (700 - _ctx->elaps)) / 100;
		}
	}

	_bShow = false;
	_bRemoveFromOT = true;
	CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _hUnreg, CORO_INFINITE);

	CORO_END_CODE;
}
コード例 #2
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;
}
コード例 #3
0
ファイル: tony.cpp プロジェクト: Cruel/scummvm
void TonyEngine::autoSave(CORO_PARAM) {
	CORO_BEGIN_CONTEXT;
	Common::String buf;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	grabThumbnail();
	CORO_INVOKE_2(CoroScheduler.waitForSingleObject, g_vm->_hEndOfFrame, CORO_INFINITE);
	CORO_INVOKE_2(CoroScheduler.waitForSingleObject, g_vm->_hEndOfFrame, CORO_INFINITE);
	_ctx->buf = getSaveStateFileName(0);
	_theEngine.saveState(_ctx->buf, (byte *)_curThumbnail, "Autosave");

	CORO_END_CODE;
}
コード例 #4
0
void RMGfxEngine::openOptionScreen(CORO_PARAM, int type) {
	CORO_BEGIN_CONTEXT;
	bool bRes;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	_ctx->bRes = false;

	if (type == 0)
		CORO_INVOKE_2(_opt.init, _bigBuf, _ctx->bRes);
	else if (type == 1)
		CORO_INVOKE_3(_opt.initLoadMenuOnly, _bigBuf, true, _ctx->bRes);
	else if (type == 2)
		CORO_INVOKE_2(_opt.initNoLoadSave, _bigBuf, _ctx->bRes);
	else if (type == 3)
		CORO_INVOKE_3(_opt.initLoadMenuOnly, _bigBuf, false, _ctx->bRes);
	else if (type == 4)
		CORO_INVOKE_3(_opt.initSaveMenuOnly, _bigBuf, false, _ctx->bRes);

	if (_ctx->bRes) {
		g_vm->pauseSound(true);

		disableInput();
		_inv.endCombine();
		_curActionObj = 0;
		_curAction = TA_GOTO;
		_point.setAction(_curAction);
		_point.setSpecialPointer(RMPointer::PTR_NONE);
		_point.setCustomPointer(NULL);
		enableMouse();
		g_vm->grabThumbnail();

		// Exists the IDLE to avoid premature death in loading
		_bMustEnterMenu = true;
		if (type == 1 || type == 2) {
			GLOBALS._bIdleExited = true;
		} else {
			CORO_INVOKE_0(_tony.stopNoAction);

			GLOBALS._bIdleExited = false;

			CoroScheduler.createProcess(exitAllIdles, &_nCurLoc, sizeof(int));
		}
	}

	CORO_END_CODE;
}
コード例 #5
0
ファイル: tonychar.cpp プロジェクト: AReim1982/scummvm
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;
}
コード例 #6
0
ファイル: tonychar.cpp プロジェクト: AReim1982/scummvm
void RMTony::moveAndDoAction(CORO_PARAM, RMPoint dst, RMItem *item, int nAction, int nActionParm) {
	CORO_BEGIN_CONTEXT;
	bool result;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// Makes normal movement, but remember if you must then perform an action
	if (item == NULL) {
		_bActionPending = false;
		_actionItem = NULL;
	} else {
		_actionItem = item;
		_action = nAction;
		_actionParm = nActionParm;
		_bActionPending = true;
	}

	CORO_INVOKE_2(RMCharacter::move, dst, &_ctx->result);
	if (!_ctx->result) {
		_bActionPending = false;
		_actionItem = NULL;
	}

	CORO_END_CODE;
}
コード例 #7
0
ファイル: actors.cpp プロジェクト: AdamRi/scummvm-pink
/**
 * Starts up process to run actor's glitter code.
 */
void ActorEvent(CORO_PARAM, int ano, TINSEL_EVENT tEvent, bool bWait, int myEscape, bool *result) {
	ATP_INIT atp;
	int	index;
	CORO_BEGIN_CONTEXT;
		PPROCESS pProc;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	index = TaggedActorIndex(ano);
	assert(taggedActors[index].hActorCode);
	if (result) *result = false;

	atp.id = 0;
	atp.event = tEvent;
	atp.pic = InitInterpretContext(GS_ACTOR,
			taggedActors[index].hActorCode,
			tEvent,
			NOPOLY,			// No polygon
			ano,			// Actor
			NULL,			// No object
			myEscape);

	if (atp.pic != NULL) {
		_ctx->pProc = g_scheduler->createProcess(PID_TCODE, ActorTinselProcess, &atp, sizeof(atp));
		AttachInterpret(atp.pic, _ctx->pProc);

		if (bWait)
			CORO_INVOKE_2(WaitInterpret,_ctx->pProc, result);
	}

	CORO_END_CODE;
}
コード例 #8
0
ファイル: tonychar.cpp プロジェクト: AReim1982/scummvm
void RMTony::doFrame(CORO_PARAM, RMGfxTargetBuffer *bigBuf, int curLoc) {
	CORO_BEGIN_CONTEXT;
	int time;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	if (!_nInList && _bShow)
		bigBuf->addPrim(new RMGfxPrimitive(this));

	setSpeed(GLOBALS._nCfgTonySpeed);

	// Runs the normal character movement
	_ctx->time = g_vm->getTime();

	do {
		_nTimeLastStep += (1000 / 40);
		CORO_INVOKE_2(RMCharacter::doFrame, bigBuf, curLoc);
	} while (_ctx->time > _nTimeLastStep + (1000 / 40));

	// Check if we are at the end of a path
	if (endOfPath() && _bActionPending) {
		// Must perform the action on which we clicked
		_bActionPending = false;
	}

	if (_bIsTalking || _bIsStaticTalk)
		_body.doFrame(bigBuf, false);

	CORO_END_CODE;
}
コード例 #9
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
void RMText::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);
	// Horizontally
	if (_aHorType == HCENTER)
		prim->getDst().topLeft() -= RMPoint(_dimx / 2, 0);
	else if (_aHorType == HRIGHT)
		prim->getDst().topLeft() -= RMPoint(_dimx, 0);

	// Vertically
	if (_aVerType == VTOP) {

	} else if (_aVerType == VCENTER) {
		prim->getDst()._y1 -= _dimy / 2;

	} else if (_aVerType == VBOTTOM) {
		prim->getDst()._y1 -= _dimy;
	}

	clipOnScreen(prim);

	CORO_INVOKE_2(RMGfxWoodyBuffer::draw, bigBuf, prim);

	CORO_END_CODE;
}
コード例 #10
0
ファイル: events.cpp プロジェクト: AReim1982/scummvm
/**
 * Run the Polygon process with the given event
 */
void PolygonEvent(CORO_PARAM, HPOLYGON hPoly, TINSEL_EVENT tEvent, int actor, bool bWait,
				  int myEscape, bool *result) {
	CORO_BEGIN_CONTEXT;
		Common::PPROCESS pProc;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	PTP_INIT to;

	if (result)
		*result = false;
	to.hPoly = -1;
	to.event = tEvent;
	to.pic = InitInterpretContext(GS_POLYGON,
			GetPolyScript(hPoly),
			tEvent,
			hPoly,			// Polygon
			actor,			// Actor
			NULL,			// No Object
			myEscape);
	if (to.pic != NULL) {
		_ctx->pProc = CoroScheduler.createProcess(PID_TCODE, PolyTinselProcess, &to, sizeof(to));
		AttachInterpret(to.pic, _ctx->pProc);

		if (bWait)
			CORO_INVOKE_2(WaitInterpret, _ctx->pProc, result);
	}

	CORO_END_CODE;
}
コード例 #11
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
void RMDialogChoice::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	if (_bShow == false)
		return;

	prim->setDst(_ptDrawPos);
	CORO_INVOKE_2(RMGfxSourceBuffer16::draw, bigBuf, prim);

	CORO_END_CODE;
}
コード例 #12
0
ファイル: tonychar.cpp プロジェクト: AReim1982/scummvm
void RMTony::waitEndOfAction(CORO_PARAM, const void *param) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	uint32 pid = *(const uint32 *)param;

	CORO_BEGIN_CODE(_ctx);

	CORO_INVOKE_2(CoroScheduler.waitForSingleObject, pid, CORO_INFINITE);

	_bAction = false;

	CORO_END_CODE;
}
コード例 #13
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
void RMFont::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim2) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	RMFontPrimitive *prim = (RMFontPrimitive *)prim2;

	CORO_BEGIN_CODE(_ctx);

	// Call the draw method of the letter assigned to the primitive
	if (prim->_nChar != -1)
		CORO_INVOKE_2(_letter[prim->_nChar].draw, bigBuf, prim);

	CORO_END_CODE;
}
コード例 #14
0
ファイル: tonychar.cpp プロジェクト: AReim1982/scummvm
void RMTony::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// Call the Draw() of the parent class if Tony is visible
	if (_bShow && _bDrawNow) {
		if (_bBodyFront) {
			prim->getDst().setEmpty();
			prim->getDst().offset(-44, -134);
			if (_bShepherdess)
				prim->getDst().offset(1, 4);
			CORO_INVOKE_2(RMCharacter::draw, bigBuf, prim);
		}

		if (_bIsTalking || _bIsStaticTalk) {
			// Offest direction from scrolling
			prim->getDst().setEmpty();
			prim->getDst().offset(-_curScroll);
			prim->getDst().offset(_pos);
			prim->getDst().offset(-44, -134);
			prim->getDst() += _nBodyOffset;
			CORO_INVOKE_2(_body.draw, bigBuf, prim);
		}

		if (!_bBodyFront) {
			prim->getDst().setEmpty();
			prim->getDst().offset(-44, -134);
			if (_bShepherdess)
				prim->getDst().offset(0, 3);
			CORO_INVOKE_2(RMCharacter::draw, bigBuf, prim);
		}
	}

	CORO_END_CODE;
}
コード例 #15
0
ファイル: tonychar.cpp プロジェクト: AReim1982/scummvm
void RMTony::stopNoAction(CORO_PARAM) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	if (_bAction)
		CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _hActionThread, CORO_INFINITE);

	_bActionPending = false;
	_actionItem = NULL;
	CORO_INVOKE_0(stop);

	CORO_END_CODE;
}
コード例 #16
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
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;
}
コード例 #17
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
void RMTextItemName::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	// If there is no text, it's pointless to continue
	if (_buf == NULL)
		return;

	// Set the destination coordinates of the mouse
	prim->getDst().topLeft() = _mpos - RMPoint(0, 30);

	CORO_INVOKE_2(RMText::draw, bigBuf, prim);

	CORO_END_CODE;
}
コード例 #18
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
void RMTextDialogScrolling::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
	CORO_BEGIN_CONTEXT;
	RMPoint curDst;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	_ctx->curDst = _dst;

	if (_curLoc != NULL)
		_dst -= _curLoc->scrollPosition() - _startScroll;

	CORO_INVOKE_2(RMTextDialog::draw, bigBuf, prim);

	_dst = _ctx->curDst;

	CORO_END_CODE;
}
コード例 #19
0
void exitAllIdles(CORO_PARAM, const void *param) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	int nCurLoc = *(const int *)param;

	CORO_BEGIN_CODE(_ctx);

	// Closes idle
	GLOBALS._bSkipSfxNoLoop = true;

	CORO_INVOKE_2(mpalEndIdlePoll, nCurLoc, NULL);

	GLOBALS._bIdleExited = true;
	GLOBALS._bSkipSfxNoLoop = false;

	CORO_END_CODE;
}
コード例 #20
0
ファイル: debugger.cpp プロジェクト: AReim1982/scummvm
void DebugChangeScene(CORO_PARAM, const void *param) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	uint32 result;
	const ChangeSceneDetails *details = (const ChangeSceneDetails *)param;
	RMPoint scenePos(details->x, details->y);

	CORO_BEGIN_CODE(_ctx);

	CORO_INVOKE_2(g_vm->getEngine()->unloadLocation, false, &result);

	g_vm->getEngine()->loadLocation(details->sceneNumber, scenePos, RMPoint(-1, -1));

	mainEnableGUI();

	CORO_END_CODE;
}
コード例 #21
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
void RMTextDialog::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
	CORO_BEGIN_CONTEXT;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	if (_startTime == 0)
		_startTime = g_vm->getTime();

	if (_bShowed) {
		if (GLOBALS._bShowSubtitles || _bAlwaysDisplay) {
			prim->getDst().topLeft() = _dst;
			CORO_INVOKE_2(RMText::draw, bigBuf, prim);
		}
	}

	CORO_END_CODE;
}
コード例 #22
0
/**
 * Run a scene process with the given event.
 */
void SceneProcessEvent(CORO_PARAM, uint32 procID, TINSEL_EVENT event, bool bWait, int myEscape,
						bool *result) {
	uint32 i;		// Loop counter
	if (result) *result = false;

	CORO_BEGIN_CONTEXT;
		PROCESS_STRUC *pStruc;
		PPROCESS pProc;
		PINT_CONTEXT pic;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	_ctx->pStruc = (PROCESS_STRUC *)LockMem(hSceneProcess);
	for (i = 0; i < numSceneProcess; i++) {
		if (FROM_LE_32(_ctx->pStruc[i].processId) == procID) {
			assert(_ctx->pStruc[i].hProcessCode);		// Must have some code to run

			_ctx->pic = InitInterpretContext(GS_PROCESS,
				FROM_LE_32(_ctx->pStruc[i].hProcessCode),
				event,
				NOPOLY,			// No polygon
				0,			// No actor
				NULL,			// No object
				myEscape);
			if (_ctx->pic == NULL)
				return;

			_ctx->pProc = g_scheduler->createProcess(PID_PROCESS + i, ProcessTinselProcess,
				&_ctx->pic, sizeof(_ctx->pic));
			AttachInterpret(_ctx->pic, _ctx->pProc);
			break;
		}
	}

	if (i == numSceneProcess)
		return;

	if (bWait) {
		CORO_INVOKE_2(WaitInterpret, _ctx->pProc, result);
	}

	CORO_END_CODE;
}
コード例 #23
0
ファイル: font.cpp プロジェクト: AlbanBedel/scummvm
void RMDialogChoice::show(CORO_PARAM, RMGfxTargetBuffer *bigBuf) {
	CORO_BEGIN_CONTEXT;
	RMPoint destpt;
	int deltay;
	int starttime;
	int elaps;
	CORO_END_CONTEXT(_ctx);

	CORO_BEGIN_CODE(_ctx);

	CORO_INVOKE_0(prepare);
	_bShow = false;

	if (!_nInList && bigBuf != NULL)
		bigBuf->addPrim(new RMGfxPrimitive(this));

	if (0) {
		_bShow = true;
	} else {
		_ctx->starttime = g_vm->getTime();
		_ctx->deltay = 480 - _ptDrawPos._y;
		_ctx->destpt = _ptDrawPos;
		_ptDrawPos.set(0, 480);

		if (!_nInList && bigBuf != NULL)
			bigBuf->addPrim(new RMGfxPrimitive(this));
		_bShow = true;

		_ctx->elaps = 0;
		while (_ctx->elaps < 700) {
			CORO_INVOKE_2(CoroScheduler.waitForSingleObject, g_vm->_hEndOfFrame, CORO_INFINITE);
			_ctx->elaps = g_vm->getTime() - _ctx->starttime;
			_ptDrawPos._y = 480 - ((_ctx->deltay * 100) / 700 * _ctx->elaps) / 100;
		}

		_ptDrawPos._y = _ctx->destpt._y;
	}

	CORO_END_CODE;
}
コード例 #24
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;
}
コード例 #25
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;
}