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