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
This commit is contained in:
Andrew Kurushin
2005-01-21 21:55:54 +00:00
parent 0228f1645f
commit 58ec0f0aad
17 changed files with 639 additions and 771 deletions
+7 -6
View File
@@ -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);
}
+21 -31
View File
@@ -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->();
queuedEvent = _eventList.pushBack(*event).operator->();
initializeEvent(queuedEvent);
initializeEvent(queued_event);
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;
+8 -5
View File
@@ -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);
+5 -5
View File
@@ -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);
+1 -1
View File
@@ -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");
}
-5
View File
@@ -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) {
-1
View File
@@ -169,7 +169,6 @@ private:
InterfacePanel _conversePanel;
SpriteList _defPortraits;
SpriteList _scenePortraits;
ScriptThread *_iThread;
PanelButton *_verbTypeToPanelButton[kVerbTypesMax];
bool _active;
+3 -3
View File
@@ -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++) {
+1 -1
View File
@@ -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,
+3 -1
View File
@@ -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;
};
+33 -28
View File
@@ -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++) {
+134 -251
View File
@@ -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();
if (_modules[scriptModuleNumber].loaded) {
return;
}
// Initialize script data structure
debug(0, "Loading script data for script module #%d", scriptModuleNumber);
debug(0, "Loading script module #%d", scriptModuleNumber);
script_data = (ScriptData *)malloc(sizeof(*script_data));
if (script_data == NULL) {
error("Memory allocation failed");
}
script_data->loaded = 0;
// Initialize script pointers
script_data->bytecode = NULL;
script_data->voice = NULL;
// Load script bytecode
scriptl_rn = _scriptLUT[scriptModuleNumber].script_rn;
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);
_vm->loadStrings(_modules[scriptModuleNumber].strings, resourcePointer, resourceLength);
RSC_FreeResource(resourcePointer);
// Load voice resource lookup table
if (_voiceLUTPresent) {
voicelut_rn = _scriptLUT[scriptModuleNumber].voice_lut_rn;
// 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);
}
_modules[scriptModuleNumber].staticOffset = _staticSize;
_staticSize += _modules[scriptModuleNumber].staticSize;
if (_staticSize > _commonBufferSize) {
error("Script::loadModule() _staticSize > _commonBufferSize");
}
_modules[scriptModuleNumber].loaded = true;
}
void Script::freeModules() {
int i;
for (i = 0; i < _modulesCount; i++) {
if (_modules[i].loaded) {
_modules[i].freeMem();
}
}
// Finish initialization
script_data->loaded = 1;
_currentScript = script_data;
return SUCCESS;
_staticSize = 0;
}
// Frees all resources associated with current script.
int Script::freeScript() {
if (_currentScript == NULL) {
return FAILURE;
}
void Script::loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength) {
int i;
if (!_currentScript->loaded) {
return FAILURE;
}
debug(0, "Loading module base...");
debug(0, "Releasing script data.");
module.moduleBase = (byte*)malloc(resourceLength);
module.moduleBaseSize = resourceLength;
// Finish initialization
_currentScript->strings.freeMem();
memcpy(module.moduleBase, resourcePointer, resourceLength);
if (_currentScript->bytecode != NULL) {
free(_currentScript->bytecode->entrypoints);
RSC_FreeResource(_currentScript->bytecode->bytecode_p);
}
MemoryReadStreamEndian scriptS(module.moduleBase, module.moduleBaseSize, IS_BIG_ENDIAN);
free(_currentScript->bytecode);
if (_voiceLUTPresent) {
free(_currentScript->voice->voices);
free(_currentScript->voice);
}
free(_currentScript);
_currentScript = NULL;
return SUCCESS;
}
// 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;
unsigned long n_entrypoints; // Number of entrypoints
size_t ep_tbl_offset; // Offset of bytecode entrypoint table
unsigned long i;
debug(0, "Loading script bytecode...");
MemoryReadStreamEndian scriptS(bytecode_p, bytecode_len, 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 ((module.moduleBaseSize - module.entryPointsTableOffset) < (module.entryPointsCount * SCRIPT_TBLENTRY_LEN)) {
error("Script::loadModuleBase() Invalid table offset");
}
if (n_entrypoints > SCRIPT_MAX) {
warning("Script limit exceeded");
return NULL;
if (module.entryPointsCount > SCRIPT_MAX) {
error("Script::loadModuleBase()Script limit exceeded");
}
// 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;
}
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;
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->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.voices = (uint16 *)malloc(module.voiceLUT.voicesCount * sizeof(*module.voiceLUT.voices));
if (module.voiceLUT.voices == NULL) {
error("Script::loadModuleVoiceLUT() not enough memory");
}
voice_lut->voices = (int *)malloc(voice_lut->n_voices * sizeof(*voice_lut->voices));
if (voice_lut->voices == NULL) {
MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, IS_BIG_ENDIAN);
return NULL;
for (i = 0; i < module.voiceLUT.voicesCount; i++) {
module.voiceLUT.voices[i] = scriptS.readUint16();
}
MemoryReadStreamEndian scriptS(voicelut_p, voicelut_len, IS_BIG_ENDIAN);
for (i = 0; i < voice_lut->n_voices; i++) {
voice_lut->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);
+149 -103
View File
@@ -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
#define DEFAULT_THREAD_STACK_SIZE 256
typedef unsigned int ScriptDataWord;
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;
};
uint sleepTime;
int entrypointNumber; // Entrypoint number
unsigned long entrypointOffset; // Entrypoint offset
unsigned long instructionOffset; // Instruction offset
struct VoiceLUT {
uint16 voicesCount;
uint16 *voices;
void freeMem() {
free(voices);
}
};
// 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.
struct ModuleData {
bool loaded; // is it loaded or not?
int scriptResourceId;
int stringsResourceId;
int voicesResourceId;
ScriptDataWord stackBuf[64];
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
int stackPtr;
int framePtr;
uint16 entryPointsTableOffset; // offset of entrypoint table in moduleBase
uint16 entryPointsCount;
EntryPoint *entryPoints;
ScriptDataWord threadVars[4];
StringsTable strings;
VoiceLUT voiceLUT;
void freeMem() {
strings.freeMem();
voiceLUT.freeMem();
free(moduleBase);
free(entryPoints);
memset(this, 0x0, sizeof(*this));
}
};
ScriptDataWord retVal;
class ScriptThread {
public:
uint16 *_stackBuf;
uint16 _stackSize; // stack size in uint16
uint16 _stackTopIndex;
uint16 _frameIndex;
ScriptDataWord stackTop() {
return stackBuf[stackPtr];
uint16 _threadVars[kThreadVarMax];
byte *_moduleBase; //
uint16 _moduleBaseSize;
byte *_commonBase; //
byte *_staticBase; //
VoiceLUT *_voiceLUT; //
StringsTable *_strings; //
int _flags; // ThreadFlags
int _waitType; // ThreadWaitTypes
uint _sleepTime;
void *_threadObj; // which object we're handling
uint16 _returnValue;
uint16 _instructionOffset; // Instruction offset
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;
}
}
int stackSize() {
return ARRAYSIZE(stackBuf) - stackPtr - 1;
int16 stackTop() {
return (int16)_stackBuf[_stackTopIndex];
}
void push(ScriptDataWord n) {
assert(stackPtr > 0);
stackBuf[--stackPtr] = n;
uint pushedSize() {
return _stackSize - _stackTopIndex - 1;
}
ScriptDataWord pop() {
assert(stackPtr < ARRAYSIZE(stackBuf));
return stackBuf[stackPtr++];
void push(int16 value) {
if (_stackTopIndex <= 0) {
error("ScriptThread::push() stack overflow");
}
_stackBuf[--_stackTopIndex] = (uint16)value;
}
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
+5 -5
View File
@@ -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) {
+147 -147
View File
@@ -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);
+2 -2
View File
@@ -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);
}
+120 -176
View File
@@ -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);
}
}