aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
authorAndrew Kurushin2005-01-21 21:55:54 +0000
committerAndrew Kurushin2005-01-21 21:55:54 +0000
commit58ec0f0aadd5228732a3c5915b9a94ec00e9cc53 (patch)
tree28c6ded9c7fd57a8284fa1212f17917900e7e57e /saga
parent0228f1645f582213ef3e12f19df8e88e61891fbe (diff)
downloadscummvm-rg350-58ec0f0aadd5228732a3c5915b9a94ec00e9cc53.tar.gz
scummvm-rg350-58ec0f0aadd5228732a3c5915b9a94ec00e9cc53.tar.bz2
scummvm-rg350-58ec0f0aadd5228732a3c5915b9a94ec00e9cc53.zip
problems solved:
- Allow more than one script work at once - Proper implementation of address methods some opcodes may be broken - cause work in progress todo: rewrite opcodes with new address functionality svn-id: r16604
Diffstat (limited to 'saga')
-rw-r--r--saga/actor.cpp13
-rw-r--r--saga/events.cpp52
-rw-r--r--saga/events.h13
-rw-r--r--saga/font.cpp10
-rw-r--r--saga/game.cpp2
-rw-r--r--saga/interface.cpp5
-rw-r--r--saga/interface.h1
-rw-r--r--saga/objectmap.cpp6
-rw-r--r--saga/render.cpp2
-rw-r--r--saga/saga.h4
-rw-r--r--saga/scene.cpp61
-rw-r--r--saga/script.cpp381
-rw-r--r--saga/script.h254
-rw-r--r--saga/sdebug.cpp10
-rw-r--r--saga/sfuncs.cpp294
-rw-r--r--saga/sprite.cpp4
-rw-r--r--saga/sthread.cpp296
17 files changed, 638 insertions, 770 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 5130c6c104..2f4e0f33d9 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -308,7 +308,7 @@ bool Actor::loadActorResources(ActorData *actor) {
framesPointer = (ActorFrameSequence *)malloc(sizeof(ActorFrameSequence) * framesCount);
if (framesPointer == NULL) {
- error("Couldn't allocate memory for sprite frames");
+ memoryError("Actor::loadActorResources");
}
MemoryReadStreamEndian readS(resourcePointer, resourceLength, IS_BIG_ENDIAN);
@@ -394,11 +394,12 @@ void Actor::stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit,
event.code = SCRIPT_EVENT;
event.op = EVENT_EXEC_NONBLOCKING;
event.time = 0;
- event.param = hitZone->getScriptNumber();
- event.param2 = kVerbEnter; // Action
- event.param3 = ID_NOTHING; // Object
- event.param4 = ID_NOTHING; // With Object
- event.param5 = ID_PROTAG; // Actor
+ event.param = _vm->_scene->getScriptModuleNumber(); // module number
+ event.param2 = hitZone->getScriptNumber(); // script entry point number
+ event.param3 = kVerbEnter; // Action
+ event.param4 = ID_NOTHING; // Object
+ event.param5 = ID_NOTHING; // With Object
+ event.param6 = ID_PROTAG; // Actor
_vm->_events->queue(&event);
}
diff --git a/saga/events.cpp b/saga/events.cpp
index c3cf7cde05..6b40aad606 100644
--- a/saga/events.cpp
+++ b/saga/events.cpp
@@ -395,20 +395,20 @@ int Events::handleOneShot(EVENT *event) {
switch (event->op) {
case EVENT_EXEC_BLOCKING:
case EVENT_EXEC_NONBLOCKING:
- debug(0, "Starting start script #%d", event->param);
+ debug(0, "Exec module number %d script entry number %d", event->param, event->param2);
- sthread = _vm->_script->createThread();
+ sthread = _vm->_script->createThread(event->param, event->param2);
if (sthread == NULL) {
_vm->_console->DebugPrintf("Thread creation failed.\n");
break;
}
- sthread->threadVars[kVarAction] = TO_LE_16(event->param2);
- sthread->threadVars[kVarObject] = TO_LE_16(event->param3);
- sthread->threadVars[kVarWithObject] = TO_LE_16(event->param4);
- sthread->threadVars[kVarActor] = TO_LE_16(event->param5);
+ sthread->_threadVars[kThreadVarAction] = TO_LE_16(event->param3);
+ sthread->_threadVars[kThreadVarObject] = TO_LE_16(event->param4);
+ sthread->_threadVars[kThreadVarWithObject] = TO_LE_16(event->param5);
+ sthread->_threadVars[kThreadVarActor] = TO_LE_16(event->param6);
- _vm->_script->executeThread(sthread, event->param);
+// _vm->_script->executeThread(sthread, event->param);
if (event->op == EVENT_EXEC_BLOCKING)
_vm->_script->completeThread();
@@ -463,45 +463,35 @@ int Events::handleInterval(EVENT *event) {
// Schedules an event in the event list; returns a pointer to the scheduled
// event suitable for chaining if desired.
EVENT *Events::queue(EVENT *event) {
- EVENT *queued_event;
+ EVENT *queuedEvent;
- event->chain = NULL;
- queued_event = _eventList.pushBack(*event).operator->();
-
- initializeEvent(queued_event);
+ queuedEvent = _eventList.pushBack(*event).operator->();
+ initializeEvent(queuedEvent);
- return queued_event;
+ return queuedEvent;
}
// Places a 'add_event' on the end of an event chain given by 'head_event'
// (head_event may be in any position in the event chain)
-EVENT *Events::chain(EVENT *head_event, EVENT *add_event) {
- EVENT *walk_event;
- EVENT *new_event;
-
- // Allocate space for new event
- new_event = (EVENT *)malloc(sizeof(*new_event));
- if (new_event == NULL) {
- return NULL;
+EVENT *Events::chain(EVENT *headEvent, EVENT *addEvent) {
+ if (headEvent == NULL) {
+ return queue(addEvent);
}
- // Copy event data to new event
- *new_event = *add_event;
-
- // Walk to end of chain
- for (walk_event = head_event; walk_event->chain != NULL; walk_event = walk_event->chain) {
+ EVENT *walkEvent;
+ for (walkEvent = headEvent; walkEvent->chain != NULL; walkEvent = walkEvent->chain) {
continue;
}
- // Place new event
- walk_event->chain = new_event;
- new_event->chain = NULL;
- initializeEvent(new_event);
+ walkEvent->chain = (EVENT *)malloc(sizeof(*walkEvent->chain));
+ *walkEvent->chain = *addEvent;
+ initializeEvent(walkEvent->chain);
- return new_event;
+ return walkEvent->chain;
}
int Events::initializeEvent(EVENT *event) {
+ event->chain = NULL;
switch (event->type) {
case ONESHOT_EVENT:
break;
diff --git a/saga/events.h b/saga/events.h
index 58d3f9ee99..b8b271dc47 100644
--- a/saga/events.h
+++ b/saga/events.h
@@ -30,7 +30,7 @@
namespace Saga {
-enum EVENT_TYPES {
+enum EventTypes {
ONESHOT_EVENT, // Event takes no time
CONTINUOUS_EVENT, // Event takes time; next event starts immediately
INTERVAL_EVENT, // Not yet implemented
@@ -42,7 +42,7 @@ enum EVENT_FLAGS {
NODESTROY = 0x4000
};
-enum EVENT_CODES {
+enum EventCodes {
BG_EVENT = 1,
ANIM_EVENT,
MUSIC_EVENT,
@@ -124,13 +124,16 @@ struct EVENT {
long param3;
long param4;
long param5;
+ long param6;
void *data; // Optional event data
long time; // Elapsed time until event
long duration; // Duration of event
long d_reserved;
EVENT *chain; // Event chain (For consecutive events)
- EVENT() { memset(this, 0, sizeof(*this)); }
+ EVENT() {
+ memset(this, 0, sizeof(*this));
+ }
};
typedef SortedList<EVENT> EventList;
@@ -138,7 +141,7 @@ typedef SortedList<EVENT> EventList;
#define EVENT_WARNINGCOUNT 1000
#define EVENT_MASK 0x00FF
-enum EVENT_STATUSCODE {
+enum EventStatusCode {
EVENT_INVALIDCODE = 0,
EVENT_DELETE,
EVENT_CONTINUE,
@@ -153,7 +156,7 @@ class Events {
int clearList();
int freeList();
EVENT *queue(EVENT *event);
- EVENT *chain(EVENT *eead_event, EVENT *add_event);
+ EVENT *chain(EVENT *headEvent, EVENT *addEvent);
private:
int handleContinuous(EVENT * event);
diff --git a/saga/font.cpp b/saga/font.cpp
index b55d33f973..a364fb3ad2 100644
--- a/saga/font.cpp
+++ b/saga/font.cpp
@@ -47,7 +47,7 @@ Font::Font(SagaEngine *vm) : _vm(vm), _initialized(false) {
_fonts = (FONT **)malloc(_vm->getFontsCount() * sizeof(*_fonts));
if (_fonts == NULL) {
- error("Font::Font(): Memory allocation failure.");
+ memoryError("Font::Font");
}
for (i = 0; i < _vm->getFontsCount(); i++) {
@@ -104,7 +104,7 @@ int Font::loadFont(uint32 fontResourceId) {
// Create new font structure
font = (FONT *)malloc(sizeof(*font));
if (font == NULL) {
- error("Font:loadFont(): Memory allocation error.");
+ memoryError("Font::loadFont");
}
// Read font header
@@ -121,7 +121,7 @@ int Font::loadFont(uint32 fontResourceId) {
// Create normal font style
normal_font = (FONT_STYLE *)malloc(sizeof(*normal_font));
if (normal_font == NULL) {
- error("Font::loadFont(): Memory allocation error.");
+ memoryError("Font::loadFont");
}
normal_font->font_free_p = fontres_p;
@@ -207,7 +207,7 @@ FONT_STYLE *Font::createOutline(FONT_STYLE *src_font) {
new_font = (FONT_STYLE *)malloc(sizeof(*new_font));
if (new_font == NULL) {
- error("Font::createOutline(): Memory allocation error.");
+ memoryError("Font::createOutline");
}
memset(new_font, 0, sizeof(*new_font));
@@ -250,7 +250,7 @@ FONT_STYLE *Font::createOutline(FONT_STYLE *src_font) {
new_font_data = (unsigned char *)malloc(new_font_data_len);
if (new_font_data == NULL) {
- error("Font::createOutline(): Memory allocation error.");
+ memoryError("Font::createOutline");
}
memset(new_font_data, 0, new_font_data_len);
diff --git a/saga/game.cpp b/saga/game.cpp
index 6dd41638ad..f03680647e 100644
--- a/saga/game.cpp
+++ b/saga/game.cpp
@@ -854,7 +854,7 @@ int SagaEngine::loadGame(int gameNumber) {
_gameFileContexts = (RSCFILE_CONTEXT **)realloc(_gameFileContexts, gameFileCount * sizeof(*_gameFileContexts));
//TODO: on exit - FREE!
if (_gameFileContexts == NULL) {
- error("SagaEngine::loadGame not enough memory");
+ memoryError("SagaEngine::loadGame");
}
diff --git a/saga/interface.cpp b/saga/interface.cpp
index a0f8f7ad27..395d3a6120 100644
--- a/saga/interface.cpp
+++ b/saga/interface.cpp
@@ -67,11 +67,6 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) {
return;
}
- _iThread = _vm->_script->createThread();
- if (_iThread == NULL) {
- error("Interface::Interface(): Error creating script thread for game interface module");
- }
-
// Load interface module resource file context
_interfaceContext = _vm->getFileContext(GAME_RESOURCEFILE, 0);
if (_interfaceContext == NULL) {
diff --git a/saga/interface.h b/saga/interface.h
index f5918d8e7f..51eee1e6c7 100644
--- a/saga/interface.h
+++ b/saga/interface.h
@@ -169,7 +169,6 @@ private:
InterfacePanel _conversePanel;
SpriteList _defPortraits;
SpriteList _scenePortraits;
- ScriptThread *_iThread;
PanelButton *_verbTypeToPanelButton[kVerbTypesMax];
bool _active;
diff --git a/saga/objectmap.cpp b/saga/objectmap.cpp
index 7b104c6d24..fe4a7a7e49 100644
--- a/saga/objectmap.cpp
+++ b/saga/objectmap.cpp
@@ -51,7 +51,7 @@ HitZone::HitZone(MemoryReadStreamEndian *readStream, int index): _index(index) {
_clickAreas = (HitZone::ClickArea *)malloc(_clickAreasCount * sizeof(*_clickAreas));
if (_clickAreas == NULL) {
- error("HitZone::HitZone Memory allocation failed");
+ memoryError("HitZone::HitZone");
}
for (i = 0; i < _clickAreasCount; i++) {
@@ -62,7 +62,7 @@ HitZone::HitZone(MemoryReadStreamEndian *readStream, int index): _index(index) {
clickArea->points = (Point *)malloc(clickArea->pointsCount * sizeof(*(clickArea->points)));
if (clickArea->points == NULL) {
- error("HitZone::HitZone Memory allocation failed");
+ memoryError("HitZone::HitZone");
}
for (j = 0; j < clickArea->pointsCount; j++) {
@@ -169,7 +169,7 @@ void ObjectMap::load(const byte *resourcePointer, size_t resourceLength) {
_hitZoneList = (HitZone **) malloc(_hitZoneListCount * sizeof(HitZone *));
if (_hitZoneList == NULL) {
- error("ObjectMap::load Memory allocation failure");
+ memoryError("ObjectMap::load");
}
for (i = 0; i < _hitZoneListCount; i++) {
diff --git a/saga/render.cpp b/saga/render.cpp
index 2446ae38e7..d384ef548f 100644
--- a/saga/render.cpp
+++ b/saga/render.cpp
@@ -59,7 +59,7 @@ Render::Render(SagaEngine *vm, OSystem *system) {
_bg_buf = (byte *)calloc(_vm->getDisplayWidth(), _vm->getDisplayHeight());
if (_bg_buf == NULL) {
- error("Render::Render not enough memory");
+ memoryError("Render::Render");
}
// Allocate temp buffer for animation decoding,
diff --git a/saga/saga.h b/saga/saga.h
index e59d7a2de8..ccf663600a 100644
--- a/saga/saga.h
+++ b/saga/saga.h
@@ -75,6 +75,8 @@ class PalAnim;
#define OBJECT_TYPE_SHIFT 13
#define OBJECT_TYPE_MASK ((1 << OBJECT_TYPE_SHIFT) - 1)
+#define memoryError(Place) error(Place##" Memory allocation error.")
+
struct RSCFILE_CONTEXT;
struct StringList;
@@ -293,7 +295,7 @@ struct GameFontDescription {
struct GameResourceDescription {
uint32 scene_lut_rn;
- uint32 script_lut_rn;
+ uint32 moduleLUTResourceId;
uint32 mainPanelResourceId;
uint32 conversePanelResourceId;
};
diff --git a/saga/scene.cpp b/saga/scene.cpp
index 0b5173ebd7..a9a1500e45 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -79,7 +79,7 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
_sceneMax = _sceneCount - 1;
_sceneLUT = (int *)malloc(_sceneMax * sizeof(*_sceneLUT));
if (_sceneLUT == NULL) {
- error("Scene::Scene(): Memory allocation failed");
+ memoryError("Scene::Scene()");
}
MemoryReadStreamEndian readS(scene_lut_p, scene_lut_len, IS_BIG_ENDIAN);
@@ -508,6 +508,9 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneD
uint32 res_number = 0;
int result;
int i;
+ EVENT event;
+ EVENT *q_event;
+ static PALENTRY current_pal[PAL_ENTRIES];
assert(_initialized);
@@ -578,20 +581,18 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneD
return FAILURE;
}
- // Load scene script data
+/* // Load scene script data
if (_desc.scriptModuleNumber > 0) {
if (_vm->_script->loadScript(_desc.scriptModuleNumber) != SUCCESS) {
warning("Scene::loadScene(): Error loading scene script");
return FAILURE;
}
}
-
+*/
_sceneLoaded = true;
-
+
+ q_event = NULL;
if (fadeType == SCENE_FADE || fadeType == SCENE_FADE_NO_INTERFACE) {
- EVENT event;
- EVENT *q_event;
- static PALENTRY current_pal[PAL_ENTRIES];
_vm->_interface->rememberMode();
_vm->_interface->setMode(kPanelFade, true);
@@ -632,22 +633,25 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneD
event.time = 0;
event.duration = 0;
q_event = _vm->_events->chain(q_event, &event);
+ }
- // Start the scene pre script, but stay with black palette
- if (_desc.startScriptEntrypointNumber > 0) {
- event.type = ONESHOT_EVENT;
- event.code = SCRIPT_EVENT;
- event.op = EVENT_EXEC_BLOCKING;
- event.time = 0;
- event.param = _desc.startScriptEntrypointNumber;
- event.param2 = 0; // Action
- event.param3 = _sceneNumber; // Object
- event.param4 = 0; // With Object - TODO: should be 'entrance'
- event.param5 = 0; // Actor
+ // Start the scene pre script, but stay with black palette
+ if (_desc.startScriptEntrypointNumber > 0) {
+ event.type = ONESHOT_EVENT;
+ event.code = SCRIPT_EVENT;
+ event.op = EVENT_EXEC_BLOCKING;
+ event.time = 0;
+ event.param = _desc.scriptModuleNumber;
+ event.param2 = _desc.startScriptEntrypointNumber;
+ event.param3 = 0; // Action
+ event.param4 = _sceneNumber; // Object
+ event.param5 = 0; // With Object - TODO: should be 'entrance'
+ event.param6 = 0; // Actor
- q_event = _vm->_events->chain(q_event, &event);
- }
+ q_event = _vm->_events->chain(q_event, &event);
+ }
+ if (fadeType == SCENE_FADE || fadeType == SCENE_FADE_NO_INTERFACE) {
// Fade in from black to the scene background palette
event.type = IMMEDIATE_EVENT;
event.code = PAL_EVENT;
@@ -922,9 +926,9 @@ int Scene::endScene() {
_sceneProc(SCENE_END, &scene_info, this);
- if (_desc.scriptModuleNumber > 0) {
+/* if (_desc.scriptModuleNumber > 0) {
_vm->_script->freeScript();
- }
+ }*/
// Free scene background
if (_bg.loaded) {
@@ -1082,11 +1086,12 @@ int Scene::defaultScene(int param, SCENE_INFO *scene_info) {
event.code = SCRIPT_EVENT;
event.op = EVENT_EXEC_NONBLOCKING;
event.time = 0;
- event.param = _desc.sceneScriptEntrypointNumber;
- event.param2 = 0; // Action
- event.param3 = _sceneNumber; // Object
- event.param4 = 0; // With Object - TODO: should be 'entrance'
- event.param5 = 0; // Actor - TODO: should be VERB_ENTER
+ event.param = _desc.scriptModuleNumber;
+ event.param2 = _desc.sceneScriptEntrypointNumber;
+ event.param3 = 0; // Action
+ event.param4 = _sceneNumber; // Object
+ event.param5 = 0; // With Object - TODO: should be 'entrance'
+ event.param6 = 0; // Actor - TODO: should be VERB_ENTER
_vm->_events->queue(&event);
}
@@ -1116,7 +1121,7 @@ void Scene::loadSceneEntryList(const byte* resourcePointer, size_t resourceLengt
_entryList.entryList = (SceneEntry *) malloc(_entryList.entryListCount * sizeof(*_entryList.entryList));
if (_entryList.entryList == NULL) {
- error("Scene::loadSceneEntryList Memory allocation failure");
+ memoryError("Scene::loadSceneEntryList");
}
for (i = 0; i < _entryList.entryListCount; i++) {
diff --git a/saga/script.cpp b/saga/script.cpp
index b75b963adc..3ebc7af395 100644
--- a/saga/script.cpp
+++ b/saga/script.cpp
@@ -43,10 +43,9 @@ namespace Saga {
// Initializes the scripting module.
// Loads script resource look-up table, initializes script data system
Script::Script() {
- RSCFILE_CONTEXT *s_lut_ctxt;
RSCFILE_CONTEXT *resourceContext;
- byte *rsc_ptr;
- size_t rsc_len;
+ byte *resourcePointer;
+ size_t resourceLength;
int prevTell;
int result;
int i, j;
@@ -58,8 +57,7 @@ Script::Script() {
_dbg_singlestep = 0;
_scriptContext = 0;
_voiceLUTPresent = false;
- _scriptLUTEntryLen = 0;
- _currentScript = 0;
+
_abortEnabled = true;
_skipSpeeches = false;
_conversingThread = NULL;
@@ -73,84 +71,74 @@ Script::Script() {
_rightButtonVerb = kVerbNone;
_pointerObject = 0;
- _dataBuf[0].data = _dataBuf[1].data = (ScriptDataWord *)calloc(SCRIPT_DATABUF_LEN, sizeof(ScriptDataWord));;
- _dataBuf[0].length = _dataBuf[1].length = SCRIPT_DATABUF_LEN;
-
- for (i = 2; i < SCRIPT_DATABUF_NUM; i++) {
- _dataBuf[i].length = 0;
- _dataBuf[i].data = NULL;
- }
-
+
+ _staticSize = 0;
+ _commonBufferSize = COMMON_BUFFER_SIZE;
+ _commonBuffer = (byte*)malloc(_commonBufferSize);
+ memset(_commonBuffer, 0, _commonBufferSize);
debug(0, "Initializing scripting subsystem");
// Load script resource file context
_scriptContext = _vm->getFileContext(GAME_SCRIPTFILE, 0);
if (_scriptContext == NULL) {
- error("Couldn't get script file context");
+ error("Script::Script() Couldn't get script file context");
}
- // Load script LUT resource
- s_lut_ctxt = _vm->getFileContext(GAME_RESOURCEFILE, 0);
- if (s_lut_ctxt == NULL) {
- error("Couldn't get resource file context");
+ resourceContext = _vm->getFileContext(GAME_RESOURCEFILE, 0);
+ if (resourceContext == NULL) {
+ error("Script::Script() Couldn't get resource file context");
}
- debug(0, "Loading script LUT from resource %u.", _vm->getResourceDescription()->script_lut_rn);
- result = RSC_LoadResource(s_lut_ctxt, _vm->getResourceDescription()->script_lut_rn, &rsc_ptr, &rsc_len);
+ debug(0, "Loading module LUT from resource %u.", _vm->getResourceDescription()->moduleLUTResourceId);
+ result = RSC_LoadResource(resourceContext, _vm->getResourceDescription()->moduleLUTResourceId, &resourcePointer, &resourceLength);
if (result != SUCCESS) {
- error("Error: Couldn't load script resource look-up table");
+ error("Script::Script() Couldn't load module LUT resource");
}
// Create logical script LUT from resource
- if (rsc_len % S_LUT_ENTRYLEN_ITECD == 0) {
- _scriptLUTEntryLen = S_LUT_ENTRYLEN_ITECD;
- } else if (rsc_len % S_LUT_ENTRYLEN_ITEDISK == 0) {
- _scriptLUTEntryLen = S_LUT_ENTRYLEN_ITEDISK;
+ if (resourceLength % S_LUT_ENTRYLEN_ITECD == 0) {
+ _modulesLUTEntryLen = S_LUT_ENTRYLEN_ITECD;
+ } else if (resourceLength % S_LUT_ENTRYLEN_ITEDISK == 0) {
+ _modulesLUTEntryLen = S_LUT_ENTRYLEN_ITEDISK;
} else {
- error("Error: Invalid script lookup table length (%d)", rsc_len);
+ error("Script::Script() Invalid script lookup table length (%d)", resourceLength);
}
// Calculate number of entries
- _scriptLUTMax = rsc_len / _scriptLUTEntryLen;
+ _modulesCount = resourceLength / _modulesLUTEntryLen;
- debug(0, "LUT has %d entries.", _scriptLUTMax);
+ debug(0, "LUT has %d entries.", _modulesCount);
// Allocate space for logical LUT
- _scriptLUT = (SCRIPT_LUT_ENTRY *)malloc(_scriptLUTMax * sizeof(SCRIPT_LUT_ENTRY));
- if (_scriptLUT == NULL) {
- error("Error: Couldn't allocate memory for script resource look-up table");
+ _modules = (ModuleData *)malloc(_modulesCount * sizeof(*_modules));
+ if (_modules == NULL) {
+ memoryError("Script::Script()");
}
// Convert LUT resource to logical LUT
- MemoryReadStreamEndian scriptS(rsc_ptr, rsc_len, IS_BIG_ENDIAN);
- for (i = 0; i < _scriptLUTMax; i++) {
+ MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, IS_BIG_ENDIAN);
+ for (i = 0; i < _modulesCount; i++) {
+ memset(&_modules[i], 0, sizeof(ModuleData));
+
prevTell = scriptS.pos();
- _scriptLUT[i].script_rn = scriptS.readUint16();
- _scriptLUT[i].diag_list_rn = scriptS.readUint16();
- _scriptLUT[i].voice_lut_rn = scriptS.readUint16();
+ _modules[i].scriptResourceId = scriptS.readUint16();
+ _modules[i].stringsResourceId = scriptS.readUint16();
+ _modules[i].voicesResourceId = scriptS.readUint16();
+
+ if (_modules[i].voicesResourceId > 0) {
+ _voiceLUTPresent = true;
+ }
+
// Skip the unused portion of the structure
- for (j = scriptS.pos(); j < prevTell + _scriptLUTEntryLen; j++) {
+ for (j = scriptS.pos(); j < prevTell + _modulesLUTEntryLen; j++) {
if (scriptS.readByte() != 0)
warning("Unused scriptLUT part isn't really unused for LUT %d (pos: %d)", i, j);
}
}
- RSC_FreeResource(rsc_ptr);
-
- // Any voice lookup table resources present?
- for (i = 0; i < _scriptLUTMax; i++) {
- if (_scriptLUT[i].voice_lut_rn) {
- _voiceLUTPresent = true;
- break;
- }
- }
-
-
- setupScriptFuncList();
-
- resourceContext = _vm->getFileContext(GAME_RESOURCEFILE, 0);
-
+ RSC_FreeResource(resourcePointer);
+
result = RSC_LoadResource(resourceContext, RID_ITE_MAIN_STRINGS, &stringsPointer, &stringsLength); // fixme: IHNM
if ((result != SUCCESS) || (stringsLength == 0)) {
error("Error loading strings list resource");
@@ -159,6 +147,8 @@ Script::Script() {
_vm->loadStrings(_mainStrings, stringsPointer, stringsLength);
RSC_FreeResource(stringsPointer);
+ setupScriptFuncList();
+
_initialized = true;
}
@@ -173,14 +163,14 @@ Script::~Script() {
_mainStrings.freeMem();
- // Free script lookup table
- free(_scriptLUT);
+ freeModules();
+ free(_modules);
- free(_dataBuf[0].data);
+ free(_commonBuffer);
_initialized = false;
}
-
+/*
int Script::getWord(int bufNumber, int wordNumber, ScriptDataWord *data) {
if ((bufNumber < 0) || (bufNumber >= SCRIPT_DATABUF_NUM)) {
return FAILURE;
@@ -265,242 +255,137 @@ int Script::getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState) {
return SUCCESS;
}
+*/
-// Loads a script; including script bytecode and dialogue list
-int Script::loadScript(int scriptModuleNumber) {
- ScriptData *script_data;
- byte *bytecode_p;
- size_t bytecode_len;
- uint32 scriptl_rn;
- byte *stringsPointer;
- size_t stringsLength;
- uint32 stringsResourceId;
- byte *voicelut_p;
- size_t voicelut_len;
- uint32 voicelut_rn;
+void Script::loadModule(int scriptModuleNumber) {
+ byte *resourcePointer;
+ size_t resourceLength;
int result;
// Validate script number
- if ((scriptModuleNumber < 0) || (scriptModuleNumber > _scriptLUTMax)) {
- warning("Script::loadScript(): Invalid script module number");
- return FAILURE;
+ if ((scriptModuleNumber < 0) || (scriptModuleNumber >= _modulesCount)) {
+ error("Script::loadScript() Invalid script module number");
}
- // Release old script data if present
- freeScript();
-
- // Initialize script data structure
- debug(0, "Loading script data for script module #%d", scriptModuleNumber);
-
- script_data = (ScriptData *)malloc(sizeof(*script_data));
- if (script_data == NULL) {
- error("Memory allocation failed");
+ if (_modules[scriptModuleNumber].loaded) {
+ return;
}
- script_data->loaded = 0;
-
- // Initialize script pointers
- script_data->bytecode = NULL;
- script_data->voice = NULL;
-
- // Load script bytecode
- scriptl_rn = _scriptLUT[scriptModuleNumber].script_rn;
+ // Initialize script data structure
+ debug(0, "Loading script module #%d", scriptModuleNumber);
- result = RSC_LoadResource(_scriptContext, scriptl_rn, &bytecode_p, &bytecode_len);
+ result = RSC_LoadResource(_scriptContext, _modules[scriptModuleNumber].scriptResourceId, &resourcePointer, &resourceLength);
if (result != SUCCESS) {
- warning("Error loading script bytecode resource");
- free(script_data);
- return FAILURE;
+ error("Script::loadModule() unable to load module base resource");
}
- script_data->bytecode = loadBytecode(bytecode_p, bytecode_len);
+ loadModuleBase(_modules[scriptModuleNumber], resourcePointer, resourceLength);
+ RSC_FreeResource(resourcePointer);
- if (script_data->bytecode == NULL) {
- error("Error interpreting script bytecode resource");
- }
-
- // Load script strings list
- stringsResourceId = _scriptLUT[scriptModuleNumber].diag_list_rn;
-
- // Load strings list resource
- result = RSC_LoadResource(_scriptContext, stringsResourceId, &stringsPointer, &stringsLength);
- if ((result != SUCCESS) || (stringsLength == 0)) {
- error("Error loading strings list resource");
+ result = RSC_LoadResource(_scriptContext, _modules[scriptModuleNumber].stringsResourceId, &resourcePointer, &resourceLength);
+ if ((result != SUCCESS) || (resourceLength == 0)) {
+ error("Script::loadModule() Error loading strings list resource");
}
- // Convert strings list resource to logical strings list
- _vm->loadStrings(script_data->strings, stringsPointer, stringsLength);
- RSC_FreeResource(stringsPointer);
-
- // Load voice resource lookup table
- if (_voiceLUTPresent) {
- voicelut_rn = _scriptLUT[scriptModuleNumber].voice_lut_rn;
+ _vm->loadStrings(_modules[scriptModuleNumber].strings, resourcePointer, resourceLength);
+ RSC_FreeResource(resourcePointer);
- // Load voice LUT resource
- result = RSC_LoadResource(_scriptContext, voicelut_rn, &voicelut_p, &voicelut_len);
+ if (_modules[scriptModuleNumber].voicesResourceId > 0) {
+ result = RSC_LoadResource(_scriptContext, _modules[scriptModuleNumber].voicesResourceId, &resourcePointer, &resourceLength);
if (result != SUCCESS) {
- error("Error loading voice LUT resource");
+ error("Script::loadModule() Error loading voice LUT resource");
}
- // Convert voice LUT resource to logical voice LUT
- script_data->voice = loadVoiceLUT(voicelut_p, voicelut_len, script_data);
- if (script_data->voice == NULL) {
- error("Error interpreting voice LUT resource");
- }
+ loadModuleVoiceLUT(_modules[scriptModuleNumber], resourcePointer, resourceLength);
+ RSC_FreeResource(resourcePointer);
}
- // Finish initialization
- script_data->loaded = 1;
- _currentScript = script_data;
-
- return SUCCESS;
-}
-
-// Frees all resources associated with current script.
-int Script::freeScript() {
- if (_currentScript == NULL) {
- return FAILURE;
- }
-
- if (!_currentScript->loaded) {
- return FAILURE;
+ _modules[scriptModuleNumber].staticOffset = _staticSize;
+ _staticSize += _modules[scriptModuleNumber].staticSize;
+ if (_staticSize > _commonBufferSize) {
+ error("Script::loadModule() _staticSize > _commonBufferSize");
}
+ _modules[scriptModuleNumber].loaded = true;
+}
- debug(0, "Releasing script data.");
-
- // Finish initialization
- _currentScript->strings.freeMem();
-
- if (_currentScript->bytecode != NULL) {
- free(_currentScript->bytecode->entrypoints);
- RSC_FreeResource(_currentScript->bytecode->bytecode_p);
- }
-
- free(_currentScript->bytecode);
-
- if (_voiceLUTPresent) {
- free(_currentScript->voice->voices);
- free(_currentScript->voice);
+void Script::freeModules() {
+ int i;
+ for (i = 0; i < _modulesCount; i++) {
+ if (_modules[i].loaded) {
+ _modules[i].freeMem();
+ }
}
-
- free(_currentScript);
-
- _currentScript = NULL;
-
- return SUCCESS;
+ _staticSize = 0;
}
-// Reads the entrypoint table from a script bytecode resource in memory.
-// Returns NULL on failure.
-SCRIPT_BYTECODE *Script::loadBytecode(byte *bytecode_p, size_t bytecode_len) {
- PROC_TBLENTRY *bc_ep_tbl = NULL;
- SCRIPT_BYTECODE *bc_new_data = NULL;
+void Script::loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength) {
+ int i;
+
+ debug(0, "Loading module base...");
- unsigned long n_entrypoints; // Number of entrypoints
- size_t ep_tbl_offset; // Offset of bytecode entrypoint table
- unsigned long i;
+ module.moduleBase = (byte*)malloc(resourceLength);
+ module.moduleBaseSize = resourceLength;
- debug(0, "Loading script bytecode...");
+ memcpy(module.moduleBase, resourcePointer, resourceLength);
- MemoryReadStreamEndian scriptS(bytecode_p, bytecode_len, IS_BIG_ENDIAN);
+ MemoryReadStreamEndian scriptS(module.moduleBase, module.moduleBaseSize, IS_BIG_ENDIAN);
- // The first two uint32 values are the number of entrypoints, and the
- // offset to the entrypoint table, respectively.
- n_entrypoints = scriptS.readUint16();
+ module.entryPointsCount = scriptS.readUint16();
scriptS.readUint16(); //skip
- ep_tbl_offset = scriptS.readUint16();
+ module.entryPointsTableOffset = scriptS.readUint16();
scriptS.readUint16(); //skip
- // Check that the entrypoint table offset is valid.
- if ((bytecode_len - ep_tbl_offset) < (n_entrypoints * SCRIPT_TBLENTRY_LEN)) {
- warning("Invalid table offset");
- return NULL;
- }
-
- if (n_entrypoints > SCRIPT_MAX) {
- warning("Script limit exceeded");
- return NULL;
+ if ((module.moduleBaseSize - module.entryPointsTableOffset) < (module.entryPointsCount * SCRIPT_TBLENTRY_LEN)) {
+ error("Script::loadModuleBase() Invalid table offset");
}
- // Allocate a new bytecode resource information structure and table of
- // entrypoints
-
- bc_new_data = (SCRIPT_BYTECODE *)malloc(sizeof(*bc_new_data));
- if (bc_new_data == NULL) {
- warning("Memory allocation failure loading script bytecode");
- return NULL;
+ if (module.entryPointsCount > SCRIPT_MAX) {
+ error("Script::loadModuleBase()Script limit exceeded");
}
-
- bc_ep_tbl = (PROC_TBLENTRY *)malloc(n_entrypoints * sizeof(*bc_ep_tbl));
- if (bc_ep_tbl == NULL) {
- warning("Memory allocation failure creating script entrypoint table");
- free(bc_new_data);
- return NULL;
+
+ module.entryPoints = (EntryPoint *)malloc(module.entryPointsCount * sizeof(*module.entryPoints));
+ if (module.entryPoints == NULL) {
+ memoryError("Script::loadModuleBase");
}
// Read in the entrypoint table
-
- while (scriptS.pos() < ep_tbl_offset)
+
+ module.staticSize = scriptS.readUint16();
+ while (scriptS.pos() < module.entryPointsTableOffset)
scriptS.readByte();
- for (i = 0; i < n_entrypoints; i++) {
+ for (i = 0; i < module.entryPointsCount; i++) {
// First uint16 is the offset of the entrypoint name from the start
// of the bytecode resource, second uint16 is the offset of the
// bytecode itself for said entrypoint
- bc_ep_tbl[i].name_offset = scriptS.readUint16();
- bc_ep_tbl[i].offset = scriptS.readUint16();
+ module.entryPoints[i].nameOffset = scriptS.readUint16();
+ module.entryPoints[i].offset = scriptS.readUint16();
// Perform a simple range check on offset values
- if ((bc_ep_tbl[i].name_offset > bytecode_len) || (bc_ep_tbl[i].offset > bytecode_len)) {
- warning("Invalid offset encountered in script entrypoint table");
- free(bc_new_data);
- free(bc_ep_tbl);
- return NULL;
+ if ((module.entryPoints[i].nameOffset >= module.moduleBaseSize) || (module.entryPoints[i].offset >= module.moduleBaseSize)) {
+ error("Script::loadModuleBase() Invalid offset encountered in script entrypoint table");
}
}
-
- bc_new_data->bytecode_p = (byte *) bytecode_p;
- bc_new_data->bytecode_len = bytecode_len;
-
- bc_new_data->n_entrypoints = n_entrypoints;
- bc_new_data->entrypoints = bc_ep_tbl;
- bc_new_data->ep_tbl_offset = ep_tbl_offset;
-
- return bc_new_data;
}
-
-// Reads a logical voice LUT from a voice LUT resource in memory.
-// Returns NULL on failure.
-VOICE_LUT *Script::loadVoiceLUT(const byte *voicelut_p, size_t voicelut_len, ScriptData *script) {
- VOICE_LUT *voice_lut;
-
+void Script::loadModuleVoiceLUT(ModuleData &module, const byte *resourcePointer, size_t resourceLength) {
uint16 i;
- voice_lut = (VOICE_LUT *)malloc(sizeof(*voice_lut));
- if (voice_lut == NULL) {
- return NULL;
- }
-
- voice_lut->n_voices = voicelut_len / 2;
- if (voice_lut->n_voices != script->strings.stringsCount) {
- warning("Error: Voice LUT entries do not match dialogue entries");
- return NULL;
+ module.voiceLUT.voicesCount = resourceLength / 2;
+ if (module.voiceLUT.voicesCount != module.strings.stringsCount) {
+ error("Script::loadModuleVoiceLUT() Voice LUT entries do not match strings entries");
}
- voice_lut->voices = (int *)malloc(voice_lut->n_voices * sizeof(*voice_lut->voices));
- if (voice_lut->voices == NULL) {
-
- return NULL;
+ module.voiceLUT.voices = (uint16 *)malloc(module.voiceLUT.voicesCount * sizeof(*module.voiceLUT.voices));
+ if (module.voiceLUT.voices == NULL) {
+ error("Script::loadModuleVoiceLUT() not enough memory");
}
- MemoryReadStreamEndian scriptS(voicelut_p, voicelut_len, IS_BIG_ENDIAN);
+ MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, IS_BIG_ENDIAN);
- for (i = 0; i < voice_lut->n_voices; i++) {
- voice_lut->voices[i] = scriptS.readUint16();
+ for (i = 0; i < module.voiceLUT.voicesCount; i++) {
+ module.voiceLUT.voices[i] = scriptS.readUint16();
}
-
- return voice_lut;
}
void Script::scriptError(ScriptThread *thread, const char *format, ...) {
@@ -511,13 +396,13 @@ void Script::scriptError(ScriptThread *thread, const char *format, ...) {
vsprintf(buf, format, argptr);
va_end (argptr);
- thread->flags |= kTFlagAborted;
- debug(0, "Script::scriptError %X: %s", thread->instructionOffset, buf);
- _vm->_console->DebugPrintf("Script::scriptError %X: %s", thread->instructionOffset, buf);
+ thread->_flags |= kTFlagAborted;
+ debug(0, "Script::scriptError %X: %s", thread->_instructionOffset, buf);
+ _vm->_console->DebugPrintf("Script::scriptError %X: %s", thread->_instructionOffset, buf);
}
void Script::scriptInfo() {
- uint32 n_entrypoints;
+/* uint32 n_entrypoints;
uint32 i;
char *name_ptr;
@@ -537,11 +422,11 @@ void Script::scriptInfo() {
name_ptr = (char *)currentScript()->bytecode->bytecode_p +
currentScript()->bytecode->entrypoints[i].name_offset;
_vm->_console->DebugPrintf("%lu: %s\n", i, name_ptr);
- }
+ }*/
}
void Script::scriptExec(int argc, const char **argv) {
- uint16 ep_num;
+/* uint16 ep_num;
ep_num = atoi(argv[1]);
@@ -559,7 +444,7 @@ void Script::scriptExec(int argc, const char **argv) {
return;
}
- executeThread(_dbg_thread, ep_num);
+ executeThread(_dbg_thread, ep_num);*/
}
// verb
@@ -699,19 +584,17 @@ void Script::doVerb() {
}
if (scriptEntrypointNumber > 0) {
- if (scriptModuleNumber != _vm->_scene->getScriptModuleNumber()) {
- warning("scriptModuleNumber != _vm->_scene->getScriptModuleNumber()");
- }
event.type = ONESHOT_EVENT;
event.code = SCRIPT_EVENT;
event.op = EVENT_EXEC_NONBLOCKING;
event.time = 0;
- event.param = scriptEntrypointNumber;
- event.param2 = _pendingVerb; // Action
- event.param3 = _pendingObject[0]; // Object
- event.param4 = _pendingObject[1]; // With Object
- event.param5 = (objectType == kGameObjectActor) ? _pendingObject[0] : ID_PROTAG; // Actor
+ event.param = scriptModuleNumber;
+ event.param2 = scriptEntrypointNumber;
+ event.param3 = _pendingVerb; // Action
+ event.param4 = _pendingObject[0]; // Object
+ event.param5 = _pendingObject[1]; // With Object
+ event.param6 = (objectType == kGameObjectActor) ? _pendingObject[0] : ID_PROTAG; // Actor
_vm->_events->queue(&event);
diff --git a/saga/script.h b/saga/script.h
index 8bf227e6c8..04796d108b 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -31,8 +31,7 @@
namespace Saga {
-#define SCRIPT_DATABUF_NUM 5
-#define SCRIPT_DATABUF_LEN 1024
+#define COMMON_BUFFER_SIZE 1024
#define S_LUT_ENTRYLEN_ITECD 22
#define S_LUT_ENTRYLEN_ITEDISK 16
@@ -48,8 +47,18 @@ namespace Saga {
#define S_WARN_PREFIX "SWarning: "
#define SCRIPT_FUNCTION_MAX 78
-
-typedef unsigned int ScriptDataWord;
+#define DEFAULT_THREAD_STACK_SIZE 256
+
+enum AddressTypes {
+ kAddressCommon = 0, // offset from global variables
+ kAddressStatic = 1, // offset from global variables
+ kAddressModule = 2, // offset from start of module
+ kAddressStack = 3, // offset from stack
+ kAddressThread = 4, // offset from thread structure
+/* kAddressId = 5, // offset from const id object
+ kAddressIdIndirect = 6, // offset from stack id object
+ kAddressIndex = 7 // index from id*/
+};
enum VerbTypes {
//todo: LUT for drawing
@@ -74,11 +83,13 @@ enum VerbTypes {
#define STHREAD_TIMESLICE 8
-enum {
- kVarObject = 0,
- kVarWithObject,
- kVarAction,
- kVarActor
+enum ThreadVarTypes {
+ kThreadVarObject = 0,
+ kThreadVarWithObject = 1,
+ kThreadVarAction = 2,
+ kThreadVarActor = 3,
+
+ kThreadVarMax = kThreadVarActor + 1
};
enum ThreadFlags {
@@ -136,104 +147,141 @@ enum ReplyFlags {
kReplyCondition = 1 << 2
};
-struct ScriptThread {
- int flags; // ThreadFlags
- int waitType; // ThreadWaitTypes
- void *threadObj; // which object we're handling
+struct EntryPoint {
+ uint16 nameOffset;
+ uint16 offset;
+};
+
+struct VoiceLUT {
+ uint16 voicesCount;
+ uint16 *voices;
+ void freeMem() {
+ free(voices);
+ }
+};
+
+struct ModuleData {
+ bool loaded; // is it loaded or not?
+ int scriptResourceId;
+ int stringsResourceId;
+ int voicesResourceId;
+
+ byte *moduleBase; // all base module
+ uint16 moduleBaseSize; // base module size
+ uint16 staticSize; // size of static data
+ uint staticOffset; // offset of static data begining in _commonBuffer
+
+ uint16 entryPointsTableOffset; // offset of entrypoint table in moduleBase
+ uint16 entryPointsCount;
+ EntryPoint *entryPoints;
+
+ StringsTable strings;
+ VoiceLUT voiceLUT;
+ void freeMem() {
+ strings.freeMem();
+ voiceLUT.freeMem();
+ free(moduleBase);
+ free(entryPoints);
+ memset(this, 0x0, sizeof(*this));
+ }
+};
+
+class ScriptThread {
+public:
+ uint16 *_stackBuf;
+ uint16 _stackSize; // stack size in uint16
+
+ uint16 _stackTopIndex;
+ uint16 _frameIndex;
+
+ uint16 _threadVars[kThreadVarMax];
- uint sleepTime;
- int entrypointNumber; // Entrypoint number
- unsigned long entrypointOffset; // Entrypoint offset
- unsigned long instructionOffset; // Instruction offset
+ byte *_moduleBase; //
+ uint16 _moduleBaseSize;
- // The scripts are allowed to access the stack like any other memory
- // area. It's therefore probably quite important that our stacks work
- // the same as in the original interpreter.
+ byte *_commonBase; //
+ byte *_staticBase; //
+ VoiceLUT *_voiceLUT; //
+ StringsTable *_strings; //
- ScriptDataWord stackBuf[64];
+ int _flags; // ThreadFlags
+ int _waitType; // ThreadWaitTypes
+ uint _sleepTime;
+ void *_threadObj; // which object we're handling
- int stackPtr;
- int framePtr;
+ uint16 _returnValue;
- ScriptDataWord threadVars[4];
+ uint16 _instructionOffset; // Instruction offset
- ScriptDataWord retVal;
- ScriptDataWord stackTop() {
- return stackBuf[stackPtr];
+public:
+ byte *baseAddress(byte addrMode) {
+ switch(addrMode) {
+ case kAddressCommon:
+ return _commonBase;
+ case kAddressStatic:
+ return _staticBase;
+ case kAddressModule:
+ return _moduleBase;
+/* case kAddressStack:
+ return _stackBuf + framePtr;*/
+ case kAddressThread:
+ return (byte*)_threadVars;
+ default:
+ return _commonBase;
+ }
+ }
+
+ int16 stackTop() {
+ return (int16)_stackBuf[_stackTopIndex];
}
- int stackSize() {
- return ARRAYSIZE(stackBuf) - stackPtr - 1;
+ uint pushedSize() {
+ return _stackSize - _stackTopIndex - 1;
}
- void push(ScriptDataWord n) {
- assert(stackPtr > 0);
- stackBuf[--stackPtr] = n;
+ void push(int16 value) {
+ if (_stackTopIndex <= 0) {
+ error("ScriptThread::push() stack overflow");
+ }
+ _stackBuf[--_stackTopIndex] = (uint16)value;
}
- ScriptDataWord pop() {
- assert(stackPtr < ARRAYSIZE(stackBuf));
- return stackBuf[stackPtr++];
+ int16 pop() {
+ if (_stackTopIndex >= _stackSize) {
+ error("ScriptThread::push() stack underflow");
+ }
+ return (int16)_stackBuf[_stackTopIndex++];
}
- void wait(int aWaitType) {
- waitType = aWaitType;
- flags |= kTFlagWaiting;
+
+// wait stuff
+ void wait(int waitType) {
+ _waitType = waitType;
+ _flags |= kTFlagWaiting;
}
- void waitWalk(void *aThreadObj) {
+ void waitWalk(void *threadObj) {
wait(kWaitTypeWalk);
- threadObj = aThreadObj;
+ _threadObj = threadObj;
}
- void waitDelay(int aSleepTime) {
+ void waitDelay(int sleepTime) {
wait(kWaitTypeDelay);
- sleepTime = aSleepTime;
+ _sleepTime = sleepTime;
}
ScriptThread() {
- memset(this, 0, sizeof(*this));
+ memset(this, 0xFE, sizeof(*this));
+ _stackBuf = NULL;
+ }
+ ~ScriptThread() {
+ free(_stackBuf);
}
};
typedef SortedList<ScriptThread> ScriptThreadList;
-struct PROC_TBLENTRY {
- size_t name_offset;
- size_t offset;
-};
-
-struct SCRIPT_BYTECODE {
- unsigned char *bytecode_p;
- size_t bytecode_len;
- size_t ep_tbl_offset;
- unsigned long n_entrypoints;
- PROC_TBLENTRY *entrypoints;
-};
-
-struct VOICE_LUT {
- int n_voices;
- int *voices;
-};
-
-struct ScriptData {
- int loaded;
- SCRIPT_BYTECODE *bytecode;
- StringsTable strings;
- VOICE_LUT *voice;
-};
-
-struct SCRIPT_LUT_ENTRY {
- int script_rn;
- int diag_list_rn;
- int voice_lut_rn;
-};
-
-struct ScriptDataBuf {
- ScriptDataWord *data;
- int length;
-};
#define SCRIPTFUNC_PARAMS ScriptThread *thread, int nArgs
@@ -246,20 +294,17 @@ public:
void CF_script_togglestep();
- int loadScript(int scriptNum);
- int freeScript();
- SCRIPT_BYTECODE *loadBytecode(byte *bytecode_p, size_t bytecode_len);
- VOICE_LUT *loadVoiceLUT(const byte *voicelut_p, size_t voicelut_len, ScriptData *script);
+ void loadModule(int scriptModuleNumber);
+ void freeModules();
bool isInitialized() const { return _initialized; }
bool isVoiceLUTPresent() const { return _voiceLUTPresent; }
- ScriptData *currentScript() { return _currentScript; }
- ScriptDataBuf *dataBuffer(int idx) { return &_dataBuf[idx]; }
+/* ScriptData *currentScript() { return _currentScript; }
int getWord(int bufNumber, int wordNumber, ScriptDataWord *data);
int putWord(int bufNumber, int wordNumber, ScriptDataWord data);
int setBit(int bufNumber, ScriptDataWord bitNumber, int bitState);
- int getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState);
- const char * getScriptString(int index) const { return _currentScript->strings.getString(index); }
+ int getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState); */
+// const char * getScriptString(int index) const { return _currentScript->strings.getString(index); }
void doVerb();
void showVerb(int statuscolor = -1);
@@ -288,17 +333,22 @@ public:
void scriptInfo();
void scriptExec(int argc, const char **argv);
-protected:
+private:
bool _initialized;
bool _voiceLUTPresent;
RSCFILE_CONTEXT *_scriptContext;
- SCRIPT_LUT_ENTRY *_scriptLUT;
- int _scriptLUTMax;
- uint16 _scriptLUTEntryLen;
- ScriptData *_currentScript;
- ScriptDataBuf _dataBuf[SCRIPT_DATABUF_NUM];
+
+ uint16 _modulesLUTEntryLen;
+ ModuleData *_modules;
+ int _modulesCount;
+
+ byte* _commonBuffer;
+ uint _commonBufferSize;
+ uint _staticSize;
+
ScriptThreadList _threadList;
+ ScriptThread *_conversingThread;
//verb
bool _firstObjectSet;
@@ -315,7 +365,6 @@ public:
int _pendingVerb;
uint16 _pointerObject;
-public:
bool _skipSpeeches;
bool _abortEnabled;
@@ -325,7 +374,7 @@ public:
TEXTLIST_ENTRY *_dbg_txtentry;
public:
- ScriptThread *createThread();
+ ScriptThread *createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber);
int executeThread(ScriptThread *thread, int entrypointNumber);
int executeThreads(uint msec);
int SThreadDebugStep();
@@ -336,20 +385,17 @@ public:
void wakeUpThreadsDelayed(int waitType, int sleepTime);
private:
- void setFramePtr(ScriptThread *thread, int newPtr);
- unsigned char *SThreadGetReadPtr(ScriptThread *thread);
- unsigned long SThreadGetReadOffset(const byte *read_p);
- size_t SThreadGetReadLen(ScriptThread *thread);
- void runThread(ScriptThread *thread, int instr_limit);
- void setThreadEntrypoint(ScriptThread *thread, int entrypointNumber);
+ void loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength);
+ void loadModuleVoiceLUT(ModuleData &module, const byte *resourcePointer, size_t resourceLength);
-private:
- ScriptThread *_conversingThread;
+ void runThread(ScriptThread *thread, uint instructionLimit);
+ void setThreadEntrypoint(ScriptThread *thread, int entrypointNumber);
public:
void finishDialog(int replyID, int flags, int bitOffset);
private:
+
typedef int (Script::*ScriptFunctionType)(SCRIPTFUNC_PARAMS);
struct ScriptFunctionDescription {
@@ -442,7 +488,7 @@ private:
int SF_playVoice(SCRIPTFUNC_PARAMS);
};
-inline int getSWord(ScriptDataWord word) {
+/*inline int getSWord(ScriptDataWord word) {
uint16 uInt = word;
int sInt;
@@ -458,7 +504,7 @@ inline int getSWord(ScriptDataWord word) {
inline uint getUWord(ScriptDataWord word) {
return (uint16) word;
}
-
+*/
} // End of namespace Saga
diff --git a/saga/sdebug.cpp b/saga/sdebug.cpp
index 9816e0bb7a..145597b920 100644
--- a/saga/sdebug.cpp
+++ b/saga/sdebug.cpp
@@ -65,12 +65,12 @@ int Script::SDebugPrintInstr(ScriptThread *thread) {
tl_e.string = disp_buf;
tl_e.display = 1;
- MemoryReadStream readS(currentScript()->bytecode->bytecode_p
- + thread->instructionOffset,
- currentScript()->bytecode->bytecode_len
- - thread->instructionOffset);
+ MemoryReadStream readS(thread->_moduleBase
+ + thread->_instructionOffset,
+ thread->_moduleBaseSize
+ - thread->_instructionOffset);
in_char = readS.readByte();
- sprintf(tmp_buf, "%04lX | %02X | ", thread->instructionOffset, in_char);
+ sprintf(tmp_buf, "%04lX | %02X | ", thread->_instructionOffset, in_char);
strncat(disp_buf, tmp_buf, SD_DISPLAY_LEN);
switch (in_char) {
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index 31cc2254b6..ed6f9e6ba3 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -133,17 +133,17 @@ void Script::setupScriptFuncList(void) {
// Script function #0 (0x00)
// Print a debugging message
int Script::SF_putString(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 stringIndex = thread->pop();
- _vm->_console->DebugPrintf(getScriptString(param));
+ _vm->_console->DebugPrintf(thread->_strings->getString(stringIndex));
return SUCCESS;
}
// Script function #1 (0x01) blocking
// Param1: time in ticks
int Script::sfWait(SCRIPTFUNC_PARAMS) {
- int time;
- time = getUWord(thread->pop());
+ int16 time;
+ time = thread->pop();
if (!_skipSpeeches) {
thread->waitDelay(ticksToMSec(time)); // put thread to sleep
@@ -176,7 +176,7 @@ int Script::SF_takeObject(SCRIPTFUNC_PARAMS) {
int Script::SF_objectIsCarried(SCRIPTFUNC_PARAMS) {
/*ScriptDataWord param =*/ thread->pop();
warning("Not implemented");
- thread->retVal = 0;
+ thread->_returnValue = 0;
/*
int index = param & 0x1FFF;
@@ -194,9 +194,9 @@ int Script::SF_objectIsCarried(SCRIPTFUNC_PARAMS) {
// Set the command display to the specified text string
// Param1: dialogue index of string
int Script::sfStatusBar(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 stringIndex = thread->pop();
- return _vm->_interface->setStatusText(getScriptString(param));
+ return _vm->_interface->setStatusText(thread->_strings->getString(stringIndex));
}
// Script function #5 (0x05)
@@ -215,13 +215,13 @@ int Script::SF_mainMode(SCRIPTFUNC_PARAMS) {
// Param2: actor x
// Param3: actor y
int Script::sfScriptWalkTo(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
Location actorLocation;
ActorData *actor;
- actorId = getSWord(thread->pop());
- actorLocation.x = getSWord(thread->pop());
- actorLocation.y = getSWord(thread->pop());
+ actorId = thread->pop();
+ actorLocation.x = thread->pop();
+ actorLocation.y = thread->pop();
actor = _vm->_actor->getActor(actorId);
actorLocation.z = actor->location.z;
@@ -236,14 +236,14 @@ int Script::sfScriptWalkTo(SCRIPTFUNC_PARAMS) {
// Script function #7 (0x07)
int Script::SF_doAction(SCRIPTFUNC_PARAMS) {
- ScriptDataWord actor_parm = thread->pop();
- ScriptDataWord action_parm = thread->pop();
- ScriptDataWord obj_parm = thread->pop();
- ScriptDataWord withobj_parm = thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
// The parameters correspond with the thread variables.
- debug(1, "stub: SF_doAction(%d, %d, %d, %d)", actor_parm, action_parm, obj_parm, withobj_parm);
+ //debug(1, "stub: SF_doAction(%d, %d, %d, %d)", actor_parm, action_parm, obj_parm, withobj_parm);
return SUCCESS;
}
@@ -251,12 +251,12 @@ int Script::SF_doAction(SCRIPTFUNC_PARAMS) {
// Param1: actor id
// Param2: actor orientation
int Script::sfSetActorFacing(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
int actorDirection;
ActorData *actor;
- actorId = getSWord(thread->pop());
- actorDirection = getSWord(thread->pop());
+ actorId = thread->pop();
+ actorDirection = thread->pop();
actor = _vm->_actor->getActor(actorId);
actor->facingDirection = actor->actionDirection = actorDirection;
@@ -267,8 +267,8 @@ int Script::sfSetActorFacing(SCRIPTFUNC_PARAMS) {
// Script function #9 (0x09)
int Script::sfStartBgdAnim(SCRIPTFUNC_PARAMS) {
- int animId = getSWord(thread->pop());
- int cycles = getSWord(thread->pop());
+ int16 animId = thread->pop();
+ int16 cycles = thread->pop();
_vm->_anim->setCycles(animId, cycles);
_vm->_anim->play(animId, kRepeatSpeed);
@@ -279,7 +279,7 @@ int Script::sfStartBgdAnim(SCRIPTFUNC_PARAMS) {
// Script function #10 (0x0A)
int Script::sfStopBgdAnim(SCRIPTFUNC_PARAMS) {
- ScriptDataWord animId = getSWord(thread->pop());
+ int16 animId = thread->pop();
_vm->_anim->stop(animId);
@@ -293,11 +293,11 @@ int Script::sfStopBgdAnim(SCRIPTFUNC_PARAMS) {
// reenabled.
// Param1: boolean
int Script::sfLockUser(SCRIPTFUNC_PARAMS) {
- ScriptDataWord b_param;
+ int16 lock;
- b_param = thread->pop();
+ lock = thread->pop();
- if (b_param) {
+ if (lock) {
_vm->_interface->deactivate();
} else {
_vm->_interface->activate();
@@ -338,8 +338,8 @@ int Script::sfFaceTowards(SCRIPTFUNC_PARAMS) {
int16 targetObject;
ActorData *actor;
- actorId = getSWord(thread->pop());
- targetObject = getSWord(thread->pop());
+ actorId = thread->pop();
+ targetObject = thread->pop();
actor = _vm->_actor->getActor(actorId);
actor->targetObject = targetObject;
@@ -356,8 +356,8 @@ int Script::sfSetFollower(SCRIPTFUNC_PARAMS) {
ActorData *actor;
- actorId = getSWord(thread->pop());
- targetObject = getSWord(thread->pop());
+ actorId = thread->pop();
+ targetObject = thread->pop();
debug(1, "sfSetFollower(%d, %d) [%d]", actorId, targetObject, _vm->_actor->actorIdToIndex(actorId));
@@ -429,8 +429,8 @@ static struct SceneSubstitutes {
// Script function #16 (0x10)
int Script::SF_gotoScene(SCRIPTFUNC_PARAMS) {
- int16 sceneNum = getSWord(thread->pop());
- int16 entrance = getSWord(thread->pop());
+ int16 sceneNum = thread->pop();
+ int16 entrance = thread->pop();
for (int i = 0; i < ARRAYSIZE(sceneSubstitutes); i++)
if (sceneSubstitutes[i].sceneId == sceneNum)
@@ -504,8 +504,8 @@ int Script::SF_getNumber(SCRIPTFUNC_PARAMS) {
// Script function #21 (0x15)
// Param1: door #
int Script::sfScriptOpenDoor(SCRIPTFUNC_PARAMS) {
- int doorNumber;
- doorNumber = getUWord(thread->pop());
+ int16 doorNumber;
+ doorNumber = thread->pop();
if (_vm->_scene->getFlags() & kSceneFlagISO) {
//todo: it
@@ -518,8 +518,8 @@ int Script::sfScriptOpenDoor(SCRIPTFUNC_PARAMS) {
// Script function #22 (0x16)
// Param1: door #
int Script::sfScriptCloseDoor(SCRIPTFUNC_PARAMS) {
- int doorNumber;
- doorNumber = getUWord(thread->pop());
+ int16 doorNumber;
+ doorNumber = thread->pop();
if (_vm->_scene->getFlags() & kSceneFlagISO) {
//todo: it
@@ -531,8 +531,8 @@ int Script::sfScriptCloseDoor(SCRIPTFUNC_PARAMS) {
// Script function #23 (0x17)
int Script::sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS) {
- int animId = getSWord(thread->pop());
- int speed = getSWord(thread->pop());
+ int16 animId = thread->pop();
+ int16 speed = thread->pop();
_vm->_anim->setFrameTime(animId, ticksToMSec(speed));
debug(1, "sfSetBgdAnimSpeed(%d, %d)", animId, speed);
@@ -552,8 +552,8 @@ int Script::SF_cycleColors(SCRIPTFUNC_PARAMS) {
// Script function #25 (0x19)
// Param1: actor id
int Script::sfDoCenterActor(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
- actorId = getSWord(thread->pop());
+ int16 actorId;
+ actorId = thread->pop();
_vm->_actor->_centerActor = _vm->_actor->getActor(actorId);
return SUCCESS;
@@ -562,9 +562,9 @@ int Script::sfDoCenterActor(SCRIPTFUNC_PARAMS) {
// Script function #26 (0x1A) nonblocking
// Starts the specified animation
int Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) {
- int animId = getSWord(thread->pop());
- int cycles = getSWord(thread->pop());
- int speed = getSWord(thread->pop());
+ int16 animId = thread->pop();
+ int16 cycles = thread->pop();
+ int16 speed = thread->pop();
_vm->_anim->setCycles(animId, cycles);
_vm->_anim->play(animId, ticksToMSec(speed));
@@ -578,13 +578,13 @@ int Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) {
// Param2: actor x
// Param3: actor y
int Script::sfScriptWalkToAsync(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
Location actorLocation;
ActorData *actor;
- actorId = getSWord(thread->pop());
- actorLocation.x = getSWord(thread->pop());
- actorLocation.y = getSWord(thread->pop());
+ actorId = thread->pop();
+ actorLocation.x = thread->pop();
+ actorLocation.y = thread->pop();
actor = _vm->_actor->getActor(actorId);
actorLocation.z = actor->location.z;
@@ -608,12 +608,12 @@ int Script::SF_enableZone(SCRIPTFUNC_PARAMS) {
// Param1: actor id
// Param2: current action
int Script::sfSetActorState(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
int currentAction;
ActorData *actor;
- actorId = getSWord(thread->pop());
- currentAction = getSWord(thread->pop());
+ actorId = thread->pop();
+ currentAction = thread->pop();
actor = _vm->_actor->getActor(actorId);
@@ -631,13 +631,13 @@ int Script::sfSetActorState(SCRIPTFUNC_PARAMS) {
// Param2: actor pos x
// Param3: actor pos y
int Script::scriptMoveTo(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
Location actorLocation;
ActorData *actor;
- actorId = getSWord(thread->pop());
- actorLocation.x = getSWord(thread->pop());
- actorLocation.y = getSWord(thread->pop());
+ actorId = thread->pop();
+ actorLocation.x = thread->pop();
+ actorLocation.y = thread->pop();
actor = _vm->_actor->getActor(actorId);
@@ -649,12 +649,12 @@ int Script::scriptMoveTo(SCRIPTFUNC_PARAMS) {
// Script function #31 (0x21)
int Script::SF_sceneEq(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 param = thread->pop();
if (_vm->_scene->getSceneLUT(param) == _vm->_scene->currentSceneNumber())
- thread->retVal = 1;
+ thread->_returnValue = 1;
else
- thread->retVal = 0;
+ thread->_returnValue = 0;
return SUCCESS;
}
@@ -687,7 +687,7 @@ int Script::SF_dropObject(SCRIPTFUNC_PARAMS) {
// Script function #33 (0x21)
int Script::sfFinishBgdAnim(SCRIPTFUNC_PARAMS) {
- ScriptDataWord animId = getSWord(thread->pop());
+ int16 animId = thread->pop();
_vm->_anim->finish(animId);
@@ -699,14 +699,14 @@ int Script::sfFinishBgdAnim(SCRIPTFUNC_PARAMS) {
// Param1: actor id 1
// Param2: actor id 2
int Script::sfSwapActors(SCRIPTFUNC_PARAMS) {
- uint16 actorId1;
- uint16 actorId2;
+ int16 actorId1;
+ int16 actorId2;
ActorData *actor1;
ActorData *actor2;
Location location;
- actorId1 = getSWord(thread->pop());
- actorId2 = getSWord(thread->pop());
+ actorId1 = thread->pop();
+ actorId2 = thread->pop();
actor1 = _vm->_actor->getActor(actorId1);
actor2 = _vm->_actor->getActor(actorId2);
@@ -738,22 +738,22 @@ int Script::sfSwapActors(SCRIPTFUNC_PARAMS) {
///....
// Param3: actor idN
int Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) {
- ScriptDataWord stringId;
- int actorsCount;
+ int16 stringId;
+ int16 actorsCount;
int i;
uint16 actorsIds[ACTOR_SPEECH_ACTORS_MAX];
const char *string;
stringId = thread->pop();
- actorsCount = getSWord(thread->pop());
+ actorsCount = thread->pop();
if (actorsCount > ACTOR_SPEECH_ACTORS_MAX)
error("sfSimulSpeech actorsCount=0x%X exceed ACTOR_SPEECH_ACTORS_MAX", actorsCount);
for (i = 0; i < actorsCount; i++)
- actorsIds[i] = getSWord(thread->pop());
+ actorsIds[i] = thread->pop();
- string = getScriptString(stringId);
+ string = thread->_strings->getString(stringId);
_vm->_actor->simulSpeech(string, actorsIds, actorsCount, 0);
return SUCCESS;
@@ -765,15 +765,15 @@ int Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) {
// Param3: actor y
// Param4: actor walk flag
int Script::sfScriptWalk(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
Location actorLocation;
ActorData *actor;
uint16 walkFlags;
- actorId = getSWord(thread->pop());
- actorLocation.x = getSWord(thread->pop());
- actorLocation.y = getSWord(thread->pop());
- walkFlags = getUWord(thread->pop());
+ actorId = thread->pop();
+ actorLocation.x = thread->pop();
+ actorLocation.y = thread->pop();
+ walkFlags = thread->pop();
actor = _vm->_actor->getActor(actorId);
actorLocation.z = actor->location.z;
@@ -800,16 +800,16 @@ int Script::sfScriptWalk(SCRIPTFUNC_PARAMS) {
// Param3: cycle frame number
// Param4: cycle delay
int Script::sfCycleFrames(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
int flags;
int cycleFrameSequence;
int cycleDelay;
ActorData *actor;
- actorId = getSWord(thread->pop());
- flags = getUWord(thread->pop());
- cycleFrameSequence = getUWord(thread->pop());
- cycleDelay = getUWord(thread->pop());
+ actorId = thread->pop();
+ flags = thread->pop();
+ cycleFrameSequence = thread->pop();
+ cycleDelay = thread->pop();
actor = _vm->_actor->getActor(actorId);
@@ -844,15 +844,15 @@ int Script::sfCycleFrames(SCRIPTFUNC_PARAMS) {
// Param2: frame type
// Param3: frame offset
int Script::sfSetFrame(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
int frameType;
int frameOffset;
ActorData *actor;
ActorFrameRange *frameRange;
- actorId = getSWord(thread->pop());
- frameType = getSWord(thread->pop());
- frameOffset = getSWord(thread->pop());
+ actorId = thread->pop();
+ frameType = thread->pop();
+ frameOffset = thread->pop();
actor = _vm->_actor->getActor(actorId);
@@ -875,7 +875,7 @@ int Script::sfSetFrame(SCRIPTFUNC_PARAMS) {
// Script function #39 (0x27)
// Sets the right-hand portrait
int Script::sfSetPortrait(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 param = thread->pop();
return _vm->_interface->setRightPortrait(param);
}
@@ -883,7 +883,7 @@ int Script::sfSetPortrait(SCRIPTFUNC_PARAMS) {
// Script function #40 (0x28)
// Sets the left-hand portrait
int Script::sfSetProtagPortrait(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 param = thread->pop();
return _vm->_interface->setLeftPortrait(param);
}
@@ -896,10 +896,10 @@ int Script::sfSetProtagPortrait(SCRIPTFUNC_PARAMS) {
// Param3: animation id link target
// Param4: animation id link source
int Script::sfChainBgdAnim(SCRIPTFUNC_PARAMS) {
- int animId1 = getSWord(thread->pop());
- int animId = getSWord(thread->pop());
- int cycles = getSWord(thread->pop());
- int speed = getSWord(thread->pop());
+ int16 animId1 = thread->pop();
+ int16 animId = thread->pop();
+ int16 cycles = thread->pop();
+ int16 speed = thread->pop();
if (speed >= 0) {
_vm->_anim->setCycles(animId, cycles);
@@ -914,12 +914,12 @@ int Script::sfChainBgdAnim(SCRIPTFUNC_PARAMS) {
// Script function #42 (0x2A)
int Script::SF_scriptSpecialWalk(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param1 = thread->pop();
- ScriptDataWord param2 = thread->pop();
- ScriptDataWord param3 = thread->pop();
- ScriptDataWord param4 = thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
- debug(1, "stub: SF_scriptSpecialWalk(%d, %d, %d, %d)", param1, param2, param3, param4);
+ //debug(1, "stub: SF_scriptSpecialWalk(%d, %d, %d, %d)", param1, param2, param3, param4);
return SUCCESS;
}
@@ -931,7 +931,7 @@ int Script::SF_scriptSpecialWalk(SCRIPTFUNC_PARAMS) {
// Param5: actor action
// Param6: actor frame number
int Script::sfPlaceActor(SCRIPTFUNC_PARAMS) {
- uint16 actorId;
+ int16 actorId;
Location actorLocation;
int actorDirection;
int frameType;
@@ -939,12 +939,12 @@ int Script::sfPlaceActor(SCRIPTFUNC_PARAMS) {
ActorData *actor;
ActorFrameRange *frameRange;
- actorId = getSWord(thread->pop());
- actorLocation.x = getSWord(thread->pop());
- actorLocation.y = getSWord(thread->pop());
- actorDirection = getSWord(thread->pop());
- frameType = getSWord(thread->pop());
- frameOffset = getSWord(thread->pop());
+ actorId = thread->pop();
+ actorLocation.x = thread->pop();
+ actorLocation.y = thread->pop();
+ actorDirection = thread->pop();
+ frameType = thread->pop();
+ frameOffset = thread->pop();
debug(1, "sfPlaceActor(%d, %d, %d, %d, %d, %d)", actorId, actorLocation.x,
actorLocation.y, actorDirection, frameType, frameOffset);
@@ -981,32 +981,32 @@ int Script::sfPlaceActor(SCRIPTFUNC_PARAMS) {
// game cinematic. Pushes a zero or positive value if the game
// has not been interrupted.
int Script::SF_checkUserInterrupt(SCRIPTFUNC_PARAMS) {
- thread->retVal = (_skipSpeeches == true);
+ thread->_returnValue = (_skipSpeeches == true);
return SUCCESS;
}
// Script function #45 (0x2D)
int Script::SF_walkRelative(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param1 = thread->pop();
- ScriptDataWord param2 = thread->pop();
- ScriptDataWord param3 = thread->pop();
- ScriptDataWord param4 = thread->pop();
- ScriptDataWord param5 = thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
- debug(1, "stub: SF_walkRelative(%d, %d, %d, %d, %d)", param1, param2, param3, param4, param5);
+ //debug(1, "stub: SF_walkRelative(%d, %d, %d, %d, %d)", param1, param2, param3, param4, param5);
return SUCCESS;
}
// Script function #46 (0x2E)
int Script::SF_moveRelative(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param1 = thread->pop();
- ScriptDataWord param2 = thread->pop();
- ScriptDataWord param3 = thread->pop();
- ScriptDataWord param4 = thread->pop();
- ScriptDataWord param5 = thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
- debug(1, "stub: SF_moveRelative(%d, %d, %d, %d, %d)", param1, param2, param3, param4, param5);
+ //debug(1, "stub: SF_moveRelative(%d, %d, %d, %d, %d)", param1, param2, param3, param4, param5);
return SUCCESS;
}
@@ -1097,7 +1097,7 @@ int Script::sfPlacard(SCRIPTFUNC_PARAMS) {
text_entry.text_y = (_vm->getSceneHeight() - _vm->_font->getHeight(MEDIUM_FONT_ID)) / 2;
text_entry.font_id = MEDIUM_FONT_ID;
text_entry.flags = FONT_OUTLINE | FONT_CENTERED;
- text_entry.string = getScriptString(stringId);
+ text_entry.string = thread->_strings->getString(stringId);
placardTextEntry = _vm->textAddEntry(scene_info.text_list, &text_entry);
@@ -1203,8 +1203,8 @@ int Script::SF_setProtagState(SCRIPTFUNC_PARAMS) {
// Script function #51 (0x33)
int Script::sfResumeBgdAnim(SCRIPTFUNC_PARAMS) {
- int animId = getSWord(thread->pop());
- int cycles = getSWord(thread->pop());
+ int16 animId = thread->pop();
+ int16 cycles = thread->pop();
_vm->_anim->resume(animId, cycles);
debug(1, "sfResumeBgdAnimSpeed(%d, %d)", animId, cycles);
@@ -1214,20 +1214,20 @@ int Script::sfResumeBgdAnim(SCRIPTFUNC_PARAMS) {
// Script function #52 (0x34)
int Script::SF_throwActor(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param1 = thread->pop();
- ScriptDataWord param2 = thread->pop();
- ScriptDataWord param3 = thread->pop();
- ScriptDataWord param4 = thread->pop();
- ScriptDataWord param5 = thread->pop();
- ScriptDataWord param6 = thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
- debug(1, "stub: SF_throwActor(%d, %d, %d, %d, %d, %d)", param1, param2, param3, param4, param5, param6);
+ //debug(1, "stub: SF_throwActor(%d, %d, %d, %d, %d, %d)", param1, param2, param3, param4, param5, param6);
return SUCCESS;
}
// Script function #53 (0x35)
int Script::SF_waitWalk(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 param = thread->pop();
debug(1, "stub: SF_waitWalk(%d)", param);
return SUCCESS;
@@ -1235,27 +1235,27 @@ int Script::SF_waitWalk(SCRIPTFUNC_PARAMS) {
// Script function #54 (0x36)
int Script::SF_sceneID(SCRIPTFUNC_PARAMS) {
- thread->retVal = _vm->_scene->currentSceneNumber();
+ thread->_returnValue = _vm->_scene->currentSceneNumber();
return SUCCESS;
}
// Script function #55 (0x37)
int Script::SF_changeActorScene(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param1 = thread->pop();
- ScriptDataWord param2 = thread->pop();
+ thread->pop();
+ thread->pop();
- debug(1, "stub: SF_changeActorScene(%d, %d)", param1, param2);
+ //debug(1, "stub: SF_changeActorScene(%d, %d)", param1, param2);
return SUCCESS;
}
// Script function #56 (0x38)
int Script::SF_climb(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param1 = thread->pop();
- ScriptDataWord param2 = thread->pop();
- ScriptDataWord param3 = thread->pop();
- ScriptDataWord param4 = thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
+ thread->pop();
- debug(1, "stub: SF_climb(%d, %d, %d, %d)", param1, param2, param3, param4);
+ //debug(1, "stub: SF_climb(%d, %d, %d, %d)", param1, param2, param3, param4);
return SUCCESS;
}
@@ -1263,10 +1263,10 @@ int Script::SF_climb(SCRIPTFUNC_PARAMS) {
// Param1: door #
// Param2: door state
int Script::sfSetDoorState(SCRIPTFUNC_PARAMS) {
- int doorNumber;
- int doorState;
- doorNumber = getUWord(thread->pop());
- doorState = getUWord(thread->pop());
+ int16 doorNumber;
+ int16 doorState;
+ doorNumber = thread->pop();
+ doorState = thread->pop();
if (_vm->_scene->getFlags() & kSceneFlagISO) {
//todo: it
@@ -1278,10 +1278,10 @@ int Script::sfSetDoorState(SCRIPTFUNC_PARAMS) {
// Script function #58 (0x3A)
int Script::SF_setActorZ(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param1 = thread->pop();
- ScriptDataWord param2 = thread->pop();
+ thread->pop();
+ thread->pop();
- debug(1, "stub: SF_setActorZ(%d, %d)", param1, param2);
+ //debug(1, "stub: SF_setActorZ(%d, %d)", param1, param2);
return SUCCESS;
}
@@ -1296,7 +1296,7 @@ int Script::SF_text(SCRIPTFUNC_PARAMS) {
// Script function #60 (0x3C)
int Script::SF_getActorX(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 param = thread->pop();
debug(1, "stub: SF_getActorX(%d)", param);
return SUCCESS;
@@ -1304,7 +1304,7 @@ int Script::SF_getActorX(SCRIPTFUNC_PARAMS) {
// Script function #61 (0x3D)
int Script::SF_getActorY(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 param = thread->pop();
debug(1, "stub: SF_getActorY(%d)", param);
return SUCCESS;
@@ -1322,15 +1322,15 @@ int Script::SF_eraseDelta(SCRIPTFUNC_PARAMS) {
// Script function #63 (0x3F)
int Script::sfPlayMusic(SCRIPTFUNC_PARAMS) {
if (_vm->getGameType() == GType_ITE) {
- ScriptDataWord param = thread->pop() + 9;
+ int16 param = thread->pop() + 9;
if (param >= 9 && param <= 34)
_vm->_music->play(param);
else
_vm->_music->stop();
} else {
- ScriptDataWord param1 = thread->pop();
- ScriptDataWord param2 = thread->pop();
+ int16 param1 = thread->pop();
+ int16 param2 = thread->pop();
debug(1, "Stub: sfPlayMusic(%d, %d)", param1, param2);
}
@@ -1468,7 +1468,7 @@ static struct {
// Script function #70 (0x46)
int Script::sfPlaySound(SCRIPTFUNC_PARAMS) {
- int param = getSWord(thread->pop());
+ int16 param = thread->pop();
int res;
if (param < ARRAYSIZE(sfxTable)) {
@@ -1522,9 +1522,9 @@ int Script::SF_protectResult(SCRIPTFUNC_PARAMS) {
// Script function #75 (0x4d)
int Script::sfRand(SCRIPTFUNC_PARAMS) {
- ScriptDataWord param = thread->pop();
+ int16 param = thread->pop();
- thread->retVal = (_vm->_rnd.getRandomNumber(param));
+ thread->_returnValue = (_vm->_rnd.getRandomNumber(param));
return SUCCESS;
}
@@ -1548,7 +1548,7 @@ void Script::finishDialog(int replyID, int flags, int bitOffset) {
if (_conversingThread) {
_vm->_interface->setMode(kPanelNull);
- _conversingThread->flags &= ~kTFlagWaiting;
+ _conversingThread->_flags &= ~kTFlagWaiting;
_conversingThread->push(replyID);
diff --git a/saga/sprite.cpp b/saga/sprite.cpp
index 36d2f0f9b4..906565102f 100644
--- a/saga/sprite.cpp
+++ b/saga/sprite.cpp
@@ -99,7 +99,7 @@ int Sprite::loadList(int resourceId, SpriteList &spriteList) {
spriteList.infoList = (SpriteInfo *)realloc(spriteList.infoList, newSpriteCount * sizeof(*spriteList.infoList));
if (spriteList.infoList == NULL) {
- error("Sprite::loadList Not enough memory");
+ memoryError("Sprite::loadList");
}
spriteList.spriteCount = newSpriteCount;
@@ -138,7 +138,7 @@ int Sprite::loadList(int resourceId, SpriteList &spriteList) {
decodeRLEBuffer(spriteDataPointer, 64000, outputLength); //todo: 64000 - should be replace by real input length
spriteInfo->decodedBuffer = (byte *) malloc(outputLength);
if (spriteInfo->decodedBuffer == NULL) {
- error("Sprite::loadList Not enough memory");
+ memoryError("Sprite::loadList");
}
memcpy(spriteInfo->decodedBuffer, _decodeBuf, outputLength);
}
diff --git a/saga/sthread.cpp b/saga/sthread.cpp
index 06742837c7..e19bc198da 100644
--- a/saga/sthread.cpp
+++ b/saga/sthread.cpp
@@ -37,29 +37,28 @@
namespace Saga {
-void Script::setFramePtr(ScriptThread *thread, int newPtr) {
- thread->framePtr = newPtr;
- dataBuffer(3)->length = ARRAYSIZE(thread->stackBuf) - thread->framePtr;
- dataBuffer(3)->data = (ScriptDataWord *) &(thread->stackBuf[newPtr]);
-}
-
-ScriptThread *Script::createThread() {
+ScriptThread *Script::createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber) {
ScriptThread *newThread;
- if (!isInitialized()) {
- return NULL;
+ loadModule(scriptModuleNumber);
+ if (_modules[scriptModuleNumber].entryPointsCount <= scriptEntryPointNumber) {
+ error("Script::createThread wrong scriptEntryPointNumber");
}
-
+
newThread = _threadList.pushFront().operator->();
+ newThread->_flags = kTFlagNone;
+ newThread->_stackSize = DEFAULT_THREAD_STACK_SIZE;
+ newThread->_stackBuf = (uint16 *)malloc(newThread->_stackSize * sizeof(*newThread->_stackBuf));
+ newThread->_stackTopIndex = newThread->_stackSize - 1; // or 2 - as in original
+ newThread->_instructionOffset = _modules[scriptModuleNumber].entryPoints[scriptEntryPointNumber].offset;
+ newThread->_commonBase = _commonBuffer;
+ newThread->_staticBase = _commonBuffer + _modules[scriptModuleNumber].staticOffset;
+ newThread->_moduleBase = _modules[scriptModuleNumber].moduleBase;
+ newThread->_moduleBaseSize = _modules[scriptModuleNumber].moduleBaseSize;
+
+ newThread->_strings = &_modules[scriptModuleNumber].strings;
+ newThread->_voiceLUT = &_modules[scriptModuleNumber].voiceLUT;
- newThread->stackPtr = ARRAYSIZE(newThread->stackBuf) - 1;
- setFramePtr(newThread, newThread->stackPtr);
-
- newThread->flags = kTFlagWaiting;
- newThread->waitType = kWaitTypePause;
-
- dataBuffer(4)->length = ARRAYSIZE(newThread->threadVars);
- dataBuffer(4)->data = newThread->threadVars;
return newThread;
}
@@ -69,8 +68,8 @@ void Script::wakeUpActorThread(int waitType, void *threadObj) {
for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) {
thread = threadIterator.operator->();
- if ((thread->flags & kTFlagWaiting) && (thread->waitType == waitType) && (thread->threadObj == threadObj)) {
- thread->flags &= ~kTFlagWaiting;
+ if ((thread->_flags & kTFlagWaiting) && (thread->_waitType == waitType) && (thread->_threadObj == threadObj)) {
+ thread->_flags &= ~kTFlagWaiting;
}
}
}
@@ -81,8 +80,8 @@ void Script::wakeUpThreads(int waitType) {
for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) {
thread = threadIterator.operator->();
- if ((thread->flags & kTFlagWaiting) && (thread->waitType == waitType)) {
- thread->flags &= ~kTFlagWaiting;
+ if ((thread->_flags & kTFlagWaiting) && (thread->_waitType == waitType)) {
+ thread->_flags &= ~kTFlagWaiting;
}
}
}
@@ -93,9 +92,9 @@ void Script::wakeUpThreadsDelayed(int waitType, int sleepTime) {
for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) {
thread = threadIterator.operator->();
- if ((thread->flags & kTFlagWaiting) && (thread->waitType == waitType)) {
- thread->waitType = kWaitTypeDelay;
- thread->sleepTime = sleepTime;
+ if ((thread->_flags & kTFlagWaiting) && (thread->_waitType == waitType)) {
+ thread->_waitType = kWaitTypeDelay;
+ thread->_sleepTime = sleepTime;
}
}
}
@@ -113,37 +112,37 @@ int Script::executeThreads(uint msec) {
while (threadIterator != _threadList.end()) {
thread = threadIterator.operator->();
- if (thread->flags & (kTFlagFinished | kTFlagAborted)) {
- if (thread->flags & kTFlagFinished)
+ if (thread->_flags & (kTFlagFinished | kTFlagAborted)) {
+ if (thread->_flags & kTFlagFinished)
setPointerVerb();
threadIterator = _threadList.erase(threadIterator);
continue;
}
- if (thread->flags & kTFlagWaiting) {
+ if (thread->_flags & kTFlagWaiting) {
- if (thread->waitType == kWaitTypeDelay) {
- if (thread->sleepTime < msec) {
- thread->sleepTime = 0;
+ if (thread->_waitType == kWaitTypeDelay) {
+ if (thread->_sleepTime < msec) {
+ thread->_sleepTime = 0;
} else {
- thread->sleepTime -= msec;
+ thread->_sleepTime -= msec;
}
- if (thread->sleepTime == 0)
- thread->flags &= ~kTFlagWaiting;
+ if (thread->_sleepTime == 0)
+ thread->_flags &= ~kTFlagWaiting;
} else {
- if (thread->waitType == kWaitTypeWalk) {
+ if (thread->_waitType == kWaitTypeWalk) {
ActorData *actor;
- actor = (ActorData *)thread->threadObj;
+ actor = (ActorData *)thread->_threadObj;
if (actor->currentAction == kActionWait) {
- thread->flags &= ~kTFlagWaiting;
+ thread->_flags &= ~kTFlagWaiting;
}
}
}
}
- if (!(thread->flags & kTFlagWaiting))
+ if (!(thread->_flags & kTFlagWaiting))
runThread(thread, STHREAD_TIMESLICE);
++threadIterator;
@@ -157,55 +156,6 @@ void Script::completeThread(void) {
executeThreads(0);
}
-void Script::setThreadEntrypoint(ScriptThread *thread, int entrypointNumber) {
- SCRIPT_BYTECODE *bytecode;
- int max_entrypoint;
-
- assert(isInitialized());
-
- bytecode = currentScript()->bytecode;
- max_entrypoint = bytecode->n_entrypoints;
-
- if ((entrypointNumber < 0) || (entrypointNumber >= max_entrypoint)) {
- error("Script::setThreadEntrypoint wrong entrypointNumber");
- }
-
- thread->entrypointNumber = entrypointNumber;
- thread->entrypointOffset = bytecode->entrypoints[entrypointNumber].offset;
-}
-
-int Script::executeThread(ScriptThread *thread, int entrypointNumber) {
- assert(isInitialized());
-
- if ((currentScript() == NULL) || (!currentScript()->loaded)) {
- return FAILURE;
- }
-
- setThreadEntrypoint(thread, entrypointNumber);
-
- thread->instructionOffset = thread->entrypointOffset;
- thread->flags = kTFlagNone;
-
- return SUCCESS;
-}
-
-
-
-unsigned char *Script::SThreadGetReadPtr(ScriptThread *thread) {
- return currentScript()->bytecode->bytecode_p + thread->instructionOffset;
-}
-
-unsigned long Script::SThreadGetReadOffset(const byte *read_p) {
- return (unsigned long)(read_p - (unsigned char *)currentScript()->bytecode->bytecode_p);
-}
-
-size_t Script::SThreadGetReadLen(ScriptThread *thread) {
- return currentScript()->bytecode->bytecode_len - thread->instructionOffset;
-}
-
-
-
-
int Script::SThreadDebugStep() {
if (_dbg_singlestep) {
_dbg_dostep = 1;
@@ -214,20 +164,20 @@ int Script::SThreadDebugStep() {
return SUCCESS;
}
-void Script::runThread(ScriptThread *thread, int instr_limit) {
- int instr_count;
+void Script::runThread(ScriptThread *thread, uint instructionLimit) {
+ uint instructionCount;
uint32 saved_offset;
- ScriptDataWord param1;
- ScriptDataWord param2;
+ uint16 param1;
+ uint16 param2;
long iparam1;
long iparam2;
long iresult;
- ScriptDataWord data;
- ScriptDataWord scriptRetVal = 0;
+ uint16 data;
+ uint16 scriptRetVal = 0;
int debug_print = 0;
int n_buf;
- int bitstate;
+// int bitstate;
int operandChar;
int i;
int unhandled = 0;
@@ -236,36 +186,33 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
if ((thread == _dbg_thread) && _dbg_singlestep) {
if (_dbg_dostep) {
debug_print = 1;
- thread->sleepTime = 0;
- instr_limit = 1;
+ thread->_sleepTime = 0;
+ instructionLimit = 1;
_dbg_dostep = 0;
} else {
return;
}
}
- MemoryReadStream/*Endian*/ scriptS(currentScript()->bytecode->bytecode_p, currentScript()->bytecode->bytecode_len/*, IS_BIG_ENDIAN*/);
+ MemoryReadStream scriptS(thread->_moduleBase, thread->_moduleBaseSize);
- dataBuffer(2)->length = currentScript()->bytecode->bytecode_len / sizeof(ScriptDataWord);
- dataBuffer(2)->data = (ScriptDataWord *) currentScript()->bytecode->bytecode_p;
+ scriptS.seek(thread->_instructionOffset);
- scriptS.seek(thread->instructionOffset);
-
- for (instr_count = 0; instr_count < instr_limit; instr_count++) {
- if (thread->flags & (kTFlagAsleep))
+ for (instructionCount = 0; instructionCount < instructionLimit; instructionCount++) {
+ if (thread->_flags & (kTFlagAsleep))
break;
- saved_offset = thread->instructionOffset;
+ saved_offset = thread->_instructionOffset;
operandChar = scriptS.readByte();
// debug print (opCode name etc) should be placed here
// SDebugPrintInstr(thread)
- debug(8, "Executing thread offset: %lu (%x) stack: %d", thread->instructionOffset, operandChar, thread->stackSize());
+ debug(8, "Executing thread offset: %lu (%x) stack: %d", thread->_instructionOffset, operandChar, thread->pushedSize());
switch (operandChar) {
case 0x01: // nextblock
// Some sort of "jump to the start of the next memory
// page" instruction, I think.
- thread->instructionOffset = 1024 * ((thread->instructionOffset / 1024) + 1);
+ thread->_instructionOffset = 1024 * ((thread->_instructionOffset / 1024) + 1);
break;
// STACK INSTRUCTIONS
@@ -284,7 +231,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
break;
case 0x06: // Push word (PUSH)
case 0x08: // Push word (PSHD) (dialogue string index)
- param1 = (ScriptDataWord)scriptS.readUint16LE();
+ param1 = scriptS.readUint16LE();
thread->push(param1);
break;
@@ -292,47 +239,47 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
case 0x0B: // Test flag (TSTF)
n_buf = scriptS.readByte();
- param1 = (ScriptDataWord)scriptS.readUint16LE();
- getBit(n_buf, param1, &bitstate);
- thread->push(bitstate);
+ param1 = scriptS.readUint16LE();
+ //getBit(n_buf, param1, &bitstate);
+// thread->push(bitstate);
break;
case 0x0C: // Get word (GETW)
n_buf = scriptS.readByte();
param1 = scriptS.readUint16LE();
- getWord(n_buf, param1, &data);
- thread->push(data);
+ //getWord(n_buf, param1, &data);
+// thread->push(data);
break;
case 0x0F: // Modify flag (MODF)
n_buf = scriptS.readByte();
- param1 = (ScriptDataWord)scriptS.readUint16LE();
+ param1 = scriptS.readUint16LE();
data = thread->stackTop();
- if (data) {
+/* if (data) {
setBit(n_buf, param1, 1);
} else {
setBit(n_buf, param1, 0);
- }
+ }*/
break;
case 0x10: // Put word (PUTW)
n_buf = scriptS.readByte();
- param1 = (ScriptDataWord)scriptS.readUint16LE();
+ param1 = scriptS.readUint16LE();
data = thread->stackTop();
- putWord(n_buf, param1, data);
+// putWord(n_buf, param1, data);
break;
case 0x13: // Modify flag and pop (MDFP)
n_buf = scriptS.readByte();
- param1 = (ScriptDataWord)scriptS.readUint16LE();
+ param1 = scriptS.readUint16LE();
data = thread->pop();
- if (data) {
+/* if (data) {
setBit(n_buf, param1, 1);
} else {
setBit(n_buf, param1, 0);
- }
+ }*/
break;
case 0x14: // Put word and pop (PTWP)
n_buf = scriptS.readByte();
- param1 = (ScriptDataWord)scriptS.readUint16LE();
+ param1 = scriptS.readUint16LE();
data = thread->stackTop();
- putWord(n_buf, param1, data);
+// putWord(n_buf, param1, data);
break;
// CONTROL INSTRUCTIONS
@@ -346,14 +293,14 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
temp = scriptS.readByte();
if (temp != 2)
error("Calling dynamically generated script? Wow");
- param1 = (ScriptDataWord)scriptS.readUint16LE();
+ param1 = scriptS.readUint16LE();
data = scriptS.pos();
thread->push(n_args);
// NOTE: The original pushes the program
// counter as a pointer here. But I don't think
// we will have to do that.
thread->push(data);
- thread->instructionOffset = (unsigned long)param1;
+ thread->_instructionOffset = param1;
}
break;
case opCcall: // Call function
@@ -374,39 +321,38 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
scriptFunction = _scriptFunctionsList[functionNumber].scriptFunction;
scriptFunctionReturnValue = (this->*scriptFunction)(thread, argumentsCount);
if (scriptFunctionReturnValue != SUCCESS) {
- _vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->instructionOffset, scriptFunctionReturnValue);
+ _vm->_console->DebugPrintf(S_WARN_PREFIX "%X: Script function %d failed.\n", thread->_instructionOffset, scriptFunctionReturnValue);
}
if (functionNumber == 16) { // SF_gotoScene
- instr_count = instr_limit; // break the loop
+ instructionCount = instructionLimit; // break the loop
break;
}
if (operandChar == opCcall) // CALL function
- thread->push(thread->retVal);
+ thread->push(thread->_returnValue);
- if (thread->flags & kTFlagAsleep)
- instr_count = instr_limit; // break out of loop!
+ if (thread->_flags & kTFlagAsleep)
+ instructionCount = instructionLimit; // break out of loop!
}
break;
case opEnter: // Enter a function
- thread->push(thread->framePtr);
- setFramePtr(thread, thread->stackPtr);
- param1 = scriptS.readUint16LE();
- thread->stackPtr -= (param1 / 2);
+ thread->push(thread->_frameIndex);
+ thread->_frameIndex = thread->_stackTopIndex;
+ thread->_stackTopIndex -= (scriptS.readUint16LE() / 2);
break;
case opReturn: // Return with value
scriptRetVal = thread->pop();
// Fall through
case opReturnV: // Return with void
- thread->stackPtr = thread->framePtr;
- setFramePtr(thread, thread->pop());
- if (thread->stackSize() == 0) {
+ thread->_stackTopIndex = thread->_frameIndex;
+ thread->_frameIndex = thread->pop();
+ if (thread->pushedSize() == 0) {
_vm->_console->DebugPrintf("Script execution complete.\n");
- thread->flags |= kTFlagFinished;
+ thread->_flags |= kTFlagFinished;
return;
} else {
- thread->instructionOffset = thread->pop();
+ thread->_instructionOffset = thread->pop();
/* int n_args = */ thread->pop();
if (operandChar == opReturn)
thread->push(scriptRetVal);
@@ -418,14 +364,14 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
// (JMP): Unconditional jump
case 0x1D:
param1 = scriptS.readUint16LE();
- thread->instructionOffset = (unsigned long)param1;
+ thread->_instructionOffset = (unsigned long)param1;
break;
// (JNZP): Jump if nonzero + POP
case 0x1E:
param1 = scriptS.readUint16LE();
data = thread->pop();
if (data) {
- thread->instructionOffset = (unsigned long)param1;
+ thread->_instructionOffset = (unsigned long)param1;
}
break;
// (JZP): Jump if zero + POP
@@ -433,7 +379,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
param1 = scriptS.readUint16LE();
data = thread->pop();
if (!data) {
- thread->instructionOffset = (unsigned long)param1;
+ thread->_instructionOffset = (unsigned long)param1;
}
break;
// (JNZ): Jump if nonzero
@@ -441,7 +387,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
param1 = scriptS.readUint16LE();
data = thread->stackTop();
if (data) {
- thread->instructionOffset = (unsigned long)param1;
+ thread->_instructionOffset = (unsigned long)param1;
}
break;
// (JZ): Jump if zero
@@ -449,14 +395,14 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
param1 = scriptS.readUint16LE();
data = thread->stackTop();
if (!data) {
- thread->instructionOffset = (unsigned long)param1;
+ thread->_instructionOffset = (unsigned long)param1;
}
break;
// (SWCH): Switch
case 0x22:
{
int n_switch;
- unsigned int switch_num;
+ uint16 switch_num;
unsigned int switch_jmp;
unsigned int default_jmp;
int case_found = 0;
@@ -468,8 +414,8 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
switch_num = scriptS.readUint16LE();
switch_jmp = scriptS.readUint16LE();
// Found the specified case
- if (data == (ScriptDataWord) switch_num) {
- thread->instructionOffset = switch_jmp;
+ if (data == switch_num) {
+ thread->_instructionOffset = switch_jmp;
case_found = 1;
break;
}
@@ -478,7 +424,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
// Jump to default case
if (!case_found) {
default_jmp = scriptS.readUint16LE();
- thread->instructionOffset = default_jmp;
+ thread->_instructionOffset = default_jmp;
}
}
break;
@@ -496,7 +442,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
uint16 offset = scriptS.readUint16LE();
if (branch_probability > probability) {
- thread->instructionOffset = offset;
+ thread->_instructionOffset = offset;
break;
}
@@ -525,28 +471,28 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
case 0x28: // inc_v increment, don't push
n_buf = scriptS.readByte();
param1 = scriptS.readUint16LE();
- getWord(n_buf, param1, &data);
- putWord(n_buf, param1, data + 1);
+ //getWord(n_buf, param1, &data);
+ //putWord(n_buf, param1, data + 1);
break;
case 0x29: // dec_v decrement, don't push
n_buf = scriptS.readByte();
param1 = scriptS.readUint16LE();
- getWord(n_buf, param1, &data);
- putWord(n_buf, param1, data - 1);
+ //getWord(n_buf, param1, &data);
+ //putWord(n_buf, param1, data - 1);
break;
case 0x2A: // postinc
n_buf = scriptS.readByte();
param1 = scriptS.readUint16LE();
- getWord(n_buf, param1, &data);
- thread->push(data);
- putWord(n_buf, param1, data + 1);
+ //getWord(n_buf, param1, &data);
+// thread->push(data);
+ //putWord(n_buf, param1, data + 1);
break;
case 0x2B: // postdec
n_buf = scriptS.readByte();
param1 = scriptS.readUint16LE();
- getWord(n_buf, param1, &data);
- thread->push(data);
- putWord(n_buf, param1, data - 1);
+ //getWord(n_buf, param1, &data);
+// thread->push(data);
+ //putWord(n_buf, param1, data - 1);
break;
// ARITHMETIC INSTRUCTIONS
@@ -558,7 +504,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 + iparam2;
- thread->push((ScriptDataWord) iresult);
+ thread->push( iresult);
break;
// (SUB): Subtraction
case 0x2D:
@@ -567,7 +513,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 - iparam2;
- thread->push((ScriptDataWord) iresult);
+ thread->push( iresult);
break;
// (MULT): Integer multiplication
case 0x2E:
@@ -576,7 +522,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 * iparam2;
- thread->push((ScriptDataWord) iresult);
+ thread->push( iresult);
break;
// (DIV): Integer division
case 0x2F:
@@ -585,7 +531,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 / iparam2;
- thread->push((ScriptDataWord) iresult);
+ thread->push( iresult);
break;
// (MOD) Modulus
case 0x30:
@@ -594,7 +540,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
iparam2 = (long)param2;
iparam1 = (long)param1;
iresult = iparam1 % iparam2;
- thread->push((ScriptDataWord) iresult);
+ thread->push( iresult);
break;
// (EQU) Test equality
case 0x33:
@@ -747,7 +693,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
data = first = thread->stackTop();
for (i = 0; i < stringsCount; i++) {
data = thread->pop();
- strings[i] = getScriptString(data);
+ strings[i] = thread->_strings->getString(data);
}
// now data contains last string index
@@ -756,10 +702,8 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
sampleResourceId = RID_SCENE1_VOICE_009 + data - 288;
}
} else {
- if (isVoiceLUTPresent()) {
- if (currentScript()->voice->n_voices > first) {
- sampleResourceId = currentScript()->voice->voices[first];
- }
+ if (thread->_voiceLUT->voicesCount > first) {
+ sampleResourceId = thread->_voiceLUT->voices[first];
}
}
@@ -767,7 +711,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
if (!(speechFlags & kSpeakAsync)) {
thread->wait(kWaitTypeSpeech);
- thread->instructionOffset = scriptS.pos();
+ thread->_instructionOffset = scriptS.pos();
return;
}
}
@@ -793,7 +737,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
case opReply: // (DLGO): Add a dialogue option to interface
{
- ScriptDataWord n = 0;
+ uint16 n = 0;
const char *str;
int replyNum = scriptS.readByte();
int flags = scriptS.readByte();
@@ -803,7 +747,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
// TODO:
}
- str = getScriptString(thread->pop());
+ str = thread->_strings->getString(thread->pop());
if (_vm->_interface->converseAddText(str, replyNum, flags, n))
warning("Error adding ConverseText (%s, %d, %d, %d)", str, replyNum, flags, n);
}
@@ -812,7 +756,7 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
scriptS.readUint16LE();
scriptS.readUint16LE();
iparam1 = (long)scriptS.readByte();
- thread->instructionOffset += iparam1;
+ thread->_instructionOffset += iparam1;
break;
// End instruction list
@@ -823,14 +767,14 @@ void Script::runThread(ScriptThread *thread, int instr_limit) {
}
// Set instruction offset only if a previous instruction didn't branch
- if (saved_offset == thread->instructionOffset) {
- thread->instructionOffset = scriptS.pos();
+ if (saved_offset == thread->_instructionOffset) {
+ thread->_instructionOffset = scriptS.pos();
} else {
- if (thread->instructionOffset >= scriptS.size()) {
+ if (thread->_instructionOffset >= scriptS.size()) {
scriptError(thread, "Out of range script execution");
return;
} else {
- scriptS.seek(thread->instructionOffset);
+ scriptS.seek(thread->_instructionOffset);
}
}