Ticket #8869: dump.patch
File dump.patch, 103.0 KB (added by , 16 years ago) |
---|
-
engines/cine/script_fw.cpp
41 41 ScriptVars globalVars(NUM_MAX_VAR); 42 42 43 43 uint16 compareVars(int16 a, int16 b); 44 void palRotate(byte a, byte b, byte c);45 void removeSeq(uint16 param1, uint16 param2, uint16 param3);46 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3);47 void addGfxElementA0(int16 param1, int16 param2);48 void removeGfxElementA0(int16 idx, int16 param);49 44 50 45 const Opcode FWScript::_opcodeTable[] = { 51 46 /* 00 */ … … 1299 1294 const char *param = getNextString(); 1300 1295 1301 1296 debugC(5, kCineDebugScript, "Line: %d: loadCt(\"%s\")", _line, param); 1302 loadCt (param);1297 loadCtFW(param); 1303 1298 return 0; 1304 1299 } 1305 1300 … … 1355 1350 debugC(5, kCineDebugScript, "Line: %d: request fadein", _line); 1356 1351 // TODO: use real code 1357 1352 1358 drawOverlays();1359 fadeRequired = true;1360 flip();1361 1362 1353 // fadeFromBlack(); 1354 1355 renderer->reloadPalette(); 1363 1356 return 0; 1364 1357 } 1365 1358 1366 1359 int FWScript::o1_fadeToBlack() { 1367 1360 debugC(5, kCineDebugScript, "Line: %d: request fadeout", _line); 1368 1361 1369 fadeToBlack();1362 renderer->fadeToBlack(); 1370 1363 return 0; 1371 1364 } 1372 1365 1373 1366 int FWScript::o1_transformPaletteRange() { 1374 1367 byte startColor = getNextByte(); 1375 1368 byte numColor = getNextByte(); 1376 uint16 r = getNextWord();1377 uint16 g = getNextWord();1378 uint16 b = getNextWord();1369 int16 r = getNextWord(); 1370 int16 g = getNextWord(); 1371 int16 b = getNextWord(); 1379 1372 1380 1373 debugC(5, kCineDebugScript, "Line: %d: transformPaletteRange(from:%d,numIdx:%d,r:%d,g:%d,b:%d)", _line, startColor, numColor, r, g, b); 1381 1374 1382 transformPaletteRange(startColor, numColor, r, g, b);1375 renderer->transformPalette(startColor, numColor, r, g, b); 1383 1376 return 0; 1384 1377 } 1385 1378 … … 1387 1380 byte param = getNextByte(); 1388 1381 1389 1382 debugC(5, kCineDebugScript, "Line: %d: setDefaultMenuColor2(%d)", _line, param); 1390 defaultMenuBoxColor2 = param; 1383 1384 renderer->_messageBg = param; 1391 1385 return 0; 1392 1386 } 1393 1387 … … 1397 1391 byte c = getNextByte(); 1398 1392 1399 1393 debugC(5, kCineDebugScript, "Line: %d: palRotate(%d,%d,%d)", _line, a, b, c); 1400 palRotate(a, b, c); 1394 1395 renderer->rotatePalette(a, b, c); 1401 1396 return 0; 1402 1397 } 1403 1398 … … 1475 1470 1476 1471 debugC(5, kCineDebugScript, "Line: %d: compare globalVars[%d] and %d", _line, varIdx, value); 1477 1472 1478 if (varIdx == 255 && (g_cine->getGameType() == Cine::GType_FW)) { // TODO: fix 1479 _compare = 1; 1480 } else { 1481 _compare = compareVars(_globalVars[varIdx], value); 1482 } 1473 _compare = compareVars(_globalVars[varIdx], value); 1483 1474 } 1484 1475 1485 1476 return 0; … … 1558 1549 byte param = getNextByte(); 1559 1550 1560 1551 debugC(5, kCineDebugScript, "Line: %d: setDefaultMenuColor(%d)", _line, param); 1561 defaultMenuBoxColor = param; 1552 1553 renderer->_cmdY = param; 1562 1554 return 0; 1563 1555 } 1564 1556 … … 1728 1720 1729 1721 //----------------------------------------------------------------------- 1730 1722 1731 void palRotate(byte a, byte b, byte c) {1732 if (c == 1) {1733 uint16 currentColor = c_palette[b];1734 1735 for (int16 i = b; i > a; i--) {1736 c_palette[i] = c_palette[i - 1];1737 }1738 1739 c_palette[a] = currentColor;1740 }1741 }1742 1743 1723 void addScriptToList0(uint16 idx) { 1744 1724 ScriptPtr tmp(scriptInfo->create(*scriptTable[idx], idx)); 1745 1725 assert(tmp); … … 1863 1843 } 1864 1844 } 1865 1845 1866 void decompileScript( byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 scriptIdx) {1846 void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx) { 1867 1847 char lineBuffer[256]; 1868 byte *localScriptPtr = scriptPtr;1848 const byte *localScriptPtr = scriptPtr; 1869 1849 uint16 exitScript; 1870 1850 uint32 position = 0; 1871 1851 1872 1852 assert(scriptPtr); 1873 // assert(stackPtr);1874 1853 1875 1854 exitScript = 0; 1876 1855 … … 2292 2271 sprintf(lineBuffer, "loadPart(%s)\n", localScriptPtr + position); 2293 2272 } 2294 2273 2295 position += strlen((c har *)localScriptPtr + position) + 1;2274 position += strlen((const char *)localScriptPtr + position) + 1; 2296 2275 break; 2297 2276 } 2298 2277 case 0x40: … … 2309 2288 2310 2289 sprintf(lineBuffer, "loadPrc(%d,%s)\n", param, localScriptPtr + position); 2311 2290 2312 position += strlen((c har *)localScriptPtr + position) + 1;2291 position += strlen((const char *)localScriptPtr + position) + 1; 2313 2292 break; 2314 2293 } 2315 2294 case OP_requestCheckPendingDataLoad: // nop … … 2461 2440 { 2462 2441 sprintf(lineBuffer, "comment: %s\n", localScriptPtr + position); 2463 2442 2464 position += strlen((c har *)localScriptPtr + position);2443 position += strlen((const char *)localScriptPtr + position); 2465 2444 break; 2466 2445 } 2467 2446 case 0x5A: … … 2540 2519 { 2541 2520 sprintf(lineBuffer, "loadDat(%s)\n", localScriptPtr + position); 2542 2521 2543 position += strlen((c har *)localScriptPtr + position) + 1;2522 position += strlen((const char *)localScriptPtr + position) + 1; 2544 2523 break; 2545 2524 } 2546 2525 case 0x6E: // nop … … 2801 2780 2802 2781 sprintf(lineBuffer, "ADDBG(%d,%s)\n", param1, localScriptPtr + position); 2803 2782 2804 position += strlen((c har *)localScriptPtr + position);2783 position += strlen((const char *)localScriptPtr + position); 2805 2784 2806 2785 break; 2807 2786 } … … 2825 2804 2826 2805 sprintf(lineBuffer, "loadABS(%d,%s)\n", param1, localScriptPtr + position); 2827 2806 2828 position += strlen((c har *)localScriptPtr + position);2807 position += strlen((const char *)localScriptPtr + position); 2829 2808 2830 2809 break; 2831 2810 } -
engines/cine/script.h
230 230 int o1_unloadMask5(); 231 231 232 232 // pointers to member functions in C++ suck... 233 int o2_loadCt(); 233 234 int o2_loadPart(); 234 235 int o2_addSeqListElement(); 235 236 int o2_removeSeq(); … … 362 363 363 364 void setupOpcodes(); 364 365 365 void decompileScript( byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 scriptIdx);366 void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx); 366 367 void dumpScript(char *dumpName); 367 368 368 369 #define OP_loadPart 0x3F -
engines/cine/pal.cpp
28 28 29 29 namespace Cine { 30 30 31 uint16 tempPalette[256];32 33 31 uint16 palEntriesCount; 34 32 35 33 PalEntry *palPtr = NULL; … … 113 111 } 114 112 } 115 113 114 void palRotate(uint16 *pal, byte a, byte b, byte c) { 115 assert(pal); 116 117 if (c == 1) { 118 uint16 currentColor = pal[b]; 119 120 for (int i = b; i > a; i--) { 121 pal[i] = pal[i - 1]; 122 } 123 124 pal[a] = currentColor; 125 } 126 } 127 128 void palRotate(byte *pal, byte a, byte b, byte c) { 129 assert(pal); 130 131 if (c == 1) { 132 byte currentR = pal[3 * b + 0]; 133 byte currentG = pal[3 * b + 1]; 134 byte currentB = pal[3 * b + 2]; 135 136 for (int i = b; i > a; i--) { 137 pal[3 * i + 0] = pal[3 * (i - 1) + 0]; 138 pal[3 * i + 1] = pal[3 * (i - 1) + 1]; 139 pal[3 * i + 2] = pal[3 * (i - 1) + 2]; 140 } 141 142 pal[3 * a + 0] = currentR; 143 pal[3 * a + 1] = currentG; 144 pal[3 * a + 2] = currentB; 145 } 146 } 147 148 uint16 transformColor(uint16 baseColor, int r, int g, int b) { 149 int8 oriR = CLIP( (baseColor & 0x007) + b, 0, 7); 150 int8 oriG = CLIP(((baseColor & 0x070) >> 4) + g, 0, 7); 151 int8 oriB = CLIP(((baseColor & 0x700) >> 8) + r, 0, 7); 152 153 return oriR | (oriG << 4) | (oriB << 8); 154 } 155 156 void transformPaletteRange(uint16 *dstPal, uint16 *srcPal, int startColor, int stopColor, int r, int g, int b) { 157 assert(srcPal && dstPal); 158 159 for (int i = startColor; i <= stopColor; i++) { 160 dstPal[i] = transformColor(srcPal[i], r, g, b); 161 } 162 } 163 164 void transformPaletteRange(byte *dstPal, byte *srcPal, int startColor, int stopColor, int r, int g, int b) { 165 assert(srcPal && dstPal); 166 167 for (int i = startColor; i <= stopColor; i++) { 168 dstPal[3 * i + 0] = CLIP(srcPal[3 * i + 0] + r * 32, 0, 255); 169 dstPal[3 * i + 1] = CLIP(srcPal[3 * i + 1] + g * 32, 0, 255); 170 dstPal[3 * i + 2] = CLIP(srcPal[3 * i + 2] + b * 32, 0, 255); 171 } 172 } 173 116 174 } // End of namespace Cine -
engines/cine/rel.cpp
81 81 char buffer[256]; 82 82 83 83 for (s = 0; s < numEntry; s++) { 84 if (relTable[s] .size) {84 if (relTable[s]->_size) { 85 85 sprintf(buffer, "%s_%03d.txt", pRelName, s); 86 86 87 decompileScript( relTable[s].data, NULL, relTable[s].size, s);87 decompileScript((const byte *)relTable[s]->getString(0), relTable[s]->_size, s); 88 88 dumpScript(buffer); 89 89 } 90 90 } -
engines/cine/bg_list.cpp
40 40 41 41 /*! \brief Add masked sprite to the background 42 42 * \param objIdx Sprite description 43 * \param addList Add sprite to incrust list if true44 * \todo Fix incrust objects on CT background. Always drawing incrust elements45 * on CT background breaks game zones46 43 */ 47 void addToBGList(int16 objIdx, bool addList) { 48 int16 x = objectTable[objIdx].x; 49 int16 y = objectTable[objIdx].y; 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(); 54 // int16 part = objectTable[objIdx].part; 44 void addToBGList(int16 objIdx) { 45 renderer->incrustSprite(objectTable[objIdx]); 55 46 56 // Operation Stealth may switch among multiple backgrounds 57 if (g_cine->getGameType() == GType_OS) { 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 } 63 } else { 64 drawSpriteRaw(data, mask, width, height, page2Raw, x, y); 65 } 66 67 if (addList) 68 createBgIncrustListElement(objIdx, 0); 47 createBgIncrustListElement(objIdx, 0); 69 48 } 70 49 71 50 /*! \brief Add filled sprite to the background 72 51 * \param objIdx Sprite description 73 * \param addList Add sprite to incrust list if true74 * \todo Fix incrust objects on CT background. Always drawing incrust elements75 * on CT background breaks game zones76 52 */ 77 void addSpriteFilledToBGList(int16 objIdx, bool addList) { 78 int16 x = objectTable[objIdx].x; 79 int16 y = objectTable[objIdx].y; 80 int16 width = animDataTable[objectTable[objIdx].frame]._realWidth; 81 int16 height = animDataTable[objectTable[objIdx].frame]._height; 82 const byte *data = animDataTable[objectTable[objIdx].frame].data(); 53 void addSpriteFilledToBGList(int16 objIdx) { 54 renderer->incrustMask(objectTable[objIdx]); 83 55 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, height, additionalBgTable[i], x, y); 90 } 91 } 92 } else { 93 gfxFillSprite(data, width, height, page2Raw, x, y); 94 } 95 } 96 97 if (addList) 98 createBgIncrustListElement(objIdx, 1); 56 createBgIncrustListElement(objIdx, 1); 99 57 } 100 58 101 59 /*! \brief Add new element to incrust list … … 115 73 bgIncrustList.push_back(tmp); 116 74 } 117 75 118 /*! \brief Reset var8 (probably something related to bgIncrustList 76 /*! \brief Reset var8 (probably something related to bgIncrustList) 119 77 */ 120 78 void resetBgIncrustList(void) { 121 79 var8 = 0; … … 142 100 bgIncrustList.push_back(tmp); 143 101 144 102 if (tmp.param == 0) { 145 addToBGList(tmp.objIdx, false);103 renderer->incrustSprite(objectTable[tmp.objIdx]); 146 104 } else { 147 addSpriteFilledToBGList(tmp.objIdx, false);105 renderer->incrustMask(objectTable[tmp.objIdx]); 148 106 } 149 107 } 150 108 } -
engines/cine/anim.cpp
53 53 54 54 static const AnimDataEntry transparencyData[] = { 55 55 {"ALPHA", 0xF}, 56 {"TITRE", 0xF}, 56 57 {"TITRE2", 0xF}, 57 58 {"ET", 0xC}, 58 59 {"L311", 0x3}, -
engines/cine/various.cpp
87 87 char newRelName[20]; 88 88 char newObjectName[20]; 89 89 char newMsgName[20]; 90 char currentBgName[8][15];91 90 char currentCtName[15]; 92 91 char currentPartName[15]; 93 92 char currentDatName[30]; … … 96 95 97 96 byte isInPause = 0; 98 97 99 uint16 defaultMenuBoxColor;100 101 98 byte inputVar1 = 0; 102 99 uint16 inputVar2 = 0, inputVar3 = 0; 103 100 … … 114 111 int16 objListTab[20]; 115 112 116 113 uint16 exitEngine; 117 uint16 defaultMenuBoxColor2;118 114 uint16 zoneData[NUM_MAX_ZONE]; 119 115 120 116 … … 140 136 tmp.type = 3; 141 137 142 138 overlayList.push_back(tmp); 139 waitForPlayerClick = 1; 143 140 } 144 141 145 142 int16 getRelEntryForObject(uint16 param1, uint16 param2, SelectedObjStruct *pSelectedObject) { … … 393 390 return broken; 394 391 } 395 392 393 /*! \todo Implement Operation Stealth loading, this is obviously Future Wars only 394 */ 396 395 bool CineEngine::makeLoad(char *saveName) { 397 396 int16 i; 398 397 int16 size; 399 398 bool broken; 400 399 Common::InSaveFile *fHandle; 400 char bgName[13]; 401 401 402 402 fHandle = g_saveFileMan->openForLoading(saveName); 403 403 … … 440 440 strcpy(newRelName, ""); 441 441 strcpy(newObjectName, ""); 442 442 strcpy(newMsgName, ""); 443 strcpy(currentBgName[0], "");444 443 strcpy(currentCtName, ""); 445 444 446 445 allowPlayerInput = 0; … … 455 454 456 455 fadeRequired = false; 457 456 458 for (i = 0; i < 16; i++) { 459 c_palette[i] = 0; 460 } 457 renderer->clear(); 461 458 462 459 checkForPendingDataLoadSwitch = 0; 463 460 … … 473 470 fHandle->read(currentPrcName, 13); 474 471 fHandle->read(currentRelName, 13); 475 472 fHandle->read(currentMsgName, 13); 476 fHandle->read( currentBgName[0], 13);473 fHandle->read(bgName, 13); 477 474 fHandle->read(currentCtName, 13); 478 475 479 476 checkDataDisk(currentDisk); … … 490 487 loadRel(currentRelName); 491 488 } 492 489 493 if (strlen( currentBgName[0])) {494 loadBg( currentBgName[0]);490 if (strlen(bgName)) { 491 loadBg(bgName); 495 492 } 496 493 497 494 if (strlen(currentCtName)) { 498 loadCt (currentCtName);495 loadCtFW(currentCtName); 499 496 } 500 497 501 498 fHandle->readUint16BE(); … … 511 508 objectTable[i].part = fHandle->readUint16BE(); 512 509 } 513 510 514 for (i = 0; i < 16; i++) { 515 c_palette[i] = fHandle->readUint16BE(); 516 } 511 renderer->restorePalette(*fHandle); 517 512 518 for (i = 0; i < 16; i++) {519 tempPalette[i] = fHandle->readUint16BE();520 }521 522 513 globalVars.load(*fHandle, NUM_MAX_VAR - 1); 523 514 524 515 for (i = 0; i < 16; i++) { … … 530 521 } 531 522 532 523 fHandle->read(commandBuffer, 0x50); 524 renderer->setCommand(commandBuffer); 533 525 534 defaultMenuBoxColor = fHandle->readUint16BE(); 526 renderer->_cmdY = fHandle->readUint16BE(); 527 535 528 bgVar0 = fHandle->readUint16BE(); 536 529 allowPlayerInput = fHandle->readUint16BE(); 537 530 playerCommand = fHandle->readSint16BE(); … … 542 535 var3 = fHandle->readUint16BE(); 543 536 var2 = fHandle->readUint16BE(); 544 537 commandVar2 = fHandle->readSint16BE(); 545 defaultMenuBoxColor2 = fHandle->readUint16BE();546 538 539 renderer->_messageBg = fHandle->readUint16BE(); 540 547 541 fHandle->readUint16BE(); 548 542 fHandle->readUint16BE(); 549 543 … … 615 609 fHandle->write(currentPrcName, 13); 616 610 fHandle->write(currentRelName, 13); 617 611 fHandle->write(currentMsgName, 13); 618 fHandle->write(currentBgName[0], 13);612 renderer->saveBg(*fHandle); 619 613 fHandle->write(currentCtName, 13); 620 614 621 615 fHandle->writeUint16BE(0xFF); … … 631 625 fHandle->writeUint16BE(objectTable[i].part); 632 626 } 633 627 634 for (i = 0; i < 16; i++) { 635 fHandle->writeUint16BE(c_palette[i]); 636 } 628 renderer->savePalette(*fHandle); 637 629 638 for (i = 0; i < 16; i++) {639 fHandle->writeUint16BE(tempPalette[i]);640 }641 642 630 globalVars.save(*fHandle, NUM_MAX_VAR - 1); 643 631 644 632 for (i = 0; i < 16; i++) { … … 651 639 652 640 fHandle->write(commandBuffer, 0x50); 653 641 654 fHandle->writeUint16BE(defaultMenuBoxColor); 642 fHandle->writeUint16BE(renderer->_cmdY); 643 655 644 fHandle->writeUint16BE(bgVar0); 656 645 fHandle->writeUint16BE(allowPlayerInput); 657 646 fHandle->writeUint16BE(playerCommand); … … 662 651 fHandle->writeUint16BE(var3); 663 652 fHandle->writeUint16BE(var2); 664 653 fHandle->writeUint16BE(commandVar2); 665 fHandle->writeUint16BE(defaultMenuBoxColor2);666 654 655 fHandle->writeUint16BE(renderer->_messageBg); 656 667 657 fHandle->writeUint16BE(0xFF); 668 658 fHandle->writeUint16BE(0x1E); 669 659 … … 864 854 } 865 855 } 866 856 867 int drawChar(byte character, int16 x, int16 y) {868 if (character == ' ') {869 x += 5;870 } else {871 byte characterWidth = fontParamTable[character].characterWidth;872 873 if (characterWidth) {874 byte characterIdx = fontParamTable[character].characterIdx;875 if (g_cine->getGameType() == Cine::GType_OS) {876 drawSpriteRaw2(textTable[characterIdx][0], 0, 2, 8, page1Raw, x, y);877 } else {878 drawSpriteRaw(textTable[characterIdx][0], textTable[characterIdx][1], 2, 8, page1Raw, x, y);879 }880 x += characterWidth + 1;881 }882 }883 884 return x;885 }886 887 857 void drawMessageBox(int16 x, int16 y, int16 width, int16 currentY, int16 offset, int16 color, byte* page) { 888 858 gfxDrawLine(x + offset, y + offset, x + width - offset, y + offset, color, page); // top 889 859 gfxDrawLine(x + offset, currentY + 4 - offset, x + width - offset, currentY + 4 - offset, color, page); // bottom … … 896 866 drawMessageBox(x, y, width, currentY, 0, color, page); 897 867 } 898 868 899 void makeTextEntry(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, uint16 width) {900 byte color = 2;901 byte color2 = defaultMenuBoxColor2;902 int16 paramY = (height * 9) + 10;903 int16 currentX, currentY;904 int16 i;905 uint16 j;906 byte currentChar;907 908 if (X + width > 319) {909 X = 319 - width;910 }911 912 if (Y + paramY > 199) {913 Y = 199 - paramY;914 }915 916 hideMouse();917 blitRawScreen(page1Raw);918 919 gfxDrawPlainBoxRaw(X, Y, X + width, Y + 4, color2, page1Raw);920 921 currentX = X + 4;922 currentY = Y + 4;923 924 for (i = 0; i < height; i++) {925 gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 9, color2, page1Raw);926 currentX = X + 4;927 928 for (j = 0; j < strlen(commandList[i]); j++) {929 currentChar = commandList[i][j];930 currentX = drawChar(currentChar, currentX, currentY);931 }932 933 currentY += 9;934 }935 936 gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 4, color2, page1Raw); // bottom part937 drawDoubleMessageBox(X, Y, width, currentY, color, page1Raw);938 939 blitRawScreen(page1Raw);940 }941 942 869 void processInventory(int16 x, int16 y) { 943 870 int16 listSize = buildObjectListCommand(-2); 944 871 uint16 button; … … 946 873 if (!listSize) 947 874 return; 948 875 949 makeTextEntry(objectListCommand, listSize, x, y, 140); 876 renderer->drawMenu(objectListCommand, listSize, x, y, 140, -1); 877 renderer->blit(); 950 878 951 879 do { 952 880 manageEvents(); … … 1085 1013 } 1086 1014 1087 1015 if (!disableSystemMenu) { 1088 isDrawCommandEnabled = 1;1016 renderer->setCommand(commandBuffer); 1089 1017 } 1090 1018 } 1091 1019 … … 1094 1022 uint16 menuVar4 = 0; 1095 1023 uint16 menuVar5 = 0; 1096 1024 1097 int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, 1098 uint16 width, bool recheckValue) { 1099 byte color = 2; 1100 byte color2 = defaultMenuBoxColor2; 1025 int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, uint16 width, bool recheckValue) { 1101 1026 int16 paramY; 1102 int16 currentX, currentY;1103 int16 i;1104 1027 uint16 button; 1105 1028 int16 var_A; 1106 1029 int16 di; … … 1110 1033 int16 var_14; 1111 1034 int16 currentSelection, oldSelection; 1112 1035 int16 var_4; 1113 byte currentChar;1114 1036 1115 1037 if (disableSystemMenu) 1116 1038 return -1; … … 1125 1047 Y = 199 - paramY; 1126 1048 } 1127 1049 1128 hideMouse();1129 blitRawScreen(page1Raw);1050 renderer->drawMenu(commandList, height, X, Y, width, -1); 1051 renderer->blit(); 1130 1052 1131 gfxDrawPlainBoxRaw(X, Y, X + width, Y + 4, color2, page1Raw);1132 1133 currentX = X + 4;1134 currentY = Y + 4;1135 1136 for (i = 0; i < height; i++) {1137 gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 9, color2, page1Raw);1138 currentX = X + 4;1139 1140 for (j = 0; j < strlen(commandList[i]); j++) {1141 currentChar = commandList[i][j];1142 currentX = drawChar(currentChar, currentX, currentY);1143 }1144 1145 currentY += 9;1146 }1147 1148 gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 4, color2, page1Raw); // bottom part1149 drawDoubleMessageBox(X, Y, width, currentY, color, page1Raw);1150 1151 blitRawScreen(page1Raw);1152 1153 1053 do { 1154 1054 manageEvents(); 1155 1055 getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16); … … 1160 1060 currentSelection = 0; 1161 1061 1162 1062 di = currentSelection * 9 + Y + 4; 1163 gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, 0, page1Raw); // draw black box behind selection1164 currentX = X + 4;1165 1063 1166 for (j = 0; j < strlen(commandList[currentSelection]); j++) { 1167 currentChar = commandList[currentSelection][j]; 1168 currentX = drawChar(currentChar, currentX, di); 1169 } 1064 renderer->drawMenu(commandList, height, X, Y, width, currentSelection); 1065 renderer->blit(); 1170 1066 1171 blitRawScreen(page1Raw);1172 1173 1067 manageEvents(); 1174 1068 getMouseData(mouseUpdateStatus, &button, (uint16 *)&mouseX, (uint16 *)&mouseY); 1175 1069 … … 1219 1113 hideMouse(); 1220 1114 } 1221 1115 1222 di = oldSelection * 9 + Y + 4;1223 1224 gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, color2, page1Raw); // restore color1225 1226 currentX = X + 4;1227 1228 for (j = 0; j < strlen(commandList[oldSelection]); j++) {1229 currentChar = commandList[oldSelection][j];1230 currentX = drawChar(currentChar, currentX, di);1231 }1232 1233 1116 di = currentSelection * 9 + Y + 4; 1234 1117 1235 gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, 0, page1Raw); // black new 1118 renderer->drawMenu(commandList, height, X, Y, width, currentSelection); 1119 renderer->blit(); 1236 1120 1237 currentX = X + 4;1238 1239 for (j = 0; j < strlen(commandList[currentSelection]); j++) {1240 currentChar = commandList[currentSelection][j];1241 currentX = drawChar(currentChar, currentX, di);1242 }1243 1244 blitRawScreen(page1Raw);1245 1246 1121 // if (needMouseSave) { 1247 1122 // gfxRedrawMouseCursor(); 1248 1123 // } … … 1271 1146 return currentSelection; 1272 1147 } 1273 1148 1274 void drawMenuBox(char *command, int16 x, int16 y) {1275 byte j;1276 byte lColor = 2;1277 1278 hideMouse();1279 1280 gfxDrawPlainBoxRaw(x, y, x + 300, y + 10, 0, page2Raw);1281 1282 drawMessageBox(x, y, 300, y + 6, -1, lColor, page2Raw);1283 1284 x += 2;1285 y += 2;1286 1287 for (j = 0; j < strlen(command); j++) {1288 byte currentChar = command[j];1289 1290 if (currentChar == ' ') {1291 x += 5;1292 } else {1293 byte characterWidth = fontParamTable[currentChar].characterWidth;1294 1295 if (characterWidth) {1296 byte characterIdx = fontParamTable[currentChar].characterIdx;1297 drawSpriteRaw(textTable[characterIdx][0], textTable[characterIdx][1], 2, 8, page2Raw, x, y);1298 x += characterWidth + 1;1299 }1300 }1301 }1302 1303 // gfxRedrawMouseCursor();1304 }1305 1306 1149 void makeActionMenu(void) { 1307 1150 uint16 mouseButton; 1308 1151 uint16 mouseX; … … 1342 1185 } 1343 1186 1344 1187 if (allowPlayerInput) { 1345 if (isDrawCommandEnabled) {1346 drawMenuBox(commandBuffer, 10, defaultMenuBoxColor);1347 isDrawCommandEnabled = 0;1348 }1349 1350 1188 getMouseData(mouseUpdateStatus, &mouseButton, &mouseX, &mouseY); 1351 1189 1352 1190 while (mouseButton && currentEntry < 200) { … … 1393 1231 if (choiceResultTable[playerCommand] == commandVar1) { 1394 1232 int16 relEntry; 1395 1233 1396 drawMenuBox(commandBuffer, 10, defaultMenuBoxColor);1397 1234 SelectedObjStruct obj; 1398 1235 obj.idx = commandVar3[0]; 1399 1236 obj.param = commandVar3[1]; … … 1410 1247 1411 1248 commandVar1 = 0; 1412 1249 strcpy(commandBuffer, ""); 1250 renderer->setCommand(""); 1413 1251 } 1414 1252 } else { 1415 1253 globalVars[VAR_MOUSE_X_POS] = mouseX; 1416 1254 globalVars[VAR_MOUSE_Y_POS] = mouseY; 1417 1255 } 1418 1256 } 1257 } else if (mouseButton & 2) { 1258 if (mouseButton & 1) { 1259 g_cine->makeSystemMenu(); 1260 } 1261 1262 makeActionMenu(); 1263 makeCommandLine(); 1419 1264 } else { 1420 if (mouseButton & 2) { 1421 if (mouseButton & 1) { 1422 g_cine->makeSystemMenu(); 1423 } 1265 int16 objIdx; 1424 1266 1425 makeActionMenu(); 1426 makeCommandLine(); 1427 } else { 1428 int16 objIdx; 1267 objIdx = getObjectUnderCursor(mouseX, mouseY); 1429 1268 1430 objIdx = getObjectUnderCursor(mouseX, mouseY); 1269 if (commandVar2 != objIdx) { 1270 if (objIdx != -1) { 1271 char command[256]; 1431 1272 1432 if (commandVar2 != objIdx) {1433 if (objIdx != -1) {1434 char command[256];1273 strcpy(command, commandBuffer); 1274 strcat(command, " "); 1275 strcat(command, objectTable[objIdx].name); 1435 1276 1436 strcpy(command, commandBuffer); 1437 strcat(command, " "); 1438 strcat(command, objectTable[objIdx].name); 1439 1440 drawMenuBox(command, 10, defaultMenuBoxColor); 1441 } else { 1442 isDrawCommandEnabled = 1; 1443 } 1277 renderer->setCommand(command); 1278 } else { 1279 isDrawCommandEnabled = 1; 1444 1280 } 1445 1446 commandVar2 = objIdx;1447 1281 } 1282 1283 commandVar2 = objIdx; 1448 1284 } 1449 1285 } else { 1450 1286 if (mouseButton & 2) { … … 1653 1489 free(msk); 1654 1490 } 1655 1491 1656 int16 additionalBgVScroll = 0; 1657 1658 void backupOverlayPage(void) { 1659 byte *scrollBg; 1660 byte *bgPage = additionalBgTable[currentAdditionalBgIdx]; 1661 1662 if (bgPage) { 1663 if (!additionalBgVScroll) { 1664 memcpy(page1Raw, bgPage, 320 * 200); 1665 } else { 1666 scrollBg = additionalBgTable[currentAdditionalBgIdx2]; 1667 1668 for (int16 i = additionalBgVScroll; i < 200 + additionalBgVScroll; i++) { 1669 if (i > 200) { 1670 memcpy(page1Raw + (i - additionalBgVScroll) * 320, scrollBg + (i - 200) * 320, 320); 1671 } else { 1672 memcpy(page1Raw + (i - additionalBgVScroll) * 320, bgPage + (i-1) * 320, 320); 1673 } 1674 } 1675 } 1676 } 1677 } 1678 1679 void drawMessage(const char *messagePtr, int16 x, int16 y, int16 width, int16 color) { 1680 byte color2 = 2; 1681 byte endOfMessageReached = 0; 1682 int16 localX, localY, localWidth; 1683 uint16 messageLength = 0, numWords = 0, messageWidth = 0; 1684 uint16 lineResult, fullLineWidth; 1685 uint16 interWordSize, interWordSizeRemain; 1686 const char *endOfMessagePtr; 1687 byte currentChar; //, characterWidth; 1688 1689 gfxDrawPlainBoxRaw(x, y, x + width, y + 4, color, page1Raw); 1690 1691 localX = x + 4; 1692 localY = y + 4; 1693 localWidth = width - 8; 1694 1695 do { 1696 messageLength = 0; 1697 1698 while (messagePtr[messageLength] == ' ') { 1699 messageLength++; 1700 } 1701 1702 messagePtr += messageLength; 1703 1704 messageLength = computeMessageLength((const byte *)messagePtr, localWidth, &numWords, &messageWidth, &lineResult); 1705 1706 endOfMessagePtr = messagePtr + messageLength; 1707 1708 if (lineResult) { 1709 fullLineWidth = localWidth - messageWidth; 1710 1711 if (numWords) { 1712 interWordSize = fullLineWidth / numWords; 1713 interWordSizeRemain = fullLineWidth % numWords; 1714 } else { 1715 interWordSize = 5; 1716 interWordSizeRemain = 0; 1717 } 1718 } else { 1719 interWordSize = 5; 1720 interWordSizeRemain = 0; 1721 } 1722 1723 gfxDrawPlainBoxRaw(x, localY, x + width, localY + 9, color, page1Raw); 1724 1725 do { 1726 currentChar = *(messagePtr++); 1727 1728 if (currentChar == 0) { 1729 endOfMessageReached = 1; 1730 } else if (currentChar == ' ') { 1731 localX += interWordSizeRemain + interWordSize; 1732 1733 if (interWordSizeRemain) 1734 interWordSizeRemain = 0; 1735 } else { 1736 localX = drawChar(currentChar, localX, localY); 1737 } 1738 } while ((messagePtr < endOfMessagePtr) && !endOfMessageReached); 1739 1740 localX = x + 4; 1741 localY += 9; 1742 } while (!endOfMessageReached); 1743 1744 gfxDrawPlainBoxRaw(x, localY, x + width, localY + 4, color, page1Raw); 1745 1746 drawDoubleMessageBox(x, y, width, localY, color2, page1Raw); 1747 } 1748 1749 void drawDialogueMessage(byte msgIdx, int16 x, int16 y, int16 width, int16 color) { 1750 if (msgIdx >= messageTable.size()) { 1751 // removeOverlay(msgIdx, 2); 1752 return; 1753 } 1754 1755 _messageLen += messageTable[msgIdx].size(); 1756 drawMessage(messageTable[msgIdx].c_str(), x, y, width, color); 1757 1758 // this invalidates the iterator in drawOverlays() 1759 // removeOverlay(msgIdx, 2); 1760 } 1761 1762 void drawFailureMessage(byte cmd) { 1763 byte msgIdx = cmd * 4 + g_cine->_rnd.getRandomNumber(3); 1764 1765 const char *messagePtr = failureMessages[msgIdx]; 1766 int len = strlen(messagePtr); 1767 1768 _messageLen += len; 1769 1770 int16 width = 6 * len + 20; 1771 1772 if (width > 300) 1773 width = 300; 1774 1775 int16 x = (320 - width) / 2; 1776 int16 y = 80; 1777 int16 color = 4; 1778 1779 drawMessage(messagePtr, x, y, width, color); 1780 1781 // this invalidates the iterator in drawOverlays() 1782 // removeOverlay(cmd, 3); 1783 } 1784 1785 void drawOverlays(void) { 1786 uint16 width, height; 1787 AnimData *pPart; 1788 int16 x, y; 1789 objectStruct *objPtr; 1790 byte messageIdx; 1492 void removeMessages() { 1791 1493 Common::List<overlay>::iterator it; 1792 1494 1793 backupOverlayPage();1794 1795 _messageLen = 0;1796 1797 for (it = overlayList.begin(); it != overlayList.end(); ++it) {1798 switch (it->type) {1799 case 0: // sprite1800 assert(it->objIdx < NUM_MAX_OBJECT);1801 1802 objPtr = &objectTable[it->objIdx];1803 x = objPtr->x;1804 y = objPtr->y;1805 1806 if (objPtr->frame < 0) {1807 continue;1808 }1809 1810 pPart = &animDataTable[objPtr->frame];1811 width = pPart->_realWidth;1812 height = pPart->_height;1813 1814 if (!pPart->data()) {1815 continue;1816 }1817 1818 // drawSprite ignores masks of Operation Stealth sprites1819 drawSprite(it, pPart->data(), pPart->mask(), width, height, page1Raw, x, y);1820 break;1821 1822 case 2: // text1823 // gfxWaitVSync();1824 // hideMouse();1825 1826 messageIdx = it->objIdx;1827 x = it->x;1828 y = it->y;1829 width = it->width;1830 height = it->color;1831 1832 blitRawScreen(page1Raw);1833 1834 drawDialogueMessage(messageIdx, x, y, width, height);1835 1836 // blitScreen(page0, NULL);1837 // gfxRedrawMouseCursor();1838 1839 waitForPlayerClick = 1;1840 1841 break;1842 1843 case 3:1844 // gfxWaitSync()1845 // hideMouse();1846 1847 blitRawScreen(page1Raw);1848 1849 drawFailureMessage(it->objIdx);1850 1851 // blitScreen(page0, NULL);1852 // gfxRedrawMouseCursor();1853 1854 waitForPlayerClick = 1;1855 1856 break;1857 1858 case 4:1859 assert(it->objIdx < NUM_MAX_OBJECT);1860 1861 objPtr = &objectTable[it->objIdx];1862 x = objPtr->x;1863 y = objPtr->y;1864 1865 if (objPtr->frame < 0) {1866 continue;1867 }1868 1869 assert(objPtr->frame < NUM_MAX_ANIMDATA);1870 1871 pPart = &animDataTable[objPtr->frame];1872 1873 width = pPart->_realWidth;1874 height = pPart->_height;1875 1876 if (!pPart->data()) {1877 continue;1878 }1879 1880 gfxFillSprite(pPart->data(), width, height, page1Raw, x, y);1881 break;1882 1883 case 20:1884 assert(it->objIdx < NUM_MAX_OBJECT);1885 1886 objPtr = &objectTable[it->objIdx];1887 x = objPtr->x;1888 y = objPtr->y;1889 var5 = it->x;1890 1891 if (objPtr->frame < 0 || var5 > 8 || !additionalBgTable[var5] || animDataTable[objPtr->frame]._bpp != 1) {1892 continue;1893 }1894 1895 width = animDataTable[objPtr->frame]._realWidth;1896 height = animDataTable[objPtr->frame]._height;1897 1898 if (!animDataTable[objPtr->frame].data()) {1899 continue;1900 }1901 1902 maskBgOverlay(additionalBgTable[var5], animDataTable[objPtr->frame].data(), width, height, page1Raw, x, y);1903 break;1904 }1905 }1906 1907 1495 for (it = overlayList.begin(); it != overlayList.end(); ) { 1908 1496 if (it->type == 2 || it->type == 3) { 1909 1497 it = overlayList.erase(it); … … 1978 1566 tmp.color = param5; 1979 1567 1980 1568 overlayList.push_back(tmp); 1569 waitForPlayerClick = 1; 1981 1570 } 1982 1571 1983 SeqListElementseqList;1572 Common::List<SeqListElement> seqList; 1984 1573 1985 1574 void removeSeq(uint16 param1, uint16 param2, uint16 param3) { 1986 SeqListElement *currentHead = &seqList; 1987 SeqListElement *tempHead = currentHead; 1575 Common::List<SeqListElement>::iterator it; 1988 1576 1989 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { 1990 tempHead = currentHead; 1991 currentHead = tempHead->next; 1577 for (it = seqList.begin(); it != seqList.end(); ++it) { 1578 if (it->objIdx == param1 && it->var4 == param2 && it->varE == param3) { 1579 it->var4 = -1; 1580 break; 1581 } 1992 1582 } 1993 1994 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) {1995 currentHead->var4 = -1;1996 }1997 1583 } 1998 1584 1999 1585 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3) { 2000 SeqListElement *currentHead = &seqList; 2001 SeqListElement *tempHead = currentHead; 1586 Common::List<SeqListElement>::iterator it; 2002 1587 2003 while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { 2004 tempHead = currentHead; 2005 currentHead = tempHead->next; 1588 for (it = seqList.begin(); it != seqList.end(); ++it) { 1589 if (it->objIdx == param1 && it->var4 == param2 && it->varE == param3) { 1590 return 1; 1591 } 2006 1592 } 2007 1593 2008 if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) {2009 return 1;2010 }2011 2012 1594 return 0; 2013 1595 } 2014 1596 2015 void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8) { 2016 SeqListElement *currentHead = &seqList; 2017 SeqListElement *tempHead = currentHead; 2018 SeqListElement *newElement; 1597 void addSeqListElement(uint16 objIdx, int16 param1, int16 param2, int16 frame, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8) { 1598 Common::List<SeqListElement>::iterator it; 1599 SeqListElement tmp; 2019 1600 2020 currentHead = tempHead->next;1601 for (it = seqList.begin(); it != seqList.end() && it->varE < param7; ++it) ; 2021 1602 2022 while (currentHead && currentHead->varE < param7) { 2023 tempHead = currentHead; 2024 currentHead = tempHead->next; 2025 } 1603 tmp.objIdx = objIdx; 1604 tmp.var4 = param1; 1605 tmp.var8 = param2; 1606 tmp.frame = frame; 1607 tmp.varC = param4; 1608 tmp.var14 = 0; 1609 tmp.var16 = 0; 1610 tmp.var18 = param5; 1611 tmp.var1A = param6; 1612 tmp.varE = param7; 1613 tmp.var10 = param8; 1614 tmp.var12 = param8; 1615 tmp.var1C = 0; 1616 tmp.var1E = 0; 2026 1617 2027 newElement = new SeqListElement; 2028 2029 newElement->next = tempHead->next; 2030 tempHead->next = newElement; 2031 2032 newElement->var6 = param0; 2033 newElement->var4 = param1; 2034 newElement->var8 = param2; 2035 newElement->varA = param3; 2036 newElement->varC = param4; 2037 newElement->var14 = 0; 2038 newElement->var16 = 0; 2039 newElement->var18 = param5; 2040 newElement->var1A = param6; 2041 newElement->varE = param7; 2042 newElement->var10 = param8; 2043 newElement->var12 = param8; 2044 newElement->var1C = 0; 2045 newElement->var1E = 0; 1618 seqList.insert(it, tmp); 2046 1619 } 2047 1620 2048 void resetSeqList() { 2049 seqList.next = NULL; 2050 } 2051 2052 void computeMove1(SeqListElement *element, int16 x, int16 y, int16 param1, 1621 void computeMove1(SeqListElement &element, int16 x, int16 y, int16 param1, 2053 1622 int16 param2, int16 x2, int16 y2) { 2054 element ->var16 = 0;2055 element ->var14 = 0;1623 element.var16 = 0; 1624 element.var14 = 0; 2056 1625 2057 1626 if (y2) { 2058 1627 if (y - param2 > y2) { 2059 element ->var16 = 2;1628 element.var16 = 2; 2060 1629 } 2061 1630 2062 1631 if (y + param2 < y2) { 2063 element ->var16 = 1;1632 element.var16 = 1; 2064 1633 } 2065 1634 } 2066 1635 2067 1636 if (x2) { 2068 1637 if (x - param1 > x2) { 2069 element ->var14 = 2;1638 element.var14 = 2; 2070 1639 } 2071 1640 2072 1641 if (x + param1 < x2) { 2073 element ->var14 = 1;1642 element.var14 = 1; 2074 1643 } 2075 1644 } 2076 1645 } 2077 1646 2078 uint16 computeMove2(SeqListElement *element) {1647 uint16 computeMove2(SeqListElement &element) { 2079 1648 int16 returnVar = 0; 2080 1649 2081 if (element ->var16 == 1) {1650 if (element.var16 == 1) { 2082 1651 returnVar = 4; 2083 } else if (element ->var16 == 2) {1652 } else if (element.var16 == 2) { 2084 1653 returnVar = 3; 2085 1654 } 2086 1655 2087 if (element ->var14 == 1) {1656 if (element.var14 == 1) { 2088 1657 returnVar = 1; 2089 } else if (element ->var14 == 2) {1658 } else if (element.var14 == 2) { 2090 1659 returnVar = 2; 2091 1660 } 2092 1661 … … 2165 1734 #endif 2166 1735 } 2167 1736 2168 uint16 addAni(uint16 param1, uint16 param2, const byte *ptr, SeqListElement *element, uint16 param3, int16 *param4) {1737 uint16 addAni(uint16 param1, uint16 objIdx, const byte *ptr, SeqListElement &element, uint16 param3, int16 *param4) { 2169 1738 const byte *currentPtr = ptr; 2170 1739 const byte *ptrData; 2171 1740 const byte *ptr2; 2172 1741 int16 di; 2173 1742 2174 1743 assert(ptr); 2175 assert(element);2176 1744 assert(param4); 2177 1745 2178 1746 dummyU16 = READ_BE_UINT16((currentPtr + param1 * 2) + 8); … … 2181 1749 2182 1750 assert(*ptrData); 2183 1751 2184 di = (objectTable[ param2].costume + 1) % (*ptrData);1752 di = (objectTable[objIdx].costume + 1) % (*ptrData); 2185 1753 ptr2 = (ptrData + (di * 8)) + 1; 2186 1754 2187 if ((checkCollision( param2, ptr2[0], ptr2[1], ptr2[2], ptr[0]) & 1)) {1755 if ((checkCollision(objIdx, ptr2[0], ptr2[1], ptr2[2], ptr[0]) & 1)) { 2188 1756 return 0; 2189 1757 } 2190 1758 2191 objectTable[ param2].x += (int8)ptr2[4];2192 objectTable[ param2].y += (int8)ptr2[5];2193 objectTable[ param2].mask += (int8)ptr2[6];1759 objectTable[objIdx].x += (int8)ptr2[4]; 1760 objectTable[objIdx].y += (int8)ptr2[5]; 1761 objectTable[objIdx].mask += (int8)ptr2[6]; 2194 1762 2195 if (objectTable[ param2].frame) {2196 resetGfxEntityEntry( param2);1763 if (objectTable[objIdx].frame) { 1764 resetGfxEntityEntry(objIdx); 2197 1765 } 2198 1766 2199 objectTable[ param2].frame = ptr2[7] + element->var8;1767 objectTable[objIdx].frame = ptr2[7] + element.var8; 2200 1768 2201 if (param3 || !element ->var14) {2202 objectTable[ param2].costume = di;1769 if (param3 || !element.var14) { 1770 objectTable[objIdx].costume = di; 2203 1771 } else { 2204 1772 *param4 = di; 2205 1773 } … … 2207 1775 return 1; 2208 1776 } 2209 1777 2210 void processSeqListElement(SeqListElement *element) {2211 int16 x = objectTable[element ->var6].x;2212 int16 y = objectTable[element ->var6].y;2213 const byte *ptr1 = animDataTable[element ->varA].data();1778 void processSeqListElement(SeqListElement &element) { 1779 int16 x = objectTable[element.objIdx].x; 1780 int16 y = objectTable[element.objIdx].y; 1781 const byte *ptr1 = animDataTable[element.frame].data(); 2214 1782 int16 var_10; 2215 1783 int16 var_4; 2216 1784 int16 var_2; 2217 1785 2218 if (element ->var12 < element->var10) {2219 element ->var12++;1786 if (element.var12 < element.var10) { 1787 element.var12++; 2220 1788 return; 2221 1789 } 2222 1790 2223 element ->var12 = 0;1791 element.var12 = 0; 2224 1792 2225 1793 if (ptr1) { 2226 1794 uint16 param1 = ptr1[1]; 2227 1795 uint16 param2 = ptr1[2]; 2228 1796 2229 if (element ->varC != 255) {1797 if (element.varC != 255) { 2230 1798 // FIXME: Why is this here? Fingolfin gets lots of these 2231 1799 // in his copy of Operation Stealth (value 0 or 236) under 2232 1800 // Mac OS X. Maybe it's a endian issue? At least the graphics 2233 1801 // in the copy protection screen are partially messed up. 2234 warning("processSeqListElement: varC = %d", element ->varC);1802 warning("processSeqListElement: varC = %d", element.varC); 2235 1803 } 2236 1804 2237 1805 if (globalVars[VAR_MOUSE_X_POS] || globalVars[VAR_MOUSE_Y_POS]) { 2238 1806 computeMove1(element, ptr1[4] + x, ptr1[5] + y, param1, param2, globalVars[VAR_MOUSE_X_POS], globalVars[VAR_MOUSE_Y_POS]); 2239 1807 } else { 2240 element ->var16 = 0;2241 element ->var14 = 0;1808 element.var16 = 0; 1809 element.var14 = 0; 2242 1810 } 2243 1811 2244 1812 var_10 = computeMove2(element); 2245 1813 2246 1814 if (var_10) { 2247 element ->var1C = var_10;2248 element ->var1E = var_10;1815 element.var1C = var_10; 1816 element.var1E = var_10; 2249 1817 } 2250 1818 2251 1819 var_4 = -1; 2252 1820 2253 if ((element ->var16 == 12254 && !addAni(3, element ->var6, ptr1, element, 0, &var_4)) || (element->var16 == 2 && !addAni(2, element->var6, ptr1, element, 0,1821 if ((element.var16 == 1 1822 && !addAni(3, element.objIdx, ptr1, element, 0, &var_4)) || (element.var16 == 2 && !addAni(2, element.objIdx, ptr1, element, 0, 2255 1823 &var_4))) { 2256 if (element ->varC == 255) {1824 if (element.varC == 255) { 2257 1825 globalVars[VAR_MOUSE_Y_POS] = 0; 2258 1826 } 2259 1827 } 2260 1828 2261 if ((element ->var14 == 12262 && !addAni(0, element ->var6, ptr1, element, 1, &var_2))) {2263 if (element ->varC == 255) {1829 if ((element.var14 == 1 1830 && !addAni(0, element.objIdx, ptr1, element, 1, &var_2))) { 1831 if (element.varC == 255) { 2264 1832 globalVars[VAR_MOUSE_X_POS] = 0; 2265 1833 2266 1834 if (var_4 != -1) { 2267 objectTable[element ->var6].costume = var_4;1835 objectTable[element.objIdx].costume = var_4; 2268 1836 } 2269 1837 } 2270 1838 } 2271 1839 2272 if ((element ->var14 == 2 && !addAni(1, element->var6, ptr1, element, 1, &var_2))) {2273 if (element ->varC == 255) {1840 if ((element.var14 == 2 && !addAni(1, element.objIdx, ptr1, element, 1, &var_2))) { 1841 if (element.varC == 255) { 2274 1842 globalVars[VAR_MOUSE_X_POS] = 0; 2275 1843 2276 1844 if (var_4 != -1) { 2277 objectTable[element ->var6].costume = var_4;1845 objectTable[element.objIdx].costume = var_4; 2278 1846 } 2279 1847 } 2280 1848 } 2281 1849 2282 if (element ->var16 + element->var14) {2283 if (element ->var1C) {2284 if (element ->var1E) {2285 objectTable[element ->var6].costume = 0;2286 element ->var1E = 0;1850 if (element.var16 + element.var14) { 1851 if (element.var1C) { 1852 if (element.var1E) { 1853 objectTable[element.objIdx].costume = 0; 1854 element.var1E = 0; 2287 1855 } 2288 1856 2289 addAni(element ->var1C + 3, element->var6, ptr1, element, 1, (int16 *) & var2);1857 addAni(element.var1C + 3, element.objIdx, ptr1, element, 1, (int16 *) & var2); 2290 1858 2291 1859 } 2292 1860 } … … 2295 1863 } 2296 1864 2297 1865 void processSeqList(void) { 2298 SeqListElement *currentHead = &seqList; 2299 SeqListElement *tempHead = currentHead; 1866 Common::List<SeqListElement>::iterator it; 2300 1867 2301 currentHead = tempHead->next; 2302 2303 while (currentHead) { 2304 if (currentHead->var4 != -1) { 2305 processSeqListElement(currentHead); 1868 for (it = seqList.begin(); it != seqList.end(); ++it) { 1869 if (it->var4 == -1) { 1870 continue; 2306 1871 } 2307 1872 2308 tempHead = currentHead; 2309 currentHead = tempHead->next; 1873 processSeqListElement(*it); 2310 1874 } 2311 1875 } 2312 1876 2313 1877 2314 1878 bool makeTextEntryMenu(const char *messagePtr, char *inputString, int stringMaxLength, int y) { 2315 int16 color = 2;2316 byte color2 = defaultMenuBoxColor2;2317 byte endOfMessageReached = 0;2318 int16 localX, localY, localWidth;2319 int margins = 16;2320 1879 int len = strlen(messagePtr); 2321 1880 int16 width = 6 * len + 20; 2322 uint16 messageLength = 0, numWords = 0, messageWidth = 0;2323 uint16 lineResult, fullLineWidth;2324 uint16 interWordSize, interWordSizeRemain;2325 const char *endOfMessagePtr;2326 byte currentChar, characterWidth;2327 1881 2328 1882 width = CLIP((int)width, 180, 250); 2329 1883 2330 1884 int16 x = (320 - width) / 2; 2331 1885 2332 gfxDrawPlainBoxRaw(x - margins, y, x + width + margins, y + 4, color2, page1Raw);2333 2334 localX = x + 4;2335 localY = y + 4;2336 localWidth = width;2337 2338 1886 getKeyData(); // clear input key 2339 1887 2340 do {2341 messageLength = 0;2342 2343 while (messagePtr[messageLength] == ' ') {2344 messageLength++;2345 }2346 2347 messagePtr += messageLength;2348 2349 messageLength = computeMessageLength((const byte *)messagePtr, localWidth, &numWords, &messageWidth, &lineResult);2350 2351 endOfMessagePtr = messagePtr + messageLength;2352 2353 if (lineResult) {2354 fullLineWidth = localWidth - messageWidth;2355 2356 if (numWords) {2357 interWordSize = fullLineWidth / numWords;2358 interWordSizeRemain = fullLineWidth % numWords;2359 } else {2360 interWordSize = 5;2361 interWordSizeRemain = 0;2362 }2363 } else {2364 interWordSize = 5;2365 interWordSizeRemain = 0;2366 }2367 2368 gfxDrawPlainBoxRaw(x - margins, localY, x + width + margins, localY + 9, color2, page1Raw);2369 2370 do {2371 currentChar = *(messagePtr++);2372 2373 if (currentChar == 0) {2374 endOfMessageReached = 1;2375 } else if (currentChar == ' ') {2376 localX += interWordSizeRemain + interWordSize;2377 2378 if (interWordSizeRemain)2379 interWordSizeRemain = 0;2380 } else {2381 characterWidth = fontParamTable[currentChar].characterWidth;2382 2383 if (characterWidth) {2384 byte characterIdx = fontParamTable[currentChar].characterIdx;2385 drawSpriteRaw(textTable[characterIdx][0], textTable[characterIdx][1], 2, 8, page1Raw, localX, localY);2386 localX += characterWidth + 1;2387 }2388 }2389 } while ((messagePtr < endOfMessagePtr) && !endOfMessageReached);2390 2391 localX = x + 4;2392 localY += 9;2393 } while (!endOfMessageReached);2394 2395 // Input string2396 gfxDrawPlainBoxRaw(x - margins, localY, x + width + margins, localY + 9, color2, page1Raw);2397 localY += 9;2398 2399 x -= margins;2400 width += margins * 2;2401 2402 gfxDrawPlainBoxRaw(x, localY, x + width, localY + 4, color2, page1Raw);2403 2404 drawDoubleMessageBox(x, y, width, localY, color, page1Raw);2405 2406 x += margins;2407 width -= margins * 2;2408 localY -= 9;2409 2410 2411 1888 int quit = 0; 2412 1889 bool redraw = true; 2413 1890 CommandeType tempString; … … 2416 1893 2417 1894 while (!quit) { 2418 1895 if (redraw) { 2419 gfxDrawPlainBoxRaw(x, localY - 1, x + width, localY + 8, 0, page1Raw); 2420 2421 int currentX = x + 4; 2422 2423 for (uint j = 0; j < strlen(inputString); j++) { 2424 currentChar = inputString[j]; 2425 currentX = drawChar(currentChar, currentX, localY); 2426 2427 // draw cursor here 2428 if (inputPos == (int)(j + 2)) 2429 gfxDrawLine(currentX, localY - 1, currentX, localY + 8, color, page1Raw); 2430 2431 } 2432 2433 if (strlen(inputString) == 0 || inputPos == 1) // cursor wasn't yet drawn 2434 gfxDrawLine(x + 4, localY - 1, x + 4, localY + 8, color, page1Raw); 2435 2436 blitRawScreen(page1Raw); 1896 renderer->drawInputBox(messagePtr, inputString, inputPos, x - 16, y, width + 32); 1897 renderer->blit(); 2437 1898 redraw = false; 2438 1899 } 2439 1900 -
engines/cine/gfx.h
26 26 #ifndef CINE_GFX_H 27 27 #define CINE_GFX_H 28 28 29 #include "common/noncopyable.h" 30 #include "cine/object.h" 31 29 32 namespace Cine { 30 33 34 /*! \brief Background with palette 35 */ 36 struct palBg { 37 byte *bg; ///< Background data 38 byte *hiPal; ///< 256 color palette 39 uint16 *lowPal; ///< 16 color palette 40 char name[15]; ///< Background filename 41 }; 42 43 /*! \brief Future Wars renderer 44 * 45 * Screen backbuffer is not cleared between frames, you can draw menus etc. 46 * without calling drawFrame() all the time 47 */ 48 class FWRenderer : public Common::NonCopyable { 49 private: 50 byte *_background; ///< Current background 51 char _bgName[13]; ///< Background filename 52 uint16 *_palette; ///< 16 color backup palette 53 54 Common::String _cmd; ///< Player command string 55 56 protected: 57 static const int _screenSize = 320 * 200; ///< Screen size 58 static const int _screenWidth = 320; ///< Screen width 59 static const int _screenHeight = 200; ///< Screen height 60 static const int _lowPalSize = 16; ///< 16 color palette size 61 62 byte *_backBuffer; ///< Screen backbuffer 63 uint16 *_activeLowPal; ///< Active 16 color palette 64 int _changePal; ///< Load active palette to video backend on next frame 65 66 void fillSprite(const objectStruct &obj, uint8 color = 0); 67 void drawMaskedSprite(const objectStruct &obj, const byte *mask); 68 virtual void drawSprite(const objectStruct &obj); 69 70 void drawCommand(); 71 void drawMessage(const char *str, int x, int y, int width, byte color); 72 void drawPlainBox(int x, int y, int width, int height, byte color); 73 void drawBorder(int x, int y, int width, int height, byte color); 74 void drawDoubleBorder(int x, int y, int width, int height, byte color); 75 virtual int drawChar(char character, int x, int y); 76 void drawLine(int x, int y, int width, int height, byte color); 77 void remaskSprite(byte *mask, Common::List<overlay>::iterator it); 78 virtual void drawBackground(); 79 80 virtual void renderOverlay(const Common::List<overlay>::iterator &it); 81 void drawOverlays(); 82 83 public: 84 uint16 _messageBg; ///< Message box background color 85 uint16 _cmdY; ///< Player command string position on screen 86 87 FWRenderer(); 88 virtual ~FWRenderer(); 89 90 /*! \brief Test if renderer is ready to draw */ 91 virtual bool ready() { return _background != NULL; } 92 93 virtual void clear(); 94 95 void drawFrame(); 96 void blit(); 97 void setCommand(const char *cmd); 98 99 virtual void incrustMask(const objectStruct &obj, uint8 color = 0); 100 virtual void incrustSprite(const objectStruct &obj); 101 102 virtual void loadBg16(const byte *bg, const char *name); 103 virtual void loadBg16(const byte *bg, const char *name, unsigned int idx); 104 virtual void loadCt16(const byte *ct, const char *name); 105 virtual void loadBg256(const byte *bg, const char *name); 106 virtual void loadBg256(const byte *bg, const char *name, unsigned int idx); 107 virtual void loadCt256(const byte *ct, const char *name); 108 virtual void selectBg(unsigned int idx); 109 virtual void selectScrollBg(unsigned int idx); 110 virtual void setScroll(unsigned int shift); 111 virtual void removeBg(unsigned int idx); 112 void saveBg(Common::OutSaveFile &fHandle); 113 114 virtual void refreshPalette(); 115 virtual void reloadPalette(); 116 void restorePalette(Common::InSaveFile &fHandle); 117 void savePalette(Common::OutSaveFile &fHandle); 118 virtual void rotatePalette(int a, int b, int c); 119 virtual void transformPalette(int first, int last, int r, int g, int b); 120 121 void drawMenu(const CommandeType *items, unsigned int height, int x, int y, int width, int selected); 122 void drawInputBox(const char *info, const char *input, int cursor, int x, int y, int width); 123 124 virtual void fadeToBlack(); 125 }; 126 127 /*! \brief Operation Stealth renderer 128 */ 129 class OSRenderer : public FWRenderer { 130 private: 131 palBg _bgTable[9]; ///< Table of backgrounds loaded into renderer 132 byte *_activeHiPal; ///< Active 256 color palette 133 unsigned int _currentBg; ///< Current background 134 unsigned int _scrollBg; ///< Current scroll background 135 unsigned int _bgShift; ///< Background shift 136 137 protected: 138 static const int _hiPalSize = 256 * 3; ///< 256 color palette size 139 140 void drawSprite(const objectStruct &obj); 141 int drawChar(char character, int x, int y); 142 void drawBackground(); 143 void renderOverlay(const Common::List<overlay>::iterator &it); 144 145 public: 146 OSRenderer(); 147 ~OSRenderer(); 148 149 /*! \brief Test if renderer is ready to draw */ 150 bool ready() { return _bgTable[_currentBg].bg != NULL; } 151 152 void clear(); 153 154 void incrustMask(const objectStruct &obj, uint8 color = 0); 155 void incrustSprite(const objectStruct &obj); 156 157 void loadBg16(const byte *bg, const char *name); 158 void loadBg16(const byte *bg, const char *name, unsigned int idx); 159 void loadCt16(const byte *ct, const char *name); 160 void loadBg256(const byte *bg, const char *name); 161 void loadBg256(const byte *bg, const char *name, unsigned int idx); 162 void loadCt256(const byte *ct, const char *name); 163 void selectBg(unsigned int idx); 164 void selectScrollBg(unsigned int idx); 165 void setScroll(unsigned int shift); 166 void removeBg(unsigned int idx); 167 168 void refreshPalette(); 169 void reloadPalette(); 170 void rotatePalette(int a, int b, int c); 171 void transformPalette(int first, int last, int r, int g, int b); 172 173 void fadeToBlack(); 174 }; 175 31 176 void gfxDrawSprite(byte *src4, uint16 sw, uint16 sh, byte *dst4, int16 sx, int16 sy); 32 177 33 extern byte *page1Raw;34 extern byte *page2Raw;35 178 extern byte *page3Raw; 179 extern FWRenderer *renderer; 36 180 37 extern uint16 c_palette[256];38 extern byte colorMode256;39 extern byte palette256[256 * 3];40 extern byte newPalette[256 * 3];41 extern byte newColorMode;42 extern byte ctColorMode;43 extern byte bgColorMode;44 45 void gfxInit();46 void gfxDestroy();47 181 void setMouseCursor(int cursor); 48 182 void gfxCopyPage(byte *source, byte *dest); 49 183 -
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 };36 37 30 byte loadBg(const char *bgName); 38 byte loadCt(const char *bgName); 31 byte loadCtFW(const char *bgName); 32 byte loadCtOS(const char *bgName); 39 33 40 //extern bgData additionalBgTable[9];41 extern byte *additionalBgTable[9];42 extern byte currentAdditionalBgIdx;43 extern byte currentAdditionalBgIdx2;44 45 34 void addBackground(const char *bgName, uint16 bgIdx); 46 35 47 36 extern uint16 bgVar0; -
engines/cine/texte.h
56 56 void loadPoldatDat(const char *fname); 57 57 void freePoldatDat(void); 58 58 59 uint16 computeMessageLength(const byte *ptr, uint16 width, uint16 *numWords, uint16 *messageWidth, uint16 *lineResult);59 int fitLine(const char *ptr, int maxWidth, int &words, int &width); 60 60 61 61 } // End of namespace Cine 62 62 -
engines/cine/xref.txt
1 script .cpp:1 script_fw.cpp: 2 2 setupOpcodes() - replaced with FWScript/OSScript class members 3 3 getNextByte() - replaced with RawScript/FWScript class members 4 4 getNextWord() - replaced with RawScript/FWScript class members … … 89 89 o1_loadMask5() - replaced with FWScript::o1_loadMask5() 90 90 o1_unloadMask5() - replaced with FWScript::o1_unloadMask5() 91 91 92 palRotate() - modified and moved to pal.cpp 93 94 script_os.cpp: 92 95 o2_loadPart() - replaced with FWScript::o2_loadPart() 93 96 o2_addSeqListElement() - replaced with FWScript::o2_addSeqListElement() 94 97 o2_removeSeq() - replaced with FWScript::o2_removeSeq() … … 134 137 various.cpp: 135 138 setupScriptList() - removed (obsoleted by new makeLoad() and 136 139 loadScriptFromSave() implementation) 140 drawChar() - removed (obsoleted by FWRenderer::drawChar()) 141 makeTextEntry() - removed (obsoleted by FWRenderer::drawMenu()) 142 drawMenuBox() - removed (obsoleted by FWRenderer::drawCommand()) 143 backupOverlayPage() - removed (obsoleted by FWRenderer::drawBackground()) 144 drawMessage() - removed (obsoleted by FWRenderer::drawMessage()) 145 drawDialogueMessage() - removed (obsoleted by FWRenderer::renderOverlay()) 146 drawFailureMessage() - removed (obsoleted by FWRenderer::renderOverlay()) 147 drawOverlays() - removed (obsoleted by FWRenderer::drawOverlays()) 148 resetSeqList() - removed (obsoleted by Common::List) 137 149 138 150 anim.cpp: 139 151 freeAnimData() - replaced with animData::clear() 140 152 allocFrame() - replaced with animData::load() 141 153 reserveFrame() - replaced with animData::load() 142 154 143 bg_list.cpp 155 bg_list.cpp: 144 156 reincrustAllBg() - removed (obsoleted by new loadResourcesFromSave() and 145 157 loadBgIncrustFromSave() implementation) 146 158 freeBgIncrustList() - removed (obsoleted by Common::List::clear()) 147 159 148 object.cpp 160 object.cpp: 149 161 unloadAllMasks() - removed (obsoleted by Common::List::clear()) 150 162 resetMessageHead() - removed (obsoleted by Common::List) 151 163 freeOverlay() - removed (duplicate of removeOverlay) 152 164 removeOverlayElement() - renamed to removeOverlay 153 165 loadOverlayElement() - renamed to addOverlay 166 167 gfx.cpp: 168 gfxInit() - removed (obsoleted by FWRenderer) 169 gfxDestroy() - removed (obsoleted by FWRenderer) 170 transformColor() - moved to pal.cpp 171 transformPaletteRange() - modified and moved to pal.cpp 172 gfxCopyRawPage() - removed (obsoleted by FWRenderer) 173 gfxFlipRawPage() - removed (obsoleted by FWRenderer::blit() and 174 FWRenderer::refreshPalette()) 175 fadeToBlack() - removed (obsoleted by FWRenderer::fadeToBlack()) 176 blitRawScreen() - removed (obsoleted by FWRenderer) 177 flip() - removed (obsoleted by FWRenderer::reloadPalette()) 178 179 bg.cpp: 180 loadCt() - split into loadCtFW() and loadCtOS() 181 loadBgHigh() - removed (obsoleted by OSRenderer::loadBg256()) 182 183 texte.cpp: 184 computeMessageLength() - replaced with fitLine() -
engines/cine/script_os.cpp
116 116 { &FWScript::o1_loadAnim, "s" }, 117 117 /* 3C */ 118 118 { &FWScript::o1_loadBg, "s" }, 119 { &FWScript::o 1_loadCt, "s" },119 { &FWScript::o2_loadCt, "s" }, 120 120 { 0, 0 }, 121 121 { &FWScript::o2_loadPart, "s" }, 122 122 /* 40 */ … … 365 365 // OPERATION STEALTH opcodes 366 366 // ------------------------------------------------------------------------ 367 367 368 int FWScript::o2_loadCt() { 369 const char *param = getNextString(); 370 371 debugC(5, kCineDebugScript, "Line: %d: loadCt(\"%s\")", _line, param); 372 loadCtOS(param); 373 return 0; 374 } 375 368 376 int FWScript::o2_loadPart() { 369 377 const char *param = getNextString(); 370 378 … … 615 623 616 624 debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _line, param); 617 625 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], ""); 626 renderer->removeBg(param); 632 627 return 0; 633 628 } 634 629 … … 644 639 int FWScript::o2_loadBg() { 645 640 byte param = getNextByte(); 646 641 647 assert(param < = 8);642 assert(param < 9); 648 643 649 644 debugC(5, kCineDebugScript, "Line: %d: useBg(%d)", _line, param); 650 645 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 } 646 renderer->selectBg(param); 663 647 return 0; 664 648 } 665 649 … … 699 683 int FWScript::o2_useBgScroll() { 700 684 byte param = getNextByte(); 701 685 702 assert(param < = 8);686 assert(param < 9); 703 687 704 688 debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _line, param); 705 689 706 if (additionalBgTable[param]) { 707 currentAdditionalBgIdx2 = param; 708 } 690 renderer->selectScrollBg(param); 709 691 return 0; 710 692 } 711 693 … … 716 698 byte param2 = getNextByte(); 717 699 718 700 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _line, param2); 719 additionalBgVScroll = _localVars[param2];701 renderer->setScroll(_localVars[param2]); 720 702 } else { 721 703 uint16 param2 = getNextWord(); 722 704 723 705 debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _line, param2); 724 additionalBgVScroll = param2;706 renderer->setScroll(param2); 725 707 } 726 708 return 0; 727 709 } -
engines/cine/object.cpp
236 236 return compareResult; 237 237 } 238 238 239 /*! \bug In Operation Stealth, if you try to go downstairs to the sea in the 240 * location between bank and hotel, getObjectParam is called with paramIdx 16 241 * and crashes 242 */ 239 243 int16 getObjectParam(uint16 objIdx, uint16 paramIdx) { 240 244 assert(objIdx <= NUM_MAX_OBJECT); 241 245 -
engines/cine/main_loop.cpp
182 182 void CineEngine::mainLoop(int bootScriptIdx) { 183 183 bool playerAction; 184 184 uint16 quitFlag; 185 uint16 i;186 185 byte di; 187 186 uint16 mouseButton; 188 187 189 188 quitFlag = 0; 190 189 191 190 if (_preLoad == false) { 192 resetSeqList();193 191 resetBgIncrustList(); 194 192 195 193 setTextWindow(0, 0, 20, 200); … … 223 221 globalVars[VAR_LOW_MEMORY] = 0; // set to 1 to disable some animations, sounds etc. 224 222 } 225 223 226 for (i = 0; i < 16; i++) {227 c_palette[i] = 0;228 }229 230 _paletteNeedUpdate = true;231 232 224 strcpy(newPrcName, ""); 233 225 strcpy(newRelName, ""); 234 226 strcpy(newObjectName, ""); 235 227 strcpy(newMsgName, ""); 236 strcpy(currentBgName[0], "");237 228 strcpy(currentCtName, ""); 238 229 strcpy(currentPartName, ""); 239 230 … … 257 248 setMouseCursor(MOUSE_CURSOR_CROSS); 258 249 } 259 250 260 drawOverlays(); 261 flip(); 251 if (renderer->ready()) { 252 renderer->drawFrame(); 253 } 262 254 263 255 if (waitForPlayerClick) { 264 256 playerAction = false; … … 289 281 } while (mouseButton != 0); 290 282 291 283 waitForPlayerClick = 0; 284 285 removeMessages(); 292 286 } 293 287 294 288 if (checkForPendingDataLoadSwitch) { -
engines/cine/cine.cpp
95 95 int CineEngine::go() { 96 96 CursorMan.showMouse(true); 97 97 mainLoop(1); 98 gfxDestroy(); 98 99 delete renderer; 100 delete[] page3Raw; 99 101 delete g_sound; 100 102 return 0; 101 103 } … … 105 107 setupOpcodes(); 106 108 107 109 initLanguage(g_cine->getLanguage()); 108 gfxInit();109 110 111 if (g_cine->getGameType() == Cine::GType_OS) { 112 renderer = new OSRenderer; 113 } else { 114 renderer = new FWRenderer; 115 } 116 117 page3Raw = new byte[320 * 200]; 110 118 textDataPtr = (byte *)malloc(8000); 111 119 112 120 partBuffer = (PartBuffer *)malloc(NUM_MAX_PARTDATA * sizeof(PartBuffer)); -
engines/cine/pal.h
36 36 37 37 void loadPal(const char *fileName); 38 38 39 extern uint16 tempPalette[256];40 41 39 void loadRelatedPalette(const char *fileName); 42 40 41 void palRotate(uint16 *pal, byte a, byte b, byte c); 42 void palRotate(byte *pal, byte a, byte b, byte c); 43 uint16 transformColor(uint16 baseColor, int r, int g, int b); 44 void transformPaletteRange(uint16 *srcPal, uint16 *dstPal, int startColor, int stopColor, int r, int g, int b); 45 void transformPaletteRange(byte *srcPal, byte *dstPal, int startColor, int stopColor, int r, int g, int b); 46 43 47 } // End of namespace Cine 44 48 45 49 #endif -
engines/cine/gfx.cpp
27 27 #include "cine/bg.h" 28 28 #include "cine/bg_list.h" 29 29 #include "cine/various.h" 30 #include "cine/pal.h" 30 31 31 32 #include "common/endian.h" 32 33 #include "common/system.h" … … 35 36 36 37 namespace Cine { 37 38 38 uint16 c_palette[256];39 byte colorMode256 = 0;40 byte palette256[256 * 3];41 byte newPalette[256 * 3];42 byte newColorMode = 0;43 byte ctColorMode = 0;44 byte bgColorMode = 0;45 46 byte *screenBuffer;47 byte *page1Raw;48 byte *page2Raw;49 39 byte *page3Raw; 40 FWRenderer *renderer = NULL; 50 41 51 42 static const byte mouseCursorNormal[] = { 52 43 0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, … … 96 87 0xff, 0xff, 0xff, 0xff 97 88 }; 98 89 99 void gfxInit() { 100 screenBuffer = (byte *)malloc(320 * 200); 101 page1Raw = (byte *)malloc(320 * 200); 102 page2Raw = (byte *)malloc(320 * 200); 103 page3Raw = (byte *)malloc(320 * 200); 104 if (!screenBuffer || !page1Raw || !page2Raw || !page3Raw) { 105 error("Unable to allocate offscreen buffers"); 90 /*! \brief Initialize renderer 91 */ 92 FWRenderer::FWRenderer() : _background(NULL), _palette(NULL), _cmd(""), 93 _cmdY(0), _messageBg(0), _backBuffer(new byte[_screenSize]), 94 _activeLowPal(NULL), _changePal(0) { 95 96 assert(_backBuffer); 97 98 memset(_backBuffer, 0, _screenSize); 99 memset(_bgName, 0, sizeof (_bgName)); 100 } 101 102 /* \brief Destroy renderer 103 */ 104 FWRenderer::~FWRenderer() { 105 delete[] _background; 106 delete[] _palette; 107 delete[] _backBuffer; 108 delete[] _activeLowPal; 109 } 110 111 /* \brief Reset renderer state 112 */ 113 void FWRenderer::clear() { 114 delete[] _background; 115 delete[] _palette; 116 delete[] _activeLowPal; 117 118 _background = NULL; 119 _palette = NULL; 120 _activeLowPal = NULL; 121 122 memset(_backBuffer, 0, _screenSize); 123 124 _cmd = ""; 125 _cmdY = 0; 126 _messageBg = 0; 127 _changePal = 0; 128 } 129 130 /*! \brief Draw 1bpp sprite using selected color 131 * \param obj Object info 132 * \param fillColor Sprite color 133 */ 134 void FWRenderer::fillSprite(const objectStruct &obj, uint8 color) { 135 const byte *data = animDataTable[obj.frame].data(); 136 int x, y, width, height; 137 138 x = obj.x; 139 y = obj.y; 140 width = animDataTable[obj.frame]._realWidth; 141 height = animDataTable[obj.frame]._height; 142 143 gfxFillSprite(data, width, height, _backBuffer, x, y, color); 144 } 145 146 /*! \brief Draw 1bpp sprite using selected color on background 147 * \param obj Object info 148 * \param fillColor Sprite color 149 */ 150 void FWRenderer::incrustMask(const objectStruct &obj, uint8 color) { 151 const byte *data = animDataTable[obj.frame].data(); 152 int x, y, width, height; 153 154 x = obj.x; 155 y = obj.y; 156 width = animDataTable[obj.frame]._realWidth; 157 height = animDataTable[obj.frame]._height; 158 159 gfxFillSprite(data, width, height, _background, x, y, color); 160 } 161 162 /*! \brief Draw color sprite using with external mask 163 * \param obj Object info 164 * \param mask External mask 165 */ 166 void FWRenderer::drawMaskedSprite(const objectStruct &obj, const byte *mask) { 167 const byte *data = animDataTable[obj.frame].data(); 168 int x, y, width, height; 169 170 x = obj.x; 171 y = obj.y; 172 width = animDataTable[obj.frame]._realWidth; 173 height = animDataTable[obj.frame]._height; 174 175 assert(mask); 176 177 drawSpriteRaw(data, mask, width, height, _backBuffer, x, y); 178 } 179 180 /*! \brief Draw color sprite 181 * \param obj Object info 182 */ 183 void FWRenderer::drawSprite(const objectStruct &obj) { 184 const byte *mask = animDataTable[obj.frame].mask(); 185 drawMaskedSprite(obj, mask); 186 } 187 188 /*! \brief Draw color sprite on background 189 * \param obj Object info 190 */ 191 void FWRenderer::incrustSprite(const objectStruct &obj) { 192 const byte *data = animDataTable[obj.frame].data(); 193 const byte *mask = animDataTable[obj.frame].mask(); 194 int x, y, width, height; 195 196 x = obj.x; 197 y = obj.y; 198 width = animDataTable[obj.frame]._realWidth; 199 height = animDataTable[obj.frame]._height; 200 201 assert(mask); 202 203 drawSpriteRaw(data, mask, width, height, _background, x, y); 204 } 205 206 /*! \brief Draw command box on screen 207 */ 208 void FWRenderer::drawCommand() { 209 unsigned int i; 210 int x = 10, y = _cmdY; 211 212 drawPlainBox(x, y, 301, 11, 0); 213 drawBorder(x - 1, y - 1, 302, 12, 2); 214 215 x += 2; 216 y += 2; 217 218 for (i = 0; i < _cmd.size(); i++) { 219 x = drawChar(_cmd[i], x, y); 106 220 } 107 memset(page1Raw, 0, 320 * 200); 108 memset(page2Raw, 0, 320 * 200); 109 memset(page3Raw, 0, 320 * 200); 221 } 110 222 111 memset(additionalBgTable, 0, sizeof(additionalBgTable)); 112 additionalBgTable[0] = page2Raw; 113 additionalBgTable[8] = page3Raw; 223 /*! \brief Draw message in a box 224 * \param str Message to draw 225 * \param x Top left message box corner coordinate 226 * \param y Top left message box corner coordinate 227 * \param width Message box width 228 * \param color Message box background color 229 */ 230 void FWRenderer::drawMessage(const char *str, int x, int y, int width, byte color) { 231 int i, tx, ty, tw; 232 int line = 0, words = 0, cw = 0; 233 int space = 0, extraSpace = 0; 234 235 drawPlainBox(x, y, width, 4, color); 236 tx = x + 4; 237 ty = str[0] ? y - 5 : y + 4; 238 tw = width - 8; 239 240 for (i = 0; str[i]; i++, line--) { 241 // Fit line of text into textbox 242 if (!line) { 243 while (str[i] == ' ') i++; 244 line = fitLine(str + i, tw, words, cw); 245 246 if ( str[i + line] != '\0' && str[i + line] != 0x7C && words) { 247 space = (tw - cw) / words; 248 extraSpace = (tw - cw) % words; 249 } else { 250 space = 5; 251 extraSpace = 0; 252 } 253 254 ty += 9; 255 drawPlainBox(x, ty, width, 9, color); 256 tx = x + 4; 257 } 258 259 // draw characters 260 if (str[i] == ' ') { 261 tx += space + extraSpace; 262 263 if (extraSpace) { 264 extraSpace = 0; 265 } 266 } else { 267 tx = drawChar(str[i], tx, ty); 268 } 269 } 270 271 ty += 9; 272 drawPlainBox(x, ty, width, 4, color); 273 drawDoubleBorder(x, y, width, ty - y + 4, 2); 114 274 } 115 275 116 void gfxDestroy() { 117 free(screenBuffer); 118 free(page1Raw); 119 free(page2Raw); 120 free(page3Raw); 276 /*! \brief Draw rectangle on screen 277 * \param x Top left corner coordinate 278 * \param y Top left corner coordinate 279 * \param width Rectangle width 280 * \param height Rectangle height 281 * \param color Fill color 282 */ 283 void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) { 284 int i; 285 byte *dest = _backBuffer + y * 320 + x; 286 287 if (width < 0) { 288 x += width; 289 width = -width; 290 } 291 292 if (height < 0) { 293 y += height; 294 height = -height; 295 } 296 297 for (i = 0; i < height; i++) { 298 memset(dest + i * 320, color, width); 299 } 121 300 } 122 301 302 /*! \brief Draw empty rectangle 303 * \param x Top left corner coordinate 304 * \param y Top left corner coordinate 305 * \param width Rectangle width 306 * \param height Rectangle height 307 * \param color Line color 308 */ 309 void FWRenderer::drawBorder(int x, int y, int width, int height, byte color) { 310 drawLine(x, y, width, 1, color); 311 drawLine(x, y + height, width, 1, color); 312 drawLine(x, y, 1, height, color); 313 drawLine(x + width, y, 1, height + 1, color); 314 } 315 316 /*! \brief Draw empty 2 color rectangle (inner line color is black) 317 * \param x Top left corner coordinate 318 * \param y Top left corner coordinate 319 * \param width Rectangle width 320 * \param height Rectangle height 321 * \param color Outter line color 322 */ 323 void FWRenderer::drawDoubleBorder(int x, int y, int width, int height, byte color) { 324 drawBorder(x + 1, y + 1, width - 2, height - 2, 0); 325 drawBorder(x, y, width, height, color); 326 } 327 328 /*! \brief Draw text character on screen 329 * \param character Character to draw 330 * \param x Character coordinate 331 * \param y Character coordinate 332 */ 333 int FWRenderer::drawChar(char character, int x, int y) { 334 int width, idx; 335 336 if (character == ' ') { 337 x += 5; 338 } else if ((width = fontParamTable[character].characterWidth)) { 339 idx = fontParamTable[character].characterIdx; 340 drawSpriteRaw(textTable[idx][0], textTable[idx][1], 16, 8, _backBuffer, x, y); 341 x += width + 1; 342 } 343 344 return x; 345 } 346 347 /*! \brief Draw Line 348 * \param x Line end coordinate 349 * \param y Line end coordinate 350 * \param width Horizontal line length 351 * \param height Vertical line length 352 * \param color Line color 353 * \note Either width or height must be equal to 1 354 */ 355 void FWRenderer::drawLine(int x, int y, int width, int height, byte color) { 356 // this line is a special case of rectangle ;-) 357 drawPlainBox(x, y, width, height, color); 358 } 359 360 /*! \brief Hide invisible parts of the sprite 361 * \param[in,out] mask Mask to be updated 362 * \param it Overlay info from overlayList 363 */ 364 void FWRenderer::remaskSprite(byte *mask, Common::List<overlay>::iterator it) { 365 AnimData &sprite = animDataTable[objectTable[it->objIdx].frame]; 366 int x, y, width, height, idx; 367 int mx, my, mw, mh; 368 369 x = objectTable[it->objIdx].x; 370 y = objectTable[it->objIdx].y; 371 width = sprite._realWidth; 372 height = sprite._height; 373 374 for (++it; it != overlayList.end(); ++it) { 375 if (it->type != 5) { 376 continue; 377 } 378 379 idx = ABS(objectTable[it->objIdx].frame); 380 mx = objectTable[it->objIdx].x; 381 my = objectTable[it->objIdx].y; 382 mw = animDataTable[idx]._realWidth; 383 mh = animDataTable[idx]._height; 384 385 gfxUpdateSpriteMask(mask, x, y, width, height, animDataTable[idx].data(), mx, my, mw, mh); 386 } 387 } 388 389 /*! \brief Draw background to backbuffer 390 */ 391 void FWRenderer::drawBackground() { 392 assert(_background); 393 memcpy(_backBuffer, _background, _screenSize); 394 } 395 396 /*! \brief Draw one overlay 397 * \param it Overlay info 398 */ 399 void FWRenderer::renderOverlay(const Common::List<overlay>::iterator &it) { 400 int idx, len, width; 401 objectStruct *obj; 402 AnimData *sprite; 403 byte *mask; 404 405 switch (it->type) { 406 // color sprite 407 case 0: 408 sprite = animDataTable + objectTable[it->objIdx].frame; 409 len = sprite->_realWidth * sprite->_height; 410 mask = new byte[len]; 411 memcpy(mask, sprite->mask(), len); 412 remaskSprite(mask, it); 413 drawMaskedSprite(objectTable[it->objIdx], mask); 414 delete[] mask; 415 break; 416 417 // game message 418 case 2: 419 if (it->objIdx >= messageTable.size()) { 420 return; 421 } 422 423 _messageLen += messageTable[it->objIdx].size(); 424 drawMessage(messageTable[it->objIdx].c_str(), it->x, it->y, it->width, it->color); 425 break; 426 427 // action failure message 428 case 3: 429 idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3); 430 len = strlen(failureMessages[idx]); 431 _messageLen += len; 432 width = 6 * len + 20; 433 width = width > 300 ? 300 : width; 434 435 drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, 4); 436 break; 437 438 // bitmap 439 case 4: 440 assert(it->objIdx < NUM_MAX_OBJECT); 441 obj = objectTable + it->objIdx; 442 443 if (obj->frame < 0) { 444 return; 445 } 446 447 if (!animDataTable[obj->frame].data()) { 448 return; 449 } 450 451 fillSprite(*obj); 452 break; 453 } 454 } 455 456 /*! \brief Draw overlays 457 */ 458 void FWRenderer::drawOverlays() { 459 Common::List<overlay>::iterator it; 460 461 for (it = overlayList.begin(); it != overlayList.end(); ++it) { 462 renderOverlay(it); 463 } 464 } 465 466 /*! \brief Draw another frame 467 */ 468 void FWRenderer::drawFrame() { 469 drawBackground(); 470 drawOverlays(); 471 472 if (!_cmd.empty()) { 473 drawCommand(); 474 } 475 476 if (_changePal) { 477 refreshPalette(); 478 } 479 480 blit(); 481 } 482 483 /*! \brief Update screen 484 */ 485 void FWRenderer::blit() { 486 g_system->copyRectToScreen(_backBuffer, 320, 0, 0, 320, 200); 487 } 488 489 /*! \brief Set player command string 490 * \param cmd New command string 491 */ 492 void FWRenderer::setCommand(const char *cmd) { 493 _cmd = cmd; 494 } 495 496 /*! \brief Refresh current palette 497 */ 498 void FWRenderer::refreshPalette() { 499 int i; 500 byte pal[16*4]; 501 502 assert(_activeLowPal); 503 504 for (i = 0; i < 16; i++) { 505 // This seems to match the output from DOSbox. 506 pal[i * 4 + 2] = ((_activeLowPal[i] & 0x00f) >> 0) * 32; 507 pal[i * 4 + 1] = ((_activeLowPal[i] & 0x0f0) >> 4) * 32; 508 pal[i * 4 + 0] = ((_activeLowPal[i] & 0xf00) >> 8) * 32; 509 pal[i * 4 + 3] = 0; 510 } 511 512 g_system->setPalette(pal, 0, 16); 513 _changePal = 0; 514 } 515 516 /*! \brief Load palette of current background 517 */ 518 void FWRenderer::reloadPalette() { 519 assert(_palette); 520 521 if (!_activeLowPal) { 522 _activeLowPal = new uint16[_lowPalSize]; 523 } 524 525 assert(_activeLowPal); 526 527 memcpy(_activeLowPal, _palette, _lowPalSize * sizeof (uint16)); 528 _changePal = 1; 529 } 530 531 /*! \brief Load background into renderer 532 * \param bg Raw background data 533 */ 534 void FWRenderer::loadBg16(const byte *bg, const char *name) { 535 int i; 536 537 if (!_background) { 538 _background = new byte[_screenSize]; 539 } 540 541 if (!_palette) { 542 _palette = new uint16[_lowPalSize]; 543 } 544 545 assert(_background && _palette); 546 547 strcpy(_bgName, name); 548 549 for (i = 0; i < _lowPalSize; i++, bg += 2) { 550 _palette[i] = READ_BE_UINT16(bg); 551 } 552 553 gfxConvertSpriteToRaw(_background, bg, 160, 200); 554 } 555 556 /*! \brief Placeholder for Operation Stealth implementation 557 */ 558 void FWRenderer::loadBg16(const byte *bg, const char *name, unsigned int idx) { 559 error("Future Wars renderer doesn't support multiple backgrounds"); 560 } 561 562 /*! \brief Placeholder for Operation Stealth implementation 563 */ 564 void FWRenderer::loadCt16(const byte *ct, const char *name) { 565 error("Future Wars renderer doesn't support multiple backgrounds"); 566 } 567 568 /*! \brief Placeholder for Operation Stealth implementation 569 */ 570 void FWRenderer::loadBg256(const byte *bg, const char *name) { 571 error("Future Wars renderer doesn't support 256 color mode"); 572 } 573 574 /*! \brief Placeholder for Operation Stealth implementation 575 */ 576 void FWRenderer::loadBg256(const byte *bg, const char *name, unsigned int idx) { 577 error("Future Wars renderer doesn't support multiple backgrounds"); 578 } 579 580 /*! \brief Placeholder for Operation Stealth implementation 581 */ 582 void FWRenderer::loadCt256(const byte *ct, const char *name) { 583 error("Future Wars renderer doesn't support multiple backgrounds"); 584 } 585 586 /*! \brief Placeholder for Operation Stealth implementation 587 */ 588 void FWRenderer::selectBg(unsigned int idx) { 589 error("Future Wars renderer doesn't support multiple backgrounds"); 590 } 591 592 /*! \brief Placeholder for Operation Stealth implementation 593 */ 594 void FWRenderer::selectScrollBg(unsigned int idx) { 595 error("Future Wars renderer doesn't support multiple backgrounds"); 596 } 597 598 /*! \brief Placeholder for Operation Stealth implementation 599 */ 600 void FWRenderer::setScroll(unsigned int shift) { 601 error("Future Wars renderer doesn't support multiple backgrounds"); 602 } 603 604 /*! \brief Placeholder for Operation Stealth implementation 605 */ 606 void FWRenderer::removeBg(unsigned int idx) { 607 error("Future Wars renderer doesn't support multiple backgrounds"); 608 } 609 610 void FWRenderer::saveBg(Common::OutSaveFile &fHandle) { 611 fHandle.write(_bgName, 13); 612 } 613 614 /*! \brief Restore active and backup palette from save 615 * \param fHandle Savefile open for reading 616 */ 617 void FWRenderer::restorePalette(Common::InSaveFile &fHandle) { 618 int i; 619 620 if (!_palette) { 621 _palette = new uint16[_lowPalSize]; 622 } 623 624 if (!_activeLowPal) { 625 _activeLowPal = new uint16[_lowPalSize]; 626 } 627 628 assert(_palette && _activeLowPal); 629 630 for (i = 0; i < _lowPalSize; i++) { 631 _activeLowPal[i] = fHandle.readUint16BE(); 632 } 633 634 for (i = 0; i < _lowPalSize; i++) { 635 _palette[i] = fHandle.readUint16BE(); 636 } 637 638 _changePal = 1; 639 } 640 641 /*! \brief Write active and backup palette to save 642 * \param fHandle Savefile open for writing 643 */ 644 void FWRenderer::savePalette(Common::OutSaveFile &fHandle) { 645 int i; 646 647 assert(_palette && _activeLowPal); 648 649 for (i = 0; i < _lowPalSize; i++) { 650 fHandle.writeUint16BE(_activeLowPal[i]); 651 } 652 653 for (i = 0; i < _lowPalSize; i++) { 654 fHandle.writeUint16BE(_palette[i]); 655 } 656 } 657 658 /*! \brief Rotate active palette 659 * \param a First color to rotate 660 * \param b Last color to rotate 661 * \param c Possibly rotation step, must be equal to 1 at the moment 662 */ 663 void FWRenderer::rotatePalette(int a, int b, int c) { 664 palRotate(_activeLowPal, a, b, c); 665 refreshPalette(); 666 } 667 668 /*! \brief Copy part of backup palette to active palette and transform 669 * \param first First color to transform 670 * \param last Last color to transform 671 * \param r Red channel transformation 672 * \param g Green channel transformation 673 * \param b Blue channel transformation 674 */ 675 void FWRenderer::transformPalette(int first, int last, int r, int g, int b) { 676 if (!_activeLowPal) { 677 _activeLowPal = new uint16[_lowPalSize]; 678 memset(_activeLowPal, 0, _lowPalSize * sizeof (uint16)); 679 } 680 681 transformPaletteRange(_activeLowPal, _palette, first, last, r, g, b); 682 refreshPalette(); 683 } 684 685 /*! \brief Draw menu box, one item per line with possible highlight 686 * \param items Menu items 687 * \param height Item count 688 * \param x Top left menu corner coordinate 689 * \param y Top left menu corner coordinate 690 * \param width Menu box width 691 * \param selected Index of highlighted item (no highlight if less than 0) 692 */ 693 void FWRenderer::drawMenu(const CommandeType *items, unsigned int height, int x, int y, int width, int selected) { 694 int tx, ty, th = height * 9 + 10; 695 unsigned int i, j; 696 697 if (x + width > 319) { 698 x = 319 - width; 699 } 700 701 if (y + th > 199) { 702 y = 199 - th; 703 } 704 705 drawPlainBox(x, y, width, 4, _messageBg); 706 707 ty = y + 4; 708 709 for (i = 0; i < height; i++, ty += 9) { 710 drawPlainBox(x, ty, width, 9, (int)i == selected ? 0 : _messageBg); 711 tx = x + 4; 712 713 for (j = 0; items[i][j]; j++) { 714 tx = drawChar(items[i][j], tx, ty); 715 } 716 } 717 718 drawPlainBox(x, ty, width, 4, _messageBg); 719 drawDoubleBorder(x, y, width, ty - y + 4, 2); 720 } 721 722 /*! \brief Draw text input box 723 * \param info Input box message 724 * \param input Text entered in the input area 725 * \param cursor Cursor position in the input area 726 * \param x Top left input box corner coordinate 727 * \param y Top left input box corner coordinate 728 * \param width Input box width 729 */ 730 void FWRenderer::drawInputBox(const char *info, const char *input, int cursor, int x, int y, int width) { 731 int i, tx, ty, tw; 732 int line = 0, words = 0, cw = 0; 733 int space = 0, extraSpace = 0; 734 735 drawPlainBox(x, y, width, 4, _messageBg); 736 tx = x + 4; 737 ty = info[0] ? y - 5 : y + 4; 738 tw = width - 8; 739 740 // input box info message 741 for (i = 0; info[i]; i++, line--) { 742 // fit line of text 743 if (!line) { 744 line = fitLine(info + i, tw, words, cw); 745 746 if ( info[i + line] != '\0' && words) { 747 space = (tw - cw) / words; 748 extraSpace = (tw - cw) % words; 749 } else { 750 space = 5; 751 extraSpace = 0; 752 } 753 754 ty += 9; 755 drawPlainBox(x, ty, width, 9, _messageBg); 756 tx = x + 4; 757 } 758 759 // draw characters 760 if (info[i] == ' ') { 761 tx += space + extraSpace; 762 763 if (extraSpace) { 764 extraSpace = 0; 765 } 766 } else { 767 tx = drawChar(info[i], tx, ty); 768 } 769 } 770 771 // input area background 772 ty += 9; 773 drawPlainBox(x, ty, width, 9, _messageBg); 774 drawPlainBox(x + 16, ty - 1, width - 32, 9, 0); 775 tx = x + 20; 776 777 // text in input area 778 for (i = 0; input[i]; i++) { 779 tx = drawChar(input[i], tx, ty); 780 781 if (cursor == i + 2) { 782 drawLine(tx, ty - 1, 1, 9, 2); 783 } 784 } 785 786 if (!input[0] || cursor == 1) { 787 drawLine(x + 20, ty - 1, 1, 9, 2); 788 } 789 790 ty += 9; 791 drawPlainBox(x, ty, width, 4, _messageBg); 792 drawDoubleBorder(x, y, width, ty - y + 4, 2); 793 } 794 795 /*! \brief Fade to black 796 */ 797 void FWRenderer::fadeToBlack() { 798 assert(_activeLowPal); 799 800 for (int i = 0; i < 8; i++) { 801 for (int j = 0; j < 16; j++) { 802 _activeLowPal[j] = transformColor(_activeLowPal[j], -1, -1, -1); 803 } 804 805 refreshPalette(); 806 g_system->updateScreen(); 807 g_system->delayMillis(50); 808 } 809 } 810 811 /*! \brief Initialize Operation Stealth renderer 812 */ 813 OSRenderer::OSRenderer() : _activeHiPal(NULL), _currentBg(0), _scrollBg(0), 814 _bgShift(0) { 815 816 int i; 817 for (i = 0; i < 9; i++) { 818 _bgTable[i].bg = NULL; 819 _bgTable[i].lowPal = NULL; 820 _bgTable[i].hiPal = NULL; 821 memset(_bgTable[i].name, 0, sizeof (_bgTable[i].name)); 822 } 823 } 824 825 /*! \brief Destroy Operation Stealth renderer 826 */ 827 OSRenderer::~OSRenderer() { 828 delete[] _activeHiPal; 829 830 for (int i = 0; i < 9; i++) { 831 delete[] _bgTable[i].bg; 832 delete[] _bgTable[i].lowPal; 833 delete[] _bgTable[i].hiPal; 834 } 835 } 836 837 /*! \brief Reset Operation Stealth renderer state 838 */ 839 void OSRenderer::clear() { 840 delete[] _activeHiPal; 841 _activeHiPal = NULL; 842 843 for (int i = 0; i < 9; i++) { 844 delete[] _bgTable[i].bg; 845 delete[] _bgTable[i].lowPal; 846 delete[] _bgTable[i].hiPal; 847 848 _bgTable[i].bg = NULL; 849 _bgTable[i].lowPal = NULL; 850 _bgTable[i].hiPal = NULL; 851 memset(_bgTable[i].name, 0, sizeof (_bgTable[i].name)); 852 } 853 854 _currentBg = 0; 855 _scrollBg = 0; 856 _bgShift = 0; 857 858 FWRenderer::clear(); 859 } 860 861 /*! \brief Draw 1bpp sprite using selected color on backgrounds 862 * \param obj Object info 863 * \param fillColor Sprite color 864 */ 865 void OSRenderer::incrustMask(const objectStruct &obj, uint8 color) { 866 const byte *data = animDataTable[obj.frame].data(); 867 int x, y, width, height, i; 868 869 x = obj.x; 870 y = obj.y; 871 width = animDataTable[obj.frame]._realWidth; 872 height = animDataTable[obj.frame]._height; 873 874 for (i = 0; i < 8; i++) { 875 if (!_bgTable[i].bg) { 876 continue; 877 } 878 879 gfxFillSprite(data, width, height, _bgTable[i].bg, x, y, color); 880 } 881 } 882 883 /*! \brief Draw color sprite 884 * \param obj Object info 885 */ 886 void OSRenderer::drawSprite(const objectStruct &obj) { 887 const byte *data = animDataTable[obj.frame].data(); 888 int x, y, width, height, transColor; 889 890 x = obj.x; 891 y = obj.y; 892 transColor = obj.part; 893 width = animDataTable[obj.frame]._realWidth; 894 height = animDataTable[obj.frame]._height; 895 896 drawSpriteRaw2(data, transColor, width, height, _backBuffer, x, y); 897 } 898 899 /*! \brief Draw color sprite 900 * \param obj Object info 901 */ 902 void OSRenderer::incrustSprite(const objectStruct &obj) { 903 const byte *data = animDataTable[obj.frame].data(); 904 int x, y, width, height, transColor, i; 905 906 x = obj.x; 907 y = obj.y; 908 transColor = obj.part; 909 width = animDataTable[obj.frame]._realWidth; 910 height = animDataTable[obj.frame]._height; 911 912 for (i = 0; i < 8; i++) { 913 if (!_bgTable[i].bg) { 914 continue; 915 } 916 917 drawSpriteRaw2(data, transColor, width, height, _bgTable[i].bg, x, y); 918 } 919 } 920 921 /*! \brief Draw text character on screen 922 * \param character Character to draw 923 * \param x Character coordinate 924 * \param y Character coordinate 925 */ 926 int OSRenderer::drawChar(char character, int x, int y) { 927 int width, idx; 928 929 if (character == ' ') { 930 x += 5; 931 } else if ((width = fontParamTable[character].characterWidth)) { 932 idx = fontParamTable[character].characterIdx; 933 drawSpriteRaw2(textTable[idx][0], 0, 16, 8, _backBuffer, x, y); 934 x += width + 1; 935 } 936 937 return x; 938 } 939 940 /*! \brief Draw background to backbuffer 941 */ 942 void OSRenderer::drawBackground() { 943 byte *main; 944 945 main = _bgTable[_currentBg].bg; 946 assert(main); 947 948 if (!_bgShift) { 949 memcpy(_backBuffer, main, _screenSize); 950 } else { 951 byte *scroll = _bgTable[_scrollBg].bg; 952 int mainShift = _bgShift * _screenWidth; 953 int mainSize = _screenSize - mainShift; 954 955 assert(scroll); 956 957 memcpy(_backBuffer, main + mainShift, mainSize); 958 memcpy(_backBuffer + mainSize, scroll, mainShift); 959 } 960 } 961 962 /*! \brief Draw one overlay 963 * \param it Overlay info 964 */ 965 void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) { 966 int len; 967 objectStruct *obj; 968 AnimData *sprite; 969 byte *mask; 970 971 switch (it->type) { 972 // color sprite 973 case 0: 974 sprite = animDataTable + objectTable[it->objIdx].frame; 975 len = sprite->_realWidth * sprite->_height; 976 mask = new byte[len]; 977 generateMask(sprite->data(), mask, len, objectTable[it->objIdx].part); 978 remaskSprite(mask, it); 979 drawMaskedSprite(objectTable[it->objIdx], mask); 980 delete[] mask; 981 break; 982 983 // masked background 984 case 20: 985 assert(it->objIdx < NUM_MAX_OBJECT); 986 obj = objectTable + it->objIdx; 987 sprite = animDataTable + obj->frame; 988 989 if (obj->frame < 0 || it->x > 8 || !_bgTable[it->x].bg || sprite->_bpp != 1) { 990 break; 991 } 992 993 maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y); 994 break; 995 996 // something else 997 default: 998 FWRenderer::renderOverlay(it); 999 break; 1000 } 1001 } 1002 1003 /*! \brief Refresh current palette 1004 */ 1005 void OSRenderer::refreshPalette() { 1006 if (!_activeHiPal) { 1007 FWRenderer::refreshPalette(); 1008 return; 1009 } 1010 1011 int i; 1012 byte pal[256*4]; 1013 1014 for (i = 0; i < 256; i++) { 1015 pal[i * 4 + 0] = _activeHiPal[i * 3 + 0]; 1016 pal[i * 4 + 1] = _activeHiPal[i * 3 + 1]; 1017 pal[i * 4 + 2] = _activeHiPal[i * 3 + 2]; 1018 pal[i * 4 + 3] = 0; 1019 } 1020 1021 g_system->setPalette(pal, 0, 256); 1022 _changePal = 0; 1023 } 1024 1025 /*! \brief Load palette of current background 1026 */ 1027 void OSRenderer::reloadPalette() { 1028 // selected background in plane takeoff scene has swapped colors 12 1029 // and 14, shift background has it right 1030 palBg *bg = _bgShift ? &_bgTable[_scrollBg] : &_bgTable[_currentBg]; 1031 1032 assert(bg->lowPal || bg->hiPal); 1033 1034 if (bg->lowPal) { 1035 if (!_activeLowPal) { 1036 _activeLowPal = new uint16[_lowPalSize]; 1037 } 1038 1039 assert(_activeLowPal); 1040 1041 delete[] _activeHiPal; 1042 _activeHiPal = NULL; 1043 1044 memcpy(_activeLowPal, bg->lowPal, _lowPalSize * sizeof (uint16)); 1045 } else { 1046 if (!_activeHiPal) { 1047 _activeHiPal = new byte[_hiPalSize]; 1048 } 1049 1050 assert(_activeHiPal); 1051 1052 delete[] _activeLowPal; 1053 _activeLowPal = NULL; 1054 1055 memcpy(_activeHiPal, bg->hiPal, _hiPalSize); 1056 } 1057 _changePal = 1; 1058 } 1059 1060 /*! \brief Rotate active palette 1061 * \param a First color to rotate 1062 * \param b Last color to rotate 1063 * \param c Possibly rotation step, must be equal to 1 at the moment 1064 */ 1065 void OSRenderer::rotatePalette(int a, int b, int c) { 1066 if (_activeLowPal) { 1067 FWRenderer::rotatePalette(a, b, c); 1068 return; 1069 } 1070 1071 palRotate(_activeHiPal, a, b, c); 1072 refreshPalette(); 1073 } 1074 1075 /*! \brief Copy part of backup palette to active palette and transform 1076 * \param first First color to transform 1077 * \param last Last color to transform 1078 * \param r Red channel transformation 1079 * \param g Green channel transformation 1080 * \param b Blue channel transformation 1081 */ 1082 void OSRenderer::transformPalette(int first, int last, int r, int g, int b) { 1083 palBg *bg = _bgShift ? &_bgTable[_scrollBg] : &_bgTable[_currentBg]; 1084 1085 if (!bg->lowPal) { 1086 if (!_activeHiPal) { 1087 _activeHiPal = new byte[_hiPalSize]; 1088 memset(_activeHiPal, 0, _hiPalSize); 1089 } 1090 1091 delete[] _activeLowPal; 1092 _activeLowPal = NULL; 1093 1094 transformPaletteRange(_activeHiPal, bg->hiPal, first, last, r, g, b); 1095 } else { 1096 if (!_activeLowPal) { 1097 _activeLowPal = new uint16[_lowPalSize]; 1098 memset(_activeLowPal, 0, _lowPalSize * sizeof (uint16)); 1099 } 1100 1101 delete[] _activeHiPal; 1102 _activeHiPal = NULL; 1103 1104 transformPaletteRange(_activeLowPal, bg->lowPal, first, last, r, g, b); 1105 } 1106 1107 refreshPalette(); 1108 } 1109 1110 /*! \brief Load 16 color background into renderer 1111 * \param bg Raw background data 1112 * \param name Background filename 1113 */ 1114 void OSRenderer::loadBg16(const byte *bg, const char *name) { 1115 loadBg16(bg, name, 0); 1116 } 1117 1118 /*! \brief Load 16 color background into renderer 1119 * \param bg Raw background data 1120 * \param name Background filename 1121 * \param pos Background index 1122 */ 1123 void OSRenderer::loadBg16(const byte *bg, const char *name, unsigned int idx) { 1124 int i; 1125 assert(idx < 9); 1126 1127 if (!_bgTable[idx].bg) { 1128 _bgTable[idx].bg = new byte[_screenSize]; 1129 } 1130 1131 if (!_bgTable[idx].lowPal) { 1132 _bgTable[idx].lowPal = new uint16[_lowPalSize]; 1133 } 1134 1135 assert(_bgTable[idx].bg && _bgTable[idx].lowPal); 1136 1137 delete[] _bgTable[idx].hiPal; 1138 _bgTable[idx].hiPal = NULL; 1139 1140 strcpy(_bgTable[idx].name, name); 1141 1142 for (i = 0; i < _lowPalSize; i++, bg += 2) { 1143 _bgTable[idx].lowPal[i] = READ_BE_UINT16(bg); 1144 } 1145 1146 gfxConvertSpriteToRaw(_bgTable[idx].bg, bg, 160, 200); 1147 } 1148 1149 /*! \brief Load 16 color CT data as background into renderer 1150 * \param ct Raw CT data 1151 * \param name Background filename 1152 */ 1153 void OSRenderer::loadCt16(const byte *ct, const char *name) { 1154 loadBg16(ct, name, 8); 1155 } 1156 1157 /*! \brief Load 256 color background into renderer 1158 * \param bg Raw background data 1159 * \param name Background filename 1160 */ 1161 void OSRenderer::loadBg256(const byte *bg, const char *name) { 1162 loadBg256(bg, name, 0); 1163 } 1164 1165 /*! \brief Load 256 color background into renderer 1166 * \param bg Raw background data 1167 * \param name Background filename 1168 * \param pos Background index 1169 */ 1170 void OSRenderer::loadBg256(const byte *bg, const char *name, unsigned int idx) { 1171 assert(idx < 9); 1172 1173 if (!_bgTable[idx].bg) { 1174 _bgTable[idx].bg = new byte[_screenSize]; 1175 } 1176 1177 if (!_bgTable[idx].hiPal) { 1178 _bgTable[idx].hiPal = new byte[_hiPalSize]; 1179 } 1180 1181 assert(_bgTable[idx].bg && _bgTable[idx].hiPal); 1182 1183 delete[] _bgTable[idx].lowPal; 1184 _bgTable[idx].lowPal = NULL; 1185 1186 strcpy(_bgTable[idx].name, name); 1187 memcpy(_bgTable[idx].hiPal, bg, _hiPalSize); 1188 memcpy(_bgTable[idx].bg, bg + _hiPalSize, _screenSize); 1189 } 1190 1191 /*! \brief Load 256 color CT data as background into renderer 1192 * \param ct Raw CT data 1193 * \param name Background filename 1194 */ 1195 void OSRenderer::loadCt256(const byte *ct, const char *name) { 1196 loadBg256(ct, name, 8); 1197 } 1198 1199 /*! \brief Select active background and load its palette 1200 * \param idx Background index 1201 */ 1202 void OSRenderer::selectBg(unsigned int idx) { 1203 assert(idx < 9 && _bgTable[idx].bg); 1204 assert(_bgTable[idx].lowPal || _bgTable[idx].hiPal); 1205 1206 _currentBg = idx; 1207 reloadPalette(); 1208 } 1209 1210 /*! \brief Select scroll background 1211 * \param idx Scroll background index 1212 */ 1213 void OSRenderer::selectScrollBg(unsigned int idx) { 1214 assert(idx < 9); 1215 1216 if (_bgTable[idx].bg) { 1217 _scrollBg = idx; 1218 } 1219 reloadPalette(); 1220 } 1221 1222 /*! \brief Set background scroll 1223 * \param shift Background scroll in pixels 1224 */ 1225 void OSRenderer::setScroll(unsigned int shift) { 1226 assert(shift <= 200); 1227 1228 _bgShift = shift; 1229 } 1230 1231 /*! \brief Unload background from renderer 1232 * \param idx Background to unload 1233 */ 1234 void OSRenderer::removeBg(unsigned int idx) { 1235 assert(idx > 0 && idx < 9); 1236 1237 if (_currentBg == idx) { 1238 _currentBg = 0; 1239 } 1240 1241 if (_scrollBg == idx) { 1242 _scrollBg = 0; 1243 } 1244 1245 delete[] _bgTable[idx].bg; 1246 delete[] _bgTable[idx].lowPal; 1247 delete[] _bgTable[idx].hiPal; 1248 _bgTable[idx].bg = NULL; 1249 _bgTable[idx].lowPal = NULL; 1250 _bgTable[idx].hiPal = NULL; 1251 memset(_bgTable[idx].name, 0, sizeof (_bgTable[idx].name)); 1252 } 1253 1254 /*! \brief Fade to black 1255 * \bug Operation Stealth sometimes seems to fade to black using 1256 * transformPalette resulting in double fadeout 1257 */ 1258 void OSRenderer::fadeToBlack() { 1259 if (!_activeHiPal) { 1260 FWRenderer::fadeToBlack(); 1261 return; 1262 } 1263 1264 for (int i = 0; i < 8; i++) { 1265 for (int j = 0; j < _hiPalSize; j++) { 1266 _activeHiPal[j] = CLIP(_activeHiPal[j] - 32, 0, 255); 1267 } 1268 1269 refreshPalette(); 1270 g_system->updateScreen(); 1271 g_system->delayMillis(50); 1272 } 1273 } 1274 123 1275 void setMouseCursor(int cursor) { 124 1276 static int currentMouseCursor = -1; 125 1277 assert(cursor >= 0 && cursor < 3); … … 147 1299 } 148 1300 } 149 1301 150 static uint16 transformColor(uint16 baseColor, int8 r, int8 g, int8 b) {151 int8 oriR = CLIP( (baseColor & 0x007) + r, 0, 7);152 int8 oriG = CLIP(((baseColor & 0x070) >> 4) + g, 0, 7);153 int8 oriB = CLIP(((baseColor & 0x700) >> 8) + b, 0, 7);154 155 return oriR | (oriG << 4) | (oriB << 8);156 }157 158 void transformPaletteRange(byte startColor, byte stopColor, int8 r, int8 g, int8 b) {159 for (byte i = startColor; i <= stopColor; i++) {160 c_palette[i] = transformColor(tempPalette[i], b, g, r);161 }162 //gfxFlipPage(page2);163 }164 165 1302 void gfxFillSprite(const byte *spritePtr, uint16 width, uint16 height, byte *page, int16 x, int16 y, uint8 fillColor) { 166 1303 int16 i, j; 167 1304 … … 170 1307 destPtr += i * 320; 171 1308 172 1309 for (j = 0; j < width; j++) { 173 if (x + j >= 0 && x + j < 320 && i + y >= 0 174 && i + y < 200) { 175 if (!*(spritePtr++)) { 176 *(destPtr++) = fillColor; 177 } else { 178 destPtr++; 179 } 180 } else { 181 destPtr++; 182 spritePtr++; 1310 if (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200 && !*spritePtr) { 1311 *destPtr = fillColor; 183 1312 } 1313 1314 destPtr++; 1315 spritePtr++; 184 1316 } 185 1317 } 186 1318 } … … 360 1492 } 361 1493 } 362 1494 363 void gfxCopyRawPage(byte *source, byte *dest) { 364 memcpy(dest, source, 320 * 200); 365 } 366 367 void gfxFlipRawPage(byte *frontBuffer) { 368 byte *page = frontBuffer; 369 int x, y, i; 370 byte *pixels = (byte *) screenBuffer; 371 byte c; 372 byte pal[256 * 4]; 373 374 for (y = 0; y < 200; y++) { 375 for (x = 0; x < 320; x++) { 376 c = *(page++); 377 378 if (!colorMode256) { 379 c = c & 15; 380 } 381 382 pixels[x + 0 + y * 320] = c; 383 } 384 } 385 386 if (colorMode256) { 387 for (i = 0; i < 256; i++) { 388 pal[i * 4 + 0] = palette256[i * 3 + 0]; 389 pal[i * 4 + 1] = palette256[i * 3 + 1]; 390 pal[i * 4 + 2] = palette256[i * 3 + 2]; 391 pal[i * 4 + 3] = 0; 392 } 393 g_system->setPalette(pal, 0, 256); 394 } else { 395 for (i = 0; i < 16; i++) { 396 // This seems to match the output from DOSbox. 397 pal[i * 4 + 2] = ((c_palette[i] & 0x00f) >> 0) * 32; 398 pal[i * 4 + 1] = ((c_palette[i] & 0x0f0) >> 4) * 32; 399 pal[i * 4 + 0] = ((c_palette[i] & 0xf00) >> 8) * 32; 400 pal[i * 4 + 3] = 0; 401 } 402 g_system->setPalette(pal, 0, 16); 403 } 404 405 g_system->copyRectToScreen(screenBuffer, 320, 0, 0, 320, 200); 406 } 407 408 void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int16 height, 409 byte *page, int16 x, int16 y) { 1495 void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int16 height, byte *page, int16 x, int16 y) { 410 1496 int16 i, j; 411 1497 412 1498 // FIXME: Is it a bug if maskPtr == NULL? … … 417 1503 byte *destPtr = page + x + y * 320; 418 1504 destPtr += i * 320; 419 1505 420 for (j = 0; j < width * 8; j++) { 421 if (((g_cine->getGameType() == Cine::GType_FW && (!maskPtr || !(*maskPtr))) || (g_cine->getGameType() == Cine::GType_OS)) && (x + j >= 0 422 && x + j < 320 && i + y >= 0 && i + y < 200)) { 1506 for (j = 0; j < width; j++) { 1507 if ((!maskPtr || !(*maskPtr)) && x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200) { 423 1508 *(destPtr++) = *(spritePtr++); 424 1509 } else { 425 1510 destPtr++; … … 432 1517 } 433 1518 } 434 1519 435 void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 height, 436 byte *page, int16 x, int16 y) { 1520 void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 height, byte *page, int16 x, int16 y) { 437 1521 int16 i, j; 438 1522 439 1523 for (i = 0; i < height; i++) { 440 1524 byte *destPtr = page + x + y * 320; 441 1525 destPtr += i * 320; 442 1526 443 for (j = 0; j < width * 8; j++) { 444 if ((*(spritePtr) != transColor) && (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200)) { 445 *(destPtr++) = *(spritePtr++); 446 } else { 447 destPtr++; 448 spritePtr++; 1527 for (j = 0; j < width; j++) { 1528 if ((*spritePtr != transColor) && (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200)) { 1529 *destPtr = *spritePtr; 449 1530 } 1531 destPtr++; 1532 spritePtr++; 450 1533 } 451 1534 } 452 1535 } … … 499 1582 } 500 1583 } 501 1584 502 /*! \todo Fix rendering to prevent fadein artifacts503 */504 void fadeFromBlack() {505 int i, j;506 int r, g, b, tr, tg, tb;507 if (newColorMode == 2) {508 colorMode256 = 1;509 memset(palette256, 0, 256*3);510 } else if (newColorMode == 1) {511 colorMode256 = 0;512 memset(c_palette, 0, 16 * sizeof(uint16));513 }514 515 for (i = 0; i < 8; i++ ) {516 gfxFlipRawPage(page1Raw);517 g_system->updateScreen();518 g_system->delayMillis(50);519 520 if (colorMode256) {521 for (j = 0; j < 256*3; j++) {522 r = palette256[j] + (newPalette[j] + 7) / 8;523 palette256[j] = CLIP(r, 0, (int)newPalette[j]);524 }525 } else {526 for (j = 0; j < 16; j++) {527 r = c_palette[j] & 0xf;528 g = (c_palette[j] & 0xf0) >> 4;529 b = (c_palette[j] & 0xf00) >> 8;530 531 tr = tempPalette[j] & 0xf;532 tg = (tempPalette[j] & 0xf0) >> 4;533 tb = (tempPalette[j] & 0xf00) >> 8;534 535 r = CLIP(r + (tr + 7) / 8, 0, tr);536 g = CLIP(g + (tg + 7) / 8, 0, tg);537 b = CLIP(b + (tb + 7) / 8, 0, tb);538 539 c_palette[j] = r | (g << 4) | (b << 8);540 }541 542 }543 }544 545 if (colorMode256) {546 memcpy(palette256, newPalette, 256*3);547 } else {548 memcpy(c_palette, tempPalette, sizeof(uint16) * 16);549 }550 }551 552 void fadeToBlack() {553 for (int i = 0; i < 8; i++) {554 if (colorMode256) {555 for (int j = 0; j < 256*3; j++) {556 palette256[j] = CLIP(palette256[j] - 32, 0, 255);557 }558 } else {559 for (int j = 0; j < 16; j++) {560 c_palette[j] = transformColor(c_palette[j], -1, -1, -1);561 }562 }563 gfxFlipRawPage(page1Raw);564 g_system->updateScreen();565 g_system->delayMillis(50);566 }567 }568 569 void blitRawScreen(byte *frontBuffer) {570 gfxFlipRawPage(frontBuffer);571 }572 573 void flip(void) {574 blitRawScreen(page1Raw);575 if (fadeRequired) {576 if (newColorMode == 3) {577 newColorMode = ctColorMode + 1;578 }579 580 if (newColorMode == 2) {581 colorMode256 = 1;582 memcpy(palette256, newPalette, 256*3);583 } else {584 colorMode256 = 0;585 memcpy(c_palette, tempPalette, sizeof(uint16) * 16);586 }587 fadeRequired = false;588 }589 }590 591 1585 } // End of namespace Cine -
engines/cine/prc.cpp
98 98 char buffer[256]; 99 99 100 100 for (s = 0; s < numScripts; s++) { 101 if (scriptTable[s] .size) {101 if (scriptTable[s]->_size) { 102 102 sprintf(buffer, "%s_%03d.txt", pPrcName, s); 103 103 104 decompileScript( scriptTable[s].ptr, scriptTable[s].stack, scriptTable[s].size, s);104 decompileScript((const byte *)scriptTable[s]->getString(0), scriptTable[s]->_size, s); 105 105 dumpScript(buffer); 106 106 } 107 107 } -
engines/cine/bg.cpp
37 37 byte *additionalBgTable[9]; 38 38 byte currentAdditionalBgIdx = 0, currentAdditionalBgIdx2 = 0; 39 39 40 byte loadCt (const char *ctName) {40 byte loadCtFW(const char *ctName) { 41 41 uint16 header[32]; 42 42 byte *ptr, *dataPtr; 43 43 … … 46 46 47 47 ptr = dataPtr = readBundleFile(findFileInBundle(ctName)); 48 48 49 if (g_cine->getGameType() == Cine::GType_OS) { 50 uint16 bpp = READ_BE_UINT16(ptr); ptr += 2; 51 if (bpp == 8) { 52 ctColorMode = 1; 53 memcpy(newPalette, ptr, 256 * 3); 54 ptr += 3 * 256; 55 memcpy(page3Raw, ptr, 320 * 200); 56 } else { 57 ctColorMode = 0; 58 for (int i = 0; i < 16; i++) { 59 tempPalette[i] = READ_BE_UINT16(ptr); 60 ptr += 2; 61 } 49 loadRelatedPalette(ctName); 62 50 63 gfxResetRawPage(page3Raw); 64 gfxConvertSpriteToRaw(page3Raw, ptr, 160, 200); 65 } 66 } else { 67 loadRelatedPalette(ctName); 51 assert(strstr(ctName, ".NEO")); 68 52 69 assert(strstr(ctName, ".NEO"));53 Common::MemoryReadStream readS(ptr, 32); 70 54 71 Common::MemoryReadStream readS(ptr, 32); 72 73 for (int i = 0; i < 16; i++) { 74 header[i] = readS.readUint16BE(); 75 } 76 77 gfxConvertSpriteToRaw(page3Raw, ptr + 0x80, 160, 200); 55 for (int i = 0; i < 16; i++) { 56 header[i] = readS.readUint16BE(); 78 57 } 79 58 59 gfxConvertSpriteToRaw(page3Raw, ptr + 0x80, 160, 200); 60 80 61 free(dataPtr); 81 62 return 0; 82 63 } 83 64 84 void loadBgHigh(const char *currentPtr) { 85 memcpy(newPalette, currentPtr, 256 * 3); 86 currentPtr += 256 * 3; 65 byte loadCtOS(const char *ctName) { 66 byte *ptr, *dataPtr; 87 67 88 memcpy(page2Raw, currentPtr, 320 * 200); 68 if (currentCtName != ctName) 69 strcpy(currentCtName, ctName); 89 70 90 newColorMode = 2; 91 bgColorMode = 1; 71 ptr = dataPtr = readBundleFile(findFileInBundle(ctName)); 92 72 73 uint16 bpp = READ_BE_UINT16(ptr); 74 ptr += 2; 75 76 if (bpp == 8) { 77 memcpy(page3Raw, ptr + 256 * 3, 320 * 200); 78 renderer->loadCt256(ptr, ctName); 79 } else { 80 gfxConvertSpriteToRaw(page3Raw, ptr + 32, 160, 200); 81 renderer->loadCt16(ptr, ctName); 82 } 83 84 free(dataPtr); 85 return 0; 93 86 } 94 87 95 88 byte loadBg(const char *bgName) { 96 89 byte *ptr, *dataPtr; 97 90 98 if (currentBgName[0] != bgName)99 strcpy(currentBgName[0], bgName);100 101 91 byte fileIdx = findFileInBundle(bgName); 102 92 ptr = dataPtr = readBundleFile(fileIdx); 103 93 104 uint16 bpp = READ_BE_UINT16(ptr); ptr += 2; 94 uint16 bpp = READ_BE_UINT16(ptr); 95 ptr += 2; 96 105 97 if (bpp == 8) { 106 loadBgHigh((const char *)ptr);98 renderer->loadBg256(ptr, bgName); 107 99 } else { 108 newColorMode = 1;109 bgColorMode = 0;110 111 for (int i = 0; i < 16; i++) {112 tempPalette[i] = READ_BE_UINT16(ptr);113 ptr += 2;114 }115 116 100 if (g_cine->getGameType() == Cine::GType_FW) { 117 101 loadRelatedPalette(bgName); 118 102 } 119 103 120 gfxResetRawPage(page2Raw); 121 gfxConvertSpriteToRaw(page2Raw, ptr, 160, 200); 104 renderer->loadBg16(ptr, bgName); 122 105 } 123 106 free(dataPtr); 124 107 return 0; … … 127 110 void addBackground(const char *bgName, uint16 bgIdx) { 128 111 byte *ptr, *dataPtr; 129 112 130 strcpy(currentBgName[bgIdx], bgName);131 132 113 byte fileIdx = findFileInBundle(bgName); 133 114 ptr = dataPtr = readBundleFile(fileIdx); 134 115 135 additionalBgTable[bgIdx] = (byte *) malloc(320 * 200);136 137 116 uint16 bpp = READ_BE_UINT16(ptr); ptr += 2; 138 117 139 118 if (bpp == 8) { 140 bgColorMode = 1; 141 memcpy(newPalette, ptr, 256 * 3); 142 ptr += 3 * 256; 143 memcpy(additionalBgTable[bgIdx], ptr, 320 * 200); 119 renderer->loadBg256(ptr, bgName, bgIdx); 144 120 } else { 145 bgColorMode = 0; 146 for (int i = 0; i < 16; i++) { 147 tempPalette[i] = READ_BE_UINT16(ptr); 148 ptr += 2; 149 } 150 151 gfxConvertSpriteToRaw(additionalBgTable[bgIdx], ptr, 160, 200); 121 renderer->loadBg16(ptr, bgName, bgIdx); 152 122 } 153 123 free(dataPtr); 154 124 } -
engines/cine/bg_list.h
46 46 extern Common::List<BGIncrust> bgIncrustList; 47 47 extern uint32 var8; 48 48 49 void addToBGList(int16 objIdx , bool addList = true);50 void addSpriteFilledToBGList(int16 idx , bool addList = true);49 void addToBGList(int16 objIdx); 50 void addSpriteFilledToBGList(int16 idx); 51 51 52 52 void createBgIncrustListElement(int16 objIdx, int16 param); 53 53 void resetBgIncrustList(void); -
engines/cine/texte.cpp
611 611 fontParamTable = 0; 612 612 } 613 613 614 uint16 computeMessageLength(const byte *ptr, uint16 width, uint16 *numWords, uint16 *messageWidth, uint16 *lineResult) { 615 const byte *localPtr = ptr; 614 /*! \brief Fit a substring of text into one line of fixed width text box 615 * \param str Text to fit 616 * \param maxWidth Text box width 617 * \param[out] words Number of words that fit 618 * \param[out] width Total width of nonblank characters that fit 619 * \return Length of substring which fits 620 */ 621 int fitLine(const char *str, int maxWidth, int &words, int &width) { 622 int i, bkpWords = 0, bkpWidth = 0, bkpLen = 0; 623 int charWidth = 0, fullWidth = 0; 616 624 617 uint16 var_2 = 0; 618 uint16 localLineResult = 0; 619 uint16 var_6 = 0; 620 uint16 var_8 = 0; 621 uint16 localMessageWidth = 0; 622 uint16 var_16 = 0; 623 uint16 finished = 0; 624 uint16 si = 0; 625 uint16 di = 0; 625 words = 0; 626 width = 0; 626 627 627 while (!finished) { 628 byte character = *(localPtr++); 629 630 if (character == ' ') { 631 var_8 = var_16; 632 var_6 = localMessageWidth; 633 localLineResult = si; 634 var_2 = di; 635 636 if (si + 5 < width) { 637 var_16++; 638 si += 5; 639 } else { 640 finished = 1; 641 } 642 } else if (character == 0x7C || character == 0) { 643 finished = 1; 644 si = 0; 628 for (i = 0; str[i]; i++) { 629 if (str[i] == 0x7C) { 630 i++; 631 break; 632 } else if (str[i] == ' ') { 633 charWidth = 5; 634 bkpWords = words++; 635 bkpWidth = width; 636 bkpLen = i + 1; 645 637 } else { 646 if (fontParamTable[character].characterWidth) { 647 uint16 var_C = fontParamTable[character].characterWidth + 1; 638 charWidth = fontParamTable[str[i]].characterWidth + 1; 639 width += charWidth; 640 } 648 641 649 if (si + var_C < width) { 650 si += var_C; 651 localMessageWidth += var_C; 652 } else { 653 finished = 1; 654 655 if (localLineResult) { 656 var_16 = var_8; 657 localMessageWidth = var_6; 658 si = localLineResult; 659 di = var_2; 660 } 661 } 662 } 642 if (!charWidth) { 643 continue; 663 644 } 664 645 665 di++; 646 if (fullWidth + charWidth < maxWidth) { 647 fullWidth += charWidth; 648 } else if (fullWidth) { 649 words = bkpWords; 650 width = bkpWidth; 651 i = bkpLen; 652 break; 653 } 666 654 } 667 655 668 *numWords = var_16; 669 *messageWidth = localMessageWidth; 670 *lineResult = si; 671 672 return di; 656 return i; 673 657 } 674 658 675 659 } // End of namespace Cine -
engines/cine/various.h
43 43 extern bool inMenu; 44 44 45 45 struct SeqListElement { 46 struct SeqListElement *next;47 46 int16 var4; 48 int16 var6;47 uint16 objIdx; 49 48 int16 var8; 50 int16 varA;49 int16 frame; 51 50 int16 varC; 52 51 int16 varE; 53 52 int16 var10; … … 60 59 int16 var1E; 61 60 }; 62 61 63 extern SeqListElementseqList;62 extern Common::List<SeqListElement> seqList; 64 63 65 64 extern uint16 var2; 66 65 extern uint16 var3; … … 97 96 extern char newObjectName[20]; 98 97 extern char newMsgName[20]; 99 98 100 extern char currentBgName[8][15];101 99 extern char currentCtName[15]; 102 100 extern char currentPartName[15]; 103 101 … … 130 128 int16 param; 131 129 }; 132 130 133 extern uint16 defaultMenuBoxColor;134 extern uint16 defaultMenuBoxColor2;135 136 131 #define NUM_MAX_ZONE 16 137 132 extern uint16 zoneData[NUM_MAX_ZONE]; 138 133 139 134 void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 param5); 140 135 141 extern int16 additionalBgVScroll;136 void removeMessages(); 142 137 143 138 void removeSeq(uint16 param1, uint16 param2, uint16 param3); 144 139 uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3); 145 void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8); 146 void resetSeqList(); 140 void addSeqListElement(uint16 objIdx, int16 param1, int16 param2, int16 frame, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8); 147 141 void processSeqList(void); 148 142 149 143 bool makeTextEntryMenu(const char *caption, char *string, int strLen, int y);