From c0d25cbae18152997cb9890b9bb6f158d0262f80 Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Mon, 3 Jan 2005 21:17:32 +0000 Subject: - script execution stops properly - placard should work over way: set Wait flag for thread (as in opSpeak) remove inner loop (processInput...) svn-id: r16418 --- saga/console.cpp | 15 ------------ saga/console.h | 2 -- saga/script.cpp | 15 +++++++++++- saga/script.h | 9 ++++--- saga/sdebug.cpp | 71 +++++++++++--------------------------------------------- saga/sfuncs.cpp | 8 ++++++- saga/sthread.cpp | 60 +++++++++++++++++++++-------------------------- 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() { } -int Console::DebugPrintf(const char *format, ...) { - int count; - va_list argptr; - - va_start(argptr, format); - - debug(1, format, argptr); - count = Common::Debugger::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 -- cgit v1.2.3