mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
files structure reorganization, compilation BROKEN. compilation will be fixed soon.
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ltask.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lmem.h"
|
||||
#include "ldo.h"
|
||||
#include "lvm.h"
|
||||
|
||||
void pause_scripts (void) {
|
||||
struct lua_Task *t;
|
||||
|
||||
for (t = L->root_task->next; t != NULL; t = t->next) {
|
||||
if ((L->curr_task != t) && (t->Tstate != DONE))
|
||||
t->Tstate = PAUSE;
|
||||
}
|
||||
}
|
||||
|
||||
void unpause_scripts (void) {
|
||||
struct lua_Task *t;
|
||||
|
||||
for (t = L->root_task->next; t != NULL; t = t->next) {
|
||||
if ((L->curr_task != t) && (t->Tstate != DONE))
|
||||
t->Tstate = YIELD;
|
||||
}
|
||||
}
|
||||
|
||||
void start_script (void) {
|
||||
struct lua_Task *old_task = L->curr_task, *new_task;
|
||||
TObject *f = L->stack.stack + L->Cstack.lua2C;
|
||||
|
||||
f = L->stack.stack + L->Cstack.lua2C;
|
||||
if (ttype(f) == LUA_T_CLOSURE)
|
||||
f = &clvalue(f)->consts[0];
|
||||
// Start nothing? start_script gets called in this fashion
|
||||
// by the scene in the scrimshaw parlor, if we just return
|
||||
// immediately the game proceeds ok.
|
||||
if (ttype(f) == LUA_T_NIL)
|
||||
return;
|
||||
if (ttype(f) != LUA_T_PROTO)
|
||||
lua_error("can only start_script with a Lua function");
|
||||
|
||||
/* Create a new task with an empty stack */
|
||||
new_task = luaI_newtask();
|
||||
|
||||
/* Put the function and arguments onto the new task's stack */
|
||||
for (int i = 0; i < old_task->Cstack.num; i++) {
|
||||
*(L->stack.top) = *(old_task->stack.stack + old_task->Cstack.lua2C + i);
|
||||
incr_top;
|
||||
}
|
||||
|
||||
/* Create a CallInfo frame */
|
||||
luaD_precall(L->stack.stack, 1, MULT_RET);
|
||||
ttype(L->stack.stack) = (ttype(L->stack.stack) == LUA_T_CLOSURE) ? LUA_T_CLMARK : LUA_T_PMARK;
|
||||
|
||||
/* Switch back to the old task */
|
||||
L->Tstate = YIELD;
|
||||
luaI_switchtask(old_task);
|
||||
L->curr_task = old_task;
|
||||
|
||||
/* Insert new task at end of list */
|
||||
L->last_task->next = new_task;
|
||||
L->last_task = new_task;
|
||||
|
||||
/* Return task handle */
|
||||
ttype(L->stack.top) = LUA_T_TASK;
|
||||
nvalue(L->stack.top) = (real)new_task->id;
|
||||
incr_top;
|
||||
}
|
||||
|
||||
void stop_script (void) {
|
||||
struct lua_Task *prev, *t;
|
||||
TObject *f = L->stack.stack + L->Cstack.lua2C;
|
||||
int match;
|
||||
|
||||
if ((f == LUA_NOOBJECT) || (ttype(f) != LUA_T_CLOSURE && ttype(f) != LUA_T_PROTO && ttype(f) != LUA_T_TASK))
|
||||
lua_error("Bad argument to stop_script");
|
||||
|
||||
prev = L->root_task;
|
||||
while ((t = prev->next) != NULL) {
|
||||
switch (ttype(f)) {
|
||||
case LUA_T_CLOSURE:
|
||||
match = (ttype(t->stack.stack) == LUA_T_CLMARK && clvalue(t->stack.stack) == clvalue(f));
|
||||
break;
|
||||
case LUA_T_PROTO:
|
||||
match = (ttype(t->stack.stack) == LUA_T_PMARK && tfvalue(t->stack.stack) == tfvalue(f));
|
||||
break;
|
||||
case LUA_T_TASK:
|
||||
match = (t->id == (int)nvalue(f));
|
||||
break;
|
||||
default: /* Shut up gcc */
|
||||
break;
|
||||
}
|
||||
|
||||
if (match) {
|
||||
prev->next = t->next; /* Remove from list of active tasks */
|
||||
t->next = NULL;
|
||||
if (prev->next == NULL) {
|
||||
L->last_task = prev;
|
||||
if (t == L->curr_task) {
|
||||
L->Tstate = DONE;
|
||||
}
|
||||
} else {
|
||||
t->Tstate = DONE;
|
||||
}
|
||||
} else {
|
||||
prev = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void next_script (void) {
|
||||
struct lua_Task *t, *prev;
|
||||
TObject *f = L->stack.stack + L->Cstack.lua2C;
|
||||
|
||||
if (f == LUA_NOOBJECT)
|
||||
lua_error("Bad argument to next_script: no obeject");
|
||||
|
||||
prev = L->root_task;
|
||||
if (ttype(f) == LUA_T_NIL) {
|
||||
t = L->root_task;
|
||||
} else if (ttype(f) == LUA_T_TASK) {
|
||||
int taskId = (int)nvalue(f);
|
||||
for (t = L->root_task->next; t != NULL; t = t->next) {
|
||||
if (t->id == taskId)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
lua_error("Bad argument to next_script.");
|
||||
}
|
||||
if (t == NULL) {
|
||||
lua_pushnil();
|
||||
} else {
|
||||
t = t->next;
|
||||
if (t == NULL) {
|
||||
lua_pushnil();
|
||||
} else {
|
||||
ttype(L->stack.top) = LUA_T_TASK;
|
||||
nvalue(L->stack.top) = (real)t->id;
|
||||
incr_top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void identify_script (void) {
|
||||
struct lua_Task *t;
|
||||
TObject *f = L->stack.stack + L->Cstack.lua2C;
|
||||
|
||||
if ((f == LUA_NOOBJECT) || ttype(f) != LUA_T_TASK) {
|
||||
lua_error("Bad argument to identify_script");
|
||||
}
|
||||
|
||||
int taskId = (int)nvalue(f);
|
||||
for (t = L->root_task->next; t != NULL; t = t->next) {
|
||||
if (t->id == taskId)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((t == NULL) || (t->Tstate == DONE)) {
|
||||
ttype(L->stack.top) = LUA_T_NIL;
|
||||
} else {
|
||||
*L->stack.top = *t->stack.stack;
|
||||
}
|
||||
incr_top;
|
||||
}
|
||||
|
||||
void find_script (void) {
|
||||
struct lua_Task *t, *foundTask = NULL;
|
||||
TObject *f = L->stack.stack + L->Cstack.lua2C;
|
||||
int countTasks = 0, taskId;
|
||||
|
||||
switch (ttype(f)) {
|
||||
case LUA_T_CLOSURE:
|
||||
for (t = L->root_task->next; t != NULL; t = t->next) {
|
||||
if ((ttype(t->stack.stack) == LUA_T_CLOSURE || ttype(t->stack.stack) == LUA_T_CMARK) && clvalue(t->stack.stack) == clvalue(f)) {
|
||||
foundTask = t;
|
||||
countTasks++;
|
||||
}
|
||||
}
|
||||
t = foundTask;
|
||||
break;
|
||||
case LUA_T_PROTO:
|
||||
for (t = L->root_task->next; t != NULL; t = t->next) {
|
||||
if ((ttype(t->stack.stack) == LUA_T_PROTO || ttype(t->stack.stack) == LUA_T_PMARK) && tfvalue(t->stack.stack) == tfvalue(f)) {
|
||||
foundTask = t;
|
||||
countTasks++;
|
||||
}
|
||||
}
|
||||
t = foundTask;
|
||||
break;
|
||||
case LUA_T_TASK:
|
||||
taskId = (int)nvalue(f);
|
||||
for (t = L->root_task->next; t != NULL; t = t->next) {
|
||||
if ((t->id == taskId) && (t->Tstate != DONE)) {
|
||||
ttype(L->stack.top) = LUA_T_TASK;
|
||||
nvalue(L->stack.top) = nvalue(f);
|
||||
incr_top;
|
||||
lua_pushnumber(1.0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lua_error("Bad argument to find_script");
|
||||
}
|
||||
|
||||
if (t != NULL) {
|
||||
ttype(L->stack.top) = LUA_T_TASK;
|
||||
nvalue(L->stack.top) = (real)t->id;
|
||||
incr_top;
|
||||
lua_pushnumber(countTasks);
|
||||
} else {
|
||||
lua_pushnil();
|
||||
lua_pushnumber(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void break_here (void) {
|
||||
struct CallInfo *ci;
|
||||
|
||||
if (L->curr_task == L->root_task) {
|
||||
lua_error("Cannot break in root thread");
|
||||
}
|
||||
/* Check for any C functions in the call stack */
|
||||
for (ci = L->ci-1; ci > L->base_ci; ci--)
|
||||
if (ci->tf == NULL)
|
||||
lua_error("Cannot yield through C function");
|
||||
|
||||
L->Tstate = YIELD;
|
||||
}
|
||||
|
||||
void current_script (void) {
|
||||
if (L->curr_task == L->root_task) {
|
||||
lua_pushnil();
|
||||
} else {
|
||||
ttype(L->stack.top) = LUA_T_TASK;
|
||||
nvalue(L->stack.top) = (real)L->curr_task->id;
|
||||
incr_top;
|
||||
}
|
||||
}
|
||||
|
||||
void lua_runtasks (void) {
|
||||
struct lua_Task *t, *prev;
|
||||
struct lua_Task *old_task = L->curr_task;
|
||||
jmp_buf myErrorJmp;
|
||||
|
||||
prev = L->root_task;
|
||||
while ((t = prev->next) != NULL) {
|
||||
luaI_switchtask(t);
|
||||
// Tstate is not available until after switching tasks
|
||||
if (t->Tstate == PAUSE) {
|
||||
prev = t;
|
||||
continue;
|
||||
}
|
||||
L->errorJmp = &myErrorJmp;
|
||||
L->Tstate = RUN;
|
||||
if (setjmp(myErrorJmp) == 0) {
|
||||
luaV_execute(L->base_ci + 1);
|
||||
if (L->Tstate == RUN) { /* Must have run to completion */
|
||||
L->Tstate = DONE;
|
||||
}
|
||||
} else { /* an error occurred */
|
||||
L->Tstate = DONE;
|
||||
}
|
||||
L->errorJmp = NULL;
|
||||
prev = t;
|
||||
}
|
||||
// Free the completed tasks
|
||||
// This MUST occur after all the tasks have been run (not during)
|
||||
// or else when one task is freed right after another the task
|
||||
// execution gets hosed. Test Case: Switching between tw.set and
|
||||
// tb.set in Rubacava causes a crash without this.
|
||||
prev = L->root_task;
|
||||
while ((t = prev->next) != NULL) {
|
||||
luaI_switchtask(t);
|
||||
if (L->Tstate == DONE) { // Remove from list of active tasks
|
||||
luaI_switchtask(old_task);
|
||||
prev->next = t->next;
|
||||
t->next = NULL;
|
||||
if (prev->next == NULL) {
|
||||
L->last_task = prev;
|
||||
}
|
||||
luaM_free(t);
|
||||
} else {
|
||||
prev = t;
|
||||
}
|
||||
}
|
||||
if (L->curr_task != old_task) {
|
||||
luaI_switchtask(old_task);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user