From c01aa37caaadb2e65667b1156a907e92e859fee8 Mon Sep 17 00:00:00 2001 From: Vincent Hamm Date: Fri, 27 Apr 2007 12:58:35 +0000 Subject: Add cruise source code for scummvm svn-id: r26605 --- engines/cruise/script.cpp | 861 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 861 insertions(+) create mode 100644 engines/cruise/script.cpp (limited to 'engines/cruise/script.cpp') diff --git a/engines/cruise/script.cpp b/engines/cruise/script.cpp new file mode 100644 index 0000000000..dcb5f3812b --- /dev/null +++ b/engines/cruise/script.cpp @@ -0,0 +1,861 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +scriptInstanceStruct scriptHandle1; +scriptInstanceStruct scriptHandle2; + +scriptInstanceStruct* currentScriptPtr; + + +uint8 getByteFromScript(void) +{ + uint8 var = currentData3DataPtr[currentScriptPtr->var4]; + + currentScriptPtr->var4 = currentScriptPtr->var4+1; + + return(var); +} + +short int getShortFromScript(void) +{ + short int var = *(int16*)(currentData3DataPtr+currentScriptPtr->var4); + + currentScriptPtr->var4 = currentScriptPtr->var4+2; + + flipShort(&var); + + return(var); +} + +int32 opcodeType0(void) // load opcode +{ + switch(currentScriptOpcodeType) + { + case 0: + { + pushVar(getShortFromScript()); + return(0); + } + case 1: + { + uint8* ptr; + int byte1 = getByteFromScript(); + int byte2 = getByteFromScript(); + short int short1 = getShortFromScript(); + + int var_E = byte1 & 7; + + if(!var_E) + { + return(-10); + } + + if(!byte2) + { + ptr = scriptDataPtrTable[var_E] + short1; + } + else // TODO: + { + if(!overlayTable[byte2].alreadyLoaded) + { + return(-7); + } + + if(!overlayTable[byte2].ovlData) + { + return(-4); + } + + if(var_E == 5) + { + ptr = overlayTable[byte2].ovlData->data4Ptr + short1; + } + else + { + assert(0); + } + } + + if(((byte1 & 0x18)>>3)==1) + { + pushVar(loadShort(ptr)); + return(0); + } + else + if(((byte1 & 0x18)>>3)==2) + { + pushVar(*ptr); + return(0); + } + else + { + printf("Unsupported code in opcodeType0 case 1!\n"); + exit(1); + } + + return(0); + } + case 2: + { + int16 var_16; + int di = getByteFromScript(); + int si = getByteFromScript(); + int var_2 = getShortFromScript(); + + if(!si) + { + si = currentScriptPtr->overlayNumber; + } + + if(getSingleObjectParam(si, var_2, di, &var_16)) + { + return -10; + } + + pushVar(var_16); + return(0); + + break; + } + case 5: + { + int byte1 = getByteFromScript(); + int byte2 = getByteFromScript(); + short int short1 = getShortFromScript(); + + short int var_12 = short1; + // short int var_10 = saveOpcodeVar; + + int var_E = byte1 & 7; + + uint8* ptr; + + if(!var_E) + { + return(-10); + } + + if(!byte2) + { + ptr = scriptDataPtrTable[var_E] + var_12; + } + else // TODO: + { + if(!overlayTable[byte2].alreadyLoaded) + { + return(-7); + } + + if(!overlayTable[byte2].ovlData) + { + return(-4); + } + + if(var_E == 5) + { + ptr = overlayTable[byte2].ovlData->data4Ptr + var_12; + } + else + { + assert(0); + } + } + + if(((byte1 & 0x18)>>3)==1) + { + pushVar(loadShort(ptr+saveOpcodeVar*2)); // TODO: check this ! + return(0); + } + else + if(((byte1 & 0x18)>>3)==2) + { + pushVar(*(ptr+saveOpcodeVar)); + return(0); + } + else + { + printf("Unsupported code in opcodeType0 case 1!\n"); + exit(1); + } + + return(0); + } + default: + { + printf("Unsupported type %d in opcodeType0\n",currentScriptOpcodeType); + exit(1); + } + } + + return 0; +} + +int32 opcodeType1(void) // save opcode +{ + int var = popVar(); + int offset = 0; + + switch(currentScriptOpcodeType) + { + case 0: + { + return(0); // strange, but happens also in original interpreter + } + case 5: + { + offset = saveOpcodeVar; + } + case 1: + { + int var_A = 0; + + int byte1 = getByteFromScript(); + int byte2 = getByteFromScript(); + + int short1 = getShortFromScript(); + + int var_6 = byte1 & 7; + + int var_C = short1; + + uint8* ptr; + int type2; + + if(!var_6) + return(-10); + + var_C = short1; + + if(byte2) + { + if(!overlayTable[byte2].alreadyLoaded) + { + return(-7); + } + + if(!overlayTable[byte2].ovlData) + { + return(-4); + } + + if(var_6 == 5) + { + ptr = overlayTable[byte2].ovlData->data4Ptr + var_C; + } + else + { + ASSERT(0); + } + } + else + { + ptr = scriptDataPtrTable[var_6] + var_C; + } + + type2 = ((byte1 & 0x18)>>3); + + switch(type2) + { + case 1: + { + saveShort(ptr+var_A+offset*2,var); + return 0; + } + case 2: + { + *(ptr+var_A+offset) = var; + return(0); + } + default: + { + printf("Unsupported code in opcodeType1 case 1!\n"); + exit(1); + } + } + + break; + } + case 2: + { + int mode = getByteFromScript(); + int di = getByteFromScript(); + int var_4 = getShortFromScript(); + + if(!di) + { + di = currentScriptPtr->overlayNumber; + } + + if(var == 0x85) // Special case to handle... + { + ASSERT(0); + } + + setObjectPosition(di, var_4, mode, var); + + break; + } + case 4: + { + saveOpcodeVar = var; + break; + } + default: + { + printf("Unsupported type %d in opcodeType1\n",currentScriptOpcodeType); + exit(1); + } + } + + return(0); +} + + +int32 opcodeType2(void) +{ + int offset = saveOpcodeVar; + int byte1 = getByteFromScript(); + int byte2 = getByteFromScript(); + short int short1 = getShortFromScript(); + + ASSERT(currentScriptOpcodeType == 1 || currentScriptOpcodeType == 5); + + if(currentScriptOpcodeType == 5) + short1 += saveOpcodeVar; + + ASSERT(byte1 & 7); + + if(!(byte1 & 7)) + { + return(-10); + } + + if(!byte2) + { + int type2; + uint8* ptr = scriptDataPtrTable[byte1 & 7] + short1; + + type2 = ((byte1&0x18)>>3); + + ASSERT(type2 == 1 || type2 == 2); + + switch(type2) + { + case 1: + { + pushPtr(ptr + offset); + return(0); + } + case 2: + { + pushPtr(ptr); + return(0); + } + default : + { + return(-10); + } + } + } + else + { + printf("Unsupported code in opcodeType2 case 1!\n"); + exit(1); + } + + return 0; +} + +int32 opcodeType10(void) // break +{ + return(0); +} + +int32 opcodeType11(void) // break +{ + return(1); +} + +int32 opcodeType4(void) // test +{ + int boolVar = 0; + + int var1 = popVar(); + int var2 = popVar(); + + switch(currentScriptOpcodeType) + { + case 0: + { + if(var2!=var1) + boolVar = 1; + break; + } + case 1: + { + if(var2==var1) + boolVar = 1; + break; + } + case 2: + { + if(var2var1) + boolVar = 1; + break; + } + case 5: + { + if(var2>=var1) + boolVar = 1; + break; + } + + } + + pushVar(boolVar); + + return(0); +} + +int32 opcodeType6(void) +{ + int si = 0; + + int pop = popVar(); + + if(!pop) + si = 1; + + if(pop<0) + { + si |= 4; + } + + if(pop>0) + { + si |= 2; + } + + currentScriptPtr->bitMask = si; + + return(0); +} + +int32 opcodeType7(void) +{ + int var1 = popVar(); + int var2 = popVar(); + + pushVar(var1); + pushVar(var2); + + return(0); +} + +int32 opcodeType5(void) +{ + int offset = currentScriptPtr->var4; + int short1 = getShortFromScript(); + int newSi = short1 + offset; + int bitMask = currentScriptPtr->bitMask; + + switch(currentScriptOpcodeType) + { + case 0: + { + if(!(bitMask & 1)) + { + currentScriptPtr->var4 = newSi; + } + break; + } + case 1: + { + if(bitMask & 1) + { + currentScriptPtr->var4 = newSi; + } + break; + } + case 2: + { + if(bitMask & 2) + { + currentScriptPtr->var4 = newSi; + } + break; + } + case 3: + { + if(bitMask & 3) + { + currentScriptPtr->var4 = newSi; + } + break; + } + case 4: + { + if(bitMask & 4) + { + currentScriptPtr->var4 = newSi; + } + break; + } + case 5: + { + if(bitMask & 5) + { + currentScriptPtr->var4 = newSi; + } + break; + } + case 6: + { + break; // never + } + case 7: + { + currentScriptPtr->var4 = newSi; //always + } + } + + return(0); +} + +int32 opcodeType3(void) // math +{ + int pop1 = popVar(); + int pop2 = popVar(); + + switch(currentScriptOpcodeType) + { + case 0: + { + pushVar(pop1+pop2); + return(0); + } + case 1: + { + pushVar(pop1/pop2); + return(0); + } + case 2: + { + pushVar(pop1-pop2); + return(0); + } + case 3: + { + pushVar(pop1*pop2); + return(0); + } + case 4: + { + pushVar(pop1%pop2); + return(0); + } + case 7: + case 5: + { + pushVar(pop2|pop1); + return(0); + } + case 6: + { + pushVar(pop2&pop1); + return(0); + } + } + + return 0; +} + +int32 opcodeType9(void) // stop script +{ + //printf("Stop a script of overlay %s\n",overlayTable[currentScriptPtr->overlayNumber].overlayName); + currentScriptPtr->scriptNumber = -1; + return(1); +} + + +void setupFuncArray() +{ + int i; + + for(i=0;i<64;i++) + { + opcodeTypeTable[i] = NULL; + } + + opcodeTypeTable[1] = opcodeType0; + opcodeTypeTable[2] = opcodeType1; + opcodeTypeTable[3] = opcodeType2; + opcodeTypeTable[4] = opcodeType3; + opcodeTypeTable[5] = opcodeType4; + opcodeTypeTable[6] = opcodeType5; + opcodeTypeTable[7] = opcodeType6; + opcodeTypeTable[8] = opcodeType7; + opcodeTypeTable[9] = opcodeType8; + opcodeTypeTable[10] = opcodeType9; + opcodeTypeTable[11] = opcodeType10; + opcodeTypeTable[12] = opcodeType11; +} + +int removeScript(int overlay,int idx,scriptInstanceStruct* headPtr) +{ + scriptInstanceStruct* scriptPtr; + + scriptPtr = headPtr->nextScriptPtr; + + if(scriptPtr) + { + do + { + if(scriptPtr->overlayNumber == overlay && (scriptPtr->scriptNumber == idx || idx == -1)) + { + scriptPtr->scriptNumber = -1; + } + + scriptPtr = scriptPtr->nextScriptPtr; + } + while(scriptPtr); + } + + return(0); +} + +uint8* attacheNewScriptToTail(int16 overlayNumber,scriptInstanceStruct* scriptHandlePtr,int16 param, int16 arg0, int16 arg1, int16 arg2, scriptTypeEnum scriptType) +{ + int useArg3Neg = 0; + ovlData3Struct* data3Ptr; + scriptInstanceStruct* tempPtr; + int var_C; + scriptInstanceStruct* oldTail; + + //printf("Starting script %d of overlay %s\n",param,overlayTable[overlayNumber].overlayName); + + if(scriptType<0) + { + useArg3Neg = 1; + scriptType = (scriptTypeEnum)-scriptType; + } + + if(scriptType == 20) + { + data3Ptr = getOvlData3Entry(overlayNumber,param); + } + else + { + if(scriptType == 30) + { + data3Ptr = scriptFunc1Sub2(overlayNumber,param); + } + else + { + return(NULL); + } + } + + if(!data3Ptr) + { + return(NULL); + } + + if(!data3Ptr->dataPtr) + { + return(NULL); + } + + var_C = data3Ptr->sysKey; + + oldTail = scriptHandlePtr; + + while(oldTail->nextScriptPtr) // go to the end of the list + { + oldTail=oldTail->nextScriptPtr; + } + + tempPtr = (scriptInstanceStruct*)mallocAndZero(sizeof(scriptInstanceStruct)); + + if(!tempPtr) + return(NULL); + + tempPtr->var6 = NULL; + + if(var_C) + { + tempPtr->var6 = (uint8*)mallocAndZero(var_C); + } + + tempPtr->varA = var_C; + tempPtr->nextScriptPtr = NULL; + tempPtr->var4 = 0; + + tempPtr->scriptNumber = param; + tempPtr->overlayNumber = overlayNumber; + + if(scriptType == 20) // Obj or not ? + { + tempPtr->sysKey = useArg3Neg; + } + else + { + tempPtr->sysKey = 1; + } + + tempPtr->var12 = 0; + tempPtr->type = scriptType; + tempPtr->var18 = arg2; + tempPtr->var16 = arg1; + tempPtr->var1A = arg0; + tempPtr->nextScriptPtr = oldTail->nextScriptPtr; // should always be NULL as it's the tail + + oldTail->nextScriptPtr = tempPtr; // attache the new node to the list + + return(tempPtr->var6); +} + +int executeScripts(scriptInstanceStruct* ptr) +{ + int numScript2; + ovlData3Struct* ptr2; + ovlDataStruct* ovlData; + uint8 opcodeType; + + numScript2 = ptr->scriptNumber; + + if(ptr->type == 20) + { + ptr2 = getOvlData3Entry(ptr->overlayNumber,numScript2); + + if(!ptr2) + { + return(-4); + } + } + else + { + if(ptr->type == 30) + { + ptr2 = scriptFunc1Sub2(ptr->overlayNumber,numScript2); + + if(!ptr2) + { + return(-4); + } + } + else + { + return(-6); + } + } + + if(!overlayTable[ptr->overlayNumber].alreadyLoaded) + { + return(-7); + } + + ovlData = overlayTable[ptr->overlayNumber].ovlData; + + if(!ovlData) + return(-4); + + currentData3DataPtr = ptr2->dataPtr; + + scriptDataPtrTable[1] = (uint8*)ptr->var6; + scriptDataPtrTable[2] = getDataFromData3(ptr2, 1); + scriptDataPtrTable[5] = ovlData->data4Ptr; // free strings + scriptDataPtrTable[6] = ovlData->ptr8; + + currentScriptPtr = ptr; + + positionInStack = 0; + + do + { + if(currentScriptPtr->var4 == 290 && currentScriptPtr->overlayNumber == 4 && currentScriptPtr->scriptNumber == 0) + { + currentScriptPtr->var4 = 923; + } + opcodeType = getByteFromScript(); + + //printf("opType: %d\n",(opcodeType&0xFB)>>3); + + currentScriptOpcodeType = opcodeType & 7; + + if(!opcodeTypeTable[(opcodeType&0xFB)>>3]) + { + printf("Unsupported opcode type %d\n",(opcodeType&0xFB)>>3); + exit(1); + return(-21); + } + }while(!opcodeTypeTable[(opcodeType&0xFB)>>3]()); + + return(0); +} + +void manageScripts(scriptInstanceStruct* scriptHandle) +{ + scriptInstanceStruct* ptr = scriptHandle; + + if(ptr) + { + do + { + if(!overlayTable[ptr->overlayNumber].executeScripts) + { + if(ptr->scriptNumber != -1 && ptr->var12 == 0 && ptr->sysKey != 0) + { + executeScripts(ptr); + } + + if(ptr->sysKey == 0) + { + ptr->sysKey = 1; + } + } + + ptr = ptr->nextScriptPtr; + + }while(ptr); + } +} + +} // End of namespace Cruise -- cgit v1.2.3