Ticket #8452: scumm_info_v7.patch

File scumm_info_v7.patch, 10.7 KB (added by lordhoto, 16 years ago)

Patch V7 against anon CVS from yesterday

  • scumm/dialogs.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/dialogs.cpp ./scummvm/scumm/dialogs.cpp
    old new  
    2121#include "common/stdafx.h"
    2222
    2323#include "common/config-manager.h"
     24#include "common/savefile.h"
    2425#include "common/system.h"
    2526#include "common/scaler.h"
    2627
     
    193194
    194195#pragma mark -
    195196
     197Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode);
     198
    196199enum {
    197200        kSaveCmd = 'SAVE',
    198201        kLoadCmd = 'LOAD',
     
    271274        GUI::ListWidget         *_list;
    272275        GUI::ButtonWidget       *_chooseButton;
    273276        GUI::GraphicsWidget     *_gfxWidget;
     277        GUI::StaticTextWidget   *_date;
     278        GUI::StaticTextWidget   *_time;
     279        GUI::StaticTextWidget   *_playtime;
    274280        ScummEngine                     *_scumm;
    275281
    276282public:
     
    300306                        ((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1) + 8);
    301307        _gfxWidget->setFlags(GUI::WIDGET_BORDER);
    302308
     309        int height = 18 + ((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1) + 8;
     310
     311        _date = new StaticTextWidget(this,
     312                                        _w - (kThumbnailWidth + 22),
     313                                        height,
     314                                        kThumbnailWidth + 8,
     315                                        kLineHeight,
     316                                        "No date saved",
     317                                        kTextAlignCenter);
     318        _date->setFlags(GUI::WIDGET_CLEARBG);
     319
     320        height += kLineHeight;
     321
     322        _time = new StaticTextWidget(this,
     323                                        _w - (kThumbnailWidth + 22),
     324                                        height,
     325                                        kThumbnailWidth + 8,
     326                                        kLineHeight,
     327                                        "No time saved",
     328                                        kTextAlignCenter);
     329        _time->setFlags(GUI::WIDGET_CLEARBG);
     330
     331        height += kLineHeight;
     332
     333        _playtime = new StaticTextWidget(this,
     334                                        _w - (kThumbnailWidth + 22),
     335                                        height,
     336                                        kThumbnailWidth + 8,
     337                                        kLineHeight,
     338                                        "No playtime saved",
     339                                        kTextAlignCenter);
     340        _playtime->setFlags(GUI::WIDGET_CLEARBG);
     341
    303342        // Buttons
    304343        addButton(this, _w - 2 * (kBigButtonWidth + 10), _h - kBigButtonHeight - 8, "Cancel", kCloseCmd, 0, GUI::kBigWidgetSize);
    305344        _chooseButton = addButton(this, _w - (kBigButtonWidth + 10), _h - kBigButtonHeight - 8, buttonLabel, kChooseCmd, 0, GUI::kBigWidgetSize);
     
    342381                Graphics::Surface *thumb;
    343382                thumb = _scumm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem);
    344383                _gfxWidget->setGfx(thumb);
     384                if (thumb)
     385                        thumb->free();
    345386                delete thumb;
    346387                _gfxWidget->draw();
     388
     389                InfoStuff infos;
     390                memset(&infos, 0, sizeof(InfoStuff));
     391                char buffer[32];
     392                if (_scumm->loadInfosFromSlot(_saveMode ? selItem + 1 : selItem, &infos)) {
     393                        snprintf(buffer, 32, "Date: %.2d.%.2d.%.4d",
     394                                (infos.date >> 24) & 0xFF, (infos.date >> 16) & 0xFF,
     395                                infos.date & 0xFFFF);
     396                        _date->setLabel(buffer);
     397                        _date->draw();
     398                       
     399                        snprintf(buffer, 32, "Time: %.2d:%.2d",
     400                                (infos.time >> 8) & 0xFF, infos.time & 0xFF);
     401                        _time->setLabel(buffer);
     402                        _time->draw();
     403
     404                        int minutes = infos.playtime / 60;
     405                        int hours = minutes / 60;
     406                        minutes %= 60;
     407
     408                        snprintf(buffer, 32, "Playtime: %.2d:%.2d",
     409                                hours & 0xFF, minutes & 0xFF);
     410                        _playtime->setLabel(buffer);
     411                        _playtime->draw();
     412                } else {
     413                        snprintf(buffer, 32, "No date saved");
     414                        _date->setLabel(buffer);
     415                        _date->draw();
     416                       
     417                        snprintf(buffer, 32, "No time saved");
     418                        _time->setLabel(buffer);
     419                        _time->draw();
     420
     421                        snprintf(buffer, 32, "No playtime saved");
     422                        _playtime->setLabel(buffer);
     423                        _playtime->draw();
     424                }
    347425
    348426                if (_saveMode) {
    349427                        _list->startEditMode();
  • scumm/saveload.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/saveload.cpp ./scummvm/scumm/saveload.cpp
    old new  
    5151        char name[32];
    5252};
    5353
     54#if !defined(__GNUC__)
     55        #pragma START_PACK_STRUCTS
     56#endif
     57
     58struct SaveInfoSection {
     59        uint32 type;
     60        uint32 version;
     61        uint32 size;
     62       
     63        uint32 timeTValue;
     64        uint32 playtime;
     65} GCC_PACK;
     66
     67#if !defined(__GNUC__)
     68        #pragma END_PACK_STRUCTS
     69#endif
     70
     71#define INFOSECTION_VERSION 1
    5472
    5573void ScummEngine::requestSave(int slot, const char *name, bool temporary) {
    5674        _saveLoadSlot = slot;
     
    84102
    85103        out->write(&hdr, sizeof(hdr));
    86104        saveThumbnail(out);
     105        saveInfos(out);
    87106
    88107        Serializer ser(0, out, CURRENT_VER);
    89108        saveOrLoad(&ser, CURRENT_VER);
     
    144163                in->skip(size - 8);
    145164        }
    146165
     166        // Since version 56 we have informations about the creation of the save game and the save time here
     167        if (hdr.ver >= VER(56)) {
     168                InfoStuff infos;
     169                if (!loadInfos(in, &infos)) {
     170                        warning("Info section could not be found");
     171                        delete in;
     172                        return false;
     173                }
     174
     175                _engineStartTime = _system->getMillis() / 1000 - infos.playtime;
     176        } else {
     177                // start time counting
     178                _engineStartTime = _system->getMillis() / 1000;
     179        }
     180
     181        _dialogStartTime = _system->getMillis() / 1000;
     182
    147183        // Due to a bug in scummvm up to and including 0.3.0, save games could be saved
    148184        // in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here
    149185        if (hdr.ver == VER(7))
     
    359395
    360396        _sound->pauseSounds(false);
    361397
     398        _engineStartTime += _system->getMillis() / 1000 - _dialogStartTime;
     399        _dialogStartTime = 0;
     400
    362401        return true;
    363402}
    364403
     
    438477
    439478        delete in;
    440479        return thumb;
     480}
     481
     482bool ScummEngine::loadInfosFromSlot(int slot, InfoStuff *stuff) {
     483        char filename[256];
     484        Common::InSaveFile *in;
     485        SaveGameHeader hdr;
     486        int len;
     487
     488        makeSavegameName(filename, slot, false);
     489        if (!(in = _saveFileMan->openForLoading(filename))) {
     490                return false;
     491        }
     492        len = in->read(&hdr, sizeof(hdr));
     493
     494        if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) {
     495                delete in;
     496                return false;
     497        }
     498
     499        if (hdr.ver > CURRENT_VER)
     500                hdr.ver = TO_LE_32(hdr.ver);
     501        if (hdr.ver < VER(56)) {
     502                delete in;
     503                return false;
     504        }
     505
     506        uint32 type;
     507        in->read(&type, 4);
     508
     509        // Check for the THMB header. Also, work around a bug which caused
     510        // the chunk type (incorrectly) to be written in LE on LE machines.
     511        if (! (type == MKID('THMB') || (hdr.ver < VER(55) && type == MKID('BMHT')))){
     512                delete in;
     513                return false;
     514        }
     515        uint32 size = in->readUint32BE();
     516        in->skip(size - 8);
     517
     518        if (!loadInfos(in, stuff)) {
     519                delete in;
     520                return false;
     521        }
     522       
     523        delete in;     
     524        return true;
     525}
     526
     527bool ScummEngine::loadInfos(Common::InSaveFile *file, InfoStuff *stuff) {
     528        memset(stuff, 0, sizeof(InfoStuff));
     529
     530        SaveInfoSection section;
     531        file->read(&section.type, 4);
     532        if (section.type != MKID('INFO')) {
     533                return false;
     534        }
     535
     536        section.version = file->readUint32BE();
     537        section.size = file->readUint32BE();
     538
     539        // if we extend this we should add a table for the special sizes at the versions to check it
     540        if (section.version == INFOSECTION_VERSION && section.size != sizeof(SaveInfoSection)) {
     541                warning("Info section is corrupt");
     542                file->skip(section.size);
     543                return false;
     544        }
     545
     546        section.timeTValue = file->readUint32BE();
     547        section.playtime = file->readUint32BE();
     548
     549        time_t curTime_ = section.timeTValue;
     550        tm *curTime = localtime(&curTime_);     
     551        stuff->date = (curTime->tm_mday & 0xFF) << 24 | ((curTime->tm_mon + 1) & 0xFF) << 16 | (curTime->tm_year + 1900) & 0xFFFF;
     552        stuff->time = (curTime->tm_hour & 0xFF) << 8 | (curTime->tm_min) & 0xFF;
     553        stuff->playtime = section.playtime;
     554
     555        // if we extend the header we should check here for the version
     556        // e.g.:
     557        // if (header.version == 2) {
     558        //      // load some things here
     559        // }
     560        //
     561        // if (header.version == 3) {
     562        //      // ...
     563        // }
     564        // and so on...
     565
     566        // skip all newer features, this could make problems if some older version uses more space for
     567        // saving informations, but this should NOT happen
     568        if (section.size > sizeof(SaveInfoSection)) {
     569                file->skip(section.size - sizeof(SaveInfoSection));
     570        }
     571
     572        return true;
     573}
     574
     575void ScummEngine::saveInfos(Common::OutSaveFile* file) {
     576        SaveInfoSection section;
     577        section.type = MKID('INFO');
     578        section.version = INFOSECTION_VERSION;
     579        section.size = sizeof(SaveInfoSection);
     580
     581        section.timeTValue = time(0);
     582        section.playtime = _system->getMillis() / 1000 - _engineStartTime;
     583
     584        file->write(&section.type, 4);
     585        file->writeUint32BE(section.version);
     586        file->writeUint32BE(section.size);
     587        file->writeUint32BE(section.timeTValue);
     588        file->writeUint32BE(section.playtime);
    441589}
    442590
    443591void ScummEngine::saveOrLoad(Serializer *s, uint32 savegameVersion) {
  • scumm/saveload.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/saveload.h ./scummvm/scumm/saveload.h
    old new  
    4545 * only saves/loads those which are valid for the version of the savegame
    4646 * which is being loaded/saved currently.
    4747 */
    48 #define CURRENT_VER 55
     48#define CURRENT_VER 56
    4949
    5050/**
    5151 * An auxillary macro, used to specify savegame versions. We use this instead
  • scumm/scumm.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/scumm.cpp ./scummvm/scumm/scumm.cpp
    old new  
    21092109#pragma mark -
    21102110
    21112111int ScummEngine::go() {
     2112        _engineStartTime = _system->getMillis() / 1000;
     2113
    21122114        // If requested, load a save game instead of running the boot script
    21132115        if (_saveLoadFlag != 2 || !loadState(_saveLoadSlot, _saveTemporaryState)) {
    21142116                int args[16];
     
    25502552#pragma mark -
    25512553
    25522554int ScummEngine::runDialog(Dialog &dialog) {
     2555        _dialogStartTime = _system->getMillis() / 1000;
     2556
    25532557        // Pause sound & video
    25542558        bool old_soundsPaused = _sound->_soundsPaused;
    25552559        _sound->pauseSounds(true);
     
    25652569        // Resume sound & video
    25662570        _sound->pauseSounds(old_soundsPaused);
    25672571        _smushPaused = oldSmushPaused;
     2572
     2573        _engineStartTime += (_system->getMillis() / 1000) - _dialogStartTime;
     2574        _dialogStartTime = 0;
    25682575
    25692576        // Return the result
    25702577        return result;
  • scumm/scumm.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/scumm.h ./scummvm/scumm/scumm.h
    old new  
    309309        int subIndex;
    310310};
    311311
     312struct InfoStuff {
     313        uint32 date;
     314        uint16 time;
     315        uint32 playtime;
     316};
     317
    312318class ResourceManager {
    313319        friend class ScummDebugger;
    314320        friend class ScummEngine;
     
    583589        void requestSave(int slot, const char *name, bool temporary = false);
    584590        void requestLoad(int slot);
    585591
    586 // thumbnail stuff
     592// thumbnail + info stuff
    587593public:
    588594        Graphics::Surface *loadThumbnailFromSlot(int slot);
     595        bool loadInfosFromSlot(int slot, InfoStuff *stuff);
    589596
    590597protected:
    591598        Graphics::Surface *loadThumbnail(Common::InSaveFile *file);
     599        bool loadInfos(Common::InSaveFile *file, InfoStuff *stuff);
    592600        void saveThumbnail(Common::OutSaveFile *file);
     601        void saveInfos(Common::OutSaveFile* file);
     602
     603        int32 _engineStartTime;
     604        int32 _dialogStartTime;
    593605
    594606protected:
    595607        /* Script VM - should be in Script class */