aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kurushin2005-01-21 23:25:54 +0000
committerAndrew Kurushin2005-01-21 23:25:54 +0000
commit899e476f014b608768b85af4f819268f32f9f385 (patch)
tree2391bbf9ca588f3e7166b5c7200fd53d438f86bc
parente488ddc7c25a366d6cee417346b5d4f863d39e16 (diff)
downloadscummvm-rg350-899e476f014b608768b85af4f819268f32f9f385.tar.gz
scummvm-rg350-899e476f014b608768b85af4f819268f32f9f385.tar.bz2
scummvm-rg350-899e476f014b608768b85af4f819268f32f9f385.zip
now you can try to:
- talk to someone - look at something svn-id: r16607
-rw-r--r--saga/script.h23
-rw-r--r--saga/sthread.cpp192
2 files changed, 120 insertions, 95 deletions
diff --git a/saga/script.h b/saga/script.h
index c0f2e5abae..7188196bb7 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -113,8 +113,25 @@ enum ThreadWaitTypes {
};
enum OpCodes {
-
+ opNextBlock = 1,
+ opDup = 2,
+ opDrop = 3,
+ opZero = 4,
+ opOne = 5,
+ opConstint = 6,
+//...
+ opStrlit = 8,
+//...
+ opGetFlag = 0xB,
+ opGetInt = 0xC,
+//...
+ opPutFlag = 0xf,
+ opPutInt = 0x10,
+ //...
+ opPutFlagV = 0x13,
+ opPutIntV = 0x14,
//...
+ opCall = 0x17,
opCcall = 0x18,
opCcallV = 0x19,
opEnter = 0x1A,
@@ -223,8 +240,8 @@ public:
return _staticBase;
case kAddressModule:
return _moduleBase;
-/* case kAddressStack:
- return _stackBuf + framePtr;*/
+ case kAddressStack:
+ return (byte*)&_stackBuf[_frameIndex];
case kAddressThread:
return (byte*)_threadVars;
default:
diff --git a/saga/sthread.cpp b/saga/sthread.cpp
index e19bc198da..ab1a475a25 100644
--- a/saga/sthread.cpp
+++ b/saga/sthread.cpp
@@ -166,13 +166,20 @@ int Script::SThreadDebugStep() {
void Script::runThread(ScriptThread *thread, uint instructionLimit) {
uint instructionCount;
- uint32 saved_offset;
+ uint16 savedInstructionOffset;
+
+ byte *addr;
uint16 param1;
uint16 param2;
- long iparam1;
- long iparam2;
+ int16 iparam1;
+ int16 iparam2;
long iresult;
+ byte argumentsCount;
+ uint16 functionNumber;
+ int scriptFunctionReturnValue;
+ ScriptFunctionType scriptFunction;
+
uint16 data;
uint16 scriptRetVal = 0;
int debug_print = 0;
@@ -202,139 +209,140 @@ void Script::runThread(ScriptThread *thread, uint instructionLimit) {
if (thread->_flags & (kTFlagAsleep))
break;
- saved_offset = thread->_instructionOffset;
+ savedInstructionOffset = thread->_instructionOffset;
operandChar = scriptS.readByte();
+
+#define CASEOP(opName) case opName: \
+ if (operandChar == opName) { \
+ debug(8, #opName); \
+ _vm->_console->DebugPrintf(#opName); \
+ }
+
// debug print (opCode name etc) should be placed here
// SDebugPrintInstr(thread)
debug(8, "Executing thread offset: %lu (%x) stack: %d", thread->_instructionOffset, operandChar, thread->pushedSize());
switch (operandChar) {
- case 0x01: // nextblock
+ CASEOP(opNextBlock)
// Some sort of "jump to the start of the next memory
// page" instruction, I think.
thread->_instructionOffset = 1024 * ((thread->_instructionOffset / 1024) + 1);
break;
// STACK INSTRUCTIONS
- case 0x02: // Dup top element (DUP)
- param1 = thread->stackTop();
- thread->push(param1);
+ CASEOP(opDup)
+ thread->push(thread->stackTop());
break;
- case 0x03: // Pop nothing (POPN)
+ CASEOP(opDrop)
thread->pop();
break;
- case 0x04: // Push false (PSHF)
+ CASEOP(opZero)
thread->push(0);
break;
- case 0x05: // Push true (PSHT)
+ CASEOP(opOne)
thread->push(1);
break;
- case 0x06: // Push word (PUSH)
- case 0x08: // Push word (PSHD) (dialogue string index)
+ CASEOP(opConstint)
+ CASEOP(opStrlit)
param1 = scriptS.readUint16LE();
thread->push(param1);
break;
// DATA INSTRUCTIONS
-
- case 0x0B: // Test flag (TSTF)
- n_buf = scriptS.readByte();
+ CASEOP(opGetFlag)
+ addr = thread->baseAddress(scriptS.readByte());
param1 = scriptS.readUint16LE();
- //getBit(n_buf, param1, &bitstate);
-// thread->push(bitstate);
+ addr += (param1 >> 3);
+ param1 = (1 << (param1 & 7));
+ thread->push((*addr) & param1 ? 1 : 0);
break;
- case 0x0C: // Get word (GETW)
- n_buf = scriptS.readByte();
+ CASEOP(opGetInt)
+ addr = thread->baseAddress(scriptS.readByte());
param1 = scriptS.readUint16LE();
- //getWord(n_buf, param1, &data);
-// thread->push(data);
+ addr += param1;
+ thread->push(*((uint16*)addr));
break;
- case 0x0F: // Modify flag (MODF)
- n_buf = scriptS.readByte();
+ CASEOP(opPutFlag)
+ addr = thread->baseAddress(scriptS.readByte());
param1 = scriptS.readUint16LE();
- data = thread->stackTop();
-/* if (data) {
- setBit(n_buf, param1, 1);
+ addr += (param1 >> 3);
+ param1 = (1 << (param1 & 7));
+ if (thread->stackTop()) {
+ *addr |= param1;
} else {
- setBit(n_buf, param1, 0);
- }*/
+ *addr &= ~param1;
+ }
break;
- case 0x10: // Put word (PUTW)
- n_buf = scriptS.readByte();
+ CASEOP(opPutInt)
+ addr = thread->baseAddress(scriptS.readByte());
param1 = scriptS.readUint16LE();
- data = thread->stackTop();
-// putWord(n_buf, param1, data);
+ addr += param1;
+ *(uint16*)addr = thread->stackTop();
break;
- case 0x13: // Modify flag and pop (MDFP)
- n_buf = scriptS.readByte();
+ CASEOP(opPutFlagV)
+ addr = thread->baseAddress(scriptS.readByte());
param1 = scriptS.readUint16LE();
- data = thread->pop();
-/* if (data) {
- setBit(n_buf, param1, 1);
+ addr += (param1 >> 3);
+ param1 = (1 << (param1 & 7));
+ if (thread->pop()) {
+ *addr |= param1;
} else {
- setBit(n_buf, param1, 0);
- }*/
+ *addr &= ~param1;
+ }
break;
- case 0x14: // Put word and pop (PTWP)
- n_buf = scriptS.readByte();
+ CASEOP(opPutIntV)
+ addr = thread->baseAddress(scriptS.readByte());
param1 = scriptS.readUint16LE();
- data = thread->stackTop();
-// putWord(n_buf, param1, data);
+ addr += param1;
+ *(uint16*)addr = thread->pop();
break;
// CONTROL INSTRUCTIONS
- case 0x17: // (GOSB): Call subscript
- {
- int n_args;
- int temp;
-
- n_args = scriptS.readByte();
- temp = scriptS.readByte();
- if (temp != 2)
- error("Calling dynamically generated script? Wow");
- 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 = param1;
+ CASEOP(opCall)
+ argumentsCount = scriptS.readByte();
+ param1 = scriptS.readByte();
+ if (param1 != kAddressModule) {
+ error("Script::runThread param1 != kAddressModule");
}
+ addr = thread->baseAddress(param1);
+ param1 = scriptS.readUint16LE();
+ addr += param1;
+ thread->push(argumentsCount);
+
+ param2 = scriptS.pos();
+ // NOTE: The original pushes the program
+ // counter as a pointer here. But I don't think
+ // we will have to do that.
+ thread->push(param2);
+ thread->_instructionOffset = param1;
+
break;
- case opCcall: // Call function
- case opCcallV: { // Call function and discard return value
- int argumentsCount;
- uint16 functionNumber;
- int scriptFunctionReturnValue;
- ScriptFunctionType scriptFunction;
-
- argumentsCount = scriptS.readByte();
- functionNumber = scriptS.readUint16LE();
- if (functionNumber >= SCRIPT_FUNCTION_MAX) {
- scriptError(thread, "Invalid script function number");
- return;
- }
+ CASEOP(opCcall)
+ CASEOP(opCcallV)
+ argumentsCount = scriptS.readByte();
+ functionNumber = scriptS.readUint16LE();
+ if (functionNumber >= SCRIPT_FUNCTION_MAX) {
+ error("Script::runThread() Invalid script function number");
+ }
- debug(9, "opCCall* Calling 0x%X %s", functionNumber, _scriptFunctionsList[functionNumber].scriptFunctionName);
- 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);
- }
+ debug(8, "Calling 0x%X %s", functionNumber, _scriptFunctionsList[functionNumber].scriptFunctionName);
+ 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);
+ }
- if (functionNumber == 16) { // SF_gotoScene
- instructionCount = instructionLimit; // break the loop
- break;
- }
+ if (scriptFunction == SF_gotoScene) { // SF_gotoScene
+ instructionCount = instructionLimit; // break the loop
+ break;
+ }
- if (operandChar == opCcall) // CALL function
- thread->push(thread->_returnValue);
+ if (operandChar == opCcall) // CALL function
+ thread->push(thread->_returnValue);
- if (thread->_flags & kTFlagAsleep)
- instructionCount = instructionLimit; // break out of loop!
- }
+ if (thread->_flags & kTFlagAsleep)
+ instructionCount = instructionLimit; // break out of loop!
break;
case opEnter: // Enter a function
thread->push(thread->_frameIndex);
@@ -767,15 +775,15 @@ void Script::runThread(ScriptThread *thread, uint instructionLimit) {
}
// Set instruction offset only if a previous instruction didn't branch
- if (saved_offset == thread->_instructionOffset) {
+ if (savedInstructionOffset == thread->_instructionOffset) {
thread->_instructionOffset = scriptS.pos();
} else {
if (thread->_instructionOffset >= scriptS.size()) {
scriptError(thread, "Out of range script execution");
return;
- } else {
- scriptS.seek(thread->_instructionOffset);
}
+
+ scriptS.seek(thread->_instructionOffset);
}
if (unhandled) { // TODO: remove it