Ticket #3815: fix_for_bug_2019355-v2.patch
File fix_for_bug_2019355-v2.patch, 23.3 KB (added by , 16 years ago) |
---|
-
engines/cine/script_fw.cpp
230 230 * \param fHandle Savefile open for reading 231 231 * \param len Size of array 232 232 */ 233 ScriptVars::ScriptVars(Common:: InSaveFile&fHandle, unsigned int len)233 ScriptVars::ScriptVars(Common::SeekableReadStream &fHandle, unsigned int len) 234 234 : _size(len), _vars(new int16[len]) { 235 235 236 236 assert(_vars); … … 306 306 /*! \brief Restore array from savefile 307 307 * \param fHandle Savefile open for reading 308 308 */ 309 void ScriptVars::load(Common:: InSaveFile&fHandle) {309 void ScriptVars::load(Common::SeekableReadStream &fHandle) { 310 310 load(fHandle, _size); 311 311 } 312 312 … … 314 314 * \param fHandle Savefile open for reading 315 315 * \param len Length of data to be read 316 316 */ 317 void ScriptVars::load(Common:: InSaveFile&fHandle, unsigned int len) {317 void ScriptVars::load(Common::SeekableReadStream &fHandle, unsigned int len) { 318 318 debug(6, "assert(%d <= %d)", len, _size); 319 319 assert(len <= _size); 320 320 for (unsigned int i = 0; i < len; i++) { -
engines/cine/script.h
61 61 public: 62 62 // Explicit to prevent var=0 instead of var[i]=0 typos. 63 63 explicit ScriptVars(unsigned int len = 50); 64 ScriptVars(Common:: InSaveFile&fHandle, unsigned int len = 50);64 ScriptVars(Common::SeekableReadStream &fHandle, unsigned int len = 50); 65 65 ScriptVars(const ScriptVars &src); 66 66 ~ScriptVars(void); 67 67 … … 71 71 72 72 void save(Common::OutSaveFile &fHandle) const; 73 73 void save(Common::OutSaveFile &fHandle, unsigned int len) const; 74 void load(Common:: InSaveFile&fHandle);75 void load(Common:: InSaveFile&fHandle, unsigned int len);74 void load(Common::SeekableReadStream &fHandle); 75 void load(Common::SeekableReadStream &fHandle, unsigned int len); 76 76 void reset(void); 77 77 }; 78 78 -
engines/cine/bg_list.cpp
83 83 /*! \brief Restore incrust list from savefile 84 84 * \param fHandle Savefile open for reading 85 85 */ 86 void loadBgIncrustFromSave(Common:: InSaveFile&fHandle) {86 void loadBgIncrustFromSave(Common::SeekableReadStream &fHandle) { 87 87 BGIncrust tmp; 88 88 int size = fHandle.readSint16BE(); 89 89 -
engines/cine/anim.cpp
769 769 770 770 /*! \brief Load animDataTable from save 771 771 * \param fHandle Savefile open for reading 772 * \param broken Broken/correct file format switch772 * \param saveGameFormat The used savegame format 773 773 * \todo Add Operation Stealth savefile support 774 774 * 775 775 * Unlike the old code, this one actually rebuilds the table one frame 776 776 * at a time. 777 777 */ 778 void loadResourcesFromSave(Common:: InSaveFile &fHandle, bool broken) {778 void loadResourcesFromSave(Common::SeekableReadStream &fHandle, enum CineSaveGameFormat saveGameFormat) { 779 779 int16 currentAnim, foundFileIdx; 780 780 int8 isMask = 0, isSpl = 0; 781 781 byte *dataPtr, *ptr; 782 782 char *animName, part[256]; 783 783 byte transparentColor = 0; 784 AnimData *currentPtr;785 784 AnimHeaderStruct animHeader; 786 785 787 786 uint16 width, height, bpp, var1; … … 791 790 792 791 strcpy(part, currentPartName); 793 792 794 for (currentAnim = 0; currentAnim < NUM_MAX_ANIMDATA; currentAnim++) {795 currentPtr = &animDataTable[currentAnim];793 // We only support these variations of the savegame format at the moment. 794 assert(saveGameFormat == ANIMSIZE_23 || saveGameFormat == ANIMSIZE_30_PTRS_INTACT); 796 795 796 const int entrySize = ((saveGameFormat == ANIMSIZE_23) ? 23 : 30); 797 const int fileStartPos = fHandle.pos(); 798 for (currentAnim = 0; currentAnim < NUM_MAX_ANIMDATA; currentAnim += animHeader.numFrames) { 799 // Initialize the number of frames variable to a sane number. 800 // This is needed when using continue later in this function. 801 animHeader.numFrames = 1; 802 803 // Seek to the start of the current animation's entry 804 fHandle.seek(fileStartPos + currentAnim * entrySize); 805 // Read in the current animation entry 797 806 width = fHandle.readUint16BE(); 798 807 var1 = fHandle.readUint16BE(); 799 808 bpp = fHandle.readUint16BE(); 800 809 height = fHandle.readUint16BE(); 801 810 802 if (!broken) { 803 if (!fHandle.readUint32BE()) { 804 fHandle.skip(18); 805 continue; 806 } 807 fHandle.readUint32BE(); 811 bool validPtr = false; 812 // Handle variables only present in animation entries of size 30 813 if (entrySize == 30) { 814 validPtr = (fHandle.readUint32BE() != 0); // Read data pointer 815 fHandle.readUint32BE(); // Discard mask pointer 808 816 } 809 817 810 818 foundFileIdx = fHandle.readSint16BE(); 811 819 frame = fHandle.readSint16BE(); 812 820 fHandle.read(name, 10); 813 821 814 if (foundFileIdx < 0 || (broken && !fHandle.readByte())) { 822 // Handle variables only present in animation entries of size 23 823 if (entrySize == 23) { 824 validPtr = (fHandle.readByte() != 0); 825 } 826 827 // Don't try to load invalid entries. 828 if (foundFileIdx < 0 || !validPtr) { 815 829 continue; 816 830 } 817 831 832 // Alright, the animation entry looks to be valid so let's start handling it... 818 833 if (strcmp(currentPartName, name)) { 819 834 closePart(); 820 835 loadPart(name); … … 823 838 animName = partBuffer[foundFileIdx].partName; 824 839 ptr = dataPtr = readBundleFile(foundFileIdx); 825 840 841 // isSpl and isMask are mutually exclusive cases 826 842 isSpl = (strstr(animName, ".SPL")) ? 1 : 0; 827 843 isMask = (strstr(animName, ".MSK")) ? 1 : 0; 828 844 829 845 if (isSpl) { 830 846 width = (uint16) partBuffer[foundFileIdx].unpackedSize; 831 847 height = 1; 832 frame = 0;848 animHeader.numFrames = 1; 833 849 type = ANIM_RAW; 834 850 } else { 835 851 Common::MemoryReadStream readS(ptr, 0x16); … … 843 859 type = ANIM_MASK; 844 860 } else { 845 861 type = ANIM_MASKSPRITE; 862 } 863 } 846 864 847 loadRelatedPalette(animName); 848 transparentColor = getAnimTransparentColor(animName); 865 loadRelatedPalette(animName); 866 transparentColor = getAnimTransparentColor(animName); 867 // Make sure we load at least one frame and also that we 868 // don't overflow the animDataTable by writing beyond its end. 869 animHeader.numFrames = CLIP<uint16>(animHeader.numFrames, 1, NUM_MAX_ANIMDATA - currentAnim); 849 870 850 // special case transparency handling 851 if (!strcmp(animName, "L2202.ANI")) { 852 transparentColor = (frame < 2) ? 0 : 7; 853 } else if (!strcmp(animName, "L4601.ANI")) { 854 transparentColor = (frame < 1) ? 0xE : 0; 855 } 871 // Load the frames 872 for (frame = 0; frame < animHeader.numFrames; frame++) { 873 // special case transparency handling 874 if (!strcmp(animName, "L2202.ANI")) { 875 transparentColor = (frame < 2) ? 0 : 7; 876 } else if (!strcmp(animName, "L4601.ANI")) { 877 transparentColor = (frame < 1) ? 0xE : 0; 856 878 } 879 880 // Load a single frame 881 animDataTable[currentAnim + frame].load(ptr + frame * width * height, type, width, height, foundFileIdx, frame, name, transparentColor); 857 882 } 858 883 859 ptr += frame * width * height;860 currentPtr->load(ptr, type, width, height, foundFileIdx, frame, name, transparentColor);861 884 free(dataPtr); 862 885 } 863 886 864 887 loadPart(part); 888 889 // Make sure we jump over all the animation entries 890 fHandle.seek(fileStartPos + NUM_MAX_ANIMDATA * entrySize); 865 891 } 866 892 867 893 } // End of namespace Cine -
engines/cine/various.cpp
246 246 return true; 247 247 } 248 248 249 /*! \brief Savegame format detector 250 * \param fHandle Savefile to check 251 * \return Savegame format on success, ANIMSIZE_UNKNOWN on failure 252 * 253 * This function seeks through the savefile and tries to determine the 254 * savegame format it uses. There's a miniscule chance that the detection 255 * algorithm could get confused and think that the file uses both the older 256 * and the newer format but that is such a remote possibility that I wouldn't 257 * worry about it at all. 258 */ 259 enum CineSaveGameFormat detectSaveGameFormat(Common::SeekableReadStream &fHandle) { 260 // The animDataTable begins at savefile position 0x2315. 261 // Each animDataTable entry takes 23 bytes in older saves (Revisions 21772-31443) 262 // and 30 bytes in the save format after that (Revision 31444 and onwards). 263 // There are 255 entries in the animDataTable in both of the savefile formats. 264 static const uint animDataTableStart = 0x2315; 265 static const uint animEntriesCount = 255; 266 static const uint oldAnimEntrySize = 23; 267 static const uint newAnimEntrySize = 30; 268 static const uint defaultAnimEntrySize = newAnimEntrySize; 269 static const uint animEntrySizeChoices[] = {oldAnimEntrySize, newAnimEntrySize}; 270 Common::Array<uint> animEntrySizeMatches; 271 const uint32 prevStreamPos = fHandle.pos(); 272 273 // Try to walk through the savefile using different animDataTable entry sizes 274 // and make a list of all the successful entry sizes. 275 for (uint i = 0; i < ARRAYSIZE(animEntrySizeChoices); i++) { 276 // 206 = 2 * 50 * 2 + 2 * 3 (Size of global and object script entries) 277 // 20 = 4 * 2 + 2 * 6 (Size of overlay and background incrust entries) 278 static const uint sizeofScreenParams = 2 * 6; 279 static const uint globalScriptEntrySize = 206; 280 static const uint objectScriptEntrySize = 206; 281 static const uint overlayEntrySize = 20; 282 static const uint bgIncrustEntrySize = 20; 283 static const uint chainEntrySizes[] = { 284 globalScriptEntrySize, 285 objectScriptEntrySize, 286 overlayEntrySize, 287 bgIncrustEntrySize 288 }; 289 290 uint animEntrySize = animEntrySizeChoices[i]; 291 // Jump over the animDataTable entries and the screen parameters 292 uint32 newPos = animDataTableStart + animEntrySize * animEntriesCount + sizeofScreenParams; 293 // Check that there's data left after the point we're going to jump to 294 if (newPos >= fHandle.size()) { 295 continue; 296 } 297 fHandle.seek(newPos); 298 299 // Jump over the remaining items in the savegame file 300 // (i.e. the global scripts, object scripts, overlays and background incrusts). 301 bool chainWalkSuccess = true; 302 for (uint chainIndex = 0; chainIndex < ARRAYSIZE(chainEntrySizes); chainIndex++) { 303 // Read entry count and jump over the entries 304 int entryCount = fHandle.readSint16BE(); 305 newPos = fHandle.pos() + chainEntrySizes[chainIndex] * entryCount; 306 // Check that we didn't go past the end of file. 307 // Note that getting exactly to the end of file is acceptable. 308 if (newPos > fHandle.size()) { 309 chainWalkSuccess = false; 310 break; 311 } 312 fHandle.seek(newPos); 313 } 314 315 // If we could walk the chain successfully and 316 // got exactly to the end of file then we've got a match. 317 if (chainWalkSuccess && fHandle.pos() == fHandle.size()) { 318 // We found a match, let's save it 319 animEntrySizeMatches.push_back(animEntrySize); 320 } 321 } 322 323 // Check that we got only one entry size match. 324 // If we didn't, then return an error. 325 enum CineSaveGameFormat result = ANIMSIZE_UNKNOWN; 326 if (animEntrySizeMatches.size() == 1) { 327 const uint animEntrySize = animEntrySizeMatches[0]; 328 assert(animEntrySize == oldAnimEntrySize || animEntrySize == newAnimEntrySize); 329 if (animEntrySize == oldAnimEntrySize) { 330 result = ANIMSIZE_23; 331 } else { // animEntrySize == newAnimEntrySize 332 // Check data and mask pointers in all of the animDataTable entries 333 // to see whether we've got the version with the broken data and mask pointers or not. 334 // In the broken format all data and mask pointers were always zero. 335 static const uint relativeDataPos = 2 * 4; 336 bool pointersIntact = false; 337 for (uint i = 0; i < animEntriesCount; i++) { 338 fHandle.seek(animDataTableStart + i * animEntrySize + relativeDataPos); 339 uint32 data = fHandle.readUint32BE(); 340 uint32 mask = fHandle.readUint32BE(); 341 if (data != NULL || mask != NULL) { 342 pointersIntact = true; 343 break; 344 } 345 } 346 result = (pointersIntact ? ANIMSIZE_30_PTRS_INTACT : ANIMSIZE_30_PTRS_BROKEN); 347 } 348 } else if (animEntrySizeMatches.size() > 1) { 349 warning("Savegame format detector got confused by input data. Detecting savegame to be using an unknown format"); 350 } else { // animEtrySizeMatches.size() == 0 351 debug(3, "Savegame format detector was unable to detect savegame's format"); 352 } 353 354 fHandle.seek(prevStreamPos); 355 return result; 356 } 357 249 358 /*! \brief Restore script list item from savefile 250 * \param fHandle Savefile handle mopen for reading359 * \param fHandle Savefile handle open for reading 251 360 * \param isGlobal Restore object or global script? 252 361 */ 253 void loadScriptFromSave(Common:: InSaveFile *fHandle, bool isGlobal) {362 void loadScriptFromSave(Common::SeekableReadStream &fHandle, bool isGlobal) { 254 363 ScriptVars localVars, labels; 255 364 uint16 compare, pos; 256 365 int16 idx; 257 366 258 labels.load( *fHandle);259 localVars.load( *fHandle);367 labels.load(fHandle); 368 localVars.load(fHandle); 260 369 261 compare = fHandle ->readUint16BE();262 pos = fHandle ->readUint16BE();263 idx = fHandle ->readUint16BE();370 compare = fHandle.readUint16BE(); 371 pos = fHandle.readUint16BE(); 372 idx = fHandle.readUint16BE(); 264 373 265 374 // no way to reinitialize these 266 375 if (idx < 0) { … … 283 392 /*! \brief Restore overlay sprites from savefile 284 393 * \param fHandle Savefile open for reading 285 394 */ 286 void loadOverlayFromSave(Common:: InSaveFile&fHandle) {395 void loadOverlayFromSave(Common::SeekableReadStream &fHandle) { 287 396 overlay tmp; 288 397 289 398 fHandle.readUint32BE(); … … 299 408 overlayList.push_back(tmp); 300 409 } 301 410 302 /*! \brief Savefile format tester303 * \param fHandle Savefile to check304 *305 * This function seeks through savefile and tries to guess if it's the original306 * savegame format or broken format from ScummVM 0.10/0.11307 * The test is incomplete but this should cover 99.99% of cases.308 * If anyone makes a savefile which could confuse this test, assert will309 * report it310 */311 bool brokenSave(Common::InSaveFile &fHandle) {312 // Backward seeking not supported in compressed savefiles313 // if you really want it, finish it yourself314 return false;315 316 // fixed size part: 14093 bytes (12308 bytes in broken save)317 // animDataTable begins at byte 6431318 319 int filesize = fHandle.size();320 int startpos = fHandle.pos();321 int pos, tmp;322 bool correct = false, broken = false;323 324 // check for correct format325 while (filesize > 14093) {326 pos = 14093;327 328 fHandle.seek(pos);329 tmp = fHandle.readUint16BE();330 pos += 2 + tmp * 206;331 if (pos >= filesize) break;332 333 fHandle.seek(pos);334 tmp = fHandle.readUint16BE();335 pos += 2 + tmp * 206;336 if (pos >= filesize) break;337 338 fHandle.seek(pos);339 tmp = fHandle.readUint16BE();340 pos += 2 + tmp * 20;341 if (pos >= filesize) break;342 343 fHandle.seek(pos);344 tmp = fHandle.readUint16BE();345 pos += 2 + tmp * 20;346 347 if (pos == filesize) correct = true;348 break;349 }350 debug(5, "brokenSave: correct format check %s: size=%d, pos=%d",351 correct ? "passed" : "failed", filesize, pos);352 353 // check for broken format354 while (filesize > 12308) {355 pos = 12308;356 357 fHandle.seek(pos);358 tmp = fHandle.readUint16BE();359 pos += 2 + tmp * 206;360 if (pos >= filesize) break;361 362 fHandle.seek(pos);363 tmp = fHandle.readUint16BE();364 pos += 2 + tmp * 206;365 if (pos >= filesize) break;366 367 fHandle.seek(pos);368 tmp = fHandle.readUint16BE();369 pos += 2 + tmp * 20;370 if (pos >= filesize) break;371 372 fHandle.seek(pos);373 tmp = fHandle.readUint16BE();374 pos += 2 + tmp * 20;375 376 if (pos == filesize) broken = true;377 break;378 }379 debug(5, "brokenSave: broken format check %s: size=%d, pos=%d",380 broken ? "passed" : "failed", filesize, pos);381 382 // there's a very small chance that both cases will match383 // if anyone runs into it, you'll have to walk through384 // the animDataTable and try to open part file for each entry385 if (!correct && !broken) {386 error("brokenSave: file format check failed");387 } else if (correct && broken) {388 error("brokenSave: both file formats seem to apply");389 }390 391 fHandle.seek(startpos);392 debug(5, "brokenSave: detected %s file format",393 correct ? "correct" : "broken");394 395 return broken;396 }397 398 411 /*! \todo Implement Operation Stealth loading, this is obviously Future Wars only 399 412 * \todo Add support for loading the zoneQuery table (Operation Stealth specific) 400 413 */ 401 414 bool CineEngine::makeLoad(char *saveName) { 402 415 int16 i; 403 416 int16 size; 404 bool broken;405 Common::InSaveFile *fHandle;406 417 char bgName[13]; 407 418 408 fHandle = g_saveFileMan->openForLoading(saveName);419 Common::SharedPtr<Common::InSaveFile> saveFile(g_saveFileMan->openForLoading(saveName)); 409 420 410 if (! fHandle) {421 if (!saveFile) { 411 422 drawString(otherMessages[0], 0); 412 423 waitPlayerInput(); 413 424 // restoreScreen(); … … 415 426 return false; 416 427 } 417 428 429 uint32 saveSize = saveFile->size(); 430 if (saveSize == 0) { // Savefile's compressed using zlib format can't tell their unpacked size, test for it 431 // Can't get information about the savefile's size so let's try 432 // reading as much as we can from the file up to a predefined upper limit. 433 // 434 // Some estimates for maximum savefile sizes (All with 255 animDataTable entries of 30 bytes each): 435 // With 256 global scripts, object scripts, overlays and background incrusts: 436 // 0x2315 + (255 * 30) + (2 * 6) + (206 + 206 + 20 + 20) * 256 = ~129kB 437 // With 512 global scripts, object scripts, overlays and background incrusts: 438 // 0x2315 + (255 * 30) + (2 * 6) + (206 + 206 + 20 + 20) * 512 = ~242kB 439 // 440 // I think it extremely unlikely that there would be over 512 global scripts, object scripts, 441 // overlays and background incrusts so 256kB seems like quite a safe upper limit. 442 // NOTE: If the savegame format is changed then this value might have to be re-evaluated! 443 // Hopefully devices with more limited memory can also cope with this memory allocation. 444 saveSize = 256 * 1024; 445 } 446 Common::SharedPtr<Common::MemoryReadStream> fHandle(saveFile->readStream(saveSize)); 447 448 // Try to detect the used savegame format 449 enum CineSaveGameFormat saveGameFormat = detectSaveGameFormat(*fHandle); 450 451 // Handle problematic savegame formats 452 if (saveGameFormat == ANIMSIZE_30_PTRS_BROKEN) { 453 // One might be able to load the ANIMSIZE_30_PTRS_BROKEN format but 454 // that's not implemented here because it was never used in a stable 455 // release of ScummVM but only during development (From revision 31453, 456 // which introduced the problem, until revision 32073, which fixed it). 457 // Therefore be bail out if we detect this particular savegame format. 458 warning("Detected a known broken savegame format, not loading savegame"); 459 return false; 460 } else if (saveGameFormat == ANIMSIZE_UNKNOWN) { 461 // If we can't detect the savegame format 462 // then let's try the default format and hope for the best. 463 warning("Couldn't detect the used savegame format, trying default savegame format. Things may break"); 464 saveGameFormat = ANIMSIZE_30_PTRS_INTACT; 465 } 466 // Now we should have either of these formats 467 assert(saveGameFormat == ANIMSIZE_23 || saveGameFormat == ANIMSIZE_30_PTRS_INTACT); 468 418 469 g_sound->stopMusic(); 419 470 freeAnimDataTable(); 420 471 overlayList.clear(); … … 464 515 465 516 checkForPendingDataLoadSwitch = 0; 466 517 467 broken = brokenSave(*fHandle);468 518 469 519 // At savefile position 0x0000: 470 520 currentDisk = fHandle->readUint16BE(); … … 588 638 fHandle->readUint16BE(); 589 639 590 640 // At 0x2315: 591 loadResourcesFromSave(*fHandle, broken);641 loadResourcesFromSave(*fHandle, saveGameFormat); 592 642 593 643 // TODO: handle screen params (really required ?) 594 644 fHandle->readUint16BE(); … … 600 650 601 651 size = fHandle->readSint16BE(); 602 652 for (i = 0; i < size; i++) { 603 loadScriptFromSave( fHandle, true);653 loadScriptFromSave(*fHandle, true); 604 654 } 605 655 606 656 size = fHandle->readSint16BE(); 607 657 for (i = 0; i < size; i++) { 608 loadScriptFromSave( fHandle, false);658 loadScriptFromSave(*fHandle, false); 609 659 } 610 660 611 661 size = fHandle->readSint16BE(); … … 615 665 616 666 loadBgIncrustFromSave(*fHandle); 617 667 618 delete fHandle;619 620 668 if (strlen(currentMsgName)) { 621 669 loadMsg(currentMsgName); 622 670 } -
engines/cine/gfx.h
113 113 114 114 virtual void refreshPalette(); 115 115 virtual void reloadPalette(); 116 void restorePalette(Common:: InSaveFile&fHandle);116 void restorePalette(Common::SeekableReadStream &fHandle); 117 117 void savePalette(Common::OutSaveFile &fHandle); 118 118 virtual void rotatePalette(int a, int b, int c); 119 119 virtual void transformPalette(int first, int last, int r, int g, int b); -
engines/cine/gfx.cpp
614 614 /*! \brief Restore active and backup palette from save 615 615 * \param fHandle Savefile open for reading 616 616 */ 617 void FWRenderer::restorePalette(Common:: InSaveFile&fHandle) {617 void FWRenderer::restorePalette(Common::SeekableReadStream &fHandle) { 618 618 int i; 619 619 620 620 if (!_palette) { -
engines/cine/bg_list.h
51 51 52 52 void createBgIncrustListElement(int16 objIdx, int16 param); 53 53 void resetBgIncrustList(void); 54 void loadBgIncrustFromSave(Common:: InSaveFile&fHandle);54 void loadBgIncrustFromSave(Common::SeekableReadStream &fHandle); 55 55 56 56 } // End of namespace Cine 57 57 -
engines/cine/anim.h
101 101 void freeAnimDataRange(byte startIdx, byte numIdx); 102 102 void loadResource(const char *resourceName); 103 103 void loadAbs(const char *resourceName, uint16 idx); 104 void loadResourcesFromSave(Common:: InSaveFile &fHandle, bool broken);104 void loadResourcesFromSave(Common::SeekableReadStream &fHandle, enum CineSaveGameFormat saveGameFormat); 105 105 void generateMask(const byte *sprite, byte *mask, uint16 size, byte transparency); 106 106 107 107 } // End of namespace Cine -
engines/cine/various.h
33 33 34 34 namespace Cine { 35 35 36 /** 37 * Cine engine's save game formats. 38 * Enumeration entries (Excluding the one used as an error) 39 * are sorted according to age (i.e. top one is oldest, last one newest etc). 40 * 41 * ANIMSIZE_UNKNOWN: 42 * - Animation data entry size is unknown (Used as an error). 43 * 44 * ANIMSIZE_23: 45 * - Animation data entry size is 23 bytes. 46 * - Used at least by 0.11.0 and 0.11.1 releases of ScummVM. 47 * - Introduced in revision 21772, stopped using in revision 31444. 48 * 49 * ANIMSIZE_30_PTRS_BROKEN: 50 * - Animation data entry size is 30 bytes. 51 * - Data and mask pointers in the saved structs are always NULL. 52 * - Introduced in revision 31453, stopped using in revision 32073. 53 * 54 * ANIMSIZE_30_PTRS_INTACT: 55 * - Animation data entry size is 30 bytes. 56 * - Data and mask pointers in the saved structs are intact, 57 * so you can test them for equality or inequality with NULL 58 * but don't try using them for anything else, it won't work. 59 * - Introduced in revision 31444, got broken in revision 31453, 60 * got fixed in revision 32073 and used after that. 61 */ 62 enum CineSaveGameFormat { 63 ANIMSIZE_UNKNOWN, 64 ANIMSIZE_23, 65 ANIMSIZE_30_PTRS_BROKEN, 66 ANIMSIZE_30_PTRS_INTACT 67 }; 68 36 69 void initLanguage(Common::Language lang); 37 70 38 71 int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, uint16 width, bool recheckValue = false);