TONY: Refactored Tony to use the Common coroutine scheduler

This commit is contained in:
Paul Gilbert 2012-05-11 23:15:59 +10:00
parent 2c1ef3ab35
commit 68c1b0b0e4
19 changed files with 166 additions and 293 deletions

View file

@ -48,8 +48,8 @@
#ifndef TONY_ADV_H #ifndef TONY_ADV_H
#define TONY_ADV_H #define TONY_ADV_H
#include "common/coroutines.h"
#include "tony/mpal/memory.h" #include "tony/mpal/memory.h"
#include "tony/coroutine.h"
#include "tony/gfxcore.h" #include "tony/gfxcore.h"

View file

@ -113,7 +113,7 @@ public:
* context, and so compilers won't complain about ";" following the macro. * context, and so compilers won't complain about ";" following the macro.
*/ */
#define CORO_BEGIN_CONTEXT \ #define CORO_BEGIN_CONTEXT \
struct CoroContextTag : CoroBaseContext { \ struct CoroContextTag : Common::CoroBaseContext { \
CoroContextTag() : CoroBaseContext(SCUMMVM_CURRENT_FUNCTION) {} \ CoroContextTag() : CoroBaseContext(SCUMMVM_CURRENT_FUNCTION) {} \
int DUMMY int DUMMY
@ -156,8 +156,8 @@ public:
return; case __LINE__:;\ return; case __LINE__:;\
} while (0) } while (0)
#define CORO_GIVE_WAY do { g_scheduler->giveWay(); CORO_SLEEP(1); } while (0) #define CORO_GIVE_WAY do { CoroScheduler.giveWay(); CORO_SLEEP(1); } while (0)
#define CORO_RESCHEDULE do { g_scheduler->reschedule(); CORO_SLEEP(1); } while (0) #define CORO_RESCHEDULE do { CoroScheduler.reschedule(); CORO_SLEEP(1); } while (0)
/** /**
* Stop the currently running coroutine and all calling coroutines. * Stop the currently running coroutine and all calling coroutines.

View file

@ -327,7 +327,7 @@ DECLARE_CUSTOM_FUNCTION(MySleep)(CORO_PARAM, uint32 dwTime, uint32, uint32, uint
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
if (!bSkipIdle) if (!bSkipIdle)
CORO_INVOKE_1(g_scheduler->sleep, dwTime); CORO_INVOKE_1(CoroScheduler.sleep, dwTime);
CORO_END_CODE; CORO_END_CODE;
} }
@ -524,8 +524,8 @@ DECLARE_CUSTOM_FUNCTION(CustLoadLocation)(CORO_PARAM, uint32 nLoc, uint32 tX, ui
_ctx->h = mpalQueryDoAction(0, nLoc, 0); _ctx->h = mpalQueryDoAction(0, nLoc, 0);
// On Enter? // On Enter?
if (_ctx->h != INVALID_PID_VALUE) if (_ctx->h != CORO_INVALID_PID_VALUE)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
CORO_END_CODE; CORO_END_CODE;
} }
@ -708,8 +708,8 @@ DECLARE_CUSTOM_FUNCTION(ChangeLocation)(CORO_PARAM, uint32 nLoc, uint32 tX, uint
bNoOcchioDiBue = false; bNoOcchioDiBue = false;
// On Enter? // On Enter?
if (_ctx->h != INVALID_PID_VALUE) if (_ctx->h != CORO_INVALID_PID_VALUE)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
CORO_END_CODE; CORO_END_CODE;
} }
@ -1843,8 +1843,8 @@ DECLARE_CUSTOM_FUNCTION(MCharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMes
// Cerca di eseguire la funzione custom per inizializzare la parlata // Cerca di eseguire la funzione custom per inizializzare la parlata
if (MCharacter[nChar].item) { if (MCharacter[nChar].item) {
_ctx->h = mpalQueryDoAction(30, MCharacter[nChar].item->MpalCode(), _ctx->parm); _ctx->h = mpalQueryDoAction(30, MCharacter[nChar].item->MpalCode(), _ctx->parm);
if (_ctx->h != INVALID_PID_VALUE) { if (_ctx->h != CORO_INVALID_PID_VALUE) {
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
} }
} }
@ -1924,8 +1924,8 @@ DECLARE_CUSTOM_FUNCTION(MCharSendMessage)(CORO_PARAM, uint32 nChar, uint32 dwMes
// Cerca di eseguire la funzione custom per chiudere la parlata // Cerca di eseguire la funzione custom per chiudere la parlata
if (MCharacter[nChar].item) { if (MCharacter[nChar].item) {
_ctx->h = mpalQueryDoAction(31, MCharacter[nChar].item->MpalCode(), _ctx->parm); _ctx->h = mpalQueryDoAction(31, MCharacter[nChar].item->MpalCode(), _ctx->parm);
if (_ctx->h != INVALID_PID_VALUE) if (_ctx->h != CORO_INVALID_PID_VALUE)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
} }
CORO_END_CODE; CORO_END_CODE;
@ -2035,8 +2035,8 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg
} else { } else {
// Cerca di eseguire la funzione custom per inizializzare la parlata // Cerca di eseguire la funzione custom per inizializzare la parlata
_ctx->h = mpalQueryDoAction(30, MCharacter[nPers].item->MpalCode(), _ctx->parm); _ctx->h = mpalQueryDoAction(30, MCharacter[nPers].item->MpalCode(), _ctx->parm);
if (_ctx->h != INVALID_PID_VALUE) if (_ctx->h != CORO_INVALID_PID_VALUE)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
MCharacter[nPers].curTalk = _ctx->parm; MCharacter[nPers].curTalk = _ctx->parm;
@ -2099,8 +2099,8 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg
// Cerca di eseguire la funzione custom per chiudere la parlata // Cerca di eseguire la funzione custom per chiudere la parlata
MCharacter[nPers].curTalk = (MCharacter[nPers].curTalk%10) + MCharacter[nPers].curgroup*10; MCharacter[nPers].curTalk = (MCharacter[nPers].curTalk%10) + MCharacter[nPers].curgroup*10;
_ctx->h = mpalQueryDoAction(31,MCharacter[nPers].item->MpalCode(),MCharacter[nPers].curTalk); _ctx->h = mpalQueryDoAction(31,MCharacter[nPers].item->MpalCode(),MCharacter[nPers].curTalk);
if (_ctx->h != INVALID_PID_VALUE) if (_ctx->h != CORO_INVALID_PID_VALUE)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
MCharacter[nPers].bInTexts = false; MCharacter[nPers].bInTexts = false;
MCharacter[nPers].numtexts = 0; MCharacter[nPers].numtexts = 0;
@ -2214,7 +2214,7 @@ DECLARE_CUSTOM_FUNCTION(StartDialog)(CORO_PARAM, uint32 nDialog, uint32 nStartGr
DECLARE_CUSTOM_FUNCTION(TakeOwnership)(CORO_PARAM, uint32 num, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(TakeOwnership)(CORO_PARAM, uint32 num, uint32, uint32, uint32) {
// EnterCriticalSection(&cs[num]); // EnterCriticalSection(&cs[num]);
// WaitForSingleObject(mut[num],INFINITE); // WaitForSingleObject(mut[num],CORO_INFINITE);
warning("TODO"); warning("TODO");
} }
@ -2264,7 +2264,7 @@ void ThreadFadeInMusic(CORO_PARAM, const void *nMusic) {
for (_ctx->i = 0; _ctx->i < 16; _ctx->i++) { for (_ctx->i = 0; _ctx->i < 16; _ctx->i++) {
_vm->SetMusicVolume(nChannel, _ctx->i * 4); _vm->SetMusicVolume(nChannel, _ctx->i * 4);
CORO_INVOKE_1(g_scheduler->sleep, 100); CORO_INVOKE_1(CoroScheduler.sleep, 100);
} }
_vm->SetMusicVolume(nChannel, 64); _vm->SetMusicVolume(nChannel, 64);
@ -2293,7 +2293,7 @@ void ThreadFadeOutMusic(CORO_PARAM, const void *nMusic) {
if (_ctx->i * 4 < _ctx->startVolume) if (_ctx->i * 4 < _ctx->startVolume)
_vm->SetMusicVolume(nChannel, _ctx->i * 4); _vm->SetMusicVolume(nChannel, _ctx->i * 4);
CORO_INVOKE_1(g_scheduler->sleep, 100); CORO_INVOKE_1(CoroScheduler.sleep, 100);
} }
if (!bFadeOutStop) if (!bFadeOutStop)
@ -2311,23 +2311,23 @@ void ThreadFadeOutMusic(CORO_PARAM, const void *nMusic) {
} }
DECLARE_CUSTOM_FUNCTION(FadeInSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(FadeInSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) {
g_scheduler->createProcess(ThreadFadeInMusic, &curSonoriz, sizeof(int)); CoroScheduler.createProcess(ThreadFadeInMusic, &curSonoriz, sizeof(int));
} }
DECLARE_CUSTOM_FUNCTION(FadeOutSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(FadeOutSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) {
bFadeOutStop = false; bFadeOutStop = false;
g_scheduler->createProcess(ThreadFadeOutMusic, &curSonoriz, sizeof(int)); CoroScheduler.createProcess(ThreadFadeOutMusic, &curSonoriz, sizeof(int));
} }
DECLARE_CUSTOM_FUNCTION(FadeOutStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(FadeOutStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
bFadeOutStop = false; bFadeOutStop = false;
int channel = 2; int channel = 2;
g_scheduler->createProcess(ThreadFadeOutMusic, &channel, sizeof(int)); CoroScheduler.createProcess(ThreadFadeOutMusic, &channel, sizeof(int));
} }
DECLARE_CUSTOM_FUNCTION(FadeInStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(FadeInStacchetto)(CORO_PARAM, uint32, uint32, uint32, uint32) {
int channel = 2; int channel = 2;
g_scheduler->createProcess(ThreadFadeInMusic, &channel, sizeof(int)); CoroScheduler.createProcess(ThreadFadeInMusic, &channel, sizeof(int));
} }
DECLARE_CUSTOM_FUNCTION(StopSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(StopSonoriz)(CORO_PARAM, uint32, uint32, uint32, uint32) {
@ -2557,12 +2557,12 @@ DECLARE_CUSTOM_FUNCTION(StacchettoFadeEnd)(CORO_PARAM, uint32 nStacc, uint32 bLo
DECLARE_CUSTOM_FUNCTION(MustSkipIdleStart)(CORO_PARAM, uint32, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(MustSkipIdleStart)(CORO_PARAM, uint32, uint32, uint32, uint32) {
bSkipIdle = true; bSkipIdle = true;
g_scheduler->setEvent(hSkipIdle); CoroScheduler.setEvent(hSkipIdle);
} }
DECLARE_CUSTOM_FUNCTION(MustSkipIdleEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(MustSkipIdleEnd)(CORO_PARAM, uint32, uint32, uint32, uint32) {
bSkipIdle = false; bSkipIdle = false;
g_scheduler->resetEvent(hSkipIdle); CoroScheduler.resetEvent(hSkipIdle);
} }
DECLARE_CUSTOM_FUNCTION(PatIrqFreeze)(CORO_PARAM, uint32 bStatus, uint32, uint32, uint32) { DECLARE_CUSTOM_FUNCTION(PatIrqFreeze)(CORO_PARAM, uint32 bStatus, uint32, uint32, uint32) {
@ -2608,7 +2608,7 @@ DECLARE_CUSTOM_FUNCTION(DoCredits)(CORO_PARAM, uint32 nMsg, uint32 dwTime, uint3
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
_ctx->msg = new RMMessage(nMsg); _ctx->msg = new RMMessage(nMsg);
_ctx->hDisable = g_scheduler->createEvent(true, false); _ctx->hDisable = CoroScheduler.createEvent(true, false);
_ctx->text = new RMTextDialog[_ctx->msg->NumPeriods()]; _ctx->text = new RMTextDialog[_ctx->msg->NumPeriods()];
@ -2649,7 +2649,7 @@ DECLARE_CUSTOM_FUNCTION(DoCredits)(CORO_PARAM, uint32 nMsg, uint32 dwTime, uint3
break; break;
} }
g_scheduler->setEvent(_ctx->hDisable); CoroScheduler.setEvent(_ctx->hDisable);
CORO_INVOKE_0(WaitFrame); CORO_INVOKE_0(WaitFrame);
CORO_INVOKE_0(WaitFrame); CORO_INVOKE_0(WaitFrame);
@ -2882,7 +2882,7 @@ void SetupGlobalVars(RMTony *tony, RMPointer *ptr, RMGameBoxes *box, RMLocation
// Crea l'evento per skippare le idle // Crea l'evento per skippare le idle
hSkipIdle = g_scheduler->createEvent(true, false); hSkipIdle = CoroScheduler.createEvent(true, false);
} }
} // end of namespace Tony } // end of namespace Tony

View file

@ -2048,16 +2048,16 @@ RMTextDialog::RMTextDialog() : RMText() {
m_bForceNoTime = false; m_bForceNoTime = false;
m_bAlwaysDisplay = false; m_bAlwaysDisplay = false;
m_bNoTab = false; m_bNoTab = false;
hCustomSkip = INVALID_PID_VALUE; hCustomSkip = CORO_INVALID_PID_VALUE;
hCustomSkip2 = INVALID_PID_VALUE; hCustomSkip2 = CORO_INVALID_PID_VALUE;
m_input = NULL; m_input = NULL;
// Crea l'evento di fine displaying // Crea l'evento di fine displaying
hEndDisplay = g_scheduler->createEvent(false, false); hEndDisplay = CoroScheduler.createEvent(false, false);
} }
RMTextDialog::~RMTextDialog() { RMTextDialog::~RMTextDialog() {
g_scheduler->closeEvent(hEndDisplay); CoroScheduler.closeEvent(hEndDisplay);
} }
void RMTextDialog::Show(void) { void RMTextDialog::Show(void) {
@ -2119,7 +2119,7 @@ void RMTextDialog::RemoveThis(CORO_PARAM, bool &result) {
// Frase NON di background // Frase NON di background
if (m_bSkipStatus) { if (m_bSkipStatus) {
if (!(bCfgDubbing && hCustomSkip2 != INVALID_PID_VALUE)) if (!(bCfgDubbing && hCustomSkip2 != CORO_INVALID_PID_VALUE))
if (bCfgTimerizedText) { if (bCfgTimerizedText) {
if (!m_bForceNoTime) if (!m_bForceNoTime)
if (_vm->GetTime() > (uint32)m_time + m_startTime) if (_vm->GetTime() > (uint32)m_time + m_startTime)
@ -2137,7 +2137,7 @@ void RMTextDialog::RemoveThis(CORO_PARAM, bool &result) {
} }
// Frase di background // Frase di background
else { else {
if (!(bCfgDubbing && hCustomSkip2 != INVALID_PID_VALUE)) if (!(bCfgDubbing && hCustomSkip2 != CORO_INVALID_PID_VALUE))
if (!m_bForceNoTime) if (!m_bForceNoTime)
if (_vm->GetTime() > (uint32)m_time + m_startTime) if (_vm->GetTime() > (uint32)m_time + m_startTime)
return; return;
@ -2148,15 +2148,15 @@ void RMTextDialog::RemoveThis(CORO_PARAM, bool &result) {
if (_vm->GetTime() > (uint32)m_time + m_startTime) if (_vm->GetTime() > (uint32)m_time + m_startTime)
return; return;
if (hCustomSkip != INVALID_PID_VALUE) { if (hCustomSkip != CORO_INVALID_PID_VALUE) {
CORO_INVOKE_3(g_scheduler->waitForSingleObject, hCustomSkip, 0, &_ctx->expired); CORO_INVOKE_3(CoroScheduler.waitForSingleObject, hCustomSkip, 0, &_ctx->expired);
// == WAIT_OBJECT_0 // == WAIT_OBJECT_0
if (!_ctx->expired) if (!_ctx->expired)
return; return;
} }
if (bCfgDubbing && hCustomSkip2 != INVALID_PID_VALUE) { if (bCfgDubbing && hCustomSkip2 != CORO_INVALID_PID_VALUE) {
CORO_INVOKE_3(g_scheduler->waitForSingleObject, hCustomSkip2, 0, &_ctx->expired); CORO_INVOKE_3(CoroScheduler.waitForSingleObject, hCustomSkip2, 0, &_ctx->expired);
// == WAIT_OBJECT_0 // == WAIT_OBJECT_0
if (!_ctx->expired) if (!_ctx->expired)
return; return;
@ -2170,7 +2170,7 @@ void RMTextDialog::RemoveThis(CORO_PARAM, bool &result) {
void RMTextDialog::Unregister(void) { void RMTextDialog::Unregister(void) {
RMGfxTask::Unregister(); RMGfxTask::Unregister();
assert(m_nInList == 0); assert(m_nInList == 0);
g_scheduler->setEvent(hEndDisplay); CoroScheduler.setEvent(hEndDisplay);
} }
void RMTextDialog::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) { void RMTextDialog::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
@ -2194,7 +2194,7 @@ void RMTextDialog::SetCustomSkipHandle2(uint32 hCustom) {
} }
void RMTextDialog::WaitForEndDisplay(CORO_PARAM) { void RMTextDialog::WaitForEndDisplay(CORO_PARAM) {
g_scheduler->waitForSingleObject(coroParam, hEndDisplay, INFINITE); CoroScheduler.waitForSingleObject(coroParam, hEndDisplay, CORO_INFINITE);
} }
void RMTextDialog::SetInput(RMInput *input) { void RMTextDialog::SetInput(RMInput *input) {
@ -2287,10 +2287,10 @@ void RMTextItemName::DoFrame(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMLocation &
ptr.SetSpecialPointer(RMPointer::PTR_NONE); ptr.SetSpecialPointer(RMPointer::PTR_NONE);
else { else {
_ctx->hThread = mpalQueryDoAction(20, m_item->MpalCode(), 0); _ctx->hThread = mpalQueryDoAction(20, m_item->MpalCode(), 0);
if (_ctx->hThread == INVALID_PID_VALUE) if (_ctx->hThread == CORO_INVALID_PID_VALUE)
ptr.SetSpecialPointer(RMPointer::PTR_NONE); ptr.SetSpecialPointer(RMPointer::PTR_NONE);
else else
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->hThread, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->hThread, CORO_INFINITE);
} }
} }
@ -2344,18 +2344,18 @@ RMDialogChoice::RMDialogChoice() {
DlgText.LoadPaletteWA(dlgpal); DlgText.LoadPaletteWA(dlgpal);
DlgTextLine.LoadPaletteWA(dlgpal); DlgTextLine.LoadPaletteWA(dlgpal);
hUnreg = g_scheduler->createEvent(false, false); hUnreg = CoroScheduler.createEvent(false, false);
bRemoveFromOT = false; bRemoveFromOT = false;
} }
RMDialogChoice::~RMDialogChoice() { RMDialogChoice::~RMDialogChoice() {
g_scheduler->closeEvent(hUnreg); CoroScheduler.closeEvent(hUnreg);
} }
void RMDialogChoice::Unregister(void) { void RMDialogChoice::Unregister(void) {
RMGfxWoodyBuffer::Unregister(); RMGfxWoodyBuffer::Unregister();
assert(!m_nInList); assert(!m_nInList);
g_scheduler->pulseEvent(hUnreg); CoroScheduler.pulseEvent(hUnreg);
bRemoveFromOT = false; bRemoveFromOT = false;
} }
@ -2547,7 +2547,7 @@ void RMDialogChoice::Hide(CORO_PARAM) {
m_bShow = false; m_bShow = false;
bRemoveFromOT = true; bRemoveFromOT = true;
CORO_INVOKE_2(g_scheduler->waitForSingleObject, hUnreg, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, hUnreg, CORO_INFINITE);
CORO_END_CODE; CORO_END_CODE;
} }

View file

@ -49,6 +49,7 @@
#define TONY_FONT_H #define TONY_FONT_H
#include "common/system.h" #include "common/system.h"
#include "common/coroutines.h"
#include "tony/gfxcore.h" #include "tony/gfxcore.h"
#include "tony/resid.h" #include "tony/resid.h"
#include "tony/sched.h" #include "tony/sched.h"

View file

@ -113,7 +113,7 @@ void MainUnfreeze(void) {
} }
void MainWaitFrame(CORO_PARAM) { void MainWaitFrame(CORO_PARAM) {
g_scheduler->waitForSingleObject(coroParam, _vm->m_hEndOfFrame, INFINITE); CoroScheduler.waitForSingleObject(coroParam, _vm->m_hEndOfFrame, CORO_INFINITE);
} }
void MainShowMouse(void) { void MainShowMouse(void) {

View file

@ -140,7 +140,7 @@ void RMGfxEngine::OpenOptionScreen(CORO_PARAM, int type) {
bIdleExited = false; bIdleExited = false;
g_scheduler->createProcess(ExitAllIdles, &m_nCurLoc, sizeof(int)); CoroScheduler.createProcess(ExitAllIdles, &m_nCurLoc, sizeof(int));
} }
} }
@ -242,7 +242,7 @@ void RMGfxEngine::DoFrame(CORO_PARAM, bool bDrawLocation) {
if (m_curAction != TA_COMBINE) if (m_curAction != TA_COMBINE)
CORO_INVOKE_3(m_tony.MoveAndDoAction, m_itemName.GetHotspot(), m_itemName.GetSelectedItem(), m_point.CurAction()); CORO_INVOKE_3(m_tony.MoveAndDoAction, m_itemName.GetHotspot(), m_itemName.GetSelectedItem(), m_point.CurAction());
else if (m_itemName.GetSelectedItem() != NULL) else if (m_itemName.GetSelectedItem() != NULL)
CORO_INVOKE_3(m_tony.MoveAndDoAction, m_itemName.GetHotspot(), m_itemName.GetSelectedItem(), TA_COMBINE, m_curActionObj); CORO_INVOKE_4(m_tony.MoveAndDoAction, m_itemName.GetHotspot(), m_itemName.GetSelectedItem(), TA_COMBINE, m_curActionObj);
} }
if (m_curAction == TA_COMBINE) { if (m_curAction == TA_COMBINE) {
@ -333,7 +333,7 @@ SKIPCLICKSINISTRO:
switch (m_nWipeType) { switch (m_nWipeType) {
case 1: case 1:
if (!(m_rcWipeEllipse.bottom - m_rcWipeEllipse.top >= FSTEP * 2)) { if (!(m_rcWipeEllipse.bottom - m_rcWipeEllipse.top >= FSTEP * 2)) {
g_scheduler->setEvent(m_hWipeEvent); CoroScheduler.setEvent(m_hWipeEvent);
m_nWipeType = 3; m_nWipeType = 3;
break; break;
} }
@ -346,7 +346,7 @@ SKIPCLICKSINISTRO:
case 2: case 2:
if (!(m_rcWipeEllipse.bottom - m_rcWipeEllipse.top < 480 - FSTEP)) { if (!(m_rcWipeEllipse.bottom - m_rcWipeEllipse.top < 480 - FSTEP)) {
g_scheduler->setEvent(m_hWipeEvent); CoroScheduler.setEvent(m_hWipeEvent);
m_nWipeType = 3; m_nWipeType = 3;
break; break;
} }
@ -529,7 +529,7 @@ uint32 RMGfxEngine::LoadLocation(int nLoc, RMPoint ptTonyStart, RMPoint start) {
m_bLocationLoaded = true; m_bLocationLoaded = true;
// On Enter per la locazion // On Enter per la locazion
return INVALID_PID_VALUE; //mpalQueryDoAction(0,m_nCurLoc,0); return CORO_INVALID_PID_VALUE; //mpalQueryDoAction(0,m_nCurLoc,0);
} }
void RMGfxEngine::UnloadLocation(CORO_PARAM, bool bDoOnExit, uint32 *result) { void RMGfxEngine::UnloadLocation(CORO_PARAM, bool bDoOnExit, uint32 *result) {
@ -545,8 +545,8 @@ void RMGfxEngine::UnloadLocation(CORO_PARAM, bool bDoOnExit, uint32 *result) {
// On Exit? // On Exit?
if (bDoOnExit) { if (bDoOnExit) {
_ctx->h = mpalQueryDoAction(1, m_nCurLoc, 0); _ctx->h = mpalQueryDoAction(1, m_nCurLoc, 0);
if (_ctx->h != INVALID_PID_VALUE) if (_ctx->h != CORO_INVALID_PID_VALUE)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->h, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->h, CORO_INFINITE);
} }
MainFreeze(); MainFreeze();
@ -557,7 +557,7 @@ void RMGfxEngine::UnloadLocation(CORO_PARAM, bool bDoOnExit, uint32 *result) {
m_loc.Unload(); m_loc.Unload();
if (result != NULL) if (result != NULL)
*result = INVALID_PID_VALUE; *result = CORO_INVALID_PID_VALUE;
CORO_END_CODE; CORO_END_CODE;
} }
@ -598,7 +598,7 @@ void RMGfxEngine::Init(/*HINSTANCE hInst*/) {
bIdleExited = false; bIdleExited = false;
m_bOption = false; m_bOption = false;
m_bWiping = false; m_bWiping = false;
m_hWipeEvent = g_scheduler->createEvent(false, false); m_hWipeEvent = CoroScheduler.createEvent(false, false);
// Crea l'evento di freeze // Crea l'evento di freeze
csMainLoop = g_system->createMutex(); csMainLoop = g_system->createMutex();
@ -1003,7 +1003,7 @@ void RMGfxEngine::CloseWipe(void) {
} }
void RMGfxEngine::WaitWipeEnd(CORO_PARAM) { void RMGfxEngine::WaitWipeEnd(CORO_PARAM) {
g_scheduler->waitForSingleObject(coroParam, m_hWipeEvent, INFINITE); CoroScheduler.waitForSingleObject(coroParam, m_hWipeEvent, CORO_INFINITE);
} }
} // End of namespace Tony } // End of namespace Tony

