Ticket #8841: script.patch
File script.patch, 135.2 KB (added by , 17 years ago) |
---|
-
engines/cine/script.h
27 27 #define CINE_SCRIPT_H 28 28 29 29 #include "common/savefile.h" 30 #include "common/array.h" 31 #include "common/list.h" 32 #include "common/ptr.h" 30 33 31 34 namespace Cine { 32 35 33 36 #define SCRIPT_STACK_SIZE 50 37 #define LOCAL_VARS_SIZE 50 34 38 39 /*! \brief Fixed size array of script variables. 40 * 41 * Array size can be set in constructors, once the instance is created, 42 * it cannot be changed directly. 43 */ 44 45 class FWScript; 46 47 typedef int (FWScript::*opFunc)(); 48 49 struct Opcode { 50 opFunc proc; 51 const char *args; 52 }; 53 54 /*! \brief Fixed size array for script variables 55 */ 35 56 class ScriptVars { 36 57 private: 37 unsigned int _size; 38 int16 *_vars; 58 unsigned int _size; ///< Size of array 59 int16 *_vars; ///< Variable values 39 60 40 61 public: 62 // Explicit to prevent var=0 instead of var[i]=0 typos. 41 63 explicit ScriptVars(unsigned int len = 50); 42 64 ScriptVars(Common::InSaveFile &fHandle, unsigned int len = 50); 43 65 ScriptVars(const ScriptVars &src); … … 47 69 int16 &operator[](unsigned int idx); 48 70 int16 operator[](unsigned int idx) const; 49 71 50 void save(Common::OutSaveFile &fHandle) ;51 void save(Common::OutSaveFile &fHandle, unsigned int len) ;72 void save(Common::OutSaveFile &fHandle) const; 73 void save(Common::OutSaveFile &fHandle, unsigned int len) const; 52 74 void load(Common::InSaveFile &fHandle); 53 75 void load(Common::InSaveFile &fHandle, unsigned int len); 54 76 void reset(void); 55 77 }; 56 78 57 struct ScriptStruct { 58 byte *ptr; 59 uint16 size; 60 int16 stack[SCRIPT_STACK_SIZE]; 79 class FWScriptInfo; 80 81 /*! \brief Script bytecode and initial labels, ScriptStruct replacement. 82 * 83 * _data is one byte longer to make sure strings in bytecode are properly 84 * terminated 85 */ 86 class RawScript { 87 private: 88 uint16 _size; ///< Bytecode length 89 byte *_data; ///< Script bytecode 90 ScriptVars _labels; ///< Initial script labels 91 92 protected: 93 void computeLabels(const FWScriptInfo &info); 94 uint16 getNextLabel(const FWScriptInfo &info, uint16 offset) const; 95 96 public: 97 explicit RawScript(uint16 size); 98 RawScript(const FWScriptInfo &info, const byte *data, uint16 size); 99 RawScript(const RawScript &src); 100 ~RawScript(void); 101 102 RawScript &operator=(const RawScript &src); 103 104 void setData(const FWScriptInfo &info, const byte *data); 105 /*! \brief Size of script 106 * \return Size of script 107 */ 108 uint16 size(void) const { return _size; } 109 const ScriptVars &labels(void) const; 110 byte getByte(unsigned int pos) const; 111 uint16 getWord(unsigned int pos) const; 112 const char *getString(unsigned int pos) const; 113 uint16 getLabel(const FWScriptInfo &info, byte index, uint16 offset) const; 61 114 }; 62 115 116 /*! \brief Object script class, RelObjectScript replacement 117 * 118 * Script parameters are not used, this class is required by different 119 * script initialization of object scripts 120 */ 121 class RawObjectScript : public RawScript { 122 private: 123 int16 _runCount; ///< How many times the script was used 124 uint16 _param1; ///< Additional parameter not used at the moment 125 uint16 _param2; ///< Additional parameter not used at the moment 126 uint16 _param3; ///< Additional parameter not used at the moment 127 128 public: 129 RawObjectScript(uint16 size, uint16 p1, uint16 p2, uint16 p3); 130 RawObjectScript(const FWScriptInfo &info, const byte *data, uint16 size, uint16 p1, uint16 p2, uint16 p3); 131 132 /// \brief Read run count 133 /// \return Run count 134 int16 runCount(void) const { return _runCount; } 135 /// \brief Run the script one more time 136 /// \return Run count before incrementation 137 int16 run(void) { return _runCount++; } 138 139 /// \brief Get the first object script parameter 140 /// \return First script parameter 141 uint16 param1(void) const { return _param1; } 142 /// \brief Get the second object script parameter 143 /// \return Second script parameter 144 uint16 param2(void) const { return _param2; } 145 /// \brief Get the third object script parameter 146 /// \return Third script parameter 147 uint16 param3(void) const { return _param3; } 148 }; 149 150 /*! \brief Future Wars script, prcLinkedListStruct replacement 151 * \todo Rewrite _globalVars initialization 152 */ 153 class FWScript { 154 private: 155 const RawScript &_script; ///< Script bytecode reference 156 uint16 _pos; ///< Current position in script 157 uint16 _line; ///< Current opcode index in bytecode for debugging 158 uint16 _compare; ///< Last compare result 159 int16 _index; ///< Index in script table 160 ScriptVars _labels; ///< Current script labels 161 ScriptVars _localVars; ///< Local script variables 162 ScriptVars &_globalVars; ///< Global variables reference 163 FWScriptInfo *_info; ///< Script info 164 165 static const Opcode _opcodeTable[]; 166 static const unsigned int _numOpcodes; 167 168 protected: 169 int o1_modifyObjectParam(); 170 int o1_getObjectParam(); 171 int o1_addObjectParam(); 172 int o1_subObjectParam(); 173 int o1_add2ObjectParam(); 174 int o1_sub2ObjectParam(); 175 int o1_compareObjectParam(); 176 int o1_setupObject(); 177 int o1_checkCollision(); 178 int o1_loadVar(); 179 int o1_addVar(); 180 int o1_subVar(); 181 int o1_mulVar(); 182 int o1_divVar(); 183 int o1_compareVar(); 184 int o1_modifyObjectParam2(); 185 int o1_loadMask0(); 186 int o1_unloadMask0(); 187 int o1_addToBgList(); 188 int o1_loadMask1(); 189 int o1_unloadMask1(); 190 int o1_loadMask4(); 191 int o1_unloadMask4(); 192 int o1_addSpriteFilledToBgList(); 193 int o1_op1B(); 194 int o1_label(); 195 int o1_goto(); 196 int o1_gotoIfSup(); 197 int o1_gotoIfSupEqu(); 198 int o1_gotoIfInf(); 199 int o1_gotoIfInfEqu(); 200 int o1_gotoIfEqu(); 201 int o1_gotoIfDiff(); 202 int o1_removeLabel(); 203 int o1_loop(); 204 int o1_startGlobalScript(); 205 int o1_endGlobalScript(); 206 int o1_loadAnim(); 207 int o1_loadBg(); 208 int o1_loadCt(); 209 int o1_loadPart(); 210 int o1_closePart(); 211 int o1_loadNewPrcName(); 212 int o1_requestCheckPendingDataLoad(); 213 int o1_blitAndFade(); 214 int o1_fadeToBlack(); 215 int o1_transformPaletteRange(); 216 int o1_setDefaultMenuColor2(); 217 int o1_palRotate(); 218 int o1_break(); 219 int o1_endScript(); 220 int o1_message(); 221 int o1_loadGlobalVar(); 222 int o1_compareGlobalVar(); 223 int o1_declareFunctionName(); 224 int o1_freePartRange(); 225 int o1_unloadAllMasks(); 226 int o1_setScreenDimensions(); 227 int o1_displayBackground(); 228 int o1_initializeZoneData(); 229 int o1_setZoneDataEntry(); 230 int o1_getZoneDataEntry(); 231 int o1_setDefaultMenuColor(); 232 int o1_allowPlayerInput(); 233 int o1_disallowPlayerInput(); 234 int o1_changeDataDisk(); 235 int o1_loadMusic(); 236 int o1_playMusic(); 237 int o1_fadeOutMusic(); 238 int o1_stopSample(); 239 int o1_op71(); 240 int o1_op72(); 241 int o1_op73(); 242 int o1_playSample(); 243 int o1_disableSystemMenu(); 244 int o1_loadMask5(); 245 int o1_unloadMask5(); 246 247 // pointers to member functions in C++ suck... 248 int o2_loadPart(); 249 int o2_addSeqListElement(); 250 int o2_removeSeq(); 251 int o2_playSample(); 252 int o2_playSampleAlt(); 253 int o2_op81(); 254 int o2_op82(); 255 int o2_isSeqRunning(); 256 int o2_gotoIfSupNearest(); 257 int o2_gotoIfSupEquNearest(); 258 int o2_gotoIfInfNearest(); 259 int o2_gotoIfInfEquNearest(); 260 int o2_gotoIfEquNearest(); 261 int o2_gotoIfDiffNearest(); 262 int o2_startObjectScript(); 263 int o2_stopObjectScript(); 264 int o2_op8D(); 265 int o2_addBackground(); 266 int o2_removeBackground(); 267 int o2_loadAbs(); 268 int o2_loadBg(); 269 int o2_wasZoneChecked(); 270 int o2_op9B(); 271 int o2_op9C(); 272 int o2_useBgScroll(); 273 int o2_setAdditionalBgVScroll(); 274 int o2_op9F(); 275 int o2_addGfxElementA0(); 276 int o2_opA1(); 277 int o2_opA2(); 278 int o2_opA3(); 279 int o2_loadMask22(); 280 int o2_unloadMask22(); 281 282 byte getNextByte(); 283 uint16 getNextWord(); 284 const char *getNextString(); 285 286 void load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos); 287 288 FWScript(const RawScript &script, int16 index, FWScriptInfo *info); 289 FWScript(RawObjectScript &script, int16 index, FWScriptInfo *info); 290 FWScript(const FWScript &src, FWScriptInfo *info); 291 292 public: 293 FWScript(const RawScript &script, int16 index); 294 // FWScript(const RawObjectScript &script, int16 index); 295 FWScript(const FWScript &src); 296 ~FWScript(void); 297 298 int execute(); 299 void save(Common::OutSaveFile &fHandle) const; 300 301 /*! \brief Index in script table 302 * \return Index in script table 303 */ 304 int16 index(void) const { return _index; } 305 306 friend class FWScriptInfo; 307 308 // workaround for bug in g++ which prevents protected member functions 309 // of FWScript from being used in OSScript::_opcodeTable[] 310 // initialization ("error: protected within this context") 311 friend class OSScript; 312 }; 313 314 /*! \brief Operation Stealth script, prcLinkedListStruct replacement 315 */ 316 class OSScript : public FWScript { 317 private: 318 static const Opcode _opcodeTable[]; 319 static const unsigned int _numOpcodes; 320 321 protected: 322 void load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos); 323 324 public: 325 OSScript(const RawScript &script, int16 index); 326 OSScript(RawObjectScript &script, int16 index); 327 OSScript(const OSScript &src); 328 329 friend class OSScriptInfo; 330 }; 331 332 /*! \brief Future Wars script factory and info 333 */ 334 class FWScriptInfo { 335 protected: 336 virtual opFunc opcodeHandler(byte opcode) const; 337 338 public: 339 virtual ~FWScriptInfo() {} 340 341 virtual const char *opcodeInfo(byte opcode) const; 342 virtual FWScript *create(const RawScript &script, int16 index) const; 343 virtual FWScript *create(const RawObjectScript &script, int16 index) const; 344 virtual FWScript *create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const; 345 virtual FWScript *create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const; 346 347 friend class FWScript; 348 }; 349 350 /*! \brief Operation Stealth script factory and info 351 */ 352 class OSScriptInfo : public FWScriptInfo { 353 protected: 354 virtual opFunc opcodeHandler(byte opcode) const; 355 356 public: 357 virtual ~OSScriptInfo() {} 358 359 virtual const char *opcodeInfo(byte opcode) const; 360 virtual FWScript *create(const RawScript &script, int16 index) const; 361 virtual FWScript *create(const RawObjectScript &script, int16 index) const; 362 virtual FWScript *create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const; 363 virtual FWScript *create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const; 364 365 friend class FWScript; 366 }; 367 368 typedef Common::SharedPtr<FWScript> ScriptPtr; 369 typedef Common::SharedPtr<RawScript> RawScriptPtr; 370 typedef Common::SharedPtr<RawObjectScript> RawObjectScriptPtr; 371 typedef Common::List<ScriptPtr> ScriptList; 372 typedef Common::Array<RawScriptPtr> RawScriptArray; 373 typedef Common::Array<RawObjectScriptPtr> RawObjectScriptArray; 374 63 375 #define NUM_MAX_SCRIPT 50 64 376 65 extern ScriptStruct scriptTable[NUM_MAX_SCRIPT]; 377 extern RawScriptArray scriptTable; 378 extern FWScriptInfo *scriptInfo; 66 379 67 380 void setupOpcodes(); 68 381 69 void computeScriptStack(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize);70 382 void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 scriptIdx); 71 383 void dumpScript(char *dumpName); 72 384 … … 79 391 int16 checkCollision(int16 objIdx, int16 x, int16 y, int16 numZones, int16 zoneIdx); 80 392 81 393 void runObjectScript(int16 entryIdx); 82 int16 stopObjectScript(int16 entryIdx);83 394 84 395 void executeList1(void); 85 396 void executeList0(void); … … 87 398 void purgeList1(void); 88 399 void purgeList0(void); 89 400 90 void o1_modifyObjectParam();91 void o1_getObjectParam();92 void o1_addObjectParam();93 void o1_subObjectParam();94 void o1_add2ObjectParam();95 void o1_sub2ObjectParam();96 void o1_compareObjectParam();97 void o1_setupObject();98 void o1_checkCollision();99 void o1_loadVar();100 void o1_addVar();101 void o1_subVar();102 void o1_mulVar();103 void o1_divVar();104 void o1_compareVar();105 void o1_modifyObjectParam2();106 void o1_loadMask0();107 void o1_unloadMask0();108 void o1_addToBgList();109 void o1_loadMask1();110 void o1_unloadMask1();111 void o1_loadMask4();112 void o1_unloadMask4();113 void o1_addSpriteFilledToBgList();114 void o1_op1B();115 void o1_label();116 void o1_goto();117 void o1_gotoIfSup();118 void o1_gotoIfSupEqu();119 void o1_gotoIfInf();120 void o1_gotoIfInfEqu();121 void o1_gotoIfEqu();122 void o1_gotoIfDiff();123 void o1_removeLabel();124 void o1_loop();125 void o1_startGlobalScript();126 void o1_endGlobalScript();127 void o1_loadAnim();128 void o1_loadBg();129 void o1_loadCt();130 void o1_loadPart();131 void o1_closePart();132 void o1_loadNewPrcName();133 void o1_requestCheckPendingDataLoad();134 void o1_blitAndFade();135 void o1_fadeToBlack();136 void o1_transformPaletteRange();137 void o1_setDefaultMenuColor2();138 void o1_palRotate();139 void o1_break();140 void o1_endScript();141 void o1_message();142 void o1_loadGlobalVar();143 void o1_compareGlobalVar();144 void o1_declareFunctionName();145 void o1_freePartRange();146 void o1_unloadAllMasks();147 void o1_setScreenDimensions();148 void o1_displayBackground();149 void o1_initializeZoneData();150 void o1_setZoneDataEntry();151 void o1_getZoneDataEntry();152 void o1_setDefaultMenuColor();153 void o1_allowPlayerInput();154 void o1_disallowPlayerInput();155 void o1_changeDataDisk();156 void o1_loadMusic();157 void o1_playMusic();158 void o1_fadeOutMusic();159 void o1_stopSample();160 void o1_op71();161 void o1_op72();162 void o1_op73();163 void o1_playSample();164 void o1_playSample();165 void o1_disableSystemMenu();166 void o1_loadMask5();167 void o1_unloadMask5();168 169 void o2_loadPart();170 void o2_addSeqListElement();171 void o2_removeSeq();172 void o2_playSample();173 void o2_playSampleAlt();174 void o2_op81();175 void o2_op82();176 void o2_isSeqRunning();177 void o2_gotoIfSupNearest();178 void o2_gotoIfSupEquNearest();179 void o2_gotoIfInfNearest();180 void o2_gotoIfInfEquNearest();181 void o2_gotoIfEquNearest();182 void o2_gotoIfDiffNearest();183 void o2_startObjectScript();184 void o2_stopObjectScript();185 void o2_op8D();186 void o2_addBackground();187 void o2_removeBackground();188 void o2_loadAbs();189 void o2_loadBg();190 void o2_wasZoneChecked();191 void o2_op9B();192 void o2_op9C();193 void o2_useBgScroll();194 void o2_setAdditionalBgVScroll();195 void o2_op9F();196 void o2_addGfxElementA0();197 void o2_opA1();198 void o2_opA2();199 void o2_opA3();200 void o2_loadMask22();201 void o2_unloadMask22();202 203 401 } // End of namespace Cine 204 402 205 403 #endif -
engines/cine/rel.cpp
31 31 32 32 namespace Cine { 33 33 34 R elObjectScript relTable[NUM_MAX_REL];34 RawObjectScriptArray relTable; ///< Object script bytecode table 35 35 36 void resetObjectScriptHead(void) { 37 objScriptList.next = NULL; 38 objScriptList.scriptIdx = -1; 39 } 40 41 void releaseObjectScripts(void) { 42 prcLinkedListStruct *currentHead = objScriptList.next; 43 44 while (currentHead) { 45 prcLinkedListStruct *temp; 46 47 assert(currentHead); 48 49 temp = currentHead->next; 50 51 delete currentHead; 52 53 currentHead = temp; 54 } 55 56 resetObjectScriptHead(); 57 } 58 36 /*! \todo Is script size of 0 valid? 37 * \todo Fix script dump code 38 */ 59 39 void loadRel(char *pRelName) { 60 40 uint16 numEntry; 61 41 uint16 i; 42 uint16 size, p1, p2, p3; 62 43 byte *ptr, *dataPtr; 63 44 64 45 checkDataDisk(-1); 65 46 66 for (i = 0; i < NUM_MAX_REL; i++) { 67 if (relTable[i].data) { 68 free(relTable[i].data); 69 relTable[i].data = NULL; 70 relTable[i].size = 0; 71 } 72 } 47 objectScripts.clear(); 48 relTable.clear(); 73 49 74 50 ptr = dataPtr = readBundleFile(findFileInBundle(pRelName)); 75 51 … … 77 53 78 54 numEntry = READ_BE_UINT16(ptr); ptr += 2; 79 55 80 assert(numEntry <= NUM_MAX_REL);81 82 56 for (i = 0; i < numEntry; i++) { 83 relTable[i].size = READ_BE_UINT16(ptr); ptr += 2; 84 relTable[i].obj1Param1 = READ_BE_UINT16(ptr); ptr += 2; 85 relTable[i].obj1Param2 = READ_BE_UINT16(ptr); ptr += 2; 86 relTable[i].obj2Param = READ_BE_UINT16(ptr); ptr += 2; 87 relTable[i].runCount = 0; 57 size = READ_BE_UINT16(ptr); ptr += 2; 58 p1 = READ_BE_UINT16(ptr); ptr += 2; 59 p2 = READ_BE_UINT16(ptr); ptr += 2; 60 p3 = READ_BE_UINT16(ptr); ptr += 2; 61 RawObjectScriptPtr tmp(new RawObjectScript(size, p1, p2, p3)); 62 assert(tmp); 63 relTable.push_back(tmp); 88 64 } 89 65 90 66 for (i = 0; i < numEntry; i++) { 91 if (relTable[i].size) { 92 relTable[i].data = (byte *)malloc(relTable[i].size); 93 94 assert(relTable[i].data); 95 96 memcpy(relTable[i].data, ptr, relTable[i].size); 97 ptr += relTable[i].size; 67 size = relTable[i]->size(); 68 // TODO: delete the test? 69 if (size) { 70 relTable[i]->setData(*scriptInfo, ptr); 71 ptr += size; 98 72 } 99 73 } 100 74 -
engines/cine/various.cpp
124 124 // } 125 125 } 126 126 127 int16 stopObjectScript(int16 entryIdx) {128 prcLinkedListStruct *currentHead = &objScriptList;129 prcLinkedListStruct *tempHead = currentHead;130 131 currentHead = tempHead->next;132 133 while (currentHead) {134 if (currentHead->scriptIdx == entryIdx) {135 currentHead->scriptIdx = -1;136 return 0;137 }138 139 currentHead = currentHead->next;140 }141 142 return -1;143 }144 145 127 void runObjectScript(int16 entryIdx) { 146 uint16 i; 147 prcLinkedListStruct *pNewElement; 148 prcLinkedListStruct *currentHead = &objScriptList; 149 prcLinkedListStruct *tempHead = currentHead; 150 151 currentHead = tempHead->next; 152 153 while (currentHead) { 154 tempHead = currentHead; 155 156 assert(tempHead); 157 158 currentHead = tempHead->next; 159 } 160 161 pNewElement = new prcLinkedListStruct; 162 163 assert(pNewElement); 164 165 pNewElement->next = tempHead->next; 166 tempHead->next = pNewElement; 167 168 // copy the stack into the script instance 169 for (i = 0; i < SCRIPT_STACK_SIZE; i++) { 170 pNewElement->stack[i] = 0; 171 } 172 173 pNewElement->compareResult = 0; 174 pNewElement->scriptPosition = 0; 175 176 pNewElement->scriptPtr = (byte *)relTable[entryIdx].data; 177 pNewElement->scriptIdx = entryIdx; 178 179 if (g_cine->getGameType() == Cine::GType_OS) { 180 pNewElement->localVars[0] = relTable[entryIdx].runCount; 181 ++relTable[entryIdx].runCount; 182 } 183 184 computeScriptStack(pNewElement->scriptPtr, pNewElement->stack, relTable[entryIdx].size); 128 ScriptPtr tmp(scriptInfo->create(*relTable[entryIdx], entryIdx)); 129 assert(tmp); 130 objectScripts.push_back(tmp); 185 131 } 186 132 187 133 void addPlayerCommandMessage(int16 cmd) { … … 214 160 215 161 int16 getRelEntryForObject(uint16 param1, uint16 param2, SelectedObjStruct *pSelectedObject) { 216 162 int16 i; 217 int16 di= -1;163 int16 found = -1; 218 164 219 for (i = 0; i < NUM_MAX_REL; i++) {220 if (relTable[i] .data && relTable[i].obj1Param1 == param1 && relTable[i].obj1Param2== pSelectedObject->idx) {165 for (i = 0; i < (int16)relTable.size(); i++) { 166 if (relTable[i]->param1() == param1 && relTable[i]->param2() == pSelectedObject->idx) { 221 167 if (param2 == 1) { 222 di= i;168 found = i; 223 169 } else if (param2 == 2) { 224 if (relTable[i] .obj2Param== pSelectedObject->param) {225 di= i;170 if (relTable[i]->param3() == pSelectedObject->param) { 171 found = i; 226 172 } 227 173 } 228 174 } 229 175 230 if ( di!= -1)176 if (found != -1) 231 177 break; 232 178 } 233 179 234 return di;180 return found; 235 181 } 236 182 237 183 int16 getObjectUnderCursor(uint16 x, uint16 y) { … … 302 248 return true; 303 249 } 304 250 251 /*! \brief Restore script list item from savefile 252 * \param fHandle Savefile handlem open for reading 253 * \param isGlobal Restore object or global script? 254 */ 305 255 void loadScriptFromSave(Common::InSaveFile *fHandle, bool isGlobal) { 306 int16 i; 256 ScriptVars localVars, labels; 257 uint16 compare, pos; 258 int16 idx; 307 259 308 prcLinkedListStruct *newElement; 309 prcLinkedListStruct *currentHead = &globalScriptsHead; 310 prcLinkedListStruct *tempHead = currentHead; 260 labels.load(*fHandle); 261 localVars.load(*fHandle); 311 262 312 currentHead = tempHead->next; 263 compare = fHandle->readUint16BE(); 264 pos = fHandle->readUint16BE(); 265 idx = fHandle->readUint16BE(); 313 266 314 while (currentHead) {315 tempHead = currentHead;316 currentHead = tempHead->next;267 // no way to reinitialize these 268 if (idx < 0) { 269 return; 317 270 } 318 271 319 newElement = new prcLinkedListStruct; 320 321 newElement->next = tempHead->next; 322 tempHead->next = newElement; 323 324 for (i = 0; i < SCRIPT_STACK_SIZE; i++) 325 newElement->stack[i] = fHandle->readUint16BE(); 326 327 newElement->localVars.load(*fHandle); 328 329 newElement->compareResult = fHandle->readUint16BE(); 330 newElement->scriptPosition = fHandle->readUint16BE(); 331 newElement->scriptIdx = fHandle->readUint16BE(); 332 333 if (isGlobal) 334 newElement->scriptPtr = scriptTable[newElement->scriptIdx].ptr; 335 else 336 newElement->scriptPtr = (byte *)relTable[newElement->scriptIdx].data; 272 // original code loaded everything into globalScripts, this should be 273 // the correct behavior 274 if (isGlobal) { 275 ScriptPtr tmp(scriptInfo->create(*scriptTable[idx], idx, labels, localVars, compare, pos)); 276 assert(tmp); 277 globalScripts.push_back(tmp); 278 } else { 279 ScriptPtr tmp(scriptInfo->create(*relTable[idx], idx, labels, localVars, compare, pos)); 280 assert(tmp); 281 objectScripts.push_back(tmp); 282 } 337 283 } 338 284 339 285 void loadOverlayFromSave(Common::InSaveFile *fHandle) { … … 370 316 currentHead->previous = newElement; 371 317 } 372 318 373 void setupScriptList(bool isGlobal) {374 prcLinkedListStruct *currentHead;375 376 if (isGlobal)377 currentHead = globalScriptsHead.next;378 else379 currentHead = objScriptList.next;380 381 while (currentHead) {382 if (isGlobal)383 currentHead->scriptPtr = scriptTable[currentHead->scriptIdx].ptr;384 else385 currentHead->scriptPtr = (byte *)relTable[currentHead->scriptIdx].data;386 currentHead = currentHead->next;387 }388 }389 390 319 bool CineEngine::makeLoad(char *saveName) { 391 320 int16 i; 392 321 int16 size; 322 bool oldSave = false; 393 323 Common::InSaveFile *fHandle; 394 324 395 325 fHandle = g_saveFileMan->openForLoading(saveName); … … 408 338 // if (g_cine->getGameType() == Cine::GType_OS) { 409 339 // freeUnkList(); 410 340 // } 411 freePrcLinkedList();412 releaseObjectScripts();413 341 freeBgIncrustList(); 414 342 closePart(); 415 343 416 for (i = 0; i < NUM_MAX_REL; i++) { 417 if (relTable[i].data) { 418 free(relTable[i].data); 419 relTable[i].data = NULL; 420 relTable[i].size = 0; 421 relTable[i].obj1Param1 = 0; 422 relTable[i].obj1Param2 = 0; 423 relTable[i].obj2Param = 0; 424 } 425 } 344 objectScripts.clear(); 345 globalScripts.clear(); 346 relTable.clear(); 347 scriptTable.clear(); 426 348 427 for (i = 0; i < NUM_MAX_SCRIPT; i++) {428 if (scriptTable[i].ptr) {429 free(scriptTable[i].ptr);430 scriptTable[i].ptr = NULL;431 scriptTable[i].size = 0;432 }433 }434 435 349 for (i = 0; i < NUM_MAX_MESSAGE; i++) { 436 350 messageTable[i].len = 0; 437 351 … … 491 405 fHandle->read(currentBgName[0], 13); 492 406 fHandle->read(currentCtName, 13); 493 407 408 checkDataDisk(currentDisk); 409 410 if (strlen(currentPartName)) { 411 loadPart(currentPartName); 412 } 413 414 if (strlen(currentPrcName)) { 415 loadPrc(currentPrcName); 416 } 417 418 if (strlen(currentRelName)) { 419 loadRel(currentRelName); 420 } 421 494 422 fHandle->readUint16BE(); 495 423 fHandle->readUint16BE(); 496 424 … … 539 467 540 468 fHandle->readUint16BE(); 541 469 fHandle->readUint16BE(); 470 471 animDataTable[0].width = fHandle->readUint16BE(); 472 animDataTable[0].var1 = fHandle->readUint16BE(); 473 animDataTable[0].bpp = fHandle->readUint16BE(); 474 animDataTable[0].height = fHandle->readUint16BE(); 475 animDataTable[0].ptr1 = NULL; 476 animDataTable[0].ptr2 = NULL; 477 animDataTable[0].fileIdx = fHandle->readSint16BE(); 478 animDataTable[0].frameIdx = fHandle->readSint16BE(); 479 fHandle->read(animDataTable[0].name, 10); 542 480 543 for (i = 0; i < NUM_MAX_ANIMDATA; i++) { 481 // ugly hack that may not work 482 // guess whether we're loading 0.10.0 buggy save or original save 483 // original save has 8 extra almost meaningless bytes before fileIdx, 484 // therefore name[8] will be non-zero 485 // 9-character part name in 0.10.0 means BIG trouble, luckily 486 // that can't happen in unmodified game 487 if (animDataTable[0].name[8] != 0) { 488 oldSave = true; 489 animDataTable[0].refresh = (animDataTable[0].fileIdx || 490 animDataTable[0].frameIdx) ? 1 : 0; 491 Common::MemoryReadStream readS((byte*)animDataTable[0].name+4, 10); 492 animDataTable[0].fileIdx = readS.readUint16BE(); 493 animDataTable[0].frameIdx = readS.readUint16BE(); 494 animDataTable[0].name[0] = animDataTable[0].name[8]; 495 animDataTable[0].name[1] = animDataTable[0].name[9]; 496 fHandle->read(animDataTable[0].name+2, 8); 497 } else { 498 animDataTable[0].refresh = (fHandle->readByte() != 0); 499 } 500 501 for (i = 1; i < NUM_MAX_ANIMDATA; i++) { 544 502 animDataTable[i].width = fHandle->readUint16BE(); 545 503 animDataTable[i].var1 = fHandle->readUint16BE(); 546 504 animDataTable[i].bpp = fHandle->readUint16BE(); 547 505 animDataTable[i].height = fHandle->readUint16BE(); 506 if(oldSave) { 507 animDataTable[i].refresh = (fHandle->readUint32BE() != 0); 508 fHandle->readUint32BE(); 509 } 548 510 animDataTable[i].ptr1 = NULL; 549 511 animDataTable[i].ptr2 = NULL; 550 512 animDataTable[i].fileIdx = fHandle->readSint16BE(); 551 513 animDataTable[i].frameIdx = fHandle->readSint16BE(); 552 514 fHandle->read(animDataTable[i].name, 10); 553 animDataTable[i].refresh = (fHandle->readByte() != 0); 515 if(!oldSave) { 516 animDataTable[i].refresh = (fHandle->readByte() != 0); 517 } 554 518 } 555 519 556 520 // TODO: handle screen params (really required ?) … … 583 547 584 548 delete fHandle; 585 549 586 checkDataDisk(currentDisk);587 588 if (strlen(currentPartName)) {589 loadPart(currentPartName);590 }591 592 if (strlen(currentPrcName)) {593 loadPrc(currentPrcName);594 setupScriptList(true);595 }596 597 if (strlen(currentRelName)) {598 loadRel(currentRelName);599 setupScriptList(false);600 }601 602 550 if (strlen(currentMsgName)) { 603 551 loadMsg(currentMsgName); 604 552 } … … 706 654 fHandle->writeUint16BE(animDataTable[i].var1); 707 655 fHandle->writeUint16BE(animDataTable[i].bpp); 708 656 fHandle->writeUint16BE(animDataTable[i].height); 657 // This file format looks like Delphine guys 658 // hacked it together 10 minutes before release deadline... 659 // Just because I write pointers to a file doesn't mean 660 // anyone should actually read those values back! 661 fHandle->writeUint32BE((uint32)animDataTable[i].ptr1); 662 fHandle->writeUint32BE((uint32)animDataTable[i].ptr2); 709 663 fHandle->writeSint16BE(animDataTable[i].fileIdx); 710 664 fHandle->writeSint16BE(animDataTable[i].frameIdx); 711 665 fHandle->write(animDataTable[i].name, 10); 712 713 // Horrifyingly, cinE used to dump the entire struct to the714 // save file, including the data pointers. While these pointers715 // would be invalid after loading, the loadResourcesFromSave()716 // function would still test if ptr1 was non-NULL, presumably717 // to see if the object was present in the room.718 719 fHandle->writeByte(animDataTable[i].ptr1 ? 1 : 0);720 666 } 721 667 722 668 fHandle->writeUint16BE(0); // Screen params, unhandled … … 727 673 fHandle->writeUint16BE(0); 728 674 729 675 { 730 int16 numScript = 0; 731 prcLinkedListStruct *currentHead = globalScriptsHead.next; 732 733 while (currentHead) { 734 numScript++; 735 currentHead = currentHead->next; 676 ScriptList::iterator it; 677 fHandle->writeUint16BE(globalScripts.size()); 678 for (it = globalScripts.begin(); it != globalScripts.end(); ++it) { 679 (*it)->save(*fHandle); 736 680 } 737 681 738 fHandle->writeUint16BE(numScript); 739 740 // actual save 741 currentHead = globalScriptsHead.next; 742 743 while (currentHead) { 744 for (i = 0; i < SCRIPT_STACK_SIZE; i++) { 745 fHandle->writeUint16BE(currentHead->stack[i]); 746 } 747 748 currentHead->localVars.save(*fHandle); 749 750 fHandle->writeUint16BE(currentHead->compareResult); 751 fHandle->writeUint16BE(currentHead->scriptPosition); 752 fHandle->writeUint16BE(currentHead->scriptIdx); 753 754 currentHead = currentHead->next; 682 fHandle->writeUint16BE(objectScripts.size()); 683 for (it = objectScripts.begin(); it != objectScripts.end(); ++it) { 684 (*it)->save(*fHandle); 755 685 } 756 686 } 757 687 758 688 { 759 689 int16 numScript = 0; 760 prcLinkedListStruct *currentHead = objScriptList.next;761 762 while (currentHead) {763 numScript++;764 currentHead = currentHead->next;765 }766 767 fHandle->writeUint16BE(numScript);768 769 // actual save770 currentHead = objScriptList.next;771 772 while (currentHead) {773 for (i = 0; i < SCRIPT_STACK_SIZE; i++) {774 fHandle->writeUint16BE(currentHead->stack[i]);775 }776 777 currentHead->localVars.save(*fHandle);778 779 fHandle->writeUint16BE(currentHead->compareResult);780 fHandle->writeUint16BE(currentHead->scriptPosition);781 fHandle->writeUint16BE(currentHead->scriptIdx);782 783 currentHead = currentHead->next;784 }785 }786 787 {788 int16 numScript = 0;789 690 overlayHeadElement *currentHead = overlayHead.next; 790 691 791 692 while (currentHead) { … … 2075 1976 2076 1977 void checkForPendingDataLoad(void) { 2077 1978 if (newPrcName[0] != 0) { 2078 freePrcLinkedList();2079 resetglobalScriptsHead();2080 2081 1979 loadPrc(newPrcName); 2082 1980 2083 1981 strcpy(currentPrcName, newPrcName); … … 2087 1985 } 2088 1986 2089 1987 if (newRelName[0] != 0) { 2090 releaseObjectScripts();2091 resetObjectScriptHead();2092 2093 1988 loadRel(newRelName); 2094 1989 2095 1990 strcpy(currentRelName, newRelName); -
engines/cine/prc.h
28 28 29 29 namespace Cine { 30 30 31 struct prcLinkedListStruct { 32 struct prcLinkedListStruct *next; 33 int16 stack[SCRIPT_STACK_SIZE]; 34 ScriptVars localVars; 35 uint16 compareResult; 36 uint16 scriptPosition; 37 byte *scriptPtr; 38 int16 scriptIdx; 39 }; 31 extern ScriptList globalScripts; 32 extern ScriptList objectScripts; 40 33 41 extern prcLinkedListStruct globalScriptsHead;42 extern prcLinkedListStruct objScriptList;43 44 void resetglobalScriptsHead(void);45 void freePrcLinkedList(void);46 34 void loadPrc(const char *pPrcName); 47 35 48 36 } // End of namespace Cine -
engines/cine/script.cpp
23 23 * 24 24 */ 25 25 26 /*! \file 27 * Script interpreter file 28 */ 26 29 27 30 #include "common/endian.h" 28 31 … … 31 34 #include "cine/object.h" 32 35 #include "cine/sound.h" 33 36 #include "cine/various.h" 37 #include "cine/script.h" 34 38 35 39 namespace Cine { 36 40 37 prcLinkedListStruct *_currentScriptElement; 38 byte *_currentScriptPtr; 39 uint16 _currentScriptParams; 40 uint16 _currentPosition; 41 uint16 _currentLine; 42 uint16 _closeScript; 41 uint16 compareVars(int16 a, int16 b); 42 void palRotate(byte a, byte b, byte c); 43 void removeSeq(uint16 param1, uint16 param2, uint16 param3); 44 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3); 45 void addGfxElementA0(int16 param1, int16 param2); 43 46 44 struct Opcode { 45 void (*proc)(); 46 const char *args; 47 const Opcode FWScript::_opcodeTable[] = { 48 /* 00 */ 49 { &FWScript::o1_modifyObjectParam, "bbw" }, 50 { &FWScript::o1_getObjectParam, "bbb" }, 51 { &FWScript::o1_addObjectParam, "bbw" }, 52 { &FWScript::o1_subObjectParam, "bbw" }, 53 /* 04 */ 54 { &FWScript::o1_add2ObjectParam, "bbw" }, 55 { &FWScript::o1_sub2ObjectParam, "bbw" }, 56 { &FWScript::o1_compareObjectParam, "bbw" }, 57 { &FWScript::o1_setupObject, "bwwww" }, 58 /* 08 */ 59 { &FWScript::o1_checkCollision, "bwwww" }, 60 { &FWScript::o1_loadVar, "bc" }, 61 { &FWScript::o1_addVar, "bc" }, 62 { &FWScript::o1_subVar, "bc" }, 63 /* 0C */ 64 { &FWScript::o1_mulVar, "bc" }, 65 { &FWScript::o1_divVar, "bc" }, 66 { &FWScript::o1_compareVar, "bc" }, 67 { &FWScript::o1_modifyObjectParam2, "bbb" }, 68 /* 10 */ 69 { 0, 0 }, 70 { 0, 0 }, 71 { 0, 0 }, 72 { &FWScript::o1_loadMask0, "b" }, 73 /* 14 */ 74 { &FWScript::o1_unloadMask0, "b" }, 75 { &FWScript::o1_addToBgList, "b" }, 76 { &FWScript::o1_loadMask1, "b" }, 77 { &FWScript::o1_unloadMask1, "b" }, 78 /* 18 */ 79 { &FWScript::o1_loadMask4, "b" }, 80 { &FWScript::o1_unloadMask4, "b" }, 81 { &FWScript::o1_addSpriteFilledToBgList, "b" }, 82 { &FWScript::o1_op1B, "" }, 83 /* 1C */ 84 { 0, 0 }, 85 { &FWScript::o1_label, "l" }, 86 { &FWScript::o1_goto, "b" }, 87 { &FWScript::o1_gotoIfSup, "b" }, 88 /* 20 */ 89 { &FWScript::o1_gotoIfSupEqu, "b" }, 90 { &FWScript::o1_gotoIfInf, "b" }, 91 { &FWScript::o1_gotoIfInfEqu, "b" }, 92 { &FWScript::o1_gotoIfEqu, "b" }, 93 /* 24 */ 94 { &FWScript::o1_gotoIfDiff, "b" }, 95 { &FWScript::o1_removeLabel, "b" }, 96 { &FWScript::o1_loop, "bb" }, 97 { 0, 0 }, 98 /* 28 */ 99 { 0, 0 }, 100 { 0, 0 }, 101 { 0, 0 }, 102 { 0, 0 }, 103 /* 2C */ 104 { 0, 0 }, 105 { 0, 0 }, 106 { 0, 0 }, 107 { 0, 0 }, 108 /* 30 */ 109 { 0, 0 }, 110 { &FWScript::o1_startGlobalScript, "b" }, 111 { &FWScript::o1_endGlobalScript, "b" }, 112 { 0, 0 }, 113 /* 34 */ 114 { 0, 0 }, 115 { 0, 0 }, 116 { 0, 0 }, 117 { 0, 0 }, 118 /* 38 */ 119 { 0, 0 }, 120 { 0, 0 }, 121 { 0, 0 }, 122 { &FWScript::o1_loadAnim, "s" }, 123 /* 3C */ 124 { &FWScript::o1_loadBg, "s" }, 125 { &FWScript::o1_loadCt, "s" }, 126 { 0, 0 }, 127 { &FWScript::o1_loadPart, "s" }, 128 /* 40 */ 129 { &FWScript::o1_closePart, "" }, 130 { &FWScript::o1_loadNewPrcName, "bs" }, 131 { &FWScript::o1_requestCheckPendingDataLoad, "" }, 132 { 0, 0 }, 133 /* 44 */ 134 { 0, 0 }, 135 { &FWScript::o1_blitAndFade, "" }, 136 { &FWScript::o1_fadeToBlack, "" }, 137 { &FWScript::o1_transformPaletteRange, "bbwww" }, 138 /* 48 */ 139 { 0, 0 }, 140 { &FWScript::o1_setDefaultMenuColor2, "b" }, 141 { &FWScript::o1_palRotate, "bbb" }, 142 { 0, 0 }, 143 /* 4C */ 144 { 0, 0 }, 145 { 0, 0 }, 146 { 0, 0 }, 147 { &FWScript::o1_break, "" }, 148 /* 50 */ 149 { &FWScript::o1_endScript, "x" }, 150 { &FWScript::o1_message, "bwwww" }, 151 { &FWScript::o1_loadGlobalVar, "bc" }, 152 { &FWScript::o1_compareGlobalVar, "bc" }, 153 /* 54 */ 154 { 0, 0 }, 155 { 0, 0 }, 156 { 0, 0 }, 157 { 0, 0 }, 158 /* 58 */ 159 { 0, 0 }, 160 { &FWScript::o1_declareFunctionName, "s" }, 161 { &FWScript::o1_freePartRange, "bb" }, 162 { &FWScript::o1_unloadAllMasks, "" }, 163 // 5C */ 164 { 0, 0 }, 165 { 0, 0 }, 166 { 0, 0 }, 167 { 0, 0 }, 168 /* 60 */ 169 { 0, 0 }, 170 { 0, 0 }, 171 { 0, 0 }, 172 { &FWScript::o1_setScreenDimensions, "wwww" }, 173 /* 64 */ 174 { &FWScript::o1_displayBackground, "" }, 175 { &FWScript::o1_initializeZoneData, "" }, 176 { &FWScript::o1_setZoneDataEntry, "bw" }, 177 { &FWScript::o1_getZoneDataEntry, "bb" }, 178 /* 68 */ 179 { &FWScript::o1_setDefaultMenuColor, "b" }, 180 { &FWScript::o1_allowPlayerInput, "" }, 181 { &FWScript::o1_disallowPlayerInput, "" }, 182 { &FWScript::o1_changeDataDisk, "b" }, 183 /* 6C */ 184 { 0, 0 }, 185 { &FWScript::o1_loadMusic, "s" }, 186 { &FWScript::o1_playMusic, "" }, 187 { &FWScript::o1_fadeOutMusic, "" }, 188 /* 70 */ 189 { &FWScript::o1_stopSample, "" }, 190 { &FWScript::o1_op71, "bw" }, 191 { &FWScript::o1_op72, "wbw" }, 192 { &FWScript::o1_op73, "wbw" }, 193 /* 74 */ 194 { 0, 0 }, 195 { 0, 0 }, 196 { 0, 0 }, 197 { &FWScript::o1_playSample, "bbwbww" }, 198 /* 78 */ 199 { &FWScript::o1_playSample, "bbwbww" }, 200 { &FWScript::o1_disableSystemMenu, "b" }, 201 { &FWScript::o1_loadMask5, "b" }, 202 { &FWScript::o1_unloadMask5, "b" } 47 203 }; 204 const unsigned int FWScript::_numOpcodes = ARRAYSIZE(FWScript::_opcodeTable); 48 205 49 const Opcode *_opcodeTable;50 int _numOpcodes;51 206 52 void setupOpcodes() { 53 static const Opcode opcodeTableFW[] = { 54 /* 00 */ 55 { o1_modifyObjectParam, "bbw" }, 56 { o1_getObjectParam, "bbb" }, 57 { o1_addObjectParam, "bbw" }, 58 { o1_subObjectParam, "bbw" }, 59 /* 04 */ 60 { o1_add2ObjectParam, "bbw" }, 61 { o1_sub2ObjectParam, "bbw" }, 62 { o1_compareObjectParam, "bbw" }, 63 { o1_setupObject, "bwwww" }, 64 /* 08 */ 65 { o1_checkCollision, "bwwww" }, 66 { o1_loadVar, "bc" }, 67 { o1_addVar, "bc" }, 68 { o1_subVar, "bc" }, 69 /* 0C */ 70 { o1_mulVar, "bc" }, 71 { o1_divVar, "bc" }, 72 { o1_compareVar, "bc" }, 73 { o1_modifyObjectParam2, "bbb" }, 74 /* 10 */ 75 { 0, 0 }, 76 { 0, 0 }, 77 { 0, 0 }, 78 { o1_loadMask0, "b" }, 79 /* 14 */ 80 { o1_unloadMask0, "b" }, 81 { o1_addToBgList, "b" }, 82 { o1_loadMask1, "b" }, 83 { o1_unloadMask1, "b" }, 84 /* 18 */ 85 { o1_loadMask4, "b" }, 86 { o1_unloadMask4, "b" }, 87 { o1_addSpriteFilledToBgList, "b" }, 88 { o1_op1B, "" }, 89 /* 1C */ 90 { 0, 0 }, 91 { o1_label, "l" }, 92 { o1_goto, "b" }, 93 { o1_gotoIfSup, "b" }, 94 /* 20 */ 95 { o1_gotoIfSupEqu, "b" }, 96 { o1_gotoIfInf, "b" }, 97 { o1_gotoIfInfEqu, "b" }, 98 { o1_gotoIfEqu, "b" }, 99 /* 24 */ 100 { o1_gotoIfDiff, "b" }, 101 { o1_removeLabel, "b" }, 102 { o1_loop, "bb" }, 103 { 0, 0 }, 104 /* 28 */ 105 { 0, 0 }, 106 { 0, 0 }, 107 { 0, 0 }, 108 { 0, 0 }, 109 /* 2C */ 110 { 0, 0 }, 111 { 0, 0 }, 112 { 0, 0 }, 113 { 0, 0 }, 114 /* 30 */ 115 { 0, 0 }, 116 { o1_startGlobalScript, "b" }, 117 { o1_endGlobalScript, "b" }, 118 { 0, 0 }, 119 /* 34 */ 120 { 0, 0 }, 121 { 0, 0 }, 122 { 0, 0 }, 123 { 0, 0 }, 124 /* 38 */ 125 { 0, 0 }, 126 { 0, 0 }, 127 { 0, 0 }, 128 { o1_loadAnim, "s" }, 129 /* 3C */ 130 { o1_loadBg, "s" }, 131 { o1_loadCt, "s" }, 132 { 0, 0 }, 133 { o1_loadPart, "s" }, 134 /* 40 */ 135 { o1_closePart, "" }, 136 { o1_loadNewPrcName, "bs" }, 137 { o1_requestCheckPendingDataLoad, "" }, 138 { 0, 0 }, 139 /* 44 */ 140 { 0, 0 }, 141 { o1_blitAndFade, "" }, 142 { o1_fadeToBlack, "" }, 143 { o1_transformPaletteRange, "bbwww" }, 144 /* 48 */ 145 { 0, 0 }, 146 { o1_setDefaultMenuColor2, "b" }, 147 { o1_palRotate, "bbb" }, 148 { 0, 0 }, 149 /* 4C */ 150 { 0, 0 }, 151 { 0, 0 }, 152 { 0, 0 }, 153 { o1_break, "" }, 154 /* 50 */ 155 { o1_endScript, "x" }, 156 { o1_message, "bwwww" }, 157 { o1_loadGlobalVar, "bc" }, 158 { o1_compareGlobalVar, "bc" }, 159 /* 54 */ 160 { 0, 0 }, 161 { 0, 0 }, 162 { 0, 0 }, 163 { 0, 0 }, 164 /* 58 */ 165 { 0, 0 }, 166 { o1_declareFunctionName, "s" }, 167 { o1_freePartRange, "bb" }, 168 { o1_unloadAllMasks, "" }, 169 // 5C */ 170 { 0, 0 }, 171 { 0, 0 }, 172 { 0, 0 }, 173 { 0, 0 }, 174 /* 60 */ 175 { 0, 0 }, 176 { 0, 0 }, 177 { 0, 0 }, 178 { o1_setScreenDimensions, "wwww" }, 179 /* 64 */ 180 { o1_displayBackground, "" }, 181 { o1_initializeZoneData, "" }, 182 { o1_setZoneDataEntry, "bw" }, 183 { o1_getZoneDataEntry, "bb" }, 184 /* 68 */ 185 { o1_setDefaultMenuColor, "b" }, 186 { o1_allowPlayerInput, "" }, 187 { o1_disallowPlayerInput, "" }, 188 { o1_changeDataDisk, "b" }, 189 /* 6C */ 190 { 0, 0 }, 191 { o1_loadMusic, "s" }, 192 { o1_playMusic, "" }, 193 { o1_fadeOutMusic, "" }, 194 /* 70 */ 195 { o1_stopSample, "" }, 196 { o1_op71, "bw" }, 197 { o1_op72, "wbw" }, 198 { o1_op73, "wbw" }, 199 /* 74 */ 200 { 0, 0 }, 201 { 0, 0 }, 202 { 0, 0 }, 203 { o1_playSample, "bbwbww" }, 204 /* 78 */ 205 { o1_playSample, "bbwbww" }, 206 { o1_disableSystemMenu, "b" }, 207 { o1_loadMask5, "b" }, 208 { o1_unloadMask5, "b" } 209 }; 207 const Opcode OSScript::_opcodeTable[] = { 208 /* 00 */ 209 { &FWScript::o1_modifyObjectParam, "bbw" }, 210 { &FWScript::o1_getObjectParam, "bbb" }, 211 { &FWScript::o1_addObjectParam, "bbw" }, 212 { &FWScript::o1_subObjectParam, "bbw" }, 213 /* 04 */ 214 { &FWScript::o1_add2ObjectParam, "bbw" }, 215 { &FWScript::o1_sub2ObjectParam, "bbw" }, 216 { &FWScript::o1_compareObjectParam, "bbw" }, 217 { &FWScript::o1_setupObject, "bwwww" }, 218 /* 08 */ 219 { &FWScript::o1_checkCollision, "bwwww" }, 220 { &FWScript::o1_loadVar, "bc" }, 221 { &FWScript::o1_addVar, "bc" }, 222 { &FWScript::o1_subVar, "bc" }, 223 /* 0C */ 224 { &FWScript::o1_mulVar, "bc" }, 225 { &FWScript::o1_divVar, "bc" }, 226 { &FWScript::o1_compareVar, "bc" }, 227 { &FWScript::o1_modifyObjectParam2, "bbb" }, 228 /* 10 */ 229 { 0, 0 }, 230 { 0, 0 }, 231 { 0, 0 }, 232 { &FWScript::o1_loadMask0, "b" }, 233 /* 14 */ 234 { &FWScript::o1_unloadMask0, "b" }, 235 { &FWScript::o1_addToBgList, "b" }, 236 { &FWScript::o1_loadMask1, "b" }, 237 { &FWScript::o1_unloadMask1, "b" }, 238 /* 18 */ 239 { &FWScript::o1_loadMask4, "b" }, 240 { &FWScript::o1_unloadMask4, "b" }, 241 { &FWScript::o1_addSpriteFilledToBgList, "b" }, 242 { &FWScript::o1_op1B, "" }, 243 /* 1C */ 244 { 0, 0 }, 245 { &FWScript::o1_label, "l" }, 246 { &FWScript::o1_goto, "b" }, 247 { &FWScript::o1_gotoIfSup, "b" }, 248 /* 20 */ 249 { &FWScript::o1_gotoIfSupEqu, "b" }, 250 { &FWScript::o1_gotoIfInf, "b" }, 251 { &FWScript::o1_gotoIfInfEqu, "b" }, 252 { &FWScript::o1_gotoIfEqu, "b" }, 253 /* 24 */ 254 { &FWScript::o1_gotoIfDiff, "b" }, 255 { &FWScript::o1_removeLabel, "b" }, 256 { &FWScript::o1_loop, "bb" }, 257 { 0, 0 }, 258 /* 28 */ 259 { 0, 0 }, 260 { 0, 0 }, 261 { 0, 0 }, 262 { 0, 0 }, 263 /* 2C */ 264 { 0, 0 }, 265 { 0, 0 }, 266 { 0, 0 }, 267 { 0, 0 }, 268 /* 30 */ 269 { 0, 0 }, 270 { &FWScript::o1_startGlobalScript, "b" }, 271 { &FWScript::o1_endGlobalScript, "b" }, 272 { 0, 0 }, 273 /* 34 */ 274 { 0, 0 }, 275 { 0, 0 }, 276 { 0, 0 }, 277 { 0, 0 }, 278 /* 38 */ 279 { 0, 0 }, 280 { 0, 0 }, 281 { 0, 0 }, 282 { &FWScript::o1_loadAnim, "s" }, 283 /* 3C */ 284 { &FWScript::o1_loadBg, "s" }, 285 { &FWScript::o1_loadCt, "s" }, 286 { 0, 0 }, 287 { &FWScript::o2_loadPart, "s" }, 288 /* 40 */ 289 { 0, 0 }, /* o1_closePart, triggered by some scripts (STARTA.PRC 4 for ex.) */ 290 { &FWScript::o1_loadNewPrcName, "bs" }, 291 { &FWScript::o1_requestCheckPendingDataLoad, "" }, 292 { 0, 0 }, 293 /* 44 */ 294 { 0, 0 }, 295 { &FWScript::o1_blitAndFade, "" }, 296 { &FWScript::o1_fadeToBlack, "" }, 297 { &FWScript::o1_transformPaletteRange, "bbwww" }, 298 /* 48 */ 299 { 0, 0 }, 300 { &FWScript::o1_setDefaultMenuColor2, "b" }, 301 { &FWScript::o1_palRotate, "bbb" }, 302 { 0, 0 }, 303 /* 4C */ 304 { 0, 0 }, 305 { 0, 0 }, 306 { 0, 0 }, 307 { &FWScript::o1_break, "" }, 308 /* 50 */ 309 { &FWScript::o1_endScript, "x" }, 310 { &FWScript::o1_message, "bwwww" }, 311 { &FWScript::o1_loadGlobalVar, "bc" }, 312 { &FWScript::o1_compareGlobalVar, "bc" }, 313 /* 54 */ 314 { 0, 0 }, 315 { 0, 0 }, 316 { 0, 0 }, 317 { 0, 0 }, 318 /* 58 */ 319 { 0, 0 }, 320 { &FWScript::o1_declareFunctionName, "s" }, 321 { &FWScript::o1_freePartRange, "bb" }, 322 { &FWScript::o1_unloadAllMasks, "" }, 323 // 5C */ 324 { 0, 0 }, 325 { 0, 0 }, 326 { 0, 0 }, 327 { 0, 0 }, 328 /* 60 */ 329 { 0, 0 }, 330 { 0, 0 }, 331 { 0, 0 }, 332 { &FWScript::o1_setScreenDimensions, "wwww" }, 333 /* 64 */ 334 { &FWScript::o1_displayBackground, "" }, 335 { &FWScript::o1_initializeZoneData, "" }, 336 { &FWScript::o1_setZoneDataEntry, "bw" }, 337 { &FWScript::o1_getZoneDataEntry, "bb" }, 338 /* 68 */ 339 { &FWScript::o1_setDefaultMenuColor, "b" }, 340 { &FWScript::o1_allowPlayerInput, "" }, 341 { &FWScript::o1_disallowPlayerInput, "" }, 342 { &FWScript::o1_changeDataDisk, "b" }, 343 /* 6C */ 344 { 0, 0 }, 345 { &FWScript::o1_loadMusic, "s" }, 346 { &FWScript::o1_playMusic, "" }, 347 { &FWScript::o1_fadeOutMusic, "" }, 348 /* 70 */ 349 { &FWScript::o1_stopSample, "" }, 350 { &FWScript::o1_op71, "bw" }, 351 { &FWScript::o1_op72, "wbw" }, 352 { &FWScript::o1_op72, "wbw" }, 353 /* 74 */ 354 { 0, 0 }, 355 { 0, 0 }, 356 { 0, 0 }, 357 { &FWScript::o2_playSample, "bbwbww" }, 358 /* 78 */ 359 { &FWScript::o2_playSampleAlt, "bbwbww" }, 360 { &FWScript::o1_disableSystemMenu, "b" }, 361 { &FWScript::o1_loadMask5, "b" }, 362 { &FWScript::o1_unloadMask5, "b" }, 363 /* 7C */ 364 { 0, 0 }, 365 { 0, 0 }, 366 { 0, 0 }, 367 { &FWScript::o2_addSeqListElement, "bbbbwww" }, 368 /* 80 */ 369 { &FWScript::o2_removeSeq, "bb" }, 370 { &FWScript::o2_op81, "" }, 371 { &FWScript::o2_op82, "bbw" }, 372 { &FWScript::o2_isSeqRunning, "bb" }, 373 /* 84 */ 374 { &FWScript::o2_gotoIfSupNearest, "b" }, 375 { &FWScript::o2_gotoIfSupEquNearest, "b" }, 376 { &FWScript::o2_gotoIfInfNearest, "b" }, 377 { &FWScript::o2_gotoIfInfEquNearest, "b" }, 378 /* 88 */ 379 { &FWScript::o2_gotoIfEquNearest, "b" }, 380 { &FWScript::o2_gotoIfDiffNearest, "b" }, 381 { 0, 0 }, 382 { &FWScript::o2_startObjectScript, "b" }, 383 /* 8C */ 384 { &FWScript::o2_stopObjectScript, "b" }, 385 { &FWScript::o2_op8D, "wwwwwwww" }, 386 { &FWScript::o2_addBackground, "bs" }, 387 { &FWScript::o2_removeBackground, "b" }, 388 /* 90 */ 389 { &FWScript::o2_loadAbs, "bs" }, 390 { &FWScript::o2_loadBg, "b" }, 391 { 0, 0 }, 392 { 0, 0 }, 393 /* 94 */ 394 { 0, 0 }, 395 { &FWScript::o1_changeDataDisk, "b" }, 396 { 0, 0 }, 397 { 0, 0 }, 398 /* 98 */ 399 { 0, 0 }, 400 { 0, 0 }, 401 { &FWScript::o2_wasZoneChecked, "" }, 402 { &FWScript::o2_op9B, "wwwwwwww" }, 403 /* 9C */ 404 { &FWScript::o2_op9C, "wwww" }, 405 { &FWScript::o2_useBgScroll, "b" }, 406 { &FWScript::o2_setAdditionalBgVScroll, "c" }, 407 { &FWScript::o2_op9F, "ww" }, 408 /* A0 */ 409 { &FWScript::o2_addGfxElementA0, "ww" }, 410 { &FWScript::o2_opA1, "ww" }, 411 { &FWScript::o2_opA2, "ww" }, 412 { &FWScript::o2_opA3, "ww" }, 413 /* A4 */ 414 { &FWScript::o2_loadMask22, "b" }, 415 { &FWScript::o2_unloadMask22, "b" }, 416 { 0, 0 }, 417 { 0, 0 }, 418 /* A8 */ 419 { 0, 0 }, 420 { &FWScript::o1_changeDataDisk, "b" } 421 }; 422 const unsigned int OSScript::_numOpcodes = ARRAYSIZE(OSScript::_opcodeTable); 210 423 211 // TODO: We need to verify the Operation Stealth opcodes. 424 FWScriptInfo *scriptInfo; ///< Script factory 425 RawScriptArray scriptTable; ///< Table of script bytecode 212 426 213 static const Opcode opcodeTableOS[] = { 214 /* 00 */ 215 { o1_modifyObjectParam, "bbw" }, 216 { o1_getObjectParam, "bbb" }, 217 { o1_addObjectParam, "bbw" }, 218 { o1_subObjectParam, "bbw" }, 219 /* 04 */ 220 { o1_add2ObjectParam, "bbw" }, 221 { o1_sub2ObjectParam, "bbw" }, 222 { o1_compareObjectParam, "bbw" }, 223 { o1_setupObject, "bwwww" }, 224 /* 08 */ 225 { o1_checkCollision, "bwwww" }, 226 { o1_loadVar, "bc" }, 227 { o1_addVar, "bc" }, 228 { o1_subVar, "bc" }, 229 /* 0C */ 230 { o1_mulVar, "bc" }, 231 { o1_divVar, "bc" }, 232 { o1_compareVar, "bc" }, 233 { o1_modifyObjectParam2, "bbb" }, 234 /* 10 */ 235 { 0, 0 }, 236 { 0, 0 }, 237 { 0, 0 }, 238 { o1_loadMask0, "b" }, 239 /* 14 */ 240 { o1_unloadMask0, "b" }, 241 { o1_addToBgList, "b" }, 242 { o1_loadMask1, "b" }, 243 { o1_unloadMask1, "b" }, 244 /* 18 */ 245 { o1_loadMask4, "b" }, 246 { o1_unloadMask4, "b" }, 247 { o1_addSpriteFilledToBgList, "b" }, 248 { o1_op1B, "" }, 249 /* 1C */ 250 { 0, 0 }, 251 { o1_label, "l" }, 252 { o1_goto, "b" }, 253 { o1_gotoIfSup, "b" }, 254 /* 20 */ 255 { o1_gotoIfSupEqu, "b" }, 256 { o1_gotoIfInf, "b" }, 257 { o1_gotoIfInfEqu, "b" }, 258 { o1_gotoIfEqu, "b" }, 259 /* 24 */ 260 { o1_gotoIfDiff, "b" }, 261 { o1_removeLabel, "b" }, 262 { o1_loop, "bb" }, 263 { 0, 0 }, 264 /* 28 */ 265 { 0, 0 }, 266 { 0, 0 }, 267 { 0, 0 }, 268 { 0, 0 }, 269 /* 2C */ 270 { 0, 0 }, 271 { 0, 0 }, 272 { 0, 0 }, 273 { 0, 0 }, 274 /* 30 */ 275 { 0, 0 }, 276 { o1_startGlobalScript, "b" }, 277 { o1_endGlobalScript, "b" }, 278 { 0, 0 }, 279 /* 34 */ 280 { 0, 0 }, 281 { 0, 0 }, 282 { 0, 0 }, 283 { 0, 0 }, 284 /* 38 */ 285 { 0, 0 }, 286 { 0, 0 }, 287 { 0, 0 }, 288 { o1_loadAnim, "s" }, 289 /* 3C */ 290 { o1_loadBg, "s" }, 291 { o1_loadCt, "s" }, 292 { 0, 0 }, 293 { o2_loadPart, "s" }, 294 /* 40 */ 295 { 0, 0 }, /* o1_closePart, triggered by some scripts (STARTA.PRC 4 for ex.) */ 296 { o1_loadNewPrcName, "bs" }, 297 { o1_requestCheckPendingDataLoad, "" }, 298 { 0, 0 }, 299 /* 44 */ 300 { 0, 0 }, 301 { o1_blitAndFade, "" }, 302 { o1_fadeToBlack, "" }, 303 { o1_transformPaletteRange, "bbwww" }, 304 /* 48 */ 305 { 0, 0 }, 306 { o1_setDefaultMenuColor2, "b" }, 307 { o1_palRotate, "bbb" }, 308 { 0, 0 }, 309 /* 4C */ 310 { 0, 0 }, 311 { 0, 0 }, 312 { 0, 0 }, 313 { o1_break, "" }, 314 /* 50 */ 315 { o1_endScript, "x" }, 316 { o1_message, "bwwww" }, 317 { o1_loadGlobalVar, "bc" }, 318 { o1_compareGlobalVar, "bc" }, 319 /* 54 */ 320 { 0, 0 }, 321 { 0, 0 }, 322 { 0, 0 }, 323 { 0, 0 }, 324 /* 58 */ 325 { 0, 0 }, 326 { o1_declareFunctionName, "s" }, 327 { o1_freePartRange, "bb" }, 328 { o1_unloadAllMasks, "" }, 329 // 5C */ 330 { 0, 0 }, 331 { 0, 0 }, 332 { 0, 0 }, 333 { 0, 0 }, 334 /* 60 */ 335 { 0, 0 }, 336 { 0, 0 }, 337 { 0, 0 }, 338 { o1_setScreenDimensions, "wwww" }, 339 /* 64 */ 340 { o1_displayBackground, "" }, 341 { o1_initializeZoneData, "" }, 342 { o1_setZoneDataEntry, "bw" }, 343 { o1_getZoneDataEntry, "bb" }, 344 /* 68 */ 345 { o1_setDefaultMenuColor, "b" }, 346 { o1_allowPlayerInput, "" }, 347 { o1_disallowPlayerInput, "" }, 348 { o1_changeDataDisk, "b" }, 349 /* 6C */ 350 { 0, 0 }, 351 { o1_loadMusic, "s" }, 352 { o1_playMusic, "" }, 353 { o1_fadeOutMusic, "" }, 354 /* 70 */ 355 { o1_stopSample, "" }, 356 { o1_op71, "bw" }, 357 { o1_op72, "wbw" }, 358 { o1_op72, "wbw" }, 359 /* 74 */ 360 { 0, 0 }, 361 { 0, 0 }, 362 { 0, 0 }, 363 { o2_playSample, "bbwbww" }, 364 /* 78 */ 365 { o2_playSampleAlt, "bbwbww" }, 366 { o1_disableSystemMenu, "b" }, 367 { o1_loadMask5, "b" }, 368 { o1_unloadMask5, "b" }, 369 /* 7C */ 370 { 0, 0 }, 371 { 0, 0 }, 372 { 0, 0 }, 373 { o2_addSeqListElement, "bbbbwww" }, 374 /* 80 */ 375 { o2_removeSeq, "bb" }, 376 { o2_op81, "" }, 377 { o2_op82, "bbw" }, 378 { o2_isSeqRunning, "bb" }, 379 /* 84 */ 380 { o2_gotoIfSupNearest, "b" }, 381 { o2_gotoIfSupEquNearest, "b" }, 382 { o2_gotoIfInfNearest, "b" }, 383 { o2_gotoIfInfEquNearest, "b" }, 384 /* 88 */ 385 { o2_gotoIfEquNearest, "b" }, 386 { o2_gotoIfDiffNearest, "b" }, 387 { 0, 0 }, 388 { o2_startObjectScript, "b" }, 389 /* 8C */ 390 { o2_stopObjectScript, "b" }, 391 { o2_op8D, "wwwwwwww" }, 392 { o2_addBackground, "bs" }, 393 { o2_removeBackground, "b" }, 394 /* 90 */ 395 { o2_loadAbs, "bs" }, 396 { o2_loadBg, "b" }, 397 { 0, 0 }, 398 { 0, 0 }, 399 /* 94 */ 400 { 0, 0 }, 401 { o1_changeDataDisk, "b" }, 402 { 0, 0 }, 403 { 0, 0 }, 404 /* 98 */ 405 { 0, 0 }, 406 { 0, 0 }, 407 { o2_wasZoneChecked, "" }, 408 { o2_op9B, "wwwwwwww" }, 409 /* 9C */ 410 { o2_op9C, "wwww" }, 411 { o2_useBgScroll, "b" }, 412 { o2_setAdditionalBgVScroll, "c" }, 413 { o2_op9F, "ww" }, 414 /* A0 */ 415 { o2_addGfxElementA0, "ww" }, 416 { o2_opA1, "ww" }, 417 { o2_opA2, "ww" }, 418 { o2_opA3, "ww" }, 419 /* A4 */ 420 { o2_loadMask22, "b" }, 421 { o2_unloadMask22, "b" }, 422 { 0, 0 }, 423 { 0, 0 }, 424 /* A8 */ 425 { 0, 0 }, 426 { o1_changeDataDisk, "b" } 427 }; 428 427 /*! \todo: replace with script subsystem 428 */ 429 void setupOpcodes() { 430 static FWScriptInfo fw; 431 static OSScriptInfo os; 429 432 if (g_cine->getGameType() == Cine::GType_FW) { 430 _opcodeTable = opcodeTableFW; 431 _numOpcodes = ARRAYSIZE(opcodeTableFW); 433 scriptInfo = &fw; 432 434 } else { 433 _opcodeTable = opcodeTableOS; 434 _numOpcodes = ARRAYSIZE(opcodeTableOS); 435 scriptInfo = &os; 435 436 } 436 437 } 437 438 438 byte getNextByte() { 439 byte val = *(_currentScriptPtr + _currentPosition); 440 _currentPosition++; 441 return val; 442 } 443 444 uint16 getNextWord() { 445 uint16 val = READ_BE_UINT16(_currentScriptPtr + _currentPosition); 446 _currentPosition += 2; 447 return val; 448 } 449 450 const char *getNextString() { 451 const char *val = (const char *)(_currentScriptPtr + _currentPosition); 452 _currentPosition += strlen(val) + 1; 453 return val; 454 } 455 456 // empty array 439 /*! \brief Allocate empty array 440 * \param len Size of array 441 * 442 * Explicit to prevent var=0 instead of var[i]=0 typos. 443 */ 457 444 ScriptVars::ScriptVars(unsigned int len) : _size(len), _vars(new int16[len]) { 458 445 assert(_vars); 459 446 reset(); 460 447 } 461 448 462 // read game save, for later use 449 /*! \brief Allocate array and read contents from savefile 450 * \param fHandle Savefile open for reading 451 * \param len Size of array 452 */ 463 453 ScriptVars::ScriptVars(Common::InSaveFile &fHandle, unsigned int len) 464 454 : _size(len), _vars(new int16[len]) { 465 455 … … 468 458 load(fHandle); 469 459 } 470 460 471 // copy constructor 461 /*! \brief Copy constructor 462 */ 472 463 ScriptVars::ScriptVars(const ScriptVars &src) : _size(src._size), _vars(new int16[_size]) { 473 464 assert(_vars); 474 465 memcpy(_vars, src._vars, _size * sizeof(int16)); 475 466 } 476 467 468 /*! \brief Destructor 469 */ 477 470 ScriptVars::~ScriptVars(void) { 478 471 delete[] _vars; 479 472 } 480 473 474 /*! \brief Assignment operator 475 */ 481 476 ScriptVars &ScriptVars::operator=(const ScriptVars &src) { 482 477 ScriptVars tmp(src); 483 478 int16 *tmpvars = _vars; … … 489 484 return *this; 490 485 } 491 486 492 // array access 487 /*! \brief Direct array item access 488 * \param idx Item index 489 * \return Reference to item 490 */ 493 491 int16 &ScriptVars::operator[](unsigned int idx) { 494 debugN(5, "assert(%d < %d) ", idx, _size);492 debugN(5, "assert(%d < %d)\n", idx, _size); 495 493 assert(idx < _size); 496 494 return _vars[idx]; 497 495 } 498 496 497 /*! \brief Direct read-only array item access 498 * \param idx Item index 499 * \return Copy of item 500 */ 499 501 int16 ScriptVars::operator[](unsigned int idx) const { 500 502 debugN(5, "assert(%d < %d)\n", idx, _size); 501 503 assert(idx < _size); 502 504 return _vars[idx]; 503 505 } 504 506 505 // dump to savefile 506 void ScriptVars::save(Common::OutSaveFile &fHandle) { 507 /*! \brief Savefile writer 508 * \param fHandle Savefile open for writing 509 */ 510 void ScriptVars::save(Common::OutSaveFile &fHandle) const { 507 511 save(fHandle, _size); 508 512 } 509 513 510 // globalVars[255] is not written to savefiles... 511 void ScriptVars::save(Common::OutSaveFile &fHandle, unsigned int len) { 514 /*! \brief Savefile writer with data length limit 515 * \param fHandle Savefile open for writing 516 * \param len Length of data to be written (len <= _size) 517 */ 518 void ScriptVars::save(Common::OutSaveFile &fHandle, unsigned int len) const { 512 519 debugN(5, "assert(%d <= %d)\n", len, _size); 513 520 assert(len <= _size); 514 521 for (unsigned int i = 0; i < len; i++) { … … 516 523 } 517 524 } 518 525 519 // read from savefile 526 /*! \brief Restore array from savefile 527 * \param fHandle Savefile open for reading 528 */ 520 529 void ScriptVars::load(Common::InSaveFile &fHandle) { 521 530 load(fHandle, _size); 522 531 } 523 532 533 /*! \brief Restore part of array from savefile 534 * \param fHandle Savefile open for reading 535 * \param len Length of data to be read 536 */ 524 537 void ScriptVars::load(Common::InSaveFile &fHandle, unsigned int len) { 525 538 debugN(5, "assert(%d <= %d)\n", len, _size); 526 539 assert(len <= _size); … … 529 542 } 530 543 } 531 544 545 /*! \brief Reset all values to 0 546 */ 532 547 void ScriptVars::reset(void) { 533 548 memset( _vars, 0, _size * sizeof(int16)); 534 549 } 535 550 536 void addGfxElementA0(int16 param1, int16 param2) { 537 overlayHeadElement *currentHead = &overlayHead; 538 overlayHeadElement *tempHead = currentHead; 539 overlayHeadElement *newElement; 551 /*! \brief Constructor for partial loading 552 * \param s Size of bytecode which will be added later 553 * 554 * This constructor _MUST_ be followed by setdata() method call before the 555 * instance can be used. It leaves the instance in partially invalid state. 556 */ 557 RawScript::RawScript(uint16 s) : _size(s), _data(NULL), 558 _labels(SCRIPT_STACK_SIZE) { } 540 559 541 currentHead = tempHead->next; 560 /*! \brief Complete constructor 561 * \param data Script bytecode 562 * \param s Bytecode length 563 */ 564 RawScript::RawScript(const FWScriptInfo &info, const byte *data, uint16 s) : 565 _size(s), _data(NULL), _labels(SCRIPT_STACK_SIZE) { 542 566 543 while (currentHead) { 544 if (objectTable[currentHead->objIdx].mask == objectTable[param1].mask) { 545 if (currentHead->type == 2 || currentHead->objIdx == 3) { 546 break; 547 } 548 } 567 setData(info, data); 568 } 549 569 550 tempHead = currentHead; 551 currentHead = currentHead->next; 552 } 570 /*! \brief Copy constructor 571 */ 572 RawScript::RawScript(const RawScript &src) : _size(src._size), 573 _data(new byte[_size+1]), _labels(src._labels) { 553 574 554 if (currentHead && currentHead->objIdx == param1 && currentHead->type == 20 && currentHead->x == param2) 555 return; 556 557 newElement = new overlayHeadElement; 558 559 newElement->next = tempHead->next; 560 tempHead->next = newElement; 561 562 newElement->objIdx = param1; 563 newElement->type = 20; 564 565 newElement->x = param2; 566 newElement->y = 0; 567 newElement->width = 0; 568 newElement->color = 0; 569 570 if (!currentHead) 571 currentHead = &overlayHead; 572 573 newElement->previous = currentHead->previous; 574 575 currentHead->previous = newElement; 575 assert(_data); 576 memcpy(_data, src._data, _size+1); 576 577 } 577 578 578 void removeSeq(uint16 param1, uint16 param2, uint16 param3) { 579 SeqListElement *currentHead = &seqList; 580 SeqListElement *tempHead = currentHead; 581 582 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { 583 tempHead = currentHead; 584 currentHead = tempHead->next; 585 } 586 587 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) { 588 currentHead->var4 = -1; 589 } 579 /*! \brief Destructor 580 */ 581 RawScript::~RawScript(void) { 582 delete[] _data; 590 583 } 591 584 592 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3) { 593 SeqListElement *currentHead = &seqList; 594 SeqListElement *tempHead = currentHead; 585 /*! \brief Assignment operator 586 */ 587 RawScript &RawScript::operator=(const RawScript &src) { 588 assert(src._data); 589 byte *tmp = new byte[src._size+1]; 595 590 596 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { 597 tempHead = currentHead; 598 currentHead = tempHead->next; 599 } 591 assert(tmp); 592 _labels = src._labels; 593 _size = src._size; 600 594 601 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) { 602 return 1; 603 } 595 delete[] _data; 596 _data = tmp; 597 memcpy(_data, src._data, _size); 598 _data[_size] = 0; 604 599 605 return 0;600 return *this; 606 601 } 607 602 608 ScriptStruct scriptTable[NUM_MAX_SCRIPT]; 603 /*! \brief Get the next label in bytecode 604 * \param info Script info instance 605 * \param offset Starting offset 606 * \return Index of the next label in bytecode or _size on end of bytecode 607 * 608 * computeScriptStackSub replacement 609 */ 610 uint16 RawScript::getNextLabel(const FWScriptInfo &info, uint16 offset) const { 611 assert(_data); 612 uint16 pos = offset; 609 613 610 void stopGlobalScript(uint16 scriptIdx) { 611 prcLinkedListStruct *currentHead = &globalScriptsHead; 612 prcLinkedListStruct *tempHead = currentHead; 614 while (pos < _size) { 615 uint8 opcode = _data[pos]; 616 pos++; 617 const char *ptr = info.opcodeInfo(opcode); 613 618 614 currentHead = tempHead->next; 615 616 while (currentHead && (currentHead->scriptIdx != scriptIdx)) { 617 tempHead = currentHead; 618 currentHead = tempHead->next; 619 } 620 621 if (!currentHead) { 622 return; 623 } 624 625 if (currentHead->scriptIdx != scriptIdx) { 626 return; 627 } 628 629 currentHead->scriptIdx = -1; 630 } 631 632 uint16 computeScriptStackSub(bool computeAllLabels, byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, byte labelIndex, uint16 startOffset) { 633 uint16 position; 634 635 if (computeAllLabels) { 636 for (int i = 0; i < SCRIPT_STACK_SIZE; i++) { 637 stackPtr[i] = -1; 638 } 639 position = 0; 640 } else { 641 position = startOffset; 642 } 643 while (position < scriptSize) { 644 uint8 opcode = scriptPtr[position]; 645 position++; 646 if (opcode == 0 || opcode > _numOpcodes) { 619 if (!ptr) { 647 620 continue; 648 621 } 649 if (!_opcodeTable[opcode - 1].args) { 650 warning("Undefined opcode 0x%02X in computeScriptStackSub", opcode - 1); 651 continue; 652 } 653 for (const char *p = _opcodeTable[opcode - 1].args; *p; ++p) { 654 switch (*p) { 622 623 for (; *ptr; ++ptr) { 624 switch (*ptr) { 655 625 case 'b': // byte 656 pos ition++;626 pos++; 657 627 break; 658 628 case 'w': // word 659 pos ition+= 2;629 pos += 2; 660 630 break; 661 631 case 'c': { // byte != 0 ? byte : word 662 uint8 test = scriptPtr[position];663 pos ition++;632 uint8 test = _data[pos]; 633 pos++; 664 634 if (test) { 665 pos ition++;635 pos++; 666 636 } else { 667 pos ition+= 2;637 pos += 2; 668 638 } 669 639 } 670 640 break; 671 case 'l': { // label 672 uint8 index = scriptPtr[position]; 673 position++; 674 if (computeAllLabels) { 675 stackPtr[index] = position; 676 } else { 677 if (labelIndex == index) { 678 return position; 679 } 680 } 681 } 682 break; 641 case 'l': // label 642 return pos; 683 643 case 's': // string 684 while ( scriptPtr[position++] != 0);644 while (_data[pos++] != 0); 685 645 break; 686 646 case 'x': // exit script 687 return position; 647 // this is a little change from the original 648 // code, I want to know if it breaks something 649 assert(pos >= _size-1); 650 return _size; 688 651 } 689 652 } 690 653 } 691 return position;654 return _size; 692 655 } 693 656 694 void computeScriptStack(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize) { 695 computeScriptStackSub(true, scriptPtr, stackPtr, scriptSize, 0, 0); 696 } 657 /*! \brief Calculate initial script labels 658 * \param info Script info instance 659 * 660 * computeScriptStack replacement 661 */ 662 void RawScript::computeLabels(const FWScriptInfo &info) { 663 assert(_data); 664 uint16 pos = 0; 665 int i; 697 666 698 uint16 computeScriptStackFromScript(byte *scriptPtr, uint16 currentPosition, uint16 labelIdx, uint16 scriptSize) { 699 return computeScriptStackSub(false, scriptPtr, (int16 *)&dummyU16, (uint16)scriptSize, labelIdx, currentPosition); 667 // reset labels 668 for (i = 0; i < SCRIPT_STACK_SIZE; i++) { 669 _labels[i] = -1; 670 } 671 672 // parse bytecode 673 while ((pos = getNextLabel(info, pos)) < _size) { 674 i = _data[pos]; 675 _labels[i] = ++pos; 676 } 700 677 } 701 678 702 void palRotate(byte a, byte b, byte c) { 703 if (c == 1) { 704 uint16 currentColor = c_palette[b]; 679 /*! \brief find the next label from current position 680 * \param info Script info instance 681 * \param index Label index to look for 682 * \param offset Current position in script 683 * \return Position of next instruction following the label 684 * 685 * computeScriptStackFromScript replacement 686 */ 687 uint16 RawScript::getLabel(const FWScriptInfo &info, byte index, uint16 offset) 688 const { 705 689 706 for (int16 i = b; i > a; i--) { 707 c_palette[i] = c_palette[i - 1]; 690 assert(_data); 691 uint16 pos = offset; 692 693 while ((pos = getNextLabel(info, pos)) < _size) { 694 if (_data[pos++] == index) { 695 return pos; 708 696 } 697 } 709 698 710 c_palette[a] = currentColor; 711 } 699 return _size; 712 700 } 713 701 714 void addScriptToList0(uint16 idx) { 715 uint16 i; 716 prcLinkedListStruct *pNewElement; 717 prcLinkedListStruct *currentHead = &globalScriptsHead; 718 prcLinkedListStruct *tempHead = currentHead; 702 /*! \brief Copy bytecode and calculate labels 703 * \param data Bytecode to copy, must be _size long 704 */ 705 void RawScript::setData(const FWScriptInfo &info, const byte *data) { 706 assert(!_data); // this function should be called only once per instance 707 _data = new byte[_size+1]; 719 708 720 assert(idx <= NUM_MAX_SCRIPT); 709 assert(data && _data); 710 memcpy(_data, data, _size * sizeof(byte)); 711 _data[_size] = 0; 721 712 722 currentHead = tempHead->next; 713 computeLabels(info); 714 } 723 715 724 while (currentHead) { 725 tempHead = currentHead; 716 /*! \brief Initial script labels 717 * \return Precalculated script labels 718 */ 719 const ScriptVars &RawScript::labels(void) const { 720 assert(_data); 721 return _labels; 722 } 726 723 727 assert(tempHead); 724 /*! \brief One byte of bytecode 725 * \param pos Index in bytecode 726 * \return Byte from bytecode 727 */ 728 byte RawScript::getByte(unsigned int pos) const { 729 assert(_data && pos < _size); 728 730 729 currentHead = tempHead->next;730 731 return _data[pos]; 732 } 731 733 732 pNewElement = new prcLinkedListStruct; 734 /*! \brief One word of bytecode 735 * \param pos Index of the first byte in bytecode 736 * \return Word of bytecode 737 */ 738 uint16 RawScript::getWord(unsigned int pos) const { 739 assert(_data && pos+1 < _size); 733 740 734 assert(pNewElement); 741 return READ_BE_UINT16(_data + pos); 742 } 735 743 736 pNewElement->next = tempHead->next; 737 tempHead->next = pNewElement; 744 /*! \brief String in bytecode 745 * \param pos Index of the first char in string 746 * \return Pointer to part of bytecode 747 */ 748 const char *RawScript::getString(unsigned int pos) const { 749 assert(_data && pos < _size); 738 750 739 // copy the stack into the script instance 740 for (i = 0; i < SCRIPT_STACK_SIZE; i++) { 741 pNewElement->stack[i] = scriptTable[idx].stack[i]; 742 } 751 return (const char*)(_data+pos); 752 } 743 753 744 pNewElement->compareResult = 0; 745 pNewElement->scriptPosition = 0; 754 /*! \brief Constructor for partial loading 755 * \param size Size of bytecode which will be added later 756 * \param p1 First object script parameter 757 * \param p2 Second object script parameter 758 * \param p3 Third object script parameter 759 * 760 * This constructor _MUST_ be followed by setdata() method call before the 761 * instance can be used. It leaves the instance in partially invalid state. 762 */ 763 RawObjectScript::RawObjectScript(uint16 s, uint16 p1, uint16 p2, uint16 p3) 764 : RawScript(s), _runCount(0), _param1(p1), _param2(p2), _param3(p3) 765 { } 746 766 747 pNewElement->scriptPtr = scriptTable[idx].ptr; 748 pNewElement->scriptIdx = idx; 767 /*! \brief Complete constructor 768 * \param data Script bytecode 769 * \param s Bytecode length 770 * \param p1 First object script parameter 771 * \param p2 Second object script parameter 772 * \param p3 Third object script parameter 773 */ 774 RawObjectScript::RawObjectScript(const FWScriptInfo &info, const byte *data, 775 uint16 s, uint16 p1, uint16 p2, uint16 p3) : RawScript(info, data, s), 776 _runCount(0), _param1(p1), _param2(p2), _param3(p3) { } 777 778 /*! \brief Contructor for global scripts 779 * \param script Script bytecode reference 780 * \param idx Script bytecode index 781 */ 782 FWScript::FWScript(const RawScript &script, int16 idx) : _script(script), 783 _pos(0), _line(0), _compare(0), _index(idx), 784 _labels(script.labels()), _localVars(LOCAL_VARS_SIZE), 785 _globalVars(globalVars), _info(new FWScriptInfo) { } 786 787 /*! \brief Copy constructor 788 */ 789 FWScript::FWScript(const FWScript &src) : _script(src._script), _pos(src._pos), 790 _line(src._line), _compare(src._compare), _index(src._index), 791 _labels(src._labels), _localVars(src._localVars), 792 _globalVars(src._globalVars), _info(new FWScriptInfo) { } 793 794 /*! \brief Contructor for global scripts in derived classes 795 * \param script Script bytecode reference 796 * \param idx Script bytecode index 797 */ 798 FWScript::FWScript(const RawScript &script, int16 idx, FWScriptInfo *info) : 799 _script(script), _pos(0), _line(0), _compare(0), _index(idx), 800 _labels(script.labels()), _localVars(LOCAL_VARS_SIZE), 801 _globalVars(globalVars), _info(info) { } 802 803 /*! \brief Constructor for object scripts in derived classes 804 * \param script Script bytecode reference 805 * \param idx Script bytecode index 806 */ 807 FWScript::FWScript(RawObjectScript &script, int16 idx, FWScriptInfo *info) : 808 _script(script), _pos(0), _line(0), _compare(0), _index(idx), 809 _labels(script.labels()), _localVars(LOCAL_VARS_SIZE), 810 _globalVars(globalVars), _info(info) { 811 812 _localVars[0] = script.run(); 749 813 } 750 814 751 int16 endScript0(uint16 scriptIdx) { 752 prcLinkedListStruct *currentHead = &globalScriptsHead; 753 prcLinkedListStruct *tempHead = currentHead; 815 /*! \brief Copy constructor for derived classes 816 */ 817 FWScript::FWScript(const FWScript &src, FWScriptInfo *info) : 818 _script(src._script), _pos(src._pos), _line(src._line), 819 _compare(src._compare), _index(src._index), _labels(src._labels), 820 _localVars(src._localVars), _globalVars(src._globalVars), _info(info) { } 754 821 755 //assert(scriptIdx <= NUM_MAX_SCRIPT); 822 FWScript::~FWScript(void) { 823 delete _info; 824 } 756 825 757 currentHead = tempHead->next; 826 /*! \brief Read next byte from bytecode 827 * \return Byte from bytecode 828 */ 829 byte FWScript::getNextByte() { 830 byte val = _script.getByte(_pos); 831 _pos++; 832 return val; 833 } 758 834 759 while (currentHead && currentHead->scriptIdx != scriptIdx) { 760 tempHead = currentHead; 761 currentHead = tempHead->next; 762 } 835 /*! \brief Read next word from bytecode 836 * \return Word from bytecode 837 */ 838 uint16 FWScript::getNextWord() { 839 uint16 val = _script.getWord(_pos); 840 _pos += 2; 841 return val; 842 } 763 843 764 if (!currentHead) { 765 return -1; 766 } 844 /*! \brief Read next string from bytecode 845 * \return Pointer to string 846 */ 847 const char *FWScript::getNextString() { 848 const char *val = _script.getString(_pos); 849 _pos += strlen(val) + 1; 850 return val; 851 } 767 852 768 if (currentHead->scriptIdx != scriptIdx) { 769 return -1; 853 /*! \brief Restore script state from savefile 854 * \param labels Restored script labels 855 * \param local Restored local script variables 856 * \param compare Restored last comparison result 857 * \param pos Restored script position 858 */ 859 void FWScript::load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) { 860 assert(pos < _script.size()); 861 _labels = labels; 862 _localVars = local; 863 _compare = compare; 864 _pos = _line = pos; 865 } 866 867 /*! \brief Execute script 868 * \return <0 on script termination, >0 on script pause 869 * 870 * executeScript replacement. 871 * Instruction handler must return 0 if the script should continue or 872 * nonzero with the same meaning as return value of this function 873 */ 874 int FWScript::execute() { 875 int ret = 0; 876 877 while (!ret) { 878 _line = _pos; 879 byte opcode = getNextByte(); 880 opFunc handler = _info->opcodeHandler(opcode); 881 882 if (handler) { 883 ret = (this->*handler)(); 884 } 770 885 } 771 886 772 currentHead->scriptIdx = -1; 887 return ret; 888 } 773 889 774 return 0; 890 /*! \brief Save script to savefile 891 * \param fHandle Savefile handle 892 */ 893 void FWScript::save(Common::OutSaveFile &fHandle) const { 894 _labels.save(fHandle); 895 _localVars.save(fHandle); 896 fHandle.writeUint16BE(_compare); 897 fHandle.writeUint16BE(_pos); 898 // data order sucks... 899 fHandle.writeUint16BE(_index); 775 900 } 776 901 777 int16 endScript1(uint16 scriptIdx) { 778 prcLinkedListStruct *currentHead = &objScriptList; 779 prcLinkedListStruct *tempHead = currentHead; 902 /*! \brief Contructor for global scripts 903 * \param script Script bytecode reference 904 * \param idx Script bytecode index 905 */ 906 OSScript::OSScript(const RawScript &script, int16 idx) : 907 FWScript(script, idx, new OSScriptInfo) {} 780 908 781 currentHead = tempHead->next; 909 /*! \brief Constructor for object scripts 910 * \param script Script bytecode reference 911 * \param idx Script bytecode index 912 */ 913 OSScript::OSScript(RawObjectScript &script, int16 idx) : 914 FWScript(script, idx, new OSScriptInfo) {} 782 915 783 while (currentHead && currentHead->scriptIdx != scriptIdx) { 784 tempHead = currentHead; 785 currentHead = tempHead->next; 786 } 916 /*! \brief Copy constructor 917 */ 918 OSScript::OSScript(const OSScript &src) : FWScript(src, new OSScriptInfo) {} 787 919 788 if (!currentHead) { 789 return -1; 920 /*! \brief Restore script state from savefile 921 * \param labels Restored script labels 922 * \param local Restored local script variables 923 * \param compare Restored last comparison result 924 * \param pos Restored script position 925 */ 926 void OSScript::load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) { 927 FWScript::load(labels, local, compare, pos); 928 } 929 /*! \brief Get opcode info string 930 * \param opcode Opcode to look for in opcode table 931 */ 932 const char *FWScriptInfo::opcodeInfo(byte opcode) const { 933 if (opcode == 0 || opcode > FWScript::_numOpcodes) { 934 return NULL; 790 935 } 791 936 792 if (currentHead->scriptIdx != scriptIdx) { 793 return -1; 937 if (!FWScript::_opcodeTable[opcode - 1].args) { 938 warning("Undefined opcode 0x%02X in FWScriptInfo::opcodeInfo", opcode - 1); 939 return NULL; 794 940 } 795 941 796 currentHead->scriptIdx = -1; 797 798 return 0; 942 return FWScript::_opcodeTable[opcode - 1].args; 799 943 } 800 944 801 int16 getZoneFromPosition(byte *page, int16 x, int16 y, int16 width) { 802 byte *ptr = page + (y * width) + x / 2; 803 byte zoneVar; 945 /*! \brief Get opcode handler pointer 946 * \param opcode Opcode to look for in opcode table 947 */ 948 opFunc FWScriptInfo::opcodeHandler(byte opcode) const { 949 if (opcode == 0 || opcode > FWScript::_numOpcodes) { 950 return NULL; 951 } 804 952 805 if (!(x % 2)) { 806 zoneVar = (*(ptr) >> 4) & 0xF; 807 } else { 808 zoneVar = (*(ptr)) & 0xF; 953 if (!FWScript::_opcodeTable[opcode - 1].proc) { 954 warning("Undefined opcode 0x%02X in FWScriptInfo::opcodeHandler", opcode - 1); 955 return NULL; 809 956 } 810 957 811 return zoneVar;958 return FWScript::_opcodeTable[opcode - 1].proc; 812 959 } 813 960 814 int16 getZoneFromPositionRaw(byte *page, int16 x, int16 y, int16 width) { 815 byte *ptr = page + (y * width) + x; 816 byte zoneVar; 961 /*! \brief Create new FWScript instance 962 * \param script Script bytecode 963 * \param index Bytecode index 964 */ 965 FWScript *FWScriptInfo::create(const RawScript &script, int16 index) const { 966 return new FWScript(script, index); 967 } 817 968 818 zoneVar = (*(ptr)) & 0xF; 969 /*! \brief Create new FWScript instance 970 * \param script Object script bytecode 971 * \param index Bytecode index 972 */ 973 FWScript *FWScriptInfo::create(const RawObjectScript &script, int16 index) const { 974 return new FWScript(script, index); 975 } 819 976 820 return zoneVar; 977 /*! \brief Load saved FWScript instance 978 * \param script Script bytecode 979 * \param index Bytecode index 980 * \param local Local variables 981 * \param labels Script labels 982 * \param compare Last compare result 983 * \param pos Position in script 984 */ 985 FWScript *FWScriptInfo::create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const { 986 FWScript *tmp = new FWScript(script, index); 987 assert(tmp); 988 tmp->load(labels, local, compare, pos); 989 return tmp; 821 990 } 822 991 823 int16 checkCollision(int16 objIdx, int16 x, int16 y, int16 numZones, int16 zoneIdx) { 824 int16 lx = objectTable[objIdx].x + x; 825 int16 ly = objectTable[objIdx].y + y; 826 int16 idx; 992 /*! \brief Load saved FWScript instance 993 * \param script Object script bytecode 994 * \param index Bytecode index 995 * \param local Local variables 996 * \param labels Script labels 997 * \param compare Last compare result 998 * \param pos Position in script 999 */ 1000 FWScript *FWScriptInfo::create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const { 1001 FWScript *tmp = new FWScript(script, index); 1002 assert(tmp); 1003 tmp->load(labels, local, compare, pos); 1004 return tmp; 1005 } 827 1006 828 for (int16 i = 0; i < numZones; i++) { 829 idx = getZoneFromPositionRaw(page3Raw, lx + i, ly, 320); 1007 /*! \brief Get opcode info string 1008 * \param opcode Opcode to look for in opcode table 1009 */ 1010 const char *OSScriptInfo::opcodeInfo(byte opcode) const { 1011 if (opcode == 0 || opcode > OSScript::_numOpcodes) { 1012 return NULL; 1013 } 830 1014 831 assert(idx >= 0 && idx <= NUM_MAX_ZONE); 832 833 if (zoneData[idx] == zoneIdx) { 834 return 1; 835 } 1015 if (!OSScript::_opcodeTable[opcode - 1].args) { 1016 warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeInfo", opcode - 1); 1017 return NULL; 836 1018 } 837 1019 838 return 0;1020 return OSScript::_opcodeTable[opcode - 1].args; 839 1021 } 840 1022 841 uint16 compareVars(int16 a, int16 b) { 842 uint16 flag = 0; 1023 /*! \brief Get opcode handler pointer 1024 * \param opcode Opcode to look for in opcode table 1025 */ 1026 opFunc OSScriptInfo::opcodeHandler(byte opcode) const { 1027 if (opcode == 0 || opcode > OSScript::_numOpcodes) { 1028 return NULL; 1029 } 843 1030 844 if (a == b) { 845 flag |= kCmpEQ; 846 } else if (a > b) { 847 flag |= kCmpGT; 848 } else if (a < b) { 849 flag |= kCmpLT; 1031 if (!OSScript::_opcodeTable[opcode - 1].proc) { 1032 warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeHandler", opcode - 1); 1033 return NULL; 850 1034 } 851 1035 852 return flag;1036 return OSScript::_opcodeTable[opcode - 1].proc; 853 1037 } 854 1038 1039 /*! \brief Create new OSScript instance 1040 * \param script Script bytecode 1041 * \param index Bytecode index 1042 */ 1043 FWScript *OSScriptInfo::create(const RawScript &script, int16 index) const { 1044 return new OSScript(script, index); 1045 } 1046 1047 /*! \brief Create new OSScript instance 1048 * \param script Object script bytecode 1049 * \param index Bytecode index 1050 */ 1051 FWScript *OSScriptInfo::create(const RawObjectScript &script, int16 index) const { 1052 return new OSScript(script, index); 1053 } 1054 1055 /*! \brief Load saved OSScript instance 1056 * \param script Script bytecode 1057 * \param index Bytecode index 1058 * \param local Local variables 1059 * \param labels Script labels 1060 * \param compare Last compare result 1061 * \param pos Position in script 1062 */ 1063 FWScript *OSScriptInfo::create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const { 1064 OSScript *tmp = new OSScript(script, index); 1065 assert(tmp); 1066 tmp->load(labels, local, compare, pos); 1067 return tmp; 1068 } 1069 1070 /*! \brief Load saved OSScript instance 1071 * \param script Object script bytecode 1072 * \param index Bytecode index 1073 * \param local Local variables 1074 * \param labels Script labels 1075 * \param compare Last compare result 1076 * \param pos Position in script 1077 */ 1078 FWScript *OSScriptInfo::create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const { 1079 OSScript *tmp = new OSScript(script, index); 1080 assert(tmp); 1081 tmp->load(labels, local, compare, pos); 1082 return tmp; 1083 } 1084 855 1085 // ------------------------------------------------------------------------ 856 1086 // FUTURE WARS opcodes 857 1087 // ------------------------------------------------------------------------ 858 1088 859 voido1_modifyObjectParam() {1089 int FWScript::o1_modifyObjectParam() { 860 1090 byte objIdx = getNextByte(); 861 1091 byte paramIdx = getNextByte(); 862 1092 int16 newValue = getNextWord(); 863 1093 864 debugC(5, kCineDebugScript, "Line: %d: modifyObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)", _ currentLine, objIdx, paramIdx, newValue);1094 debugC(5, kCineDebugScript, "Line: %d: modifyObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)", _line, objIdx, paramIdx, newValue); 865 1095 866 1096 modifyObjectParam(objIdx, paramIdx, newValue); 1097 return 0; 867 1098 } 868 1099 869 voido1_getObjectParam() {1100 int FWScript::o1_getObjectParam() { 870 1101 byte objIdx = getNextByte(); 871 1102 byte paramIdx = getNextByte(); 872 1103 byte newValue = getNextByte(); 873 1104 874 debugC(5, kCineDebugScript, "Line: %d: getObjectParam(objIdx:%d,paramIdx:%d,var:%d)", _ currentLine, objIdx, paramIdx, newValue);1105 debugC(5, kCineDebugScript, "Line: %d: getObjectParam(objIdx:%d,paramIdx:%d,var:%d)", _line, objIdx, paramIdx, newValue); 875 1106 876 _currentScriptElement->localVars[newValue] = getObjectParam(objIdx, paramIdx); 1107 _localVars[newValue] = getObjectParam(objIdx, paramIdx); 1108 return 0; 877 1109 } 878 1110 879 voido1_addObjectParam() {1111 int FWScript::o1_addObjectParam() { 880 1112 byte objIdx = getNextByte(); 881 1113 byte paramIdx = getNextByte(); 882 1114 int16 newValue = getNextWord(); 883 1115 884 debugC(5, kCineDebugScript, "Line: %d: addObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)", _ currentLine, objIdx, paramIdx, newValue);1116 debugC(5, kCineDebugScript, "Line: %d: addObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)", _line, objIdx, paramIdx, newValue); 885 1117 886 1118 addObjectParam(objIdx, paramIdx, newValue); 1119 return 0; 887 1120 } 888 1121 889 voido1_subObjectParam() {1122 int FWScript::o1_subObjectParam() { 890 1123 byte objIdx = getNextByte(); 891 1124 byte paramIdx = getNextByte(); 892 1125 int16 newValue = getNextWord(); 893 1126 894 debugC(5, kCineDebugScript, "Line: %d: subObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)", _ currentLine, objIdx, paramIdx, newValue);1127 debugC(5, kCineDebugScript, "Line: %d: subObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)", _line, objIdx, paramIdx, newValue); 895 1128 896 1129 subObjectParam(objIdx, paramIdx, newValue); 1130 return 0; 897 1131 } 898 1132 899 void o1_add2ObjectParam() { 1133 /*! \todo Implement this instruction 1134 */ 1135 int FWScript::o1_add2ObjectParam() { 900 1136 getNextByte(); 901 1137 getNextByte(); 902 1138 getNextWord(); 903 1139 warning("STUB: o1_add2ObjectParam()"); 1140 return 0; 904 1141 } 905 1142 906 void o1_sub2ObjectParam() { 1143 /*! \todo Implement this instruction 1144 */ 1145 int FWScript::o1_sub2ObjectParam() { 907 1146 getNextByte(); 908 1147 getNextByte(); 909 1148 getNextWord(); 910 1149 warning("STUB: o1_sub2ObjectParam()"); 1150 return 0; 911 1151 } 912 1152 913 voido1_compareObjectParam() {1153 int FWScript::o1_compareObjectParam() { 914 1154 byte objIdx = getNextByte(); 915 1155 byte param1 = getNextByte(); 916 1156 int16 param2 = getNextWord(); 917 1157 918 debugC(5, kCineDebugScript, "Line: %d: compareObjectParam(objIdx:%d,type:%d,value:%d)", _ currentLine, objIdx, param1, param2);1158 debugC(5, kCineDebugScript, "Line: %d: compareObjectParam(objIdx:%d,type:%d,value:%d)", _line, objIdx, param1, param2); 919 1159 920 _currentScriptElement->compareResult = compareObjectParam(objIdx, param1, param2); 1160 _compare = compareObjectParam(objIdx, param1, param2); 1161 return 0; 921 1162 } 922 1163 923 voido1_setupObject() {1164 int FWScript::o1_setupObject() { 924 1165 byte objIdx = getNextByte(); 925 1166 int16 param1 = getNextWord(); 926 1167 int16 param2 = getNextWord(); 927 1168 int16 param3 = getNextWord(); 928 1169 int16 param4 = getNextWord(); 929 1170 930 debugC(5, kCineDebugScript, "Line: %d: setupObject(objIdx:%d,%d,%d,%d,%d)", _ currentLine, objIdx, param1, param2, param3, param4);1171 debugC(5, kCineDebugScript, "Line: %d: setupObject(objIdx:%d,%d,%d,%d,%d)", _line, objIdx, param1, param2, param3, param4); 931 1172 932 1173 setupObject(objIdx, param1, param2, param3, param4); 1174 return 0; 933 1175 } 934 1176 935 voido1_checkCollision() {1177 int FWScript::o1_checkCollision() { 936 1178 byte objIdx = getNextByte(); 937 1179 int16 param1 = getNextWord(); 938 1180 int16 param2 = getNextWord(); 939 1181 int16 param3 = getNextWord(); 940 1182 int16 param4 = getNextWord(); 941 1183 942 debugC(5, kCineDebugScript, "Line: %d: checkCollision(objIdx:%d,%d,%d,%d,%d)", _ currentLine, objIdx, param1, param2, param3, param4);1184 debugC(5, kCineDebugScript, "Line: %d: checkCollision(objIdx:%d,%d,%d,%d,%d)", _line, objIdx, param1, param2, param3, param4); 943 1185 944 _currentScriptElement->compareResult = checkCollision(objIdx, param1, param2, param3, param4); 1186 _compare = checkCollision(objIdx, param1, param2, param3, param4); 1187 return 0; 945 1188 } 946 1189 947 voido1_loadVar() {1190 int FWScript::o1_loadVar() { 948 1191 byte varIdx = getNextByte(); 949 1192 byte varType = getNextByte(); 950 1193 … … 954 1197 955 1198 switch (varType) { 956 1199 case 1: 957 debugC(5, kCineDebugScript, "Line: %d: var[%d] = var[%d]", _ currentLine, varIdx, dataIdx);958 _ currentScriptElement->localVars[varIdx] = _currentScriptElement->localVars[dataIdx];1200 debugC(5, kCineDebugScript, "Line: %d: var[%d] = var[%d]", _line, varIdx, dataIdx); 1201 _localVars[varIdx] = _localVars[dataIdx]; 959 1202 break; 960 1203 case 2: 961 debugC(5, kCineDebugScript, "Line: %d: var[%d] = globalVars[%d]", _ currentLine, varIdx, dataIdx);962 _ currentScriptElement->localVars[varIdx] =globalVars[dataIdx];1204 debugC(5, kCineDebugScript, "Line: %d: var[%d] = globalVars[%d]", _line, varIdx, dataIdx); 1205 _localVars[varIdx] = _globalVars[dataIdx]; 963 1206 break; 964 1207 case 3: 965 debugC(5, kCineDebugScript, "Line: %d: var[%d] = mouseX", _ currentLine, varIdx);966 getMouseData(mouseUpdateStatus, &dummyU16, (uint16 *)&var, (uint16 *)&dummyU16);967 _ currentScriptElement->localVars[varIdx] = var;1208 debugC(5, kCineDebugScript, "Line: %d: var[%d] = mouseX", _line, varIdx); 1209 getMouseData(mouseUpdateStatus, &dummyU16, (uint16 *)&var, &dummyU16); 1210 _localVars[varIdx] = var; 968 1211 break; 969 1212 case 4: 970 debugC(5, kCineDebugScript, "Line: %d: var[%d] = mouseY", _ currentLine, varIdx);971 getMouseData(mouseUpdateStatus, &dummyU16, (uint16 *)&dummyU16, (uint16 *)&var);972 _ currentScriptElement->localVars[varIdx] = var;1213 debugC(5, kCineDebugScript, "Line: %d: var[%d] = mouseY", _line, varIdx); 1214 getMouseData(mouseUpdateStatus, &dummyU16, &dummyU16, (uint16 *)&var); 1215 _localVars[varIdx] = var; 973 1216 break; 974 1217 case 5: 975 debugC(5, kCineDebugScript, "Line: %d: var[%d] = rand mod %d", _ currentLine, varIdx, dataIdx);976 _ currentScriptElement->localVars[varIdx] = g_cine->_rnd.getRandomNumber(dataIdx - 1);1218 debugC(5, kCineDebugScript, "Line: %d: var[%d] = rand mod %d", _line, varIdx, dataIdx); 1219 _localVars[varIdx] = g_cine->_rnd.getRandomNumber(dataIdx - 1); 977 1220 break; 978 1221 case 8: 979 debugC(5, kCineDebugScript, "Line: %d: var[%d] = file[%d].packedSize", _ currentLine, varIdx, dataIdx);980 _ currentScriptElement->localVars[varIdx] = partBuffer[dataIdx].packedSize;1222 debugC(5, kCineDebugScript, "Line: %d: var[%d] = file[%d].packedSize", _line, varIdx, dataIdx); 1223 _localVars[varIdx] = partBuffer[dataIdx].packedSize; 981 1224 break; 982 1225 case 9: 983 debugC(5, kCineDebugScript, "Line: %d: var[%d] = file[%d].unpackedSize", _ currentLine, varIdx, dataIdx);984 _ currentScriptElement->localVars[varIdx] = partBuffer[dataIdx].unpackedSize;1226 debugC(5, kCineDebugScript, "Line: %d: var[%d] = file[%d].unpackedSize", _line, varIdx, dataIdx); 1227 _localVars[varIdx] = partBuffer[dataIdx].unpackedSize; 985 1228 break; 986 1229 default: 987 1230 error("executeScript: o1_loadVar: Unknown variable type %d", varType); … … 989 1232 } else { 990 1233 int16 value = getNextWord(); 991 1234 992 debugC(5, kCineDebugScript, "Line: %d: var[%d] = %d", _ currentLine, varIdx, value);993 _ currentScriptElement->localVars[varIdx] = value;1235 debugC(5, kCineDebugScript, "Line: %d: var[%d] = %d", _line, varIdx, value); 1236 _localVars[varIdx] = value; 994 1237 } 1238 1239 return 0; 995 1240 } 996 1241 997 voido1_addVar() {1242 int FWScript::o1_addVar() { 998 1243 byte varIdx = getNextByte(); 999 1244 byte varType = getNextByte(); 1000 1245 1001 1246 if (varType) { 1002 1247 byte dataIdx = getNextByte(); 1003 1248 1004 debugC(5, kCineDebugScript, "Line: %d: var[%d] += var[%d]", _currentLine, varIdx, dataIdx); 1005 _currentScriptElement->localVars[varIdx] += _currentScriptElement->localVars[dataIdx]; 1249 if (varType == 1) { 1250 debugC(5, kCineDebugScript, "Line: %d: var[%d] += var[%d]", _line, varIdx, dataIdx); 1251 _localVars[varIdx] += _localVars[dataIdx]; 1252 } else if (varType == 2) { 1253 debugC(5, kCineDebugScript, "Line: %d: var[%d] += globalVar[%d]", _line, varIdx, dataIdx); 1254 _localVars[varIdx] += _globalVars[dataIdx]; 1255 } 1006 1256 } else { 1007 1257 int16 value = getNextWord(); 1008 1258 1009 debugC(5, kCineDebugScript, "Line: %d: var[%d] += %d", _ currentLine, varIdx, value);1010 _ currentScriptElement->localVars[varIdx] += value;1259 debugC(5, kCineDebugScript, "Line: %d: var[%d] += %d", _line, varIdx, value); 1260 _localVars[varIdx] += value; 1011 1261 } 1262 1263 return 0; 1012 1264 } 1013 1265 1014 voido1_subVar() {1266 int FWScript::o1_subVar() { 1015 1267 byte varIdx = getNextByte(); 1016 1268 byte varType = getNextByte(); 1017 1269 1018 1270 if (varType) { 1019 1271 byte dataIdx = getNextByte(); 1020 1272 1021 debugC(5, kCineDebugScript, "Line: %d: var[%d] -= var[%d]", _currentLine, varIdx, dataIdx); 1022 _currentScriptElement->localVars[varIdx] -= _currentScriptElement->localVars[dataIdx]; 1273 if (varType == 1) { 1274 debugC(5, kCineDebugScript, "Line: %d: var[%d] -= var[%d]", _line, varIdx, dataIdx); 1275 _localVars[varIdx] -= _localVars[dataIdx]; 1276 } else if (varType == 2) { 1277 debugC(5, kCineDebugScript, "Line: %d: var[%d] -= globalVar[%d]", _line, varIdx, dataIdx); 1278 _localVars[varIdx] -= _globalVars[dataIdx]; 1279 } 1280 1023 1281 } else { 1024 1282 int16 value = getNextWord(); 1025 1283 1026 debugC(5, kCineDebugScript, "Line: %d: var[%d] -= %d", _ currentLine, varIdx, value);1027 _ currentScriptElement->localVars[varIdx] -= value;1284 debugC(5, kCineDebugScript, "Line: %d: var[%d] -= %d", _line, varIdx, value); 1285 _localVars[varIdx] -= value; 1028 1286 } 1287 1288 return 0; 1029 1289 } 1030 1290 1031 voido1_mulVar() {1291 int FWScript::o1_mulVar() { 1032 1292 byte varIdx = getNextByte(); 1033 1293 byte varType = getNextByte(); 1034 1294 1035 1295 if (varType) { 1036 1296 byte dataIdx = getNextByte(); 1037 1297 1038 debugC(5, kCineDebugScript, "Line: %d: var[%d] *= var[%d]", _currentLine, varIdx, dataIdx); 1039 _currentScriptElement->localVars[varIdx] *= _currentScriptElement->localVars[dataIdx]; 1298 if (varType == 1) { 1299 debugC(5, kCineDebugScript, "Line: %d: var[%d] *= var[%d]", _line, varIdx, dataIdx); 1300 _localVars[varIdx] *= _localVars[dataIdx]; 1301 } else if (varType == 2) { 1302 debugC(5, kCineDebugScript, "Line: %d: var[%d] *= globalVar[%d]", _line, varIdx, dataIdx); 1303 _localVars[varIdx] *= _globalVars[dataIdx]; 1304 } 1040 1305 } else { 1041 1306 int16 value = getNextWord(); 1042 1307 1043 debugC(5, kCineDebugScript, "Line: %d: var[%d] *= %d", _ currentLine, varIdx, value);1044 _ currentScriptElement->localVars[varIdx] *= value;1308 debugC(5, kCineDebugScript, "Line: %d: var[%d] *= %d", _line, varIdx, value); 1309 _localVars[varIdx] *= value; 1045 1310 } 1311 1312 return 0; 1046 1313 } 1047 1314 1048 voido1_divVar() {1315 int FWScript::o1_divVar() { 1049 1316 byte varIdx = getNextByte(); 1050 1317 byte varType = getNextByte(); 1051 1318 1052 1319 if (varType) { 1053 1320 byte dataIdx = getNextByte(); 1054 1321 1055 debugC(5, kCineDebugScript, "Line: %d: var[%d] /= var[%d]", _currentLine, varIdx, dataIdx); 1056 _currentScriptElement->localVars[varIdx] /= _currentScriptElement->localVars[dataIdx]; 1322 if (varType == 1) { 1323 debugC(5, kCineDebugScript, "Line: %d: var[%d] /= var[%d]", _line, varIdx, dataIdx); 1324 _localVars[varIdx] /= _localVars[dataIdx]; 1325 } else if (varType == 2) { 1326 debugC(5, kCineDebugScript, "Line: %d: var[%d] /= globalVar[%d]", _line, varIdx, dataIdx); 1327 _localVars[varIdx] /= _globalVars[dataIdx]; 1328 } 1057 1329 } else { 1058 1330 int16 value = getNextWord(); 1059 1331 1060 debugC(5, kCineDebugScript, "Line: %d: var[%d] /= %d", _ currentLine, varIdx, value);1061 _ currentScriptElement->localVars[varIdx] /= value;1332 debugC(5, kCineDebugScript, "Line: %d: var[%d] /= %d", _line, varIdx, value); 1333 _localVars[varIdx] /= value; 1062 1334 } 1335 1336 return 0; 1063 1337 } 1064 1338 1065 voido1_compareVar() {1339 int FWScript::o1_compareVar() { 1066 1340 byte varIdx = getNextByte(); 1067 1341 byte varType = getNextByte(); 1068 1342 1069 1343 if (varType) { 1070 1344 byte dataIdx = getNextByte(); 1071 1345 1072 // printf("Val: %d\n", dataIdx);1073 1074 1346 if (varType == 1) { 1075 assert(varIdx < 50); 1076 assert(dataIdx < 50); 1077 1078 debugC(5, kCineDebugScript, "Line: %d: compare var[%d] and var[%d]", _currentLine, varIdx, dataIdx); 1079 _currentScriptElement->compareResult = compareVars(_currentScriptElement->localVars[varIdx], _currentScriptElement->localVars[dataIdx]); 1347 debugC(5, kCineDebugScript, "Line: %d: compare var[%d] and var[%d]", _line, varIdx, dataIdx); 1348 _compare = compareVars(_localVars[varIdx], _localVars[dataIdx]); 1080 1349 } else if (varType == 2) { 1081 assert(varIdx < 50); 1082 1083 debugC(5, kCineDebugScript, "Line: %d: compare var[%d] and globalVar[%d]", _currentLine, varIdx, dataIdx); 1084 _currentScriptElement->compareResult = compareVars(_currentScriptElement->localVars[varIdx], globalVars[dataIdx]); 1350 debugC(5, kCineDebugScript, "Line: %d: compare var[%d] and globalVar[%d]", _line, varIdx, dataIdx); 1351 _compare = compareVars(_localVars[varIdx], _globalVars[dataIdx]); 1085 1352 } 1086 1353 } else { 1087 1354 int16 value = getNextWord(); 1088 1355 1089 debugC(5, kCineDebugScript, "Line: %d: compare var[%d] and %d", _ currentLine, varIdx, value);1090 _c urrentScriptElement->compareResult = compareVars(_currentScriptElement->localVars[varIdx], value);1356 debugC(5, kCineDebugScript, "Line: %d: compare var[%d] and %d", _line, varIdx, value); 1357 _compare = compareVars(_localVars[varIdx], value); 1091 1358 } 1359 1360 return 0; 1092 1361 } 1093 1362 1094 voido1_modifyObjectParam2() {1363 int FWScript::o1_modifyObjectParam2() { 1095 1364 byte objIdx = getNextByte(); 1096 1365 byte paramIdx = getNextByte(); 1097 1366 byte newValue = getNextByte(); 1098 1367 1099 debugC(5, kCineDebugScript, "Line: %d: modifyObjectParam2(objIdx:%d,paramIdx:%d,var[%d])", _ currentLine, objIdx, paramIdx, newValue);1368 debugC(5, kCineDebugScript, "Line: %d: modifyObjectParam2(objIdx:%d,paramIdx:%d,var[%d])", _line, objIdx, paramIdx, newValue); 1100 1369 1101 modifyObjectParam(objIdx, paramIdx, _currentScriptElement->localVars[newValue]); 1370 modifyObjectParam(objIdx, paramIdx, _localVars[newValue]); 1371 return 0; 1102 1372 } 1103 1373 1104 voido1_loadMask0() {1374 int FWScript::o1_loadMask0() { 1105 1375 // OP_loadV7Element 1106 1376 byte param = getNextByte(); 1107 1377 1108 debugC(5, kCineDebugScript, "Line: %d: addSpriteOverlay(%d)", _ currentLine, param);1378 debugC(5, kCineDebugScript, "Line: %d: addSpriteOverlay(%d)", _line, param); 1109 1379 loadOverlayElement(param, 0); 1380 return 0; 1110 1381 } 1111 1382 1112 voido1_unloadMask0() {1383 int FWScript::o1_unloadMask0() { 1113 1384 byte param = getNextByte(); 1114 1385 1115 debugC(5, kCineDebugScript, "Line: %d: removeSpriteOverlay(%d)", _ currentLine, param);1386 debugC(5, kCineDebugScript, "Line: %d: removeSpriteOverlay(%d)", _line, param); 1116 1387 freeOverlay(param, 0); 1388 return 0; 1117 1389 } 1118 1390 1119 voido1_addToBgList() {1391 int FWScript::o1_addToBgList() { 1120 1392 byte param = getNextByte(); 1121 1393 1122 debugC(5, kCineDebugScript, "Line: %d: addToBGList(%d)", _ currentLine, param);1394 debugC(5, kCineDebugScript, "Line: %d: addToBGList(%d)", _line, param); 1123 1395 addToBGList(param); 1396 return 0; 1124 1397 } 1125 1398 1126 voido1_loadMask1() {1399 int FWScript::o1_loadMask1() { 1127 1400 byte param = getNextByte(); 1128 1401 1129 debugC(5, kCineDebugScript, "Line: %d: addOverlay1(%d)", _ currentLine, param);1402 debugC(5, kCineDebugScript, "Line: %d: addOverlay1(%d)", _line, param); 1130 1403 loadOverlayElement(param, 1); 1404 return 0; 1131 1405 } 1132 1406 1133 voido1_unloadMask1() {1407 int FWScript::o1_unloadMask1() { 1134 1408 byte param = getNextByte(); 1135 1409 1136 debugC(5, kCineDebugScript, "Line: %d: removeOverlay1(%d)", _ currentLine, param);1410 debugC(5, kCineDebugScript, "Line: %d: removeOverlay1(%d)", _line, param); 1137 1411 freeOverlay(param, 1); 1412 return 0; 1138 1413 } 1139 1414 1140 voido1_loadMask4() {1415 int FWScript::o1_loadMask4() { 1141 1416 byte param = getNextByte(); 1142 1417 1143 debugC(5, kCineDebugScript, "Line: %d: addOverlayType4(%d)", _ currentLine, param);1418 debugC(5, kCineDebugScript, "Line: %d: addOverlayType4(%d)", _line, param); 1144 1419 loadOverlayElement(param, 4); 1420 return 0; 1145 1421 } 1146 1422 1147 voido1_unloadMask4() {1423 int FWScript::o1_unloadMask4() { 1148 1424 byte param = getNextByte(); 1149 1425 1150 debugC(5, kCineDebugScript, "Line: %d: removeSpriteOverlay4(%d)", _ currentLine, param);1426 debugC(5, kCineDebugScript, "Line: %d: removeSpriteOverlay4(%d)", _line, param); 1151 1427 freeOverlay(param, 4); 1428 return 0; 1152 1429 } 1153 1430 1154 voido1_addSpriteFilledToBgList() {1431 int FWScript::o1_addSpriteFilledToBgList() { 1155 1432 byte param = getNextByte(); 1156 1433 1157 debugC(5, kCineDebugScript, "Line: %d: op1A(%d) -> TODO !", _ currentLine, param);1434 debugC(5, kCineDebugScript, "Line: %d: op1A(%d) -> TODO !", _line, param); 1158 1435 addSpriteFilledToBGList(param); 1436 return 0; 1159 1437 } 1160 1438 1161 voido1_op1B() {1162 debugC(5, kCineDebugScript, "Line: %d: freeBgIncrustList", _ currentLine);1439 int FWScript::o1_op1B() { 1440 debugC(5, kCineDebugScript, "Line: %d: freeBgIncrustList", _line); 1163 1441 freeBgIncrustList(); 1442 return 0; 1164 1443 } 1165 1444 1166 voido1_label() {1445 int FWScript::o1_label() { 1167 1446 byte labelIdx = getNextByte(); 1168 1447 1169 debugC(5, kCineDebugScript, "Line: %d: label(%d)", _currentLine, labelIdx); 1170 _currentScriptElement->stack[labelIdx] = _currentPosition; 1448 debugC(5, kCineDebugScript, "Line: %d: label(%d)", _line, labelIdx); 1449 _labels[labelIdx] = _pos; 1450 return 0; 1171 1451 } 1172 1452 1173 voido1_goto() {1453 int FWScript::o1_goto() { 1174 1454 byte labelIdx = getNextByte(); 1175 1455 1176 assert(_ currentScriptElement->stack[labelIdx] != -1);1456 assert(_labels[labelIdx] != -1); 1177 1457 1178 debugC(5, kCineDebugScript, "Line: %d: goto label(%d)", _currentLine, labelIdx); 1179 _currentPosition = _currentScriptElement->stack[labelIdx]; 1458 debugC(5, kCineDebugScript, "Line: %d: goto label(%d)", _line, labelIdx); 1459 _pos = _labels[labelIdx]; 1460 return 0; 1180 1461 } 1181 1462 1182 voido1_gotoIfSup() {1463 int FWScript::o1_gotoIfSup() { 1183 1464 byte labelIdx = getNextByte(); 1184 1465 1185 if (_c urrentScriptElement->compareResult== kCmpGT) {1186 assert(_ currentScriptElement->stack[labelIdx] != -1);1466 if (_compare == kCmpGT) { 1467 assert(_labels[labelIdx] != -1); 1187 1468 1188 debugC(5, kCineDebugScript, "Line: %d: if(>) goto %d (true)", _ currentLine, labelIdx);1189 _ currentPosition = _currentScriptElement->stack[labelIdx];1469 debugC(5, kCineDebugScript, "Line: %d: if(>) goto %d (true)", _line, labelIdx); 1470 _pos = _labels[labelIdx]; 1190 1471 } else { 1191 debugC(5, kCineDebugScript, "Line: %d: if(>) goto %d (false)", _ currentLine, labelIdx);1472 debugC(5, kCineDebugScript, "Line: %d: if(>) goto %d (false)", _line, labelIdx); 1192 1473 } 1474 return 0; 1193 1475 } 1194 1476 1195 voido1_gotoIfSupEqu() {1477 int FWScript::o1_gotoIfSupEqu() { 1196 1478 byte labelIdx = getNextByte(); 1197 1479 1198 if (_c urrentScriptElement->compareResult& (kCmpGT | kCmpEQ)) {1199 assert(_ currentScriptElement->stack[labelIdx] != -1);1480 if (_compare & (kCmpGT | kCmpEQ)) { 1481 assert(_labels[labelIdx] != -1); 1200 1482 1201 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto %d (true)", _ currentLine, labelIdx);1202 _ currentPosition = _currentScriptElement->stack[labelIdx];1483 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto %d (true)", _line, labelIdx); 1484 _pos = _labels[labelIdx]; 1203 1485 } else { 1204 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto %d (false)", _ currentLine, labelIdx);1486 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto %d (false)", _line, labelIdx); 1205 1487 } 1488 return 0; 1206 1489 } 1207 1490 1208 voido1_gotoIfInf() {1491 int FWScript::o1_gotoIfInf() { 1209 1492 byte labelIdx = getNextByte(); 1210 1493 1211 if (_c urrentScriptElement->compareResult== kCmpLT) {1212 assert(_ currentScriptElement->stack[labelIdx] != -1);1494 if (_compare == kCmpLT) { 1495 assert(_labels[labelIdx] != -1); 1213 1496 1214 debugC(5, kCineDebugScript, "Line: %d: if(<) goto %d (true)", _ currentLine, labelIdx);1215 _ currentPosition = _currentScriptElement->stack[labelIdx];1497 debugC(5, kCineDebugScript, "Line: %d: if(<) goto %d (true)", _line, labelIdx); 1498 _pos = _labels[labelIdx]; 1216 1499 } else { 1217 debugC(5, kCineDebugScript, "Line: %d: if(<) goto %d (false)", _ currentLine, labelIdx);1500 debugC(5, kCineDebugScript, "Line: %d: if(<) goto %d (false)", _line, labelIdx); 1218 1501 } 1502 return 0; 1219 1503 } 1220 1504 1221 voido1_gotoIfInfEqu() {1505 int FWScript::o1_gotoIfInfEqu() { 1222 1506 byte labelIdx = getNextByte(); 1223 1507 1224 if (_c urrentScriptElement->compareResult& (kCmpLT | kCmpEQ)) {1225 assert(_ currentScriptElement->stack[labelIdx] != -1);1508 if (_compare & (kCmpLT | kCmpEQ)) { 1509 assert(_labels[labelIdx] != -1); 1226 1510 1227 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto %d (true)", _ currentLine, labelIdx);1228 _ currentPosition = _currentScriptElement->stack[labelIdx];1511 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto %d (true)", _line, labelIdx); 1512 _pos = _labels[labelIdx]; 1229 1513 } else { 1230 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto %d (false)", _ currentLine, labelIdx);1514 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto %d (false)", _line, labelIdx); 1231 1515 } 1516 return 0; 1232 1517 } 1233 1518 1234 voido1_gotoIfEqu() {1519 int FWScript::o1_gotoIfEqu() { 1235 1520 byte labelIdx = getNextByte(); 1236 1521 1237 if (_c urrentScriptElement->compareResult== kCmpEQ) {1238 assert(_ currentScriptElement->stack[labelIdx] != -1);1522 if (_compare == kCmpEQ) { 1523 assert(_labels[labelIdx] != -1); 1239 1524 1240 debugC(5, kCineDebugScript, "Line: %d: if(==) goto %d (true)", _ currentLine, labelIdx);1241 _ currentPosition = _currentScriptElement->stack[labelIdx];1525 debugC(5, kCineDebugScript, "Line: %d: if(==) goto %d (true)", _line, labelIdx); 1526 _pos = _labels[labelIdx]; 1242 1527 } else { 1243 debugC(5, kCineDebugScript, "Line: %d: if(==) goto %d (false)", _ currentLine, labelIdx);1528 debugC(5, kCineDebugScript, "Line: %d: if(==) goto %d (false)", _line, labelIdx); 1244 1529 } 1530 return 0; 1245 1531 } 1246 1532 1247 voido1_gotoIfDiff() {1533 int FWScript::o1_gotoIfDiff() { 1248 1534 byte labelIdx = getNextByte(); 1249 1535 1250 if (_c urrentScriptElement->compareResult!= kCmpEQ) {1251 assert(_ currentScriptElement->stack[labelIdx] != -1);1536 if (_compare != kCmpEQ) { 1537 assert(_labels[labelIdx] != -1); 1252 1538 1253 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto %d (true)", _ currentLine, labelIdx);1254 _ currentPosition = _currentScriptElement->stack[labelIdx];1539 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto %d (true)", _line, labelIdx); 1540 _pos = _labels[labelIdx]; 1255 1541 } else { 1256 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto %d (false)", _ currentLine, labelIdx);1542 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto %d (false)", _line, labelIdx); 1257 1543 } 1544 return 0; 1258 1545 } 1259 1546 1260 voido1_removeLabel() {1547 int FWScript::o1_removeLabel() { 1261 1548 byte labelIdx = getNextByte(); 1262 1549 1263 debugC(5, kCineDebugScript, "Line: %d: removeLabel(%d)", _currentLine, labelIdx); 1264 _currentScriptElement->stack[labelIdx] = -1; 1550 debugC(5, kCineDebugScript, "Line: %d: removeLabel(%d)", _line, labelIdx); 1551 _labels[labelIdx] = -1; 1552 return 0; 1265 1553 } 1266 1554 1267 voido1_loop() {1555 int FWScript::o1_loop() { 1268 1556 byte varIdx = getNextByte(); 1269 1557 byte labelIdx = getNextByte(); 1270 1558 1271 _ currentScriptElement->localVars[varIdx]--;1559 _localVars[varIdx]--; 1272 1560 1273 if (_ currentScriptElement->localVars[varIdx] >= 0) {1274 assert(_ currentScriptElement->stack[labelIdx] != -1);1561 if (_localVars[varIdx] >= 0) { 1562 assert(_labels[labelIdx] != -1); 1275 1563 1276 debugC(5, kCineDebugScript, "Line: %d: loop(var[%d]) goto %d (continue)", _ currentLine, varIdx, labelIdx);1277 _ currentPosition = _currentScriptElement->stack[labelIdx];1564 debugC(5, kCineDebugScript, "Line: %d: loop(var[%d]) goto %d (continue)", _line, varIdx, labelIdx); 1565 _pos = _labels[labelIdx]; 1278 1566 } else { 1279 debugC(5, kCineDebugScript, "Line: %d: loop(var[%d]) goto %d (stop)", _ currentLine, varIdx, labelIdx);1567 debugC(5, kCineDebugScript, "Line: %d: loop(var[%d]) goto %d (stop)", _line, varIdx, labelIdx); 1280 1568 } 1569 return 0; 1281 1570 } 1282 1571 1283 voido1_startGlobalScript() {1572 int FWScript::o1_startGlobalScript() { 1284 1573 // OP_startScript 1285 1574 byte param = getNextByte(); 1286 1575 1287 1576 assert(param < NUM_MAX_SCRIPT); 1288 1577 1289 debugC(5, kCineDebugScript, "Line: %d: startScript(%d)", _ currentLine, param);1578 debugC(5, kCineDebugScript, "Line: %d: startScript(%d)", _line, param); 1290 1579 addScriptToList0(param); 1580 return 0; 1291 1581 } 1292 1582 1293 voido1_endGlobalScript() {1583 int FWScript::o1_endGlobalScript() { 1294 1584 byte scriptIdx = getNextByte(); 1295 1585 1296 debugC(5, kCineDebugScript, "Line: %d: stopGlobalScript(%d)", _currentLine, scriptIdx); 1297 stopGlobalScript(scriptIdx); 1586 debugC(5, kCineDebugScript, "Line: %d: stopGlobalScript(%d)", _line, scriptIdx); 1587 1588 ScriptList::iterator it = globalScripts.begin(); 1589 1590 for (; it != globalScripts.end(); ++it) { 1591 if ((*it)->index() == scriptIdx) { 1592 (*it)->_index = -1; 1593 } 1594 } 1595 1596 return 0; 1298 1597 } 1299 1598 1300 voido1_loadAnim() {1599 int FWScript::o1_loadAnim() { 1301 1600 // OP_loadResource 1302 1601 const char *param = getNextString(); 1303 1602 1304 debugC(5, kCineDebugScript, "Line: %d: loadResource(\"%s\")", _ currentLine, param);1603 debugC(5, kCineDebugScript, "Line: %d: loadResource(\"%s\")", _line, param); 1305 1604 loadResource(param); 1605 return 0; 1306 1606 } 1307 1607 1308 voido1_loadBg() {1608 int FWScript::o1_loadBg() { 1309 1609 const char *param = getNextString(); 1310 1610 1311 debugC(5, kCineDebugScript, "Line: %d: loadBg(\"%s\")", _ currentLine, param);1611 debugC(5, kCineDebugScript, "Line: %d: loadBg(\"%s\")", _line, param); 1312 1612 1313 1613 loadBg(param); 1314 1614 freeBgIncrustList(); 1315 1615 bgVar0 = 0; 1616 return 0; 1316 1617 } 1317 1618 1318 voido1_loadCt() {1619 int FWScript::o1_loadCt() { 1319 1620 const char *param = getNextString(); 1320 1621 1321 debugC(5, kCineDebugScript, "Line: %d: loadCt(\"%s\")", _ currentLine, param);1622 debugC(5, kCineDebugScript, "Line: %d: loadCt(\"%s\")", _line, param); 1322 1623 loadCt(param); 1624 return 0; 1323 1625 } 1324 1626 1325 voido1_loadPart() {1627 int FWScript::o1_loadPart() { 1326 1628 const char *param = getNextString(); 1327 1629 1328 debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _ currentLine, param);1630 debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _line, param); 1329 1631 loadPart(param); 1632 return 0; 1330 1633 } 1331 1634 1332 voido1_closePart() {1333 debugC(5, kCineDebugScript, "Line: %d: closePart", _ currentLine);1635 int FWScript::o1_closePart() { 1636 debugC(5, kCineDebugScript, "Line: %d: closePart", _line); 1334 1637 closePart(); 1638 return 0; 1335 1639 } 1336 1640 1337 voido1_loadNewPrcName() {1641 int FWScript::o1_loadNewPrcName() { 1338 1642 // OP_loadData 1339 1643 byte param1 = getNextByte(); 1340 1644 const char *param2 = getNextString(); … … 1343 1647 1344 1648 switch (param1) { 1345 1649 case 0: 1346 debugC(5, kCineDebugScript, "Line: %d: loadPrc(\"%s\")", _ currentLine, param2);1650 debugC(5, kCineDebugScript, "Line: %d: loadPrc(\"%s\")", _line, param2); 1347 1651 strcpy(newPrcName, param2); 1348 1652 break; 1349 1653 case 1: 1350 debugC(5, kCineDebugScript, "Line: %d: loadRel(\"%s\")", _ currentLine, param2);1654 debugC(5, kCineDebugScript, "Line: %d: loadRel(\"%s\")", _line, param2); 1351 1655 strcpy(newRelName, param2); 1352 1656 break; 1353 1657 case 2: 1354 debugC(5, kCineDebugScript, "Line: %d: loadObject(\"%s\")", _ currentLine, param2);1658 debugC(5, kCineDebugScript, "Line: %d: loadObject(\"%s\")", _line, param2); 1355 1659 strcpy(newObjectName, param2); 1356 1660 break; 1357 1661 case 3: 1358 debugC(5, kCineDebugScript, "Line: %d: loadMsg(\"%s\")", _ currentLine, param2);1662 debugC(5, kCineDebugScript, "Line: %d: loadMsg(\"%s\")", _line, param2); 1359 1663 strcpy(newMsgName, param2); 1360 1664 break; 1361 1665 } 1666 return 0; 1362 1667 } 1363 1668 1364 voido1_requestCheckPendingDataLoad() {1365 debugC(5, kCineDebugScript, "Line: %d: request data load", _ currentLine);1669 int FWScript::o1_requestCheckPendingDataLoad() { 1670 debugC(5, kCineDebugScript, "Line: %d: request data load", _line); 1366 1671 checkForPendingDataLoadSwitch = 1; 1672 return 0; 1367 1673 } 1368 1674 1369 voido1_blitAndFade() {1370 debugC(5, kCineDebugScript, "Line: %d: request fadein", _ currentLine);1675 int FWScript::o1_blitAndFade() { 1676 debugC(5, kCineDebugScript, "Line: %d: request fadein", _line); 1371 1677 // TODO: use real code 1372 1678 1373 1679 drawOverlays(); 1374 1680 fadeRequired = true; 1375 1681 flip(); 1682 return 0; 1376 1683 } 1377 1684 1378 voido1_fadeToBlack() {1379 debugC(5, kCineDebugScript, "Line: %d: request fadeout", _ currentLine);1685 int FWScript::o1_fadeToBlack() { 1686 debugC(5, kCineDebugScript, "Line: %d: request fadeout", _line); 1380 1687 1381 1688 fadeToBlack(); 1689 return 0; 1382 1690 } 1383 1691 1384 voido1_transformPaletteRange() {1692 int FWScript::o1_transformPaletteRange() { 1385 1693 byte startColor = getNextByte(); 1386 1694 byte numColor = getNextByte(); 1387 1695 uint16 r = getNextWord(); 1388 1696 uint16 g = getNextWord(); 1389 1697 uint16 b = getNextWord(); 1390 1698 1391 debugC(5, kCineDebugScript, "Line: %d: transformPaletteRange(from:%d,numIdx:%d,r:%d,g:%d,b:%d)", _ currentLine, startColor, numColor, r, g, b);1699 debugC(5, kCineDebugScript, "Line: %d: transformPaletteRange(from:%d,numIdx:%d,r:%d,g:%d,b:%d)", _line, startColor, numColor, r, g, b); 1392 1700 1393 1701 transformPaletteRange(startColor, numColor, r, g, b); 1702 return 0; 1394 1703 } 1395 1704 1396 voido1_setDefaultMenuColor2() {1705 int FWScript::o1_setDefaultMenuColor2() { 1397 1706 byte param = getNextByte(); 1398 1707 1399 debugC(5, kCineDebugScript, "Line: %d: setDefaultMenuColor2(%d)", _ currentLine, param);1708 debugC(5, kCineDebugScript, "Line: %d: setDefaultMenuColor2(%d)", _line, param); 1400 1709 defaultMenuBoxColor2 = param; 1710 return 0; 1401 1711 } 1402 1712 1403 voido1_palRotate() {1713 int FWScript::o1_palRotate() { 1404 1714 byte a = getNextByte(); 1405 1715 byte b = getNextByte(); 1406 1716 byte c = getNextByte(); 1407 1717 1408 debugC(5, kCineDebugScript, "Line: %d: palRotate(%d,%d,%d)", _ currentLine, a, b, c);1718 debugC(5, kCineDebugScript, "Line: %d: palRotate(%d,%d,%d)", _line, a, b, c); 1409 1719 palRotate(a, b, c); 1720 return 0; 1410 1721 } 1411 1722 1412 void o1_break() { 1413 debugC(5, kCineDebugScript, "Line: %d: break", _currentLine); 1723 /*!\brief Pause script 1724 * \todo Make sure it works 1725 */ 1726 int FWScript::o1_break() { 1727 debugC(5, kCineDebugScript, "Line: %d: break", _line); 1414 1728 1415 _currentScriptElement->scriptPosition = _currentPosition; 1416 _closeScript = 1; 1729 return 1; 1417 1730 } 1418 1731 1419 void o1_endScript() { 1420 debugC(5, kCineDebugScript, "Line: %d: endScript", _currentLine); 1732 /*! \brief Terminate script 1733 * \todo Make sure it works 1734 */ 1735 int FWScript::o1_endScript() { 1736 debugC(5, kCineDebugScript, "Line: %d: endScript", _line); 1421 1737 1422 if (_currentScriptParams == 0) { 1423 endScript0(_currentScriptElement->scriptIdx); 1424 } else { 1425 endScript1(_currentScriptElement->scriptIdx); 1426 } 1427 1428 _closeScript = 1; 1738 return -1; 1429 1739 } 1430 1740 1431 voido1_message() {1741 int FWScript::o1_message() { 1432 1742 byte param1 = getNextByte(); 1433 1743 uint16 param2 = getNextWord(); 1434 1744 uint16 param3 = getNextWord(); 1435 1745 uint16 param4 = getNextWord(); 1436 1746 uint16 param5 = getNextWord(); 1437 1747 1438 debugC(5, kCineDebugScript, "Line: %d: message(%d,%d,%d,%d,%d)", _ currentLine, param1, param2, param3, param4, param5);1748 debugC(5, kCineDebugScript, "Line: %d: message(%d,%d,%d,%d,%d)", _line, param1, param2, param3, param4, param5); 1439 1749 1440 1750 addMessage(param1, param2, param3, param4, param5); 1751 return 0; 1441 1752 } 1442 1753 1443 voido1_loadGlobalVar() {1754 int FWScript::o1_loadGlobalVar() { 1444 1755 byte varIdx = getNextByte(); 1445 1756 byte varType = getNextByte(); 1446 1757 … … 1448 1759 byte dataIdx = getNextByte(); 1449 1760 1450 1761 if (varType == 1) { 1451 debugC(5, kCineDebugScript, "Line: %d: globalVars[%d] = var[%d]", _ currentLine, varIdx, dataIdx);1452 globalVars[varIdx] = _currentScriptElement->localVars[dataIdx];1762 debugC(5, kCineDebugScript, "Line: %d: globalVars[%d] = var[%d]", _line, varIdx, dataIdx); 1763 _globalVars[varIdx] = _localVars[dataIdx]; 1453 1764 } else { 1454 debugC(5, kCineDebugScript, "Line: %d: globalVars[%d] = globalVars[%d]", _ currentLine, varIdx, dataIdx);1455 globalVars[varIdx] =globalVars[dataIdx];1765 debugC(5, kCineDebugScript, "Line: %d: globalVars[%d] = globalVars[%d]", _line, varIdx, dataIdx); 1766 _globalVars[varIdx] = _globalVars[dataIdx]; 1456 1767 } 1457 1768 } else { 1458 1769 uint16 value = getNextWord(); 1459 1770 1460 debugC(5, kCineDebugScript, "Line: %d: globalVars[%d] = %d", _ currentLine, varIdx, value);1461 globalVars[varIdx] = value;1771 debugC(5, kCineDebugScript, "Line: %d: globalVars[%d] = %d", _line, varIdx, value); 1772 _globalVars[varIdx] = value; 1462 1773 } 1774 1775 return 0; 1463 1776 } 1464 1777 1465 voido1_compareGlobalVar() {1778 int FWScript::o1_compareGlobalVar() { 1466 1779 byte varIdx = getNextByte(); 1467 1780 byte varType = getNextByte(); 1468 1781 1469 1782 if (varType) { 1470 1783 byte value = getNextByte(); 1471 1784 1472 debugC(5, kCineDebugScript, "Line: %d: compare globalVars[%d] and var[%d]", _ currentLine, varIdx, value);1473 _c urrentScriptElement->compareResult = compareVars(globalVars[varIdx], _currentScriptElement->localVars[value]);1785 debugC(5, kCineDebugScript, "Line: %d: compare globalVars[%d] and var[%d]", _line, varIdx, value); 1786 _compare = compareVars(_globalVars[varIdx], _localVars[value]); 1474 1787 } else { 1475 1788 uint16 value = getNextWord(); 1476 1789 1477 debugC(5, kCineDebugScript, "Line: %d: compare globalVars[%d] and %d", _ currentLine, varIdx, value);1790 debugC(5, kCineDebugScript, "Line: %d: compare globalVars[%d] and %d", _line, varIdx, value); 1478 1791 1479 1792 if (varIdx == 255 && (g_cine->getGameType() == Cine::GType_FW)) { // TODO: fix 1480 _c urrentScriptElement->compareResult= 1;1793 _compare = 1; 1481 1794 } else { 1482 _c urrentScriptElement->compareResult = compareVars(globalVars[varIdx], value);1795 _compare = compareVars(_globalVars[varIdx], value); 1483 1796 } 1484 1797 } 1798 1799 return 0; 1485 1800 } 1486 1801 1487 voido1_declareFunctionName() {1802 int FWScript::o1_declareFunctionName() { 1488 1803 const char *param = getNextString(); 1489 1804 1490 debugC(5, kCineDebugScript, "Line: %d: comment(%s)", _currentLine, param); 1805 debugC(5, kCineDebugScript, "Line: %d: comment(%s)", _line, param); 1806 return 0; 1491 1807 } 1492 1808 1493 voido1_freePartRange() {1809 int FWScript::o1_freePartRange() { 1494 1810 byte startIdx = getNextByte(); 1495 1811 byte numIdx = getNextByte(); 1496 1812 1497 1813 assert(startIdx + numIdx <= NUM_MAX_ANIMDATA); 1498 1814 1499 debugC(5, kCineDebugScript, "Line: %d: freePartRange(%d,%d)", _ currentLine, startIdx, numIdx);1815 debugC(5, kCineDebugScript, "Line: %d: freePartRange(%d,%d)", _line, startIdx, numIdx); 1500 1816 freeAnimDataRange(startIdx, numIdx); 1817 return 0; 1501 1818 } 1502 1819 1503 voido1_unloadAllMasks() {1504 debugC(5, kCineDebugScript, "Line: %d: unloadAllMasks()", _ currentLine);1820 int FWScript::o1_unloadAllMasks() { 1821 debugC(5, kCineDebugScript, "Line: %d: unloadAllMasks()", _line); 1505 1822 unloadAllMasks(); 1823 return 0; 1506 1824 } 1507 1825 1508 void o1_setScreenDimensions() { 1826 /*! \todo Implement this instruction 1827 */ 1828 int FWScript::o1_setScreenDimensions() { 1509 1829 warning("STUB: o1_setScreenDimensions()"); 1510 1830 getNextWord(); 1511 1831 getNextWord(); 1512 1832 getNextWord(); 1513 1833 getNextWord(); 1514 1834 // setupScreenParam 1835 return 0; 1515 1836 } 1516 1837 1517 void o1_displayBackground() { 1838 /*! \todo Implement this instruction 1839 */ 1840 int FWScript::o1_displayBackground() { 1518 1841 warning("STUB: o1_displayBackground()"); 1842 return 0; 1519 1843 } 1520 1844 1521 voido1_initializeZoneData() {1522 debugC(5, kCineDebugScript, "Line: %d: initializeZoneData()", _ currentLine);1845 int FWScript::o1_initializeZoneData() { 1846 debugC(5, kCineDebugScript, "Line: %d: initializeZoneData()", _line); 1523 1847 1524 1848 for (int i = 0; i < NUM_MAX_ZONE; i++) { 1525 1849 zoneData[i] = i; 1526 1850 } 1851 return 0; 1527 1852 } 1528 1853 1529 voido1_setZoneDataEntry() {1854 int FWScript::o1_setZoneDataEntry() { 1530 1855 byte zoneIdx = getNextByte(); 1531 1856 uint16 var = getNextWord(); 1532 1857 1533 debugC(5, kCineDebugScript, "Line: %d: setZone[%d] = %d", _ currentLine, zoneIdx, var);1858 debugC(5, kCineDebugScript, "Line: %d: setZone[%d] = %d", _line, zoneIdx, var); 1534 1859 zoneData[zoneIdx] = var; 1860 return 0; 1535 1861 } 1536 1862 1537 voido1_getZoneDataEntry() {1863 int FWScript::o1_getZoneDataEntry() { 1538 1864 byte zoneIdx = getNextByte(); 1539 1865 byte var = getNextByte(); 1540 1866 1541 _currentScriptElement->localVars[var] = zoneData[zoneIdx]; 1867 _localVars[var] = zoneData[zoneIdx]; 1868 return 0; 1542 1869 } 1543 1870 1544 voido1_setDefaultMenuColor() {1871 int FWScript::o1_setDefaultMenuColor() { 1545 1872 byte param = getNextByte(); 1546 1873 1547 debugC(5, kCineDebugScript, "Line: %d: setDefaultMenuColor(%d)", _ currentLine, param);1874 debugC(5, kCineDebugScript, "Line: %d: setDefaultMenuColor(%d)", _line, param); 1548 1875 defaultMenuBoxColor = param; 1876 return 0; 1549 1877 } 1550 1878 1551 voido1_allowPlayerInput() {1552 debugC(5, kCineDebugScript, "Line: %d: allowPlayerInput()", _ currentLine);1879 int FWScript::o1_allowPlayerInput() { 1880 debugC(5, kCineDebugScript, "Line: %d: allowPlayerInput()", _line); 1553 1881 allowPlayerInput = 1; 1882 return 0; 1554 1883 } 1555 1884 1556 voido1_disallowPlayerInput() {1557 debugC(5, kCineDebugScript, "Line: %d: dissallowPlayerInput()", _ currentLine);1885 int FWScript::o1_disallowPlayerInput() { 1886 debugC(5, kCineDebugScript, "Line: %d: dissallowPlayerInput()", _line); 1558 1887 allowPlayerInput = 0; 1888 return 0; 1559 1889 } 1560 1890 1561 voido1_changeDataDisk() {1891 int FWScript::o1_changeDataDisk() { 1562 1892 byte newDisk = getNextByte(); 1563 1893 1564 debugC(5, kCineDebugScript, "Line: %d: changeDataDisk(%d)", _ currentLine, newDisk);1894 debugC(5, kCineDebugScript, "Line: %d: changeDataDisk(%d)", _line, newDisk); 1565 1895 checkDataDisk(newDisk); 1896 return 0; 1566 1897 } 1567 1898 1568 voido1_loadMusic() {1899 int FWScript::o1_loadMusic() { 1569 1900 const char *param = getNextString(); 1570 1901 1571 debugC(5, kCineDebugScript, "Line: %d: loadMusic(%s)", _ currentLine, param);1902 debugC(5, kCineDebugScript, "Line: %d: loadMusic(%s)", _line, param); 1572 1903 g_sound->loadMusic(param); 1904 return 0; 1573 1905 } 1574 1906 1575 voido1_playMusic() {1576 debugC(5, kCineDebugScript, "Line: %d: playMusic()", _ currentLine);1907 int FWScript::o1_playMusic() { 1908 debugC(5, kCineDebugScript, "Line: %d: playMusic()", _line); 1577 1909 g_sound->playMusic(); 1910 return 0; 1578 1911 } 1579 1912 1580 voido1_fadeOutMusic() {1581 debugC(5, kCineDebugScript, "Line: %d: fadeOutMusic()", _ currentLine);1913 int FWScript::o1_fadeOutMusic() { 1914 debugC(5, kCineDebugScript, "Line: %d: fadeOutMusic()", _line); 1582 1915 g_sound->fadeOutMusic(); 1916 return 0; 1583 1917 } 1584 1918 1585 voido1_stopSample() {1586 debugC(5, kCineDebugScript, "Line: %d: stopSample()", _ currentLine);1919 int FWScript::o1_stopSample() { 1920 debugC(5, kCineDebugScript, "Line: %d: stopSample()", _line); 1587 1921 g_sound->stopMusic(); 1922 return 0; 1588 1923 } 1589 1924 1590 void o1_op71() { 1925 /*! \todo Implement this instruction 1926 */ 1927 int FWScript::o1_op71() { 1591 1928 warning("STUB: o1_op71()"); 1592 1929 getNextByte(); 1593 1930 getNextWord(); 1931 return 0; 1594 1932 } 1595 1933 1596 void o1_op72() { 1934 /*! \todo Implement this instruction 1935 */ 1936 int FWScript::o1_op72() { 1597 1937 warning("STUB: o1_op72()"); 1598 1938 getNextWord(); 1599 1939 getNextByte(); 1600 1940 getNextWord(); 1941 return 0; 1601 1942 } 1602 1943 1603 void o1_op73() { 1944 /*! \todo Implement this instruction 1945 */ 1946 int FWScript::o1_op73() { 1604 1947 // I believe this opcode is identical to o1_op72(). In fact, Operation 1605 1948 // Stealth doesn't even have it. It uses o1_op72() instead. 1606 1949 warning("STUB: o1_op73()"); 1607 1950 getNextWord(); 1608 1951 getNextByte(); 1609 1952 getNextWord(); 1953 return 0; 1610 1954 } 1611 1955 1612 voido1_playSample() {1613 debugC(5, kCineDebugScript, "Line: %d: playSample()", _ currentLine);1956 int FWScript::o1_playSample() { 1957 debugC(5, kCineDebugScript, "Line: %d: playSample()", _line); 1614 1958 1615 1959 byte anim = getNextByte(); 1616 1960 byte channel = getNextByte(); … … 1622 1966 uint16 size = getNextWord(); 1623 1967 1624 1968 if (!animDataTable[anim].ptr1) { 1625 return ;1969 return 0; 1626 1970 } 1627 1971 1628 1972 if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) { … … 1658 2002 volume = 50; 1659 2003 } 1660 2004 if (g_cine->getGameType() == Cine::GType_OS && size == 0) { 1661 return ;2005 return 0; 1662 2006 } 1663 2007 g_sound->stopMusic(); 1664 2008 if (size == 0xFFFF) { … … 1667 2011 g_sound->stopSound(channel); 1668 2012 } 1669 2013 } 2014 return 0; 1670 2015 } 1671 2016 1672 voido1_disableSystemMenu() {2017 int FWScript::o1_disableSystemMenu() { 1673 2018 byte param = getNextByte(); 1674 2019 1675 debugC(5, kCineDebugScript, "Line: %d: disableSystemMenu(%d)", _ currentLine, param);2020 debugC(5, kCineDebugScript, "Line: %d: disableSystemMenu(%d)", _line, param); 1676 2021 disableSystemMenu = (param != 0); 2022 return 0; 1677 2023 } 1678 2024 1679 voido1_loadMask5() {2025 int FWScript::o1_loadMask5() { 1680 2026 byte param = getNextByte(); 1681 2027 1682 debugC(5, kCineDebugScript, "Line: %d: addOverlay5(%d)", _ currentLine, param);2028 debugC(5, kCineDebugScript, "Line: %d: addOverlay5(%d)", _line, param); 1683 2029 loadOverlayElement(param, 5); 2030 return 0; 1684 2031 } 1685 2032 1686 voido1_unloadMask5() {2033 int FWScript::o1_unloadMask5() { 1687 2034 byte param = getNextByte(); 1688 2035 1689 debugC(5, kCineDebugScript, "Line: %d: freeOverlay5(%d)", _ currentLine, param);2036 debugC(5, kCineDebugScript, "Line: %d: freeOverlay5(%d)", _line, param); 1690 2037 freeOverlay(param, 5); 2038 return 0; 1691 2039 } 1692 2040 1693 2041 // ------------------------------------------------------------------------ 1694 2042 // OPERATION STEALTH opcodes 1695 2043 // ------------------------------------------------------------------------ 1696 2044 1697 voido2_loadPart() {2045 int FWScript::o2_loadPart() { 1698 2046 const char *param = getNextString(); 1699 2047 1700 debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _currentLine, param); 2048 debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _line, param); 2049 return 0; 1701 2050 } 1702 2051 1703 voido2_playSample() {2052 int FWScript::o2_playSample() { 1704 2053 if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) { 1705 2054 // no-op in these versions 1706 2055 getNextByte(); … … 1709 2058 getNextByte(); 1710 2059 getNextWord(); 1711 2060 getNextWord(); 1712 return ;2061 return 0; 1713 2062 } 1714 o1_playSample();2063 return o1_playSample(); 1715 2064 } 1716 2065 1717 voido2_playSampleAlt() {2066 int FWScript::o2_playSampleAlt() { 1718 2067 byte num = getNextByte(); 1719 2068 byte channel = getNextByte(); 1720 2069 uint16 frequency = getNextWord(); … … 1735 2084 g_sound->playSound(channel, frequency, animDataTable[num].ptr1, size, 0, 0, 63, 0); 1736 2085 } 1737 2086 } 2087 return 0; 1738 2088 } 1739 2089 1740 voido2_addSeqListElement() {2090 int FWScript::o2_addSeqListElement() { 1741 2091 byte param1 = getNextByte(); 1742 2092 byte param2 = getNextByte(); 1743 2093 byte param3 = getNextByte(); … … 1746 2096 uint16 param6 = getNextWord(); 1747 2097 uint16 param7 = getNextWord(); 1748 2098 1749 debugC(5, kCineDebugScript, "Line: %d: addSeqListElement(%d,%d,%d,%d,%d,%d,%d)", _ currentLine, param1, param2, param3, param4, param5, param6, param7);2099 debugC(5, kCineDebugScript, "Line: %d: addSeqListElement(%d,%d,%d,%d,%d,%d,%d)", _line, param1, param2, param3, param4, param5, param6, param7); 1750 2100 addSeqListElement(param1, 0, param2, param3, param4, param5, param6, 0, param7); 2101 return 0; 1751 2102 } 1752 2103 1753 voido2_removeSeq() {2104 int FWScript::o2_removeSeq() { 1754 2105 byte a = getNextByte(); 1755 2106 byte b = getNextByte(); 1756 2107 1757 debugC(5, kCineDebugScript, "Line: %d: removeSeq(%d,%d) -> TODO", _ currentLine, a, b);2108 debugC(5, kCineDebugScript, "Line: %d: removeSeq(%d,%d) -> TODO", _line, a, b); 1758 2109 removeSeq(a, 0, b); 2110 return 0; 1759 2111 } 1760 2112 1761 void o2_op81() { 2113 /*! \todo Implement this instruction 2114 */ 2115 int FWScript::o2_op81() { 1762 2116 warning("STUB: o2_op81()"); 1763 2117 // freeUnkList(); 2118 return 0; 1764 2119 } 1765 2120 1766 void o2_op82() { 2121 /*! \todo Implement this instruction 2122 */ 2123 int FWScript::o2_op82() { 1767 2124 warning("STUB: o2_op82()"); 1768 2125 getNextByte(); 1769 2126 getNextByte(); 1770 2127 getNextWord(); 2128 return 0; 1771 2129 } 1772 2130 1773 voido2_isSeqRunning() {2131 int FWScript::o2_isSeqRunning() { 1774 2132 byte a = getNextByte(); 1775 2133 byte b = getNextByte(); 1776 2134 1777 debugC(5, kCineDebugScript, "Line: %d: OP83(%d,%d) -> TODO", _ currentLine, a, b);2135 debugC(5, kCineDebugScript, "Line: %d: OP83(%d,%d) -> TODO", _line, a, b); 1778 2136 1779 2137 if (isSeqRunning(a, 0, b)) { 1780 _c urrentScriptElement->compareResult= 1;2138 _compare = 1; 1781 2139 } else { 1782 _c urrentScriptElement->compareResult= 0;2140 _compare = 0; 1783 2141 } 2142 return 0; 1784 2143 } 1785 2144 1786 void o2_gotoIfSupNearest() { 2145 /*! \todo The assert may produce false positives and requires testing 2146 */ 2147 int FWScript::o2_gotoIfSupNearest() { 1787 2148 byte labelIdx = getNextByte(); 1788 2149 1789 if (_c urrentScriptElement->compareResult== kCmpGT) {1790 assert(_ currentScriptElement->stack[labelIdx] != -1);2150 if (_compare == kCmpGT) { 2151 assert(_labels[labelIdx] != -1); 1791 2152 1792 debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (true)", _ currentLine, labelIdx);1793 _ currentPosition = computeScriptStackFromScript(_currentScriptElement->scriptPtr, _currentPosition, labelIdx, scriptTable[_currentScriptElement->scriptIdx].size);2153 debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (true)", _line, labelIdx); 2154 _pos = _script.getLabel(*_info, labelIdx, _pos); 1794 2155 } else { 1795 debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (false)", _ currentLine, labelIdx);2156 debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (false)", _line, labelIdx); 1796 2157 } 2158 return 0; 1797 2159 } 1798 2160 1799 void o2_gotoIfSupEquNearest() { 2161 /*! \todo The assert may produce false positives and requires testing 2162 */ 2163 int FWScript::o2_gotoIfSupEquNearest() { 1800 2164 byte labelIdx = getNextByte(); 1801 2165 1802 if (_c urrentScriptElement->compareResult& (kCmpGT | kCmpEQ)) {1803 assert(_ currentScriptElement->stack[labelIdx] != -1);2166 if (_compare & (kCmpGT | kCmpEQ)) { 2167 assert(_labels[labelIdx] != -1); 1804 2168 1805 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (true)", _ currentLine, labelIdx);1806 _ currentPosition = computeScriptStackFromScript(_currentScriptElement->scriptPtr, _currentPosition, labelIdx, scriptTable[_currentScriptElement->scriptIdx].size);2169 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (true)", _line, labelIdx); 2170 _pos = _script.getLabel(*_info, labelIdx, _pos); 1807 2171 } else { 1808 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (false)", _ currentLine, labelIdx);2172 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (false)", _line, labelIdx); 1809 2173 } 2174 return 0; 1810 2175 } 1811 2176 1812 void o2_gotoIfInfNearest() { 2177 /*! \todo The assert may produce false positives and requires testing 2178 */ 2179 int FWScript::o2_gotoIfInfNearest() { 1813 2180 byte labelIdx = getNextByte(); 1814 2181 1815 if (_c urrentScriptElement->compareResult== kCmpLT) {1816 assert(_ currentScriptElement->stack[labelIdx] != -1);2182 if (_compare == kCmpLT) { 2183 assert(_labels[labelIdx] != -1); 1817 2184 1818 debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (true)", _ currentLine, labelIdx);1819 _ currentPosition = computeScriptStackFromScript(_currentScriptElement->scriptPtr, _currentPosition, labelIdx, scriptTable[_currentScriptElement->scriptIdx].size);2185 debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (true)", _line, labelIdx); 2186 _pos = _script.getLabel(*_info, labelIdx, _pos); 1820 2187 } else { 1821 debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (false)", _ currentLine, labelIdx);2188 debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (false)", _line, labelIdx); 1822 2189 } 2190 return 0; 1823 2191 } 1824 2192 1825 void o2_gotoIfInfEquNearest() { 2193 /*! \todo The assert may produce false positives and requires testing 2194 */ 2195 int FWScript::o2_gotoIfInfEquNearest() { 1826 2196 byte labelIdx = getNextByte(); 1827 2197 1828 if (_c urrentScriptElement->compareResult& (kCmpLT | kCmpEQ)) {1829 assert(_ currentScriptElement->stack[labelIdx] != -1);2198 if (_compare & (kCmpLT | kCmpEQ)) { 2199 assert(_labels[labelIdx] != -1); 1830 2200 1831 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (true)", _ currentLine, labelIdx);1832 _ currentPosition = computeScriptStackFromScript(_currentScriptElement->scriptPtr, _currentPosition, labelIdx, scriptTable[_currentScriptElement->scriptIdx].size);2201 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (true)", _line, labelIdx); 2202 _pos = _script.getLabel(*_info, labelIdx, _pos); 1833 2203 } else { 1834 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (false)", _ currentLine, labelIdx);2204 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (false)", _line, labelIdx); 1835 2205 } 2206 return 0; 1836 2207 } 1837 2208 1838 void o2_gotoIfEquNearest() { 2209 /*! \todo The assert may produce false positives and requires testing 2210 */ 2211 int FWScript::o2_gotoIfEquNearest() { 1839 2212 byte labelIdx = getNextByte(); 1840 2213 1841 if (_c urrentScriptElement->compareResult== kCmpEQ) {1842 assert(_ currentScriptElement->stack[labelIdx] != -1);2214 if (_compare == kCmpEQ) { 2215 assert(_labels[labelIdx] != -1); 1843 2216 1844 debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (true)", _ currentLine, labelIdx);1845 _ currentPosition = computeScriptStackFromScript(_currentScriptElement->scriptPtr, _currentPosition, labelIdx, scriptTable[_currentScriptElement->scriptIdx].size);2217 debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (true)", _line, labelIdx); 2218 _pos = _script.getLabel(*_info, labelIdx, _pos); 1846 2219 } else { 1847 debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (false)", _ currentLine, labelIdx);2220 debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (false)", _line, labelIdx); 1848 2221 } 2222 return 0; 1849 2223 } 1850 2224 1851 void o2_gotoIfDiffNearest() { 2225 /*! \todo The assert may produce false positives and requires testing 2226 */ 2227 int FWScript::o2_gotoIfDiffNearest() { 1852 2228 byte labelIdx = getNextByte(); 1853 2229 1854 if (_c urrentScriptElement->compareResult!= kCmpEQ) {1855 assert(_ currentScriptElement->stack[labelIdx] != -1);2230 if (_compare != kCmpEQ) { 2231 assert(_labels[labelIdx] != -1); 1856 2232 1857 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (true)", _ currentLine, labelIdx);1858 _ currentPosition = computeScriptStackFromScript(_currentScriptElement->scriptPtr, _currentPosition, labelIdx, scriptTable[_currentScriptElement->scriptIdx].size);2233 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (true)", _line, labelIdx); 2234 _pos = _script.getLabel(*_info, labelIdx, _pos); 1859 2235 } else { 1860 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (false)", _ currentLine, labelIdx);2236 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (false)", _line, labelIdx); 1861 2237 } 2238 return 0; 1862 2239 } 1863 2240 1864 voido2_startObjectScript() {2241 int FWScript::o2_startObjectScript() { 1865 2242 byte param = getNextByte(); 1866 2243 1867 debugC(5, kCineDebugScript, "Line: %d: startObjectScript(%d)", _ currentLine, param);2244 debugC(5, kCineDebugScript, "Line: %d: startObjectScript(%d)", _line, param); 1868 2245 runObjectScript(param); 2246 return 0; 1869 2247 } 1870 2248 1871 voido2_stopObjectScript() {2249 int FWScript::o2_stopObjectScript() { 1872 2250 byte param = getNextByte(); 1873 2251 1874 debugC(5, kCineDebugScript, "Line: %d: stopObjectScript(%d)", _currentLine, param); 1875 stopObjectScript(param); 2252 debugC(5, kCineDebugScript, "Line: %d: stopObjectScript(%d)", _line, param); 2253 ScriptList::iterator it = objectScripts.begin(); 2254 2255 for (; it != objectScripts.end(); ++it) { 2256 if ((*it)->index() == param) { 2257 (*it)->_index = -1; 2258 } 2259 } 2260 return 0; 1876 2261 } 1877 2262 1878 void o2_op8D() { 2263 /*! \todo Implement this instruction 2264 */ 2265 int FWScript::o2_op8D() { 1879 2266 warning("STUB: o2_op8D()"); 1880 2267 getNextWord(); 1881 2268 getNextWord(); … … 1886 2273 getNextWord(); 1887 2274 getNextWord(); 1888 2275 // _currentScriptElement->compareResult = ... 2276 return 0; 1889 2277 } 1890 2278 1891 voido2_addBackground() {2279 int FWScript::o2_addBackground() { 1892 2280 byte param1 = getNextByte(); 1893 2281 const char *param2 = getNextString(); 1894 2282 1895 debugC(5, kCineDebugScript, "Line: %d: addBackground(%s,%d)", _ currentLine, param2, param1);2283 debugC(5, kCineDebugScript, "Line: %d: addBackground(%s,%d)", _line, param2, param1); 1896 2284 addBackground(param2, param1); 2285 return 0; 1897 2286 } 1898 2287 1899 voido2_removeBackground() {2288 int FWScript::o2_removeBackground() { 1900 2289 byte param = getNextByte(); 1901 2290 1902 2291 assert(param); 1903 2292 1904 debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _ currentLine, param);2293 debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _line, param); 1905 2294 1906 2295 if (additionalBgTable[param]) { 1907 2296 free(additionalBgTable[param]); … … 1917 2306 } 1918 2307 1919 2308 strcpy(currentBgName[param], ""); 2309 return 0; 1920 2310 } 1921 2311 1922 voido2_loadAbs() {2312 int FWScript::o2_loadAbs() { 1923 2313 byte param1 = getNextByte(); 1924 2314 const char *param2 = getNextString(); 1925 2315 1926 debugC(5, kCineDebugScript, "Line: %d: loadABS(%d,%s)", _ currentLine, param1, param2);2316 debugC(5, kCineDebugScript, "Line: %d: loadABS(%d,%s)", _line, param1, param2); 1927 2317 loadAbs(param2, param1); 2318 return 0; 1928 2319 } 1929 2320 1930 voido2_loadBg() {2321 int FWScript::o2_loadBg() { 1931 2322 byte param = getNextByte(); 1932 2323 1933 2324 assert(param <= 8); 1934 2325 1935 debugC(5, kCineDebugScript, "Line: %d: useBg(%d)", _ currentLine, param);2326 debugC(5, kCineDebugScript, "Line: %d: useBg(%d)", _line, param); 1936 2327 1937 2328 if (additionalBgTable[param]) { 1938 2329 currentAdditionalBgIdx = param; … … 1941 2332 //} 1942 2333 fadeRequired = true; 1943 2334 } 2335 return 0; 1944 2336 } 1945 2337 1946 void o2_wasZoneChecked() { 2338 /*! \todo Implement this instruction 2339 */ 2340 int FWScript::o2_wasZoneChecked() { 1947 2341 warning("STUB: o2_wasZoneChecked()"); 2342 return 0; 1948 2343 } 1949 2344 1950 void o2_op9B() { 2345 /*! \todo Implement this instruction 2346 */ 2347 int FWScript::o2_op9B() { 1951 2348 warning("STUB: o2_op9B()"); 1952 2349 getNextWord(); 1953 2350 getNextWord(); … … 1957 2354 getNextWord(); 1958 2355 getNextWord(); 1959 2356 getNextWord(); 2357 return 0; 1960 2358 } 1961 2359 1962 void o2_op9C() { 2360 /*! \todo Implement this instruction 2361 */ 2362 int FWScript::o2_op9C() { 1963 2363 warning("STUB: o2_op9C()"); 1964 2364 getNextWord(); 1965 2365 getNextWord(); 1966 2366 getNextWord(); 1967 2367 getNextWord(); 2368 return 0; 1968 2369 } 1969 2370 1970 voido2_useBgScroll() {2371 int FWScript::o2_useBgScroll() { 1971 2372 byte param = getNextByte(); 1972 2373 1973 2374 assert(param <= 8); 1974 2375 1975 debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _ currentLine, param);2376 debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _line, param); 1976 2377 1977 2378 if (additionalBgTable[param]) { 1978 2379 currentAdditionalBgIdx2 = param; 1979 2380 } 2381 return 0; 1980 2382 } 1981 2383 1982 voido2_setAdditionalBgVScroll() {2384 int FWScript::o2_setAdditionalBgVScroll() { 1983 2385 byte param1 = getNextByte(); 1984 2386 1985 2387 if (param1) { 1986 2388 byte param2 = getNextByte(); 1987 2389 1988 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _ currentLine, param2);1989 additionalBgVScroll = _ currentScriptElement->localVars[param2];2390 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _line, param2); 2391 additionalBgVScroll = _localVars[param2]; 1990 2392 } else { 1991 2393 uint16 param2 = getNextWord(); 1992 2394 1993 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _ currentLine, param2);2395 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _line, param2); 1994 2396 additionalBgVScroll = param2; 1995 2397 } 2398 return 0; 1996 2399 } 1997 2400 1998 void o2_op9F() { 2401 /*! \todo Implement this instruction 2402 */ 2403 int FWScript::o2_op9F() { 1999 2404 warning("o2_op9F()"); 2000 2405 getNextWord(); 2001 2406 getNextWord(); 2407 return 0; 2002 2408 } 2003 2409 2004 voido2_addGfxElementA0() {2410 int FWScript::o2_addGfxElementA0() { 2005 2411 uint16 param1 = getNextWord(); 2006 2412 uint16 param2 = getNextWord(); 2007 2413 2008 debugC(5, kCineDebugScript, "Line: %d: addGfxElementA0(%d,%d)", _ currentLine, param1, param2);2414 debugC(5, kCineDebugScript, "Line: %d: addGfxElementA0(%d,%d)", _line, param1, param2); 2009 2415 addGfxElementA0(param1, param2); 2416 return 0; 2010 2417 } 2011 2418 2012 void o2_opA1() { 2419 /*! \todo Implement this instruction 2420 */ 2421 int FWScript::o2_opA1() { 2013 2422 warning("STUB: o2_opA1()"); 2014 2423 getNextWord(); 2015 2424 getNextWord(); 2016 2425 // removeGfxElementA0( ... ); 2426 return 0; 2017 2427 } 2018 2428 2019 void o2_opA2() { 2429 /*! \todo Implement this instruction 2430 */ 2431 int FWScript::o2_opA2() { 2020 2432 warning("STUB: o2_opA2()"); 2021 2433 getNextWord(); 2022 2434 getNextWord(); 2023 2435 // addGfxElementA2(); 2436 return 0; 2024 2437 } 2025 2438 2026 void o2_opA3() { 2439 /*! \todo Implement this instruction 2440 */ 2441 int FWScript::o2_opA3() { 2027 2442 warning("STUB: o2_opA3()"); 2028 2443 getNextWord(); 2029 2444 getNextWord(); 2030 2445 // removeGfxElementA2(); 2446 return 0; 2031 2447 } 2032 2448 2033 voido2_loadMask22() {2449 int FWScript::o2_loadMask22() { 2034 2450 byte param = getNextByte(); 2035 2451 2036 debugC(5, kCineDebugScript, "Line: %d: addOverlay22(%d)", _ currentLine, param);2452 debugC(5, kCineDebugScript, "Line: %d: addOverlay22(%d)", _line, param); 2037 2453 loadOverlayElement(param, 22); 2454 return 0; 2038 2455 } 2039 2456 2040 voido2_unloadMask22() {2457 int FWScript::o2_unloadMask22() { 2041 2458 byte param = getNextByte(); 2042 2459 2043 debugC(5, kCineDebugScript, "Line: %d: removeOverlay22(%d)", _ currentLine, param);2460 debugC(5, kCineDebugScript, "Line: %d: removeOverlay22(%d)", _line, param); 2044 2461 freeOverlay(param, 22); 2462 return 0; 2045 2463 } 2046 2464 2047 // ------------------------------------------------------------------------2465 //----------------------------------------------------------------------- 2048 2466 2049 void executeScript(prcLinkedListStruct *scriptElement, uint16 params) { 2050 assert(scriptElement); 2467 void addGfxElementA0(int16 param1, int16 param2) { 2468 overlayHeadElement *currentHead = &overlayHead; 2469 overlayHeadElement *tempHead = currentHead; 2470 overlayHeadElement *newElement; 2051 2471 2052 if (scriptElement->scriptIdx == -1) { 2472 currentHead = tempHead->next; 2473 2474 while (currentHead) { 2475 if (objectTable[currentHead->objIdx].mask == objectTable[param1].mask) { 2476 if (currentHead->type == 2 || currentHead->objIdx == 3) { 2477 break; 2478 } 2479 } 2480 2481 tempHead = currentHead; 2482 currentHead = currentHead->next; 2483 } 2484 2485 if (currentHead && currentHead->objIdx == param1 && currentHead->type == 20 && currentHead->x == param2) 2053 2486 return; 2487 2488 newElement = new overlayHeadElement; 2489 2490 newElement->next = tempHead->next; 2491 tempHead->next = newElement; 2492 2493 newElement->objIdx = param1; 2494 newElement->type = 20; 2495 2496 newElement->x = param2; 2497 newElement->y = 0; 2498 newElement->width = 0; 2499 newElement->color = 0; 2500 2501 if (!currentHead) 2502 currentHead = &overlayHead; 2503 2504 newElement->previous = currentHead->previous; 2505 2506 currentHead->previous = newElement; 2507 } 2508 2509 void removeSeq(uint16 param1, uint16 param2, uint16 param3) { 2510 SeqListElement *currentHead = &seqList; 2511 SeqListElement *tempHead = currentHead; 2512 2513 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { 2514 tempHead = currentHead; 2515 currentHead = tempHead->next; 2054 2516 } 2055 2517 2056 assert(scriptElement->scriptPtr); 2518 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) { 2519 currentHead->var4 = -1; 2520 } 2521 } 2057 2522 2058 _currentScriptElement = scriptElement; 2059 _currentScriptParams = params; 2060 _currentScriptPtr = scriptElement->scriptPtr; 2061 _currentPosition = scriptElement->scriptPosition; 2523 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3) { 2524 SeqListElement *currentHead = &seqList; 2525 SeqListElement *tempHead = currentHead; 2062 2526 2063 _closeScript = 0; 2527 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { 2528 tempHead = currentHead; 2529 currentHead = tempHead->next; 2530 } 2064 2531 2065 while (!_closeScript) { 2066 _currentLine = _currentPosition; 2532 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) { 2533 return 1; 2534 } 2067 2535 2068 byte opcode = getNextByte(); 2536 return 0; 2537 } 2069 2538 2070 if (opcode && opcode < _numOpcodes) { 2071 if (_opcodeTable[opcode - 1].proc) 2072 (_opcodeTable[opcode - 1].proc) (); 2073 else 2074 warning("Undefined opcode 0x%02X in executeScript", opcode - 1); 2539 void palRotate(byte a, byte b, byte c) { 2540 if (c == 1) { 2541 uint16 currentColor = c_palette[b]; 2542 2543 for (int16 i = b; i > a; i--) { 2544 c_palette[i] = c_palette[i - 1]; 2075 2545 } 2546 2547 c_palette[a] = currentColor; 2076 2548 } 2077 2549 } 2078 2550 2079 void executeList1(void) { 2080 prcLinkedListStruct *currentHead = objScriptList.next; 2551 void addScriptToList0(uint16 idx) { 2552 ScriptPtr tmp(scriptInfo->create(*scriptTable[idx], idx)); 2553 assert(tmp); 2554 globalScripts.push_back(tmp); 2555 } 2081 2556 2082 while (currentHead) { 2083 prcLinkedListStruct *tempHead; 2557 int16 getZoneFromPosition(byte *page, int16 x, int16 y, int16 width) { 2558 byte *ptr = page + (y * width) + x / 2; 2559 byte zoneVar; 2084 2560 2085 tempHead = currentHead->next; 2561 if (!(x % 2)) { 2562 zoneVar = (*(ptr) >> 4) & 0xF; 2563 } else { 2564 zoneVar = (*(ptr)) & 0xF; 2565 } 2086 2566 2087 executeScript(currentHead, 1); 2567 return zoneVar; 2568 } 2088 2569 2089 currentHead = tempHead; 2570 int16 getZoneFromPositionRaw(byte *page, int16 x, int16 y, int16 width) { 2571 byte *ptr = page + (y * width) + x; 2572 byte zoneVar; 2573 2574 zoneVar = (*(ptr)) & 0xF; 2575 2576 return zoneVar; 2577 } 2578 2579 int16 checkCollision(int16 objIdx, int16 x, int16 y, int16 numZones, int16 zoneIdx) { 2580 int16 lx = objectTable[objIdx].x + x; 2581 int16 ly = objectTable[objIdx].y + y; 2582 int16 idx; 2583 2584 for (int16 i = 0; i < numZones; i++) { 2585 idx = getZoneFromPositionRaw(page3Raw, lx + i, ly, 320); 2586 2587 assert(idx >= 0 && idx <= NUM_MAX_ZONE); 2588 2589 if (zoneData[idx] == zoneIdx) { 2590 return 1; 2591 } 2090 2592 } 2593 2594 return 0; 2091 2595 } 2092 2596 2093 void executeList0(void) {2094 prcLinkedListStruct *currentHead = globalScriptsHead.next;2597 uint16 compareVars(int16 a, int16 b) { 2598 uint16 flag = 0; 2095 2599 2096 while (currentHead) { 2097 prcLinkedListStruct *tempHead; 2600 if (a == b) { 2601 flag |= kCmpEQ; 2602 } else if (a > b) { 2603 flag |= kCmpGT; 2604 } else if (a < b) { 2605 flag |= kCmpLT; 2606 } 2098 2607 2099 executeScript(currentHead, 0); 2608 return flag; 2609 } 2100 2610 2101 tempHead = currentHead->next; 2102 currentHead = tempHead; 2611 void executeList1(void) { 2612 ScriptList::iterator it = objectScripts.begin(); 2613 for (; it != objectScripts.end();) { 2614 if ((*it)->index() < 0 || (*it)->execute() < 0) { 2615 it = objectScripts.erase(it); 2616 } else { 2617 ++it; 2618 } 2103 2619 } 2104 2620 } 2105 2621 2622 void executeList0(void) { 2623 ScriptList::iterator it = globalScripts.begin(); 2624 for (; it != globalScripts.end();) { 2625 if ((*it)->index() < 0 || (*it)->execute() < 0) { 2626 it = globalScripts.erase(it); 2627 } else { 2628 ++it; 2629 } 2630 } 2631 } 2632 2633 /*! \todo objectScripts.clear()? 2634 */ 2106 2635 void purgeList1(void) { 2107 2636 } 2108 2637 … … 2804 3333 sprintf(lineBuffer, "disallowPlayerInput()\n"); 2805 3334 break; 2806 3335 } 2807 case OP_changeDataDisk:3336 case 0x6B: 2808 3337 { 2809 3338 byte newDisk; 2810 3339 … … 2878 3407 2879 3408 if (opcode - 1 == 0x77) { 2880 3409 sprintf(lineBuffer, "playSample(%d,%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5, param6); 2881 else if (opcode - 1 == 0x78) {3410 } else if (opcode - 1 == 0x78) { 2882 3411 sprintf(lineBuffer, "OP_78(%d,%d,%d,%d,%d,%d)\n", param1, param2, param3, param4, param5, param6); 2883 3412 } 2884 3413 -
engines/cine/main_loop.cpp
192 192 freeAnimDataTable(); 193 193 resetMessageHead(); 194 194 resetSeqList(); 195 resetglobalScriptsHead();196 resetObjectScriptHead();197 195 resetBgIncrustList(); 198 196 199 197 setTextWindow(0, 0, 20, 200); … … 320 318 g_sound->stopMusic(); 321 319 freeAnimDataTable(); 322 320 unloadAllMasks(); 323 freePrcLinkedList();324 releaseObjectScripts();325 321 // if (g_cine->getGameType() == Cine::GType_OS) { 326 322 // freeUnkList(); 327 323 // } -
engines/cine/cine.cpp
124 124 loadErrmessDat("errmess.dat"); 125 125 } 126 126 127 // in case ScummVM engines can be restarted in the future 128 scriptTable.clear(); 129 relTable.clear(); 130 objectScripts.clear(); 131 globalScripts.clear(); 132 127 133 memset(objectTable, 0, sizeof(objectTable)); 128 memset(scriptTable, 0, sizeof(scriptTable));129 134 memset(messageTable, 0, sizeof(messageTable)); 130 memset(relTable, 0, sizeof(relTable));131 135 132 136 for (int i = 0; i < NUM_MAX_ANIMDATA; i++) { 133 137 animDataTable[i].ptr1 = animDataTable[i].ptr2 = NULL; … … 138 142 var8 = 0; 139 143 bgIncrustList = NULL; 140 144 141 objScriptList.next = NULL;142 objScriptList.scriptPtr = NULL;143 144 globalScriptsHead.next = NULL;145 globalScriptsHead.scriptPtr = NULL;146 147 145 var2 = var3 = var4 = var5 = 0; 148 146 149 freePrcLinkedList();150 151 147 _preLoad = false; 152 148 if (ConfMan.hasKey("save_slot")) { 153 149 char saveNameBuffer[256]; -
engines/cine/prc.cpp
33 33 34 34 namespace Cine { 35 35 36 prcLinkedListStruct globalScriptsHead;37 prcLinkedListStruct objScriptList;36 ScriptList globalScripts; 37 ScriptList objectScripts; 38 38 39 39 //char currentPrcName[20]; 40 40 41 void resetglobalScriptsHead(void) { 42 globalScriptsHead.next = NULL; 43 globalScriptsHead.scriptIdx = -1; 44 } 45 46 void freePrcLinkedList(void) { 47 prcLinkedListStruct *currentHead = globalScriptsHead.next; 48 49 while (currentHead) { 50 prcLinkedListStruct *temp; 51 52 assert(currentHead); 53 54 temp = currentHead->next; 55 56 delete currentHead; 57 58 currentHead = temp; 59 } 60 61 resetglobalScriptsHead(); 62 } 63 41 /*! \todo Is script size of 0 valid? 42 * \todo Fix script dump code 43 */ 64 44 void loadPrc(const char *pPrcName) { 65 45 byte i; 66 46 uint16 numScripts; … … 68 48 69 49 assert(pPrcName); 70 50 71 for (i = 0; i < NUM_MAX_SCRIPT; i++) { 72 if (scriptTable[i].ptr) { 73 assert(scriptTable[i].ptr); 74 free(scriptTable[i].ptr); 75 scriptTable[i].ptr = NULL; 76 scriptTable[i].size = 0; 77 } 78 } 51 globalScripts.clear(); 52 scriptTable.clear(); 79 53 80 54 // This is copy protection. Used to hang the machine 81 55 if (!scumm_stricmp(pPrcName, "L201.ANI")) { … … 100 74 assert(numScripts <= NUM_MAX_SCRIPT); 101 75 102 76 for (i = 0; i < numScripts; i++) { 103 scriptTable[i].size = READ_BE_UINT16(scriptPtr); scriptPtr += 2; 77 RawScriptPtr tmp(new RawScript(READ_BE_UINT16(scriptPtr))); 78 scriptPtr += 2; 79 assert(tmp); 80 scriptTable.push_back(tmp); 104 81 } 105 82 106 83 for (i = 0; i < numScripts; i++) { 107 uint16 size = scriptTable[i].size; 84 uint16 size = scriptTable[i]->size(); 85 // TODO: delete the test? 108 86 if (size) { 109 scriptTable[i].ptr = (byte *) malloc(size); 110 assert(scriptTable[i].ptr); 111 memcpy(scriptTable[i].ptr, scriptPtr, size); 87 scriptTable[i]->setData(*scriptInfo, scriptPtr); 112 88 scriptPtr += size; 113 computeScriptStack(scriptTable[i].ptr, scriptTable[i].stack, size);114 89 } 115 90 } 116 91 -
engines/cine/rel.h
26 26 #ifndef CINE_REL_H 27 27 #define CINE_REL_H 28 28 29 #include "cine/script.h" 29 30 namespace Cine { 30 31 31 struct RelObjectScript { 32 byte *data; 33 uint16 size; 34 uint16 obj1Param1; 35 uint16 obj1Param2; 36 uint16 obj2Param; 37 uint16 runCount; 38 }; 32 extern RawObjectScriptArray relTable; 39 33 40 #define NUM_MAX_REL 25541 42 extern RelObjectScript relTable[NUM_MAX_REL];43 44 void releaseObjectScripts(void);45 void resetObjectScriptHead(void);46 47 34 void loadRel(char *pRelName); 48 35 49 36 } // End of namespace Cine