/** * 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; }
/** * Please Save Scene */ void TinselSaveScene(CORO_PARAM) { // only called by save_scene PCODE CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); assert(savedSceneCount < MAX_NEST); // nesting limit reached // Don't save the same thing multiple times! // FIXME/TODO: Maybe this can be changed to an assert? if (savedSceneCount && ssData[savedSceneCount-1].SavedSceneHandle == GetSceneHandle()) CORO_KILL_SELF(); DoSaveScene(&ssData[savedSceneCount++]); CORO_END_CODE; }
/** * Decide when to scroll and scroll when decided to. */ void ScrollProcess(CORO_PARAM, const void *) { // COROUTINE CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); // In Tinsel v2, scenes may play movies, so the background may not always // already be initialized like it is in v1 while (!GetBgObject()) CORO_SLEEP(1); g_ImageH = BgHeight(); // Dimensions g_ImageW = BgWidth(); // of this scene. // Give up if there'll be no purpose in this process if (g_ImageW == SCREEN_WIDTH && g_ImageH == SCREEN_HEIGHT) CORO_KILL_SELF(); if (!TinselV2) { g_LeftScroll = g_DownScroll = 0; // No iterations outstanding g_oldx = g_oldy = 0; g_scrollPixelsX = g_scrollPixelsY = SCROLLPIXELS; } if (!g_scrollActor) g_scrollActor = GetLeadId(); g_pScrollMover = GetMover(g_scrollActor); while (1) { MonitorScroll(); // Set scroll requirement if (g_LeftScroll || g_DownScroll) // Scroll if required ScrollImage(); CORO_SLEEP(1); // allow re-scheduling } CORO_END_CODE; }
/** * Handles launching a single click action result if the timeout for a double-click * expires */ static void SingleLeftProcess(CORO_PARAM, const void *) { CORO_BEGIN_CONTEXT; uint32 endTicks; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); // Work out when to wait until _ctx->endTicks = DwGetCurrentTime() + (uint32)dclickSpeed; // Timeout a double click (may not work once every 49 days!) do { CORO_SLEEP(1); } while (DwGetCurrentTime() < _ctx->endTicks); if (GetProvNotProcessed()) PlayerEvent(PLR_WALKTO, clickPos); CORO_KILL_SELF(); CORO_END_CODE; }
/** * If this is a single click, wait to check it's not the first half of a * double click. * If this is a double click, the process from the waiting single click * gets killed. */ void AllowDclick(CORO_PARAM, PLR_EVENT be) { CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); if (be == PLR_SLEFT) { GetToken(TOKEN_LEFT_BUT); CORO_SLEEP(_vm->_config->_dclickSpeed+1); FreeToken(TOKEN_LEFT_BUT); // Prevent activation of 2 events on the same tick if (++g_eCount != 1) CORO_KILL_SELF(); break; } else if (be == PLR_DLEFT) { GetToken(TOKEN_LEFT_BUT); FreeToken(TOKEN_LEFT_BUT); } CORO_END_CODE; }
/** * 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; }