Ticket #8981: save-iq-on-change.patch

File save-iq-on-change.patch, 5.8 KB (added by SF/tobigun, 15 years ago)

Save on IQ change

  • engines/scumm/input.cpp

     
    429429                // SCUMM var 244 is the episode score
    430430                // and var 245 is the series score
    431431                char text[50];
    432 
    433                 // FIXME: Currently, the series score does not work properly
    434                 // This workaround just sets it equal to the episode score
    435                 // However, at the end of the game, it does show the episode
    436                 // score by itself
    437                 int a = _scummVars[245];
    438                 if (!a)
    439                         a = _scummVars[244];
    440 
    441                 sprintf(text, "IQ Points: Episode = %d, Series = %d", _scummVars[244], a);
     432               
     433                updateIQPoints();
     434               
     435                sprintf(text, "IQ Points: Episode = %d, Series = %d", _scummVars[244], _scummVars[245]);
    442436                Indy3IQPointsDialog indy3IQPointsDialog(this, text);
    443437                runDialog(indy3IQPointsDialog);
    444438        }
  • engines/scumm/intern.h

     
    7878
    7979        virtual void scummLoop_handleActors();
    8080
     81        virtual void scummLoop_handleSaveLoad();
     82
    8183        virtual void setupScummVars();
    8284        virtual void resetScummVars();
    8385        virtual void decodeParseString();
     
    8991        int getWordVararg(int *ptr);
    9092        void saveVars();
    9193        void loadVars();
     94
    9295        void saveIQPoints();
    93         void loadIQPoints();
     96        void loadIQPoints(byte *ptr, int size);
     97        void updateIQPoints();
    9498
    9599        virtual int getVar();
    96100        virtual int getVarOrDirectByte(byte mask);
  • engines/scumm/script_v5.cpp

     
    948948                        if (a == STRINGID_IQ_SERIES && b == STRINGID_IQ_SERIES) {
    949949                                // Zak256 loads the IQ script-slot but does not use it -> ignore it
    950950                                if (_game.id == GID_INDY3) {
    951                                         loadIQPoints();
     951                                        byte *ptr = getResourceAddress(rtString, STRINGID_IQ_SERIES);           
     952                                        if (ptr) {
     953                                                int size = getResourceSize(rtString, STRINGID_IQ_SERIES);
     954                                                loadIQPoints(ptr, size);
     955                                        }
    952956                                }
    953957                                break;
    954958                        }
     
    995999        }
    9961000}
    9971001
     1002/**
     1003 * IQ Point calculation for Indy3.
     1004 * The scripts that perform this task are
     1005 * - script-9 (save/load dialog initialization, loads room 14),
     1006 * - room-14-204 (load series IQ string),
     1007 * - room-14-205 (save series IQ string),
     1008 * - room-14-206 (calculate series IQ string).
     1009 * Unfortunately script-9 contains lots of GUI stuff so calling this script
     1010 * directly is not possible. The other scripts depend on script-9.
     1011 */
     1012void ScummEngine_v5::updateIQPoints() {
     1013        int seriesIQ;
     1014        int episodeIQStringSize;
     1015        byte *episodeIQString;
     1016        byte seriesIQString[73];
     1017
     1018        // load string with IQ points given per puzzle in any savegame
     1019        // IMPORTANT: the resource string STRINGID_IQ_SERIES is only valid while
     1020        // the original save/load dialog is executed, so do not use it here.
     1021        memset(seriesIQString, 0, sizeof(seriesIQString));
     1022        loadIQPoints(seriesIQString, sizeof(seriesIQString));
     1023
     1024        // string with IQ points given per puzzle in current savegame
     1025        episodeIQString = getResourceAddress(rtString, STRINGID_IQ_EPISODE);
     1026        if (!episodeIQString)
     1027                return;
     1028        episodeIQStringSize = getResourceSize(rtString, STRINGID_IQ_EPISODE);
     1029        if (episodeIQStringSize < 73)
     1030                return;
     1031
     1032        // merge episode and series IQ strings and calculate series IQ
     1033        seriesIQ = 0;
     1034        // iterate over puzzles (each of the first 73 bytes corresponds to a puzzle's IQ)
     1035        for (int i = 0; i < 73 ; ++i) {
     1036                char puzzleIQ = seriesIQString[i];
     1037                // if puzzle is solved copy points to episode string
     1038                if (puzzleIQ > 0)
     1039                        episodeIQString[i] = puzzleIQ;
     1040                // add puzzle's IQ-points to series IQ
     1041                seriesIQ += episodeIQString[i];
     1042        }
     1043        _scummVars[245] = seriesIQ;
     1044
     1045        // save series IQ string
     1046        saveIQPoints();
     1047}
     1048
    9981049void ScummEngine_v5::saveIQPoints() {
    9991050        // save Indy3 IQ-points
    10001051        Common::OutSaveFile *file;
     
    10021053
    10031054        file = _saveFileMan->openForSaving(filename.c_str());
    10041055        if (file != NULL) {
    1005                 int size = getResourceSize(rtString, STRINGID_IQ_EPISODE);
    10061056                byte *ptr = getResourceAddress(rtString, STRINGID_IQ_EPISODE);
    1007                 file->write(ptr, size);
     1057                if (ptr) {
     1058                        int size = getResourceSize(rtString, STRINGID_IQ_EPISODE);
     1059                        file->write(ptr, size);
     1060                }
    10081061                delete file;
    10091062        }
    10101063}
    10111064
    1012 void ScummEngine_v5::loadIQPoints() {
     1065void ScummEngine_v5::loadIQPoints(byte *ptr, int size) {
    10131066        // load Indy3 IQ-points
    10141067        Common::InSaveFile *file;
    10151068        Common::String filename = _targetName + ".iq";
    10161069
    10171070        file = _saveFileMan->openForLoading(filename.c_str());
    10181071        if (file != NULL) {
    1019                 int size = getResourceSize(rtString, STRINGID_IQ_SERIES);
    1020                 byte *ptr = getResourceAddress(rtString, STRINGID_IQ_SERIES);
    10211072                byte *tmp = (byte*)malloc(size);
    10221073                int nread = file->read(tmp, size);
    10231074                if (nread == size) {
     
    23702421        }
    23712422
    23722423        runScript(script, (op & 0x20) != 0, (op & 0x40) != 0, data);
     2424
     2425        // WORKAROUND: Indy3 does not save the series IQ automatically after changing it.
     2426        // Save on IQ increment (= script 125 was executed).
     2427        if (_game.id == GID_INDY3 && script == 125)
     2428                updateIQPoints();
    23732429}
    23742430
    23752431void ScummEngine_v5::o5_stopObjectCode() {
  • engines/scumm/scumm.cpp

     
    20682068        }
    20692069}
    20702070
     2071void ScummEngine_v5::scummLoop_handleSaveLoad() {
     2072        byte saveLoad = (_saveLoadFlag != 0);
     2073
     2074        ScummEngine::scummLoop_handleSaveLoad();
     2075
     2076        // update IQ points after loading
     2077        if (saveLoad == 2) {
     2078                if (_game.id == GID_INDY3)
     2079                        updateIQPoints();
     2080                if (_game.id == GID_INDY4)
     2081                        runScript(145, 0, 0, 0);
     2082        }
     2083}
     2084
    20712085#ifdef ENABLE_SCUMM_7_8
    20722086void ScummEngine_v8::scummLoop_handleSaveLoad() {
    20732087        ScummEngine::scummLoop_handleSaveLoad();