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