aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
authorTorbjörn Andersson2004-10-09 07:39:46 +0000
committerTorbjörn Andersson2004-10-09 07:39:46 +0000
commit64a91605a11152e2b1c54eba0e5ae9d514530028 (patch)
treed090c55c229e7aded7829780b0403891a5808109 /saga
parentc68b6323e502af2bc8af682dac17603091cd5240 (diff)
downloadscummvm-rg350-64a91605a11152e2b1c54eba0e5ae9d514530028.tar.gz
scummvm-rg350-64a91605a11152e2b1c54eba0e5ae9d514530028.tar.bz2
scummvm-rg350-64a91605a11152e2b1c54eba0e5ae9d514530028.zip
Initial attempt at fixing the SData problem. I'm still not sure exactly how
to fix the script "static" area, though. In addition, initialise a few variables, and test for NULL-ness of a few pointers. This fixes a few crashes I saw with yesterday's CVS snapshot. There's still an unexpected scene change in the intro (I think it triggers on Rhene walking too close to the exit), but at least it no longer crashes. svn-id: r15484
Diffstat (limited to 'saga')
-rw-r--r--saga/isomap.cpp1
-rw-r--r--saga/render.cpp6
-rw-r--r--saga/scene.cpp19
-rw-r--r--saga/script.cpp2
-rw-r--r--saga/script.h10
-rw-r--r--saga/sdata.cpp33
-rw-r--r--saga/sthread.cpp18
-rw-r--r--saga/xref.txt5
8 files changed, 77 insertions, 17 deletions
diff --git a/saga/isomap.cpp b/saga/isomap.cpp
index ccb2398bbb..bf8a6ef2b2 100644
--- a/saga/isomap.cpp
+++ b/saga/isomap.cpp
@@ -34,6 +34,7 @@ namespace Saga {
IsoMap::IsoMap(Gfx *gfx) {
_gfx = gfx;
_init = 1;
+ _tiles_loaded = 0;
}
int IsoMap::loadTileset(const byte *tileres_p, size_t tileres_len) {
diff --git a/saga/render.cpp b/saga/render.cpp
index 10c26a661c..f401611412 100644
--- a/saga/render.cpp
+++ b/saga/render.cpp
@@ -134,8 +134,10 @@ int Render::drawScene() {
// Display scene maps, if applicable
if (getFlags() & RF_OBJECTMAP_TEST) {
- _vm->_scene->_objectMap->draw(backbuf_surface, mouse_pt, _vm->_gfx->getWhite(), _vm->_gfx->getBlack());
- _vm->_scene->_actionMap->draw(backbuf_surface, _vm->_gfx->matchColor(R_RGB_RED));
+ if (_vm->_scene->_objectMap)
+ _vm->_scene->_objectMap->draw(backbuf_surface, mouse_pt, _vm->_gfx->getWhite(), _vm->_gfx->getBlack());
+ if (_vm->_scene->_actionMap)
+ _vm->_scene->_actionMap->draw(backbuf_surface, _vm->_gfx->matchColor(R_RGB_RED));
}
// Draw queued actors
diff --git a/saga/scene.cpp b/saga/scene.cpp
index 13ef26c975..f2eadaea0b 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -138,6 +138,8 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
_animEntries = 0;
_animList = NULL;
_sceneProc = NULL;
+ _objectMap = NULL;
+ _actionMap = NULL;
memset(&_bg, 0, sizeof(_bg));
memset(&_bgMask, 0, sizeof(_bgMask));
@@ -858,6 +860,9 @@ int Scene::endScene() {
delete _objectMap;
delete _actionMap;
+ _objectMap = NULL;
+ _actionMap = NULL;
+
ys_dll_destroy(_animList);
_animEntries = 0;
@@ -984,6 +989,12 @@ int Scene::defaultScene(int param, R_SCENE_INFO *scene_info) {
_vm->_console->print("Thread creation failed.");
break;
}
+
+ _startScriptThread->threadVars[kVarAction] = 0;
+ _startScriptThread->threadVars[kVarObject] = _sceneNumber;
+ _startScriptThread->threadVars[kVarWithObject] = 0; // TOTO: entrance
+ _startScriptThread->threadVars[kVarActor] = 0;
+
_vm->_script->SThreadExecute(_startScriptThread, _desc.startScriptNum);
_vm->_script->SThreadCompleteThread();
}
@@ -998,7 +1009,7 @@ int Scene::defaultScene(int param, R_SCENE_INFO *scene_info) {
_vm->_events->queue(&event);
} else
_vm->_music->stop();
- //break; //HACK to disable faery script
+
if (_desc.sceneScriptNum > 0) {
R_SCRIPT_THREAD *_sceneScriptThread;
@@ -1010,8 +1021,10 @@ int Scene::defaultScene(int param, R_SCENE_INFO *scene_info) {
break;
}
- // TODO: Set up thread variables. First we'll need to
- // add the concept of thread variables...
+ _sceneScriptThread->threadVars[kVarAction] = 0;
+ _sceneScriptThread->threadVars[kVarObject] = _sceneNumber;
+ _sceneScriptThread->threadVars[kVarWithObject] = 0; // TODO: entrance
+ _sceneScriptThread->threadVars[kVarActor] = 0; // TODO: VERB_ENTER
_vm->_script->SThreadExecute(_sceneScriptThread, _desc.sceneScriptNum);
}
diff --git a/saga/script.cpp b/saga/script.cpp
index d2b25f699e..6d4f11f6b8 100644
--- a/saga/script.cpp
+++ b/saga/script.cpp
@@ -112,7 +112,7 @@ Script::Script() {
// Skip the unused portion of the structure
for (j = scriptS.pos(); j < prevTell + _scriptLUTEntryLen; j++) {
if (scriptS.readByte() != 0)
- error("Unused scriptLUT part isn't really unused for LUT %d (pos: %d)", i, j);
+ warning("Unused scriptLUT part isn't really unused for LUT %d (pos: %d)", i, j);
}
}
diff --git a/saga/script.h b/saga/script.h
index 91f4317964..1ca262d060 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -68,6 +68,13 @@ struct R_SEMAPHORE {
int hold_count;
};
+enum {
+ kVarObject = 0,
+ kVarWithObject,
+ kVarAction,
+ kVarActor
+};
+
struct R_SCRIPT_THREAD {
int executing;
@@ -87,6 +94,8 @@ struct R_SCRIPT_THREAD {
int stackPtr;
int framePtr;
+ SDataWord_T threadVars[4];
+
SDataWord_T retVal;
SDataWord_T stackTop() {
@@ -203,6 +212,7 @@ public:
int SThreadDestroy(R_SCRIPT_THREAD *thread);
private:
+ void setFramePtr(R_SCRIPT_THREAD *thread, int newPtr);
unsigned char *SThreadGetReadPtr(R_SCRIPT_THREAD *thread);
unsigned long SThreadGetReadOffset(const byte *read_p);
size_t SThreadGetReadLen(R_SCRIPT_THREAD *thread);
diff --git a/saga/sdata.cpp b/saga/sdata.cpp
index bcdaa9d99b..e1a26a8b8c 100644
--- a/saga/sdata.cpp
+++ b/saga/sdata.cpp
@@ -30,29 +30,48 @@
namespace Saga {
SData::SData() {
- unsigned int i;
void *alloc_ptr;
+ int i;
debug(0, "Initializing script data buffers");
+
for (i = 0; i < R_SCRIPT_DATABUF_NUM; i++) {
alloc_ptr = malloc(sizeof *_vm->_script->dataBuffer(0));
+
if (alloc_ptr == NULL) {
error("Couldn't allocate memory for script data buffer %d", i);
}
_vm->_script->setBuffer(i, (R_SCRIPT_DATABUF *)alloc_ptr);
- alloc_ptr = calloc(R_SCRIPT_DATABUF_LEN, sizeof(SDataWord_T));
+ }
- if (alloc_ptr == NULL) {
- error("Couldn't allocate memory for script data buffer %d", i);
- }
+ alloc_ptr = calloc(R_SCRIPT_DATABUF_LEN, sizeof(SDataWord_T));
+
+ if (alloc_ptr == NULL) {
+ error("Couldn't allocate memory for shared script buffer");
+ }
+
+ // Buffer 0 is the shared data buffer. All scripts can access this.
+ _vm->_script->dataBuffer(0)->len = R_SCRIPT_DATABUF_LEN;
+ _vm->_script->dataBuffer(0)->data = (SDataWord_T *)alloc_ptr;
+
+ // FIXME: Buffer 1 is the script's static area. The original
+ // interpreter uses part of buffer 0 for this, but I don't yet
+ // understand quite how.
+
+ _vm->_script->setBuffer(1, (R_SCRIPT_DATABUF *)alloc_ptr);
+ _vm->_script->dataBuffer(1)->len = R_SCRIPT_DATABUF_LEN;
+ _vm->_script->dataBuffer(1)->data = (SDataWord_T *)alloc_ptr;
- _vm->_script->dataBuffer(i)->len = R_SCRIPT_DATABUF_LEN;
- _vm->_script->dataBuffer(i)->data = (SDataWord_T *)alloc_ptr;
+ // Remaining buffers are per-script.
+ for (i = 2; i < R_SCRIPT_DATABUF_NUM; i++) {
+ _vm->_script->dataBuffer(i)->len = 0;
+ _vm->_script->dataBuffer(i)->data = NULL;
}
}
SData::~SData() {
+ // TODO: Free the script data buffers
}
int SData::getWord(int n_buf, int n_word, SDataWord_T *data) {
diff --git a/saga/sthread.cpp b/saga/sthread.cpp
index 68adc7e565..68f80ff054 100644
--- a/saga/sthread.cpp
+++ b/saga/sthread.cpp
@@ -35,6 +35,12 @@
namespace Saga {
+void Script::setFramePtr(R_SCRIPT_THREAD *thread, int newPtr) {
+ thread->framePtr = newPtr;
+ dataBuffer(3)->len = 2 * (ARRAYSIZE(thread->stackBuf) - thread->framePtr);
+ dataBuffer(3)->data = (SDataWord_T *) &(thread->stackBuf[newPtr]);
+}
+
R_SCRIPT_THREAD *Script::SThreadCreate() {
YS_DL_NODE *new_node;
R_SCRIPT_THREAD *new_thread;
@@ -49,7 +55,10 @@ R_SCRIPT_THREAD *Script::SThreadCreate() {
}
new_thread->stackPtr = ARRAYSIZE(new_thread->stackBuf) - 1;
- new_thread->framePtr = ARRAYSIZE(new_thread->stackBuf) - 1;
+ setFramePtr(new_thread, new_thread->stackPtr);
+
+ dataBuffer(4)->len = sizeof(new_thread->threadVars);
+ dataBuffer(4)->data = new_thread->threadVars;
new_node = ys_dll_add_head(threadList(), new_thread, sizeof *new_thread);
@@ -199,6 +208,9 @@ int Script::SThreadRun(R_SCRIPT_THREAD *thread, int instr_limit, int msec) {
MemoryReadStream scriptS(currentScript()->bytecode->bytecode_p, currentScript()->bytecode->bytecode_len);
+ dataBuffer(2)->len = currentScript()->bytecode->bytecode_len;
+ dataBuffer(2)->data = (SDataWord_T *) currentScript()->bytecode->bytecode_p;
+
scriptS.seek(thread->i_offset);
for (instr_count = 0; instr_count < instr_limit; instr_count++) {
@@ -353,7 +365,7 @@ int Script::SThreadRun(R_SCRIPT_THREAD *thread, int instr_limit, int msec) {
break;
case 0x1A: // (ENTR) Enter the dragon
thread->push(thread->framePtr);
- thread->framePtr = thread->stackPtr;
+ setFramePtr(thread, thread->stackPtr);
param1 = scriptS.readUint16LE();
thread->stackPtr -= (param1 / 2);
break;
@@ -362,7 +374,7 @@ int Script::SThreadRun(R_SCRIPT_THREAD *thread, int instr_limit, int msec) {
// FALL THROUGH
case 0x1C: // Return with void
thread->stackPtr = thread->framePtr;
- thread->framePtr = thread->pop();
+ setFramePtr(thread, thread->pop());
if (thread->stackSize() == 0) {
_vm->_console->print("Script execution complete.");
thread->executing = 0;
diff --git a/saga/xref.txt b/saga/xref.txt
index 4a26f4a2d3..ad1415287b 100644
--- a/saga/xref.txt
+++ b/saga/xref.txt
@@ -65,4 +65,7 @@ Interp.c
ModuleEntry->codeID _scriptLUT->script_rn
ModuleEntry->strID _scriptLUT->diag_list_rn
ModuleEntry->vtableID _scriptLUT->voice_lut_rn
-
+ threadBase.theAction threadVars[kVarAction]
+ threadBase.theObject threadVars[kVarObject]
+ threadBase.withObject threadVars[kVarWithObject]
+ threadBase.theActor threadVars[kVarActor]