/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * Run a global process with the given event. */ bool GlobalProcessEvent(CORO_PARAM, uint32 procID, TINSEL_EVENT event, bool bWait, int myEscape) { CORO_BEGIN_CONTEXT; PINT_CONTEXT pic; PPROCESS pProc; CORO_END_CONTEXT(_ctx); bool result = false; CORO_BEGIN_CODE(_ctx); uint32 i; // Loop counter _ctx->pProc = NULL; for (i = 0; i < numGlobalProcess; ++i) { if (pGlobalProcess[i].processId == procID) { assert(pGlobalProcess[i].hProcessCode); // Must have some code to run _ctx->pic = InitInterpretContext(GS_GPROCESS, pGlobalProcess[i].hProcessCode, event, NOPOLY, // No polygon 0, // No actor NULL, // No object myEscape); if (_ctx->pic != NULL) { _ctx->pProc = g_scheduler->createProcess(PID_GPROCESS + i, ProcessTinselProcess, &_ctx->pic, sizeof(_ctx->pic)); AttachInterpret(_ctx->pic, _ctx->pProc); } break; } } if ((i == numGlobalProcess) || (_ctx->pic == NULL)) result = false; else if (bWait) CORO_INVOKE_ARGS_V(WaitInterpret, false, (CORO_SUBCTX, _ctx->pProc, &result)); CORO_END_CODE; return result; }
/** * 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; }