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; }
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; }
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; } } }
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; }
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; }