View file

@ -253,7 +253,7 @@ int RMPattern::Update(uint32 hEndPattern, byte &bFlag, RMSfx *sfx) {
// Se la speed e' 0, il pattern non avanza mai // Se la speed e' 0, il pattern non avanza mai
if (m_speed == 0) { if (m_speed == 0) {
g_scheduler->pulseEvent(hEndPattern); CoroScheduler.pulseEvent(hEndPattern);
bFlag=m_slots[m_nCurSlot].m_flag; bFlag=m_slots[m_nCurSlot].m_flag;
return m_nCurSprite; return m_nCurSprite;
} }
@ -267,7 +267,7 @@ int RMPattern::Update(uint32 hEndPattern, byte &bFlag, RMSfx *sfx) {
m_nCurSlot = 0; m_nCurSlot = 0;
bFlag = m_slots[m_nCurSlot].m_flag; bFlag = m_slots[m_nCurSlot].m_flag;
g_scheduler->pulseEvent(hEndPattern); CoroScheduler.pulseEvent(hEndPattern);
// @@@ Se non c'e' loop avverte che il pattern e' finito // @@@ Se non c'e' loop avverte che il pattern e' finito
// Se non c'e' loop rimane sull'ultimo frame // Se non c'e' loop rimane sull'ultimo frame
@ -835,12 +835,12 @@ RMItem::RMItem() {
m_bPal = 0; m_bPal = 0;
m_nCurSprite = 0; m_nCurSprite = 0;
m_hEndPattern = g_scheduler->createEvent(false, false); m_hEndPattern = CoroScheduler.createEvent(false, false);
} }
RMItem::~RMItem() { RMItem::~RMItem() {
Unload(); Unload();
g_scheduler->closeEvent(m_hEndPattern); CoroScheduler.closeEvent(m_hEndPattern);
} }
//FIXME: Pass uint32 directly for hCustomSkip //FIXME: Pass uint32 directly for hCustomSkip
@ -852,12 +852,12 @@ void RMItem::WaitForEndPattern(CORO_PARAM, uint32 hCustomSkip) {
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
if (m_nCurPattern != 0) { if (m_nCurPattern != 0) {
if (hCustomSkip == INVALID_PID_VALUE) if (hCustomSkip == CORO_INVALID_PID_VALUE)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, m_hEndPattern, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, m_hEndPattern, CORO_INFINITE);
else { else {
_ctx->h[0] = hCustomSkip; _ctx->h[0] = hCustomSkip;
_ctx->h[1] = m_hEndPattern; _ctx->h[1] = m_hEndPattern;
CORO_INVOKE_4(g_scheduler->waitForMultipleObjects, 2, &_ctx->h[0], false, INFINITE); CORO_INVOKE_4(CoroScheduler.waitForMultipleObjects, 2, &_ctx->h[0], false, CORO_INFINITE);
} }
} }
@ -888,13 +888,13 @@ void RMItem::PauseSound(bool bPause) {
RMWipe::RMWipe() { RMWipe::RMWipe() {
m_hUnregistered = g_scheduler->createEvent(false, false); m_hUnregistered = CoroScheduler.createEvent(false, false);
m_hEndOfFade = g_scheduler->createEvent(false, false); m_hEndOfFade = CoroScheduler.createEvent(false, false);
} }
RMWipe::~RMWipe() { RMWipe::~RMWipe() {
g_scheduler->closeEvent(m_hUnregistered); CoroScheduler.closeEvent(m_hUnregistered);
g_scheduler->closeEvent(m_hEndOfFade); CoroScheduler.closeEvent(m_hEndOfFade);
} }
int RMWipe::Priority(void) { int RMWipe::Priority(void) {
@ -904,7 +904,7 @@ int RMWipe::Priority(void) {
void RMWipe::Unregister(void) { void RMWipe::Unregister(void) {
RMGfxTask::Unregister(); RMGfxTask::Unregister();
assert(m_nInList == 0); assert(m_nInList == 0);
g_scheduler->setEvent(m_hUnregistered); CoroScheduler.setEvent(m_hUnregistered);
} }
bool RMWipe::RemoveThis(void) { bool RMWipe::RemoveThis(void) {
@ -917,7 +917,7 @@ void RMWipe::WaitForFadeEnd(CORO_PARAM) {
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
CORO_INVOKE_2(g_scheduler->waitForSingleObject, m_hEndOfFade, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, m_hEndOfFade, CORO_INFINITE);
m_bEndFade = true; m_bEndFade = true;
m_bFading = false; m_bFading = false;
@ -930,7 +930,7 @@ void RMWipe::WaitForFadeEnd(CORO_PARAM) {
void RMWipe::CloseFade(void) { void RMWipe::CloseFade(void) {
// m_bUnregister=true; // m_bUnregister=true;
// WaitForSingleObject(m_hUnregistered,INFINITE); // WaitForSingleObject(m_hUnregistered,CORO_INFINITE);
m_wip0r.Unload(); m_wip0r.Unload();
} }
@ -967,7 +967,7 @@ void RMWipe::DoFrame(RMGfxTargetBuffer &bigBuf) {
m_nFadeStep++; m_nFadeStep++;
if (m_nFadeStep == 10) { if (m_nFadeStep == 10) {
g_scheduler->setEvent(m_hEndOfFade); CoroScheduler.setEvent(m_hEndOfFade);
} }
} }
} }
@ -1096,7 +1096,7 @@ void RMCharacter::GoTo(CORO_PARAM, RMPoint destcoord, bool bReversed) {
if (m_pos == destcoord) { if (m_pos == destcoord) {
if (minpath == 0) { if (minpath == 0) {
CORO_INVOKE_0(Stop); CORO_INVOKE_0(Stop);
g_scheduler->pulseEvent(hEndOfPath); CoroScheduler.pulseEvent(hEndOfPath);
return; return;
} }
} }
@ -1478,7 +1478,7 @@ void RMCharacter::DoFrame(CORO_PARAM, RMGfxTargetBuffer* bigBuf, int loc) {
if (!bEndOfPath) if (!bEndOfPath)
CORO_INVOKE_0(Stop); CORO_INVOKE_0(Stop);
bEndOfPath = true; bEndOfPath = true;
g_scheduler->pulseEvent(hEndOfPath); CoroScheduler.pulseEvent(hEndOfPath);
} }
walkcount++; walkcount++;
@ -1516,7 +1516,7 @@ void RMCharacter::DoFrame(CORO_PARAM, RMGfxTargetBuffer* bigBuf, int loc) {
if (!bEndOfPath) if (!bEndOfPath)
CORO_INVOKE_0(Stop); CORO_INVOKE_0(Stop);
bEndOfPath = true; bEndOfPath = true;
g_scheduler->pulseEvent(hEndOfPath); CoroScheduler.pulseEvent(hEndOfPath);
} }
} else { } else {
// Se siamo già entrati nell'ultimo box, dobbiamo solo muoverci in linea retta verso il // Se siamo già entrati nell'ultimo box, dobbiamo solo muoverci in linea retta verso il
@ -1687,7 +1687,7 @@ void RMCharacter::WaitForEndMovement(CORO_PARAM) {
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
if (bMoving) if (bMoving)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, hEndOfPath, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, hEndOfPath, CORO_INFINITE);
CORO_END_CODE; CORO_END_CODE;
} }
@ -1701,7 +1701,7 @@ bool RMCharacter::RemoveThis(void) {
RMCharacter::RMCharacter() { RMCharacter::RMCharacter() {
csMove = g_system->createMutex(); csMove = g_system->createMutex();
hEndOfPath = g_scheduler->createEvent(false, false); hEndOfPath = CoroScheduler.createEvent(false, false);
minpath = 0; minpath = 0;
curSpeed = 3; curSpeed = 3;
bRemoveFromOT = false; bRemoveFromOT = false;
@ -1722,7 +1722,7 @@ RMCharacter::RMCharacter() {
RMCharacter::~RMCharacter() { RMCharacter::~RMCharacter() {
g_system->deleteMutex(csMove); g_system->deleteMutex(csMove);
g_scheduler->closeEvent(hEndOfPath); CoroScheduler.closeEvent(hEndOfPath);
} }
void RMCharacter::LinkToBoxes(RMGameBoxes *boxes) { void RMCharacter::LinkToBoxes(RMGameBoxes *boxes) {

View file

@ -292,7 +292,7 @@ public:
void Unload(void); void Unload(void);
// Aspetta la fine del pattern in play // Aspetta la fine del pattern in play
void WaitForEndPattern(CORO_PARAM, uint32 hCustomSkip = INVALID_PID_VALUE); void WaitForEndPattern(CORO_PARAM, uint32 hCustomSkip = CORO_INVALID_PID_VALUE);
// Setta un nuovo hotspot per l'oggetto // Setta un nuovo hotspot per l'oggetto
void ChangeHotspot(RMPoint pt); void ChangeHotspot(RMPoint pt);

View file

@ -1,7 +1,6 @@
MODULE := engines/tony MODULE := engines/tony
MODULE_OBJS := \ MODULE_OBJS := \
coroutine.o \
custom.o \ custom.o \
detection.o \ detection.o \
font.o \ font.o \
@ -11,7 +10,6 @@ MODULE_OBJS := \
input.o \ input.o \
inventory.o \ inventory.o \
loc.o \ loc.o \
sched.o \
sound.o \ sound.o \
tony.o \ tony.o \
tonychar.o \ tonychar.o \

View file

@ -883,13 +883,13 @@ void ScriptThread(CORO_PARAM, const void *param) {
for (_ctx->i = 0; _ctx->i < s->nMoments; _ctx->i++) { for (_ctx->i = 0; _ctx->i < s->nMoments; _ctx->i++) {
// Dorme il tempo necessario per arrivare al momento successivo // Dorme il tempo necessario per arrivare al momento successivo
if (s->Moment[_ctx->i].dwTime == -1) { if (s->Moment[_ctx->i].dwTime == -1) {
CORO_INVOKE_4(g_scheduler->waitForMultipleObjects, _ctx->numHandles, cfHandles, true, INFINITE); CORO_INVOKE_4(CoroScheduler.waitForMultipleObjects, _ctx->numHandles, cfHandles, true, CORO_INFINITE);
_ctx->dwStartTime = _vm->GetTime(); _ctx->dwStartTime = _vm->GetTime();
} else { } else {
_ctx->dwCurTime = _vm->GetTime(); _ctx->dwCurTime = _vm->GetTime();
if (_ctx->dwCurTime < _ctx->dwStartTime + (s->Moment[_ctx->i].dwTime * 100)) { 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); // 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); CORO_INVOKE_1(CoroScheduler.sleep, _ctx->dwStartTime+(s->Moment[_ctx->i].dwTime * 100) - _ctx->dwCurTime);
} }
} }
@ -913,7 +913,7 @@ void ScriptThread(CORO_PARAM, const void *param) {
_ctx->p->arg4=s->Command[_ctx->k].arg4; _ctx->p->arg4=s->Command[_ctx->k].arg4;
// !!! Nuova gestione dei thread // !!! Nuova gestione dei thread
if ((cfHandles[_ctx->numHandles++] = g_scheduler->createProcess(CustomThread, &_ctx->p, sizeof(LPCFCALL))) == 0) { if ((cfHandles[_ctx->numHandles++] = CoroScheduler.createProcess(CustomThread, &_ctx->p, sizeof(LPCFCALL))) == 0) {
mpalError = 1; mpalError = 1;
CORO_KILL_SELF(); CORO_KILL_SELF();
@ -976,7 +976,7 @@ void ActionThread(CORO_PARAM, const void *param) {
if (item->Command[_ctx->k].type == 1) { if (item->Command[_ctx->k].type == 1) {
// Custom function // Custom function
debugC(DEBUG_DETAILED, kTonyDebugActions, "Action Process %d Call=%s params=%d,%d,%d,%d", debugC(DEBUG_DETAILED, kTonyDebugActions, "Action Process %d Call=%s params=%d,%d,%d,%d",
g_scheduler->getCurrentPID(), lplpFunctionStrings[item->Command[_ctx->k].nCf].c_str(), CoroScheduler.getCurrentPID(), lplpFunctionStrings[item->Command[_ctx->k].nCf].c_str(),
item->Command[_ctx->k].arg1, item->Command[_ctx->k].arg2, item->Command[_ctx->k].arg1, item->Command[_ctx->k].arg2,
item->Command[_ctx->k].arg3, item->Command[_ctx->k].arg4 item->Command[_ctx->k].arg3, item->Command[_ctx->k].arg4
); );
@ -991,7 +991,7 @@ void ActionThread(CORO_PARAM, const void *param) {
} else if (item->Command[_ctx->k].type == 2) { } else if (item->Command[_ctx->k].type == 2) {
// Variable assign // Variable assign
debugC(DEBUG_DETAILED, kTonyDebugActions, "Action Process %d Variable=%s", debugC(DEBUG_DETAILED, kTonyDebugActions, "Action Process %d Variable=%s",
g_scheduler->getCurrentPID(), item->Command[_ctx->k].lpszVarName); CoroScheduler.getCurrentPID(), item->Command[_ctx->k].lpszVarName);
LockVar(); LockVar();
varSetValue(item->Command[_ctx->k].lpszVarName, EvaluateExpression(item->Command[_ctx->k].expr)); varSetValue(item->Command[_ctx->k].lpszVarName, EvaluateExpression(item->Command[_ctx->k].expr));
@ -1005,7 +1005,7 @@ void ActionThread(CORO_PARAM, const void *param) {
GlobalFree(item); GlobalFree(item);
debugC(DEBUG_DETAILED, kTonyDebugActions, "Action Process %d ended", g_scheduler->getCurrentPID()); debugC(DEBUG_DETAILED, kTonyDebugActions, "Action Process %d ended", CoroScheduler.getCurrentPID());
CORO_KILL_SELF(); CORO_KILL_SELF();
@ -1026,7 +1026,7 @@ void ShutUpActionThread(CORO_PARAM, const void *param) {
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
CORO_INVOKE_2(g_scheduler->waitForSingleObject, pid, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, pid, CORO_INFINITE);
bExecutingAction = false; bExecutingAction = false;
@ -1200,7 +1200,7 @@ void LocationPollThread(CORO_PARAM, const void *param) {
/* Ci addormentiamo, ma controllando sempre l'evento che viene settato /* Ci addormentiamo, ma controllando sempre l'evento che viene settato
quando viene richiesta la nostra chiusura */ quando viene richiesta la nostra chiusura */
CORO_INVOKE_3(g_scheduler->waitForSingleObject, hEndPollingLocations[id], _ctx->dwSleepTime, &_ctx->expired); CORO_INVOKE_3(CoroScheduler.waitForSingleObject, hEndPollingLocations[id], _ctx->dwSleepTime, &_ctx->expired);
//if (_ctx->k == WAIT_OBJECT_0) //if (_ctx->k == WAIT_OBJECT_0)
if (!_ctx->expired) if (!_ctx->expired)
@ -1208,7 +1208,7 @@ void LocationPollThread(CORO_PARAM, const void *param) {
for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++) for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++)
if (_ctx->MyThreads[_ctx->i].nItem != 0) { if (_ctx->MyThreads[_ctx->i].nItem != 0) {
CORO_INVOKE_3(g_scheduler->waitForSingleObject, _ctx->MyThreads[_ctx->i].hThread, 0, &_ctx->delayExpired); CORO_INVOKE_3(CoroScheduler.waitForSingleObject, _ctx->MyThreads[_ctx->i].hThread, 0, &_ctx->delayExpired);
// if result ) == WAIT_OBJECT_0) // if result ) == WAIT_OBJECT_0)
if (!_ctx->delayExpired) if (!_ctx->delayExpired)
@ -1279,7 +1279,7 @@ void LocationPollThread(CORO_PARAM, const void *param) {
_ctx->MyThreads[_ctx->i].nItem = _ctx->MyActions[_ctx->k].nItem; _ctx->MyThreads[_ctx->i].nItem = _ctx->MyActions[_ctx->k].nItem;
// !!! Nuova gestione dei thread // !!! Nuova gestione dei thread
if ((_ctx->MyThreads[_ctx->i].hThread = g_scheduler->createProcess(ActionThread, &_ctx->newItem, sizeof(LPMPALITEM))) == 0) { if ((_ctx->MyThreads[_ctx->i].hThread = CoroScheduler.createProcess(ActionThread, &_ctx->newItem, sizeof(LPMPALITEM))) == 0) {
//if ((_ctx->MyThreads[_ctx->i].hThread=(void*)_beginthread(ActionThread, 10240,(void *)_ctx->newItem))==(void*)-1) //if ((_ctx->MyThreads[_ctx->i].hThread=(void*)_beginthread(ActionThread, 10240,(void *)_ctx->newItem))==(void*)-1)
GlobalFree(_ctx->newItem); GlobalFree(_ctx->newItem);
GlobalFree(_ctx->MyThreads); GlobalFree(_ctx->MyThreads);
@ -1309,18 +1309,18 @@ void LocationPollThread(CORO_PARAM, const void *param) {
// Set idle skip on // Set idle skip on
// FIXME: Convert to co-routine // FIXME: Convert to co-routine
lplpFunctions[200](nullContext, 0, 0, 0, 0); CORO_INVOKE_4(lplpFunctions[200], 0, 0, 0, 0);
for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++) for (_ctx->i = 0; _ctx->i < _ctx->nRealItems; _ctx->i++)
if (_ctx->MyThreads[_ctx->i].nItem != 0) { if (_ctx->MyThreads[_ctx->i].nItem != 0) {
CORO_INVOKE_3(g_scheduler->waitForSingleObject, _ctx->MyThreads[_ctx->i].hThread, 5000, &_ctx->delayExpired); CORO_INVOKE_3(CoroScheduler.waitForSingleObject, _ctx->MyThreads[_ctx->i].hThread, 5000, &_ctx->delayExpired);
/* /*
//if (result != WAIT_OBJECT_0) //if (result != WAIT_OBJECT_0)
if (_ctx->delayExpired) if (_ctx->delayExpired)
TerminateThread(_ctx->MyThreads[_ctx->i].hThread, 0); TerminateThread(_ctx->MyThreads[_ctx->i].hThread, 0);
*/ */
g_scheduler->killMatchingProcess(_ctx->MyThreads[_ctx->i].hThread); CoroScheduler.killMatchingProcess(_ctx->MyThreads[_ctx->i].hThread);
} }
// Set idle skip off // Set idle skip off
@ -1361,13 +1361,13 @@ void ShutUpDialogThread(CORO_PARAM, const void *param) {
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
CORO_INVOKE_2(g_scheduler->waitForSingleObject, pid, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, pid, CORO_INFINITE);
bExecutingDialog = false; bExecutingDialog = false;
nExecutingDialog = 0; nExecutingDialog = 0;
nExecutingChoice = 0; nExecutingChoice = 0;
g_scheduler->setEvent(hAskChoice); CoroScheduler.setEvent(hAskChoice);
CORO_KILL_SELF(); CORO_KILL_SELF();
@ -1519,9 +1519,9 @@ void DoChoice(CORO_PARAM, uint32 nChoice) {
/* Avvertiamo il gioco che c'e' una scelta da far fare all'utente, /* Avvertiamo il gioco che c'e' una scelta da far fare all'utente,
e restiamo in attesa della risposta */ e restiamo in attesa della risposta */
g_scheduler->resetEvent(hDoneChoice); CoroScheduler.resetEvent(hDoneChoice);
g_scheduler->setEvent(hAskChoice); CoroScheduler.setEvent(hAskChoice);
CORO_INVOKE_2(g_scheduler->waitForSingleObject, hDoneChoice, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, hDoneChoice, CORO_INFINITE);
/* Ora che la scelta e' stata effettuata, possiamo eseguire _ctx->i gruppi /* Ora che la scelta e' stata effettuata, possiamo eseguire _ctx->i gruppi
associati con la scelta */ associati con la scelta */
@ -1569,7 +1569,7 @@ void DoChoice(CORO_PARAM, uint32 nChoice) {
* uint32 dwParam Eventuale parametro per l'azione * uint32 dwParam Eventuale parametro per l'azione
* *
* Return: Handle del thread che sta eseguendo l'azione, oppure * Return: Handle del thread che sta eseguendo l'azione, oppure
* INVALID_PID_VALUE se l'azione non e' definita, o l'item * CORO_INVALID_PID_VALUE se l'azione non e' definita, o l'item
* e' disattivato. * e' disattivato.
* *
* Note: Si puo' ottenere l'indice dell'item a partire dal suo numero * Note: Si puo' ottenere l'indice dell'item a partire dal suo numero
@ -1588,7 +1588,7 @@ static uint32 DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
item+=ordItem; item+=ordItem;
Common::String buf = Common::String::format("Status.%u", item->nObj); Common::String buf = Common::String::format("Status.%u", item->nObj);
if (varGetValue(buf.c_str()) <= 0) if (varGetValue(buf.c_str()) <= 0)
return INVALID_PID_VALUE; return CORO_INVALID_PID_VALUE;
for (i = 0; i < item->nActions; i++) { for (i = 0; i < item->nActions; i++) {
if (item->Action[i].num != nAction) if (item->Action[i].num != nAction)
@ -1606,7 +1606,7 @@ static uint32 DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
// Duplichiamo l'item corrente e copiamo la azione #i nella #0 // Duplichiamo l'item corrente e copiamo la azione #i nella #0
newitem = (LPMPALITEM)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(MPALITEM)); newitem = (LPMPALITEM)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(MPALITEM));
if (newitem == NULL) if (newitem == NULL)
return INVALID_PID_VALUE; return CORO_INVALID_PID_VALUE;
// Nella nuova versione scriviamo il numero dell'azione in dwRes // Nella nuova versione scriviamo il numero dell'azione in dwRes
Common::copy((byte *)item, (byte *)item + sizeof(MPALITEM), (byte *)newitem); Common::copy((byte *)item, (byte *)item + sizeof(MPALITEM), (byte *)newitem);
@ -1619,11 +1619,11 @@ static uint32 DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
// 0 dell'item, e poi liberera' la memoria con la GlobalFree() // 0 dell'item, e poi liberera' la memoria con la GlobalFree()
// !!! New thread management // !!! New thread management
if ((h = g_scheduler->createProcess(ActionThread, &newitem, sizeof(LPMPALITEM))) == NULL) if ((h = CoroScheduler.createProcess(ActionThread, &newitem, sizeof(LPMPALITEM))) == NULL)
return INVALID_PID_VALUE; return CORO_INVALID_PID_VALUE;
if (g_scheduler->createProcess(ShutUpActionThread, &h, sizeof(uint32)) == NULL) if (CoroScheduler.createProcess(ShutUpActionThread, &h, sizeof(uint32)) == NULL)
return INVALID_PID_VALUE; return CORO_INVALID_PID_VALUE;
nExecutingAction = item->nObj; nExecutingAction = item->nObj;
bExecutingAction = true; bExecutingAction = true;
@ -1631,7 +1631,7 @@ static uint32 DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
return h; return h;
} }
return INVALID_PID_VALUE; return CORO_INVALID_PID_VALUE;
} }
/** /**
@ -1640,7 +1640,7 @@ static uint32 DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
* @param nDlgOrd The index of the dialog in the dialog list * @param nDlgOrd The index of the dialog in the dialog list
* @param nGroup Number of the group to perform * @param nGroup Number of the group to perform
* @returns The process Id of the process running the dialog * @returns The process Id of the process running the dialog
* or INVALID_PID_VALUE on error * or CORO_INVALID_PID_VALUE on error
* @remarks The dialogue runs in a thread created on purpose, * @remarks The dialogue runs in a thread created on purpose,
* so that must inform through an event and when 'necessary to you make a choice. * so that must inform through an event and when 'necessary to you make a choice.
* The data on the choices may be obtained through various queries. * The data on the choices may be obtained through various queries.
@ -1654,20 +1654,20 @@ static uint32 DoDialog(uint32 nDlgOrd, uint32 nGroup) {
// Enables the flag to indicate that there is' a running dialogue // Enables the flag to indicate that there is' a running dialogue
bExecutingDialog = true; bExecutingDialog = true;
g_scheduler->resetEvent(hAskChoice); CoroScheduler.resetEvent(hAskChoice);
g_scheduler->resetEvent(hDoneChoice); CoroScheduler.resetEvent(hDoneChoice);
// Create a thread that performs the dialogue group // Create a thread that performs the dialogue group
// Create the process // Create the process
if ((h = g_scheduler->createProcess(GroupThread, &nGroup, sizeof(uint32))) == INVALID_PID_VALUE) if ((h = CoroScheduler.createProcess(GroupThread, &nGroup, sizeof(uint32))) == CORO_INVALID_PID_VALUE)
return INVALID_PID_VALUE; return CORO_INVALID_PID_VALUE;
// Create a thread that waits until the end of the dialog process, and will restore the global variables // Create a thread that waits until the end of the dialog process, and will restore the global variables
if (g_scheduler->createProcess(ShutUpDialogThread, &h, sizeof(uint32)) == INVALID_PID_VALUE) { if (CoroScheduler.createProcess(ShutUpDialogThread, &h, sizeof(uint32)) == CORO_INVALID_PID_VALUE) {
// Something went wrong, so kill the previously started dialog process // Something went wrong, so kill the previously started dialog process
g_scheduler->killMatchingProcess(h); CoroScheduler.killMatchingProcess(h);
return INVALID_PID_VALUE; return CORO_INVALID_PID_VALUE;
} }
return h; return h;
@ -1700,7 +1700,7 @@ bool DoSelection(uint32 i, uint32 dwData) {
return false; return false;
nSelectedChoice = j; nSelectedChoice = j;
g_scheduler->setEvent(hDoneChoice); CoroScheduler.setEvent(hDoneChoice);
return true; return true;
} }
@ -1877,8 +1877,8 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName,
/* Crea l'evento che verra' utilizzato per avvertire il gioco che c'e' /* Crea l'evento che verra' utilizzato per avvertire il gioco che c'e'
da effettuare una scelta */ da effettuare una scelta */
hAskChoice = g_scheduler->createEvent(true, false); hAskChoice = CoroScheduler.createEvent(true, false);
hDoneChoice = g_scheduler->createEvent(true, false); hDoneChoice = CoroScheduler.createEvent(true, false);
return true; return true;
} }
@ -2070,7 +2070,7 @@ uint32 mpalQueryDWORD(uint16 wQueryType, ...) {
if (y != -1) { if (y != -1) {
dwRet = DoAction(x, y, GETARG(uint32)); dwRet = DoAction(x, y, GETARG(uint32));
} else { } else {
dwRet = INVALID_PID_VALUE; dwRet = CORO_INVALID_PID_VALUE;
mpalError = 1; mpalError = 1;
} }
@ -2278,9 +2278,9 @@ void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, ...) {
/* /*
* void mpalQuery(MPQ_DIALOG_WAITFORCHOICE); * void mpalQuery(MPQ_DIALOG_WAITFORCHOICE);
*/ */
CORO_INVOKE_2(g_scheduler->waitForSingleObject, hAskChoice, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, hAskChoice, CORO_INFINITE);
g_scheduler->resetEvent(hAskChoice); CoroScheduler.resetEvent(hAskChoice);
if (bExecutingDialog) if (bExecutingDialog)
*dwRet = (uint32)nExecutingChoice; *dwRet = (uint32)nExecutingChoice;
@ -2338,7 +2338,7 @@ bool EXPORT mpalExecuteScript(int nScript) {
UnlockScripts(); UnlockScripts();
// !!! Nuova gestione dei thread // !!! Nuova gestione dei thread
if (g_scheduler->createProcess(ScriptThread, &s, sizeof(LPMPALSCRIPT)) == INVALID_PID_VALUE) if (CoroScheduler.createProcess(ScriptThread, &s, sizeof(LPMPALSCRIPT)) == CORO_INVALID_PID_VALUE)
return false; return false;
return true; return true;
@ -2388,9 +2388,9 @@ bool mpalStartIdlePoll(int nLoc) {
if (nPollingLocations[i] == 0) { if (nPollingLocations[i] == 0) {
nPollingLocations[i] = nLoc; nPollingLocations[i] = nLoc;
hEndPollingLocations[i] = g_scheduler->createEvent(true, false); hEndPollingLocations[i] = CoroScheduler.createEvent(true, false);
// !!! Nuova gestione dei thread // !!! Nuova gestione dei thread
if ((PollingThreads[i] = g_scheduler->createProcess(LocationPollThread, &i, sizeof(uint32))) == 0) if ((PollingThreads[i] = CoroScheduler.createProcess(LocationPollThread, &i, sizeof(uint32))) == 0)
// if ((hEndPollingLocations[i]=(void*)_beginthread(LocationPollThread, 10240,(void *)i))==(void*)-1) // if ((hEndPollingLocations[i]=(void*)_beginthread(LocationPollThread, 10240,(void *)i))==(void*)-1)
return false; return false;
@ -2425,11 +2425,11 @@ void mpalEndIdlePoll(CORO_PARAM, int nLoc, bool *result) {
for (_ctx->i = 0; _ctx->i < MAXPOLLINGLOCATIONS; _ctx->i++) { for (_ctx->i = 0; _ctx->i < MAXPOLLINGLOCATIONS; _ctx->i++) {
if (nPollingLocations[_ctx->i] == (uint32)nLoc) { if (nPollingLocations[_ctx->i] == (uint32)nLoc) {
g_scheduler->setEvent(hEndPollingLocations[_ctx->i]); CoroScheduler.setEvent(hEndPollingLocations[_ctx->i]);
CORO_INVOKE_2(g_scheduler->waitForSingleObject, PollingThreads[_ctx->i], INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, PollingThreads[_ctx->i], CORO_INFINITE);
g_scheduler->closeEvent(hEndPollingLocations[_ctx->i]); CoroScheduler.closeEvent(hEndPollingLocations[_ctx->i]);
nPollingLocations[_ctx->i] = 0; nPollingLocations[_ctx->i] = 0;
if (result) if (result)

View file

@ -118,9 +118,9 @@
#define TONY_MPAL_H #define TONY_MPAL_H
#include "common/scummsys.h" #include "common/scummsys.h"
#include "common/coroutines.h"
#include "common/rect.h" #include "common/rect.h"
#include "common/str.h" #include "common/str.h"
#include "tony/coroutine.h"
namespace Tony { namespace Tony {
@ -537,7 +537,7 @@ typedef LPITEMIRQFUNCTION* LPLPITEMIRQFUNCTION;
* uint32 dwParam Action parameter * uint32 dwParam Action parameter
* *
* Return: Handle to the thread that is performing the action, or * Return: Handle to the thread that is performing the action, or
* INVALID_PID_VALUE if the action is not 'defined for * CORO_INVALID_PID_VALUE if the action is not 'defined for
* the item, or the item and 'off. * the item, or the item and 'off.
* *
* Note: The parameter is used primarily to implement actions * Note: The parameter is used primarily to implement actions
@ -561,7 +561,7 @@ typedef LPITEMIRQFUNCTION* LPLPITEMIRQFUNCTION;
* uint32 nGroup Group number to use * uint32 nGroup Group number to use
* *
* Return: Handle to the thread that is running the box, or * Return: Handle to the thread that is running the box, or
* INVALID_PID_VALUE if the dialogue does not exist. * CORO_INVALID_PID_VALUE if the dialogue does not exist.
* *
\****************************************************************************/ \****************************************************************************/

View file

@ -24,133 +24,4 @@
#ifndef TONY_SCHED_H #ifndef TONY_SCHED_H
#define TONY_SCHED_H #define TONY_SCHED_H
#include "common/list.h"
#include "tony/coroutine.h"
namespace Tony {
// the size of process specific info
#define PARAM_SIZE 32
// the maximum number of processes
#define NUM_PROCESS 100
#define MAX_PROCESSES 100
#define INFINITE 0xffffffff
#define INVALID_PID_VALUE 0
typedef void (*CORO_ADDR)(CoroContext &, const void *);
/** process structure */
struct PROCESS {
PROCESS *pNext; ///< pointer to next process in active or free list
PROCESS *pPrevious; ///< pointer to previous process in active or free list
CoroContext state; ///< the state of the coroutine
CORO_ADDR coroAddr; ///< the entry point of the coroutine
int sleepTime; ///< number of scheduler cycles to sleep
uint32 pid; ///< process ID
bool waiting; ///< process is currently in a waiting state
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).
*/
class Scheduler {
public:
/** Pointer to a function of the form "void function(PPROCESS)" */
typedef void (*VFPTRPP)(PROCESS *);
private:
/** list of all processes */
PROCESS *processList;
/** active process list - also saves scheduler state */
PROCESS *active;
/** pointer to free process list */
PROCESS *pFreeProcesses;
/** the currently active process */
PROCESS *pCurrent;
/** Auto-incrementing process Id */
int pidCounter;
/** Event list */
Common::List<EVENT *> _events;
#ifdef DEBUG
// diagnostic process counters
int numProcs;
int maxProcs;
void CheckStack();
#endif
/**
* Called from killProcess() to enable other resources
* a process may be allocated to be released.
*/
VFPTRPP pRCfunction;
PROCESS *getProcess(uint32 pid);
EVENT *getEvent(uint32 pid);
public:
Scheduler();
~Scheduler();
void reset();
#ifdef DEBUG
void printStats();
#endif
void schedule();
void rescheduleAll();
void reschedule(PPROCESS pReSchedProc = NULL);
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);
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) {
return createProcess(coroAddr, &pParam, sizeof(void *));
}
void killProcess(PROCESS *pKillProc);
PROCESS *getCurrentProcess();
int getCurrentPID() const;
int killMatchingProcess(uint32 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);
void pulseEvent(uint32 pidEvent);
};
extern Scheduler *g_scheduler; // FIXME: Temporary global var, to be used until everything has been OOifyied
} // End of namespace Tony
#endif // TONY_SCHED_H #endif // TONY_SCHED_H

View file

@ -1021,7 +1021,7 @@ FPSFX::FPSFX(LPDIRECTSOUND lpds, HWND hWnd, bool bSoundOn) {
lpDSNotify = NULL; lpDSNotify = NULL;
lpDS = lpds; lpDS = lpds;
lastVolume = 63; lastVolume = 63;
hEndOfBuffer = INVALID_PID_VALUE; hEndOfBuffer = CORO_INVALID_PID_VALUE;
bIsVoice = false; bIsVoice = false;
if (bSoundSupported == false) if (bSoundSupported == false)
@ -1053,7 +1053,7 @@ FPSFX::~FPSFX() {
RELEASE(lpDSNotify); RELEASE(lpDSNotify);
if (hEndOfBuffer != INVALID_PID_VALUE) if (hEndOfBuffer != CORO_INVALID_PID_VALUE)
CloseHandle(hEndOfBuffer); CloseHandle(hEndOfBuffer);
RELEASE(lpDSBuffer); RELEASE(lpDSBuffer);
@ -1415,7 +1415,7 @@ bool FPSFX::LoadFile(const char *lpszFileName, uint32 dwCodec) {
bool FPSFX::Play() { bool FPSFX::Play() {
#ifdef REFACTOR_ME #ifdef REFACTOR_ME
if (bFileLoaded) { if (bFileLoaded) {
if (hEndOfBuffer != INVALID_PID_VALUE) if (hEndOfBuffer != CORO_INVALID_PID_VALUE)
ResetEvent(hEndOfBuffer); ResetEvent(hEndOfBuffer);
lpDSBuffer->SetCurrentPosition(0); lpDSBuffer->SetCurrentPosition(0);
@ -2012,7 +2012,7 @@ bool FPSTREAM::Stop(bool bSync) {
/* Avverte il thread che deve uscire e aspetta che si chiuda */ /* Avverte il thread che deve uscire e aspetta che si chiuda */
SetEvent(hThreadEnd); SetEvent(hThreadEnd);
WaitForSingleObject(hPlayThread, INFINITE); WaitForSingleObject(hPlayThread, CORO_INFINITE);
/* Chiude l'handle del thread e disalloca la memoria temporanea */ /* Chiude l'handle del thread e disalloca la memoria temporanea */
CloseHandle(hPlayThread); CloseHandle(hPlayThread);
@ -2048,7 +2048,7 @@ void FPSTREAM::WaitForSync(FPSTREAM *toplay) {
this->lpDSBuffer, &this->SyncToPlay, SyncToPlay, &bSyncExit, bSyncExit, GetCurrentThreadId()); this->lpDSBuffer, &this->SyncToPlay, SyncToPlay, &bSyncExit, bSyncExit, GetCurrentThreadId());
warning(buf); warning(buf);
WaitForSingleObject(hPlayThread, INFINITE); WaitForSingleObject(hPlayThread, CORO_INFINITE);
/* Chiude l'handle del thread e disalloca la memoria temporanea */ /* Chiude l'handle del thread e disalloca la memoria temporanea */
CloseHandle(hPlayThread); CloseHandle(hPlayThread);
@ -2109,7 +2109,7 @@ void PASCAL FPSTREAM::PlayThread(FPSTREAM *This) {
// sprintf(buf, "WFMO: %x (buf status: %x) MyThread: 0x%x\n", This->lpDSBuffer, dwBufStatus, GetCurrentThreadId()); // sprintf(buf, "WFMO: %x (buf status: %x) MyThread: 0x%x\n", This->lpDSBuffer, dwBufStatus, GetCurrentThreadId());
// warning(buf); // warning(buf);
dwResult = WaitForMultipleObjects(5, hList, false, INFINITE); dwResult = WaitForMultipleObjects(5, hList, false, CORO_INFINITE);
/* uint32 dwPlay, dwWrite; /* uint32 dwPlay, dwWrite;
This->lpDSBuffer->GetCurrentPosition(&dwPlay, &dwWrite); This->lpDSBuffer->GetCurrentPosition(&dwPlay, &dwWrite);

View file

@ -36,7 +36,7 @@ namespace Tony {
TonyEngine *_vm; TonyEngine *_vm;
TonyEngine::TonyEngine(OSystem *syst, const TonyGameDescription *gameDesc) : Engine(syst), TonyEngine::TonyEngine(OSystem *syst, const TonyGameDescription *gameDesc) : Engine(syst),
_gameDescription(gameDesc), _randomSource("tony"), _scheduler() { _gameDescription(gameDesc), _randomSource("tony") {
_vm = this; _vm = this;
DebugMan.addDebugChannel(kTonyDebugAnimations, "animations", "Animations debugging"); DebugMan.addDebugChannel(kTonyDebugAnimations, "animations", "Animations debugging");
@ -48,6 +48,9 @@ TonyEngine::TonyEngine(OSystem *syst, const TonyGameDescription *gameDesc) : Eng
TonyEngine::~TonyEngine() { TonyEngine::~TonyEngine() {
// Close the voice database // Close the voice database
CloseVoiceDatabase(); CloseVoiceDatabase();
// Reset the coroutine scheduler
CoroScheduler.reset();
} }
/** /**
@ -68,14 +71,14 @@ Common::Error TonyEngine::run() {
* Initialise the game * Initialise the game
*/ */
Common::ErrorCode TonyEngine::Init() { Common::ErrorCode TonyEngine::Init() {
m_hEndOfFrame = g_scheduler->createEvent(false, false); m_hEndOfFrame = CoroScheduler.createEvent(false, false);
m_bPaused = false; m_bPaused = false;
m_bDrawLocation = true; m_bDrawLocation = true;
m_startTime = g_system->getMillis(); m_startTime = g_system->getMillis();
// Reset the scheduler // Reset the scheduler
_scheduler.reset(); CoroScheduler.reset();
// Initialise the graphics window // Initialise the graphics window
_window.Init(); _window.Init();
@ -413,7 +416,7 @@ void TonyEngine::PlayProcess(CORO_PARAM, const void *param) {
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
// Infinite loop. We rely on the outer main process to detect if a shutdown is required, // CORO_INFINITE loop. We rely on the outer main process to detect if a shutdown is required,
// and kill the scheudler and all the processes, including this one // and kill the scheudler and all the processes, including this one
for (;;) { for (;;) {
// Se siamo in pausa, entra nel loop appropriato // Se siamo in pausa, entra nel loop appropriato
@ -421,14 +424,14 @@ void TonyEngine::PlayProcess(CORO_PARAM, const void *param) {
_vm->PauseLoop(); _vm->PauseLoop();
// Wait for the next frame // Wait for the next frame
CORO_INVOKE_1(g_scheduler->sleep, 50); CORO_INVOKE_1(CoroScheduler.sleep, 50);
// Call the engine to handle the next frame // Call the engine to handle the next frame
// FIXME: This needs to be moved into it's own process // FIXME: This needs to be moved into it's own process
CORO_INVOKE_1(_vm->_theEngine.DoFrame, _vm->m_bDrawLocation); CORO_INVOKE_1(_vm->_theEngine.DoFrame, _vm->m_bDrawLocation);
// Warns that a frame is finished // Warns that a frame is finished
g_scheduler->pulseEvent(_vm->m_hEndOfFrame); CoroScheduler.pulseEvent(_vm->m_hEndOfFrame);
// Handle drawing the frame // Handle drawing the frame
if (!_vm->m_bPaused) { if (!_vm->m_bPaused) {
@ -450,7 +453,7 @@ void TonyEngine::PlayProcess(CORO_PARAM, const void *param) {
*/ */
void TonyEngine::Play(void) { void TonyEngine::Play(void) {
// Create the game player process // Create the game player process
g_scheduler->createProcess(PlayProcess, NULL); CoroScheduler.createProcess(PlayProcess, NULL);
// Loop through calling the scheduler until it's time for the game to quit // Loop through calling the scheduler until it's time for the game to quit
while (!shouldQuit() && !m_bQuitNow) { while (!shouldQuit() && !m_bQuitNow) {
@ -458,7 +461,7 @@ void TonyEngine::Play(void) {
g_system->delayMillis(10); g_system->delayMillis(10);
// Call any scheduled processes // Call any scheduled processes
_scheduler.schedule(); CoroScheduler.schedule();
} }
} }
@ -466,7 +469,7 @@ void TonyEngine::Play(void) {
void TonyEngine::Close(void) { void TonyEngine::Close(void) {
CloseMusic(); CloseMusic();
g_scheduler->closeEvent(m_hEndOfFrame); CoroScheduler.closeEvent(m_hEndOfFrame);
_theBoxes.Close(); _theBoxes.Close();
_theEngine.Close(); _theEngine.Close();
_window.Close(); _window.Close();

View file

@ -26,6 +26,7 @@
#include "common/scummsys.h" #include "common/scummsys.h"
#include "common/system.h" #include "common/system.h"
#include "common/array.h" #include "common/array.h"
#include "common/coroutines.h"
#include "common/error.h" #include "common/error.h"
#include "common/random.h" #include "common/random.h"
#include "common/util.h" #include "common/util.h"
@ -97,7 +98,6 @@ public:
Common::File _vdbFP; Common::File _vdbFP;
Common::Array<VoiceHeader> _voices; Common::Array<VoiceHeader> _voices;
FPSOUND _theSound; FPSOUND _theSound;
Scheduler _scheduler;
enum DATADIR { enum DATADIR {
DD_BASE = 1, DD_BASE = 1,

View file

@ -67,7 +67,7 @@ void RMTony::WaitEndOfAction(CORO_PARAM, const void *param) {
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
CORO_INVOKE_2(g_scheduler->waitForSingleObject, pid, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, pid, CORO_INFINITE);
m_bAction = false; m_bAction = false;
@ -236,15 +236,15 @@ void RMTony::ExecuteAction(int nAction, int nActionItem, int nParm) {
pid = mpalQueryDoAction(TA_COMBINE, nParm, nActionItem); pid = mpalQueryDoAction(TA_COMBINE, nParm, nActionItem);
// Se è fallito il combine, proviamo con il ReceiveCombine // Se è fallito il combine, proviamo con il ReceiveCombine
if (pid == INVALID_PID_VALUE) { if (pid == CORO_INVALID_PID_VALUE) {
pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, nParm); pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, nParm);
// Se è fallito il receive, andiamo con quelli generici // Se è fallito il receive, andiamo con quelli generici
// @@@ CombineGive! // @@@ CombineGive!
if (pid == INVALID_PID_VALUE) { if (pid == CORO_INVALID_PID_VALUE) {
pid = mpalQueryDoAction(TA_COMBINE, nParm, 0); pid = mpalQueryDoAction(TA_COMBINE, nParm, 0);
if (pid == INVALID_PID_VALUE){ if (pid == CORO_INVALID_PID_VALUE){
pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, 0); pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, 0);
} }
} }
@ -254,25 +254,25 @@ void RMTony::ExecuteAction(int nAction, int nActionItem, int nParm) {
pid = mpalQueryDoAction(nAction, nActionItem, 0); pid = mpalQueryDoAction(nAction, nActionItem, 0);
} }
if (pid != INVALID_PID_VALUE) { if (pid != CORO_INVALID_PID_VALUE) {
m_bAction = true; m_bAction = true;
g_scheduler->createProcess(WaitEndOfAction, &pid, sizeof(uint32)); CoroScheduler.createProcess(WaitEndOfAction, &pid, sizeof(uint32));
hActionThread = pid; hActionThread = pid;
} else if (nAction != TA_GOTO) { } else if (nAction != TA_GOTO) {
if (nAction == TA_TALK) { if (nAction == TA_TALK) {
pid = mpalQueryDoAction(6, 1, 0); pid = mpalQueryDoAction(6, 1, 0);
m_bAction = true; m_bAction = true;
g_scheduler->createProcess(WaitEndOfAction, &pid, sizeof(uint32)); CoroScheduler.createProcess(WaitEndOfAction, &pid, sizeof(uint32));
hActionThread = pid; hActionThread = pid;
} else if (nAction == TA_PALESATI) { } else if (nAction == TA_PALESATI) {
pid = mpalQueryDoAction(7, 1, 0); pid = mpalQueryDoAction(7, 1, 0);
m_bAction = true; m_bAction = true;
g_scheduler->createProcess(WaitEndOfAction, &pid, sizeof(uint32)); CoroScheduler.createProcess(WaitEndOfAction, &pid, sizeof(uint32));
hActionThread = pid; hActionThread = pid;
} else { } else {
pid = mpalQueryDoAction(5, 1, 0); pid = mpalQueryDoAction(5, 1, 0);
m_bAction = true; m_bAction = true;
g_scheduler->createProcess(WaitEndOfAction, &pid, sizeof(uint32)); CoroScheduler.createProcess(WaitEndOfAction, &pid, sizeof(uint32));
hActionThread = pid; hActionThread = pid;
} }
} }
@ -286,7 +286,7 @@ void RMTony::StopNoAction(CORO_PARAM) {
CORO_BEGIN_CODE(_ctx); CORO_BEGIN_CODE(_ctx);
if (m_bAction) if (m_bAction)
CORO_INVOKE_2(g_scheduler->waitForSingleObject, hActionThread, INFINITE); CORO_INVOKE_2(CoroScheduler.waitForSingleObject, hActionThread, CORO_INFINITE);
m_bActionPending = false; m_bActionPending = false;
m_ActionItem = NULL; m_ActionItem = NULL;
@ -306,12 +306,12 @@ void RMTony::Stop(CORO_PARAM) {
// Richiama l'MPAL per scegliere la direzione // Richiama l'MPAL per scegliere la direzione
_ctx->pid = mpalQueryDoAction(21, m_ActionItem->MpalCode(), 0); _ctx->pid = mpalQueryDoAction(21, m_ActionItem->MpalCode(), 0);
if (_ctx->pid == INVALID_PID_VALUE) if (_ctx->pid == CORO_INVALID_PID_VALUE)
CORO_INVOKE_0(RMCharacter::Stop); CORO_INVOKE_0(RMCharacter::Stop);
else { else {
bNeedToStop = false; // Se facciamo la OnWhichDirection, almeno dopo non dobbiamo fare la Stop() bNeedToStop = false; // Se facciamo la OnWhichDirection, almeno dopo non dobbiamo fare la Stop()
bMoving = false; bMoving = false;
CORO_INVOKE_2(g_scheduler->waitForSingleObject, _ctx->pid, INFINITE); // @@@ Mettere un assert dopo 10 secondi CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->pid, CORO_INFINITE); // @@@ Mettere un assert dopo 10 secondi
} }
} else { } else {
CORO_INVOKE_0(RMCharacter::Stop); CORO_INVOKE_0(RMCharacter::Stop);

View file

@ -48,8 +48,8 @@
#ifndef TONY_TONYCHAR_H #ifndef TONY_TONYCHAR_H
#define TONY_TONYCHAR_H #define TONY_TONYCHAR_H
#include "common/coroutines.h"
#include "tony/mpal/stubs.h" #include "tony/mpal/stubs.h"
#include "tony/coroutine.h"
#include "tony/loc.h" #include "tony/loc.h"
namespace Tony { namespace Tony {
@ -408,7 +408,7 @@ public:
int GetCurPattern(); int GetCurPattern();
// Attende la fine di un pattern // Attende la fine di un pattern
void WaitForEndPattern(CORO_PARAM, uint32 hCustomSkip = INVALID_PID_VALUE) { void WaitForEndPattern(CORO_PARAM, uint32 hCustomSkip = CORO_INVALID_PID_VALUE) {
RMCharacter::WaitForEndPattern(coroParam, hCustomSkip); RMCharacter::WaitForEndPattern(coroParam, hCustomSkip);
} }

View file

@ -178,7 +178,7 @@ bool RMSnapshot::GetFreeSnapName(char *fn) {
wsprintf(bufName,"rm%d00",i); wsprintf(bufName,"rm%d00",i);
_makepath(fn,bufDrive,bufDir,bufName,".bmp"); _makepath(fn,bufDrive,bufDir,bufName,".bmp");
h = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL); h = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_PID_VALUE) if (h == CORO_INVALID_PID_VALUE)
break; break;
CloseHandle(h); CloseHandle(h);
} }
@ -189,7 +189,7 @@ bool RMSnapshot::GetFreeSnapName(char *fn) {
wsprintf(bufName,"rm%d%d0",i,j); wsprintf(bufName,"rm%d%d0",i,j);
_makepath(fn,bufDrive,bufDir,bufName,".bmp"); _makepath(fn,bufDrive,bufDir,bufName,".bmp");
h=CreateFile(fn,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL); h=CreateFile(fn,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
if (h==INVALID_PID_VALUE) if (h==CORO_INVALID_PID_VALUE)
break; break;
CloseHandle(h); CloseHandle(h);
} }
@ -200,7 +200,7 @@ bool RMSnapshot::GetFreeSnapName(char *fn) {
wsprintf(bufName,"rm%d%d%d",i,j,k); wsprintf(bufName,"rm%d%d%d",i,j,k);
_makepath(fn,bufDrive,bufDir,bufName,".bmp"); _makepath(fn,bufDrive,bufDir,bufName,".bmp");
h = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL); h = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
if (h==INVALID_PID_VALUE) if (h==CORO_INVALID_PID_VALUE)
break; break;
CloseHandle(h); CloseHandle(h);
} }