diff options
-rw-r--r-- | engines/tony/adv.h | 4 | ||||
-rw-r--r-- | engines/tony/custom.cpp | 622 | ||||
-rw-r--r-- | engines/tony/font.cpp | 167 | ||||
-rw-r--r-- | engines/tony/font.h | 25 | ||||
-rw-r--r-- | engines/tony/game.cpp | 8 | ||||
-rw-r--r-- | engines/tony/gfxengine.cpp | 90 | ||||
-rw-r--r-- | engines/tony/gfxengine.h | 8 | ||||
-rw-r--r-- | engines/tony/loc.cpp | 45 | ||||
-rw-r--r-- | engines/tony/loc.h | 10 | ||||
-rw-r--r-- | engines/tony/mpal/loadmpc.cpp | 59 | ||||
-rw-r--r-- | engines/tony/mpal/mpal.cpp | 156 | ||||
-rw-r--r-- | engines/tony/mpal/stubs.cpp | 70 | ||||
-rw-r--r-- | engines/tony/mpal/stubs.h | 36 | ||||
-rw-r--r-- | engines/tony/sched.cpp | 34 | ||||
-rw-r--r-- | engines/tony/sched.h | 4 | ||||
-rw-r--r-- | engines/tony/sound.cpp | 3 | ||||
-rw-r--r-- | engines/tony/sound.h | 2 | ||||
-rw-r--r-- | engines/tony/tony.cpp | 35 | ||||
-rw-r--r-- | engines/tony/tony.h | 8 | ||||
-rw-r--r-- | engines/tony/tonychar.cpp | 38 | ||||
-rw-r--r-- | engines/tony/tonychar.h | 8 |
21 files changed, 772 insertions, 660 deletions
diff --git a/engines/tony/adv.h b/engines/tony/adv.h index 056934e932..22205cf05b 100644 --- a/engines/tony/adv.h +++ b/engines/tony/adv.h @@ -96,7 +96,7 @@ void MainUnloadLocation(CORO_PARAM, bool bDoOnExit, HANDLE *result); void MainLinkGraphicTask(RMGfxTask *task); void MainFreeze(void); void MainUnfreeze(void); -void MainWaitFrame(void); +void MainWaitFrame(CORO_PARAM); void MainShowMouse(void); void MainHideMouse(void); void MainEnableInput(void); @@ -104,7 +104,7 @@ void MainDisableInput(void); void MainPlayMusic(int nChannel, const char *filename, int nFX, bool bLoop, int nSync); void MainInitWipe(int type); void MainCloseWipe(void); -void MainWaitWipeEnd(void); +void MainWaitWipeEnd(CORO_PARAM); void MainEnableGUI(void); void MainDisableGUI(void); void MainSetPalesati(bool bPalesati); diff --git a/engines/tony/custom.cpp b/engines/tony/custom.cpp index 18a92899df..9d46d7e6b7 100644 --- a/engines/tony/custom.cpp +++ b/engines/tony/custom.cpp @@ -56,6 +56,7 @@ #include "tony/font.h" #include "tony/game.h" #include "tony/gfxcore.h" +#include "tony/sched.h" #include "tony/tony.h" #include "tony/tonychar.h" #include "tony/utils.h" @@ -76,9 +77,9 @@ void (*UnloadLocation)(CORO_PARAM, bool bDoOnExit, HANDLE *result); void (*LinkGraphicTask)(RMGfxTask *task); void (*Freeze)(void); void (*Unfreeze)(void); -void (*WaitFrame)(void); +void (*WaitFrame)(CORO_PARAM); void (*PlayMusic)(int nChannel, const char *fileName, int nFX, bool bLoop, int nSync); -void (*WaitWipeEnd)(void); +void (*WaitWipeEnd)(CORO_PARAM); void (*CloseWipe)(void); void (*InitWipe)(int type); void (*EnableGUI)(void); @@ -96,7 +97,7 @@ OSystem::MutexRef vdb; HANDLE mut[10]; bool bSkipIdle = false; -HANDLE hSkipIdle; +uint32 hSkipIdle; int lastMusic = 0, lastTappeto = 0; @@ -319,8 +320,16 @@ DECLARE_CUSTOM_FUNCTION(TonySetPalesati)(CORO_PARAM, uint32 bStatus, uint32, uin } DECLARE_CUSTOM_FUNCTION(MySleep)(CORO_PARAM, uint32 dwTime, uint32, uint32, uint32) { - if (bSkipIdle) return; - Sleep(dwTime); + CORO_BEGIN_CONTEXT; + int i; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + if (!bSkipIdle) + CORO_INVOKE_1(g_scheduler->sleep, dwTime); + + CORO_END_CODE; } DECLARE_CUSTOM_FUNCTION(SetAlwaysDisplay)(CORO_PARAM, uint32 val, uint32, uint32, uint32) { @@ -376,6 +385,7 @@ DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX int curOffset; VoiceHeader *curVoc; FPSFX *voice; + RMTextDialog text; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); @@ -422,39 +432,38 @@ DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX } if (curBackText) - curBackText->Hide(); + CORO_INVOKE_0(curBackText->Hide); + bTonyIsSpeaking = true; for (_ctx->i = 0; _ctx->i < _ctx->msg->NumPeriods() && !bSkipIdle; _ctx->i++) { - RMTextDialog text; - - text.SetInput(Input); + _ctx->text.SetInput(Input); // Allineamento - text.SetAlignType(RMText::HCENTER,RMText::VBOTTOM); + _ctx->text.SetAlignType(RMText::HCENTER,RMText::VBOTTOM); // Colore - text.SetColor(0,255,0); + _ctx->text.SetColor(0,255,0); // Scrive il testo - text.WriteText((*_ctx->msg)[_ctx->i],0); + _ctx->text.WriteText((*_ctx->msg)[_ctx->i],0); // Setta la posizione if (nX == 0 && nY == 0) - text.SetPosition(Tony->Position() - RMPoint(0, 130) - Loc->ScrollPosition()); + _ctx->text.SetPosition(Tony->Position() - RMPoint(0, 130) - Loc->ScrollPosition()); else - text.SetPosition(RMPoint(nX, nY) - Loc->ScrollPosition()); + _ctx->text.SetPosition(RMPoint(nX, nY) - Loc->ScrollPosition()); // 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 (_ctx->curVoc) { if (_ctx->i == 0) { _ctx->voice->Play(); - text.SetCustomSkipHandle2(_ctx->voice->hEndOfBuffer); + _ctx->text.SetCustomSkipHandle2(_ctx->voice->hEndOfBuffer); } else { g_system->lockMutex(vdb); // fseek(_vm->m_vdbFP, _ctx->curOffset, SEEK_SET); @@ -465,14 +474,14 @@ DECLARE_CUSTOM_FUNCTION(SendTonyMessage)(CORO_PARAM, uint32 dwMessage, uint32 nX _ctx->curOffset = _vm->_vdbFP.pos(); _ctx->voice->SetLoop(false); _ctx->voice->Play(); - text.SetCustomSkipHandle2(_ctx->voice->hEndOfBuffer); + _ctx->text.SetCustomSkipHandle2(_ctx->voice->hEndOfBuffer); g_system->unlockMutex(vdb); } } // Aspetta la fine della visualizzazione - text.SetCustomSkipHandle(hSkipIdle); - text.WaitForEndDisplay(); + _ctx->text.SetCustomSkipHandle(hSkipIdle); + CORO_INVOKE_0(_ctx->text.WaitForEndDisplay); if (_ctx->curVoc) { _ctx->voice->Stop(); @@ -497,7 +506,11 @@ DECLARE_CUSTOM_FUNCTION(ChangeBoxStatus)(CORO_PARAM, uint32 nLoc, uint32 nBox, u DECLARE_CUSTOM_FUNCTION(CustLoadLocation)(CORO_PARAM, uint32 nLoc, uint32 tX, uint32 tY, uint32 bUseStartPos) { - HANDLE h; + CORO_BEGIN_CONTEXT; + uint32 h; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); Freeze(); @@ -508,11 +521,13 @@ DECLARE_CUSTOM_FUNCTION(CustLoadLocation)(CORO_PARAM, uint32 nLoc, uint32 tX, ui LoadLocation(nLoc, RMPoint(tX, tY), RMPoint(-1, -1)); Unfreeze(); - h = mpalQueryDoAction(0, nLoc, 0); + _ctx->h = mpalQueryDoActionU32(0, nLoc, 0); // On Enter? - if (h != INVALID_HANDLE_VALUE) - WaitForSingleObject(h, INFINITE); + if (_ctx->h != INVALID_PID_VALUE) + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); + + CORO_END_CODE; } @@ -524,6 +539,7 @@ DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgStart)(CORO_PARAM, uint32 nMsg, uint32 RMMessage *msg; RMGfxClearTask clear; int i; + RMTextDialog text; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); @@ -541,38 +557,36 @@ DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgStart)(CORO_PARAM, uint32 nMsg, uint32 Unfreeze(); for (_ctx->i = 0; _ctx->i < _ctx->msg->NumPeriods() && !bSkipIdle; _ctx->i++) { - RMTextDialog text; - - text.SetInput(Input); + _ctx->text.SetInput(Input); // Allineamento - text.SetAlignType(RMText::HCENTER,RMText::VCENTER); + _ctx->text.SetAlignType(RMText::HCENTER,RMText::VCENTER); // Forza il testo a scomparire a tempo - text.ForceTime(); + _ctx->text.ForceTime(); // Colore - text.SetColor(255,255,255); + _ctx->text.SetColor(255,255,255); // Scrive il testo if (nFont == 0) - text.WriteText((*_ctx->msg)[_ctx->i], 1); + _ctx->text.WriteText((*_ctx->msg)[_ctx->i], 1); else if (nFont == 1) - text.WriteText((*_ctx->msg)[_ctx->i], 0); + _ctx->text.WriteText((*_ctx->msg)[_ctx->i], 0); // Setta la posizione - text.SetPosition(RMPoint(320, 240)); + _ctx->text.SetPosition(RMPoint(320, 240)); - text.SetAlwaysDisplay(); - text.ForceTime(); + _ctx->text.SetAlwaysDisplay(); + _ctx->text.ForceTime(); // Registra il testo LinkGraphicTask(&_ctx->clear); - LinkGraphicTask(&text); + LinkGraphicTask(&_ctx->text); // Aspetta la fine della visualizzazione - text.SetCustomSkipHandle(hSkipIdle); - text.WaitForEndDisplay(); + _ctx->text.SetCustomSkipHandle(hSkipIdle); + CORO_INVOKE_0(_ctx->text.WaitForEndDisplay); } delete _ctx->msg; @@ -581,10 +595,18 @@ DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgStart)(CORO_PARAM, uint32 nMsg, uint32 } DECLARE_CUSTOM_FUNCTION(ClearScreen)(CORO_PARAM, uint32, uint32, uint32, uint32) { - RMGfxClearTask clear; + CORO_BEGIN_CONTEXT; + char buf[256]; + RMGfxClearTask clear; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + LinkGraphicTask(&_ctx->clear); + + CORO_INVOKE_0(WaitFrame); - LinkGraphicTask(&clear); - WaitFrame(); + CORO_END_CODE; } DECLARE_CUSTOM_FUNCTION(SendFullscreenMsgEnd)(CORO_PARAM, uint32 bNotEnableTony, uint32, uint32, uint32) { @@ -625,7 +647,7 @@ DECLARE_CUSTOM_FUNCTION(CloseLocation)(CORO_PARAM, uint32, uint32, uint32, uint3 if (!bNoOcchioDiBue) { InitWipe(1); - WaitWipeEnd(); + CORO_INVOKE_0(WaitWipeEnd); } _vm->StopMusic(4); @@ -640,14 +662,14 @@ DECLARE_CUSTOM_FUNCTION(CloseLocation)(CORO_PARAM, uint32, uint32, uint32, uint3 DECLARE_CUSTOM_FUNCTION(ChangeLocation)(CORO_PARAM, uint32 nLoc, uint32 tX, uint32 tY, uint32 bUseStartPos) { CORO_BEGIN_CONTEXT; - HANDLE h; + uint32 h; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); if (!bNoOcchioDiBue) { InitWipe(1); - WaitWipeEnd(); + CORO_INVOKE_0(WaitWipeEnd); } if (lastTappeto != tappeti[nLoc]) { @@ -676,18 +698,18 @@ DECLARE_CUSTOM_FUNCTION(ChangeLocation)(CORO_PARAM, uint32 nLoc, uint32 tX, uint Unfreeze(); - _ctx->h = mpalQueryDoAction(0, nLoc, 0); + _ctx->h = mpalQueryDoActionU32(0, nLoc, 0); if (!bNoOcchioDiBue) { - WaitWipeEnd(); + CORO_INVOKE_0(WaitWipeEnd); CloseWipe(); } bNoOcchioDiBue = false; // On Enter? - if (_ctx->h != INVALID_HANDLE_VALUE) - WaitForSingleObject(_ctx->h, INFINITE); + if (_ctx->h != INVALID_PID_VALUE) + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); CORO_END_CODE; } @@ -725,7 +747,7 @@ DECLARE_CUSTOM_FUNCTION(EnableInput)(CORO_PARAM, uint32, uint32, uint32, uint32) } DECLARE_CUSTOM_FUNCTION(StopTony)(CORO_PARAM, uint32, uint32, uint32, uint32) { - Tony->StopNoAction(); + Tony->StopNoAction(coroParam); } @@ -1328,114 +1350,123 @@ DECLARE_CUSTOM_FUNCTION(MoveTony)(CORO_PARAM, uint32 nX, uint32 nY, uint32, uint } DECLARE_CUSTOM_FUNCTION(ScrollLocation)(CORO_PARAM, uint32 nX, uint32 nY, uint32 sX, uint32 sY) { - int lx, ly; - RMPoint pt; + CORO_BEGIN_CONTEXT; + int lx, ly; + RMPoint pt; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); // Prende le coordinate di quanto scrollare - lx=*((int*)&nX); - ly=*((int*)&nY); + _ctx->lx = (int32)nX; + _ctx->ly = (int32)nY; - pt=Loc->ScrollPosition(); + _ctx->pt = Loc->ScrollPosition(); - while ((lx != 0 || ly != 0) && !bSkipIdle) { - if (lx > 0) { - lx -= (int32)sX; if (lx < 0) lx = 0; - pt.Offset((int32)sX, 0); - } else if (lx < 0) { - lx += (int32)sX; if (lx > 0) lx = 0; - pt.Offset(-(int32)sX, 0); + while ((_ctx->lx != 0 || _ctx->ly != 0) && !bSkipIdle) { + if (_ctx->lx > 0) { + _ctx->lx -= (int32)sX; if (_ctx->lx < 0) _ctx->lx = 0; + _ctx->pt.Offset((int32)sX, 0); + } else if (_ctx->lx < 0) { + _ctx->lx += (int32)sX; if (_ctx->lx > 0) _ctx->lx = 0; + _ctx->pt.Offset(-(int32)sX, 0); } - if (ly > 0) { - ly -= sY; if (ly < 0) ly = 0; - pt.Offset(0, sY); - } else if (ly < 0) { - ly += sY; if (ly > 0) ly = 0; - pt.Offset(0, -(int32)sY); + if (_ctx->ly > 0) { + _ctx->ly -= sY; if (_ctx->ly < 0) _ctx->ly = 0; + _ctx->pt.Offset(0, sY); + } else if (_ctx->ly < 0) { + _ctx->ly += sY; if (_ctx->ly > 0) _ctx->ly = 0; + _ctx->pt.Offset(0, -(int32)sY); } - WaitFrame(); + CORO_INVOKE_0(WaitFrame); Freeze(); - Loc->SetScrollPosition(pt); - Tony->SetScrollPosition(pt); + Loc->SetScrollPosition(_ctx->pt); + Tony->SetScrollPosition(_ctx->pt); Unfreeze(); - } + + CORO_END_CODE; } DECLARE_CUSTOM_FUNCTION(SyncScrollLocation)(CORO_PARAM, uint32 nX, uint32 nY, uint32 sX, uint32 sY) { - int lx, ly; - RMPoint pt, startpt; - uint32 dwStartTime, dwCurTime, dwTotalTime; - uint32 stepX, stepY; - int dimx, dimy; + CORO_BEGIN_CONTEXT; + int lx, ly; + RMPoint pt, startpt; + uint32 dwStartTime, dwCurTime, dwTotalTime; + uint32 stepX, stepY; + int dimx, dimy; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); // Prende le coordinate di quanto scrollare - lx=*((int*)&nX); - ly=*((int*)&nY); - dimx = lx; - dimy = ly; - if (lx < 0) dimx = -lx; - if (ly < 0) dimy = -ly; + _ctx->lx=*((int*)&nX); + _ctx->ly=*((int*)&nY); + _ctx->dimx = _ctx->lx; + _ctx->dimy = _ctx->ly; + if (_ctx->lx < 0) _ctx->dimx = -_ctx->lx; + if (_ctx->ly < 0) _ctx->dimy = -_ctx->ly; - stepX = sX; - stepY = sY; + _ctx->stepX = sX; + _ctx->stepY = sY; - startpt = Loc->ScrollPosition(); + _ctx->startpt = Loc->ScrollPosition(); - dwStartTime = timeGetTime(); + _ctx->dwStartTime = _vm->GetTime(); if (sX) - dwTotalTime = dimx * (1000 / 35) / sX; + _ctx->dwTotalTime = _ctx->dimx * (1000 / 35) / sX; else - dwTotalTime = dimy * (1000 / 35) / sY; + _ctx->dwTotalTime = _ctx->dimy * (1000 / 35) / sY; - while ((lx != 0 || ly != 0) && !bSkipIdle) { - dwCurTime = _vm->GetTime() - dwStartTime; - if (dwCurTime>dwTotalTime) + while ((_ctx->lx != 0 || _ctx->ly != 0) && !bSkipIdle) { + _ctx->dwCurTime = _vm->GetTime() - _ctx->dwStartTime; + if (_ctx->dwCurTime > _ctx->dwTotalTime) break; - pt = startpt; + _ctx->pt = _ctx->startpt; if (sX) { - if (lx > 0) - pt.x += (dimx * dwCurTime) / dwTotalTime; + if (_ctx->lx > 0) + _ctx->pt.x += (_ctx->dimx * _ctx->dwCurTime) / _ctx->dwTotalTime; else - pt.x -= (dimx * dwCurTime) / dwTotalTime; + _ctx->pt.x -= (_ctx->dimx * _ctx->dwCurTime) / _ctx->dwTotalTime; } else { - if (ly > 0) - pt.y += (dimy*dwCurTime) / dwTotalTime; + if (_ctx->ly > 0) + _ctx->pt.y += (_ctx->dimy*_ctx->dwCurTime) / _ctx->dwTotalTime; else - pt.y -= (dimy*dwCurTime) / dwTotalTime; + _ctx->pt.y -= (_ctx->dimy*_ctx->dwCurTime) / _ctx->dwTotalTime; } /* - sX = stepX * (dwCurTime-dwLastTime) / (1000 / 35); - sY = stepY * (dwCurTime-dwLastTime) / (1000 / 35); - - if (lx > 0) { - lx-=sX; if (lx < 0) lx = 0; - pt.Offset(sX,0); - } else if (lx < 0) { - lx+=sX; if (lx > 0) lx = 0; - pt.Offset(-sX,0); + sX = _ctx->stepX * (_ctx->dwCurTime-dwLastTime) / (1000 / 35); + sY = _ctx->stepY * (_ctx->dwCurTime-dwLastTime) / (1000 / 35); + + if (_ctx->lx > 0) { + _ctx->lx-=sX; if (_ctx->lx < 0) _ctx->lx = 0; + _ctx->pt.Offset(sX,0); + } else if (_ctx->lx < 0) { + _ctx->lx+=sX; if (_ctx->lx > 0) _ctx->lx = 0; + _ctx->pt.Offset(-sX,0); } - if (ly > 0) { - ly-=sY; if (ly<0) ly = 0; - pt.Offset(0,sY); - } else if (ly<0) { - ly+=sY; if (ly > 0) ly = 0; - pt.Offset(0,-sY); + if (_ctx->ly > 0) { + _ctx->ly-=sY; if (_ctx->ly<0) _ctx->ly = 0; + _ctx->pt.Offset(0,sY); + } else if (_ctx->ly<0) { + _ctx->ly+=sY; if (_ctx->ly > 0) _ctx->ly = 0; + _ctx->pt.Offset(0,-sY); } */ - WaitFrame(); + CORO_INVOKE_0(WaitFrame); Freeze(); - Loc->SetScrollPosition(pt); - Tony->SetScrollPosition(pt); + Loc->SetScrollPosition(_ctx->pt); + Tony->SetScrollPosition(_ctx->pt); Unfreeze(); } @@ -1443,22 +1474,23 @@ DECLARE_CUSTOM_FUNCTION(SyncScrollLocation)(CORO_PARAM, uint32 nX, uint32 nY, ui // Setta la posizione finale if (sX) { - if (lx > 0) - pt.x = startpt.x + dimx; + if (_ctx->lx > 0) + _ctx->pt.x = _ctx->startpt.x + _ctx->dimx; else - pt.x = startpt.x - dimx; + _ctx->pt.x = _ctx->startpt.x - _ctx->dimx; } else { - if (ly > 0) - pt.y = startpt.y + dimy; + if (_ctx->ly > 0) + _ctx->pt.y = _ctx->startpt.y + _ctx->dimy; else - pt.y = startpt.y - dimy; - + _ctx->pt.y = _ctx->startpt.y - _ctx->dimy; } Freeze(); - Loc->SetScrollPosition(pt); - Tony->SetScrollPosition(pt); + Loc->SetScrollPosition(_ctx->pt); + Tony->SetScrollPosition(_ctx->pt); Unfreeze(); + + CORO_END_CODE; } @@ -1484,7 +1516,7 @@ DECLARE_CUSTOM_FUNCTION(ChangeHotspot)(CORO_PARAM, uint32 dwCode, uint32 nX, uin DECLARE_CUSTOM_FUNCTION(AutoSave)(CORO_PARAM, uint32, uint32, uint32, uint32) { - _vm->AutoSave(); + _vm->AutoSave(coroParam); } DECLARE_CUSTOM_FUNCTION(Abort)(CORO_PARAM, uint32, uint32, uint32, uint32) { @@ -1492,33 +1524,41 @@ DECLARE_CUSTOM_FUNCTION(Abort)(CORO_PARAM, uint32, uint32, uint32, uint32) { } DECLARE_CUSTOM_FUNCTION(TremaSchermo)(CORO_PARAM, uint32 nScosse, uint32, uint32, uint32) { - uint32 i; - uint32 curTime = _vm->GetTime(); - int dirx,diry; + CORO_BEGIN_CONTEXT; + uint32 i; + uint32 curTime; + int dirx,diry; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + _ctx->curTime = _vm->GetTime(); - dirx = 1; - diry = 1; + _ctx->dirx = 1; + _ctx->diry = 1; - while (_vm->GetTime() < curTime + nScosse) { - WaitFrame(); + while (_vm->GetTime() < _ctx->curTime + nScosse) { + CORO_INVOKE_0(WaitFrame); Freeze(); - Loc->SetFixedScroll(RMPoint(1 * dirx, 1 * diry)); - Tony->SetFixedScroll(RMPoint(1 * dirx, 1 * diry)); + Loc->SetFixedScroll(RMPoint(1 * _ctx->dirx, 1 * _ctx->diry)); + Tony->SetFixedScroll(RMPoint(1 * _ctx->dirx, 1 * _ctx->diry)); Unfreeze(); - i = _vm->_randomSource.getRandomNumber(2); + _ctx->i = _vm->_randomSource.getRandomNumber(2); - if (i == 0 || i == 2) - dirx = -dirx; - else if (i == 1 || i == 2) - diry = -diry; + if (_ctx->i == 0 || _ctx->i == 2) + _ctx->dirx = -_ctx->dirx; + else if (_ctx->i == 1 || _ctx->i == 2) + _ctx->diry = -_ctx->diry; } Freeze(); Loc->SetFixedScroll(RMPoint(0, 0)); Tony->SetFixedScroll(RMPoint(0, 0)); Unfreeze(); + + CORO_END_CODE; } @@ -1607,7 +1647,7 @@ DECLARE_CUSTOM_FUNCTION(CharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMess if (bIsBack) { curBackText = _ctx->text = new RMTextDialogScrolling(Loc); if (bTonyIsSpeaking) - curBackText->Hide(); + CORO_INVOKE_0(curBackText->Hide); } else _ctx->text = new RMTextDialog; @@ -1649,7 +1689,7 @@ DECLARE_CUSTOM_FUNCTION(CharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMess // Aspetta la fine della visualizzazione _ctx->text->SetCustomSkipHandle(hSkipIdle); - _ctx->text->WaitForEndDisplay(); + CORO_INVOKE_0(_ctx->text->WaitForEndDisplay); if (_ctx->curVoc) { _ctx->voice->Stop(); @@ -1769,13 +1809,22 @@ DECLARE_CUSTOM_FUNCTION(MCharSetAlwaysBack)(CORO_PARAM, uint32 nChar, uint32 bAl DECLARE_CUSTOM_FUNCTION(MCharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMessage, uint32 bIsBack, uint32 nFont) { - RMMessage msg(dwMessage); - int i; - int parm; - RMPoint pt; - HANDLE h; - RMTextDialog *text; - int curOffset = 0; + CORO_BEGIN_CONTEXT; + RMMessage *msg; + int i; + int parm; + RMPoint pt; + uint32 h; + RMTextDialog *text; + int curOffset; + VoiceHeader *curVoc; + FPSFX *voice; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + _ctx->msg = new RMMessage(dwMessage); + _ctx->curOffset = 0; assert(nChar < 10); @@ -1783,99 +1832,103 @@ DECLARE_CUSTOM_FUNCTION(MCharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMes // Calcola la posizione del testo in base al frame corrente if (MCharacter[nChar].x==-1) - pt=MCharacter[nChar].item->CalculatePos()-RMPoint(-60,20)-Loc->ScrollPosition(); + _ctx->pt=MCharacter[nChar].item->CalculatePos()-RMPoint(-60,20)-Loc->ScrollPosition(); else - pt=RMPoint(MCharacter[nChar].x,MCharacter[nChar].y); + _ctx->pt=RMPoint(MCharacter[nChar].x,MCharacter[nChar].y); // Parametro per le azioni speciali: random tra le parlate - parm = (MCharacter[nChar].curgroup * 10) + _vm->_randomSource.getRandomNumber( + _ctx->parm = (MCharacter[nChar].curgroup * 10) + _vm->_randomSource.getRandomNumber( MCharacter[nChar].numtalks[MCharacter[nChar].curgroup] - 1) + 1; // Cerca di eseguire la funzione custom per inizializzare la parlata if (MCharacter[nChar].item) { - h = mpalQueryDoAction(30,MCharacter[nChar].item->MpalCode(), parm); - if (h != INVALID_HANDLE_VALUE) - WaitForSingleObject(h,INFINITE); + _ctx->h = mpalQueryDoActionU32(30, MCharacter[nChar].item->MpalCode(), _ctx->parm); + if (_ctx->h != INVALID_PID_VALUE) { + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); + } } - 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 g_system->lockMutex(vdb); // fseek(_vm->m_vdbFP, curVoc->offset, SEEK_SET); - _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++) { // Crea l'oggetto diverso se è back o no if (bIsBack) { - curBackText=text = new RMTextDialogScrolling(Loc); + curBackText=_ctx->text = new RMTextDialogScrolling(Loc); if (bTonyIsSpeaking) - curBackText->Hide(); + CORO_INVOKE_0(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(MCharacter[nChar].r,MCharacter[nChar].g,MCharacter[nChar].b); + _ctx->text->SetColor(MCharacter[nChar].r,MCharacter[nChar].g,MCharacter[nChar].b); // Scrive il testo - text->WriteText(msg[i],nFont); + _ctx->text->WriteText((*_ctx->msg)[_ctx->i], nFont); // 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); + CORO_INVOKE_0(_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; + curBackText = NULL; + delete _ctx->text; + delete _ctx->msg; } // Cerca di eseguire la funzione custom per chiudere la parlata if (MCharacter[nChar].item) { - h = mpalQueryDoAction(31,MCharacter[nChar].item->MpalCode(),parm); - if (h!=INVALID_HANDLE_VALUE) - WaitForSingleObject(h,INFINITE); + _ctx->h = mpalQueryDoActionU32(31, MCharacter[nChar].item->MpalCode(), _ctx->parm); + if (_ctx->h != INVALID_PID_VALUE) + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); } + + CORO_END_CODE; } @@ -1894,7 +1947,7 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg LPSTR string; RMTextDialog *text; int parm; - HANDLE h; + uint32 h; bool bIsBack; VoiceHeader *curVoc; FPSFX *voice; @@ -1968,12 +2021,10 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg _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(); + _ctx->pt = MCharacter[nPers].item->CalculatePos() - RMPoint(-60, 20) - Loc->ScrollPosition(); else - pt = RMPoint(MCharacter[nPers].x, MCharacter[nPers].y); + _ctx->pt = RMPoint(MCharacter[nPers].x, MCharacter[nPers].y); // Parametro per le azioni speciali: random tra le parlate _ctx->parm = (MCharacter[nPers].curgroup * 10) + _vm->_randomSource.getRandomNumber( @@ -1983,9 +2034,9 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg MCharacter[nPers].numtexts--; } else { // Cerca di eseguire la funzione custom per inizializzare la parlata - _ctx->h = mpalQueryDoAction(30, MCharacter[nPers].item->MpalCode(), _ctx->parm); - if (_ctx->h != INVALID_HANDLE_VALUE) - WaitForSingleObject(_ctx->h,INFINITE); + _ctx->h = mpalQueryDoActionU32(30, MCharacter[nPers].item->MpalCode(), _ctx->parm); + if (_ctx->h != INVALID_PID_VALUE) + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); MCharacter[nPers].curTalk = _ctx->parm; @@ -1998,7 +2049,8 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg if (MCharacter[nPers].bAlwaysBack) { _ctx->text = curBackText = new RMTextDialogScrolling(Loc); if (bTonyIsSpeaking) - curBackText->Hide(); + CORO_INVOKE_0(curBackText->Hide); + _ctx->bIsBack = true; } else _ctx->text = new RMTextDialog; @@ -2006,7 +2058,7 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg _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); + _ctx->text->SetPosition(_ctx->pt); } if (!bSkipIdle) { @@ -2022,7 +2074,7 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg // Aspetta la fine della visualizzazione _ctx->text->SetCustomSkipHandle(hSkipIdle); - _ctx->text->WaitForEndDisplay(); + CORO_INVOKE_0(_ctx->text->WaitForEndDisplay); } if (_ctx->curVoc) { @@ -2046,9 +2098,9 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg 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; - _ctx->h = mpalQueryDoAction(31,MCharacter[nPers].item->MpalCode(),MCharacter[nPers].curTalk); - if (_ctx->h!=INVALID_HANDLE_VALUE) - WaitForSingleObject(_ctx->h,INFINITE); + _ctx->h = mpalQueryDoActionU32(31,MCharacter[nPers].item->MpalCode(),MCharacter[nPers].curTalk); + if (_ctx->h != INVALID_PID_VALUE) + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); MCharacter[nPers].bInTexts = false; MCharacter[nPers].numtexts = 0; @@ -2121,14 +2173,14 @@ DECLARE_CUSTOM_FUNCTION(StartDialog)(CORO_PARAM, uint32 nDialog, uint32 nStartGr // Attiva l'oggetto LinkGraphicTask(&_ctx->dc); - _ctx->dc.Show(); + CORO_INVOKE_0(_ctx->dc.Show); // Disegna il puntatore Pointer->SetSpecialPointer(Pointer->PTR_NONE); MainShowMouse(); while (!(Input->MouseLeftClicked() && ((_ctx->sel = _ctx->dc.GetSelection()) != -1))) { - WaitFrame(); + CORO_INVOKE_0(WaitFrame); Freeze(); _ctx->dc.DoFrame(Input->MousePos()); Unfreeze(); @@ -2137,7 +2189,7 @@ DECLARE_CUSTOM_FUNCTION(StartDialog)(CORO_PARAM, uint32 nDialog, uint32 nStartGr // Nascondi il puntatore MainHideMouse(); - _ctx->dc.Hide(); + CORO_INVOKE_0(_ctx->dc.Hide); mpalQueryDialogSelectionU32(_ctx->nChoice, _ctx->sl[_ctx->sel]); // Chiude la scelta @@ -2162,7 +2214,8 @@ DECLARE_CUSTOM_FUNCTION(StartDialog)(CORO_PARAM, uint32 nDialog, uint32 nStartGr DECLARE_CUSTOM_FUNCTION(TakeOwnership)(CORO_PARAM, uint32 num, uint32, uint32, uint32) { // EnterCriticalSection(&cs[num]); - WaitForSingleObject(mut[num],INFINITE); +// WaitForSingleObject(mut[num],INFINITE); + warning("TODO"); } DECLARE_CUSTOM_FUNCTION(ReleaseOwnership)(CORO_PARAM, uint32 num, uint32, uint32, uint32) { @@ -2197,33 +2250,50 @@ int curSonoriz = 0; bool bFadeOutStop; -void ThreadFadeInMusic(void *nMusic) { - int i; - int nChannel = (int)nMusic; +void ThreadFadeInMusic(CORO_PARAM, const void *nMusic) { + CORO_BEGIN_CONTEXT; + int i; + CORO_END_CONTEXT(_ctx); + + int nChannel = *(const int *)nMusic; + + CORO_BEGIN_CODE(_ctx); debug("Start FadeIn Music\n"); - for (i = 0; i < 16; i++) { - _vm->SetMusicVolume(nChannel, i * 4); - Sleep(100); + for (_ctx->i = 0; _ctx->i < 16; _ctx->i++) { + _vm->SetMusicVolume(nChannel, _ctx->i * 4); + + CORO_INVOKE_1(g_scheduler->sleep, 100); } _vm->SetMusicVolume(nChannel, 64); debug("End FadeIn Music\n"); - _endthread(); + + CORO_KILL_SELF(); + + CORO_END_CODE; } -void ThreadFadeOutMusic(void *nMusic) { - int i; - int nChannel = (int)nMusic; - int startVolume = _vm->GetMusicVolume(nChannel); +void ThreadFadeOutMusic(CORO_PARAM, const void *nMusic) { + CORO_BEGIN_CONTEXT; + int i; + int startVolume; + CORO_END_CONTEXT(_ctx); + + int nChannel = *(const int *)nMusic; + + CORO_BEGIN_CODE(_ctx); + + _ctx->startVolume = _vm->GetMusicVolume(nChannel); debug("Start FadeOut Music\n"); - for (i = 16; i > 0 && !bFadeOutStop; i--) { - if (i * 4 < startVolume) - _vm->SetMusicVolume(nChannel, i * 4); - Sleep(100); + for (_ctx->i = 16; _ctx->i > 0 && !bFadeOutStop; _ctx->i--) { + if (_ctx->i * 4 < _ctx->startVolume) + _vm->SetMusicVolume(nChannel, _ctx->i * 4); + + CORO_INVOKE_1(g_scheduler->sleep, 100); } if (!bFadeOutStop) @@ -2235,25 +2305,29 @@ void ThreadFadeOutMusic(void *nMusic) { debug("End FadeOut Music\n"); - _endthread(); + CORO_KILL_SELF(); + + CORO_END_CODE; } DECLARE_CUSTOM_FUNCTION(FadeInSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) { - _beginthread(ThreadFadeInMusic, 10240, (void*)curSonoriz); + g_scheduler->createProcess(ThreadFadeInMusic, &curSonoriz, sizeof(int)); } DECLARE_CUSTOM_FUNCTION(FadeOutSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) { bFadeOutStop = false; - _beginthread(ThreadFadeOutMusic, 10240, (void *)curSonoriz); + g_scheduler->createProcess(ThreadFadeOutMusic, &curSonoriz, sizeof(int)); } DECLARE_CUSTOM_FUNCTION(FadeOutStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) { bFadeOutStop = false; - _beginthread(ThreadFadeOutMusic, 10240, (void*)2); + int channel = 2; + g_scheduler->createProcess(ThreadFadeOutMusic, &channel, sizeof(int)); } DECLARE_CUSTOM_FUNCTION(FadeInStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) { - _beginthread(ThreadFadeInMusic, 10240, (void*)2); + int channel = 2; + g_scheduler->createProcess(ThreadFadeInMusic, &channel, sizeof(int)); } DECLARE_CUSTOM_FUNCTION(StopSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) { @@ -2475,12 +2549,12 @@ DECLARE_CUSTOM_FUNCTION(StacchettoFadeEnd)(CORO_PARAM, uint32 nStacc, uint32 bLo DECLARE_CUSTOM_FUNCTION(MustSkipIdleStart)(CORO_PARAM, uint32, uint32, uint32, uint32) { bSkipIdle = true; - SetEvent(hSkipIdle); + g_scheduler->setEvent(hSkipIdle); } DECLARE_CUSTOM_FUNCTION(MustSkipIdleEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) { bSkipIdle = false; - ResetEvent(hSkipIdle); + g_scheduler->resetEvent(hSkipIdle); } DECLARE_CUSTOM_FUNCTION(PatIrqFreeze)(CORO_PARAM, uint32 bStatus, uint32, uint32, uint32) { @@ -2488,70 +2562,94 @@ DECLARE_CUSTOM_FUNCTION(PatIrqFreeze)(CORO_PARAM, uint32 bStatus, uint32, uint32 } DECLARE_CUSTOM_FUNCTION(OpenInitLoadMenu)(CORO_PARAM, uint32, uint32, uint32, uint32) { + CORO_BEGIN_CONTEXT; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + Freeze(); - _vm->OpenInitLoadMenu(); + CORO_INVOKE_0(_vm->OpenInitLoadMenu); Unfreeze(); + + CORO_END_CODE; } DECLARE_CUSTOM_FUNCTION(OpenInitOptions)(CORO_PARAM, uint32, uint32, uint32, uint32) { + CORO_BEGIN_CONTEXT; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + Freeze(); - _vm->OpenInitOptions(); + CORO_INVOKE_0(_vm->OpenInitOptions); Unfreeze(); + + CORO_END_CODE; } DECLARE_CUSTOM_FUNCTION(DoCredits)(CORO_PARAM, uint32 nMsg, uint32 dwTime, uint32, uint32) { - RMMessage msg(nMsg); - RMTextDialog *text; - HANDLE hDisable = CreateEvent(NULL, true, false, NULL); - int i; - uint32 startTime; + CORO_BEGIN_CONTEXT; + RMMessage *msg; + RMTextDialog *text; + uint32 hDisable; + int i; + uint32 startTime; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + _ctx->msg = new RMMessage(nMsg); + _ctx->hDisable = g_scheduler->createEvent(true, false); - text = new RMTextDialog[msg.NumPeriods()]; + _ctx->text = new RMTextDialog[_ctx->msg->NumPeriods()]; - for (i = 0; i < msg.NumPeriods(); i++) { - text[i].SetInput(Input); + for (_ctx->i = 0; _ctx->i < _ctx->msg->NumPeriods(); _ctx->i++) { + _ctx->text[_ctx->i].SetInput(Input); // Allineamento - if (msg[i][0] == '@') { - text[i].SetAlignType(RMText::HCENTER, RMText::VTOP); - text[i].WriteText(&msg[i][1], 3); - text[i].SetPosition(RMPoint(414, 70 + i * 26)); // 70 + if ((*_ctx->msg)[_ctx->i][0] == '@') { + _ctx->text[_ctx->i].SetAlignType(RMText::HCENTER, RMText::VTOP); + _ctx->text[_ctx->i].WriteText(_ctx->msg[_ctx->i][1], 3); + _ctx->text[_ctx->i].SetPosition(RMPoint(414, 70 + _ctx->i * 26)); // 70 } else { - text[i].SetAlignType(RMText::HLEFT,RMText::VTOP); - text[i].WriteText(msg[i], 3); - text[i].SetPosition(RMPoint(260, 70 + i * 26)); + _ctx->text[_ctx->i].SetAlignType(RMText::HLEFT,RMText::VTOP); + _ctx->text[_ctx->i].WriteText((*_ctx->msg)[_ctx->i], 3); + _ctx->text[_ctx->i].SetPosition(RMPoint(260, 70 + _ctx->i * 26)); } // Setta la posizione - text[i].SetAlwaysDisplay(); - text[i].SetForcedTime(dwTime * 1000); - text[i].SetNoTab(); + _ctx->text[_ctx->i].SetAlwaysDisplay(); + _ctx->text[_ctx->i].SetForcedTime(dwTime * 1000); + _ctx->text[_ctx->i].SetNoTab(); // Aspetta la fine della visualizzazione - text[i].SetCustomSkipHandle(hDisable); + _ctx->text[_ctx->i].SetCustomSkipHandle(_ctx->hDisable); // Registra il testo - LinkGraphicTask(&text[i]); + LinkGraphicTask(&_ctx->text[_ctx->i]); } - startTime = _vm->GetTime(); + _ctx->startTime = _vm->GetTime(); - while (startTime + dwTime * 1000 > _vm->GetTime()) { - WaitFrame(); + while (_ctx->startTime + dwTime * 1000 > _vm->GetTime()) { + CORO_INVOKE_0(WaitFrame); if (Input->MouseLeftClicked() || Input->MouseRightClicked()) break; if ((GetAsyncKeyState(Common::KEYCODE_TAB) & 0x8001) == 0x8001) break; } - SetEvent(hDisable); + g_scheduler->setEvent(_ctx->hDisable); + + CORO_INVOKE_0(WaitFrame); + CORO_INVOKE_0(WaitFrame); - WaitFrame(); - WaitFrame(); + delete[] _ctx->text; + delete _ctx->msg; - delete[] text; + CORO_END_CODE; } @@ -2776,7 +2874,7 @@ void SetupGlobalVars(RMTony *tony, RMPointer *ptr, RMGameBoxes *box, RMLocation // Crea l'evento per skippare le idle - hSkipIdle = CreateEvent(NULL, true, false, NULL); + hSkipIdle = g_scheduler->createEvent(true, false); } } // end of namespace Tony diff --git a/engines/tony/font.cpp b/engines/tony/font.cpp index 28e8f14d38..d04e1f0a13 100644 --- a/engines/tony/font.cpp +++ b/engines/tony/font.cpp @@ -2048,23 +2048,23 @@ RMTextDialog::RMTextDialog() : RMText() { m_bForceNoTime = false; m_bAlwaysDisplay = false; m_bNoTab = false; - hCustomSkip = INVALID_HANDLE_VALUE; - hCustomSkip2 = INVALID_HANDLE_VALUE; + hCustomSkip = INVALID_PID_VALUE; + hCustomSkip2 = INVALID_PID_VALUE; m_input = NULL; // Crea l'evento di fine displaying - hEndDisplay = CreateEvent(NULL, false, false, NULL); + hEndDisplay = g_scheduler->createEvent(false, false); } RMTextDialog::~RMTextDialog() { - CloseHandle(hEndDisplay); + g_scheduler->closeEvent(hEndDisplay); } void RMTextDialog::Show(void) { m_bShowed = true; } -void RMTextDialog::Hide(void) { +void RMTextDialog::Hide(CORO_PARAM) { m_bShowed = false; } @@ -2084,7 +2084,7 @@ void RMTextDialog::WriteText(RMString text, RMFontColor *font, int *time) { void RMTextDialog::SetSkipStatus(bool bEnabled) { - m_bSkipStatus=bEnabled; + m_bSkipStatus = bEnabled; } void RMTextDialog::ForceTime(void) { @@ -2107,53 +2107,70 @@ void RMTextDialog::SetAlwaysDisplay(void) { m_bAlwaysDisplay = true; } -bool RMTextDialog::RemoveThis(void) { +void RMTextDialog::RemoveThis(CORO_PARAM, bool &result) { + CORO_BEGIN_CONTEXT; + bool expired; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + // Presume successful result + result = true; + // Frase NON di background if (m_bSkipStatus) { - if (!(bCfgDubbing && hCustomSkip2 != INVALID_HANDLE_VALUE)) + if (!(bCfgDubbing && hCustomSkip2 != INVALID_PID_VALUE)) if (bCfgTimerizedText) { if (!m_bForceNoTime) if (_vm->GetTime() > (uint32)m_time + m_startTime) - return true; + return; } if (!m_bNoTab) if ((GetAsyncKeyState(Common::KEYCODE_TAB) & 0x8001) == 0x8001) - return true; + return; if (!m_bNoTab) if (m_input) if (m_input->MouseLeftClicked() || m_input->MouseRightClicked()) - return true; + return; } // Frase di background else { - if (!(bCfgDubbing && hCustomSkip2 != INVALID_HANDLE_VALUE)) + if (!(bCfgDubbing && hCustomSkip2 != INVALID_PID_VALUE)) if (!m_bForceNoTime) if (_vm->GetTime() > (uint32)m_time + m_startTime) - return true; + return; } // Se il tempo è forzato if (m_bForceTime) if (_vm->GetTime() > (uint32)m_time + m_startTime) - return true; + return; - if (hCustomSkip != INVALID_HANDLE_VALUE) - if (WaitForSingleObject(hCustomSkip, 0) == WAIT_OBJECT_0) - return true; + if (hCustomSkip != INVALID_PID_VALUE) { + CORO_INVOKE_3(g_scheduler->waitForSingleObject, hCustomSkip, 0, &_ctx->expired); + // == WAIT_OBJECT_0 + if (!_ctx->expired) + return; + } + + if (bCfgDubbing && hCustomSkip2 != INVALID_PID_VALUE) { + CORO_INVOKE_3(g_scheduler->waitForSingleObject, hCustomSkip2, 0, &_ctx->expired); + // == WAIT_OBJECT_0 + if (!_ctx->expired) + return; + } - if (bCfgDubbing && hCustomSkip2 != INVALID_HANDLE_VALUE) - if (WaitForSingleObject(hCustomSkip2,0) == WAIT_OBJECT_0) - return true; + result = false; - return false; + CORO_END_CODE; } void RMTextDialog::Unregister(void) { RMGfxTask::Unregister(); assert(m_nInList == 0); - SetEvent(hEndDisplay); + g_scheduler->setEvent(hEndDisplay); } void RMTextDialog::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) { @@ -2168,16 +2185,16 @@ void RMTextDialog::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) { } } -void RMTextDialog::SetCustomSkipHandle(HANDLE hCustom) { +void RMTextDialog::SetCustomSkipHandle(uint32 hCustom) { hCustomSkip = hCustom; } -void RMTextDialog::SetCustomSkipHandle2(HANDLE hCustom) { +void RMTextDialog::SetCustomSkipHandle2(uint32 hCustom) { hCustomSkip2 = hCustom; } -void RMTextDialog::WaitForEndDisplay(void) { - WaitForSingleObject(hEndDisplay, INFINITE); +void RMTextDialog::WaitForEndDisplay(CORO_PARAM) { + g_scheduler->waitForSingleObject(coroParam, hEndDisplay, INFINITE); } void RMTextDialog::SetInput(RMInput *input) { @@ -2231,9 +2248,16 @@ RMTextItemName::~RMTextItemName() { } -void RMTextItemName::DoFrame(RMGfxTargetBuffer& bigBuf, RMLocation &loc, RMPointer &ptr, RMInventory &inv) { - RMString itemName; - RMItem *lastItem = m_item; +void RMTextItemName::DoFrame(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMLocation &loc, RMPointer &ptr, RMInventory &inv) { + CORO_BEGIN_CONTEXT; + RMString itemName; + RMItem *lastItem; + uint32 hThread; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + _ctx->lastItem = m_item; // Si aggiunge alla lista se c'e' bisogno if (!m_nInList) @@ -2248,27 +2272,29 @@ void RMTextItemName::DoFrame(RMGfxTargetBuffer& bigBuf, RMLocation &loc, RMPoint else m_item = loc.WhichItemIsIn(m_mpos); - itemName = ""; + _ctx->itemName = ""; // Si fa dare il nuovo nome if (m_item != NULL) - m_item->GetName(itemName); + m_item->GetName(_ctx->itemName); // Se lo scrive - WriteText(itemName, 1); + WriteText(_ctx->itemName, 1); // Se e' diverso dal precedente, e' il caso di aggiornare anche il puntatore con la WhichPointer - if (lastItem != m_item) { + if (_ctx->lastItem != m_item) { if (m_item == NULL) ptr.SetSpecialPointer(RMPointer::PTR_NONE); else { - HANDLE hThread = mpalQueryDoAction(20, m_item->MpalCode(), 0); - if (hThread == INVALID_HANDLE_VALUE) + _ctx->hThread = mpalQueryDoActionU32(20, m_item->MpalCode(), 0); + if (_ctx->hThread == INVALID_PID_VALUE) ptr.SetSpecialPointer(RMPointer::PTR_NONE); else - WaitForSingleObject(hThread,INFINITE); + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->hThread, INFINITE); } } + + CORO_END_CODE; } @@ -2318,18 +2344,18 @@ RMDialogChoice::RMDialogChoice() { DlgText.LoadPaletteWA(dlgpal); DlgTextLine.LoadPaletteWA(dlgpal); - hUnreg=CreateEvent(NULL, false, false, NULL); + hUnreg = g_scheduler->createEvent(false, false); bRemoveFromOT = false; } RMDialogChoice::~RMDialogChoice() { - CloseHandle(hUnreg); + g_scheduler->closeEvent(hUnreg); } void RMDialogChoice::Unregister(void) { RMGfxWoodyBuffer::Unregister(); assert(!m_nInList); - PulseEvent(hUnreg); + g_scheduler->pulseEvent(hUnreg); bRemoveFromOT = false; } @@ -2444,7 +2470,16 @@ void RMDialogChoice::SetSelected(int pos) { m_curSelection = pos; } -void RMDialogChoice::Show(RMGfxTargetBuffer *bigBuf) { +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); + Prepare(); m_bShow = false; @@ -2454,30 +2489,28 @@ void RMDialogChoice::Show(RMGfxTargetBuffer *bigBuf) { if (0) { m_bShow = true; } else { - RMPoint destpt; - int deltay; - int starttime = _vm->GetTime(); - int elaps; - - deltay=480 - m_ptDrawPos.y; - destpt = m_ptDrawPos; + _ctx->starttime = _vm->GetTime(); + _ctx->deltay = 480 - m_ptDrawPos.y; + _ctx->destpt = m_ptDrawPos; m_ptDrawPos.Set(0, 480); if (!m_nInList && bigBuf != NULL) bigBuf->AddPrim(new RMGfxPrimitive(this)); m_bShow = true; - elaps = 0; - while (elaps < 700) { - MainWaitFrame(); + _ctx->elaps = 0; + while (_ctx->elaps < 700) { + CORO_INVOKE_0(MainWaitFrame); MainFreeze(); - elaps = _vm->GetTime() - starttime; - m_ptDrawPos.y = 480 - ((deltay * 100) / 700 * elaps) / 100; + _ctx->elaps = _vm->GetTime() - _ctx->starttime; + m_ptDrawPos.y = 480 - ((_ctx->deltay * 100) / 700 * _ctx->elaps) / 100; MainUnfreeze(); } - m_ptDrawPos.y = destpt.y; + m_ptDrawPos.y = _ctx->destpt.y; } + + CORO_END_CODE; } void RMDialogChoice::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) { @@ -2489,26 +2522,34 @@ void RMDialogChoice::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) { } -void RMDialogChoice::Hide(void) { - if (1) { +void RMDialogChoice::Hide(CORO_PARAM) { + CORO_BEGIN_CONTEXT; int deltay; - int starttime = _vm->GetTime(); + int starttime; int elaps; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); - deltay=480 - m_ptDrawPos.y; - elaps = 0; - while (elaps < 700) { - MainWaitFrame(); + if (1) { + _ctx->starttime = _vm->GetTime(); + + _ctx->deltay = 480 - m_ptDrawPos.y; + _ctx->elaps = 0; + while (_ctx->elaps < 700) { + CORO_INVOKE_0(MainWaitFrame); MainFreeze(); - elaps=_vm->GetTime()-starttime; - m_ptDrawPos.y=480-((deltay*100)/700*(700-elaps))/100; + _ctx->elaps = _vm->GetTime()-_ctx->starttime; + m_ptDrawPos.y = 480 - ((_ctx->deltay * 100) / 700 * (700 - _ctx->elaps)) / 100; MainUnfreeze(); } } m_bShow = false; bRemoveFromOT = true; - WaitForSingleObject(hUnreg, INFINITE); + CORO_INVOKE_2(g_scheduler->waitForSingleObject, hUnreg, INFINITE); + + CORO_END_CODE; } diff --git a/engines/tony/font.h b/engines/tony/font.h index 3012502d4c..0306c6c673 100644 --- a/engines/tony/font.h +++ b/engines/tony/font.h @@ -51,6 +51,7 @@ #include "common/system.h" #include "tony/gfxcore.h" #include "tony/resid.h" +#include "tony/sched.h" namespace Tony { @@ -247,12 +248,12 @@ class RMTextDialog : public RMText { int m_time; bool m_bSkipStatus; RMPoint dst; - HANDLE hEndDisplay; + uint32 hEndDisplay; bool m_bShowed; bool m_bForceTime; bool m_bForceNoTime; - HANDLE hCustomSkip; - HANDLE hCustomSkip2; + uint32 hCustomSkip; + uint32 hCustomSkip2; RMInput *m_input; bool m_bAlwaysDisplay; bool m_bNoTab; @@ -267,7 +268,7 @@ class RMTextDialog : public RMText { // Overloading della funzione ereditata da RMGfxTask per decidere // quando eliminare un oggetto dalla OTLIST - virtual bool RemoveThis(void); + virtual void RemoveThis(CORO_PARAM, bool &result); // Overloading della funzione di deregistrazione, utilizzata per capire // quando ci leviamo di torno @@ -280,9 +281,9 @@ class RMTextDialog : public RMText { void SetPosition(RMPoint pt) { dst=pt; } // Aspetta che venga finita la visualizzazione - void WaitForEndDisplay(void); - void SetCustomSkipHandle(HANDLE hCustomSkip); - void SetCustomSkipHandle2(HANDLE hCustomSkip); + void WaitForEndDisplay(CORO_PARAM); + void SetCustomSkipHandle(uint32 hCustomSkip); + void SetCustomSkipHandle2(uint32 hCustomSkip); void SetSkipStatus(bool bEnabled); void SetForcedTime(uint32 dwTime); void SetNoTab(void); @@ -294,7 +295,7 @@ class RMTextDialog : public RMText { void SetInput(RMInput* input); void Show(void); - void Hide(void); + void Hide(CORO_PARAM); }; class RMTextDialogScrolling : public RMTextDialog { @@ -332,7 +333,7 @@ public: void SetMouseCoord(RMPoint m) { m_mpos=m; } - void DoFrame(RMGfxTargetBuffer &bigBuf, RMLocation &loc, RMPointer &ptr, RMInventory &inv); + void DoFrame(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMLocation &loc, RMPointer &ptr, RMInventory &inv); virtual void Draw(RMGfxTargetBuffer& bigBuf, RMGfxPrimitive* prim); RMPoint GetHotspot(); @@ -358,7 +359,7 @@ private: RMGfxSourceBuffer8 DlgText; RMGfxSourceBuffer8 DlgTextLine; RMPoint m_ptDrawPos; - HANDLE hUnreg; + uint32 hUnreg; bool bRemoveFromOT; protected: @@ -389,8 +390,8 @@ public: // Mostra e nasconde la scelta, con eventuali animazioni // NOTA: Se non viene passato parametro alla Show(), è obbligo del // chiamante assicurarsi che la classe venga inserita alla OTlist - void Show(RMGfxTargetBuffer* bigBuf = NULL); - void Hide(void); + void Show(CORO_PARAM, RMGfxTargetBuffer* bigBuf = NULL); + void Hide(CORO_PARAM); // Polling di aggiornamento void DoFrame(RMPoint ptMousePos); diff --git a/engines/tony/game.cpp b/engines/tony/game.cpp index 4eef8b0c96..59196ec18a 100644 --- a/engines/tony/game.cpp +++ b/engines/tony/game.cpp @@ -112,8 +112,8 @@ void MainUnfreeze(void) { _vm->GetEngine()->Unfreeze(); } -void MainWaitFrame(void) { - WaitForSingleObject(_vm->m_hEndOfFrame, INFINITE); +void MainWaitFrame(CORO_PARAM) { + g_scheduler->waitForSingleObject(coroParam, _vm->m_hEndOfFrame, INFINITE); } void MainShowMouse(void) { @@ -144,8 +144,8 @@ void MainCloseWipe(void) { _vm->GetEngine()->CloseWipe(); } -void MainWaitWipeEnd(void) { - _vm->GetEngine()->WaitWipeEnd(); +void MainWaitWipeEnd(CORO_PARAM) { + _vm->GetEngine()->WaitWipeEnd(coroParam); } void MainEnableGUI(void) { diff --git a/engines/tony/gfxengine.cpp b/engines/tony/gfxengine.cpp index acf6339e73..12de3573eb 100644 --- a/engines/tony/gfxengine.cpp +++ b/engines/tony/gfxengine.cpp @@ -65,10 +65,12 @@ extern bool bSkipSfxNoLoop; bool bIdleExited; -void ExitAllIdles(CORO_PARAM, int nCurLoc) { +void ExitAllIdles(CORO_PARAM, const void *param) { CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); + int nCurLoc = *(const int *)param; + CORO_BEGIN_CODE(_ctx); // Chiude le idle @@ -96,28 +98,27 @@ RMGfxEngine::~RMGfxEngine() { g_system->deleteMutex(csMainLoop); } -void RMGfxEngine::OpenOptionScreen(int type) { - bool bRes = false; - - switch (type) { - case 0: - bRes = m_opt.Init(m_bigBuf); - break; - case 1: - bRes = m_opt.InitLoadMenuOnly(m_bigBuf,true); - break; - case 2: - bRes = m_opt.InitNoLoadSave(m_bigBuf); - break; - case 3: - bRes = m_opt.InitLoadMenuOnly(m_bigBuf,false); - break; - case 4: - bRes = m_opt.InitSaveMenuOnly(m_bigBuf,false); - break; - } +void RMGfxEngine::OpenOptionScreen(CORO_PARAM, int type) { + CORO_BEGIN_CONTEXT; + bool bRes; + CORO_END_CONTEXT(_ctx); - if (bRes) { + CORO_BEGIN_CODE(_ctx); + + _ctx->bRes = false; + + if (type == 0) + _ctx->bRes = m_opt.Init(m_bigBuf); + else if (type == 1) + _ctx->bRes = m_opt.InitLoadMenuOnly(m_bigBuf, true); + else if (type == 2) + _ctx->bRes = m_opt.InitNoLoadSave(m_bigBuf); + else if (type == 3) + _ctx->bRes = m_opt.InitLoadMenuOnly(m_bigBuf, false); + else if (type == 4) + _ctx->bRes = m_opt.InitSaveMenuOnly(m_bigBuf, false); + + if (_ctx->bRes) { _vm->PauseSound(true); DisableInput(); @@ -135,16 +136,23 @@ void RMGfxEngine::OpenOptionScreen(int type) { if (type == 1 || type == 2) { bIdleExited = true; } else { - m_tony.StopNoAction(); + CORO_INVOKE_0(m_tony.StopNoAction); - uint32 id; bIdleExited = false; - CreateThread(NULL, 10240, (LPTHREAD_START_ROUTINE)ExitAllIdles, (void *)m_nCurLoc, 0, &id); + + g_scheduler->createProcess(ExitAllIdles, &m_nCurLoc, sizeof(int)); } } + + CORO_END_CODE; } -void RMGfxEngine::DoFrame(bool bDrawLocation) { +void RMGfxEngine::DoFrame(CORO_PARAM, bool bDrawLocation) { + CORO_BEGIN_CONTEXT; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + g_system->lockMutex(csMainLoop); // Poll dei dispositivi di input @@ -212,15 +220,15 @@ void RMGfxEngine::DoFrame(bool bDrawLocation) { if (m_bGUIOption) { if (!m_tony.InAction() && m_bInput) { if ((m_input.MouseLeftClicked() && m_input.MousePos().x < 3 && m_input.MousePos().y < 3)) { - OpenOptionScreen(0); + OpenOptionScreen(nullContext, 0); goto SKIPCLICKSINISTRO; } else if ((GetAsyncKeyState(Common::KEYCODE_ESCAPE)&0x8001) == 0x8001) - OpenOptionScreen(0); + OpenOptionScreen(nullContext, 0); else if (_vm->getIsDemo()) { if ((GetAsyncKeyState(Common::KEYCODE_F3) & 0x8001) == 0x8001) - OpenOptionScreen(3); + OpenOptionScreen(nullContext, 3); else if ((GetAsyncKeyState(Common::KEYCODE_F2) & 0x8001) == 0x8001) - OpenOptionScreen(4); + OpenOptionScreen(nullContext, 4); } } } @@ -287,7 +295,7 @@ SKIPCLICKSINISTRO: // Aggiorna il nome sotto il puntatore del mouse m_itemName.SetMouseCoord(m_input.MousePos()); if (!m_inter.Active() && !m_inv.MiniActive()) - m_itemName.DoFrame(m_bigBuf,m_loc,m_point,m_inv); + CORO_INVOKE_4(m_itemName.DoFrame, m_bigBuf, m_loc, m_point, m_inv); } // Inventario & interfaccia @@ -325,7 +333,7 @@ SKIPCLICKSINISTRO: switch (m_nWipeType) { case 1: if (!(m_rcWipeEllipse.bottom - m_rcWipeEllipse.top >= FSTEP * 2)) { - SetEvent(m_hWipeEvent); + g_scheduler->setEvent(m_hWipeEvent); m_nWipeType = 3; break; } @@ -338,7 +346,7 @@ SKIPCLICKSINISTRO: case 2: if (!(m_rcWipeEllipse.bottom - m_rcWipeEllipse.top < 480 - FSTEP)) { - SetEvent(m_hWipeEvent); + g_scheduler->setEvent(m_hWipeEvent); m_nWipeType = 3; break; } @@ -352,6 +360,8 @@ SKIPCLICKSINISTRO: } g_system->unlockMutex(csMainLoop); + + CORO_END_CODE; } @@ -524,7 +534,7 @@ HANDLE RMGfxEngine::LoadLocation(int nLoc, RMPoint ptTonyStart, RMPoint start) { void RMGfxEngine::UnloadLocation(CORO_PARAM, bool bDoOnExit, HANDLE *result) { CORO_BEGIN_CONTEXT; - HANDLE h; + uint32 h; CORO_END_CONTEXT(_ctx); CORO_BEGIN_CODE(_ctx); @@ -534,9 +544,9 @@ void RMGfxEngine::UnloadLocation(CORO_PARAM, bool bDoOnExit, HANDLE *result) { // On Exit? if (bDoOnExit) { - _ctx->h = mpalQueryDoAction(1, m_nCurLoc, 0); - if (_ctx->h != INVALID_HANDLE_VALUE) - WaitForSingleObject(_ctx->h, INFINITE); + _ctx->h = mpalQueryDoActionU32(1, m_nCurLoc, 0); + if (_ctx->h != INVALID_PID_VALUE) + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); } MainFreeze(); @@ -588,7 +598,7 @@ void RMGfxEngine::Init(/*HINSTANCE hInst*/) { bIdleExited = false; m_bOption = false; m_bWiping = false; - m_hWipeEvent = CreateEvent(NULL, false, false, NULL); + m_hWipeEvent = g_scheduler->createEvent(false, false); // Crea l'evento di freeze csMainLoop = g_system->createMutex(); @@ -986,8 +996,8 @@ void RMGfxEngine::CloseWipe(void) { m_bWiping = false; } -void RMGfxEngine::WaitWipeEnd(void) { - WaitForSingleObject(m_hWipeEvent,INFINITE); +void RMGfxEngine::WaitWipeEnd(CORO_PARAM) { + g_scheduler->waitForSingleObject(coroParam, m_hWipeEvent, INFINITE); } } // End of namespace Tony diff --git a/engines/tony/gfxengine.h b/engines/tony/gfxengine.h index 42b2050046..11d591b408 100644 --- a/engines/tony/gfxengine.h +++ b/engines/tony/gfxengine.h @@ -85,7 +85,7 @@ private: OSystem::MutexRef csMainLoop; int m_nWipeType; - HANDLE m_hWipeEvent; + uint32 m_hWipeEvent; int m_nWipeStep; bool m_bMustEnterMenu; @@ -103,7 +103,7 @@ public: virtual ~RMGfxEngine(); // Draw the next frame - void DoFrame(bool bDrawLocation); + void DoFrame(CORO_PARAM, bool bDrawLocation); // Initialises the graphics engine void Init(); @@ -118,7 +118,7 @@ public: void GDIControl(bool bCon); // Warns when entering or exits the options menu - void OpenOptionScreen(int type); + void OpenOptionScreen(CORO_PARAM, int type); // Enables or disables mouse input void EnableInput(void); @@ -157,7 +157,7 @@ public: // Wipe void InitWipe(int type); void CloseWipe(void); - void WaitWipeEnd(void); + void WaitWipeEnd(CORO_PARAM); void SetPalesati(bool bpal) { m_inter.SetPalesati(bpal); } }; diff --git a/engines/tony/loc.cpp b/engines/tony/loc.cpp index 4eced3fbd5..a412f9cfd2 100644 --- a/engines/tony/loc.cpp +++ b/engines/tony/loc.cpp @@ -248,12 +248,12 @@ int RMPattern::Init(RMSfx *sfx, bool bPlayP0, byte *bFlag) { return m_nCurSprite; } -int RMPattern::Update(HANDLE hEndPattern, byte &bFlag, RMSfx *sfx) { +int RMPattern::Update(uint32 hEndPattern, byte &bFlag, RMSfx *sfx) { int CurTime = _vm->GetTime(); // Se la speed e' 0, il pattern non avanza mai if (m_speed == 0) { - PulseEvent(hEndPattern); + g_scheduler->pulseEvent(hEndPattern); bFlag=m_slots[m_nCurSlot].m_flag; return m_nCurSprite; } @@ -266,7 +266,8 @@ int RMPattern::Update(HANDLE hEndPattern, byte &bFlag, RMSfx *sfx) { if (m_nCurSlot == m_nSlots) { m_nCurSlot = 0; bFlag = m_slots[m_nCurSlot].m_flag; - PulseEvent(hEndPattern); + + g_scheduler->pulseEvent(hEndPattern); // @@@ Se non c'e' loop avverte che il pattern e' finito // Se non c'e' loop rimane sull'ultimo frame @@ -705,9 +706,8 @@ 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((HANDLE)m_hEndPattern, m_bCurFlag, m_sfx); + m_nCurSprite = m_patterns[m_nCurPattern].Update(m_hEndPattern, m_bCurFlag, m_sfx); // Se la funzione ha ritornato -1, vuol dire che il pattern e' finito if (m_nCurSprite == -1) { @@ -844,7 +844,7 @@ RMItem::~RMItem() { } //FIXME: Pass uint32 directly for hCustomSkip -void RMItem::WaitForEndPattern(CORO_PARAM, HANDLE hCustomSkip) { +void RMItem::WaitForEndPattern(CORO_PARAM, uint32 hCustomSkip) { CORO_BEGIN_CONTEXT; uint32 h[2]; CORO_END_CONTEXT(_ctx); @@ -852,10 +852,10 @@ void RMItem::WaitForEndPattern(CORO_PARAM, HANDLE hCustomSkip) { CORO_BEGIN_CODE(_ctx); if (m_nCurPattern != 0) { - if (hCustomSkip == INVALID_HANDLE_VALUE) + if (hCustomSkip == INVALID_PID_VALUE) CORO_INVOKE_2(g_scheduler->waitForSingleObject, m_hEndPattern, INFINITE); else { - _ctx->h[0] = (uint32)hCustomSkip; + _ctx->h[0] = hCustomSkip; _ctx->h[1] = m_hEndPattern; CORO_INVOKE_4(g_scheduler->waitForMultipleObjects, 2, &_ctx->h[0], false, INFINITE); } @@ -888,13 +888,13 @@ void RMItem::PauseSound(bool bPause) { RMWipe::RMWipe() { - m_hUnregistered=CreateEvent(NULL,false,false,NULL); - m_hEndOfFade=CreateEvent(NULL,false,false,NULL); + m_hUnregistered = g_scheduler->createEvent(false, false); + m_hEndOfFade = g_scheduler->createEvent(false, false); } RMWipe::~RMWipe() { - CloseHandle(m_hUnregistered); - CloseHandle(m_hEndOfFade); + g_scheduler->closeEvent(m_hUnregistered); + g_scheduler->closeEvent(m_hEndOfFade); } int RMWipe::Priority(void) { @@ -904,19 +904,28 @@ int RMWipe::Priority(void) { void RMWipe::Unregister(void) { RMGfxTask::Unregister(); assert(m_nInList == 0); - SetEvent(m_hUnregistered); + g_scheduler->setEvent(m_hUnregistered); } bool RMWipe::RemoveThis(void) { return m_bUnregister; } -void RMWipe::WaitForFadeEnd(void) { - WaitForSingleObject(m_hEndOfFade, INFINITE); +void RMWipe::WaitForFadeEnd(CORO_PARAM) { + CORO_BEGIN_CONTEXT; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + CORO_INVOKE_2(g_scheduler->waitForSingleObject, m_hEndOfFade, INFINITE); + m_bEndFade = true; m_bFading = false; - MainWaitFrame(); - MainWaitFrame(); + + CORO_INVOKE_0(MainWaitFrame); + CORO_INVOKE_0(MainWaitFrame); + + CORO_END_CODE; } void RMWipe::CloseFade(void) { @@ -958,7 +967,7 @@ void RMWipe::DoFrame(RMGfxTargetBuffer &bigBuf) { m_nFadeStep++; if (m_nFadeStep == 10) { - SetEvent(m_hEndOfFade); + g_scheduler->setEvent(m_hEndOfFade); } } } diff --git a/engines/tony/loc.h b/engines/tony/loc.h index 153ef7f18c..744dab3c25 100644 --- a/engines/tony/loc.h +++ b/engines/tony/loc.h @@ -171,7 +171,7 @@ public: // Update the pattern, checking to see if it's time to change slot and executing // any associated commands - int Update(HANDLE hEndPattern, byte& bFlag, RMSfx* sfx); + int Update(uint32 hEndPattern, byte &bFlag, RMSfx *sfx); // Stop a sound effect void StopSfx(RMSfx *sfx); @@ -292,7 +292,7 @@ public: void Unload(void); // Aspetta la fine del pattern in play - void WaitForEndPattern(CORO_PARAM, HANDLE hCustomSkip = INVALID_HANDLE_VALUE); + void WaitForEndPattern(CORO_PARAM, uint32 hCustomSkip = INVALID_PID_VALUE); // Setta un nuovo hotspot per l'oggetto void ChangeHotspot(RMPoint pt); @@ -494,9 +494,9 @@ private: bool m_bFading; bool m_bEndFade; bool m_bUnregister; - HANDLE m_hUnregistered; + uint32 m_hUnregistered; int m_nFadeStep; - HANDLE m_hEndOfFade; + uint32 m_hEndOfFade; bool m_bMustRegister; RMItem m_wip0r; @@ -510,7 +510,7 @@ public: void InitFade(int type); void CloseFade(void); - void WaitForFadeEnd(void); + void WaitForFadeEnd(CORO_PARAM); virtual void Unregister(void); virtual bool RemoveThis(void); diff --git a/engines/tony/mpal/loadmpc.cpp b/engines/tony/mpal/loadmpc.cpp index 27ef3f99c5..9d6ef19e55 100644 --- a/engines/tony/mpal/loadmpc.cpp +++ b/engines/tony/mpal/loadmpc.cpp @@ -174,10 +174,8 @@ static const byte *ParseDialog(const byte *lpBuf, LPMPALDIALOG lpmdDialog) { /* Periodi */ num = READ_LE_UINT16(lpBuf); lpBuf += 2; - if (num >= MAX_PERIODS_PER_DIALOG - 1) { - Common::String msg = Common::String::format("Too much periods in dialog #%d", lpmdDialog->nObj); - MessageBox(msg); - } + if (num >= MAX_PERIODS_PER_DIALOG - 1) + error("Too much periods in dialog #%d", lpmdDialog->nObj); for (i = 0; i < num; i++) { lpmdDialog->PeriodNums[i] = READ_LE_UINT16(lpBuf); lpBuf += 2; @@ -195,19 +193,15 @@ static const byte *ParseDialog(const byte *lpBuf, LPMPALDIALOG lpmdDialog) { num = READ_LE_UINT16(lpBuf); lpBuf += 2; curCmd = 0; - if (num >= MAX_GROUPS_PER_DIALOG) { - Common::String msg = Common::String::format("Too much groups in dialog #%d", lpmdDialog->nObj); - MessageBox(msg); - } + if (num >= MAX_GROUPS_PER_DIALOG) + error("Too much groups in dialog #%d", lpmdDialog->nObj); for (i = 0; i < num; i++) { lpmdDialog->Group[i].num = READ_LE_UINT16(lpBuf); lpBuf += 2; lpmdDialog->Group[i].nCmds = *lpBuf; lpBuf++; - if (lpmdDialog->Group[i].nCmds >= MAX_COMMANDS_PER_GROUP) { - Common::String msg = Common::String::format("Too much commands in group #%d in dialog #%d",lpmdDialog->Group[i].num,lpmdDialog->nObj); - MessageBox(msg); - } + if (lpmdDialog->Group[i].nCmds >= MAX_COMMANDS_PER_GROUP) + error("Too much commands in group #%d in dialog #%d",lpmdDialog->Group[i].num,lpmdDialog->nObj); for (j = 0; j < lpmdDialog->Group[i].nCmds; j++) { lpmdDialog->Command[curCmd].type = *lpBuf; @@ -262,28 +256,22 @@ static const byte *ParseDialog(const byte *lpBuf, LPMPALDIALOG lpmdDialog) { } } - if (curCmd >= MAX_COMMANDS_PER_DIALOG) { - Common::String msg = Common::String::format("Too much commands in dialog #%d",lpmdDialog->nObj); - MessageBox(msg); - } + if (curCmd >= MAX_COMMANDS_PER_DIALOG) + error("Too much commands in dialog #%d",lpmdDialog->nObj); /* Choices */ num=*(uint16 *)lpBuf; lpBuf += 2; - if (num >= MAX_CHOICES_PER_DIALOG) { - Common::String msg = Common::String::format("Too much choices in dialog #%d",lpmdDialog->nObj); - MessageBox(msg); - } + if (num >= MAX_CHOICES_PER_DIALOG) + error("Too much choices in dialog #%d",lpmdDialog->nObj); for (i = 0; i < num; i++) { lpmdDialog->Choice[i].nChoice = READ_LE_UINT16(lpBuf); lpBuf += 2; num2 = *lpBuf++; - if (num2 >= MAX_SELECTS_PER_CHOICE) { - Common::String msg = Common::String::format("Too much selects in choice #%d in dialog #%d",lpmdDialog->Choice[i].nChoice,lpmdDialog->nObj); - MessageBox(msg); - } + if (num2 >= MAX_SELECTS_PER_CHOICE) + error("Too much selects in choice #%d in dialog #%d",lpmdDialog->Choice[i].nChoice,lpmdDialog->nObj); for (j = 0; j < num2; j++) { // When @@ -311,10 +299,8 @@ static const byte *ParseDialog(const byte *lpBuf, LPMPALDIALOG lpmdDialog) { // PlayGroup num3 = *lpBuf; *lpBuf++; - if (num3 >= MAX_PLAYGROUPS_PER_SELECT) { - Common::String msg = Common::String::format("Too much playgroups in select #%d in choice #%d in dialog #%d", j, lpmdDialog->Choice[i].nChoice, lpmdDialog->nObj); - MessageBox(msg); - } + if (num3 >= MAX_PLAYGROUPS_PER_SELECT) + error("Too much playgroups in select #%d in choice #%d in dialog #%d", j, lpmdDialog->Choice[i].nChoice, lpmdDialog->nObj); for (z = 0; z < num3; z++) { lpmdDialog->Choice[i].Select[j].wPlayGroup[z] = READ_LE_UINT16(lpBuf); lpBuf += 2; @@ -365,10 +351,8 @@ static const byte *ParseItem(const byte *lpBuf, LPMPALITEM lpmiItem) { CopyMemory(lpmiItem->lpszDescribe,lpBuf, MIN((byte)127, len)); lpBuf+=len; - if (len >= MAX_DESCRIBE_SIZE) { - Common::String msg = Common::String::format("Describe too long in item #%d",lpmiItem->nObj); - MessageBox(msg); - } + if (len >= MAX_DESCRIBE_SIZE) + error("Describe too long in item #%d",lpmiItem->nObj); lpmiItem->nActions=*lpBuf; lpBuf++; @@ -408,10 +392,8 @@ static const byte *ParseItem(const byte *lpBuf, LPMPALITEM lpmiItem) { lpmiItem->Action[i].nCmds=*lpBuf; lpBuf++; - if (lpmiItem->Action[i].nCmds >= MAX_COMMANDS_PER_ACTION) { - Common::String msg = Common::String::format("Too much commands in action #%d in item #%d",lpmiItem->Action[i].num,lpmiItem->nObj); - MessageBox(msg); - } + if (lpmiItem->Action[i].nCmds >= MAX_COMMANDS_PER_ACTION) + error("Too much commands in action #%d in item #%d",lpmiItem->Action[i].num,lpmiItem->nObj); for (j=0;j<lpmiItem->Action[i].nCmds;j++) { lpmiItem->Command[curCmd].type=*lpBuf; @@ -455,9 +437,8 @@ static const byte *ParseItem(const byte *lpBuf, LPMPALITEM lpmiItem) { curCmd++; if (curCmd >= MAX_COMMANDS_PER_ITEM) { - Common::String msg = Common::String::format("Too much commands in item #%d",lpmiItem->nObj); - MessageBox(msg); - curCmd=0; + error("Too much commands in item #%d",lpmiItem->nObj); + //curCmd=0; } } } diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp index 0cea50a3d3..d6230d7768 100644 --- a/engines/tony/mpal/mpal.cpp +++ b/engines/tony/mpal/mpal.cpp @@ -137,9 +137,9 @@ uint32 * lpResources; bool bExecutingAction; bool bExecutingDialog; -uint32 nPollingLocations[MAXPOLLINGLOCATIONS]; -HANDLE hEndPollingLocations[MAXPOLLINGLOCATIONS]; -uint32 PollingThreads[MAXPOLLINGLOCATIONS]; +uint32 nPollingLocations[MAXPOLLINGLOCATIONS]; +uint32 hEndPollingLocations[MAXPOLLINGLOCATIONS]; +uint32 PollingThreads[MAXPOLLINGLOCATIONS]; uint32 hAskChoice; uint32 hDoneChoice; @@ -830,14 +830,20 @@ static LPITEM GetItemData(uint32 nOrdItem) { * \****************************************************************************/ -void PASCAL CustomThread(LPCFCALL p) { - // FIXME: Convert to proper corotuine call - warning("FIXME: CustomThread call"); +void CustomThread(CORO_PARAM, const void *param) { + CORO_BEGIN_CONTEXT; + LPCFCALL p; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + _ctx->p = *(LPCFCALL *)param; - lplpFunctions[p->nCf](nullContext, p->arg1, p->arg2, p->arg3, p->arg4); - GlobalFree(p); - ExitThread(1); -// _endthread(); + CORO_INVOKE_4(lplpFunctions[_ctx->p->nCf], _ctx->p->arg1, _ctx->p->arg2, _ctx->p->arg3, _ctx->p->arg4); + + GlobalFree(_ctx->p); + + CORO_END_CODE; } @@ -855,78 +861,87 @@ void PASCAL CustomThread(LPCFCALL p) { * \****************************************************************************/ -void PASCAL ScriptThread(LPMPALSCRIPT s) { - uint i,j,k; - uint32 dwStartTime = timeGetTime(); - uint32 dwCurTime; - uint32 dwId; - static HANDLE cfHandles[MAX_COMMANDS_PER_MOMENT]; - int numHandles = 0; - LPCFCALL p; +void ScriptThread(CORO_PARAM, const void *param) { + CORO_BEGIN_CONTEXT; + uint i, j, k; + uint32 dwStartTime; + uint32 dwCurTime; + uint32 dwId; + int numHandles; + LPCFCALL p; + CORO_END_CONTEXT(_ctx); + + static uint32 cfHandles[MAX_COMMANDS_PER_MOMENT]; + LPMPALSCRIPT s = *(const LPMPALSCRIPT *)param; + + CORO_BEGIN_CODE(_ctx); + + _ctx->dwStartTime = _vm->GetTime(); + _ctx->numHandles = 0; // warning("PlayScript(): Moments: %u\n",s->nMoments); - for (i = 0; i < s->nMoments; i++) { + for (_ctx->i = 0; _ctx->i < s->nMoments; _ctx->i++) { // Dorme il tempo necessario per arrivare al momento successivo - if (s->Moment[i].dwTime == -1) { - WaitForMultipleObjects(numHandles, cfHandles, true, INFINITE); - dwStartTime = timeGetTime(); + if (s->Moment[_ctx->i].dwTime == -1) { + CORO_INVOKE_4(g_scheduler->waitForMultipleObjects, _ctx->numHandles, cfHandles, true, INFINITE); + _ctx->dwStartTime = _vm->GetTime(); } else { - dwCurTime = timeGetTime(); - if (dwCurTime < dwStartTime + (s->Moment[i].dwTime * 100)) { - // warning("PlayScript(): Sleeping %lums\n",dwStartTime+(s->Moment[i].dwTime*100)-dwCurTime); - Sleep(dwStartTime+(s->Moment[i].dwTime * 100) - dwCurTime); + _ctx->dwCurTime = _vm->GetTime(); + if (_ctx->dwCurTime < _ctx->dwStartTime + (s->Moment[_ctx->i].dwTime * 100)) { + // warning("PlayScript(): Sleeping %lums\n",_ctx->dwStartTime+(s->Moment[_ctx->i].dwTime*100)-_ctx->dwCurTime); + CORO_INVOKE_1(g_scheduler->sleep, _ctx->dwStartTime+(s->Moment[_ctx->i].dwTime * 100) - _ctx->dwCurTime); } } - numHandles = 0; - for (j = 0;j<s->Moment[i].nCmds; j++) { - k=s->Moment[i].CmdNum[j]; + _ctx->numHandles = 0; + for (_ctx->j = 0; _ctx->j<s->Moment[_ctx->i].nCmds; _ctx->j++) { + _ctx->k = s->Moment[_ctx->i].CmdNum[_ctx->j]; - switch (s->Command[k].type) { - case 1: - p=(LPCFCALL)GlobalAlloc(GMEM_FIXED, sizeof(CFCALL)); - if (p == NULL) { + if (s->Command[_ctx->k].type == 1) { + _ctx->p=(LPCFCALL)GlobalAlloc(GMEM_FIXED, sizeof(CFCALL)); + if (_ctx->p == NULL) { mpalError = 1; - ExitThread(0); -// _endthread(); + + CORO_KILL_SELF(); + return; } - p->nCf=s->Command[k].nCf; - p->arg1=s->Command[k].arg1; - p->arg2=s->Command[k].arg2; - p->arg3=s->Command[k].arg3; - p->arg4=s->Command[k].arg4; + _ctx->p->nCf=s->Command[_ctx->k].nCf; + _ctx->p->arg1=s->Command[_ctx->k].arg1; + _ctx->p->arg2=s->Command[_ctx->k].arg2; + _ctx->p->arg3=s->Command[_ctx->k].arg3; + _ctx->p->arg4=s->Command[_ctx->k].arg4; // !!! Nuova gestione dei thread - if ((cfHandles[numHandles++] = CreateThread(NULL, 10240, (LPTHREAD_START_ROUTINE)CustomThread,(void *)p, 0, &dwId)) == NULL) { - //if ((cfHandles[numHandles++]=(void*)_beginthread(CustomThread, 10240, (void *)p))==(void*)-1) + if ((cfHandles[_ctx->numHandles++] = g_scheduler->createProcess(CustomThread, &_ctx->p, sizeof(LPCFCALL))) == 0) { mpalError = 1; - ExitThread(0); -// _endthread(); - } - break; - case 2: + CORO_KILL_SELF(); + return; + } + } else if (s->Command[_ctx->k].type == 2) { LockVar(); varSetValue( - s->Command[k].lpszVarName, - EvaluateExpression(s->Command[k].expr) + s->Command[_ctx->k].lpszVarName, + EvaluateExpression(s->Command[_ctx->k].expr) ); UnlockVar(); - break; - default: + } else { mpalError = 1; GlobalFree(s); - ExitThread(0); -// _endthread(); + + CORO_KILL_SELF(); + return; } } } GlobalFree(s); - ExitThread(1); - //_endthread(); + + CORO_KILL_SELF(); + + CORO_END_CODE; } @@ -1063,6 +1078,7 @@ void LocationPollThread(CORO_PARAM, const void *param) { uint32 dwId; int ord; bool delayExpired; + bool expired; MYACTION *MyActions; MYTHREAD *MyThreads; @@ -1122,7 +1138,7 @@ void LocationPollThread(CORO_PARAM, const void *param) { } /* Inizializziamo le routine random */ - //curTime = timeGetTime(); + //curTime = _vm->GetTime(); //srand(curTime); @@ -1157,7 +1173,7 @@ void LocationPollThread(CORO_PARAM, const void *param) { CopyMemory(_ctx->MyActions[_ctx->k].CmdNum, _ctx->curItem->Action[_ctx->j].CmdNum, MAX_COMMANDS_PER_ACTION * sizeof(uint16)); - _ctx->MyActions[_ctx->k].dwLastTime = timeGetTime(); + _ctx->MyActions[_ctx->k].dwLastTime = _vm->GetTime(); _ctx->k++; } } @@ -1172,7 +1188,7 @@ void LocationPollThread(CORO_PARAM, const void *param) { while (1) { /* Cerchiamo tra tutte le idle actions quella a cui manca meno tempo per l'esecuzione */ - _ctx->curTime = timeGetTime(); + _ctx->curTime = _vm->GetTime(); _ctx->dwSleepTime = (uint32)-1L; for (_ctx->k = 0;_ctx->k<_ctx->nIdleActions;_ctx->k++) @@ -1184,8 +1200,11 @@ void LocationPollThread(CORO_PARAM, const void *param) { /* Ci addormentiamo, ma controllando sempre l'evento che viene settato quando viene richiesta la nostra chiusura */ - _ctx->k = WaitForSingleObject(hEndPollingLocations[id], _ctx->dwSleepTime); - if (_ctx->k == WAIT_OBJECT_0) + + CORO_INVOKE_3(g_scheduler->waitForSingleObject, hEndPollingLocations[id], _ctx->dwSleepTime, &_ctx->expired); + + //if (_ctx->k == WAIT_OBJECT_0) + if (!_ctx->expired) break; for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++) @@ -1197,7 +1216,7 @@ void LocationPollThread(CORO_PARAM, const void *param) { _ctx->MyThreads[_ctx->i].nItem = 0; } - _ctx->curTime = timeGetTime(); + _ctx->curTime = _vm->GetTime(); /* Cerchiamo all'interno delle idle actions quale e' necessario eseguire */ for (_ctx->k = 0; _ctx->k < _ctx->nIdleActions; _ctx->k++) @@ -2163,10 +2182,9 @@ bool EXPORT mpalExecuteScript(int nScript) { CopyMemory(s, lpmsScripts+n, sizeof(MPALSCRIPT)); UnlockScripts(); -// !!! Nuova gestione dei thread - if (CreateThread(NULL, 10240,(LPTHREAD_START_ROUTINE)ScriptThread,(void *)s, 0, &dwId) == NULL) - //if ((void*)_beginthread(ScriptThread, 10240,(void *)s)==(void*)-1) - return false; + // !!! Nuova gestione dei thread + if (g_scheduler->createProcess(ScriptThread, &s, sizeof(LPMPALSCRIPT)) == INVALID_PID_VALUE) + return false; return true; } @@ -2213,9 +2231,9 @@ bool mpalStartIdlePoll(int nLoc) { for (i = 0; i < MAXPOLLINGLOCATIONS; i++) { if (nPollingLocations[i] == 0) { - nPollingLocations[i]=nLoc; + nPollingLocations[i] = nLoc; - hEndPollingLocations[i] = CreateEvent(NULL, true, false, NULL); + hEndPollingLocations[i] = g_scheduler->createEvent(true, false); // !!! Nuova gestione dei thread if ((PollingThreads[i] = g_scheduler->createProcess(LocationPollThread, &i, sizeof(uint32))) == 0) // if ((hEndPollingLocations[i]=(void*)_beginthread(LocationPollThread, 10240,(void *)i))==(void*)-1) @@ -2252,11 +2270,11 @@ void mpalEndIdlePoll(CORO_PARAM, int nLoc, bool *result) { for (_ctx->i = 0; _ctx->i < MAXPOLLINGLOCATIONS; _ctx->i++) { if (nPollingLocations[_ctx->i] == (uint32)nLoc) { - SetEvent(hEndPollingLocations[_ctx->i]); + g_scheduler->setEvent(hEndPollingLocations[_ctx->i]); CORO_INVOKE_2(g_scheduler->waitForSingleObject, PollingThreads[_ctx->i], INFINITE); - CloseHandle(hEndPollingLocations[_ctx->i]); + g_scheduler->closeEvent(hEndPollingLocations[_ctx->i]); nPollingLocations[_ctx->i] = 0; if (result) diff --git a/engines/tony/mpal/stubs.cpp b/engines/tony/mpal/stubs.cpp index 58ecc6d6d9..23bc18b0ea 100644 --- a/engines/tony/mpal/stubs.cpp +++ b/engines/tony/mpal/stubs.cpp @@ -36,76 +36,6 @@ namespace Tony { namespace MPAL { -/** - * Display a message - * @param msg Message to display - */ -void MessageBox(const Common::String &msg) { - - _vm->GUIError(msg); -} - -/** - * Gets the current time in milliseconds - */ -uint32 timeGetTime() { - return g_system->getMillis(); -} - -HANDLE CreateThread(void *lpThreadAttributes, size_t dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, void *lpParameter, - uint32 dwCreationFlags, uint32 *lpThreadId) { - *lpThreadId = 0; - return 0; -} - -void _beginthread(LPTHREAD_ROUTINE lpStartAddress, size_t dwStackSize, void *lpParameter) { -} - -void ExitThread(int ThreadId) { -} - -void _endthread() { -} - -void TerminateThread(HANDLE ThreadId, uint32 dwExitCode) { - -} - -void CloseHandle(HANDLE ThreadId) { - -} - -void Sleep(uint32 time) { -} - -int WaitForSingleObject(HANDLE ThreadId, uint32 dwSleepTime) { - warning("TODO: Old style WaitForSingleObject"); - return 0; -} - -uint32 WaitForMultipleObjects(uint32 nCount, const HANDLE *lpHandles, bool bWaitAll, uint32 dwMilliseconds) { - warning("TODO: Old style WaitForMultipleObjects"); - return 0; -} - -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) { return 0; } diff --git a/engines/tony/mpal/stubs.h b/engines/tony/mpal/stubs.h index 5c50b76db1..082974898c 100644 --- a/engines/tony/mpal/stubs.h +++ b/engines/tony/mpal/stubs.h @@ -71,42 +71,8 @@ Out CopyMemory(Out dst, In first, int size) { * Methods \****************************************************************************/ -extern void MessageBox(const Common::String &msg); - -extern uint32 timeGetTime(); - -#define INFINITE 0xffffffff -#define WAIT_OBJECT_0 -2 // Horrendously bad cast -#define INVALID_HANDLE_VALUE (void *)-3 - -extern HANDLE CreateThread(void *lpThreadAttributes, size_t dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, void *lpParameter, - uint32 dwCreationFlags, uint32 *lpThreadId); - -extern void _beginthread(LPTHREAD_ROUTINE lpStartAddress, size_t dwStackSize, void *lpParameter); - -extern void ExitThread(int ThreadId); - -extern void _endthread(); - -extern void TerminateThread(HANDLE ThreadId, uint32 dwExitCode); - -extern void CloseHandle(HANDLE ThreadId); - -extern void Sleep(uint32 time); - -extern int WaitForSingleObject(HANDLE ThreadId, uint32 dwSleepTime); - -extern uint32 WaitForMultipleObjects(uint32 nCount, const HANDLE *lpHandles, bool bWaitAll, uint32 dwMilliseconds); - -extern HANDLE CreateEvent(void *lpEventAttributes, bool bManualReset, bool bInitialState, const char *lpName); - -extern void SetEvent(HANDLE hEvent); - -extern void ResetEvent(HANDLE hEvent); - -extern void PulseEvent(HANDLE hEvent); +#define INVALID_HANDLE_VALUE (void *)-1 extern uint16 GetAsyncKeyState(Common::KeyCode kc); diff --git a/engines/tony/sched.cpp b/engines/tony/sched.cpp index 2671b01b7f..c447afa094 100644 --- a/engines/tony/sched.cpp +++ b/engines/tony/sched.cpp @@ -437,6 +437,40 @@ void Scheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, CORO_END_CODE; } +/** + * Make the active process sleep for the given duration in milliseconds + * @param duration Duration in milliseconds + * @remarks This duration won't be precise, since it relies on the frequency the + * scheduler is called. + */ +void Scheduler::sleep(CORO_PARAM, uint32 duration) { + if (!pCurrent) + error("Called Scheduler::waitForSingleObject from the main process"); + + CORO_BEGIN_CONTEXT; + uint32 endTime; + PROCESS *pProcess; + EVENT *pEvent; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + // Signal as waiting + pCurrent->waiting = true; + + _ctx->endTime = g_system->getMillis() + duration; + + // Outer loop for doing checks until expiry + while (g_system->getMillis() < _ctx->endTime) { + // Sleep until the next cycle + CORO_SLEEP(1); + } + + // Signal waiting is done + pCurrent->waiting = false; + + CORO_END_CODE; +} /** * Creates a new process. diff --git a/engines/tony/sched.h b/engines/tony/sched.h index 3997cb2c47..a9868edad0 100644 --- a/engines/tony/sched.h +++ b/engines/tony/sched.h @@ -37,6 +37,7 @@ namespace Tony { #define MAX_PROCESSES 100 #define INFINITE 0xffffffff +#define INVALID_PID_VALUE 0 typedef void (*CORO_ADDR)(CoroContext &, const void *); @@ -125,7 +126,8 @@ public: void giveWay(PPROCESS pReSchedProc = 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 duration, bool *expired = NULL); + void Scheduler::sleep(CORO_PARAM, uint32 duration); uint32 createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam); uint32 createProcess(CORO_ADDR coroAddr, const void *pParam) { diff --git a/engines/tony/sound.cpp b/engines/tony/sound.cpp index 7c340be86e..b376d14149 100644 --- a/engines/tony/sound.cpp +++ b/engines/tony/sound.cpp @@ -2179,8 +2179,9 @@ void PASCAL FPSTREAM::PlayThread(FPSTREAM *This) { // sprintf(buf, "Exiting thread. Buffer = %x, MyThread = 0x%x\n", This->lpDSBuffer, GetCurrentThreadId()); // warning(buf); This->lpDSBuffer->Stop(); -#endif + ExitThread(0); +#endif } diff --git a/engines/tony/sound.h b/engines/tony/sound.h index 8853e1a344..e263c7ee51 100644 --- a/engines/tony/sound.h +++ b/engines/tony/sound.h @@ -240,7 +240,7 @@ private: // DSBPOSITIONNOTIFY dspnHot[2]; public: - HANDLE hEndOfBuffer; + uint32 hEndOfBuffer; private: diff --git a/engines/tony/tony.cpp b/engines/tony/tony.cpp index d0bce68c3b..ef27f509b9 100644 --- a/engines/tony/tony.cpp +++ b/engines/tony/tony.cpp @@ -68,7 +68,7 @@ Common::Error TonyEngine::run() { * Initialise the game */ Common::ErrorCode TonyEngine::Init() { - m_hEndOfFrame = CreateEvent(NULL, false, false, NULL); + m_hEndOfFrame = g_scheduler->createEvent(false, false); m_bPaused = false; m_bDrawLocation = true; @@ -295,16 +295,22 @@ void TonyEngine::GetSaveStateFileName(int n, char *buf) { name += ".sav"; } -void TonyEngine::AutoSave(void) { - char buf[256]; +void TonyEngine::AutoSave(CORO_PARAM) { + CORO_BEGIN_CONTEXT; + char buf[256]; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); GrabThumbnail(); - MainWaitFrame(); - MainWaitFrame(); + CORO_INVOKE_0(MainWaitFrame); + CORO_INVOKE_0(MainWaitFrame); MainFreeze(); - GetSaveStateFileName(0,buf); - _theEngine.SaveState(buf, (byte *)m_curThumbnail, "Autosave", true); + GetSaveStateFileName(0, _ctx->buf); + _theEngine.SaveState(_ctx->buf, (byte *)m_curThumbnail, "Autosave", true); MainUnfreeze(); + + CORO_END_CODE; } @@ -375,12 +381,12 @@ void TonyEngine::GrabThumbnail(void) { void TonyEngine::OptionScreen(void) { } -void TonyEngine::OpenInitLoadMenu(void) { - _theEngine.OpenOptionScreen(1); +void TonyEngine::OpenInitLoadMenu(CORO_PARAM) { + _theEngine.OpenOptionScreen(coroParam, 1); } -void TonyEngine::OpenInitOptions(void) { - _theEngine.OpenOptionScreen(2); +void TonyEngine::OpenInitOptions(CORO_PARAM) { + _theEngine.OpenOptionScreen(coroParam, 2); } void TonyEngine::Abort(void) { @@ -400,10 +406,11 @@ void TonyEngine::Play(void) { _scheduler.schedule(); // Call the engine to handle the next frame - _theEngine.DoFrame(m_bDrawLocation); + // FIXME: This needs to be moved into it's own process + _theEngine.DoFrame(nullContext, m_bDrawLocation); // Warns that a frame is finished - PulseEvent(m_hEndOfFrame); + g_scheduler->pulseEvent(m_hEndOfFrame); // Handle drawing the frame if (!m_bPaused) { @@ -422,7 +429,7 @@ void TonyEngine::Play(void) { void TonyEngine::Close(void) { CloseMusic(); - CloseHandle(m_hEndOfFrame); + g_scheduler->closeEvent(m_hEndOfFrame); _theBoxes.Close(); _theEngine.Close(); _window.Close(); diff --git a/engines/tony/tony.h b/engines/tony/tony.h index 3c7e8fe6b2..fdb92e3795 100644 --- a/engines/tony/tony.h +++ b/engines/tony/tony.h @@ -92,7 +92,7 @@ public: Common::RandomSource _randomSource; MPAL::MemoryManager _memoryManager; RMResUpdate _resUpdate; - HANDLE m_hEndOfFrame; + uint32 m_hEndOfFrame; Common::File _vdbFP; Common::Array<VoiceHeader> _voices; FPSOUND _theSound; @@ -191,7 +191,7 @@ public: int GetMusicVolume(int nChannel); // Salvataggio - void AutoSave(void); + void AutoSave(CORO_PARAM); void SaveState(int n, const char *name); void LoadState(int n); void GetSaveStateFileName(int n, char *buf); @@ -202,8 +202,8 @@ public: void Quit(void) { m_bQuitNow = true; } - void OpenInitLoadMenu(void); - void OpenInitOptions(void); + void OpenInitLoadMenu(CORO_PARAM); + void OpenInitOptions(CORO_PARAM); }; // Global reference to the TonyEngine object diff --git a/engines/tony/tonychar.cpp b/engines/tony/tonychar.cpp index ad13d49d54..ea233233d2 100644 --- a/engines/tony/tonychar.cpp +++ b/engines/tony/tonychar.cpp @@ -212,6 +212,7 @@ void RMTony::MoveAndDoAction(RMPoint dst, RMItem *item, int nAction, int nAction void RMTony::ExecuteAction(int nAction, int nActionItem, int nParm) { + // fixme: See if hThread can be converted to uint32 HANDLE hThread; uint32 pid; @@ -241,53 +242,64 @@ void RMTony::ExecuteAction(int nAction, int nActionItem, int nParm) { m_bAction = true; pid = (uint32)hThread; g_scheduler->createProcess(WaitEndOfAction, &pid, sizeof(uint32)); - hActionThread = hThread; + hActionThread = pid; } else if (nAction != TA_GOTO) { if (nAction == TA_TALK) { hThread = mpalQueryDoAction(6, 1, 0); m_bAction = true; pid = (uint32)hThread; g_scheduler->createProcess(WaitEndOfAction, &pid, sizeof(uint32)); - hActionThread = hThread; + hActionThread = pid; } else if (nAction == TA_PALESATI) { hThread = mpalQueryDoAction(7, 1, 0); m_bAction = true; pid = (uint32)hThread; g_scheduler->createProcess(WaitEndOfAction, &pid, sizeof(uint32)); - hActionThread=hThread; + hActionThread = pid; } else { hThread = mpalQueryDoAction(5, 1, 0); m_bAction = true; pid = (uint32)hThread; g_scheduler->createProcess(WaitEndOfAction, &pid, sizeof(uint32)); - hActionThread = hThread; + hActionThread = pid; } } } -void RMTony::StopNoAction(void) { +void RMTony::StopNoAction(CORO_PARAM) { + CORO_BEGIN_CONTEXT; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + if (m_bAction) - WaitForSingleObject(hActionThread, INFINITE); + CORO_INVOKE_2(g_scheduler->waitForSingleObject, hActionThread, INFINITE); m_bActionPending = false; m_ActionItem = NULL; - Stop(); + CORO_INVOKE_0(Stop); + + CORO_END_CODE; } -void RMTony::Stop(void) { - HANDLE hThread; +void RMTony::Stop(CORO_PARAM) { + CORO_BEGIN_CONTEXT; + uint32 hThread; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); if (m_ActionItem != NULL) { // Richiama l'MPAL per scegliere la direzione - hThread = mpalQueryDoAction(21, m_ActionItem->MpalCode(), 0); + _ctx->hThread = mpalQueryDoActionU32(21, m_ActionItem->MpalCode(), 0); - if (hThread==INVALID_HANDLE_VALUE) + if (_ctx->hThread == INVALID_PID_VALUE) RMCharacter::Stop(); else { bNeedToStop = false; // Se facciamo la OnWhichDirection, almeno dopo non dobbiamo fare la Stop() bMoving = false; - WaitForSingleObject(hThread, INFINITE); // @@@ Mettere un assert dopo 10 secondi + CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->hThread, INFINITE); // @@@ Mettere un assert dopo 10 secondi } } else { RMCharacter::Stop(); @@ -301,6 +313,8 @@ void RMTony::Stop(void) { ExecuteAction(m_Action, m_ActionItem->MpalCode(), m_ActionParm); m_ActionItem=NULL; + + CORO_END_CODE; } diff --git a/engines/tony/tonychar.h b/engines/tony/tonychar.h index 2cbcf60a00..98f247f688 100644 --- a/engines/tony/tonychar.h +++ b/engines/tony/tonychar.h @@ -123,7 +123,7 @@ private: int m_nTimeLastStep; RMItem m_body; - HANDLE hActionThread; + uint32 hActionThread; protected: // Overload dell'allocazione degli sprites per cambiare il tipo @@ -398,8 +398,8 @@ public: void MoveAndDoAction(RMPoint dst, RMItem *item, int nAction, int nActionParm = 0); // Ferma Tony (dalla parte giusta rispetto a un eventuale oggetto) - virtual void Stop(void); - void StopNoAction(void); + virtual void Stop(CORO_PARAM); + void StopNoAction(CORO_PARAM); // Setta un pattern void SetPattern(int npatt, bool bPlayP0 = false); @@ -408,7 +408,7 @@ public: int GetCurPattern(); // Attende la fine di un pattern - void WaitForEndPattern(CORO_PARAM, HANDLE hCustomSkip = INVALID_HANDLE_VALUE) { + void WaitForEndPattern(CORO_PARAM, uint32 hCustomSkip = INVALID_PID_VALUE) { RMCharacter::WaitForEndPattern(coroParam, hCustomSkip); } |