Ticket #8405: thumbnail-v4.patch

File thumbnail-v4.patch, 27.9 KB (added by lordhoto, 16 years ago)

new standalone patch

  • backends/sdl/graphics.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/backends/sdl/graphics.cpp ./scummvm/backends/sdl/graphics.cpp
    old new  
    720720        }
    721721}
    722722
     723void OSystem_SDL::grabScreen(byte* buf) {
     724        assert(buf); assert(_screen);
     725        Common::StackLock lock(_graphicsMutex);
     726       
     727        memcpy(buf, _screen->pixels, sizeof(byte) * _screenWidth * _screenHeight);     
     728}
     729
    723730void OSystem_SDL::clearScreen() {
    724731        assert (_transactionMode == kTransactionNone);
    725732
  • backends/sdl/sdl-common.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/backends/sdl/sdl-common.h ./scummvm/backends/sdl/sdl-common.h
    old new  
    6767        // The screen will not be updated to reflect the new bitmap
    6868        void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h);
    6969
     70        // Copies the screen to a buffer
     71        void grabScreen(byte *buf);
     72
    7073        // Clear the screen
    7174        void clearScreen();
    7275
  • common/module.mk

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/common/module.mk ./scummvm/common/module.mk
    old new  
    2121        common/scaler/hq3x.o \
    2222        common/scaler/scale2x.o \
    2323        common/scaler/scale3x.o \
    24         common/scaler/scalebit.o
     24        common/scaler/scalebit.o \
     25        common/scaler/thumbnail.o
    2526
    2627ifdef HAVE_NASM
    2728MODULE_OBJS += \
  • common/scaler/thumbnail.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/common/scaler/thumbnail.cpp ./scummvm/common/scaler/thumbnail.cpp
    old new  
     1/* ScummVM - Scumm Interpreter
     2 * Copyright (C) 2001  Ludvig Strigeus
     3 * Copyright (C) 2001-2005 The ScummVM project
     4 *
     5 * This program is free software; you can redistribute it and/or
     6 * modify it under the terms of the GNU General Public License
     7 * as published by the Free Software Foundation; either version 2
     8 * of the License, or (at your option) any later version.
     9
     10 * This program is distributed in the hope that it will be useful,
     11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 * GNU General Public License for more details.
     14
     15 * You should have received a copy of the GNU General Public License
     16 * along with this program; if not, write to the Free Software
     17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 *
     19 * $Header: $
     20 *
     21 */
     22
     23#include "stdafx.h"
     24#include "common/scummsys.h"
     25#include "scaler.h"
     26#include "scaler/intern.h"
     27
     28template<int bitFormat>
     29void createThumbnail_2(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) {
     30        for (int y = 0; y < height; y += 2) {
     31                for (int x = 0; x < width; x += 2, dstPtr += 2) {
     32                        uint16 colorx1y1 = *(((const uint16*)src) + x);
     33                        uint16 colorx2y1 = *(((const uint16*)src) + x + 1);
     34                       
     35                        uint16 colorx1y2 = *(((const uint16*)(src + srcPitch)) + x);
     36                        uint16 colorx2y2 = *(((const uint16*)(src + srcPitch)) + x + 1);
     37                               
     38                        *((uint16*)dstPtr) = Q_INTERPOLATE<bitFormat>(colorx1y1, colorx2y1, colorx1y2, colorx2y2);                     
     39                }
     40                dstPtr += (dstPitch - 320);
     41                src += 2 * srcPitch;
     42        }
     43}
     44
     45template<int bitFormat>
     46void createThumbnail_4(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) {
     47        for (int y = 0; y < height; y += 4) {
     48                for (int x = 0; x < width; x += 4, dstPtr += 2) {
     49                        uint16 colorx1y1 = *(((const uint16*)src) + x);
     50                        uint16 colorx2y1 = *(((const uint16*)src) + x + 1);
     51                        uint16 colorx3y1 = *(((const uint16*)src) + x + 2);
     52                        uint16 colorx4y1 = *(((const uint16*)src) + x + 3);
     53                       
     54                        uint16 colorx1y2 = *(((const uint16*)(src + srcPitch)) + x);
     55                        uint16 colorx2y2 = *(((const uint16*)(src + srcPitch)) + x + 1);
     56                        uint16 colorx3y2 = *(((const uint16*)(src + srcPitch)) + x + 2);
     57                        uint16 colorx4y2 = *(((const uint16*)(src + srcPitch)) + x + 3);
     58                       
     59                        uint16 colorx1y3 = *(((const uint16*)(src + srcPitch * 2)) + x);
     60                        uint16 colorx2y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 1);
     61                        uint16 colorx3y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 2);
     62                        uint16 colorx4y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 3);
     63                       
     64                        uint16 colorx1y4 = *(((const uint16*)(src + srcPitch * 3)) + x);
     65                        uint16 colorx2y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 1);
     66                        uint16 colorx3y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 2);
     67                        uint16 colorx4y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 3);
     68                               
     69                        uint16 upleft = Q_INTERPOLATE<bitFormat>(colorx1y1, colorx2y1, colorx1y2, colorx2y2);
     70                        uint16 upright = Q_INTERPOLATE<bitFormat>(colorx3y1, colorx4y1, colorx3y2, colorx4y2);
     71                        uint16 downleft = Q_INTERPOLATE<bitFormat>(colorx1y3, colorx2y3, colorx1y4, colorx2y4);
     72                        uint16 downright = Q_INTERPOLATE<bitFormat>(colorx3y3, colorx4y3, colorx3y4, colorx4y4);
     73                               
     74                        *((uint16*)dstPtr) = Q_INTERPOLATE<bitFormat>(upleft, upright, downleft, downright);                   
     75                }
     76                dstPtr += (dstPitch - 320);
     77                src += 4 * srcPitch;
     78        }
     79}
     80
     81void createThumbnail(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) {
     82        // only 1/2 and 1/4 downscale supported
     83        if(width != 320 && width != 640)
     84                return;
     85               
     86        const int downScaleMode = (width == 320) ? 2 : 4;
     87       
     88        if(downScaleMode == 2) {
     89                createThumbnail_2<565>(src, srcPitch, dstPtr, dstPitch, width, height);
     90        } else if(downScaleMode == 4) {
     91                createThumbnail_4<565>(src, srcPitch, dstPtr, dstPitch, width, height);
     92        }
     93}
  • common/scaler.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/common/scaler.h ./scummvm/common/scaler.h
    old new  
    5959
    6060extern int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY);
    6161
     62// creates a 160x100 thumbnail for 320x200 games
     63// and 160x120 thumbnail for 320x240 and 640x480 games
     64// only 565 mode
     65enum {
     66        kThumbnailWidth = 160,
     67        kThumbnailHeight_1 = 100,
     68        kThumbnailHeight_2 = 120
     69};
     70extern void createThumbnail(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height);
     71
    6272enum {
    6373        GFX_NORMAL = 0,
    6474        GFX_DOUBLESIZE = 1,
  • common/system.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/common/system.h ./scummvm/common/system.h
    old new  
    357357         * @see updateScreen
    358358         */
    359359        virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) = 0;
     360
     361        /**
     362         * Copies the screen to a buffer
     363         */
     364        virtual void grabScreen(byte *buf) {}
    360365       
    361366        /**
    362367         * Clear the screen to black.
  • gui/newgui.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/gui/newgui.cpp ./scummvm/gui/newgui.cpp
    old new  
    2121#include "stdafx.h"
    2222#include "common/system.h"
    2323#include "common/util.h"
     24#include "common/scaler.h"
    2425#include "gui/newgui.h"
    2526#include "gui/dialog.h"
    2627
     
    437438}
    438439
    439440//
     441// Copies a Surface to the Overlay
     442//
     443void NewGui::drawSurface(const OverlayColor* data, int x, int y, int width, int height, int pitch) {
     444        if(_scaleFactor == 1) {
     445                uint8* dst = (uint8*)getBasePtr(x, y); 
     446                for (int y_ = 0; y_ < height; ++y_, dst += _screen.pitch) {
     447                        memcpy(dst, &((const uint8*)data)[y_ * pitch], width * sizeof(OverlayColor));
     448                }
     449        } else if(_scaleFactor == 2) {
     450                Normal2x((const uint8*)data, pitch, (uint8*)getBasePtr(x * 2, y * 2), _screen.pitch, width, height);
     451        }       
     452        addDirtyRect(x, y, width, height);
     453}
     454
     455//
    440456// Draw the mouse cursor (animated). This is mostly ripped from the cursor code in gfx.cpp
    441457// We could plug in a different cursor here if we like to.
    442458//
  • gui/newgui.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/gui/newgui.h ./scummvm/gui/newgui.h
    old new  
    146146        int getFontHeight() const;
    147147
    148148        void drawBitmap(uint32 *bitmap, int x, int y, OverlayColor color, int h = 8);
     149        void drawSurface(const OverlayColor* data, int x, int y, int width, int height, int pitch);
    149150
    150151        void addDirtyRect(int x, int y, int w, int h);
    151152};
  • gui/widget.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/gui/widget.cpp ./scummvm/gui/widget.cpp
    old new  
    2424#include "gui/dialog.h"
    2525#include "gui/newgui.h"
    2626
    27 
    2827namespace GUI {
    2928
    3029Widget::Widget(GuiObject *boss, int x, int y, int w, int h)
     
    260259        return (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin;
    261260}
    262261
     262#pragma mark -
     263
     264GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h)
     265        : Widget(boss, x, y, w, h), _gfx(0), _gfxWidth(0), _gfxHeight(0), _bpp(0) {
     266        _flags = WIDGET_ENABLED | WIDGET_CLEARBG;
     267        _type = kGraphicsWidget;
     268}
     269
     270GraphicsWidget::~GraphicsWidget() {
     271        delete [] _gfx;
     272}
     273
     274void GraphicsWidget::setGfx(int width, int height, int bpp, const uint8 *data) {
     275        delete [] _gfx;
     276        _gfx = 0;
     277       
     278        if(!data)
     279                return;
     280       
     281        _gfx = new uint8[width * height * bpp];
     282        assert(_gfx);
     283       
     284        _gfxWidth = width;
     285        _gfxHeight = height;
     286        _bpp = bpp;
     287
     288        memcpy(_gfx, data, width * height * bpp);
     289}
     290
     291void GraphicsWidget::drawWidget(bool hilite) {
     292        if(sizeof(OverlayColor) != _bpp || !_gfx) {
     293                g_gui.drawString("No preview", _x, _y + _h / 2 - g_gui.getFontHeight() / 2, _w, g_gui._textcolor, Graphics::kTextAlignCenter);
     294                return;
     295        }
     296       
     297        uint drawWidth = _gfxWidth, drawHeight = _gfxHeight;
     298       
     299        if(_w < _gfxWidth)
     300                drawWidth = _w;
     301        if(_h < _gfxHeight)
     302                drawHeight = _h;
     303       
     304        g_gui.drawSurface((OverlayColor*)_gfx, _x, _y, drawWidth, drawHeight, _gfxWidth * _bpp);
     305}
     306
    263307} // End of namespace GUI
  • gui/widget.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/gui/widget.h ./scummvm/gui/widget.h
    old new  
    5252        kListWidget                     = 'LIST',
    5353        kScrollBarWidget        = 'SCRB',
    5454        kPopUpWidget            = 'POPU',
    55         kTabWidget                      = 'TABW'
     55        kTabWidget                      = 'TABW',
     56        kGraphicsWidget         = 'GFXW'
    5657};
    5758
    5859enum {
     
    210211        int posToValue(int pos);
    211212};
    212213
     214/* GraphicsWidget */
     215class GraphicsWidget : public Widget {
     216public:
     217        GraphicsWidget(GuiObject *boss, int x, int y, int w, int h);
     218        ~GraphicsWidget();
     219       
     220        // bpp = _byte_ per pixel
     221        void setGfx(int width, int height, int bpp, const uint8 *data);
     222protected:
     223        void drawWidget(bool hilite);
     224       
     225        uint8 *_gfx;
     226        int _gfxWidth, _gfxHeight, _bpp;
     227};
     228
    213229} // End of namespace GUI
    214230
    215231#endif
  • scumm/dialogs.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/dialogs.cpp ./scummvm/scumm/dialogs.cpp
    old new  
    2222
    2323#include "common/config-manager.h"
    2424#include "common/system.h"
     25#include "common/scaler.h"
    2526
    2627#include "gui/chooser.h"
    2728#include "gui/newgui.h"
     
    147148
    148149#pragma mark -
    149150
    150 
    151151const Common::String ScummDialog::queryResString(int stringno) {
    152152        byte buf[256];
    153153        byte *result;
     
    199199        kQuitCmd = 'QUIT'
    200200};
    201201
    202 class SaveLoadChooser : public GUI::ChooserDialog {
     202class SaveLoadChooser : public GUI::ChooserDialog, public ScummSaveLoadChooser {
    203203        typedef Common::String String;
    204204        typedef Common::StringList StringList;
    205205protected:
     
    210210       
    211211        virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
    212212        const String &getResultString() const;
     213        void setList(const StringList& list) { GUI::ChooserDialog::setList(list); }
     214        int runModal() { return GUI::ChooserDialog::runModal(); }
    213215};
    214216
    215217SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode)
     
    250252        }
    251253}
    252254
     255#pragma mark -
     256
     257enum {
     258        kChooseCmd = 'Chos'
     259};
     260
     261// only for use with >= 640x400 resolutions
     262class SaveLoadChooserEx : public GUI::Dialog, public ScummSaveLoadChooser {
     263        typedef Common::String String;
     264        typedef Common::StringList StringList;
     265protected:
     266        bool _saveMode;
     267        GUI::ListWidget         *_list;
     268        GUI::ButtonWidget       *_chooseButton;
     269        GUI::GraphicsWidget     *_gfxWidget;
     270        ScummEngine                     *_scumm;
     271
     272public:
     273        SaveLoadChooserEx(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine);
     274       
     275        virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
     276        const String &getResultString() const; 
     277        void setList(const StringList& list);
     278        int runModal();
     279};
     280
     281SaveLoadChooserEx::SaveLoadChooserEx(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine)
     282        : Dialog(8, 8, engine->_system->getOverlayWidth() - 2 * 8, engine->_system->getOverlayHeight() - 16), _saveMode(saveMode), _list(0), _chooseButton(0), _gfxWidget(0), _scumm(engine) {
     283       
     284        new StaticTextWidget(this, 10, 6, _w - 2 * 10, kLineHeight, title, kTextAlignCenter);
     285       
     286        // Add choice list
     287        _list = new GUI::ListWidget(this, 10, 18, _w - 2 * 10 - 180, _h - 14 - 24 - 10);
     288        _list->setEditable(saveMode);
     289        _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero);
     290       
     291        // Add the thumbnail displayer
     292        _gfxWidget = new GUI::GraphicsWidget(this, _w - (kThumbnailWidth + 22), _y + 6, kThumbnailWidth + 8, ((_scumm->_system->getHeight() % 200) ? kThumbnailHeight_2 : kThumbnailHeight_1) + 8);
     293        _gfxWidget->setFlags(GUI::WIDGET_BORDER);
     294       
     295        // Buttons
     296        addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0);
     297        _chooseButton = addButton(_w-(kButtonWidth + 10), _h - 24, buttonLabel, kChooseCmd, 0);
     298        _chooseButton->setEnabled(false);
     299}
     300
     301const Common::String &SaveLoadChooserEx::getResultString() const {
     302        return _list->getSelectedString();
     303}
     304
     305void SaveLoadChooserEx::setList(const StringList& list) {
     306        _list->setList(list);
     307}
     308
     309int SaveLoadChooserEx::runModal() {
     310        g_gui.enableScaling(false);
     311        _gfxWidget->setGfx(0, 0, 0, 0);
     312        int ret = GUI::Dialog::runModal();
     313        g_gui.enableScaling(true);
     314        return ret;
     315}
     316
     317void SaveLoadChooserEx::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
     318        int selItem = _list->getSelected();
     319        switch (cmd) {
     320        case GUI::kListItemActivatedCmd:
     321        case GUI::kListItemDoubleClickedCmd:
     322                if (selItem >= 0) {
     323                        if (_saveMode || !getResultString().isEmpty()) {
     324                                _list->endEditMode();
     325                                setResult(selItem);
     326                                close();
     327                        }
     328                }
     329                break;
     330        case kChooseCmd:
     331                _list->endEditMode();
     332                setResult(selItem);
     333                close();
     334                break;
     335        case GUI::kListSelectionChangedCmd:
     336                _scumm->getThumbnail(_saveMode ? selItem + 1 : selItem);
     337                _gfxWidget->setGfx(_scumm->getThumbnailWidth(), _scumm->getThumbnailHeight(), 2, (const uint8*)_scumm->getThumbnail());
     338                _gfxWidget->draw();
     339
     340                if (_saveMode) {
     341                        _list->startEditMode();
     342                }
     343                // Disable button if nothing is selected, or (in load mode) if an empty
     344                // list item is selected. We allow choosing an empty item in save mode
     345                // because we then just assign a default name.
     346                _chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().isEmpty()));
     347                _chooseButton->draw();
     348                break;
     349        case kCloseCmd:
     350                setResult(-1);
     351        default:
     352                GUI::Dialog::handleCommand(sender, cmd, data);
     353        }
     354}
     355
     356#pragma mark -
     357
    253358Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) {
    254359        // Get savegame names
    255360        Common::StringList l;
     
    308413#ifndef DISABLE_HELP
    309414        _helpDialog = new HelpDialog(scumm);
    310415#endif
    311         _saveDialog = new SaveLoadChooser("Save game:", "Save", true);
    312         _loadDialog = new SaveLoadChooser("Load game:", "Load", false);
     416        if(scumm->_system->getOverlayWidth() == 320) {
     417                _saveDialog = new SaveLoadChooser("Save game:", "Save", true);
     418                _loadDialog = new SaveLoadChooser("Load game:", "Load", false);
     419        } else {
     420                _saveDialog = new SaveLoadChooserEx("Save game:", "Save", true, scumm);
     421                _loadDialog = new SaveLoadChooserEx("Load game:", "Load", false, scumm);
     422        }
    313423}
    314424
    315425MainMenuDialog::~MainMenuDialog() {
  • scumm/dialogs.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/dialogs.h ./scummvm/scumm/dialogs.h
    old new  
    5454        const String queryResString(int stringno);
    5555};
    5656
    57 class SaveLoadChooser;
     57// to have a base for all different Save/Load Choosers
     58// currently only for SaveLoadChooser (320x200)
     59// and for SaveLoadChooserEx (640x400/640x480)
     60class ScummSaveLoadChooser
     61{
     62public:
     63        virtual ~ScummSaveLoadChooser() {};
     64       
     65        virtual const Common::String &getResultString() const = 0;
     66        virtual void setList(const Common::StringList& list) = 0;
     67        virtual int runModal() = 0;
     68};
    5869
    5970class MainMenuDialog : public ScummDialog {
    6071public:
     
    6879#ifndef DISABLE_HELP
    6980        GUI::Dialog             *_helpDialog;
    7081#endif
    71         SaveLoadChooser *_saveDialog;
    72         SaveLoadChooser *_loadDialog;
     82        ScummSaveLoadChooser    *_saveDialog;
     83        ScummSaveLoadChooser    *_loadDialog;
    7384
    7485        void save();
    7586        void load();
  • scumm/module.mk

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/module.mk ./scummvm/scumm/module.mk
    old new  
    7575        scumm/smush/smush_player.o \
    7676        scumm/smush/saud_channel.o \
    7777        scumm/smush/smush_mixer.o \
    78         scumm/smush/smush_font.o
     78        scumm/smush/smush_font.o \
     79        scumm/thumbnail.o
    7980
    8081MODULE_DIRS += \
    8182        scumm \
  • scumm/saveload.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/saveload.cpp ./scummvm/scumm/saveload.cpp
    old new  
    8383        hdr.ver = TO_LE_32(CURRENT_VER);
    8484
    8585        out->write(&hdr, sizeof(hdr));
     86        saveThumbnail(out);
    8687
    8788        Serializer ser(out, true, CURRENT_VER);
    8889        saveOrLoad(&ser, CURRENT_VER);
     
    120121                delete in;
    121122                return false;
    122123        }
     124       
     125        // Sine version 48 a thumbnail is saved directly after the header
     126        if (hdr.ver >= VER(48)) {
     127                if(!loadThumbnail(in)) {
     128                        warning("Can not load thumbnail");
     129                        delete in;
     130                        return false;
     131                }
     132        }
    123133
    124134        // Due to a bug in scummvm up to and including 0.3.0, save games could be saved
    125135        // in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here
     
    378388        return true;
    379389}
    380390
     391bool ScummEngine::getThumbnail(int slot) {
     392        char filename[256];
     393        SaveFile *in;
     394        SaveGameHeader hdr;
     395        int len;
     396
     397        _thumbnailWidth = _thumbnailHeight = 0;
     398        delete [] _thumbnail;
     399        _thumbnail = 0;
     400
     401        makeSavegameName(filename, slot, false);
     402        if (!(in = _saveFileMan->openSavefile(filename, false))) {
     403                return false;
     404        }
     405        len = in->read(&hdr, sizeof(hdr));
     406
     407        if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) {
     408                delete in;
     409                return false;
     410        }
     411
     412        if (hdr.ver > CURRENT_VER)
     413                hdr.ver = TO_LE_32(hdr.ver);
     414        if (hdr.ver < VER(48)) {
     415                delete in;
     416                return false;
     417        }
     418
     419        ThumbnailHeader header;
     420        header.type = in->readUint32BE();
     421        if(header.type != MKID('THMB'))
     422                return false;
     423
     424        header.size = in->readUint32BE();
     425        header.version = in->readByte();
     426
     427        if (header.version > THMB_VERSION) {
     428                return false;
     429        }
     430
     431        header.width = in->readUint16BE();
     432        header.height = in->readUint16BE();
     433        header.bpp = in->readByte();
     434
     435        _thumbnailWidth = header.width;
     436        _thumbnailHeight = header.height;
     437        _thumbnailBpp = header.bpp;
     438
     439        if(_thumbnailBpp != 2)
     440                return false;
     441       
     442        _thumbnail = new uint16[_thumbnailWidth*_thumbnailHeight];
     443        for (uint16 p = 0; p <_thumbnailWidth*_thumbnailHeight; ++p)
     444                _thumbnail[p] = in->readUint16BE();
     445       
     446        loadThumbnailFromData(_thumbnail);
     447
     448        delete in;
     449        return true;
     450}
     451
    381452void ScummEngine::saveOrLoad(Serializer *s, uint32 savegameVersion) {
    382453        const SaveLoadEntry polygonEntries[] = {
    383454                MKLINE(WizPolygon, vert[0].x, sleInt16, VER(40)),
  • scumm/saveload.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/saveload.h ./scummvm/scumm/saveload.h
    old new  
    3232// Can be useful for other ports too :)
    3333
    3434#define VER(x) x
    35 #define CURRENT_VER 47
     35#define CURRENT_VER 48
    3636
    3737// To work around a warning in GCC 3.2 (and 3.1 ?) regarding non-POD types,
    3838// we use a small trick: instead of 0 we use 42. Why? Well, it seems newer GCC
  • scumm/scumm.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/scumm.cpp ./scummvm/scumm/scumm.cpp
    old new  
    596596          _features(gs.features),
    597597          gdi(this),
    598598          res(this),
    599           _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0),
     599          _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0), _thumbnail(0), _thumbnailWidth(0), _thumbnailHeight(0),
    600600          _targetName(detector->_targetName) {
    601601
    602602        // Copy MD5 checksum
  • scumm/scumm.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/scumm.h ./scummvm/scumm/scumm.h
    old new  
    3333#include "scumm/script.h"
    3434#include "scumm/util.h"
    3535
     36// FIXME: move this to another location
     37#define THMB_VERSION 1
     38
    3639namespace GUI {
    3740        class Dialog;
    3841}
    3942using GUI::Dialog;
    4043class GameDetector;
    41 
     44class SaveFile;
    4245
    4346namespace Scumm {
    4447
     
    591594        void requestSave(int slot, const char *name, bool temporary = false);
    592595        void requestLoad(int slot);
    593596
     597// thumbnail stuff
     598public:
     599        void createThumbnail();
     600        bool getThumbnail(int slot);
     601        const uint16* getThumbnail() { return _thumbnail; }
     602        uint16 getThumbnailHeight() { return _thumbnailHeight; }
     603        uint16 getThumbnailWidth() { return _thumbnailWidth; }
     604
     605protected:
     606        void loadThumbnailFromData(const uint16* data);
     607        bool loadThumbnail(SaveFile *file);
     608        void saveThumbnail(SaveFile *file);
     609        uint16 *_thumbnail;
     610        uint16 _thumbnailWidth, _thumbnailHeight;
     611        byte _thumbnailBpp;
     612
     613        struct ThumbnailHeader {
     614                uint32 type;
     615                uint32 size;
     616                byte version;
     617                uint16 width, height;
     618                byte bpp;
     619        };
     620// ends here
     621
    594622protected:
    595623        /* Script VM - should be in Script class */
    596624        uint32 _localScriptOffsets[256];
  • scumm/thumbnail.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/thumbnail.cpp ./scummvm/scumm/thumbnail.cpp
    old new  
     1/* ScummVM - Scumm Interpreter
     2 * Copyright (C) 2001  Ludvig Strigeus
     3 * Copyright (C) 2001-2005 The ScummVM project
     4 *
     5 * This program is free software; you can redistribute it and/or
     6 * modify it under the terms of the GNU General Public License
     7 * as published by the Free Software Foundation; either version 2
     8 * of the License, or (at your option) any later version.
     9
     10 * This program is distributed file the hope that it will be useful,
     11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 * GNU General Public License for more details.
     14
     15 * You should have received a copy of the GNU General Public License
     16 * along with this program; if not, write to the Free Software
     17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 *
     19 * $Header: $
     20 *
     21 */
     22 
     23#include "common/stdafx.h"
     24#include "common/scummsys.h"
     25#include "common/system.h"
     26#include "common/savefile.h"
     27#include "common/scaler.h"
     28#include "scumm.h"
     29
     30namespace Scumm {
     31
     32inline uint16 RGBToColor(const uint8 r, const uint8 g, const uint8 b) {
     33        return ((((r >> 3) & 0x1F) << 11) | (((g >> 2) & 0x3F) << 5) | ((b >> 3) & 0x1F));
     34}
     35
     36inline void colorToRGB(uint16 color, uint8 &r, uint8 &g, uint8 &b) {
     37        r = (((color >> 11) & 0x1F) << 3);
     38        g = (((color >> 5) & 0x3F) << 2);
     39        b = ((color&0x1F) << 3);
     40}
     41
     42void ScummEngine::createThumbnail() {
     43        _thumbnailWidth = 0;   
     44        if (sizeof(OverlayColor) != sizeof(uint16))
     45                return;
     46
     47        _thumbnailBpp = 2;
     48       
     49        byte *temporaryScreen = new byte[_system->getWidth() * _system->getHeight()];
     50        assert(temporaryScreen);
     51       
     52        _system->grabScreen(temporaryScreen);
     53       
     54        uint16 *screen = new uint16[_system->getWidth() * _system->getHeight()];
     55        assert(screen);
     56       
     57        const uint8 *palette = _currentPalette;
     58       
     59        for(int y = 0; y < _system->getHeight(); ++y) {
     60                for(int x = 0; x < _system->getWidth(); ++x) {
     61                        uint8 index = temporaryScreen[y * _system->getWidth() + x];                     
     62                        screen[y * _system->getWidth() + x] = RGBToColor(palette[index * 3], palette[index * 3 + 1], palette[index * 3 + 2]);
     63                }
     64        }
     65       
     66        delete [] temporaryScreen;
     67        temporaryScreen = 0;
     68
     69        uint16 newHeight = _system->getHeight() == 480 ? kThumbnailHeight_2 : kThumbnailHeight_1;
     70       
     71        if (_thumbnail && _thumbnailHeight != newHeight)
     72                delete [] _thumbnail;
     73       
     74        _thumbnailWidth = kThumbnailWidth;
     75        _thumbnailHeight = newHeight;
     76        _thumbnail = new uint16[kThumbnailWidth * newHeight];
     77        ::createThumbnail((const uint8*)screen, _system->getWidth() * 2, (uint8*)_thumbnail, 320, _system->getWidth(), _system->getHeight());
     78       
     79        delete [] screen;
     80}
     81
     82void ScummEngine::loadThumbnailFromData(const uint16* data) {
     83        if(sizeof(OverlayColor) != sizeof(uint16) || !_thumbnail)
     84                return;
     85
     86        for (int y = 0; y < _thumbnailHeight; ++y) {
     87                for (int x = 0; x < _thumbnailWidth; ++x) {
     88                        uint8 r, g, b;
     89                        colorToRGB(data[y * 160 + x], r, g, b);
     90                       
     91                        // converting to current OSystem Color
     92                        _thumbnail[y * 160 + x] = _system->RGBToColor(r, g, b);
     93                }
     94        }
     95}
     96
     97bool ScummEngine::loadThumbnail(SaveFile *file) {
     98        delete [] _thumbnail;   
     99        _thumbnail = 0;
     100
     101        ThumbnailHeader header;
     102        header.type = file->readUint32BE();
     103        if(header.type != MKID('THMB'))
     104                return false;
     105
     106        header.size = file->readUint32BE();
     107        header.version = file->readByte();
     108
     109        if (header.version > THMB_VERSION) {
     110                byte *buf = new byte[header.size - sizeof(uint32) * 2 - sizeof(byte)];
     111                file->read(buf, header.size - sizeof(uint32) * 2 - sizeof(byte));
     112                delete [] buf; 
     113                warning("Loading a newer thumbnail version");
     114                return true;
     115        }
     116
     117        header.width = file->readUint16BE();
     118        header.height = file->readUint16BE();
     119        header.bpp = file->readByte();
     120
     121        _thumbnailWidth = header.width;
     122        _thumbnailHeight = header.height;
     123        _thumbnailBpp = header.bpp;
     124       
     125        if(_thumbnailBpp != 2) {
     126                // skip all data
     127                byte *buf = new byte[_thumbnailWidth * _thumbnailHeight * _thumbnailBpp];
     128                file->read(buf, _thumbnailWidth * _thumbnailHeight * _thumbnailBpp);
     129                delete [] buf;
     130                return true;
     131        }
     132       
     133        _thumbnail = new uint16[_thumbnailWidth*_thumbnailHeight];
     134        for (uint16 p = 0; p <_thumbnailWidth*_thumbnailHeight; ++p)
     135                _thumbnail[p] = file->readUint16BE();
     136
     137        loadThumbnailFromData(_thumbnail);
     138
     139        return true;
     140}
     141
     142void ScummEngine::saveThumbnail(SaveFile *file) {
     143        createThumbnail();
     144       
     145        ThumbnailHeader header;
     146        header.type = MKID('THMB');
     147        header.size = sizeof(header) + _thumbnailWidth*_thumbnailHeight*_thumbnailBpp;
     148        header.version = THMB_VERSION;
     149        header.width = _thumbnailWidth;
     150        header.height = _thumbnailHeight;
     151        header.bpp = _thumbnailBpp;
     152
     153        file->writeUint32BE(header.type);
     154        file->writeUint32BE(header.size);
     155        file->writeByte(header.version);
     156        file->writeUint16BE(header.width);
     157        file->writeUint16BE(header.height);
     158        file->writeByte(header.bpp);
     159
     160        for (uint16 p = 0; p < _thumbnailWidth*_thumbnailHeight; ++p)
     161                file->writeUint16BE(_thumbnail[p]);
     162
     163        delete [] _thumbnail;
     164        _thumbnail = 0;
     165}
     166} // end of namespace Scumm