Ticket #8405: thumbnail-v4-2pre1.patch
File thumbnail-v4-2pre1.patch, 33.6 KB (added by , 20 years ago) |
---|
-
backends/sdl/graphics.cpp
diff -d -u --rec -N --exclude=CVS scummvm.old/backends/sdl/graphics.cpp scummvm/backends/sdl/graphics.cpp
old new 25 25 #include "common/util.h" 26 26 #include "graphics/font.h" 27 27 #include "graphics/fontman.h" 28 #include "graphics/surface.h" 28 29 29 30 static const OSystem::GraphicsMode s_supportedGraphicsModes[] = { 30 31 {"1x", "Normal (no scaling)", GFX_NORMAL}, … … 800 801 SDL_UnlockSurface(_screen); 801 802 } 802 803 804 void OSystem_SDL::grabRawScreen(Graphics::Surface *surf) { 805 assert(_screen); 806 assert(surf); 807 808 Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends 809 810 surf->create(_screenWidth, _screenHeight, _screen->format->BytesPerPixel); 811 812 // Try to lock the screen surface 813 if (SDL_LockSurface(_screen) == -1) 814 error("SDL_LockSurface failed: %s", SDL_GetError()); 815 816 memcpy(surf->pixels, _screen->pixels, _screenWidth * _screenHeight * _screen->format->BytesPerPixel); 817 818 // Unlock the screen surface 819 SDL_UnlockSurface(_screen); 820 } 803 821 804 822 void OSystem_SDL::addDirtyRect(int x, int y, int w, int h, bool mouseRect) { 805 823 if (_forceFull) … … 982 1000 // Some games blink cursors with palette 983 1001 if (!_overlayVisible && (!_cursorHasOwnPalette || _cursorPaletteDisabled)) 984 1002 blitCursor(); 1003 } 1004 1005 void OSystem_SDL::grabPalette(byte *colors, uint start, uint num) { 1006 assert(colors); 1007 const SDL_Color *base = _currentPalette + start; 1008 1009 for (uint i = 0; i < num; ++i) { 1010 colors[i * 4] = base[i].r; 1011 colors[i * 4 + 1] = base[i].g; 1012 colors[i * 4 + 2] = base[i].b; 1013 colors[i * 4 + 3] = 0xFF; 1014 } 985 1015 } 986 1016 987 1017 void OSystem_SDL::setCursorPalette(const byte *colors, uint start, uint num) { -
backends/sdl/sdl-common.h
diff -d -u --rec -N --exclude=CVS scummvm.old/backends/sdl/sdl-common.h scummvm/backends/sdl/sdl-common.h
old new 78 78 79 79 // Set colors of the palette 80 80 void setPalette(const byte *colors, uint start, uint num); 81 82 // Get colors of the palette 83 void grabPalette(byte *colors, uint start, uint num); 81 84 82 85 // Draw a bitmap to screen. 83 86 // The screen will not be updated to reflect the new bitmap 84 87 void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); 88 89 // Copies the screen to a buffer 90 void grabRawScreen(Graphics::Surface *surf); 85 91 86 92 // Clear the screen 87 93 void clearScreen(); -
common/module.mk
diff -d -u --rec -N --exclude=CVS scummvm.old/common/module.mk scummvm/common/module.mk
old new 21 21 common/scaler/hq3x.o \ 22 22 common/scaler/scale2x.o \ 23 23 common/scaler/scale3x.o \ 24 common/scaler/scalebit.o 24 common/scaler/scalebit.o \ 25 common/scaler/thumbnail.o 25 26 26 27 ifdef HAVE_NASM 27 28 MODULE_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 "common/system.h" 26 27 #include "scaler.h" 28 #include "scaler/intern.h" 29 30 template<int bitFormat> 31 void createThumbnail_2(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) { 32 for (int y = 0; y < height; y += 2) { 33 for (int x = 0; x < width; x += 2, dstPtr += 2) { 34 uint16 colorx1y1 = *(((const uint16*)src) + x); 35 uint16 colorx2y1 = *(((const uint16*)src) + x + 1); 36 37 uint16 colorx1y2 = *(((const uint16*)(src + srcPitch)) + x); 38 uint16 colorx2y2 = *(((const uint16*)(src + srcPitch)) + x + 1); 39 40 *((uint16*)dstPtr) = Q_INTERPOLATE<bitFormat>(colorx1y1, colorx2y1, colorx1y2, colorx2y2); 41 } 42 dstPtr += (dstPitch - 320); 43 src += 2 * srcPitch; 44 } 45 } 46 47 template<int bitFormat> 48 void createThumbnail_4(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) { 49 for (int y = 0; y < height; y += 4) { 50 for (int x = 0; x < width; x += 4, dstPtr += 2) { 51 uint16 colorx1y1 = *(((const uint16*)src) + x); 52 uint16 colorx2y1 = *(((const uint16*)src) + x + 1); 53 uint16 colorx3y1 = *(((const uint16*)src) + x + 2); 54 uint16 colorx4y1 = *(((const uint16*)src) + x + 3); 55 56 uint16 colorx1y2 = *(((const uint16*)(src + srcPitch)) + x); 57 uint16 colorx2y2 = *(((const uint16*)(src + srcPitch)) + x + 1); 58 uint16 colorx3y2 = *(((const uint16*)(src + srcPitch)) + x + 2); 59 uint16 colorx4y2 = *(((const uint16*)(src + srcPitch)) + x + 3); 60 61 uint16 colorx1y3 = *(((const uint16*)(src + srcPitch * 2)) + x); 62 uint16 colorx2y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 1); 63 uint16 colorx3y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 2); 64 uint16 colorx4y3 = *(((const uint16*)(src + srcPitch * 2)) + x + 3); 65 66 uint16 colorx1y4 = *(((const uint16*)(src + srcPitch * 3)) + x); 67 uint16 colorx2y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 1); 68 uint16 colorx3y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 2); 69 uint16 colorx4y4 = *(((const uint16*)(src + srcPitch * 3)) + x + 3); 70 71 uint16 upleft = Q_INTERPOLATE<bitFormat>(colorx1y1, colorx2y1, colorx1y2, colorx2y2); 72 uint16 upright = Q_INTERPOLATE<bitFormat>(colorx3y1, colorx4y1, colorx3y2, colorx4y2); 73 uint16 downleft = Q_INTERPOLATE<bitFormat>(colorx1y3, colorx2y3, colorx1y4, colorx2y4); 74 uint16 downright = Q_INTERPOLATE<bitFormat>(colorx3y3, colorx4y3, colorx3y4, colorx4y4); 75 76 *((uint16*)dstPtr) = Q_INTERPOLATE<bitFormat>(upleft, upright, downleft, downright); 77 } 78 dstPtr += (dstPitch - 320); 79 src += 4 * srcPitch; 80 } 81 } 82 83 void createThumbnail(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height) { 84 // only 1/2 and 1/4 downscale supported 85 if (width != 320 && width != 640) 86 return; 87 88 int downScaleMode = (width == 320) ? 2 : 4; 89 90 if (downScaleMode == 2) { 91 createThumbnail_2<565>(src, srcPitch, dstPtr, dstPitch, width, height); 92 } else if (downScaleMode == 4) { 93 createThumbnail_4<565>(src, srcPitch, dstPtr, dstPitch, width, height); 94 } 95 } 96 97 bool createThumbnailFromScreen(Graphics::Surface* surf) { 98 assert(surf); 99 100 int screenWidth = OSystem::instance().getWidth(); 101 int screenHeight = OSystem::instance().getHeight(); 102 103 Graphics::Surface screen; 104 OSystem::instance().grabScreen(&screen); 105 106 if (!screen.pixels) 107 return false; 108 109 uint16 width = screenWidth; 110 111 if (screenWidth < 320) { 112 width = 320; 113 114 // center MM NES screen 115 Graphics::Surface newscreen; 116 newscreen.create(width, screen.h, screen.bytesPerPixel); 117 118 uint8 *dst = (uint8*)newscreen.getBasePtr((320 - screenWidth) / 2, 0); 119 uint8 *src = (uint8*)screen.getBasePtr(0, 0); 120 uint16 height = screen.h; 121 122 while (height--) { 123 memcpy(dst, src, screen.pitch); 124 dst += newscreen.pitch; 125 src += screen.pitch; 126 } 127 128 screen.free(); 129 screen = newscreen; 130 } 131 132 uint16 newHeight = !(screenHeight % 240) ? kThumbnailHeight_2 : kThumbnailHeight_1; 133 134 surf->create(kThumbnailWidth, newHeight, sizeof(uint16)); 135 createThumbnail((const uint8*)screen.pixels, width * sizeof(uint16), (uint8*)surf->pixels, surf->pitch, width, screenHeight); 136 137 screen.free(); 138 139 return true; 140 } -
common/scaler.h
diff -d -u --rec -N --exclude=CVS scummvm.old/common/scaler.h scummvm/common/scaler.h
old new 23 23 24 24 #include "common/stdafx.h" 25 25 #include "common/scummsys.h" 26 #include "graphics/surface.h" 26 27 27 28 extern void InitScalers(uint32 BitFormat); 28 29 … … 59 60 60 61 extern int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY); 61 62 63 // creates a 160x100 thumbnail for 320x200 games 64 // and 160x120 thumbnail for 320x240 and 640x480 games 65 // only 565 mode 66 enum { 67 kThumbnailWidth = 160, 68 kThumbnailHeight_1 = 100, 69 kThumbnailHeight_2 = 120 70 }; 71 extern void createThumbnail(const uint8* src, uint32 srcPitch, uint8* dstPtr, uint32 dstPitch, int width, int height); 72 73 /** 74 * creates a thumbnail from the current screen (without overlay) 75 * @param surf a surface (will always have 16 bpp after this for now) 76 * @return false if a error occured 77 */ 78 extern bool createThumbnailFromScreen(Graphics::Surface* surf); 62 79 63 80 #endif -
common/system.cpp
diff -d -u --rec -N --exclude=CVS scummvm.old/common/system.cpp scummvm/common/system.cpp
old new 33 33 #include "common/system.h" 34 34 #include "common/util.h" 35 35 36 #include "graphics/surface.h" 37 36 38 DECLARE_SINGLETON(OSystem); 37 39 38 40 OSystem *OSystem::makeInstance() { … … 91 93 92 94 SaveFileManager *OSystem::getSavefileManager() { 93 95 return new DefaultSaveFileManager(); 96 } 97 98 void OSystem::grabScreen(Graphics::Surface *surf, int bitsPerPixel) { 99 Graphics::Surface screen; 100 grabRawScreen(&screen); 101 102 if (screen.bytesPerPixel != 1 || screen.pixels == 0) 103 return; 104 105 byte palette[256 * 4]; 106 grabPalette(&palette[0], 0, 256); 107 108 surf->create(screen.w, screen.h, (bitsPerPixel + 1) / 8); 109 110 for (uint y = 0; y < screen.h; ++y) { 111 for (uint x = 0; x < screen.w; ++x) { 112 byte r, g, b; 113 r = palette[((uint8*)screen.pixels)[y * screen.pitch + x] * 4]; 114 g = palette[((uint8*)screen.pixels)[y * screen.pitch + x] * 4 + 1]; 115 b = palette[((uint8*)screen.pixels)[y * screen.pitch + x] * 4 + 2]; 116 117 if (bitsPerPixel == 15) { 118 ((uint16*)surf->pixels)[y * surf->w + x] = (((r >> 3) & 0x1F) << 10) | (((g >> 3) & 0x1F) << 5) | ((b >> 3) & 0x1F); 119 } else if (bitsPerPixel == 16) { 120 ((uint16*)surf->pixels)[y * surf->w + x] = (((r >> 3) & 0x1F) << 11) | (((g >> 2) & 0x3F) << 5) | ((b >> 3) & 0x1F); 121 } else if (bitsPerPixel == 24) { 122 #ifdef SCUMM_BIG_ENDIAN 123 ((uint8*)surf->pixels)[y * surf->pitch + x * surf->bytesPerPixel + 2] = r; 124 ((uint8*)surf->pixels)[y * surf->pitch + x * surf->bytesPerPixel + 1] = g; 125 ((uint8*)surf->pixels)[y * surf->pitch + x * surf->bytesPerPixel] = b; 126 #else 127 ((uint8*)surf->pixels)[y * surf->pitch + x * surf->bytesPerPixel] = r; 128 ((uint8*)surf->pixels)[y * surf->pitch + x * surf->bytesPerPixel + 1] = g; 129 ((uint8*)surf->pixels)[y * surf->pitch + x * surf->bytesPerPixel + 2] = b; 130 #endif 131 } else if (bitsPerPixel == 32) { 132 ((uint32*)surf->pixels)[y * surf->w + x] = 0xFF << 24 | r << 16 | g << 8 | b << 8; 133 } 134 } 135 } 136 137 screen.free(); 94 138 } -
common/system.h
diff -d -u --rec -N --exclude=CVS scummvm.old/common/system.h scummvm/common/system.h
old new 28 28 #include "common/rect.h" 29 29 #include "common/singleton.h" 30 30 31 namespace Graphics { 32 class Surface; 33 } // end of namespace Graphics 34 31 35 class SaveFileManager; 32 36 33 37 /** … … 347 351 * API are probably going to remove it. 348 352 */ 349 353 virtual void setPalette(const byte *colors, uint start, uint num) = 0; 354 355 /** 356 * Grabs a specified part of the palette 357 * format is like it is discribed in setPalette 358 * 359 * @param buf the buffer 360 * @param start the first platte entry 361 * @param num nummber of the entries 362 */ 363 virtual void grabPalette(byte *colors, uint start, uint num) = 0; 350 364 351 365 /** 352 366 * Blit a bitmap to the virtual screen. … … 357 371 * @see updateScreen 358 372 */ 359 373 virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) = 0; 374 375 /** 376 * Copies the screen to a surface 377 * @param surf the surfce to store the data in it 378 * @param bitsPerPixel must be higher than 15 and lower than 32 379 */ 380 virtual void grabScreen(Graphics::Surface *surf, int bitsPerPixel = 16); 381 382 /** 383 * Copies the screen to a surface (with original bit depth) 384 * It should return a 1 byte per pixel surface in all cases 385 * because currently all games supported by ScummVM are 386 * using 1 byte per pixel. 387 * 388 * @param surf the surfce to store the data in it 389 */ 390 virtual void grabRawScreen(Graphics::Surface *surf) = 0; 360 391 361 392 /** 362 393 * Clear the screen to black. -
graphics/surface.cpp
diff -d -u --rec -N --exclude=CVS scummvm.old/graphics/surface.cpp scummvm/graphics/surface.cpp
old new 24 24 25 25 namespace Graphics { 26 26 27 void Surface::create(uint16 width, uint16 height, uint8 bytesPP) { 28 free(); 29 30 w = width; h = height; 31 bytesPerPixel = bytesPP; 32 pitch = w * bytesPP; 33 34 pixels = calloc(width * height, bytesPP); 35 assert(pixels); 36 } 37 38 void Surface::free() { 39 ::free(pixels); 40 pixels = 0; 41 w = h = pitch = 0; 42 bytesPerPixel = 0; 43 } 44 27 45 void Surface::hLine(int x, int y, int x2, uint32 color) const { 28 46 // Clipping 29 47 if (y < 0 || y >= h) -
graphics/surface.h
diff -d -u --rec -N --exclude=CVS scummvm.old/graphics/surface.h scummvm/graphics/surface.h
old new 43 43 return (void *)((byte *)pixels + y * pitch + x * bytesPerPixel); 44 44 } 45 45 46 void create(uint16 width, uint16 height, uint8 bytesPP); 47 void free(); 48 46 49 void hLine(int x, int y, int x2, uint32 color) const; 47 50 void vLine(int x, int y, int y2, uint32 color) const; 48 51 void fillRect(const Common::Rect &r, uint32 color) const; -
gui/newgui.cpp
diff -d -u --rec -N --exclude=CVS scummvm.old/gui/newgui.cpp scummvm/gui/newgui.cpp
old new 21 21 #include "stdafx.h" 22 22 #include "common/system.h" 23 23 #include "common/util.h" 24 #include "common/scaler.h" 24 25 #include "gui/newgui.h" 25 26 #include "gui/dialog.h" 26 27 … … 434 435 ptr[x] = color; 435 436 } 436 437 } 438 } 439 440 // 441 // Copies a Surface to the Overlay 442 // 443 void 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); 437 453 } 438 454 439 455 // -
gui/newgui.h
diff -d -u --rec -N --exclude=CVS scummvm.old/gui/newgui.h scummvm/gui/newgui.h
old new 146 146 int getFontHeight() const; 147 147 148 148 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); 149 150 150 151 void addDirtyRect(int x, int y, int w, int h); 151 152 }; -
gui/widget.cpp
diff -d -u --rec -N --exclude=CVS scummvm.old/gui/widget.cpp scummvm/gui/widget.cpp
old new 24 24 #include "gui/dialog.h" 25 25 #include "gui/newgui.h" 26 26 27 28 27 namespace GUI { 29 28 30 29 Widget::Widget(GuiObject *boss, int x, int y, int w, int h) … … 258 257 259 258 int SliderWidget::posToValue(int pos) { 260 259 return (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin; 260 } 261 262 #pragma mark - 263 264 GraphicsWidget::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 270 GraphicsWidget::~GraphicsWidget() { 271 delete [] _gfx; 272 } 273 274 void 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 291 void 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); 261 305 } 262 306 263 307 } // 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 52 52 kListWidget = 'LIST', 53 53 kScrollBarWidget = 'SCRB', 54 54 kPopUpWidget = 'POPU', 55 kTabWidget = 'TABW' 55 kTabWidget = 'TABW', 56 kGraphicsWidget = 'GFXW' 56 57 }; 57 58 58 59 enum { … … 208 209 209 210 int valueToPos(int value); 210 211 int posToValue(int pos); 212 }; 213 214 /* GraphicsWidget */ 215 class GraphicsWidget : public Widget { 216 public: 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); 222 protected: 223 void drawWidget(bool hilite); 224 225 uint8 *_gfx; 226 int _gfxWidth, _gfxHeight, _bpp; 211 227 }; 212 228 213 229 } // 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 22 22 23 23 #include "common/config-manager.h" 24 24 #include "common/system.h" 25 #include "common/scaler.h" 25 26 26 27 #include "gui/chooser.h" 27 28 #include "gui/newgui.h" … … 147 148 148 149 #pragma mark - 149 150 150 151 151 const Common::String ScummDialog::queryResString(int stringno) { 152 152 byte buf[256]; 153 153 byte *result; … … 199 199 kQuitCmd = 'QUIT' 200 200 }; 201 201 202 class SaveLoadChooser : public GUI::ChooserDialog {202 class SaveLoadChooser : public GUI::ChooserDialog, public ScummSaveLoadChooser { 203 203 typedef Common::String String; 204 204 typedef Common::StringList StringList; 205 205 protected: … … 210 210 211 211 virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); 212 212 const String &getResultString() const; 213 void setList(const StringList& list) { GUI::ChooserDialog::setList(list); } 214 int runModal() { return GUI::ChooserDialog::runModal(); } 213 215 }; 214 216 215 217 SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode) … … 250 252 } 251 253 } 252 254 255 #pragma mark - 256 257 enum { 258 kChooseCmd = 'Chos' 259 }; 260 261 // only for use with >= 640x400 resolutions 262 class SaveLoadChooserEx : public GUI::Dialog, public ScummSaveLoadChooser { 263 typedef Common::String String; 264 typedef Common::StringList StringList; 265 protected: 266 bool _saveMode; 267 GUI::ListWidget *_list; 268 GUI::ButtonWidget *_chooseButton; 269 GUI::GraphicsWidget *_gfxWidget; 270 ScummEngine *_scumm; 271 272 public: 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 281 SaveLoadChooserEx::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 301 const Common::String &SaveLoadChooserEx::getResultString() const { 302 return _list->getSelectedString(); 303 } 304 305 void SaveLoadChooserEx::setList(const StringList& list) { 306 _list->setList(list); 307 } 308 309 int 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 317 void 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 253 358 Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) { 254 359 // Get savegame names 255 360 Common::StringList l; … … 308 413 #ifndef DISABLE_HELP 309 414 _helpDialog = new HelpDialog(scumm); 310 415 #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 } 313 423 } 314 424 315 425 MainMenuDialog::~MainMenuDialog() { -
scumm/dialogs.h
diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/dialogs.h scummvm/scumm/dialogs.h
old new 54 54 const String queryResString(int stringno); 55 55 }; 56 56 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) 60 class ScummSaveLoadChooser 61 { 62 public: 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 }; 58 69 59 70 class MainMenuDialog : public ScummDialog { 60 71 public: … … 68 79 #ifndef DISABLE_HELP 69 80 GUI::Dialog *_helpDialog; 70 81 #endif 71 S aveLoadChooser *_saveDialog;72 S aveLoadChooser *_loadDialog;82 ScummSaveLoadChooser *_saveDialog; 83 ScummSaveLoadChooser *_loadDialog; 73 84 74 85 void save(); 75 86 void load(); -
scumm/module.mk
diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/module.mk scummvm/scumm/module.mk
old new 78 78 scumm/smush/smush_player.o \ 79 79 scumm/smush/saud_channel.o \ 80 80 scumm/smush/smush_mixer.o \ 81 scumm/smush/smush_font.o 81 scumm/smush/smush_font.o \ 82 scumm/thumbnail.o 82 83 83 84 MODULE_DIRS += \ 84 85 scumm \ -
scumm/saveload.cpp
diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/saveload.cpp scummvm/scumm/saveload.cpp
old new 83 83 hdr.ver = TO_LE_32(CURRENT_VER); 84 84 85 85 out->write(&hdr, sizeof(hdr)); 86 saveThumbnail(out); 86 87 87 88 Serializer ser(0, out, CURRENT_VER); 88 89 saveOrLoad(&ser, CURRENT_VER); … … 120 121 delete in; 121 122 return false; 122 123 } 124 125 // Sine version 49 a thumbnail is saved directly after the header 126 if (hdr.ver >= VER(49)) { 127 if(!loadThumbnail(in)) { 128 warning("Can not load thumbnail"); 129 delete in; 130 return false; 131 } 132 } 123 133 124 134 // Due to a bug in scummvm up to and including 0.3.0, save games could be saved 125 135 // in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here … … 375 385 376 386 memcpy(desc, hdr.name, sizeof(hdr.name)); 377 387 desc[sizeof(hdr.name) - 1] = 0; 388 return true; 389 } 390 391 bool ScummEngine::getThumbnail(int slot) { 392 char filename[256]; 393 InSaveFile *in; 394 SaveGameHeader hdr; 395 int len; 396 397 if (_thumbnail) 398 _thumbnail->free(); 399 delete _thumbnail; 400 _thumbnail = 0; 401 402 makeSavegameName(filename, slot, false); 403 if (!(in = _saveFileMan->openForLoading(filename))) { 404 return false; 405 } 406 len = in->read(&hdr, sizeof(hdr)); 407 408 if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) { 409 delete in; 410 return false; 411 } 412 413 if (hdr.ver > CURRENT_VER) 414 hdr.ver = TO_LE_32(hdr.ver); 415 if (hdr.ver < VER(49)) { 416 delete in; 417 return false; 418 } 419 420 loadThumbnail(in); 421 422 delete in; 378 423 return true; 379 424 } 380 425 -
scumm/saveload.h
diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/saveload.h scummvm/scumm/saveload.h
old new 33 33 // Can be useful for other ports too :) 34 34 35 35 #define VER(x) x 36 #define CURRENT_VER 4 836 #define CURRENT_VER 49 37 37 38 38 // To work around a warning in GCC 3.2 (and 3.1 ?) regarding non-POD types, 39 39 // we use a small trick: instead of 0 we use 42. Why? Well, it seems newer GCC -
scumm/scumm.cpp
diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/scumm.cpp scummvm/scumm/scumm.cpp
old new 618 618 _features(gs.features), 619 619 gdi(this), 620 620 res(this), 621 _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0), 621 _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0), _thumbnail(0), 622 622 _targetName(detector->_targetName) { 623 623 624 624 // Copy MD5 checksum -
scumm/scumm.h
diff -d -u --rec -N --exclude=CVS scummvm.old/scumm/scumm.h scummvm/scumm/scumm.h
old new 28 28 #include "common/map.h" 29 29 #include "common/rect.h" 30 30 #include "common/str.h" 31 #include "graphics/surface.h" 31 32 32 33 #include "scumm/gfx.h" 33 34 #include "scumm/script.h" 34 35 36 // FIXME: 37 // define it in a other location 38 #define THMB_VERSION 1 39 35 40 namespace GUI { 36 41 class Dialog; 37 42 } 38 43 using GUI::Dialog; 39 44 class GameDetector; 40 45 class InSaveFile; 46 class OutSaveFile; 41 47 42 48 namespace Scumm { 43 49 … … 593 599 594 600 void requestSave(int slot, const char *name, bool temporary = false); 595 601 void requestLoad(int slot); 602 603 // thumbnail stuff 604 public: 605 bool getThumbnail(int slot); 606 const void* getThumbnail() { if(_thumbnail) return _thumbnail->pixels; return 0; } 607 uint16 getThumbnailHeight() { if(_thumbnail) return _thumbnail->h; return 0; } 608 uint16 getThumbnailWidth() { if(_thumbnail) return _thumbnail->w; return 0; } 609 610 protected: 611 bool loadThumbnail(InSaveFile *file); 612 void saveThumbnail(OutSaveFile *file); 613 614 Graphics::Surface *_thumbnail; 615 616 struct ThumbnailHeader { 617 uint32 type; 618 uint32 size; 619 byte version; 620 uint16 width, height; 621 byte bpp; 622 }; 623 // ends here 596 624 597 625 protected: 598 626 /* Script VM - should be in Script class */ -
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 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 30 namespace Scumm { 31 inline uint16 RGBToColor(const uint8 r, const uint8 g, const uint8 b) { 32 return ((((r >> 3) & 0x1F) << 11) | (((g >> 2) & 0x3F) << 5) | ((b >> 3) & 0x1F)); 33 } 34 35 inline void colorToRGB(uint16 color, uint8 &r, uint8 &g, uint8 &b) { 36 r = (((color >> 11) & 0x1F) << 3); 37 g = (((color >> 5) & 0x3F) << 2); 38 b = ((color&0x1F) << 3); 39 } 40 41 bool ScummEngine::loadThumbnail(InSaveFile *file) { 42 if (_thumbnail) 43 _thumbnail->free(); 44 delete _thumbnail; 45 _thumbnail = 0; 46 47 ThumbnailHeader header; 48 header.type = file->readUint32BE(); 49 if(header.type != MKID('THMB')) 50 return false; 51 52 header.size = file->readUint32BE(); 53 header.version = file->readByte(); 54 55 if (header.version > THMB_VERSION) { 56 // TODO: maybe add a skip method to the SaveFile class to get rid of this 57 byte *buf = new byte[header.size - sizeof(uint32) * 2 - sizeof(byte)]; 58 file->read(buf, header.size - sizeof(uint32) * 2 - sizeof(byte)); 59 delete [] buf; 60 warning("Loading a newer thumbnail version"); 61 return true; 62 } 63 64 header.width = file->readUint16BE(); 65 header.height = file->readUint16BE(); 66 header.bpp = file->readByte(); 67 68 // TODO: support other bpp values than 2 69 if(header.bpp != 2) { 70 // skip all data 71 // TODO: maybe add a skip method to the SaveFile class to get rid of this 72 byte *buf = new byte[header.width * header.height * header.bpp]; 73 file->read(buf, header.width * header.height * header.bpp); 74 delete [] buf; 75 return true; 76 } 77 78 _thumbnail = new Graphics::Surface(); 79 _thumbnail->create(header.width, header.height, sizeof(uint16)); 80 for (uint16 p = 0; p <_thumbnail->w*_thumbnail->h; ++p) 81 ((uint16*)_thumbnail->pixels)[p] = file->readUint16BE(); 82 83 uint16* pixels = (uint16*)_thumbnail->pixels; 84 85 for (int y = 0; y < _thumbnail->h; ++y) { 86 for (int x = 0; x < _thumbnail->w; ++x) { 87 uint8 r, g, b; 88 colorToRGB(((const uint16*)pixels)[y * _thumbnail->w + x], r, g, b); 89 90 // converting to current OSystem Color 91 pixels[y * _thumbnail->w + x] = _system->RGBToColor(r, g, b); 92 } 93 } 94 95 return true; 96 } 97 98 void ScummEngine::saveThumbnail(OutSaveFile *file) { 99 if (_thumbnail) 100 _thumbnail->free(); 101 else if (!_thumbnail) 102 _thumbnail = new Graphics::Surface(); 103 104 if (!createThumbnailFromScreen(_thumbnail)) 105 _thumbnail->create(kThumbnailWidth, kThumbnailHeight_2, sizeof(uint16)); 106 107 ThumbnailHeader header; 108 header.type = MKID('THMB'); 109 header.size = sizeof(header) + _thumbnail->w*_thumbnail->h*_thumbnail->bytesPerPixel; 110 header.version = THMB_VERSION; 111 header.width = _thumbnail->w; 112 header.height = _thumbnail->h; 113 header.bpp = _thumbnail->bytesPerPixel; 114 115 file->writeUint32BE(header.type); 116 file->writeUint32BE(header.size); 117 file->writeByte(header.version); 118 file->writeUint16BE(header.width); 119 file->writeUint16BE(header.height); 120 file->writeByte(header.bpp); 121 122 // TODO: for later this shouldn't be hardcastet to uint16... 123 for (uint16 p = 0; p < _thumbnail->w*_thumbnail->h; ++p) 124 file->writeUint16BE(((uint16*)_thumbnail->pixels)[p]); 125 126 if (_thumbnail) 127 _thumbnail->free(); 128 delete _thumbnail; 129 _thumbnail = 0; 130 } 131 } // end of namespace Scumm