aboutsummaryrefslogtreecommitdiff
path: root/engines/tony
diff options
context:
space:
mode:
authorPaul Gilbert2012-05-08 08:25:33 +1000
committerPaul Gilbert2012-05-08 08:25:33 +1000
commit8527302057052e784c3ea32ca8eebb0220bf15e6 (patch)
tree6de91ecaacd51a1182bd44f21c94edfac4daa4b1 /engines/tony
parent0b8974ec4ab37ef056ac50c098d3fe8045ec172b (diff)
downloadscummvm-rg350-8527302057052e784c3ea32ca8eebb0220bf15e6.tar.gz
scummvm-rg350-8527302057052e784c3ea32ca8eebb0220bf15e6.tar.bz2
scummvm-rg350-8527302057052e784c3ea32ca8eebb0220bf15e6.zip
TONY: Added support for threading events to scheduler, converted more procs to coroutines
Diffstat (limited to 'engines/tony')
-rw-r--r--engines/tony/custom.cpp610
-rw-r--r--engines/tony/loc.cpp31
-rw-r--r--engines/tony/loc.h5
-rw-r--r--engines/tony/mpal/mpal.cpp27
-rw-r--r--engines/tony/mpal/stubs.cpp4
-rw-r--r--engines/tony/sched.cpp182
-rw-r--r--engines/tony/sched.h25
-rw-r--r--engines/tony/tonychar.cpp194
-rw-r--r--engines/tony/tonychar.h18
9 files changed, 771 insertions, 325 deletions
diff --git a/engines/tony/custom.cpp b/engines/tony/custom.cpp
index e7878c5a5d..800b5d8d50 100644
--- a/engines/tony/custom.cpp
+++ b/engines/tony/custom.cpp
@@ -370,50 +370,62 @@ VoiceHeader *SearchVoiceHeader(uint32 codehi, uint32 codelo) {
DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX, uint32 nY, uint32) {
- RMMessage msg(dwMessage);
- int i;
- int curOffset = 0;
+ CORO_BEGIN_CONTEXT;
+ RMMessage *msg;
+ int i;
+ int curOffset;
+ VoiceHeader *curVoc;
+ FPSFX *voice;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->curOffset = 0;
if (bSkipIdle) return;
- if (!msg.IsValid())
+ _ctx->msg = new RMMessage(dwMessage);
+ if (!_ctx->msg->IsValid()) {
+ delete _ctx->msg;
return;
+ }
- VoiceHeader *curVoc = SearchVoiceHeader(0, dwMessage);
- FPSFX *voice = NULL;
- if (curVoc) {
+ _ctx->curVoc = SearchVoiceHeader(0, dwMessage);
+ _ctx->voice = NULL;
+ if (_ctx->curVoc) {
// Si posiziona all'interno del database delle voci all'inizio della prima
- curOffset = curVoc->offset;
+ _ctx->curOffset = _ctx->curVoc->offset;
// PRIMA VOLTA PREALLOCA
g_system->lockMutex(vdb);
- //fseek(_vm->m_vdbFP, curOffset, SEEK_SET);
- _vm->_vdbFP.seek(curOffset);
- _vm->_theSound.CreateSfx(&voice);
- voice->LoadVoiceFromVDB(_vm->_vdbFP);
-// curOffset = ftell(_vm->m_vdbFP);
- curOffset = _vm->_vdbFP.pos();
-
- voice->SetLoop(false);
+ //fseek(_vm->m_vdbFP, _ctx->curOffset, SEEK_SET);
+ _vm->_vdbFP.seek(_ctx->curOffset);
+ _vm->_theSound.CreateSfx(&_ctx->voice);
+ _ctx->voice->LoadVoiceFromVDB(_vm->_vdbFP);
+// _ctx->curOffset = ftell(_vm->m_vdbFP);
+ _ctx->curOffset = _vm->_vdbFP.pos();
+
+ _ctx->voice->SetLoop(false);
g_system->unlockMutex(vdb);
}
if (nTonyNextTalkType != Tony->TALK_NORMAL) {
- Tony->StartTalk(nTonyNextTalkType);
+ CORO_INVOKE_1(Tony->StartTalk, nTonyNextTalkType);
+
if (!bStaticTalk)
nTonyNextTalkType = Tony->TALK_NORMAL;
} else {
- if (msg.NumPeriods() > 1)
- Tony->StartTalk(Tony->TALK_FIANCHI);
+ if (_ctx->msg->NumPeriods() > 1)
+ CORO_INVOKE_1(Tony->StartTalk, Tony->TALK_FIANCHI);
else
- Tony->StartTalk(Tony->TALK_NORMAL);
+ CORO_INVOKE_1(Tony->StartTalk, Tony->TALK_NORMAL);
}
if (curBackText)
curBackText->Hide();
bTonyIsSpeaking = true;
- for (i = 0; i < msg.NumPeriods() && !bSkipIdle; i++) {
+ for (_ctx->i = 0; _ctx->i < _ctx->msg->NumPeriods() && !bSkipIdle; _ctx->i++) {
RMTextDialog text;
text.SetInput(Input);
@@ -425,7 +437,7 @@ DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX
text.SetColor(0,255,0);
// Scrive il testo
- text.WriteText(msg[i],0);
+ text.WriteText((*_ctx->msg)[_ctx->i],0);
// Setta la posizione
if (nX == 0 && nY == 0)
@@ -439,21 +451,21 @@ DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX
// Registra il testo
LinkGraphicTask(&text);
- if (curVoc) {
- if (i == 0) {
- voice->Play();
- text.SetCustomSkipHandle2(voice->hEndOfBuffer);
+ if (_ctx->curVoc) {
+ if (_ctx->i == 0) {
+ _ctx->voice->Play();
+ text.SetCustomSkipHandle2(_ctx->voice->hEndOfBuffer);
} else {
g_system->lockMutex(vdb);
- // fseek(_vm->m_vdbFP, curOffset, SEEK_SET);
- _vm->_vdbFP.seek(curOffset);
- _vm->_theSound.CreateSfx(&voice);
- voice->LoadVoiceFromVDB(_vm->_vdbFP);
- // curOffset = ftell(_vm->m_vdbFP);
- curOffset = _vm->_vdbFP.pos();
- voice->SetLoop(false);
- voice->Play();
- text.SetCustomSkipHandle2(voice->hEndOfBuffer);
+ // fseek(_vm->m_vdbFP, _ctx->curOffset, SEEK_SET);
+ _vm->_vdbFP.seek(_ctx->curOffset);
+ _vm->_theSound.CreateSfx(&_ctx->voice);
+ _ctx->voice->LoadVoiceFromVDB(_vm->_vdbFP);
+ // _ctx->curOffset = ftell(_vm->m_vdbFP);
+ _ctx->curOffset = _vm->_vdbFP.pos();
+ _ctx->voice->SetLoop(false);
+ _ctx->voice->Play();
+ text.SetCustomSkipHandle2(_ctx->voice->hEndOfBuffer);
g_system->unlockMutex(vdb);
}
}
@@ -462,10 +474,10 @@ DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX
text.SetCustomSkipHandle(hSkipIdle);
text.WaitForEndDisplay();
- if (curVoc) {
- voice->Stop();
- voice->Release();
- voice=NULL;
+ if (_ctx->curVoc) {
+ _ctx->voice->Stop();
+ _ctx->voice->Release();
+ _ctx->voice=NULL;
}
}
@@ -473,7 +485,10 @@ DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX
if (curBackText)
curBackText->Show();
- Tony->EndTalk();
+ CORO_INVOKE_0(Tony->EndTalk);
+ delete _ctx->msg;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(ChangeBoxStatus)(CORO_PARAM, uint32 nLoc, uint32 nBox, uint32 nStatus, uint32) {
@@ -718,134 +733,164 @@ DECLARE_CUSTOM_FUNCTION(CustEnableGUI)(CORO_PARAM, uint32, uint32, uint32, uint3
EnableGUI();
}
-DECLARE_CUSTOM_FUNCTION(CustDisableGUI)(CORO_PARAM, uint32, uint32, uint32, uint32)
-{
- DisableGUI();
+DECLARE_CUSTOM_FUNCTION(CustDisableGUI)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ DisableGUI();
}
-void TonyGenericTake1(uint32 nDirection) {
+
+void TonyGenericTake1(CORO_PARAM, uint32 nDirection) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
Freeze();
- Tony->Take(nDirection,0);
+ Tony->Take(nDirection, 0);
Unfreeze();
if (!bSkipIdle)
- Tony->WaitForEndPattern();
+ CORO_INVOKE_0(Tony->WaitForEndPattern);
+
+ CORO_END_CODE;
}
-void TonyGenericTake2(uint32 nDirection) {
+void TonyGenericTake2(CORO_PARAM, uint32 nDirection) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
Freeze();
- Tony->Take(nDirection,1);
+ Tony->Take(nDirection, 1);
Unfreeze();
if (!bSkipIdle)
- Tony->WaitForEndPattern();
+ CORO_INVOKE_0(Tony->WaitForEndPattern);
Freeze();
Tony->Take(nDirection,2);
Unfreeze();
+
+ CORO_END_CODE;
}
-void TonyGenericPut1(uint32 nDirection) {
+void TonyGenericPut1(CORO_PARAM, uint32 nDirection) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
Freeze();
- Tony->Put(nDirection,0);
+ Tony->Put(nDirection, 0);
Unfreeze();
if (!bSkipIdle)
- Tony->WaitForEndPattern();
+ CORO_INVOKE_0(Tony->WaitForEndPattern);
+
+ CORO_END_CODE;
}
-void TonyGenericPut2(uint32 nDirection) {
+void TonyGenericPut2(CORO_PARAM, uint32 nDirection) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
Freeze();
Tony->Put(nDirection,1);
Unfreeze();
if (!bSkipIdle)
- Tony->WaitForEndPattern();
+ CORO_INVOKE_0(Tony->WaitForEndPattern);
Freeze();
Tony->Put(nDirection,2);
Unfreeze();
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyTakeUp1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericTake1(0);
+ TonyGenericTake1(coroParam, 0);
}
DECLARE_CUSTOM_FUNCTION(TonyTakeMid1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericTake1(1);
+ TonyGenericTake1(coroParam, 1);
}
DECLARE_CUSTOM_FUNCTION(TonyTakeDown1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericTake1(2);
+ TonyGenericTake1(coroParam, 2);
}
DECLARE_CUSTOM_FUNCTION(TonyTakeUp2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericTake2(0);
+ TonyGenericTake2(coroParam, 0);
}
DECLARE_CUSTOM_FUNCTION(TonyTakeMid2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericTake2(1);
+ TonyGenericTake2(coroParam, 1);
}
DECLARE_CUSTOM_FUNCTION(TonyTakeDown2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericTake2(2);
+ TonyGenericTake2(coroParam, 2);
}
-
-
-
-
DECLARE_CUSTOM_FUNCTION(TonyPutUp1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericPut1(0);
+ TonyGenericPut1(coroParam, 0);
}
DECLARE_CUSTOM_FUNCTION(TonyPutMid1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericPut1(1);
+ TonyGenericPut1(coroParam, 1);
}
DECLARE_CUSTOM_FUNCTION(TonyPutDown1)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericPut1(2);
+ TonyGenericPut1(coroParam, 2);
}
DECLARE_CUSTOM_FUNCTION(TonyPutUp2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericPut2(0);
+ TonyGenericPut2(coroParam, 0);
}
DECLARE_CUSTOM_FUNCTION(TonyPutMid2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericPut2(1);
+ TonyGenericPut2(coroParam, 1);
}
DECLARE_CUSTOM_FUNCTION(TonyPutDown2)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- TonyGenericPut2(2);
+ TonyGenericPut2(coroParam, 2);
}
-
DECLARE_CUSTOM_FUNCTION(TonyPerTerra)(CORO_PARAM, uint32 dwParte, uint32, uint32, uint32) {
- if (dwParte== 0)
+ if (dwParte == 0)
Tony->SetPattern(Tony->PAT_PERTERRALEFT);
else
Tony->SetPattern(Tony->PAT_PERTERRARIGHT);
}
DECLARE_CUSTOM_FUNCTION(TonySiRialza)(CORO_PARAM, uint32 dwParte, uint32, uint32, uint32) {
- if (dwParte== 0)
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ if (dwParte == 0)
Tony->SetPattern(Tony->PAT_SIRIALZALEFT);
else
Tony->SetPattern(Tony->PAT_SIRIALZARIGHT);
if (!bSkipIdle)
- Tony->WaitForEndPattern();
+ CORO_INVOKE_0(Tony->WaitForEndPattern);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyPastorella)(CORO_PARAM, uint32 bIsPast, uint32, uint32, uint32) {
@@ -853,10 +898,18 @@ DECLARE_CUSTOM_FUNCTION(TonyPastorella)(CORO_PARAM, uint32 bIsPast, uint32, uint
}
DECLARE_CUSTOM_FUNCTION(TonyFischietto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
Tony->SetPattern(Tony->PAT_FISCHIETTORIGHT);
if (!bSkipIdle)
- Tony->WaitForEndPattern();
+ CORO_INVOKE_0(Tony->WaitForEndPattern);
+
Tony->SetPattern(Tony->PAT_STANDRIGHT);
+
+ CORO_END_CODE;
}
@@ -951,101 +1004,212 @@ DECLARE_CUSTOM_FUNCTION(TonyConPupazzoANIM)(CORO_PARAM, uint32 dwText, uint32, u
}
DECLARE_CUSTOM_FUNCTION(TonyConPupazzoStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
nTonyNextTalkType = Tony->TALK_CONPUPAZZOSTATIC;
bStaticTalk = true;
- Tony->StartStatic(Tony->TALK_CONPUPAZZOSTATIC);
+ CORO_INVOKE_1(Tony->StartStatic, Tony->TALK_CONPUPAZZOSTATIC);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConPupazzoEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- Tony->EndStatic(Tony->TALK_CONPUPAZZOSTATIC);
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_1(Tony->EndStatic, Tony->TALK_CONPUPAZZOSTATIC);
bStaticTalk = false;
nTonyNextTalkType = Tony->TALK_NORMAL;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConConiglioStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
nTonyNextTalkType = Tony->TALK_CONCONIGLIOSTATIC;
bStaticTalk = true;
- Tony->StartStatic(Tony->TALK_CONCONIGLIOSTATIC);
+ CORO_INVOKE_1(Tony->StartStatic, Tony->TALK_CONCONIGLIOSTATIC);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConConiglioEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- Tony->EndStatic(Tony->TALK_CONCONIGLIOSTATIC);
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_1(Tony->EndStatic, Tony->TALK_CONCONIGLIOSTATIC);
bStaticTalk = false;
nTonyNextTalkType = Tony->TALK_NORMAL;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConRicettaStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
nTonyNextTalkType = Tony->TALK_CONRICETTASTATIC;
bStaticTalk = true;
- Tony->StartStatic(Tony->TALK_CONRICETTASTATIC);
+ CORO_INVOKE_1(Tony->StartStatic, Tony->TALK_CONRICETTASTATIC);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConRicettaEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- Tony->EndStatic(Tony->TALK_CONRICETTASTATIC);
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_1(Tony->EndStatic, Tony->TALK_CONRICETTASTATIC);
bStaticTalk = false;
nTonyNextTalkType = Tony->TALK_NORMAL;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConCarteStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
nTonyNextTalkType = Tony->TALK_CONCARTESTATIC;
bStaticTalk = true;
- Tony->StartStatic(Tony->TALK_CONCARTESTATIC);
+ CORO_INVOKE_1(Tony->StartStatic, Tony->TALK_CONCARTESTATIC);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConCarteEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- Tony->EndStatic(Tony->TALK_CONCARTESTATIC);
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_1(Tony->EndStatic, Tony->TALK_CONCARTESTATIC);
bStaticTalk = false;
nTonyNextTalkType = Tony->TALK_NORMAL;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConTaccuinoStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
nTonyNextTalkType = Tony->TALK_CONTACCUINOSTATIC;
bStaticTalk = true;
- Tony->StartStatic(Tony->TALK_CONTACCUINOSTATIC);
+ CORO_INVOKE_1(Tony->StartStatic, Tony->TALK_CONTACCUINOSTATIC);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConTaccuinoEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- Tony->EndStatic(Tony->TALK_CONTACCUINOSTATIC);
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_1(Tony->EndStatic, Tony->TALK_CONTACCUINOSTATIC);
bStaticTalk = false;
nTonyNextTalkType = Tony->TALK_NORMAL;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConMegafonoStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
nTonyNextTalkType = Tony->TALK_CONMEGAFONOSTATIC;
bStaticTalk = true;
- Tony->StartStatic(Tony->TALK_CONMEGAFONOSTATIC);
+ CORO_INVOKE_1(Tony->StartStatic, Tony->TALK_CONMEGAFONOSTATIC);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConMegafonoEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- Tony->EndStatic(Tony->TALK_CONMEGAFONOSTATIC);
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_1(Tony->EndStatic, Tony->TALK_CONMEGAFONOSTATIC);
bStaticTalk = false;
nTonyNextTalkType = Tony->TALK_NORMAL;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConBarbaStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
nTonyNextTalkType = Tony->TALK_CONBARBASTATIC;
bStaticTalk = true;
- Tony->StartStatic(Tony->TALK_CONBARBASTATIC);
+ CORO_INVOKE_1(Tony->StartStatic, Tony->TALK_CONBARBASTATIC);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonyConBarbaEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- Tony->EndStatic(Tony->TALK_CONBARBASTATIC);
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_1(Tony->EndStatic, Tony->TALK_CONBARBASTATIC);
bStaticTalk = false;
nTonyNextTalkType = Tony->TALK_NORMAL;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonySpaventatoStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
nTonyNextTalkType = Tony->TALK_SPAVENTATOSTATIC;
bStaticTalk = true;
- Tony->StartStatic(Tony->TALK_SPAVENTATOSTATIC);
+ CORO_INVOKE_1(Tony->StartStatic, Tony->TALK_SPAVENTATOSTATIC);
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(TonySpaventatoEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
- Tony->EndStatic(Tony->TALK_SPAVENTATOSTATIC);
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_1(Tony->EndStatic, Tony->TALK_SPAVENTATOSTATIC);
bStaticTalk = false;
nTonyNextTalkType = Tony->TALK_NORMAL;
-}
+ CORO_END_CODE;
+}
DECLARE_CUSTOM_FUNCTION(TonySchifato)(CORO_PARAM, uint32 dwText, uint32, uint32, uint32) {
@@ -1060,7 +1224,7 @@ DECLARE_CUSTOM_FUNCTION(TonySniffaLeft)(CORO_PARAM, uint32, uint32, uint32, uint
CORO_BEGIN_CODE(_ctx);
Tony->SetPattern(Tony->PAT_SNIFFA_LEFT);
- Tony->WaitForEndPattern();
+ CORO_INVOKE_0(Tony->WaitForEndPattern);
CORO_INVOKE_4(LeftToMe, 0, 0, 0, 0);
CORO_END_CODE;
@@ -1073,7 +1237,7 @@ DECLARE_CUSTOM_FUNCTION(TonySniffaRight)(CORO_PARAM, uint32, uint32, uint32, uin
CORO_BEGIN_CODE(_ctx);
Tony->SetPattern(Tony->PAT_SNIFFA_RIGHT);
- Tony->WaitForEndPattern();
+ CORO_INVOKE_0(Tony->WaitForEndPattern);
CORO_INVOKE_4(RightToMe, 0, 0, 0, 0);
CORO_END_CODE;
@@ -1126,10 +1290,18 @@ DECLARE_CUSTOM_FUNCTION(DisableTony)(CORO_PARAM, uint32 bShowOmbra, uint32, uint
}
DECLARE_CUSTOM_FUNCTION(WaitForPatternEnd)(CORO_PARAM, uint32 nItem, uint32, uint32, uint32) {
- RMItem *item = Loc->GetItemFromCode(nItem);
+ CORO_BEGIN_CONTEXT;
+ RMItem *item;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->item = Loc->GetItemFromCode(nItem);
- if (!bSkipIdle && item != NULL)
- item->WaitForEndPattern(hSkipIdle);
+ if (!bSkipIdle && _ctx->item != NULL)
+ CORO_INVOKE_1(_ctx->item->WaitForEndPattern, hSkipIdle);
+
+ CORO_END_CODE;
}
@@ -1383,106 +1555,119 @@ DECLARE_CUSTOM_FUNCTION(CharSetStartEndTalkPattern)(CORO_PARAM, uint32 nChar, ui
}
DECLARE_CUSTOM_FUNCTION(CharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMessage, uint32 bIsBack, uint32) {
- RMMessage msg(dwMessage);
- int i;
- RMPoint pt;
- RMTextDialog *text;
- int curOffset = 0;
+ CORO_BEGIN_CONTEXT;
+ RMMessage *msg;
+ int i;
+ RMPoint pt;
+ RMTextDialog *text;
+ int curOffset;
+ VoiceHeader *curVoc;
+ FPSFX *voice;
+ CORO_END_CONTEXT(_ctx);
- assert(nChar<16);
- pt=Character[nChar].item->CalculatePos()-RMPoint(-60,20)-Loc->ScrollPosition();
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->msg = new RMMessage(dwMessage);
+ _ctx->curOffset = 0;
+
+ assert(nChar < 16);
+ _ctx->pt = Character[nChar].item->CalculatePos() - RMPoint(-60, 20) - Loc->ScrollPosition();
if (Character[nChar].starttalkpattern != 0) {
Freeze();
Character[nChar].item->SetPattern(Character[nChar].starttalkpattern);
Unfreeze();
- Character[nChar].item->WaitForEndPattern();
+
+ CORO_INVOKE_0(Character[nChar].item->WaitForEndPattern);
}
Freeze();
Character[nChar].item->SetPattern(Character[nChar].talkpattern);
Unfreeze();
- VoiceHeader *curVoc = SearchVoiceHeader(0, dwMessage);
- FPSFX *voice = NULL;
- if (curVoc) {
+ _ctx->curVoc = SearchVoiceHeader(0, dwMessage);
+ _ctx->voice = NULL;
+ if (_ctx->curVoc) {
// Si posiziona all'interno del database delle voci all'inizio della prima
-// fseek(_vm->m_vdbFP, curVoc->offset, SEEK_SET);
+// fseek(_vm->m_vdbFP, _ctx->curVoc->offset, SEEK_SET);
g_system->lockMutex(vdb);
- _vm->_vdbFP.seek(curVoc->offset);
- curOffset = curVoc->offset;
+ _vm->_vdbFP.seek(_ctx->curVoc->offset);
+ _ctx->curOffset = _ctx->curVoc->offset;
g_system->unlockMutex(vdb);
}
- for (i = 0; i<msg.NumPeriods() && !bSkipIdle; i++) {
+ for (_ctx->i = 0; _ctx->i<_ctx->msg->NumPeriods() && !bSkipIdle; _ctx->i++) {
if (bIsBack) {
- curBackText = text = new RMTextDialogScrolling(Loc);
+ curBackText = _ctx->text = new RMTextDialogScrolling(Loc);
if (bTonyIsSpeaking)
curBackText->Hide();
} else
- text = new RMTextDialog;
+ _ctx->text = new RMTextDialog;
- text->SetInput(Input);
+ _ctx->text->SetInput(Input);
// Skipping
- text->SetSkipStatus(!bIsBack);
+ _ctx->text->SetSkipStatus(!bIsBack);
// Allineamento
- text->SetAlignType(RMText::HCENTER,RMText::VBOTTOM);
+ _ctx->text->SetAlignType(RMText::HCENTER,RMText::VBOTTOM);
// Colore
- text->SetColor(Character[nChar].r,Character[nChar].g,Character[nChar].b);
+ _ctx->text->SetColor(Character[nChar].r,Character[nChar].g,Character[nChar].b);
// Scrive il testo
- text->WriteText(msg[i],0);
+ _ctx->text->WriteText((*_ctx->msg)[_ctx->i],0);
// Setta la posizione
- text->SetPosition(pt);
+ _ctx->text->SetPosition(_ctx->pt);
// Setta l'always display
- if (bAlwaysDisplay) { text->SetAlwaysDisplay(); text->ForceTime(); }
+ if (bAlwaysDisplay) { _ctx->text->SetAlwaysDisplay(); _ctx->text->ForceTime(); }
// Registra il testo
- LinkGraphicTask(text);
+ LinkGraphicTask(_ctx->text);
- if (curVoc) {
+ if (_ctx->curVoc) {
g_system->lockMutex(vdb);
- _vm->_theSound.CreateSfx(&voice);
- _vm->_vdbFP.seek(curOffset);
- voice->LoadVoiceFromVDB(_vm->_vdbFP);
- voice->SetLoop(false);
- if (bIsBack) voice->SetVolume(55);
- voice->Play();
- text->SetCustomSkipHandle2(voice->hEndOfBuffer);
- curOffset = _vm->_vdbFP.pos();
+ _vm->_theSound.CreateSfx(&_ctx->voice);
+ _vm->_vdbFP.seek(_ctx->curOffset);
+ _ctx->voice->LoadVoiceFromVDB(_vm->_vdbFP);
+ _ctx->voice->SetLoop(false);
+ if (bIsBack) _ctx->voice->SetVolume(55);
+ _ctx->voice->Play();
+ _ctx->text->SetCustomSkipHandle2(_ctx->voice->hEndOfBuffer);
+ _ctx->curOffset = _vm->_vdbFP.pos();
g_system->unlockMutex(vdb);
}
// Aspetta la fine della visualizzazione
- text->SetCustomSkipHandle(hSkipIdle);
- text->WaitForEndDisplay();
+ _ctx->text->SetCustomSkipHandle(hSkipIdle);
+ _ctx->text->WaitForEndDisplay();
- if (curVoc) {
- voice->Stop();
- voice->Release();
- voice=NULL;
+ if (_ctx->curVoc) {
+ _ctx->voice->Stop();
+ _ctx->voice->Release();
+ _ctx->voice=NULL;
}
curBackText=NULL;
- delete text;
+ delete _ctx->text;
}
if (Character[nChar].endtalkpattern != 0) {
Freeze();
Character[nChar].item->SetPattern(Character[nChar].endtalkpattern);
Unfreeze();
- Character[nChar].item->WaitForEndPattern();
+ CORO_INVOKE_0(Character[nChar].item->WaitForEndPattern);
}
Freeze();
Character[nChar].item->SetPattern(Character[nChar].standpattern);
Unfreeze();
+ delete _ctx->msg;
+
+ CORO_END_CODE;
}
DECLARE_CUSTOM_FUNCTION(AddInventory)(CORO_PARAM, uint32 dwCode, uint32, uint32, uint32) {
@@ -1698,97 +1883,104 @@ DECLARE_CUSTOM_FUNCTION(MCharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMes
int curDialog;
DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg, uint32, uint32) {
- LPSTR string;
- RMTextDialog *text;
- int parm;
- HANDLE h;
- bool bIsBack = false;
+ CORO_BEGIN_CONTEXT;
+ LPSTR string;
+ RMTextDialog *text;
+ int parm;
+ HANDLE h;
+ bool bIsBack;
+ VoiceHeader *curVoc;
+ FPSFX *voice;
+ RMPoint pt;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->bIsBack = false;
// La SendDialogMessage puņ andare in background se č un personaggio in MCHAR settato
// con la SetAlwaysBack
if (nPers != 0 && IsMChar[nPers] && MCharacter[nPers].bAlwaysBack)
- bIsBack = true;
+ _ctx->bIsBack = true;
- VoiceHeader *curVoc = SearchVoiceHeader(curDialog, nMsg);
- FPSFX *voice = NULL;
+ _ctx->curVoc = SearchVoiceHeader(curDialog, nMsg);
+ _ctx->voice = NULL;
- if (curVoc) {
+ if (_ctx->curVoc) {
// Si posiziona all'interno del database delle voci all'inizio della prima
g_system->lockMutex(vdb);
-// fseek(_vm->m_vdbFP, curVoc->offset, SEEK_SET);
- _vm->_vdbFP.seek(curVoc->offset);
- _vm->_theSound.CreateSfx(&voice);
- voice->LoadVoiceFromVDB(_vm->_vdbFP);
- voice->SetLoop(false);
- if (bIsBack) voice->SetVolume(55);
+// fseek(_vm->m_vdbFP, _ctx->curVoc->offset, SEEK_SET);
+ _vm->_vdbFP.seek(_ctx->curVoc->offset);
+ _vm->_theSound.CreateSfx(&_ctx->voice);
+ _ctx->voice->LoadVoiceFromVDB(_vm->_vdbFP);
+ _ctx->voice->SetLoop(false);
+ if (_ctx->bIsBack) _ctx->voice->SetVolume(55);
g_system->unlockMutex(vdb);
}
- string = mpalQueryDialogPeriod(nMsg);
+ _ctx->string = mpalQueryDialogPeriod(nMsg);
if (nPers == 0) {
- text = new RMTextDialog;
- text->SetColor(0,255,0);
- text->SetPosition(Tony->Position()-RMPoint(0,130)-Loc->ScrollPosition());
- text->WriteText(string,0);
+ _ctx->text = new RMTextDialog;
+ _ctx->text->SetColor(0,255,0);
+ _ctx->text->SetPosition(Tony->Position()-RMPoint(0,130)-Loc->ScrollPosition());
+ _ctx->text->WriteText(_ctx->string,0);
if (dwTonyNumTexts > 0) {
if (!bTonyInTexts) {
if (nTonyNextTalkType != Tony->TALK_NORMAL) {
- Tony->StartTalk(nTonyNextTalkType);
+ CORO_INVOKE_1(Tony->StartTalk, nTonyNextTalkType);
if (!bStaticTalk)
nTonyNextTalkType = Tony->TALK_NORMAL;
} else
- Tony->StartTalk(Tony->TALK_NORMAL);
+ CORO_INVOKE_1(Tony->StartTalk, Tony->TALK_NORMAL);
bTonyInTexts = true;
}
dwTonyNumTexts--;
} else {
- Tony->StartTalk(nTonyNextTalkType);
+ CORO_INVOKE_1(Tony->StartTalk, nTonyNextTalkType);
if (!bStaticTalk)
nTonyNextTalkType = Tony->TALK_NORMAL;
}
} else if (!IsMChar[nPers]) {
- RMPoint pt;
-
- text = new RMTextDialog;
+ _ctx->text = new RMTextDialog;
- pt=Character[nPers].item->CalculatePos()-RMPoint(-60,20)-Loc->ScrollPosition();
+ _ctx->pt = Character[nPers].item->CalculatePos() - RMPoint(-60, 20) - Loc->ScrollPosition();
if (Character[nPers].starttalkpattern != 0) {
Freeze();
Character[nPers].item->SetPattern(Character[nPers].starttalkpattern);
Unfreeze();
- Character[nPers].item->WaitForEndPattern();
+ CORO_INVOKE_0(Character[nPers].item->WaitForEndPattern);
}
Character[nPers].item->SetPattern(Character[nPers].talkpattern);
- text->SetColor(Character[nPers].r,Character[nPers].g,Character[nPers].b);
- text->WriteText(string,0);
- text->SetPosition(pt);
+ _ctx->text->SetColor(Character[nPers].r, Character[nPers].g,Character[nPers].b);
+ _ctx->text->WriteText(_ctx->string, 0);
+ _ctx->text->SetPosition(_ctx->pt);
} else {
RMPoint pt;
- if (MCharacter[nPers].x==-1)
- pt=MCharacter[nPers].item->CalculatePos()-RMPoint(-60,20)-Loc->ScrollPosition();
+ if (MCharacter[nPers].x == -1)
+ pt = MCharacter[nPers].item->CalculatePos() - RMPoint(-60, 20) - Loc->ScrollPosition();
else
- pt=RMPoint(MCharacter[nPers].x,MCharacter[nPers].y);
+ pt = RMPoint(MCharacter[nPers].x, MCharacter[nPers].y);
// Parametro per le azioni speciali: random tra le parlate
- parm = (MCharacter[nPers].curgroup * 10) + _vm->_randomSource.getRandomNumber(
+ _ctx->parm = (MCharacter[nPers].curgroup * 10) + _vm->_randomSource.getRandomNumber(
MCharacter[nPers].numtalks[MCharacter[nPers].curgroup] - 1) + 1;
if (MCharacter[nPers].numtexts != 0 && MCharacter[nPers].bInTexts) {
MCharacter[nPers].numtexts--;
} else {
// Cerca di eseguire la funzione custom per inizializzare la parlata
- h = mpalQueryDoAction(30, MCharacter[nPers].item->MpalCode(), parm);
- if (h != INVALID_HANDLE_VALUE)
- WaitForSingleObject(h,INFINITE);
+ _ctx->h = mpalQueryDoAction(30, MCharacter[nPers].item->MpalCode(), _ctx->parm);
+ if (_ctx->h != INVALID_HANDLE_VALUE)
+ WaitForSingleObject(_ctx->h,INFINITE);
- MCharacter[nPers].curTalk = parm;
+ MCharacter[nPers].curTalk = _ctx->parm;
if (MCharacter[nPers].numtexts != 0) {
MCharacter[nPers].bInTexts = true;
@@ -1797,39 +1989,39 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg
}
if (MCharacter[nPers].bAlwaysBack) {
- text = curBackText = new RMTextDialogScrolling(Loc);
+ _ctx->text = curBackText = new RMTextDialogScrolling(Loc);
if (bTonyIsSpeaking)
curBackText->Hide();
- bIsBack = true;
+ _ctx->bIsBack = true;
} else
- text = new RMTextDialog;
+ _ctx->text = new RMTextDialog;
- text->SetSkipStatus(!MCharacter[nPers].bAlwaysBack);
- text->SetColor(MCharacter[nPers].r,MCharacter[nPers].g,MCharacter[nPers].b);
- text->WriteText(string,0);
- text->SetPosition(pt);
+ _ctx->text->SetSkipStatus(!MCharacter[nPers].bAlwaysBack);
+ _ctx->text->SetColor(MCharacter[nPers].r,MCharacter[nPers].g,MCharacter[nPers].b);
+ _ctx->text->WriteText(_ctx->string,0);
+ _ctx->text->SetPosition(pt);
}
if (!bSkipIdle) {
- text->SetInput(Input);
- if (bAlwaysDisplay) { text->SetAlwaysDisplay(); text->ForceTime(); }
- text->SetAlignType(RMText::HCENTER,RMText::VBOTTOM);
- LinkGraphicTask(text);
-
- if (curVoc) {
- voice->Play();
- text->SetCustomSkipHandle2(voice->hEndOfBuffer);
+ _ctx->text->SetInput(Input);
+ if (bAlwaysDisplay) { _ctx->text->SetAlwaysDisplay(); _ctx->text->ForceTime(); }
+ _ctx->text->SetAlignType(RMText::HCENTER,RMText::VBOTTOM);
+ LinkGraphicTask(_ctx->text);
+
+ if (_ctx->curVoc) {
+ _ctx->voice->Play();
+ _ctx->text->SetCustomSkipHandle2(_ctx->voice->hEndOfBuffer);
}
// Aspetta la fine della visualizzazione
- text->SetCustomSkipHandle(hSkipIdle);
- text->WaitForEndDisplay();
+ _ctx->text->SetCustomSkipHandle(hSkipIdle);
+ _ctx->text->WaitForEndDisplay();
}
- if (curVoc) {
- voice->Stop();
- voice->Release();
- voice=NULL;
+ if (_ctx->curVoc) {
+ _ctx->voice->Stop();
+ _ctx->voice->Release();
+ _ctx->voice=NULL;
}
if (nPers != 0) {
@@ -1838,37 +2030,39 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg
Freeze();
Character[nPers].item->SetPattern(Character[nPers].endtalkpattern);
Unfreeze();
- Character[nPers].item->WaitForEndPattern();
+ CORO_INVOKE_0(Character[nPers].item->WaitForEndPattern);
}
Character[nPers].item->SetPattern(Character[nPers].standpattern);
- delete text;
+ delete _ctx->text;
} else {
if ((MCharacter[nPers].bInTexts && MCharacter[nPers].numtexts== 0) || !MCharacter[nPers].bInTexts) {
// Cerca di eseguire la funzione custom per chiudere la parlata
MCharacter[nPers].curTalk = (MCharacter[nPers].curTalk%10) + MCharacter[nPers].curgroup*10;
- h = mpalQueryDoAction(31,MCharacter[nPers].item->MpalCode(),MCharacter[nPers].curTalk);
- if (h!=INVALID_HANDLE_VALUE)
- WaitForSingleObject(h,INFINITE);
+ _ctx->h = mpalQueryDoAction(31,MCharacter[nPers].item->MpalCode(),MCharacter[nPers].curTalk);
+ if (_ctx->h!=INVALID_HANDLE_VALUE)
+ WaitForSingleObject(_ctx->h,INFINITE);
MCharacter[nPers].bInTexts = false;
MCharacter[nPers].numtexts = 0;
}
curBackText = NULL;
- delete text;
+ delete _ctx->text;
}
} else {
if ((dwTonyNumTexts== 0 && bTonyInTexts) || !bTonyInTexts) {
- Tony->EndTalk();
+ CORO_INVOKE_0(Tony->EndTalk);
dwTonyNumTexts = 0;
bTonyInTexts = false;
}
- delete text;
+ delete _ctx->text;
}
- GlobalFree(string);
+ GlobalFree(_ctx->string);
+
+ CORO_END_CODE;
}
diff --git a/engines/tony/loc.cpp b/engines/tony/loc.cpp
index 9a2f4cfe6a..e6914ebc87 100644
--- a/engines/tony/loc.cpp
+++ b/engines/tony/loc.cpp
@@ -705,8 +705,9 @@ bool RMItem::DoFrame(RMGfxTargetBuffer *bigBuf, bool bAddToList) {
return false;
// Facciamo un update del pattern, che ci ritorna anche il frame corrente
+ // FIXME: Get rid of HANDLE cast
if (m_nCurPattern != 0)
- m_nCurSprite=m_patterns[m_nCurPattern].Update(m_hEndPattern,m_bCurFlag, m_sfx);
+ m_nCurSprite = m_patterns[m_nCurPattern].Update((HANDLE)m_hEndPattern, m_bCurFlag, m_sfx);
// Se la funzione ha ritornato -1, vuol dire che il pattern e' finito
if (m_nCurSprite == -1) {
@@ -831,30 +832,36 @@ RMItem::RMItem() {
m_nSprites = 0;
m_nSfx = 0;
m_nPatterns = 0;
- m_hEndPattern = 0;
m_bPal = 0;
m_nCurSprite = 0;
- m_hEndPattern = CreateEvent(NULL, false, false, NULL);
+ m_hEndPattern = _vm->_scheduler.createEvent(false, false);
}
RMItem::~RMItem() {
- Unload();
- CloseHandle(m_hEndPattern);
+ Unload();
+ _vm->_scheduler.closeEvent(m_hEndPattern);
}
-void RMItem::WaitForEndPattern(HANDLE hCustomSkip) {
+//FIXME: Pass uint32 directly for hCustomSkip
+void RMItem::WaitForEndPattern(CORO_PARAM, HANDLE hCustomSkip) {
+ CORO_BEGIN_CONTEXT;
+ uint32 h[2];
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
if (m_nCurPattern != 0) {
if (hCustomSkip == INVALID_HANDLE_VALUE)
- WaitForSingleObject(m_hEndPattern,INFINITE);
+ CORO_INVOKE_2(_vm->_scheduler.waitForSingleObject, m_hEndPattern, INFINITE);
else {
- HANDLE h[2];
-
- h[0] = hCustomSkip;
- h[1] = m_hEndPattern;
- WaitForMultipleObjects(2, h, false, INFINITE);
+ _ctx->h[0] = (uint32)hCustomSkip;
+ _ctx->h[1] = m_hEndPattern;
+ CORO_INVOKE_4(_vm->_scheduler.waitForMultipleObjects, 2, &_ctx->h[0], false, INFINITE);
}
}
+
+ CORO_END_CODE;
}
void RMItem::ChangeHotspot(RMPoint pt) {
diff --git a/engines/tony/loc.h b/engines/tony/loc.h
index 9ed1a284d1..3a312a0d3c 100644
--- a/engines/tony/loc.h
+++ b/engines/tony/loc.h
@@ -52,6 +52,7 @@
#include "common/system.h"
#include "common/file.h"
#include "tony/mpal/stubs.h"
+#include "tony/sched.h"
#include "tony/sound.h"
#include "tony/utils.h"
@@ -245,7 +246,7 @@ private:
byte m_bCurFlag;
int m_nCurSprite;
bool m_bIsActive;
- HANDLE m_hEndPattern;
+ uint32 m_hEndPattern;
bool m_bInitCurPattern;
public:
@@ -291,7 +292,7 @@ public:
void Unload(void);
// Aspetta la fine del pattern in play
- void WaitForEndPattern(HANDLE hCustomSkip = INVALID_HANDLE_VALUE);
+ void WaitForEndPattern(CORO_PARAM, HANDLE hCustomSkip = INVALID_HANDLE_VALUE);
// Setta un nuovo hotspot per l'oggetto
void ChangeHotspot(RMPoint pt);
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 592c4788df..c5ded67c81 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -141,8 +141,8 @@ uint32 nPollingLocations[MAXPOLLINGLOCATIONS];
HANDLE hEndPollingLocations[MAXPOLLINGLOCATIONS];
uint32 PollingThreads[MAXPOLLINGLOCATIONS];
-HANDLE hAskChoice;
-HANDLE hDoneChoice;
+uint32 hAskChoice;
+uint32 hDoneChoice;
uint32 nExecutingAction;
@@ -1349,7 +1349,7 @@ void ShutUpDialogThread(CORO_PARAM, const void *param) {
nExecutingDialog = 0;
nExecutingChoice = 0;
- SetEvent(hAskChoice);
+ _vm->_scheduler.setEvent(hAskChoice);
CORO_KILL_SELF();
@@ -1501,9 +1501,9 @@ void DoChoice(CORO_PARAM, uint32 nChoice) {
/* Avvertiamo il gioco che c'e' una scelta da far fare all'utente,
e restiamo in attesa della risposta */
- ResetEvent(hDoneChoice);
- SetEvent(hAskChoice);
- WaitForSingleObject(hDoneChoice, INFINITE);
+ _vm->_scheduler.resetEvent(hDoneChoice);
+ _vm->_scheduler.setEvent(hAskChoice);
+ CORO_INVOKE_2(_vm->_scheduler.waitForSingleObject, hDoneChoice, INFINITE);
/* Ora che la scelta e' stata effettuata, possiamo eseguire _ctx->i gruppi
associati con la scelta */
@@ -1644,8 +1644,8 @@ static uint32 DoDialog(uint32 nDlgOrd, uint32 nGroup) {
// Enables the flag to indicate that there is' a running dialogue
bExecutingDialog = true;
- ResetEvent(hAskChoice);
- ResetEvent(hDoneChoice);
+ _vm->_scheduler.resetEvent(hAskChoice);
+ _vm->_scheduler.resetEvent(hDoneChoice);
// Create a thread that performs the dialogue group
@@ -1690,7 +1690,7 @@ bool DoSelection(uint32 i, uint32 dwData) {
return false;
nSelectedChoice = j;
- SetEvent(hDoneChoice);
+ _vm->_scheduler.setEvent(hDoneChoice);
return true;
}
@@ -1867,8 +1867,8 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName,
/* Crea l'evento che verra' utilizzato per avvertire il gioco che c'e'
da effettuare una scelta */
- hAskChoice = CreateEvent(NULL, true, false, NULL);
- hDoneChoice = CreateEvent(NULL, true, false, NULL);
+ hAskChoice = _vm->_scheduler.createEvent(true, false);
+ hDoneChoice = _vm->_scheduler.createEvent(true, false);
return true;
}
@@ -2031,8 +2031,9 @@ void mpalQueryInner(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, va_list v) {
/*
* void mpalQuery(MPQ_DIALOG_WAITFORCHOICE);
*/
- WaitForSingleObject(hAskChoice, INFINITE);
- ResetEvent(hAskChoice);
+ CORO_INVOKE_2(_vm->_scheduler.waitForSingleObject, hAskChoice, INFINITE);
+
+ _vm->_scheduler.resetEvent(hAskChoice);
if (bExecutingDialog)
*dwRet = (uint32)nExecutingChoice;
diff --git a/engines/tony/mpal/stubs.cpp b/engines/tony/mpal/stubs.cpp
index 0fc01d4d07..58ecc6d6d9 100644
--- a/engines/tony/mpal/stubs.cpp
+++ b/engines/tony/mpal/stubs.cpp
@@ -90,16 +90,20 @@ uint32 WaitForMultipleObjects(uint32 nCount, const HANDLE *lpHandles, bool bWait
}
HANDLE CreateEvent(void *lpEventAttributes, bool bManualReset, bool bInitialState, const char *lpName) {
+ warning("TODO: Refactor call to old style CreateEvent method");
return 0;
}
void SetEvent(HANDLE hEvent) {
+ warning("TODO: Refactor call to old style SetEvent method");
}
void ResetEvent(HANDLE hEvent) {
+ warning("TODO: Refactor call to old style ResetEvent method");
}
void PulseEvent(HANDLE hEvent) {
+ warning("TODO: Refactor call to old style PulseEvent method");
}
uint16 GetAsyncKeyState(Common::KeyCode kc) {
diff --git a/engines/tony/sched.cpp b/engines/tony/sched.cpp
index 41531bf225..199f5991ce 100644
--- a/engines/tony/sched.cpp
+++ b/engines/tony/sched.cpp
@@ -67,6 +67,11 @@ Scheduler::~Scheduler() {
delete active;
active = 0;
+
+ // Clear the event list
+ Common::List<EVENT *>::iterator i;
+ for (i = _events.begin(); i != _events.end(); ++i)
+ delete (*i);
}
/**
@@ -292,39 +297,52 @@ void Scheduler::giveWay(PPROCESS pReSchedProc) {
}
/**
- * Continously makes a given process wait for another process to finish
+ * Continously makes a given process wait for another process to finish or event to signal.
*
- * @param pid Process identifier
+ * @param pid Process/Event identifier
* @param duration Duration in milliseconds
- * @param expired Set to true if delay period expired
+ * @param expired If specified, set to true if delay period expired
*/
-void Scheduler::waitForSingleObject(CORO_PARAM, int pid, int duration, bool *expired) {
+void Scheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired) {
if (!pCurrent)
error("Called Scheduler::waitForSingleObject from the main process");
CORO_BEGIN_CONTEXT;
uint32 endTime;
- PROCESS *pProc;
+ PROCESS *pProcess;
+ EVENT *pEvent;
CORO_END_CONTEXT(_ctx);
CORO_BEGIN_CODE(_ctx);
_ctx->endTime = (duration == INFINITE) ? INFINITE : g_system->getMillis() + duration;
if (expired)
- *expired = false;
+ // Presume it will expire
+ *expired = true;
// Outer loop for doing checks until expiry
while (g_system->getMillis() < _ctx->endTime) {
- // Check to see if a process with the given Id exists
- _ctx->pProc = active->pNext;
- while ((_ctx->pProc != NULL) && (_ctx->pProc->pid != pid))
- _ctx->pProc = _ctx->pProc->pNext;
+ // Check to see if a process or event with the given Id exists
+ _ctx->pProcess = getProcess(pid);
+ _ctx->pEvent = !_ctx->pProcess ? getEvent(pid) : NULL;
- if (_ctx->pProc == NULL) {
- // No match process found, so it's okay to break out of loop
+ // If there's no active process or event, presume it's a process that's finished,
+ // so the waiting can immediately exit
+ if ((_ctx->pProcess == NULL) && (_ctx->pEvent == NULL)) {
if (expired)
- *expired = true;
+ *expired = false;
+ break;
+ }
+
+ // If a process was found, don't go into the if statement, and keep waiting.
+ // Likewise if it's an event that's not yet signalled
+ if ((_ctx->pEvent != NULL) && _ctx->pEvent->signalled) {
+ // Unless the event is flagged for manual reset, reset it now
+ if (!_ctx->pEvent->manualReset)
+ _ctx->pEvent->signalled = false;
+ if (expired)
+ *expired = false;
break;
}
@@ -336,6 +354,76 @@ void Scheduler::waitForSingleObject(CORO_PARAM, int pid, int duration, bool *exp
}
/**
+ * Continously makes a given process wait for given prcesses to finished or events to be set
+ *
+ * @param nCount Number of Id's being passed
+ * @param evtList List of pids to wait for
+ * @param bWaitAll Specifies whether all or any of the processes/events
+ * @param duration Duration in milliseconds
+ * @param expired Set to true if delay period expired
+ */
+void Scheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll,
+ uint32 duration, bool *expired) {
+ if (!pCurrent)
+ error("Called Scheduler::waitForMultipleEvents from the main process");
+
+ CORO_BEGIN_CONTEXT;
+ uint32 endTime;
+ bool signalled;
+ bool pidSignalled;
+ int i;
+ PROCESS *pProcess;
+ EVENT *pEvent;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->endTime = (duration == INFINITE) ? INFINITE : g_system->getMillis() + duration;
+ if (expired)
+ // Presume that delay will expire
+ *expired = true;
+
+ // Outer loop for doing checks until expiry
+ while (g_system->getMillis() < _ctx->endTime) {
+ _ctx->signalled = bWaitAll;
+
+ for (_ctx->i = 0; _ctx->i < nCount; ++_ctx->i) {
+ _ctx->pProcess = getProcess(pidList[_ctx->i]);
+ _ctx->pEvent = !_ctx->pProcess ? getEvent(pidList[_ctx->i]) : NULL;
+
+ // Determine the signalled state
+ _ctx->pidSignalled = (_ctx->pProcess) || !_ctx->pEvent ? false : _ctx->pEvent->signalled;
+
+ if (bWaitAll && _ctx->pidSignalled)
+ _ctx->signalled = false;
+ else if (!bWaitAll & _ctx->pidSignalled)
+ _ctx->signalled = true;
+ }
+
+ // At this point, if the signalled variable is set, waiting is finished
+ if (_ctx->signalled) {
+ // Automatically reset any events not flagged for manual reset
+ for (_ctx->i = 0; _ctx->i < nCount; ++_ctx->i) {
+ _ctx->pEvent = getEvent(pidList[_ctx->i]);
+
+ if (_ctx->pEvent->manualReset)
+ _ctx->pEvent->signalled = false;
+ }
+
+ if (expired)
+ *expired = false;
+ break;
+ }
+
+ // Sleep until the next cycle
+ CORO_SLEEP(1);
+ }
+
+ CORO_END_CODE;
+}
+
+
+/**
* Creates a new process.
*
* @param pid process identifier
@@ -541,4 +629,72 @@ void Scheduler::setResourceCallback(VFPTRPP pFunc) {
pRCfunction = pFunc;
}
+PROCESS *Scheduler::getProcess(uint32 pid) {
+ PROCESS *pProc = active->pNext;
+ while ((pProc != NULL) && (pProc->pid != pid))
+ pProc = pProc->pNext;
+
+ return pProc;
+}
+
+EVENT *Scheduler::getEvent(uint32 pid) {
+ Common::List<EVENT *>::iterator i;
+ for (i = _events.begin(); i != _events.end(); ++i) {
+ EVENT *evt = *i;
+ if (evt->pid == pid)
+ return evt;
+ }
+
+ return NULL;
+}
+
+
+/**
+ * Creates a new event object
+ * @param bManualReset Events needs to be manually reset. Otherwise, events
+ * will be automatically reset after a process waits on the event finishes
+ * @param bInitialState Specifies whether the event is signalled or not initially
+ */
+uint32 Scheduler::createEvent(bool bManualReset, bool bInitialState) {
+ EVENT *evt = new EVENT();
+ evt->pid = ++pidCounter;
+ evt->manualReset = bManualReset;
+ evt->signalled = bInitialState;
+
+ _events.push_back(evt);
+ return evt->pid;
+}
+
+/**
+ * Destroys the given event
+ * @param pidEvent Event PID
+ */
+void Scheduler::closeEvent(uint32 pidEvent) {
+ EVENT *evt = getEvent(pidEvent);
+ if (evt) {
+ _events.remove(evt);
+ delete evt;
+ }
+}
+
+/**
+ * Sets the event
+ * @param pidEvent Event PID
+ */
+void Scheduler::setEvent(uint32 pidEvent) {
+ EVENT *evt = getEvent(pidEvent);
+ if (evt)
+ evt->signalled = true;
+}
+
+/**
+ * Resets the event
+ * @param pidEvent Event PID
+ */
+void Scheduler::resetEvent(uint32 pidEvent) {
+ EVENT *evt = getEvent(pidEvent);
+ if (evt)
+ evt->signalled = false;
+}
+
} // End of namespace Tony
diff --git a/engines/tony/sched.h b/engines/tony/sched.h
index 54f44aa5fd..80df1eb942 100644
--- a/engines/tony/sched.h
+++ b/engines/tony/sched.h
@@ -24,6 +24,7 @@
#ifndef TONY_SCHED_H
#define TONY_SCHED_H
+#include "common/list.h"
#include "tony/coroutine.h"
namespace Tony {
@@ -48,13 +49,20 @@ struct PROCESS {
CORO_ADDR coroAddr; ///< the entry point of the coroutine
int sleepTime; ///< number of scheduler cycles to sleep
- int pid; ///< process ID
+ uint32 pid; ///< process ID
char param[PARAM_SIZE]; ///< process specific info
};
typedef PROCESS *PPROCESS;
struct INT_CONTEXT;
+/** Event structure */
+struct EVENT {
+ uint32 pid;
+ bool manualReset;
+ bool signalled;
+};
+
/**
* Create and manage "processes" (really coroutines).
*/
@@ -80,6 +88,8 @@ private:
/** Auto-incrementing process Id */
int pidCounter;
+ /** Event list */
+ Common::List<EVENT *> _events;
#ifdef DEBUG
// diagnostic process counters
@@ -95,7 +105,8 @@ private:
*/
VFPTRPP pRCfunction;
-
+ PROCESS *getProcess(uint32 pid);
+ EVENT *getEvent(uint32 pid);
public:
Scheduler();
@@ -111,7 +122,9 @@ public:
void rescheduleAll();
void reschedule(PPROCESS pReSchedProc = NULL);
void giveWay(PPROCESS pReSchedProc = NULL);
- void waitForSingleObject(CORO_PARAM, int pid, int duration, bool *delay = NULL);
+ void waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired = NULL);
+ void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll,
+ uint32 duration, bool *expired = NULL);
uint32 createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam);
uint32 createProcess(CORO_ADDR coroAddr, const void *pParam) {
@@ -123,9 +136,13 @@ public:
int getCurrentPID() const;
int killMatchingProcess(int pidKill, int pidMask = -1);
-
void setResourceCallback(VFPTRPP pFunc);
+ /* Event methods */
+ uint32 createEvent(bool bManualReset, bool bInitialState);
+ void closeEvent(uint32 pidEvent);
+ void setEvent(uint32 pidEvent);
+ void resetEvent(uint32 pidEvent);
};
extern Scheduler *g_scheduler; // FIXME: Temporary global var, to be used until everything has been OOifyied
diff --git a/engines/tony/tonychar.cpp b/engines/tony/tonychar.cpp
index de6189876b..073ebf2be4 100644
--- a/engines/tony/tonychar.cpp
+++ b/engines/tony/tonychar.cpp
@@ -519,10 +519,8 @@ void RMTony::Put(int nWhere, int nPart) {
}
-void RMTony::StartTalk(TALKTYPE nTalkType) {
- int headStartPat = 0, bodyStartPat = 0;
- int headLoopPat = 0, bodyLoopPat = 0;
-
+bool RMTony::StartTalkCalculate(TALKTYPE nTalkType, int &headStartPat, int &bodyStartPat,
+ int &headLoopPat, int &bodyLoopPat) {
assert(!m_bIsTalking);
m_bIsTalking = true;
@@ -585,7 +583,7 @@ void RMTony::StartTalk(TALKTYPE nTalkType) {
break;
}
MainUnfreeze();
- return;
+ return false;
}
headStartPat = bodyStartPat = 0;
@@ -1077,35 +1075,47 @@ void RMTony::StartTalk(TALKTYPE nTalkType) {
}
break;
}
+}
+
+void RMTony::StartTalk(CORO_PARAM, TALKTYPE 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;
// Esegue il set dei pattern vero e proprio
- if (headStartPat != 0 || bodyStartPat != 0) {
+ if (_ctx->headStartPat != 0 || _ctx->bodyStartPat != 0) {
MainFreeze();
- SetPattern(headStartPat);
- m_body.SetPattern(bodyStartPat);
+ SetPattern(_ctx->headStartPat);
+ m_body.SetPattern(_ctx->bodyStartPat);
MainUnfreeze();
- if (bodyStartPat!=0)
- m_body.WaitForEndPattern();
- if (headStartPat!=0)
- WaitForEndPattern();
+ if (_ctx->bodyStartPat != 0)
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
+ if (_ctx->headStartPat != 0)
+ CORO_INVOKE_0(WaitForEndPattern);
}
MainFreeze();
- SetPattern(headLoopPat);
- if (bodyLoopPat)
- m_body.SetPattern(bodyLoopPat);
+ SetPattern(_ctx->headLoopPat);
+ if (_ctx->bodyLoopPat)
+ m_body.SetPattern(_ctx->bodyLoopPat);
MainUnfreeze();
-}
+ CORO_END_CODE;
+}
-void RMTony::EndTalk(void) {
- int headStandPat = 0;
- int headEndPat = 0;
- int bodyEndPat = 0;
- int finalPat = 0;
- bool bStatic = false;
+bool RMTony::EndTalkCalculate(int &headStandPat, int &headEndPat, int &bodyEndPat, int &finalPat, bool &bStatic) {
bodyEndPat = 0;
headEndPat = 0;
@@ -1136,7 +1146,7 @@ void RMTony::EndTalk(void) {
SetPattern(finalPat);
MainUnfreeze();
m_bIsTalking = false;
- return;
+ return false;
}
@@ -1379,6 +1389,28 @@ void RMTony::EndTalk(void) {
break;
}
+ return true;
+}
+
+void RMTony::EndTalk(CORO_PARAM) {
+ CORO_BEGIN_CONTEXT;
+ int headStandPat, headEndPat;
+ int bodyEndPat, finalPat;
+ bool bStatic;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->headStandPat = _ctx->headEndPat = 0;
+ _ctx->bodyEndPat = _ctx->finalPat = 0;
+ _ctx->bStatic = false;
+
+ _ctx->bodyEndPat = 0;
+ _ctx->headEndPat = 0;
+
+ if (!EndTalkCalculate(_ctx->headStandPat, _ctx->headEndPat, _ctx->bodyEndPat, _ctx->finalPat, _ctx->bStatic))
+ return;
+
// Gestisce la fine di una animazione static lasciando tutto invariato
if (m_bIsStaticTalk) {
if (m_nTalkType == TALK_CONBARBASTATIC) {
@@ -1394,10 +1426,10 @@ void RMTony::EndTalk(void) {
MainUnfreeze();
} else {
MainFreeze();
- SetPattern(headStandPat);
+ SetPattern(_ctx->headStandPat);
MainUnfreeze();
- m_body.WaitForEndPattern();
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
}
m_bIsTalking = false;
@@ -1405,60 +1437,58 @@ void RMTony::EndTalk(void) {
}
// Set dei pattern
- if (headEndPat != 0 && bodyEndPat != 0) {
+ if (_ctx->headEndPat != 0 && _ctx->bodyEndPat != 0) {
MainFreeze();
- SetPattern(headEndPat);
+ SetPattern(_ctx->headEndPat);
MainUnfreeze();
- m_body.WaitForEndPattern();
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
MainFreeze();
- m_body.SetPattern(bodyEndPat);
+ m_body.SetPattern(_ctx->bodyEndPat);
MainUnfreeze();
- WaitForEndPattern();
- m_body.WaitForEndPattern();
- } else if (bodyEndPat != 0) {
+ CORO_INVOKE_0(WaitForEndPattern);
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
+ } else if (_ctx->bodyEndPat != 0) {
MainFreeze();
- SetPattern(headStandPat);
+ SetPattern(_ctx->headStandPat);
MainUnfreeze();
- m_body.WaitForEndPattern();
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
MainFreeze();
- m_body.SetPattern(bodyEndPat);
+ m_body.SetPattern(_ctx->bodyEndPat);
MainUnfreeze();
- m_body.WaitForEndPattern();
- } else if (headEndPat != 0) {
- m_body.WaitForEndPattern();
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
+ } else if (_ctx->headEndPat != 0) {
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
MainFreeze();
- SetPattern(headEndPat);
+ SetPattern(_ctx->headEndPat);
MainUnfreeze();
- WaitForEndPattern();
+ CORO_INVOKE_0(WaitForEndPattern);
} else {
- m_body.WaitForEndPattern();
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
}
- if (finalPat != 0) {
+ if (_ctx->finalPat != 0) {
MainFreeze();
m_body.SetPattern(0);
- SetPattern(finalPat);
+ SetPattern(_ctx->finalPat);
MainUnfreeze();
}
m_bIsTalking = false;
-}
-void RMTony::StartStatic(TALKTYPE nTalk) {
- int nPat = 0;
- int headPat = 0, headLoopPat = 0;
- int bodyStartPat = 0;
- int bodyLoopPat = 0;
+ CORO_END_CODE;
+}
- nPat = GetCurPattern();
+void RMTony::StartStaticCalculate(TALKTYPE nTalk, int &headPat, int &headLoopPat,
+ int &bodyStartPat, int &bodyLoopPat) {
+ int nPat = GetCurPattern();
headLoopPat = -1;
@@ -1661,31 +1691,41 @@ void RMTony::StartStatic(TALKTYPE nTalk) {
default:
break;
}
+}
+
+void RMTony::StartStatic(CORO_PARAM, TALKTYPE 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;
// e vai con i pattern
m_bIsStaticTalk = true;
MainFreeze();
- SetPattern(headPat);
- m_body.SetPattern(bodyStartPat);
+ SetPattern(_ctx->headPat);
+ m_body.SetPattern(_ctx->bodyStartPat);
MainUnfreeze();
- m_body.WaitForEndPattern();
- WaitForEndPattern();
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
+ CORO_INVOKE_0(WaitForEndPattern);
MainFreeze();
- if (headLoopPat != -1)
- SetPattern(headLoopPat);
- m_body.SetPattern(bodyLoopPat);
+ if (_ctx->headLoopPat != -1)
+ SetPattern(_ctx->headLoopPat);
+ m_body.SetPattern(_ctx->bodyLoopPat);
MainUnfreeze();
-}
+ CORO_END_CODE;
+}
-void RMTony::EndStatic(TALKTYPE nTalk) {
- int bodyEndPat = 0;
- int finalPat = 0;
- int headEndPat = 0;
+void RMTony::EndStaticCalculate(TALKTYPE nTalk, int &bodyEndPat, int &finalPat, int &headEndPat) {
switch (m_TalkDirection) {
case UP:
case LEFT:
@@ -1818,28 +1858,46 @@ void RMTony::EndStatic(TALKTYPE nTalk) {
default:
break;
}
+}
+
+void RMTony::EndStatic(CORO_PARAM, TALKTYPE nTalk) {
+ CORO_BEGIN_CONTEXT;
+ int bodyEndPat;
+ int finalPat;
+ int headEndPat;
+ CORO_END_CONTEXT(_ctx);
- if (headEndPat != 0) {
+ 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) {
MainFreeze();
- SetPattern(headEndPat);
+ SetPattern(_ctx->headEndPat);
MainUnfreeze();
- WaitForEndPattern();
+ CORO_INVOKE_0(WaitForEndPattern);
} else {
// Play please
MainFreeze();
- m_body.SetPattern(bodyEndPat);
+ m_body.SetPattern(_ctx->bodyEndPat);
MainUnfreeze();
- m_body.WaitForEndPattern();
+ CORO_INVOKE_0(m_body.WaitForEndPattern);
}
MainFreeze();
- SetPattern(finalPat);
+ SetPattern(_ctx->finalPat);
m_body.SetPattern(0);
MainUnfreeze();
m_bIsStaticTalk = false;
+
+ CORO_END_CODE;
}
} // End of namespace Tony
diff --git a/engines/tony/tonychar.h b/engines/tony/tonychar.h
index 266b34e697..2cbcf60a00 100644
--- a/engines/tony/tonychar.h
+++ b/engines/tony/tonychar.h
@@ -408,7 +408,9 @@ public:
int GetCurPattern();
// Attende la fine di un pattern
- void WaitForEndPattern(HANDLE hCustomSkip = INVALID_HANDLE_VALUE) { RMCharacter::WaitForEndPattern(hCustomSkip);}
+ void WaitForEndPattern(CORO_PARAM, HANDLE hCustomSkip = INVALID_HANDLE_VALUE) {
+ RMCharacter::WaitForEndPattern(coroParam, hCustomSkip);
+ }
// Controlla se si trova in azione
bool InAction() { return (m_bActionPending&&m_Action != 0) | m_bAction; }
@@ -427,12 +429,18 @@ public:
void Put(int nWhere, int nPart);
// Start e End Talk
- void StartTalk(TALKTYPE nTalkType);
- void EndTalk(void);
+ bool StartTalkCalculate(TALKTYPE nTalkType, int &headStartPat, int &bodyStartPat,
+ int &headLoopPat, int &bodyLoopPat);
+ void StartTalk(CORO_PARAM, TALKTYPE nTalkType);
+ bool EndTalkCalculate(int &headStandPat, int &headEndPat, int &bodyEndPat, int &finalPat, bool &bStatic);
+ void EndTalk(CORO_PARAM);
// Start e End Static
- void StartStatic(TALKTYPE nTalkType);
- void EndStatic(TALKTYPE nTalkType);
+ void StartStaticCalculate(TALKTYPE nTalk, int &headPat, int &headLoopPat,
+ int &bodyStartPat, int &bodyLoopPat);
+ void StartStatic(CORO_PARAM, TALKTYPE nTalkType);
+ void EndStaticCalculate(TALKTYPE nTalk, int &bodyEndPat, int &finalPat, int &headEndPat);
+ void EndStatic(CORO_PARAM, TALKTYPE nTalkType);
// Tony si traveste!
void SetPastorella(bool bIsPast) { m_bPastorella=bIsPast; }