diff options
author | Andrew Kurushin | 2005-01-21 21:55:54 +0000 |
---|---|---|
committer | Andrew Kurushin | 2005-01-21 21:55:54 +0000 |
commit | 58ec0f0aadd5228732a3c5915b9a94ec00e9cc53 (patch) | |
tree | 28c6ded9c7fd57a8284fa1212f17917900e7e57e | |
parent | 0228f1645f582213ef3e12f19df8e88e61891fbe (diff) | |
download | scummvm-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
-rw-r--r-- | saga/actor.cpp | 13 | ||||
-rw-r--r-- | saga/events.cpp | 52 | ||||
-rw-r--r-- | saga/events.h | 13 | ||||
-rw-r--r-- | saga/font.cpp | 10 | ||||
-rw-r--r-- | saga/game.cpp | 2 | ||||
-rw-r--r-- | saga/interface.cpp | 5 | ||||
-rw-r--r-- | saga/interface.h | 1 | ||||
-rw-r--r-- | saga/objectmap.cpp | 6 | ||||
-rw-r--r-- | saga/render.cpp | 2 | ||||
-rw-r--r-- | saga/saga.h | 4 | ||||
-rw-r--r-- | saga/scene.cpp | 61 | ||||
-rw-r--r-- | saga/script.cpp | 381 | ||||
-rw-r--r-- | saga/script.h | 254 | ||||
-rw-r--r-- | saga/sdebug.cpp | 10 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 294 | ||||
-rw-r--r-- | saga/sprite.cpp | 4 | ||||
-rw-r--r-- | saga/sthread.cpp | 296 |
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); } } |