void RMTony::endStatic(CORO_PARAM, CharacterTalkType nTalk) { CORO_BEGIN_CONTEXT; int bodyEndPat; int finalPat; int headEndPat; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); _ctx->bodyEndPat = 0; _ctx->finalPat = 0; _ctx->headEndPat = 0; endStaticCalculate(nTalk, _ctx->bodyEndPat, _ctx->finalPat, _ctx->headEndPat); if (_ctx->headEndPat != 0) { setPattern(_ctx->headEndPat); CORO_INVOKE_0(waitForEndPattern); } else { // Play please _body.setPattern(_ctx->bodyEndPat); CORO_INVOKE_0(_body.waitForEndPattern); } setPattern(_ctx->finalPat); _body.setPattern(0); _bIsStaticTalk = false; CORO_END_CODE; }
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; }
void RMTony::startStatic(CORO_PARAM, CharacterTalkType nTalk) { CORO_BEGIN_CONTEXT; int headPat, headLoopPat; int bodyStartPat, bodyLoopPat; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); _ctx->headPat = _ctx->headLoopPat = 0; _ctx->bodyStartPat = _ctx->bodyLoopPat = 0; startStaticCalculate(nTalk, _ctx->headPat, _ctx->headLoopPat, _ctx->bodyStartPat, _ctx->bodyLoopPat); // e vai con i pattern _bIsStaticTalk = true; setPattern(_ctx->headPat); _body.setPattern(_ctx->bodyStartPat); CORO_INVOKE_0(_body.waitForEndPattern); CORO_INVOKE_0(waitForEndPattern); if (_ctx->headLoopPat != -1) setPattern(_ctx->headLoopPat); _body.setPattern(_ctx->bodyLoopPat); CORO_END_CODE; }
/** * 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; }
/** * 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; }
/** * Moving actor process - 1 per moving actor in current scene. */ void T1MoverProcess(CORO_PARAM, const void *param) { // COROUTINE CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); const PMOVER pActor = *(const PMOVER *)param; CORO_BEGIN_CODE(_ctx); while (1) { if (pActor->bSpecReel) { if (!pActor->bHidden) #ifdef DEBUG assert(StepAnimScript(&pActor->actorAnim) != ScriptFinished); // Actor reel has finished! #else StepAnimScript(&pActor->actorAnim); #endif } else DoMoveActor(pActor); CORO_SLEEP(1); // allow rescheduling } 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; }
/** * 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; }
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; }
void TonyEngine::doNextMusic(CORO_PARAM, const void *param) { CORO_BEGIN_CONTEXT; Common::String fn; CORO_END_CONTEXT(_ctx); FPStream **streams = g_vm->_stream; CORO_BEGIN_CODE(_ctx); if (!g_vm->getIsDemo()) { if (!streams[GLOBALS._nextChannel]->loadFile(GLOBALS._nextMusic, GLOBALS._nextSync)) error("failed to open next music file '%s'", GLOBALS._nextMusic.c_str()); } else { streams[GLOBALS._nextChannel]->loadFile(GLOBALS._nextMusic, GLOBALS._nextSync); } streams[GLOBALS._nextChannel]->setLoop(GLOBALS._nextLoop); //streams[GLOBALS._nextChannel]->prefetch(); streams[GLOBALS._curChannel]->waitForSync(streams[GLOBALS._nextChannel]); streams[GLOBALS._curChannel]->unloadFile(); GLOBALS._flipflop = 1 - GLOBALS._flipflop; CORO_END_CODE; }
void RMDialogChoice::prepare(CORO_PARAM) { CORO_BEGIN_CONTEXT; int i; RMPoint ptPos; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); addPrim(new RMGfxPrimitive(&_dlgText, RMPoint(0, 0))); addPrim(new RMGfxPrimitive(&_dlgTextLine, RMPoint(0, 155))); addPrim(new RMGfxPrimitive(&_dlgTextLine, RMPoint(0, 155 + 83))); addPrim(new RMGfxPrimitive(&_dlgTextLine, RMPoint(0, 155 + 83 + 83))); addPrim(new RMGfxPrimitive(&_dlgTextLine, RMPoint(0, 155 + 83 + 83 + 83))); _ctx->ptPos.set(20, 90); for (_ctx->i = 0; _ctx->i < _numChoices; _ctx->i++) { addPrim(new RMGfxPrimitive(&_drawedStrings[_ctx->i], _ctx->ptPos)); _ptDrawStrings[_ctx->i] = _ctx->ptPos; _ctx->ptPos.offset(0, _drawedStrings[_ctx->i].getDimy() + 15); } CORO_INVOKE_0(drawOT); clearOT(); _ptDrawPos.set(0, 480 - _ctx->ptPos._y); CORO_END_CODE; }
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; }
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; }
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; }
/** * Given the scene background film, extracts the palette handle for * everything else's use, then starts a display process for each reel * in the film. * @param hFilm Scene background film */ void StartupBackground(CORO_PARAM, SCNHANDLE hFilm) { CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); const FILM *pfilm; IMAGE *pim; hBackground = hFilm; // Save handle in case of Save_Scene() pim = GetImageFromFilm(hFilm, 0, NULL, NULL, &pfilm); SetBackPal(FROM_LE_32(pim->hImgPal)); // Extract the film speed BGspeed = ONE_SECOND / FROM_LE_32(pfilm->frate); // Start display process for each reel in the film g_scheduler->createProcess(PID_REEL, BGmainProcess, &pfilm->reels[0], sizeof(FREEL)); if (TinselV0) { for (uint i = 1; i < FROM_LE_32(pfilm->numreels); ++i) g_scheduler->createProcess(PID_REEL, BGotherProcess, &pfilm->reels[i], sizeof(FREEL)); } if (pBG[0] == NULL) ControlStartOff(); if (TinselV2 && (coroParam != nullContext)) CORO_GIVE_WAY; CORO_END_CODE; }
/** * Set actor hidden status to true. * For a moving actor, actually hide it. * @param ano Actor Id */ void HideActor(CORO_PARAM, int ano) { PMOVER pMover; assert((ano > 0 && ano <= NumActors) || ano == LEAD_ACTOR); // illegal actor CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); if (TinselV2) { actorInfo[ano - 1].bHidden = true; // Send event to tagged actors // (this is duplicated in HideMover()) if (IsTaggedActor(ano)) { CORO_INVOKE_ARGS(ActorEvent, (CORO_SUBCTX, ano, HIDEEVENT, true, 0)); // It may be pointed to SetActorPointedTo(ano, false); SetActorTagWanted(ano, false, false, 0); } } // Get moving actor involved pMover = GetMover(ano); if (pMover) HideMover(pMover, 0); else if (!TinselV2) actorInfo[ano - 1].bHidden = true; CORO_END_CODE; }
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::startTalk(CORO_PARAM, CharacterTalkType nTalkType) { CORO_BEGIN_CONTEXT; int headStartPat, bodyStartPat; int headLoopPat, bodyLoopPat; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); _ctx->headStartPat = _ctx->bodyStartPat = 0; _ctx->headLoopPat = _ctx->bodyLoopPat = 0; if (!startTalkCalculate(nTalkType, _ctx->headStartPat, _ctx->bodyStartPat, _ctx->headLoopPat, _ctx->bodyLoopPat)) return; // Perform the set pattern if (_ctx->headStartPat != 0 || _ctx->bodyStartPat != 0) { setPattern(_ctx->headStartPat); _body.setPattern(_ctx->bodyStartPat); if (_ctx->bodyStartPat != 0) CORO_INVOKE_0(_body.waitForEndPattern); if (_ctx->headStartPat != 0) CORO_INVOKE_0(waitForEndPattern); } setPattern(_ctx->headLoopPat); if (_ctx->bodyLoopPat) _body.setPattern(_ctx->bodyLoopPat); CORO_END_CODE; }
/** * 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; }
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; }
/** * WaitInterpret */ void WaitInterpret(CORO_PARAM, PPROCESS pWaitProc, bool *result) { int i; PPROCESS currentProcess = g_scheduler->getCurrentProcess(); assert(currentProcess); assert(currentProcess != pWaitProc); if (result) *result = false; /* * Calling process is the waiter, find its interpret context. */ CORO_BEGIN_CONTEXT; PINT_CONTEXT picWaiter, picWaitee; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); for (i = 0, _ctx->picWaiter = icList; i < NUM_INTERPRET; i++, _ctx->picWaiter++) { if (_ctx->picWaiter->GSort != GS_NONE && _ctx->picWaiter->pProc == currentProcess) { break; } } /* * Find the interpret context of the process we're waiting for */ for (i = 0, _ctx->picWaitee = icList; i < NUM_INTERPRET; i++, _ctx->picWaitee++) { if (_ctx->picWaitee->GSort != GS_NONE && _ctx->picWaitee->pProc == pWaitProc) { break; } } /* * Set the first as waiting for the second */ assert(_ctx->picWaitee->waitNumber2 == 0); _ctx->picWaiter->waitNumber1 = _ctx->picWaitee->waitNumber2 = UniqueWaitNumber(); _ctx->picWaiter->resumeCode = RES_WAITING; /* * Wait for it */ CORO_GIVE_WAY; while (_ctx->picWaiter->resumeCode == RES_WAITING) { CORO_SLEEP(1); } if (result) *result = (_ctx->picWaiter->resumeCode == RES_FINISHED); CORO_END_CODE; }
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; }
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; }
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; }
/** * 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; }
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; }
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; }
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; }
/** * 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; }
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; }