Ticket #8853: overlay.patch
File overlay.patch, 80.6 KB (added by , 17 years ago) |
---|
-
engines/cine/script_fw.cpp
24 24 */ 25 25 26 26 /*! \file 27 * Script interpreter file27 * Future Wars script interpreter file 28 28 */ 29 29 30 30 #include "common/endian.h" … … 204 204 }; 205 205 const unsigned int FWScript::_numOpcodes = ARRAYSIZE(FWScript::_opcodeTable); 206 206 207 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);424 425 207 FWScriptInfo *scriptInfo; ///< Script factory 426 208 RawScriptArray scriptTable; ///< Table of script bytecode 427 209 … … 898 680 fHandle.writeUint16BE(_index); 899 681 } 900 682 901 /*! \brief Contructor for global scripts902 * \param script Script bytecode reference903 * \param idx Script bytecode index904 */905 OSScript::OSScript(const RawScript &script, int16 idx) :906 FWScript(script, idx, new OSScriptInfo) {}907 908 /*! \brief Constructor for object scripts909 * \param script Script bytecode reference910 * \param idx Script bytecode index911 */912 OSScript::OSScript(RawObjectScript &script, int16 idx) :913 FWScript(script, idx, new OSScriptInfo) {}914 915 /*! \brief Copy constructor916 */917 OSScript::OSScript(const OSScript &src) : FWScript(src, new OSScriptInfo) {}918 919 /*! \brief Restore script state from savefile920 * \param labels Restored script labels921 * \param local Restored local script variables922 * \param compare Restored last comparison result923 * \param pos Restored script position924 */925 void OSScript::load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) {926 FWScript::load(labels, local, compare, pos);927 }928 683 /*! \brief Get opcode info string 929 684 * \param opcode Opcode to look for in opcode table 930 685 */ … … 1003 758 return tmp; 1004 759 } 1005 760 1006 /*! \brief Get opcode info string1007 * \param opcode Opcode to look for in opcode table1008 */1009 const char *OSScriptInfo::opcodeInfo(byte opcode) const {1010 if (opcode == 0 || opcode > OSScript::_numOpcodes) {1011 return NULL;1012 }1013 1014 if (!OSScript::_opcodeTable[opcode - 1].args) {1015 warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeInfo", opcode - 1);1016 return NULL;1017 }1018 1019 return OSScript::_opcodeTable[opcode - 1].args;1020 }1021 1022 /*! \brief Get opcode handler pointer1023 * \param opcode Opcode to look for in opcode table1024 */1025 opFunc OSScriptInfo::opcodeHandler(byte opcode) const {1026 if (opcode == 0 || opcode > OSScript::_numOpcodes) {1027 return NULL;1028 }1029 1030 if (!OSScript::_opcodeTable[opcode - 1].proc) {1031 warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeHandler", opcode - 1);1032 return NULL;1033 }1034 1035 return OSScript::_opcodeTable[opcode - 1].proc;1036 }1037 1038 /*! \brief Create new OSScript instance1039 * \param script Script bytecode1040 * \param index Bytecode index1041 */1042 FWScript *OSScriptInfo::create(const RawScript &script, int16 index) const {1043 return new OSScript(script, index);1044 }1045 1046 /*! \brief Create new OSScript instance1047 * \param script Object script bytecode1048 * \param index Bytecode index1049 */1050 FWScript *OSScriptInfo::create(const RawObjectScript &script, int16 index) const {1051 return new OSScript(script, index);1052 }1053 1054 /*! \brief Load saved OSScript instance1055 * \param script Script bytecode1056 * \param index Bytecode index1057 * \param local Local variables1058 * \param labels Script labels1059 * \param compare Last compare result1060 * \param pos Position in script1061 */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 instance1070 * \param script Object script bytecode1071 * \param index Bytecode index1072 * \param local Local variables1073 * \param labels Script labels1074 * \param compare Last compare result1075 * \param pos Position in script1076 */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 1084 761 // ------------------------------------------------------------------------ 1085 762 // FUTURE WARS opcodes 1086 763 // ------------------------------------------------------------------------ … … 1375 1052 byte param = getNextByte(); 1376 1053 1377 1054 debugC(5, kCineDebugScript, "Line: %d: addSpriteOverlay(%d)", _line, param); 1378 loadOverlayElement(param, 0);1055 addOverlay(param, 0); 1379 1056 return 0; 1380 1057 } 1381 1058 … … 1383 1060 byte param = getNextByte(); 1384 1061 1385 1062 debugC(5, kCineDebugScript, "Line: %d: removeSpriteOverlay(%d)", _line, param); 1386 freeOverlay(param, 0);1063 removeOverlay(param, 0); 1387 1064 return 0; 1065 return 0; 1388 1066 } 1389 1067 1390 1068 int FWScript::o1_addToBgList() { … … 1399 1077 byte param = getNextByte(); 1400 1078 1401 1079 debugC(5, kCineDebugScript, "Line: %d: addOverlay1(%d)", _line, param); 1402 loadOverlayElement(param, 1);1080 addOverlay(param, 1); 1403 1081 return 0; 1404 1082 } 1405 1083 … … 1407 1085 byte param = getNextByte(); 1408 1086 1409 1087 debugC(5, kCineDebugScript, "Line: %d: removeOverlay1(%d)", _line, param); 1410 freeOverlay(param, 1);1088 removeOverlay(param, 1); 1411 1089 return 0; 1090 return 0; 1412 1091 } 1413 1092 1414 1093 int FWScript::o1_loadMask4() { 1415 1094 byte param = getNextByte(); 1416 1095 1417 1096 debugC(5, kCineDebugScript, "Line: %d: addOverlayType4(%d)", _line, param); 1418 loadOverlayElement(param, 4);1097 addOverlay(param, 4); 1419 1098 return 0; 1420 1099 } 1421 1100 … … 1423 1102 byte param = getNextByte(); 1424 1103 1425 1104 debugC(5, kCineDebugScript, "Line: %d: removeSpriteOverlay4(%d)", _line, param); 1426 freeOverlay(param, 4);1105 removeOverlay(param, 4); 1427 1106 return 0; 1428 1107 } 1429 1108 … … 1825 1504 1826 1505 int FWScript::o1_unloadAllMasks() { 1827 1506 debugC(5, kCineDebugScript, "Line: %d: unloadAllMasks()", _line); 1828 unloadAllMasks();1507 overlayList.clear(); 1829 1508 return 0; 1830 1509 } 1831 1510 … … 2034 1713 byte param = getNextByte(); 2035 1714 2036 1715 debugC(5, kCineDebugScript, "Line: %d: addOverlay5(%d)", _line, param); 2037 loadOverlayElement(param, 5);1716 addOverlay(param, 5); 2038 1717 return 0; 2039 1718 } 2040 1719 … … 2042 1721 byte param = getNextByte(); 2043 1722 2044 1723 debugC(5, kCineDebugScript, "Line: %d: freeOverlay5(%d)", _line, param); 2045 freeOverlay(param, 5);1724 removeOverlay(param, 5); 2046 1725 return 0; 2047 1726 } 2048 1727 2049 // ------------------------------------------------------------------------2050 // OPERATION STEALTH opcodes2051 // ------------------------------------------------------------------------2052 2053 int FWScript::o2_loadPart() {2054 const char *param = getNextString();2055 2056 debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _line, param);2057 return 0;2058 }2059 2060 int FWScript::o2_playSample() {2061 if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) {2062 // no-op in these versions2063 getNextByte();2064 getNextByte();2065 getNextWord();2066 getNextByte();2067 getNextWord();2068 getNextWord();2069 return 0;2070 }2071 return o1_playSample();2072 }2073 2074 int FWScript::o2_playSampleAlt() {2075 byte num = getNextByte();2076 byte channel = getNextByte();2077 uint16 frequency = getNextWord();2078 getNextByte();2079 getNextWord();2080 uint16 size = getNextWord();2081 2082 if (size == 0xFFFF) {2083 size = animDataTable[num]._width * animDataTable[num]._height;2084 }2085 if (animDataTable[num].data()) {2086 if (g_cine->getPlatform() == Common::kPlatformPC) {2087 // if speaker output is available, play sound on it2088 // if it's another device, don't play anything2089 // TODO: implement this, it's used in the introduction for example2090 // on each letter displayed2091 } else {2092 g_sound->playSound(channel, frequency, animDataTable[num].data(), size, 0, 0, 63, 0);2093 }2094 }2095 return 0;2096 }2097 2098 int FWScript::o2_addSeqListElement() {2099 byte param1 = getNextByte();2100 byte param2 = getNextByte();2101 byte param3 = getNextByte();2102 byte param4 = getNextByte();2103 uint16 param5 = getNextWord();2104 uint16 param6 = getNextWord();2105 uint16 param7 = getNextWord();2106 2107 debugC(5, kCineDebugScript, "Line: %d: addSeqListElement(%d,%d,%d,%d,%d,%d,%d)", _line, param1, param2, param3, param4, param5, param6, param7);2108 addSeqListElement(param1, 0, param2, param3, param4, param5, param6, 0, param7);2109 return 0;2110 }2111 2112 int FWScript::o2_removeSeq() {2113 byte a = getNextByte();2114 byte b = getNextByte();2115 2116 debugC(5, kCineDebugScript, "Line: %d: removeSeq(%d,%d) -> TODO", _line, a, b);2117 removeSeq(a, 0, b);2118 return 0;2119 }2120 2121 /*! \todo Implement this instruction2122 */2123 int FWScript::o2_op81() {2124 warning("STUB: o2_op81()");2125 // freeUnkList();2126 return 0;2127 }2128 2129 /*! \todo Implement this instruction2130 */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;2137 }2138 2139 int FWScript::o2_isSeqRunning() {2140 byte a = getNextByte();2141 byte b = getNextByte();2142 2143 debugC(5, kCineDebugScript, "Line: %d: OP83(%d,%d) -> TODO", _line, a, b);2144 2145 if (isSeqRunning(a, 0, b)) {2146 _compare = 1;2147 } else {2148 _compare = 0;2149 }2150 return 0;2151 }2152 2153 /*! \todo The assert may produce false positives and requires testing2154 */2155 int FWScript::o2_gotoIfSupNearest() {2156 byte labelIdx = getNextByte();2157 2158 if (_compare == kCmpGT) {2159 assert(_labels[labelIdx] != -1);2160 2161 debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (true)", _line, labelIdx);2162 _pos = _script.getLabel(*_info, labelIdx, _pos);2163 } else {2164 debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (false)", _line, labelIdx);2165 }2166 return 0;2167 }2168 2169 /*! \todo The assert may produce false positives and requires testing2170 */2171 int FWScript::o2_gotoIfSupEquNearest() {2172 byte labelIdx = getNextByte();2173 2174 if (_compare & (kCmpGT | kCmpEQ)) {2175 assert(_labels[labelIdx] != -1);2176 2177 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (true)", _line, labelIdx);2178 _pos = _script.getLabel(*_info, labelIdx, _pos);2179 } else {2180 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (false)", _line, labelIdx);2181 }2182 return 0;2183 }2184 2185 /*! \todo The assert may produce false positives and requires testing2186 */2187 int FWScript::o2_gotoIfInfNearest() {2188 byte labelIdx = getNextByte();2189 2190 if (_compare == kCmpLT) {2191 assert(_labels[labelIdx] != -1);2192 2193 debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (true)", _line, labelIdx);2194 _pos = _script.getLabel(*_info, labelIdx, _pos);2195 } else {2196 debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (false)", _line, labelIdx);2197 }2198 return 0;2199 }2200 2201 /*! \todo The assert may produce false positives and requires testing2202 */2203 int FWScript::o2_gotoIfInfEquNearest() {2204 byte labelIdx = getNextByte();2205 2206 if (_compare & (kCmpLT | kCmpEQ)) {2207 assert(_labels[labelIdx] != -1);2208 2209 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (true)", _line, labelIdx);2210 _pos = _script.getLabel(*_info, labelIdx, _pos);2211 } else {2212 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (false)", _line, labelIdx);2213 }2214 return 0;2215 }2216 2217 /*! \todo The assert may produce false positives and requires testing2218 */2219 int FWScript::o2_gotoIfEquNearest() {2220 byte labelIdx = getNextByte();2221 2222 if (_compare == kCmpEQ) {2223 assert(_labels[labelIdx] != -1);2224 2225 debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (true)", _line, labelIdx);2226 _pos = _script.getLabel(*_info, labelIdx, _pos);2227 } else {2228 debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (false)", _line, labelIdx);2229 }2230 return 0;2231 }2232 2233 /*! \todo The assert may produce false positives and requires testing2234 */2235 int FWScript::o2_gotoIfDiffNearest() {2236 byte labelIdx = getNextByte();2237 2238 if (_compare != kCmpEQ) {2239 assert(_labels[labelIdx] != -1);2240 2241 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (true)", _line, labelIdx);2242 _pos = _script.getLabel(*_info, labelIdx, _pos);2243 } else {2244 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (false)", _line, labelIdx);2245 }2246 return 0;2247 }2248 2249 int FWScript::o2_startObjectScript() {2250 byte param = getNextByte();2251 2252 debugC(5, kCineDebugScript, "Line: %d: startObjectScript(%d)", _line, param);2253 runObjectScript(param);2254 return 0;2255 }2256 2257 int FWScript::o2_stopObjectScript() {2258 byte param = getNextByte();2259 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;2269 }2270 2271 /*! \todo Implement this instruction2272 */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);2283 // _currentScriptElement->compareResult = ...2284 return 0;2285 }2286 2287 int FWScript::o2_addBackground() {2288 byte param1 = getNextByte();2289 const char *param2 = getNextString();2290 2291 debugC(5, kCineDebugScript, "Line: %d: addBackground(%s,%d)", _line, param2, param1);2292 addBackground(param2, param1);2293 return 0;2294 }2295 2296 int FWScript::o2_removeBackground() {2297 byte param = getNextByte();2298 2299 assert(param);2300 2301 debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _line, param);2302 2303 if (additionalBgTable[param]) {2304 free(additionalBgTable[param]);2305 additionalBgTable[param] = NULL;2306 }2307 2308 if (currentAdditionalBgIdx == param) {2309 currentAdditionalBgIdx = 0;2310 }2311 2312 if (currentAdditionalBgIdx2 == param) {2313 currentAdditionalBgIdx2 = 0;2314 }2315 2316 strcpy(currentBgName[param], "");2317 return 0;2318 }2319 2320 int FWScript::o2_loadAbs() {2321 byte param1 = getNextByte();2322 const char *param2 = getNextString();2323 2324 debugC(5, kCineDebugScript, "Line: %d: loadABS(%d,%s)", _line, param1, param2);2325 loadAbs(param2, param1);2326 return 0;2327 }2328 2329 int FWScript::o2_loadBg() {2330 byte param = getNextByte();2331 2332 assert(param <= 8);2333 2334 debugC(5, kCineDebugScript, "Line: %d: useBg(%d)", _line, param);2335 2336 if (additionalBgTable[param]) {2337 currentAdditionalBgIdx = param;2338 if (param == 8) {2339 newColorMode = 3;2340 } else {2341 newColorMode = bgColorMode + 1;2342 }2343 //if (_screenNeedFadeOut == 0) {2344 // adBgVar1 = 1;2345 //}2346 fadeRequired = true;2347 }2348 return 0;2349 }2350 2351 /*! \todo Implement this instruction2352 */2353 int FWScript::o2_wasZoneChecked() {2354 warning("STUB: o2_wasZoneChecked()");2355 return 0;2356 }2357 2358 /*! \todo Implement this instruction2359 */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;2371 }2372 2373 /*! \todo Implement this instruction2374 */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;2382 }2383 2384 int FWScript::o2_useBgScroll() {2385 byte param = getNextByte();2386 2387 assert(param <= 8);2388 2389 debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _line, param);2390 2391 if (additionalBgTable[param]) {2392 currentAdditionalBgIdx2 = param;2393 }2394 return 0;2395 }2396 2397 int FWScript::o2_setAdditionalBgVScroll() {2398 byte param1 = getNextByte();2399 2400 if (param1) {2401 byte param2 = getNextByte();2402 2403 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _line, param2);2404 additionalBgVScroll = _localVars[param2];2405 } else {2406 uint16 param2 = getNextWord();2407 2408 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _line, param2);2409 additionalBgVScroll = param2;2410 }2411 return 0;2412 }2413 2414 /*! \todo Implement this instruction2415 */2416 int FWScript::o2_op9F() {2417 warning("o2_op9F()");2418 getNextWord();2419 getNextWord();2420 return 0;2421 }2422 2423 int FWScript::o2_addGfxElementA0() {2424 uint16 param1 = getNextWord();2425 uint16 param2 = getNextWord();2426 2427 debugC(5, kCineDebugScript, "Line: %d: addGfxElementA0(%d,%d)", _line, param1, param2);2428 addGfxElementA0(param1, param2);2429 return 0;2430 }2431 2432 /*! \todo Implement this instruction2433 */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;2440 }2441 2442 /*! \todo Implement this instruction2443 */2444 int FWScript::o2_opA2() {2445 uint16 a = getNextWord();2446 uint16 b = getNextWord();2447 warning("STUB: o2_opA2(%x, %x)", a, b);2448 // addGfxElementA2();2449 return 0;2450 }2451 2452 /*! \todo Implement this instruction2453 */2454 int FWScript::o2_opA3() {2455 uint16 a = getNextWord();2456 uint16 b = getNextWord();2457 warning("STUB: o2_opA3(%x, %x)", a, b);2458 // removeGfxElementA2();2459 return 0;2460 }2461 2462 int FWScript::o2_loadMask22() {2463 byte param = getNextByte();2464 2465 debugC(5, kCineDebugScript, "Line: %d: addOverlay22(%d)", _line, param);2466 loadOverlayElement(param, 22);2467 return 0;2468 }2469 2470 int FWScript::o2_unloadMask22() {2471 byte param = getNextByte();2472 2473 debugC(5, kCineDebugScript, "Line: %d: removeOverlay22(%d)", _line, param);2474 freeOverlay(param, 22);2475 return 0;2476 }2477 2478 1728 //----------------------------------------------------------------------- 2479 1729 2480 void addGfxElementA0(int16 param1, int16 param2) {2481 overlayHeadElement *currentHead = &overlayHead;2482 overlayHeadElement *tempHead = currentHead;2483 overlayHeadElement *newElement;2484 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)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 works2523 */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;2540 }2541 }2542 2543 void removeSeq(uint16 param1, uint16 param2, uint16 param3) {2544 SeqListElement *currentHead = &seqList;2545 SeqListElement *tempHead = currentHead;2546 2547 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) {2548 tempHead = currentHead;2549 currentHead = tempHead->next;2550 }2551 2552 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) {2553 currentHead->var4 = -1;2554 }2555 }2556 2557 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3) {2558 SeqListElement *currentHead = &seqList;2559 SeqListElement *tempHead = currentHead;2560 2561 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) {2562 tempHead = currentHead;2563 currentHead = tempHead->next;2564 }2565 2566 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) {2567 return 1;2568 }2569 2570 return 0;2571 }2572 2573 1730 void palRotate(byte a, byte b, byte c) { 2574 1731 if (c == 1) { 2575 1732 uint16 currentColor = c_palette[b]; -
engines/cine/module.mk
14 14 part.o \ 15 15 prc.o \ 16 16 rel.o \ 17 script.o \ 17 script_fw.o \ 18 script_os.o \ 18 19 sound.o \ 19 20 texte.o \ 20 21 unpack.o \ -
engines/cine/object.h
40 40 uint16 part; 41 41 }; 42 42 43 struct overlayHeadElement { 44 struct overlayHeadElement *next; 45 struct overlayHeadElement *previous; 43 struct overlay { 46 44 uint16 objIdx; 47 45 uint16 type; 48 46 int16 x; … … 57 55 extern objectStruct objectTable[NUM_MAX_OBJECT]; 58 56 extern ScriptVars globalVars; 59 57 60 extern overlayHeadElement overlayHead;58 extern Common::List<overlay> overlayList; 61 59 62 void unloadAllMasks(void);63 void resetMessageHead(void);60 //void unloadAllMasks(void); 61 //void resetMessageHead(void); 64 62 65 63 void loadObject(char *pObjectName); 66 64 void setupObject(byte objIdx, uint16 param1, uint16 param2, uint16 param3, uint16 param4); 67 65 void modifyObjectParam(byte objIdx, byte paramIdx, int16 newValue); 68 66 69 void loadOverlayElement(uint16 objIdx, uint16 param); 70 int8 removeOverlayElement(uint16 objIdx, uint16 param); 67 void addOverlay(uint16 objIdx, uint16 param); 68 int removeOverlay(uint16 objIdx, uint16 param); 69 void addGfxElementA0(int16 objIdx, int16 param); 70 void removeGfxElementA0(int16 objIdx, int16 param); 71 71 72 72 int16 getObjectParam(uint16 objIdx, uint16 paramIdx); 73 int16 freeOverlay(uint16 objIdx, uint16 param);74 73 75 74 void addObjectParam(byte objIdx, byte paramIdx, int16 newValue); 76 75 void subObjectParam(byte objIdx, byte paramIdx, int16 newValue); -
engines/cine/bg_list.cpp
77 77 void addSpriteFilledToBGList(int16 objIdx, bool addList) { 78 78 int16 x = objectTable[objIdx].x; 79 79 int16 y = objectTable[objIdx].y; 80 int16 width = animDataTable[objectTable[objIdx].frame]._ width;80 int16 width = animDataTable[objectTable[objIdx].frame]._realWidth; 81 81 int16 height = animDataTable[objectTable[objIdx].frame]._height; 82 82 const byte *data = animDataTable[objectTable[objIdx].frame].data(); 83 83 … … 86 86 if (g_cine->getGameType() == GType_OS) { 87 87 for (int i = 0; i < 8; i++) { 88 88 if (additionalBgTable[i]) { 89 gfxFillSprite(data, width / 2, height, additionalBgTable[i], x, y);89 gfxFillSprite(data, width, height, additionalBgTable[i], x, y); 90 90 } 91 91 } 92 92 } else { 93 gfxFillSprite(data, width / 2, height, page2Raw, x, y);93 gfxFillSprite(data, width, height, page2Raw, x, y); 94 94 } 95 95 } 96 96 -
engines/cine/anim.cpp
186 186 }; 187 187 188 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 189 void convert8BBP(byte *dest, const byte *source, int16 width, int16 height); 191 190 void convert8BBP2(byte *dest, byte *source, int16 width, int16 height); 192 191 -
engines/cine/various.cpp
130 130 objectScripts.push_back(tmp); 131 131 } 132 132 133 /*! \brief Add action result message to overlay list 134 * \param cmd Message description 135 * \todo Why are x, y, width and color left uninitialized? 136 */ 133 137 void addPlayerCommandMessage(int16 cmd) { 134 overlay HeadElement *currentHeadPtr = overlayHead.next;135 overlayHeadElement *tempHead = &overlayHead;136 overlayHeadElement *pNewElement;138 overlay tmp; 139 tmp.objIdx = cmd; 140 tmp.type = 3; 137 141 138 while (currentHeadPtr) { 139 tempHead = currentHeadPtr; 140 currentHeadPtr = tempHead->next; 141 } 142 143 pNewElement = new overlayHeadElement; 144 145 assert(pNewElement); 146 147 pNewElement->next = tempHead->next; 148 tempHead->next = pNewElement; 149 150 pNewElement->objIdx = cmd; 151 pNewElement->type = 3; 152 153 if (!currentHeadPtr) { 154 currentHeadPtr = &overlayHead; 155 } 156 157 pNewElement->previous = currentHeadPtr->previous; 158 currentHeadPtr->previous = pNewElement; 142 overlayList.push_back(tmp); 159 143 } 160 144 161 145 int16 getRelEntryForObject(uint16 param1, uint16 param2, SelectedObjStruct *pSelectedObject) { … … 180 164 return found; 181 165 } 182 166 167 /*! \brief Find index of the object under cursor 168 * \param x Mouse cursor coordinate 169 * \param y Mouse cursor coordinate 170 * \todo Fix displaced type 1 objects 171 */ 183 172 int16 getObjectUnderCursor(uint16 x, uint16 y) { 184 overlayHeadElement *currentHead = overlayHead.previous;173 Common::List<overlay>::iterator it; 185 174 186 175 int16 objX, objY, frame, part, threshold, height, xdif, ydif; 187 176 int width; 188 177 189 while (currentHead) {190 if (currentHead->type < 2) {191 if (objectTable[currentHead->objIdx].name[0]) {192 objX = objectTable[currentHead->objIdx].x;193 objY = objectTable[currentHead->objIdx].y;178 // reverse_iterator would be nice 179 for (it = overlayList.reverse_begin(); it != overlayList.end(); --it) { 180 if (it->type >= 2 || !objectTable[it->objIdx].name[0]) { 181 continue; 182 } 194 183 195 frame = ABS((int16)(objectTable[currentHead->objIdx].frame)); 184 objX = objectTable[it->objIdx].x; 185 objY = objectTable[it->objIdx].y; 196 186 197 part = objectTable[currentHead->objIdx].part; 187 frame = ABS((int16)(objectTable[it->objIdx].frame)); 188 part = objectTable[it->objIdx].part; 198 189 199 if (currentHead->type == 0) {200 201 202 203 190 if (it->type == 0) { 191 threshold = animDataTable[frame]._var1; 192 } else { 193 threshold = animDataTable[frame]._width / 2; 194 } 204 195 205 206 196 height = animDataTable[frame]._height; 197 width = animDataTable[frame]._realWidth; 207 198 208 209 199 xdif = x - objX; 200 ydif = y - objY; 210 201 211 if ((xdif >= 0) && ((threshold << 4) > xdif) && (ydif > 0) && (ydif < height)) { 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)) { 215 return currentHead->objIdx; 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 } 221 } else if (currentHead->type == 1) { // is mask 222 if (gfxGetBit(x - objX, y - objY, animDataTable[frame].data(), animDataTable[frame]._width * 4)) { 223 return currentHead->objIdx; 224 } 225 } 226 } 227 } 228 } 202 if ((xdif < 0) || ((threshold << 4) <= xdif) || (ydif < 0) || (ydif >= height) || !animDataTable[frame].data()) { 203 continue; 229 204 } 230 205 231 currentHead = currentHead->previous; 206 if (g_cine->getGameType() == Cine::GType_OS) { 207 if (xdif >= width) { 208 continue; 209 } 210 211 if (it->type == 0 && animDataTable[frame].getColor(xdif, ydif) != part) { 212 return it->objIdx; 213 } else if (it->type == 1 && gfxGetBit(xdif, ydif, animDataTable[frame].data(), animDataTable[frame]._width * 4)) { 214 return it->objIdx; 215 } 216 } else if (it->type == 0) { // use generated mask 217 if (gfxGetBit(xdif, ydif, animDataTable[frame].mask(), animDataTable[frame]._width)) { 218 return it->objIdx; 219 } 220 } else if (it->type == 1) { // is mask 221 if (gfxGetBit(xdif, ydif, animDataTable[frame].data(), animDataTable[frame]._width * 4)) { 222 return it->objIdx; 223 } 224 } 232 225 } 233 226 234 227 return -1; … … 285 278 } 286 279 } 287 280 288 void loadOverlayFromSave(Common::InSaveFile *fHandle) { 289 overlayHeadElement *newElement; 290 overlayHeadElement *currentHead = &overlayHead; 291 overlayHeadElement *tempHead = currentHead; 281 /*! \brief Restore overlay sprites from savefile 282 * \param fHandle Savefile open for reading 283 */ 284 void loadOverlayFromSave(Common::InSaveFile &fHandle) { 285 overlay tmp; 292 286 293 currentHead = tempHead->next; 287 fHandle.readUint32BE(); 288 fHandle.readUint32BE(); 294 289 295 while (currentHead) { 296 tempHead = currentHead; 297 currentHead = tempHead->next; 298 } 290 tmp.objIdx = fHandle.readUint16BE(); 291 tmp.type = fHandle.readUint16BE(); 292 tmp.x = fHandle.readSint16BE(); 293 tmp.y = fHandle.readSint16BE(); 294 tmp.width = fHandle.readSint16BE(); 295 tmp.color = fHandle.readSint16BE(); 299 296 300 newElement = new overlayHeadElement; 301 302 fHandle->readUint32BE(); 303 fHandle->readUint32BE(); 304 305 newElement->objIdx = fHandle->readUint16BE(); 306 newElement->type = fHandle->readUint16BE(); 307 newElement->x = fHandle->readSint16BE(); 308 newElement->y = fHandle->readSint16BE(); 309 newElement->width = fHandle->readSint16BE(); 310 newElement->color = fHandle->readSint16BE(); 311 312 newElement->next = tempHead->next; 313 tempHead->next = newElement; 314 315 if (!currentHead) 316 currentHead = &overlayHead; 317 318 newElement->previous = currentHead->previous; 319 currentHead->previous = newElement; 297 overlayList.push_back(tmp); 320 298 } 321 299 322 300 /*! \brief Savefile format tester … … 433 411 434 412 g_sound->stopMusic(); 435 413 freeAnimDataTable(); 436 unloadAllMasks();414 overlayList.clear(); 437 415 // if (g_cine->getGameType() == Cine::GType_OS) { 438 416 // freeUnkList(); 439 417 // } … … 599 577 600 578 size = fHandle->readSint16BE(); 601 579 for (i = 0; i < size; i++) { 602 loadOverlayFromSave( fHandle);580 loadOverlayFromSave(*fHandle); 603 581 } 604 582 605 583 loadBgIncrustFromSave(*fHandle); … … 722 700 } 723 701 724 702 { 725 int16 numScript = 0; 726 overlayHeadElement *currentHead = overlayHead.next; 703 Common::List<overlay>::iterator it; 727 704 728 while (currentHead) { 729 numScript++; 730 currentHead = currentHead->next; 731 } 705 fHandle->writeUint16BE(overlayList.size()); 732 706 733 fHandle->writeUint16BE(numScript); 734 735 // actual save 736 currentHead = overlayHead.next; 737 738 while (currentHead) { 707 for (it = overlayList.begin(); it != overlayList.end(); ++it) { 739 708 fHandle->writeUint32BE(0); 740 709 fHandle->writeUint32BE(0); 741 fHandle->writeUint16BE(currentHead->objIdx); 742 fHandle->writeUint16BE(currentHead->type); 743 fHandle->writeSint16BE(currentHead->x); 744 fHandle->writeSint16BE(currentHead->y); 745 fHandle->writeSint16BE(currentHead->width); 746 fHandle->writeSint16BE(currentHead->color); 747 748 currentHead = currentHead->next; 710 fHandle->writeUint16BE(it->objIdx); 711 fHandle->writeUint16BE(it->type); 712 fHandle->writeSint16BE(it->x); 713 fHandle->writeSint16BE(it->y); 714 fHandle->writeSint16BE(it->width); 715 fHandle->writeSint16BE(it->color); 749 716 } 750 717 } 751 718 … … 762 729 fHandle->writeUint16BE(it->frame); 763 730 fHandle->writeUint16BE(it->part); 764 731 } 765 /*766 int numBgIncrustList = 0;767 BGIncrustList *bgIncrustPtr = bgIncrustList;768 732 769 while (bgIncrustPtr) {770 numBgIncrustList++;771 bgIncrustPtr = bgIncrustPtr->next;772 }773 774 fHandle->writeUint16BE(numBgIncrustList);775 bgIncrustPtr = bgIncrustList;776 while (bgIncrustPtr) {777 fHandle->writeUint32BE(0); // next778 fHandle->writeUint32BE(0); // unkPtr779 fHandle->writeUint16BE(bgIncrustPtr->objIdx);780 fHandle->writeUint16BE(bgIncrustPtr->param);781 fHandle->writeUint16BE(bgIncrustPtr->x);782 fHandle->writeUint16BE(bgIncrustPtr->y);783 fHandle->writeUint16BE(bgIncrustPtr->frame);784 fHandle->writeUint16BE(bgIncrustPtr->part);785 786 bgIncrustPtr = bgIncrustPtr->next;787 }788 */789 790 733 delete fHandle; 791 734 792 735 setMouseCursor(MOUSE_CURSOR_NORMAL); … … 1682 1625 return var_5E; 1683 1626 } 1684 1627 1685 void drawSprite(overlayHeadElement *currentOverlay, const byte *spritePtr, 1686 const byte *maskPtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) { 1687 byte *ptr = NULL; 1628 void drawSprite(Common::List<overlay>::iterator it, const byte *spritePtr, const byte *maskPtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) { 1688 1629 byte *msk = NULL; 1689 byte i = 0;1690 uint16 si = 0;1691 overlayHeadElement *pCurrentOverlay = currentOverlay;1692 1630 int16 maskX, maskY, maskWidth, maskHeight; 1693 1631 uint16 maskSpriteIdx; 1694 1632 1633 msk = (byte *)malloc(width * height); 1634 1695 1635 if (g_cine->getGameType() == Cine::GType_OS) { 1696 drawSpriteRaw2(spritePtr, objectTable[currentOverlay->objIdx].part, width, height, page, x, y); 1697 return; 1636 generateMask(spritePtr, msk, width * height, objectTable[it->objIdx].part); 1637 } else { 1638 memcpy(msk, maskPtr, width * height); 1698 1639 } 1699 1640 1700 while (pCurrentOverlay) { 1701 if (pCurrentOverlay->type == 5) { 1702 if (!si) { 1703 ptr = (byte *)malloc(width * 8 * height); 1704 msk = (byte *)malloc(width * 8 * height); 1705 si = 1; 1706 } 1641 for (++it; it != overlayList.end(); ++it) { 1642 if (it->type != 5) { 1643 continue; 1644 } 1707 1645 1708 maskX = objectTable[pCurrentOverlay->objIdx].x;1709 maskY = objectTable[pCurrentOverlay->objIdx].y;1646 maskX = objectTable[it->objIdx].x; 1647 maskY = objectTable[it->objIdx].y; 1710 1648 1711 maskSpriteIdx = objectTable[pCurrentOverlay->objIdx].frame;1649 maskSpriteIdx = ABS((int16)(objectTable[it->objIdx].frame)); 1712 1650 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++); 1651 maskWidth = animDataTable[maskSpriteIdx]._realWidth; 1652 maskHeight = animDataTable[maskSpriteIdx]._height; 1653 gfxUpdateSpriteMask(msk, x, y, width, height, animDataTable[maskSpriteIdx].data(), maskX, maskY, maskWidth, maskHeight); 1654 1716 1655 #ifdef DEBUG_SPRITE_MASK 1717 1656 gfxFillSprite(animDataTable[maskSpriteIdx].data(), maskWidth, maskHeight, page, maskX, maskY, 1); 1718 1657 #endif 1719 }1720 1721 pCurrentOverlay = pCurrentOverlay->next;1722 1658 } 1723 1659 1724 if (si) { 1725 gfxDrawMaskedSprite(ptr, msk, width, height, page, x, y); 1726 free(ptr); 1727 free(msk); 1728 } else { 1729 gfxDrawMaskedSprite(spritePtr, maskPtr, width, height, page, x, y); 1730 } 1660 gfxDrawMaskedSprite(spritePtr, msk, width, height, page, x, y); 1661 free(msk); 1731 1662 } 1732 1663 1733 1664 int16 additionalBgVScroll = 0; … … 1827 1758 const char *messagePtr = (const char *)messageTable[msgIdx].ptr; 1828 1759 1829 1760 if (!messagePtr) { 1830 freeOverlay(msgIdx, 2);1761 removeOverlay(msgIdx, 2); 1831 1762 return; 1832 1763 } 1833 1764 … … 1835 1766 1836 1767 drawMessage(messagePtr, x, y, width, color); 1837 1768 1838 freeOverlay(msgIdx, 2);1769 removeOverlay(msgIdx, 2); 1839 1770 } 1840 1771 1841 1772 void drawFailureMessage(byte cmd) { … … 1857 1788 1858 1789 drawMessage(messagePtr, x, y, width, color); 1859 1790 1860 freeOverlay(cmd, 3);1791 removeOverlay(cmd, 3); 1861 1792 } 1862 1793 1863 /*! \todo Fix Operation Stealth logo in intro (the green text after the plane1864 * takes off). Each letter should slowly grow top-down, it has something to1865 * do with object 10 (some mask or something)1866 */1867 1794 void drawOverlays(void) { 1868 uint16 partVar1, partVar2;1795 uint16 width, height; 1869 1796 AnimData *pPart; 1870 overlayHeadElement *currentOverlay, *nextOverlay;1871 1797 int16 x, y; 1872 1798 objectStruct *objPtr; 1873 1799 byte messageIdx; 1874 int16 part;1800 Common::List<overlay>::iterator it; 1875 1801 1876 1802 backupOverlayPage(); 1877 1803 1878 1804 _messageLen = 0; 1879 1805 1880 currentOverlay = (&overlayHead)->next; 1806 for (it = overlayList.begin(); it != overlayList.end(); ++it) { 1807 switch (it->type) { 1808 case 0: // sprite 1809 assert(it->objIdx < NUM_MAX_OBJECT); 1881 1810 1882 while (currentOverlay) { 1883 nextOverlay = currentOverlay->next; 1811 objPtr = &objectTable[it->objIdx]; 1812 x = objPtr->x; 1813 y = objPtr->y; 1884 1814 1885 switch (currentOverlay->type) { 1886 case 0: // sprite 1887 { 1888 assert(currentOverlay->objIdx <= NUM_MAX_OBJECT); 1815 if (objPtr->frame < 0) { 1816 continue; 1817 } 1889 1818 1890 objPtr = &objectTable[currentOverlay->objIdx]; 1819 pPart = &animDataTable[objPtr->frame]; 1820 width = pPart->_realWidth; 1821 height = pPart->_height; 1891 1822 1892 x = objPtr->x; 1893 y = objPtr->y; 1823 if (!pPart->data()) { 1824 continue; 1825 } 1894 1826 1895 if (objPtr->frame >= 0) {1896 if (g_cine->getGameType() == Cine::GType_OS) {1897 pPart = &animDataTable[objPtr->frame];1827 // drawSprite ignores masks of Operation Stealth sprites 1828 drawSprite(it, pPart->data(), pPart->mask(), width, height, page1Raw, x, y); 1829 break; 1898 1830 1899 partVar1 = pPart->_var1; 1900 partVar2 = pPart->_height; 1831 case 2: // text 1832 // gfxWaitVSync(); 1833 // hideMouse(); 1901 1834 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); 1906 } 1907 } else { 1908 part = objPtr->part; 1835 messageIdx = it->objIdx; 1836 x = it->x; 1837 y = it->y; 1838 width = it->width; 1839 height = it->color; 1909 1840 1910 assert(part >= 0 && part <= NUM_MAX_ANIMDATA);1841 blitRawScreen(page1Raw); 1911 1842 1912 pPart = &animDataTable[objPtr->frame];1843 drawDialogueMessage(messageIdx, x, y, width, height); 1913 1844 1914 partVar1 = pPart->_var1;1915 partVar2 = pPart->_height;1845 // blitScreen(page0, NULL); 1846 // gfxRedrawMouseCursor(); 1916 1847 1917 if (pPart->data()) { 1918 drawSprite(currentOverlay, pPart->data(), pPart->mask(), partVar1, partVar2, page1Raw, x, y); 1919 } 1920 } 1921 } 1922 break; 1923 } 1924 case 2: // text 1925 { 1926 // gfxWaitVSync(); 1927 // hideMouse(); 1848 waitForPlayerClick = 1; 1928 1849 1929 messageIdx = currentOverlay->objIdx; 1930 x = currentOverlay->x; 1931 y = currentOverlay->y; 1932 partVar1 = currentOverlay->width; 1933 partVar2 = currentOverlay->color; 1850 break; 1934 1851 1935 blitRawScreen(page1Raw); 1852 case 3: 1853 // gfxWaitSync() 1854 // hideMouse(); 1936 1855 1937 drawDialogueMessage(messageIdx, x, y, partVar1, partVar2);1856 blitRawScreen(page1Raw); 1938 1857 1939 // blitScreen(page0, NULL); 1940 // gfxRedrawMouseCursor(); 1858 drawFailureMessage(it->objIdx); 1941 1859 1942 waitForPlayerClick = 1; 1860 // blitScreen(page0, NULL); 1861 // gfxRedrawMouseCursor(); 1943 1862 1944 break; 1945 } 1946 case 3: 1947 { 1948 // gfxWaitSync() 1949 // hideMouse(); 1863 waitForPlayerClick = 1; 1950 1864 1951 blitRawScreen(page1Raw);1865 break; 1952 1866 1953 drawFailureMessage(currentOverlay->objIdx); 1867 case 4: 1868 assert(it->objIdx < NUM_MAX_OBJECT); 1954 1869 1955 // blitScreen(page0, NULL); 1956 // gfxRedrawMouseCursor(); 1870 objPtr = &objectTable[it->objIdx]; 1871 x = objPtr->x; 1872 y = objPtr->y; 1957 1873 1958 waitForPlayerClick = 1; 1959 1960 break; 1874 if (objPtr->frame < 0) { 1875 continue; 1961 1876 } 1962 case 4:1963 {1964 assert(currentOverlay->objIdx <= NUM_MAX_OBJECT);1965 1877 1966 objPtr = &objectTable[currentOverlay->objIdx];1878 assert(objPtr->frame < NUM_MAX_ANIMDATA); 1967 1879 1968 x = objPtr->x; 1969 y = objPtr->y; 1880 pPart = &animDataTable[objPtr->frame]; 1970 1881 1882 width = pPart->_realWidth; 1883 height = pPart->_height; 1971 1884 1972 if (objPtr->frame >= 0) { 1973 part = objPtr->part; 1885 if (!pPart->data()) { 1886 continue; 1887 } 1974 1888 1975 assert(part >= 0 && part <= NUM_MAX_ANIMDATA); 1889 gfxFillSprite(pPart->data(), width, height, page1Raw, x, y); 1890 break; 1976 1891 1977 pPart = &animDataTable[objPtr->frame]; 1892 case 20: 1893 assert(it->objIdx < NUM_MAX_OBJECT); 1978 1894 1979 partVar1 = pPart->_width / 2; 1980 partVar2 = pPart->_height; 1895 objPtr = &objectTable[it->objIdx]; 1896 x = objPtr->x; 1897 y = objPtr->y; 1898 var5 = it->x; 1981 1899 1982 if (pPart->data()) { 1983 gfxFillSprite(pPart->data(), partVar1, partVar2, page1Raw, x, y); 1984 } 1985 } 1986 break; 1900 if (objPtr->frame < 0 || var5 > 8 || !additionalBgTable[var5] || animDataTable[objPtr->frame]._bpp != 1) { 1901 continue; 1987 1902 } 1988 case 20:1989 {1990 assert(currentOverlay->objIdx <= NUM_MAX_OBJECT);1991 1903 1992 objPtr = &objectTable[currentOverlay->objIdx]; 1904 width = animDataTable[objPtr->frame]._width / 2; 1905 height = animDataTable[objPtr->frame]._height; 1993 1906 1994 x = objPtr->x; 1995 y = objPtr->y; 1996 1997 var5 = currentOverlay->x; 1998 1999 if (objPtr->frame >= 0 && var5 <= 8 && additionalBgTable[var5] && animDataTable[objPtr->frame]._bpp == 1) { 2000 int16 x2; 2001 int16 y2; 2002 2003 x2 = animDataTable[objPtr->frame]._width / 2; 2004 y2 = animDataTable[objPtr->frame]._height; 2005 2006 if (animDataTable[objPtr->frame].data()) { 2007 maskBgOverlay(additionalBgTable[var5], animDataTable[objPtr->frame].data(), x2, y2, page1Raw, x, y); 2008 } 2009 } 2010 break; 1907 if (!animDataTable[objPtr->frame].data()) { 1908 continue; 2011 1909 } 2012 }2013 1910 2014 currentOverlay = nextOverlay; 1911 maskBgOverlay(additionalBgTable[var5], animDataTable[objPtr->frame].data(), width, height, page1Raw, x, y); 1912 break; 1913 } 2015 1914 } 2016 1915 } 2017 1916 … … 2040 1939 } 2041 1940 2042 1941 if (newObjectName[0] != 0) { 2043 unloadAllMasks(); 2044 resetMessageHead(); 1942 overlayList.clear(); 2045 1943 2046 1944 loadObject(newObjectName); 2047 1945 … … 2071 1969 } 2072 1970 2073 1971 void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 param5) { 2074 overlayHeadElement *currentHead = &overlayHead; 2075 overlayHeadElement *tempHead = currentHead; 2076 overlayHeadElement *newElement; 1972 overlay tmp; 2077 1973 2078 currentHead = tempHead->next; 1974 tmp.objIdx = param1; 1975 tmp.type = 2; 1976 tmp.x = param2; 1977 tmp.y = param3; 1978 tmp.width = param4; 1979 tmp.color = param5; 2079 1980 2080 while (currentHead) { 1981 overlayList.push_back(tmp); 1982 } 1983 1984 SeqListElement seqList; 1985 1986 void removeSeq(uint16 param1, uint16 param2, uint16 param3) { 1987 SeqListElement *currentHead = &seqList; 1988 SeqListElement *tempHead = currentHead; 1989 1990 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { 2081 1991 tempHead = currentHead; 2082 1992 currentHead = tempHead->next; 2083 1993 } 2084 1994 2085 newElement = new overlayHeadElement; 1995 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) { 1996 currentHead->var4 = -1; 1997 } 1998 } 2086 1999 2087 newElement->next = tempHead->next; 2088 tempHead->next = newElement; 2000 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3) { 2001 SeqListElement *currentHead = &seqList; 2002 SeqListElement *tempHead = currentHead; 2089 2003 2090 newElement->objIdx = param1; 2091 newElement->type = 2; 2004 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { 2005 tempHead = currentHead; 2006 currentHead = tempHead->next; 2007 } 2092 2008 2093 newElement->x = param2; 2094 newElement->y = param3; 2095 newElement->width = param4; 2096 newElement->color = param5; 2009 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) { 2010 return 1; 2011 } 2097 2012 2098 if (!currentHead) 2099 currentHead = &overlayHead; 2100 2101 newElement->previous = currentHead->previous; 2102 2103 currentHead->previous = newElement; 2013 return 0; 2104 2014 } 2105 2015 2106 SeqListElement seqList;2107 2108 2016 void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8) { 2109 2017 SeqListElement *currentHead = &seqList; 2110 2018 SeqListElement *tempHead = currentHead; -
engines/cine/gfx.h
53 53 void gfxDrawMaskedSprite(const byte *ptr, const byte *msk, uint16 width, uint16 height, byte *page, int16 x, int16 y); 54 54 void gfxFillSprite(const byte *src4, uint16 sw, uint16 sh, byte *dst4, int16 sx, int16 sy, uint8 fillColor = 0); 55 55 56 void gfxUpdateSpriteMask(const byte *spritePtr, const byte *spriteMskPtr, int16 width, int16 height, const byte *maskPtr, 57 int16 maskWidth, int16 maskHeight, byte *bufferSprPtr, byte *bufferMskPtr, int16 xs, int16 ys, int16 xm, int16 ym, byte maskIdx); 56 void gfxUpdateSpriteMask(byte *destMask, int16 x, int16 y, int16 width, int16 height, const byte *maskPtr, int16 xm, int16 ym, int16 maskWidth, int16 maskHeight); 58 57 59 58 void gfxDrawLine(int16 x1, int16 y1, int16 x2, int16 y2, byte color, byte *page); 60 59 void gfxDrawPlainBox(int16 x1, int16 y1, int16 x2, int16 y2, byte color); -
engines/cine/xref.txt
144 144 reincrustAllBg() - removed (obsoleted by new loadResourcesFromSave() and 145 145 loadBgIncrustFromSave() implementation) 146 146 freeBgIncrustList() - removed (obsoleted by Common::List::clear()) 147 148 object.cpp 149 unloadAllMasks() - removed (obsoleted by Common::List::clear()) 150 resetMessageHead() - removed (obsoleted by Common::List) 151 freeOverlay() - removed (duplicate of removeOverlay) 152 removeOverlayElement() - renamed to removeOverlay 153 loadOverlayElement() - renamed to addOverlay -
engines/cine/script_os.cpp
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/cine/script.cpp $ 22 * $Id: script.cpp 31444 2008-04-07 20:24:40Z sev $ 23 * 24 */ 25 26 /*! \file 27 * Operation Stealth script interpreter file 28 */ 29 30 #include "common/endian.h" 31 32 #include "cine/cine.h" 33 #include "cine/bg_list.h" 34 #include "cine/object.h" 35 #include "cine/sound.h" 36 #include "cine/various.h" 37 #include "cine/script.h" 38 39 namespace Cine { 40 41 const Opcode OSScript::_opcodeTable[] = { 42 /* 00 */ 43 { &FWScript::o1_modifyObjectParam, "bbw" }, 44 { &FWScript::o1_getObjectParam, "bbb" }, 45 { &FWScript::o1_addObjectParam, "bbw" }, 46 { &FWScript::o1_subObjectParam, "bbw" }, 47 /* 04 */ 48 { &FWScript::o1_add2ObjectParam, "bbw" }, 49 { &FWScript::o1_sub2ObjectParam, "bbw" }, 50 { &FWScript::o1_compareObjectParam, "bbw" }, 51 { &FWScript::o1_setupObject, "bwwww" }, 52 /* 08 */ 53 { &FWScript::o1_checkCollision, "bwwww" }, 54 { &FWScript::o1_loadVar, "bc" }, 55 { &FWScript::o1_addVar, "bc" }, 56 { &FWScript::o1_subVar, "bc" }, 57 /* 0C */ 58 { &FWScript::o1_mulVar, "bc" }, 59 { &FWScript::o1_divVar, "bc" }, 60 { &FWScript::o1_compareVar, "bc" }, 61 { &FWScript::o1_modifyObjectParam2, "bbb" }, 62 /* 10 */ 63 { 0, 0 }, 64 { 0, 0 }, 65 { 0, 0 }, 66 { &FWScript::o1_loadMask0, "b" }, 67 /* 14 */ 68 { &FWScript::o1_unloadMask0, "b" }, 69 { &FWScript::o1_addToBgList, "b" }, 70 { &FWScript::o1_loadMask1, "b" }, 71 { &FWScript::o1_unloadMask1, "b" }, 72 /* 18 */ 73 { &FWScript::o1_loadMask4, "b" }, 74 { &FWScript::o1_unloadMask4, "b" }, 75 { &FWScript::o1_addSpriteFilledToBgList, "b" }, 76 { &FWScript::o1_op1B, "" }, 77 /* 1C */ 78 { 0, 0 }, 79 { &FWScript::o1_label, "l" }, 80 { &FWScript::o1_goto, "b" }, 81 { &FWScript::o1_gotoIfSup, "b" }, 82 /* 20 */ 83 { &FWScript::o1_gotoIfSupEqu, "b" }, 84 { &FWScript::o1_gotoIfInf, "b" }, 85 { &FWScript::o1_gotoIfInfEqu, "b" }, 86 { &FWScript::o1_gotoIfEqu, "b" }, 87 /* 24 */ 88 { &FWScript::o1_gotoIfDiff, "b" }, 89 { &FWScript::o1_removeLabel, "b" }, 90 { &FWScript::o1_loop, "bb" }, 91 { 0, 0 }, 92 /* 28 */ 93 { 0, 0 }, 94 { 0, 0 }, 95 { 0, 0 }, 96 { 0, 0 }, 97 /* 2C */ 98 { 0, 0 }, 99 { 0, 0 }, 100 { 0, 0 }, 101 { 0, 0 }, 102 /* 30 */ 103 { 0, 0 }, 104 { &FWScript::o1_startGlobalScript, "b" }, 105 { &FWScript::o1_endGlobalScript, "b" }, 106 { 0, 0 }, 107 /* 34 */ 108 { 0, 0 }, 109 { 0, 0 }, 110 { 0, 0 }, 111 { 0, 0 }, 112 /* 38 */ 113 { 0, 0 }, 114 { 0, 0 }, 115 { 0, 0 }, 116 { &FWScript::o1_loadAnim, "s" }, 117 /* 3C */ 118 { &FWScript::o1_loadBg, "s" }, 119 { &FWScript::o1_loadCt, "s" }, 120 { 0, 0 }, 121 { &FWScript::o2_loadPart, "s" }, 122 /* 40 */ 123 { 0, 0 }, /* o1_closePart, triggered by some scripts (STARTA.PRC 4 for ex.) */ 124 { &FWScript::o1_loadNewPrcName, "bs" }, 125 { &FWScript::o1_requestCheckPendingDataLoad, "" }, 126 { 0, 0 }, 127 /* 44 */ 128 { 0, 0 }, 129 { &FWScript::o1_blitAndFade, "" }, 130 { &FWScript::o1_fadeToBlack, "" }, 131 { &FWScript::o1_transformPaletteRange, "bbwww" }, 132 /* 48 */ 133 { 0, 0 }, 134 { &FWScript::o1_setDefaultMenuColor2, "b" }, 135 { &FWScript::o1_palRotate, "bbb" }, 136 { 0, 0 }, 137 /* 4C */ 138 { 0, 0 }, 139 { 0, 0 }, 140 { 0, 0 }, 141 { &FWScript::o1_break, "" }, 142 /* 50 */ 143 { &FWScript::o1_endScript, "x" }, 144 { &FWScript::o1_message, "bwwww" }, 145 { &FWScript::o1_loadGlobalVar, "bc" }, 146 { &FWScript::o1_compareGlobalVar, "bc" }, 147 /* 54 */ 148 { 0, 0 }, 149 { 0, 0 }, 150 { 0, 0 }, 151 { 0, 0 }, 152 /* 58 */ 153 { 0, 0 }, 154 { &FWScript::o1_declareFunctionName, "s" }, 155 { &FWScript::o1_freePartRange, "bb" }, 156 { &FWScript::o1_unloadAllMasks, "" }, 157 // 5C */ 158 { 0, 0 }, 159 { 0, 0 }, 160 { 0, 0 }, 161 { 0, 0 }, 162 /* 60 */ 163 { 0, 0 }, 164 { 0, 0 }, 165 { 0, 0 }, 166 { &FWScript::o1_setScreenDimensions, "wwww" }, 167 /* 64 */ 168 { &FWScript::o1_displayBackground, "" }, 169 { &FWScript::o1_initializeZoneData, "" }, 170 { &FWScript::o1_setZoneDataEntry, "bw" }, 171 { &FWScript::o1_getZoneDataEntry, "bb" }, 172 /* 68 */ 173 { &FWScript::o1_setDefaultMenuColor, "b" }, 174 { &FWScript::o1_allowPlayerInput, "" }, 175 { &FWScript::o1_disallowPlayerInput, "" }, 176 { &FWScript::o1_changeDataDisk, "b" }, 177 /* 6C */ 178 { 0, 0 }, 179 { &FWScript::o1_loadMusic, "s" }, 180 { &FWScript::o1_playMusic, "" }, 181 { &FWScript::o1_fadeOutMusic, "" }, 182 /* 70 */ 183 { &FWScript::o1_stopSample, "" }, 184 { &FWScript::o1_op71, "bw" }, 185 { &FWScript::o1_op72, "wbw" }, 186 { &FWScript::o1_op72, "wbw" }, 187 /* 74 */ 188 { 0, 0 }, 189 { 0, 0 }, 190 { 0, 0 }, 191 { &FWScript::o2_playSample, "bbwbww" }, 192 /* 78 */ 193 { &FWScript::o2_playSampleAlt, "bbwbww" }, 194 { &FWScript::o1_disableSystemMenu, "b" }, 195 { &FWScript::o1_loadMask5, "b" }, 196 { &FWScript::o1_unloadMask5, "b" }, 197 /* 7C */ 198 { 0, 0 }, 199 { 0, 0 }, 200 { 0, 0 }, 201 { &FWScript::o2_addSeqListElement, "bbbbwww" }, 202 /* 80 */ 203 { &FWScript::o2_removeSeq, "bb" }, 204 { &FWScript::o2_op81, "" }, 205 { &FWScript::o2_op82, "bbw" }, 206 { &FWScript::o2_isSeqRunning, "bb" }, 207 /* 84 */ 208 { &FWScript::o2_gotoIfSupNearest, "b" }, 209 { &FWScript::o2_gotoIfSupEquNearest, "b" }, 210 { &FWScript::o2_gotoIfInfNearest, "b" }, 211 { &FWScript::o2_gotoIfInfEquNearest, "b" }, 212 /* 88 */ 213 { &FWScript::o2_gotoIfEquNearest, "b" }, 214 { &FWScript::o2_gotoIfDiffNearest, "b" }, 215 { 0, 0 }, 216 { &FWScript::o2_startObjectScript, "b" }, 217 /* 8C */ 218 { &FWScript::o2_stopObjectScript, "b" }, 219 { &FWScript::o2_op8D, "wwwwwwww" }, 220 { &FWScript::o2_addBackground, "bs" }, 221 { &FWScript::o2_removeBackground, "b" }, 222 /* 90 */ 223 { &FWScript::o2_loadAbs, "bs" }, 224 { &FWScript::o2_loadBg, "b" }, 225 { 0, 0 }, 226 { 0, 0 }, 227 /* 94 */ 228 { 0, 0 }, 229 { &FWScript::o1_changeDataDisk, "b" }, 230 { 0, 0 }, 231 { 0, 0 }, 232 /* 98 */ 233 { 0, 0 }, 234 { 0, 0 }, 235 { &FWScript::o2_wasZoneChecked, "" }, 236 { &FWScript::o2_op9B, "wwwwwwww" }, 237 /* 9C */ 238 { &FWScript::o2_op9C, "wwww" }, 239 { &FWScript::o2_useBgScroll, "b" }, 240 { &FWScript::o2_setAdditionalBgVScroll, "c" }, 241 { &FWScript::o2_op9F, "ww" }, 242 /* A0 */ 243 { &FWScript::o2_addGfxElementA0, "ww" }, 244 { &FWScript::o2_removeGfxElementA0, "ww" }, 245 { &FWScript::o2_opA2, "ww" }, 246 { &FWScript::o2_opA3, "ww" }, 247 /* A4 */ 248 { &FWScript::o2_loadMask22, "b" }, 249 { &FWScript::o2_unloadMask22, "b" }, 250 { 0, 0 }, 251 { 0, 0 }, 252 /* A8 */ 253 { 0, 0 }, 254 { &FWScript::o1_changeDataDisk, "b" } 255 }; 256 const unsigned int OSScript::_numOpcodes = ARRAYSIZE(OSScript::_opcodeTable); 257 258 /*! \brief Contructor for global scripts 259 * \param script Script bytecode reference 260 * \param idx Script bytecode index 261 */ 262 OSScript::OSScript(const RawScript &script, int16 idx) : 263 FWScript(script, idx, new OSScriptInfo) {} 264 265 /*! \brief Constructor for object scripts 266 * \param script Script bytecode reference 267 * \param idx Script bytecode index 268 */ 269 OSScript::OSScript(RawObjectScript &script, int16 idx) : 270 FWScript(script, idx, new OSScriptInfo) {} 271 272 /*! \brief Copy constructor 273 */ 274 OSScript::OSScript(const OSScript &src) : FWScript(src, new OSScriptInfo) {} 275 276 /*! \brief Restore script state from savefile 277 * \param labels Restored script labels 278 * \param local Restored local script variables 279 * \param compare Restored last comparison result 280 * \param pos Restored script position 281 */ 282 void OSScript::load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) { 283 FWScript::load(labels, local, compare, pos); 284 } 285 286 /*! \brief Get opcode info string 287 * \param opcode Opcode to look for in opcode table 288 */ 289 const char *OSScriptInfo::opcodeInfo(byte opcode) const { 290 if (opcode == 0 || opcode > OSScript::_numOpcodes) { 291 return NULL; 292 } 293 294 if (!OSScript::_opcodeTable[opcode - 1].args) { 295 warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeInfo", opcode - 1); 296 return NULL; 297 } 298 299 return OSScript::_opcodeTable[opcode - 1].args; 300 } 301 302 /*! \brief Get opcode handler pointer 303 * \param opcode Opcode to look for in opcode table 304 */ 305 opFunc OSScriptInfo::opcodeHandler(byte opcode) const { 306 if (opcode == 0 || opcode > OSScript::_numOpcodes) { 307 return NULL; 308 } 309 310 if (!OSScript::_opcodeTable[opcode - 1].proc) { 311 warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeHandler", opcode - 1); 312 return NULL; 313 } 314 315 return OSScript::_opcodeTable[opcode - 1].proc; 316 } 317 318 /*! \brief Create new OSScript instance 319 * \param script Script bytecode 320 * \param index Bytecode index 321 */ 322 FWScript *OSScriptInfo::create(const RawScript &script, int16 index) const { 323 return new OSScript(script, index); 324 } 325 326 /*! \brief Create new OSScript instance 327 * \param script Object script bytecode 328 * \param index Bytecode index 329 */ 330 FWScript *OSScriptInfo::create(const RawObjectScript &script, int16 index) const { 331 return new OSScript(script, index); 332 } 333 334 /*! \brief Load saved OSScript instance 335 * \param script Script bytecode 336 * \param index Bytecode index 337 * \param local Local variables 338 * \param labels Script labels 339 * \param compare Last compare result 340 * \param pos Position in script 341 */ 342 FWScript *OSScriptInfo::create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const { 343 OSScript *tmp = new OSScript(script, index); 344 assert(tmp); 345 tmp->load(labels, local, compare, pos); 346 return tmp; 347 } 348 349 /*! \brief Load saved OSScript instance 350 * \param script Object script bytecode 351 * \param index Bytecode index 352 * \param local Local variables 353 * \param labels Script labels 354 * \param compare Last compare result 355 * \param pos Position in script 356 */ 357 FWScript *OSScriptInfo::create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const { 358 OSScript *tmp = new OSScript(script, index); 359 assert(tmp); 360 tmp->load(labels, local, compare, pos); 361 return tmp; 362 } 363 364 // ------------------------------------------------------------------------ 365 // OPERATION STEALTH opcodes 366 // ------------------------------------------------------------------------ 367 368 int FWScript::o2_loadPart() { 369 const char *param = getNextString(); 370 371 debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _line, param); 372 return 0; 373 } 374 375 int FWScript::o2_playSample() { 376 if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) { 377 // no-op in these versions 378 getNextByte(); 379 getNextByte(); 380 getNextWord(); 381 getNextByte(); 382 getNextWord(); 383 getNextWord(); 384 return 0; 385 } 386 return o1_playSample(); 387 } 388 389 int FWScript::o2_playSampleAlt() { 390 byte num = getNextByte(); 391 byte channel = getNextByte(); 392 uint16 frequency = getNextWord(); 393 getNextByte(); 394 getNextWord(); 395 uint16 size = getNextWord(); 396 397 if (size == 0xFFFF) { 398 size = animDataTable[num]._width * animDataTable[num]._height; 399 } 400 if (animDataTable[num].data()) { 401 if (g_cine->getPlatform() == Common::kPlatformPC) { 402 // if speaker output is available, play sound on it 403 // if it's another device, don't play anything 404 // TODO: implement this, it's used in the introduction for example 405 // on each letter displayed 406 } else { 407 g_sound->playSound(channel, frequency, animDataTable[num].data(), size, 0, 0, 63, 0); 408 } 409 } 410 return 0; 411 } 412 413 int FWScript::o2_addSeqListElement() { 414 byte param1 = getNextByte(); 415 byte param2 = getNextByte(); 416 byte param3 = getNextByte(); 417 byte param4 = getNextByte(); 418 uint16 param5 = getNextWord(); 419 uint16 param6 = getNextWord(); 420 uint16 param7 = getNextWord(); 421 422 debugC(5, kCineDebugScript, "Line: %d: addSeqListElement(%d,%d,%d,%d,%d,%d,%d)", _line, param1, param2, param3, param4, param5, param6, param7); 423 addSeqListElement(param1, 0, param2, param3, param4, param5, param6, 0, param7); 424 return 0; 425 } 426 427 int FWScript::o2_removeSeq() { 428 byte a = getNextByte(); 429 byte b = getNextByte(); 430 431 debugC(5, kCineDebugScript, "Line: %d: removeSeq(%d,%d) -> TODO", _line, a, b); 432 removeSeq(a, 0, b); 433 return 0; 434 } 435 436 /*! \todo Implement this instruction 437 */ 438 int FWScript::o2_op81() { 439 warning("STUB: o2_op81()"); 440 // freeUnkList(); 441 return 0; 442 } 443 444 /*! \todo Implement this instruction 445 */ 446 int FWScript::o2_op82() { 447 byte a = getNextByte(); 448 byte b = getNextByte(); 449 uint16 c = getNextWord(); 450 warning("STUB: o2_op82(%x, %x, %x)", a, b, c); 451 return 0; 452 } 453 454 int FWScript::o2_isSeqRunning() { 455 byte a = getNextByte(); 456 byte b = getNextByte(); 457 458 debugC(5, kCineDebugScript, "Line: %d: OP83(%d,%d) -> TODO", _line, a, b); 459 460 if (isSeqRunning(a, 0, b)) { 461 _compare = 1; 462 } else { 463 _compare = 0; 464 } 465 return 0; 466 } 467 468 /*! \todo The assert may produce false positives and requires testing 469 */ 470 int FWScript::o2_gotoIfSupNearest() { 471 byte labelIdx = getNextByte(); 472 473 if (_compare == kCmpGT) { 474 assert(_labels[labelIdx] != -1); 475 476 debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (true)", _line, labelIdx); 477 _pos = _script.getLabel(*_info, labelIdx, _pos); 478 } else { 479 debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (false)", _line, labelIdx); 480 } 481 return 0; 482 } 483 484 /*! \todo The assert may produce false positives and requires testing 485 */ 486 int FWScript::o2_gotoIfSupEquNearest() { 487 byte labelIdx = getNextByte(); 488 489 if (_compare & (kCmpGT | kCmpEQ)) { 490 assert(_labels[labelIdx] != -1); 491 492 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (true)", _line, labelIdx); 493 _pos = _script.getLabel(*_info, labelIdx, _pos); 494 } else { 495 debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (false)", _line, labelIdx); 496 } 497 return 0; 498 } 499 500 /*! \todo The assert may produce false positives and requires testing 501 */ 502 int FWScript::o2_gotoIfInfNearest() { 503 byte labelIdx = getNextByte(); 504 505 if (_compare == kCmpLT) { 506 assert(_labels[labelIdx] != -1); 507 508 debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (true)", _line, labelIdx); 509 _pos = _script.getLabel(*_info, labelIdx, _pos); 510 } else { 511 debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (false)", _line, labelIdx); 512 } 513 return 0; 514 } 515 516 /*! \todo The assert may produce false positives and requires testing 517 */ 518 int FWScript::o2_gotoIfInfEquNearest() { 519 byte labelIdx = getNextByte(); 520 521 if (_compare & (kCmpLT | kCmpEQ)) { 522 assert(_labels[labelIdx] != -1); 523 524 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (true)", _line, labelIdx); 525 _pos = _script.getLabel(*_info, labelIdx, _pos); 526 } else { 527 debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (false)", _line, labelIdx); 528 } 529 return 0; 530 } 531 532 /*! \todo The assert may produce false positives and requires testing 533 */ 534 int FWScript::o2_gotoIfEquNearest() { 535 byte labelIdx = getNextByte(); 536 537 if (_compare == kCmpEQ) { 538 assert(_labels[labelIdx] != -1); 539 540 debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (true)", _line, labelIdx); 541 _pos = _script.getLabel(*_info, labelIdx, _pos); 542 } else { 543 debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (false)", _line, labelIdx); 544 } 545 return 0; 546 } 547 548 /*! \todo The assert may produce false positives and requires testing 549 */ 550 int FWScript::o2_gotoIfDiffNearest() { 551 byte labelIdx = getNextByte(); 552 553 if (_compare != kCmpEQ) { 554 assert(_labels[labelIdx] != -1); 555 556 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (true)", _line, labelIdx); 557 _pos = _script.getLabel(*_info, labelIdx, _pos); 558 } else { 559 debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (false)", _line, labelIdx); 560 } 561 return 0; 562 } 563 564 int FWScript::o2_startObjectScript() { 565 byte param = getNextByte(); 566 567 debugC(5, kCineDebugScript, "Line: %d: startObjectScript(%d)", _line, param); 568 runObjectScript(param); 569 return 0; 570 } 571 572 int FWScript::o2_stopObjectScript() { 573 byte param = getNextByte(); 574 575 debugC(5, kCineDebugScript, "Line: %d: stopObjectScript(%d)", _line, param); 576 ScriptList::iterator it = objectScripts.begin(); 577 578 for (; it != objectScripts.end(); ++it) { 579 if ((*it)->_index == param) { 580 (*it)->_index = -1; 581 } 582 } 583 return 0; 584 } 585 586 /*! \todo Implement this instruction 587 */ 588 int FWScript::o2_op8D() { 589 uint16 a = getNextWord(); 590 uint16 b = getNextWord(); 591 uint16 c = getNextWord(); 592 uint16 d = getNextWord(); 593 uint16 e = getNextWord(); 594 uint16 f = getNextWord(); 595 uint16 g = getNextWord(); 596 uint16 h = getNextWord(); 597 warning("STUB: o2_op8D(%x, %x, %x, %x, %x, %x, %x, %x)", a, b, c, d, e, f, g, h); 598 // _currentScriptElement->compareResult = ... 599 return 0; 600 } 601 602 int FWScript::o2_addBackground() { 603 byte param1 = getNextByte(); 604 const char *param2 = getNextString(); 605 606 debugC(5, kCineDebugScript, "Line: %d: addBackground(%s,%d)", _line, param2, param1); 607 addBackground(param2, param1); 608 return 0; 609 } 610 611 int FWScript::o2_removeBackground() { 612 byte param = getNextByte(); 613 614 assert(param); 615 616 debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _line, param); 617 618 if (additionalBgTable[param]) { 619 free(additionalBgTable[param]); 620 additionalBgTable[param] = NULL; 621 } 622 623 if (currentAdditionalBgIdx == param) { 624 currentAdditionalBgIdx = 0; 625 } 626 627 if (currentAdditionalBgIdx2 == param) { 628 currentAdditionalBgIdx2 = 0; 629 } 630 631 strcpy(currentBgName[param], ""); 632 return 0; 633 } 634 635 int FWScript::o2_loadAbs() { 636 byte param1 = getNextByte(); 637 const char *param2 = getNextString(); 638 639 debugC(5, kCineDebugScript, "Line: %d: loadABS(%d,%s)", _line, param1, param2); 640 loadAbs(param2, param1); 641 return 0; 642 } 643 644 int FWScript::o2_loadBg() { 645 byte param = getNextByte(); 646 647 assert(param <= 8); 648 649 debugC(5, kCineDebugScript, "Line: %d: useBg(%d)", _line, param); 650 651 if (additionalBgTable[param]) { 652 currentAdditionalBgIdx = param; 653 if (param == 8) { 654 newColorMode = 3; 655 } else { 656 newColorMode = bgColorMode + 1; 657 } 658 //if (_screenNeedFadeOut == 0) { 659 // adBgVar1 = 1; 660 //} 661 fadeRequired = true; 662 } 663 return 0; 664 } 665 666 /*! \todo Implement this instruction 667 */ 668 int FWScript::o2_wasZoneChecked() { 669 warning("STUB: o2_wasZoneChecked()"); 670 return 0; 671 } 672 673 /*! \todo Implement this instruction 674 */ 675 int FWScript::o2_op9B() { 676 uint16 a = getNextWord(); 677 uint16 b = getNextWord(); 678 uint16 c = getNextWord(); 679 uint16 d = getNextWord(); 680 uint16 e = getNextWord(); 681 uint16 f = getNextWord(); 682 uint16 g = getNextWord(); 683 uint16 h = getNextWord(); 684 warning("STUB: o2_op9B(%x, %x, %x, %x, %x, %x, %x, %x)", a, b, c, d, e, f, g, h); 685 return 0; 686 } 687 688 /*! \todo Implement this instruction 689 */ 690 int FWScript::o2_op9C() { 691 uint16 a = getNextWord(); 692 uint16 b = getNextWord(); 693 uint16 c = getNextWord(); 694 uint16 d = getNextWord(); 695 warning("STUB: o2_op9C(%x, %x, %x, %x)", a, b, c, d); 696 return 0; 697 } 698 699 int FWScript::o2_useBgScroll() { 700 byte param = getNextByte(); 701 702 assert(param <= 8); 703 704 debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _line, param); 705 706 if (additionalBgTable[param]) { 707 currentAdditionalBgIdx2 = param; 708 } 709 return 0; 710 } 711 712 int FWScript::o2_setAdditionalBgVScroll() { 713 byte param1 = getNextByte(); 714 715 if (param1) { 716 byte param2 = getNextByte(); 717 718 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _line, param2); 719 additionalBgVScroll = _localVars[param2]; 720 } else { 721 uint16 param2 = getNextWord(); 722 723 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _line, param2); 724 additionalBgVScroll = param2; 725 } 726 return 0; 727 } 728 729 /*! \todo Implement this instruction 730 */ 731 int FWScript::o2_op9F() { 732 warning("o2_op9F()"); 733 getNextWord(); 734 getNextWord(); 735 return 0; 736 } 737 738 int FWScript::o2_addGfxElementA0() { 739 uint16 param1 = getNextWord(); 740 uint16 param2 = getNextWord(); 741 742 debugC(5, kCineDebugScript, "Line: %d: addGfxElementA0(%d,%d)", _line, param1, param2); 743 addGfxElementA0(param1, param2); 744 return 0; 745 } 746 747 /*! \todo Implement this instruction 748 */ 749 int FWScript::o2_removeGfxElementA0() { 750 uint16 idx = getNextWord(); 751 uint16 param = getNextWord(); 752 warning("STUB? o2_removeGfxElementA0(%x, %x)", idx, param); 753 removeGfxElementA0(idx, param); 754 return 0; 755 } 756 757 /*! \todo Implement this instruction 758 */ 759 int FWScript::o2_opA2() { 760 uint16 a = getNextWord(); 761 uint16 b = getNextWord(); 762 warning("STUB: o2_opA2(%x, %x)", a, b); 763 // addGfxElementA2(); 764 return 0; 765 } 766 767 /*! \todo Implement this instruction 768 */ 769 int FWScript::o2_opA3() { 770 uint16 a = getNextWord(); 771 uint16 b = getNextWord(); 772 warning("STUB: o2_opA3(%x, %x)", a, b); 773 // removeGfxElementA2(); 774 return 0; 775 } 776 777 int FWScript::o2_loadMask22() { 778 byte param = getNextByte(); 779 780 debugC(5, kCineDebugScript, "Line: %d: addOverlay22(%d)", _line, param); 781 addOverlay(param, 22); 782 return 0; 783 } 784 785 int FWScript::o2_unloadMask22() { 786 byte param = getNextByte(); 787 788 debugC(5, kCineDebugScript, "Line: %d: removeOverlay22(%d)", _line, param); 789 removeOverlay(param, 22); 790 return 0; 791 } 792 793 } // End of namespace Cine -
engines/cine/object.cpp
37 37 38 38 objectStruct objectTable[NUM_MAX_OBJECT]; 39 39 ScriptVars globalVars(NUM_MAX_VAR); 40 overlayHeadElement overlayHead;40 Common::List<overlay> overlayList; 41 41 42 void unloadAllMasks(void) {43 overlayHeadElement *current = overlayHead.next;44 45 while (current) {46 overlayHeadElement *next = current->next;47 48 delete current;49 50 current = next;51 }52 53 resetMessageHead();54 }55 56 void resetMessageHead(void) {57 overlayHead.next = NULL;58 overlayHead.previous = NULL;59 }60 61 42 void loadObject(char *pObjectName) { 62 43 uint16 numEntry; 63 44 uint16 entrySize; … … 100 81 free(dataPtr); 101 82 } 102 83 103 int8 removeOverlayElement(uint16 objIdx, uint16 param) { 104 overlayHeadElement *currentHeadPtr = &overlayHead; 105 overlayHeadElement *tempHead = currentHeadPtr; 106 overlayHeadElement *tempPtr2; 84 /*! \brief Remove overlay sprite from the list 85 * \param objIdx Remove overlay associated with this object 86 * \param param Remove overlay of this type 87 */ 88 int removeOverlay(uint16 objIdx, uint16 param) { 89 Common::List<overlay>::iterator it; 107 90 108 currentHeadPtr = tempHead->next;109 110 while (currentHeadPtr && (currentHeadPtr->objIdx != objIdx || currentHeadPtr->type != param)) {111 tempHead = currentHeadPtr;112 currentHeadPtr = tempHead->next;91 for (it = overlayList.begin(); it != overlayList.end(); ++it) { 92 if (it->objIdx == objIdx && it->type == param) { 93 overlayList.erase(it); 94 return 1; 95 } 113 96 } 114 97 115 if (!currentHeadPtr || currentHeadPtr->objIdx != objIdx || currentHeadPtr->type != param) { 116 return -1; 117 } 98 return 0; 99 } 118 100 119 tempHead->next = tempPtr2 = currentHeadPtr->next; 101 /*! \brief Add new overlay sprite to the list 102 * \param objIdx Associate the overlay with this object 103 * \param param Type of new overlay 104 * \todo Why are x, y, width and color left uninitialized? 105 */ 106 void addOverlay(uint16 objIdx, uint16 param) { 107 Common::List<overlay>::iterator it; 108 overlay tmp; 120 109 121 if (!tempPtr2) { 122 tempPtr2 = &overlayHead; 110 for (it = overlayList.begin(); it != overlayList.end(); ++it) { 111 if (objectTable[it->objIdx].mask >= objectTable[objIdx].mask) { 112 break; 113 } 123 114 } 124 115 125 tempPtr2->previous = currentHeadPtr->previous; 116 tmp.objIdx = objIdx; 117 tmp.type = param; 126 118 127 delete currentHeadPtr; 128 129 return 0; 119 overlayList.insert(it, tmp); 130 120 } 131 121 132 int16 freeOverlay(uint16 objIdx, uint16 param) { 133 overlayHeadElement *currentHeadPtr = overlayHead.next; 134 overlayHeadElement *previousPtr = &overlayHead; 135 overlayHeadElement *tempPtr2; 122 /*! \brief Add new background mask overlay 123 * \param objIdx Associate the overlay with this object 124 * \param param source background index 125 */ 126 void addGfxElementA0(int16 objIdx, int16 param) { 127 Common::List<overlay>::iterator it; 128 overlay tmp; 136 129 137 while (currentHeadPtr && ((currentHeadPtr->objIdx != objIdx) || (currentHeadPtr->type != param))) { 138 previousPtr = currentHeadPtr; 139 currentHeadPtr = previousPtr->next; 130 for (it = overlayList.begin(); it != overlayList.end(); ++it) { 131 // wtf?! 132 if (objectTable[it->objIdx].mask == objectTable[objIdx].mask && 133 (it->type == 2 || it->type == 3)) { 134 break; 135 } 140 136 } 141 137 142 if ( !currentHeadPtr || !((currentHeadPtr->objIdx == objIdx) && (currentHeadPtr->type == param))) {143 return -1;138 if (it != overlayList.end() && it->objIdx == objIdx && it->type == 20 && it->x == param) { 139 return; 144 140 } 145 141 146 previousPtr->next = tempPtr2 = currentHeadPtr->next; 142 tmp.objIdx = objIdx; 143 tmp.type = 20; 144 tmp.x = param; 145 tmp.y = 0; 146 tmp.width = 0; 147 tmp.color = 0; 147 148 148 if (!tempPtr2) { 149 tempPtr2 = &overlayHead; 150 } 151 152 tempPtr2->previous = currentHeadPtr->previous; 153 154 delete currentHeadPtr; 155 return 0; 149 overlayList.insert(it, tmp); 156 150 } 157 151 158 void loadOverlayElement(uint16 objIdx, uint16 param) { 159 overlayHeadElement *currentHeadPtr = &overlayHead; 160 overlayHeadElement *pNewElement; 152 /*! \brief Remove background mask overlay 153 * \param objIdx Remove overlay associated with this object 154 * \param param Remove overlay using this background 155 * \todo Check that it works 156 */ 157 void removeGfxElementA0(int16 objIdx, int16 param) { 158 Common::List<overlay>::iterator it; 161 159 162 uint16 si = objectTable[objIdx].mask; 163 164 overlayHeadElement *tempHead = currentHeadPtr; 165 166 currentHeadPtr = tempHead->next; 167 168 while (currentHeadPtr && (objectTable[currentHeadPtr->objIdx].mask < si)) { 169 tempHead = currentHeadPtr; 170 currentHeadPtr = tempHead->next; 160 for (it = overlayList.begin(); it != overlayList.end(); ++it) { 161 if (it->objIdx == objIdx && it->type == 20 && it->x == param) { 162 overlayList.erase(it); 163 return; 164 } 171 165 } 172 173 pNewElement = new overlayHeadElement;174 175 assert(pNewElement);176 177 pNewElement->next = tempHead->next;178 tempHead->next = pNewElement;179 180 pNewElement->objIdx = objIdx;181 pNewElement->type = param;182 183 if (!currentHeadPtr) {184 currentHeadPtr = &overlayHead;185 }186 187 pNewElement->previous = currentHeadPtr->previous;188 currentHeadPtr->previous = pNewElement;189 166 } 190 167 191 168 void setupObject(byte objIdx, uint16 param1, uint16 param2, uint16 param3, uint16 param4) { … … 194 171 objectTable[objIdx].mask = param3; 195 172 objectTable[objIdx].frame = param4; 196 173 197 if ( !removeOverlayElement(objIdx, 0)) {198 loadOverlayElement(objIdx, 0);174 if (removeOverlay(objIdx, 0)) { 175 addOverlay(objIdx, 0); 199 176 } 200 177 } 201 178 … … 223 200 case 2: 224 201 objectTable[objIdx].mask = newValue; 225 202 226 if ( !removeOverlayElement(objIdx, 0)) {227 loadOverlayElement(objIdx, 0);203 if (removeOverlay(objIdx, 0)) { 204 addOverlay(objIdx, 0); 228 205 } 229 206 break; 230 207 case 3: -
engines/cine/main_loop.cpp
189 189 quitFlag = 0; 190 190 191 191 if (_preLoad == false) { 192 resetMessageHead();193 192 resetSeqList(); 194 193 resetBgIncrustList(); 195 194 … … 315 314 316 315 hideMouse(); 317 316 g_sound->stopMusic(); 318 unloadAllMasks();319 317 // if (g_cine->getGameType() == Cine::GType_OS) { 320 318 // freeUnkList(); 321 319 // } -
engines/cine/cine.cpp
129 129 globalScripts.clear(); 130 130 bgIncrustList.clear(); 131 131 freeAnimDataTable(); 132 overlayList.clear(); 132 133 133 134 memset(objectTable, 0, sizeof(objectTable)); 134 135 memset(messageTable, 0, sizeof(messageTable)); 135 136 136 overlayHead.next = overlayHead.previous = NULL;137 138 137 var8 = 0; 139 // bgIncrustList = NULL;140 138 141 139 var2 = var3 = var4 = var5 = 0; 142 140 -
engines/cine/gfx.cpp
168 168 byte *destPtr = page + x + y * 320; 169 169 destPtr += i * 320; 170 170 171 for (j = 0; j < width * 8; j++) {171 for (j = 0; j < width; j++) { 172 172 if (x + j >= 0 && x + j < 320 && i + y >= 0 173 173 && i + y < 200) { 174 174 if (!*(spritePtr++)) { … … 191 191 byte *destPtr = page + x + y * 320; 192 192 destPtr += i * 320; 193 193 194 for (j = 0; j < width * 8; j++) {194 for (j = 0; j < width; j++) { 195 195 if (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200 && *maskPtr == 0) { 196 196 *destPtr = *spritePtr; 197 197 } … … 202 202 } 203 203 } 204 204 205 void gfxUpdateSpriteMask(const byte *spritePtr, const byte *spriteMskPtr, int16 width, int16 height, const byte *maskPtr, 206 int16 maskWidth, int16 maskHeight, byte *bufferSprPtr, byte *bufferMskPtr, int16 xs, int16 ys, int16 xm, int16 ym, byte maskIdx) { 205 void gfxUpdateSpriteMask(byte *destMask, int16 x, int16 y, int16 width, int16 height, const byte *srcMask, int16 xm, int16 ym, int16 maskWidth, int16 maskHeight) { 207 206 int16 i, j, d, spritePitch, maskPitch; 208 207 209 width *= 8;210 maskWidth *= 8;211 212 208 spritePitch = width; 213 209 maskPitch = maskWidth; 214 210 215 if (maskIdx == 0) { 216 memcpy(bufferSprPtr, spritePtr, spritePitch * height); 217 memcpy(bufferMskPtr, spriteMskPtr, spritePitch * height); 218 } 219 220 if (ys > ym) { 221 d = ys - ym; 222 maskPtr += d * maskPitch; 211 // crop update area to overlapping parts of masks 212 if (y > ym) { 213 d = y - ym; 214 srcMask += d * maskPitch; 223 215 maskHeight -= d; 224 } 225 if (maskHeight <= 0) { 226 return; 227 } 228 if (xs > xm) { 229 d = xs - xm; 230 maskPtr += d; 231 maskWidth -= d; 232 } 233 if (maskWidth <= 0) { 234 return; 235 } 236 if (ys < ym) { 237 d = ym - ys; 238 spriteMskPtr += d * spritePitch; 239 bufferMskPtr += d * spritePitch; 216 } else if (y < ym) { 217 d = ym - y; 218 destMask += d * spritePitch; 240 219 height -= d; 241 220 } 242 if (height <= 0) { 243 return; 244 } 245 if (xs < xm) { 246 d = xm - xs; 247 spriteMskPtr += d; 248 bufferMskPtr += d; 221 222 if (x > xm) { 223 d = x - xm; 224 srcMask += d; 225 maskWidth -= d; 226 } else if (x < xm) { 227 d = xm - x; 228 destMask += d; 249 229 width -= d; 250 230 } 251 if (width <= 0) { 252 return; 253 } 231 232 // update mask 254 233 for (j = 0; j < MIN(maskHeight, height); ++j) { 255 234 for (i = 0; i < MIN(maskWidth, width); ++i) { 256 bufferMskPtr[i] |= maskPtr[i] ^ 1;235 destMask[i] |= srcMask[i] ^ 1; 257 236 } 258 bufferMskPtr+= spritePitch;259 maskPtr+= maskPitch;237 destMask += spritePitch; 238 srcMask += maskPitch; 260 239 } 261 240 } 262 241 -
engines/cine/bg.cpp
134 134 135 135 additionalBgTable[bgIdx] = (byte *) malloc(320 * 200); 136 136 137 debug("addBackground %d", bgIdx);138 139 137 uint16 bpp = READ_BE_UINT16(ptr); ptr += 2; 140 138 141 139 if (bpp == 8) { -
engines/cine/anim.h
102 102 void loadResource(const char *animName); 103 103 void loadAbs(const char *resourceName, uint16 idx); 104 104 void loadResourcesFromSave(Common::InSaveFile &fHandle, bool broken); 105 void generateMask(const byte *sprite, byte *mask, uint16 size, byte transparency); 105 106 106 107 } // End of namespace Cine 107 108 -
engines/cine/various.h
149 149 150 150 extern int16 additionalBgVScroll; 151 151 152 void removeSeq(uint16 param1, uint16 param2, uint16 param3); 153 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3); 152 154 void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8); 153 155 void resetSeqList(); 154 156 void processSeqList(void);