Ticket #8405: thumbnails-v2.patch

File thumbnails-v2.patch, 30.6 KB (added by lordhoto, 19 years ago)

new standalone patch

  • common/module.mk

    diff -d -u --rec -N --exclude=CVS scummvm.old/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 -d -u --rec -N --exclude=CVS scummvm.old/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_4(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) {
     30        for (int y = 0; y < height; y += 4) {
     31                for (int x = 0; x < width; x += 4, dstPtr += 2) {
     32                        uint16 colorx1y1 = *(((const uint16*)src) + x);
     33                        uint16 colorx2y1 = *(((const uint16*)src) + x + 1);
     34                        uint16 colorx3y1 = *(((const uint16*)src) + x + 2);
     35                        uint16 colorx4y1 = *(((const uint16*)src) + x + 3);
     36                       
     37                        uint16 colorx1y2 = *(((const uint16*)(src + srcPitch)) + x);
     38                        uint16 colorx2y2 = *(((const uint16*)(src + srcPitch)) + x + 1);
     39                        uint16 colorx3y2 = *(((const uint16*)(src + srcPitch)) + x + 2);
     40                        uint16 colorx4y2 = *(((const uint16*)(src + srcPitch)) + x + 3);
     41                       
     42                        uint16 colorx1y3 = *(((const uint16*)(src + srcPitch * 2)) + x);
     43                        uint16 colorx2y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 1);
     44                        uint16 colorx3y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 2);
     45                        uint16 colorx4y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 3);
     46                       
     47                        uint16 colorx1y4 = *(((const uint16*)(src + srcPitch * 3)) + x);
     48                        uint16 colorx2y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 1);
     49                        uint16 colorx3y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 2);
     50                        uint16 colorx4y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 3);
     51                               
     52                        uint16 upleft = Q_INTERPOLATE<bitFormat>(colorx1y1, colorx2y1, colorx1y2, colorx2y2);
     53                        uint16 upright = Q_INTERPOLATE<bitFormat>(colorx3y1, colorx4y1, colorx3y2, colorx4y2);
     54                        uint16 downleft = Q_INTERPOLATE<bitFormat>(colorx1y3, colorx2y3, colorx1y4, colorx2y4);
     55                        uint16 downright = Q_INTERPOLATE<bitFormat>(colorx3y3, colorx4y3, colorx3y4, colorx4y4);
     56                               
     57                        *((uint16*)dstPtr) = Q_INTERPOLATE<bitFormat>(upleft, upright, downleft, downright);                   
     58                }
     59                dstPtr += (dstPitch - 160);
     60                src += 4 * srcPitch;
     61        }
     62}
     63
     64template<int bitFormat>
     65void createThumbnail_8(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) {
     66        for (int y = 0; y < height; y += 8) {
     67                for (int x = 0; x < width; x += 8, dstPtr += 2) {
     68                        uint16 colorx1y1 = *(((const uint16*)src) + x);
     69                        uint16 colorx2y1 = *(((const uint16*)src) + x + 1);
     70                        uint16 colorx3y1 = *(((const uint16*)src) + x + 2);
     71                        uint16 colorx4y1 = *(((const uint16*)src) + x + 3);
     72                       
     73                        uint32 colorx5y1 = *(((const uint16*)src) + x + 4);
     74                        uint16 colorx6y1 = *(((const uint16*)src) + x + 5);
     75                        uint16 colorx7y1 = *(((const uint16*)src) + x + 6);
     76                        uint16 colorx8y1 = *(((const uint16*)src) + x + 7);
     77                       
     78                        uint16 colorx1y2 = *(((const uint16*)(src + srcPitch)) + x);
     79                        uint16 colorx2y2 = *(((const uint16*)(src + srcPitch)) + x + 1);
     80                        uint16 colorx3y2 = *(((const uint16*)(src + srcPitch)) + x + 2);
     81                        uint16 colorx4y2 = *(((const uint16*)(src + srcPitch)) + x + 3);
     82                       
     83                        uint16 colorx5y2 = *(((const uint16*)(src + srcPitch)) + x + 4);
     84                        uint16 colorx6y2 = *(((const uint16*)(src + srcPitch)) + x + 5);
     85                        uint16 colorx7y2 = *(((const uint16*)(src + srcPitch)) + x + 6);
     86                        uint16 colorx8y2 = *(((const uint16*)(src + srcPitch)) + x + 7);
     87                       
     88                        uint16 colorx1y3 = *(((const uint16*)(src + srcPitch * 2)) + x);
     89                        uint16 colorx2y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 1);
     90                        uint16 colorx3y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 2);
     91                        uint16 colorx4y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 3);
     92                       
     93                        uint16 colorx5y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 4);
     94                        uint16 colorx6y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 5);
     95                        uint16 colorx7y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 6);
     96                        uint16 colorx8y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 7);
     97                       
     98                        uint16 colorx1y4 = *(((const uint16*)(src + srcPitch * 3)) + x);
     99                        uint16 colorx2y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 1);
     100                        uint16 colorx3y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 2);
     101                        uint16 colorx4y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 3);
     102                       
     103                        uint16 colorx5y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 4);
     104                        uint16 colorx6y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 5);
     105                        uint16 colorx7y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 6);
     106                        uint16 colorx8y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 7);
     107                       
     108                        uint16 colorx1y5 = *(((const uint16*)(src + srcPitch * 3)) + x);
     109                        uint16 colorx2y5 = *(((const uint16*)(src + srcPitch * 3)) + x + 1);
     110                        uint16 colorx3y5 = *(((const uint16*)(src + srcPitch * 3)) + x + 2);
     111                        uint16 colorx4y5 = *(((const uint16*)(src + srcPitch * 3)) + x + 3);
     112                       
     113                        uint16 colorx5y5 = *(((const uint16*)(src + srcPitch * 4)) + x + 4);
     114                        uint16 colorx6y5 = *(((const uint16*)(src + srcPitch * 4)) + x + 5);
     115                        uint16 colorx7y5 = *(((const uint16*)(src + srcPitch * 4)) + x + 6);
     116                        uint16 colorx8y5 = *(((const uint16*)(src + srcPitch * 4)) + x + 7);
     117                       
     118                        uint16 colorx1y6 = *(((const uint16*)(src + srcPitch * 5)) + x);
     119                        uint16 colorx2y6 = *(((const uint16*)(src + srcPitch * 5)) + x + 1);
     120                        uint16 colorx3y6 = *(((const uint16*)(src + srcPitch * 5)) + x + 2);
     121                        uint16 colorx4y6 = *(((const uint16*)(src + srcPitch * 5)) + x + 3);
     122                       
     123                        uint16 colorx5y6 = *(((const uint16*)(src + srcPitch * 5)) + x + 4);
     124                        uint16 colorx6y6 = *(((const uint16*)(src + srcPitch * 5)) + x + 5);
     125                        uint16 colorx7y6 = *(((const uint16*)(src + srcPitch * 5)) + x + 6);
     126                        uint16 colorx8y6 = *(((const uint16*)(src + srcPitch * 5)) + x + 7);
     127                       
     128                        uint16 colorx1y7 = *(((const uint16*)(src + srcPitch * 6)) + x);
     129                        uint16 colorx2y7 = *(((const uint16*)(src + srcPitch * 6)) + x + 1);
     130                        uint16 colorx3y7 = *(((const uint16*)(src + srcPitch * 6)) + x + 2);
     131                        uint16 colorx4y7 = *(((const uint16*)(src + srcPitch * 6)) + x + 3);
     132                       
     133                        uint16 colorx5y7 = *(((const uint16*)(src + srcPitch * 6)) + x + 4);
     134                        uint16 colorx6y7 = *(((const uint16*)(src + srcPitch * 6)) + x + 5);
     135                        uint16 colorx7y7 = *(((const uint16*)(src + srcPitch * 6)) + x + 6);
     136                        uint16 colorx8y7 = *(((const uint16*)(src + srcPitch * 6)) + x + 7);
     137                       
     138                        uint16 colorx1y8 = *(((const uint16*)(src + srcPitch * 7)) + x);
     139                        uint16 colorx2y8 = *(((const uint16*)(src + srcPitch * 7)) + x + 1);
     140                        uint16 colorx3y8 = *(((const uint16*)(src + srcPitch * 7)) + x + 2);
     141                        uint16 colorx4y8 = *(((const uint16*)(src + srcPitch * 7)) + x + 3);
     142                       
     143                        uint16 colorx5y8 = *(((const uint16*)(src + srcPitch * 7)) + x + 4);
     144                        uint16 colorx6y8 = *(((const uint16*)(src + srcPitch * 7)) + x + 5);
     145                        uint16 colorx7y8 = *(((const uint16*)(src + srcPitch * 7)) + x + 6);
     146                        uint16 colorx8y8 = *(((const uint16*)(src + srcPitch * 7)) + x + 7);
     147                               
     148                        uint16 rectx1y1 = Q_INTERPOLATE<bitFormat>(colorx1y1, colorx2y1, colorx1y2, colorx2y2);
     149                        uint16 rectx2y1 = Q_INTERPOLATE<bitFormat>(colorx3y1, colorx4y1, colorx3y2, colorx4y2);
     150                        uint16 rectx3y1 = Q_INTERPOLATE<bitFormat>(colorx5y1, colorx6y1, colorx5y2, colorx6y2);
     151                        uint16 rectx4y1 = Q_INTERPOLATE<bitFormat>(colorx7y1, colorx8y1, colorx7y2, colorx8y2);
     152                       
     153                        uint16 rectx1y2 = Q_INTERPOLATE<bitFormat>(colorx1y3, colorx2y3, colorx1y4, colorx2y4);
     154                        uint16 rectx2y2 = Q_INTERPOLATE<bitFormat>(colorx3y3, colorx4y3, colorx3y4, colorx4y4);
     155                        uint16 rectx3y2 = Q_INTERPOLATE<bitFormat>(colorx5y3, colorx6y3, colorx5y4, colorx6y4);
     156                        uint16 rectx4y2 = Q_INTERPOLATE<bitFormat>(colorx7y3, colorx8y3, colorx7y4, colorx8y4);
     157                       
     158                        uint16 rectx1y3 = Q_INTERPOLATE<bitFormat>(colorx1y5, colorx2y5, colorx1y6, colorx2y6);
     159                        uint16 rectx2y3 = Q_INTERPOLATE<bitFormat>(colorx3y5, colorx4y5, colorx3y6, colorx4y6);
     160                        uint16 rectx3y3 = Q_INTERPOLATE<bitFormat>(colorx5y5, colorx6y5, colorx5y6, colorx6y6);
     161                        uint16 rectx4y3 = Q_INTERPOLATE<bitFormat>(colorx7y5, colorx8y5, colorx7y6, colorx8y6);
     162                       
     163                        uint16 rectx1y4 = Q_INTERPOLATE<bitFormat>(colorx1y7, colorx2y7, colorx1y8, colorx2y8);
     164                        uint16 rectx2y4 = Q_INTERPOLATE<bitFormat>(colorx3y7, colorx4y7, colorx3y8, colorx4y8);
     165                        uint16 rectx3y4 = Q_INTERPOLATE<bitFormat>(colorx5y7, colorx6y7, colorx5y8, colorx6y8);
     166                        uint16 rectx4y4 = Q_INTERPOLATE<bitFormat>(colorx7y7, colorx8y7, colorx7y8, colorx8y8);                                 
     167                       
     168                        uint16 upleft = Q_INTERPOLATE<bitFormat>(rectx1y1, rectx2y1, rectx1y2, rectx2y2);
     169                        uint16 upright = Q_INTERPOLATE<bitFormat>(rectx3y1, rectx4y1, rectx3y2, rectx4y2);
     170                        uint16 downleft = Q_INTERPOLATE<bitFormat>(rectx1y3, rectx2y3, rectx1y4, rectx2y4);
     171                        uint16 downright = Q_INTERPOLATE<bitFormat>(rectx3y3, rectx4y3, rectx3y4, rectx4y4);
     172                               
     173                        *((uint16*)dstPtr) = Q_INTERPOLATE<bitFormat>(upleft, upright, downleft, downright);                   
     174                }
     175                dstPtr += (dstPitch - 160);
     176                src += 8 * srcPitch;
     177        }
     178}
     179
     180void createThumbnail(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) {
     181        // only 1/4 and 1/8 downscale supported
     182        if(width != 320 && width != 640)
     183                return;
     184               
     185        const int downScaleMode = (width == 320) ? 4 : 8;
     186       
     187        if(downScaleMode == 4) {
     188                createThumbnail_4<565>(src, srcPitch, dstPtr, dstPitch, width, height);
     189        } else if(downScaleMode == 8) {
     190                createThumbnail_8<565>(src, srcPitch, dstPtr, dstPitch, width, height);
     191        }
     192}
  • common/scaler.h

    diff -d -u --rec -N --exclude=CVS scummvm.old/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 80x50 thumbnail for 320x200 games
     63// and 80x60 thumbnail for 320x240 and 640x480 games
     64// only 565 mode
     65extern void createThumbnail(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height);
     66
    6267enum {
    6368        GFX_NORMAL = 0,
    6469        GFX_DOUBLESIZE = 1,
  • gui/ListWidget.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/gui/ListWidget.cpp scummvm/gui/ListWidget.cpp
    old new  
    380380}
    381381
    382382void ListWidget::endEditMode() {
     383        if(!_editMode)
     384                return;
    383385        // send a message that editing finished with a return/enter key press
    384386        _editMode = false;
    385387        _list[_selectedItem] = _editString;
  • gui/ListWidget.h

    diff -d -u --rec -N --exclude=CVS scummvm.old/gui/ListWidget.h scummvm/gui/ListWidget.h
    old new  
    8686
    8787        // Made startEditMode for SCUMM's SaveLoadChooser
    8888        void startEditMode();
     89        void endEditMode();
    8990
    9091protected:
    9192        void drawWidget(bool hilite);
     
    9394        int findItem(int x, int y) const;
    9495        void scrollBarRecalc();
    9596
    96         void endEditMode();
    9797        void abortEditMode();
    9898       
    9999        Common::Rect getEditRect() const;
  • gui/newgui.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/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
     
    400401                        if (bitmap[y / _scaleFactor] & mask)
    401402                                        ptr[x] = color;
    402403                }
     404        }
     405}
     406
     407//
     408// Copies a Surface to the Overlay
     409//
     410void NewGui::drawSurface(const OverlayColor* data, int x, int y, int width, int height, int pitch) {
     411        if(_scaleFactor == 1) {
     412                uint8* dst = (uint8*)getBasePtr(x, y); 
     413                for (int y_ = 0; y_ < height; ++y_, dst += _screen.pitch) {
     414                        memcpy(dst, &((const uint8*)data)[y_ * pitch], pitch);
     415                }
     416        } else if(_scaleFactor == 2) {
     417                Normal2x((const uint8*)data, pitch, (uint8*)getBasePtr(x * 2, y * 2), _screen.pitch, width, height);
    403418        }
    404419}
    405420
  • gui/newgui.h

    diff -d -u --rec -N --exclude=CVS scummvm.old/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 -d -u --rec -N --exclude=CVS scummvm.old/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)
     
    258257
    259258int SliderWidget::posToValue(int pos) {
    260259        return (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin;
     260}
     261
     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        g_gui.addDirtyRect(_x, _y, _w, _h);
    261306}
    262307
    263308} // End of namespace GUI
  • gui/widget.h

    diff -d -u --rec -N --exclude=CVS scummvm.old/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 {
     
    208209
    209210        int valueToPos(int value);
    210211        int posToValue(int pos);
     212};
     213
     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;
    211227};
    212228
    213229} // End of namespace GUI
  • scumm/dialogs.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/dialogs.cpp scummvm/scumm/dialogs.cpp
    old new  
    2323#include "common/config-manager.h"
    2424#include "common/system.h"
    2525
    26 #include "gui/chooser.h"
    2726#include "gui/newgui.h"
    2827#include "gui/ListWidget.h"
    2928
     
    5453using GUI::WIDGET_ENABLED;
    5554
    5655typedef GUI::OptionsDialog GUI_OptionsDialog;
    57 typedef GUI::ChooserDialog GUI_ChooserDialog;
    5856typedef GUI::Dialog GUI_Dialog;
    5957
    6058namespace Scumm {
     
    199197        kQuitCmd = 'QUIT'
    200198};
    201199
    202 class SaveLoadChooser : public GUI::ChooserDialog {
     200enum {
     201        kChooseCmd = 'Chos'
     202};
     203
     204class SaveLoadChooser : public GUI::Dialog {
    203205        typedef Common::String String;
    204206        typedef Common::StringList StringList;
    205207protected:
    206208        bool _saveMode;
     209        GUI::ListWidget         *_list;
     210        GUI::ButtonWidget       *_chooseButton;
     211        GUI::GraphicsWidget     *_gfxWidget;
     212        ScummEngine                     *_scumm;
    207213
    208214public:
    209         SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode);
     215        SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine);
    210216       
    211217        virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
    212         const String &getResultString() const;
     218        const String &getResultString() const; 
     219        void setList(const StringList& list);
    213220};
    214221
    215 SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode)
    216         : GUI::ChooserDialog(title, buttonLabel, 182), _saveMode(saveMode) {
    217 
     222SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine)
     223        : Dialog(8, (200 - 182) / 2, 320 - 2 * 8, 182), _saveMode(saveMode), _list(0), _chooseButton(0), _gfxWidget(0), _scumm(engine) {
     224       
     225        new StaticTextWidget(this, 10, 6, _w - 2 * 10, kLineHeight, title, kTextAlignCenter);
     226       
     227        // Add choice list
     228        _list = new GUI::ListWidget(this, 10, 18, _w - 2 * 10 - 100, _h - 14 - 24 - 10);
    218229        _list->setEditable(saveMode);
    219230        _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero);
     231       
     232        // Add the thumbnail displayer
     233        _gfxWidget = new GUI::GraphicsWidget(this, _w - 102, _y + 6, 88, 68);
     234        _gfxWidget->setFlags(GUI::WIDGET_BORDER);
     235       
     236        // Buttons
     237        addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0);
     238        _chooseButton = addButton(_w-(kButtonWidth + 10), _h - 24, buttonLabel, kChooseCmd, 0);
     239        _chooseButton->setEnabled(false);
     240       
     241        _scumm->_hasThumbnail = false;
    220242}
    221243
    222244const Common::String &SaveLoadChooser::getResultString() const {
    223245        return _list->getSelectedString();
    224246}
    225247
     248void SaveLoadChooser::setList(const StringList& list) {
     249        _list->setList(list);
     250}
     251
    226252void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
    227253        int selItem = _list->getSelected();
    228254        switch (cmd) {
     
    230256        case GUI::kListItemDoubleClickedCmd:
    231257                if (selItem >= 0) {
    232258                        if (_saveMode || !getResultString().isEmpty()) {
     259                                _list->endEditMode();
    233260                                setResult(selItem);
    234261                                close();
    235262                        }
    236263                }
    237264                break;
     265        case kChooseCmd:
     266                _list->endEditMode();
     267                setResult(selItem);
     268                close();
     269                break;
    238270        case GUI::kListSelectionChangedCmd:
     271                _scumm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem);
     272                _gfxWidget->setGfx(80, 60, 2, _scumm->_hasThumbnail == true ? (const uint8*)_scumm->getThumbnail() : 0);
     273                _gfxWidget->draw();
    239274                if (_saveMode) {
    240275                        _list->startEditMode();
    241276                }
     
    245280                _chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().isEmpty()));
    246281                _chooseButton->draw();
    247282                break;
     283        case kCloseCmd:
     284                setResult(-1);
    248285        default:
    249                 GUI_ChooserDialog::handleCommand(sender, cmd, data);
     286                GUI::Dialog::handleCommand(sender, cmd, data);
    250287        }
    251288}
    252289
     290#pragma mark -
     291
    253292Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) {
    254293        // Get savegame names
    255294        Common::StringList l;
     
    308347#ifndef DISABLE_HELP
    309348        _helpDialog = new HelpDialog(scumm);
    310349#endif
    311         _saveDialog = new SaveLoadChooser("Save game:", "Save", true);
    312         _loadDialog = new SaveLoadChooser("Load game:", "Load", false);
     350        _saveDialog = new SaveLoadChooser("Save game:", "Save", true, scumm);
     351        _loadDialog = new SaveLoadChooser("Load game:", "Load", false, scumm);
    313352}
    314353
    315354MainMenuDialog::~MainMenuDialog() {
  • scumm/gfx.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/gfx.cpp scummvm/scumm/gfx.cpp
    old new  
    525525                _vm->_system->copyRectToScreen(_herculesBuf + x + y * Common::kHercW,
    526526                        Common::kHercW, x + (Common::kHercW - _vm->_screenWidth * 2) / 2, y, width, height);
    527527        } else {
    528                 // Finally blit the whole thing to the screen
    529                 _vm->_system->copyRectToScreen(_compositeBuf + x + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height);
     528                if(_vm->creatingThumbnail()) {
     529                        _vm->copyToThumbnailScreen(_compositeBuf + x + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height);
     530                } else {
     531                        // Finally blit the whole thing to the screen
     532                        _vm->_system->copyRectToScreen(_compositeBuf + x + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height);
     533                }
    530534        }
    531535}
    532536
  • scumm/module.mk

    diff -d -u --rec -N --exclude=CVS scummvm.old/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/object.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/object.cpp scummvm/scumm/object.cpp
    old new  
    15351535void ScummEngine::removeBlastObjects() {
    15361536        BlastObject *eo;
    15371537        int i;
     1538       
     1539        // for thumbnails
     1540        if(_blastObjectQueuePos)
     1541                backUpBlastObjectQueue();
    15381542
    15391543        eo = _blastObjectQueue;
    15401544        for (i = 0; i < _blastObjectQueuePos; i++, eo++) {
  • scumm/saveload.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/saveload.cpp scummvm/scumm/saveload.cpp
    old new  
    8787        Serializer ser(out, true, CURRENT_VER);
    8888        saveOrLoad(&ser, CURRENT_VER);
    8989        delete out;
     90       
     91        // create thumbnail file
     92        makeSavegameName(filename, slot, false);
     93        strcat(filename, ".tmb");       
     94        if (!(out = _saveFileMan->openSavefile(filename, true)))
     95                return false;           
     96        createThumbnail();     
     97        out->write(_thumbnail, sizeof(uint16) * 80*60);
     98        delete out;
     99        // --------------------
     100       
    90101        debug(1, "State saved as '%s'", filename);
    91102        return true;
    92103}
  • scumm/scumm.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/scumm.cpp scummvm/scumm/scumm.cpp
    old new  
    574574          _heversion(gs.heversion),
    575575          _numActors(gs.numActors),
    576576          _features(gs.features),
    577           gdi(this), _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0),
     577          gdi(this), _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0), _createThumbnail(false), _temporaryScreen(0),
    578578          _targetName(detector->_targetName) {
     579         
     580        // fill thumbnail with 0
     581        memset(_thumbnail, 0, 80*60*2);
    579582
    580583        // Copy MD5 checksum
    581584        memcpy(_gameMD5, md5sum, 16);
  • scumm/scumm.h

    diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/scumm.h scummvm/scumm/scumm.h
    old new  
    542542        void lock(int type, int i);
    543543        void unlock(int type, int i);
    544544
     545// thumbnail stuff
     546public:
     547        void createThumbnail();
     548        void loadThumbnailFromData(const uint16* data);
     549        void loadThumbnailFromSlot(int slot);
     550        const uint16* getThumbnail() { return _thumbnail; }
     551       
     552        bool creatingThumbnail() { return _createThumbnail; }
     553        void copyToThumbnailScreen(const byte *buf, int pitch, int x, int y, int w, int h);
     554
     555        bool _hasThumbnail;
     556protected:
     557        uint16 _thumbnail[80*60];
     558        byte *_temporaryScreen;
     559        bool _createThumbnail;
     560       
     561        void backUpBlastObjectQueue();
     562        void insertBackUpedBlastObjectQueue();
     563       
     564        int _blastObjectQueueBackUPPos;
     565        BlastObject _blastObjectQueueBackUP[128];
     566       
     567        void backUpBlastTextQueue();
     568        void insertBackUpedBlastTextQueue();
     569
     570        int _blastTextQueueBackUPPos;
     571        BlastText _blastTextQueueBackUP[50];
     572// ends here
     573
    545574protected:
    546575        /* Heap and memory management */
    547576        uint32 _maxHeapThreshold, _minHeapThreshold;
  • scumm/string.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/string.cpp scummvm/scumm/string.cpp
    old new  
    785785
    786786void ScummEngine::removeBlastTexts() {
    787787        int i;
     788       
     789        // for thumbnails
     790        if(_blastTextQueuePos)
     791                backUpBlastTextQueue();
    788792
    789793        for (i = 0; i < _blastTextQueuePos; i++) {
    790794                restoreBG(_blastTextQueue[i].rect);
  • scumm/thumbnail.cpp

    diff -d -u --rec -N --exclude=CVS scummvm.old/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 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 "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        if(sizeof(OverlayColor) != sizeof(uint16))
     44                return;
     45       
     46        _temporaryScreen = new byte[_system->getWidth() * _system->getHeight()];
     47        assert(_temporaryScreen);
     48       
     49        _createThumbnail = true;       
     50        int pos = 0;
     51       
     52        for (VirtScreen *vs = &virtscr[0]; pos < ARRAYSIZE(virtscr); ++pos, vs = &virtscr[pos]) {
     53                markRectAsDirty((VirtScreenNumber)pos, 0, vs->w, 0, vs->h);
     54        }
     55       
     56        insertBackUpedBlastObjectQueue();
     57        insertBackUpedBlastTextQueue();
     58       
     59        if (_version >= 7 && VAR(VAR_BLAST_ABOVE_TEXT) == 1) {
     60                drawBlastTexts();
     61                drawBlastObjects();
     62        } else {
     63                drawBlastObjects();
     64                drawBlastTexts();
     65        }
     66       
     67        drawDirtyScreenParts();
     68       
     69        removeBlastTexts();
     70        removeBlastObjects();   
     71       
     72        _blastTextQueuePos = _blastObjectQueuePos = 0;
     73       
     74        uint16 *screen = new uint16[_system->getWidth() * _system->getHeight()];
     75        assert(screen);
     76       
     77        const uint8 *palette = _currentPalette;
     78       
     79        for(int y = 0; y < _system->getHeight(); ++y) {
     80                for(int x = 0; x < _system->getWidth(); ++x) {
     81                        uint8 index = _temporaryScreen[y * _system->getWidth() + x];                   
     82                        screen[y * _system->getWidth() + x] = RGBToColor(palette[index * 3], palette[index * 3 + 1], palette[index * 3 + 2]);
     83                }
     84        }
     85       
     86        _createThumbnail = false;
     87        delete [] _temporaryScreen;
     88        _temporaryScreen = 0;
     89       
     90        memset(_thumbnail, 0, 80*60*2);
     91        ::createThumbnail((const uint8*)screen, _system->getWidth() * 2, (uint8*)_thumbnail, 160, _system->getWidth(), _system->getHeight());
     92       
     93        delete [] screen;
     94}
     95
     96void ScummEngine::loadThumbnailFromData(const uint16* data) {
     97        if(sizeof(OverlayColor) != sizeof(uint16))
     98                return;
     99
     100        for (int y = 0; y < 60; ++y) {
     101                for (int x = 0; x < 80; ++x) {
     102                        uint8 r, g, b;
     103                        colorToRGB(data[y * 80 + x], r, g, b);
     104                       
     105                        // converting to current OSystem Color
     106                        _thumbnail[y * 80 + x] = _system->RGBToColor(r, g, b);
     107                }
     108        }
     109}
     110
     111void ScummEngine::copyToThumbnailScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
     112        assert(_temporaryScreen);
     113        uint8* dst = _temporaryScreen + y * _system->getWidth() + x;
     114        while (h--) {
     115                memcpy(dst, buf, w);
     116                buf += pitch;
     117                dst += _system->getWidth();
     118        }
     119}
     120
     121void ScummEngine::loadThumbnailFromSlot(int slot) {
     122        char filename[256];
     123        makeSavegameName(filename, slot, false);
     124        strcat(filename, ".tmb");
     125       
     126        SaveFile *out;
     127        if (!(out = _saveFileMan->openSavefile(filename, false))) {
     128                delete out;
     129                memset(_thumbnail, 0, sizeof(uint16) * 80*60);
     130                _hasThumbnail = false;
     131                return;
     132        }
     133               
     134        out->read(_thumbnail, sizeof(uint16) * 80*60);
     135        loadThumbnailFromData(_thumbnail);
     136        _hasThumbnail = true;
     137        delete out;
     138}
     139
     140void ScummEngine::backUpBlastObjectQueue() {
     141        _blastObjectQueueBackUPPos = _blastObjectQueuePos;
     142        for (int i = 0; i < _blastObjectQueuePos; i++) {
     143                memcpy(&_blastObjectQueueBackUP[i], &_blastObjectQueue[i], sizeof(BlastObject));
     144        }
     145}
     146
     147void ScummEngine::insertBackUpedBlastObjectQueue() {
     148        _blastObjectQueuePos = _blastObjectQueueBackUPPos;
     149        for (int i = 0; i < _blastObjectQueuePos; i++) {
     150                memcpy(&_blastObjectQueue[i], &_blastObjectQueueBackUP[i], sizeof(BlastObject));
     151        }
     152}
     153
     154void ScummEngine::backUpBlastTextQueue() {
     155        _blastTextQueueBackUPPos = _blastTextQueuePos;
     156        for (int i = 0; i < _blastTextQueuePos; i++) {
     157                memcpy(&_blastTextQueueBackUP[i], &_blastTextQueue[i], sizeof(BlastText));
     158        }
     159}
     160
     161void ScummEngine::insertBackUpedBlastTextQueue() {
     162        _blastTextQueuePos = _blastTextQueueBackUPPos;
     163        for (int i = 0; i < _blastTextQueuePos; i++) {
     164                memcpy(&_blastTextQueue[i], &_blastTextQueueBackUP[i], sizeof(BlastText));
     165        }
     166}
     167
     168} // end of namespace Scumm