Ticket #8405: thumbnail-v4-2-new.patch
File thumbnail-v4-2-new.patch, 33.7 KB (added by , 20 years ago) |
---|
-
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 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}, … … 806 807 SDL_UnlockSurface(_screen); 807 808 } 808 809 810 void OSystem_SDL::grabRawScreen(Graphics::Surface *surf) { 811 assert(_screen); 812 assert(surf); 813 814 Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends 815 816 surf->create(_screenWidth, _screenHeight, _screen->format->BytesPerPixel); 817 818 // Try to lock the screen surface 819 if (SDL_LockSurface(_screen) == -1) 820 error("SDL_LockSurface failed: %s", SDL_GetError()); 821 822 memcpy(surf->pixels, _screen->pixels, _screenWidth * _screenHeight * _screen->format->BytesPerPixel); 823 824 // Unlock the screen surface 825 SDL_UnlockSurface(_screen); 826 } 809 827 810 828 void OSystem_SDL::addDirtyRect(int x, int y, int w, int h, bool mouseRect) { 811 829 if (_forceFull) … … 992 1010 blitCursor(); 993 1011 } 994 1012 1013 void OSystem_SDL::grabPalette(byte *colors, uint start, uint num) { 1014 assert(colors); 1015 const SDL_Color *base = _currentPalette + start; 1016 1017 for (uint i = 0; i < num; ++i) { 1018 colors[i * 4] = base[i].r; 1019 colors[i * 4 + 1] = base[i].g; 1020 colors[i * 4 + 2] = base[i].b; 1021 colors[i * 4 + 3] = 0xFF; 1022 } 1023 } 1024 995 1025 void OSystem_SDL::setCursorPalette(const byte *colors, uint start, uint num) { 996 1026 assert(colors); 997 1027 const byte *b = colors; -
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 80 80 81 81 // Set colors of the palette 82 82 void setPalette(const byte *colors, uint start, uint num); 83 84 // Get colors of the palette 85 void grabPalette(byte *colors, uint start, uint num); 83 86 84 87 // Draw a bitmap to screen. 85 88 // The screen will not be updated to reflect the new bitmap 86 89 void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); 87 90 91 // Copies the screen to a buffer 92 void grabRawScreen(Graphics::Surface *surf); 93 88 94 // Clear the screen 89 95 void clearScreen(); 90 96 -
common/module.mk
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/common/module.mk ./scummvm/common/module.mk
old new 22 22 common/scaler/hq3x.o \ 23 23 common/scaler/scale2x.o \ 24 24 common/scaler/scale3x.o \ 25 common/scaler/scalebit.o 25 common/scaler/scalebit.o \ 26 common/scaler/thumbnail.o 26 27 27 28 ifdef HAVE_NASM 28 29 MODULE_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 "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 if (gBitFormat == 565) 92 createThumbnail_2<565>(src, srcPitch, dstPtr, dstPitch, width, height); 93 else if (gBitFormat == 555) 94 createThumbnail_2<555>(src, srcPitch, dstPtr, dstPitch, width, height); 95 } else if (downScaleMode == 4) { 96 if (gBitFormat == 565) 97 createThumbnail_4<565>(src, srcPitch, dstPtr, dstPitch, width, height); 98 else if (gBitFormat = 555) 99 createThumbnail_4<555>(src, srcPitch, dstPtr, dstPitch, width, height); 100 } 101 } 102 103 bool createThumbnailFromScreen(Graphics::Surface* surf) { 104 assert(surf); 105 106 int screenWidth = OSystem::instance().getWidth(); 107 int screenHeight = OSystem::instance().getHeight(); 108 109 Graphics::Surface screen; 110 OSystem::instance().grabScreen(&screen, 16); 111 112 if (!screen.pixels) 113 return false; 114 115 uint16 width = screenWidth; 116 117 if (screenWidth < 320) { 118 width = 320; 119 120 // center MM NES screen 121 Graphics::Surface newscreen; 122 newscreen.create(width, screen.h, screen.bytesPerPixel); 123 124 uint8 *dst = (uint8*)newscreen.getBasePtr((320 - screenWidth) / 2, 0); 125 uint8 *src = (uint8*)screen.getBasePtr(0, 0); 126 uint16 height = screen.h; 127 128 while (height--) { 129 memcpy(dst, src, screen.pitch); 130 dst += newscreen.pitch; 131 src += screen.pitch; 132 } 133 134 screen.free(); 135 screen = newscreen; 136 } 137 if (screenWidth == 720) { 138 width = 640; 139 screenHeight = 400; 140 141 // cut off menu and so on.. 142 Graphics::Surface newscreen; 143 newscreen.create(width, 400, screen.bytesPerPixel); 144 145 uint8 *dst = (uint8*)newscreen.getBasePtr(0, (400 - 240) / 2); 146 uint8 *src = (uint8*)screen.getBasePtr(41, 28); 147 148 for (int y = 0; y < 240; ++y) { 149 memcpy(dst, src, 640 * screen.bytesPerPixel); 150 dst += newscreen.pitch; 151 src += screen.pitch; 152 } 153 154 screen.free(); 155 screen = newscreen; 156 } 157 158 uint16 newHeight = !(screenHeight % 240) ? kThumbnailHeight_2 : kThumbnailHeight_1; 159 160 int gBitFormatBackUp = gBitFormat; 161 gBitFormat = 565; 162 surf->create(kThumbnailWidth, newHeight, sizeof(uint16)); 163 createThumbnail((const uint8*)screen.pixels, width * sizeof(uint16), (uint8*)surf->pixels, surf->pitch, width, screenHeight); 164 gBitFormat = gBitFormatBackUp; 165 166 screen.free(); 167 168 return true; 169 } -
common/scaler.h
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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 --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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() { … … 92 94 SaveFileManager *OSystem::getSavefileManager() { 93 95 return new DefaultSaveFileManager(); 94 96 } 97 98 void OSystem::grabScreen(Graphics::Surface *surf, int bitsPerPixel) { 99 if (bitsPerPixel != 15 && bitsPerPixel != 16) 100 error("only 15 and 16 bpp are supported"); 101 102 Graphics::Surface screen; 103 grabRawScreen(&screen); 104 105 if (screen.bytesPerPixel != 1 || screen.pixels == 0) 106 return; 107 108 byte palette[256 * 4]; 109 grabPalette(&palette[0], 0, 256); 110 111 surf->create(screen.w, screen.h, (bitsPerPixel + 1) / 8); 112 113 for (uint y = 0; y < screen.h; ++y) { 114 for (uint x = 0; x < screen.w; ++x) { 115 byte r, g, b; 116 r = palette[((uint8*)screen.pixels)[y * screen.pitch + x] * 4]; 117 g = palette[((uint8*)screen.pixels)[y * screen.pitch + x] * 4 + 1]; 118 b = palette[((uint8*)screen.pixels)[y * screen.pitch + x] * 4 + 2]; 119 120 if (bitsPerPixel == 15) { 121 ((uint16*)surf->pixels)[y * surf->w + x] = (((r >> 3) & 0x1F) << 10) | (((g >> 3) & 0x1F) << 5) | ((b >> 3) & 0x1F); 122 } else if (bitsPerPixel == 16) { 123 ((uint16*)surf->pixels)[y * surf->w + x] = (((r >> 3) & 0x1F) << 11) | (((g >> 2) & 0x3F) << 5) | ((b >> 3) & 0x1F); 124 } 125 } 126 } 127 128 screen.free(); 129 } -
common/system.h
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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 /** … … 358 362 * API are probably going to remove it. 359 363 */ 360 364 virtual void setPalette(const byte *colors, uint start, uint num) = 0; 365 366 /** 367 * Grabs a specified part of the palette 368 * format is like it is described in setPalette 369 * 370 * @param buf the buffer 371 * @param start the first platte entry 372 * @param num nummber of the entries 373 */ 374 virtual void grabPalette(byte *colors, uint start, uint num) = 0; 361 375 362 376 /** 363 377 * Blit a bitmap to the virtual screen. … … 368 382 * @see updateScreen 369 383 */ 370 384 virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) = 0; 385 386 /** 387 * Copies the screen to a surface 388 * if bitsPerPixel = 15 a RGB555 format is used 389 * if bitsPerPixel = 16 a RGB565 format is used 390 * WARNING: surf->free() musst be called by the user 391 * 392 * @param surf the surfce to store the data in it 393 * @param bitsPerPixel must be higher than 15 and lower than 16 394 */ 395 virtual void grabScreen(Graphics::Surface *surf, int bitsPerPixel); 396 397 /** 398 * Copies the screen to a surface (with original bit depth) 399 * It should return a 1 byte per pixel surface in all cases 400 * because currently all games supported by ScummVM are 401 * using 1 byte per pixel. 402 * WARNING: surf->free() musst be called by the user 403 * 404 * @param surf the surfce to store the data in it 405 */ 406 virtual void grabRawScreen(Graphics::Surface *surf) = 0; 371 407 372 408 /** 373 409 * Clear the screen to black. -
graphics/surface.cpp
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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) { 28 46 // Clipping 29 47 if (y < 0 || y >= h) -
graphics/surface.h
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/graphics/surface.h ./scummvm/graphics/surface.h
old new 46 46 inline void *getBasePtr(int x, int y) { 47 47 return static_cast<void *>(static_cast<byte *>(pixels) + y * pitch + x * bytesPerPixel); 48 48 } 49 50 void create(uint16 width, uint16 height, uint8 bytesPP); 51 void free(); 49 52 50 53 void hLine(int x, int y, int x2, uint32 color); 51 54 void vLine(int x, int y, int y2, uint32 color); -
gui/newgui.cpp
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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 … … 341 342 return; 342 343 343 344 assert(s.bytesPerPixel == sizeof(OverlayColor)); 344 345 345 346 OverlayColor *src = (OverlayColor *)s.pixels; 346 347 OverlayColor *dst = getBasePtr(rect.left, rect.top); 347 348 348 int w = rect.width(); 349 349 int h = rect.height(); 350 350 -
gui/widget.cpp
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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) … … 276 275 return (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin; 277 276 } 278 277 278 #pragma mark - 279 280 GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h) 281 : Widget(boss, x, y, w, h), _gfx() { 282 _flags = WIDGET_ENABLED | WIDGET_CLEARBG; 283 _type = kGraphicsWidget; 284 } 285 286 GraphicsWidget::~GraphicsWidget() { 287 _gfx.free(); 288 } 289 290 void GraphicsWidget::setGfx(const Graphics::Surface *gfx) { 291 _gfx.free(); 292 293 if(!gfx) 294 return; 295 if(!gfx->pixels) 296 return; 297 298 // TODO: add conversion to OverlayColor 299 _gfx.create(gfx->w, gfx->h, gfx->bytesPerPixel); 300 memcpy(_gfx.pixels, gfx->pixels, gfx->h * gfx->pitch); 301 } 302 303 void GraphicsWidget::drawWidget(bool hilite) { 304 if(sizeof(OverlayColor) != _gfx.bytesPerPixel || !_gfx.pixels) { 305 g_gui.drawString("No preview", _x, _y + _h / 2 - g_gui.getFontHeight() / 2, _w, g_gui._textcolor, Graphics::kTextAlignCenter); 306 return; 307 } 308 309 uint drawWidth = _gfx.w, drawHeight = _gfx.h; 310 311 if(_w < _gfx.w) 312 drawWidth = _w; 313 if(_h < _gfx.h) 314 drawHeight = _h; 315 316 g_gui.drawSurface(_gfx, _x, _y); 317 } 318 279 319 } // 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 24 24 #include "common/scummsys.h" 25 25 #include "common/str.h" 26 26 #include "graphics/font.h" 27 #include "graphics/surface.h" 27 28 #include "gui/object.h" 28 29 29 30 namespace GUI { … … 52 53 kListWidget = 'LIST', 53 54 kScrollBarWidget = 'SCRB', 54 55 kPopUpWidget = 'POPU', 55 kTabWidget = 'TABW' 56 kTabWidget = 'TABW', 57 kGraphicsWidget = 'GFXW' 56 58 }; 57 59 58 60 enum { … … 210 212 int posToValue(int pos); 211 213 }; 212 214 215 /* GraphicsWidget */ 216 class GraphicsWidget : public Widget { 217 public: 218 GraphicsWidget(GuiObject *boss, int x, int y, int w, int h); 219 ~GraphicsWidget(); 220 221 void setGfx(const Graphics::Surface *gfx); 222 protected: 223 void drawWidget(bool hilite); 224 225 Graphics::Surface _gfx; 226 }; 227 213 228 } // End of namespace GUI 214 229 215 230 #endif -
scumm/dialogs.cpp
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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 BaseSaveLoadChooser { 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 BaseSaveLoadChooser { 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 bool wantsScaling() const { return false; } 281 }; 282 283 SaveLoadChooserEx::SaveLoadChooserEx(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine) 284 : Dialog(8, 8, engine->_system->getOverlayWidth() - 2 * 8, engine->_system->getOverlayHeight() - 16), _saveMode(saveMode), _list(0), _chooseButton(0), _gfxWidget(0), _scumm(engine) { 285 286 new StaticTextWidget(this, 10, 6, _w - 2 * 10, kLineHeight, title, kTextAlignCenter); 287 288 // Add choice list 289 _list = new GUI::ListWidget(this, 10, 18, _w - 2 * 10 - 180, _h - 14 - 24 - 10); 290 _list->setEditable(saveMode); 291 _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero); 292 293 // Add the thumbnail display 294 _gfxWidget = new GUI::GraphicsWidget(this, _w - (kThumbnailWidth + 22), _y + 6, kThumbnailWidth + 8, ((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight_2 : kThumbnailHeight_1) + 8); 295 _gfxWidget->setFlags(GUI::WIDGET_BORDER); 296 297 // Buttons 298 addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0); 299 _chooseButton = addButton(_w-(kButtonWidth + 10), _h - 24, buttonLabel, kChooseCmd, 0); 300 _chooseButton->setEnabled(false); 301 } 302 303 const Common::String &SaveLoadChooserEx::getResultString() const { 304 return _list->getSelectedString(); 305 } 306 307 void SaveLoadChooserEx::setList(const StringList& list) { 308 _list->setList(list); 309 } 310 311 int SaveLoadChooserEx::runModal() { 312 _gfxWidget->setGfx(0); 313 int ret = GUI::Dialog::runModal(); 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->_thumbnail); 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 --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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 BaseSaveLoadChooser 61 { 62 public: 63 virtual ~BaseSaveLoadChooser() {}; 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 SaveLoadChooser *_saveDialog;72 SaveLoadChooser *_loadDialog;82 BaseSaveLoadChooser *_saveDialog; 83 BaseSaveLoadChooser *_loadDialog; 73 84 74 85 void save(); 75 86 void load(); -
scumm/module.mk
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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 --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/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); … … 126 127 delete in; 127 128 return false; 128 129 } 130 131 // Sine version 52 a thumbnail is saved directly after the header 132 if (hdr.ver >= VER(52)) { 133 if(!loadThumbnail(in)) { 134 warning("Can not load thumbnail"); 135 delete in; 136 return false; 137 } 138 } 129 139 130 140 // Due to a bug in scummvm up to and including 0.3.0, save games could be saved 131 141 // in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here … … 387 397 return true; 388 398 } 389 399 400 bool ScummEngine::getThumbnail(int slot) { 401 char filename[256]; 402 InSaveFile *in; 403 SaveGameHeader hdr; 404 int len; 405 406 if (_thumbnail) 407 _thumbnail->free(); 408 delete _thumbnail; 409 _thumbnail = 0; 410 411 makeSavegameName(filename, slot, false); 412 if (!(in = _saveFileMan->openForLoading(filename))) { 413 return false; 414 } 415 len = in->read(&hdr, sizeof(hdr)); 416 417 if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) { 418 delete in; 419 return false; 420 } 421 422 if (hdr.ver > CURRENT_VER) 423 hdr.ver = TO_LE_32(hdr.ver); 424 if (hdr.ver < VER(52)) { 425 delete in; 426 return false; 427 } 428 429 loadThumbnail(in); 430 431 delete in; 432 return true; 433 } 434 390 435 void ScummEngine::saveOrLoad(Serializer *s, uint32 savegameVersion) { 391 436 const SaveLoadEntry objectEntries[] = { 392 437 MKLINE(ObjectData, OBIMoffset, sleUint32, VER(8)), -
scumm/saveload.h
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/saveload.h ./scummvm/scumm/saveload.h
old new 43 43 * only saves/loads those which are valid for the version of the savegame 44 44 * which is being loaded/saved currently. 45 45 */ 46 #define CURRENT_VER 5 146 #define CURRENT_VER 52 47 47 48 48 /** 49 49 * An auxillary macro, used to specify savegame versions. We use this instead -
scumm/scumm.cpp
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/scumm.cpp ./scummvm/scumm/scumm.cpp
old new 648 648 _platform(gs.platform), 649 649 gdi(this), 650 650 res(this), 651 _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0), 651 _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0), _thumbnail(0), 652 652 _targetName(detector->_targetName) { 653 653 654 654 // 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 27 27 #include "common/file.h" 28 28 #include "common/rect.h" 29 29 #include "common/str.h" 30 #include "graphics/surface.h" 30 31 31 32 #include "scumm/gfx.h" 32 33 #include "scumm/script.h" 33 34 35 // FIXME: 36 // define it in a other location 37 #define THMB_VERSION 1 38 34 39 namespace GUI { 35 40 class Dialog; 36 41 } 37 42 using GUI::Dialog; 38 43 class GameDetector; 39 44 class InSaveFile; 45 class OutSaveFile; 40 46 41 47 namespace Scumm { 42 48 … … 53 59 class ScummDebugger; 54 60 class Serializer; 55 61 class Sound; 62 class SaveLoadChooserEx; 56 63 57 64 struct Box; 58 65 struct BoxCoords; … … 353 360 friend class Insane; 354 361 friend class CharsetRenderer; 355 362 friend class ResourceManager; 363 friend class SaveLoadChooserEx; 356 364 357 365 void errorString(const char *buf_input, char *buf_output); 358 366 public: … … 577 585 void requestSave(int slot, const char *name, bool temporary = false); 578 586 void requestLoad(int slot); 579 587 588 // thumbnail stuff 589 public: 590 bool getThumbnail(int slot); 591 const void* getThumbnail() { if(_thumbnail) return _thumbnail->pixels; return 0; } 592 uint16 getThumbnailHeight() { if(_thumbnail) return _thumbnail->h; return 0; } 593 uint16 getThumbnailWidth() { if(_thumbnail) return _thumbnail->w; return 0; } 594 595 protected: 596 bool loadThumbnail(InSaveFile *file); 597 void saveThumbnail(OutSaveFile *file); 598 599 Graphics::Surface *_thumbnail; 600 601 struct ThumbnailHeader { 602 uint32 type; 603 uint32 size; 604 byte version; 605 uint16 width, height; 606 byte bpp; 607 }; 608 // ends here 609 580 610 protected: 581 611 /* Script VM - should be in Script class */ 582 612 uint32 _localScriptOffsets[1024]; -
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 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 casted 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