aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kurushin2005-01-03 21:17:32 +0000
committerAndrew Kurushin2005-01-03 21:17:32 +0000
commitc0d25cbae18152997cb9890b9bb6f158d0262f80 (patch)
tree02a78d961453ca2e45cdc786b16f546c1bb75bee
parent9f0783e3914a45283cd09cc0d8861c8acd7c9d0e (diff)
downloadscummvm-rg350-c0d25cbae18152997cb9890b9bb6f158d0262f80.tar.gz
scummvm-rg350-c0d25cbae18152997cb9890b9bb6f158d0262f80.tar.bz2
scummvm-rg350-c0d25cbae18152997cb9890b9bb6f158d0262f80.zip
- script execution stops properly
- placard should work over way: set Wait flag for thread (as in opSpeak) remove inner loop (processInput...) svn-id: r16418
-rw-r--r--saga/console.cpp15
-rw-r--r--saga/console.h2
-rw-r--r--saga/script.cpp15
-rw-r--r--saga/script.h9
-rw-r--r--saga/sdebug.cpp71
-rw-r--r--saga/sfuncs.cpp8
-rw-r--r--saga/sthread.cpp60
7 files changed, 68 insertions, 112 deletions
diff --git a/saga/console.cpp b/saga/console.cpp
index cda0a20e8f..3e5184f5fb 100644
--- a/saga/console.cpp
+++ b/saga/console.cpp
@@ -86,21 +86,6 @@ Console::Console(SagaEngine *vm) : Common::Debugger<Console>() {
Console::~Console() {
}
-int Console::DebugPrintf(const char *format, ...) {
- int count;
- va_list argptr;
-
- va_start(argptr, format);
-
- debug(1, format, argptr);
- count = Common::Debugger<Console>::DebugPrintf(format);
-
- va_end (argptr);
-
- return count;
-}
-
-
void Console::preEnter() {
}
diff --git a/saga/console.h b/saga/console.h
index 63276045b5..e5ecd8cedf 100644
--- a/saga/console.h
+++ b/saga/console.h
@@ -35,8 +35,6 @@ public:
Console(SagaEngine *vm);
~Console(void);
- int DebugPrintf(const char *format, ...);
-
protected:
virtual void preEnter();
virtual void postEnter();
diff --git a/saga/script.cpp b/saga/script.cpp
index 3cf41d77b0..8482bc6880 100644
--- a/saga/script.cpp
+++ b/saga/script.cpp
@@ -96,7 +96,7 @@ Script::Script() {
_scriptLUTMax = rsc_len / _scriptLUTEntryLen;
debug(0, "LUT has %d entries.", _scriptLUTMax);
-
+
// Allocate space for logical LUT
_scriptLUT = (SCRIPT_LUT_ENTRY *)malloc(_scriptLUTMax * sizeof(SCRIPT_LUT_ENTRY));
if (_scriptLUT == NULL) {
@@ -529,6 +529,19 @@ VOICE_LUT *Script::loadVoiceLUT(const byte *voicelut_p, size_t voicelut_len, SCR
return voice_lut;
}
+void Script::scriptError(SCRIPT_THREAD *thread, const char *format, ...) {
+ char buf[STRINGBUFLEN];
+ va_list argptr;
+
+ va_start(argptr, format);
+ vsprintf(buf, format, argptr);
+ va_end (argptr);
+
+ thread->flags |= kTFlagAborted;
+ debug(0, "Script::scriptError %X: %s", thread->i_offset, buf);
+ _vm->_console->DebugPrintf("Script::scriptError %X: %s", thread->i_offset, buf);
+}
+
void Script::scriptInfo() {
uint32 n_entrypoints;
uint32 i;
diff --git a/saga/script.h b/saga/script.h
index c49b7d1219..fdb60ec185 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -84,7 +84,7 @@ enum ThreadFlags {
kTFlagWaiting = 1, // wait for even denoted in waitType
kTFlagFinished = 2,
kTFlagAborted = 4,
- kTFlagAsleep = 7 // Combination of all flags which can halt a thread
+ kTFlagAsleep = kTFlagWaiting | kTFlagFinished | kTFlagAborted // Combination of all flags which can halt a thread
};
enum ThreadWaitTypes {
@@ -103,6 +103,9 @@ enum OpCodes {
//...
opCcall = 0x18,
opCcallV = 0x19,
+ opEnter = 0x1A,
+ opReturn = 0x1B,
+ opReturnV = 0x1C,
//...
opSpeak = 0x53
};
@@ -279,7 +282,6 @@ public:
int executeThreads(uint msec);
int SThreadDebugStep();
void SThreadCompleteThread(void);
- int SThreadDestroy(SCRIPT_THREAD *thread);
void wakeUpActorThread(int waitType, void *threadObj);
void wakeUpThreads(int waitType);
@@ -290,7 +292,7 @@ private:
unsigned char *SThreadGetReadPtr(SCRIPT_THREAD *thread);
unsigned long SThreadGetReadOffset(const byte *read_p);
size_t SThreadGetReadLen(SCRIPT_THREAD *thread);
- int SThreadRun(SCRIPT_THREAD *thread, int instr_limit);
+ void runThread(SCRIPT_THREAD *thread, int instr_limit);
int SThreadSetEntrypoint(SCRIPT_THREAD *thread, int ep_num);
private:
@@ -303,6 +305,7 @@ private:
const ScriptFunctionDescription *_scriptFunctionsList;
void setupScriptFuncList(void);
+ void scriptError(SCRIPT_THREAD *thread, const char *format, ...);
int SDebugPrintInstr(SCRIPT_THREAD *thread);
int SF_putString(SCRIPTFUNC_PARAMS);
diff --git a/saga/sdebug.cpp b/saga/sdebug.cpp
index ee86db0913..e0b35d370c 100644
--- a/saga/sdebug.cpp
+++ b/saga/sdebug.cpp
@@ -65,10 +65,10 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
tl_e.string = disp_buf;
tl_e.display = 1;
- MemoryReadStream/*Endian*/ readS(currentScript()->bytecode->bytecode_p
+ MemoryReadStream readS(currentScript()->bytecode->bytecode_p
+ thread->i_offset,
currentScript()->bytecode->bytecode_len
- - thread->i_offset/*, IS_BIG_ENDIAN*/);
+ - thread->i_offset);
in_char = readS.readByte();
sprintf(tmp_buf, "%04lX | %02X | ", thread->i_offset, in_char);
strncat(disp_buf, tmp_buf, SD_DISPLAY_LEN);
@@ -219,46 +219,20 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
}
break;
// Call function
- case 0x19:
- case 0x18:
- {
- int func_num;
- int param;
-
- SD_ADDTXT("CALL | ");
- func_num = readS.readByte();
- sprintf(tmp_buf, "%02X ", func_num);
- SD_ADDTXT(tmp_buf);
- param = readS.readUint16LE();
- sprintf(tmp_buf, "%04X ", param);
- SD_ADDTXT(tmp_buf);
- }
+ case opCcall:
+ SD_ADDTXT("opCall");
break;
- // Begin subscript
- case 0x1A:
- {
- int param;
-
- SD_ADDTXT("ENTR | ");
- param = readS.readUint16LE();
- sprintf(tmp_buf, "%04X ", param);
- SD_ADDTXT(tmp_buf);
-/*
- for(i = 0 ; i < script_list->n_scripts ; i++) {
- if(op_offset == script_list->scripts[i].offset) {
- debug(2, "; Entrypoint \"%s\".", script_list->scriptl_p + script_list->scripts[i].name_offset);
- break;
- }
- }
-*/
- }
+ case opCcallV:
+ SD_ADDTXT("opCallV");
break;
- case 0x1B:
- SD_ADDTXT("??? ");
+ case opEnter:
+ SD_ADDTXT("opEnter");
+ break;
+ case opReturn:
+ SD_ADDTXT("opReturn");
break;
- // End subscript
- case 0x1C:
- SD_ADDTXT("EXIT |");
+ case opReturnV:
+ SD_ADDTXT("opReturnV");
break;
// Unconditional jump
case 0x1D:
@@ -453,20 +427,7 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
SD_ADDTXT("LXOR |");
break;
case opSpeak:
- {
- int stringsCount;
- uint16 actorId;
- int speechFlags;
-
- SD_ADDTXT("opSpeak | ");
- stringsCount = readS.readByte();
- actorId = readS.readUint16LE();
- speechFlags = readS.readByte();
- // ignored ?
- readS.readUint16LE();
- sprintf(tmp_buf, "%02X %04X %02X", stringsCount, actorId, speechFlags);
- SD_ADDTXT(tmp_buf);
- }
+ SD_ADDTXT("opSpeak");
break;
case 0x54:
SD_ADDTXT("DLGS |");
@@ -506,10 +467,6 @@ int Script::SDebugPrintInstr(SCRIPT_THREAD *thread) {
SD_ADDTXT(tmp_buf);
}
break;
- default:
- sprintf(tmp_buf, "Invalid opcode.\n");
- SD_ADDTXT(tmp_buf);
- break;
}
_dbg_txtentry = _vm->textAddEntry(si.text_list, &tl_e);
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index d3c57bc8b3..e378cc4b51 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -918,11 +918,17 @@ int Script::SF_simulSpeech2(SCRIPTFUNC_PARAMS) {
}
// Script function #48 (0x30)
+// Param1: string rid
int Script::sfPlacard(SCRIPTFUNC_PARAMS) {
+ int stringId;
+ const char *string;
GAME_DISPLAYINFO disp;
SURFACE *back_buf = _vm->_gfx->getBackBuffer();
PALENTRY cur_pal[PAL_ENTRIES];
PALENTRY *pal;
+
+ stringId = thread->pop();
+ string = getString(stringId);
_vm->getDisplayInfo(&disp);
@@ -941,7 +947,7 @@ int Script::sfPlacard(SCRIPTFUNC_PARAMS) {
// It doesn't end up in exactly the same spot as the original did it,
// but it's close enough for now at least.
- _vm->textDraw(MEDIUM_FONT_ID, back_buf, getString(thread->pop()),
+ _vm->textDraw(MEDIUM_FONT_ID, back_buf, string,
disp.logical_w / 2,
(disp.scene_h - _vm->_font->getHeight(MEDIUM_FONT_ID)) / 2,
_vm->_gfx->getWhite(), _vm->_gfx->getBlack(),
diff --git a/saga/sthread.cpp b/saga/sthread.cpp
index b3cd01bba0..378633102d 100644
--- a/saga/sthread.cpp
+++ b/saga/sthread.cpp
@@ -59,7 +59,6 @@ SCRIPT_THREAD *Script::SThreadCreate() {
dataBuffer(4)->length = ARRAYSIZE(new_thread->threadVars);
dataBuffer(4)->data = new_thread->threadVars;
-
return new_thread;
}
@@ -144,7 +143,7 @@ int Script::executeThreads(uint msec) {
}
if (!(thread->flags & kTFlagWaiting))
- SThreadRun(thread, STHREAD_TIMESLICE);
+ runThread(thread, STHREAD_TIMESLICE);
++threadIterator;
}
@@ -216,7 +215,7 @@ int Script::SThreadDebugStep() {
return SUCCESS;
}
-int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
+void Script::runThread(SCRIPT_THREAD *thread, int instr_limit) {
int instr_count;
uint32 saved_offset;
ScriptDataWord param1;
@@ -242,7 +241,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
instr_limit = 1;
_dbg_dostep = 0;
} else {
- return SUCCESS;
+ return;
}
}
@@ -254,11 +253,13 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
scriptS.seek(thread->i_offset);
for (instr_count = 0; instr_count < instr_limit; instr_count++) {
- if (thread->flags & kTFlagWaiting)
+ if (thread->flags & (kTFlagAsleep))
break;
saved_offset = thread->i_offset;
operandChar = scriptS.readByte();
+// debug print (opCode name etc) should be placed here
+// SDebugPrintInstr(thread)
// debug(2, "Executing thread offset: %lu (%x) stack: %d", thread->i_offset, operandChar, thread->stackSize());
switch (operandChar) {
@@ -357,9 +358,8 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
thread->i_offset = (unsigned long)param1;
}
break;
- case opCcall: // (CALL): Call function
- case opCcallV: // (CALL_V): Call function and discard return value
- {
+ case opCcall: // Call function
+ case opCcallV: { // Call function and discard return value
int argumentsCount;
uint16 functionNumber;
int scriptFunctionReturnValue;
@@ -368,9 +368,8 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
argumentsCount = scriptS.readByte();
functionNumber = scriptS.readUint16LE();
if (functionNumber >= SCRIPT_FUNCTION_MAX) {
- _vm->_console->DebugPrintf(S_ERROR_PREFIX "Invalid script function number: (%X)\n", functionNumber);
- thread->flags |= kTFlagAborted;
- break;
+ scriptError(thread, "Invalid script function number");
+ return;
}
debug(9, "opCCall* Calling 0x%X %s", functionNumber, _scriptFunctionsList[functionNumber].scriptFunctionName);
@@ -385,32 +384,32 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
break;
}
- if (operandChar == 0x18) // CALL function
+ if (operandChar == opCcall) // CALL function
thread->push(thread->retVal);
if (thread->flags & kTFlagAsleep)
instr_count = instr_limit; // break out of loop!
}
break;
- case 0x1A: // (ENTR) Enter the dragon
+ case opEnter: // Enter a function
thread->push(thread->framePtr);
setFramePtr(thread, thread->stackPtr);
param1 = scriptS.readUint16LE();
thread->stackPtr -= (param1 / 2);
break;
- case 0x1B: // Return with value
+ case opReturn: // Return with value
scriptRetVal = thread->pop();
- // FALL THROUGH
- case 0x1C: // Return with void
+ case opReturnV: // Return with void
thread->stackPtr = thread->framePtr;
setFramePtr(thread, thread->pop());
if (thread->stackSize() == 0) {
_vm->_console->DebugPrintf("Script execution complete.\n");
thread->flags |= kTFlagFinished;
+ return;
} else {
thread->i_offset = thread->pop();
/* int n_args = */ thread->pop();
- if (operandChar == 0x1B)
+ if (operandChar == opReturn)
thread->push(scriptRetVal);
}
break;
@@ -737,7 +736,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
if (_vm->_actor->isSpeaking()) {
thread->wait(kWaitTypeSpeech);
- return SUCCESS;
+ return;
}
stringsCount = scriptS.readByte();
@@ -774,6 +773,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
if (!(speechFlags & kSpeakAsync)) {
thread->wait(kWaitTypeSpeech);
+ return;
}
}
break;
@@ -807,9 +807,8 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
// End instruction list
default:
- _vm->_console->DebugPrintf(S_ERROR_PREFIX "%X: Invalid opcode encountered: (%X).\n", thread->i_offset, operandChar);
- thread->flags |= kTFlagAborted;
- break;
+ scriptError(thread, "Invalid opcode encountered");
+ return;
}
// Set instruction offset only if a previous instruction didn't branch
@@ -817,22 +816,17 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) {
thread->i_offset = scriptS.pos();
} else {
if (thread->i_offset >= scriptS.size()) {
- _vm->_console->DebugPrintf("Out of range script execution at %x size %x\n", thread->i_offset, scriptS.size());
- thread->flags |= kTFlagFinished;
- }
- else
+ scriptError(thread, "Out of range script execution");
+ return;
+ } else {
scriptS.seek(thread->i_offset);
+ }
}
- if (unhandled) {
- _vm->_console->DebugPrintf(S_ERROR_PREFIX "%X: Unhandled opcode.\n", thread->i_offset);
- thread->flags |= kTFlagAborted;
- }
- if ((thread->flags == kTFlagNone) && debug_print) {
- SDebugPrintInstr(thread);
+
+ if (unhandled) { // TODO: remove it
+ scriptError(thread, "Unhandled opcode");
}
}
-
- return SUCCESS;
}
} // End of namespace Saga