aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2012-05-06 23:51:11 +1000
committerPaul Gilbert2012-05-06 23:51:11 +1000
commit0b8974ec4ab37ef056ac50c098d3fe8045ec172b (patch)
treeb9b5c371a532c0bd58fecf83a374206622a15ec6 /engines
parent156d8cdb733fe03688da9e2e9844b722681bed7f (diff)
downloadscummvm-rg350-0b8974ec4ab37ef056ac50c098d3fe8045ec172b.tar.gz
scummvm-rg350-0b8974ec4ab37ef056ac50c098d3fe8045ec172b.tar.bz2
scummvm-rg350-0b8974ec4ab37ef056ac50c098d3fe8045ec172b.zip
TONY: Beginnings of converting dialog processes to coroutines
Diffstat (limited to 'engines')
-rw-r--r--engines/tony/custom.cpp70
-rw-r--r--engines/tony/mpal/mpal.cpp585
-rw-r--r--engines/tony/mpal/mpal.h8
-rw-r--r--engines/tony/mpal/stubs.cpp2
-rw-r--r--engines/tony/sched.cpp3
5 files changed, 335 insertions, 333 deletions
diff --git a/engines/tony/custom.cpp b/engines/tony/custom.cpp
index dadc84e606..e7878c5a5d 100644
--- a/engines/tony/custom.cpp
+++ b/engines/tony/custom.cpp
@@ -1699,7 +1699,7 @@ int curDialog;
DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg, uint32, uint32) {
LPSTR string;
- RMTextDialog* text;
+ RMTextDialog *text;
int parm;
HANDLE h;
bool bIsBack = false;
@@ -1875,70 +1875,80 @@ DECLARE_CUSTOM_FUNCTION(SendDialogMessage)(CORO_PARAM, uint32 nPers, uint32 nMsg
// @@@@ This cannot be skipped!!!!!!!!!!!!!!!!!!!
DECLARE_CUSTOM_FUNCTION(StartDialog)(CORO_PARAM, uint32 nDialog, uint32 nStartGroup, uint32, uint32) {
- int nChoice;
- uint32 *sl;
- int i,num;
- char* string;
- RMDialogChoice dc;
- int sel;
+ CORO_BEGIN_CONTEXT;
+ uint32 nChoice;
+ uint32 *sl;
+ int i, num;
+ char *string;
+ RMDialogChoice dc;
+ int sel;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
curDialog = nDialog;
- // Chiama l'MPAL per iniziare il dialogo
+ // Call MPAL to start the dialog
mpalQueryDoDialogU32(nDialog, nStartGroup);
- // Aspetta che una scelta si presenti
- while ((nChoice = mpalQueryDialogWaitForChoice()) != -1) {
+ // Wait until a choice is selected
+ mpalQueryDialogWaitForChoice(&_ctx->nChoice);
+ while (_ctx->nChoice != -1) {
// Si fa dare la lista di opzioni e le conta
- sl = mpalQueryDialogSelectList(nChoice);
- for (num = 0; sl[num] != 0; num++)
+ _ctx->sl = mpalQueryDialogSelectList(_ctx->nChoice);
+ for (_ctx->num = 0; _ctx->sl[_ctx->num] != 0; _ctx->num++)
;
// Se c'e' una sola opzione, la fa automaticamente, e aspetta la prossima scelta
- if (num == 1) {
- mpalQueryDialogSelectionU32(nChoice, sl[0]);
- GlobalFree(sl);
+ if (_ctx->num == 1) {
+ mpalQueryDialogSelectionU32(_ctx->nChoice, _ctx->sl[0]);
+ GlobalFree(_ctx->sl);
continue;
}
// Crea una scelta per il dialogo
- dc.Init();
- dc.SetNumChoices(num);
+ _ctx->dc.Init();
+ _ctx->dc.SetNumChoices(_ctx->num);
// Scrive tutte le possibili opzioni
- for (i = 0; i < num; i++) {
- string = mpalQueryDialogPeriod(sl[i]);
- assert(string != NULL);
- dc.AddChoice(string);
- GlobalFree(string);
+ for (_ctx->i = 0; _ctx->i < _ctx->num; _ctx->i++) {
+ _ctx->string = mpalQueryDialogPeriod(_ctx->sl[_ctx->i]);
+ assert(_ctx->string != NULL);
+ _ctx->dc.AddChoice(_ctx->string);
+ GlobalFree(_ctx->string);
}
// Attiva l'oggetto
- LinkGraphicTask(&dc);
- dc.Show();
+ LinkGraphicTask(&_ctx->dc);
+ _ctx->dc.Show();
// Disegna il puntatore
Pointer->SetSpecialPointer(Pointer->PTR_NONE);
MainShowMouse();
- while (!(Input->MouseLeftClicked() && ((sel = dc.GetSelection()) != -1))) {
+ while (!(Input->MouseLeftClicked() && ((_ctx->sel = _ctx->dc.GetSelection()) != -1))) {
WaitFrame();
Freeze();
- dc.DoFrame(Input->MousePos());
+ _ctx->dc.DoFrame(Input->MousePos());
Unfreeze();
}
// Nascondi il puntatore
MainHideMouse();
- dc.Hide();
- mpalQueryDialogSelectionU32(nChoice, sl[sel]);
+ _ctx->dc.Hide();
+ mpalQueryDialogSelectionU32(_ctx->nChoice, _ctx->sl[_ctx->sel]);
// Chiude la scelta
- dc.Close();
+ _ctx->dc.Close();
+
+ GlobalFree(_ctx->sl);
- GlobalFree(sl);
+ // Wait for the next choice to be made
+ mpalQueryDialogWaitForChoice(&_ctx->nChoice);
}
+
+ CORO_END_CODE;
}
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 26cbf3652d..592c4788df 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -1335,93 +1335,101 @@ void LocationPollThread(CORO_PARAM, const void *param) {
*
\****************************************************************************/
-void PASCAL ShutUpDialogThread(HANDLE hThread) {
- WaitForSingleObject(hThread, INFINITE);
+void ShutUpDialogThread(CORO_PARAM, const void *param) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ uint32 pid = *(const uint32 *)param;
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_2(_vm->_scheduler.waitForSingleObject, pid, INFINITE);
bExecutingDialog = false;
nExecutingDialog = 0;
nExecutingChoice = 0;
SetEvent(hAskChoice);
- ExitThread(1);
-// _endthread();
+
+ CORO_KILL_SELF();
+
+ CORO_END_CODE;
}
+void DoChoice(CORO_PARAM, uint32 nChoice);
-/****************************************************************************\
-*
-* Function: void GroupThread(uint32 nGroup);
-*
-* Description: Esegue un gruppo del dialogo corrente. Puo' essere lo
-* starting point di un thread.
-*
-* Input: uint32 nGroup Numero del gruppo da eseguire
-*
-\****************************************************************************/
-void DoChoice(uint32 nChoice);
+/**
+ * Executes a group of the current dialog. Can 'be the Starting point of a process.
+ * @parm nGroup Number of the group to perform
+ */
+void GroupThread(CORO_PARAM, const void *param) {
+ CORO_BEGIN_CONTEXT;
+ LPMPALDIALOG dialog;
+ int i, j, k;
+ int type;
+ CORO_END_CONTEXT(_ctx);
-void PASCAL GroupThread(uint32 nGroup) {
- LPMPALDIALOG dialog;
- int i, j, k;
+ uint32 nGroup = *(const uint32 *)param;
+
+ CORO_BEGIN_CODE(_ctx);
- /* Locka i dialoghi */
+ // Lock the _ctx->dialog
LockDialogs();
- /* Trova il puntatore al dialogo corrente */
- dialog = lpmdDialogs+nExecutingDialog;
-
- /* Cerca il gruppo richiesto all'interno del dialogo */
- for (i = 0; dialog->Group[i].num != 0; i++)
- if (dialog->Group[i].num==nGroup) {
- /* Cicla eseguendo i comandi del gruppo */
- for (j = 0; j < dialog->Group[i].nCmds; j++) {
- k=dialog->Group[i].CmdNum[j];
-
- switch (dialog->Command[k].type) {
- /* Funzione custom: la richiama */
- case 1:
- // FIXME: Convert to co-routine
- lplpFunctions[dialog->Command[k].nCf](
- nullContext,
- dialog->Command[k].arg1,
- dialog->Command[k].arg2,
- dialog->Command[k].arg3,
- dialog->Command[k].arg4
+ // Find the pointer to the current _ctx->dialog
+ _ctx->dialog = lpmdDialogs + nExecutingDialog;
+
+ // Search inside the group requesting the _ctx->dialog
+ for (_ctx->i = 0; _ctx->dialog->Group[_ctx->i].num != 0; _ctx->i++) {
+ if (_ctx->dialog->Group[_ctx->i].num == nGroup) {
+ // Cycle through executing the commands of the group
+ for (_ctx->j = 0; _ctx->j < _ctx->dialog->Group[_ctx->i].nCmds; _ctx->j++) {
+ _ctx->k = _ctx->dialog->Group[_ctx->i].CmdNum[_ctx->j];
+
+ _ctx->type = _ctx->dialog->Command[_ctx->k].type;
+ if (_ctx->type == 1) {
+ // Call custom function
+ CORO_INVOKE_4(lplpFunctions[_ctx->dialog->Command[_ctx->k].nCf],
+ _ctx->dialog->Command[_ctx->k].arg1,
+ _ctx->dialog->Command[_ctx->k].arg2,
+ _ctx->dialog->Command[_ctx->k].arg3,
+ _ctx->dialog->Command[_ctx->k].arg4
);
- break;
- /* Variabile: la setta */
- case 2:
+ } else if (_ctx->type == 2) {
+ // Set a variable
LockVar();
- varSetValue(dialog->Command[k].lpszVarName,EvaluateExpression(dialog->Command[k].expr));
+ varSetValue(_ctx->dialog->Command[_ctx->k].lpszVarName, EvaluateExpression(_ctx->dialog->Command[_ctx->k].expr));
UnlockVar();
- break;
-
- /* DoChoice: richiama la funzione di scelta */
- case 3:
- DoChoice((uint32)dialog->Command[k].nChoice);
- break;
-
- default:
+
+ } else if (_ctx->type == 3) {
+ // DoChoice: call the chosen function
+ CORO_INVOKE_1(DoChoice, (uint32)_ctx->dialog->Command[_ctx->k].nChoice);
+
+ } else {
mpalError = 1;
UnlockDialogs();
- ExitThread(0);
-// _endthread();
+
+ CORO_KILL_SELF();
+ return;
+ }
}
- }
- /* Abbiamo eseguito il gruppo. Possiamo uscire alla funzione chiamante.
- Se il gruppo era il primo chiamato, allora automaticamente il
- thread viene chiuso, altrimenti si ritorno al gruppo chiamante. */
- UnlockDialogs();
- return;
+ /* The gruop is finished, so we can return to the calling function.
+ * If the group was the first called, then the process will automatically
+ * end. Otherwise it returns to the caller method
+ */
+ return;
+ }
}
/* Se siamo qui, vuol dire che non abbiamo trovato il gruppo richiesto */
mpalError = 1;
UnlockDialogs();
- ExitThread(0);
-// _endthread();
+
+ CORO_KILL_SELF();
+
+ CORO_END_CODE;
}
@@ -1435,52 +1443,58 @@ void PASCAL GroupThread(uint32 nGroup) {
*
\****************************************************************************/
-void DoChoice(uint32 nChoice) {
- LPMPALDIALOG dialog;
- int i,j,k;
+void DoChoice(CORO_PARAM, uint32 nChoice) {
+ CORO_BEGIN_CONTEXT;
+ LPMPALDIALOG dialog;
+ int i, j, k;
+ uint32 nGroup;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
- /* Locka i dialoghi */
+ /* Locka _ctx->i dialoghi */
LockDialogs();
/* Trova il puntatore al dialogo corrente */
- dialog=lpmdDialogs+nExecutingDialog;
+ _ctx->dialog=lpmdDialogs+nExecutingDialog;
/* Cerca la scelta richiesta tra quelle nel dialogo */
- for (i = 0; dialog->Choice[i].nChoice != 0; i++)
- if (dialog->Choice[i].nChoice == nChoice)
+ for (_ctx->i = 0; _ctx->dialog->Choice[_ctx->i].nChoice != 0; _ctx->i++)
+ if (_ctx->dialog->Choice[_ctx->i].nChoice == nChoice)
break;
/* Se non l'ha trovata, esce con errore */
- if (dialog->Choice[i].nChoice == 0) {
+ if (_ctx->dialog->Choice[_ctx->i].nChoice == 0) {
/* Se siamo qui, non abbiamo trovato la choice richiesta */
mpalError = 1;
UnlockDialogs();
- ExitThread(0);
-// _endthread();
+
+ CORO_KILL_SELF();
+ return;
}
/* Abbiamo trova la choice richiesta. Ricordiamoci qual e' nella
variabile globale */
- nExecutingChoice = i;
+ nExecutingChoice = _ctx->i;
while (1) {
- nExecutingChoice = i;
+ nExecutingChoice = _ctx->i;
- k = 0;
+ _ctx->k = 0;
/* Calcoliamo le when expression di ciascun select, per vedere se sono
attivi o disattivi */
- for (j = 0; dialog->Choice[i].Select[j].dwData != 0; j++)
- if (dialog->Choice[i].Select[j].when == NULL) {
- dialog->Choice[i].Select[j].curActive = 1;
- k++;
- } else if (EvaluateExpression(dialog->Choice[i].Select[j].when)) {
- dialog->Choice[i].Select[j].curActive = 1;
- k++;
+ for (_ctx->j = 0; _ctx->dialog->Choice[_ctx->i].Select[_ctx->j].dwData != 0; _ctx->j++)
+ if (_ctx->dialog->Choice[_ctx->i].Select[_ctx->j].when == NULL) {
+ _ctx->dialog->Choice[_ctx->i].Select[_ctx->j].curActive = 1;
+ _ctx->k++;
+ } else if (EvaluateExpression(_ctx->dialog->Choice[_ctx->i].Select[_ctx->j].when)) {
+ _ctx->dialog->Choice[_ctx->i].Select[_ctx->j].curActive = 1;
+ _ctx->k++;
} else
- dialog->Choice[i].Select[j].curActive = 0;
+ _ctx->dialog->Choice[_ctx->i].Select[_ctx->j].curActive = 0;
/* Se non ci sono scelte attivate, la scelta e' finita */
- if (k == 0) {
+ if (_ctx->k == 0) {
UnlockDialogs();
break;
}
@@ -1491,31 +1505,36 @@ void DoChoice(uint32 nChoice) {
SetEvent(hAskChoice);
WaitForSingleObject(hDoneChoice, INFINITE);
- /* Ora che la scelta e' stata effettuata, possiamo eseguire i gruppi
+ /* Ora che la scelta e' stata effettuata, possiamo eseguire _ctx->i gruppi
associati con la scelta */
- j=nSelectedChoice;
- for (k = 0; dialog->Choice[i].Select[j].wPlayGroup[k] != 0; k++)
- GroupThread(dialog->Choice[i].Select[j].wPlayGroup[k]);
+ _ctx->j = nSelectedChoice;
+ for (_ctx->k = 0; _ctx->dialog->Choice[_ctx->i].Select[_ctx->j].wPlayGroup[_ctx->k] != 0; _ctx->k++) {
+ _ctx->nGroup = _ctx->dialog->Choice[_ctx->i].Select[_ctx->j].wPlayGroup[_ctx->k];
+ CORO_INVOKE_1(GroupThread, &_ctx->nGroup);
+ }
/* Controllo sugli attributi */
- if (dialog->Choice[i].Select[j].attr & (1 << 0)) {
+ if (_ctx->dialog->Choice[_ctx->i].Select[_ctx->j].attr & (1 << 0)) {
/* Bit 0 settato: fine della scelta */
UnlockDialogs();
break;
}
- if (dialog->Choice[i].Select[j].attr & (1 << 1)) {
+ if (_ctx->dialog->Choice[_ctx->i].Select[_ctx->j].attr & (1 << 1)) {
/* Bit 1 settato: fine del dialogo */
UnlockDialogs();
- ExitThread(1);
-// _endthread();
+
+ CORO_KILL_SELF();
+ return;
}
/* Fine della scelta senza attributi: bisogna rifarla */
}
- /* Se siamo qui, abbiamo trovato un end choice. Ritorna al gruppo chiamante */
+ // If we're here, we found an end choice. Return to the caller group
return;
+
+ CORO_END_CODE;
}
@@ -1605,57 +1624,40 @@ static HANDLE DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) {
return INVALID_HANDLE_VALUE;
}
+/**
+ * Shows a dialog in a separate process.
+ *
+ * @param nDlgOrd The index of the dialog in the dialog list
+ * @param nGroup Number of the group to perform
+ * @returns The process Id of the process running the dialog
+ * or INVALID_HANDLE_VALUE on error
+ * @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.
+ * The data on the choices may be obtained through various queries.
+ */
+static uint32 DoDialog(uint32 nDlgOrd, uint32 nGroup) {
+ uint32 h;
-/****************************************************************************\
-*
-* Function: HANDLE DoDialog(uint32 nDlgOrd, uint32 nGroup);
-*
-* Description: Esegue un dialogo in un thread
-*
-* Input: uint32 nDlgOrd Indice del dialogo da eseguire
-* all'interno dell'array di strutture
-* dei dialoghi
-* uint32 nGroup Numero del gruppo da eseguire
-*
-* Return: Handle del thread che sta eseguendo il dialogo, o
-* INVALID_HANDLE_VALUE in caso di errore
-*
-* Note: Il dialogo viene eseguito in un thread creato apposta, che
-* deve informa tramite un evento quando e' necessario far
-* fare una scelta all'utente. I dati sulle scelte possono
-* essere richiesti tramite le varie query.
-*
-\****************************************************************************/
-
-static HANDLE DoDialog(uint32 nDlgOrd, uint32 nGroup) {
-// LPMPALDIALOG dialog=lpmdDialogs+nDlgOrd;
- uint32 dwId;
- HANDLE h;
-
- /* Si ricorda nella variabile globale qual e' il dialogo in esecuzione */
+ // Store the running dialog in a global variable
nExecutingDialog = nDlgOrd;
- /* Attiva la flag per indicare che c'e' un dialogo in esecuzione */
+ // Enables the flag to indicate that there is' a running dialogue
bExecutingDialog = true;
ResetEvent(hAskChoice);
ResetEvent(hDoneChoice);
- /* Crea un thread in cui esegue un gruppo del dialogo */
+ // Create a thread that performs the dialogue group
- // !!! Nuova gestione dei thread
- if ((h = CreateThread(NULL, 10240, (LPTHREAD_START_ROUTINE)GroupThread, (void *)nGroup, 0, &dwId)) == NULL)
- // if ((h=(void*)_beginthread(GroupThread, 10240,(void *)nGroup))==(void*)-1)
- return INVALID_HANDLE_VALUE;
+ // Create the process
+ if ((h = _vm->_scheduler.createProcess(GroupThread, &nGroup, sizeof(uint32))) == 0)
+ return 0;
- /* Crea un thread che attende la fine del dialogo e rimette a posto le
- variabili globali */
- // !!! Nuova gestione dei thread
- if (CreateThread(NULL, 10240,(LPTHREAD_START_ROUTINE)ShutUpDialogThread,(void *)h, 0, &dwId) == NULL) {
- //if ((h=(void*)_beginthread(ShutUpDialogThread, 10240,(void *)h))==(void*)-1)
- TerminateThread(h, 0);
- CloseHandle(h);
- return INVALID_HANDLE_VALUE;
+ // Create a thread that waits until the end of the dialog process, and will restore the global variables
+ if (_vm->_scheduler.createProcess(ShutUpDialogThread, &h, sizeof(uint32)) == 0) {
+ // Something went wrong, so kill the previously started dialog process
+ _vm->_scheduler.killMatchingProcess(h);
+ return 0;
}
return h;
@@ -1893,243 +1895,230 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName,
#define GETARG(type) va_arg(v,type)
-uint32 mpalQuery(uint16 wQueryType, ...) {
- uint32 dwRet = 0;
- int x, y, z;
- char *n;
- va_list v;
- Common::String buf;
+void mpalQueryInner(CORO_PARAM, uint16 wQueryType, uint32 *dwRet, va_list v) {
+ CORO_BEGIN_CONTEXT;
+ int x, y, z;
+ char *n;
+ Common::String buf;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
mpalError = OK;
- va_start(v, wQueryType);
- switch (wQueryType) {
- /*
- * uint32 mpalQuery(MPQ_VERSION);
- */
- case MPQ_VERSION:
- dwRet = HEX_VERSION;
- break;
+ if (wQueryType == MPQ_VERSION) {
+ /*
+ * uint32 mpalQuery(MPQ_VERSION);
+ */
+ *dwRet = HEX_VERSION;
- /*
- * uint32 mpalQuery(MPQ_GLOBAL_VAR, char * lpszVarName);
- */
- case MPQ_GLOBAL_VAR:
+ } else if (wQueryType == MPQ_GLOBAL_VAR) {
+ /*
+ * uint32 mpalQuery(MPQ_GLOBAL_VAR, char * lpszVarName);
+ */
LockVar();
- dwRet = (uint32)varGetValue(GETARG(char *));
+ *dwRet = (uint32)varGetValue(GETARG(char *));
UnlockVar();
- break;
- /*
- * char * mpalQuery(MPQ_MESSAGE, uint32 nMsg);
- */
- case MPQ_MESSAGE:
+ } else if (wQueryType == MPQ_MESSAGE) {
+ /*
+ * char * mpalQuery(MPQ_MESSAGE, uint32 nMsg);
+ */
LockMsg();
- dwRet = (uint32)DuplicateMessage(msgGetOrderFromNum(GETARG(uint32)));
+ *dwRet = (uint32)DuplicateMessage(msgGetOrderFromNum(GETARG(uint32)));
UnlockMsg();
- break;
-
- /*
- * uint32 mpalQuery(MPQ_ITEM_PATTERN, uint32 nItem);
- */
- case MPQ_ITEM_PATTERN:
+
+ } else if (wQueryType == MPQ_ITEM_PATTERN) {
+ /*
+ * uint32 mpalQuery(MPQ_ITEM_PATTERN, uint32 nItem);
+ */
LockVar();
- buf = Common::String::format("Pattern.%u", GETARG(uint32));
- dwRet = (uint32)varGetValue(buf.c_str());
+ _ctx->buf = Common::String::format("Pattern.%u", GETARG(uint32));
+ *dwRet = (uint32)varGetValue(_ctx->buf.c_str());
UnlockVar();
- break;
-
- /*
- * uint32 mpalQuery(MPQ_LOCATION_SIZE, uint32 nLoc, uint32 dwCoord);
- */
- case MPQ_LOCATION_SIZE:
+
+ } else if (wQueryType == MPQ_LOCATION_SIZE) {
+ /*
+ * uint32 mpalQuery(MPQ_LOCATION_SIZE, uint32 nLoc, uint32 dwCoord);
+ */
LockLocations();
- x = locGetOrderFromNum(GETARG(uint32));
- y = GETARG(uint32);
- if (x != -1) {
- if (y == MPQ_X)
- dwRet = lpmlLocations[x].dwXlen;
- else if (y == MPQ_Y)
- dwRet = lpmlLocations[x].dwYlen;
+ _ctx->x = locGetOrderFromNum(GETARG(uint32));
+ _ctx->y = GETARG(uint32);
+ if (_ctx->x != -1) {
+ if (_ctx->y == MPQ_X)
+ *dwRet = lpmlLocations[_ctx->x].dwXlen;
+ else if (_ctx->y == MPQ_Y)
+ *dwRet = lpmlLocations[_ctx->x].dwYlen;
else
mpalError = 1;
} else
mpalError = 1;
UnlockLocations();
- break;
-
- /*
- * HGLOBAL mpalQuery(MPQ_LOCATION_IMAGE, uint32 nLoc);
- */
- case MPQ_LOCATION_IMAGE:
+
+ } else if (wQueryType == MPQ_LOCATION_IMAGE) {
+ /*
+ * HGLOBAL mpalQuery(MPQ_LOCATION_IMAGE, uint32 nLoc);
+ */
LockLocations();
- x = locGetOrderFromNum(GETARG(uint32));
- dwRet = (uint32)resLoad(lpmlLocations[x].dwPicRes);
+ _ctx->x = locGetOrderFromNum(GETARG(uint32));
+ *dwRet = (uint32)resLoad(lpmlLocations[_ctx->x].dwPicRes);
UnlockLocations();
- break;
- /*
- * HGLOBAL mpalQuery(MPQ_RESOURCE, uint32 dwRes);
- */
- case MPQ_RESOURCE:
- dwRet = (uint32)resLoad(GETARG(uint32));
- break;
+ } else if (wQueryType == MPQ_RESOURCE) {
+ /*
+ * HGLOBAL mpalQuery(MPQ_RESOURCE, uint32 dwRes);
+ */
+ *dwRet = (uint32)resLoad(GETARG(uint32));
- /*
- * uint32 mpalQuery(MPQ_ITEM_LIST, uint32 nLoc);
- */
- case MPQ_ITEM_LIST:
+ } else if (wQueryType == MPQ_ITEM_LIST) {
+ /*
+ * uint32 mpalQuery(MPQ_ITEM_LIST, uint32 nLoc);
+ */
LockVar();
- dwRet = (uint32)GetItemList(GETARG(uint32));
+ *dwRet = (uint32)GetItemList(GETARG(uint32));
LockVar();
- break;
- /*
- * LPITEM mpalQuery(MPQ_ITEM_DATA, uint32 nItem);
- */
- case MPQ_ITEM_DATA:
+ } else if (wQueryType == MPQ_ITEM_DATA) {
+ /*
+ * LPITEM mpalQuery(MPQ_ITEM_DATA, uint32 nItem);
+ */
LockItems();
- dwRet = (uint32)GetItemData(itemGetOrderFromNum(GETARG(uint32)));
+ *dwRet = (uint32)GetItemData(itemGetOrderFromNum(GETARG(uint32)));
UnlockItems();
- break;
- /*
- * bool mpalQuery(MPQ_ITEM_IS_ACTIVE, uint32 nItem);
- */
- case MPQ_ITEM_IS_ACTIVE:
+ } else if (wQueryType == MPQ_ITEM_IS_ACTIVE) {
+ /*
+ * bool mpalQuery(MPQ_ITEM_IS_ACTIVE, uint32 nItem);
+ */
LockVar();
- x = GETARG(uint32);
- buf = Common::String::format("Status.%u", x);
- if (varGetValue(buf.c_str()) <= 0)
- dwRet = (uint32)false;
+ _ctx->x = GETARG(uint32);
+ _ctx->buf = Common::String::format("Status.%u", _ctx->x);
+ if (varGetValue(_ctx->buf.c_str()) <= 0)
+ *dwRet = (uint32)false;
else
- dwRet = (uint32)true;
+ *dwRet = (uint32)true;
UnlockVar();
- break;
-
- /*
- * uint32 mpalQuery(MPQ_ITEM_NAME, uint32 nItem, char * lpszName);
- */
- case MPQ_ITEM_NAME:
+ } else if (wQueryType == MPQ_ITEM_NAME) {
+ /*
+ * uint32 mpalQuery(MPQ_ITEM_NAME, uint32 nItem, char * lpszName);
+ */
LockVar();
- x = GETARG(uint32);
- n=GETARG(char *);
- buf = Common::String::format("Status.%u", x);
- if (varGetValue(buf.c_str()) <= 0)
- n[0]='\0';
+ _ctx->x = GETARG(uint32);
+ _ctx->n = GETARG(char *);
+ _ctx->buf = Common::String::format("Status.%u", _ctx->x);
+ if (varGetValue(_ctx->buf.c_str()) <= 0)
+ _ctx->n[0]='\0';
else {
LockItems();
- y = itemGetOrderFromNum(x);
- CopyMemory(n, (char *)(lpmiItems+y)->lpszDescribe, MAX_DESCRIBE_SIZE);
+ _ctx->y = itemGetOrderFromNum(_ctx->x);
+ CopyMemory(_ctx->n, (char *)(lpmiItems+_ctx->y)->lpszDescribe, MAX_DESCRIBE_SIZE);
UnlockItems();
}
UnlockVar();
- break;
-
- /*
- * char * mpalQuery(MPQ_DIALOG_PERIOD, uint32 nDialog, uint32 nPeriod);
- */
- case MPQ_DIALOG_PERIOD:
+ } else if (wQueryType == MPQ_DIALOG_PERIOD) {
+ /*
+ * char * mpalQuery(MPQ_DIALOG_PERIOD, uint32 nDialog, uint32 nPeriod);
+ */
LockDialogs();
- y = GETARG(uint32);
- dwRet = (uint32)DuplicateDialogPeriod(y);
+ _ctx->y = GETARG(uint32);
+ *dwRet = (uint32)DuplicateDialogPeriod(_ctx->y);
UnlockDialogs();
- break;
-
- /*
- * void mpalQuery(MPQ_DIALOG_WAITFORCHOICE);
- */
- case MPQ_DIALOG_WAITFORCHOICE:
+ } else if (wQueryType == MPQ_DIALOG_WAITFORCHOICE) {
+ /*
+ * void mpalQuery(MPQ_DIALOG_WAITFORCHOICE);
+ */
WaitForSingleObject(hAskChoice, INFINITE);
ResetEvent(hAskChoice);
if (bExecutingDialog)
- dwRet = (uint32)nExecutingChoice;
+ *dwRet = (uint32)nExecutingChoice;
else
- dwRet = (uint32)((int)-1);
- break;
-
+ *dwRet = (uint32)((int)-1);
- /*
- * uint32 *mpalQuery(MPQ_DIALOG_SELECTLIST, uint32 nChoice);
- */
- case MPQ_DIALOG_SELECTLIST:
+ } else if (wQueryType == MPQ_DIALOG_SELECTLIST) {
+ /*
+ * uint32 *mpalQuery(MPQ_DIALOG_SELECTLIST, uint32 nChoice);
+ */
LockDialogs();
- dwRet = (uint32)GetSelectList(GETARG(uint32));
+ *dwRet = (uint32)GetSelectList(GETARG(uint32));
UnlockDialogs();
break;
- /*
- * bool mpalQuery(MPQ_DIALOG_SELECTION, uint32 nChoice, uint32 dwData);
- */
- case MPQ_DIALOG_SELECTION:
+ } else if (wQueryType == MPQ_DIALOG_SELECTION) {
+ /*
+ * bool mpalQuery(MPQ_DIALOG_SELECTION, uint32 nChoice, uint32 dwData);
+ */
LockDialogs();
- x = GETARG(uint32);
- y = GETARG(uint32);
- dwRet = (uint32)DoSelection(x,y);
+ _ctx->x = GETARG(uint32);
+ _ctx->y = GETARG(uint32);
+ *dwRet = (uint32)DoSelection(_ctx->x,_ctx->y);
UnlockDialogs();
- break;
-
-
- /*
- * int mpalQuery(MPQ_DO_ACTION, uint32 nAction, uint32 nItem, uint32 dwParam);
- */
- case MPQ_DO_ACTION:
- /*
- if (bExecutingAction)
- {
- dwRet = (uint32)INVALID_HANDLE_VALUE;
- break;
- }
- */
+ } else if (wQueryType == MPQ_DO_ACTION) {
+ /*
+ * int mpalQuery(MPQ_DO_ACTION, uint32 nAction, uint32 nItem, uint32 dwParam);
+ */
LockItems();
LockVar();
- x = GETARG(uint32);
- z = GETARG(uint32);
- y = itemGetOrderFromNum(z);
- if (y!=-1) {
- dwRet = (uint32)DoAction(x, y, GETARG(uint32));
+ _ctx->x = GETARG(uint32);
+ _ctx->z = GETARG(uint32);
+ _ctx->y = itemGetOrderFromNum(_ctx->z);
+ if (_ctx->y!=-1) {
+ *dwRet = (uint32)DoAction(_ctx->x, _ctx->y, GETARG(uint32));
} else {
- dwRet = (uint32)INVALID_HANDLE_VALUE;
+ *dwRet = (uint32)INVALID_HANDLE_VALUE;
mpalError = 1;
}
UnlockVar();
UnlockItems();
- break;
- /*
- * int mpalQuery(MPQ_DO_DIALOG, uint32 nDialog, uint32 nGroup);
- */
- case MPQ_DO_DIALOG:
- if (bExecutingDialog)
- break;
+ } else if (wQueryType == MPQ_DO_DIALOG) {
+ /*
+ * int mpalQuery(MPQ_DO_DIALOG, uint32 nDialog, uint32 nGroup);
+ */
+ if (!bExecutingDialog) {
+ LockDialogs();
- LockDialogs();
-
- x = dialogGetOrderFromNum(GETARG(uint32));
- y = GETARG(uint32);
- dwRet = (uint32)DoDialog(x, y);
- UnlockDialogs();
- break;
-
- /*
- * DEFAULT -> ERROR
- */
- default:
+ _ctx->x = dialogGetOrderFromNum(GETARG(uint32));
+ _ctx->y = GETARG(uint32);
+ *dwRet = DoDialog(_ctx->x, _ctx->y);
+ UnlockDialogs();
+ }
+ } else {
+ /*
+ * DEFAULT -> ERROR
+ */
mpalError = 1;
- break;
}
+ CORO_END_CODE;
+}
+
+uint32 mpalQuery(uint16 wQueryType, ...) {
+ uint32 dwRet;
+ va_list v;
+ va_start(v, wQueryType);
+
+ mpalQueryInner(nullContext, wQueryType, &dwRet, v);
+
va_end(v);
return dwRet;
}
+void mpalQueryCoro(CORO_PARAM, uint32 *dwRet, uint16 wQueryType, ...) {
+ va_list v;
+ va_start(v, wQueryType);
+
+ mpalQueryInner(coroParam, wQueryType, dwRet, v);
+
+ va_end(v);
+}
+
/****************************************************************************\
*
diff --git a/engines/tony/mpal/mpal.h b/engines/tony/mpal/mpal.h
index c9f8625744..5517a6518c 100644
--- a/engines/tony/mpal/mpal.h
+++ b/engines/tony/mpal/mpal.h
@@ -474,10 +474,8 @@ typedef LPITEMIRQFUNCTION* LPLPITEMIRQFUNCTION;
*
\****************************************************************************/
-#define mpalQueryDialogWaitForChoice() \
- (int)mpalQuery(MPQ_DIALOG_WAITFORCHOICE)
-
-
+#define mpalQueryDialogWaitForChoice(dwRet) \
+ CORO_INVOKE_2(mpalQueryCoro, dwRet, MPQ_DIALOG_WAITFORCHOICE)
/****************************************************************************\
*
@@ -627,7 +625,7 @@ bool EXPORT mpalInit(const char *lpszFileName, const char *lpszMprFileName,
uint32 EXPORT mpalQuery(uint16 wQueryType, ...);
-
+void mpalQueryCoro(CORO_PARAM, uint32 *dwRet, uint16 wQueryType, ...);
/****************************************************************************\
*
diff --git a/engines/tony/mpal/stubs.cpp b/engines/tony/mpal/stubs.cpp
index 9d4a87d61c..0fc01d4d07 100644
--- a/engines/tony/mpal/stubs.cpp
+++ b/engines/tony/mpal/stubs.cpp
@@ -80,10 +80,12 @@ 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;
}
diff --git a/engines/tony/sched.cpp b/engines/tony/sched.cpp
index f8a7fd2538..41531bf225 100644
--- a/engines/tony/sched.cpp
+++ b/engines/tony/sched.cpp
@@ -299,6 +299,9 @@ void Scheduler::giveWay(PPROCESS pReSchedProc) {
* @param expired Set to true if delay period expired
*/
void Scheduler::waitForSingleObject(CORO_PARAM, int pid, int duration, bool *expired) {
+ if (!pCurrent)
+ error("Called Scheduler::waitForSingleObject from the main process");
+
CORO_BEGIN_CONTEXT;
uint32 endTime;
PROCESS *pProc;