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 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 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; }
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::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; }
/** * 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; }
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 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; }
/** * 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; }
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; }
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 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; }
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 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 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; }
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; }
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; }
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; }
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; }
/** * 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; }
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; }
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; }
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; }