diff options
author | Norbert Lange | 2009-08-24 17:51:47 +0000 |
---|---|---|
committer | Norbert Lange | 2009-08-24 17:51:47 +0000 |
commit | 917d4b78b36d6c5a5c25a03e7ee6a1c1b6a85fd5 (patch) | |
tree | e652563203a00f8acecfaafbf93c64dbfbd13f25 | |
parent | 5f87d5090cfcb34cda3c1f5d430e0865344d7366 (diff) | |
parent | dd7868acc2512c9761d892e67a4837f4dc38bdc0 (diff) | |
download | scummvm-rg350-917d4b78b36d6c5a5c25a03e7ee6a1c1b6a85fd5.tar.gz scummvm-rg350-917d4b78b36d6c5a5c25a03e7ee6a1c1b6a85fd5.tar.bz2 scummvm-rg350-917d4b78b36d6c5a5c25a03e7ee6a1c1b6a85fd5.zip |
Merge with trunk
svn-id: r43701
232 files changed, 6083 insertions, 6629 deletions
@@ -159,6 +159,9 @@ ScummVM Team iPhone: Oystein Eftevaag + LinuxMoto: + Lubomyr Lisen + Maemo: Frantisek Dufka @@ -314,6 +317,7 @@ Other contributions Andreas Karlsson - Initial port for SymbianOS Claudio Matsuoka - Daily Linux builds Thomas Mayer - PSP port contributions + Yotam Barnoy - PSP port suspend/resume support Sean Murray - ScummVM tools GUI application (GSoC 2007 task) n0p - Windows CE port aspect ratio correction scaler and right click input method @@ -205,3 +205,4 @@ Robert Wohlrab "moshroum" Xanathar "xanathar" Grant Yeager "glo_kidd" Benjamin W. Zale "junior_aepi" +Yotam Barnoy "bluddy" @@ -68,7 +68,7 @@ config.h config.mk: $(srcdir)/configure ifeq "$(findstring config.mk,$(MAKEFILE_LIST))" "config.mk" @echo "Running $(srcdir)/configure with the last specified parameters" @sleep 2 - LDFLAGS="$(SAVED_LDFLAGS)" CXX="$(SAVED_CXX)" CXXFLAGS="$(SAVED_CXXFLAGS)" CPPFLAGS="$(SAVED_CPPFLAGS)" \ + LDFLAGS="$(SAVED_LDFLAGS)" CXX="$(SAVED_CXX)" CXXFLAGS="$(SAVED_CXXFLAGS)" CPPFLAGS="$(SAVED_CPPFLAGS)" ASFLAGS="$(SAVED_ASFLAGS)" \ $(srcdir)/configure $(SAVED_CONFIGFLAGS) else $(error You need to run $(srcdir)/configure before you can run make. Check $(srcdir)/configure --help for a list of parameters) diff --git a/Makefile.common b/Makefile.common index caf5ba22fa..81593edf9d 100644 --- a/Makefile.common +++ b/Makefile.common @@ -62,9 +62,25 @@ DEPFILES = # the build date in gScummVMBuildDate is correct. base/version.o: $(filter-out base/libbase.a,$(OBJS)) +# Replace regular output with quiet messages +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifneq ($(VERBOSE_BUILD),1) +ifneq ($(VERBOSE_BUILD),yes) +QUIET_CXX = @echo ' ' C++ ' ' $@; +QUIET_AS = @echo ' ' AS ' ' $@; +QUIET_NASM = @echo ' ' NASM ' ' $@; +QUIET_AR = @echo ' ' AR ' ' $@; +QUIET_RANLIB = @echo ' ' RANLIB ' ' $@; +QUIET_PLUGIN = @echo ' ' PLUGIN ' ' $@; +QUIET_LINK = @echo ' ' LINK ' ' $@; +QUIET = @ +endif +endif +endif + # The build rule for the ScummVM executable $(EXECUTABLE): $(OBJS) - $(CXX) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) -o $@ + $(QUIET_LINK)$(CXX) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) -o $@ distclean: clean $(RM) config.h config.mk config.log @@ -83,27 +99,30 @@ ifndef HAVE_GCC3 # If you use GCC, disable the above and enable this for intelligent # dependency tracking. %.o: %.cpp - $(MKDIR) $(*D)/$(DEPDIR) - $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o - $(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d - $(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d" - $(RM) "$(*D)/$(DEPDIR)/$(*F).d2" + $(QUIET)$(MKDIR) $(*D)/$(DEPDIR) + $(QUIET_CXX)$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o + $(QUIET)$(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d + $(QUIET)$(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d" + $(QUIET)$(RM) "$(*D)/$(DEPDIR)/$(*F).d2" else # If you even have GCC 3.x, you can use this build rule, which is safer; the above # rule can get you into a bad state if you Ctrl-C at the wrong moment. # Also, with this GCC inserts additional dummy rules for the involved headers, # which ensures a smooth compilation even if said headers become obsolete. %.o: %.cpp - $(MKDIR) $(*D)/$(DEPDIR) - $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o + $(QUIET)$(MKDIR) $(*D)/$(DEPDIR) + $(QUIET_CXX)$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o %.o: %.m - $(MKDIR) $(*D)/$(DEPDIR) - $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(OBJCFLAGS) -c $(<) -o $*.o + $(QUIET)$(MKDIR) $(*D)/$(DEPDIR) + $(QUIET_CXX)$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(OBJCFLAGS) -c $(<) -o $*.o endif +%.o: %.s + $(QUIET_AS)$(AS) $(ASFLAGS) $(<) -o $*.o + ifdef HAVE_NASM %.o: %.asm - $(NASM) -O1 $(NASMFLAGS) -g -o $*.o $(<) + $(QUIET_NASM)$(NASM) -O1 $(NASMFLAGS) -g -o $*.o $(<) endif # Include the dependency tracking files. @@ -2,6 +2,12 @@ For a more comprehensive changelog for the latest experimental SVN code, see: http://scummvm.svn.sourceforge.net/viewvc/scummvm/?view=log 1.1.0 (????-??-??) + New Games: + - Added support for Blue's Art Time Activities. + - Added support for Blue's Reading Time Activities. + - Added support for Freddi Fish 5: The Case of the Creature of Coral Cave. + - Added support for Pajama Sam: Games to Play on Any Day. + General: - Added support for a custom SJIS font for FM-TOWNS and PC98 games. @@ -9,7 +15,7 @@ For a more comprehensive changelog for the latest experimental SVN code, see: - Added support for the Amiga version of The Legend of Kyrandia. - Adapted KYRA to support the custom SJIS font. -1.0.0 (2009-??-??) +1.0.0rc1 (2009-08-31) New Games: - Added support for Discworld. - Added support for Discworld 2 - Missing Presumed ...!?. @@ -59,6 +65,9 @@ For a more comprehensive changelog for the latest experimental SVN code, see: - Added support for PC Speaker based music and sound effects. - Added support for 16 color dithering in Kyrandia PC-9801. + PSP port: + - Added support for sleep mode (suspend/resume). + WinCE port: - Speed optimized versions of low-res Smartphone and 2x scalers. - New aspect correction scaler for VGA (or higher) devices. @@ -260,6 +260,8 @@ SCUMM Games by Humongous Entertainment: Big Thinkers Kindergarten [thinkerk] Blue's 123 Time Activities [Blues123Time] Blue's ABC Time Activities [BluesABCTime] + Blue's Art Time Activities [arttime] + Blue's Reading Time Activities [readtime] Fatty Bear's Birthday Surprise [fbear] Fatty Bear's Fun Pack [fbpack] Freddi Fish 1: The Case of the Missing @@ -270,6 +272,8 @@ SCUMM Games by Humongous Entertainment: Conch Shell [freddi3] Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch [freddi4] + Freddi Fish 5: The Case of the Creature + of Coral Cave [freddicove] Freddi Fish and Luther's Maze Madness [maze] Freddi Fish and Luther's Water Worries [water] Let's Explore the Airport with Buzzy [airport] @@ -295,6 +299,7 @@ SCUMM Games by Humongous Entertainment: Putt-Putt's Fun Pack [funpack] SPY Fox 1: Dry Cereal [spyfox] SPY Fox 2: Some Assembly Required [spyfox2] + SPY Fox 3: Operation Ozone [spyozon] SPY Fox in Cheese Chase [chase] SPY Fox in Hold the Mustard [mustard] @@ -304,10 +309,15 @@ If you want the latest updates on game compatibility, visit our web site and view the compatibility chart. Backyard Baseball [baseball] + Backyard Baseball 2001 [baseball2001] + Backyard Baseball 2003 [baseball2003] + Backyard Football 2002 [football2002] Backyard Soccer [soccer] + Backyard Soccer MLS [soccermls] + Backyard Soccer 2004 [soccer2004] Blue's Birthday Adventure [BluesBirthday] Blue's Treasure Hunt [BluesTreasureHunt] - SPY Fox 3: Operation Ozone [spyozon] + Pajama Sam: Games to Play on Any Day [pjgames] The following games are based on the SCUMM engine, but NOT supported by ScummVM (yet): diff --git a/backends/fs/psp/psp-fs-factory.cpp b/backends/fs/psp/psp-fs-factory.cpp index 27bee4de86..7ed84de034 100644 --- a/backends/fs/psp/psp-fs-factory.cpp +++ b/backends/fs/psp/psp-fs-factory.cpp @@ -34,7 +34,13 @@ AbstractFSNode *PSPFilesystemFactory::makeRootFileNode() const { AbstractFSNode *PSPFilesystemFactory::makeCurrentDirectoryFileNode() const { char buf[MAXPATHLEN]; - return getcwd(buf, MAXPATHLEN) ? new PSPFilesystemNode(buf) : NULL; + char * ret = 0; + + PowerMan.beginCriticalSection(); + ret = getcwd(buf, MAXPATHLEN); + PowerMan.endCriticalSection(); + + return (ret ? new PSPFilesystemNode(buf) : NULL); } AbstractFSNode *PSPFilesystemFactory::makeFileNodePath(const Common::String &path) const { diff --git a/backends/fs/psp/psp-fs.cpp b/backends/fs/psp/psp-fs.cpp index f5ff65c9fa..03247e86ad 100644 --- a/backends/fs/psp/psp-fs.cpp +++ b/backends/fs/psp/psp-fs.cpp @@ -26,7 +26,8 @@ #include "engines/engine.h" #include "backends/fs/abstract-fs.h" -#include "backends/fs/stdiostream.h" +#include "backends/fs/psp/psp-stream.h" +#include "backends/platform/psp/powerman.h" #include <sys/stat.h> #include <unistd.h> @@ -35,6 +36,9 @@ #define ROOT_PATH "ms0:/" +#include "backends/platform/psp/trace.h" + + /** * Implementation of the ScummVM file system API based on PSPSDK API. * @@ -61,13 +65,13 @@ public: */ PSPFilesystemNode(const Common::String &p, bool verify = true); - virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; } + virtual bool exists() const; virtual Common::String getDisplayName() const { return _displayName; } virtual Common::String getName() const { return _displayName; } virtual Common::String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } - virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } + virtual bool isReadable() const; + virtual bool isWritable() const; virtual AbstractFSNode *getChild(const Common::String &n) const; virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const; @@ -94,11 +98,44 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) { if (verify) { struct stat st; + PowerMan.beginCriticalSection(); _isValid = (0 == stat(_path.c_str(), &st)); + PowerMan.endCriticalSection(); _isDirectory = S_ISDIR(st.st_mode); } } +bool PSPFilesystemNode::exists() const { + int ret = 0; + + PowerMan.beginCriticalSection(); // Make sure to block in case of suspend + ret = access(_path.c_str(), F_OK); + PowerMan.endCriticalSection(); + + return ret == 0; +} + +bool PSPFilesystemNode::isReadable() const { + int ret = 0; + + PowerMan.beginCriticalSection(); // Make sure to block in case of suspend + ret = access(_path.c_str(), R_OK); + PowerMan.endCriticalSection(); + + return ret == 0; +} + +bool PSPFilesystemNode::isWritable() const { + int ret = 0; + + PowerMan.beginCriticalSection(); // Make sure to block in case of suspend + ret = access(_path.c_str(), W_OK); + PowerMan.endCriticalSection(); + + return ret == 0; +} + + AbstractFSNode *PSPFilesystemNode::getChild(const Common::String &n) const { // FIXME: Pretty lame implementation! We do no error checking to speak // of, do not check if this is a special node, etc. @@ -117,6 +154,10 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool //TODO: honor the hidden flag + bool ret = true; + + PowerMan.beginCriticalSection(); // Make sure to block in case of suspend + int dfd = sceIoDopen(_path.c_str()); if (dfd > 0) { SceIoDirent dir; @@ -149,10 +190,13 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool } sceIoDclose(dfd); - return true; - } else { - return false; + ret = true; + } else { // dfd <= 0 + ret = false; } + + PowerMan.endCriticalSection(); + return ret; } AbstractFSNode *PSPFilesystemNode::getParent() const { @@ -166,11 +210,11 @@ AbstractFSNode *PSPFilesystemNode::getParent() const { } Common::SeekableReadStream *PSPFilesystemNode::createReadStream() { - return StdioStream::makeFromPath(getPath().c_str(), false); + return PSPIoStream::makeFromPath(getPath(), false); } Common::WriteStream *PSPFilesystemNode::createWriteStream() { - return StdioStream::makeFromPath(getPath().c_str(), true); + return PSPIoStream::makeFromPath(getPath(), true); } #endif //#ifdef __PSP__ diff --git a/backends/module.mk b/backends/module.mk index f3294c5dc6..42fbeb07eb 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -11,6 +11,7 @@ MODULE_OBJS := \ fs/posix/posix-fs-factory.o \ fs/ps2/ps2-fs-factory.o \ fs/psp/psp-fs-factory.o \ + fs/psp/psp-stream.o \ fs/symbian/symbian-fs-factory.o \ fs/windows/windows-fs-factory.o \ fs/wii/wii-fs-factory.o \ diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h index b67bbb51a1..f5d200968e 100644 --- a/backends/platform/dc/dc.h +++ b/backends/platform/dc/dc.h @@ -84,7 +84,7 @@ class OSystem_Dreamcast : private DCHardware, public BaseBackend, public Filesys // Set the size of the video bitmap. // Typically, 320x200 - void initSize(uint w, uint h); + void initSize(uint w, uint h, const Graphics::PixelFormat *format); int16 getHeight() { return _screen_h; } int16 getWidth() { return _screen_w; } @@ -105,7 +105,7 @@ class OSystem_Dreamcast : private DCHardware, public BaseBackend, public Filesys void warpMouse(int x, int y); // Set the bitmap that's used when drawing the cursor. - void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); + void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // Replace the specified range of cursor the palette with new colors. void setCursorPalette(const byte *colors, uint start, uint num); diff --git a/backends/platform/dc/display.cpp b/backends/platform/dc/display.cpp index d1e95c6a91..c6be514e36 100644 --- a/backends/platform/dc/display.cpp +++ b/backends/platform/dc/display.cpp @@ -193,7 +193,7 @@ void OSystem_Dreamcast::setScaling() } } -void OSystem_Dreamcast::initSize(uint w, uint h) +void OSystem_Dreamcast::initSize(uint w, uint h, const Graphics::PixelFormat *format) { assert(w <= SCREEN_W && h <= SCREEN_H); @@ -263,7 +263,7 @@ void OSystem_Dreamcast::warpMouse(int x, int y) void OSystem_Dreamcast::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, - byte keycolor, int cursorTargetScale) + uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { _ms_cur_w = w; _ms_cur_h = h; @@ -271,7 +271,7 @@ void OSystem_Dreamcast::setMouseCursor(const byte *buf, uint w, uint h, _ms_hotspot_x = hotspot_x; _ms_hotspot_y = hotspot_y; - _ms_keycolor = keycolor; + _ms_keycolor = (byte)keycolor; if (_ms_buf) free(_ms_buf); diff --git a/backends/platform/gp2x/gp2x-common.h b/backends/platform/gp2x/gp2x-common.h index 4e6421f353..c8bbd93de0 100644 --- a/backends/platform/gp2x/gp2x-common.h +++ b/backends/platform/gp2x/gp2x-common.h @@ -58,7 +58,7 @@ public: // Set the size of the video bitmap. // Typically, 320x200 - void initSize(uint w, uint h); + void initSize(uint w, uint h, const Graphics::PixelFormat *format); int getScreenChangeID() const { return _screenChangeCount; } @@ -87,7 +87,7 @@ public: void warpMouse(int x, int y); // Set the bitmap that's used when drawing the cursor. - void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); + void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // Set colors of cursor palette void setCursorPalette(const byte *colors, uint start, uint num); diff --git a/backends/platform/gp2x/graphics.cpp b/backends/platform/gp2x/graphics.cpp index 229f840d11..cf874323e0 100644 --- a/backends/platform/gp2x/graphics.cpp +++ b/backends/platform/gp2x/graphics.cpp @@ -240,9 +240,27 @@ int OSystem_GP2X::getGraphicsMode() const { return _videoMode.mode; } -void OSystem_GP2X::initSize(uint w, uint h){ +void OSystem_GP2X::initSize(uint w, uint h, const Graphics::PixelFormat *format) { assert(_transactionMode == kTransactionActive); +#ifdef USE_RGB_COLOR + //avoid redundant format changes + Graphics::PixelFormat newFormat; + if (!format) + newFormat = Graphics::PixelFormat::createFormatCLUT8(); + else + newFormat = *format; + + assert(newFormat.bytesPerPixel > 0); + + if (newFormat != _videoMode.format) + { + _videoMode.format = newFormat; + _transactionDetails.formatChanged = true; + _screenFormat = newFormat; + } +#endif + // Avoid redundant res changes if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight) return; @@ -1212,7 +1230,17 @@ void OSystem_GP2X::warpMouse(int x, int y) { } } -void OSystem_GP2X::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) { +void OSystem_GP2X::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +#ifdef USE_RGB_COLOR + if (!format) + _cursorFormat = Graphics::PixelFormat::createFormatCLUT8(); + else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel) + _cursorFormat = *format; + keycolor &= (1 << (_cursorFormat.bytesPerPixel << 3)) - 1; +#else + keycolor &= 0xFF; +#endif + if (w == 0 || h == 0) return; @@ -1246,16 +1274,26 @@ void OSystem_GP2X::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x } free(_mouseData); - +#ifdef USE_RGB_COLOR + _mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel); + memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel); +#else _mouseData = (byte *)malloc(w * h); memcpy(_mouseData, buf, w * h); +#endif + blitCursor(); } void OSystem_GP2X::blitCursor() { byte *dstPtr; const byte *srcPtr = _mouseData; +#ifdef USE_RGB_COLOR + uint32 color; + uint32 colormask = (1 << (_cursorFormat.bytesPerPixel << 3)) - 1; +#else byte color; +#endif int w, h, i, j; if (!_mouseOrigSurface || !_mouseData) @@ -1289,13 +1327,29 @@ void OSystem_GP2X::blitCursor() { for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { - color = *srcPtr; - if (color != _mouseKeyColor) { // transparent, don't draw - *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, - palette[color].r, palette[color].g, palette[color].b); +#ifdef USE_RGB_COLOR + if (_cursorFormat.bytesPerPixel > 1) { + color = (*(uint32 *) srcPtr) & colormask; + if (color != _mouseKeyColor) { // transparent, don't draw + uint8 r,g,b; + _cursorFormat.colorToRGB(color,r,g,b); + *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, + r, g, b); + } + dstPtr += 2; + srcPtr += _cursorFormat.bytesPerPixel; + } else { +#endif + color = *srcPtr; + if (color != _mouseKeyColor) { // transparent, don't draw + *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, + palette[color].r, palette[color].g, palette[color].b); + } + dstPtr += 2; + srcPtr++; +#ifdef USE_RGB_COLOR } - dstPtr += 2; - srcPtr++; +#endif } dstPtr += _mouseOrigSurface->pitch - w * 2; } diff --git a/backends/platform/iphone/osys_main.h b/backends/platform/iphone/osys_main.h index 705f89319a..c4c1a8b080 100644 --- a/backends/platform/iphone/osys_main.h +++ b/backends/platform/iphone/osys_main.h @@ -126,7 +126,7 @@ public: bool setGraphicsMode(const char *name); virtual bool setGraphicsMode(int mode); virtual int getGraphicsMode() const; - virtual void initSize(uint width, uint height); + virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format); virtual int16 getHeight(); virtual int16 getWidth(); virtual void setPalette(const byte *colors, uint start, uint num); @@ -149,7 +149,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL); virtual bool pollEvent(Common::Event &event); virtual uint32 getMillis(); diff --git a/backends/platform/iphone/osys_video.cpp b/backends/platform/iphone/osys_video.cpp index 641c341f50..6cb5e18d95 100644 --- a/backends/platform/iphone/osys_video.cpp +++ b/backends/platform/iphone/osys_video.cpp @@ -46,7 +46,7 @@ int OSystem_IPHONE::getGraphicsMode() const { return -1; } -void OSystem_IPHONE::initSize(uint width, uint height) { +void OSystem_IPHONE::initSize(uint width, uint height, const Graphics::PixelFormat *format) { //printf("initSize(%i, %i)\n", width, height); _screenWidth = width; @@ -438,7 +438,7 @@ void OSystem_IPHONE::dirtyFullOverlayScreen() { } } -void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) { +void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { //printf("setMouseCursor(%i, %i)\n", hotspotX, hotspotY); if (_mouseBuf != NULL && (_mouseWidth != w || _mouseHeight != h)) { @@ -455,7 +455,7 @@ void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspot _mouseHotspotX = hotspotX; _mouseHotspotY = hotspotY; - _mouseKeyColour = keycolor; + _mouseKeyColour = (byte)keycolor; memcpy(_mouseBuf, buf, w * h); diff --git a/backends/platform/linuxmoto/hardwarekeys.cpp b/backends/platform/linuxmoto/hardwarekeys.cpp new file mode 100644 index 0000000000..e65d2bec2b --- /dev/null +++ b/backends/platform/linuxmoto/hardwarekeys.cpp @@ -0,0 +1,100 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + +#include "backends/platform/linuxmoto/linuxmoto-sdl.h" +#include "backends/keymapper/keymapper.h" +#include "common/keyboard.h" + +#ifdef ENABLE_KEYMAPPER + +using namespace Common; + +struct Key { + const char *hwId; + KeyCode keycode; + uint16 ascii; + const char *desc; + KeyType preferredAction; + bool shiftable; +}; + +static const Key keys[] = { + { "FIRE", KEYCODE_RETURN, ASCII_RETURN, "Fire", kActionKeyType, false }, + { "CAMERA", KEYCODE_PAUSE, 0, "Camera", kActionKeyType, false }, + { "HANGUP", KEYCODE_ESCAPE, ASCII_ESCAPE, "Hangup", kStartKeyType, false }, + { "CALL", KEYCODE_SPACE, ASCII_SPACE, "Call", kActionKeyType, false }, + { "PLUS", KEYCODE_PLUS, '+', "+", kActionKeyType, false }, + { "MINUS", KEYCODE_MINUS, '-', "-", kActionKeyType, false }, + + { "a", KEYCODE_a, 'a', "a", kActionKeyType, true }, + { "b", KEYCODE_b, 'b', "b", kActionKeyType, true }, + { "c", KEYCODE_c, 'c', "c", kActionKeyType, true }, + { "d", KEYCODE_d, 'd', "d", kActionKeyType, true }, + { "e", KEYCODE_e, 'e', "e", kActionKeyType, true }, + { "f", KEYCODE_f, 'f', "f", kActionKeyType, true }, + { "g", KEYCODE_g, 'g', "g", kActionKeyType, true }, + { "h", KEYCODE_h, 'h', "h", kActionKeyType, true }, + { "i", KEYCODE_i, 'i', "i", kActionKeyType, true }, + { "j", KEYCODE_j, 'j', "j", kActionKeyType, true }, + + // Numeric keypad + + // Arrows + Home/End pad + {"UP", KEYCODE_UP, 0, "Up", kDirUpKeyType, false}, + {"DOWN", KEYCODE_DOWN, 0, "Down", kDirDownKeyType, false}, + {"RIGHT", KEYCODE_RIGHT, 0, "Right", kDirRightKeyType, false}, + {"LEFT", KEYCODE_LEFT, 0, "Left", kDirLeftKeyType, false}, + + // Function keys + + // Miscellaneous function keys + + {0, KEYCODE_INVALID, 0, 0, kGenericKeyType, false} +}; + +struct Mod { + byte flag; + const char *id; + const char *desc; + bool shiftable; +}; + +static const Mod modifiers[] = { + { 0, "", "", false }, + { KBD_CTRL, "C+", "Ctrl+", false }, + { KBD_ALT, "A+", "Alt+", false }, + { KBD_SHIFT, "", "", true }, + { KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", false }, + { KBD_SHIFT | KBD_CTRL, "S+C+", "Shift+Ctrl+", true }, + { KBD_SHIFT | KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", true }, + { 0, 0, 0, false } +}; +#endif + + +Common::HardwareKeySet *OSystem_LINUXMOTO::getHardwareKeySet() { + OSystem_SDL::getHardwareKeySet(); +} diff --git a/backends/platform/linuxmoto/linuxmoto-events.cpp b/backends/platform/linuxmoto/linuxmoto-events.cpp new file mode 100644 index 0000000000..be5eec5c7e --- /dev/null +++ b/backends/platform/linuxmoto/linuxmoto-events.cpp @@ -0,0 +1,192 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + +#include "backends/platform/linuxmoto/linuxmoto-sdl.h" +#include "backends/platform/sdl/sdl.h" + +static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode) { + if (key >= SDLK_F1 && key <= SDLK_F9) { + return key - SDLK_F1 + Common::ASCII_F1; + } else if (key >= SDLK_KP0 && key <= SDLK_KP9) { + return key - SDLK_KP0 + '0'; + } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) { + return key; + } else if (unicode) { + return unicode; + } else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) { + return key & ~0x20; + } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) { + return 0; + } + return key; +} + +bool OSystem_LINUXMOTO::remapKey(SDL_Event &ev, Common::Event &event) { + // Motorol A1200/E6/A1600 remapkey by Lubomyr +#ifdef MOTOEZX + // Quit on MOD+Camera Key on A1200 + if (ev.key.keysym.sym == SDLK_e) { + event.type = Common::EVENT_QUIT; + return true; + } + // '1' Bypass security protection - MOD+Call key + if (ev.key.keysym.sym == SDLK_f) { + ev.key.keysym.sym = SDLK_1; + } + // F5 Game Menu - Call key + else if (ev.key.keysym.sym == SDLK_SPACE) { + ev.key.keysym.sym = SDLK_F5; + } + // Camera to VirtualKeyboard + else if (ev.key.keysym.sym == SDLK_PAUSE) { + ev.key.keysym.sym = SDLK_F7; + } + // mod+fire to enter + else if (ev.key.keysym.sym == SDLK_b) { + ev.key.keysym.sym = SDLK_RETURN; + } +#endif + // Motorola Z6/V8 remapkey by Ant-On +#ifdef MOTOMAGX + // Quit on cancel + if (ev.key.keysym.sym == SDLK_ESCAPE) { + event.type = Common::EVENT_QUIT; + return true; + } else + // F5 Game Menu - Call key + if (ev.key.keysym.sym == SDLK_SPACE) { + ev.key.keysym.sym = SDLK_F5; + } + // 'y' - Mod+Right key + // 'y' - Left soft + else if (ev.key.keysym.sym == SDLK_F9) { + ev.key.keysym.sym = SDLK_y; + } + // 'n' - Mod+Left key + // 'n' - rigth soft + else if (ev.key.keysym.sym == SDLK_F11) { + ev.key.keysym.sym = SDLK_n; + } +#endif + +// Joystick to Mouse + else if (ev.key.keysym.sym == SDLK_LEFT) { + if (ev.type == SDL_KEYDOWN) { + _km.x_vel = -1; + _km.x_down_count = 1; + } else { + _km.x_vel = 0; + _km.x_down_count = 0; + } + + event.type = Common::EVENT_MOUSEMOVE; + fillMouseEvent(event, _km.x, _km.y); + return true; + } else if (ev.key.keysym.sym == SDLK_RIGHT) { + if (ev.type == SDL_KEYDOWN) { + _km.x_vel = 1; + _km.x_down_count = 1; + } else { + _km.x_vel = 0; + _km.x_down_count = 0; + } + + event.type = Common::EVENT_MOUSEMOVE; + fillMouseEvent(event, _km.x, _km.y); + + return true; + } else if (ev.key.keysym.sym == SDLK_DOWN) { + if (ev.type == SDL_KEYDOWN) { + _km.y_vel = 1; + _km.y_down_count = 1; + } else { + _km.y_vel = 0; + _km.y_down_count = 0; + } + + event.type = Common::EVENT_MOUSEMOVE; + fillMouseEvent(event, _km.x, _km.y); + + return true; + } else if (ev.key.keysym.sym == SDLK_UP) { + if (ev.type == SDL_KEYDOWN) { + _km.y_vel = -1; + _km.y_down_count = 1; + } else { + _km.y_vel = 0; + _km.y_down_count = 0; + } + + event.type = Common::EVENT_MOUSEMOVE; + fillMouseEvent(event, _km.x, _km.y); + + return true; + } else if (ev.key.keysym.sym == SDLK_RETURN) { // Joystick center to pressing Left Mouse + // _km.y_vel = 0; + // _km.y_down_count = 0; + if (ev.key.type == SDL_KEYDOWN) { + event.type = Common::EVENT_LBUTTONDOWN; + } else { + event.type = Common::EVENT_LBUTTONUP; + } + + fillMouseEvent(event, _km.x, _km.y); + + return true; + } else if (ev.key.keysym.sym == SDLK_PLUS) { // Volume Up to pressing Right Mouse + // _km.y_vel = 0; + // _km.y_down_count = 0; + if (ev.key.type == SDL_KEYDOWN ) { + event.type = Common::EVENT_RBUTTONDOWN; + } else { + event.type = Common::EVENT_RBUTTONUP; + } + fillMouseEvent(event, _km.x, _km.y); + + return true; + } else if (ev.key.keysym.sym == SDLK_MINUS) { // Volume Down to pressing Left Mouse + //_km.y_vel = 0; + //_km.y_down_count = 0; + if (ev.key.type == SDL_KEYDOWN) { + event.type = Common::EVENT_LBUTTONDOWN; + } else { + event.type = Common::EVENT_LBUTTONUP; + } + + fillMouseEvent(event, _km.x, _km.y); + + return true; + } else { + // Let the events fall through if we didn't change them, this may not be the best way to + // set it up, but i'm not sure how sdl would like it if we let if fall through then redid it though. + // and yes i have an huge terminal size so i dont wrap soon enough. + event.type = Common::EVENT_KEYDOWN; + event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym; + event.kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode); + } + + return false; +} diff --git a/backends/platform/linuxmoto/linuxmoto-sdl.cpp b/backends/platform/linuxmoto/linuxmoto-sdl.cpp new file mode 100644 index 0000000000..82c69bc7d7 --- /dev/null +++ b/backends/platform/linuxmoto/linuxmoto-sdl.cpp @@ -0,0 +1,69 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + +#include "backends/platform/linuxmoto/linuxmoto-sdl.h" + +void OSystem_LINUXMOTO::preprocessEvents(SDL_Event *event) { + if (event->type == SDL_ACTIVEEVENT) { + if (event->active.state == SDL_APPINPUTFOCUS && !event->active.gain) { + suspendAudio(); + for (;;) { + if (!SDL_WaitEvent(event)) { + SDL_Delay(10); + continue; + } + if (event->type == SDL_QUIT) + return; + if (event->type != SDL_ACTIVEEVENT) + continue; + if (event->active.state == SDL_APPINPUTFOCUS && event->active.gain) { + resumeAudio(); + return; + } + } + } + } +} + +void OSystem_LINUXMOTO::suspendAudio() { + SDL_CloseAudio(); + _audioSuspended = true; +} + +int OSystem_LINUXMOTO::resumeAudio() { + if (!_audioSuspended) + return -2; + if (SDL_OpenAudio(&_obtainedRate, NULL) < 0){ + return -1; + } + SDL_PauseAudio(0); + _audioSuspended = false; + return 0; +} + +void OSystem_LINUXMOTO::setupMixer() { + OSystem_SDL::setupMixer(); +} diff --git a/backends/platform/psp/osys_psp_gu.h b/backends/platform/linuxmoto/linuxmoto-sdl.h index e828a36b7d..27c423b071 100644 --- a/backends/platform/psp/osys_psp_gu.h +++ b/backends/platform/linuxmoto/linuxmoto-sdl.h @@ -18,42 +18,29 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * $URL$ + * $Id$ * */ -#include <pspgu.h> -#include "common/scummsys.h" -#include "common/rect.h" -#include "osys_psp.h" +#ifndef LINUXMOTO_SDL +#define LINUXMOTO_SDL -class OSystem_PSP_GU : public OSystem_PSP -{ +#include "backends/platform/sdl/sdl.h" + +#include <SDL.h> + +class OSystem_LINUXMOTO : public OSystem_SDL { +private: + bool _audioSuspended; public: - struct Vertex - { - float u,v; - float x,y,z; - }; - - OSystem_PSP_GU(); - ~OSystem_PSP_GU(); - void updateScreen(); - void initSize(uint width, uint height); - int getDefaultGraphicsMode() const; - bool setGraphicsMode(int mode); - bool setGraphicsMode(const char *name); - int getGraphicsMode() const; - void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale); - void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) ; - void setPalette(const byte *colors, uint start, uint num); - bool pollEvent(Common::Event &event); - int _graphicMode; - struct Vertex *_vertices; - unsigned short* _clut; - unsigned short* _kbdClut; - bool _keyboardVisible; - int _keySelected; - int _keyboardMode; + virtual bool remapKey(SDL_Event &ev, Common::Event &event); + virtual void preprocessEvents(SDL_Event *event); + virtual void setupMixer(); + virtual Common::HardwareKeySet *getHardwareKeySet(); + void suspendAudio(); + int resumeAudio(); }; +#endif diff --git a/backends/platform/linuxmoto/main.cpp b/backends/platform/linuxmoto/main.cpp new file mode 100644 index 0000000000..7f015faff4 --- /dev/null +++ b/backends/platform/linuxmoto/main.cpp @@ -0,0 +1,44 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include <common/scummsys.h> +#include <common/system.h> + +#include <SDL/SDL.h> +#include <SDL/SDL_syswm.h> + +#include "backends/platform/linuxmoto/linuxmoto-sdl.h" +#include "base/main.h" +#include "base/internal_version.h" + +int main(int argc, char *argv[]) { + g_system = new OSystem_LINUXMOTO(); + assert(g_system); + // Invoke the actual ScummVM main entry point: + int res = scummvm_main(argc, argv); + g_system->quit(); // TODO: Consider removing / replacing this! + + return res; +} diff --git a/backends/platform/linuxmoto/module.mk b/backends/platform/linuxmoto/module.mk new file mode 100644 index 0000000000..4d816eb227 --- /dev/null +++ b/backends/platform/linuxmoto/module.mk @@ -0,0 +1,29 @@ +MODULE := backends/platform/linuxmoto + +MODULE_OBJS := \ + main.o \ + hardwarekeys.o \ + linuxmoto-events.o \ + linuxmoto-sdl.o + +MODULE_DIRS += \ + backends/platform/linuxmoto/ + +# We don't use the rules.mk here on purpose +OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) + +MODULE := backends/platform/sdl + +MODULE_OBJS := \ + events.o \ + graphics.o \ + hardwarekeys.o \ + main.o \ + sdl.o + +MODULE_DIRS += \ + backends/platform/sdl/ + +# We don't use the rules.mk here on purpose +OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) + diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index 91a0c60bd6..8be3937ff2 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -49,7 +49,7 @@ STRIP = psp-strip MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf -MKSFO = mksfo +MKSFO = mksfoex -d MEMSIZE=1 PACK_PBP = pack-pbp FIXUP = psp-fixup-imports @@ -62,7 +62,7 @@ endif INCDIR := $(srcdir) . $(srcdir)/engines/ . $(PSPSDK)/include LIBDIR := $(LIBDIR) . $(PSPSDK)/lib -CXXFLAGS = -O2 -Wall -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -Wno-multichar `$(PSPBIN)/sdl-config --cflags` +CXXFLAGS = -O3 -Wall -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -Wno-multichar `$(PSPBIN)/sdl-config --cflags` CXXFLAGS:= $(addprefix -I,$(INCDIR)) $(CXXFLAGS) LDFLAGS := $(addprefix -L,$(LIBDIR)) $(LDFLAGS) LIBS = @@ -75,14 +75,14 @@ LIBS += -lmad CXXFLAGS+= -DUSE_VORBIS -DUSE_TREMOR LIBS += -lvorbisidec -LIBS += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspsdk -lpspuser +LIBS += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspuser -lpsppower CXXFLAGS := $(CXXFLAGS) -fno-exceptions -fno-rtti TARGET = scummvm-psp -OBJS := psp_main.o \ +OBJS := powerman.o \ + psp_main.o \ osys_psp.o \ - osys_psp_gu.o \ kbd_ss_c.o \ kbd_s_c.o \ kbd_ls_c.o \ diff --git a/backends/platform/psp/README.PSP.in b/backends/platform/psp/README.PSP.in index 2a2b53e721..7eeba7d391 100644 --- a/backends/platform/psp/README.PSP.in +++ b/backends/platform/psp/README.PSP.in @@ -13,15 +13,17 @@ Controls ======== Left trigger - ESC -Right trigger - Enter +Right trigger - Modifier key (see below for uses) Analog - Mouse movement +Right trigger + Analog - Fine control mouse Directionals - Mouse movement -Analog + triangle - Fine control mouse +Triangle - Enter Cross - Mouse button 1 Circle - Mouse button 2 Square - '.' (skip dialogue in some games) Select - Show/Hide Virtual Keyboard Start - F5 +Right trigger + Start - Return-To-Launcher menu Notes ===== @@ -32,9 +34,6 @@ Notes As such, it is recommended to play games in their original, uncompressed, form whenever possible. -- Sleep/Suspend mode currently isn't supported, so don't use it when - running ScummVM. - - This README may be outdated, for more up-to-date instructions and notes see the PSP Port Wiki: http://wiki.scummvm.org/index.php/PlayStation_Portable diff --git a/backends/platform/psp/module.mk b/backends/platform/psp/module.mk index afe9a23f58..a5c17ffa57 100644 --- a/backends/platform/psp/module.mk +++ b/backends/platform/psp/module.mk @@ -1,9 +1,9 @@ MODULE := backends/platform/psp MODULE_OBJS := \ + powerman.o \ psp_main.o \ osys_psp.o \ - osys_psp_gu.o \ kbd_ss_c.o \ kbd_s_c.o \ kbd_ls_c.o \ diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp index 45be0a0cd3..023ec0cc82 100644 --- a/backends/platform/psp/osys_psp.cpp +++ b/backends/platform/psp/osys_psp.cpp @@ -23,43 +23,76 @@ * */ +#include <pspgu.h> +#include <pspdisplay.h> + +#include <time.h> +#include <zlib.h> + #include "common/config-manager.h" #include "common/events.h" -#include "common/rect.h" #include "common/scummsys.h" #include "osys_psp.h" +#include "trace.h" #include "backends/saves/psp/psp-saves.h" #include "backends/timer/default/default-timer.h" #include "graphics/surface.h" -#include "graphics/scaler.h" #include "sound/mixer_intern.h" -#include <pspgu.h> -#include <pspdisplay.h> -#include <time.h> +#define SAMPLES_PER_SEC 44100 -#include "./trace.h" -#define SAMPLES_PER_SEC 44100 +#define PIXEL_SIZE (4) +#define BUF_WIDTH (512) +#define PSP_SCREEN_WIDTH 480 +#define PSP_SCREEN_HEIGHT 272 +#define PSP_FRAME_SIZE (BUF_WIDTH * PSP_SCREEN_HEIGHT * PIXEL_SIZE) +#define MOUSE_SIZE 128 +#define KBD_DATA_SIZE 130560 + +#define MAX_FPS 30 + +unsigned int __attribute__((aligned(16))) displayList[262144]; +unsigned short __attribute__((aligned(16))) clut256[256]; +unsigned short __attribute__((aligned(16))) mouseClut[256]; +unsigned short __attribute__((aligned(16))) cursorPalette[256]; +unsigned short __attribute__((aligned(16))) kbClut[256]; +//unsigned int __attribute__((aligned(16))) offscreen256[640*480]; +//unsigned int __attribute__((aligned(16))) overlayBuffer256[640*480*2]; +unsigned int __attribute__((aligned(16))) mouseBuf256[MOUSE_SIZE*MOUSE_SIZE]; + +extern unsigned int size_keyboard_symbols_compressed; +extern unsigned char keyboard_symbols_compressed[]; +extern unsigned int size_keyboard_symbols_shift_compressed; +extern unsigned char keyboard_symbols_shift_compressed[]; +extern unsigned int size_keyboard_letters_compressed; +extern unsigned char keyboard_letters_compressed[]; +extern unsigned int size_keyboard_letters_shift_compressed; +extern unsigned char keyboard_letters_shift_compressed[]; +unsigned char *keyboard_symbols; +unsigned char *keyboard_symbols_shift; +unsigned char *keyboard_letters; +unsigned char *keyboard_letters_shift; + +unsigned char kbd_ascii[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '[', ']', '\\', ';', '\'', ',', '.', '/', '`'}; +Common::KeyCode kbd_code[] = {Common::KEYCODE_1, Common::KEYCODE_2, Common::KEYCODE_3, Common::KEYCODE_4, Common::KEYCODE_5, Common::KEYCODE_6, Common::KEYCODE_7, Common::KEYCODE_8, Common::KEYCODE_9, Common::KEYCODE_0, Common::KEYCODE_MINUS, Common::KEYCODE_EQUALS, Common::KEYCODE_LEFTBRACKET, Common::KEYCODE_RIGHTBRACKET, + Common::KEYCODE_BACKSLASH, Common::KEYCODE_SEMICOLON, Common::KEYCODE_QUOTE, Common::KEYCODE_COMMA, Common::KEYCODE_PERIOD, Common::KEYCODE_SLASH, Common::KEYCODE_BACKQUOTE}; +unsigned char kbd_ascii_cl[] = {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '{', '}', '|', ':', '"', '<', '>', '?', '~'}; +Common::KeyCode kbd_code_cl[] = {Common::KEYCODE_EXCLAIM, Common::KEYCODE_AT, Common::KEYCODE_HASH, Common::KEYCODE_DOLLAR, (Common::KeyCode)37, Common::KEYCODE_CARET, Common::KEYCODE_AMPERSAND, Common::KEYCODE_ASTERISK, Common::KEYCODE_LEFTPAREN, Common::KEYCODE_RIGHTPAREN, Common::KEYCODE_UNDERSCORE, + Common::KEYCODE_PLUS, (Common::KeyCode)123, (Common::KeyCode)125, (Common::KeyCode)124, Common::KEYCODE_COLON, Common::KEYCODE_QUOTEDBL, Common::KEYCODE_LESS, Common::KEYCODE_GREATER, Common::KEYCODE_QUESTION, (Common::KeyCode)126}; +#define CAPS_LOCK (1 << 0) +#define SYMBOLS (1 << 1) -#define SCREEN_WIDTH 480 -#define SCREEN_HEIGHT 272 -unsigned short *DrawBuffer = (unsigned short *)0x44044000; -unsigned short *DisplayBuffer = (unsigned short *)0x44000000; unsigned long RGBToColour(unsigned long r, unsigned long g, unsigned long b) { return (((b >> 3) << 10) | ((g >> 3) << 5) | ((r >> 3) << 0)) | 0x8000; } -void putPixel(uint16 x, uint16 y, unsigned long colour) { - *(unsigned short *)(DrawBuffer + (y << 9) + x ) = colour; -} - static int timer_handler(int t) { DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager(); tm->handler(); @@ -75,25 +108,88 @@ const OSystem::GraphicsMode OSystem_PSP::s_supportedGraphicsModes[] = { }; -OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0), _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _padAccel(0), _mixer(0) { - +OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0), _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _lastScreenUpdate(0), _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _padAccel(0), _mixer(0) { memset(_palette, 0, sizeof(_palette)); + _cursorPaletteDisabled = true; + _samplesPerSec = 0; //init SDL uint32 sdlFlags = SDL_INIT_AUDIO | SDL_INIT_TIMER; SDL_Init(sdlFlags); - sceDisplaySetMode(0, SCREEN_WIDTH, SCREEN_HEIGHT); - sceDisplaySetFrameBuf((char *)DisplayBuffer, 512, 1, 1); + + //decompress keyboard data + uLongf kbdSize = KBD_DATA_SIZE; + keyboard_letters = (unsigned char *)memalign(16, KBD_DATA_SIZE); + if (Z_OK != uncompress((Bytef *)keyboard_letters, &kbdSize, (const Bytef *)keyboard_letters_compressed, size_keyboard_letters_compressed)) + error("OSystem_PSP: uncompressing keyboard_letters failed"); + + kbdSize = KBD_DATA_SIZE; + keyboard_letters_shift = (unsigned char *)memalign(16, KBD_DATA_SIZE); + if (Z_OK != uncompress((Bytef *)keyboard_letters_shift, &kbdSize, (const Bytef *)keyboard_letters_shift_compressed, size_keyboard_letters_shift_compressed)) + error("OSystem_PSP: uncompressing keyboard_letters_shift failed"); + + kbdSize = KBD_DATA_SIZE; + keyboard_symbols = (unsigned char *)memalign(16, KBD_DATA_SIZE); + if (Z_OK != uncompress((Bytef *)keyboard_symbols, &kbdSize, (const Bytef *)keyboard_symbols_compressed, size_keyboard_symbols_compressed)) + error("OSystem_PSP: uncompressing keyboard_symbols failed"); + + kbdSize = KBD_DATA_SIZE; + keyboard_symbols_shift = (unsigned char *)memalign(16, KBD_DATA_SIZE); + if (Z_OK != uncompress((Bytef *)keyboard_symbols_shift, &kbdSize, (const Bytef *)keyboard_symbols_shift_compressed, size_keyboard_symbols_shift_compressed)) + error("OSystem_PSP: uncompressing keyboard_symbols_shift failed"); + + _keyboardVisible = false; + _clut = (unsigned short *)(((unsigned int)clut256) | 0x40000000); + _kbdClut = (unsigned short *)(((unsigned int)kbClut) | 0x40000000); + _mouseBuf = (byte *)mouseBuf256; + _graphicMode = STRETCHED_480X272; + _keySelected = 1; + _keyboardMode = 0; + _mouseX = PSP_SCREEN_WIDTH >> 1; + _mouseY = PSP_SCREEN_HEIGHT >> 1; + + + //sceKernelDcacheWritebackAll(); + + // setup + sceGuInit(); + sceGuStart(0, displayList); + sceGuDrawBuffer(GU_PSM_8888, (void *)0, BUF_WIDTH); + sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)PSP_FRAME_SIZE, BUF_WIDTH); + sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * 2), BUF_WIDTH); + sceGuOffset(2048 - (PSP_SCREEN_WIDTH/2), 2048 - (PSP_SCREEN_HEIGHT/2)); + sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); + sceGuDepthRange(0xC350, 0x2710); + sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + sceGuFrontFace(GU_CW); + sceGuEnable(GU_TEXTURE_2D); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + sceGuFinish(); + sceGuSync(0,0); + sceDisplayWaitVblankStart(); + sceGuDisplay(1); + } OSystem_PSP::~OSystem_PSP() { + free(keyboard_symbols_shift); + free(keyboard_symbols); + free(keyboard_letters_shift); + free(keyboard_letters); + free(_offscreen); free(_overlayBuffer); free(_mouseBuf); + + _offscreen = 0; + _overlayBuffer = 0; + _mouseBuf = 0; + sceGuTerm(); } @@ -110,14 +206,14 @@ void OSystem_PSP::initBackend() { bool OSystem_PSP::hasFeature(Feature f) { - return false; + return (f == kFeatureOverlaySupportsAlpha || f == kFeatureCursorHasPalette); } void OSystem_PSP::setFeatureState(Feature f, bool enable) { } bool OSystem_PSP::getFeatureState(Feature f) { - return (f == kFeatureOverlaySupportsAlpha); + return false; } const OSystem::GraphicsMode* OSystem_PSP::getSupportedGraphicsModes() const { @@ -126,36 +222,56 @@ const OSystem::GraphicsMode* OSystem_PSP::getSupportedGraphicsModes() const { int OSystem_PSP::getDefaultGraphicsMode() const { - return -1; + return STRETCHED_480X272; } bool OSystem_PSP::setGraphicsMode(int mode) { + _graphicMode = mode; return true; } bool OSystem_PSP::setGraphicsMode(const char *name) { - return true; + int i = 0; + + while (s_supportedGraphicsModes[i].name) { + if (!strcmpi(s_supportedGraphicsModes[i].name, name)) { + _graphicMode = s_supportedGraphicsModes[i].id; + return true; + } + i++; + } + + return false; } int OSystem_PSP::getGraphicsMode() const { - return -1; + return _graphicMode; } -void OSystem_PSP::initSize(uint width, uint height) { - _overlayWidth = _screenWidth = width; - _overlayHeight = _screenHeight = height; - - free(_offscreen); +void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) { + PSPDebugTrace("initSize\n"); + _screenWidth = width; + _screenHeight = height; - _offscreen = (byte *)malloc(width * height); + _overlayWidth = PSP_SCREEN_WIDTH; //width; + _overlayHeight = PSP_SCREEN_HEIGHT; //height; - free(_overlayBuffer); +// _offscreen = (byte *)offscreen256; + _overlayBuffer = (OverlayColor *)0x44000000 + PSP_FRAME_SIZE; - _overlayBuffer = (OverlayColor *)malloc(_overlayWidth * _overlayHeight * sizeof(OverlayColor)); + _offscreen = (byte *)_overlayBuffer + _overlayWidth * _overlayHeight * sizeof(OverlayColor); bzero(_offscreen, width * height); clearOverlay(); + memset(_palette, 0xFFFF, 256 * sizeof(unsigned short)); + _kbdClut[0] = 0xFFFF; + _kbdClut[246] = 0x4CCC; + _kbdClut[247] = 0x0000; + + for (int i = 1; i < 31; i++) + _kbdClut[i] = 0xF888; _mouseVisible = false; + sceKernelDcacheWritebackAll(); } int16 OSystem_PSP::getWidth() { @@ -173,6 +289,34 @@ void OSystem_PSP::setPalette(const byte *colors, uint start, uint num) { _palette[start + i] = RGBToColour(b[0], b[1], b[2]); b += 4; } + + //copy to CLUT + memcpy(_clut, _palette, 256 * sizeof(unsigned short)); + + //force update of mouse CLUT as well, as it may have been set up before this palette was set + memcpy(mouseClut, _palette, 256 * sizeof(unsigned short)); + mouseClut[_mouseKeyColour] = 0; + + sceKernelDcacheWritebackAll(); +} + +void OSystem_PSP::setCursorPalette(const byte *colors, uint start, uint num) { + const byte *b = colors; + + for (uint i = 0; i < num; ++i) { + cursorPalette[start + i] = RGBToColour(b[0], b[1], b[2]); + b += 4; + } + + cursorPalette[0] = 0; + + _cursorPaletteDisabled = false; + + sceKernelDcacheWritebackAll(); +} + +void OSystem_PSP::disableCursorPalette(bool disable) { + _cursorPaletteDisabled = disable; } void OSystem_PSP::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) { @@ -202,10 +346,21 @@ void OSystem_PSP::copyRectToScreen(const byte *buf, int pitch, int x, int y, int byte *dst = _offscreen + y * _screenWidth + x; - if (_screenWidth == pitch && pitch == w) { + + if (_screenWidth == pitch && pitch == w) + { memcpy(dst, buf, h * w); - } else { - do { +/* + sceGuStart(0, displayList); + sceGuCopyImage( 3, 0, 0, w/2, h, w/2, (void *)buf, x/2, y, _screenWidth /2, _offscreen); + sceGuFinish(); + sceGuSync(0,0); +*/ + } + else + { + do + { memcpy(dst, buf, w); buf += pitch; dst += _screenWidth; @@ -228,52 +383,205 @@ void OSystem_PSP::unlockScreen() { } void OSystem_PSP::updateScreen() { - unsigned short *temp; + u32 now = getMillis(); + if (now - _lastScreenUpdate < 1000 / MAX_FPS) + return; - uint xStart = (SCREEN_WIDTH >> 1) - (_screenWidth >> 1); - uint yStart = (SCREEN_HEIGHT >> 1) - (_screenHeight >> 1); + _lastScreenUpdate = now; - for (int i = 0; i < _screenHeight; ++i) { - for (int j = 0; j < _screenWidth; ++j) { - putPixel(xStart + j, yStart + i, _palette[_offscreen[i * _screenWidth +j]]); - } + + sceGuStart(0, displayList); + + sceGuClearColor(0xFF000000); + sceGuClear(GU_COLOR_BUFFER_BIT); + + sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0); + sceGuClutLoad(32, clut256); // upload 32*8 entries (256) + sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image + if (_screenWidth == 320) + sceGuTexImage(0, 512, 256, _screenWidth, _offscreen); + else + sceGuTexImage(0, 512, 512, _screenWidth, _offscreen); + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); + sceGuTexFilter(GU_LINEAR, GU_LINEAR); + sceGuTexOffset(0,0); + sceGuAmbientColor(0xFFFFFFFF); + sceGuColor(0xFFFFFFFF); + + struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); + vertices[0].u = 0.5; vertices[0].v = 0.5; + vertices[1].u = _screenWidth - 0.5; vertices[1].v = _screenHeight - 0.5; + switch(_graphicMode) { + case CENTERED_320X200: + vertices[0].x = (PSP_SCREEN_WIDTH - 320) / 2; vertices[0].y = (PSP_SCREEN_HEIGHT - 200) / 2; vertices[0].z = 0; + vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 320) / 2; vertices[1].y = PSP_SCREEN_HEIGHT - (PSP_SCREEN_HEIGHT - 200) / 2; vertices[1].z = 0; + break; + case CENTERED_435X272: + vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2; vertices[0].y = 0; vertices[0].z = 0; + vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 435) / 2; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[1].z = 0; + break; + case STRETCHED_480X272: + vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0; + vertices[1].x = PSP_SCREEN_WIDTH; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[1].z = 0; + break; + case CENTERED_362X272: + vertices[0].x = (PSP_SCREEN_WIDTH - 362) / 2; vertices[0].y = 0; vertices[0].z = 0; + vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 362) / 2; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[1].z = 0; + break; } - if (_overlayVisible) { - for (int i = 0; i < _screenHeight; ++i) { - for (int j = 0; j < _screenWidth; ++j) { + if (_shakePos) { + vertices[0].y += _shakePos; + vertices[1].y += _shakePos; + } + + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices); + if (_screenWidth == 640) { + sceGuTexImage(0, 512, 512, _screenWidth, _offscreen+512); + vertices[0].u = 512 + 0.5; vertices[1].v = _screenHeight - 0.5; + vertices[0].x += (vertices[1].x - vertices[0].x) * 511 / 640; vertices[0].y = 0; vertices[0].z = 0; + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices); + } - OverlayColor pixel = _overlayBuffer[(i * _overlayWidth +j)]; - if (pixel & 0x8000) - putPixel(xStart + j, yStart + i, pixel); - } + // draw overlay + if (_overlayVisible) { + vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0; + vertices[1].x = PSP_SCREEN_WIDTH; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[1].z = 0; + vertices[0].u = 0.5; vertices[0].v = 0.5; + vertices[1].u = _overlayWidth - 0.5; vertices[1].v = _overlayHeight - 0.5; + sceGuTexMode(GU_PSM_4444, 0, 0, 0); // 16-bit image + sceGuDisable(GU_ALPHA_TEST); + sceGuEnable(GU_BLEND); + + //sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_ALPHA, 0xFFFFFFFF, 0); + + if (_overlayWidth > 320) + sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer); + else + sceGuTexImage(0, 512, 256, _overlayWidth, _overlayBuffer); + + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices); + // need to render twice for textures > 512 + if ( _overlayWidth > 512) { + sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer + 512); + vertices[0].u = 512 + 0.5; vertices[1].v = _overlayHeight - 0.5; + vertices[0].x = PSP_SCREEN_WIDTH * 512 / 640; vertices[0].y = 0; vertices[0].z = 0; + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices); } + sceGuDisable(GU_BLEND); } - //draw mouse on top + // draw mouse if (_mouseVisible) { - for (int y = 0; y < _mouseHeight; ++y) { - for (int x = 0; x < _mouseWidth; ++x) { - if (_mouseBuf[y * _mouseHeight + x] != _mouseKeyColour) { - int my = _mouseY + y; // + _mouseHotspotY; - int mx = _mouseX + x; // + _mouseHotspotX; - - if (mx >= 0 && mx < _screenWidth && my >= 0 && my < _screenHeight) - putPixel(xStart + mx, yStart + my, _palette[_mouseBuf[y * _mouseHeight + x]]); - } + sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image + sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0); + sceGuClutLoad(32, _cursorPaletteDisabled ? mouseClut : cursorPalette); // upload 32*8 entries (256) + sceGuAlphaFunc(GU_GREATER, 0, 0xFF); + sceGuEnable(GU_ALPHA_TEST); + sceGuTexImage(0, MOUSE_SIZE, MOUSE_SIZE, MOUSE_SIZE, _mouseBuf); + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + + vertices[0].u = 0.5; vertices[0].v = 0.5; + vertices[1].u = _mouseWidth - 0.5; vertices[1].v = _mouseHeight - 0.5; + + //adjust cursor position + int mX = _mouseX - _mouseHotspotX; + int mY = _mouseY - _mouseHotspotY; + + if (_overlayVisible) { + float scalex, scaley; + + scalex = (float)PSP_SCREEN_WIDTH /_overlayWidth; + scaley = (float)PSP_SCREEN_HEIGHT /_overlayHeight; + + vertices[0].x = mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; + vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; + } else + switch(_graphicMode) { + case CENTERED_320X200: + vertices[0].x = (PSP_SCREEN_WIDTH - 320) / 2 + mX; vertices[0].y = (PSP_SCREEN_HEIGHT - 200) / 2 + mY; vertices[0].z = 0; + vertices[1].x = vertices[0].x+_mouseWidth; vertices[1].y = vertices[0].y + _mouseHeight; vertices[1].z = 0; + break; + case CENTERED_435X272: + { + float scalex, scaley; + + scalex = 435.0f / _screenWidth; + scaley = 272.0f / _screenHeight; + + vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2 + mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; + vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; + } + break; + case CENTERED_362X272: + { + float scalex, scaley; + + scalex = 362.0f / _screenWidth; + scaley = 272.0f / _screenHeight; + + vertices[0].x = (PSP_SCREEN_WIDTH - 362) / 2 + mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; + vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; + } + break; + case STRETCHED_480X272: + { + float scalex, scaley; + + scalex = (float)PSP_SCREEN_WIDTH / _screenWidth; + scaley = (float)PSP_SCREEN_HEIGHT / _screenHeight; + + vertices[0].x = mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; + vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; + } + break; } + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices); } + if (_keyboardVisible) { + sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image + sceGuClutMode(GU_PSM_4444, 0, 0xFF, 0); + sceGuClutLoad(32, kbClut); // upload 32*8 entries (256) + sceGuDisable(GU_ALPHA_TEST); + sceGuEnable(GU_BLEND); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + switch(_keyboardMode) { + case 0: + sceGuTexImage(0, 512, 512, 480, keyboard_letters); + break; + case CAPS_LOCK: + sceGuTexImage(0, 512, 512, 480, keyboard_letters_shift); + break; + case SYMBOLS: + sceGuTexImage(0, 512, 512, 480, keyboard_symbols); + break; + case (CAPS_LOCK | SYMBOLS): + sceGuTexImage(0, 512, 512, 480, keyboard_symbols_shift); + break; + } + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + + vertices[0].u = 0.5; vertices[0].v = 0.5; + vertices[1].u = PSP_SCREEN_WIDTH-0.5; vertices[1].v = PSP_SCREEN_HEIGHT-0.5; + vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0; + vertices[1].x = PSP_SCREEN_WIDTH; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[0].z = 0; + sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices); + sceGuDisable(GU_BLEND); + } + sceKernelDcacheWritebackAll(); + + sceGuFinish(); + sceGuSync(0,0); - // switch buffers - temp = DrawBuffer; - DrawBuffer = DisplayBuffer; - DisplayBuffer = temp; sceDisplayWaitVblankStart(); - sceDisplaySetFrameBuf((char *)DisplayBuffer, 512, 1, 1); + sceGuSwapBuffers(); + //sceKernelDcacheWritebackAll(); } void OSystem_PSP::setShakePos(int shakeOffset) { @@ -380,7 +688,7 @@ void OSystem_PSP::warpMouse(int x, int y) { _mouseY = y; } -void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) { +void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { //TODO: handle cursorTargetScale _mouseWidth = w; _mouseHeight = h; @@ -388,18 +696,20 @@ void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, _mouseHotspotX = hotspotX; _mouseHotspotY = hotspotY; - _mouseKeyColour = keycolor; + _mouseKeyColour = keycolor & 0xFF; - free(_mouseBuf); + memcpy(mouseClut, _palette, 256 * sizeof(unsigned short)); + mouseClut[_mouseKeyColour] = 0; + sceKernelDcacheWritebackAll(); - _mouseBuf = (byte *)malloc(w * h); - memcpy(_mouseBuf, buf, w * h); + for (unsigned int i = 0; i < h; i++) + memcpy(_mouseBuf + i * MOUSE_SIZE, buf + i * w, w); } #define PAD_CHECK_TIME 40 #define PAD_DIR_MASK (PSP_CTRL_UP | PSP_CTRL_DOWN | PSP_CTRL_LEFT | PSP_CTRL_RIGHT) -bool OSystem_PSP::pollEvent(Common::Event &event) { +bool OSystem_PSP::processInput(Common::Event &event) { s8 analogStepAmountX = 0; s8 analogStepAmountY = 0; /* @@ -411,7 +721,7 @@ bool OSystem_PSP::pollEvent(Common::Event &event) { */ uint32 buttonsChanged = pad.Buttons ^ _prevButtons; - if (buttonsChanged & (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START | PSP_CTRL_SELECT | PSP_CTRL_SQUARE)) { + if (buttonsChanged & (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START | PSP_CTRL_SELECT | PSP_CTRL_SQUARE | PSP_CTRL_TRIANGLE)) { if (buttonsChanged & PSP_CTRL_CROSS) { event.type = (pad.Buttons & PSP_CTRL_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP; } else if (buttonsChanged & PSP_CTRL_CIRCLE) { @@ -419,23 +729,29 @@ bool OSystem_PSP::pollEvent(Common::Event &event) { } else { //any of the other buttons. event.type = buttonsChanged & pad.Buttons ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP; + event.kbd.ascii = 0; event.kbd.flags = 0; if (buttonsChanged & PSP_CTRL_LTRIGGER) { event.kbd.keycode = Common::KEYCODE_ESCAPE; event.kbd.ascii = 27; - } else if (buttonsChanged & PSP_CTRL_RTRIGGER) { - event.kbd.keycode = Common::KEYCODE_RETURN; - event.kbd.ascii = 13; } else if (buttonsChanged & PSP_CTRL_START) { event.kbd.keycode = Common::KEYCODE_F5; event.kbd.ascii = Common::ASCII_F5; + if (pad.Buttons & PSP_CTRL_RTRIGGER) { + event.kbd.flags = Common::KBD_CTRL; // Main menu to allow RTL + } /* } else if (buttonsChanged & PSP_CTRL_SELECT) { event.kbd.keycode = Common::KEYCODE_0; event.kbd.ascii = '0'; */ } else if (buttonsChanged & PSP_CTRL_SQUARE) { event.kbd.keycode = Common::KEYCODE_PERIOD; event.kbd.ascii = '.'; + } else if (buttonsChanged & PSP_CTRL_TRIANGLE) { + event.kbd.keycode = Common::KEYCODE_RETURN; + event.kbd.ascii = 13; + } else if (pad.Buttons & PSP_CTRL_RTRIGGER) { + event.kbd.flags |= Common::KBD_SHIFT; } } @@ -484,7 +800,7 @@ bool OSystem_PSP::pollEvent(Common::Event &event) { newY += _padAccel >> 2; // If no movement then this has no effect - if (pad.Buttons & PSP_CTRL_TRIANGLE) { + if (pad.Buttons & PSP_CTRL_RTRIGGER) { // Fine control mode for analog if (analogStepAmountX != 0) { if (analogStepAmountX > 0) @@ -535,6 +851,136 @@ bool OSystem_PSP::pollEvent(Common::Event &event) { return false; } +bool OSystem_PSP::pollEvent(Common::Event &event) { + float nub_angle = -1; + int x, y; + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(1); + sceCtrlReadBufferPositive(&pad, 1); + + uint32 buttonsChanged = pad.Buttons ^ _prevButtons; + + if ((buttonsChanged & PSP_CTRL_SELECT) || (pad.Buttons & PSP_CTRL_SELECT)) { + if ( !(pad.Buttons & PSP_CTRL_SELECT) ) + _keyboardVisible = !_keyboardVisible; + _prevButtons = pad.Buttons; + return false; + } + + if (!_keyboardVisible) + return processInput(event); + + if ( (buttonsChanged & PSP_CTRL_RTRIGGER) && !(pad.Buttons & PSP_CTRL_RTRIGGER)) + _keyboardMode ^= CAPS_LOCK; + + if ( (buttonsChanged & PSP_CTRL_LTRIGGER) && !(pad.Buttons & PSP_CTRL_LTRIGGER)) + _keyboardMode ^= SYMBOLS; + + if ( (buttonsChanged & PSP_CTRL_LEFT) && !(pad.Buttons & PSP_CTRL_LEFT)) { + event.kbd.flags = 0; + event.kbd.ascii = 0; + event.kbd.keycode = Common::KEYCODE_LEFT; + _prevButtons = pad.Buttons; + return true; + } + + if ( (buttonsChanged & PSP_CTRL_RIGHT) && !(pad.Buttons & PSP_CTRL_RIGHT)) { + event.kbd.flags = 0; + event.kbd.ascii = 0; + event.kbd.keycode = Common::KEYCODE_RIGHT; + _prevButtons = pad.Buttons; + return true; + } + + if ( (buttonsChanged & PSP_CTRL_UP) && !(pad.Buttons & PSP_CTRL_UP)) { + event.kbd.flags = 0; + event.kbd.ascii = 0; + event.kbd.keycode = Common::KEYCODE_UP; + _prevButtons = pad.Buttons; + return true; + } + + if ( (buttonsChanged & PSP_CTRL_DOWN) && !(pad.Buttons & PSP_CTRL_DOWN)) { + event.kbd.flags = 0; + event.kbd.ascii = 0; + event.kbd.keycode = Common::KEYCODE_DOWN; + _prevButtons = pad.Buttons; + return true; + } + + // compute nub direction + x = pad.Lx-128; + y = pad.Ly-128; + _kbdClut[_keySelected] = 0xf888; + if (x*x + y*y > 10000) { + nub_angle = atan2(y, x); + _keySelected = (int)(1 + (M_PI + nub_angle) * 30 / (2 * M_PI)); + _keySelected -= 2; + if (_keySelected < 1) + _keySelected += 30; + _kbdClut[_keySelected] = 0xFFFF; + + if (buttonsChanged & PSP_CTRL_CROSS) { + event.type = (pad.Buttons & PSP_CTRL_CROSS) ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP; + if (_keySelected > 26) { + event.kbd.flags = 0; + switch(_keySelected) { + case 27: + event.kbd.ascii = ' '; + event.kbd.keycode = Common::KEYCODE_SPACE; + break; + case 28: + event.kbd.ascii = 127; + event.kbd.keycode = Common::KEYCODE_DELETE; + break; + case 29: + event.kbd.ascii = 8; + event.kbd.keycode = Common::KEYCODE_BACKSPACE; + break; + case 30: + event.kbd.ascii = 13; + event.kbd.keycode = Common::KEYCODE_RETURN; + break; + } + } else { + switch( _keyboardMode) { + case 0: + event.kbd.flags = 0; + event.kbd.ascii = 'a'+_keySelected-1; + event.kbd.keycode = (Common::KeyCode)(Common::KEYCODE_a + _keySelected-1); + break; + case CAPS_LOCK: + event.kbd.ascii = 'A'+_keySelected-1; + event.kbd.keycode = (Common::KeyCode)(Common::KEYCODE_a + _keySelected-1); + event.kbd.flags = Common::KBD_SHIFT; + break; + case SYMBOLS: + if (_keySelected < 21) { + event.kbd.flags = 0; + event.kbd.ascii = kbd_ascii[_keySelected-1]; + event.kbd.keycode = kbd_code[ _keySelected-1]; + } + break; + case (SYMBOLS|CAPS_LOCK): + if (_keySelected < 21) { + event.kbd.flags = 0; + event.kbd.ascii = kbd_ascii_cl[_keySelected-1]; + event.kbd.keycode = kbd_code_cl[ _keySelected-1]; + } + break; + } + } + _prevButtons = pad.Buttons; + return true; + } + } + + _prevButtons = pad.Buttons; + return false; +} + + uint32 OSystem_PSP::getMillis() { return SDL_GetTicks(); } diff --git a/backends/platform/psp/osys_psp.h b/backends/platform/psp/osys_psp.h index 34957b293c..047fbff97e 100644 --- a/backends/platform/psp/osys_psp.h +++ b/backends/platform/psp/osys_psp.h @@ -23,6 +23,9 @@ * */ +#ifndef OSYS_PSP_H +#define OSYS_PSP_H + #include "common/scummsys.h" #include "graphics/surface.h" #include "graphics/colormasks.h" @@ -47,6 +50,11 @@ public: static OSystem *instance(); protected: + struct Vertex { + float u,v; + float x,y,z; + }; + uint16 _screenWidth; uint16 _screenHeight; uint16 _overlayWidth; @@ -56,6 +64,7 @@ protected: uint16 _palette[256]; bool _overlayVisible; uint32 _shakePos; + uint32 _lastScreenUpdate; Graphics::Surface _framebuffer; @@ -65,6 +74,15 @@ protected: int _mouseHotspotX, _mouseHotspotY; byte _mouseKeyColour; byte *_mouseBuf; + bool _cursorPaletteDisabled; + + int _graphicMode; + Vertex *_vertices; + unsigned short* _clut; + unsigned short* _kbdClut; + bool _keyboardVisible; + int _keySelected; + int _keyboardMode; uint32 _prevButtons; uint32 _lastPadCheck; @@ -78,7 +96,6 @@ protected: Common::TimerManager *_timer; public: - OSystem_PSP(); virtual ~OSystem_PSP(); @@ -87,15 +104,21 @@ public: virtual bool hasFeature(Feature f); virtual void setFeatureState(Feature f, bool enable); virtual bool getFeatureState(Feature f); + virtual const GraphicsMode *getSupportedGraphicsModes() const; virtual int getDefaultGraphicsMode() const; virtual bool setGraphicsMode(int mode); bool setGraphicsMode(const char *name); virtual int getGraphicsMode() const; - virtual void initSize(uint width, uint height); + + virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format); virtual int16 getWidth(); virtual int16 getHeight(); + virtual void setPalette(const byte *colors, uint start, uint num); + virtual void grabPalette(byte *colors, uint start, uint num); + virtual void setCursorPalette(const byte *colors, uint start, uint num); + virtual void disableCursorPalette(bool disable); virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h); virtual Graphics::Surface *lockScreen(); virtual void unlockScreen(); @@ -109,15 +132,15 @@ public: virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); virtual int16 getOverlayHeight(); virtual int16 getOverlayWidth(); - virtual void grabPalette(byte *colors, uint start, uint num); virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<4444>(); } virtual bool showMouse(bool visible); - virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); virtual bool pollEvent(Common::Event &event); + virtual bool processInput(Common::Event &event); + virtual uint32 getMillis(); virtual void delayMillis(uint msecs); @@ -144,3 +167,5 @@ public: virtual Common::WriteStream *createConfigWriteStream(); }; + +#endif /* OSYS_PSP_H */ diff --git a/backends/platform/psp/osys_psp_gu.cpp b/backends/platform/psp/osys_psp_gu.cpp deleted file mode 100644 index 76f6b42e37..0000000000 --- a/backends/platform/psp/osys_psp_gu.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#include "osys_psp_gu.h" -#include "trace.h" -#include "common/events.h" - -#include <zlib.h> - -#include <pspdisplay.h> - -#define PIXEL_SIZE (4) -#define BUF_WIDTH (512) -#define PSP_SCREEN_WIDTH 480 -#define PSP_SCREEN_HEIGHT 272 -#define PSP_FRAME_SIZE (BUF_WIDTH * PSP_SCREEN_HEIGHT * PIXEL_SIZE) -#define MOUSE_SIZE 128 -#define KBD_DATA_SIZE 130560 - -unsigned int __attribute__((aligned(16))) list[262144]; -unsigned short __attribute__((aligned(16))) clut256[256]; -unsigned short __attribute__((aligned(16))) mouseClut[256]; -unsigned short __attribute__((aligned(16))) kbClut[256]; -//unsigned int __attribute__((aligned(16))) offscreen256[640*480]; -//unsigned int __attribute__((aligned(16))) overlayBuffer256[640*480*2]; -unsigned int __attribute__((aligned(16))) mouseBuf256[MOUSE_SIZE*MOUSE_SIZE]; - -extern unsigned long RGBToColour(unsigned long r, unsigned long g, unsigned long b); - -extern unsigned int size_keyboard_symbols_compressed; -extern unsigned char keyboard_symbols_compressed[]; -extern unsigned int size_keyboard_symbols_shift_compressed; -extern unsigned char keyboard_symbols_shift_compressed[]; -extern unsigned int size_keyboard_letters_compressed; -extern unsigned char keyboard_letters_compressed[]; -extern unsigned int size_keyboard_letters_shift_compressed; -extern unsigned char keyboard_letters_shift_compressed[]; -unsigned char *keyboard_symbols; -unsigned char *keyboard_symbols_shift; -unsigned char *keyboard_letters; -unsigned char *keyboard_letters_shift; - -unsigned char kbd_ascii[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '[', ']', '\\', ';', '\'', ',', '.', '/', '`'}; -Common::KeyCode kbd_code[] = {Common::KEYCODE_1, Common::KEYCODE_2, Common::KEYCODE_3, Common::KEYCODE_4, Common::KEYCODE_5, Common::KEYCODE_6, Common::KEYCODE_7, Common::KEYCODE_8, Common::KEYCODE_9, Common::KEYCODE_0, Common::KEYCODE_MINUS, Common::KEYCODE_EQUALS, Common::KEYCODE_LEFTBRACKET, Common::KEYCODE_RIGHTBRACKET, - Common::KEYCODE_BACKSLASH, Common::KEYCODE_SEMICOLON, Common::KEYCODE_QUOTE, Common::KEYCODE_COMMA, Common::KEYCODE_PERIOD, Common::KEYCODE_SLASH, Common::KEYCODE_BACKQUOTE}; -unsigned char kbd_ascii_cl[] = {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '{', '}', '|', ':', '"', '<', '>', '?', '~'}; -Common::KeyCode kbd_code_cl[] = {Common::KEYCODE_EXCLAIM, Common::KEYCODE_AT, Common::KEYCODE_HASH, Common::KEYCODE_DOLLAR, (Common::KeyCode)37, Common::KEYCODE_CARET, Common::KEYCODE_AMPERSAND, Common::KEYCODE_ASTERISK, Common::KEYCODE_LEFTPAREN, Common::KEYCODE_RIGHTPAREN, Common::KEYCODE_UNDERSCORE, - Common::KEYCODE_PLUS, (Common::KeyCode)123, (Common::KeyCode)125, (Common::KeyCode)124, Common::KEYCODE_COLON, Common::KEYCODE_QUOTEDBL, Common::KEYCODE_LESS, Common::KEYCODE_GREATER, Common::KEYCODE_QUESTION, (Common::KeyCode)126}; -#define CAPS_LOCK (1 << 0) -#define SYMBOLS (1 << 1) - - -OSystem_PSP_GU::OSystem_PSP_GU() { - //sceKernelDcacheWritebackAll(); - - // setup - sceGuInit(); - sceGuStart(0, list); - sceGuDrawBuffer(GU_PSM_8888, (void *)0, BUF_WIDTH); - sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)PSP_FRAME_SIZE, BUF_WIDTH); - sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * 2), BUF_WIDTH); - sceGuOffset(2048 - (PSP_SCREEN_WIDTH/2), 2048 - (PSP_SCREEN_HEIGHT/2)); - sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); - sceGuDepthRange(0xc350, 0x2710); - sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); - sceGuEnable(GU_SCISSOR_TEST); - sceGuFrontFace(GU_CW); - sceGuEnable(GU_TEXTURE_2D); - sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); - sceGuFinish(); - sceGuSync(0,0); - - sceDisplayWaitVblankStart(); - sceGuDisplay(1); - - //decompress keyboard data - uLongf kbdSize = KBD_DATA_SIZE; - keyboard_letters = (unsigned char *)memalign(16, KBD_DATA_SIZE); - if (Z_OK != uncompress((Bytef *)keyboard_letters, &kbdSize, (const Bytef *)keyboard_letters_compressed, size_keyboard_letters_compressed)) - error("OSystem_PSP_GU: uncompressing keyboard_letters failed"); - - kbdSize = KBD_DATA_SIZE; - keyboard_letters_shift = (unsigned char *)memalign(16, KBD_DATA_SIZE); - if (Z_OK != uncompress((Bytef *)keyboard_letters_shift, &kbdSize, (const Bytef *)keyboard_letters_shift_compressed, size_keyboard_letters_shift_compressed)) - error("OSystem_PSP_GU: uncompressing keyboard_letters_shift failed"); - - kbdSize = KBD_DATA_SIZE; - keyboard_symbols = (unsigned char *)memalign(16, KBD_DATA_SIZE); - if (Z_OK != uncompress((Bytef *)keyboard_symbols, &kbdSize, (const Bytef *)keyboard_symbols_compressed, size_keyboard_symbols_compressed)) - error("OSystem_PSP_GU: uncompressing keyboard_symbols failed"); - - kbdSize = KBD_DATA_SIZE; - keyboard_symbols_shift = (unsigned char *)memalign(16, KBD_DATA_SIZE); - if (Z_OK != uncompress((Bytef *)keyboard_symbols_shift, &kbdSize, (const Bytef *)keyboard_symbols_shift_compressed, size_keyboard_symbols_shift_compressed)) - error("OSystem_PSP_GU: uncompressing keyboard_symbols_shift failed"); - - _keyboardVisible = false; - _clut = (unsigned short*)(((unsigned int)clut256)|0x40000000); - _kbdClut = (unsigned short*)(((unsigned int)kbClut)|0x40000000); - _mouseBuf = (byte *)mouseBuf256; - _graphicMode = STRETCHED_480X272; - _keySelected = 1; - _keyboardMode = 0; - _mouseX = PSP_SCREEN_WIDTH >> 1; - _mouseY = PSP_SCREEN_HEIGHT >> 1; -} - -OSystem_PSP_GU::~OSystem_PSP_GU() { - free(keyboard_symbols_shift); - free(keyboard_symbols); - free(keyboard_letters_shift); - free(keyboard_letters); - - _offscreen = 0; - _overlayBuffer = 0; - _mouseBuf = 0; - sceGuTerm(); -} - -void OSystem_PSP_GU::initSize(uint width, uint height) { - PSPDebugTrace("initSize\n"); - _screenWidth = width; - _screenHeight = height; - - _overlayWidth = PSP_SCREEN_WIDTH; //width; - _overlayHeight = PSP_SCREEN_HEIGHT; //height; - -// _offscreen = (byte *)offscreen256; - _overlayBuffer = (OverlayColor *)0x44000000 + PSP_FRAME_SIZE; - - _offscreen = (byte *)_overlayBuffer + _overlayWidth * _overlayHeight * sizeof(OverlayColor); - bzero(_offscreen, width * height); - clearOverlay(); - memset(_palette, 0xffff, 256 * sizeof(unsigned short)); - _kbdClut[0] = 0xffff; - _kbdClut[246] = 0x4ccc; - _kbdClut[247] = 0x0000; - for (int i=1;i<31;i++) - _kbdClut[i] = 0xf888; - _mouseVisible = false; - sceKernelDcacheWritebackAll(); -} - -int OSystem_PSP_GU::getDefaultGraphicsMode() const { - return STRETCHED_480X272; -} - -bool OSystem_PSP_GU::setGraphicsMode(int mode) { - _graphicMode = mode; - return true; -} - -bool OSystem_PSP_GU::setGraphicsMode(const char *name) { - int i = 0; - - while (s_supportedGraphicsModes[i].name) { - if (!strcmpi(s_supportedGraphicsModes[i].name, name)) { - _graphicMode = s_supportedGraphicsModes[i].id; - return true; - } - i++; - } - - return false; -} - -int OSystem_PSP_GU::getGraphicsMode() const { - return _graphicMode; -} - -void OSystem_PSP_GU::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) { - //TODO: handle cursorTargetScale - _mouseWidth = w; - _mouseHeight = h; - - _mouseHotspotX = hotspotX; - _mouseHotspotY = hotspotY; - - _mouseKeyColour = keycolor; - - memcpy(mouseClut, _palette, 256*sizeof(unsigned short)); - mouseClut[_mouseKeyColour] = 0; - sceKernelDcacheWritebackAll(); - - for (unsigned int i=0;i<h;i++) - memcpy(_mouseBuf+i*MOUSE_SIZE, buf+i*w, w); -} - -void OSystem_PSP_GU::setPalette(const byte *colors, uint start, uint num) { - const byte *b = colors; - - for (uint i = 0; i < num; ++i) { - _palette[start + i] = RGBToColour(b[0], b[1], b[2]); - b += 4; - } - - //copy to CLUT - memcpy(_clut, _palette, 256*sizeof(unsigned short)); - - //force update of mouse CLUT as well, as it may have been set up before this palette was set - memcpy(mouseClut, _palette, 256*sizeof(unsigned short)); - mouseClut[_mouseKeyColour] = 0; - - sceKernelDcacheWritebackAll(); -} - - -void OSystem_PSP_GU::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) { - //Clip the coordinates - if (x < 0) { - w += x; - buf -= x; - x = 0; - } - - if (y < 0) { - h += y; - buf -= y * pitch; - y = 0; - } - - if (w > _screenWidth - x) { - w = _screenWidth - x; - } - - if (h > _screenHeight - y) { - h = _screenHeight - y; - } - - if (w <= 0 || h <= 0) - return; - - - byte *dst = _offscreen + y * _screenWidth + x; - - if (_screenWidth == pitch && pitch == w) - { - memcpy(dst, buf, h * w); -/* - sceGuStart(0,list); - sceGuCopyImage( 3, 0, 0, w/2, h, w/2, (void *)buf, x/2, y, _screenWidth /2, _offscreen); - sceGuFinish(); - sceGuSync(0,0); -*/ - } - else - { - do - { - memcpy(dst, buf, w); - buf += pitch; - dst += _screenWidth; - } while (--h); - } -} - -void OSystem_PSP_GU::updateScreen() { - sceGuStart(0,list); - - sceGuClearColor(0xff000000); - sceGuClear(GU_COLOR_BUFFER_BIT); - - sceGuClutMode(GU_PSM_5551, 0, 0xff, 0); - sceGuClutLoad(32, clut256); // upload 32*8 entries (256) - sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image - if (_screenWidth == 320) - sceGuTexImage(0, 512, 256, _screenWidth, _offscreen); - else - sceGuTexImage(0, 512, 512, _screenWidth, _offscreen); - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); - sceGuTexFilter(GU_LINEAR, GU_LINEAR); - sceGuTexOffset(0,0); - sceGuAmbientColor(0xffffffff); - sceGuColor(0xffffffff); - - struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); - vertices[0].u = 0.5; vertices[0].v = 0.5; - vertices[1].u = _screenWidth - 0.5; vertices[1].v = _screenHeight - 0.5; - switch(_graphicMode) { - case CENTERED_320X200: - vertices[0].x = (PSP_SCREEN_WIDTH - 320) / 2; vertices[0].y = (PSP_SCREEN_HEIGHT - 200) / 2; vertices[0].z = 0; - vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 320) / 2; vertices[1].y = PSP_SCREEN_HEIGHT - (PSP_SCREEN_HEIGHT - 200) / 2; vertices[1].z = 0; - break; - case CENTERED_435X272: - vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2; vertices[0].y = 0; vertices[0].z = 0; - vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 435) / 2; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[1].z = 0; - break; - case STRETCHED_480X272: - vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0; - vertices[1].x = PSP_SCREEN_WIDTH; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[1].z = 0; - break; - case CENTERED_362X272: - vertices[0].x = (PSP_SCREEN_WIDTH - 362) / 2; vertices[0].y = 0; vertices[0].z = 0; - vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 362) / 2; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[1].z = 0; - break; - } - - if (_shakePos) { - vertices[0].y += _shakePos; - vertices[1].y += _shakePos; - } - - sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices); - if (_screenWidth == 640) { - sceGuTexImage(0, 512, 512, _screenWidth, _offscreen+512); - vertices[0].u = 512 + 0.5; vertices[1].v = _screenHeight - 0.5; - vertices[0].x += (vertices[1].x - vertices[0].x) * 511 / 640; vertices[0].y = 0; vertices[0].z = 0; - sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices); - } - - - // draw overlay - if (_overlayVisible) { - vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0; - vertices[1].x = PSP_SCREEN_WIDTH; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[1].z = 0; - vertices[0].u = 0.5; vertices[0].v = 0.5; - vertices[1].u = _overlayWidth - 0.5; vertices[1].v = _overlayHeight - 0.5; - sceGuTexMode(GU_PSM_4444, 0, 0, 0); // 16-bit image - sceGuDisable(GU_ALPHA_TEST); - sceGuEnable(GU_BLEND); - - //sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); - sceGuBlendFunc(GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_ALPHA, 0xFFFFFFFF, 0); - - if (_overlayWidth > 320) - sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer); - else - sceGuTexImage(0, 512, 256, _overlayWidth, _overlayBuffer); - - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); - sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices); - // need to render twice for textures > 512 - if ( _overlayWidth > 512) { - sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer + 512); - vertices[0].u = 512 + 0.5; vertices[1].v = _overlayHeight - 0.5; - vertices[0].x = PSP_SCREEN_WIDTH * 512 / 640; vertices[0].y = 0; vertices[0].z = 0; - sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices); - } - sceGuDisable(GU_BLEND); - } - - // draw mouse - if (_mouseVisible) { - sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image - sceGuClutMode(GU_PSM_5551, 0, 0xff, 0); - sceGuClutLoad(32, mouseClut); // upload 32*8 entries (256) - sceGuAlphaFunc(GU_GREATER,0,0xff); - sceGuEnable(GU_ALPHA_TEST); - sceGuTexImage(0, MOUSE_SIZE, MOUSE_SIZE, MOUSE_SIZE, _mouseBuf); - sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - - vertices[0].u = 0.5; vertices[0].v = 0.5; - vertices[1].u = _mouseWidth - 0.5; vertices[1].v = _mouseHeight - 0.5; - - //adjust cursor position - int mX = _mouseX - _mouseHotspotX; - int mY = _mouseY - _mouseHotspotY; - - if (_overlayVisible) { - float scalex, scaley; - - scalex = (float)PSP_SCREEN_WIDTH /_overlayWidth; - scaley = (float)PSP_SCREEN_HEIGHT /_overlayHeight; - - vertices[0].x = mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; - vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; - } else - switch(_graphicMode) { - case CENTERED_320X200: - vertices[0].x = (PSP_SCREEN_WIDTH - 320) / 2 + mX; vertices[0].y = (PSP_SCREEN_HEIGHT - 200) / 2 + mY; vertices[0].z = 0; - vertices[1].x = vertices[0].x+_mouseWidth; vertices[1].y = vertices[0].y + _mouseHeight; vertices[1].z = 0; - break; - case CENTERED_435X272: - { - float scalex, scaley; - - scalex = 435.0f / _screenWidth; - scaley = 272.0f / _screenHeight; - - vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2 + mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; - vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; - - } - break; - case CENTERED_362X272: - { - float scalex, scaley; - - scalex = 362.0f / _screenWidth; - scaley = 272.0f / _screenHeight; - - vertices[0].x = (PSP_SCREEN_WIDTH - 362) / 2 + mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; - vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; - } - break; - case STRETCHED_480X272: - { - float scalex, scaley; - - scalex = (float)PSP_SCREEN_WIDTH / _screenWidth; - scaley = (float)PSP_SCREEN_HEIGHT / _screenHeight; - - vertices[0].x = mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; - vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; - } - break; - } - sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices); - } - - if (_keyboardVisible) { - sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image - sceGuClutMode(GU_PSM_4444, 0, 0xff, 0); - sceGuClutLoad(32, kbClut); // upload 32*8 entries (256) - sceGuDisable(GU_ALPHA_TEST); - sceGuEnable(GU_BLEND); - sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); - switch(_keyboardMode) { - case 0: - sceGuTexImage(0, 512, 512, 480, keyboard_letters); - break; - case CAPS_LOCK: - sceGuTexImage(0, 512, 512, 480, keyboard_letters_shift); - break; - case SYMBOLS: - sceGuTexImage(0, 512, 512, 480, keyboard_symbols); - break; - case (CAPS_LOCK | SYMBOLS): - sceGuTexImage(0, 512, 512, 480, keyboard_symbols_shift); - break; - } - sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); - - vertices[0].u = 0.5; vertices[0].v = 0.5; - vertices[1].u = PSP_SCREEN_WIDTH-0.5; vertices[1].v = PSP_SCREEN_HEIGHT-0.5; - vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0; - vertices[1].x = PSP_SCREEN_WIDTH; vertices[1].y = PSP_SCREEN_HEIGHT; vertices[0].z = 0; - sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices); - sceGuDisable(GU_BLEND); - } - sceKernelDcacheWritebackAll(); - - sceGuFinish(); - sceGuSync(0,0); - - sceDisplayWaitVblankStart(); - sceGuSwapBuffers(); - - //sceKernelDcacheWritebackAll(); -} - -bool OSystem_PSP_GU::pollEvent(Common::Event &event) { - float nub_angle = -1; - int x, y; - - sceCtrlSetSamplingCycle(0); - sceCtrlSetSamplingMode(1); - sceCtrlReadBufferPositive(&pad, 1); - - uint32 buttonsChanged = pad.Buttons ^ _prevButtons; - - if ((buttonsChanged & PSP_CTRL_SELECT) || (pad.Buttons & PSP_CTRL_SELECT)) { - if ( !(pad.Buttons & PSP_CTRL_SELECT) ) - _keyboardVisible = !_keyboardVisible; - _prevButtons = pad.Buttons; - return false; - } - - if (!_keyboardVisible) - return OSystem_PSP::pollEvent(event); - - if ( (buttonsChanged & PSP_CTRL_RTRIGGER) && !(pad.Buttons & PSP_CTRL_RTRIGGER)) - _keyboardMode ^= CAPS_LOCK; - - if ( (buttonsChanged & PSP_CTRL_LTRIGGER) && !(pad.Buttons & PSP_CTRL_LTRIGGER)) - _keyboardMode ^= SYMBOLS; - - if ( (buttonsChanged & PSP_CTRL_LEFT) && !(pad.Buttons & PSP_CTRL_LEFT)) { - event.kbd.flags = 0; - event.kbd.ascii = 0; - event.kbd.keycode = Common::KEYCODE_LEFT; - _prevButtons = pad.Buttons; - return true; - } - - if ( (buttonsChanged & PSP_CTRL_RIGHT) && !(pad.Buttons & PSP_CTRL_RIGHT)) { - event.kbd.flags = 0; - event.kbd.ascii = 0; - event.kbd.keycode = Common::KEYCODE_RIGHT; - _prevButtons = pad.Buttons; - return true; - } - - if ( (buttonsChanged & PSP_CTRL_UP) && !(pad.Buttons & PSP_CTRL_UP)) { - event.kbd.flags = 0; - event.kbd.ascii = 0; - event.kbd.keycode = Common::KEYCODE_UP; - _prevButtons = pad.Buttons; - return true; - } - - if ( (buttonsChanged & PSP_CTRL_DOWN) && !(pad.Buttons & PSP_CTRL_DOWN)) { - event.kbd.flags = 0; - event.kbd.ascii = 0; - event.kbd.keycode = Common::KEYCODE_DOWN; - _prevButtons = pad.Buttons; - return true; - } - - // compute nub direction - x = pad.Lx-128; - y = pad.Ly-128; - _kbdClut[_keySelected] = 0xf888; - if (x*x + y*y > 10000) { - nub_angle = atan2(y, x); - _keySelected = (int)(1 + (M_PI + nub_angle) * 30 / (2 * M_PI)); - _keySelected -= 2; - if (_keySelected < 1) - _keySelected += 30; - _kbdClut[_keySelected] = 0xffff; - - if (buttonsChanged & PSP_CTRL_CROSS) { - event.type = (pad.Buttons & PSP_CTRL_CROSS) ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP; - if (_keySelected > 26) { - event.kbd.flags = 0; - switch(_keySelected) { - case 27: - event.kbd.ascii = ' '; - event.kbd.keycode = Common::KEYCODE_SPACE; - break; - case 28: - event.kbd.ascii = 127; - event.kbd.keycode = Common::KEYCODE_DELETE; - break; - case 29: - event.kbd.ascii = 8; - event.kbd.keycode = Common::KEYCODE_BACKSPACE; - break; - case 30: - event.kbd.ascii = 13; - event.kbd.keycode = Common::KEYCODE_RETURN; - break; - } - } else { - switch( _keyboardMode) { - case 0: - event.kbd.flags = 0; - event.kbd.ascii = 'a'+_keySelected-1; - event.kbd.keycode = (Common::KeyCode)(Common::KEYCODE_a + _keySelected-1); - break; - case CAPS_LOCK: - event.kbd.ascii = 'A'+_keySelected-1; - event.kbd.keycode = (Common::KeyCode)(Common::KEYCODE_a + _keySelected-1); - event.kbd.flags = Common::KBD_SHIFT; - break; - case SYMBOLS: - if (_keySelected < 21) { - event.kbd.flags = 0; - event.kbd.ascii = kbd_ascii[_keySelected-1]; - event.kbd.keycode = kbd_code[ _keySelected-1]; - } - break; - case (SYMBOLS|CAPS_LOCK): - if (_keySelected < 21) { - event.kbd.flags = 0; - event.kbd.ascii = kbd_ascii_cl[_keySelected-1]; - event.kbd.keycode = kbd_code_cl[ _keySelected-1]; - } - break; - } - } - _prevButtons = pad.Buttons; - return true; - } - } - - _prevButtons = pad.Buttons; - return false; -} - diff --git a/backends/platform/psp/psp.mk b/backends/platform/psp/psp.mk index 10e272a593..998a420ffc 100644 --- a/backends/platform/psp/psp.mk +++ b/backends/platform/psp/psp.mk @@ -9,7 +9,7 @@ PSP_EBOOT_SFO = param.sfo PSP_EBOOT_TITLE = ScummVM-PSP DATE = $(shell date +%Y%m%d) -MKSFO = mksfo +MKSFO = mksfoex -d MEMSIZE=1 PACK_PBP = pack-pbp $(PSP_EXE_STRIPPED): $(PSP_EXE) diff --git a/backends/platform/psp/psp.spec b/backends/platform/psp/psp.spec index 807b8f93b7..e319b022f7 100644 --- a/backends/platform/psp/psp.spec +++ b/backends/platform/psp/psp.spec @@ -1,3 +1,3 @@ %rename lib old_lib *lib: -%(old_lib) -lpspdebug -lpspgu -lpspctrl -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lc -lpspuser -lpsputility -lpspkernel -lpspnet_inet -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspsdk -lpspuser +%(old_lib) -lpspdebug -lpspgu -lpspctrl -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lc -lpspuser -lpsputility -lpspkernel -lpspnet_inet -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspuser -lpsppower diff --git a/backends/platform/psp/psp_main.cpp b/backends/platform/psp/psp_main.cpp index 0af7ebf269..74363e4ac9 100644 --- a/backends/platform/psp/psp_main.cpp +++ b/backends/platform/psp/psp_main.cpp @@ -31,12 +31,16 @@ #include <pspdebug.h> #endif +#include <psppower.h> + #include <common/system.h> #include <engines/engine.h> #include <base/main.h> #include <base/plugins.h> +#include "backends/platform/psp/powerman.h" + -#include "osys_psp_gu.h" +#include "osys_psp.h" #include "./trace.h" @@ -58,9 +62,8 @@ PSP_MODULE_INFO("SCUMMVM-PSP", 0, 1, 1); * code (crt0.c) starts this program in to be in usermode * even though the module was started in kernelmode */ -#ifndef USERSPACE_ONLY PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); -#endif +PSP_HEAP_SIZE_KB(-128); //Leave 128kb for thread stacks, etc. #ifndef USERSPACE_ONLY @@ -91,17 +94,36 @@ void loaderInit() { #endif /* Exit callback */ -SceKernelCallbackFunction exit_callback(int /*arg1*/, int /*arg2*/, void * /*common*/) { +int exit_callback(void) { sceKernelExitGame(); return 0; } +/* Function for handling suspend/resume */ +void power_callback(int , int powerinfo) { + if (powerinfo & PSP_POWER_CB_POWER_SWITCH || powerinfo & PSP_POWER_CB_SUSPENDING) { + PowerMan.suspend(); + } else if (powerinfo & PSP_POWER_CB_RESUME_COMPLETE) { + PowerMan.resume(); + } +} + /* Callback thread */ int CallbackThread(SceSize /*size*/, void *arg) { int cbid; cbid = sceKernelCreateCallback("Exit Callback", (SceKernelCallbackFunction)exit_callback, NULL); sceKernelRegisterExitCallback(cbid); + /* Set up callbacks for PSPIoStream */ + + cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0); + if (cbid >= 0) { + if(scePowerRegisterCallback(-1, cbid) < 0) { + PSPDebugTrace("SetupCallbacks(): Couldn't register callback for power_callback\n"); + } + } else { + PSPDebugTrace("SetupCallbacks(): Couldn't create a callback for power_callback\n"); + } sceKernelSleepThreadCB(); return 0; @@ -119,18 +141,25 @@ int SetupCallbacks(void) { #undef main int main(void) { + //change clock rate to 333mhz + scePowerSetClockFrequency(333, 333, 166); + + PowerManager::instance(); // Setup power manager + SetupCallbacks(); static const char *argv[] = { "scummvm", NULL }; static int argc = sizeof(argv)/sizeof(char *)-1; - g_system = new OSystem_PSP_GU(); + g_system = new OSystem_PSP(); assert(g_system); int res = scummvm_main(argc, argv); g_system->quit(); // TODO: Consider removing / replacing this! + PowerManager::destroy(); // get rid of PowerManager + sceKernelSleepThread(); return res; diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp index feb2c9a9c5..e6c8d716e3 100644 --- a/backends/platform/sdl/events.cpp +++ b/backends/platform/sdl/events.cpp @@ -186,6 +186,8 @@ bool OSystem_SDL::pollEvent(Common::Event &event) { } while (SDL_PollEvent(&ev)) { + preprocessEvents(&ev); + switch (ev.type) { case SDL_KEYDOWN:{ b = event.kbd.flags = SDLModToOSystemKeyFlags(SDL_GetModState()); diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp index f3e4ce626b..a67e35cf73 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/platform/sdl/graphics.cpp @@ -26,6 +26,9 @@ #include "backends/platform/sdl/sdl.h" #include "common/mutex.h" #include "common/util.h" +#ifdef USE_RGB_COLOR +#include "common/list.h" +#endif #include "graphics/font.h" #include "graphics/fontman.h" #include "graphics/scaler.h" @@ -97,6 +100,9 @@ void OSystem_SDL::beginGFXTransaction(void) { _transactionDetails.needUpdatescreen = false; _transactionDetails.normal1xScaler = false; +#ifdef USE_RGB_COLOR + _transactionDetails.formatChanged = false; +#endif _oldVideoMode = _videoMode; } @@ -120,6 +126,13 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) { _videoMode.mode = _oldVideoMode.mode; _videoMode.scaleFactor = _oldVideoMode.scaleFactor; +#ifdef USE_RGB_COLOR + } else if (_videoMode.format != _oldVideoMode.format) { + errors |= kTransactionFormatNotSupported; + + _videoMode.format = _oldVideoMode.format; + _screenFormat = _videoMode.format; +#endif } else if (_videoMode.screenWidth != _oldVideoMode.screenWidth || _videoMode.screenHeight != _oldVideoMode.screenHeight) { errors |= kTransactionSizeChangeFailed; @@ -143,7 +156,11 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) { } } +#ifdef USE_RGB_COLOR + if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged) { +#else if (_transactionDetails.sizeChanged) { +#endif unloadGFXMode(); if (!loadGFXMode()) { if (_oldVideoMode.setup) { @@ -186,12 +203,94 @@ OSystem::TransactionError OSystem_SDL::endGFXTransaction(void) { } else if (_transactionDetails.needUpdatescreen) { setGraphicsModeIntern(); internUpdateScreen(); - } + } _transactionMode = kTransactionNone; return (TransactionError)errors; } +#ifdef USE_RGB_COLOR +const Graphics::PixelFormat RGBList[] = { +#ifdef ENABLE_32BIT + // RGBA8888, ARGB8888, RGB888 + Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0), + Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24), + Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0), +#endif + // RGB565, XRGB1555, RGB555, RGBA4444, ARGB4444 + Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), + Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15), + Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), + Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0), + Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12) +}; +const Graphics::PixelFormat BGRList[] = { +#ifdef ENABLE_32BIT + // ABGR8888, BGRA8888, BGR888 + Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24), + Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0), + Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), +#endif + // BGR565, XBGR1555, BGR555, ABGR4444, BGRA4444 + Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0), + Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15), + Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0), + Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12), + Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0) +}; + +// TODO: prioritize matching alpha masks +Common::List<Graphics::PixelFormat> OSystem_SDL::getSupportedFormats() { + static Common::List<Graphics::PixelFormat> list; + static bool inited = false; + + if (inited) + return list; + + bool BGR = false; + int listLength = ARRAYSIZE(RGBList); + + Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8(); + if (_hwscreen) { + // Get our currently set hardware format + format = Graphics::PixelFormat(_hwscreen->format->BytesPerPixel, + 8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss, + 8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss, + _hwscreen->format->Rshift, _hwscreen->format->Gshift, + _hwscreen->format->Bshift, _hwscreen->format->Ashift); + + // Workaround to MacOSX SDL not providing an accurate Aloss value. + if (_hwscreen->format->Amask == 0) + format.aLoss = 8; + + // Push it first, as the prefered format. + list.push_back(format); + + if (format.bShift > format.rShift) + BGR = true; + + // Mark that we don't need to do this any more. + inited = true; + } + + for (int i = 0; i < listLength; i++) { + if (inited && (RGBList[i].bytesPerPixel > format.bytesPerPixel)) + continue; + if (BGR) { + if (BGRList[i] != format) + list.push_back(BGRList[i]); + list.push_back(RGBList[i]); + } else { + if (RGBList[i] != format) + list.push_back(RGBList[i]); + list.push_back(BGRList[i]); + } + } + list.push_back(Graphics::PixelFormat::createFormatCLUT8()); + return list; +} +#endif + bool OSystem_SDL::setGraphicsMode(int mode) { Common::StackLock lock(_graphicsMutex); @@ -340,9 +439,27 @@ int OSystem_SDL::getGraphicsMode() const { return _videoMode.mode; } -void OSystem_SDL::initSize(uint w, uint h) { +void OSystem_SDL::initSize(uint w, uint h, const Graphics::PixelFormat *format) { assert(_transactionMode == kTransactionActive); +#ifdef USE_RGB_COLOR + //avoid redundant format changes + Graphics::PixelFormat newFormat; + if (!format) + newFormat = Graphics::PixelFormat::createFormatCLUT8(); + else + newFormat = *format; + + assert(newFormat.bytesPerPixel > 0); + + if (newFormat != _videoMode.format) + { + _videoMode.format = newFormat; + _transactionDetails.formatChanged = true; + _screenFormat = newFormat; + } +#endif + // Avoid redundant res changes if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight) return; @@ -426,9 +543,21 @@ bool OSystem_SDL::loadGFXMode() { // // Create the surface that contains the 8 bit game data // +#ifdef USE_RGB_COLOR + _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, + _screenFormat.bytesPerPixel << 3, + ((1 << _screenFormat.rBits()) - 1) << _screenFormat.rShift , + ((1 << _screenFormat.gBits()) - 1) << _screenFormat.gShift , + ((1 << _screenFormat.bBits()) - 1) << _screenFormat.bShift , + ((1 << _screenFormat.aBits()) - 1) << _screenFormat.aShift ); + if (_screen == NULL) + error("allocating _screen failed"); + +#else _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0); if (_screen == NULL) error("allocating _screen failed"); +#endif // // Create the surface that contains the scaled graphics in 16 bit mode @@ -571,8 +700,8 @@ bool OSystem_SDL::hotswapGFXMode() { // Keep around the old _screen & _overlayscreen so we can restore the screen data // after the mode switch. SDL_Surface *old_screen = _screen; - SDL_Surface *old_overlayscreen = _overlayscreen; _screen = NULL; + SDL_Surface *old_overlayscreen = _overlayscreen; _overlayscreen = NULL; // Release the HW screen surface @@ -846,30 +975,6 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int * and just updates those, on the actual display. */ addDirtyRgnAuto(src); } else { - /* Clip the coordinates */ - if (x < 0) { - w += x; - src -= x; - x = 0; - } - - if (y < 0) { - h += y; - src -= y * pitch; - y = 0; - } - - if (w > _videoMode.screenWidth - x) { - w = _videoMode.screenWidth - x; - } - - if (h > _videoMode.screenHeight - y) { - h = _videoMode.screenHeight - y; - } - - if (w <= 0 || h <= 0) - return; - _cksumValid = false; addDirtyRect(x, y, w, h); } @@ -878,8 +983,19 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int if (SDL_LockSurface(_screen) == -1) error("SDL_LockSurface failed: %s", SDL_GetError()); +#ifdef USE_RGB_COLOR + byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth * _screenFormat.bytesPerPixel + x * _screenFormat.bytesPerPixel; + if (_videoMode.screenWidth == w && pitch == w * _screenFormat.bytesPerPixel) { + memcpy(dst, src, h*w*_screenFormat.bytesPerPixel); + } else { + do { + memcpy(dst, src, w * _screenFormat.bytesPerPixel); + src += pitch; + dst += _videoMode.screenWidth * _screenFormat.bytesPerPixel; + } while (--h); + } +#else byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; - if (_videoMode.screenWidth == pitch && pitch == w) { memcpy(dst, src, h*w); } else { @@ -889,6 +1005,7 @@ void OSystem_SDL::copyRectToScreen(const byte *src, int pitch, int x, int y, int dst += _videoMode.screenWidth; } while (--h); } +#endif // Unlock the screen surface SDL_UnlockSurface(_screen); @@ -912,7 +1029,11 @@ Graphics::Surface *OSystem_SDL::lockScreen() { _framebuffer.w = _screen->w; _framebuffer.h = _screen->h; _framebuffer.pitch = _screen->pitch; +#ifdef USE_RGB_COLOR + _framebuffer.bytesPerPixel = _screenFormat.bytesPerPixel; +#else _framebuffer.bytesPerPixel = 1; +#endif return &_framebuffer; } @@ -1096,6 +1217,11 @@ int16 OSystem_SDL::getWidth() { void OSystem_SDL::setPalette(const byte *colors, uint start, uint num) { assert(colors); +#ifdef USE_RGB_COLOR + if (_screenFormat.bytesPerPixel > 1) + return; //not using a paletted pixel format +#endif + // Setting the palette before _screen is created is allowed - for now - // since we don't actually set the palette until the screen is updated. // But it could indicate a programming error, so let's warn about it. @@ -1149,10 +1275,10 @@ void OSystem_SDL::setCursorPalette(const byte *colors, uint start, uint num) { } _cursorPaletteDisabled = false; - blitCursor(); } + void OSystem_SDL::setShakePos(int shake_pos) { assert (_transactionMode == kTransactionNone); @@ -1357,7 +1483,17 @@ void OSystem_SDL::warpMouse(int x, int y) { } } -void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) { +void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +#ifdef USE_RGB_COLOR + if (!format) + _cursorFormat = Graphics::PixelFormat::createFormatCLUT8(); + else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel) + _cursorFormat = *format; + keycolor &= (1 << (_cursorFormat.bytesPerPixel << 3)) - 1; +#else + keycolor &= 0xFF; +#endif + if (w == 0 || h == 0) return; @@ -1391,16 +1527,26 @@ void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, } free(_mouseData); - +#ifdef USE_RGB_COLOR + _mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel); + memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel); +#else _mouseData = (byte *)malloc(w * h); memcpy(_mouseData, buf, w * h); +#endif + blitCursor(); } void OSystem_SDL::blitCursor() { byte *dstPtr; const byte *srcPtr = _mouseData; +#ifdef USE_RGB_COLOR + uint32 color; + uint32 colormask = (1 << (_cursorFormat.bytesPerPixel << 3)) - 1; +#else byte color; +#endif int w, h, i, j; if (!_mouseOrigSurface || !_mouseData) @@ -1434,13 +1580,29 @@ void OSystem_SDL::blitCursor() { for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { - color = *srcPtr; - if (color != _mouseKeyColor) { // transparent, don't draw - *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, - palette[color].r, palette[color].g, palette[color].b); +#ifdef USE_RGB_COLOR + if (_cursorFormat.bytesPerPixel > 1) { + color = (*(uint32 *) srcPtr) & colormask; + if (color != _mouseKeyColor) { // transparent, don't draw + uint8 r,g,b; + _cursorFormat.colorToRGB(color,r,g,b); + *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, + r, g, b); + } + dstPtr += 2; + srcPtr += _cursorFormat.bytesPerPixel; + } else { +#endif + color = *srcPtr; + if (color != _mouseKeyColor) { // transparent, don't draw + *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, + palette[color].r, palette[color].g, palette[color].b); + } + dstPtr += 2; + srcPtr++; +#ifdef USE_RGB_COLOR } - dstPtr += 2; - srcPtr++; +#endif } dstPtr += _mouseOrigSurface->pitch - w * 2; } diff --git a/backends/platform/sdl/main.cpp b/backends/platform/sdl/main.cpp index 021bda155c..fa8f6ededb 100644 --- a/backends/platform/sdl/main.cpp +++ b/backends/platform/sdl/main.cpp @@ -37,7 +37,7 @@ #include "SymbianOs.h" #endif -#if !defined(__MAEMO__) && !defined(_WIN32_WCE) && !defined(GP2XWIZ) +#if !defined(__MAEMO__) && !defined(_WIN32_WCE) && !defined(GP2XWIZ)&& !defined(LINUXMOTO) #if defined (WIN32) int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) { diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 7b3cf4eaa1..547720d435 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -222,6 +222,10 @@ OSystem_SDL::OSystem_SDL() _osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0), #endif _hwscreen(0), _screen(0), _tmpscreen(0), +#ifdef USE_RGB_COLOR + _screenFormat(Graphics::PixelFormat::createFormatCLUT8()), + _cursorFormat(Graphics::PixelFormat::createFormatCLUT8()), +#endif _overlayVisible(false), _overlayscreen(0), _tmpscreen2(0), _samplesPerSec(0), @@ -691,7 +695,6 @@ void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) { void OSystem_SDL::setupMixer() { SDL_AudioSpec desired; - SDL_AudioSpec obtained; // Determine the desired output sampling frequency. _samplesPerSec = 0; @@ -721,7 +724,7 @@ void OSystem_SDL::setupMixer() { _mixer = new Audio::MixerImpl(this); assert(_mixer); - if (SDL_OpenAudio(&desired, &obtained) != 0) { + if (SDL_OpenAudio(&desired, &_obtainedRate) != 0) { warning("Could not open audio device: %s", SDL_GetError()); _samplesPerSec = 0; _mixer->setReady(false); @@ -729,7 +732,7 @@ void OSystem_SDL::setupMixer() { // Note: This should be the obtained output rate, but it seems that at // least on some platforms SDL will lie and claim it did get the rate // even if it didn't. Probably only happens for "weird" rates, though. - _samplesPerSec = obtained.freq; + _samplesPerSec = _obtainedRate.freq; debug(1, "Output sample rate: %d Hz", _samplesPerSec); // Tell the mixer that we are ready and start the sound processing @@ -737,7 +740,7 @@ void OSystem_SDL::setupMixer() { _mixer->setReady(true); #ifdef MIXER_DOUBLE_BUFFERING - initThreadedMixer(_mixer, obtained.samples * 4); + initThreadedMixer(_mixer, _obtainedRate.samples * 4); #endif // start the sound system diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 2a5fda30bd..82c1e7bf1b 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -93,9 +93,17 @@ public: void beginGFXTransaction(void); TransactionError endGFXTransaction(void); - // Set the size of the video bitmap. - // Typically, 320x200 - virtual void initSize(uint w, uint h); // overloaded by CE backend +#ifdef USE_RGB_COLOR + // Game screen + virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; } + + // Highest supported + virtual Common::List<Graphics::PixelFormat> getSupportedFormats(); +#endif + + // Set the size and format of the video bitmap. + // Typically, 320x200 CLUT8 + virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format); // overloaded by CE backend virtual int getScreenChangeID() const { return _screenChangeCount; } @@ -124,7 +132,7 @@ public: virtual void warpMouse(int x, int y); // overloaded by CE backend (FIXME) // Set the bitmap that's used when drawing the cursor. - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); // overloaded by CE backend (FIXME) + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend (FIXME) // Set colors of cursor palette void setCursorPalette(const byte *colors, uint start, uint num); @@ -186,6 +194,7 @@ public: // Overlay virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; } + virtual void showOverlay(); virtual void hideOverlay(); virtual void clearOverlay(); @@ -207,6 +216,7 @@ public: virtual bool hasFeature(Feature f); virtual void setFeatureState(Feature f, bool enable); virtual bool getFeatureState(Feature f); + virtual void preprocessEvents(SDL_Event *event) {}; #ifdef USE_OSD void displayMessageOnOSD(const char *msg); @@ -221,6 +231,7 @@ public: protected: bool _inited; + SDL_AudioSpec _obtainedRate; #ifdef USE_OSD SDL_Surface *_osdSurface; @@ -239,6 +250,10 @@ protected: // unseen game screen SDL_Surface *_screen; +#ifdef USE_RGB_COLOR + Graphics::PixelFormat _screenFormat; + Graphics::PixelFormat _cursorFormat; +#endif // temporary screen (for scalers) SDL_Surface *_tmpscreen; @@ -272,6 +287,9 @@ protected: bool needHotswap; bool needUpdatescreen; bool normal1xScaler; +#ifdef USE_RGB_COLOR + bool formatChanged; +#endif }; TransactionDetails _transactionDetails; @@ -288,6 +306,9 @@ protected: int screenWidth, screenHeight; int overlayWidth, overlayHeight; int hardwareWidth, hardwareHeight; +#ifdef USE_RGB_COLOR + Graphics::PixelFormat format; +#endif }; VideoState _videoMode, _oldVideoMode; diff --git a/backends/platform/wii/osystem.cpp b/backends/platform/wii/osystem.cpp index ae1eb11f4f..3f53605e85 100644 --- a/backends/platform/wii/osystem.cpp +++ b/backends/platform/wii/osystem.cpp @@ -52,6 +52,11 @@ OSystem_Wii::OSystem_Wii() : _currentHeight(0), _activeGraphicsMode(0), +#ifdef USE_RGB_COLOR + _texturePF(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)), + _screenPF(Graphics::PixelFormat::createFormatCLUT8()), + _cursorPF(Graphics::PixelFormat::createFormatCLUT8()), +#endif _fullscreen(false), diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h index e4176e8415..72263af5a8 100644 --- a/backends/platform/wii/osystem.h +++ b/backends/platform/wii/osystem.h @@ -75,6 +75,11 @@ private: u16 _currentWidth, _currentHeight; s32 _activeGraphicsMode; +#ifdef USE_RGB_COLOR + const Graphics::PixelFormat _texturePF; + Graphics::PixelFormat _screenPF; + Graphics::PixelFormat _cursorPF; +#endif bool _fullscreen; @@ -82,7 +87,7 @@ private: s32 _mouseX, _mouseY; u32 _mouseWidth, _mouseHeight; s32 _mouseHotspotX, _mouseHotspotY; - u8 _mouseKeyColor; + u16 _mouseKeyColor; u8 *_mouseCursor; bool _kbd_active; @@ -119,8 +124,13 @@ public: virtual const GraphicsMode *getSupportedGraphicsModes() const; virtual int getDefaultGraphicsMode() const; virtual bool setGraphicsMode(int mode); +#ifdef USE_RGB_COLOR + virtual Graphics::PixelFormat getScreenFormat() const; + virtual Common::List<Graphics::PixelFormat> getSupportedFormats(); +#endif virtual int getGraphicsMode() const; - virtual void initSize(uint width, uint height); + virtual void initSize(uint width, uint height, + const Graphics::PixelFormat *format); virtual int16 getWidth(); virtual int16 getHeight(); virtual void setPalette(const byte *colors, uint start, uint num); @@ -142,14 +152,15 @@ public: int x, int y, int w, int h); virtual int16 getOverlayWidth(); virtual int16 getOverlayHeight(); - virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<565>(); } + virtual Graphics::PixelFormat getOverlayFormat() const; virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, - int hotspotY, byte keycolor = 255, - int cursorTargetScale = 1); + int hotspotY, uint32 keycolor, + int cursorTargetScale, + const Graphics::PixelFormat *format); virtual bool pollEvent(Common::Event &event); virtual uint32 getMillis(); diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp index 4454acb318..b0e3f112c1 100644 --- a/backends/platform/wii/osystem_gfx.cpp +++ b/backends/platform/wii/osystem_gfx.cpp @@ -21,6 +21,8 @@ #include <malloc.h> +#include "graphics/conversion.h" + #include "osystem.h" #include "gx_supp.h" @@ -143,21 +145,70 @@ int OSystem_Wii::getGraphicsMode() const { return _activeGraphicsMode; } -void OSystem_Wii::initSize(uint width, uint height) { - if (_gameWidth != width || _gameHeight != height) { - printf("initSize %u %u\n", width, height); +#ifdef USE_RGB_COLOR +Graphics::PixelFormat OSystem_Wii::getScreenFormat() const { + return _screenPF; +} + +Common::List<Graphics::PixelFormat> OSystem_Wii::getSupportedFormats() { + Common::List<Graphics::PixelFormat> res; + res.push_back(_texturePF); + res.push_back(Graphics::PixelFormat::createFormatCLUT8()); + + return res; +} +#endif + +void OSystem_Wii::initSize(uint width, uint height, + const Graphics::PixelFormat *format) { + bool update = false; + +#ifdef USE_RGB_COLOR + Graphics::PixelFormat newFormat; + if (format) + newFormat = *format; + else + newFormat = Graphics::PixelFormat::createFormatCLUT8(); + if (newFormat.bytesPerPixel > 2) + newFormat = Graphics::PixelFormat::createFormatCLUT8(); + + if (_screenPF != newFormat) { + _screenPF = newFormat; + update = true; + } +#endif + + if (_gameWidth != width || _gameHeight != height) { assert((width <= 640) && (height <= 480)); _gameWidth = width; _gameHeight = height; + update = true; + } + + if (update) { +#ifdef USE_RGB_COLOR + printf("initSize %u*%u*%u (%u,%u,%u)\n", + _gameWidth, _gameHeight, + _screenPF.bytesPerPixel * 8, + _screenPF.rShift, _screenPF.gShift, _screenPF.bShift); +#else + printf("initSize %u*%u\n", _gameWidth, _gameHeight); +#endif if(_gamePixels) free(_gamePixels); +#ifdef USE_RGB_COLOR + _gamePixels = (u8 *) memalign(32, _gameWidth * _gameHeight * + _screenPF.bytesPerPixel); + memset(_gamePixels, 0, _gameWidth * _gameHeight * + _screenPF.bytesPerPixel); +#else _gamePixels = (u8 *) memalign(32, _gameWidth * _gameHeight); memset(_gamePixels, 0, _gameWidth * _gameHeight); - +#endif if (!_overlayVisible) { _currentWidth = _gameWidth; _currentHeight = _gameHeight; @@ -177,6 +228,10 @@ int16 OSystem_Wii::getHeight() { } void OSystem_Wii::setPalette(const byte *colors, uint start, uint num) { +#ifdef USE_RGB_COLOR + assert(_screenPF.bytesPerPixel == 1); +#endif + const byte *p = colors; for (uint i = 0; i < num; ++i) { _palette[start + i] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(p[0], p[1], p[2]); @@ -213,37 +268,36 @@ void OSystem_Wii::disableCursorPalette(bool disable) { void OSystem_Wii::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) { - if (x < 0) { - w += x; - buf -= x; - x = 0; - } - - if (y < 0) { - h += y; - buf -= y * pitch; - y = 0; - } - - if (w > _gameWidth - x) - w = _gameWidth - x; - - if (h > _gameHeight - y) - h = _gameHeight - y; - - if (w <= 0 || h <= 0) - return; - - byte *dst = _gamePixels + y * _gameWidth + x; - if (_gameWidth == pitch && pitch == w) { - memcpy(dst, buf, h * w); + assert(x >= 0 && x < _gameWidth); + assert(y >= 0 && y < _gameHeight); + assert(w > 0 && x + w <= _gameWidth); + assert(h > 0 && y + h <= _gameHeight); + +#ifdef USE_RGB_COLOR + if (_screenPF.bytesPerPixel > 1) { + if (!Graphics::crossBlit(_gamePixels + + y * _gameWidth * _screenPF.bytesPerPixel + + x * _screenPF.bytesPerPixel, + buf, _gameWidth * _screenPF.bytesPerPixel, + pitch, w, h, _texturePF, _screenPF)) { + printf("crossBlit failed\n"); + ::abort(); + } } else { - do { - memcpy(dst, buf, w); - buf += pitch; - dst += _gameWidth; - } while (--h); +#endif + byte *dst = _gamePixels + y * _gameWidth + x; + if (_gameWidth == pitch && pitch == w) { + memcpy(dst, buf, h * w); + } else { + do { + memcpy(dst, buf, w); + buf += pitch; + dst += _gameWidth; + } while (--h); + } +#ifdef USE_RGB_COLOR } +#endif } void OSystem_Wii::updateScreen() { @@ -251,6 +305,9 @@ void OSystem_Wii::updateScreen() { static s16 msx, msy, mox, moy, mskip; static u16 mpx, mpy; static u8 *s; +#ifdef USE_RGB_COLOR + static u16 *s2; +#endif static u16 *d, *p; u32 now = getMillis(); @@ -267,12 +324,21 @@ void OSystem_Wii::updateScreen() { if (_overlayVisible) { memcpy(_texture, _overlayPixels, _overlaySize); } else { - for (y = 0; y < _gameHeight; ++y) { - for (x = 0; x < _gameWidth; ++x) - _texture[h + x] = _palette[_gamePixels[h + x]]; +#ifdef USE_RGB_COLOR + if (_screenPF.bytesPerPixel > 1) { + memcpy(_texture, _gamePixels, + _gameWidth * _gameHeight * _screenPF.bytesPerPixel); + } else { +#endif + for (y = 0; y < _gameHeight; ++y) { + for (x = 0; x < _gameWidth; ++x) + _texture[h + x] = _palette[_gamePixels[h + x]]; - h += _gameWidth; + h += _gameWidth; + } +#ifdef USE_RGB_COLOR } +#endif } if (_mouseVisible) { @@ -308,25 +374,51 @@ void OSystem_Wii::updateScreen() { skip = _currentWidth - mpx; mskip = _mouseWidth - mpx; - s = _mouseCursor + moy * _mouseWidth + mox; - d = _texture + (msy * _currentWidth + msx); +#ifdef USE_RGB_COLOR + if (_cursorPF.bytesPerPixel > 1) { + s2 = (u16 *) _mouseCursor + moy * _mouseWidth + mox; + d = _texture + (msy * _currentWidth + msx); - for (y = 0; y < mpy; ++y) { - for (x = 0; x < mpx; ++x) { - if (*s == _mouseKeyColor) { - s++; - d++; + for (y = 0; y < mpy; ++y) { + for (x = 0; x < mpx; ++x) { + if (*s2 == _mouseKeyColor) { + s2++; + d++; - continue; + continue; + } + + *d++ = *s2; + s2++; } - *d++ = p[*s]; - s++; + d += skip; + s2 += mskip; } + } else { +#endif + s = _mouseCursor + moy * _mouseWidth + mox; + d = _texture + (msy * _currentWidth + msx); + + for (y = 0; y < mpy; ++y) { + for (x = 0; x < mpx; ++x) { + if (*s == _mouseKeyColor) { + s++; + d++; + + continue; + } - d += skip; - s += mskip; + *d++ = p[*s]; + s++; + } + + d += skip; + s += mskip; + } +#ifdef USE_RGB_COLOR } +#endif } GX_Render(_currentWidth, _currentHeight, (u8 *) _texture, @@ -338,7 +430,11 @@ Graphics::Surface *OSystem_Wii::lockScreen() { _surface.w = _gameWidth; _surface.h = _gameHeight; _surface.pitch = _gameWidth; +#ifdef USE_RGB_COLOR + _surface.bytesPerPixel = _screenPF.bytesPerPixel; +#else _surface.bytesPerPixel = 1; +#endif return &_surface; } @@ -429,6 +525,10 @@ int16 OSystem_Wii::getOverlayHeight() { return _overlayHeight; } +Graphics::PixelFormat OSystem_Wii::getOverlayFormat() const { + return Graphics::createPixelFormat<565>(); +} + bool OSystem_Wii::showMouse(bool visible) { bool last = _mouseVisible; _mouseVisible = visible; @@ -442,20 +542,37 @@ void OSystem_Wii::warpMouse(int x, int y) { } void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, - int hotspotY, byte keycolor, - int cursorTargetScale) { + int hotspotY, uint32 keycolor, + int cursorTargetScale, + const Graphics::PixelFormat *format) { (void) cursorTargetScale; // TODO +#ifdef USE_RGB_COLOR + if (!format) + _cursorPF = Graphics::PixelFormat::createFormatCLUT8(); + else + _cursorPF = *format; + + if (_cursorPF.bytesPerPixel > 1) + _mouseKeyColor = keycolor & 0xffff; + else +#endif + _mouseKeyColor = keycolor & 0xff; + _mouseWidth = w; _mouseHeight = h; _mouseHotspotX = hotspotX; _mouseHotspotY = hotspotY; - _mouseKeyColor = keycolor; if (_mouseCursor) free(_mouseCursor); +#ifdef USE_RGB_COLOR + _mouseCursor = (u8 *) memalign(32, w * h * _cursorPF.bytesPerPixel); + memcpy(_mouseCursor, buf, w * h * _cursorPF.bytesPerPixel); +#else _mouseCursor = (u8 *) memalign(32, w * h); memcpy(_mouseCursor, buf, w * h); +#endif } diff --git a/backends/platform/wince/CEScaler.cpp b/backends/platform/wince/CEScaler.cpp index d26db3190f..0a71fda167 100644 --- a/backends/platform/wince/CEScaler.cpp +++ b/backends/platform/wince/CEScaler.cpp @@ -27,25 +27,25 @@ template<int bitFormat> void PocketPCPortraitTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { - uint8 *work; - int i; + uint16 *work; + // Various casts below go via (void *) to avoid warning. This is + // safe as these are all even addresses. while (height--) { - i = 0; - work = dstPtr; + work = (uint16 *)(void *)dstPtr; for (int i=0; i<width; i+=4) { // Work with 4 pixels - uint16 color1 = *(((const uint16 *)srcPtr) + i); - uint16 color2 = *(((const uint16 *)srcPtr) + (i + 1)); - uint16 color3 = *(((const uint16 *)srcPtr) + (i + 2)); - uint16 color4 = *(((const uint16 *)srcPtr) + (i + 3)); + uint16 color1 = *(((const uint16 *)(const void *)srcPtr) + i); + uint16 color2 = *(((const uint16 *)(const void *)srcPtr) + (i + 1)); + uint16 color3 = *(((const uint16 *)(const void *)srcPtr) + (i + 2)); + uint16 color4 = *(((const uint16 *)(const void *)srcPtr) + (i + 3)); - *(((uint16 *)work) + 0) = interpolate32_3_1<bitFormat>(color1, color2); - *(((uint16 *)work) + 1) = interpolate32_1_1<bitFormat>(color2, color3); - *(((uint16 *)work) + 2) = interpolate32_3_1<bitFormat>(color4, color3); + work[0] = interpolate32_3_1<bitFormat>(color1, color2); + work[1] = interpolate32_1_1<bitFormat>(color2, color3); + work[2] = interpolate32_3_1<bitFormat>(color4, color3); - work += 3 * sizeof(uint16); + work += 3; } srcPtr += srcPitch; dstPtr += dstPitch; @@ -65,7 +65,8 @@ void PocketPCLandscapeAspect(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr int i,j; unsigned int p1, p2; - uint8 *inbuf, *outbuf, *instart, *outstart; + const uint8 *inbuf, *instart; + uint8 *outbuf, *outstart; #define RB(x) ((x & RBM)<<8) #define G(x) ((x & GM)<<3) @@ -77,34 +78,36 @@ void PocketPCLandscapeAspect(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr #define MAKEPIXEL(rb,g) ((((rb)>>8) & RBM | ((g)>>3) & GM)) - inbuf = (uint8 *)srcPtr; + inbuf = (const uint8 *)srcPtr; outbuf = (uint8 *)dstPtr; height /= 5; + // Various casts below go via (void *) to avoid warning. This is + // safe as these are all even addresses. for (i = 0; i < height; i++) { instart = inbuf; outstart = outbuf; for (j=0; j < width; j++) { - p1 = *(uint16*)inbuf; inbuf += srcPitch; - *(uint16*)outbuf = p1; outbuf += dstPitch; + p1 = *(const uint16*)(const void *)inbuf; inbuf += srcPitch; + *(uint16*)(void *)outbuf = p1; outbuf += dstPitch; - p2 = *(uint16*)inbuf; inbuf += srcPitch; - *(uint16*)outbuf = MAKEPIXEL(P20(RB(p1))+P80(RB(p2)),P20(G(p1))+P80(G(p2))); outbuf += dstPitch; + p2 = *(const uint16*)(const void *)inbuf; inbuf += srcPitch; + *(uint16*)(void *)outbuf = MAKEPIXEL(P20(RB(p1))+P80(RB(p2)),P20(G(p1))+P80(G(p2))); outbuf += dstPitch; p1 = p2; - p2 = *(uint16*)inbuf; inbuf += srcPitch; - *(uint16*)outbuf = MAKEPIXEL(P40(RB(p1))+P60(RB(p2)),P40(G(p1))+P60(G(p2))); outbuf += dstPitch; + p2 = *(const uint16*)(const void *)inbuf; inbuf += srcPitch; + *(uint16*)(void *)outbuf = MAKEPIXEL(P40(RB(p1))+P60(RB(p2)),P40(G(p1))+P60(G(p2))); outbuf += dstPitch; p1 = p2; - p2 = *(uint16*)inbuf; inbuf += srcPitch; - *(uint16*)outbuf = MAKEPIXEL(P60(RB(p1))+P40(RB(p2)),P60(G(p1))+P40(G(p2))); outbuf += dstPitch; + p2 = *(const uint16*)(const void *)inbuf; inbuf += srcPitch; + *(uint16*)(void *)outbuf = MAKEPIXEL(P60(RB(p1))+P40(RB(p2)),P60(G(p1))+P40(G(p2))); outbuf += dstPitch; p1 = p2; - p2 = *(uint16*)inbuf; - *(uint16*)outbuf = MAKEPIXEL(P80(RB(p1))+P20(RB(p2)),P80(G(p1))+P20(G(p2))); outbuf += dstPitch; + p2 = *(const uint16*)(const void *)inbuf; + *(uint16*)(void *)outbuf = MAKEPIXEL(P80(RB(p1))+P20(RB(p2)),P80(G(p1))+P20(G(p2))); outbuf += dstPitch; - *(uint16*)outbuf = p2; + *(uint16*)(void *)outbuf = p2; inbuf = inbuf - srcPitch*4 + sizeof(uint16); outbuf = outbuf - dstPitch*5 + sizeof(uint16); @@ -127,11 +130,9 @@ extern "C" { template<int bitFormat> void PocketPCHalfTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint8 *work; - int i; uint16 srcPitch16 = (uint16)(srcPitch / sizeof(uint16)); while ((height -= 2) >= 0) { - i = 0; work = dstPtr; for (int i=0; i<width; i+=2) { @@ -163,23 +164,20 @@ void PocketPCHalf(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 ds template<int bitFormat> void PocketPCHalfZoomTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { - uint8 *work; - int i; - uint16 srcPitch16 = (uint16)(srcPitch / sizeof(uint16)); + uint16 *work; if (!height) return; + // Various casts below go via (void *) to avoid warning. This is + // safe as these are all even addresses. while (height--) { - i = 0; - work = dstPtr; + work = (uint16 *)(void *)dstPtr; for (int i = 0; i < width; i += 2) { - uint16 color1 = *(((const uint16 *)srcPtr) + i); - uint16 color2 = *(((const uint16 *)srcPtr) + (i + 1)); - *(((uint16 *)work) + 0) = interpolate32_1_1<bitFormat>(color1, color2); - - work += sizeof(uint16); + uint16 color1 = *(((const uint16 *)(const void *)srcPtr) + i); + uint16 color2 = *(((const uint16 *)(const void *)srcPtr) + (i + 1)); + *work++ = interpolate32_1_1<bitFormat>(color1, color2); } srcPtr += srcPitch; dstPtr += dstPitch; @@ -190,11 +188,9 @@ MAKE_WRAPPER(PocketPCHalfZoom) template<int bitFormat> void SmartphoneLandscapeTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint8 *work; - int i; int line = 0; while (height--) { - i = 0; work = dstPtr; for (int i = 0; i < width; i += 3) { diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp index 65082014da..ab7860dd85 100644 --- a/backends/platform/wince/wince-sdl.cpp +++ b/backends/platform/wince/wince-sdl.cpp @@ -1084,7 +1084,7 @@ void OSystem_WINCE3::update_game_settings() { _noDoubleTapRMB = ConfMan.getBool("no_doubletap_rightclick"); } -void OSystem_WINCE3::initSize(uint w, uint h) { +void OSystem_WINCE3::initSize(uint w, uint h, const Graphics::PixelFormat *format) { if (_hasSmartphoneResolution && h == 240) h = 200; // mainly for the launcher @@ -1120,7 +1120,7 @@ void OSystem_WINCE3::initSize(uint w, uint h) { _videoMode.overlayWidth = w; _videoMode.overlayHeight = h; - OSystem_SDL::initSize(w, h); + OSystem_SDL::initSize(w, h, format); if (_scalersChanged) { unloadGFXMode(); diff --git a/backends/platform/wince/wince-sdl.h b/backends/platform/wince/wince-sdl.h index deafde6d80..7b4d0f2b25 100644 --- a/backends/platform/wince/wince-sdl.h +++ b/backends/platform/wince/wince-sdl.h @@ -66,7 +66,7 @@ public: void internUpdateScreen(); void setGraphicsModeIntern(); - void initSize(uint w, uint h); + void initSize(uint w, uint h, const Graphics::PixelFormat *format); void initBackend(); // Overloaded from SDL backend (toolbar handling) diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp index bd2222bbbc..dd468bbe09 100644 --- a/backends/timer/default/default-timer.cpp +++ b/backends/timer/default/default-timer.cpp @@ -124,6 +124,12 @@ bool DefaultTimerManager::installTimerProc(TimerProc callback, int32 interval, v slot->nextFireTimeMicro = interval % 1000; slot->next = 0; + // FIXME: It seems we do allow the client to add one callback multiple times over here, + // but "removeTimerProc" will remove *all* added instances. We should either prevent + // multiple additions of a timer proc OR we should change removeTimerProc to only remove + // a specific timer proc entry. + // Probably we can safely just allow a single addition of a specific function once + // and just update our Timer documentation accordingly. insertPrioQueue(_head, slot); return true; diff --git a/base/main.cpp b/base/main.cpp index d108512416..03db00a1d9 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -45,9 +45,12 @@ #include "common/file.h" #include "common/fs.h" #include "common/system.h" + #include "gui/GuiManager.h" #include "gui/message.h" +#include "sound/audiocd.h" + #include "backends/keymapper/keymapper.h" #if defined(_WIN32_WCE) @@ -416,6 +419,15 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { warning("Could not find any engine capable of running the selected game"); } + // We will destroy the AudioCDManager singleton here to save some memory. + // This will not make the CD audio stop, one would have to enable this: + //AudioCD.stop(); + // but the engine is responsible for stopping CD playback anyway and + // this way we catch engines not doing it properly. For some more + // information about why AudioCDManager::destroy does not stop the CD + // playback read the FIXME in sound/audiocd.h + Audio::AudioCDManager::destroy(); + // reset the graphics to default setupGraphics(system); launcherDialog(); diff --git a/base/version.cpp b/base/version.cpp index eabafecc30..ad74c64265 100644 --- a/base/version.cpp +++ b/base/version.cpp @@ -86,6 +86,10 @@ const char *gScummVMFeatures = "" "ALSA " #endif +#ifdef USE_RGB_COLOR + "RGB " +#endif + #ifdef USE_ZLIB "zLib " #endif diff --git a/common/EventRecorder.cpp b/common/EventRecorder.cpp index 3d5eee3e52..57ab475f4a 100644 --- a/common/EventRecorder.cpp +++ b/common/EventRecorder.cpp @@ -100,6 +100,7 @@ EventRecorder::EventRecorder() { _lastEventCount = 0; _lastMillis = 0; + _recordMode = kPassthrough; } EventRecorder::~EventRecorder() { diff --git a/common/error.h b/common/error.h index 23305a5c2e..d91ce2971a 100644 --- a/common/error.h +++ b/common/error.h @@ -48,6 +48,7 @@ enum Error { kInvalidPathError, //!< Engine initialization: Invalid game path was passed kNoGameDataFoundError, //!< Engine initialization: No game data was found in the specified location kUnsupportedGameidError, //!< Engine initialization: Gameid not supported by this (Meta)Engine + kUnsupportedColorMode, //!< Engine initialization: Engine does not support backend's color mode kReadPermissionDenied, //!< Unable to read data due to missing read permission diff --git a/common/system.h b/common/system.h index 5c91296ab1..f4704f5e0e 100644 --- a/common/system.h +++ b/common/system.h @@ -31,6 +31,9 @@ #include "common/rect.h" #include "graphics/pixelformat.h" +#ifdef USE_RGB_COLOR +#include "graphics/conversion.h" +#endif namespace Audio { class Mixer; @@ -347,8 +350,52 @@ public: */ virtual int getGraphicsMode() const = 0; +#ifdef USE_RGB_COLOR + /** + * Determine the pixel format currently in use for screen rendering. + * @return the active screen pixel format. + * @see Graphics::PixelFormat + */ + virtual Graphics::PixelFormat getScreenFormat() const = 0; + /** - * Set the size of the virtual screen. Typical sizes include: + * Returns a list of all pixel formats supported by the backend. + * The first item in the list must be directly supported by hardware, + * and provide the largest color space of those formats with direct + * hardware support. It is also strongly recommended that remaining + * formats should be placed in order of descending preference for the + * backend to use. + * + * EG: a backend that supports 32-bit ABGR and 16-bit 555 BGR in hardware + * and provides conversion from equivalent RGB(A) modes should order its list + * 1) Graphics::PixelFormat(4, 0, 0, 0, 0, 0, 8, 16, 24) + * 2) Graphics::PixelFormat(2, 3, 3, 3, 8, 0, 5, 10, 0) + * 3) Graphics::PixelFormat(4, 0, 0, 0, 0, 24, 16, 8, 0) + * 4) Graphics::PixelFormat(2, 3, 3, 3, 8, 10, 5, 0, 0) + * 5) Graphics::PixelFormat::createFormatCLUT8() + * + * @see Graphics::PixelFormat + * + * @note Backends supporting RGB color should accept game data in RGB color + * order, even if hardware uses BGR or some other color order. + * + * @see convertScreenRect + */ + virtual Common::List<Graphics::PixelFormat> getSupportedFormats() = 0; +#else + inline Graphics::PixelFormat getScreenFormat() const { + return Graphics::PixelFormat::createFormatCLUT8(); + }; + + inline Common::List<Graphics::PixelFormat> getSupportedFormats() const { + Common::List<Graphics::PixelFormat> list; + list.push_back(Graphics::PixelFormat::createFormatCLUT8()); + return list; + }; +#endif + + /** + * Set the size and color format of the virtual screen. Typical sizes include: * - 320x200 (e.g. for most SCUMM games, and Simon) * - 320x240 (e.g. for FM-TOWN SCUMM games) * - 640x480 (e.g. for Curse of Monkey Island) @@ -359,10 +406,21 @@ public: * GraphicsMode); stretch the data to perform aspect ratio correction; * or shrink it to fit on small screens (in cell phones). * + * Typical formats include: + * CLUT8 (e.g. 256 color, for most games) + * RGB555 (e.g. 16-bit color, for later SCUMM HE games) + * RGB565 (e.g. 16-bit color, for Urban Runner) + * + * This is the pixel format for which the client code generates data; + * this is not necessarily equal to the hardware pixel format. For example, + * a backend may perform color lookup of 8-bit graphics before pushing + * a screen to hardware, or correct the ARGB color order via convertScreenRect. + * * @param width the new virtual screen width * @param height the new virtual screen height + * @param format the new virtual screen pixel format */ - virtual void initSize(uint width, uint height) = 0; + virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) = 0; /** * Return an int value which is changed whenever any screen @@ -411,7 +469,8 @@ public: kTransactionAspectRatioFailed = (1 << 0), /**< Failed switching aspect ratio correction mode */ kTransactionFullscreenFailed = (1 << 1), /**< Failed switching fullscreen mode */ kTransactionModeSwitchFailed = (1 << 2), /**< Failed switching the GFX graphics mode (setGraphicsMode) */ - kTransactionSizeChangeFailed = (1 << 3) /**< Failed switching the screen dimensions (initSize) */ + kTransactionSizeChangeFailed = (1 << 3), /**< Failed switching the screen dimensions (initSize) */ + kTransactionFormatNotSupported = (1 << 4) /**< Failed setting the color format */ }; /** @@ -705,8 +764,9 @@ public: * @param hotspotY vertical offset from the top side to the hotspot * @param keycolor transparency color index * @param cursorTargetScale scale factor which cursor is designed for + * @param format pointer to the pixel format which cursor graphic uses */ - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1) = 0; + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0; /** * Replace the specified range of cursor the palette with new colors. @@ -29,6 +29,7 @@ SAVED_LDFLAGS=$LDFLAGS SAVED_CXX=$CXX SAVED_CXXFLAGS=$CXXFLAGS SAVED_CPPFLAGS=$CPPFLAGS +SAVED_ASFLAGS=$ASFLAGS # Use environment vars if set CXXFLAGS="$CXXFLAGS $CPPFLAGS" @@ -110,6 +111,7 @@ _alsa=auto _zlib=auto _mpeg2=no _fluidsynth=auto +_16bit=auto _readline=auto # Default option behaviour yes/no _text_console=no @@ -124,6 +126,7 @@ _backend=sdl _endian=unknown _need_memalign=no _have_x86=no +_verbose_build=no _dynamic_modules=no _plugins_default=static _nasm=auto @@ -131,6 +134,7 @@ _nasm=auto _ranlib=ranlib _strip=strip _ar="ar cru" +_as="as" _windres=windres _win32path="C:/scummvm" _aos4path="Games:ScummVM" @@ -553,7 +557,7 @@ Usage: $0 [OPTIONS]... Configuration: -h, --help display this help and exit - --backend=BACKEND backend to build (sdl, dc, gp2x, gp2xwiz, iphone, morphos, nds, psp, wii, wince, null) [sdl] + --backend=BACKEND backend to build (sdl, dc, gp2x, gp2xwiz, iphone, morphos, nds, psp, wii, wince, linuxmoto, null) [sdl] Installation directories: --prefix=DIR use this prefix for installing ScummVM [/usr/local] @@ -582,9 +586,11 @@ $engines_help --enable-plugins enable the support for dynamic plugins --default-dynamic make plugins dynamic by default --disable-mt32emu don't enable the integrated MT-32 emulator + --disable-16bit don't enable 16bit color support --disable-hq-scalers exclude HQ2x and HQ3x scalers --disable-scalers exclude scalers --enable-text-console use text console instead of graphical console + --enable-verbose-build enable regular echoing of commands during build process Optional Libraries: --with-alsa-prefix=DIR Prefix where alsa is installed (optional) @@ -627,6 +633,7 @@ Some influential environment variables: CXXFLAGS C++ compiler flags CPPFLAGS C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> + ASFLAGS assembler flags EOF exit 0 @@ -637,6 +644,7 @@ DEBFLAGS="-g" for ac_option in $@; do case "$ac_option" in + --disable-16bit) _16bit=no ;; --disable-hq-scalers) _build_hq_scalers=no ;; --disable-scalers) _build_scalers=no ;; --enable-alsa) _alsa=yes ;; @@ -657,6 +665,7 @@ for ac_option in $@; do --disable-fluidsynth) _fluidsynth=no ;; --enable-readline) _readline=yes ;; --disable-readline) _readline=no ;; + --enable-verbose-build) _verbose_build=yes ;; --enable-plugins) _dynamic_modules=yes ;; --default-dynamic) _plugins_default=dynamic ;; --enable-mt32emu) _mt32emu=yes ;; @@ -794,6 +803,16 @@ linupy) _host_os=linux _host_cpu=arm ;; +motoezx) + _host_os=linux + _host_cpu=arm + _host_alias=arm-linux-gnu + ;; +motomagx) + _host_os=linux + _host_cpu=arm + _host_alias=arm-linux-gnueabi + ;; arm-riscos) _host_os=riscos _host_cpu=arm @@ -870,6 +889,13 @@ esac if test -z "$_host_alias"; then _host_alias="$_host_cpu-$_host_os" +else + # if _host_alias was set, default to the standard GNU tools + _ranlib=$_host_alias-ranlib + _strip=$_host_alias-strip + _ar="$_host_alias-ar cru" + _as="$_host_alias-as" + _windres=$_host_alias-windres fi # @@ -1178,7 +1204,7 @@ case $_host_os in # TODO nds ;; psp) - CXXFLAGS="$CXXFLAGS -O2 -G0 -I$PSPDEV/psp/sdk/include -D_PSP_FW_VERSION=150" + CXXFLAGS="$CXXFLAGS -O3 -G0 -I$PSPDEV/psp/sdk/include -D_PSP_FW_VERSION=150" ;; wince) CXXFLAGS="$CXXFLAGS -O3 -march=armv4 -mtune=xscale -D_WIN32_WCE=300 -D__ARM__ -D_ARM_ -DUNICODE -DFPM_DEFAULT -DNONSTANDARD_PORT" @@ -1216,6 +1242,34 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' ;; + motoezx) + echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes" + DEFINES="$DEFINES -DUNIX -DMOTOEZX -DUSE_ARM_SMUSH_ASM" + #not true for all ARM systems, but the interesting ones are all LE. Most (if not all) BE arm devices don't have a screen + ASFLAGS="$ASFLAGS -mfpu=vfp" + _endian=little + _need_memalign=yes + type_1_byte='char' + type_2_byte='short' + type_4_byte='int' + add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' + add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' + _backend="linuxmoto" + ;; + motomagx) + echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes" + DEFINES="$DEFINES -DUNIX -DMOTOMAGX -DUSE_ARM_SMUSH_ASM" + #not true for all ARM systems, but the interesting ones are all LE. Most (if not all) BE arm devices don't have a screen + ASFLAGS="$ASFLAGS -mfpu=vfp" + _endian=little + _need_memalign=yes + type_1_byte='char' + type_2_byte='short' + type_4_byte='int' + add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' + add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' + _backend="linuxmoto" + ;; bfin*) _need_memalign=yes ;; @@ -1233,8 +1287,6 @@ if test -n "$_host"; then type_1_byte='char' type_2_byte='short' type_4_byte='int' - _ar="$_host_alias-ar cru" - _ranlib=$_host_alias-ranlib add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' @@ -1248,14 +1300,13 @@ if test -n "$_host"; then echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes" DEFINES="$DEFINES -DUNIX -DGP2X -DNDEBUG -DUSE_ARM_SMUSH_ASM -DUSE_ARM_GFX_ASM -DUSE_ARM_SCALER_ASM -DUSE_ARM_COSTUME_ASM" CXXFLAGS="$CXXFLAGS -march=armv4t" + ASFLAGS="$ASFLAGS -mfloat-abi=soft" LDFLAGS="$LDFLAGS -static" _endian=little _need_memalign=yes type_1_byte='char' type_2_byte='short' type_4_byte='int' - _ar="$_host_alias-ar cru" - _ranlib=$_host_alias-ranlib add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' @@ -1320,9 +1371,6 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' _backend="iphone" _build_hq_scalers="no" - _ar="$_host_alias-ar cru" - _ranlib=$_host_alias-ranlib - _strip=$_host_alias-strip ;; wince) echo "Cross-compiling to $_host, forcing endianness, alignment and type sizes" @@ -1339,10 +1387,6 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' _backend="wince" - _ar="$_host_alias-ar cru" - _ranlib=$_host_alias-ranlib - _strip=$_host_alias-strip - _windres=$_host_alias-windres _mt32emu="no" add_line_to_config_mk 'include $(srcdir)/backends/platform/wince/wince.mk' ;; @@ -1360,8 +1404,6 @@ if test -n "$_host"; then _build_hq_scalers="no" _mad="yes" _zlib="yes" - _ar="$_host_alias-ar cru" - _ranlib=$_host_alias-ranlib add_line_to_config_mk 'include $(srcdir)/backends/platform/dc/dreamcast.mk' ;; wii) @@ -1371,9 +1413,6 @@ if test -n "$_host"; then type_1_byte='char' type_2_byte='short' type_4_byte='int' - _ar="$_host_alias-ar cru" - _ranlib=$_host_alias-ranlib - _strip=$_host_alias-strip _backend="wii" _build_hq_scalers="no" add_line_to_config_mk 'GAMECUBE = 0' @@ -1391,9 +1430,6 @@ if test -n "$_host"; then type_1_byte='char' type_2_byte='short' type_4_byte='int' - _ar="$_host_alias-ar cru" - _ranlib=$_host_alias-ranlib - _strip=$_host_alias-strip _backend="wii" _build_hq_scalers="no" _mt32emu="no" @@ -1429,9 +1465,6 @@ if test -n "$_host"; then type_1_byte='char' type_2_byte='short' type_4_byte='int' - _ar="$_host_alias-ar cru" - _ranlib=$_host_alias-ranlib - _strip=$_host_alias-strip _backend="psp" _build_scalers="no" _build_hq_scalers="no" @@ -1492,6 +1525,23 @@ EOF fi # +# Enable 16bit support only for backends which support it +# +case $_backend in + sdl | wii) + if test "$_16bit" = auto ; then + _16bit=yes + else + _16bit=no + fi + ;; + *) + _16bit=no + ;; +esac + + +# # Add the results of the above checks to config.h # case $_endian in @@ -1512,6 +1562,12 @@ add_to_config_h_if_yes $_have_x86 '#define HAVE_X86' add_to_config_h_if_yes $_need_memalign '#define SCUMM_NEED_ALIGNMENT' +# +# Check whether to enable a verbose build +# +echo_n "Checking whether to have a verbose build... " +echo "$_verbose_build" +add_to_config_mk_if_yes "$_verbose_build" 'VERBOSE_BUILD = 1' # # Check whether plugin support is requested and possible @@ -1647,6 +1703,16 @@ fi add_to_config_mk_if_yes "$_mt32emu" 'USE_MT32EMU = 1' # +# Check whether 16bit color support is requested +# +if test "$_16bit" = no ; then + _def_16bit='#undef USE_RGB_COLOR' +else + _def_16bit='#define USE_RGB_COLOR' +fi +add_to_config_mk_if_yes "$_16bit" 'USE_RGB_COLOR = 1' + +# # Check whether to enable the (hq) scalers # add_to_config_mk_if_no $_build_hq_scalers 'DISABLE_HQ_SCALERS = 1' @@ -1996,6 +2062,10 @@ if test "$_nasm" = yes ; then echo_n ", assembly routines" fi +if test "$_16bit" = yes ; then + echo_n ", 16bit color" +fi + if test "$_build_hq_scalers" = yes ; then echo_n ", HQ scalers" fi @@ -2031,6 +2101,12 @@ case $_backend in LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`" DEFINES="$DEFINES -DSDL_BACKEND" ;; + linuxmoto) + find_sdlconfig + INCLUDES="$INCLUDES `$_sdlconfig --prefix="$_sdlpath" --cflags`" + LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`" + DEFINES="$DEFINES -DSDL_BACKEND -DLINUXMOTO" + ;; gp2x) find_sdlconfig INCLUDES="$INCLUDES `$_sdlconfig --prefix="$_sdlpath" --cflags`" @@ -2073,7 +2149,7 @@ case $_backend in # TODO nds ;; psp) - DEFINES="$DEFINES -D__PSP__ -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE" + DEFINES="$DEFINES -D__PSP__ -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DDISABLE_DOSBOX_OPL" INCLUDES="$INCLUDES -I$PSPDEV/psp/include/SDL" LIBS="$LIBS -lSDL" ;; @@ -2231,6 +2307,7 @@ $_def_readline /* Options */ $_def_text_console $_def_mt32emu +$_def_16bit /* Plugin settings */ $_def_plugin @@ -2248,6 +2325,8 @@ LIBS += $LIBS RANLIB := $_ranlib STRIP := $_strip AR := $_ar +AS := $_as +ASFLAGS := $ASFLAGS WINDRES := $_windres WIN32PATH=$_win32path AOS4PATH=$_aos4path @@ -2280,6 +2359,7 @@ SAVED_LDFLAGS := $SAVED_LDFLAGS SAVED_CXX := $SAVED_CXX SAVED_CXXFLAGS := $SAVED_CXXFLAGS SAVED_CPPFLAGS := $SAVED_CPPFLAGS +SAVED_ASFLAGS := $SAVED_ASFLAGS EOF # diff --git a/dists/motoezx/scummvm-sm.png b/dists/motoezx/scummvm-sm.png Binary files differnew file mode 100644 index 0000000000..e6341243c4 --- /dev/null +++ b/dists/motoezx/scummvm-sm.png diff --git a/dists/motoezx/scummvm.desktop b/dists/motoezx/scummvm.desktop new file mode 100644 index 0000000000..ddd8ad7f57 --- /dev/null +++ b/dists/motoezx/scummvm.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +BigIcon=scummvm.png +Comment=ScummVM +Exec=scummvm.lin +Icon=scummvm-sm.png +Name=ScummVM +OsVersion=0.1 +Shared=0 +Type=Application diff --git a/dists/motoezx/scummvm.lin b/dists/motoezx/scummvm.lin new file mode 100644 index 0000000000..a3c6f3831b --- /dev/null +++ b/dists/motoezx/scummvm.lin @@ -0,0 +1,10 @@ +#!/bin/sh +. /home/native/.profile +myfile=`basename $0` +mypath=`echo $0 | sed -e 's/'$myfile'//g'` +export LD_LIBRARY_PATH=/mmc/mmca1/games/lib:$LD_LIBRARY_PATH +#export SDL_QT_INVERT_ROTATION=1 +export SDL_QT_MODIFICATOR=1 +export HOME=/mmc/mmca1/games +cd $mypath +exec $mypath/scummvm --path=/mmc/mmca1/games/data --gfx-mode=1x > /mmc/mmca1/games/logs/scummvm.log 2>&1 diff --git a/dists/motoezx/scummvm.png b/dists/motoezx/scummvm.png Binary files differnew file mode 100644 index 0000000000..4a0c65b544 --- /dev/null +++ b/dists/motoezx/scummvm.png diff --git a/dists/msvc8/ScummVM_Global.vsprops b/dists/msvc8/ScummVM_Global.vsprops index afcfab102b..1fafddbb46 100644 --- a/dists/msvc8/ScummVM_Global.vsprops +++ b/dists/msvc8/ScummVM_Global.vsprops @@ -10,7 +10,7 @@ Name="VCCLCompilerTool" DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996" AdditionalIncludeDirectories="../..;../../engines" - PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE" + PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;USE_RGB_COLOR;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE" ExceptionHandling="0" RuntimeTypeInfo="false" WarningLevel="4" diff --git a/dists/msvc8/groovie.vcproj b/dists/msvc8/groovie.vcproj index 5404803ae9..cc8f060b06 100644 --- a/dists/msvc8/groovie.vcproj +++ b/dists/msvc8/groovie.vcproj @@ -1,48 +1,244 @@ <?xml version="1.0" encoding="windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8,00" + Version="8.00" Name="groovie" ProjectGUID="{2C1EA540-0B09-11DD-BD00-000000000000}" RootNamespace="groovie" Keyword="Win32Proj" > <Platforms> - <Platform Name="Win32" /> + <Platform + Name="Win32" + /> </Platforms> + <ToolFiles> + </ToolFiles> <Configurations> - <Configuration Name="Debug|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Debug.vsprops" /> - <Configuration Name="Release|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Release.vsprops" /> + <Configuration + Name="Debug|Win32" + ConfigurationType="4" + InheritedPropertySheets=".\ScummVM_Debug.vsprops" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + PreprocessorDefinitions="GROOVIE_EXPERIMENTAL" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + ConfigurationType="4" + InheritedPropertySheets=".\ScummVM_Release.vsprops" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> </Configurations> + <References> + </References> <Files> - <File RelativePath="..\..\engines\groovie\cell.cpp" /> - <File RelativePath="..\..\engines\groovie\cell.h" /> - <File RelativePath="..\..\engines\groovie\cursor.cpp" /> - <File RelativePath="..\..\engines\groovie\cursor.h" /> - <File RelativePath="..\..\engines\groovie\debug.cpp" /> - <File RelativePath="..\..\engines\groovie\debug.h" /> - <File RelativePath="..\..\engines\groovie\detection.cpp" /> - <File RelativePath="..\..\engines\groovie\font.cpp" /> - <File RelativePath="..\..\engines\groovie\font.h" /> - <File RelativePath="..\..\engines\groovie\graphics.cpp" /> - <File RelativePath="..\..\engines\groovie\graphics.h" /> - <File RelativePath="..\..\engines\groovie\groovie.cpp" /> - <File RelativePath="..\..\engines\groovie\groovie.h" /> - <File RelativePath="..\..\engines\groovie\lzss.cpp" /> - <File RelativePath="..\..\engines\groovie\lzss.h" /> - <File RelativePath="..\..\engines\groovie\music.cpp" /> - <File RelativePath="..\..\engines\groovie\music.h" /> - <File RelativePath="..\..\engines\groovie\player.cpp" /> - <File RelativePath="..\..\engines\groovie\player.h" /> - <File RelativePath="..\..\engines\groovie\resource.cpp" /> - <File RelativePath="..\..\engines\groovie\resource.h" /> - <File RelativePath="..\..\engines\groovie\roq.cpp" /> - <File RelativePath="..\..\engines\groovie\roq.h" /> - <File RelativePath="..\..\engines\groovie\saveload.cpp" /> - <File RelativePath="..\..\engines\groovie\saveload.h" /> - <File RelativePath="..\..\engines\groovie\script.cpp" /> - <File RelativePath="..\..\engines\groovie\script.h" /> - <File RelativePath="..\..\engines\groovie\vdx.cpp" /> - <File RelativePath="..\..\engines\groovie\vdx.h" /> + <File + RelativePath="..\..\engines\groovie\cell.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\cell.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\cursor.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\cursor.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\debug.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\debug.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\detection.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\font.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\font.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\graphics.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\graphics.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\groovie.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\groovie.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\lzss.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\lzss.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\music.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\music.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\player.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\player.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\resource.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\resource.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\roq.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\roq.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\saveload.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\saveload.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\script.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\script.h" + > + </File> + <File + RelativePath="..\..\engines\groovie\vdx.cpp" + > + </File> + <File + RelativePath="..\..\engines\groovie\vdx.h" + > + </File> </Files> + <Globals> + </Globals> </VisualStudioProject> diff --git a/dists/msvc8/sci.vcproj b/dists/msvc8/sci.vcproj index 4a9862d7f6..47abc4f2ed 100644 --- a/dists/msvc8/sci.vcproj +++ b/dists/msvc8/sci.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8,00" + Version="8.00" Name="sci" ProjectGUID="{53F17B2B-0412-4EC3-A999-ED0537BB5223}" RootNamespace="sci" @@ -124,6 +124,7 @@ <File RelativePath="..\..\engines\sci\decompressor.cpp" /> <File RelativePath="..\..\engines\sci\decompressor.h" /> <File RelativePath="..\..\engines\sci\detection.cpp" /> + <File RelativePath="..\..\engines\sci\detection_tables.h" /> <File RelativePath="..\..\engines\sci\exereader.cpp" /> <File RelativePath="..\..\engines\sci\exereader.h" /> <File RelativePath="..\..\engines\sci\resource.cpp" /> diff --git a/dists/msvc8/scumm.vcproj b/dists/msvc8/scumm.vcproj index e71317ac16..e99fdae790 100644 --- a/dists/msvc8/scumm.vcproj +++ b/dists/msvc8/scumm.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8,00" + Version="8.00" Name="scumm" ProjectGUID="{B6AFD548-63D2-40CD-A652-E87095AFCBAF}" RootNamespace="scumm" diff --git a/dists/msvc8/scummvm.vcproj b/dists/msvc8/scummvm.vcproj index 27e37add0b..47555e36ff 100644 --- a/dists/msvc8/scummvm.vcproj +++ b/dists/msvc8/scummvm.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8,00" + Version="8.00" Name="scummvm" ProjectGUID="{8434CB15-D08F-427D-9E6D-581AE5B28440}" RootNamespace="scummvm" @@ -47,6 +47,9 @@ <File RelativePath="..\..\common\debug.h" /> <File RelativePath="..\..\common\endian.h" /> <File RelativePath="..\..\common\error.h" /> + <File RelativePath="..\..\common\EventDispatcher.cpp" /> + <File RelativePath="..\..\common\EventRecorder.cpp" /> + <File RelativePath="..\..\common\EventRecorder.h" /> <File RelativePath="..\..\common\events.h" /> <File RelativePath="..\..\common\file.cpp" /> <File RelativePath="..\..\common\file.h" /> @@ -347,6 +350,8 @@ </Filter> <Filter Name="graphics"> <File RelativePath="..\..\graphics\colormasks.h" /> + <File RelativePath="..\..\graphics\conversion.cpp" /> + <File RelativePath="..\..\graphics\conversion.h" /> <File RelativePath="..\..\graphics\cursorman.cpp" /> <File RelativePath="..\..\graphics\cursorman.h" /> <File RelativePath="..\..\graphics\dither.cpp" /> @@ -359,6 +364,8 @@ <File RelativePath="..\..\graphics\iff.h" /> <File RelativePath="..\..\graphics\imagedec.cpp" /> <File RelativePath="..\..\graphics\imagedec.h" /> + <File RelativePath="..\..\graphics\jpeg.cpp" /> + <File RelativePath="..\..\graphics\jpeg.h" /> <File RelativePath="..\..\graphics\pixelformat.h" /> <File RelativePath="..\..\graphics\primitives.cpp" /> <File RelativePath="..\..\graphics\primitives.h" /> diff --git a/dists/msvc9/ScummVM_Global.vsprops b/dists/msvc9/ScummVM_Global.vsprops index 2fe13f5cc4..1fafddbb46 100644 --- a/dists/msvc9/ScummVM_Global.vsprops +++ b/dists/msvc9/ScummVM_Global.vsprops @@ -8,14 +8,14 @@ > <Tool Name="VCCLCompilerTool" + DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996" AdditionalIncludeDirectories="../..;../../engines" - PreprocessorDefinitions="USE_NASM;USE_ZLIB;ENABLE_AGOS2;ENABLE_PN;ENABLE_KYRA;ENABLE_LOL;ENABLE_SCUMM;ENABLE_SCUMM_7_8;ENABLE_HE" + PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;USE_RGB_COLOR;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE" ExceptionHandling="0" RuntimeTypeInfo="false" WarningLevel="4" WarnAsError="true" CompileAs="0" - DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996" /> <Tool Name="VCLibrarianTool" diff --git a/dists/msvc9/sci.vcproj b/dists/msvc9/sci.vcproj index 1fe6c97ec8..c49cf03097 100644 --- a/dists/msvc9/sci.vcproj +++ b/dists/msvc9/sci.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="9,00" + Version="9.00" Name="sci" ProjectGUID="{53F17B2B-0412-4EC3-A999-ED0537BB5223}" RootNamespace="sci" @@ -125,6 +125,7 @@ <File RelativePath="..\..\engines\sci\decompressor.cpp" /> <File RelativePath="..\..\engines\sci\decompressor.h" /> <File RelativePath="..\..\engines\sci\detection.cpp" /> + <File RelativePath="..\..\engines\sci\detection_tables.h" /> <File RelativePath="..\..\engines\sci\exereader.cpp" /> <File RelativePath="..\..\engines\sci\exereader.h" /> <File RelativePath="..\..\engines\sci\resource.cpp" /> diff --git a/dists/msvc9/scumm.vcproj b/dists/msvc9/scumm.vcproj index e77ab97292..e261319fdb 100644 --- a/dists/msvc9/scumm.vcproj +++ b/dists/msvc9/scumm.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="9,00" + Version="9.00" Name="scumm" ProjectGUID="{B6AFD548-63D2-40CD-A652-E87095AFCBAF}" RootNamespace="scumm" diff --git a/dists/msvc9/scummvm.vcproj b/dists/msvc9/scummvm.vcproj index 93e4d851dd..1dd95998dd 100644 --- a/dists/msvc9/scummvm.vcproj +++ b/dists/msvc9/scummvm.vcproj @@ -1312,6 +1312,14 @@ > </File> <File + RelativePath="..\..\graphics\conversion.cpp" + > + </File> + <File + RelativePath="..\..\graphics\conversion.h" + > + </File> + <File RelativePath="..\..\graphics\cursorman.cpp" > </File> @@ -1360,6 +1368,14 @@ > </File> <File + RelativePath="..\..\graphics\jpeg.cpp" + > + </File> + <File + RelativePath="..\..\graphics\jpeg.h" + > + </File> + <File RelativePath="..\..\graphics\pixelformat.h" > </File> diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index 69b27e10f9..746636d031 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -652,6 +652,8 @@ void AgiEngine::initialize() { } AgiEngine::~AgiEngine() { + _timer->removeTimerProc(agiTimerFunctionLow); + // If the engine hasn't been initialized yet via AgiEngine::initialize(), don't attempt to free any resources, // as they haven't been allocated. Fixes bug #1742432 - AGI: Engine crashes if no game is detected if (_game.state == STATE_INIT) { diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp index d212f8c2e0..2b4ef7f60a 100644 --- a/engines/agi/cycle.cpp +++ b/engines/agi/cycle.cpp @@ -266,8 +266,8 @@ process_key: } // commented out to close Sarien bug #438872 - if (key) - _game.keypress = key; + //if (key) + // _game.keypress = key; } break; case INPUT_GETSTRING: diff --git a/engines/agi/menu.cpp b/engines/agi/menu.cpp index 5d30eda81d..e1db04ff49 100644 --- a/engines/agi/menu.cpp +++ b/engines/agi/menu.cpp @@ -408,6 +408,7 @@ bool Menu::keyhandler(int key) { if (d->enabled) { debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event); _vm->_game.controllerOccured[d->event] = true; + _vm->_menuSelected = true; goto exit_menu; } break; diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 07b5c12247..ee2ef98c42 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -899,7 +899,7 @@ AGOSEngine::~AGOSEngine() { if (_driver) delete _driver; - AudioCD.destroy(); + AudioCD.stop(); for (uint i = 0; i < _itemHeap.size(); i++) { delete[] _itemHeap[i]; diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index d5146ae408..c390269fec 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -92,7 +92,7 @@ void AGOSEngine::changeDoorState(SubRoom *r, uint16 d, uint16 n) { mask <<= d; n <<= d; r->roomExitStates &= ~mask; - r->roomExitStates|= n; + r->roomExitStates |= n; } void AGOSEngine::setDoorState(Item *i, uint16 d, uint16 n) { diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index 8a54151f91..8470203640 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -1252,23 +1252,38 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) { if (_roomsListPtr) { byte *p = _roomsListPtr; - for (;;) { - uint16 minNum = READ_BE_UINT16(p); p += 2; - if (minNum == 0) - break; - - uint16 maxNum = READ_BE_UINT16(p); p += 2; + if (room == _currentRoom) { + for (;;) { + uint16 minNum = READ_BE_UINT16(p); p += 2; + if (minNum == 0) + break; + + uint16 maxNum = READ_BE_UINT16(p); p += 2; + + for (uint16 z = minNum; z <= maxNum; z++) { + uint16 itemNum = z + 2; + Item *item = derefItem(itemNum); + + num = (itemNum - _itemArrayInited); + _roomStates[num].state = item->state; + _roomStates[num].classFlags = item->classFlags; + SubRoom *subRoom = (SubRoom *)findChildOfType(item, kRoomType); + _roomStates[num].roomExitStates = subRoom->roomExitStates; + } + } + } else { + for (;;) { + uint16 minNum = READ_BE_UINT16(p); p += 2; + if (minNum == 0) + break; - for (uint16 z = minNum; z <= maxNum; z++) { - uint16 itemNum = z + 2; - Item *item = derefItem(itemNum); - item->parent = 0; + uint16 maxNum = READ_BE_UINT16(p); p += 2; - num = (itemNum - _itemArrayInited); - item->state = _roomStates[num].state; - item->classFlags = _roomStates[num].classFlags; - SubRoom *subRoom = (SubRoom *)findChildOfType(item, kRoomType); - subRoom->roomExitStates = _roomStates[num].roomExitStates; + for (uint16 z = minNum; z <= maxNum; z++) { + uint16 itemNum = z + 2; + Item *item = derefItem(itemNum); + item->parent = 0; + } } } } @@ -1439,7 +1454,6 @@ bool AGOSEngine_Elvira2::saveGame(uint slot, const char *caption) { for (uint16 z = minNum; z <= maxNum; z++) { uint16 itemNum = z + 2; Item *item = derefItem(itemNum); - item->parent = 0; uint16 num = (itemNum - _itemArrayInited); _roomStates[num].state = item->state; diff --git a/engines/cine/pal.h b/engines/cine/pal.h index 4764d5a474..26513eb5a1 100644 --- a/engines/cine/pal.h +++ b/engines/cine/pal.h @@ -36,7 +36,8 @@ namespace Cine { #define kLowPalNumBytes ((kLowPalNumColors) * (kLowPalBytesPerColor)) /*! \brief Low resolution (9-bit) color format used in Cine's 16-color modes. */ -static const Graphics::PixelFormat kLowPalFormat = {kLowPalBytesPerColor, 5, 5, 5, 8, 8, 4, 0, 0}; + static const Graphics::PixelFormat kLowPalFormat(kLowPalBytesPerColor, 5, 5, 5, 8, 8, 4, 0, 0); + // Constants related to kHighPalFormat #define kHighPalBytesPerColor 3 @@ -44,10 +45,10 @@ static const Graphics::PixelFormat kLowPalFormat = {kLowPalBytesPerColor, 5, 5, #define kHighPalNumBytes ((kHighPalNumColors) * (kHighPalBytesPerColor)) /*! \brief High resolution (24-bit) color format used in Cine's 256-color modes. */ -static const Graphics::PixelFormat kHighPalFormat = {kHighPalBytesPerColor, 0, 0, 0, 8, 0, 8, 16, 0}; +static const Graphics::PixelFormat kHighPalFormat(kHighPalBytesPerColor, 0, 0, 0, 8, 0, 8, 16, 0); /*! \brief The color format used by OSystem's setPalette-function. */ -static const Graphics::PixelFormat kSystemPalFormat = {4, 0, 0, 0, 8, 0, 8, 16, 0}; +static const Graphics::PixelFormat kSystemPalFormat(4, 0, 0, 0, 8, 0, 8, 16, 0); /*! \brief Endian types. Used at least by Palette class's load and save functions. * TODO: Move somewhere more general as this is definitely not Cine-engine specific diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp index 1286c38ff3..c4b2cd53fe 100644 --- a/engines/cruise/cruise.cpp +++ b/engines/cruise/cruise.cpp @@ -201,6 +201,8 @@ void CruiseEngine::pauseEngine(bool pause) { flipScreen(); changeCursor(_savedCursor); } + + gfxModuleData_addDirtyRect(Common::Rect(64, 100, 256, 117)); } Common::Error CruiseEngine::loadGameState(int slot) { diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h index 574017dfc7..eff3e9b92f 100644 --- a/engines/cruise/cruise.h +++ b/engines/cruise/cruise.h @@ -83,6 +83,7 @@ public: virtual bool hasFeature(EngineFeature f) const; int getGameType() const; + const char *getGameId() const; uint32 getFeatures() const; Common::Language getLanguage() const; Common::Platform getPlatform() const; diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp index aa3283aab7..5bde40b7ad 100644 --- a/engines/cruise/cruise_main.cpp +++ b/engines/cruise/cruise_main.cpp @@ -1330,6 +1330,8 @@ bool checkInput(int16 *buttonPtr) { return false; } +extern bool manageEvents(); + int CruiseEngine::processInput(void) { int16 mouseX = 0; int16 mouseY = 0; @@ -1367,6 +1369,7 @@ int CruiseEngine::processInput(void) { bool pausedButtonDown = false; while (!_vm->shouldQuit()) { + manageEvents(); getMouseStatus(&main10, &mouseX, &button, &mouseY); if (button) pausedButtonDown = true; diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp index 1045ed3b0b..054550e439 100644 --- a/engines/cruise/detection.cpp +++ b/engines/cruise/detection.cpp @@ -41,6 +41,10 @@ struct CRUISEGameDescription { uint32 features; }; +const char *CruiseEngine::getGameId() const { + return _gameDescription->desc.gameid; +} + int CruiseEngine::getGameType() const { return _gameDescription->gameType; } diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp index 7e454e78f8..c620a39b7d 100644 --- a/engines/cruise/menu.cpp +++ b/engines/cruise/menu.cpp @@ -27,8 +27,13 @@ #include "cruise/cruise_main.h" #include "cruise/staticres.h" +#include "engines/metaengine.h" +#include "gui/saveload.h" + namespace Cruise { +extern int currentMouseButton; + menuStruct *menuTable[8]; menuStruct *createMenu(int X, int Y, const char *menuName) { @@ -202,6 +207,38 @@ int processMenu(menuStruct *pMenu) { return -1; } +static void handleSaveLoad(bool saveFlag) { + const EnginePlugin *plugin = 0; + EngineMan.findGame(_vm->getGameId(), &plugin); + GUI::SaveLoadChooser *dialog; + if (saveFlag) + dialog = new GUI::SaveLoadChooser("Save game:", "Save"); + else + dialog = new GUI::SaveLoadChooser("Load game:", "Load"); + + dialog->setSaveMode(saveFlag); + int slot = dialog->runModal(plugin, ConfMan.getActiveDomainName()); + + if (slot >= 0) { + if (!saveFlag) + _vm->loadGameState(slot); + else { + Common::String result(dialog->getResultString()); + if (result.empty()) { + // If the user was lazy and entered no save name, come up with a default name. + char buf[20]; + snprintf(buf, 20, "Save %d", slot + 1); + + _vm->saveGameState(slot, buf); + } else { + _vm->saveGameState(slot, result.c_str()); + } + } + } + + delete dialog; +} + int playerMenu(int menuX, int menuY) { int retourMenu; //int restartGame = 0; @@ -251,15 +288,14 @@ int playerMenu(int menuX, int menuY) { freeMenu(menuTable[0]); menuTable[0] = NULL; + currentMouseButton = 0; switch (retourMenu) { case 3: // select save drive break; case 4: // save - saveSavegameData(0, "Default Save"); - break; case 5: // load - loadSavegameData(0); + handleSaveLoad(retourMenu == 4); break; case 6: // restart _vm->sound().fadeOutMusic(); diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp index 2e3db3478e..3920f8a56c 100644 --- a/engines/drascula/drascula.cpp +++ b/engines/drascula/drascula.cpp @@ -106,6 +106,7 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam DrasculaEngine::~DrasculaEngine() { delete _rnd; + stopSound(); free(_charMap); free(_itemLocations); diff --git a/engines/engine.cpp b/engines/engine.cpp index 0847e27246..a64a2fd1f3 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -125,11 +125,21 @@ void initCommonGFX(bool defaultTo1XScaler) { g_system->setFeatureState(OSystem::kFeatureFullscreenMode, ConfMan.getBool("fullscreen")); } -void initGraphics(int width, int height, bool defaultTo1xScaler) { +void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics::PixelFormat *format) { + g_system->beginGFXTransaction(); initCommonGFX(defaultTo1xScaler); +#ifdef USE_RGB_COLOR + if (format) + g_system->initSize(width, height, format); + else { + Graphics::PixelFormat Format = g_system->getSupportedFormats().front(); + g_system->initSize(width, height, &Format); + } +#else g_system->initSize(width, height); +#endif OSystem::TransactionError gfxError = g_system->endGFXTransaction(); @@ -150,6 +160,15 @@ void initGraphics(int width, int height, bool defaultTo1xScaler) { } // Just show warnings then these occur: +#ifdef USE_RGB_COLOR + if (gfxError & OSystem::kTransactionFormatNotSupported) { + Common::String message = "Could not initialize color format."; + + GUI::MessageDialog dialog(message); + dialog.runModal(); + } +#endif + if (gfxError & OSystem::kTransactionModeSwitchFailed) { Common::String message = "Could not switch to video mode: '"; message += ConfMan.get("gfx_mode"); @@ -169,6 +188,14 @@ void initGraphics(int width, int height, bool defaultTo1xScaler) { dialog.runModal(); } } +void initGraphics(int width, int height, bool defaultTo1xScaler, const Common::List<Graphics::PixelFormat> &formatList) { + Graphics::PixelFormat format = Graphics::findCompatibleFormat(g_system->getSupportedFormats(),formatList); + initGraphics(width,height,defaultTo1xScaler,&format); +} +void initGraphics(int width, int height, bool defaultTo1xScaler) { + Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8(); + initGraphics(width,height,defaultTo1xScaler,&format); +} void GUIErrorMessage(const Common::String msg) { g_system->setWindowCaption("Error"); diff --git a/engines/engine.h b/engines/engine.h index ff3ce6c326..cd39c0065d 100644 --- a/engines/engine.h +++ b/engines/engine.h @@ -29,6 +29,7 @@ #include "common/error.h" #include "common/fs.h" #include "common/str.h" +#include "graphics/pixelformat.h" class OSystem; @@ -58,8 +59,14 @@ void initCommonGFX(bool defaultTo1XScaler); * * Errors out when backend is not able to switch to the specified * mode. + * + * Defaults to 256 color paletted mode if no graphics format is provided. + * Uses the backend's preferred format if graphics format pointer is NULL. + * Finds the best compatible format if a list of graphics formats is provided. */ void initGraphics(int width, int height, bool defaultTo1xScaler); +void initGraphics(int width, int height, bool defaultTo1xScaler, const Graphics::PixelFormat *format); +void initGraphics(int width, int height, bool defaultTo1xScaler, const Common::List<Graphics::PixelFormat> &formatList); /** * Initializes graphics and shows error message. diff --git a/engines/gob/demos/demoplayer.cpp b/engines/gob/demos/demoplayer.cpp index 13b7aa5327..bb56633525 100644 --- a/engines/gob/demos/demoplayer.cpp +++ b/engines/gob/demos/demoplayer.cpp @@ -56,6 +56,7 @@ DemoPlayer::Script DemoPlayer::_scripts[] = { }; DemoPlayer::DemoPlayer(GobEngine *vm) : _vm(vm) { + _autoDouble = false; _doubleMode = false; _rebase0 = false; } diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 057f52b360..43a4941402 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -557,7 +557,9 @@ protected: virtual void setupOpcodesFunc(); virtual void setupOpcodesGob(); + bool oPlaytoons_F_1B(OpFuncParams ¶ms); bool oPlaytoons_checkData(OpFuncParams ¶ms); + bool oPlaytoons_readData(OpFuncParams ¶ms); void oPlaytoons_CD_20_23(); void oPlaytoons_CD_25(); void oPlaytoons_openItk(); diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp index e224f29734..d7cb6b79c2 100644 --- a/engines/gob/inter_playtoons.cpp +++ b/engines/gob/inter_playtoons.cpp @@ -25,6 +25,8 @@ #include "common/endian.h" +#include "gui/message.h" + #include "gob/gob.h" #include "gob/inter.h" #include "gob/helper.h" @@ -77,12 +79,33 @@ void Inter_Playtoons::setupOpcodesDraw() { void Inter_Playtoons::setupOpcodesFunc() { Inter_v6::setupOpcodesFunc(); + OPCODEFUNC(0x1B, oPlaytoons_F_1B); OPCODEFUNC(0x3F, oPlaytoons_checkData); + OPCODEFUNC(0x4D, oPlaytoons_readData); } void Inter_Playtoons::setupOpcodesGob() { } +bool Inter_Playtoons::oPlaytoons_F_1B(OpFuncParams ¶ms) { + int16 var1; + int16 var2; + int16 var3; + int16 var4; + + var1 = _vm->_game->_script->readValExpr(); + var2 = _vm->_game->_script->readValExpr(); + + _vm->_game->_script->evalExpr(0); + + var3 = _vm->_game->_script->readValExpr(); + var4 = _vm->_game->_script->readValExpr(); + + warning("oPlaytoons_F_1B not handled"); + + return false; +} + bool Inter_Playtoons::oPlaytoons_checkData(OpFuncParams ¶ms) { int16 handle; int16 varOff; @@ -101,18 +124,16 @@ bool Inter_Playtoons::oPlaytoons_checkData(OpFuncParams ¶ms) { // In this case, "@:\" is replaced by the CD drive letter. // As the files are copied on the HDD, those characters are skipped. if (strncmp(file, "@:\\", 3) == 0) { - debugC(2, kDebugFileIO, "File check: \"%s\" instead of \"%s\"", file + 3, file); + debugC(2, kDebugFileIO, "oPlaytoons_checkData: \"%s\" instead of \"%s\"", file + 3, file); file += 3; } mode = _vm->_saveLoad->getSaveMode(file); if (mode == SaveLoad::kSaveModeNone) { - if (_vm->_dataIO->existData(file)) size = _vm->_dataIO->getDataSize(file); else warning("File \"%s\" not found", file); - } else if (mode == SaveLoad::kSaveModeSave) size = _vm->_saveLoad->getSize(file); else if (mode == SaveLoad::kSaveModeExists) @@ -130,6 +151,97 @@ bool Inter_Playtoons::oPlaytoons_checkData(OpFuncParams ¶ms) { return false; } +bool Inter_Playtoons::oPlaytoons_readData(OpFuncParams ¶ms) { + int32 retSize; + int32 size; + int32 offset; + int16 dataVar; + int16 handle; + byte *buf; + SaveLoad::SaveMode mode; + + _vm->_game->_script->evalExpr(0); + dataVar = _vm->_game->_script->readVarIndex(); + size = _vm->_game->_script->readValExpr(); + _vm->_game->_script->evalExpr(0); + offset = _vm->_game->_script->getResultInt(); + retSize = 0; + + char *file = _vm->_game->_script->getResultStr(); + + // WORKAROUND: In Playtoons games, some files are read on CD (and only on CD). + // In this case, "@:\" is replaced by the CD drive letter. + // As the files are copied on the HDD, those characters are skipped. + if (strncmp(file, "@:\\", 3) == 0) { + debugC(2, kDebugFileIO, "oPlaytoons_readData: \"%s\" instead of \"%s\"", file + 3, file); + file += 3; + } + + debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)", + file, dataVar, size, offset); + + mode = _vm->_saveLoad->getSaveMode(file); + if (mode == SaveLoad::kSaveModeSave) { + + WRITE_VAR(1, 1); + + if (!_vm->_saveLoad->load(file, dataVar, size, offset)) { + GUI::MessageDialog dialog("Failed to load game state from file."); + dialog.runModal(); + } else + WRITE_VAR(1, 0); + + return false; + + } else if (mode == SaveLoad::kSaveModeIgnore) + return false; + + if (size < 0) { + warning("Attempted to read a raw sprite from file \"%s\"", + file); + return false ; + } else if (size == 0) { + dataVar = 0; + size = _vm->_game->_script->getVariablesCount() * 4; + } + + buf = _variables->getAddressOff8(dataVar); + + if (file[0] == 0) { + WRITE_VAR(1, size); + return false; + } + + WRITE_VAR(1, 1); + handle = _vm->_dataIO->openData(file); + + if (handle < 0) + return false; + + DataStream *stream = _vm->_dataIO->openAsStream(handle, true); + + _vm->_draw->animateCursor(4); + if (offset < 0) + stream->seek(offset + 1, SEEK_END); + else + stream->seek(offset); + + if (((dataVar >> 2) == 59) && (size == 4)) { + WRITE_VAR(59, stream->readUint32LE()); + // The scripts in some versions divide through 256^3 then, + // effectively doing a LE->BE conversion + if ((_vm->getPlatform() != Common::kPlatformPC) && (VAR(59) < 256)) + WRITE_VAR(59, SWAP_BYTES_32(VAR(59))); + } else + retSize = stream->read(buf, size); + + if (retSize == size) + WRITE_VAR(1, 0); + + delete stream; + return false; +} + void Inter_Playtoons::oPlaytoons_CD_20_23() { _vm->_game->_script->evalExpr(0); } diff --git a/engines/gob/save/savehandler.cpp b/engines/gob/save/savehandler.cpp index 4e2c09bdca..5f24115a6c 100644 --- a/engines/gob/save/savehandler.cpp +++ b/engines/gob/save/savehandler.cpp @@ -229,6 +229,9 @@ int32 TempSpriteHandler::getSize() { } bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) { + if (isDummy(size)) + return true; + // Sprite available? if (!_sprite) return false; @@ -274,6 +277,9 @@ bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) { bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { SurfaceDescPtr sprite; + if (isDummy(size)) + return true; + if (!createSprite(dataVar, size, offset, &sprite)) return false; @@ -320,6 +326,12 @@ bool TempSpriteHandler::createSprite(int16 dataVar, int32 size, return true; } +// A size of 0 means no proper sprite should be saved/loaded, +// but no error should be thrown either. +bool TempSpriteHandler::isDummy(int32 size) { + return (size == 0); +} + // A negative size is the flag for using a sprite bool TempSpriteHandler::isSprite(int32 size) { return (size < 0); diff --git a/engines/gob/save/savehandler.h b/engines/gob/save/savehandler.h index 55505d1b9a..6a7e563a8f 100644 --- a/engines/gob/save/savehandler.h +++ b/engines/gob/save/savehandler.h @@ -144,6 +144,8 @@ public: protected: SavePartSprite *_sprite; + /** Determine whether it's a dummy sprite save/load. */ + static bool isDummy(int32 size); /** Determine whether using a sprite was requested. */ static bool isSprite(int32 size); /** Determine which sprite is meant. */ diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h index 4779de703c..8e1240daf1 100644 --- a/engines/gob/save/saveload.h +++ b/engines/gob/save/saveload.h @@ -77,6 +77,9 @@ public: static const uint32 kSlotCount = 15; static const uint32 kSlotNameLength = 40; + /** The index. kSlotCount * kSlotNameLength bytes. */ + static const uint32 kIndexSize = kSlotCount * kSlotNameLength; + SaveLoad_v2(GobEngine *vm, const char *targetName); virtual ~SaveLoad_v2(); @@ -111,8 +114,7 @@ protected: int getSlotRemainder(int32 offset) const; }; - /** The index. kSlotCount * kSlotNameLength bytes. */ - byte _index[600]; + byte _index[kIndexSize]; bool _hasIndex; File *_slotFile; @@ -139,6 +141,10 @@ public: static const uint32 kSlotCount = 30; static const uint32 kSlotNameLength = 40; + static const uint32 kPropsSize = 500; + /** Index. kSlotCount * kSlotNameLength bytes. */ + static const uint32 kIndexSize = kSlotCount * kSlotNameLength; + enum ScreenshotType { kScreenshotTypeGob3, //!< Goblins 3 type screenshot kScreenshotTypeLost //!< Lost in Time type screenshot @@ -193,9 +199,8 @@ protected: bool _firstSize; /** Global properties. */ - byte _props[500]; - /** Index. kSlotCount * kSlotNameLength bytes. */ - byte _index[1200]; + byte _props[kPropsSize]; + byte _index[kIndexSize]; bool _hasIndex; SaveReader *_reader; @@ -251,6 +256,7 @@ protected: GameHandler *_gameHandler; NotesHandler *_notesHandler; + TempSpriteHandler *_tempSpriteHandler; ScreenshotHandler *_screenshotHandler; SaveHandler *getHandler(const char *fileName) const; @@ -266,6 +272,10 @@ public: static const uint32 kSlotCount = 10; static const uint32 kSlotNameLength = 40; + static const uint32 kPropsSize = 500; + /** Index. kSlotCount * kSlotNameLength bytes + 800 bytes 0. */ + static const uint32 kIndexSize = (kSlotCount * kSlotNameLength) + 800; + SaveLoad_v4(GobEngine *vm, const char *targetName); virtual ~SaveLoad_v4(); @@ -311,9 +321,8 @@ protected: private: bool _firstSize; - byte _props[500]; - /** The index. kSlotCount * kSlotNameLength bytes + 800 bytes 0. */ - byte _index[1200]; + byte _props[kPropsSize]; + byte _index[kIndexSize]; bool _hasIndex; File *_slotFile; @@ -392,6 +401,10 @@ public: static const uint32 kSlotCount = 60; static const uint32 kSlotNameLength = 40; + static const uint32 kPropsSize = 500; + /** Index. kSlotCount * kSlotNameLength bytes. */ + static const uint32 kIndexSize = kSlotCount * kSlotNameLength; + SaveLoad_v6(GobEngine *vm, const char *targetName); virtual ~SaveLoad_v6(); @@ -426,9 +439,8 @@ protected: int getSlotRemainder(int32 offset) const; }; - byte _props[500]; - /** The index. 500 bytes properties + kSlotCount * kSlotNameLength bytes. */ - byte _index[2400]; + byte _props[kPropsSize]; + byte _index[kIndexSize]; File *_slotFile; @@ -454,6 +466,10 @@ public: static const uint32 kSlotCount = 60; static const uint32 kSlotNameLength = 40; + static const uint32 kPropsSize = 1642; + /** Index. kSlotCount * kSlotNameLength bytes. */ + static const uint32 kIndexSize = kSlotCount * kSlotNameLength; + SaveLoad_Playtoons(GobEngine *vm, const char *targetName); virtual ~SaveLoad_Playtoons(); @@ -488,9 +504,8 @@ protected: int getSlotRemainder(int32 offset) const; }; - byte _props[500]; - /** The index. 500 bytes properties + kSlotCount * kSlotNameLength bytes. */ - byte _index[2400]; + byte _props[kPropsSize]; + byte _index[kIndexSize]; File *_slotFile; diff --git a/engines/gob/save/saveload_playtoons.cpp b/engines/gob/save/saveload_playtoons.cpp index 392c9a94ac..48adcdc59e 100644 --- a/engines/gob/save/saveload_playtoons.cpp +++ b/engines/gob/save/saveload_playtoons.cpp @@ -30,27 +30,39 @@ namespace Gob { SaveLoad_Playtoons::SaveFile SaveLoad_Playtoons::_saveFiles[] = { - { "did.inf", kSaveModeSave, 0, 0}, // - { "dan.itk", kSaveModeNone, 0, 0}, // Playtoons CK initial detection file - { "disk.001", kSaveModeExists, 0, 0}, // Playtoons 1 identification file - { "disk.002", kSaveModeExists, 0, 0}, // Playtoons 2 identification file - { "disk.003", kSaveModeExists, 0, 0}, // Playtoons 3 identification file - { "disk.004", kSaveModeExists, 0, 0}, // Playtoons 4 identification file - { "disk.005", kSaveModeExists, 0, 0}, // Playtoons 5 identification file - { "disk.006", kSaveModeExists, 0, 0}, // Playtoons CK 1 identification file - { "disk.007", kSaveModeExists, 0, 0}, // Playtoons CK 2 identification file - { "disk.008", kSaveModeExists, 0, 0}, // Playtoons CK 3 identification file -/* - { "titre.001", kSaveModeExists, 0, 0}, // Playtoons 1 titles - { "titre.002", kSaveModeExists, 0, 0}, // Playtoons 2 titles - { "titre.003", kSaveModeExists, 0, 0}, // Playtoons 3 titles - { "titre.004", kSaveModeExists, 0, 0}, // Playtoons 4 titles - { "titre.005", kSaveModeExists, 0, 0}, // Playtoons 5 titles - { "titre.006", kSaveModeExists, 0, 0}, // Playtoons CK 1 empty title (???) - { "titre.007", kSaveModeExists, 0, 0}, // Playtoons CK 2 empty title (???) - { "titre.008", kSaveModeExists, 0, 0}, // Playtoons CK 3 empty title (???) - { "mdo.def", kSaveModeExists, 0, 0}, // -*/ + { "did.inf", kSaveModeSave, 0, 0}, // Purpose ignored at the moment, intensively used to save things. + { "dan.itk", kSaveModeNone, 0, 0}, // Playtoons CK detection file + { "titre.009", kSaveModeIgnore, 0, 0}, // Playtoons theoritical title files that are checked for nothing + { "titre.010", kSaveModeIgnore, 0, 0}, + { "titre.011", kSaveModeIgnore, 0, 0}, + { "titre.012", kSaveModeIgnore, 0, 0}, + { "titre.013", kSaveModeIgnore, 0, 0}, + { "titre.014", kSaveModeIgnore, 0, 0}, + { "titre.015", kSaveModeIgnore, 0, 0}, + { "titre.016", kSaveModeIgnore, 0, 0}, + { "titre.017", kSaveModeIgnore, 0, 0}, + { "titre.018", kSaveModeIgnore, 0, 0}, + { "titre.019", kSaveModeIgnore, 0, 0}, + { "titre.020", kSaveModeIgnore, 0, 0}, + { "titre.021", kSaveModeIgnore, 0, 0}, + { "titre.022", kSaveModeIgnore, 0, 0}, + { "titre.023", kSaveModeIgnore, 0, 0}, + { "titre.024", kSaveModeIgnore, 0, 0}, + { "titre.025", kSaveModeIgnore, 0, 0}, + { "titre.026", kSaveModeIgnore, 0, 0}, + { "titre.027", kSaveModeIgnore, 0, 0}, + { "titre.028", kSaveModeIgnore, 0, 0}, + { "titre.029", kSaveModeIgnore, 0, 0}, + { "titre.030", kSaveModeIgnore, 0, 0}, + { "titre.031", kSaveModeIgnore, 0, 0}, + { "titre.032", kSaveModeIgnore, 0, 0}, + { "titre.033", kSaveModeIgnore, 0, 0}, + { "titre.034", kSaveModeIgnore, 0, 0}, + { "titre.035", kSaveModeIgnore, 0, 0}, + { "titre.036", kSaveModeIgnore, 0, 0}, + { "titre.037", kSaveModeIgnore, 0, 0}, + { "titre.038", kSaveModeIgnore, 0, 0}, + { "titre.039", kSaveModeIgnore, 0, 0}, }; SaveLoad_Playtoons::GameHandler::File::File(GobEngine *vm, const char *base) : @@ -66,7 +78,7 @@ int SaveLoad_Playtoons::GameHandler::File::getSlot(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 2900) / varSize); + return ((offset - (kPropsSize + kIndexSize)) / varSize); } int SaveLoad_Playtoons::GameHandler::File::getSlotRemainder(int32 offset) const { @@ -75,13 +87,13 @@ int SaveLoad_Playtoons::GameHandler::File::getSlotRemainder(int32 offset) const if (varSize == 0) return -1; - return ((offset - 2900) % varSize); + return ((offset - (kPropsSize + kIndexSize)) % varSize); } SaveLoad_Playtoons::GameHandler::GameHandler(GobEngine *vm, const char *target) : SaveHandler(vm) { - memset(_props, 0, 500); - memset(_index, 0, 2400); + memset(_props, 0, kPropsSize); + memset(_index, 0, kIndexSize); _slotFile = new File(vm, target); } @@ -96,7 +108,7 @@ int32 SaveLoad_Playtoons::GameHandler::getSize() { if (varSize == 0) return -1; - return _slotFile->tallyUpFiles(varSize, 2900); + return _slotFile->tallyUpFiles(varSize, kPropsSize + kIndexSize); } bool SaveLoad_Playtoons::GameHandler::load(int16 dataVar, int32 size, int32 offset) { @@ -111,20 +123,20 @@ bool SaveLoad_Playtoons::GameHandler::load(int16 dataVar, int32 size, int32 offs size = varSize; } - if (offset < 500) { + if (((uint32) offset) < kPropsSize) { // Properties - if ((offset + size) > 500) { + if (((uint32) (offset + size)) > kPropsSize) { warning("Wrong index size (%d, %d)", size, offset); return false; } _vm->_inter->_variables->copyFrom(dataVar, _props + offset, size); - } else if (offset < 2900) { + } else if (((uint32) offset) < kPropsSize + kIndexSize) { // Save index - if (size != 2400) { + if (((uint32) size) != kIndexSize) { warning("Wrong index size (%d, %d)", size, offset); return false; } @@ -198,26 +210,26 @@ bool SaveLoad_Playtoons::GameHandler::save(int16 dataVar, int32 size, int32 offs size = varSize; } - if (offset < 500) { + if (((uint32) offset) < kPropsSize) { // Properties - if ((offset + size) > 500) { + if (((uint32) (offset + size)) > kPropsSize) { warning("Wrong index size (%d, %d)", size, offset); return false; } _vm->_inter->_variables->copyTo(dataVar, _props + offset, size); - } else if (offset < 2900) { + } else if (((uint32) offset) < kPropsSize + kIndexSize) { // Save index - if (size != 2400) { + if (((uint32) size) != kIndexSize) { warning("Wrong index size (%d, %d)", size, offset); return false; } // Just copy the index into our buffer - _vm->_inter->_variables->copyTo(dataVar, _index, 2400); + _vm->_inter->_variables->copyTo(dataVar, _index, kIndexSize); } else { // Save slot, whole variable block diff --git a/engines/gob/save/saveload_v2.cpp b/engines/gob/save/saveload_v2.cpp index da1135df21..ea639b861a 100644 --- a/engines/gob/save/saveload_v2.cpp +++ b/engines/gob/save/saveload_v2.cpp @@ -51,7 +51,7 @@ int SaveLoad_v2::GameHandler::File::getSlot(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 600) / varSize); + return ((offset - kIndexSize) / varSize); } int SaveLoad_v2::GameHandler::File::getSlotRemainder(int32 offset) const { @@ -60,12 +60,12 @@ int SaveLoad_v2::GameHandler::File::getSlotRemainder(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 600) % varSize); + return ((offset - kIndexSize) % varSize); } SaveLoad_v2::GameHandler::GameHandler(GobEngine *vm, const char *target) : SaveHandler(vm) { - memset(_index, 0, 600); + memset(_index, 0, kIndexSize); _hasIndex = false; _slotFile = new File(vm, target); @@ -81,7 +81,7 @@ int32 SaveLoad_v2::GameHandler::getSize() { if (varSize == 0) return -1; - return _slotFile->tallyUpFiles(varSize, 600); + return _slotFile->tallyUpFiles(varSize, kIndexSize); } bool SaveLoad_v2::GameHandler::load(int16 dataVar, int32 size, int32 offset) { @@ -99,7 +99,7 @@ bool SaveLoad_v2::GameHandler::load(int16 dataVar, int32 size, int32 offset) { if (offset == 0) { // Save index - if (size != 600) { + if (((uint32) size) != kIndexSize) { warning("Requested index has wrong size (%d)", size); return false; } @@ -184,13 +184,13 @@ bool SaveLoad_v2::GameHandler::save(int16 dataVar, int32 size, int32 offset) { if (offset == 0) { // Save index - if (size != 600) { + if (((uint32) size) != kIndexSize) { warning("Requested index has wrong size (%d)", size); return false; } // Just copy the index into our buffer - _vm->_inter->_variables->copyTo(dataVar, _index, 600); + _vm->_inter->_variables->copyTo(dataVar, _index, kIndexSize); _hasIndex = true; } else { diff --git a/engines/gob/save/saveload_v3.cpp b/engines/gob/save/saveload_v3.cpp index c24b13d27b..bb60f94725 100644 --- a/engines/gob/save/saveload_v3.cpp +++ b/engines/gob/save/saveload_v3.cpp @@ -33,8 +33,8 @@ namespace Gob { SaveLoad_v3::SaveFile SaveLoad_v3::_saveFiles[] = { { "cat.inf", kSaveModeSave , 0, "savegame"}, { "ima.inf", kSaveModeSave , 0, "screenshot"}, + { "intro.$$$", kSaveModeSave , 0, "temporary sprite"}, { "bloc.inf", kSaveModeSave , 0, "notes"}, - { "intro.$$$", kSaveModeIgnore, 0, "temporary sprite"}, { "prot", kSaveModeIgnore, 0, 0}, { "config", kSaveModeIgnore, 0, 0} }; @@ -57,7 +57,7 @@ int SaveLoad_v3::GameHandler::File::getSlot(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 1700) / varSize); + return ((offset - (kPropsSize + kIndexSize)) / varSize); } int SaveLoad_v3::GameHandler::File::getSlotRemainder(int32 offset) const { @@ -66,7 +66,7 @@ int SaveLoad_v3::GameHandler::File::getSlotRemainder(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 1700) % varSize); + return ((offset - (kPropsSize + kIndexSize)) % varSize); } @@ -78,8 +78,8 @@ SaveLoad_v3::GameHandler::GameHandler(GobEngine *vm, const char *target, _usesScreenshots = usesScreenshots; _firstSize = true; - memset(_props, 0, 500); - memset(_index, 0, 1200); + memset(_props, 0, kPropsSize); + memset(_index, 0, kIndexSize); _hasIndex = false; _writer = 0; @@ -104,7 +104,7 @@ int32 SaveLoad_v3::GameHandler::getSize() { if (varSize == 0) return -1; - return _slotFile->tallyUpFiles(varSize, 1700); + return _slotFile->tallyUpFiles(varSize, kPropsSize + kIndexSize); } bool SaveLoad_v3::GameHandler::load(int16 dataVar, int32 size, int32 offset) { @@ -119,22 +119,22 @@ bool SaveLoad_v3::GameHandler::load(int16 dataVar, int32 size, int32 offset) { size = varSize; } - if (offset < 500) { + if (((uint32) offset) < kPropsSize) { // Global properties, like joker usage debugC(3, kDebugSaveLoad, "Loading global properties"); - if ((size + offset) > 500) { + if (((uint32) (offset + size)) > kPropsSize) { warning("Wrong global properties list size (%d, %d)", size, offset); return false; } _vm->_inter->_variables->copyFrom(dataVar, _props + offset, size); - } else if (offset == 500) { + } else if (((uint32) offset) == kPropsSize) { // Save index - if (size != 1200) { + if (((uint32) size) != kIndexSize) { warning("Requested index has wrong size (%d)", size); return false; } @@ -193,28 +193,28 @@ bool SaveLoad_v3::GameHandler::save(int16 dataVar, int32 size, int32 offset) { size = varSize; } - if (offset < 500) { + if (((uint32) offset) < kPropsSize) { // Global properties, like joker usage debugC(3, kDebugSaveLoad, "Saving global properties"); - if ((size + offset) > 500) { + if (((uint32) (offset + size)) > kPropsSize) { warning("Wrong global properties list size (%d, %d)", size, offset); return false; } _vm->_inter->_variables->copyTo(dataVar, _props + offset, size); - } else if (offset == 500) { + } else if (((uint32) offset) == kPropsSize) { // Save index - if (size != 1200) { + if (((uint32) size) != kIndexSize) { warning("Requested index has wrong size (%d)", size); return false; } // Just copy the index into our buffer - _vm->_inter->_variables->copyTo(dataVar, _index, 1200); + _vm->_inter->_variables->copyTo(dataVar, _index, kIndexSize); _hasIndex = true; } else { @@ -496,17 +496,20 @@ SaveLoad_v3::SaveLoad_v3(GobEngine *vm, const char *targetName, ScreenshotType s _screenshotHandler = new ScreenshotHandler(vm, _gameHandler, sShotType); } + _tempSpriteHandler = new TempSpriteHandler(vm); _notesHandler = new NotesHandler(2560, vm, targetName); _saveFiles[0].handler = _gameHandler; _saveFiles[1].handler = _screenshotHandler; - _saveFiles[2].handler = _notesHandler; + _saveFiles[2].handler = _tempSpriteHandler; + _saveFiles[3].handler = _notesHandler; } SaveLoad_v3::~SaveLoad_v3() { delete _screenshotHandler; delete _gameHandler; delete _notesHandler; + delete _tempSpriteHandler; } const SaveLoad_v3::SaveFile *SaveLoad_v3::getSaveFile(const char *fileName) const { diff --git a/engines/gob/save/saveload_v4.cpp b/engines/gob/save/saveload_v4.cpp index 16c87b9a64..e6973efd64 100644 --- a/engines/gob/save/saveload_v4.cpp +++ b/engines/gob/save/saveload_v4.cpp @@ -63,7 +63,7 @@ int SaveLoad_v4::GameHandler::File::getSlot(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 1700) / varSize); + return ((offset - (kPropsSize + kIndexSize)) / varSize); } int SaveLoad_v4::GameHandler::File::getSlotRemainder(int32 offset) const { @@ -72,14 +72,14 @@ int SaveLoad_v4::GameHandler::File::getSlotRemainder(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 1700) % varSize); + return ((offset - (kPropsSize + kIndexSize)) % varSize); } SaveLoad_v4::GameHandler::GameHandler(GobEngine *vm, const char *target) : SaveHandler(vm) { _firstSize = true; - memset(_props, 0, 500); - memset(_index, 0, 1200); + memset(_props, 0, kPropsSize); + memset(_index, 0, kIndexSize); _hasIndex = false; _slotFile = new File(vm, target); @@ -112,7 +112,7 @@ int32 SaveLoad_v4::GameHandler::getSize() { if (varSize == 0) return -1; - return _slotFile->tallyUpFiles(varSize, 1700); + return _slotFile->tallyUpFiles(varSize, kPropsSize + kIndexSize); } bool SaveLoad_v4::GameHandler::load(int16 dataVar, int32 size, int32 offset) { @@ -127,22 +127,22 @@ bool SaveLoad_v4::GameHandler::load(int16 dataVar, int32 size, int32 offset) { size = varSize; } - if (offset < 500) { + if (((uint32) offset) < kPropsSize) { // Global properties debugC(3, kDebugSaveLoad, "Loading global properties"); - if ((size + offset) > 500) { + if (((uint32) (offset + size)) > kPropsSize) { warning("Wrong global properties list size (%d, %d)", size, offset); return false; } _vm->_inter->_variables->copyFrom(dataVar, _props + offset, size); - } else if (offset == 500) { + } else if (((uint32) offset) == kPropsSize) { // Save index - if (size != 1200) { + if (((uint32) size) != kIndexSize) { warning("Requested index has wrong size (%d)", size); return false; } @@ -202,28 +202,28 @@ bool SaveLoad_v4::GameHandler::save(int16 dataVar, int32 size, int32 offset) { size = varSize; } - if (offset < 500) { + if (((uint32) offset) < kPropsSize) { // Global properties debugC(3, kDebugSaveLoad, "Saving global properties"); - if ((size + offset) > 500) { + if (((uint32) (offset + size)) > kPropsSize) { warning("Wrong global properties list size (%d, %d)", size, offset); return false; } _vm->_inter->_variables->copyTo(dataVar, _props + offset, size); - } else if (offset == 500) { + } else if (((uint32) offset) == kPropsSize) { // Save index - if (size != 1200) { + if (((uint32) size) != kIndexSize) { warning("Requested index has wrong size (%d)", size); return false; } // Just copy the index into our buffer - _vm->_inter->_variables->copyTo(dataVar, _index, 1200); + _vm->_inter->_variables->copyTo(dataVar, _index, kIndexSize); _hasIndex = true; } else { diff --git a/engines/gob/save/saveload_v6.cpp b/engines/gob/save/saveload_v6.cpp index 45622bee73..e31c8b4809 100644 --- a/engines/gob/save/saveload_v6.cpp +++ b/engines/gob/save/saveload_v6.cpp @@ -50,7 +50,7 @@ int SaveLoad_v6::GameHandler::File::getSlot(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 2900) / varSize); + return ((offset - (kPropsSize + kIndexSize)) / varSize); } int SaveLoad_v6::GameHandler::File::getSlotRemainder(int32 offset) const { @@ -59,13 +59,13 @@ int SaveLoad_v6::GameHandler::File::getSlotRemainder(int32 offset) const { if (varSize == 0) return -1; - return ((offset - 2900) % varSize); + return ((offset - (kPropsSize + kIndexSize)) % varSize); } SaveLoad_v6::GameHandler::GameHandler(GobEngine *vm, const char *target) : SaveHandler(vm) { - memset(_props, 0, 500); - memset(_index, 0, 2400); + memset(_props, 0, kPropsSize); + memset(_index, 0, kIndexSize); _slotFile = new File(vm, target); } @@ -80,7 +80,7 @@ int32 SaveLoad_v6::GameHandler::getSize() { if (varSize == 0) return -1; - return _slotFile->tallyUpFiles(varSize, 2900); + return _slotFile->tallyUpFiles(varSize, kPropsSize + kIndexSize); } bool SaveLoad_v6::GameHandler::load(int16 dataVar, int32 size, int32 offset) { @@ -95,22 +95,22 @@ bool SaveLoad_v6::GameHandler::load(int16 dataVar, int32 size, int32 offset) { size = varSize; } - if (offset < 500) { + if (((uint32) offset) < kPropsSize) { // Properties refreshProps(); - if ((offset + size) > 500) { + if (((uint32) (offset + size)) > kPropsSize) { warning("Wrong index size (%d, %d)", size, offset); return false; } _vm->_inter->_variables->copyFrom(dataVar, _props + offset, size); - } else if (offset < 2900) { + } else if (((uint32) offset) < kPropsSize + kIndexSize) { // Save index - if (size != 2400) { + if (((uint32) size) != kIndexSize) { warning("Wrong index size (%d, %d)", size, offset); return false; } @@ -191,10 +191,10 @@ bool SaveLoad_v6::GameHandler::save(int16 dataVar, int32 size, int32 offset) { size = varSize; } - if (offset < 500) { + if (((uint32) offset) < kPropsSize) { // Properties - if ((offset + size) > 500) { + if (((uint32) (offset + size)) > kPropsSize) { warning("Wrong index size (%d, %d)", size, offset); return false; } @@ -203,16 +203,16 @@ bool SaveLoad_v6::GameHandler::save(int16 dataVar, int32 size, int32 offset) { refreshProps(); - } else if (offset < 2900) { + } else if (((uint32) offset) < kPropsSize + kIndexSize) { // Save index - if (size != 2400) { + if (((uint32) size) != kIndexSize) { warning("Wrong index size (%d, %d)", size, offset); return false; } // Just copy the index into our buffer - _vm->_inter->_variables->copyTo(dataVar, _index, 2400); + _vm->_inter->_variables->copyTo(dataVar, _index, kIndexSize); } else { // Save slot, whole variable block diff --git a/engines/gob/sound/cdrom.cpp b/engines/gob/sound/cdrom.cpp index 4d6a7ec966..68cbb1b9e2 100644 --- a/engines/gob/sound/cdrom.cpp +++ b/engines/gob/sound/cdrom.cpp @@ -46,6 +46,7 @@ CDROM::CDROM() { } CDROM::~CDROM() { + stop(); } void CDROM::readLIC(DataStream &stream) { diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp index b526b63a37..98cf4a5d4f 100644 --- a/engines/gob/video_v2.cpp +++ b/engines/gob/video_v2.cpp @@ -64,12 +64,15 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, memBuffer = new byte[4370]; assert(memBuffer); + memset(memBuffer, 0, 4370); + srcPtr = sprBuf + 3; + sourceLeft = READ_LE_UINT32(srcPtr); destPtr = destDesc.getVidMem() + destDesc.getWidth() * y + x; - curWidth = 0; + curWidth = 0; curHeight = 0; linePtr = destPtr; @@ -89,58 +92,64 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, cmdVar = 0; while (1) { cmdVar >>= 1; - if ((cmdVar & 0x100) == 0) { - cmdVar = *srcPtr | 0xFF00; - srcPtr++; - } + if ((cmdVar & 0x100) == 0) + cmdVar = *srcPtr++ | 0xFF00; + if ((cmdVar & 1) != 0) { temp = *srcPtr++; + if ((temp != 0) || (transp == 0)) *destPtr = temp; + destPtr++; curWidth++; + if (curWidth >= srcWidth) { curWidth = 0; linePtr += destDesc.getWidth(); destPtr = linePtr; - curHeight++; - if (curHeight >= srcHeight) + if (++curHeight >= srcHeight) break; } - sourceLeft--; + memBuffer[bufPos] = temp; - bufPos++; - bufPos %= 4096; - if (sourceLeft == 0) + + bufPos = (bufPos + 1) % 4096; + + if (--sourceLeft == 0) break; + } else { offset = *srcPtr++; - offset |= (*srcPtr & 0xF0) << 4; - strLen = (*srcPtr & 0x0F) + 3; - *srcPtr++; + temp = *srcPtr++; + + offset |= (temp & 0xF0) << 4; + strLen = (temp & 0x0F) + 3; + if (strLen == lenCmd) strLen = *srcPtr++ + 18; for (counter2 = 0; counter2 < strLen; counter2++) { temp = memBuffer[(offset + counter2) % 4096]; + if ((temp != 0) || (transp == 0)) *destPtr = temp; - destPtr++; + destPtr++; curWidth++; + if (curWidth >= srcWidth) { curWidth = 0; linePtr += destDesc.getWidth(); destPtr = linePtr; - curHeight++; - if (curHeight >= srcHeight) { + if (++curHeight >= srcHeight) { delete[] memBuffer; return 1; } } + memBuffer[bufPos] = temp; - bufPos++; - bufPos %= 4096; + bufPos = (bufPos + 1) % 4096; } if (strLen >= ((int32) sourceLeft)) { @@ -148,7 +157,9 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, return 1; } else sourceLeft--; + } + } } else return 0; diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp index c51b027bad..6f39edb588 100644 --- a/engines/gob/video_v6.cpp +++ b/engines/gob/video_v6.cpp @@ -84,8 +84,23 @@ char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, return 1; } - warning("Urban Stub: spriteUncompressor(), sprBuf[0,1] = %d,%d", - sprBuf[0], sprBuf[1]); + if (srcWidth & 0xC000) { + warning("Playtoons Stub: srcWidth & 0xC000 == %04X", srcWidth & 0xC000); + srcWidth &= 0x3FFF; + } + + if ((sprBuf[0] == 1) && (sprBuf[1] == 2)) { + if (Video_v2::spriteUncompressor(sprBuf, srcWidth, srcHeight, x, y, transp, destDesc)) + return 1; + + _vm->validateVideoMode(destDesc._vidMode); + + _videoDriver->drawPackedSprite(sprBuf, srcWidth, srcHeight, x, y, transp, destDesc); + return 1; + } + + warning("Urban Stub: spriteUncompressor(), sprBuf[0,1,2] = %d,%d,%d", + sprBuf[0], sprBuf[1], sprBuf[2]); return 1; } diff --git a/engines/groovie/graphics.cpp b/engines/groovie/graphics.cpp index 647eaa913b..1e54f0e79b 100644 --- a/engines/groovie/graphics.cpp +++ b/engines/groovie/graphics.cpp @@ -31,8 +31,8 @@ namespace Groovie { GraphicsMan::GraphicsMan(GroovieEngine *vm) : _vm(vm), _changed(false), _fading(0) { // Create the game surfaces - _foreground.create(640, 320, 1); - _background.create(640, 320, 1); + _foreground.create(640, 320, _vm->_pixelFormat.bytesPerPixel); + _background.create(640, 320, _vm->_pixelFormat.bytesPerPixel); } GraphicsMan::~GraphicsMan() { diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp index 9381b5b47c..bb4e142196 100644 --- a/engines/groovie/groovie.cpp +++ b/engines/groovie/groovie.cpp @@ -70,7 +70,20 @@ GroovieEngine::~GroovieEngine() { Common::Error GroovieEngine::run() { // Initialize the graphics - initGraphics(640, 480, true); + switch (_gameDescription->version) { + case kGroovieV2: + // Request the mode with the highest precision available + initGraphics(640, 480, true, NULL); + + // Save the enabled mode as it can be both an RGB mode or CLUT8 + _pixelFormat = _system->getScreenFormat(); + _mode8bit = (_pixelFormat == Graphics::PixelFormat::createFormatCLUT8()); + break; + case kGroovieT7G: + initGraphics(640, 480, true); + _pixelFormat = Graphics::PixelFormat::createFormatCLUT8(); + break; + } // Create debugger. It requires GFX to be initialized _debugger = new Debugger(this); @@ -204,13 +217,18 @@ Common::Error GroovieEngine::run() { case Common::EVENT_LBUTTONDOWN: // Send the event to the scripts - _script.setMouseClick(); + _script.setMouseClick(1); // Continue the script execution to handle // the click _waitingForInput = false; break; + case Common::EVENT_RBUTTONDOWN: + // Send the event to the scripts (to skip the video) + _script.setMouseClick(2); + break; + case Common::EVENT_QUIT: quitGame(); break; diff --git a/engines/groovie/groovie.h b/engines/groovie/groovie.h index a137193adf..bf57ae77de 100644 --- a/engines/groovie/groovie.h +++ b/engines/groovie/groovie.h @@ -85,6 +85,8 @@ protected: public: void waitForInput(); + Graphics::PixelFormat _pixelFormat; + bool _mode8bit; Script _script; ResMan *_resMan; GrvCursorMan *_grvCursorMan; diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp index 797290a6f3..a92beee17e 100644 --- a/engines/groovie/music.cpp +++ b/engines/groovie/music.cpp @@ -38,6 +38,10 @@ MusicPlayer::MusicPlayer(GroovieEngine *vm) : _prevCDtrack(0), _backgroundDelay(0) { } +MusicPlayer::~MusicPlayer() { + AudioCD.stop(); +} + void MusicPlayer::playSong(uint32 fileref) { Common::StackLock lock(_mutex); diff --git a/engines/groovie/music.h b/engines/groovie/music.h index 9909c8a185..fb1ddfe9c3 100644 --- a/engines/groovie/music.h +++ b/engines/groovie/music.h @@ -37,7 +37,7 @@ namespace Groovie { class MusicPlayer { public: MusicPlayer(GroovieEngine *vm); - virtual ~MusicPlayer() {} + virtual ~MusicPlayer(); void playSong(uint32 fileref); void setBackgroundSong(uint32 fileref); diff --git a/engines/groovie/roq.cpp b/engines/groovie/roq.cpp index dcb8eafcb8..3ff852934d 100644 --- a/engines/groovie/roq.cpp +++ b/engines/groovie/roq.cpp @@ -29,6 +29,12 @@ #include "groovie/groovie.h" #include "groovie/roq.h" +#include "graphics/jpeg.h" + +#ifdef USE_RGB_COLOR +// Required for the YUV to RGB conversion +#include "graphics/conversion.h" +#endif #include "sound/mixer.h" namespace Groovie { @@ -43,50 +49,52 @@ ROQPlayer::ROQPlayer(GroovieEngine *vm) : _currBuf = new Graphics::Surface(); _prevBuf = new Graphics::Surface(); - byte pal[256 * 4]; + if (_vm->_mode8bit) { + byte pal[256 * 4]; #ifdef DITHER - byte pal3[256 * 3]; - // Initialize to a black palette - for (int i = 0; i < 256 * 3; i++) { - pal3[i] = 0; - } - - // Build a basic color palette - for (int r = 0; r < 4; r++) { - for (int g = 0; g < 4; g++) { - for (int b = 0; b < 4; b++) { - byte col = (r << 4) | (g << 2) | (b << 0); - pal3[3 * col + 0] = r << 6; - pal3[3 * col + 1] = g << 6; - pal3[3 * col + 2] = b << 6; + byte pal3[256 * 3]; + // Initialize to a black palette + for (int i = 0; i < 256 * 3; i++) { + pal3[i] = 0; + } + + // Build a basic color palette + for (int r = 0; r < 4; r++) { + for (int g = 0; g < 4; g++) { + for (int b = 0; b < 4; b++) { + byte col = (r << 4) | (g << 2) | (b << 0); + pal3[3 * col + 0] = r << 6; + pal3[3 * col + 1] = g << 6; + pal3[3 * col + 2] = b << 6; + } } } - } - // Initialize the dithering algorithm - _paletteLookup = new Graphics::PaletteLUT(8, Graphics::PaletteLUT::kPaletteYUV); - _paletteLookup->setPalette(pal3, Graphics::PaletteLUT::kPaletteRGB, 8); - for (int i = 0; (i < 64) && !_vm->shouldQuit(); i++) { - debug("Groovie::ROQ: Building palette table: %02d/63", i); - _paletteLookup->buildNext(); - } + // Initialize the dithering algorithm + _paletteLookup = new Graphics::PaletteLUT(8, Graphics::PaletteLUT::kPaletteYUV); + _paletteLookup->setPalette(pal3, Graphics::PaletteLUT::kPaletteRGB, 8); + for (int i = 0; (i < 64) && !_vm->shouldQuit(); i++) { + debug("Groovie::ROQ: Building palette table: %02d/63", i); + _paletteLookup->buildNext(); + } - // Prepare the palette to show - for (int i = 0; i < 256; i++) { - pal[(i * 4) + 0] = pal3[(i * 3) + 0]; - pal[(i * 4) + 1] = pal3[(i * 3) + 1]; - pal[(i * 4) + 2] = pal3[(i * 3) + 2]; - } -#else - // Set a grayscale palette - for (int i = 0; i < 256; i++) { - pal[(i * 4) + 0] = i; - pal[(i * 4) + 1] = i; - pal[(i * 4) + 2] = i; - } -#endif + // Prepare the palette to show + for (int i = 0; i < 256; i++) { + pal[(i * 4) + 0] = pal3[(i * 3) + 0]; + pal[(i * 4) + 1] = pal3[(i * 3) + 1]; + pal[(i * 4) + 2] = pal3[(i * 3) + 2]; + } +#else // !DITHER + // Set a grayscale palette + for (int i = 0; i < 256; i++) { + pal[(i * 4) + 0] = i; + pal[(i * 4) + 1] = i; + pal[(i * 4) + 2] = i; + } +#endif // DITHER - _syst->setPalette(pal, 0, 256); + _syst->setPalette(pal, 0, 256); + } } ROQPlayer::~ROQPlayer() { @@ -152,22 +160,39 @@ void ROQPlayer::buildShowBuf() { for (int line = 0; line < _showBuf.h; line++) { byte *out = (byte *)_showBuf.getBasePtr(0, line); - byte *in = (byte *)_prevBuf->getBasePtr(0, line / _scaleY); + byte *in = (byte *)_currBuf->getBasePtr(0, line / _scaleY); for (int x = 0; x < _showBuf.w; x++) { + if (_vm->_mode8bit) { #ifdef DITHER - *out = _dither->dither(*in, *(in + 1), *(in + 2), x); + *out = _dither->dither(*in, *(in + 1), *(in + 2), x); #else - // Just use the luminancy component - *out = *in; -#endif - out++; + // Just use the luminancy component + *out = *in; +#endif // DITHER +#ifdef USE_RGB_COLOR + } else { + // Do the format conversion (YUV -> RGB -> Screen format) + byte r, g, b; + Graphics::YUV2RGB(*in, *(in + 1), *(in + 2), r, g, b); + // FIXME: this is fixed to 16bit + *(uint16 *)out = (uint16)_vm->_pixelFormat.RGBToColor(r, g, b); +#endif // USE_RGB_COLOR + } + + // Skip to the next pixel + out += _vm->_pixelFormat.bytesPerPixel; if (!(x % _scaleX)) - in += _prevBuf->bytesPerPixel; + in += _currBuf->bytesPerPixel; } #ifdef DITHER _dither->nextLine(); #endif } + + // Swap buffers + Graphics::Surface *tmp = _prevBuf; + _prevBuf = _currBuf; + _currBuf = tmp; } bool ROQPlayer::playFrameInternal() { @@ -180,7 +205,7 @@ bool ROQPlayer::playFrameInternal() { } if (_dirty) { - // Build the show buffer from the previous (back) buffer + // Build the show buffer from the current buffer buildShowBuf(); } @@ -189,7 +214,7 @@ bool ROQPlayer::playFrameInternal() { if (_dirty) { // Update the screen - _syst->copyRectToScreen((byte *)_showBuf.getBasePtr(0, 0), _showBuf.w, 0, (_syst->getHeight() - _showBuf.h) / 2, _showBuf.pitch, _showBuf.h); + _syst->copyRectToScreen((byte *)_showBuf.getBasePtr(0, 0), _showBuf.pitch, 0, (_syst->getHeight() - _showBuf.h) / 2, _showBuf.w, _showBuf.h); _syst->updateScreen(); // Clear the dirty flag @@ -240,19 +265,15 @@ bool ROQPlayer::processBlock() { case 0x1002: // Quad codebook definition ok = processBlockQuadCodebook(blockHeader); break; - case 0x1011: { // Quad vector quantised video frame + case 0x1011: // Quad vector quantised video frame ok = processBlockQuadVector(blockHeader); _dirty = true; endframe = true; - - // Swap buffers - Graphics::Surface *tmp = _prevBuf; - _prevBuf = _currBuf; - _currBuf = tmp; break; - } case 0x1012: // Still image (JPEG) ok = processBlockStill(blockHeader); + _dirty = true; + endframe = true; break; case 0x1013: // Hang assert(blockHeader.size == 0 && blockHeader.param == 0); @@ -317,7 +338,19 @@ bool ROQPlayer::processBlockInfo(ROQBlockHeader &blockHeader) { // Allocate new buffers _currBuf->create(width, height, 3); _prevBuf->create(width, height, 3); - _showBuf.create(width * _scaleX, height * _scaleY, 1); + _showBuf.create(width * _scaleX, height * _scaleY, _vm->_pixelFormat.bytesPerPixel); + + // Clear the buffers with black YUV values + byte *ptr1 = (byte *)_currBuf->getBasePtr(0, 0); + byte *ptr2 = (byte *)_prevBuf->getBasePtr(0, 0); + for (int i = 0; i < width * height; i++) { + *ptr1++ = 0; + *ptr1++ = 128; + *ptr1++ = 128; + *ptr2++ = 0; + *ptr2++ = 128; + *ptr2++ = 128; + } #ifdef DITHER // Reset the dithering algorithm with the new width @@ -456,10 +489,23 @@ void ROQPlayer::processBlockQuadVectorBlockSub(int baseX, int baseY, int8 Mx, in bool ROQPlayer::processBlockStill(ROQBlockHeader &blockHeader) { debugC(5, kGroovieDebugVideo | kGroovieDebugAll, "Groovie::ROQ: Processing still (JPEG) block"); - warning("Groovie::ROQ: JPEG frame (unimplemented)"); - memset(_prevBuf->getBasePtr(0, 0), 0, _prevBuf->w * _prevBuf->h * _prevBuf->bytesPerPixel); + warning("Groovie::ROQ: JPEG frame (unfinshed)"); + + Graphics::JPEG *jpg = new Graphics::JPEG(); + jpg->read(_file); + byte *y = (byte *)jpg->getComponent(1)->getBasePtr(0, 0); + byte *u = (byte *)jpg->getComponent(2)->getBasePtr(0, 0); + byte *v = (byte *)jpg->getComponent(3)->getBasePtr(0, 0); + + byte *ptr = (byte *)_currBuf->getBasePtr(0, 0); + for (int i = 0; i < _currBuf->w * _currBuf->h; i++) { + *ptr++ = *y++; + *ptr++ = *u++; + *ptr++ = *v++; + } + memcpy(_prevBuf->getBasePtr(0, 0), _currBuf->getBasePtr(0, 0), _prevBuf->w * _prevBuf->h * 3); - _file->skip(blockHeader.size); + delete jpg; return true; } diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp index 5ee58184f2..2ef3df56a1 100644 --- a/engines/groovie/script.cpp +++ b/engines/groovie/script.cpp @@ -102,6 +102,7 @@ Script::Script(GroovieEngine *vm, EngineVersion version) : _hotspotSlot = (uint16)-1; _oldInstruction = (uint16)-1; + _videoSkipAddress = 0; } Script::~Script() { @@ -235,8 +236,8 @@ void Script::step() { (this->*op)(); } -void Script::setMouseClick() { - _eventMouseClicked = true; +void Script::setMouseClick(uint8 button) { + _eventMouseClicked = button; } void Script::setKbdChar(uint8 c) { @@ -359,7 +360,7 @@ bool Script::hotspot(Common::Rect rect, uint16 address, uint8 cursor) { Common::isDebugChannelEnabled(kGroovieDebugAll)) { rect.translate(0, -80); _vm->_graphicsMan->_foreground.frameRect(rect, 250); - _vm->_system->copyRectToScreen((byte*)_vm->_graphicsMan->_foreground.getBasePtr(0, 0), 640, 0, 80, 640, 320); + _vm->_system->copyRectToScreen((byte*)_vm->_graphicsMan->_foreground.getBasePtr(0, 0), _vm->_graphicsMan->_foreground.pitch, 0, 80, 640, 320); _vm->_system->updateScreen(); } @@ -559,6 +560,21 @@ bool Script::playvideofromref(uint32 fileref) { } _bitflags = 0; + + // Reset the clicked mouse events + _eventMouseClicked = 0; + } + + // Check if the user wants to skip the video + if ((_eventMouseClicked == 2) && (_videoSkipAddress != 0)) { + // Jump to the given address + _currentInstruction = _videoSkipAddress; + + // Reset the skip address + _videoSkipAddress = 0; + + // End the playback + return true; } // Video available, play one frame @@ -573,7 +589,7 @@ bool Script::playvideofromref(uint32 fileref) { _videoRef = 0; // Clear the input events while playing the video - _eventMouseClicked = false; + _eventMouseClicked = 0; _eventKbdChar = 0; // Newline @@ -604,8 +620,8 @@ void Script::o_inputloopstart() { //0x0B _inputLoopAddress = _currentInstruction - 1; // Save the current mouse state for the whole loop - _mouseClicked = _eventMouseClicked; - _eventMouseClicked = false; + _mouseClicked = (_eventMouseClicked == 1); + _eventMouseClicked = 0; // Save the current pressed character for the whole loop _kbdChar = _eventKbdChar; @@ -1535,20 +1551,19 @@ void Script::o_stub59() { debugScript(1, true, "STUB59: 0x%04X 0x%02X", val1, val2); } -void Script::o2_playsong(){ +void Script::o2_playsong() { uint32 fileref = readScript32bits(); debugScript(1, true, "PlaySong(0x%08X): Play xmidi file", fileref); _vm->_musicPlayer->playSong(fileref); - } -void Script::o2_setbackgroundsong(){ +void Script::o2_setbackgroundsong() { uint32 fileref = readScript32bits(); debugScript(1, true, "SetBackgroundSong(0x%08X)", fileref); _vm->_musicPlayer->setBackgroundSong(fileref); } -void Script::o2_videofromref(){ +void Script::o2_videofromref() { uint32 fileref = readScript32bits(); // Show the debug information just when starting the playback @@ -1556,6 +1571,7 @@ void Script::o2_videofromref(){ debugScript(1, true, "VIDEOFROMREF(0x%08X) (Not fully imp): Play video file from ref", fileref); debugC(5, kGroovieDebugVideo | kGroovieDebugAll, "Playing video 0x%08X via 0x09", fileref); } + // Play the video if (!playvideofromref(fileref)) { // Move _currentInstruction back @@ -1563,7 +1579,7 @@ void Script::o2_videofromref(){ } } -void Script::o2_vdxtransition(){ +void Script::o2_vdxtransition() { uint32 fileref = readScript32bits(); // Show the debug information just when starting the playback @@ -1587,11 +1603,21 @@ void Script::o2_vdxtransition(){ } } -void Script::o2_stub52(){ +void Script::o2_setvideoskip() { + _videoSkipAddress = readScript16bits(); + debugScript(1, true, "SetVideoSkip (0x%04X)", _videoSkipAddress); +} + +void Script::o2_stub52() { uint8 arg = readScript8bits(); debugScript(1, true, "STUB52 (0x%02X)", arg); } +void Script::o2_setscriptend() { + uint16 arg = readScript16bits(); + debugScript(1, true, "SetScriptEnd (0x%04X)", arg); +} + Script::OpcodeFunc Script::_opcodesT7G[NUM_OPCODES] = { &Script::o_nop, // 0x00 &Script::o_nop, @@ -1692,11 +1718,11 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_invalid, // 0x00 &Script::o_nop, &Script::o2_playsong, - &Script::o_bf9on, - &Script::o_palfadeout, // 0x04 - &Script::o_bf8on, - &Script::o_bf6on, - &Script::o_bf7on, + &Script::o_nop, + &Script::o_nop, // 0x04 + &Script::o_nop, + &Script::o_nop, + &Script::o_nop, &Script::o2_setbackgroundsong, // 0x08 &Script::o2_videofromref, &Script::o_bf5on, @@ -1719,7 +1745,7 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_xor_obfuscate, &Script::o2_vdxtransition, // 0x1C &Script::o_swap, - &Script::o_nop8, + &Script::o_invalid, &Script::o_inc, &Script::o_dec, // 0x20 &Script::o_strcmpnejmp_var, @@ -1729,10 +1755,10 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_add, &Script::o_videofromstring1, &Script::o_videofromstring2, - &Script::o_nop16, // 0x28 - &Script::o_stopmidi, - &Script::o_endscript, + &Script::o_invalid, // 0x28 &Script::o_nop, + &Script::o_endscript, + &Script::o_invalid, &Script::o_sethotspottop, // 0x2C &Script::o_sethotspotbottom, &Script::o_loadgame, @@ -1759,22 +1785,22 @@ Script::OpcodeFunc Script::_opcodesV2[NUM_OPCODES] = { &Script::o_returnscript, &Script::o_sethotspotright, // 0x44 &Script::o_sethotspotleft, - &Script::o_nop, - &Script::o_nop, - &Script::o_nop8, // 0x48 - &Script::o_nop, - &Script::o_nop16, - &Script::o_nop8, - &Script::o_getcd, // 0x4C - &Script::o_playcd, + &Script::o_invalid, + &Script::o_invalid, + &Script::o_invalid, // 0x48 + &Script::o_invalid, &Script::o_nop16, + &Script::o_invalid, + &Script::o_invalid, // 0x4C + &Script::o_invalid, + &Script::o_invalid, &Script::o_nop16, &Script::o_nop16, // 0x50 - &Script::o_nop16, + &Script::o2_setvideoskip, &Script::o2_stub52, &Script::o_hotspot_outrect, - &Script::o_nop, // 0x54 - &Script::o_nop16, + &Script::o_invalid, // 0x54 + &Script::o2_setscriptend, &Script::o_stub56, &Script::o_invalid, &Script::o_invalid, // 0x58 diff --git a/engines/groovie/script.h b/engines/groovie/script.h index e9e0be69ec..9e35d6fcde 100644 --- a/engines/groovie/script.h +++ b/engines/groovie/script.h @@ -58,7 +58,7 @@ public: void directGameLoad(int slot); void step(); - void setMouseClick(); + void setMouseClick(uint8 button); void setKbdChar(uint8 c); Common::String &getContext(); @@ -96,7 +96,7 @@ private: // Input bool _mouseClicked; - bool _eventMouseClicked; + uint8 _eventMouseClicked; uint8 _kbdChar; uint8 _eventKbdChar; uint16 _inputLoopAddress; @@ -115,6 +115,7 @@ private: Common::SeekableReadStream *_videoFile; uint32 _videoRef; uint16 _bitflags; + uint16 _videoSkipAddress; // Debugging Debugger *_debugger; @@ -228,7 +229,9 @@ private: void o2_setbackgroundsong(); void o2_videofromref(); void o2_vdxtransition(); + void o2_setvideoskip(); void o2_stub52(); + void o2_setscriptend(); }; } // End of Groovie namespace diff --git a/engines/groovie/vdx.cpp b/engines/groovie/vdx.cpp index bee84b4adb..0bc6acb1c0 100644 --- a/engines/groovie/vdx.cpp +++ b/engines/groovie/vdx.cpp @@ -118,6 +118,7 @@ uint16 VDXPlayer::loadInternal() { bool VDXPlayer::playFrameInternal() { byte currRes = 0x80; + Common::ReadStream *vdxData = 0; while (!_file->eos() && currRes == 0x80) { currRes = _file->readByte(); @@ -130,7 +131,9 @@ bool VDXPlayer::playFrameInternal() { uint8 lengthbits = _file->readByte(); // Read the chunk data and decompress if needed - Common::ReadStream *vdxData = new Common::SubReadStream(_file, compSize); + if (compSize) + vdxData = _file->readStream(compSize); + if (lengthmask && lengthbits) { Common::ReadStream *decompData = new LzssReadStream(vdxData, lengthmask, lengthbits); delete vdxData; @@ -157,7 +160,9 @@ bool VDXPlayer::playFrameInternal() { default: error("Groovie::VDX: Invalid resource type: %d", currRes); } - delete vdxData; + if (vdxData) + delete vdxData; + vdxData = 0; } // Wait until the current frame can be shown diff --git a/engines/kyra/animator_lok.cpp b/engines/kyra/animator_lok.cpp index a05eabe3e1..04c31a1422 100644 --- a/engines/kyra/animator_lok.cpp +++ b/engines/kyra/animator_lok.cpp @@ -37,7 +37,6 @@ Animator_LoK::Animator_LoK(KyraEngine_LoK *vm, OSystem *system) { _vm = vm; _screen = vm->screen(); _initOk = false; - _updateScreen = false; _system = system; _screenObjects = _actors = _items = _sprites = _objectQueue = 0; _noDrawShapesFlag = 0; @@ -382,15 +381,11 @@ void Animator_LoK::copyChangedObjectsForward(int refreshFlag) { _screen->copyRegion(xpos << 3, ypos, xpos << 3, ypos, width << 3, height, 2, 0); curObject->refreshFlag = 0; - _updateScreen = true; } } } - if (_updateScreen) { - _screen->updateScreen(); - _updateScreen = false; - } + _screen->updateScreen(); } void Animator_LoK::updateAllObjectShapes() { diff --git a/engines/kyra/animator_lok.h b/engines/kyra/animator_lok.h index ba5882c710..618a210082 100644 --- a/engines/kyra/animator_lok.h +++ b/engines/kyra/animator_lok.h @@ -95,7 +95,6 @@ public: int16 fetchAnimHeight(const uint8 *shape, int16 mult); int _noDrawShapesFlag; - bool _updateScreen; uint16 _brandonDrawFrame; int _brandonScaleX; int _brandonScaleY; diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index cc1add9ce7..e49085103a 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -232,10 +232,11 @@ void GUI::processHighlights(Menu &menu) { menu.highlightedItem = i; redrawHighlight(menu); - _screen->updateScreen(); } } } + + _screen->updateScreen(); } void GUI::redrawText(const Menu &menu) { @@ -424,7 +425,8 @@ void GUI::checkTextfieldInput() { Common::Point pos = _vm->getMousePos(); _vm->_mouseX = pos.x; _vm->_mouseY = pos.y; - _screen->updateScreen(); + + _vm->_system->updateScreen(); _lastScreenUpdate = now; } break; @@ -490,14 +492,24 @@ bool MainMenu::getInput() { Common::Event event; Common::EventManager *eventMan = _vm->getEventManager(); + bool updateScreen = false; + while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_LBUTTONUP: return true; + + case Common::EVENT_MOUSEMOVE: + updateScreen = true; + break; + default: break; } } + + if (updateScreen) + _system->updateScreen(); return false; } diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp index e9c71f511d..3c5fbe4f1c 100644 --- a/engines/kyra/gui_lok.cpp +++ b/engines/kyra/gui_lok.cpp @@ -522,7 +522,6 @@ int GUI_LoK::buttonMenuCallback(Button *caller) { if (_menuRestoreScreen) { restorePalette(); _screen->loadPageFromDisk("SEENPAGE.TMP", 0); - _vm->_animator->_updateScreen = true; } else { _screen->deletePageFromDisk(0); } diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index 9ee6935384..cf2b360d79 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -439,11 +439,8 @@ void KyraEngine_v1::updateInput() { } } - // TODO: Check whether we should really call Screen::updateScreen here. - // We might simply want to call OSystem::updateScreen instead, since Screen::updateScreen - // copies changed screen parts to the screen buffer, which might not be desired. if (updateScreen) - screen()->updateScreen(); + _system->updateScreen(); } void KyraEngine_v1::removeInputTop() { diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 816e244531..eb313821af 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -65,6 +65,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy case Common::JA_JPN: _lang = 0; + break; default: warning("unsupported language, switching back to English"); diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 1c89a7a1eb..7a112cfd8f 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -366,6 +366,10 @@ private: static const CharacterPrev _charPreviews[]; + // PC98 specific data + static const uint16 _charPosXPC98[]; + static const uint8 _charNamesPC98[][11]; + WSAMovie_v2 *_chargenWSA; static const uint8 _chargenFrameTableTalkie[]; static const uint8 _chargenFrameTableFloppy[]; diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index f5570acd72..6542b15183 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -51,6 +51,7 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system) memset(_fonts, 0, sizeof(_fonts)); _currentFont = FID_8_FNT; + _paletteChanged = true; } Screen::~Screen() { @@ -206,6 +207,9 @@ void Screen::setResolution() { } void Screen::updateScreen() { + bool needRealUpdate = _forceFullUpdate || !_dirtyRects.empty() || _paletteChanged; + _paletteChanged = false; + if (_useOverlays) updateDirtyRectsOvl(); else if (_isAmiga && _interfacePaletteEnabled) @@ -214,13 +218,16 @@ void Screen::updateScreen() { updateDirtyRects(); if (_debugEnabled) { + needRealUpdate = true; + if (!_useOverlays) _system->copyRectToScreen(getPagePtr(2), SCREEN_W, 320, 0, SCREEN_W, SCREEN_H); else _system->copyRectToScreen(getPagePtr(2), SCREEN_W, 640, 0, SCREEN_W, SCREEN_H); } - _system->updateScreen(); + if (needRealUpdate) + _system->updateScreen(); } void Screen::updateDirtyRects() { @@ -330,6 +337,7 @@ void Screen::updateDirtyRectsOvl() { _system->copyRectToScreen(dst, 640, it->left<<1, it->top<<1, it->width()<<1, it->height()<<1); } } + _forceFullUpdate = false; _dirtyRects.clear(); } @@ -562,6 +570,12 @@ void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) { assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H); if (pageNum == 0 || pageNum == 1) addDirtyRect(x, y, 1, 1); + + if (_use16ColorMode) { + color &= 0x0F; + color |= (color << 4); + } + _pagePtrs[pageNum][y * SCREEN_W + x] = color; } @@ -703,6 +717,7 @@ void Screen::setScreenPalette(const Palette &pal) { screenPal[4 * i + 3] = 0; } + _paletteChanged = true; _system->setPalette(screenPal, 0, pal.getNumColors()); } @@ -738,6 +753,7 @@ void Screen::setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b) screenPal[4 * i + 3] = 0; } + _paletteChanged = true; _system->setPalette(screenPal, 32, pal.getNumColors()); } @@ -954,6 +970,11 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum, clearOverlayRect(pageNum, x1, y1, x2-x1+1, y2-y1+1); + if (_use16ColorMode) { + color &= 0x0F; + color |= (color << 4); + } + if (xored) { for (; y1 <= y2; ++y1) { for (int x = x1; x <= x2; ++x) @@ -1035,6 +1056,11 @@ void Screen::drawClippedLine(int x1, int y1, int x2, int y2, int color) { void Screen::drawLine(bool vertical, int x, int y, int length, int color) { uint8 *ptr = getPagePtr(_curPage) + y * SCREEN_W + x; + if (_use16ColorMode) { + color &= 0x0F; + color |= (color << 4); + } + if (vertical) { assert((y + length) <= SCREEN_H); int currLine = 0; @@ -2974,6 +3000,9 @@ byte *Screen::getOverlayPtr(int page) { if (_vm->gameFlags().gameID == GI_KYRA2) { if (page == 12 || page == 13) return _sjisOverlayPtrs[3]; + } else if (_vm->gameFlags().gameID == GI_LOL) { + if (page == 4 || page == 5) + return _sjisOverlayPtrs[3]; } return 0; diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 73a29ee2c7..7553a0132b 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -308,7 +308,6 @@ public: virtual bool init(); virtual void setResolution(); - void updateScreen(); // debug functions @@ -508,6 +507,7 @@ protected: }; bool _forceFullUpdate; + bool _paletteChanged; Common::List<Common::Rect> _dirtyRects; void addDirtyRect(int x, int y, int w, int h); diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp index 1b8c1d32b3..a811952801 100644 --- a/engines/kyra/script_hof.cpp +++ b/engines/kyra/script_hof.cpp @@ -186,20 +186,14 @@ int KyraEngine_HoF::o2_displayWsaFrame(EMCState *script) { int backUp = stackPos(8); _screen->hideMouse(); - uint32 endTime = _system->getMillis() + waitTime * _tickLength; + const uint32 endTime = _system->getMillis() + waitTime * _tickLength; _wsaSlots[slot]->displayFrame(frame, dstPage, x, y, copyParam | 0xC000, 0, 0); _screen->updateScreen(); if (backUp) memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); - while (_system->getMillis() < endTime) { - if (doUpdate) - update(); - - if (endTime - _system->getMillis() >= 10) - delay(10); - } + delayUntil(endTime, false, doUpdate != 0); _screen->showMouse(); return 0; } @@ -224,34 +218,22 @@ int KyraEngine_HoF::o2_displayWsaSequentialFramesLooping(EMCState *script) { while (curTime < maxTimes) { if (startFrame < endFrame) { for (int i = startFrame; i <= endFrame; ++i) { - uint32 endTime = _system->getMillis() + waitTime * _tickLength; + const uint32 endTime = _system->getMillis() + waitTime * _tickLength; _wsaSlots[slot]->displayFrame(i, 0, x, y, 0xC000 | copyFlags, 0, 0); if (!skipFlag()) { _screen->updateScreen(); - - do { - update(); - - if (endTime - _system->getMillis() >= 10) - delay(10); - } while (_system->getMillis() < endTime); + delayUntil(endTime, false, true); } } } else { for (int i = startFrame; i >= endFrame; --i) { - uint32 endTime = _system->getMillis() + waitTime * _tickLength; + const uint32 endTime = _system->getMillis() + waitTime * _tickLength; _wsaSlots[slot]->displayFrame(i, 0, x, y, 0xC000 | copyFlags, 0, 0); if (!skipFlag()) { _screen->updateScreen(); - - do { - update(); - - if (endTime - _system->getMillis() >= 10 && !skipFlag()) - delay(10); - } while (_system->getMillis() < endTime && !skipFlag()); + delayUntil(endTime, false, true); } } } @@ -282,7 +264,7 @@ int KyraEngine_HoF::o2_displayWsaSequentialFrames(EMCState *script) { _screen->hideMouse(); while (currentFrame <= lastFrame) { - uint32 endTime = _system->getMillis() + frameDelay; + const uint32 endTime = _system->getMillis() + frameDelay; _wsaSlots[index]->displayFrame(currentFrame++, 0, stackPos(0), stackPos(1), copyParam, 0, 0); if (!skipFlag()) { _screen->updateScreen(); @@ -310,7 +292,7 @@ int KyraEngine_HoF::o2_displayWsaSequence(EMCState *script) { const int lastFrame = _wsaSlots[index]->frames(); while (currentFrame <= lastFrame) { - uint32 endTime = _system->getMillis() + frameDelay; + const uint32 endTime = _system->getMillis() + frameDelay; _wsaSlots[index]->displayFrame(currentFrame++, 0, stackPos(0), stackPos(1), copyParam, 0, 0); if (!skipFlag()) { if (doUpdate) diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp index a778a2066b..0a96db8277 100644 --- a/engines/kyra/script_lok.cpp +++ b/engines/kyra/script_lok.cpp @@ -429,22 +429,13 @@ int KyraEngine_LoK::o1_runWSAFromBeginningToEnd(EMCState *script) { int wsaFrame = 0; while (running) { + const uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + _movieObjects[wsaIndex]->displayFrame(wsaFrame++, 0, xpos, ypos, 0, 0, 0); - _animator->_updateScreen = true; if (wsaFrame >= _movieObjects[wsaIndex]->frames()) running = false; - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - while (_system->getMillis() < continueTime) { - if (worldUpdate) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - } else { - _screen->updateScreen(); - } - if (continueTime - _system->getMillis() >= 10) - delay(10); - } + delayUntil(continueTime, false, worldUpdate != 0); } _screen->showMouse(); @@ -460,18 +451,9 @@ int KyraEngine_LoK::o1_displayWSAFrame(EMCState *script) { int waitTime = stackPos(3); int wsaIndex = stackPos(4); _screen->hideMouse(); + const uint32 continueTime = waitTime * _tickLength + _system->getMillis(); _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos, 0, 0, 0); - _animator->_updateScreen = true; - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (skipFlag()) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } + delayUntil(continueTime, false, true); _screen->showMouse(); return 0; } @@ -501,15 +483,9 @@ int KyraEngine_LoK::o1_runWSAFrames(EMCState *script) { int wsaIndex = stackPos(5); _screen->hideMouse(); for (; startFrame <= endFrame; ++startFrame) { - uint32 nextRun = _system->getMillis() + delayTime * _tickLength; + const uint32 nextRun = _system->getMillis() + delayTime * _tickLength; _movieObjects[wsaIndex]->displayFrame(startFrame, 0, xpos, ypos, 0, 0, 0); - _animator->_updateScreen = true; - while (_system->getMillis() < nextRun) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (nextRun - _system->getMillis() >= 10) - delay(10); - } + delayUntil(nextRun, false, true); } _screen->showMouse(); return 0; @@ -597,7 +573,6 @@ int KyraEngine_LoK::o1_setCustomPaletteRange(EMCState *script) { int KyraEngine_LoK::o1_loadPageFromDisk(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); _screen->loadPageFromDisk(stackPosString(0), stackPos(1)); - _animator->_updateScreen = true; return 0; } @@ -665,7 +640,6 @@ int KyraEngine_LoK::o1_copyWSARegion(EMCState *script) { int srcPage = stackPos(4); int dstPage = stackPos(5); _screen->copyRegion(xpos, ypos, xpos, ypos, width, height, srcPage, dstPage); - _animator->_updateScreen = true; return 0; } @@ -693,18 +667,9 @@ int KyraEngine_LoK::o1_displayWSAFrameOnHidPage(EMCState *script) { int wsaIndex = stackPos(4); _screen->hideMouse(); - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + const uint32 continueTime = waitTime * _tickLength + _system->getMillis(); _movieObjects[wsaIndex]->displayFrame(frame, 2, xpos, ypos, 0, 0, 0); - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (skipFlag()) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } + delayUntil(continueTime, false, true); _screen->showMouse(); return 0; @@ -776,37 +741,17 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) { if (endFrame >= startFrame) { int frame = startFrame; while (endFrame >= frame) { - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + const uint32 continueTime = waitTime * _tickLength + _system->getMillis(); _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos, 0, 0, 0); - if (waitTime) - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (skipFlag()) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } + delayUntil(continueTime, false, true); ++frame; } } else { int frame = startFrame; while (endFrame <= frame) { - uint32 continueTime = waitTime * _tickLength + _system->getMillis(); + const uint32 continueTime = waitTime * _tickLength + _system->getMillis(); _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos, 0, 0, 0); - if (waitTime) - _animator->_updateScreen = true; - while (_system->getMillis() < continueTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (skipFlag()) - break; - - if (continueTime - _system->getMillis() >= 10) - delay(10); - } + delayUntil(continueTime, false, true); --frame; } } @@ -1060,16 +1005,7 @@ int KyraEngine_LoK::o1_walkCharacterToPoint(EMCState *script) { setCharacterPosition(character, 0); ++curPos; - nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(); - while (_system->getMillis() < nextFrame) { - _sprites->updateSceneAnims(); - updateMousePointer(); - _timer->update(); - _animator->updateAllObjectShapes(); - updateTextFade(); - if ((nextFrame - _system->getMillis()) >= 10) - delay(10); - } + delayUntil(nextFrame = _timer->getDelay(5 + character) * _tickLength + _system->getMillis(), true, true); } return 0; } @@ -1318,9 +1254,8 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) { assert(_amuleteAnim); _screen->hideMouse(); snd_playSoundEffect(0x70); - uint32 nextTime = 0; for (int i = 0; _amuleteAnim[i] != 0xFF; ++i) { - nextTime = _system->getMillis() + 5 * _tickLength; + const uint32 nextTime = _system->getMillis() + 5 * _tickLength; uint8 code = _amuleteAnim[i]; if (code == 3 || code == 7) @@ -1333,14 +1268,7 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) { snd_playSoundEffect(0x73); amulet->displayFrame(code, 0, 224, 152, 0, 0, 0); - _animator->_updateScreen = true; - - while (_system->getMillis() < nextTime) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (nextTime - _system->getMillis() >= 10) - delay(10); - } + delayUntil(nextTime, false, true); } _screen->showMouse(); } diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp index 819bf838ca..9943fe419d 100644 --- a/engines/kyra/script_mr.cpp +++ b/engines/kyra/script_mr.cpp @@ -266,7 +266,7 @@ int KyraEngine_MR::o3_wipeDownMouseItem(EMCState *script) { for (int curY = y, height = 20; height > 0; height -= 2, curY += 2) { restoreGfxRect32x32(x, y); _screen->setNewShapeHeight(shape, height); - uint32 waitTime = _system->getMillis() + _tickLength; + const uint32 waitTime = _system->getMillis() + _tickLength; _screen->drawShape(0, shape, x, curY, 0, 0); _screen->updateScreen(); delayUntil(waitTime); @@ -1131,15 +1131,7 @@ int KyraEngine_MR::o3d_updateAnim(EMCState *script) { int KyraEngine_MR::o3d_delay(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3d_delay(%p) (%d)", (const void *)script, stackPos(0)); - const uint32 endTime = _system->getMillis() + stackPos(0) * _tickLength; - while (_system->getMillis() < endTime) { - if (_chatText) - updateWithText(); - else - update(); - - _system->delayMillis(10); - } + delayUntil(_system->getMillis() + stackPos(0) * _tickLength, false, true); return 0; } diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index 26c09bcf43..16c9b75f3a 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -1952,7 +1952,6 @@ void KyraEngine_LoK::updateKyragemFading() { } _screen->setScreenPalette(_screen->getPalette(0)); - _animator->_updateScreen = true; switch (_kyragemFadingState.nextOperation) { case 0: diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp index c1ceba34e9..3b061e5062 100644 --- a/engines/kyra/sequences_lol.cpp +++ b/engines/kyra/sequences_lol.cpp @@ -289,18 +289,56 @@ int LoLEngine::chooseCharacter() { _screen->setFont(Screen::FID_9_FNT); _screen->_curPage = 2; - for (int i = 0; i < 4; ++i) - _screen->fprintStringIntro("%s", _charPreviews[i].x + 16, _charPreviews[i].y + 36, 0xC0, 0x00, 0x9C, 0x120, _charPreviews[i].name); + if (_flags.platform == Common::kPlatformPC98) { + _screen->fillRect(17, 29, 94, 97, 17); + _screen->fillRect(68, 167, 310, 199, 17); + _screen->drawClippedLine(68, 166, 311, 166, 238); + _screen->drawClippedLine(68, 166, 68, 199, 238); + _screen->drawClippedLine(311, 166, 311, 199, 238); - for (int i = 0; i < 4; ++i) { - _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 48, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[0]); - _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 56, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[1]); - _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 64, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[2]); - } + _screen->_curPage = 4; + _screen->fillRect(17, 29, 94, 97, 17); + _screen->_curPage = 2; + + for (int i = 0; i < 4; ++i) { + _screen->printText((const char *)_charNamesPC98[i], _charPosXPC98[i], 168, 0xC1, 0x00); + + // Since our SJIS font does not support ASCII digits currently, we have to use the + // digits from the SJIS range, which looks different to the original. + for (int j = 0; j < 3; ++j) { + uint8 buffer[5]; + snprintf((char *)buffer, 5, "%2d", _charPreviews[i].attrib[j]); + + buffer[3] = buffer[1] - '0' + 0x4F; + buffer[2] = 0x82; + if (buffer[0] != ' ') { + buffer[1] = buffer[0] - '0' + 0x4F; + buffer[0] = 0x82; + } else { + buffer[1] = 0x40; + buffer[0] = 0x81; + } + buffer[4] = 0x00; + + _screen->printText((const char *)buffer, _charPosXPC98[i] + 16, 176 + j * 8, 0x81, 0x00); + } + } - _screen->fprintStringIntro("%s", 36, 173, 0x98, 0x00, 0x9C, 0x20, _tim->getCTableEntry(51)); - _screen->fprintStringIntro("%s", 36, 181, 0x98, 0x00, 0x9C, 0x20, _tim->getCTableEntry(53)); - _screen->fprintStringIntro("%s", 36, 189, 0x98, 0x00, 0x9C, 0x20, _tim->getCTableEntry(55)); + _screen->printText(_tim->getCTableEntry(51), 72, 176, 0x81, 0x00); + _screen->printText(_tim->getCTableEntry(53), 72, 184, 0x81, 0x00); + _screen->printText(_tim->getCTableEntry(55), 72, 192, 0x81, 0x00); + } else { + for (int i = 0; i < 4; ++i) { + _screen->fprintStringIntro("%s", _charPreviews[i].x + 16, _charPreviews[i].y + 36, 0xC0, 0x00, 0x9C, 0x120, _charPreviews[i].name); + _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 48, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[0]); + _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 56, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[1]); + _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 64, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[2]); + } + + _screen->fprintStringIntro("%s", 36, 173, 0x98, 0x00, 0x9C, 0x20, _tim->getCTableEntry(51)); + _screen->fprintStringIntro("%s", 36, 181, 0x98, 0x00, 0x9C, 0x20, _tim->getCTableEntry(53)); + _screen->fprintStringIntro("%s", 36, 189, 0x98, 0x00, 0x9C, 0x20, _tim->getCTableEntry(55)); + } _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); _screen->_curPage = 0; @@ -337,6 +375,8 @@ int LoLEngine::chooseCharacter() { } else { break; } + + delay(10); } if (shouldQuit()) @@ -363,11 +403,13 @@ void LoLEngine::kingSelectionIntro() { _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); int y = 38; - _screen->fprintStringIntro("%s", 8, y, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(57)); - _screen->fprintStringIntro("%s", 8, y + 10, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(58)); - _screen->fprintStringIntro("%s", 8, y + 20, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(59)); - _screen->fprintStringIntro("%s", 8, y + 30, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(60)); - _screen->fprintStringIntro("%s", 8, y + 40, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(61)); + if (_flags.platform == Common::kPlatformPC98) { + for (int i = 0; i < 5; ++i) + _screen->printText(_tim->getCTableEntry(57 + i), 16, 32 + i * 8, 0xC1, 0x00); + } else { + for (int i = 0; i < 5; ++i) + _screen->fprintStringIntro("%s", 8, y + i * 10, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(57 + i)); + } _sound->voicePlay("KING01", &_speechHandle); @@ -405,8 +447,13 @@ void LoLEngine::kingSelectionReminder() { _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); int y = 48; - _screen->fprintStringIntro("%s", 8, y, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(62)); - _screen->fprintStringIntro("%s", 8, y + 10, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(63)); + if (_flags.platform == Common::kPlatformPC98) { + _screen->printText(_tim->getCTableEntry(62), 16, 32, 0xC1, 0x00); + _screen->printText(_tim->getCTableEntry(63), 16, 40, 0xC1, 0x00); + } else { + _screen->fprintStringIntro("%s", 8, y, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(62)); + _screen->fprintStringIntro("%s", 8, y + 10, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(63)); + } _sound->voicePlay("KING02", &_speechHandle); @@ -540,13 +587,17 @@ int LoLEngine::selectionCharInfo(int character) { static const uint8 charSelectInfoIdx[] = { 0x1D, 0x22, 0x27, 0x2C }; const int idx = charSelectInfoIdx[character]; - _screen->fprintStringIntro("%s", 50, 127, 0x53, 0x00, 0xCF, 0x20, _tim->getCTableEntry(idx+0)); - _screen->fprintStringIntro("%s", 50, 137, 0x53, 0x00, 0xCF, 0x20, _tim->getCTableEntry(idx+1)); - _screen->fprintStringIntro("%s", 50, 147, 0x53, 0x00, 0xCF, 0x20, _tim->getCTableEntry(idx+2)); - _screen->fprintStringIntro("%s", 50, 157, 0x53, 0x00, 0xCF, 0x20, _tim->getCTableEntry(idx+3)); - _screen->fprintStringIntro("%s", 50, 167, 0x53, 0x00, 0xCF, 0x20, _tim->getCTableEntry(idx+4)); + if (_flags.platform == Common::kPlatformPC98) { + for (int i = 0; i < 5; ++i) + _screen->printText(_tim->getCTableEntry(idx+i), 60, 128 + i * 8, 0x41, 0x00); + + _screen->printText(_tim->getCTableEntry(69), 112, 168, 0x01, 0x00); + } else { + for (int i = 0; i < 5; ++i) + _screen->fprintStringIntro("%s", 50, 127 + i * 10, 0x53, 0x00, 0xCF, 0x20, _tim->getCTableEntry(idx+i)); - _screen->fprintStringIntro("%s", 100, 168, 0x32, 0x00, 0xCF, 0x20, _tim->getCTableEntry(69)); + _screen->fprintStringIntro("%s", 100, 168, 0x32, 0x00, 0xCF, 0x20, _tim->getCTableEntry(69)); + } selectionCharInfoIntro(vocFilename); if (_charSelectionInfoResult == -1) { @@ -568,11 +619,13 @@ int LoLEngine::selectionCharInfo(int character) { _screen->copyRegion(48, 127, 48, 160, 272, 35, 4, 0, Screen::CR_NO_P_CHECK); _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); - _screen->fprintStringIntro("%s", 3, 28, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(64)); - _screen->fprintStringIntro("%s", 3, 38, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(65)); - _screen->fprintStringIntro("%s", 3, 48, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(66)); - _screen->fprintStringIntro("%s", 3, 58, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(67)); - _screen->fprintStringIntro("%s", 3, 68, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(68)); + if (_flags.platform == Common::kPlatformPC98) { + for (int i = 0; i < 5; ++i) + _screen->printText(_tim->getCTableEntry(64+i), 16, 32 + i * 8, 0xC1, 0x00); + } else { + for (int i = 0; i < 5; ++i) + _screen->fprintStringIntro("%s", 3, 28 + i * 10, 0x32, 0x00, 0x9C, 0x20, _tim->getCTableEntry(64+i)); + } resetSkipFlag(); kingSelectionOutro(); @@ -875,20 +928,15 @@ void HistoryPlayer::play() { while (sound->voiceIsPlaying() && !_vm->shouldQuit() && !_vm->skipFlag()) _vm->delay(10); - if (_vm->skipFlag()) { + if (_vm->skipFlag()) sound->voiceStop(); - _vm->resetSkipFlag(); - } ++voiceFilename[4]; } - - if (_vm->skipFlag()) - _vm->resetSkipFlag(); } if (_vm->skipFlag()) - _vm->resetSkipFlag(); + _vm->_eventList.clear(); pal.fill(0, 256, 63); if (_fireWsa->opened()) @@ -899,6 +947,9 @@ void HistoryPlayer::play() { _screen->clearPage(0); pal.fill(0, 256, 0); _screen->fadePalette(pal, 0x3C); + + if (_vm->skipFlag()) + _vm->_eventList.clear(); } void HistoryPlayer::loadWsa(const char *filename) { diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index d4882a12af..be73df47f7 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -3208,6 +3208,17 @@ const LoLEngine::CharacterPrev LoLEngine::_charPreviews[] = { { "Conrad", 0x10F, 0x7F, { 0x0A, 0x0C, 0x0A } } }; +const uint16 LoLEngine::_charPosXPC98[] = { + 92, 152, 212, 268 +}; + +const uint8 LoLEngine::_charNamesPC98[][11] = { + { 0x83, 0x41, 0x83, 0x4E, 0x83, 0x56, 0x83, 0x46, 0x83, 0x8B, 0x00 }, + { 0x83, 0x7D, 0x83, 0x43, 0x83, 0x50, 0x83, 0x8B, 0x00, 0x00, 0x00 }, + { 0x83, 0x4C, 0x81, 0x5B, 0x83, 0x89, 0x83, 0x93, 0x00, 0x00, 0x00 }, + { 0x83, 0x52, 0x83, 0x93, 0x83, 0x89, 0x83, 0x62, 0x83, 0x68, 0x00 } +}; + const uint8 LoLEngine::_chargenFrameTableTalkie[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x03, 0x02, 0x01, diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp index d2128b7037..178966196c 100644 --- a/engines/kyra/text_lok.cpp +++ b/engines/kyra/text_lok.cpp @@ -97,7 +97,6 @@ void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const currPage = _screen->_curPage; _screen->_curPage = 2; _text->printCharacterText(chatStr, charNum, _characterList[charNum].x1); - _animator->_updateScreen = true; _screen->_curPage = currPage; } diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp index 7eb76cad32..e921b93384 100644 --- a/engines/lure/res.cpp +++ b/engines/lure/res.cpp @@ -550,6 +550,7 @@ void Resources::setTalkingCharacter(uint16 id) { uint16 englishLoadOffsets[] = {0x3afe, 0x41BD, 0x7167, 0x7172, 0x8617, 0x88ac, 0}; Hotspot *Resources::activateHotspot(uint16 hotspotId) { + Resources &resources = Resources::getReference(); HotspotData *res = getHotspot(hotspotId); if (!res) return NULL; res->roomNumber &= 0x7fff; // clear any suppression bit in room # @@ -561,7 +562,6 @@ Hotspot *Resources::activateHotspot(uint16 hotspotId) { // If it's NPC with a schedule, then activate the schedule if ((res->npcScheduleId != 0) && (res->npcSchedule.isEmpty())) { - Resources &resources = Resources::getReference(); CharacterScheduleEntry *entry = resources.charSchedules().getEntry(res->npcScheduleId); res->npcSchedule.addFront(DISPATCH_ACTION, entry, res->roomNumber); } @@ -621,9 +621,12 @@ Hotspot *Resources::activateHotspot(uint16 hotspotId) { // Special post-load handling if (res->loadOffset == 3) hotspot->setPersistant(true); if (res->loadOffset == 5) hotspot->handleTalkDialog(); - if (hotspotId == CASTLE_SKORL_ID) + if (hotspotId == CASTLE_SKORL_ID) { // The Castle skorl has a default room #99, so it needs to be adjusted dynamically - res->npcSchedule.top().setRoomNumber(res->roomNumber); + res->npcSchedule.clear(); + CharacterScheduleEntry *entry = resources.charSchedules().getEntry(res->npcScheduleId); + res->npcSchedule.addFront(DISPATCH_ACTION, entry, res->roomNumber); + } // TODO: Figure out why there's a room set in the animation decode for a range of characters, // particularly since it doesn't seem to match what happens in-game diff --git a/engines/m4/script.h b/engines/m4/script.h index 63dc32958b..2eb608ccbb 100644 --- a/engines/m4/script.h +++ b/engines/m4/script.h @@ -119,9 +119,17 @@ public: ~ScriptDataCache() { clear(); } + + // WORKAROUND: The old prototype for this function was: + // template<class T> T *load(Common::File *fd, uint32 ofs); + // that caused a parser error in g++ 3.3.6 used by our + // "motoezx" target of our buildbot. The actual parser + // error happended, when calling the function like this: + // "T *result = _dataCache->load<T>(_scriptFile, _data[value.value]->offset);" + // in ScriptInterpreter::toData. To work around this + // we moved the return value as parameter instead. template<class T> - T *load(Common::File *fd, uint32 ofs) { - T *item; + void load(Common::File *fd, uint32 ofs, T *&item) { if (_cache.contains(ofs)) { item = (T*)(_cache[ofs]); } else { @@ -130,7 +138,6 @@ public: item->load(fd); _cache[ofs] = item; } - return item; } void clear() { // TODO: Free all cached items @@ -300,7 +307,8 @@ public: const T& toData(const ScriptValue &value) { printf("ScriptInterpreter::toData() index = %d; type = %d; max = %d\n", value.value, _data[value.value]->type, _data.size()); assert((uint32)value.value < _data.size()); - T *result = _dataCache->load<T>(_scriptFile, _data[value.value]->offset); + T *result = 0; + _dataCache->load(_scriptFile, _data[value.value]->offset, result); return *result; } diff --git a/engines/made/made.cpp b/engines/made/made.cpp index c83f7aaf02..e826e3788a 100644 --- a/engines/made/made.cpp +++ b/engines/made/made.cpp @@ -127,6 +127,8 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng } MadeEngine::~MadeEngine() { + AudioCD.stop(); + delete _rnd; delete _pmvPlayer; delete _res; diff --git a/engines/made/pmvplayer.cpp b/engines/made/pmvplayer.cpp index 9796b01dfc..a6ee649eda 100644 --- a/engines/made/pmvplayer.cpp +++ b/engines/made/pmvplayer.cpp @@ -62,12 +62,8 @@ bool PmvPlayer::play(const char *filename) { } uint frameDelay = _fd->readUint16LE(); - int unk; _fd->skip(4); // always 0? - unk = _fd->readByte(); - debug(2, "%i", unk); - unk = _fd->readByte(); - debug(2, "%i", unk); + uint frameCount = _fd->readUint16LE(); _fd->skip(4); // always 0? uint soundFreq = _fd->readUint16LE(); @@ -80,7 +76,7 @@ bool PmvPlayer::play(const char *filename) { if (soundFreq == 22254) soundFreq = 22050; for (int i = 0; i < 22; i++) { - unk = _fd->readUint16LE(); + int unk = _fd->readUint16LE(); debug(2, "%i ", unk); } @@ -90,7 +86,7 @@ bool PmvPlayer::play(const char *filename) { _fd->read(_paletteRGB, 768); _vm->_screen->setRGBPalette(_paletteRGB); - uint32 frameCount = 0; + uint32 frameNumber = 0; uint16 chunkCount = 0; uint32 soundSize = 0; uint32 soundChunkOfs = 0, palChunkOfs = 0; @@ -108,7 +104,7 @@ bool PmvPlayer::play(const char *filename) { // get it to work well? _audioStream = Audio::makeAppendableAudioStream(soundFreq, Audio::Mixer::FLAG_UNSIGNED); - while (!_vm->shouldQuit() && !_aborted && !_fd->eos()) { + while (!_vm->shouldQuit() && !_aborted && !_fd->eos() && frameNumber < frameCount) { int32 frameTime = _vm->_system->getMillis(); @@ -117,9 +113,6 @@ bool PmvPlayer::play(const char *filename) { warning("Unknown chunk type"); } - if (_fd->eos()) - break; - // Only reallocate the frame data buffer if its size has changed if (prevChunkSize != chunkSize || !frameData) { if (frameData) @@ -192,7 +185,7 @@ bool PmvPlayer::play(const char *filename) { updateScreen(); if (skipFrames == 0) { - int32 waitTime = (frameCount * frameDelay) - + int32 waitTime = (frameNumber * frameDelay) - (g_system->getMillis() - soundStartTime) - (_vm->_system->getMillis() - frameTime); if (waitTime < 0) { @@ -204,7 +197,7 @@ bool PmvPlayer::play(const char *filename) { } else skipFrames--; - frameCount++; + frameNumber++; } diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp index c7d15dae73..72aa006c68 100644 --- a/engines/made/resource.cpp +++ b/engines/made/resource.cpp @@ -525,7 +525,10 @@ bool ResourceReader::loadResource(ResourceSlot *slot, byte *&buffer, uint32 &siz ResourceSlot *ResourceReader::getResourceSlot(uint32 resType, uint index) { ResourceSlots *slots = _resSlots[resType]; - assert(slots); + + if (!slots) + return NULL; + if (index >= 1 && index < slots->size()) { return &(*slots)[index]; } else { diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp index d55b663296..7471743ba4 100644 --- a/engines/made/screen.cpp +++ b/engines/made/screen.cpp @@ -188,7 +188,7 @@ void Screen::drawSurface(Graphics::Surface *sourceSurface, int x, int y, int16 f if (flipX) { linePtrAdd = -1; - sourceAdd = sourceSurface->w; + sourceAdd = sourceSurface->w - 1; } else { linePtrAdd = 1; sourceAdd = 0; @@ -210,6 +210,7 @@ void Screen::drawSurface(Graphics::Surface *sourceSurface, int x, int y, int16 f } linePtr += linePtrAdd; } + source += sourcePitch; dest += clipInfo.destSurface->pitch; if (_vm->getGameID() != GID_RTZ) diff --git a/engines/saga/actor.h b/engines/saga/actor.h index d998c65240..57d06e9e3a 100644 --- a/engines/saga/actor.h +++ b/engines/saga/actor.h @@ -183,8 +183,8 @@ enum DragonMoveTypes { struct PathDirectionData { int8 direction; - int x; - int y; + int16 x; + int16 y; }; struct ActorFrameRange { diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index 27566de2c3..8ca946a127 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -41,190 +41,6 @@ namespace Saga { #define BUFFER_SIZE 4096 #define MUSIC_SUNSPOT 26 -class DigitalMusicInputStream : public Audio::AudioStream { -private: - Audio::AudioStream *_compressedStream; - ResourceContext *_context; - ResourceData * resourceData; - GameSoundTypes soundType; - Common::File *_file; - uint32 _filePos; - uint32 _startPos; - uint32 _endPos; - bool _finished; - bool _looping; - int16 _buf[BUFFER_SIZE]; - const int16 *_bufferEnd; - const int16 *_pos; - MemoryReadStream *_memoryStream; - SagaEngine *_vm; - - void refill(); - bool eosIntern() const { - return _pos >= _bufferEnd; - } - -public: - DigitalMusicInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart); - ~DigitalMusicInputStream(); - - void createCompressedStream(); - - int readBuffer(int16 *buffer, const int numSamples); - - bool endOfData() const { return eosIntern(); } - bool isStereo() const { - // The digital music in the ITE Mac demo version is not stereo - return _vm->getFeatures() & GF_MONO_MUSIC ? false : true; - } - int getRate() const { return 11025; } -}; - -DigitalMusicInputStream::DigitalMusicInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart) - : _vm(vm), _context(context), _finished(false), _looping(looping), _bufferEnd(_buf + BUFFER_SIZE) { - - byte compressedHeader[10]; - - resourceData = context->getResourceData(resourceId); - _file = context->getFile(resourceData); - - _compressedStream = NULL; - - if (context->isCompressed) { - // Read compressed header to determine compression type - _file->seek((long)resourceData->offset, SEEK_SET); - _file->read(compressedHeader, 9); - - if (compressedHeader[0] == char(0)) { - soundType = kSoundMP3; - } else if (compressedHeader[0] == char(1)) { - soundType = kSoundOGG; - } else if (compressedHeader[0] == char(2)) { - soundType = kSoundFLAC; - } - - createCompressedStream(); - } - - // Determine the end position - _filePos = resourceData->offset; - _endPos = _filePos + resourceData->size; - - if (_compressedStream != NULL) { - _filePos += 9; // skip compressed header - _endPos -= 9; // decrease size by the size of the compressed header - } - - _startPos = _filePos + loopStart; - if (_startPos >= _endPos) - _startPos = _filePos; - - // Read in initial data - refill(); -} - -DigitalMusicInputStream::~DigitalMusicInputStream() { - delete _compressedStream; -} - -void DigitalMusicInputStream::createCompressedStream() { -#if defined(USE_MAD) || defined(USE_VORBIS) || defined(USE_FLAC) - uint numLoops = _looping ? 0 : 1; -#endif - _memoryStream = _file->readStream(resourceData->size - 9); - - switch (soundType) { -#ifdef USE_MAD - case kSoundMP3: - debug(1, "Playing MP3 compressed digital music"); - _compressedStream = Audio::makeMP3Stream(_memoryStream, true, 0, 0, numLoops); - break; -#endif -#ifdef USE_VORBIS - case kSoundOGG: - debug(1, "Playing OGG compressed digital music"); - _compressedStream = Audio::makeVorbisStream(_memoryStream, true, 0, 0, numLoops); - break; -#endif -#ifdef USE_FLAC - case kSoundFLAC: - debug(1, "Playing FLAC compressed digital music"); - _compressedStream = Audio::makeFlacStream(_memoryStream, true, 0, 0, numLoops); - break; -#endif - default: - // Unknown compression - error("Trying to play compressed digital music, but the compression is not known"); - break; - } -} - -int DigitalMusicInputStream::readBuffer(int16 *buffer, const int numSamples) { - if (_compressedStream != NULL) - return _compressedStream->readBuffer(buffer, numSamples); - - int samples = 0; - int len = 0; - - while (samples < numSamples && !eosIntern()) { - len = MIN(numSamples - samples, (int) (_bufferEnd - _pos)); - memcpy(buffer, _pos, len * 2); - buffer += len; - _pos += len; - samples += len; - if (_pos >= _bufferEnd) - refill(); - } - return samples; -} - -void DigitalMusicInputStream::refill() { - if (_finished) - return; - - uint32 lengthLeft; - byte *ptr = (byte *) _buf; - - _file->seek(_filePos, SEEK_SET); - - if (_looping) - lengthLeft = 2 * BUFFER_SIZE; - else - lengthLeft = MIN((uint32) (2 * BUFFER_SIZE), _endPos - _filePos); - - while (lengthLeft > 0) { - uint32 len = _file->read(ptr, MIN(lengthLeft, _endPos - _file->pos())); - - if (len & 1) - len--; - -#ifdef SCUMM_BIG_ENDIAN - if (!_context->isBigEndian) { -#else - if (_context->isBigEndian) { -#endif - uint16 *ptr16 = (uint16 *)ptr; - for (uint32 i = 0; i < (len / 2); i++) - ptr16[i] = SWAP_BYTES_16(ptr16[i]); - } - - lengthLeft -= len; - ptr += len; - - if (lengthLeft > 0) - _file->seek(_startPos); - } - - _filePos = _file->pos(); - _pos = _buf; - _bufferEnd = (int16 *)ptr; - - if (!_looping && _filePos >= _endPos) { - _finished = true; - } -} - - MusicPlayer::MusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false) { memset(_channel, 0, sizeof(_channel)); _masterVolume = 0; @@ -461,9 +277,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) { sprintf(trackName[1], "track%02d", realTrackNumber); Audio::AudioStream *stream = 0; for (int i = 0; i < 2; ++i) { - // We multiply by 40 / 3 = 1000 / 75 to convert frames to milliseconds - // FIXME: Do we really want a duration of 10000 frames = 133 seconds, or is that just a random value? - stream = Audio::AudioStream::openStreamFile(trackName[i], 0, 10000 * 40 / 3, (flags == MUSIC_LOOP) ? 0 : 1); + stream = Audio::AudioStream::openStreamFile(trackName[i], 0, 0, (flags == MUSIC_LOOP) ? 0 : 1); if (stream) { _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream); _digitalMusic = true; @@ -474,15 +288,48 @@ void Music::play(uint32 resourceId, MusicFlags flags) { if (_vm->getGameId() == GID_ITE) { if (resourceId >= 9 && resourceId <= 34) { if (_digitalMusicContext != NULL) { - //TODO: check resource size loopStart = 0; - // fix ITE sunstatm/sunspot score - if ((_vm->getGameId() == GID_ITE) && (resourceId == MUSIC_SUNSPOT)) { + // Fix ITE sunstatm/sunspot score + if (resourceId == MUSIC_SUNSPOT) loopStart = 4 * 18727; - } - // digital music - audioStream = new DigitalMusicInputStream(_vm, _digitalMusicContext, resourceId - 9, flags == MUSIC_LOOP, loopStart); + // Digital music + ResourceData *resData = _digitalMusicContext->getResourceData(resourceId - 9); + Common::File *musicFile = _digitalMusicContext->getFile(resData); + int offs = (_digitalMusicContext->isCompressed) ? 9 : 0; + + Common::SeekableSubReadStream *musicStream = new Common::SeekableSubReadStream(musicFile, + (uint32)resData->offset + offs, (uint32)resData->offset + resData->size - offs); + + if (!_digitalMusicContext->isCompressed) { + byte musicFlags = Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_STEREO | + Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN; + if (flags == MUSIC_LOOP) + musicFlags |= Audio::Mixer::FLAG_LOOP; + + Audio::LinearDiskStreamAudioBlock audioBlocks[1]; + audioBlocks[0].pos = 0; + audioBlocks[0].len = resData->size / 2; // 16-bit sound + audioStream = Audio::makeLinearDiskStream(musicStream, audioBlocks, 1, 11025, musicFlags, false, loopStart, 0); + } else { + // Read compressed header to determine compression type + musicFile->seek((uint32)resData->offset, SEEK_SET); + byte identifier = musicFile->readByte(); + + if (identifier == 0) { // MP3 +#ifdef USE_MAD + audioStream = Audio::makeMP3Stream(musicStream, false, 0, 0, (flags == MUSIC_LOOP ? 0 : 1)); +#endif + } else if (identifier == 1) { // OGG +#ifdef USE_VORBIS + audioStream = Audio::makeVorbisStream(musicStream, false, 0, 0, (flags == MUSIC_LOOP ? 0 : 1)); +#endif + } else if (identifier == 2) { // FLAC +#ifdef USE_FLAC + audioStream = Audio::makeFlacStream(musicStream, false, 0, 0, (flags == MUSIC_LOOP ? 0 : 1)); +#endif + } + } } } } diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 88bd0d63c3..ef229c8a19 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -27,6 +27,7 @@ #include "base/plugins.h" #include "sci/sci.h" +#include "sci/engine/kernel.h" #include "sci/exereader.h" #include "sci/engine/seg_manager.h" @@ -103,2875 +104,7 @@ static const PlainGameDescriptor SciGameTitles[] = { {0, 0} }; -#define FANMADE_L(name, resMapMd5, resMapSize, resMd5, resSize, lang) \ - {{"sci-fanmade", name, { \ - {"resource.map", 0, resMapMd5, resMapSize}, \ - {"resource.001", 0, resMd5, resSize}, \ - {NULL, 0, NULL, 0}}, lang, Common::kPlatformPC, 0, GUIO_NOSPEECH}, \ - 0 \ - } - -#define FANMADE(name, resMapMd5, resMapSize, resMd5, resSize) FANMADE_L(name, resMapMd5, resMapSize, resMd5, resSize, Common::EN_ANY) - -using Common::GUIO_NONE; -using Common::GUIO_NOSPEECH; - -// Game descriptions -static const struct SciGameDescription SciGameDescriptions[] = { - // Astro Chicken - English DOS - // SCI interpreter version 0.000.453 - {{"astrochicken", "", { - {"resource.map", 0, "f3d1be7752d30ba60614533d531e2e98", 474}, - {"resource.001", 0, "6fd05926c2199af0af6f72f90d0d7260", 126895}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Castle of Dr. Brain - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.005.000" - // SCI interpreter version 1.000.510 - {{"castlebrain", "", { - {"resource.map", 0, "9f9fb826aa7e944b95eadbf568244a68", 2766}, - {"resource.000", 0, "0efa8409c43d42b32642f96652d3230d", 314773}, - {"resource.001", 0, "3fb02ce493f6eacdcc3713851024f80e", 559540}, - {"resource.002", 0, "d226d7d3b4f77c4a566913fc310487fc", 792380}, - {"resource.003", 0, "d226d7d3b4f77c4a566913fc310487fc", 464348}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Castle of Dr. Brain - German Amiga (from www.back2roots.org) - // Executable scanning reports "1.005.001" - // SCI interpreter version 1.000.510 - {{"castlebrain", "", { - {"resource.map", 0, "8e60424682db52a982bcc3535a7e86f3", 2796}, - {"resource.000", 0, "0efa8409c43d42b32642f96652d3230d", 332468}, - {"resource.001", 0, "4e0836fadc324316c1a418125709ba45", 569057}, - {"resource.002", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 826309}, - {"resource.003", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 493638}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Castle of Dr. Brain - English DOS Non-Interactive Demo - // SCI interpreter version 1.000.005 - {{"castlebrain", "Demo", { - {"resource.map", 0, "467bb5e3224bb54640c3280032aebff5", 633}, - {"resource.000", 0, "9780f040d58182994e22d2e34fab85b0", 67367}, - {"resource.001", 0, "2af49dbd8f2e1db4ab09f9310dc91259", 570553}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Castle of Dr. Brain - English DOS Floppy (from jvprat) - // Executable scanning reports "1.000.044", Floppy label reports "1.0, 10.30.91", VERSION file reports "1.000" - // SCI interpreter version 1.000.510 - {{"castlebrain", "", { - {"resource.map", 0, "1302ceb141d44b05a42723791b2d84c6", 2739}, - {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 346731}, - {"resource.001", 0, "d2f5a1be74ed963fa849a76892be5290", 794832}, - {"resource.002", 0, "c0c29c51af66d65cb53f49e785a2d978", 1280907}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Castle of Dr. Brain - English DOS Floppy 1.1 - {{"castlebrain", "", { - {"resource.map", 0, "f77728304c70017c54793eb6ca648174", 2745}, - {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 347071}, - {"resource.001", 0, "13e81e1839cd7b216d2bb5615c1ca160", 796776}, - {"resource.002", 0, "930e416bec196b9703a331d81b3d66f2", 1283812}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Castle of Dr. Brain - Spanish DOS - // SCI interpreter version 1.000.510 - {{"castlebrain", "", { - {"resource.map", 0, "5738c163e014bbe046474de009020b82", 2727}, - {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 1197694}, - {"resource.001", 0, "735be4e58957180cfc807d5e18fdffcd", 1433302}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Christmas Card 1988 - English DOS - // SCI interpreter version 0.000.294 - {{"christmas1988", "", { - {"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426}, - {"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Christmas Card 1990: The Seasoned Professional - English DOS (16 Colors) - // SCI interpreter version 1.000.172 - {{"christmas1990", "16 Colors", { - {"resource.map", 0, "8f656714a05b94423ac6eb10ee8797d0", 600}, - {"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 272629}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Christmas Card 1990: The Seasoned Professional - English DOS (256 Colors) - // SCI interpreter version 1.000.174 - {{"christmas1990", "256 Colors", { - {"resource.map", 0, "44b8f45b841b9b5e17e939a35e443988", 600}, - {"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 335362}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Christmas Card 1992 - English DOS - // SCI interpreter version 1.001.055 - {{"christmas1992", "", { - {"resource.map", 0, "f1f8c8a8443f523422af70b4ec85b71c", 318}, - {"resource.000", 0, "62fb9256f8e7e6e65a6875efdb7939ac", 203396}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Codename: Iceman - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.002.031" - // SCI interpreter version 0.000.685 - {{"iceman", "", { - {"resource.map", 0, "035829b391709a4e542d7c7b224625f6", 6000}, - {"resource.000", 0, "b1bccd827453d4cb834bfd5b45bef63c", 73682}, - {"resource.001", 0, "ede5a0e1e2a80fb629dae72c72f33d37", 293145}, - {"resource.002", 0, "36670a917550757d57df84c96cf9e6d9", 469387}, - {"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 619219}, - {"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 713382}, - {"resource.005", 0, "605b67a9ef199a9bb015745e7c004cf4", 478384}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Codename: Iceman - English DOS Non-Interactive Demo - // Executable scanning reports "0.000.685" - {{"iceman", "Demo", { - {"resource.map", 0, "782974f29d8a824782d2d4aea39964e3", 1056}, - {"resource.001", 0, "d4b75e280d1c3a97cfef1b0bebff387c", 573647}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Codename: Iceman - English DOS (from jvprat) - // Executable scanning reports "0.000.685", Floppy label reports "1.033, 6.8.90", VERSION file reports "1.033" - // SCI interpreter version 0.000.685 - {{"iceman", "", { - {"resource.map", 0, "a18f3cef4481a81d3415fb87a754343e", 5700}, - {"resource.000", 0, "b1bccd827453d4cb834bfd5b45bef63c", 26989}, - {"resource.001", 0, "32b351072fccf76fc82234d73d28c08b", 438872}, - {"resource.002", 0, "36670a917550757d57df84c96cf9e6d9", 566549}, - {"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 624303}, - {"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 670883}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Codename: Iceman - English DOS (from FRG) - // SCI interpreter version 0.000.668 - {{"iceman", "", { - {"resource.map", 0, "554b44b79b0e9a7fc59f66dda0daac02", 5670}, - {"resource.000", 0, "b1bccd827453d4cb834bfd5b45bef63c", 26974}, - {"resource.001", 0, "005bd332d4b0f9d8e99d3b905223a332", 438501}, - {"resource.002", 0, "250b859381ebf2bf8922bd99683b0cc1", 566464}, - {"resource.003", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 622118}, - {"resource.004", 0, "64f342463f6f35ba71b3509ef696ae3f", 669188}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of Camelot - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.002.030" - // SCI interpreter version 0.000.685 - {{"camelot", "", { - {"resource.map", 0, "51aba42f8e63b219755d4372ea424509", 6654}, - {"resource.000", 0, "dfadf0b4c9fb44ce55570149856c302d", 128100}, - {"resource.001", 0, "67391de361b9347f123ac0899b4b91f7", 300376}, - {"resource.002", 0, "8c7f12b2c38d225d4c7121b30ea1b4d2", 605334}, - {"resource.003", 0, "82a73e7572e7ee627429bb5111ff82ca", 672392}, - {"resource.004", 0, "6821dc97cf643ba521a4e840dda3c58b", 647410}, - {"resource.005", 0, "c6e551bdc24f0acc193159038d4ca767", 605882}, - {"resource.006", 0, "8f880a536908ab496bbc552f7f5c3738", 585255}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of Camelot - English DOS Non-Interactive Demo - // SCI interpreter version 0.000.668 - {{"camelot", "Demo", { - {"resource.map", 0, "f4cd75c15be75e04cdca3acda2c0b0ea", 468}, - {"resource.001", 0, "4930708722f34bfbaa4945fb08f55f61", 232523}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of Camelot - English DOS (from jvprat) - // Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000" - // SCI interpreter version 0.000.685 - {{"camelot", "", { - {"resource.map", 0, "95eca3991906dfd7ed26d193df07596f", 7278}, - {"resource.001", 0, "8e1a3a8c588007404b532b8dfacc1460", 596774}, - {"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 722250}, - {"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712}, - {"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of Camelot - English DOS - // SCI interpreter version 0.000.685 - {{"camelot", "", { - {"resource.map", 0, "86bffb2a393b7a5d8de45e735091f037", 9504}, - {"resource.001", 0, "8e1a3a8c588007404b532b8dfacc1460", 212461}, - {"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 317865}, - {"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 359145}, - {"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 345180}, - {"resource.005", 0, "8e1a3a8c588007404b532b8dfacc1460", 345734}, - {"resource.006", 0, "8e1a3a8c588007404b532b8dfacc1460", 332446}, - {"resource.007", 0, "8e1a3a8c588007404b532b8dfacc1460", 358182}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of the Longbow - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.005.001" - // SCI interpreter version 1.000.510 - {{"longbow", "", { - {"resource.map", 0, "6204f3d00c0f6c0f5f95a29a4190f2f9", 6048}, - {"resource.000", 0, "8d11c744b4a51e7a8ceac687a46f08ca", 830333}, - {"resource.001", 0, "76caf8593e065a98c8ab4a6e2c7dbafc", 839008}, - {"resource.002", 0, "eb312373045906b54a3181bebaf6651a", 733145}, - {"resource.003", 0, "7fe3b3372d7fdda60045807e9c8e4867", 824554}, - {"resource.004", 0, "d1038c75d85a6650d48e07d174a6a913", 838175}, - {"resource.005", 0, "1c3804e56b114028c5873a35c2f06d13", 653002}, - {"resource.006", 0, "f9487732289a4f4966b4e34eea413325", 842817}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of the Longbow - English DOS - // SCI interpreter version 1.000.510 - {{"longbow", "", { - {"resource.map", 0, "36d3b81ff75b67dd4d27b7f5d3166503", 6261}, - {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 1096767}, - {"resource.001", 0, "d4c299213f8d799da1492680d12d0fb3", 1133226}, - {"resource.002", 0, "7f6ce331219d58d5087731e4475ab4f1", 1128555}, - {"resource.003", 0, "21ebe6b39b57a73fc449f67f013765aa", 972635}, - {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1064637}, - {"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1154950}, - {"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1042966}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of the Longbow - English DOS Floppy (from jvprat) - // Executable scanning reports "1.000.168", Floppy label reports "1.1, 1.13.92", VERSION file reports "1.1" - // SCI interpreter version 1.000.510 - {{"longbow", "", { - {"resource.map", 0, "247f955865572569342751de47e861ab", 6027}, - {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 1297120}, - {"resource.001", 0, "1e6084a19f7a6c50af88d3a9b32c411e", 1366155}, - {"resource.002", 0, "7f6ce331219d58d5087731e4475ab4f1", 1234743}, - {"resource.003", 0, "1867136d01ece57b531032d466910522", 823686}, - {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1261462}, - {"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284720}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of the Longbow - English DOS - // SCI interpreter version 1.000.510 - {{"longbow", "", { - {"resource.map", 0, "737c6f83a1ee601727ff026898f19fa1", 6045}, - {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 1296607}, - {"resource.001", 0, "1e6084a19f7a6c50af88d3a9b32c411e", 1379267}, - {"resource.002", 0, "7f6ce331219d58d5087731e4475ab4f1", 1234140}, - {"resource.003", 0, "1867136d01ece57b531032d466910522", 823610}, - {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1260237}, - {"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284609}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of the Longbow EGA - English DOS - // SCI interpreter version 1.000.510 - {{"longbow", "EGA", { - {"resource.map", 0, "7676ec9f08967d7a9a7724f5170456e0", 6261}, - {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 718161}, - {"resource.001", 0, "3c3735caa34fa3f261a9552831bb43ed", 705680}, - {"resource.002", 0, "7025b87e735b1df3f0e9488a621f4333", 700633}, - {"resource.003", 0, "eaca7933e8e56bea22b42f7fd5d7a8a7", 686510}, - {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631}, - {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243}, - {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0, - }, - - // Conquests of the Longbow - English DOS Non-Interactive Demo - // SCI interpreter version 1.000.510 - {{"longbow", "Demo", { - {"resource.map", 0, "cbc5cb73341de1bff1b1e20a640af220", 588}, - {"resource.001", 0, "f05a20cc07eee85da8e999d0ac0f596b", 869916}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Conquests of the Longbow - German DOS (suplied by markcoolio in bug report #2727681) - // SCI interpreter version 1.000.510 - {{"longbow", "", { - {"resource.map", 0, "7376b7a07f8bd3a8ab8d67595d3f5b51", 6285}, - {"resource.000", 0, "ee39f92e006142424cf9209329e727c6", 977281}, - {"resource.001", 0, "d4c299213f8d799da1492680d12d0fb3", 1167657}, - {"resource.002", 0, "7f6ce331219d58d5087731e4475ab4f1", 1172521}, - {"resource.003", 0, "a204de2a083a7770ff455a838210a678", 1165249}, - {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1101869}, - {"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1176914}, - {"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1123585}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest - English DOS Non-Interactive Demo (from FRG) - // Executable scanning reports "x.yyy.zzz" - // SCI interpreter version 1.001.069 (just a guess) - {{"ecoquest", "Demo", { - {"resource.map", 0, "c819e171359b7c95f4c13b846d5c034e", 873}, - {"resource.001", 0, "baf9393a9bfa73098adb501e5bc5487b", 657518}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest - English DOS CD 1.1 - // SCI interpreter version 1.001.064 - {{"ecoquest", "CD", { - {"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804}, - {"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Eco Quest - English DOS Floppy - // SCI interpreter version 1.000.510 - {{"ecoquest", "Floppy", { - {"resource.map", 0, "704367225929a88aad281ac72844ddac", 4053}, - {"resource.000", 0, "241b98d3903f6a5b872baa19b80aef3b", 1099239}, - {"resource.001", 0, "96d4435d24c01f1c1675e46457604c5f", 1413719}, - {"resource.002", 0, "28fe9b4f0567e71feb198bc9f3a2c605", 1241816}, - {"resource.003", 0, "f3146df0ad4297f5ce35aa8c4753bf6c", 586832}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest - English DOS Floppy - // SCI interpreter version 1.000.510 - {{"ecoquest", "Floppy", { - {"resource.map", 0, "f77baec05fae76707205f5be6534a7f3", 4059}, - {"resource.000", 0, "241b98d3903f6a5b872baa19b80aef3b", 858490}, - {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212161}, - {"resource.002", 0, "323b3b12f43d53f27d259beb225f0aa7", 1129316}, - {"resource.003", 0, "83ac03e4bddb2c1ac2d36d2a587d0536", 1145616}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest - German DOS Floppy (supplied by markcoolio in bug report #2723744) - // SCI interpreter version 1.000.510 - {{"ecoquest", "Floppy", { - {"resource.map", 0, "7a9b43bf27dc000ac8559ecbe824b659", 4395}, - {"resource.000", 0, "99b73d40403a51c7e60d01df0d6cd34a", 998227}, - {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212060}, - {"resource.002", 0, "02d7d0411f7903aacb3bc8b0f8ca8a9a", 1202581}, - {"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1175835}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest - Spanish DOS Floppy (from jvprat) - // Executable scanning reports "1.ECO.013", VERSION file reports "1.000, 11.12.92" - // SCI interpreter version 1.000.510 - {{"ecoquest", "Floppy", { - {"resource.map", 0, "82e6b1e3bdb2f064b18380009df7b345", 4395}, - {"resource.000", 0, "0b12a91c935e385308af8d17811deded", 1004085}, - {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212060}, - {"resource.002", 0, "2d21a1d2dcbffa551552e3e0725d2284", 1186033}, - {"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1174993}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest - French DOS Floppy (from Strangerke) - // SCI interpreter version 1.ECO.013 - {{"ecoquest", "Floppy", { - {"resource.map", 0, "67742945cd59b896d9f22a549f605217", 4407}, - {"resource.000", 0, "0b12a91c935e385308af8d17811deded", 973723}, - {"resource.001", 0, "fc7fba54b6bb88fd7e9c229636599aa9", 1205841}, - {"resource.002", 0, "b836c6ee9de67d814ac5d1b05f5b9858", 1173872}, - {"resource.003", 0, "f8f767f9d6351432621c6e54c1b2ba8c", 1141520}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest 2 - English DOS Non-Interactive Demo - // SCI interpreter version 1.001.055 - {{"ecoquest2", "Demo", { - {"resource.map", 0, "607cfa0d8a03b7d348c06ee727e3d939", 1321}, - {"resource.000", 0, "dd6f614c43c029f063e93cd243af90a4", 525992}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest 2 - English DOS Floppy (supplied by markcoolio in bug report #2723761) - // SCI interpreter version 1.001.065 - {{"ecoquest2", "Floppy", { - {"resource.map", 0, "28fb7b6abb9fc1cb8882d7c2e701b63f", 5658}, - {"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4208192}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Eco Quest 2 - French DOS Floppy (from Strangerke) - // SCI interpreter version 1.001.081 - {{"ecoquest2", "Floppy", { - {"resource.map", 0, "c22ab8b33c339c138b6b1697b77b9e79", 5588}, - {"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4231946}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Freddy Pharkas - English DOS demo (from FRG) - // SCI interpreter version 1.001.069 - {{"freddypharkas", "Demo", { - {"resource.map", 0, "97aa9fcfe84c9993a64debd28c32393a", 1909}, - {"resource.000", 0, "5ea8e7a3ea10cce6efd5c106dc62fd8c", 867724}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Freddy Pharkas - English CD (from FRG) - // SCI interpreter version 1.001.132 - {{"freddypharkas", "CD", { - {"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058}, - {"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Freddy Pharkas - English DOS Floppy (updated information from markcoolio in bug reports #2723773 and #2724720) - // Executable scanning reports "1.cfs.081" - // SCI interpreter version 1.001.132 (just a guess) - {{"freddypharkas", "Floppy", { - {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, - {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, - {"resource.msg", 0, "554f65315d851184f6e38211489fdd8f", -1}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Freddy Pharkas - German DOS Floppy (from Tobis87, updated information from markcoolio in bug reports #2723772 and #2724720) - // Executable scanning reports "1.cfs.081" - // SCI interpreter version 1.001.132 (just a guess) - {{"freddypharkas", "", { - {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, - {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, - {"resource.msg", 0, "304b5a5781800affd2235152a5794fa8", -1}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Freddy Pharkas - Spanish DOS (from jvprat) - // Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995" - // SCI interpreter version 1.001.132 (just a guess) - {{"freddypharkas", "CD", { - {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, - {"resource.000", 0, "fed4808fdb72486908ac7ad0044b14d8", 1456640}, - {"resource.001", 0, "15298fac241b5360763bfb68add1db07", 1456640}, - {"resource.002", 0, "419dbd5366f702b4123dedbbb0cffaae", 1456640}, - {"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310}, - {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Freddy Pharkas - Spanish DOS (from jvprat) - // Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995" - // SCI interpreter version 1.001.132 (just a guess) - {{"freddypharkas", "Floppy", { - {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, - {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, - {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Freddy Pharkas - English DOS CD Demo - // SCI interpreter version 1.001.095 - {{"freddypharkas", "CD Demo", { - {"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918}, - {"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE}, - 0 - }, - - // Fun Seeker's Guide - English DOS - // SCI interpreter version 0.000.506 - {{"funseeker", "", { - {"resource.map", 0, "7ee6859ef74314f6d91938c3595348a9", 282}, - {"resource.001", 0, "f1e680095424e31f7fae1255d36bacba", 40692}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Gabriel Knight - English DOS CD Demo - // SCI interpreter version 1.001.092 - {{"gk1", "CD Demo", { - {"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490}, - {"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE}, - 0 - }, - -#ifdef ENABLE_SCI32 - // Gabriel Knight - English DOS Floppy - // SCI interpreter version 2.000.000 - {{"gk1", "", { - {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10783}, - {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Gabriel Knight - English DOS Floppy (supplied my markcoolio in bug report #2723777) - // SCI interpreter version 2.000.000 - {{"gk1", "", { - {"resource.map", 0, "65e8c14092e4c9b3b3538b7602c8c5ec", 10783}, - {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Gabriel Knight - German DOS Floppy (supplied my markcoolio in bug report #2723775) - // SCI interpreter version 2.000.000 - {{"gk1", "", { - {"resource.map", 0, "ad6508b0296b25c07b1f58828dc33696", 10789}, - {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13077029}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Gabriel Knight - English DOS CD (from jvprat) - // Executable scanning reports "2.000.000", VERSION file reports "01.100.000" - {{"gk1", "CD", { - {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996}, - {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Gabriel Knight - German DOS CD (from Tobis87) - // SCI interpreter version 2.000.000 - {{"gk1", "CD", { - {"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392}, - {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Gabriel Knight - Spanish DOS CD (from jvprat) - // Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995" - {{"gk1", "CD", { - {"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404}, - {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Gabriel Knight 2 - English Windows Non-Interactive Demo - // Executable scanning reports "2.100.002" - {{"gk2", "Demo", { - {"resource.map", 0, "e0effce11c4908f4b91838741716c83d", 1351}, - {"resource.000", 0, "d04cfc7f04b6f74d13025378be49ec2b", 4640330}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - // Gabriel Knight 2 - English DOS (from jvprat) - // Executable scanning reports "2.100.002", VERSION file reports "1.1" - {{"gk2", "", { - {"resmap.001", 0, "1b8bf6a23b37ed67358eb825fc687260", 2776}, - {"ressci.001", 0, "24463ae235b1afbbc4ff5e2ed1b8e3b2", 50496082}, - {"resmap.002", 0, "2028230674bb54cd24370e0745e7a9f4", 1975}, - {"ressci.002", 0, "f0edc1dcd704bd99e598c5a742dc7150", 42015676}, - {"resmap.003", 0, "51f3372a2133c406719dafad86369be3", 1687}, - {"ressci.003", 0, "86cb3f3d176994e7f8a9ad663a4b907e", 35313750}, - {"resmap.004", 0, "0f6e48f3e84e867f7d4a5215fcff8d5c", 2719}, - {"ressci.004", 0, "4f30aa6e6f895132402c8652f9e1d741", 58317316}, - {"resmap.005", 0, "2dac0e232262b4a51271fd28559b3e70", 2065}, - {"ressci.005", 0, "14b62d4a3bddee57a03cb1495a798a0f", 38075705}, - {"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977}, - {"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, -#endif // ENABLE_SCI32 - - // Hoyle 1 - English DOS (supplied by wibble92 in bug report #2644547) - // SCI interpreter version 0.000.530 - {{"hoyle1", "", { - {"resource.map", 0, "9de9aa6d23569b3c8bf798503cf1216a", 7818}, - {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 162783}, - {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342309}, - {"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328912}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Hoyle 1 - English DOS (supplied by merkur in bug report #2719227) - // SCI interpreter version 0.000.530 - {{"hoyle1", "", { - {"resource.map", 0, "1034a218943d12f1f36e753fa10c95b8", 4386}, - {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518308}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - -#if 0 // TODO: unknown if these files are corrupt - // Hoyle 1 - English Amiga (from www.back2roots.org) - // SCI interpreter version 0.000.519 - FIXME: some have 0.000.530, others x.yyy.zzz - {{"hoyle1", "", { - {"resource.map", 0, "2a72b1aba65fa6e339370eb86d8601d1", 5166}, - {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 218755}, - {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 439502}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, -#endif - - // Hoyle 2 - English DOS - // SCI interpreter version 0.000.572 - {{"hoyle2", "", { - {"resource.map", 0, "4f894d203f64aa23d9ff64d30ae36926", 2100}, - {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 98138}, - {"resource.002", 0, "8f2dd70abe01112eca464cda818b5eb6", 196631}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Hoyle 2 - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.002.032" - // SCI interpreter version 0.000.685 - {{"hoyle2", "", { - {"resource.map", 0, "62ed48d20c580e5a98f102f7cd93706a", 1356}, - {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 222704}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - -#if 0 // TODO: unknown if these files are corrupt - // Hoyle 3 - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.005.000" - // SCI interpreter version 1.000.510 - {{"hoyle3", "", { - {"resource.map", 0, "f1f158e428398cb87fc41fb4aa8c2119", 2088}, - {"resource.000", 0, "595b6039ea1356e7f96a52c58eedcf22", 355791}, - {"resource.001", 0, "143df8aef214a2db34c2d48190742012", 632273}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, -#endif - - // Hoyle 3 - English DOS Non-Interactive Demo - // Executable scanning reports "x.yyy.zzz" - // SCI interpreter version 1.000.510 (just a guess) - {{"hoyle3", "Demo", { - {"resource.map", 0, "0d06cacc87dc21a08cd017e73036f905", 735}, - {"resource.001", 0, "24db2bccda0a3c43ac4a7b5edb116c7e", 797678}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Hoyle 3 - English DOS Floppy (from jvprat) - // Executable scanning reports "x.yyy.zzz", Floppy label reports "1.0, 11.2.91", VERSION file reports "1.000" - // SCI interpreter version 1.000.510 (just a guess) - {{"hoyle3", "", { - {"resource.map", 0, "7216a2972f9c595c45ab314941628e43", 2247}, - {"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 541845}, - {"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 845795}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Hoyle 4 - English DOS Demo - // SCI interpreter version 1.001.200 (just a guess) - {{"hoyle4", "Demo", { - {"resource.map", 0, "662087cb383e52e3cc4ae7ecb10e20aa", 938}, - {"resource.000", 0, "24c10844792c54d476d272213cbac300", 675252}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - -#if 0 - // Jones in the Fast Lane - English DOS - // SCI interpreter version 1.000.172 - {{"jones", "", { - {"resource.map", 0, "65cbe19b36fffc71c8e7b2686bd49ad7", 1800}, - {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 313476}, - {"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 719747}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, -#endif - - // King's Quest 1 SCI Remake - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.003.007" - // SCI interpreter version 0.001.010 - {{"kq1sci", "SCI Remake", { - {"resource.map", 0, "37ed1a05eb719629eba15059c2eb6cbe", 6798}, - {"resource.001", 0, "9ae2a13708d691cd42f9129173c4b39d", 266621}, - {"resource.002", 0, "9ae2a13708d691cd42f9129173c4b39d", 795123}, - {"resource.003", 0, "9ae2a13708d691cd42f9129173c4b39d", 763224}, - {"resource.004", 0, "9ae2a13708d691cd42f9129173c4b39d", 820443}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 1 SCI Remake - English DOS Non-Interactive Demo - // Executable scanning reports "S.old.010" - {{"kq1sci", "SCI Remake Demo", { - {"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954}, - {"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection) - // Executable scanning reports "S.old.010", VERSION file reports "1.000.051" - // SCI interpreter version 0.000.999 - {{"kq1sci", "SCI Remake", { - {"resource.map", 0, "7fe9399a0bec84ca5727309778d27f07", 5790}, - {"resource.001", 0, "fed9e0072ffd511d248674e60dee2099", 555439}, - {"resource.002", 0, "fed9e0072ffd511d248674e60dee2099", 714062}, - {"resource.003", 0, "fed9e0072ffd511d248674e60dee2099", 717478}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 4 - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.002.032" - // SCI interpreter version 0.000.685 - {{"kq4sci", "", { - {"resource.map", 0, "f88dd267fb9504d40a04d599c048d42b", 6354}, - {"resource.000", 0, "77615c595388acf3d1df8e107bfb6b52", 138523}, - {"resource.001", 0, "52c2231765eced34faa7f7bcff69df83", 44751}, - {"resource.002", 0, "fb351106ec865fad9af5d78bd6b8e3cb", 663629}, - {"resource.003", 0, "fd16c9c223f7dc5b65f06447615224ff", 683016}, - {"resource.004", 0, "3fac034c7d130e055d05bc43a1f8d5f8", 549993}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 4 - English DOS Non-Interactive Demo - // Executable scanning reports "0.000.494" - {{"kq4sci", "Demo", { - {"resource.map", 0, "992ac7cc31d3717fe53818a9bb6d1dae", 594}, - {"resource.001", 0, "143e1c14f15ad0fbfc714f648a65f661", 205330}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // King's Quest 4 - English DOS (from the King's Quest Collection) - // Executable scanning reports "0.000.502" - // SCI interpreter version 0.000.502 - {{"kq4sci", "", { - {"resource.map", 0, "3164a39790b599c954ecf716d0b32be8", 7476}, - {"resource.001", 0, "77615c595388acf3d1df8e107bfb6b52", 452523}, - {"resource.002", 0, "77615c595388acf3d1df8e107bfb6b52", 536573}, - {"resource.003", 0, "77615c595388acf3d1df8e107bfb6b52", 707591}, - {"resource.004", 0, "77615c595388acf3d1df8e107bfb6b52", 479562}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // King's Quest 4 - English DOS - // SCI interpreter version 0.000.274 - {{"kq4sci", "", { - {"resource.map", 0, "adbe267662a5915d3c89c9075ec8cf3e", 9474}, - {"resource.001", 0, "851a62d00972dc4002f472cc0d84e71d", 188239}, - {"resource.002", 0, "851a62d00972dc4002f472cc0d84e71d", 329895}, - {"resource.003", 0, "851a62d00972dc4002f472cc0d84e71d", 355385}, - {"resource.004", 0, "851a62d00972dc4002f472cc0d84e71d", 322951}, - {"resource.005", 0, "851a62d00972dc4002f472cc0d84e71d", 321593}, - {"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777}, - {"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // King's Quest 4 - English DOS - // SCI interpreter version 0.000.253 - {{"kq4sci", "", { - {"resource.map", 0, "381d9dcb69c626f0a60631dbfec1d13a", 9474}, - {"resource.001", 0, "0c8566848a76eea19a6d6220914030a7", 191559}, - {"resource.002", 0, "0c8566848a76eea19a6d6220914030a7", 333345}, - {"resource.003", 0, "0c8566848a76eea19a6d6220914030a7", 358513}, - {"resource.004", 0, "0c8566848a76eea19a6d6220914030a7", 326297}, - {"resource.005", 0, "0c8566848a76eea19a6d6220914030a7", 325102}, - {"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288}, - {"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // King's Quest 5 - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.004.018" - // SCI interpreter version 1.000.060 - {{"kq5", "", { - {"resource.map", 0, "fcbcca058e1157221ffc27251cd59bc3", 8040}, - {"resource.000", 0, "c595ca99e7fa9b2cabcf69cfab0caf67", 344909}, - {"resource.001", 0, "964a3be90d810a99baf72ea70c09f935", 836477}, - {"resource.002", 0, "d10f3e8ff2cd95a798b21cd08797b694", 814730}, - {"resource.003", 0, "f72fdd994d9ba03a8360d639f256344e", 804882}, - {"resource.004", 0, "a5b80f95c66b3a032348989408eec287", 747914}, - {"resource.005", 0, "31a5487f4d942e6354d5be49d59707c9", 834146}, - {"resource.006", 0, "26c0c25399b6715fec03fc3e12544fe3", 823048}, - {"resource.007", 0, "b914b5901e786327213e779725d30dd1", 778772}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 5 - German Amiga - // Executable scanning reports "1.004.024" - // SCI interpreter version 1.000.060 - {{"kq5", "", { - {"resource.map", 0, "bfbffd923cd64b24498e54f797aa6e41", 8250}, - {"resource.000", 0, "79479b5e4e5b0085d8eea1c7ff0f9f5a", 306893}, - {"resource.001", 0, "7840aadc82977c7b4f504a7e4a12829f", 720376}, - {"resource.002", 0, "d547167d4204170b44de8e1d63506215", 792586}, - {"resource.003", 0, "9cbb0712816097cbc9d0c1f987717c7f", 646446}, - {"resource.004", 0, "319712573661bd122390cdfbafb000fd", 831842}, - {"resource.005", 0, "5aa3d59968b569cd509dde00d4eb8751", 754201}, - {"resource.006", 0, "56546b20db11a4836f900efa6d3a3e74", 672099}, - {"resource.007", 0, "56546b20db11a4836f900efa6d3a3e74", 794194}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 5 - Italian Amiga - // Executable scanning reports "1.004.024" - // SCI interpreter version 1.000.060 - {{"kq5", "", { - {"resource.map", 0, "12e2f80c0269932411716dad06d2b229", 8250}, - {"resource.000", 0, "c598ff615a61bc0e418761283409f128", 305879}, - {"resource.001", 0, "17e63cfe78632fe07222e13a26dc0fb2", 720023}, - {"resource.002", 0, "abb340a53e4873a7c3bacfb16c0b779d", 792432}, - {"resource.003", 0, "aced8ce0be07eef77c0e7cff8cc4e476", 646088}, - {"resource.004", 0, "13fc1f1679f7f226ba52ffffe2e65f38", 831805}, - {"resource.005", 0, "de3c5c09e350fded36ca354998c2194d", 754784}, - {"resource.006", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 672527}, - {"resource.007", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 794259}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 5 - English DOS CD (from the King's Quest Collection) - // Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052" - // SCI interpreter version 1.000.784 - {{"kq5", "CD", { - {"resource.map", 0, "f68ba690e5920725dcf9328001b90e33", 13122}, - {"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368}, - {"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // King's Quest 5 - English DOS Floppy - // SCI interpreter version 1.000.060 - {{"kq5", "", { - {"resource.map", 0, "d6172c27b453350e158815fbae23f41e", 8004}, - {"resource.000", 0, "a591bd4b879fc832b8095c0b3befe9e2", 276351}, - {"resource.001", 0, "3f28c72dc7531aaccf8e972c7ee50d14", 1022087}, - {"resource.002", 0, "3e56ba5bf5e8637c619b57f6b6cacbb4", 1307211}, - {"resource.003", 0, "5d5d498f33ca7cde0d5b058630b36ad3", 1347875}, - {"resource.004", 0, "944a996f9cc90dabde9f51ed7dd52366", 1239689}, - {"resource.005", 0, "b6c43441cb78a9b484efc8e614aac092", 1287999}, - {"resource.006", 0, "672ede1136e9e401658538e51bd5dc22", 1172619}, - {"resource.007", 0, "2f48faf27666b58c276dda20f91f4a93", 1240456}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101) - // SCI interpreter version 1.000.060 - {{"kq5", "", { - {"resource.map", 0, "bff44f0c326a71b1757c793a02b502d6", 8283}, - {"resource.000", 0, "d7ed18ec4a5de02a9a57830aa65a600d", 336826}, - {"resource.001", 0, "b1e5ec6a17be7e75ddb955f6f73191e4", 1136919}, - {"resource.002", 0, "04a88122db44610a4af019a579ec5ff6", 1340813}, - {"resource.003", 0, "215bb35acefae75fc80757c717166d7e", 1323916}, - {"resource.004", 0, "fecdec847e3bd8e3b0f9827900aa95fd", 1331811}, - {"resource.005", 0, "9c429782d102739f6bbb81e8b953b0cb", 1267525}, - {"resource.006", 0, "d1a75fdc01840664d00366cff6919366", 1208972}, - {"resource.007", 0, "c07494f0cce7c05210893938786a955b", 1337361}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 5 - French DOS Floppy (from the King's Quest Collector's Edition 1994) - // Supplied by aroenai in bug report #2812611 - // VERSION file reports "1.000", SCI interpreter version 1.000.784 - {{"kq5", "", { - {"resource.map", 0, "eb7853832f3bb10900b13b421a0bbe7f", 8283}, - {"resource.000", 0, "f063775b279208c14a83eda47073be90", 332806}, - {"resource.001", 0, "3e6add38564250fd1a5bb10593007530", 1136827}, - {"resource.002", 0, "d9a97a9cf6c79bbe8f19378f6dea45d5", 1343738}, - {"resource.003", 0, "bef90d755076c110e67ee3e635503f82", 1324811}, - {"resource.004", 0, "c14dbafcfbe00855ac6b2f2701058047", 1332216}, - {"resource.005", 0, "f4b31cafc5defac75125c5f7b7f9a31a", 1268334}, - {"resource.006", 0, "f7dc85307632ef657ceb1651204f6f51", 1210081}, - {"resource.007", 0, "7db4d0a1d8d547c0019cb7d2a6acbdd4", 1338473}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 5 - Italian DOS Floppy (from glorifindel) - // SCI interpreter version 1.000.060 - {{"kq5", "", { - {"resource.map", 0, "d55c9e83894a0885e37cd79bacf86384", 8283}, - {"resource.000", 0, "c99bbb11ace4aaacdc98b588a2ecea06", 332246}, - {"resource.001", 0, "42b98457b1a7282daa27afd89eef53f4", 1136389}, - {"resource.002", 0, "8cdc160f9dfc84aed7caa6c66fa31000", 1340730}, - {"resource.003", 0, "d0cb52dc41488c018359aa79a6527f51", 1323676}, - {"resource.004", 0, "e5c57060adf2b5c6fc24142acba023da", 1331097}, - {"resource.005", 0, "f4e441f284560eaa8022102315656a7d", 1267757}, - {"resource.006", 0, "8eeabd92af71e766e323db2100879102", 1209325}, - {"resource.007", 0, "dc10c107e0923b902326a040b9c166b9", 1337859}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 5 - Polish DOS Floppy (supplied by jacek909 in bug report #2725722) - // SCI interpreter version 1.000.060 - {{"kq5", "", { - {"resource.map", 0, "70010c20138541f89013bb5e1b30f16a", 7998}, - {"resource.000", 0, "a591bd4b879fc832b8095c0b3befe9e2", 276398}, - {"resource.001", 0, "c0f48d4a7ebeaa6aa074fc98d77423e9", 1018560}, - {"resource.002", 0, "7f188a95acdb60bbe32a8379ba299393", 1307048}, - {"resource.003", 0, "0860785af59518b94d54718dddcd6907", 1348500}, - {"resource.004", 0, "c4745dd1e261c22daa6477961d08bf6c", 1239887}, - {"resource.005", 0, "6556ff8e7c4d1acf6a78aea154daa76c", 1287869}, - {"resource.006", 0, "da82e4beb744731d0a151f1d4922fafa", 1170456}, - {"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176}, - {NULL, 0, NULL, 0}}, Common::PL_POL, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 6 - English DOS Non-Interactive Demo - // Executable scanning reports "1.001.055", VERSION file reports "1.000.000" - // SCI interpreter version 1.001.055 - {{"kq6", "Demo", { - {"resource.map", 0, "f75727c00a6d884234fa2a43c951943a", 706}, - {"resource.000", 0, "535b1b920441ec73f42eaa4ccfd47b89", 264116}, - {"resource.msg", 0, "54d1fdc936f98c81f9e4c19e04fb1510", 8260}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 6 - English DOS Floppy - // SCI interpreter version 1.001.054 - {{"kq6", "", { - {"resource.map", 0, "a362063318eebe7d6423b1d9dc6213e1", 8703}, - {"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, - {"resource.msg", 0, "3cf5de44de36191f109d425b8450efc8", 258590}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 6 - German DOS Floppy (supplied by markcoolio in bug report #2727156) - // SCI interpreter version 1.001.054 - {{"kq6", "", { - {"resource.map", 0, "a362063318eebe7d6423b1d9dc6213e1", 8703}, - {"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, - {"resource.msg", 0, "756297b2155db9e43f621c6f6fb763c3", 282822}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 6 - English Windows CD (from the King's Quest Collection) - // Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G" - // SCI interpreter version 1.001.054 - {{"kq6", "CD", { - {"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215}, - {"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // King's Quest 6 - Spanish DOS CD (from jvprat) - // Executable scanning reports "1.cfs.158", VERSION file reports "1.000.000, July 5, 1994" - // SCI interpreter version 1.001.055 - {{"kq6", "CD", { - {"resource.map", 0, "a73a5ab04b8f60c4b75b946a4dccea5a", 8953}, - {"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260}, - {"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - -#ifdef ENABLE_SCI32 - // King's Quest 7 - English DOS (from the King's Quest Collection) - // Executable scanning reports "2.100.002", VERSION file reports "1.4" - {{"kq7", "", { - {"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697}, - {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 7 - English DOS (from FRG) - // SCI interpreter version 2.100.002 - {{"kq7", "", { - {"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709}, - {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402) - // SCI interpreter version 2.100.002 - {{"kq7", "", { - {"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697}, - {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 7 - Spanish DOS (from jvprat) - // Executable scanning reports "2.100.002", VERSION file reports "2.00" - {{"kq7", "", { - {"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709}, - {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // King's Quest 7 - English DOS Non-Interactive Demo - // SCI interpreter version 2.100.002 - {{"kq7", "Demo", { - {"resource.map", 0, "b44f774108d63faa1d021101221c5a54", 1690}, - {"resource.000", 0, "d9659d2cf0c269c6a9dc776707f5bea0", 2433827}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, -#endif // ENABLE_SCI32 - - // Laura Bow - English Amiga - // Executable scanning reports "1.002.030" - // SCI interpreter version 0.000.685 - {{"laurabow", "", { - {"resource.map", 0, "731ab85e138f8cef1a7f4d1f36dfd375", 7422}, - {"resource.000", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 126317}, - {"resource.001", 0, "42fe895e9eb60e103025fd9ca737a849", 264763}, - {"resource.002", 0, "6f1ebd3692ce76644e0e06a38b7b56b5", 677436}, - {"resource.003", 0, "2ab23f64306b18c28302c8ec2964c5d6", 605134}, - {"resource.004", 0, "aa553977f7e5804081de293800d3bcce", 695067}, - {"resource.005", 0, "bfd870d51dc97729f0914095f58e6957", 676881}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow - English Atari ST (from jvprat) - // Executable scanning reports "1.002.030", Floppy label reports "1.000.062, 9.23.90" - // SCI interpreter version 0.000.685 - {{"laurabow", "", { - {"resource.map", 0, "9f90878e6e1b8c96e692203f068ce2b1", 8478}, - {"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 515964}, - {"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 721149}, - {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667365}, - {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683737}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow - English DOS Non-Interactive Demo - // Executable scanning reports "x.yyy.zzz" - {{"laurabow", "Demo", { - {"resource.map", 0, "e625726268ff4e123ada11f31f0249f3", 768}, - {"resource.001", 0, "0c8912290af0890f8d95faeb4ddb2d68", 333031}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow - English DOS 3.5" Floppy (from "The Roberta Williams Anthology"/1996) - // SCI interpreter version 0.000.631 - {{"laurabow", "", { - {"resource.map", 0, "4e511f47d9893fa529d6621a93fa0030", 8478}, - {"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 515788}, - {"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 721381}, - {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667468}, - {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683807}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow - English DOS (from FRG) - // SCI interpreter version 0.000.631 (or 0.000.685?) - {{"laurabow", "", { - {"resource.map", 0, "b1905f6aa68ff65a057b080b1eae954c", 12030}, - {"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 108032}, - {"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 354680}, - {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 361815}, - {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 339714}, - {"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465}, - {"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, - {"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow - German DOS (from Tobis87) - // SCI interpreter version 0.000.631 (or 0.000.685?) - {{"laurabow", "", { - {"resource.map", 0, "b1905f6aa68ff65a057b080b1eae954c", 12030}, - {"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 108032}, - {"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 354680}, - {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 361815}, - {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 339714}, - {"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465}, - {"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, - {"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow 2 - English DOS Non-Interactive Demo (from FRG) - // Executable scanning reports "x.yyy.zzz" - // SCI interpreter version 1.001.069 (just a guess) - {{"laurabow2", "Demo", { - {"resource.map", 0, "24dffc5db1d88c7999f13e8767ed7346", 855}, - {"resource.000", 0, "2b2b1b4f7584f9b38fd13f6ab95634d1", 781912}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow 2 - English DOS Floppy - // Executable scanning reports "2.000.274" - // SCI interpreter version 1.001.069 (just a guess) - {{"laurabow2", "", { - {"resource.map", 0, "610bfd9a852004222f0faaf5fc9e630a", 6489}, - {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5035964}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow 2 - English DOS CD (from "The Roberta Williams Antology"/1996) - // Executable scanning reports "1.001.072", VERSION file reports "1.1" (from jvprat) - // SCI interpreter version 1.001.069 (just a guess) - {{"laurabow2", "CD", { - {"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274}, - {"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Laura Bow 2 v1.1 - German DOS Floppy (from Tobis87, updated info from markcoolio in bug report #2723787, updated info from #2797962)) - // Executable scanning reports "2.000.274" - {{"laurabow2", "", { - {"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, - {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, - {"resource.msg", 0, "795c928cd00dfec9fbc62ebcd12e1f65", 303185}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Laura Bow 2 - Spanish DOS CD (from jvprat) - // Executable scanning reports "2.000.274", VERSION file reports "1.000.000, May 10, 1994" - {{"laurabow2", "CD", { - {"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, - {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, - {"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 1 EGA Remake - English DOS (from spookypeanut) - // SCI interpreter version 0.000.510 (or 0.000.577?) - {{"lsl1sci", "EGA Remake", { - {"resource.map", 0, "abc0dc50c55de5b9723bb6de193f8756", 3282}, - {"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 451366}, - {"resource.001", 0, "38936d3c68b6f79d3ffb13955713fed7", 591352}, - {"resource.002", 0, "24c958bc922b07f91e25e8c93aa01fcf", 491230}, - {"resource.003", 0, "685cd6c1e05a695ab1e0db826337ee2a", 553279}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 1 VGA Remake - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.004.024" - // SCI interpreter version 1.000.784 - {{"lsl1sci", "VGA Remake", { - {"resource.map", 0, "7d115a9e27dc8ac71e8d5ef33d589bd5", 3366}, - {"resource.000", 0, "e67fd129d5810fc7ad8ea509d891cc00", 363073}, - {"resource.001", 0, "24ed6dc01b1e7fbc66c3d63a5994549a", 750465}, - {"resource.002", 0, "5790ac0505f7ca98d4567132b875eb1e", 681041}, - {"resource.003", 0, "4a34c3367c2fe7eb380d741374da1989", 572251}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 1 VGA Remake - English DOS (from spookypeanut) - // Executable scanning reports "1.000.577", VERSION file reports "2.1" - {{"lsl1sci", "VGA Remake", { - {"resource.map", 0, "6d04d26466337a1a64b8c6c0eb65c9a9", 3222}, - {"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 922406}, - {"resource.001", 0, "ec20246209d7b19f38989261e5c8f5b8", 1111226}, - {"resource.002", 0, "85d6935ef77e6b0e16bc307640a0d913", 1088312}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 1 VGA Remake - English DOS (from FRG) - // SCI interpreter version 1.000.510 - {{"lsl1sci", "VGA Remake", { - {"resource.map", 0, "8606b083b011a0cc4a1fbfc2198a0a77", 3198}, - {"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 918242}, - {"resource.001", 0, "d34cadb11e1aefbb497cf91bc1d3baa7", 1114688}, - {"resource.002", 0, "85b030bb66d5342b0a068f1208c431a8", 1078443}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 1 VGA Remake - English DOS Non-Interactive Demo - // SCI interpreter version 1.000.084 - {{"lsl1sci", "VGA Remake Demo", { - {"resource.map", 0, "434e1f6c39d71647b34f0ee57b2bbd68", 444}, - {"resource.001", 0, "0c0768215c562d9dace4a5ca53696cf3", 359913}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Larry 1 VGA Remake - Spanish DOS (from the Leisure Suit Larry Collection) - // Executable scanning reports "1.SQ4.057", VERSION file reports "1.000" - // This version is known to be corrupted - // SCI interpreter version 1.000.510 - {{"lsl1sci", "VGA Remake", { - {"resource.map", 0, "4fbe5c25878d51d7b2a68b710de4491b", 3327}, - {"resource.000", 0, "5e501a9bf8c753bf4c96158042422f00", 839172}, - {"resource.001", 0, "112648995dbc194037f1e4ed2e195910", 1063341}, - {"resource.002", 0, "3fe2a3aec0ed53c7d6db1845a67e3aa2", 1095908}, - {"resource.003", 0, "ac175df0ea9a2cba57f0248651856d27", 376556}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 1 VGA Remake - Russian DOS - // Executable scanning reports "1.000.510", VERSION file reports "2.0" - // SCI interpreter version 1.000.510 - {{"lsl1sci", "VGA Remake", { - {"resource.map", 0, "b54413d35e206d21ae2b2bdb092bd13a", 3198}, - {"resource.000", 0, "0d7b2afa666bd36d9535a15d3a837a66", 928566}, - {"resource.001", 0, "bc8ca10c807515d959cbd91f9ba47735", 1123759}, - {"resource.002", 0, "b7409ab32bc3bee2d6cce887cd33f2b6", 1092160}, - {NULL, 0, NULL, 0}}, Common::RU_RUS, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 2 - English Amiga (from www.back2roots.org) - // Executable scanning reports "x.yyy.zzz" - // SCI interpreter version 0.000.572 - {{"lsl2", "", { - {"resource.map", 0, "e36ce0fc94d1678d15acbf12d84ec47d", 6612}, - {"resource.001", 0, "a0d4a625311d307257da7fc43d00459d", 409124}, - {"resource.002", 0, "a0d4a625311d307257da7fc43d00459d", 630106}, - {"resource.003", 0, "a0d4a625311d307257da7fc43d00459d", 570356}, - {"resource.004", 0, "a0d4a625311d307257da7fc43d00459d", 717844}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 2 - English DOS Non-Interactive Demo - // Executable scanning reports "x.yyy.zzz" - // SCI interpreter version 0.000.409 - {{"lsl2", "Demo", { - {"resource.map", 0, "03dba704bb77da55a91ad27b5a3cac09", 528}, - {"resource.001", 0, "9f5520f0297206928df0b0b36493cd33", 127532}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 2 - English DOS - // SCI interpreter version 0.000.409 - {{"lsl2", "", { - {"resource.map", 0, "42258cf767a8ebaa9e66b6151a80e601", 5628}, - {"resource.001", 0, "4a24443a25e2b1492462a52809605dc2", 143847}, - {"resource.002", 0, "4a24443a25e2b1492462a52809605dc2", 348331}, - {"resource.003", 0, "4a24443a25e2b1492462a52809605dc2", 236550}, - {"resource.004", 0, "4a24443a25e2b1492462a52809605dc2", 204861}, - {"resource.005", 0, "4a24443a25e2b1492462a52809605dc2", 277732}, - {"resource.006", 0, "4a24443a25e2b1492462a52809605dc2", 345683}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 2 - English DOS - // SCI interpreter version 0.000.343 - {{"lsl2", "", { - {"resource.map", 0, "6bd43c92eaf561f64818116eed683fcf", 5598}, - {"resource.001", 0, "96033f57accfca903750413fd09193c8", 140526}, - {"resource.002", 0, "96033f57accfca903750413fd09193c8", 348672}, - {"resource.003", 0, "96033f57accfca903750413fd09193c8", 236676}, - {"resource.004", 0, "96033f57accfca903750413fd09193c8", 204867}, - {"resource.005", 0, "96033f57accfca903750413fd09193c8", 274953}, - {"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 3 - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.002.032" - // SCI interpreter version 0.000.685 - {{"lsl3", "", { - {"resource.map", 0, "4a6da6322ce189431b5ffbac992bad3a", 5328}, - {"resource.000", 0, "cdc2e21e297b10fe8fed6377af8c5698", 66523}, - {"resource.001", 0, "6abbaf8c7e3b36dd868868ed187e8995", 71761}, - {"resource.002", 0, "a883424fe6d594fec0cd5a79e7ad54c8", 476490}, - {"resource.003", 0, "5c10e462c8cf589610773e4fe8bfd996", 527238}, - {"resource.004", 0, "f408e59cbee1457f042e5773b8c53951", 651634}, - {"resource.005", 0, "433911eb764089d493aed1f958a5615a", 524259}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 3 - English DOS - // SCI interpreter version 0.000.572 - {{"lsl3", "", { - {"resource.map", 0, "0b6bd3e039682830a51c5755c06591db", 5916}, - {"resource.001", 0, "f18441027154292836b973c655fa3175", 456722}, - {"resource.002", 0, "f18441027154292836b973c655fa3175", 578024}, - {"resource.003", 0, "f18441027154292836b973c655fa3175", 506807}, - {"resource.004", 0, "f18441027154292836b973c655fa3175", 513651}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 3 - English DOS - // SCI interpreter version 0.000.572 - {{"lsl3", "", { - {"resource.map", 0, "0f429f5186f96d6c501838a1cb44bd43", 7452}, - {"resource.001", 0, "f18441027154292836b973c655fa3175", 141381}, - {"resource.002", 0, "f18441027154292836b973c655fa3175", 345171}, - {"resource.003", 0, "f18441027154292836b973c655fa3175", 329214}, - {"resource.004", 0, "f18441027154292836b973c655fa3175", 290173}, - {"resource.005", 0, "f18441027154292836b973c655fa3175", 302946}, - {"resource.006", 0, "f18441027154292836b973c655fa3175", 282465}, - {"resource.007", 0, "f18441027154292836b973c655fa3175", 257174}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 3 - English DOS Non-Interactive Demo - // SCI interpreter version 0.000.530 - {{"lsl3", "Demo", { - {"resource.map", 0, "33a2384f395470af3d2180e37ad0322a", 1140}, - {"resource.001", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 76525}, - {"resource.002", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 268299}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 3 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723832) - // Executable scanning reports "S.old.123" - // SCI interpreter version 0.000.572 (just a guess) - {{"lsl3", "", { - {"resource.map", 0, "4a77c8382e48a90c4168d3c144fc1b8f", 6480}, - {"resource.001", 0, "3827a9b17b926e12dcc336860f50612a", 460488}, - {"resource.002", 0, "3827a9b17b926e12dcc336860f50612a", 672403}, - {"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 587036}, - {"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 691932}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 3 - French DOS (provided by richiefs in bug report #2670691) - // Executable scanning reports "S.old.123" - // SCI interpreter version 0.000.572 (just a guess) - {{"lsl3", "", { - {"resource.map", 0, "13541234d440c7988a13582468b0e4be", 6480}, - {"resource.001", 0, "65f1bdaa20f6d0470e9d969f22473873", 457402}, - {"resource.002", 0, "65f1bdaa20f6d0470e9d969f22473873", 671614}, - {"resource.003", 0, "65f1bdaa20f6d0470e9d969f22473873", 586921}, - {"resource.004", 0, "65f1bdaa20f6d0470e9d969f22473873", 690826}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Larry 5 - English Amiga - // Executable scanning reports "1.004.023" - // SCI interpreter version 1.000.784 - {{"lsl5", "", { - {"resource.map", 0, "e36052ae0c8b14d6f074bcb0aee50a38", 6096}, - {"resource.000", 0, "d8b58ce10de52aa16f8b2006838c4fcc", 310510}, - {"resource.001", 0, "8caa8fbb50ea43f3efdfb66f1e68998b", 800646}, - {"resource.002", 0, "abdaa299e00c908052d33cd82eb60e9b", 784576}, - {"resource.003", 0, "810ad1d61638c27a780576cb09f18ed7", 805941}, - {"resource.004", 0, "3ce5901f1bc171ac0274d99a4eeb9e57", 623022}, - {"resource.005", 0, "f8b2d1137bb767e5d232056b99dd69eb", 623621}, - {"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 715598}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 5 - German Amiga - // Executable scanning reports "1.004.024" - // SCI interpreter version 1.000.784 - {{"lsl5", "", { - {"resource.map", 0, "863326c2eb5160f0b0960e159e8bf954", 6372}, - {"resource.000", 0, "5113d03db08e3da77a5b61294001331b", 357525}, - {"resource.001", 0, "59eba83ad465b08d763b44f86afa86f6", 837566}, - {"resource.002", 0, "59eba83ad465b08d763b44f86afa86f6", 622229}, - {"resource.003", 0, "59eba83ad465b08d763b44f86afa86f6", 383690}, - {"resource.004", 0, "59eba83ad465b08d763b44f86afa86f6", 654296}, - {"resource.005", 0, "59eba83ad465b08d763b44f86afa86f6", 664717}, - {"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 754966}, - {"resource.007", 0, "59eba83ad465b08d763b44f86afa86f6", 683135}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 5 - English DOS Non-Interactive Demo (from FRG) - // SCI interpreter version 1.000.181 - {{"lsl5", "Demo", { - {"resource.map", 0, "efe8d3f45ce4f6bd9a6643e0ac8d2a97", 504}, - {"resource.001", 0, "8bd8d9c0b5f455ee1269d63ce86c50dd", 531380}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Larry 5 - English DOS (from spookypeanut) - // SCI interpreter version 1.000.510 - {{"lsl5", "", { - {"resource.map", 0, "be00ef895197754ae4eab021ca44cbcd", 6417}, - {"resource.000", 0, "f671ab479df0c661b19cd16237692846", 726823}, - {"resource.001", 0, "db4a1381d88028876a99303bfaaba893", 751296}, - {"resource.002", 0, "d39d8db1a1e7806e7ccbfea3ef22df44", 1137646}, - {"resource.003", 0, "13fd4942bb818f9acd2970d66fca6509", 768599}, - {"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 1024516}, - {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 1011944}, - {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1024810}, - {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 1030656}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 5 - German DOS (from Tobis87) - // SCI interpreter version 1.000.510 (just a guess) - {{"lsl5", "", { - {"resource.map", 0, "c97297aa76d4dd2ed144c7b7769e2caf", 6867}, - {"resource.000", 0, "4c00c14b8181ad47076a51d86097d97e", 759095}, - {"resource.001", 0, "245c44f8ccd796732e61857e67b30079", 918742}, - {"resource.002", 0, "e86aeb27711f4a673e06ec32cfc84125", 947382}, - {"resource.003", 0, "74edc89d8c1cb346ca346081b927e4c6", 1006884}, - {"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 1023776}, - {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 959342}, - {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1021774}, - {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 993408}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 5 - French DOS (provided by richiefs in bug report #2670691) - // Executable scanning reports "1.lsl5.019" - // SCI interpreter version 1.000.510 (just a guess) - {{"lsl5", "", { - {"resource.map", 0, "499898e652dc41b51e368ae41acce41f", 7023}, - {"resource.000", 0, "4c00c14b8181ad47076a51d86097d97e", 958096}, - {"resource.001", 0, "245c44f8ccd796732e61857e67b30079", 1196765}, - {"resource.002", 0, "e86aeb27711f4a673e06ec32cfc84125", 948898}, - {"resource.003", 0, "74edc89d8c1cb346ca346081b927e4c6", 1006608}, - {"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 971293}, - {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 920524}, - {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 946540}, - {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 958842}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 5 - Spanish DOS (from the Leisure Suit Larry Collection) - // Executable scanning reports "1.ls5.006", VERSION file reports "1.000, 4/21/92" - // SCI interpreter version 1.000.510 (just a guess) - {{"lsl5", "", { - {"resource.map", 0, "b6f7da7bf24e5a6b2946032cec3ea59c", 6861}, - {"resource.000", 0, "4c00c14b8181ad47076a51d86097d97e", 765418}, - {"resource.001", 0, "245c44f8ccd796732e61857e67b30079", 916028}, - {"resource.002", 0, "e86aeb27711f4a673e06ec32cfc84125", 929645}, - {"resource.003", 0, "74edc89d8c1cb346ca346081b927e4c6", 1005496}, - {"resource.004", 0, "999f407c9f38f937d4b8c4230ff5bb38", 1021996}, - {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 958079}, - {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1015136}, - {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 987222}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 5 - Italian DOS Floppy (from glorifindel) - // SCI interpreter version 1.000.510 (just a guess) - {{"lsl5", "", { - {"resource.map", 0, "a99776df795127f387cb35dae872d4e4", 5919}, - {"resource.000", 0, "a8989a5a89e7d4f702b26b378c7a357a", 7001981}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 6 - English DOS (from spookypeanut) - // SCI interpreter version 1.001.113 - {{"lsl6", "", { - {"resource.map", 0, "bb8a39d9e2a77ba449a1e591109ad9a8", 6973}, - {"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 6 - English/German/French DOS CD - LORES - // SCI interpreter version 1.001.115 - {{"lsl6", "", { - {"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263}, - {"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 6 - German DOS CD - LORES (provided by richiefs in bug report #2670691) - // SCI interpreter version 1.001.115 - {{"lsl6", "", { - {"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268}, - {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 6 - French DOS CD - LORES (provided by richiefs in bug report #2670691) - // SCI interpreter version 1.001.115 - {{"lsl6", "", { - {"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268}, - {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 6 - Spanish DOS - LORES (from the Leisure Suit Larry Collection) - // Executable scanning reports "1.001.113", VERSION file reports "1.000, 11.06.93, FIVE PATCHES ADDED TO DISK 6 ON 11-18-93" - {{"lsl6", "", { - {"resource.map", 0, "633bf8f42170b6271019917c8009989b", 6943}, - {"resource.000", 0, "7884a8db9253e29e6b37a2651fd90ba3", 5733116}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Leisure Suit Larry's Casino - English DOS (from the Leisure Suit Larry Collection) - // Executable scanning reports "1.001.029", VERSION file reports "1.000" - {{"lslcasino", "", { - {"resource.map", 0, "194f1578f2624db813c9072359ad1639", 783}, - {"resource.001", 0, "3733433b517ec3d14a3331d9ab3842ae", 344830}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - -#ifdef ENABLE_SCI32 - // Larry 6 - English/German DOS CD - HIRES - // SCI interpreter version 2.100.002 - {{"lsl6", "", { - {"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872}, - {"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 6 - German DOS CD - HIRES (provided by richiefs in bug report #2670691) - // SCI interpreter version 2.100.002 - {{"lsl6", "", { - {"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896}, - {"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 6 - French DOS CD - HIRES (provided by richiefs in bug report #2670691) - // SCI interpreter version 2.100.002 - {{"lsl6", "", { - {"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896}, - {"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 7 - English DOS CD (from spookypeanut) - // SCI interpreter version 3.000.000 - {{"lsl7", "", { - {"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188}, - {"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 7 - German DOS (from Tobis87) - // SCI interpreter version 3.000.000 - {{"lsl7", "", { - {"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188}, - {"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 7 - French DOS (provided by richiefs in bug report #2670691) - // SCI interpreter version 3.000.000 - {{"lsl7", "", { - {"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206}, - {"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 7 - Italian DOS CD (from glorifindel) - // SCI interpreter version 3.000.000 - {{"lsl7", "", { - {"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212}, - {"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection) - // Executable scanning reports "3.000.000", VERSION file reports "1.0s" - {{"lsl7", "", { - {"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188}, - {"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691) - // SCI interpreter version 2.100.002 - {{"lsl7", "Demo", { - {"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878}, - {"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Lighthouse - English Windows Demo (from jvprat) - // Executable scanning reports "2.100.002", VERSION file reports "1.00" - {{"lighthouse", "Demo", { - {"resource.map", 0, "543124606352bfa5e07696ddf2a669be", 64}, - {"resource.000", 0, "5d7714416b612463d750fb9c5690c859", 28952}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Lighthouse - English Windows Demo - // Executable scanning reports "3.000.000", VERSION file reports "1.00" - {{"lighthouse", "Demo", { - {"resmap.000", 0, "3bdee7a16926975a4729f75cf6b80a92", 1525}, - {"ressci.000", 0, "3c585827fa4a82f4c04a56a0bc52ccee", 11494351}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Lighthouse - English DOS (from jvprat) - // Executable scanning reports "3.000.000", VERSION file reports "1.1" - {{"lighthouse", "", { - {"resmap.001", 0, "47abc502c0b541b582db28f38dbc6a56", 7801}, - {"ressci.001", 0, "14e922c47b92156377cb49e241691792", 99591924}, - {"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573}, - {"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Lighthouse - Spanish DOS (from jvprat) - // Executable scanning reports "3.000.000", VERSION file reports "1.1" - {{"lighthouse", "", { - {"resmap.001", 0, "c5d49b2a8a4eafc92fd041a3a0f2da68", 7846}, - {"ressci.001", 0, "18553177dbf83fb2cb6c8edcbb174183", 99543093}, - {"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630}, - {"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, -#endif // ENABLE_SCI32 - - // Mixed-Up Fairy Tales v1.000 - English DOS Non-Interactive Demo - {{"fairytales", "Demo", { - {"resource.map", 0, "c2cf672c3f4251e7472d4542af3bf764", 933}, - {"resource.000", 0, "8be56a3a88c065ee00c02c0e29199f3a", 14643}, - {"resource.001", 0, "9e33566515b18bee7915db448063bba2", 871853}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791) - // Executable scanning reports "1.000.145" - {{"fairytales", "", { - {"resource.map", 0, "9ae5aecc1cb797b11ea5cf0caeea272c", 3261}, - {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 923685}, - {"resource.001", 0, "49c8f7dcd9989e4491a93554bec325b0", 52324}, - {"resource.002", 0, "6767f8c8585f617aaa91d442f41ae714", 1032989}, - {"resource.003", 0, "b1288e0821ee358d1ffe877e5900c8ec", 1047565}, - {"resource.004", 0, "f79daa70390d73746742ffcfc3dc4471", 937580}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Mixed-Up Fairy Tales - English DOS Floppy (from jvprat) - // Executable scanning reports "1.000.145", Floppy label reports "1.0, 11.13.91", VERSION file reports "1.000" - {{"fairytales", "", { - {"resource.map", 0, "66105c02fa8f1785a3fd28957e41cb48", 3249}, - {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 984439}, - {"resource.001", 0, "49c8f7dcd9989e4491a93554bec325b0", 238019}, - {"resource.002", 0, "564f516d991032e781492592a4eaa275", 1414142}, - {"resource.003", 0, "dd6cef0c592eadb7e6be9a25307c57a2", 1344719}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Mixed-Up Mother Goose - English Amiga (from www.back2roots.org) - // Executable scanning reports "1.003.009" - // SCI interpreter version 0.001.010 - {{"mothergoose", "", { - {"resource.map", 0, "4aa28ac93fae03cf854594da13d9229c", 2700}, - {"resource.001", 0, "fb552ae550ca1dac19ed8f6a3767612d", 262885}, - {"resource.002", 0, "fb552ae550ca1dac19ed8f6a3767612d", 817191}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795) - // Executable scanning reports "1.001.031" - {{"mothergoose", "", { - {"resource.map", 0, "52aae15e493cafd1da7e1c9b657a5bb9", 7026}, - {"resource.000", 0, "b7ecd8ae9e254e80310b5a668b276e6e", 2948975}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Mixed-Up Mother Goose - English DOS CD (from jvprat) - // Executable scanning reports "x.yyy.zzz" - // SCI interpreter version 0.000.999 (just a guess) - {{"mothergoose", "CD", { - {"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790}, - {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Mixed-Up Mother Goose - English Windows Interactive Demo - // Executable scanning reports "x.yyy.zzz" - {{"mothergoose", "Demo", { - {"resource.map", 0, "87f9dc1cafc4d4fa835fb2f00cf3a6ef", 4560}, - {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 2070072}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - -#ifdef ENABLE_SCI32 - // Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810) - // Executable scanning reports "2.100.002" - {{"mothergoose", "", { - {"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741}, - {"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, -#endif // ENABLE_SCI32 - - // Ms. Astro Chicken - English DOS - // SCI interpreter version 1.000.679 - {{"msastrochicken", "", { - {"resource.map", 0, "5b457cbe5042f557e5b610148171f6c0", 1158}, - {"resource.001", 0, "453ea81ef66a50cbe33ce06302afe47f", 229737}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - -#ifdef ENABLE_SCI32 - // Phantasmagoria - English DOS (from jvprat) - // Executable scanning reports "2.100.002", VERSION file reports "1.100.000UK" - {{"phantasmagoria", "", { - {"resmap.001", 0, "416138651ea828219ca454cae18341a3", 11518}, - {"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612}, - {"resmap.002", 0, "de521d0c7ab32897e7fe58e421c816b7", 12058}, - {"ressci.002", 0, "3aae6559aa1df273bc542d5ac6330d75", 71588691}, - {"resmap.003", 0, "25df95bd7da3686f71a0af8784a2b8ca", 12334}, - {"ressci.003", 0, "3aae6559aa1df273bc542d5ac6330d75", 73651084}, - {"resmap.004", 0, "e108a3d35794f1721aeea3e62a3f8b3b", 12556}, - {"ressci.004", 0, "3aae6559aa1df273bc542d5ac6330d75", 75811935}, - {"resmap.005", 0, "390d81f9e14a3f3ee2ea477135f0288e", 12604}, - {"ressci.005", 0, "3aae6559aa1df273bc542d5ac6330d75", 78814934}, - {"resmap.006", 0, "8ea3c954606e80604680f9fe707f15d8", 12532}, - {"ressci.006", 0, "3aae6559aa1df273bc542d5ac6330d75", 77901360}, - {"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972}, - //{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Phantasmagoria 2 - English Windows (from jvprat) - // Executable scanning reports "3.000.000", VERSION file reports "001.0.06" - {{"phantasmagoria2", "", { - {"resmap.001", 0, "0a961e135f4f7effb195158325856633", 1108}, - {"ressci.001", 0, "53f457cddb0dffc056593905c4cbb989", 24379964}, - {"resmap.002", 0, "5d3189fe3d4f286f83c5c8031fa3e9f7", 1126}, - {"ressci.002", 0, "53f457cddb0dffc056593905c4cbb989", 34465805}, - {"resmap.003", 0, "c92e3c840b827c236ab6671c03760c56", 1162}, - {"ressci.003", 0, "53f457cddb0dffc056593905c4cbb989", 38606375}, - {"resmap.004", 0, "8d5cfe19365f71370b87063686f39171", 1288}, - {"ressci.004", 0, "53f457cddb0dffc056593905c4cbb989", 42447131}, - {"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942}, - {"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, -#endif // ENABLE_SCI32 - - // Pepper's Adventure In Time 1.000 English - // Executable scanning reports "1.001.072", VERSION file reports "1.000" - {{"pepper", "", { - {"resource.map", 0, "72726dc81c1b4c1110c486be77369bc8", 5179}, - {"resource.000", 0, "670d0c53622429f4b11275caf7f8d292", 5459574}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Pepper - English DOS Non-Interactive Demo - // Executable scanning reports "1.001.060", VERSION file reports "1.000" - {{"pepper", "Demo", { - {"resource.map", 0, "379bb4fb896630b14f2d91ed21e36ba1", 984}, - {"resource.000", 0, "118f6c31a93ec7fd9a231c61125229e3", 645494}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Pepper - English DOS/Windows Interactive Demo - // Executable scanning reports "1.001.069", VERSION file reports ".001" - {{"pepper", "Demo", { - {"resource.map", 0, "975e8df76106a5c13d12ab674f906a02", 2514}, - {"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1698164}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Pepper - English DOS Interactive Demo - // Executable scanning reports "1.001.072", VERSION file reports "1.000" - {{"pepper", "Demo", { - {"resource.map", 0, "9c9b7b900651a370dd3fb38d478b1798", 2524}, - {"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1713544}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 1 VGA Remake - English DOS (from the Police Quest Collection) - // Executable scanning reports "1.001.029", VERSION file reports "2.000" - {{"pq1sci", "VGA Remake", { - {"resource.map", 0, "35efa814fb994b1cbdac9611e401da67", 5013}, - {"resource.000", 0, "e0d5ddf34eda903a38f0837e2aa7145b", 6401433}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 2 - English Amiga (from www.back2roots.org) - // SCI interpreter version 0.000.685 (just a guess) - {{"pq2", "", { - {"resource.map", 0, "499de78ae72b7ce219f944c5e7ef0c5b", 3426}, - {"resource.000", 0, "77f02def3094af804fd2371db25b7100", 250232}, - {"resource.001", 0, "523db0c07f1da2a822c2c39ee0482544", 179334}, - {"resource.002", 0, "499737c21a28ac026e11ab817100d610", 511099}, - {"resource.003", 0, "e008f5d6e2a7c4d4a0da0173e4fa8f8b", 553970}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 2 - English DOS Non-Interactive Demo - // Executable scanning reports "0.000.413" - {{"pq2", "Demo", { - {"resource.map", 0, "8b77d0d4650c2052b356cece28294b58", 576}, - {"resource.001", 0, "376ef6d6eaaeed66e1424bd219c4b9ab", 215398}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Police Quest 2 - English DOS (provided by richiefs in bug report #2670691) - // SCI interpreter version 0.000.395 - {{"pq2", "", { - {"resource.map", 0, "9cff78c4be9e6a4848b6e9377569e3d9", 5700}, - {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 163291}, - {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 329367}, - {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 305819}, - {"resource.004", 0, "77f02def3094af804fd2371db25b7100", 342149}, - {"resource.005", 0, "77f02def3094af804fd2371db25b7100", 349899}, - {"resource.006", 0, "77f02def3094af804fd2371db25b7100", 354991}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Police Quest 2 - English DOS (from the Police Quest Collection) - // Executable scanning reports "0.000.490" - {{"pq2", "", { - {"resource.map", 0, "28a6f471c7900c2c92da40eecb615d9d", 4584}, - {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509525}, - {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000}, - {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Police Quest 2 - English DOS (from FRG) - // SCI interpreter version 0.000.395 - {{"pq2", "", { - {"resource.map", 0, "fe019e9773623fcb7da810db9e64c8a9", 4548}, - {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509760}, - {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 542897}, - {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 586857}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Police Quest 3 - English Amiga - // Executable scanning reports "1.004.024" - // SCI interpreter version 1.000.784 - {{"pq3", "", { - {"resource.map", 0, "29923fe1ef1f0909b57255d61c558e68", 5742}, - {"resource.000", 0, "4908e4f4977e8e19c90c29b36a741ffe", 298541}, - {"resource.001", 0, "0eb943ca807e2f69578821d490770d2c", 836567}, - {"resource.002", 0, "f7044bb08a1fcbe5077791ed8d4996f0", 691207}, - {"resource.003", 0, "630bfa65beb05f743552704ac2899dae", 759891}, - {"resource.004", 0, "7b229fbdf30d670d0728cede3e984a7e", 838663}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 3 - German Amiga - // Executable scanning reports "1.004.024" - // SCI interpreter version 1.000.784 - {{"pq3", "", { - {"resource.map", 0, "357304811fc2bbaa3443fc62d677fe06", 6282}, - {"resource.000", 0, "49879e6ce7c19151ffa6af1a09763dc7", 324273}, - {"resource.001", 0, "015e6119badb391ab5f4b36abedb5d4a", 718814}, - {"resource.002", 0, "1ee419ba252fbed47fbce8399f56f8ad", 674823}, - {"resource.003", 0, "87361c17fd863b58f98828de68770279", 682288}, - {"resource.004", 0, "6258d5dd85898d8e218eb8113ebc9059", 722738}, - {"resource.005", 0, "6258d5dd85898d8e218eb8113ebc9059", 704485}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 3 - English DOS (from the Police Quest Collection) - // Executable scanning reports "T.A00.178", VERSION file reports "1.00" - // SCI interpreter version 1.000.510 - {{"pq3", "", { - {"resource.map", 0, "6457bf0c8ca865a42d9ff5827ab49b89", 5559}, - {"resource.000", 0, "7659713720d61d9465a59091b7ee63ea", 737253}, - {"resource.001", 0, "61c7c187d25a8346be0a092d5f037278", 1196787}, - {"resource.002", 0, "c18e0d408e4f4f40365d42aa15931f67", 1153561}, - {"resource.003", 0, "8791b9eef53edf77c2dac950142221d3", 1159791}, - {"resource.004", 0, "1b91e891a3c60a941dac0eecdf83375b", 1143606}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 3 - English DOS Non-Interactive Demo - // Executable scanning reports "T.A00.052" - // SCI interpreter version 1.000.510 - {{"pq3", "Demo", { - {"resource.map", 0, "ec8e58e7663ae5173853abf6c76b52bb", 867}, - {"resource.000", 0, "277f97771f7a6d89677141f02da313d6", 65150}, - {"resource.001", 0, "5c5a551b6c86cce2ee75becb90e0b586", 624411}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 3 - German DOS (supplied by markcoolio in bug report #2723837) - // Executable scanning reports "T.A00.178" - // SCI interpreter version 1.000.510 - {{"pq3", "", { - {"resource.map", 0, "8a970edf98eba4c11bb1827aab1694d1", 5625}, - {"resource.000", 0, "5ee460af3d70c06a745cc482b6c783ba", 865204}, - {"resource.001", 0, "ff6182bf96c8f8af5bd8c11769c9cbf2", 1183456}, - {"resource.002", 0, "cce99b96a578b62ff6cebdae8d122feb", 1179358}, - {"resource.003", 0, "4836f460f4cfc8de61e2df4c45775504", 1180956}, - {"resource.004", 0, "0c3eb84b9755852d9e795e0d5c9373c7", 1171760}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 4 - English DOS Non-Interactive Demo (from FRG) - // SCI interpreter version 1.001.096 - {{"pq4", "Demo", { - {"resource.map", 0, "be56f87a1c4a13062a30a362df860c2f", 1472}, - {"resource.000", 0, "527d5684016e6816157cd15d9071b11b", 1121310}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - -#ifdef ENABLE_SCI32 - // Police Quest 4 - English DOS (from the Police Quest Collection) - // Executable scanning reports "2.100.002", VERSION file reports "1.100.000" - {{"pq4", "", { - {"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374}, - {"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 4 - English DOS - // SCI interpreter version 2.000.000 (a guess?) - {{"pq4", "", { - {"resource.map", 0, "aed9643158ccf01b71f359db33137f82", 9895}, - {"resource.000", 0, "da383857b3be1e4514daeba2524359e0", 15141432}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest 4 - German DOS (supplied by markcoolio in bug report #2723840) - // SCI interpreter version 2.000.000 (a guess?) - {{"pq4", "", { - {"resource.map", 0, "2393ee728ab930b2762cb5889f9b5aff", 9256}, - {"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730155}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest: SWAT - English DOS/Windows Demo (from jvprat) - // Executable scanning reports "2.100.002", VERSION file reports "0.001.200" - {{"pqswat", "Demo", { - {"resource.map", 0, "8c96733ef94c21526792f7ca4e3f2120", 1648}, - {"resource.000", 0, "d8892f1b8c56c8f7704325460f49b300", 3676175}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Police Quest: SWAT - English Windows (from the Police Quest Collection) - // Executable scanning reports "2.100.002", VERSION file reports "1.0c" - {{"pqswat", "", { - {"resmap.001", 0, "de5ea1beb3d9490737aa5fd398fe9765", 6937}, - {"ressci.001", 0, "7cd5414f54748f90904a46123a52472f", 29467363}, - {"resmap.002", 0, "ff7a7e0f3dea2c73182b7ea84e3431cc", 6211}, - {"ressci.002", 0, "e613357f3349c4bfa5a7b7b312be7f97", 25987989}, - {"resmap.003", 0, "84303aa019fa75a0eb20ba502bc4ccae", 6601}, - {"ressci.003", 0, "00a755e917c442ca8cf1a1bea689e6fb", 45073980}, - {"resmap.004", 0, "4228038906f041623e65789500b22285", 6835}, - {"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, -#endif // ENABLE_SCI32 - - // Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by merkur in bug report #2718784) - // Executable scanning reports "0.000.566" - {{"qfg1", "", { - {"resource.map", 0, "c1dc4470fb947c067567252f62d6c1b6", 6474}, - {"resource.000", 0, "481b034132106390cb5160fe61dd5f58", 80334}, - {"resource.001", 0, "4d67acf52833ff45c7f753d6663532e8", 462727}, - {"resource.002", 0, "439ba9b6dde216e6eb97ef3a9830fbe4", 646869}, - {"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203}, - {"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by markcoolio in bug report #2723843) - // Executable scanning reports "0.000.566" - {{"qfg1", "", { - {"resource.map", 0, "94bc3f2ae2dad12f1303606740d087ff", 6936}, - {"resource.000", 0, "481b034132106390cb5160fe61dd5f58", 80334}, - {"resource.001", 0, "4d67acf52833ff45c7f753d6663532e8", 95498}, - {"resource.002", 0, "3e2a89d60d385caca5b3394049da4bc4", 271587}, - {"resource.003", 0, "e56e9fd2f7d2c98774699f7a5087e524", 255998}, - {"resource.004", 0, "d74cd4290bf60e1409117202e4ce8592", 266415}, - {"resource.005", 0, "7288ed6d5da89b7a80b4af3897a7963a", 271185}, - {"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852}, - {"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Quest for Glory 1 - Japanese PC-98 5.25" Floppy - // Executable scanning reports "S.old.201" - {{"qfg1", "8 Colors", { - {"resource.map", 0, "5cbeb95dd2a4b7cb242b415cc6ec1c47", 6444}, - {"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 859959}, - {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968}, - {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897}, - {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 1 - Japanese PC-98 5.25" Floppy - // Executable scanning reports "S.old.201" - {{"qfg1", "16 Colors", { - {"resource.map", 0, "3ecaba33bf77cb434067a0b8aee15097", 6444}, - {"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 864754}, - {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121}, - {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575}, - {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 1 - English Amiga - // Executable scanning reports "1.002.020" - // SCI interpreter version 0.000.685 - {{"qfg1", "", { - {"resource.map", 0, "e65034832f0c9df1dc22128227b782d0", 6066}, - {"resource.000", 0, "1c0255dea2d3cd71eee9f2db201eee3f", 111987}, - {"resource.001", 0, "a270012fa74445d74c044d1b65a9ff8c", 143570}, - {"resource.002", 0, "e64004e020fdf1813be52b639b08be89", 553201}, - {"resource.003", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 654096}, - {"resource.004", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 689124}, - {"resource.005", 0, "5f3386ef2f2b1254e4a066f5d9027324", 609529}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 1 - English DOS - // SCI interpreter version 0.000.629 - {{"qfg1", "", { - {"resource.map", 0, "74a108a7fb345bfc84f4113b6e5241bb", 6432}, - {"resource.000", 0, "40332d3ebfc70a4b6a6a0443c2763287", 79181}, - {"resource.001", 0, "917fcef303e9489597154727baaa9e07", 461422}, - {"resource.002", 0, "05ddce5f437a516b89ede2438fac09d8", 635734}, - {"resource.003", 0, "951299a82a8134ed12c5c18118d45c2f", 640483}, - {"resource.004", 0, "951299a82a8134ed12c5c18118d45c2f", 644443}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 1 VGA Remake - English DOS - // Executable scanning reports "2.000.411" - {{"qfg1", "VGA Remake", { - {"resource.map", 0, "a731fb6c9c0b282443f7027bc8694d4c", 8469}, - {"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 1 VGA Remake - English DOS Non-Interactive Demo (from FRG) - // SCI interpreter version 1.001.029 - {{"qfg1", "VGA Remake Demo", { - {"resource.map", 0, "ac0257051c95a59c0cdc0be24d9b11fa", 729}, - {"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 2 - English Amiga - // Executable scanning reports "1.003.004" - // SCI interpreter version 0.001.010 - {{"qfg2", "", { - {"resource.map", 0, "365ea1033ba26d227ec4007be88c59cc", 7596}, - {"resource.000", 0, "810245be50fde5a67e3ea95e876e3e64", 233341}, - {"resource.001", 0, "7a5fde9875211ed67a896fc0d91940c8", 127294}, - {"resource.002", 0, "dcf6bc2c18660d7ad532fb61861eb721", 543644}, - {"resource.003", 0, "dcf6bc2c18660d7ad532fb61861eb721", 565044}, - {"resource.004", 0, "dcf6bc2c18660d7ad532fb61861eb721", 466630}, - {"resource.005", 0, "a77d2576c842b2b06da57d4ac8fc51c0", 579975}, - {"resource.006", 0, "ccf5dba33e5cab6d5872838c0f8db44c", 500039}, - {"resource.007", 0, "4c9fc1587545879295cb9627f56a2cb8", 575056}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 2 - English (from FRG) - // Executable scanning reports "1.000.072" - {{"qfg2", "", { - {"resource.map", 0, "bc79c5685c00edab3ad6df18691703bc", 6906}, - {"resource.000", 0, "a17e374c4d33b81208c862bc0ffc1a38", 212119}, - {"resource.001", 0, "e08d7887e30b12008c40f9570447711a", 867866}, - {"resource.002", 0, "df137dc7869cab07e1149ba2333c815c", 790750}, - {"resource.003", 0, "b192607c42f6960ecdf2ad2e4f90e9bc", 972804}, - {"resource.004", 0, "cd2de58e27665d5853530de93fae7cd6", 983617}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 2 - English DOS - // Executable scanning reports "1.000.072" - {{"qfg2", "", { - {"resource.map", 0, "be23af27e9557bf232efe213ac7f277c", 8166}, - {"resource.000", 0, "a17e374c4d33b81208c862bc0ffc1a38", 212120}, - {"resource.001", 0, "e08d7887e30b12008c40f9570447711a", 331973}, - {"resource.002", 0, "df137dc7869cab07e1149ba2333c815c", 467505}, - {"resource.003", 0, "df137dc7869cab07e1149ba2333c815c", 502560}, - {"resource.004", 0, "df137dc7869cab07e1149ba2333c815c", 488541}, - {"resource.005", 0, "df137dc7869cab07e1149ba2333c815c", 478688}, - {"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489}, - {"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 3 - English DOS Non-Interactive Demo (from FRG) - // Executable scanning reports "1.001.021", VERSION file reports "1.000, 0.001.059, 6.12.92" - {{"qfg3", "Demo", { - {"resource.map", 0, "fd71de9b588a45f085317caacf050e91", 687}, - {"resource.000", 0, "b6c69bf6c18bf177492249fe81fc6a6d", 648702}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 3 - English DOS - // SCI interpreter version 1.001.050 - {{"qfg3", "", { - {"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, - {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 3 - German DOS (supplied by markcoolio in bug report #2723846) - // Executable scanning reports "L.rry.083" - {{"qfg3", "", { - {"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, - {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 3 - Spanish DOS CD (from jvprat) - // Executable scanning reports "L.rry.083", VERSION file reports "1.000.000, June 30, 1994" - {{"qfg3", "", { - {"resource.map", 0, "10809197c33a5e62819311d8a2f73f85", 5978}, - {"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098}, - {"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Quest for Glory 4 - English DOS Non-Interactive Demo (from FRG) - // SCI interpreter version 1.001.069 (just a guess) - {{"qfg4", "Demo", { - {"resource.map", 0, "1ba7c7ae1efb315326d45cb931569b1b", 922}, - {"resource.000", 0, "41ba03f0b188b029132daa3ece0d3e14", 623154}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - -#ifdef ENABLE_SCI32 - // Quest for Glory 4 1.1 Floppy - English DOS (supplied by markcool in bug report #2723852) - // SCI interpreter version 2.000.000 (a guess?) - {{"qfg4", "", { - {"resource.map", 0, "685bdb1ed47bbbb0e5e25db392da83ce", 9301}, - {"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11004993}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 4 1.1 Floppy - German DOS (supplied by markcool in bug report #2723850) - // SCI interpreter version 2.000.000 (a guess?) - {{"qfg4", "", { - {"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301}, - {"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Quest for Glory 4 - English DOS/Windows (from jvprat) - // Executable scanning reports "2.100.002", VERSION file reports "1.0" - {{"qfg4", "", { - {"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, - {"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - -#if 0 - // NOTE: This version looks to be exactly the same as the English one - // Perhaps it's the English one? - - // Quest for Glory 4 - German DOS/Windows (from PCJoker 2/98) - {{"qfg4", "", { - {"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, - {"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, -#endif - - // Quest for Glory 4 - German DOS/Windows Disk V1.1 (from PCJoker 2/89) - // SCI interpreter version 2.000.000 (a guess?) - {{"qfg4", "", { - {"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301}, - {"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // RAMA - English DOS/Windows Demo - // Executable scanning reports "2.100.002", VERSION file reports "000.000.008" - {{"rama", "Demo", { - {"resmap.001", 0, "775304e9b2a545156be4d94209550094", 1393}, - {"ressci.001", 0, "259437fd75fdf51e8207fda8c01fa4fd", 2334384}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // RAMA - English Windows (from jvprat) - // Executable scanning reports "3.000.000", VERSION file reports "1.100.000" - {{"rama", "", { - {"resmap.001", 0, "3bac72a1910a563f8f92cf5b77c8b7f2", 8338}, - {"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70588050}, - {"resmap.002", 0, "83c2aa4653a985ab4b49ff60532ed08f", 12082}, - {"ressci.002", 0, "2a68edd064e5e4937b5e9c74b38f2082", 128562138}, - {"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636}, - {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, - - // RAMA - Italian Windows CD (from glorifindel) - // SCI interpreter version 3.000.000 (a guess?) - {{"rama", "", { - {"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091}, - {"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE}, - 0 - }, - - // Shivers - English Windows (from jvprat) - // Executable scanning reports "2.100.002", VERSION file reports "1.02" - {{"shivers", "", { - {"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525}, - {"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, - - // Shivers - German Windows (from Tobis87) - {{"shivers", "", { - {"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537}, - {"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, - - // Shivers - English Windows Demo - // Executable scanning reports "2.100.002" - {{"shivers", "Demo", { - {"resmap.000", 0, "d9e0bc5eddefcbe47f528760085d8927", 1186}, - {"ressci.000", 0, "3a93c6340b54e07e65d0e5583354d186", 10505469}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Shivers2 - English Windows Demo - // Executable scanning reports "3.000.000" - {{"shivers2", "Demo", { - {"resmap.000", 0, "d8659188b84beaef076bd869837cd530", 634}, - {"ressci.000", 0, "7fbac0807a044c9543e8ac376d200e59", 4925003}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, -#endif // ENABLE_SCI32 - - // Slater & Charlie Go Camping - English DOS Demo - // Executable scanning reports "1.cfs.081", VERSION file reports "1.000" - {{"slater", "Demo", { - {"resource.map", 0, "61b4f74039399e5aa1e737b16d0fc023", 1409}, - {"resource.msg", 0, "1aeafe2b495de288d002109650b66614", 1364}, - {"resource.000", 0, "8e10d4f05c1fd9f883384fa38a898489", 377394}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org) - // SCI interpreter version 1.000.510 (just a guess) - {{"sq1sci", "VGA Remake", { - {"resource.map", 0, "106484b372af1d4cbf866472cc2813dc", 6396}, - {"resource.000", 0, "cc9d6ace343661ae51ec8bd6e6b00a8c", 340944}, - {"resource.001", 0, "59efcfa2268d2f8608f544e2674d8151", 761721}, - {"resource.002", 0, "f00ef883128bf5fc2fbb888cdd7adf25", 814461}, - {"resource.003", 0, "2588c1c2ca8b9bed0e3411948c0856a9", 839302}, - {"resource.004", 0, "b25a1539c71701f7715f738c5037e9a6", 775515}, - {"resource.005", 0, "640ffe1a9acde392cc33cc1b1a528328", 806324}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 1 VGA Remake - English DOS (from the Space Quest Collection) - // Executable scanning reports "T.A00.081", VERSION file reports "2.000" - // SCI interpreter version 1.000.510 (just a guess) - {{"sq1sci", "VGA Remake", { - {"resource.map", 0, "38a74d8f555a2da9ca4f21d14e3c1d33", 5913}, - {"resource.000", 0, "e9d866534f8c84de82e25f2631ff258c", 1016436}, - {"resource.001", 0, "a89b7b52064c75b1985b289edc2f5c69", 1038757}, - {"resource.002", 0, "a9e847c687529481f3a22b9bf01f45f7", 1169831}, - {"resource.003", 0, "c47600e50c6fc591957ae0c5020ee7b8", 1213262}, - {"resource.004", 0, "e19ea4ad131472f9238590f2e1d40289", 1203051}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 1 VGA Remake - English Non-Interactive Demo (from FRG) - // SCI interpreter version 1.000.181 - {{"sq1sci", "VGA Remake Demo", { - {"resource.map", 0, "5af709ac5e0e923e0b8174f49978c30e", 636}, - {"resource.001", 0, "fd99ea43f57576ded7c86036996346cf", 507642}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 1 VGA Remake - Spanish DOS Floppy (from jvprat) - // Executable scanning reports "T.A00.081", VERSION file reports "2.000" - // SCI interpreter version 1.000.510 (just a guess) - {{"sq1sci", "VGA Remake", { - {"resource.map", 0, "cee2a67fa7f8f1f520f398110ca1c37e", 6111}, - {"resource.000", 0, "945081a73211e0c40e62f709edcd8d1d", 970657}, - {"resource.001", 0, "94692dc84c85c93bb8850f58aebf3cfc", 1085687}, - {"resource.002", 0, "fc9ad3357e4cedec1611ad2b67b193a9", 1175465}, - {"resource.003", 0, "8c22700a02991b763f512f837636b3ca", 1211307}, - {"resource.004", 0, "9b78228ad4f9f335fedf74f1812dcfca", 513325}, - {"resource.005", 0, "7d4ebcb745c0bf8fc42e4013f52ecd49", 1101812}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 3 - English Amiga (from www.back2roots.org) - // SCI interpreter version 0.000.453 (just a guess) - {{"sq3", "", { - {"resource.map", 0, "bad41385acde6d677a8d55a7b20437e3", 5868}, - {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 171636}, - {"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 754432}, - {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 746496}, - {"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 761984}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Space Quest 3 - German Amiga - // Executable scanning reports "1.004.006" - // SCI interpreter version 0.000.453 (just a guess) - {{"sq3", "", { - {"resource.map", 0, "44f53185fdf3f44f946e9cac3ca6588b", 6348}, - {"resource.001", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 238664}, - {"resource.002", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 642014}, - {"resource.003", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 712374}, - {"resource.004", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 545053}, - {"resource.005", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 687507}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 3 - English DOS Non-Interactive Demo - // SCI interpreter version 0.000.453 - {{"sq3", "Demo", { - {"resource.map", 0, "ec66ac2b1ce58b2575ba00b65058de1a", 612}, - {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 180245}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Space Quest 3 - English DOS (provided by richiefs in bug report #2670691) - // SCI interpreter version 0.000.453 - {{"sq3", "", { - {"resource.map", 0, "fee82d211c3918a90ce3b476d3dbb245", 5484}, - {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 485158}, - {"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720244}, - {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688367}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Space Quest 3 - English DOS (from the Space Quest Collection) - // Executable scanning reports "0.000.685", VERSION file reports "1.018" - {{"sq3", "", { - {"resource.map", 0, "55e91aeef1705bce2a9b79172682f36d", 5730}, - {"resource.001", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 490247}, - {"resource.002", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 715777}, - {"resource.003", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 703370}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 3 - German DOS (from Tobis87) - // SCI interpreter version 0.000.453 (?) - {{"sq3", "", { - {"resource.map", 0, "4965c78b5eff50d5e4148ce114594ba8", 7584}, - {"resource.001", 0, "9107c2aa5398e28b5c5406df13491f85", 117869}, - {"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 336101}, - {"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 350391}, - {"resource.004", 0, "9107c2aa5398e28b5c5406df13491f85", 349750}, - {"resource.005", 0, "9107c2aa5398e28b5c5406df13491f85", 322107}, - {"resource.006", 0, "9107c2aa5398e28b5c5406df13491f85", 320643}, - {"resource.007", 0, "9107c2aa5398e28b5c5406df13491f85", 344287}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - GF_FOR_SCI0_BEFORE_629 - }, - - // Space Quest 3 v1.052 - German DOS (supplied by markcoolio in bug report #2723860) - // Executable scanning reports "S.old.114" - {{"sq3", "", { - {"resource.map", 0, "f0dd735098c254f584878649c6f08dbc", 5154}, - {"resource.001", 0, "9107c2aa5398e28b5c5406df13491f85", 567245}, - {"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 596768}, - {"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 693573}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - English Amiga - // Executable scanning reports "1.004.024" - // SCI interpreter version 1.000.200 - {{"sq4", "", { - {"resource.map", 0, "d87ae90031e7fd04f32a27db054f5c9c", 6174}, - {"resource.000", 0, "19671ac620a0a4720a1937c20c2e24a1", 323309}, - {"resource.001", 0, "abca51a4c896df550f095a2db71dce46", 805915}, - {"resource.002", 0, "5667852471ba5b7f5b9a770eabd07df2", 796615}, - {"resource.003", 0, "6ec43464f6a17e612636e2928fd9471c", 803868}, - {"resource.004", 0, "1887ed88bb34ae7238650e8f77f26315", 798226}, - {"resource.005", 0, "3540d1cc84d674cf4b2c898b88a3b563", 790296}, - {"resource.006", 0, "ade814bc4d56244c156d9e9bcfebbc11", 664085}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - German Amiga (from www.back2roots.org) - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "79641c0d43408e33c251a1d494d2575e", 6252}, - {"resource.000", 0, "feff51c52146b3a31d4793c718279e13", 345170}, - {"resource.001", 0, "ab33060bfebe32450c0b8d9a3a066efc", 822470}, - {"resource.002", 0, "f79fd6a62da082addb205ed6cef99629", 810458}, - {"resource.003", 0, "f4c21da916f450d4b893b4cba6120866", 815854}, - {"resource.004", 0, "99c6a017da5e769a3b427ca52c8a564f", 824601}, - {"resource.005", 0, "10ee1709e6559c724676d058199b75b5", 818745}, - {"resource.006", 0, "67fb188b191d88efe8414af6ea297b93", 672675}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - English DOS - // Executable scanning reports "1.000.753" - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "a18088c8aceb06025dbc945f29e02935", 5124}, - {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 5502009}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - English DOS - // Executable scanning reports "1.000.753" - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "71ccf4f82ac4efb588731acfb7bf2603", 5646}, - {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 933928}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 1.052 - English DOS Floppy (supplied by markcoolio in bug report #2723865) - // Executable scanning reports "1.000.753" - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "98852d6379622001efd0b50ae93c9a30", 5928}, - {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 173330}, - {"resource.001", 0, "cc2f89e6057e05b040566b3699df7288", 1247215}, - {"resource.002", 0, "9c342cd76b421369406d6fafd7b1a285", 1218373}, - {"resource.003", 0, "96fa33d89d838bc3f671c5b953e7a896", 1240130}, - {"resource.004", 0, "ff9c87da3bc53473fdee8b9d3edbc93c", 1200631}, - {"resource.005", 0, "e33019ac19f755ae33fbf49b4fc9066c", 1053294}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - German DOS (from Tobis87) - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "71715e775e3791178d606cfe6c7e1fb9", 6339}, - {"resource.000", 0, "5f6a1fff40584ee807efd547899b1ba5", 206032}, - {"resource.001", 0, "e924cf86a72ada7736043f045cce345f", 1065442}, - {"resource.002", 0, "e18d731c3fba51333a7f402e454714a5", 858402}, - {"resource.003", 0, "7c2e7508af1a6af877d921e476f70b5e", 1172738}, - {"resource.004", 0, "b8d6efbd3235329bfe844c794097b2c9", 1064761}, - {"resource.005", 0, "47ee647b5b12232d27e63cc627c25899", 1156765}, - {"resource.006", 0, "dfb023e4e2a1e7a00fa18f9ede72a91b", 924059}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - Italian DOS Floppy (from glorifindel) - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "e753dfa96d68dd95f84f6cd80479a35e", 6135}, - {"resource.000", 0, "2ac39ff61e369b79f3d7a4ad514f8e29", 203170}, - {"resource.001", 0, "99a6df6d366b3f061271ff3450ac0d32", 1286269}, - {"resource.002", 0, "a6a8d7a24dbb7a266a26b084e7275e89", 1241124}, - {"resource.003", 0, "5289000399d503b59da9e23129256f1a", 1325546}, - {"resource.004", 0, "4277c61bed40a50dadc4b5a344520af2", 1251000}, - {"resource.005", 0, "5f885abd335978e2fd4e5f886d7676c8", 1102880}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - Japanese PC-98 5.25" Floppy - // SCI interpreter version 1.000.1068 - {{"sq4", "", { - {"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, - {"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, - {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, - {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, - {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - Japanese PC-98 5.25" Floppy - // SCI interpreter version 1.000.1068 - {{"sq4", "", { - {"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, - {"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, - {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, - {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 - English DOS CD (from the Space Quest Collection) - // Executable scanning reports "1.001.064", VERSION file reports "1.0" - {{"sq4", "CD", { - {"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054}, - {"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Space Quest 4 - Spanish DOS CD (from jvprat) - // Executable scanning reports "1.SQ4.057", VERSION file reports "1.000" - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "51bcb305568ec19713f8b79727f10071", 6159}, - {"resource.000", 0, "8000a55aebc50a68b7cce07a8c33758c", 204315}, - {"resource.001", 0, "99a6df6d366b3f061271ff3450ac0d32", 1269094}, - {"resource.002", 0, "a6a8d7a24dbb7a266a26b084e7275e89", 1240998}, - {"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1319306}, - {"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752}, - {"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Space Quest 4 - Spanish DOS Floppy (from jvprat) - // Executable scanning reports "1.SQ4.056", VERSION file reports "1.000" - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "41543ae71036046fef69df29a838ee05", 5589}, - {"resource.000", 0, "2ac39ff61e369b79f3d7a4ad514f8e29", 242470}, - {"resource.001", 0, "567608beb69d9dffdb42a8f39cb11a5e", 994323}, - {"resource.002", 0, "74c62fa2146ff3b3b2ea2b3fb95b9af9", 1140801}, - {"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1088408}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 4 1.000 - German DOS Floppy (supplied by markcoolio in bug report #2723862) - // Executable scanning reports "1.SQ4.030" - // SCI interpreter version 1.000.200 (just a guess) - {{"sq4", "", { - {"resource.map", 0, "8f08b97ca093f370c56d99715b015554", 6153}, - {"resource.000", 0, "5f6a1fff40584ee807efd547899b1ba5", 206032}, - {"resource.001", 0, "99a6df6d366b3f061271ff3450ac0d32", 1270577}, - {"resource.002", 0, "a6a8d7a24dbb7a266a26b084e7275e89", 1242817}, - {"resource.003", 0, "47ee647b5b12232d27e63cc627c25899", 1321146}, - {"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368}, - {"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 5 - English DOS (from the Space Quest Collection) - // Executable scanning reports "1.001.068", VERSION file reports "1.04" - {{"sq5", "", { - {"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, - {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, - {"resource.msg", 0, "bb8ad78793c26bdb3f77498b1d6515a9", 125988}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 5 - English DOS - // SCI interpreter version 1.001.067 - {{"sq5", "", { - {"resource.map", 0, "8bde0a9adb9a3e9aaa861826874c9834", 6473}, - {"resource.000", 0, "f4a48705764544d7cc64a7bb22a610df", 6025184}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 5 v1.04 - German DOS (from Tobis87, updated information by markcool from bug reports #2723935 and #2724762) - // SCI interpreter version 1.001.068 - {{"sq5", "", { - {"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, - {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, - {"resource.msg", 0, "7c71cfc36153cfe07b450423a51f7e68", 146282}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 5 - Italian DOS Floppy (from glorifindel) - // SCI interpreter version 1.001.068 (just a guess) - {{"sq5", "", { - {"resource.000", 0, "5040026519f37199f3616fb1d4704dff", 6047170}, - {"resource.map", 0, "5b09168baa2f6e2e22787429b2d72f54", 6492}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - -#ifdef ENABLE_SCI32 - // Space Quest 6 - English DOS/Win3.11 CD (from the Space Quest Collection) - // Executable scanning reports "2.100.002", VERSION file reports "1.0" - {{"sq6", "", { - {"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528}, - {"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Space Quest 6 - English DOS/Win3.11 CD ver 1.11 (from FRG) - // SCI interpreter version 2.100.002 (just a guess) - {{"sq6", "", { - {"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528}, - {"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // Space Quest 6 - English DOS/Win3.11 Interactive Demo (from FRG) - // SCI interpreter version 2.100.002 (just a guess) - {{"sq6", "Demo", { - {"resource.map", 0, "368f07b07433db3f819fa3fa0e5efee5", 2572}, - {"resource.000", 0, "ab12724e078dea34b624e0d2a38dcd7c", 2272050}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Space Quest 6 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723884) - // SCI interpreter version 2.100.002 (just a guess) - {{"sq6", "", { - {"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534}, - {"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, -#endif // ENABLE_SCI32 - - // The Island of Dr. Brain - English DOS CD (from jvprat) - // Executable scanning reports "1.001.053", VERSION file reports "1.0 10.27.92" - {{"islandbrain", "", { - {"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281}, - {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, - 0 - }, - - // The Island of Dr. Brain - English DOS (from Quietust) - // Executable scanning reports "1.001.053", VERSION file reports "1.1 2.3.93" - {{"islandbrain", "", { - {"resource.map", 0, "3c07da06bdd1689f9d07af78fb94d0ec", 3101}, - {"resource.000", 0, "ecc686e0034fb4d41de077ac7167b3cf", 1947866}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, - 0 - }, - - // The Island of Dr. Brain - English DOS Non-Interactive Demo - // SCI interpreter version 1.001.053 (just a guess) - {{"islandbrain", "Demo", { - {"resource.map", 0, "a8e5ca8ed1996974afa59f4c45e06195", 986}, - {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 586560}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - -#ifdef ENABLE_SCI32 - // Torin's Passage - English Windows Interactive Demo - // SCI interpreter version 2.100.002 (just a guess) - {{"torin", "Demo", { - {"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403}, - {"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, - 0 - }, - - // Torin's Passage - English Windows - // SCI interpreter version 2.100.002 (just a guess) - {{"torin", "", { - {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, - {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, - - // Torin's Passage - Spanish Windows (from jvprat) - // Executable scanning reports "2.100.002", VERSION file reports "1.0" - {{"torin", "", { - {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, - {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - // TODO: depend on one of the patches? - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, - - // Torin's Passage - French Windows - // SCI interpreter version 2.100.002 (just a guess) - {{"torin", "", { - {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, - {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, - - // Torin's Passage - German Windows - // SCI interpreter version 2.100.002 (just a guess) - {{"torin", "", { - {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, - {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, - 0 - }, - - // Torin's Passage - Italian Windows CD (from glorifindel) - // SCI interpreter version 2.100.002 (just a guess) - {{"torin", "", { - {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, - {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE}, - 0 - }, -#endif // ENABLE_SCI32 - - // SCI Fanmade Games - FANMADE("Al Pond 2: Island Quest", "9625372e710d1a95d2027b48f9e325af", 1506, "a0f9aa65b9bf3d8703adff5a621f243c", 889843), - FANMADE("Al Pond: Island Quest 2", "4cba6a5a4c8f66f21935ed78b0511a92", 870, "876587dc9a5ec569287a3dc4b29139d8", 613769), - FANMADE("Another DG Game: I Want My C64 Back", "4a8ca7ca2abd18899ef856f47665e2e9", 588, "12ff558d20c72e42cc6adb408f34d6d8", 150513), - FANMADE_L("Another DG Game: I Want My C64 Back", "13dc1d9ebc57daf8895412eee5e39fea", 576, "e2ad60b3a280171429db5c85f158f84a", 141697, Common::FR_FRA), - FANMADE("Bluntman and Chronic (Politically Correct Version)", "c3ef9fa6c7c5fb840078bf28d87c7f8b", 1362, "441636a9f6f86710844868fded868ee7", 596688), - FANMADE("Cascade Quest", "c94efc10d18c040b6e22a1dc6d3adfe1", 3468, "8ada33dfa945f81531e5508240b573de", 1432195), - FANMADE("Curt Quest 1.0", "b0e555370380d218968a40a68eaaaffc", 1146, "c851182cdf6fc6a81b840f4d4875f1a0", 307165), - FANMADE("Curt Quest 1.1", "54084c29346683296e45ef32d7ae74f3", 1128, "c851182cdf6fc6a81b840f4d4875f1a0", 302000), - FANMADE("Demo Quest", "c89a0c9e0a4e4af0ecedb300a3b31dbf", 384, "a32f3495ba24764cba091119cc3f1e13", 160098), - FANMADE("Dr. Jummybummy's Space Adventure 2", "6ae6cb7de423f51736d9487b4ca0c6da", 810, "26e5b563f578e104d79689f36568b7cf", 394670), - FANMADE_L("Grostesteing: Plus Mechant que Jamais", "ec9a97ccb134f69249f6ea8b16c13d8e", 1500, "b869f5f11bfe2ab5f67f4f0c618f2ce1", 464657, Common::FR_FRA), // FIXME: Accent - FANMADE("Jim Quest", "0af50be1d3f0cb77a09137709a76ef4f", 960, "9c042c136548b20d9183495668e03526", 496446), - FANMADE("Knight's Quest Demo 1.0", "5e816edf993956752ed06fccfeeae6d9", 1260, "959321f88a22905fa1f8c6d897874744", 703836), - FANMADE("LockerGnome Quest", "3eeff9130206cad0c4e1551e2b9dd2c5", 420, "ae05ca90806fd90cc43f147c82d3547c", 158906), - FANMADE("New Year's Mystery", "efd1beb5120293725065c95959144f81", 714, "b3bd3c2372ed6efa28adb12403c4c31a", 305027), - FANMADE("Osama", "db8f1710453cfbecf4214b2946970043", 390, "7afd75d4620dedf97a84ae8f0a7523cf", 123827), - FANMADE("Quest for the Cheat", "a359d4cf27f98264b42b55c017671214", 882, "8a943029f73c4bc85d454b7f473455ba", 455209), - FANMADE("SCI Companion Template", "ad54d4f504086cd597aa2348d0aa3b09", 354, "6798b7b601ce8154c1d1bc0f0edcdd18", 113061), - FANMADE("SCI Studio Template 3.0", "ca0dc8d586e0a8670b7621cde090b532", 354, "58a48ee692a86c0575e6bd0b00a92b9a", 113097), - FANMADE("SCI Quest", "9067e1f1e54436d2dbfce855524bc84a", 552, "ffa7d355cd9223f245289108a696bcd2", 149634), - FANMADE("The Legend of the Lost Jewel", "ba1bca315e3818c5626eda51bcfbcccf", 636, "9b0736d69924af0cff32a0f78db96855", 300398), - - // FIXME: The vga demo does not have a resource.000/001 file. - //FANMADE_V("SCI VGA Demo", "00b1abd87bad356b90fcdfcb6132c26f", 8, "", 0, 0), - - {AD_TABLE_END_MARKER, 0} -}; +#include "sci/detection_tables.h" /** * The fallback game descriptor used by the SCI engine's fallbackDetector. @@ -2985,7 +118,7 @@ static SciGameDescription s_fallbackDesc = { Common::UNK_LANG, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NONE + Common::GUIO_NONE }, 0 }; @@ -2993,7 +126,7 @@ static SciGameDescription s_fallbackDesc = { static const ADParams detectionParams = { // Pointer to ADGameDescription or its superset structure - (const byte *)SciGameDescriptions, + (const byte *)Sci::SciGameDescriptions, // Size of that superset structure sizeof(SciGameDescription), // Number of bytes to compute MD5 sum for @@ -3032,12 +165,108 @@ public: const ADGameDescription *fallbackDetect(const Common::FSList &fslist) const; }; +Common::String convertSierraGameId(Common::String sierraId) { + // TODO: SCI32 IDs + + // TODO: The internal id of christmas1988 is "demo" + if (sierraId == "card") { + // This could either be christmas1990 or christmas1992 + // christmas1990 has a "resource.001" file, whereas + // christmas1992 has a "resource.000" file + return (Common::File::exists("resource.001")) ? "christmas1990" : "christmas1992"; + } + if (sierraId == "arthur") + return "camelot"; + if (sierraId == "brain") { + // This could either be The Castle of Dr. Brain, or The Island of Dr. Brain + // castlebrain has resource.001, whereas islandbrain doesn't + return (Common::File::exists("resource.001")) ? "castlebrain" : "islandbrain"; + } + // iceman is the same + // longbow is the same + if (sierraId == "eco") + return "ecoquest"; + if (sierraId == "rain") + return "ecoquest2"; + if (sierraId == "fp") + return "freddypharkas"; + if (sierraId == "emc") + return "funseeker"; + if (sierraId == "cardgames") + return "hoyle1"; + if (sierraId == "solitare") + return "hoyle2"; + // hoyle3 is the same + // hoyle4 is the same + if (sierraId == "kq1") + return "kq1sci"; + if (sierraId == "kq4") + return "kq4sci"; + if (sierraId == "lsl1") + return "lsl1sci"; + // lsl2 is the same + // lsl3 is the same + // lsl5 is the same + // lsl6 is the same + // TODO: lslcasino + if (sierraId == "tales") + return "fairytales"; + if (sierraId == "mg") + return "mothergoose"; + if (sierraId == "cb1") + return "laurabow"; + if (sierraId == "lb2") + return "laurabow2"; + // TODO: lb2 floppy (its resources can't be read) + if (sierraId == "twisty") + return "pepper"; + // TODO: pq1sci (its resources can't be read) + if (sierraId == "pq") + return "pq2"; + // pq3 is the same + if (sierraId == "glory") + return "qfg1"; + // TODO: qfg1 VGA (its resources can't be read) + if (sierraId == "trial") + return "qfg2"; + if (sierraId == "qfg1") + return "qfg3"; + if (sierraId == "thegame") + return "slater"; + if (sierraId == "sq1") + return "sq1sci"; + if (sierraId == "sq3") { + // Both SQ3 and the separately released subgame, Astro Chicken, + // have internal ID "sq3", but Astro Chicken only has "resource.map" + // and "resource.001". Detect if it's SQ3 by the existence of + // "resource.002" + return (Common::File::exists("resource.002")) ? "sq3" : "astrochicken"; + } + if (sierraId == "sq4") { + // Both SQ4 and the separately released subgame, Ms. Astro Chicken, + // have internal ID "sq4", but Astro Chicken only has "resource.map" + // and "resource.001". Detect if it's SQ4 by the existence of + // "resource.000" (which exists in both SQ4 floppy and CD, but not in + // the subgame) + return (Common::File::exists("resource.000")) ? "sq4" : "msastrochicken"; + } + // sq4 is the same + // sq5 is the same + + return sierraId; +} const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fslist) const { bool foundResMap = false; bool foundRes000 = false; Common::Platform exePlatform = Common::kPlatformUnknown; - Common::String exeVersionString; + + // Set some defaults + s_fallbackDesc.desc.extra = ""; + s_fallbackDesc.desc.language = Common::UNK_LANG; + s_fallbackDesc.desc.flags = ADGF_NO_FLAGS; + s_fallbackDesc.desc.platform = Common::kPlatformUnknown; + s_fallbackDesc.desc.gameid = "sci"; // First grab all filenames for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { @@ -3047,8 +276,44 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl Common::String filename = file->getName(); filename.toLowercase(); - if (filename.contains("resource.map") || filename.contains("resmap.000")) + if (filename.contains("resource.map") || filename.contains("resmap.000")) { + // HACK: resource.map is located in the same directory as the other resource files, + // therefore add the directory here, so that the game files can be opened later on + // We now add the parent directory temporary to our SearchMan so the engine code + // used in the detection can access all files via Common::File without any problems. + // In all branches returning from this function, we need to have a call to + // SearchMan.remove to remove it from the default directory pool again. + // + // A proper solution to remove this hack would be to have the code, which is needed + // for detection, to operate on Stream objects, so they can be easily called from + // the detection code. This might be easily to achieve through refactoring the + // code needed for detection. + assert(!SearchMan.hasArchive("SCI_detection")); + SearchMan.addDirectory("SCI_detection", file->getParent()); foundResMap = true; + } + + // Determine if we got a CD version and set the CD flag accordingly, by checking for + // resource.aud. We assume that the file should be over 10MB, as it contains all the + // game speech and is usually around 450MB+. The size check is for some floppy game + // versions like KQ6 floppy, which also have a small resource.aud file + if (filename.contains("resource.aud")) { + Common::SeekableReadStream *tmpStream = file->createReadStream(); + if (tmpStream->size() > 10 * 1024 * 1024) { + // We got a CD version, so set the CD flag accordingly + s_fallbackDesc.desc.flags |= ADGF_CD; + s_fallbackDesc.desc.extra = "CD"; + } + delete tmpStream; + } + + // Check if we got a map file for older SCI1 CD versions (like KQ5CD) + // It's named like "audioXXX.map" + if (filename.contains("audio") && filename.contains(".map")) { + // We got a CD version, so set the CD flag accordingly + s_fallbackDesc.desc.flags |= ADGF_CD; + s_fallbackDesc.desc.extra = "CD"; + } if (filename.contains("resource.000") || filename.contains("resource.001") || filename.contains("ressci.000") || filename.contains("ressci.001")) @@ -3056,54 +321,86 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl // Check if it's a known executable name // Note: "sier" matches "sier.exe", "sierra.exe", "sierw.exe" and "sierw5.exe" + // TODO: Try to remove this code, and base platform detection on game resources + // instead of the executable itself if (filename.contains("scidhuv") || filename.contains("sciduv") || filename.contains("sciv") || filename.contains("sciw") || filename.contains("prog") || filename.contains("sier")) { - // We already found a valid exe, no need to check this one. - if (!exeVersionString.empty()) - continue; - // Is it really an executable file? Common::SeekableReadStream *fileStream = file->createReadStream(); exePlatform = getGameExePlatform(fileStream); - - // It's a valid exe, read the interpreter version string - if (exePlatform != Common::kPlatformUnknown) - exeVersionString = readSciVersionFromExe(fileStream, exePlatform); - delete fileStream; } } // If these files aren't found, it can't be SCI - if (!foundResMap && !foundRes000) + if (!foundResMap && !foundRes000) { + SearchMan.remove("SCI_detection"); return 0; + } + + ResourceManager *resMgr = new ResourceManager(fslist); + SciVersion version = resMgr->sciVersion(); + ViewType gameViews = resMgr->getViewType(); + + // Have we identified the game views? If not, stop here + if (gameViews == kViewUnknown) { + SearchMan.remove("SCI_detection"); + return (const ADGameDescription *)&s_fallbackDesc; + } + +#ifndef ENABLE_SCI32 + // Is SCI32 compiled in? If not, and this is a SCI32 game, + // stop here + if (resMgr->sciVersion() == SCI_VERSION_32) { + SearchMan.remove("SCI_detection"); + return (const ADGameDescription *)&s_fallbackDesc; + } +#endif + + // EGA views + if (gameViews == kViewEga) + s_fallbackDesc.desc.extra = "EGA"; + + SegManager *segManager = new SegManager(resMgr, version); + + if (exePlatform == Common::kPlatformUnknown) { + // Try to determine the platform from game resources + if (gameViews == kViewEga || gameViews == kViewVga || + gameViews == kViewVga11) { + // Must be PC or Mac, set to PC for now + // TODO: Is there a reliable way to determine the game + // platform from the resources? So far, I've noticed + // that Mac versions have a different signature for + // kGetEvent and kNewWindow. I'm unsure about Atari ST + // versions. Could we base detection on this? + exePlatform = Common::kPlatformPC; + } else if (gameViews == kViewAmiga) { + exePlatform = Common::kPlatformAmiga; + } + // TODO: detection for Mac and Atari ST + } - // Set some defaults - s_fallbackDesc.desc.gameid = "sci"; - s_fallbackDesc.desc.extra = ""; - s_fallbackDesc.desc.language = Common::UNK_LANG; s_fallbackDesc.desc.platform = exePlatform; - s_fallbackDesc.desc.flags = ADGF_NO_FLAGS; -#if 0 // Determine the game id - // TODO - ResourceManager *resMgr = new ResourceManager(256 * 1024); - SciVersion version = resMgr->sciVersion(); - SegManager *segManager = new SegManager(resMgr, version); + if (!script_instantiate(resMgr, segManager, version, 0)) { + warning("fallbackDetect(): Could not instantiate script 0"); + SearchMan.remove("SCI_detection"); + delete segManager; + delete resMgr; + return 0; + } reg_t game_obj = script_lookup_export(segManager, 0, 0); - Common::String gameName = obj_get_name(segManager,version, game_obj); - debug(2, " \"%s\" at %04x:%04x", gameName.c_str(), PRINT_REG(game_obj)); + Common::String gameName = obj_get_name(segManager, version, game_obj); + debug(2, "Detected ID: \"%s\" at %04x:%04x", gameName.c_str(), PRINT_REG(game_obj)); + gameName.toLowercase(); + s_fallbackDesc.desc.gameid = strdup(convertSierraGameId(gameName).c_str()); delete segManager; delete resMgr; -#endif - printf("If this is *NOT* a fan-modified version (in particular, not a fan-made\n"); - printf("translation), please, report the data above, including the following\n"); - printf("version number, from the game's executable:\n"); - printf("Version: %s\n\n", exeVersionString.empty() ? "not found" : exeVersionString.c_str()); + SearchMan.remove("SCI_detection"); return (const ADGameDescription *)&s_fallbackDesc; } diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index 6872039c89..994054f6a7 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -43,7 +43,7 @@ int _reset_graphics_input(EngineState *s) { gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 }; debug(2, "Initializing graphics"); - if (!s->resmgr->isVGA()) { + if (s->resmgr->getViewType() == kViewEga) { for (int i = 0; i < 16; i++) { if (gfxop_set_color(s->gfx_state, &(s->ega_colors[i]), gfx_sci0_image_colors[sci0_palette][i].r, gfx_sci0_image_colors[sci0_palette][i].g, gfx_sci0_image_colors[sci0_palette][i].b, 0, -1, -1)) { @@ -188,157 +188,10 @@ int game_init_sound(EngineState *s, int sound_flags) { return 0; } -int create_class_table_sci11(EngineState *s) { - int scriptnr; - unsigned int seeker_offset; - char *seeker_ptr; - int classnr; - - Resource *vocab996 = s->resmgr->findResource(ResourceId(kResourceTypeVocab, 996), 1); - - if (!vocab996) - s->seg_manager->_classtable.resize(20); - else - s->seg_manager->_classtable.resize(vocab996->size >> 2); - - for (scriptnr = 0; scriptnr < 1000; scriptnr++) { - Resource *heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, scriptnr), 0); - - if (heap) { - int global_vars = READ_LE_UINT16(heap->data + 2); - - seeker_ptr = (char*)heap->data + 4 + global_vars * 2; - seeker_offset = 4 + global_vars * 2; - - while (READ_LE_UINT16((byte*)seeker_ptr) == SCRIPT_OBJECT_MAGIC_NUMBER) { - if (READ_LE_UINT16((byte*)seeker_ptr + 14) & SCRIPT_INFO_CLASS) { - classnr = READ_LE_UINT16((byte*)seeker_ptr + 10); - if (classnr >= (int)s->seg_manager->_classtable.size()) { - if (classnr >= SCRIPT_MAX_CLASSTABLE_SIZE) { - warning("Invalid class number 0x%x in script.%d(0x%x), offset %04x", - classnr, scriptnr, scriptnr, seeker_offset); - return 1; - } - - s->seg_manager->_classtable.resize(classnr + 1); // Adjust maximum number of entries - } - - s->seg_manager->_classtable[classnr].reg.offset = seeker_offset; - s->seg_manager->_classtable[classnr].reg.segment = 0; - s->seg_manager->_classtable[classnr].script = scriptnr; - } - - seeker_ptr += READ_LE_UINT16((byte*)seeker_ptr + 2) * 2; - seeker_offset += READ_LE_UINT16((byte*)seeker_ptr + 2) * 2; - } - } - } - - s->resmgr->unlockResource(vocab996); - vocab996 = NULL; - return 0; -} - -static int create_class_table_sci0(EngineState *s) { - int scriptnr; - unsigned int seeker; - int classnr; - int magic_offset; // For strange scripts in older SCI versions - - Resource *vocab996 = s->resmgr->findResource(ResourceId(kResourceTypeVocab, 996), 1); - SciVersion version = s->_version; // for the offset defines - - if (!vocab996) - s->seg_manager->_classtable.resize(20); - else - s->seg_manager->_classtable.resize(vocab996->size >> 2); - - for (scriptnr = 0; scriptnr < 1000; scriptnr++) { - int objtype = 0; - Resource *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, scriptnr), 0); - - if (script) { - if (((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader()) - magic_offset = seeker = 2; - else - magic_offset = seeker = 0; - - do { - while (seeker < script->size) { - unsigned int lastseeker = seeker; - objtype = (int16)READ_LE_UINT16(script->data + seeker); - if (objtype == SCI_OBJ_CLASS || objtype == SCI_OBJ_TERMINATOR) - break; - seeker += (int16)READ_LE_UINT16(script->data + seeker + 2); - if (seeker <= lastseeker) { - s->seg_manager->_classtable.clear(); - error("Script version is invalid"); - } - } - - if (objtype == SCI_OBJ_CLASS) { - int sugg_script; - - seeker -= SCRIPT_OBJECT_MAGIC_OFFSET; // Adjust position; script home is base +8 bytes - - classnr = (int16)READ_LE_UINT16(script->data + seeker + 4 + SCRIPT_SPECIES_OFFSET); - if (classnr >= (int)s->seg_manager->_classtable.size()) { - - if (classnr >= SCRIPT_MAX_CLASSTABLE_SIZE) { - warning("Invalid class number 0x%x in script.%d(0x%x), offset %04x", - classnr, scriptnr, scriptnr, seeker); - return 1; - } - - s->seg_manager->_classtable.resize(classnr + 1); // Adjust maximum number of entries - } - - // Map the class ID to the script the corresponding class is contained in - // The script number is found in vocab.996, if it exists - if (!vocab996 || (uint32)classnr >= vocab996->size >> 2) - sugg_script = -1; - else - sugg_script = (int16)READ_LE_UINT16(vocab996->data + 2 + (classnr << 2)); - - // First, test whether the script hasn't been claimed, or if it's been claimed by the wrong script - - if (sugg_script == -1 || scriptnr == sugg_script /*|| !s->_classtable[classnr].reg.segment*/) { - // Now set the home script of the class - s->seg_manager->_classtable[classnr].reg.offset = seeker + 4 - magic_offset; - s->seg_manager->_classtable[classnr].reg.segment = 0; - s->seg_manager->_classtable[classnr].script = scriptnr; - } - - seeker += SCRIPT_OBJECT_MAGIC_OFFSET; // Re-adjust position - seeker += (int16)READ_LE_UINT16(script->data + seeker + 2); // Move to next - } - - } while (objtype != SCI_OBJ_TERMINATOR && seeker <= script->size); - - } - } - s->resmgr->unlockResource(vocab996); - vocab996 = NULL; - return 0; -} - // Architectural stuff: Init/Unintialize engine int script_init_engine(EngineState *s) { - int result; - s->kernel_opt_flags = 0; s->seg_manager = new SegManager(s->resmgr, s->_version); - - if (s->_version >= SCI_VERSION_1_1) - result = create_class_table_sci11(s); - else - result = create_class_table_sci0(s); - - if (result) { - debug(2, "Failed to initialize class table"); - return 1; - } - s->gc_countdown = GC_INTERVAL - 1; SegmentId script_000_segment = s->seg_manager->getSegment(0, SCRIPT_GET_LOCK); diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 6d027d5788..687e621405 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -33,11 +33,7 @@ namespace Sci { -/** The string used to identify the "unknown" SCI0 function for each game */ -#define SCRIPT_UNKNOWN_FUNCTION_STRING "[Unknown]" - // Default kernel name table -#define SCI0_KNAMES_WELL_DEFINED 0x6e #define SCI_KNAMES_DEFAULT_ENTRIES_NR 0x89 static const char *sci_default_knames[SCI_KNAMES_DEFAULT_ENTRIES_NR] = { @@ -370,8 +366,9 @@ static const char *argtype_description[] = { Kernel::Kernel(ResourceManager *resmgr) : _resmgr(resmgr) { memset(&_selectorMap, 0, sizeof(_selectorMap)); // FIXME: Remove this once/if we C++ify selector_map_t - detectSciFeatures(); // must be called before loadSelectorNames() loadSelectorNames(); + detectSciFeatures(); + mapSelectors(); // Map a few special selectors for later use loadOpcodes(); loadKernelNames(); @@ -382,61 +379,30 @@ Kernel::~Kernel() { } void Kernel::detectSciFeatures() { - // FIXME Much of this is unreliable - - Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0); - - Common::StringList staticSelectorTable; - - if (!r) { // No such resource? - staticSelectorTable = checkStaticSelectorNames(); - if (staticSelectorTable.empty()) - error("Kernel: Could not retrieve selector names"); - } + SciVersion version = _resmgr->sciVersion(); - int count = staticSelectorTable.empty() ? READ_LE_UINT16(r->data) + 1 : staticSelectorTable.size(); // Counter is slightly off features = 0; // Initialize features based on SCI version - switch (_resmgr->sciVersion()) { - case SCI_VERSION_0_EARLY: - features |= kFeatureOldScriptHeader; - /* Fallthrough */ - case SCI_VERSION_0_LATE: - features |= kFeatureOldGfxFunctions; - break; - default: - break; - } - for (int i = 0; i < count; i++) { - Common::String tmp; - - if (staticSelectorTable.empty()) { - int offset = READ_LE_UINT16(r->data + 2 + i * 2); - int len = READ_LE_UINT16(r->data + offset); - - tmp = Common::String((const char *)r->data + offset + 2, len); - } else { - tmp = staticSelectorTable[i]; - } - - if (tmp == "motionCue") - features &= ~kFeatureOldGfxFunctions; + // Script header and graphics functions + if (version == SCI_VERSION_0_EARLY) { + features |= kFeatureOldScriptHeader | kFeatureOldGfxFunctions; + } else if (version == SCI_VERSION_0_LATE) { + if (findSelector("motionCue") == -1) + features |= kFeatureOldGfxFunctions; + } - if (tmp == "egoMoveSpeed" && _resmgr->sciVersion() < SCI_VERSION_1_1) + // Lofs absolute/relative + if (version >= SCI_VERSION_1_MIDDLE && version < SCI_VERSION_1_1) { + // Assume all games use absolute lofs + features |= kFeatureLofsAbsolute; + } else if (version == SCI_VERSION_1_EARLY) { + // Use heuristic + if (findSelector("egoMoveSpeed") != -1) features |= kFeatureLofsAbsolute; - - if (tmp == "setVol") - features |= kFeatureSci1Sound; - - if (tmp == "nodePtr") - features |= kFeatureSci01Sound; } - if (features & kFeatureSci1Sound) - features &= ~kFeatureSci01Sound; - printf("Kernel auto-detected features:\n"); printf("Graphics functions: "); @@ -445,19 +411,13 @@ void Kernel::detectSciFeatures() { else printf("new\n"); - printf("lofs parameters: "); - if (features & kFeatureLofsAbsolute) - printf("absolute\n"); - else - printf("relative\n"); - - printf("Sound functions: "); - if (features & kFeatureSci1Sound) - printf("SCI1\n"); - else if (features & kFeatureSci01Sound) - printf("SCI01\n"); - else - printf("SCI0\n"); + if (version < SCI_VERSION_1_1) { + printf("lofs parameters: "); + if (features & kFeatureLofsAbsolute) + printf("absolute\n"); + else + printf("relative\n"); + } } void Kernel::loadSelectorNames() { @@ -473,7 +433,7 @@ void Kernel::loadSelectorNames() { for (uint32 i = 0; i < staticSelectorTable.size(); i++) { _selectorNames.push_back(staticSelectorTable[i]); - if (features & kFeatureOldScriptHeader) + if (_resmgr->sciVersion() == SCI_VERSION_0_EARLY) _selectorNames.push_back(staticSelectorTable[i]); } @@ -492,7 +452,7 @@ void Kernel::loadSelectorNames() { // Early SCI versions used the LSB in the selector ID as a read/write // toggle. To compensate for that, we add every selector name twice. - if (features & kFeatureOldScriptHeader) + if (_resmgr->sciVersion() == SCI_VERSION_0_EARLY) _selectorNames.push_back(tmp); } } @@ -819,37 +779,45 @@ reg_t *kernel_dereference_reg_pointer(EngineState *s, reg_t pointer, int entries } void Kernel::setDefaultKernelNames() { - bool isSci0 = (_resmgr->sciVersion() <= SCI_VERSION_0_LATE); - int offset = 0; - - _kernelNames.resize(SCI_KNAMES_DEFAULT_ENTRIES_NR + (isSci0 ? 4 : 0)); - for (int i = 0; i < SCI_KNAMES_DEFAULT_ENTRIES_NR; i++) { - // In SCI0, Platform was DoAvoider - if (!strcmp(sci_default_knames[i], "Platform") && isSci0) { - _kernelNames[i + offset] = "DoAvoider"; - continue; - } + _kernelNames = Common::StringList(sci_default_knames, SCI_KNAMES_DEFAULT_ENTRIES_NR); - _kernelNames[i + offset] = sci_default_knames[i]; + switch (_resmgr->sciVersion()) { + case SCI_VERSION_0_EARLY: + case SCI_VERSION_0_LATE: + // Insert SCI0 file functions after SetCursor (0x28) + _kernelNames.insert_at(0x29, "FOpen"); + _kernelNames.insert_at(0x2A, "FPuts"); + _kernelNames.insert_at(0x2B, "FGets"); + _kernelNames.insert_at(0x2C, "FClose"); - // SCI0 has 4 extra functions between SetCursor (0x28) and Savegame - if (!strcmp(sci_default_knames[i], "SetCursor") && isSci0) { - _kernelNames[i + 1] = "FOpen"; - _kernelNames[i + 2] = "FPuts"; - _kernelNames[i + 3] = "FGets"; - _kernelNames[i + 4] = "FClose"; - offset = 4; - } - } + // Function 0x55 is DoAvoider + _kernelNames[0x55] = "DoAvoider"; + + // Cut off unused functions + _kernelNames.resize(0x72); + break; + + case SCI_VERSION_01: + // Multilingual SCI01 games have StrSplit as function 0x78 + _kernelNames[0x78] = "StrSplit"; + + // Cut off unused functions + _kernelNames.resize(0x79); + break; - if (_resmgr->sciVersion() == SCI_VERSION_1_1) { - // HACK: KQ6CD calls unimplemented function 0x26 + case SCI_VERSION_1_1: + // KQ6CD calls unimplemented function 0x26 _kernelNames[0x26] = "Dummy"; + break; + + default: + // Use default table for the other versions + break; } } #ifdef ENABLE_SCI32 -static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &names) { +//static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &names) { /* 999.voc format for SCI1.1 games: [b] # of kernel functions @@ -859,7 +827,7 @@ static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &name {[w name-len][function name]} ... */ - //unsigned int size = 64, pos = 3; +/* //unsigned int size = 64, pos = 3; int len; Resource *r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES), 0); if(r == NULL) // failed to open vocab.999 (happens with SCI1 demos) @@ -872,7 +840,7 @@ static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &name len = READ_LE_UINT16(r->data + off); names[i] = Common::String((char *)r->data + off + 2, len); } -} +}*/ #endif bool Kernel::loadKernelNames() { diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index bb5563a876..a85025f514 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -60,13 +60,14 @@ struct KernelFuncWithSignature { enum AutoDetectedFeatures { kFeatureOldScriptHeader = 1 << 0, kFeatureOldGfxFunctions = 1 << 1, - kFeatureLofsAbsolute = 1 << 2, - kFeatureSci01Sound = 1 << 3, - kFeatureSci1Sound = 1 << 4 + kFeatureLofsAbsolute = 1 << 2 }; class Kernel { public: + /** + * Initializes the SCI kernel + */ Kernel(ResourceManager *resmgr); ~Kernel(); @@ -119,16 +120,6 @@ public: */ bool hasLofsAbsolute() const { return (features & kFeatureLofsAbsolute); } - /** - * Determines if the game is using SCI01 sound functions - */ - bool usesSci01SoundFunctions() const { return (features & kFeatureSci01Sound); } - - /** - * Determines if the game is using SCI1 sound functions - */ - bool usesSci1SoundFunctions() const { return (features & kFeatureSci1Sound); } - // Script dissection/dumping functions void dissectScript(int scriptNumber, Vocabulary *vocab); void dumpScriptObject(char *data, int seeker, int objsize); diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index 43d1f25e01..a9ae77972f 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -36,7 +36,7 @@ Node *lookup_node(EngineState *s, reg_t addr) { if (!mobj) { // FIXME: This occurs right at the beginning of SQ4, when walking north from the first screen. It doesn't // seem to have any apparent ill-effects, though, so it's been changed to non-fatal, for now - //error("%s, L%d: Attempt to use non-node %04x:%04x as list node\n", __FILE__, __LINE__, PRINT_REG(addr)); + //error("%s, L%d: Attempt to use non-node %04x:%04x as list node", __FILE__, __LINE__, PRINT_REG(addr)); warning("Attempt to use non-node %04x:%04x as list node", PRINT_REG(addr)); return NULL; } @@ -44,7 +44,7 @@ Node *lookup_node(EngineState *s, reg_t addr) { NodeTable *nt = (NodeTable *)mobj; if (!nt->isValidEntry(addr.offset)) { - error("Attempt to use non-node %04x:%04x as list node\n", PRINT_REG(addr)); + error("Attempt to use non-node %04x:%04x as list node", PRINT_REG(addr)); return NULL; } @@ -55,14 +55,14 @@ List *lookup_list(EngineState *s, reg_t addr) { MemObject *mobj = GET_SEGMENT(*s->seg_manager, addr.segment, MEM_OBJ_LISTS); if (!mobj) { - error("Attempt to use non-list %04x:%04x as list\n", PRINT_REG(addr)); + error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr)); return NULL; } ListTable *lt = (ListTable *)mobj; if (!lt->isValidEntry(addr.offset)) { - error("Attempt to use non-list %04x:%04x as list\n", PRINT_REG(addr)); + error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr)); return NULL; } diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 2f0072ec67..90ae88b73f 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -63,14 +63,27 @@ reg_t kHaveMouse(EngineState *s, int funct_nr, int argc, reg_t *argv) { return make_reg(0, -1); } +enum kMemoryInfoFunc { + K_MEMORYINFO_LARGEST_HEAP_BLOCK = 0, // Largest heap block available + K_MEMORYINFO_FREE_HEAP = 1, // Total free heap memory + K_MEMORYINFO_LARGEST_HUNK_BLOCK = 2, // Largest available hunk memory block + K_MEMORYINFO_FREE_HUNK = 3, // Amount of free DOS paragraphs + K_MEMORYINFO_TOTAL_HUNK = 4 // Total amount of hunk memory (SCI01) +}; + reg_t kMemoryInfo(EngineState *s, int funct_nr, int argc, reg_t *argv) { + uint16 size = 0x7fff; // Must not be 0xffff, or some memory calculations will overflow + switch (argv[0].offset) { - case 0: // Total free heap memory - case 1: // Largest heap block available - case 2: // Largest available hunk memory block - case 3: // Total amount of hunk memory - case 4: // Amount of free DOS paragraphs- SCI01 - return make_reg(0, 0x7fff); // Must not be 0xffff, or some memory calculations will overflow + case K_MEMORYINFO_LARGEST_HEAP_BLOCK: + // In order to prevent "Memory fragmented" dialogs from + // popping up in some games, we must return FREE_HEAP - 2 here. + return make_reg(0, size - 2); + case K_MEMORYINFO_FREE_HEAP: + case K_MEMORYINFO_LARGEST_HUNK_BLOCK: + case K_MEMORYINFO_FREE_HUNK: + case K_MEMORYINFO_TOTAL_HUNK: + return make_reg(0, size); default: warning("Unknown MemoryInfo operation: %04x", argv[0].offset); diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp index da24a388fa..ad14202257 100644 --- a/engines/sci/engine/kpathing.cpp +++ b/engines/sci/engine/kpathing.cpp @@ -1406,7 +1406,7 @@ static PathfindingState *convert_polygon_set(EngineState *s, reg_t poly_list, Co err = nearest_intersection(pf_s, start, end, &intersection); if (err == PF_FATAL) { - warning("AvoidPath: fatal error finding nearest intersecton"); + warning("AvoidPath: fatal error finding nearest intersection"); delete pf_s; return NULL; } diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 4d90dd68ac..41eb9f624d 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -74,7 +74,7 @@ int invoke_selector(EngineState *s, reg_t object, int selector_id, SelectorInvoc warning("Selector '%s' of object at %04x:%04x could not be invoked (%s L%d)", ((SciEngine*)g_engine)->getKernel()->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line); if (noinvalid == kStopOnInvalidSelector) - error("[Kernel] Not recoverable: VM was halted\n"); + error("[Kernel] Not recoverable: VM was halted"); return 1; } if (slc_type == kSelectorVariable) // Swallow silently diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 38baeafad8..44b2404e41 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -204,7 +204,7 @@ void process_sound_events(EngineState *s) { /* Get all sound events, apply their } -reg_t kDoSound_SCI0(EngineState *s, int funct_nr, int argc, reg_t *argv) { +reg_t kDoSoundSci0(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t obj = (argc > 1) ? argv[1] : NULL_REG; uint16 command = argv[0].toUint16(); SongHandle handle = FROBNICATE_HANDLE(obj); @@ -383,7 +383,7 @@ reg_t kDoSound_SCI0(EngineState *s, int funct_nr, int argc, reg_t *argv) { } -reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { +reg_t kDoSoundSci1Early(EngineState *s, int funct_nr, int argc, reg_t *argv) { uint16 command = argv[0].toUint16(); reg_t obj = (argc > 1) ? argv[1] : NULL_REG; SongHandle handle = FROBNICATE_HANDLE(obj); @@ -673,7 +673,7 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { return s->r_acc; } -reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { +reg_t kDoSoundSci1Late(EngineState *s, int funct_nr, int argc, reg_t *argv) { uint16 command = argv[0].toUint16(); reg_t obj = (argc > 1) ? argv[1] : NULL_REG; SongHandle handle = FROBNICATE_HANDLE(obj); @@ -988,12 +988,17 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { * Used for synthesized music playback */ reg_t kDoSound(EngineState *s, int funct_nr, int argc, reg_t *argv) { - if (((SciEngine*)g_engine)->getKernel()->usesSci1SoundFunctions()) - return kDoSound_SCI1(s, funct_nr, argc, argv); - else if (((SciEngine*)g_engine)->getKernel()->usesSci01SoundFunctions()) - return kDoSound_SCI01(s, funct_nr, argc, argv); - else - return kDoSound_SCI0(s, funct_nr, argc, argv); + switch(s->detectDoSoundType()) { + case EngineState::kDoSoundTypeSci0: + return kDoSoundSci0(s, funct_nr, argc, argv); + case EngineState::kDoSoundTypeSci1Early: + return kDoSoundSci1Early(s, funct_nr, argc, argv); + case EngineState::kDoSoundTypeSci1Late: + return kDoSoundSci1Late(s, funct_nr, argc, argv); + default: + warning("Unknown DoSound type"); + return NULL_REG; + } } /** diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 1768695244..b53e9d522c 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -701,8 +701,7 @@ static void reconstruct_sounds(EngineState *s) { Song *seeker; SongIteratorType it_type; - if (((SciEngine *)g_engine)->getKernel()->usesSci01SoundFunctions() - || ((SciEngine *)g_engine)->getKernel()->usesSci1SoundFunctions()) + if (s->_version > SCI_VERSION_01) it_type = SCI_SONG_ITERATOR_TYPE_SCI1; else it_type = SCI_SONG_ITERATOR_TYPE_SCI0; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index f47a874528..0c88481125 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -68,6 +68,13 @@ SegManager::SegManager(ResourceManager *resMgr, SciVersion version) { exports_wide = 0; _version = version; _resMgr = resMgr; + + int result = 0; + + result = createClassTable(); + + if (result) + error("SegManager: Failed to initialize class table"); } // Destroy the object, free the memorys if allocated before @@ -139,7 +146,7 @@ void SegManager::setScriptSize(Script &scr, int script_nr) { if (!script || (_version >= SCI_VERSION_1_1 && !heap)) { error("SegManager::setScriptSize: failed to load %s", !script ? "script" : "heap"); } - if (((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader()) { + if (_version == SCI_VERSION_0_EARLY) { // check if we got an old script header scr.buf_size = script->size + READ_LE_UINT16(script->data) * 2; //locals_size = READ_LE_UINT16(script->data) * 2; } else if (_version < SCI_VERSION_1_1) { @@ -155,7 +162,7 @@ void SegManager::setScriptSize(Script &scr, int script_nr) { } if (scr.buf_size > 65535) { - error("Script and heap sizes combined exceed 64K.\n" + error("Script and heap sizes combined exceed 64K." "This means a fundamental design bug was made in SCI\n" "regarding SCI1.1 games.\nPlease report this so it can be" "fixed in the next major version"); @@ -677,12 +684,11 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { int species = READ_LE_UINT16(seeker + 10); if (species < 0 || species >= (int)_classtable.size()) { - error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d\n", + error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d", species, species, _classtable.size(), scr->nr); return; } - _classtable[species].script = scr->nr; _classtable[species].reg.segment = seg; _classtable[species].reg.offset = classpos; } @@ -906,5 +912,25 @@ int SegManager::freeDynmem(reg_t addr) { return 0; // OK } +int SegManager::createClassTable() { + Resource *vocab996 = _resMgr->findResource(ResourceId(kResourceTypeVocab, 996), 1); + + if (!vocab996) + error("SegManager: failed to open vocab 996"); + + int totalClasses = vocab996->size >> 2; + _classtable.resize(totalClasses); + + for (uint16 classNr = 0; classNr < totalClasses; classNr++) { + uint16 scriptNr = READ_LE_UINT16(vocab996->data + classNr * 4 + 2); + + _classtable[classNr].reg = NULL_REG; + _classtable[classNr].script = scriptNr; + } + + _resMgr->unlockResource(vocab996); + + return 0; +} } // End of namespace Sci diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index f73c788b37..27c8ad446a 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -360,6 +360,7 @@ private: LocalVariables *allocLocalsSegment(Script *scr, int count); MemObject *memObjAllocate(SegmentId segid, int hash_id, MemObjectType type); int deallocate(SegmentId seg, bool recursive); + int createClassTable(); Hunk *alloc_Hunk(reg_t *); diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index fd45ef5834..baa51bcb58 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -24,6 +24,8 @@ */ #include "sci/engine/state.h" +#include "sci/engine/vm.h" +#include "sci/console.h" // For parse_reg_t namespace Sci { @@ -116,6 +118,8 @@ EngineState::EngineState(ResourceManager *res, SciVersion version, uint32 flags) successor = 0; speedThrottler = new SpeedThrottler(version); + + _doSoundType = kDoSoundTypeUnknown; } EngineState::~EngineState() { @@ -242,4 +246,75 @@ Common::String EngineState::strSplit(const char *str, const char *sep) { return retval; } +EngineState::DoSoundType EngineState::detectDoSoundType() { + if (_doSoundType == kDoSoundTypeUnknown) { + reg_t soundClass; + const uint checkBytes = 6; // Number of bytes to check + + if (!parse_reg_t(this, "?Sound", &soundClass)) { + reg_t fptr; + + Object *obj = obj_get(seg_manager, _version, soundClass); + SelectorType sel = lookup_selector(this, soundClass, ((SciEngine*)g_engine)->getKernel()->_selectorMap.play, NULL, &fptr); + + if (obj && (sel == kSelectorMethod)) { + Script *script = seg_manager->getScript(fptr.segment); + + if (fptr.offset > checkBytes) { + // Go to the last portion of Sound::init, should be right before the play function + fptr.offset -= checkBytes; + byte *buf = script->buf + fptr.offset; + + // Check the call to DoSound's INIT_HANDLE function. + // It's either subfunction 0, 5 or 6, depending on the version of DoSound. + uint sum = 0; + for (uint i = 0; i < checkBytes; i++) + sum += buf[i]; + + switch(sum) { + case 0x1B2: // SCI0 + case 0x1AE: // SCI01 + _doSoundType = kDoSoundTypeSci0; + break; + case 0x13D: + _doSoundType = kDoSoundTypeSci1Early; + break; + case 0x13E: + _doSoundType = kDoSoundTypeSci1Late; + } + } + } + } + + if (_doSoundType == kDoSoundTypeUnknown) { + warning("DoSound detection failed, taking an educated guess"); + + if (_version >= SCI_VERSION_1_MIDDLE) + _doSoundType = kDoSoundTypeSci1Late; + else if (_version > SCI_VERSION_01) + _doSoundType = kDoSoundTypeSci1Early; + else + _doSoundType = kDoSoundTypeSci0; + } + + debugCN(1, kDebugLevelSound, "Detected DoSound type: "); + + switch(_doSoundType) { + case kDoSoundTypeSci0: + debugC(1, kDebugLevelSound, "SCI0"); + break; + case kDoSoundTypeSci1Early: + debugC(1, kDebugLevelSound, "SCI1 Early"); + break; + case kDoSoundTypeSci1Late: + debugC(1, kDebugLevelSound, "SCI1 Late"); + break; + default: + break; + } + } + + return _doSoundType; +} + } // End of namespace Sci diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index c8e9139f27..a3983f6ae4 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -163,6 +163,14 @@ struct EngineState : public Common::Serializable { public: EngineState(ResourceManager *res, SciVersion version, uint32 flags); virtual ~EngineState(); + + enum DoSoundType { + kDoSoundTypeUnknown, + kDoSoundTypeSci0, + kDoSoundTypeSci1Early, + kDoSoundTypeSci1Late + }; + virtual void saveLoadWithSerializer(Common::Serializer &ser); kLanguage getLanguage(); @@ -272,6 +280,12 @@ public: */ Common::String strSplit(const char *str, const char *sep = "\r----------\r"); + /** + * Autodetects the DoSound type + * @return DoSound type + */ + DoSoundType detectDoSoundType(); + /* Debugger data: */ Breakpoint *bp_list; /**< List of breakpoints */ int have_bp; /**< Bit mask specifying which types of breakpoints are used in bp_list */ @@ -301,6 +315,7 @@ public: EngineState *successor; /**< Successor of this state: Used for restoring */ private: + DoSoundType _doSoundType; kLanguage charToLanguage(const char c) const; Common::String getLanguageString(const char *str, kLanguage lang) const; }; diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp index c1d0ad9bac..1897748c6d 100644 --- a/engines/sci/engine/static_selectors.cpp +++ b/engines/sci/engine/static_selectors.cpp @@ -26,9 +26,6 @@ // We place selector vocab name tables here for any game that doesn't have // them. This includes the King's Quest IV Demo and LSL3 Demo. -#ifndef SCI_STATIC_SELECTORS_H -#define SCI_STATIC_SELECTORS_H - #include "sci/engine/kernel.h" namespace Sci { @@ -397,6 +394,100 @@ static const SelectorRemap iceman_demo_selectors[] = { { "setTarget", 171 } }; +// Taken from Space Quest 1 VGA (Demo) +static const SelectorRemap lsl5_demo_selectors[] = { + { "init", 103 }, + { "play", 42 }, + { "replay", 65 }, + { "x", 4 }, + { "y", 3 }, + { "z", 85 }, + { "priority", 63 }, + { "view", 5 }, + { "loop", 6 }, + { "cel", 7 }, + { "brLeft", 20 }, + { "brRight", 22 }, + { "brTop", 19 }, + { "brBottom", 21 }, + { "xStep", 54 }, + { "yStep", 55 }, + { "nsBottom", 11 }, + { "nsTop", 9 }, + { "nsLeft", 10 }, + { "nsRight", 12 }, + { "font", 33 }, + { "text", 26 }, + { "type", 34 }, + { "state", 32 }, + { "doit", 60 }, + { "delete", 84 }, + { "signal", 17 }, + { "underBits", 8 }, + { "canBeHere", 57 }, + { "client", 45 }, + { "dx", 46 }, + { "dy", 47 }, + { "xStep", 54 }, + { "yStep", 55 }, + { "b-moveCnt", 48 }, + { "b-i1", 49 }, + { "b-i2", 50 }, + { "b-di", 51 }, + { "b-xAxis", 52 }, + { "b-incr", 53 }, + { "completed", 207 }, + { "illegalBits", 18 }, + { "dispose", 104 }, + { "prevSignal", 148 }, + { "message", 40 }, + { "modifiers", 64 }, + { "cue", 135 }, + { "owner", 149 }, + { "handle", 93 }, + { "number", 43 }, + { "max", 37 }, + { "cursor", 36 }, + { "claimed", 76 }, + { "edgeHit", 308 }, + { "wordFail", 71 }, + { "syntaxFail", 72 }, + { "semanticFail", 73 }, + { "cycler", 212 }, + { "elements", 27 }, + { "lsTop", 13 }, + { "lsBottom", 15 }, + { "lsLeft", 14 }, + { "lsRight", 16 }, + { "baseSetter", 277 }, + { "who", 39 }, + { "distance", 221 }, + { "mover", 59 }, + { "looper", 62 }, + { "isBlocked", 61 }, + { "heading", 58 }, + { "mode", 30 }, + { "caller", 133 }, + { "moveDone", 100 }, + { "vol", 97 }, + { "pri", 98 }, + { "min", 94 }, + { "sec", 95 }, + { "frame", 96 }, + { "dataInc", 92 }, + { "size", 89 }, + { "palette", 91 }, + { "moveSpeed", 56 }, + { "nodePtr", 44 }, + { "flags", 150 }, + { "points", 90 }, + { "printLang", 87 }, + { "subtitleLang", 88 }, + { "parseLang", 86 }, + { "motionCue", 210 }, + { "egoMoveSpeed", 357 } +}; + // A macro for loading one of the above tables in the function below #define USE_SELECTOR_TABLE(x) \ do { \ @@ -408,10 +499,12 @@ static const SelectorRemap iceman_demo_selectors[] = { } while (0) Common::StringList Kernel::checkStaticSelectorNames() { - Common::String gameID = ((SciEngine*)g_engine)->getGameID(); - Common::StringList names; - + if (!g_engine) + return names; + + Common::String gameID = ((SciEngine*)g_engine)->getGameID(); + if (gameID == "kq4sci") USE_SELECTOR_TABLE(kq4_demo_selectors); else if (gameID == "lsl3" || gameID == "iceman") // identical, except iceman has "flags" @@ -420,10 +513,10 @@ Common::StringList Kernel::checkStaticSelectorNames() { USE_SELECTOR_TABLE(christmas1992_selectors); else if (gameID == "lsl1sci") USE_SELECTOR_TABLE(lsl1_demo_selectors); + else if (gameID == "lsl5") + USE_SELECTOR_TABLE(lsl5_demo_selectors); return names; } } // End of namespace Sci - -#endif // SCI_STATIC_SELECTORS_H diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index fbd3bc3baf..fbdb3d1c85 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -79,7 +79,7 @@ static StackPtr validate_stack_addr(EngineState *s, StackPtr sp) { if (sp >= s->stack_base && sp < s->stack_top) return sp; - error("[VM] Stack index %d out of valid range [%d..%d]\n", + error("[VM] Stack index %d out of valid range [%d..%d]", (int)(sp - s->stack_base), 0, (int)(s->stack_top - s->stack_base - 1)); return 0; } @@ -87,9 +87,9 @@ static StackPtr validate_stack_addr(EngineState *s, StackPtr sp) { static int validate_arithmetic(reg_t reg) { if (reg.segment) { if (g_debug_weak_validations) - warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]\n", reg.segment); + warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment); else - error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]\n", reg.segment); + error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment); return 0; } @@ -99,9 +99,9 @@ static int validate_arithmetic(reg_t reg) { static int signed_validate_arithmetic(reg_t reg) { if (reg.segment) { if (g_debug_weak_validations) - warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]\n", reg.segment); + warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment); else - error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]\n", reg.segment); + error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment); return 0; } @@ -214,7 +214,7 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP int temp = s->seg_manager->validateExportFunc(pubfunct, seg); if (!temp) { - error("Request for invalid exported function 0x%x of script 0x%x\n", pubfunct, script); + error("Request for invalid exported function 0x%x of script 0x%x", pubfunct, script); return NULL; } @@ -312,14 +312,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt ObjVarRef varp; switch (lookup_selector(s, send_obj, selector, &varp, &funcp)) { case kSelectorNone: - // WORKAROUND: LSL6 tries to access the invalid 'keep' selector of the game object. - // FIXME: Find out if this is a game bug. - if ((s->_gameName == "LSL6") && (selector == 0x18c)) { - debug("LSL6 detected, continuing..."); - break; - } - - error("Send to invalid selector 0x%x of object at %04x:%04x\n", 0xffff & selector, PRINT_REG(send_obj)); + error("Send to invalid selector 0x%x of object at %04x:%04x", 0xffff & selector, PRINT_REG(send_obj)); break; @@ -930,7 +923,7 @@ void run_vm(EngineState *s, int restoring) { } if (opparams[0] >= (int)((SciEngine*)g_engine)->getKernel()->_kernelFuncs.size()) { - error("Invalid kernel function 0x%x requested\n", opparams[0]); + error("Invalid kernel function 0x%x requested", opparams[0]); } else { int argc = ASSERT_ARITHMETIC(scriptState.xs->sp[0]); @@ -941,7 +934,7 @@ void run_vm(EngineState *s, int restoring) { && !kernel_matches_signature(s, ((SciEngine*)g_engine)->getKernel()->_kernelFuncs[opparams[0]].signature, argc, scriptState.xs->sp + 1)) { - error("[VM] Invalid arguments to kernel call %x\n", opparams[0]); + error("[VM] Invalid arguments to kernel call %x", opparams[0]); } else { s->r_acc = ((SciEngine*)g_engine)->getKernel()->_kernelFuncs[opparams[0]].fun(s, opparams[0], argc, scriptState.xs->sp + 1); @@ -1195,7 +1188,7 @@ void run_vm(EngineState *s, int restoring) { #ifndef DISABLE_VALIDATIONS if (r_temp.offset >= code_buf_size) { error("VM: lofss operation overflowed: %04x:%04x beyond end" - " of script (at %04x)\n", PRINT_REG(r_temp), code_buf_size); + " of script (at %04x)", PRINT_REG(r_temp), code_buf_size); } #endif PUSH32(r_temp); @@ -1492,7 +1485,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select if (!obj) { - error("lookup_selector(): Error while looking up Species class.\nOriginal address was %04x:%04x. Species address was %04x:%04x\n", + error("lookup_selector(): Error while looking up Species class.\nOriginal address was %04x:%04x. Species address was %04x:%04x", PRINT_REG(obj_location), PRINT_REG(obj->_variables[SCRIPT_SPECIES_SELECTOR])); return kSelectorNone; } @@ -1573,7 +1566,7 @@ int script_instantiate_common(ResourceManager *resMgr, SegManager *segManager, S return seg_id; } -int script_instantiate_sci0(ResourceManager *resMgr, SegManager *segManager, SciVersion version, int script_nr) { +int script_instantiate_sci0(ResourceManager *resMgr, SegManager *segManager, SciVersion version, bool oldScriptHeader, int script_nr) { int objtype; unsigned int objlength; reg_t reg; @@ -1593,7 +1586,7 @@ int script_instantiate_sci0(ResourceManager *resMgr, SegManager *segManager, Sci Script *scr = segManager->getScript(seg_id); - if (((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader()) { + if (oldScriptHeader) { // int locals_nr = READ_LE_UINT16(script->data); @@ -1660,7 +1653,6 @@ int script_instantiate_sci0(ResourceManager *resMgr, SegManager *segManager, Sci return 1; } - segManager->_classtable[species].script = script_nr; segManager->_classtable[species].reg = addr; segManager->_classtable[species].reg.offset = classpos; // Set technical class position-- into the block allocated for it @@ -1765,7 +1757,7 @@ int script_instantiate(ResourceManager *resMgr, SegManager *segManager, SciVersi if (version >= SCI_VERSION_1_1) return script_instantiate_sci11(resMgr, segManager, version, script_nr); else - return script_instantiate_sci0(resMgr, segManager, version, script_nr); + return script_instantiate_sci0(resMgr, segManager, version, (version == SCI_VERSION_0_EARLY), script_nr); } void script_uninstantiate_sci0(SegManager *segManager, SciVersion version, int script_nr, SegmentId seg) { diff --git a/engines/sci/exereader.cpp b/engines/sci/exereader.cpp index ce6bf184fb..fbeda66b45 100644 --- a/engines/sci/exereader.cpp +++ b/engines/sci/exereader.cpp @@ -96,62 +96,6 @@ Common::Platform getGameExePlatform(Common::SeekableReadStream *exeStream) { return Common::kPlatformUnknown; } -bool isLZEXECompressed(Common::SeekableReadStream *exeStream) { - uint32 filepos = 0; - - exeStream->seek(0, SEEK_SET); - - // First 2 bytes should be "MZ" (0x5A4D) - if (exeStream->readUint16LE() != 0x5A4D) // at pos 0, +2 - return false; - - exeStream->skip(6); - - // Header size should be 2 - filepos = exeStream->readUint16LE(); - if (filepos != 2) // at pos 8, +2 - return false; - - exeStream->skip(12); - - // Calculate code segment offset in exe file - filepos += exeStream->readUint16LE(); // at pos 22, +2 - filepos <<= 4; - - // First relocation item offset should be 0x1c - if (exeStream->readUint16LE() != 0x1c) // at pos 24, +2 - return false; - - // Number of overlays should be 0 - if (exeStream->readUint16LE() != 0) // at pos 26, +2 - return false; - - // Look for LZEXE signature - byte magic[4]; - exeStream->read(magic, 4); - - if (memcmp(magic, "LZ09", 4) && memcmp(magic, "LZ91", 4)) - return false; - - // Seek to offset 8 of info table at start of code segment - exeStream->seek(filepos + 8, SEEK_SET); - if (exeStream->err()) - return false; - - // Read size of compressed data in paragraphs - uint16 size = exeStream->readUint16LE(); - - // Move file pointer to start of compressed data - filepos -= size << 4; - exeStream->seek(filepos, SEEK_SET); - if (exeStream->err()) - return false; - - // All conditions met, this is an LZEXE packed file - // We are currently at the start of the compressed file data - return true; -} - uint getBit(Common::SeekableReadStream *input) { uint bit = _bits & 1; _bitCount--; @@ -172,120 +116,4 @@ uint getBit(Common::SeekableReadStream *input) { return bit; } -Common::String readSciVersionFromExe(Common::SeekableReadStream *exeStream, Common::Platform platform) { - int len = exeStream->size(); - unsigned char *buffer = NULL; - - // Read the executable - bool isLZEXE = isLZEXECompressed(exeStream); - - if (!isLZEXE) { - buffer = new unsigned char[exeStream->size()]; - - exeStream->seek(0, SEEK_SET); - exeStream->read(buffer, exeStream->size()); - } else { - buffer = new unsigned char[exeStream->size() * 3]; - _bitCount = 0; - - // Skip LZEXE header - exeStream->seek(32, SEEK_SET); - - int pos = 0; - int repeat; - short offset; - - while (1) { - if (exeStream->ioFailed()) { - warning("Error reading from input file"); - delete[] buffer; - return NULL; - } - - if (getBit(exeStream)) { - buffer[pos++] = exeStream->readByte(); - } else { - if (getBit(exeStream)) { - byte tmp[2]; - exeStream->read(tmp, 2); - repeat = (tmp[1] & 0x07); - offset = ((tmp[1] & ~0x07) << 5) | tmp[0] | 0xE000; - - if (repeat == 0) { - repeat = exeStream->readByte(); - - if (repeat == 0) { - len = pos; - break; - } - else if (repeat == 1) - continue; - else - repeat++; - } else - repeat += 2; - } else { - repeat = getBit(exeStream) << 1; - repeat += getBit(exeStream) + 2; - offset = exeStream->readByte() | 0xFF00; - } - - while (repeat > 0) { - buffer[pos] = buffer[pos + offset]; - pos++; - repeat--; - } - } - } - } - - // Find SCI version number - - int state = 0; - /* 'state' encodes how far we have matched the version pattern - ** "n.nnn.nnn" - ** - ** n.nnn.nnn - ** 0123456789 - ** - ** Since we cannot be certain that the pattern does not begin with an - ** alphanumeric character, some states are ambiguous. - ** The pattern is expected to be terminated with a non-alphanumeric - ** character. - */ - - - int accept; - unsigned char *buf = buffer; - - // String-encoded result, copied from buffer - char currentString[10]; - - for (int i = 0; i < len; i++) { - unsigned char ch = *buf++; - // By default, we don't like this character - accept = 0; - - if (isalnum(ch)) { - accept = (state != 1 && state != 5 && state != 9); - } else if (ch == '.') { - accept = (state == 1 || state == 5); - } else if (state == 9) { - // Terminate string - currentString[9] = 0; - - // Return the current string - return currentString; - } - - if (accept) - currentString[state++] = ch; - else - state = 0; - } - - delete[] buffer; - return "unknown"; -} - } // End of namespace Sci diff --git a/engines/sci/exereader.h b/engines/sci/exereader.h index e30d3d90c4..e114c0a3a4 100644 --- a/engines/sci/exereader.h +++ b/engines/sci/exereader.h @@ -32,7 +32,6 @@ namespace Sci { Common::Platform getGameExePlatform(Common::SeekableReadStream *exeStream); -Common::String readSciVersionFromExe(Common::SeekableReadStream *exeStream, Common::Platform platform); } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_driver.cpp b/engines/sci/gfx/gfx_driver.cpp index 0b1387074c..b71152822c 100644 --- a/engines/sci/gfx/gfx_driver.cpp +++ b/engines/sci/gfx/gfx_driver.cpp @@ -27,18 +27,19 @@ #include "common/system.h" #include "graphics/cursorman.h" #include "graphics/primitives.h" +#include "graphics/surface.h" #include "sci/sci.h" #include "sci/gfx/gfx_driver.h" #include "sci/gfx/gfx_tools.h" + namespace Sci { -GfxDriver::GfxDriver(int xfact, int yfact, int bytespp) { +GfxDriver::GfxDriver(int xfact, int yfact, Graphics::PixelFormat format) { int i; - Graphics::PixelFormat format = { bytespp, 0, 0, 0, 0, 0, 0, 0, 0 }; - _mode = gfx_new_mode(xfact, yfact, format, new Palette(256), 0); + _mode = gfx_new_mode(xfact, yfact, format, format.bytesPerPixel == 1 ? new Palette(256) : 0, 0); _mode->xsize = xfact * 320; _mode->ysize = yfact * 200; @@ -51,14 +52,15 @@ GfxDriver::GfxDriver(int xfact, int yfact, int bytespp) { // create the visual buffers for (i = 0; i < 2; i++) { _visual[i] = NULL; - _visual[i] = new byte[_mode->xsize * _mode->ysize]; + _visual[i] = new byte[_mode->xsize * _mode->ysize * _mode->bytespp]; if (!_visual[i]) { error("Out of memory: Could not allocate visual buffers! (%dx%d)\n", _mode->xsize, _mode->ysize); } - memset(_visual[i], 0, _mode->xsize * _mode->ysize); + memset(_visual[i], 0, _mode->xsize * _mode->ysize * _mode->bytespp); } - _mode->palette->name = "global"; + if (_mode->palette) + _mode->palette->name = "global"; } GfxDriver::~GfxDriver() { @@ -77,10 +79,12 @@ GfxDriver::~GfxDriver() { // Drawing operations +template<int COPY_BYTES, typename SIZETYPE, int EXTRA_BYTE_OFFSET> static void drawProc(int x, int y, int c, void *data) { GfxDriver *drv = (GfxDriver *)data; byte *p = drv->getVisual0(); - p[y * 320* drv->getMode()->xfact + x] = c; + SIZETYPE col = c << (EXTRA_BYTE_OFFSET * 8); + memcpy(p + (y * 320* drv->getMode()->xfact + x) * COPY_BYTES, &col, COPY_BYTES); } int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t color, @@ -91,6 +95,28 @@ int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t colo int xsize = _mode->xsize; int ysize = _mode->ysize; + void (*modeDrawProc)(int,int,int,void*); + switch (_mode->bytespp) { + case 1: + modeDrawProc = drawProc<1, uint8, 0>; + break; + case 2: + modeDrawProc = drawProc<2, uint16, 0>; + break; + case 3: +#ifdef SCUMM_BIG_ENDIAN + modeDrawProc = drawProc<3, uint32, 1>; +#else + modeDrawProc = drawProc<3, uint32, 0>; +#endif + break; + case 4: + modeDrawProc = drawProc<4, uint32, 0>; + break; + default: + error("Invalid mode->bytespp=%d", _mode->bytespp); + } + if (color.mask & GFX_MASK_VISUAL) { Common::Point nstart, nend; @@ -102,7 +128,7 @@ int GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t colo nend.x = CLIP<int16>(end.x + xc, 0, xsize - 1); nend.y = CLIP<int16>(end.y + yc, 0, ysize - 1); - Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, drawProc, this); + Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, modeDrawProc, this); if (color.mask & GFX_MASK_PRIORITY) { gfx_draw_line_pixmap_i(_priority[0], nstart, nend, color.priority); @@ -118,7 +144,8 @@ int GfxDriver::drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color gfx_rectangle_fill_t shade_mode) { if (color1.mask & GFX_MASK_VISUAL) { for (int i = rect.y; i < rect.y + rect.height; i++) { - memset(_visual[0] + i * _mode->xsize + rect.x, color1.visual.parent_index, rect.width); + memset(_visual[0] + (i * _mode->xsize + rect.x) * _mode->bytespp, + color1.visual.parent_index, rect.width * _mode->bytespp); } } @@ -138,8 +165,10 @@ int GfxDriver::drawPixmap(gfx_pixmap_t *pxm, int priority, rect_t src, rect_t de return GFX_ERROR; } - gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, _visual[bufnr], _mode->xsize, - _priority[bufnr]->index_data, _priority[bufnr]->index_width, 1, 0); + gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, _visual[bufnr], + _mode->xsize * _mode->bytespp, + _priority[bufnr]->index_data, + _priority[bufnr]->index_width, 1, 0); return GFX_OK; } @@ -161,7 +190,9 @@ int GfxDriver::grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map) { pxm->width = src.width; pxm->height = src.height; for (int i = 0; i < src.height; i++) { - memcpy(pxm->data + i * src.width, _visual[0] + (i + src.y) * _mode->xsize + src.x, src.width); + memcpy(pxm->data + i * src.width * _mode->bytespp, + _visual[0] + _mode->bytespp * ((i + src.y) * _mode->xsize + src.x), + src.width * _mode->bytespp); } break; @@ -193,17 +224,18 @@ int GfxDriver::update(rect_t src, Common::Point dest, gfx_buffer_t buffer) { switch (buffer) { case GFX_BUFFER_BACK: for (int i = 0; i < src.height; i++) { - memcpy(_visual[0] + (dest.y + i) * _mode->xsize + dest.x, - _visual[1] + (src.y + i) * _mode->xsize + src.x, src.width); + memcpy(_visual[0] + _mode->bytespp * ( (dest.y + i) * _mode->xsize + dest.x), + _visual[1] + _mode->bytespp * ( (src.y + i) * _mode->xsize + src.x), src.width * _mode->bytespp ); } if ((src.x == dest.x) && (src.y == dest.y)) gfx_copy_pixmap_box_i(_priority[0], _priority[1], src); break; - case GFX_BUFFER_FRONT: - g_system->copyRectToScreen(_visual[0] + src.x + src.y * _mode->xsize, _mode->xsize, dest.x, dest.y, src.width, src.height); + case GFX_BUFFER_FRONT: { + g_system->copyRectToScreen(_visual[0] + _mode->bytespp * (src.x + src.y * _mode->xsize), _mode->xsize * _mode->bytespp, dest.x, dest.y, src.width, src.height); g_system->updateScreen(); break; + } default: error("Invalid buffer %d in update", buffer); return GFX_ERROR; @@ -213,7 +245,7 @@ int GfxDriver::update(rect_t src, Common::Point dest, gfx_buffer_t buffer) { } int GfxDriver::setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority) { - memcpy(_visual[1], pic->data, _mode->xsize * _mode->ysize); + memcpy(_visual[1], pic->data, _mode->xsize * _mode->ysize * _mode->bytespp); gfx_copy_pixmap_box_i(_priority[1], priority, gfx_rect(0, 0, _mode->xsize, _mode->ysize)); return GFX_OK; diff --git a/engines/sci/gfx/gfx_driver.h b/engines/sci/gfx/gfx_driver.h index f7cbd0b6c2..cc8a5208d4 100644 --- a/engines/sci/gfx/gfx_driver.h +++ b/engines/sci/gfx/gfx_driver.h @@ -29,6 +29,8 @@ #include "sci/gfx/gfx_system.h" #include "sci/uinput.h" +#include "graphics/pixelformat.h" + namespace Sci { enum gfx_buffer_t { @@ -85,7 +87,7 @@ public: * not be set, or GFX_FATAL if the graphics target * is unuseable. */ - GfxDriver(int xfact, int yfact, int bytespp); + GfxDriver(int xfact, int yfact, Graphics::PixelFormat mode); /** * Uninitializes the current graphics mode. diff --git a/engines/sci/gfx/gfx_pixmap_scale.cpp b/engines/sci/gfx/gfx_pixmap_scale.cpp index 034efafe8d..41e6102cbd 100644 --- a/engines/sci/gfx/gfx_pixmap_scale.cpp +++ b/engines/sci/gfx/gfx_pixmap_scale.cpp @@ -70,14 +70,11 @@ void _gfx_xlate_pixmap_unfiltered(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale // Calculate all colors for (i = 0; i < pxm->colors_nr(); i++) { int col; - const PaletteEntry& color = pxm->palette->getColor(i); if (mode->palette) col = color.parent_index; else { - col = mode->red_mask & ((EXTEND_COLOR(color.r)) >> mode->red_shift); - col |= mode->green_mask & ((EXTEND_COLOR(color.g)) >> mode->green_shift); - col |= mode->blue_mask & ((EXTEND_COLOR(color.b)) >> mode->blue_shift); + col = mode->format.ARGBToColor(0, color.r, color.g, color.b); col |= alpha_ormask; } result_colors[i] = col; diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp index 5619a896cf..8ce7a50ed5 100644 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ b/engines/sci/gfx/gfx_resmgr.cpp @@ -100,7 +100,7 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic if (_version == SCI_VERSION_1_1) gfxr_draw_pic11(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _staticPalette, _portBounds); else - gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _resManager->isVGA(), _staticPalette, _portBounds); + gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _resManager->getViewType(), _staticPalette, _portBounds); } if (scaled_pic && scaled_pic->undithered_buffer) @@ -109,9 +109,9 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic if (_version == SCI_VERSION_1_1) gfxr_draw_pic11(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _staticPalette, _portBounds); else - gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _resManager->isVGA(), _staticPalette, _portBounds); + gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _resManager->getViewType(), _staticPalette, _portBounds); - if (!_resManager->isVGA()) { + if (_version <= SCI_VERSION_1_EGA) { if (need_unscaled) gfxr_remove_artifacts_pic0(scaled_pic, unscaled_pic); @@ -269,7 +269,8 @@ void GfxResManager::setStaticPalette(Palette *newPalette) _staticPalette = newPalette; _staticPalette->name = "static palette"; - _staticPalette->mergeInto(_driver->getMode()->palette); + if (_driver->getMode()->palette) + _staticPalette->mergeInto(_driver->getMode()->palette); } #if 0 @@ -320,7 +321,8 @@ gfx_mode_t mode_1x1_color_index = { /* Fake 1x1 mode */ /* palette */ NULL, /* color masks */ 0, 0, 0, 0, - /* color shifts */ 0, 0, 0, 0 + /* color shifts */ 0, 0, 0, 0, + Graphics::PixelFormat() }; gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_palette, bool scaled) { @@ -530,28 +532,25 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { return NULL; int resid = GFXR_RES_ID(GFX_RESOURCE_TYPE_VIEW, nr); - - if (!_resManager->isVGA()) { + ViewType viewType = _resManager->getViewType(); + + if (viewType == kViewEga) { int pal = (_version <= SCI_VERSION_01) ? -1 : palette; view = getEGAView(resid, viewRes->data, viewRes->size, pal); } else { - if (_version < SCI_VERSION_1_1) - view = getVGAView(resid, viewRes->data, viewRes->size, _staticPalette, false); - else - view = getVGAView(resid, viewRes->data, viewRes->size, 0, true); - - if (!view->palette) { - view->palette = new Palette(_staticPalette->size()); - view->palette->name = "interpreter_get_view"; - } - - // Palettize view - for (unsigned i = 0; i < MIN(view->palette->size(), _staticPalette->size()); i++) { - const PaletteEntry& vc = view->palette->getColor(i); - if (vc.r == 0 && vc.g == 0 && vc.b == 0) { - const PaletteEntry& sc = _staticPalette->getColor(i); - view->palette->setColor(i, sc.r, sc.g, sc.b); + view = getVGAView(resid, viewRes->data, viewRes->size, viewType); + + if (view->palette) { + // Palettize view + for (unsigned i = 0; i < MIN(view->palette->size(), _staticPalette->size()); i++) { + const PaletteEntry& vc = view->palette->getColor(i); + if (vc.r == 0 && vc.g == 0 && vc.b == 0) { + const PaletteEntry& sc = _staticPalette->getColor(i); + view->palette->setColor(i, sc.r, sc.g, sc.b); + } } + } else { + view->palette = _staticPalette->getref(); } } diff --git a/engines/sci/gfx/gfx_resource.h b/engines/sci/gfx/gfx_resource.h index 9c83cf07cd..35d7ef58d6 100644 --- a/engines/sci/gfx/gfx_resource.h +++ b/engines/sci/gfx/gfx_resource.h @@ -77,6 +77,15 @@ extern gfx_pixmap_color_t gfx_sci0_image_colors[][16]; */ extern Palette* gfx_sci0_pic_colors; + +enum ViewType { + kViewUnknown, + kViewEga, + kViewVga, + kViewVga11, + kViewAmiga +}; + struct gfxr_pic0_params_t { gfx_line_mode_t line_mode; /* one of GFX_LINE_MODE_* */ gfx_brush_mode_t brush_mode; @@ -190,13 +199,13 @@ void gfxr_clear_pic0(gfxr_pic_t *pic, int titlebar_size); * @param[in] resource Pointer to the resource data * @param[in] style The drawing style * @param[in] resid The resource ID - * @param[in] sci1 true if SCI1, false otherwise + * @param[in] viewType The view type for embedded views * @param[in] static_pal The static palette * @param[in] portBounds The bounds of the port being drawn to */ void gfxr_draw_pic01(gfxr_pic_t *pic, int fill_normally, int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, int sci1, + gfxr_pic0_params_t *style, int resid, ViewType viewType, Palette *static_pal, Common::Rect portBounds); /** @@ -312,9 +321,9 @@ Palette *gfxr_read_pal11(int id, byte *resource, int size); * @param[in] isSci11 true if SCI1.1, false otherwise * @return The resulting view */ -gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, bool isSci11); +gfxr_view_t *getVGAView(int id, byte *resource, int size, ViewType viewType); -gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, bool isAmiga, bool isSci11); +gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, ViewType viewType); /** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_system.h b/engines/sci/gfx/gfx_system.h index 20c92efa2d..0f5292aedf 100644 --- a/engines/sci/gfx/gfx_system.h +++ b/engines/sci/gfx/gfx_system.h @@ -30,6 +30,7 @@ #include "common/rect.h" #include "sci/tools.h" #include "sci/gfx/palette.h" +#include "graphics/pixelformat.h" namespace Sci { @@ -74,8 +75,10 @@ struct gfx_mode_t { */ Palette *palette; + // TODO: remove those uint32 red_mask, green_mask, blue_mask, alpha_mask; short red_shift, green_shift, blue_shift, alpha_shift; + Graphics::PixelFormat format; }; diff --git a/engines/sci/gfx/gfx_tools.cpp b/engines/sci/gfx/gfx_tools.cpp index e3d35ecb14..9e81ec1a8a 100644 --- a/engines/sci/gfx/gfx_tools.cpp +++ b/engines/sci/gfx/gfx_tools.cpp @@ -49,6 +49,7 @@ gfx_mode_t *gfx_new_mode(int xfact, int yfact, const Graphics::PixelFormat &form mode->xfact = xfact; mode->yfact = yfact; mode->bytespp = format.bytesPerPixel; + mode->format = format; // FIXME: I am not sure whether the following assignments are quite right. // The only code using these are the built-in scalers of the SCI engine. @@ -60,10 +61,10 @@ gfx_mode_t *gfx_new_mode(int xfact, int yfact, const Graphics::PixelFormat &form mode->green_mask = format.ARGBToColor(0, 0, 0xFF, 0); mode->blue_mask = format.ARGBToColor(0, 0, 0, 0xFF); mode->alpha_mask = format.ARGBToColor(0xFF, 0, 0, 0); - mode->red_shift = format.rLoss; - mode->green_shift = format.gLoss; - mode->blue_shift = format.bLoss; - mode->alpha_shift = format.aLoss; + mode->red_shift = format.rShift; + mode->green_shift = format.gShift; + mode->blue_shift = format.bShift; + mode->alpha_shift = format.aShift; } else { mode->red_mask = mode->green_mask = mode->blue_mask = 0; mode->alpha_mask = 0; diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp index 94bb6e0443..b3a1be68d1 100644 --- a/engines/sci/gfx/operations.cpp +++ b/engines/sci/gfx/operations.cpp @@ -404,8 +404,9 @@ static void init_aux_pixmap(gfx_pixmap_t **pixmap) { (*pixmap)->palette = new Palette(default_colors, DEFAULT_COLORS_NR); } -int gfxop_init(int version, GfxState *state, gfx_options_t *options, ResourceManager *resManager, - int xfact, int yfact, gfx_color_mode_t bpp) { +int gfxop_init(int version, GfxState *state, + gfx_options_t *options, ResourceManager *resManager, + Graphics::PixelFormat mode, int xfact, int yfact) { //int color_depth = bpp ? bpp : 1; //int initialized = 0; @@ -421,7 +422,7 @@ int gfxop_init(int version, GfxState *state, gfx_options_t *options, ResourceMan state->pic_port_bounds = gfx_rect(0, 10, 320, 190); state->_dirtyRects.clear(); - state->driver = new GfxDriver(xfact, yfact, bpp); + state->driver = new GfxDriver(xfact, yfact, mode); state->gfxResMan = new GfxResManager(state->options, state->driver, resManager); @@ -1131,8 +1132,10 @@ static int _gfxop_set_pointer(GfxState *state, gfx_pixmap_t *pxm, Common::Point // may change when a new PIC is loaded. The cursor has to be regenerated // from this pxm at that point. (An alternative might be to ensure the // cursor only uses colours in the static part of the palette?) - if (pxm && pxm->palette) + if (pxm && state->driver->getMode()->palette) { + assert(pxm->palette); pxm->palette->mergeInto(state->driver->getMode()->palette); + } state->driver->setPointer(pxm, hotspot); return GFX_OK; @@ -1736,7 +1739,7 @@ int gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette) { if (state->driver->getMode()->xfact == 1 && state->driver->getMode()->yfact == 1) { state->pic_unscaled = state->pic; } else { - state->pic = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false); + state->pic_unscaled = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false); } if (!state->pic || !state->pic_unscaled) { diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h index b9a16d4a27..ec0a810224 100644 --- a/engines/sci/gfx/operations.h +++ b/engines/sci/gfx/operations.h @@ -138,17 +138,16 @@ struct GfxState { * @param[in] state The state to initialize * @param[in] xfact Horizontal scale factor * @param[in] yfact Vertical scale factors - * @param[in] bpp Bytes per pixel to initialize with, or 0 - * (GFX_COLOR_MODE_AUTO) to auto-detect + * @param[in] mode Graphics mode to use * @param[in] options Rendering options * @param[in] resManager Resource manager to use * @return GFX_OK on success, GFX_ERROR if that particular mode * is unavailable, or GFX_FATAL if the graphics driver * is unable to provide any useful graphics support */ -int gfxop_init(int version, GfxState *state, gfx_options_t *options, - ResourceManager *resManager, int xfact = 1, int yfact = 1, - gfx_color_mode_t bpp = GFX_COLOR_MODE_INDEX); +int gfxop_init(int version, GfxState *state, + gfx_options_t *options, ResourceManager *resManager, + Graphics::PixelFormat mode, int xfact = 1, int yfact = 1); /** * Deinitializes a currently active driver. diff --git a/engines/sci/gfx/res_pic.cpp b/engines/sci/gfx/res_pic.cpp index e7b34976b0..09b98d12aa 100644 --- a/engines/sci/gfx/res_pic.cpp +++ b/engines/sci/gfx/res_pic.cpp @@ -1135,7 +1135,7 @@ extern gfx_pixmap_t *gfxr_draw_cel0(int id, int loop, int cel, byte *resource, i extern void _gfx_crossblit_simple(byte *dest, byte *src, int dest_line_width, int src_line_width, int xl, int yl, int bpp); void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, int sci1, Palette *static_pal, Common::Rect portBounds) { + gfxr_pic0_params_t *style, int resid, ViewType viewType, Palette *static_pal, Common::Rect portBounds) { const int default_palette_table[GFXR_PIC0_PALETTE_SIZE] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x88, @@ -1189,7 +1189,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, case PIC_OP_SET_COLOR: p0printf("Set color @%d\n", pos); - if (!sci1) { + if (viewType == kViewEga) { pal = *(resource + pos++); index = pal % GFXR_PIC0_PALETTE_SIZE; pal /= GFXR_PIC0_PALETTE_SIZE; @@ -1216,7 +1216,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, case PIC_OP_SET_PRIORITY: p0printf("Set priority @%d\n", pos); - if (!sci1) { + if (viewType == kViewEga) { pal = *(resource + pos++); index = pal % GFXR_PIC0_PALETTE_SIZE; pal /= GFXR_PIC0_PALETTE_SIZE; // Ignore pal @@ -1425,7 +1425,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, opx = *(resource + pos++); p0printf("OPX: "); - if (sci1) + if (viewType != kViewEga) opx += SCI1_OP_OFFSET; // See comment at the definition of SCI1_OP_OFFSET. switch (opx) { @@ -1509,11 +1509,13 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, bytesize = (*(resource + pos)) + (*(resource + pos + 1) << 8); p0printf("(%d, %d)\n", posx, posy); pos += 2; - if (!sci1 && !nodraw) - view = gfxr_draw_cel0(-1, -1, -1, resource + pos, bytesize, NULL, flags & DRAWPIC1_FLAG_MIRRORED); - else - view = gfxr_draw_cel1(-1, -1, -1, flags & DRAWPIC1_FLAG_MIRRORED, resource + pos, resource + pos, - bytesize, NULL, (static_pal && static_pal->size() == GFX_SCI1_AMIGA_COLORS_NR), false); + if (!nodraw) { + if (viewType == kViewEga) + view = gfxr_draw_cel0(-1, -1, -1, resource + pos, bytesize, NULL, flags & DRAWPIC1_FLAG_MIRRORED); + else + view = gfxr_draw_cel1(-1, -1, -1, flags & DRAWPIC1_FLAG_MIRRORED, resource + pos, resource + pos, + bytesize, NULL, viewType); + } pos += bytesize; if (nodraw) continue; @@ -1526,20 +1528,22 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, // we can only safely replace the palette if it's static // *if it's not for some reason, we should die - if (view->palette && view->palette->isShared() && !sci1) { + if (view->palette && view->palette->isShared() && (viewType == kViewEga)) { warning("gfx_draw_pic0(): can't set a non-static palette for an embedded view"); } // For SCI0, use special color mapping to copy the low // nibble of the color index to the high nibble. - if (sci1) { - if (static_pal && static_pal->size() == GFX_SCI1_AMIGA_COLORS_NR) { - // Assume Amiga game + if (viewType != kViewEga) { + if (view->palette) + view->palette->free(); + + if (viewType == kViewAmiga) { pic->visual_map->palette = static_pal->getref(); + } else { + view->palette = pic->visual_map->palette->copy(); } - if (view->palette) view->palette->free(); - view->palette = pic->visual_map->palette->copy(); } else view->palette = embedded_view_pal->getref(); @@ -1548,7 +1552,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, view->index_height = CLIP<int>(view->index_height, 0, portBounds.height()); // Set up mode structure for resizing the view - Graphics::PixelFormat format = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1byte/p, which handles masks and the rest for us + Graphics::PixelFormat format(1, 0, 0, 0, 0, 0, 0, 0, 0); // 1byte/p, which handles masks and the rest for us gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320, pic->visual_map->index_height / 200, format, view->palette, 0); @@ -1648,13 +1652,13 @@ void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size, pic->visual_map->palette = gfxr_read_pal11(-1, resource + palette_data_ptr, 1284); if (has_bitmap) - view = gfxr_draw_cel1(-1, 0, 0, flags & DRAWPIC1_FLAG_MIRRORED, resource, resource + bitmap_data_ptr, size - bitmap_data_ptr, NULL, 0, true); + view = gfxr_draw_cel1(-1, 0, 0, flags & DRAWPIC1_FLAG_MIRRORED, resource, resource + bitmap_data_ptr, size - bitmap_data_ptr, NULL, kViewVga11); if (view) { view->palette = pic->visual_map->palette->getref(); // Set up mode structure for resizing the view - Graphics::PixelFormat format = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1 byte/p, which handles masks and the rest for us + Graphics::PixelFormat format(1, 0, 0, 0, 0, 0, 0, 0, 0); // 1 byte/p, which handles masks and the rest for us gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320, pic->visual_map->index_height / 200, format, view->palette, 0); gfx_xlate_pixmap(view, mode, GFX_XLATE_FILTER_NONE); @@ -1677,7 +1681,7 @@ void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size, warning("[GFX] No view was contained in SCI1.1 pic resource"); } - gfxr_draw_pic01(pic, flags, default_palette, size - vector_data_ptr, resource + vector_data_ptr, style, resid, 1, static_pal, portBounds); + gfxr_draw_pic01(pic, flags, default_palette, size - vector_data_ptr, resource + vector_data_ptr, style, resid, kViewVga11, static_pal, portBounds); } void gfxr_dither_pic0(gfxr_pic_t *pic, int dmode, int pattern) { diff --git a/engines/sci/gfx/res_view.cpp b/engines/sci/gfx/res_view.cpp index d484136f8e..95f6919b0c 100644 --- a/engines/sci/gfx/res_view.cpp +++ b/engines/sci/gfx/res_view.cpp @@ -326,19 +326,19 @@ static int decompress_sci_view_amiga(int id, int loop, int cel, byte *resource, return 0; } -gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, bool isAmiga, bool isSci11) { +gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, ViewType viewType) { int xl = READ_LE_UINT16(cel_base); int yl = READ_LE_UINT16(cel_base + 2); int pixmap_size = xl * yl; - int xdisplace = isSci11 ? READ_LE_UINT16(cel_base + 4) : (int8) cel_base[4]; - int ydisplace = isSci11 ? READ_LE_UINT16(cel_base + 6) : cel_base[5]; - int runlength_offset = isSci11 ? READ_LE_UINT16(cel_base + 24) : 8; - int literal_offset = isSci11 ? READ_LE_UINT16(cel_base + 28) : 8; + int xdisplace = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 4) : (int8) cel_base[4]; + int ydisplace = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 6) : cel_base[5]; + int runlength_offset = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 24) : 8; + int literal_offset = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 28) : 8; gfx_pixmap_t *retval = gfx_pixmap_alloc_index_data(gfx_new_pixmap(xl, yl, id, loop, cel)); byte *dest = retval->index_data; int decompress_failed; - retval->color_key = cel_base[isSci11 ? 8 : 6]; + retval->color_key = cel_base[(viewType == kViewVga11) ? 8 : 6]; retval->xoffset = mirrored ? xdisplace : -xdisplace; retval->yoffset = -ydisplace; // FIXME: In LSL5, it seems that the inventory has views without palettes (or we don't load palettes properly) @@ -350,12 +350,12 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso return NULL; } - if (!isAmiga) - decompress_failed = decompress_sci_view(id, loop, cel, resource, dest, mirrored, pixmap_size, size, runlength_offset, - literal_offset, xl, yl, retval->color_key); - else + if (viewType == kViewAmiga) decompress_failed = decompress_sci_view_amiga(id, loop, cel, resource, dest, mirrored, pixmap_size, size, runlength_offset, xl, yl, retval->color_key); + else + decompress_failed = decompress_sci_view(id, loop, cel, resource, dest, mirrored, pixmap_size, size, runlength_offset, + literal_offset, xl, yl, retval->color_key); if (decompress_failed) { gfx_free_pixmap(retval); @@ -365,27 +365,22 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso return retval; } -gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, bool isSci11) { - uint16 palOffset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET + (isSci11 ? 2 : 0)); - uint16 headerSize = isSci11 ? READ_LE_UINT16(resource + V2_HEADER_SIZE) : 0; +gfxr_view_t *getVGAView(int id, byte *resource, int size, ViewType viewType) { + uint16 palOffset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET + ((viewType == kViewVga11) ? 2 : 0)); + uint16 headerSize = (viewType == kViewVga11) ? READ_LE_UINT16(resource + V2_HEADER_SIZE) : 0; byte* seeker = resource + headerSize; uint16 loopOffset = 0; - int amiga_game = 0; gfxr_view_t *view = (gfxr_view_t *)malloc(sizeof(gfxr_view_t)); view->ID = id; view->flags = 0; - view->loops_nr = READ_LE_UINT16(resource + V1_LOOPS_NR_OFFSET + (isSci11 ? 2 : 0)) & 0xFF; + view->loops_nr = READ_LE_UINT16(resource + V1_LOOPS_NR_OFFSET + ((viewType == kViewVga11) ? 2 : 0)) & 0xFF; if (palOffset > 0) { - if (!isSci11) - view->palette = gfxr_read_pal1(id, resource + palOffset, size - palOffset); - else + if (viewType == kViewVga11) view->palette = gfxr_read_pal11(id, resource + palOffset, size - palOffset); - } else if (static_pal && static_pal->size() == GFX_SCI1_AMIGA_COLORS_NR) { - // Assume we're running an amiga game. - amiga_game = 1; - view->palette = static_pal->getref(); + else + view->palette = gfxr_read_pal1(id, resource + palOffset, size - palOffset); } else { view->palette = NULL; } @@ -393,7 +388,7 @@ gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, b view->loops = (gfxr_loop_t *)calloc(view->loops_nr, sizeof(gfxr_loop_t)); for (int i = 0; i < view->loops_nr; i++) { - if (!isSci11) { + if (viewType != kViewVga11) { bool mirrored = READ_LE_UINT16(resource + V1_MIRROR_MASK) & (1 << i); loopOffset = READ_LE_UINT16(resource + V1_FIRST_LOOP_OFFSET + (i << 1)); view->loops[i].cels_nr = READ_LE_UINT16(resource + loopOffset); @@ -405,7 +400,7 @@ gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, b resource + cel_offset, resource + cel_offset, size - cel_offset, - view, amiga_game, false); + view, viewType); } } else { byte copy_entry = seeker[V2_COPY_OF_LOOP]; @@ -417,7 +412,7 @@ gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, b byte* cellSeeker = resource + loopOffset; for (int j = 0; j < view->loops[i].cels_nr; j++) { - view->loops[i].cels[j] = gfxr_draw_cel1(id, i, j, mirrored, resource, cellSeeker, size, view, 0, true); + view->loops[i].cels[j] = gfxr_draw_cel1(id, i, j, mirrored, resource, cellSeeker, size, view, viewType); cellSeeker += resource[V2_BYTES_PER_CEL]; } diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index ef31fcdd7d..e07b904324 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -112,6 +112,20 @@ ResourceSource *ResourceManager::addExternalMap(const char *file_name) { newsrc->source_type = kSourceExtMap; newsrc->location_name = file_name; + newsrc->resourceFile = 0; + newsrc->scanned = false; + newsrc->associated_map = NULL; + + _sources.push_back(newsrc); + return newsrc; +} + +ResourceSource *ResourceManager::addExternalMap(const Common::FSNode *mapFile) { + ResourceSource *newsrc = new ResourceSource(); + + newsrc->source_type = kSourceExtMap; + newsrc->location_name = mapFile->getName(); + newsrc->resourceFile = mapFile; newsrc->scanned = false; newsrc->associated_map = NULL; @@ -125,6 +139,21 @@ ResourceSource *ResourceManager::addSource(ResourceSource *map, ResSourceType ty newsrc->source_type = type; newsrc->scanned = false; newsrc->location_name = filename; + newsrc->resourceFile = 0; + newsrc->volume_number = number; + newsrc->associated_map = map; + + _sources.push_back(newsrc); + return newsrc; +} + +ResourceSource *ResourceManager::addSource(ResourceSource *map, ResSourceType type, const Common::FSNode *resFile, int number) { + ResourceSource *newsrc = new ResourceSource(); + + newsrc->source_type = type; + newsrc->scanned = false; + newsrc->location_name = resFile->getName(); + newsrc->resourceFile = resFile; newsrc->volume_number = number; newsrc->associated_map = map; @@ -322,12 +351,24 @@ int sci0_get_compression_method(Common::ReadStream &stream) { int ResourceManager::addAppropriateSources() { ResourceSource *map; - if (!Common::File::exists("RESOURCE.MAP")) + if (Common::File::exists("RESOURCE.MAP")) + map = addExternalMap("RESOURCE.MAP"); +#ifdef ENABLE_SCI32 + else if (Common::File::exists("RESMAP.000")) + map = addExternalMap("RESMAP.000"); + else if (Common::File::exists("RESMAP.001")) + map = addExternalMap("RESMAP.001"); +#endif + else return 0; - map = addExternalMap("RESOURCE.MAP"); + Common::ArchiveMemberList files; SearchMan.listMatchingMembers(files, "RESOURCE.0??"); + +#ifdef ENABLE_SCI32 + SearchMan.listMatchingMembers(files, "RESSCI.0??"); +#endif for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { const Common::String name = (*x)->getName(); @@ -342,6 +383,48 @@ int ResourceManager::addAppropriateSources() { return 1; } +int ResourceManager::addAppropriateSources(const Common::FSList &fslist) { + ResourceSource *map = 0; + + // First, find resource.map + for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + if (file->isDirectory()) + continue; + + Common::String filename = file->getName(); + filename.toLowercase(); + + if (filename.contains("resource.map") || filename.contains("resmap.000")) { + map = addExternalMap(file); + break; + } + } + + if (!map) + return 0; + + // Now find all the resource.0?? files + for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + if (file->isDirectory()) + continue; + + Common::String filename = file->getName(); + filename.toLowercase(); + + if (filename.contains("resource.0") || filename.contains("ressci.0")) { + const char *dot = strrchr(filename.c_str(), '.'); + int number = atoi(dot + 1); + + addSource(map, kSourceVolume, file, number); + } + } + + // This function is only called by the advanced detector, and we don't really need + // to add a patch directory or message.map here + + return 1; +} + int ResourceManager::addInternalSources() { Common::List<ResourceId> *resources = listResources(kResourceTypeMap); Common::List<ResourceId>::iterator itr = resources->begin(); @@ -396,16 +479,23 @@ void ResourceManager::freeResourceSources() { _sources.clear(); } -ResourceManager::ResourceManager(int maxMemory) { - _maxMemory = maxMemory; +ResourceManager::ResourceManager() { + addAppropriateSources(); + init(); +} + +ResourceManager::ResourceManager(const Common::FSList &fslist) { + addAppropriateSources(fslist); + init(); +} + +void ResourceManager::init() { _memoryLocked = 0; _memoryLRU = 0; _LRU.clear(); _resMap.clear(); _audioMapSCI1 = NULL; - addAppropriateSources(); - // FIXME: put this in an Init() function, so that we can error out if detection fails completely _mapVersion = detectMapVersion(); @@ -432,7 +522,7 @@ ResourceManager::ResourceManager(int maxMemory) { if (_sciVersion != SCI_VERSION_AUTODETECT) debug("Resmgr: Detected %s", versionNames[_sciVersion]); else - debug("Resmgr: Couldn't determine SCI version"); + warning("Resmgr: Couldn't determine SCI version"); switch (_viewType) { case kViewEga: @@ -443,6 +533,12 @@ ResourceManager::ResourceManager(int maxMemory) { break; case kViewVga11: debug("Resmgr: Detected SCI1.1 VGA graphic resources"); + break; + case kViewAmiga: + debug("Resmgr: Detected Amiga graphic resources"); + break; + default: + warning("Resmgr: Couldn't determine view type"); } } @@ -506,7 +602,7 @@ void ResourceManager::printLRU() { } void ResourceManager::freeOldResources() { - while (_maxMemory < _memoryLRU) { + while (MAX_MEMORY < _memoryLRU) { assert(!_LRU.empty()); Resource *goner = *_LRU.reverse_begin(); removeFromLRU(goner); @@ -602,7 +698,8 @@ const char *ResourceManager::versionDescription(ResVersion version) const { } ResourceManager::ResVersion ResourceManager::detectMapVersion() { - Common::File file; + Common::SeekableReadStream *fileStream = 0; + Common::File *file = 0; byte buff[6]; ResourceSource *rsrc= 0; @@ -610,22 +707,29 @@ ResourceManager::ResVersion ResourceManager::detectMapVersion() { rsrc = *it; if (rsrc->source_type == kSourceExtMap) { - file.open(rsrc->location_name); + if (rsrc->resourceFile) { + fileStream = rsrc->resourceFile->createReadStream(); + } else { + file = new Common::File(); + file->open(rsrc->location_name); + if (file->isOpen()) + fileStream = file; + } break; } } - if (file.isOpen() == false) { + + if (!fileStream) error("Failed to open resource map file"); - return kResVersionUnknown; - } + // detection // SCI0 and SCI01 maps have last 6 bytes set to FF - file.seek(-4, SEEK_END); - uint32 uEnd = file.readUint32LE(); + fileStream->seek(-4, SEEK_END); + uint32 uEnd = fileStream->readUint32LE(); if (uEnd == 0xFFFFFFFF) { // check if 0 or 01 - try to read resources in SCI0 format and see if exists - file.seek(0, SEEK_SET); - while (file.read(buff, 6) == 6 && !(buff[0] == 0xFF && buff[1] == 0xFF && buff[2] == 0xFF)) { + fileStream->seek(0, SEEK_SET); + while (fileStream->read(buff, 6) == 6 && !(buff[0] == 0xFF && buff[1] == 0xFF && buff[2] == 0xFF)) { if (getVolume(rsrc, (buff[5] & 0xFC) >> 2) == NULL) return kResVersionSci1Middle; } @@ -639,15 +743,22 @@ ResourceManager::ResVersion ResourceManager::detectMapVersion() { uint16 lastDirectoryOffset = 0; uint16 directorySize = 0; ResVersion mapDetected = kResVersionUnknown; - file.seek(0, SEEK_SET); - while (!file.eos()) { - directoryType = file.readByte(); - directoryOffset = file.readUint16LE(); - if ((directoryType < 0x80) || ((directoryType > 0xA0) && (directoryType != 0xFF))) + fileStream->seek(0, SEEK_SET); + + while (!fileStream->eos()) { + directoryType = fileStream->readByte(); + directoryOffset = fileStream->readUint16LE(); + + // Only SCI32 has directory type < 0x80 + if (directoryType < 0x80 && (mapDetected == kResVersionUnknown || mapDetected == kResVersionSci32)) + mapDetected = kResVersionSci32; + else if ((directoryType < 0x80) || (directoryType > 0xA0 && directoryType != 0xFF)) break; + // Offset is above file size? -> definitely not SCI1/SCI1.1 - if (directoryOffset > file.size()) + if (directoryOffset > fileStream->size()) break; + if (lastDirectoryOffset) { directorySize = directoryOffset - lastDirectoryOffset; if ((directorySize % 5) && (directorySize % 6 == 0)) @@ -655,49 +766,52 @@ ResourceManager::ResVersion ResourceManager::detectMapVersion() { if ((directorySize % 5 == 0) && (directorySize % 6)) mapDetected = kResVersionSci11; } - if (directoryType==0xFF) { + + if (directoryType == 0xFF) { // FFh entry needs to point to EOF - if (directoryOffset != file.size()) + if (directoryOffset != fileStream->size()) break; - if (mapDetected) + + delete fileStream; + + if (mapDetected) return mapDetected; return kResVersionSci1Late; } + lastDirectoryOffset = directoryOffset; } -#ifdef ENABLE_SCI32 - // late SCI1.1 and SCI32 maps have last directory entry set to 0xFF - // offset set to filesize and 4 more bytes - - // TODO/FIXME: This code was not updated in r42300, which changed the behavior of this - // function a lot. To make it compile again "off" was changed to the newly introduced - // "lastDirectoryOffset". This is probably not the correct fix, since before r43000 - // the loop above could not prematurely terminate and thus this would always check the - // last directory entry instead of the last checked directory entry. - file.seek(lastDirectoryOffset - 7, SEEK_SET); - if (file.readByte() == 0xFF && file.readUint16LE() == file.size()) - return kResVersionSci32; // TODO : check if there is a difference between these maps -#endif + delete fileStream; return kResVersionUnknown; } ResourceManager::ResVersion ResourceManager::detectVolVersion() { - Common::File file; + Common::SeekableReadStream *fileStream = 0; + Common::File *file = 0; ResourceSource *rsrc; + for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) { rsrc = *it; if (rsrc->source_type == kSourceVolume) { - file.open(rsrc->location_name); + if (rsrc->resourceFile) { + fileStream = rsrc->resourceFile->createReadStream(); + } else { + file = new Common::File(); + file->open(rsrc->location_name); + if (file->isOpen()) + fileStream = file; + } break; } } - if (file.isOpen() == false) { + if (!fileStream) { error("Failed to open volume file"); return kResVersionUnknown; } + // SCI0 volume format: {wResId wPacked+4 wUnpacked wCompression} = 8 bytes // SCI1 volume format: {bResType wResNumber wPacked+4 wUnpacked wCompression} = 9 bytes // SCI1.1 volume format: {bResType wResNumber wPacked wUnpacked wCompression} = 9 bytes @@ -710,15 +824,17 @@ ResourceManager::ResVersion ResourceManager::detectVolVersion() { bool failed = false; // Check for SCI0, SCI1, SCI1.1 and SCI32 v2 (Gabriel Knight 1 CD) formats - while (!file.eos() && file.pos() < 0x100000) { + while (!fileStream->eos() && fileStream->pos() < 0x100000) { if (curVersion > kResVersionSci0Sci1Early) - file.readByte(); - resId = file.readUint16LE(); - dwPacked = (curVersion < kResVersionSci32) ? file.readUint16LE() : file.readUint32LE(); - dwUnpacked = (curVersion < kResVersionSci32) ? file.readUint16LE() : file.readUint32LE(); - wCompression = (curVersion < kResVersionSci32) ? file.readUint16LE() : file.readUint32LE(); - if (file.eos()) + fileStream->readByte(); + resId = fileStream->readUint16LE(); + dwPacked = (curVersion < kResVersionSci32) ? fileStream->readUint16LE() : fileStream->readUint32LE(); + dwUnpacked = (curVersion < kResVersionSci32) ? fileStream->readUint16LE() : fileStream->readUint32LE(); + wCompression = (curVersion < kResVersionSci32) ? fileStream->readUint16LE() : fileStream->readUint32LE(); + if (fileStream->eos()) { + delete fileStream; return curVersion; + } int chk = (curVersion == kResVersionSci0Sci1Early) ? 4 : 20; int offs = curVersion < kResVersionSci11 ? 4 : 0; @@ -740,18 +856,20 @@ ResourceManager::ResVersion ResourceManager::detectVolVersion() { break; } - file.seek(0, SEEK_SET); + fileStream->seek(0); continue; } if (curVersion < kResVersionSci11) - file.seek(dwPacked - 4, SEEK_CUR); + fileStream->seek(dwPacked - 4, SEEK_CUR); else if (curVersion == kResVersionSci11) - file.seek((9 + dwPacked) % 2 ? dwPacked + 1 : dwPacked, SEEK_CUR); + fileStream->seek((9 + dwPacked) % 2 ? dwPacked + 1 : dwPacked, SEEK_CUR); else if (curVersion == kResVersionSci32) - file.seek(dwPacked, SEEK_CUR);//(9 + wPacked) % 2 ? wPacked + 1 : wPacked, SEEK_CUR); + fileStream->seek(dwPacked - 2, SEEK_CUR); } + delete fileStream; + if (!failed) return curVersion; @@ -797,7 +915,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType restype, patch_data_offset = 2; break; default: - warning("Resource patch unsupported special case %X\n", patch_data_offset); + warning("Resource patch unsupported special case %X", patch_data_offset); } } @@ -909,7 +1027,7 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) { res->id = resId; res->source = getVolume(map, offset >> bShift); if (!res->source) { - warning("Could not get volume for resource %d, VolumeID %d\n", id, offset >> bShift); + warning("Could not get volume for resource %d, VolumeID %d", id, offset >> bShift); } _resMap.setVal(resId, res); } @@ -1393,22 +1511,64 @@ ResourceCompression ResourceManager::getViewCompression() { return kCompNone; } -ResourceManager::ViewType ResourceManager::detectViewType() { +ViewType ResourceManager::detectViewType() { for (int i = 0; i < 1000; i++) { Resource *res = findResource(ResourceId(kResourceTypeView, i), 0); + if (res) { - //FIXME: Amiga switch(res->data[1]) { - case 0: - return kViewEga; - default: + case 128: + // If the 2nd byte is 128, it's a VGA game return kViewVga; + case 0: + // EGA or Amiga, try to read as Amiga view + + if (res->size < 10) + return kViewUnknown; + + // Read offset of first loop + uint16 offset = READ_LE_UINT16(res->data + 8); + + if (offset + 6U >= res->size) + return kViewUnknown; + + // Read offset of first cel + offset = READ_LE_UINT16(res->data + offset + 4); + + if (offset + 4U >= res->size) + return kViewUnknown; + + // Check palette offset, amiga views have no palette + if (READ_LE_UINT16(res->data + 6) != 0) + return kViewEga; + + uint16 width = READ_LE_UINT16(res->data + offset); + offset += 2; + uint16 height = READ_LE_UINT16(res->data + offset); + offset += 6; + + // Check that the RLE data stays within bounds + int y; + for (y = 0; y < height; y++) { + int x = 0; + + while ((x < width) && (offset < res->size)) { + byte op = res->data[offset++]; + x += (op & 0x07) ? op & 0x07 : op >> 3; + } + + // Make sure we got exactly the right number of pixels for this row + if (x != width) + return kViewEga; + } + + return kViewAmiga; } } } warning("Resmgr: Couldn't find any views"); - return kViewVga; + return kViewUnknown; } SciVersion ResourceManager::detectSciVersion() { @@ -1480,7 +1640,7 @@ SciVersion ResourceManager::detectSciVersion() { // If this turns out to be unreliable, we could do some pic resource checks instead. return SCI_VERSION_1_EARLY; case kResVersionSci1Middle: - return SCI_VERSION_1_LATE; + return SCI_VERSION_1_MIDDLE; case kResVersionSci1Late: if (_viewType == kViewVga11) { // SCI1.1 resources, assume SCI1.1 diff --git a/engines/sci/resource.h b/engines/sci/resource.h index d38cff87df..5ba2d03beb 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -28,11 +28,14 @@ #include "common/str.h" #include "common/file.h" +#include "common/fs.h" #include "common/archive.h" #include "sound/audiostream.h" #include "sound/mixer.h" // for SoundHandle +#include "gfx/gfx_resource.h" // for ViewType + #include "sci/decompressor.h" namespace Common { @@ -52,7 +55,8 @@ enum SciVersion { SCI_VERSION_01, // KQ1 and multilingual games (S.old.*) SCI_VERSION_1_EGA, // EGA with parser, QFG2 SCI_VERSION_1_EARLY, // KQ5. (EGA/VGA) - SCI_VERSION_1_LATE, // ECO1, LSL1, LSL5. (EGA/VGA) + SCI_VERSION_1_MIDDLE, // LSL1, JONESCD. (EGA?/VGA) + SCI_VERSION_1_LATE, // ECO1, LSL5. (EGA/VGA) SCI_VERSION_1_1, // KQ6, ECO2 SCI_VERSION_32 // GK }; @@ -135,6 +139,7 @@ struct ResourceSource { ResSourceType source_type; bool scanned; Common::String location_name; // FIXME: Replace by FSNode ? + const Common::FSNode *resourceFile; int volume_number; ResourceSource *associated_map; }; @@ -227,15 +232,10 @@ public: kResVersionSci32 }; - // TODO: Amiga - enum ViewType { - kViewEga, - kViewVga, - kViewVga11 - }; - bool isVGA() const { return (_viewType == kViewVga) || (_viewType == kViewVga11); } + ViewType getViewType() const { return _viewType; } + /** * Returns the SCI version as detected by the resource manager * @return SCI version @@ -244,15 +244,9 @@ public: /** * Creates a new SCI resource manager. - * @param version The SCI version to look for; use SCI_VERSION_AUTODETECT - * in the default case. - * @param maxMemory Maximum number of bytes to allow allocated for resources - * - * @note maxMemory will not be interpreted as a hard limit, only as a restriction - * for resources which are not explicitly locked. However, a warning will be - * issued whenever this limit is exceeded. */ - ResourceManager(int maxMemory); + ResourceManager(); + ResourceManager(const Common::FSList &fslist); ~ResourceManager(); /** @@ -293,8 +287,13 @@ public: void setAudioLanguage(int language); protected: + // Maximum number of bytes to allow being allocated for resources + // Note: maxMemory will not be interpreted as a hard limit, only as a restriction + // for resources which are not explicitly locked. However, a warning will be + // issued whenever this limit is exceeded. + #define MAX_MEMORY 256 * 1024 // 256KB + ViewType _viewType; // Used to determine if the game has EGA or VGA graphics - int _maxMemory; //!< Config option: Maximum total byte number allocated Common::List<ResourceSource *> _sources; int _memoryLocked; //!< Amount of resource bytes in locked memory int _memoryLRU; //!< Amount of resource bytes under LRU control @@ -307,6 +306,11 @@ protected: SciVersion _sciVersion; //!< Detected SCI version */ /** + * Initializes the resource manager + */ + void init(); + + /** * Add a path to the resource manager's list of sources. * @return a pointer to the added source structure, or NULL if an error occurred. */ @@ -323,12 +327,19 @@ protected: */ ResourceSource *addSource(ResourceSource *map, ResSourceType type, const char *filename, int number); + + ResourceSource *addSource(ResourceSource *map, ResSourceType type, + const Common::FSNode *resFile, int number); + /** * Add an external (i.e., separate file) map resource to the resource manager's list of sources. * @param file_name The name of the volume to add * @return A pointer to the added source structure, or NULL if an error occurred. */ ResourceSource *addExternalMap(const char *file_name); + + ResourceSource *addExternalMap(const Common::FSNode *mapFile); + /** * Add an internal (i.e., resource) map to the resource manager's list of sources. * @param name The name of the resource to add @@ -345,6 +356,7 @@ protected: */ void scanNewSources(); int addAppropriateSources(); + int addAppropriateSources(const Common::FSList &fslist); int addInternalSources(); void freeResourceSources(); diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index b799af9e83..3f148f54e7 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -44,13 +44,14 @@ namespace Sci { class GfxDriver; // FIXME: error-prone -const char *versionNames[9] = { +const char *versionNames[10] = { "Autodetect", "SCI0 Early", "SCI0 Late", "SCI01", "SCI1 EGA", "SCI1 Early", + "SCI1 Middle", "SCI1 Late", "SCI1.1", "SCI32" @@ -110,7 +111,13 @@ SciEngine::~SciEngine() { } Common::Error SciEngine::run() { + Graphics::PixelFormat gfxmode; +#if 0 && defined(USE_RGB_COLOR) + initGraphics(320, 200, false, NULL); +#else initGraphics(320, 200, false); +#endif + gfxmode = _system->getScreenFormat(); // Create debugger console. It requires GFX to be initialized _console = new Console(this); @@ -134,7 +141,7 @@ Common::Error SciEngine::run() { const uint32 flags = getFlags(); - _resmgr = new ResourceManager(256 * 1024); + _resmgr = new ResourceManager(); _version = _resmgr->sciVersion(); if (!_resmgr) { @@ -189,7 +196,7 @@ Common::Error SciEngine::run() { // Default config ends #endif - if (gfxop_init(_resmgr->sciVersion(), &gfx_state, &gfx_options, _resmgr)) { + if (gfxop_init(_resmgr->sciVersion(), &gfx_state, &gfx_options, _resmgr, gfxmode, 1, 1)) { warning("Graphics initialization failed. Aborting..."); return Common::kUnknownError; } diff --git a/engines/sci/sfx/core.cpp b/engines/sci/sfx/core.cpp index 95d79b3666..c8cf773eae 100644 --- a/engines/sci/sfx/core.cpp +++ b/engines/sci/sfx/core.cpp @@ -1060,7 +1060,7 @@ static void deDPCM16(byte *soundBuf, Common::SeekableReadStream &audioStream, ui s += tableDPCM16[b]; s = CLIP<int32>(s, -32768, 32767); - *out++ = TO_BE_16(s); + *out++ = s; } } @@ -1070,7 +1070,7 @@ static void deDPCM8Nibble(byte *soundBuf, int32 &s, byte b) { else s += tableDPCM8[b & 7]; s = CLIP<int32>(s, 0, 255); - *soundBuf = s; + *soundBuf = TO_LE_16(s); } static void deDPCM8(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { @@ -1106,7 +1106,8 @@ static byte* readSOLAudio(Common::SeekableReadStream *audioStream, uint32 &size, // Convert the SOL stream flags to our own format flags = 0; if (audioFlags & kSolFlag16Bit) - flags |= Audio::Mixer::FLAG_16BITS; + flags |= Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN; + if (!(audioFlags & kSolFlagIsSigned)) flags |= Audio::Mixer::FLAG_UNSIGNED; diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 3033904357..9dab776b67 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -2451,7 +2451,7 @@ void ScummEngine_v71he::postProcessAuxQueue() { uint8 *dst2 = pvs->getBackPixels(0, pvs->topline); switch (comp) { case 1: - Wiz::copyAuxImage(dst1, dst2, axfd + 10, pvs->w, pvs->h, x, y, w, h); + Wiz::copyAuxImage(dst1, dst2, axfd + 10, pvs->pitch, pvs->h, x, y, w, h, _bitDepth); break; default: error("unimplemented compression type %d", comp); @@ -2551,9 +2551,10 @@ void Actor::saveLoadWithSerializer(Serializer *ser) { MKLINE(Actor, _flip, sleByte, VER(32)), MKLINE(Actor, _heSkipLimbs, sleByte, VER(32)), - // Actor palette grew from 64 to 256 bytes + // Actor palette grew from 64 to 256 bytes and switched to uint16 in HE games MKARRAY_OLD(Actor, _palette[0], sleByte, 64, VER(8), VER(9)), - MKARRAY(Actor, _palette[0], sleByte, 256, VER(10)), + MKARRAY_OLD(Actor, _palette[0], sleByte, 256, VER(10), VER(79)), + MKARRAY(Actor, _palette[0], sleUint16, 256, VER(80)), MK_OBSOLETE(Actor, _mask, sleByte, VER(8), VER(9)), MKLINE(Actor, _shadowMode, sleByte, VER(8)), diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 3f67d42a50..c3edd24a39 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -157,7 +157,7 @@ protected: }; - byte _palette[256]; + uint16 _palette[256]; int _elevation; uint16 _facing; uint16 _targetFacing; diff --git a/engines/scumm/akos.cpp b/engines/scumm/akos.cpp index ab7db2c4a7..f4bb8a2c8b 100644 --- a/engines/scumm/akos.cpp +++ b/engines/scumm/akos.cpp @@ -289,7 +289,7 @@ void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { } while ((uint16)mask); } -void AkosRenderer::setPalette(byte *new_palette) { +void AkosRenderer::setPalette(uint16 *new_palette) { uint size, i; size = _vm->getResourceDataSize(akpl); @@ -299,22 +299,23 @@ void AkosRenderer::setPalette(byte *new_palette) { if (size > 256) error("akos_setPalette: %d is too many colors", size); - if (_vm->_game.heversion >= 99 && _paletteNum) { - for (i = 0; i < size; i++) - _palette[i] = (byte)_vm->_hePalettes[_paletteNum * 1024 + 768 + akpl[i]]; - } else if ((_vm->_game.features & GF_16BIT_COLOR) && rgbs) { - for (i = 0; i < size; i++) { - if (new_palette[i] == 0xFF) { - uint8 col = akpl[i]; - uint8 r = rgbs[col * 3 + 0]; - uint8 g = rgbs[col * 3 + 1]; - uint8 b = rgbs[col * 3 + 2]; - - _palette[i] = _vm->remapPaletteColor(r, g, b, -1); - } else { - _palette[i] = new_palette[i]; + if (_vm->_game.features & GF_16BIT_COLOR) { + if (_paletteNum) { + for (i = 0; i < size; i++) + _palette[i] = READ_LE_UINT16(_vm->_hePalettes + _paletteNum * _vm->_hePaletteSlot + 768 + akpl[i] * 2); + } else if (rgbs) { + for (i = 0; i < size; i++) { + if (new_palette[i] == 0xFF) { + uint8 col = akpl[i]; + _palette[i] = _vm->get16BitColor(rgbs[col * 3 + 0], rgbs[col * 3 + 1], rgbs[col * 3 + 2]); + } else { + _palette[i] = new_palette[i]; + } } } + } else if (_vm->_game.heversion >= 99 && _paletteNum) { + for (i = 0; i < size; i++) + _palette[i] = (byte)_vm->_hePalettes[_paletteNum * _vm->_hePaletteSlot + 768 + akpl[i]]; } else { for (i = 0; i < size; i++) { _palette[i] = new_palette[i] != 0xFF ? new_palette[i] : akpl[i]; @@ -545,7 +546,7 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) { byte *dst; byte len, maskbit; int y; - uint color, height, pcolor; + uint16 color, height, pcolor; const byte *scaleytab; bool masked; bool skip_column = false; @@ -589,7 +590,11 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) { } else if (_shadow_mode == 2) { error("codec1_spec2"); // TODO } else if (_shadow_mode == 3) { - if (_vm->_game.heversion >= 90) { + if (_vm->_game.features & GF_16BIT_COLOR) { + uint16 srcColor = (pcolor >> 1) & 0x7DEF; + uint16 dstColor = (READ_UINT16(dst) >> 1) & 0x7DEF; + pcolor = srcColor + dstColor; + } else if (_vm->_game.heversion >= 90) { pcolor = (pcolor << 8) + *dst; pcolor = xmap[pcolor]; } else if (pcolor < 8) { @@ -597,7 +602,11 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) { pcolor = _shadow_table[pcolor]; } } - *dst = pcolor; + if (_vm->_bitDepth == 2) { + WRITE_UINT16(dst, pcolor); + } else { + *dst = pcolor; + } } } dst += _out.pitch; @@ -617,7 +626,7 @@ void AkosRenderer::codec1_genericDecode(Codec1 &v1) { if (v1.x < 0 || v1.x >= v1.boundsRect.right) return; maskbit = revBitMask(v1.x & 7); - v1.destptr += v1.scaleXstep; + v1.destptr += v1.scaleXstep * _vm->_bitDepth; skip_column = false; } else skip_column = true; @@ -987,7 +996,7 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) { if (_draw_bottom < rect.bottom) _draw_bottom = rect.bottom; - v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x; + v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x * _vm->_bitDepth; codec1_genericDecode(v1); @@ -1056,7 +1065,12 @@ byte AkosRenderer::codec5(int xmoveCur, int ymoveCur) { bdd.shadowMode = _shadow_mode; bdd.shadowPalette = _vm->_shadowPalette; - bdd.actorPalette = _useBompPalette ? _palette : 0; + bdd.actorPalette = 0; + if (_useBompPalette) { + for (uint i = 0; i < 256; i++) + bdd.actorPalette[i] = _palette[i]; + } + bdd.mirror = !_mirror; drawBomp(bdd); @@ -1176,6 +1190,8 @@ void AkosRenderer::akos16Decompress(byte *dest, int32 pitch, const byte *src, in } byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) { + assert(_vm->_bitDepth == 1); + Common::Rect clip; int32 minx, miny, maxw, maxh; int32 skip_x, skip_y, cur_x, cur_y; @@ -1278,7 +1294,7 @@ byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) { int32 numskip_before = skip_x + (skip_y * _width); int32 numskip_after = _width - cur_x; - byte *dst = (byte *)_out.pixels + width_unk + height_unk * _out.pitch; + byte *dst = (byte *)_out.pixels + height_unk * _out.pitch + width_unk * _vm->_bitDepth; akos16Decompress(dst, _out.pitch, _srcptr, cur_x, out_height, dir, numskip_before, numskip_after, transparency, clip.left, clip.top, _zbuf); return 0; @@ -1335,18 +1351,27 @@ byte AkosRenderer::codec32(int xmoveCur, int ymoveCur) { _draw_bottom = dst.bottom; const uint8 *palPtr = NULL; - if (_vm->_game.heversion >= 99) { - palPtr = _vm->_hePalettes + 1792; + if (_vm->_game.features & GF_16BIT_COLOR) { + palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768; + if (_paletteNum) { + palPtr = _vm->_hePalettes + _paletteNum * _vm->_hePaletteSlot + 768; + } else if (rgbs) { + for (uint i = 0; i < 256; i++) + WRITE_LE_UINT16(_palette + i, _vm->get16BitColor(rgbs[i * 3 + 0], rgbs[i * 3 + 1], rgbs[i * 3 + 2])); + palPtr = (uint8 *)_palette; + } + } else if (_vm->_game.heversion >= 99) { + palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768; } - byte *dstPtr = (byte *)_out.pixels + dst.left + dst.top * _out.pitch; + byte *dstPtr = (byte *)_out.pixels + dst.top * _out.pitch + dst.left * _vm->_bitDepth; if (_shadow_mode == 3) { - Wiz::decompressWizImage<kWizXMap>(dstPtr, _out.pitch, _srcptr, src, 0, palPtr, xmap); + Wiz::decompressWizImage<kWizXMap>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, palPtr, xmap, _vm->_bitDepth); } else { if (palPtr != NULL) { - Wiz::decompressWizImage<kWizRMap>(dstPtr, _out.pitch, _srcptr, src, 0, palPtr); + Wiz::decompressWizImage<kWizRMap>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, palPtr, NULL, _vm->_bitDepth); } else { - Wiz::decompressWizImage<kWizCopy>(dstPtr, _out.pitch, _srcptr, src, 0); + Wiz::decompressWizImage<kWizCopy>(dstPtr, _out.pitch, kDstScreen, _srcptr, src, 0, NULL, NULL, _vm->_bitDepth); } } #endif diff --git a/engines/scumm/akos.h b/engines/scumm/akos.h index be532b804d..9f4f09d4dc 100644 --- a/engines/scumm/akos.h +++ b/engines/scumm/akos.h @@ -60,7 +60,7 @@ protected: uint16 _codec; // actor _palette - byte _palette[256]; + uint16 _palette[256]; bool _useBompPalette; // pointer to various parts of the costume resource @@ -107,7 +107,7 @@ public: int16 _actorHitX, _actorHitY; bool _actorHitResult; - void setPalette(byte *_palette); + void setPalette(uint16 *_palette); void setFacing(const Actor *a); void setCostume(int costume, int shadow); diff --git a/engines/scumm/base-costume.cpp b/engines/scumm/base-costume.cpp index 795abb8685..ef706afaac 100644 --- a/engines/scumm/base-costume.cpp +++ b/engines/scumm/base-costume.cpp @@ -40,7 +40,7 @@ byte BaseCostumeRenderer::drawCostume(const VirtScreen &vs, int numStrips, const _out.pixels = vs.getPixels(0, 0); _actorX += _vm->_virtscr[kMainVirtScreen].xstart & 7; - _out.w = _out.pitch; + _out.w = _out.pitch / _vm->_bitDepth; _out.pixels = (byte *)_out.pixels - (_vm->_virtscr[kMainVirtScreen].xstart & 7); _numStrips = numStrips; diff --git a/engines/scumm/base-costume.h b/engines/scumm/base-costume.h index 59ca3ded1f..d41d795e34 100644 --- a/engines/scumm/base-costume.h +++ b/engines/scumm/base-costume.h @@ -145,7 +145,7 @@ public: } virtual ~BaseCostumeRenderer() {} - virtual void setPalette(byte *palette) = 0; + virtual void setPalette(uint16 *palette) = 0; virtual void setFacing(const Actor *a) = 0; virtual void setCostume(int costume, int shadow) = 0; diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp index 193fc434e4..d6dfa4c5bb 100644 --- a/engines/scumm/charset.cpp +++ b/engines/scumm/charset.cpp @@ -819,9 +819,9 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, byte imagePalette[256]; memset(imagePalette, 0, sizeof(imagePalette)); memcpy(imagePalette, _vm->_charsetColorMap, 4); - Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, imagePalette); + Wiz::copyWizImage(dstPtr, charPtr, vs->pitch, kDstScreen, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, imagePalette, NULL, _vm->_bitDepth); } else { - Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen); + Wiz::copyWizImage(dstPtr, charPtr, vs->pitch, kDstScreen, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, NULL, NULL, _vm->_bitDepth); } if (_blitAlso && vs->hasTwoBuffers) { diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 57b793d579..6923c27b38 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -791,7 +791,7 @@ byte ClassicCostumeRenderer::drawLimb(const Actor *a, int limb) { } -void NESCostumeRenderer::setPalette(byte *palette) { +void NESCostumeRenderer::setPalette(uint16 *palette) { // TODO } @@ -874,17 +874,20 @@ void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) } while (mask&0xFFFF); } -void ClassicCostumeRenderer::setPalette(byte *palette) { +void ClassicCostumeRenderer::setPalette(uint16 *palette) { int i; byte color; if (_loaded._format == 0x57) { - memcpy(_palette, palette, 13); + for (i = 0; i < 13; i++) + _palette[i] = palette[i]; } else if (_vm->_game.features & GF_OLD_BUNDLE) { if (_vm->getCurrentLights() & LIGHTMODE_actor_use_colors) { - memcpy(_palette, palette, 16); + for (i = 0; i < 16; i++) + _palette[i] = palette[i]; } else { - memset(_palette, 8, 16); + for (i = 0; i < 16; i++) + _palette[i] = 8; _palette[12] = 0; } _palette[_loaded._palette[0]] = _palette[0]; diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h index 8e1910abcf..929eb8c451 100644 --- a/engines/scumm/costume.h +++ b/engines/scumm/costume.h @@ -98,7 +98,7 @@ protected: public: ClassicCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {} - void setPalette(byte *palette); + void setPalette(uint16 *palette); void setFacing(const Actor *a); void setCostume(int costume, int shadow); @@ -120,7 +120,7 @@ protected: public: NESCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {} - void setPalette(byte *palette); + void setPalette(uint16 *palette); void setFacing(const Actor *a); void setCostume(int costume, int shadow); @@ -135,7 +135,7 @@ protected: public: C64CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {} - void setPalette(byte *palette) {} + void setPalette(uint16 *palette) {} void setFacing(const Actor *a) {} void setCostume(int costume, int shadow); diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp index 64829114ca..7818d6a98e 100644 --- a/engines/scumm/cursor.cpp +++ b/engines/scumm/cursor.cpp @@ -111,11 +111,20 @@ void ScummEngine_v6::setCursorTransparency(int a) { } void ScummEngine::updateCursor() { - const int transColor = (_game.heversion >= 80) ? 5 : 255; + int transColor = (_game.heversion >= 80) ? 5 : 255; +#ifdef USE_RGB_COLOR + Graphics::PixelFormat format = _system->getScreenFormat(); + CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height, + _cursor.hotspotX, _cursor.hotspotY, + (_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor), + (_game.heversion == 70 ? 2 : 1), + &format); +#else CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height, _cursor.hotspotX, _cursor.hotspotY, (_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor), (_game.heversion == 70 ? 2 : 1)); +#endif } void ScummEngine_v6::grabCursor(int x, int y, int w, int h) { @@ -138,7 +147,7 @@ void ScummEngine::setCursorFromBuffer(const byte *ptr, int width, int height, in uint size; byte *dst; - size = width * height; + size = width * height * _bitDepth; if (size > sizeof(_grabbedCursor)) error("grabCursor: grabbed cursor too big"); @@ -148,8 +157,8 @@ void ScummEngine::setCursorFromBuffer(const byte *ptr, int width, int height, in dst = _grabbedCursor; for (; height; height--) { - memcpy(dst, ptr, width); - dst += width; + memcpy(dst, ptr, width * _bitDepth); + dst += width * _bitDepth; ptr += pitch; } @@ -166,8 +175,13 @@ void ScummEngine_v70he::setDefaultCursor() { static const byte palette[] = {0, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0}; - - memset(_grabbedCursor, 5, sizeof(_grabbedCursor)); + + if (_bitDepth == 2) { + for (i = 0; i < 1024; i++) + WRITE_UINT16(_grabbedCursor + i * 2, 5); + } else { + memset(_grabbedCursor, 5, sizeof(_grabbedCursor)); + } _cursor.hotspotX = _cursor.hotspotY = 2; src = default_he_cursor; @@ -180,10 +194,16 @@ void ScummEngine_v70he::setDefaultCursor() { for (j = 0; j < 32; j++) { switch ((p & (0x3 << 14)) >> 14) { case 1: - _grabbedCursor[32 * i + j] = 0xfe; + if (_bitDepth == 2) + WRITE_UINT16(_grabbedCursor + 64 * i + j * 2, get16BitColor(palette[4], palette[5], palette[6])); + else + _grabbedCursor[32 * i + j] = 0xfe; break; case 2: - _grabbedCursor[32 * i + j] = 0xfd; + if (_bitDepth == 2) + WRITE_UINT16(_grabbedCursor + 64 * i + j * 2, get16BitColor(palette[0], palette[1], palette[2])); + else + _grabbedCursor[32 * i + j] = 0xfd; break; default: break; @@ -195,9 +215,11 @@ void ScummEngine_v70he::setDefaultCursor() { } } - // Since white color position is not guaranteed - // we setup our own palette if supported by backend - CursorMan.replaceCursorPalette(palette, 0xfd, 3); + if (_bitDepth == 1) { + // Since white color position is not guaranteed + // we setup our own palette if supported by backend + CursorMan.replaceCursorPalette(palette, 0xfd, 3); + } updateCursor(); } diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index 99a28153c4..57fe251e05 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -80,13 +80,22 @@ static const PlainGameDescriptor gameDescriptions[] = { { "puttputt", "Putt-Putt Joins the Parade" }, #ifdef ENABLE_HE - { "airport", "Let's Explore the Airport with Buzzy" }, +#ifdef USE_RGB_COLOR { "arttime", "Blue's Art Time Activities" }, - { "balloon", "Putt-Putt and Pep's Balloon-O-Rama" }, - { "baseball", "Backyard Baseball" }, { "baseball2001", "Backyard Baseball 2001" }, { "Baseball2003", "Backyard Baseball 2003" }, { "basketball", "Backyard Basketball" }, + { "football2002", "Backyard Football 2002" }, + { "freddicove", "Freddi Fish 5: The Case of the Creature of Coral Cave" }, + { "moonbase", "Moonbase Commander" }, + { "pjgames", "Pajama Sam: Games to Play on Any Day" }, + { "readtime", "Blue's Reading Time Activities" }, + { "Soccer2004", "Backyard Soccer 2004" }, + { "SoccerMLS", "Backyard Soccer MLS Edition" }, +#endif + { "airport", "Let's Explore the Airport with Buzzy" }, + { "balloon", "Putt-Putt and Pep's Balloon-O-Rama" }, + { "baseball", "Backyard Baseball" }, { "Blues123Time", "Blue's 123 Time Activities" }, { "BluesABCTime", "Blue's ABC Time Activities" }, { "BluesBirthday", "Blue's Birthday Adventure" }, @@ -96,32 +105,25 @@ static const PlainGameDescriptor gameDescriptions[] = { { "dog", "Putt-Putt and Pep's Dog on a Stick" }, { "farm", "Let's Explore the Farm with Buzzy" }, { "football", "Backyard Football" }, - { "football2002", "Backyard Football 2002" }, { "freddi", "Freddi Fish 1: The Case of the Missing Kelp Seeds" }, { "freddi2", "Freddi Fish 2: The Case of the Haunted Schoolhouse" }, { "freddi3", "Freddi Fish 3: The Case of the Stolen Conch Shell" }, { "freddi4", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch" }, - { "freddicove", "Freddi Fish 5: The Case of the Creature of Coral Cave" }, { "FreddisFunShop", "Freddi Fish's One-Stop Fun Shop" }, { "jungle", "Let's Explore the Jungle with Buzzy" }, { "lost", "Pajama Sam's Lost & Found" }, { "maze", "Freddi Fish and Luther's Maze Madness" }, - { "moonbase", "Moonbase Commander" }, { "mustard", "SPY Fox in Hold the Mustard" }, { "pajama", "Pajama Sam 1: No Need to Hide When It's Dark Outside" }, { "pajama2", "Pajama Sam 2: Thunder and Lightning Aren't so Frightening" }, { "pajama3", "Pajama Sam 3: You Are What You Eat From Your Head to Your Feet" }, - { "pjgames", "Pajama Sam: Games to Play On Any Day" }, { "puttcircus", "Putt-Putt Joins the Circus" }, { "puttrace", "Putt-Putt Enters the Race" }, { "PuttsFunShop", "Putt-Putt's One-Stop Fun Shop" }, { "putttime", "Putt-Putt Travels Through Time" }, { "puttzoo", "Putt-Putt Saves the Zoo" }, - { "readtime", "Blue's Reading Time Activities" }, { "SamsFunShop", "Pajama Sam's One-Stop Fun Shop" }, { "soccer", "Backyard Soccer" }, - { "Soccer2004", "Backyard Soccer 2004" }, - { "SoccerMLS", "Backyard Soccer MLS Edition" }, { "socks", "Pajama Sam's Sock Works" }, { "spyfox", "SPY Fox 1: Dry Cereal" }, { "spyfox2", "SPY Fox 2: Some Assembly Required" }, @@ -343,8 +345,14 @@ static const GameSettings gameVariantsTable[] = { {"SamsFunShop", 0, 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO_NOMIDI}, {"PuttsFunShop", 0, 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED, UNK, GUIO_NOMIDI}, + // Added the use of smacker videos + {"BluesTreasureHunt", 0, 0, GID_TREASUREHUNT, 6, 99, MDT_NONE, GF_HE_LOCALIZED | GF_USE_KEY, UNK, GUIO_NOMIDI}, + +#ifdef USE_RGB_COLOR // Added 16bit color + {"arttime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, {"baseball2001", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, + {"readtime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, {"SoccerMLS", 0, 0, GID_SOCCER, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, {"spyozon", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, @@ -355,12 +363,7 @@ static const GameSettings gameVariantsTable[] = { // Restructured the Scumm engine {"pjgames", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, - // Uses smacker in external files, for testing only - {"arttime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, - {"readtime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, - {"BluesTreasureHunt", 0, 0, GID_TREASUREHUNT, 6, 99, MDT_NONE, GF_HE_LOCALIZED | GF_USE_KEY, UNK, GUIO_NOMIDI}, - - // Uses bink in external files for logos + // Added the use of bink videos {"Baseball2003", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, {"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, {"football2002", 0, 0, GID_FOOTBALL, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, @@ -369,6 +372,7 @@ static const GameSettings gameVariantsTable[] = { // U32 code required, for testing only {"moonbase", 0, 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOMIDI}, {"moonbase", "Demo", 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR | GF_DEMO, UNK, GUIO_NOMIDI}, +#endif // The following are meant to be generic HE game variants and as such do // not specify a game ID. Make sure that these are last in the table, else @@ -500,23 +504,12 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "puttputt", "Putt-Putt", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 }, #ifdef ENABLE_HE - { "airport", "airport", kGenHEPC, UNK_LANG, UNK, 0 }, - { "airport", "airdemo", kGenHEPC, UNK_LANG, UNK, 0 }, - { "airport", "Airport Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "airport", "The AirPort", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - +#ifdef USE_RGB_COLOR { "arttime", "arttime", kGenHEPC, UNK_LANG, UNK, 0 }, { "arttime", "Blues-ArtTime", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "arttime", "artdemo", kGenHEPC, UNK_LANG, UNK, 0 }, { "arttime", "Blues-ArtTime Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "balloon", "balloon", kGenHEPC, UNK_LANG, UNK, 0 }, - { "balloon", "Balloon-O-Rama", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - - { "baseball", "baseball", kGenHEPC, UNK_LANG, UNK, 0 }, - { "baseball", "BaseBall", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "baseball", "basedemo.cup", kGenUnchanged, UNK_LANG, UNK, 0 }, - { "baseball2001", "baseball2001", kGenHEPC, UNK_LANG, UNK, 0 }, { "baseball2001", "bb2demo", kGenHEPC, UNK_LANG, UNK, 0 }, { "baseball2001", "Baseball 2001 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, @@ -529,6 +522,62 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "basketball", "basketball", kGenHEPC, UNK_LANG, UNK, 0 }, { "basketball", "Basketball", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "football2002", "FootBall2002", kGenHEPC, UNK_LANG, UNK, 0 }, + { "football2002", "Football 2002", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + + { "freddicove", "freddicove", kGenHEPC, UNK_LANG, UNK, 0 }, + { "freddicove", "FreddiCCC", kGenHEPC, UNK_LANG, UNK, 0 }, + { "freddicove", "FreddiCove", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "freddicove", "FreddiDZZ", kGenHEPC, Common::NL_NLD, UNK, 0 }, + { "freddicove", "FreddiDZZ", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, + { "freddicove", "FreddiMML", kGenHEPC, Common::FR_FRA, UNK, 0 }, + { "freddicove", "FreddiMML", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, + { "freddicove", "FFCoveDemo", kGenHEPC, UNK_LANG, UNK, 0 }, + { "freddicove", "FreddiCoveDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "freddicove", "ff5demo", kGenHEPC, UNK_LANG, UNK, 0 }, + { "freddicove", "FF5Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, + + { "moonbase", "moonbase", kGenHEPC, UNK_LANG, UNK, 0 }, + { "moonbase", "moondemo", kGenHEPC, UNK_LANG, UNK, 0 }, + + { "pjgames", "pjgames", kGenHEPC, UNK_LANG, UNK, 0 }, + { "pjgames", "PJGames", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + + { "readtime", "Blue's Reading Time", kGenHEPC, UNK_LANG, UNK, 0 }, + { "readtime", "Blues-ReadingTime", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "readtime", "readDemo", kGenHEPC, UNK_LANG, UNK, 0 }, + { "readtime", "Blues-ReadingTime Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + + { "Soccer2004", "Soccer2004", kGenHEPC, UNK_LANG, UNK, 0 }, + { "Soccer2004", "Soccer 2004", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + + { "SoccerMLS", "SoccerMLS", kGenHEPC, UNK_LANG, UNK, 0 }, + { "SoccerMLS", "Backyard Soccer MLS", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + + { "spyozon", "spyozon", kGenHEPC, UNK_LANG, UNK, 0 }, + { "spyozon", "sf3-demo", kGenHEPC, UNK_LANG, UNK, 0 }, + { "spyozon", "SF3Demo", kGenHEPC, Common::FR_FRA, UNK, 0 }, + { "spyozon", "Spy Ozone Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "spyozon", "SPYFoxAIW", kGenHEPC, Common::DE_DEU, UNK, 0 }, + { "spyozon", "SPYFoxOZU", kGenHEPC, UNK_LANG, UNK, 0 }, + { "spyozon", "SPYFoxSOS", kGenHEPC, Common::FR_FRA, UNK, 0 }, + { "spyozon", "SPYFoxSOS", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, + { "spyozon", "SpyOzon", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "spyozon", "ozonepre.cup", kGenUnchanged, UNK_LANG, UNK, "HE CUP" }, +#endif + + { "airport", "airport", kGenHEPC, UNK_LANG, UNK, 0 }, + { "airport", "airdemo", kGenHEPC, UNK_LANG, UNK, 0 }, + { "airport", "Airport Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "airport", "The AirPort", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + + { "balloon", "balloon", kGenHEPC, UNK_LANG, UNK, 0 }, + { "balloon", "Balloon-O-Rama", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + + { "baseball", "baseball", kGenHEPC, UNK_LANG, UNK, 0 }, + { "baseball", "BaseBall", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "baseball", "basedemo.cup", kGenUnchanged, UNK_LANG, UNK, 0 }, + { "blues123time", "Blues123time", kGenHEPC, UNK_LANG, UNK, 0 }, { "blues123time", "Blue's 123 Time", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, @@ -571,9 +620,6 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "football", "FootBall Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "football", "footdemo", kGenHEPC, UNK_LANG, UNK, 0 }, - { "football2002", "FootBall2002", kGenHEPC, UNK_LANG, UNK, 0 }, - { "football2002", "Football 2002", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "freddi", "freddi", kGenHEPC, UNK_LANG, UNK, 0 }, { "freddi", "Freddi", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "freddi", "Freddi1", kGenHEPC, UNK_LANG, UNK, 0 }, @@ -632,18 +678,6 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "freddi4", "MaliceMRC", kGenHEPC, Common::FR_FRA, UNK, 0 }, { "freddi4", "Mm4demo", kGenHEPC, Common::FR_FRA, UNK, 0 }, - { "freddicove", "freddicove", kGenHEPC, UNK_LANG, UNK, 0 }, - { "freddicove", "FreddiCCC", kGenHEPC, UNK_LANG, UNK, 0 }, - { "freddicove", "FreddiCove", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "freddicove", "FreddiDZZ", kGenHEPC, Common::NL_NLD, UNK, 0 }, - { "freddicove", "FreddiDZZ", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, - { "freddicove", "FreddiMML", kGenHEPC, Common::FR_FRA, UNK, 0 }, - { "freddicove", "FreddiMML", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, - { "freddicove", "FFCoveDemo", kGenHEPC, UNK_LANG, UNK, 0 }, - { "freddicove", "FreddiCoveDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "freddicove", "ff5demo", kGenHEPC, UNK_LANG, UNK, 0 }, - { "freddicove", "FF5Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, - { "FreddisFunShop", "FreddisFunShop", kGenHEPC, UNK_LANG, UNK, 0 }, { "FreddisFunShop", "Freddi's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, @@ -661,9 +695,6 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "maze", "Doolhof", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, { "maze", "Maze Madness", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "moonbase", "moonbase", kGenHEPC, UNK_LANG, UNK, 0 }, - { "moonbase", "moondemo", kGenHEPC, UNK_LANG, UNK, 0 }, - { "mustard", "mustard", kGenHEPC, UNK_LANG, UNK, 0 }, { "mustard", "Mustard", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, @@ -716,9 +747,6 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "pajama3", "PyjamaSKS", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 }, { "pajama3", "UKPajamaEAT", kGenHEPC, Common::RU_RUS, UNK, 0 }, - { "pjgames", "pjgames", kGenHEPC, UNK_LANG, UNK, 0 }, - { "pjgames", "PJGames", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "puttcircus", "puttcircus", kGenHEPC, UNK_LANG, UNK, 0 }, { "puttcircus", "circdemo", kGenHEPC, UNK_LANG, UNK, 0 }, { "puttcircus", "CircusDemo", kGenHEPC, Common::FR_FRA, UNK, 0 }, @@ -788,23 +816,12 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "puttzoo", "Zoo Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "puttzoo", "Putt-Putt Saves the Zoo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "readtime", "Blue's Reading Time", kGenHEPC, UNK_LANG, UNK, 0 }, - { "readtime", "Blues-ReadingTime", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "readtime", "readDemo", kGenHEPC, UNK_LANG, UNK, 0 }, - { "readtime", "Blues-ReadingTime Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "SamsFunShop", "SamsFunShop", kGenHEPC, UNK_LANG, UNK, 0 }, { "SamsFunShop", "Sam's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "soccer", "soccer", kGenHEPC, UNK_LANG, UNK, 0 }, { "soccer", "Soccer", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "SoccerMLS", "SoccerMLS", kGenHEPC, UNK_LANG, UNK, 0 }, - { "SoccerMLS", "Backyard Soccer MLS", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - - { "Soccer2004", "Soccer2004", kGenHEPC, UNK_LANG, UNK, 0 }, - { "Soccer2004", "Soccer 2004", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "socks", "socks", kGenHEPC, UNK_LANG, UNK, 0 }, { "socks", "SockWorks", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "socks", "SokkenSoep", kGenHEPC, Common::NL_NLD, UNK, 0 }, @@ -846,17 +863,6 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "spyfox2", "SPYMini", kGenHEPC, UNK_LANG, UNK, 0 }, { "spyfox2", "spy2preview.cup", kGenUnchanged, UNK_LANG, UNK, 0 }, - { "spyozon", "spyozon", kGenHEPC, UNK_LANG, UNK, 0 }, - { "spyozon", "sf3-demo", kGenHEPC, UNK_LANG, UNK, 0 }, - { "spyozon", "SF3Demo", kGenHEPC, Common::FR_FRA, UNK, 0 }, - { "spyozon", "Spy Ozone Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "spyozon", "SPYFoxAIW", kGenHEPC, Common::DE_DEU, UNK, 0 }, - { "spyozon", "SPYFoxOZU", kGenHEPC, UNK_LANG, UNK, 0 }, - { "spyozon", "SPYFoxSOS", kGenHEPC, Common::FR_FRA, UNK, 0 }, - { "spyozon", "SPYFoxSOS", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, - { "spyozon", "SpyOzon", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "spyozon", "ozonepre.cup", kGenUnchanged, UNK_LANG, UNK, "HE CUP" }, - { "thinker1", "1grademo", kGenHEPC, UNK_LANG, UNK, 0 }, { "thinker1", "thinker1", kGenHEPC, UNK_LANG, UNK, 0 }, { "thinker1", "Thinker1", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp index 63ac952265..53097b6815 100644 --- a/engines/scumm/dialogs.cpp +++ b/engines/scumm/dialogs.cpp @@ -213,8 +213,6 @@ ScummDialog::ScummDialog(String name) : GUI::Dialog(name) { #pragma mark - -Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode); - enum { kSaveCmd = 'SAVE', kLoadCmd = 'LOAD', @@ -226,213 +224,6 @@ enum { kChooseCmd = 'CHOS' }; -SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine) - : Dialog("ScummSaveLoad"), _saveMode(saveMode), _list(0), _chooseButton(0), _gfxWidget(0), _vm(engine) { - - _backgroundType = GUI::ThemeEngine::kDialogBackgroundSpecial; - - new StaticTextWidget(this, "ScummSaveLoad.Title", title); - - // Add choice list - _list = new GUI::ListWidget(this, "ScummSaveLoad.List"); - _list->setEditable(saveMode); - _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero); - -// Tanoku: SVNMerge removed this. Unconvinient. /////////////// -// _container = new GUI::ContainerWidget(this, 0, 0, 10, 10); -/////////////////////////////////////////////////////////////// - - _gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10); - - _date = new StaticTextWidget(this, 0, 0, 10, 10, "No date saved", kTextAlignCenter); - _time = new StaticTextWidget(this, 0, 0, 10, 10, "No time saved", kTextAlignCenter); - _playtime = new StaticTextWidget(this, 0, 0, 10, 10, "No playtime saved", kTextAlignCenter); - - // Buttons - new GUI::ButtonWidget(this, "ScummSaveLoad.Cancel", "Cancel", kCloseCmd, 0); - _chooseButton = new GUI::ButtonWidget(this, "ScummSaveLoad.Choose", buttonLabel, kChooseCmd, 0); - _chooseButton->setEnabled(false); - - _container = new GUI::ContainerWidget(this, 0, 0, 10, 10); -// _container->setHints(GUI::THEME_HINT_USE_SHADOW); -} - -SaveLoadChooser::~SaveLoadChooser() { -} - -const Common::String &SaveLoadChooser::getResultString() const { - return _list->getSelectedString(); -} - -void SaveLoadChooser::setList(const StringList& list) { - _list->setList(list); -} - -int SaveLoadChooser::runModal() { - if (_gfxWidget) - _gfxWidget->setGfx(0); - int ret = Dialog::runModal(); - return ret; -} - -void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { - int selItem = _list->getSelected(); - switch (cmd) { - case GUI::kListItemActivatedCmd: - case GUI::kListItemDoubleClickedCmd: - if (selItem >= 0) { - if (_saveMode || !getResultString().empty()) { - _list->endEditMode(); - setResult(selItem); - close(); - } - } - break; - case kChooseCmd: - _list->endEditMode(); - setResult(selItem); - close(); - break; - case GUI::kListSelectionChangedCmd: { - if (_gfxWidget) { - updateInfos(true); - } - - if (_saveMode) { - _list->startEditMode(); - } - // Disable button if nothing is selected, or (in load mode) if an empty - // list item is selected. We allow choosing an empty item in save mode - // because we then just assign a default name. - _chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().empty())); - _chooseButton->draw(); - } break; - case kCloseCmd: - setResult(-1); - default: - Dialog::handleCommand(sender, cmd, data); - } -} - -void SaveLoadChooser::reflowLayout() { - if (g_gui.xmlEval()->getVar("Globals.ScummSaveLoad.ExtInfo.Visible") == 1) { - int16 x, y; - uint16 w, h; - - if (!g_gui.xmlEval()->getWidgetData("ScummSaveLoad.Thumbnail", x, y, w, h)) - error("Error when loading position data for Save/Load Thumbnails."); - - int thumbW = kThumbnailWidth; - int thumbH = ((g_system->getHeight() % 200 && g_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1); - int thumbX = x + (w >> 1) - (thumbW >> 1); - int thumbY = y + kLineHeight; - - _container->resize(x, y, w, h); - _gfxWidget->resize(thumbX, thumbY, thumbW, thumbH); - - int height = thumbY + thumbH + kLineHeight; - - _date->resize(thumbX, height, kThumbnailWidth, kLineHeight); - - height += kLineHeight; - - _time->resize(thumbX, height, kThumbnailWidth, kLineHeight); - - height += kLineHeight; - - _playtime->resize(thumbX, height, kThumbnailWidth, kLineHeight); - - _container->setVisible(true); - _gfxWidget->setVisible(true); - _date->setVisible(true); - _time->setVisible(true); - _playtime->setVisible(true); - - _fillR = 0; //g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillR"); - _fillG = 0; //g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillG"); - _fillB = 0; //g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillB"); - } else { - _container->setVisible(false); - _gfxWidget->setVisible(false); - _date->setVisible(false); - _time->setVisible(false); - _playtime->setVisible(false); - } - - Dialog::reflowLayout(); - - if (_container->isVisible()) - updateInfos(false); -} - -void SaveLoadChooser::updateInfos(bool redraw) { - int selItem = _list->getSelected(); - Graphics::Surface *thumb = 0; - if (selItem >= 0 && !_list->getSelectedString().empty()) - thumb = _vm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem); - - if (thumb) { - _gfxWidget->setGfx(thumb); - _gfxWidget->useAlpha(256); - thumb->free(); - delete thumb; - } else { - _gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB); - } - - InfoStuff infos; - memset(&infos, 0, sizeof(InfoStuff)); - if (selItem >= 0 && !_list->getSelectedString().empty() - && _vm->loadInfosFromSlot(_saveMode ? selItem + 1 : selItem, &infos)) { - char buffer[32]; - snprintf(buffer, 32, "Date: %.2d.%.2d.%.4d", - (infos.date >> 24) & 0xFF, (infos.date >> 16) & 0xFF, - infos.date & 0xFFFF); - _date->setLabel(buffer); - - snprintf(buffer, 32, "Time: %.2d:%.2d", - (infos.time >> 8) & 0xFF, infos.time & 0xFF); - _time->setLabel(buffer); - - int minutes = infos.playtime / 60; - int hours = minutes / 60; - minutes %= 60; - - snprintf(buffer, 32, "Playtime: %.2d:%.2d", hours, minutes); - _playtime->setLabel(buffer); - } else { - _date->setLabel("No date saved"); - _time->setLabel("No time saved"); - _playtime->setLabel("No playtime saved"); - } - - if (redraw) { - _gfxWidget->draw(); - _date->draw(); - _time->draw(); - _playtime->draw(); - } -} - -#pragma mark - - -Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) { - // Get savegame descriptions - Common::StringList descriptions; - uint i = saveMode ? 1 : 0; //the autosave is on slot #0 - bool avail_saves[81]; - - scumm->listSavegames(avail_saves, ARRAYSIZE(avail_saves)); - for (; i < ARRAYSIZE(avail_saves); i++) { - Common::String name; - if (avail_saves[i]) - scumm->getSavegameName(i, name); - descriptions.push_back(name); - } - - return descriptions; -} - ScummMenuDialog::ScummMenuDialog(ScummEngine *scumm) : ScummDialog("ScummMain"), _vm(scumm) { @@ -457,8 +248,10 @@ ScummMenuDialog::ScummMenuDialog(ScummEngine *scumm) #ifndef DISABLE_HELP _helpDialog = new HelpDialog(scumm->_game); #endif - _saveDialog = new SaveLoadChooser("Save game:", "Save", true, scumm); - _loadDialog = new SaveLoadChooser("Load game:", "Load", false, scumm); + _saveDialog = new GUI::SaveLoadChooser("Save game:", "Save"); + _saveDialog->setSaveMode(true); + _loadDialog = new GUI::SaveLoadChooser("Load game:", "Load"); + _loadDialog->setSaveMode(false); } ScummMenuDialog::~ScummMenuDialog() { @@ -513,28 +306,34 @@ void ScummMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 da } void ScummMenuDialog::save() { - int idx; - _saveDialog->setList(generateSavegameList(_vm, true)); - idx = _saveDialog->runModal(); + Common::String gameId = ConfMan.get("gameid"); + + const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); + + int idx = _saveDialog->runModal(plugin, ConfMan.getActiveDomainName()); if (idx >= 0) { String result(_saveDialog->getResultString()); char buffer[20]; const char *str; if (result.empty()) { // If the user was lazy and entered no save name, come up with a default name. - sprintf(buffer, "Save %d", idx + 1); + sprintf(buffer, "Save %d", idx); str = buffer; } else str = result.c_str(); - _vm->requestSave(idx + 1, str); + _vm->requestSave(idx, str); close(); } } void ScummMenuDialog::load() { - int idx; - _loadDialog->setList(generateSavegameList(_vm, false)); - idx = _loadDialog->runModal(); + Common::String gameId = ConfMan.get("gameid"); + + const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); + + int idx = _loadDialog->runModal(plugin, ConfMan.getActiveDomainName()); if (idx >= 0) { _vm->requestLoad(idx); close(); diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h index 85b562ed67..644c028c5e 100644 --- a/engines/scumm/dialogs.h +++ b/engines/scumm/dialogs.h @@ -29,6 +29,7 @@ #include "gui/dialog.h" #include "gui/options.h" #include "gui/widget.h" +#include "gui/saveload.h" #include "scumm/detection.h" #ifndef DISABLE_HELP @@ -53,35 +54,6 @@ protected: typedef Common::String String; }; -class SaveLoadChooser : public GUI::Dialog { - typedef Common::String String; - typedef Common::StringList StringList; -protected: - bool _saveMode; - GUI::ListWidget *_list; - GUI::ButtonWidget *_chooseButton; - GUI::GraphicsWidget *_gfxWidget; - GUI::StaticTextWidget *_date; - GUI::StaticTextWidget *_time; - GUI::StaticTextWidget *_playtime; - GUI::ContainerWidget *_container; - ScummEngine *_vm; - - uint8 _fillR, _fillG, _fillB; - - void updateInfos(bool redraw); -public: - SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine); - ~SaveLoadChooser(); - - virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); - const String &getResultString() const; - void setList(const StringList& list); - int runModal(); - - virtual void reflowLayout(); -}; - class ScummMenuDialog : public ScummDialog { public: ScummMenuDialog(ScummEngine *scumm); @@ -99,8 +71,8 @@ protected: #ifndef DISABLE_HELP GUI::Dialog *_helpDialog; #endif - SaveLoadChooser *_saveDialog; - SaveLoadChooser *_loadDialog; + GUI::SaveLoadChooser *_saveDialog; + GUI::SaveLoadChooser *_loadDialog; GUI::ButtonWidget *_saveButton; diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index fa5d2011b0..fd298c2980 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -38,17 +38,17 @@ #ifdef USE_ARM_GFX_ASM extern "C" void asmDrawStripToScreen(int height, int width, void const* text, void const* src, byte* dst, int vsPitch, int vmScreenWidth, int textSurfacePitch); -extern "C" void asmCopy8Col(byte* dst, int dstPitch, const byte* src, int height); +extern "C" void asmCopy8Col(byte* dst, int dstPitch, const byte* src, int height, uint8 bitDepth); #endif /* USE_ARM_GFX_ASM */ namespace Scumm { -static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h); -static void fill(byte *dst, int dstPitch, byte color, int w, int h); +static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h, uint8 bitDepth); +static void fill(byte *dst, int dstPitch, uint16 color, int w, int h, uint8 bitDepth); #ifndef USE_ARM_GFX_ASM -static void copy8Col(byte *dst, int dstPitch, const byte *src, int height); +static void copy8Col(byte *dst, int dstPitch, const byte *src, int height, uint8 bitDepth); #endif -static void clear8Col(byte *dst, int dstPitch, int height); +static void clear8Col(byte *dst, int dstPitch, int height, uint8 bitDepth); static void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height); static void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h); @@ -231,6 +231,9 @@ GdiV2::~GdiV2() { free(_roomStrips); } +Gdi16Bit::Gdi16Bit(ScummEngine *vm) : Gdi(vm) { +} + void Gdi::init() { _numStrips = _vm->_screenWidth / 8; @@ -341,8 +344,8 @@ void ScummEngine::initVirtScreen(VirtScreenNumber slot, int top, int width, int vs->hasTwoBuffers = twobufs; vs->xstart = 0; vs->backBuf = NULL; - vs->bytesPerPixel = 1; - vs->pitch = width; + vs->bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1; + vs->pitch = width * vs->bytesPerPixel; if (_game.version >= 7) { // Increase the pitch by one; needed to accomodate the extra screen @@ -586,7 +589,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i vsPitch = _screenWidth * m - width * m; } else { - vsPitch = vs->pitch - width; + vsPitch = vs->pitch - width * vs->bytesPerPixel; } @@ -612,36 +615,49 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i #else // We blit four pixels at a time, for improved performance. const uint32 *src32 = (const uint32 *)src; - const uint32 *text32 = (const uint32 *)text; uint32 *dst32 = (uint32 *)_compositeBuf; vsPitch >>= 2; - const int textPitch = (_textSurface.pitch - width * m) >> 2; - for (int h = height * m; h > 0; --h) { - for (int w = width*m; w > 0; w-=4) { - uint32 temp = *text32++; - - // Generate a byte mask for those text pixels (bytes) with - // value CHARSET_MASK_TRANSPARENCY. In the end, each byte - // in mask will be either equal to 0x00 or 0xFF. - // Doing it this way avoids branches and bytewise operations, - // at the cost of readability ;). - uint32 mask = temp ^ CHARSET_MASK_TRANSPARENCY_32; - mask = (((mask & 0x7f7f7f7f) + 0x7f7f7f7f) | mask) & 0x80808080; - mask = ((mask >> 7) + 0x7f7f7f7f) ^ 0x80808080; - - // The following line is equivalent to this code: - // *dst32++ = (*src32++ & mask) | (temp & ~mask); - // However, some compilers can generate somewhat better - // machine code for this equivalent statement: - *dst32++ = ((temp ^ *src32++) & mask) ^ temp; + + if (_bitDepth == 2) { + // Sprites always seem to be used for subtitles in 16Bit color HE games, and not + // the charset renderer, so charset masking isn't required. + for (int h = height * m; h > 0; --h) { + for (int w = width * m; w > 0; w -= 4) { + *dst32++ = *src32++; + *dst32++ = *src32++; + } + src32 += vsPitch; + } + } else { + const uint32 *text32 = (const uint32 *)text; + const int textPitch = (_textSurface.pitch - width * m) >> 2; + for (int h = height * m; h > 0; --h) { + for (int w = width * m; w > 0; w -= 4) { + uint32 temp = *text32++; + + // Generate a byte mask for those text pixels (bytes) with + // value CHARSET_MASK_TRANSPARENCY. In the end, each byte + // in mask will be either equal to 0x00 or 0xFF. + // Doing it this way avoids branches and bytewise operations, + // at the cost of readability ;). + uint32 mask = temp ^ CHARSET_MASK_TRANSPARENCY_32; + mask = (((mask & 0x7f7f7f7f) + 0x7f7f7f7f) | mask) & 0x80808080; + mask = ((mask >> 7) + 0x7f7f7f7f) ^ 0x80808080; + + // The following line is equivalent to this code: + // *dst32++ = (*src32++ & mask) | (temp & ~mask); + // However, some compilers can generate somewhat better + // machine code for this equivalent statement: + *dst32++ = ((temp ^ *src32++) & mask) ^ temp; + } + src32 += vsPitch; + text32 += textPitch; } - src32 += vsPitch; - text32 += textPitch; } #endif src = _compositeBuf; - pitch = width; + pitch = width * vs->bytesPerPixel; if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height); @@ -768,8 +784,10 @@ void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *wid } void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) { - uint16 *dstL1 = (uint16 *)dst; - uint16 *dstL2 = (uint16 *)(dst + dstPitch); + /* dst and dstPitch should both be even. So the use of (void *) in + * the following casts to avoid the unnecessary warning is valid. */ + uint16 *dstL1 = (uint16 *)(void *)dst; + uint16 *dstL2 = (uint16 *)(void *)(dst + dstPitch); const int dstAdd = dstPitch - w; const int srcAdd = srcPitch - w; @@ -986,13 +1004,13 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) { return; if (vs->hasTwoBuffers && _currentRoom != 0 && isLightOn()) { - blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height); + blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height, vs->bytesPerPixel); if (vs->number == kMainVirtScreen && _charset->_hasMask) { byte *mask = (byte *)_textSurface.getBasePtr(rect.left, rect.top - _screenTop); - fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height); + fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height, _textSurface.bytesPerPixel); } } else { - fill(screenBuf, vs->pitch, backColor, width, height); + fill(screenBuf, vs->pitch, backColor, width, height, vs->bytesPerPixel); } } @@ -1021,7 +1039,7 @@ void ScummEngine::restoreCharsetBg() { if (vs->number != kMainVirtScreen) { // Restore from back buffer const byte *backBuf = vs->getBackPixels(0, 0); - blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h); + blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h, vs->bytesPerPixel); } } else { // Clear area @@ -1057,51 +1075,63 @@ byte *Gdi::getMaskBuffer(int x, int y, int z) { #pragma mark --- Misc --- #pragma mark - -static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) { +static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h, uint8 bitDepth) { assert(w > 0); assert(h > 0); assert(src != NULL); assert(dst != NULL); - if (w == srcPitch && w == dstPitch) { - memcpy(dst, src, w*h); + if ((w * bitDepth == srcPitch) && (w * bitDepth == dstPitch)) { + memcpy(dst, src, w * h * bitDepth); } else { do { - memcpy(dst, src, w); + memcpy(dst, src, w * bitDepth); dst += dstPitch; src += srcPitch; } while (--h); } } -static void fill(byte *dst, int dstPitch, byte color, int w, int h) { +static void fill(byte *dst, int dstPitch, uint16 color, int w, int h, uint8 bitDepth) { assert(h > 0); assert(dst != NULL); - if (w == dstPitch) { - memset(dst, color, w*h); - } else { + if (bitDepth == 2) { do { - memset(dst, color, w); + for (int i = 0; i < w; i++) + WRITE_UINT16(dst + i * 2, color); dst += dstPitch; } while (--h); + } else { + if (w == dstPitch) { + memset(dst, color, w * h); + } else { + do { + memset(dst, color, w); + dst += dstPitch; + } while (--h); + } } } #ifdef USE_ARM_GFX_ASM -#define copy8Col(A,B,C,D) asmCopy8Col(A,B,C,D) +#define copy8Col(A,B,C,D,E) asmCopy8Col(A,B,C,D,E) #else -static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) { +static void copy8Col(byte *dst, int dstPitch, const byte *src, int height, uint8 bitDepth) { do { #if defined(SCUMM_NEED_ALIGNMENT) - memcpy(dst, src, 8); + memcpy(dst, src, 8 * bitDepth); #else ((uint32 *)dst)[0] = ((const uint32 *)src)[0]; ((uint32 *)dst)[1] = ((const uint32 *)src)[1]; + if (bitDepth == 2) { + ((uint32 *)dst)[2] = ((const uint32 *)src)[2]; + ((uint32 *)dst)[3] = ((const uint32 *)src)[3]; + } #endif dst += dstPitch; src += dstPitch; @@ -1110,13 +1140,17 @@ static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) { #endif /* USE_ARM_GFX_ASM */ -static void clear8Col(byte *dst, int dstPitch, int height) { +static void clear8Col(byte *dst, int dstPitch, int height, uint8 bitDepth) { do { #if defined(SCUMM_NEED_ALIGNMENT) - memset(dst, 0, 8); + memset(dst, 0, 8 * bitDepth); #else ((uint32 *)dst)[0] = 0; ((uint32 *)dst)[1] = 0; + if (bitDepth == 2) { + ((uint32 *)dst)[2] = 0; + ((uint32 *)dst)[3] = 0; + } #endif dst += dstPitch; } while (--height); @@ -1181,41 +1215,41 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) { if (color == -1) { if (vs->number != kMainVirtScreen) error("can only copy bg to main window"); - blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height); + blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel); if (_charset->_hasMask) { byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop) * _textSurfaceMultiplier); - fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier); + fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); } } else if (_game.heversion >= 72) { // Flags are used for different methods in HE games uint32 flags = color; if ((flags & 0x2000) || (flags & 0x4000000)) { - blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height); + blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel); } else if ((flags & 0x4000) || (flags & 0x2000000)) { - blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height); + blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->bytesPerPixel); } else if ((flags & 0x8000) || (flags & 0x1000000)) { flags &= (flags & 0x1000000) ? 0xFFFFFF : 0x7FFF; - fill(backbuff, vs->pitch, flags, width, height); - fill(bgbuff, vs->pitch, flags, width, height); + fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); + fill(bgbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); } else { - fill(backbuff, vs->pitch, flags, width, height); + fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); } } else if (_game.heversion >= 60) { // Flags are used for different methods in HE games uint16 flags = color; if (flags & 0x2000) { - blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height); + blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel); } else if (flags & 0x4000) { - blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height); + blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->bytesPerPixel); } else if (flags & 0x8000) { flags &= 0x7FFF; - fill(backbuff, vs->pitch, flags, width, height); - fill(bgbuff, vs->pitch, flags, width, height); + fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); + fill(bgbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); } else { - fill(backbuff, vs->pitch, flags, width, height); + fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); } } else { - fill(backbuff, vs->pitch, color, width, height); + fill(backbuff, vs->pitch, color, width, height, vs->bytesPerPixel); } } @@ -1253,7 +1287,7 @@ void ScummEngine_v5::drawFlashlight() { _flashlight.y, _flashlight.y + _flashlight.h, USAGE_BIT_DIRTY); if (_flashlight.buffer) { - fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h); + fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h, vs->bytesPerPixel); } _flashlight.isDrawn = false; } @@ -1300,7 +1334,7 @@ void ScummEngine_v5::drawFlashlight() { _flashlight.buffer = vs->getPixels(_flashlight.x, _flashlight.y); bgbak = vs->getBackPixels(_flashlight.x, _flashlight.y); - blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h); + blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h, vs->bytesPerPixel); // Round the corners. To do so, we simply hard-code a set of nicely // rounded corners. @@ -1609,7 +1643,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const warning("Gdi::drawBitmap, strip drawn to %d below window bottom %d", y + height, vs->h); } - _vertStripNextInc = height * vs->pitch - 1; + _vertStripNextInc = height * vs->pitch - 1 * vs->bytesPerPixel; _objectMode = (flag & dbObjectMode) == dbObjectMode; prepareDrawBitmap(ptr, vs, x, y, width, height, stripnr, numstrip); @@ -1642,9 +1676,9 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const // In the case of a double buffered virtual screen, we draw to // the backbuffer, otherwise to the primary surface memory. if (vs->hasTwoBuffers) - dstPtr = vs->backBuf + y * vs->pitch + x * 8; + dstPtr = vs->backBuf + y * vs->pitch + (x * 8 * vs->bytesPerPixel); else - dstPtr = (byte *)vs->pixels + y * vs->pitch + x * 8; + dstPtr = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->bytesPerPixel); transpStrip = drawStrip(dstPtr, vs, x, y, width, height, stripnr, smap_ptr); @@ -1653,11 +1687,11 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const transpStrip = true; if (vs->hasTwoBuffers) { - byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + x * 8; + byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->bytesPerPixel); if (lightsOn) - copy8Col(frontBuf, vs->pitch, dstPtr, height); + copy8Col(frontBuf, vs->pitch, dstPtr, height, vs->bytesPerPixel); else - clear8Col(frontBuf, vs->pitch, height); + clear8Col(frontBuf, vs->pitch, height, vs->bytesPerPixel); } decodeMask(x, y, width, height, stripnr, numzbuf, zplane_list, transpStrip, flag, tmsk_ptr); @@ -1885,7 +1919,7 @@ void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) { drawStripHE(dst, vs->pitch, bmap_ptr, vs->w, vs->h, true); break; case 150: - fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h); + fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h, vs->bytesPerPixel); break; default: // Alternative russian freddi3 uses badly formatted bitmaps @@ -1941,12 +1975,12 @@ void Gdi::drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, assert(bmap_ptr); byte code = *bmap_ptr++; - int scrX = _vm->_screenStartStrip * 8; + int scrX = _vm->_screenStartStrip * 8 * _vm->_bitDepth; if (code == 8 || code == 9) { Common::Rect rScreen(0, 0, vs->w, vs->h); byte *dst = (byte *)_vm->_virtscr[kMainVirtScreen].backBuf + scrX; - Wiz::copyWizImage(dst, bmap_ptr, vs->w, vs->h, x - scrX, y, w, h, &rScreen); + Wiz::copyWizImage(dst, bmap_ptr, vs->pitch, kDstScreen, vs->w, vs->h, x - scrX, y, w, h, &rScreen, 0, 0, 0, _vm->_bitDepth); } Common::Rect rect1(x, y, x + w, y + h); @@ -1996,7 +2030,7 @@ void ScummEngine_v70he::restoreBackgroundHE(Common::Rect rect, int dirtybit) { assert(rw <= _screenWidth && rw > 0); assert(rh <= _screenHeight && rh > 0); - blit(dst, _virtscr[kMainVirtScreen].pitch, src, _virtscr[kMainVirtScreen].pitch, rw, rh); + blit(dst, _virtscr[kMainVirtScreen].pitch, src, _virtscr[kMainVirtScreen].pitch, rw, rh, vs->bytesPerPixel); markRectAsDirty(kMainVirtScreen, rect, dirtybit); } #endif @@ -2026,15 +2060,15 @@ void Gdi::resetBackground(int top, int bottom, int strip) { if (bottom > vs->bdirty[strip]) vs->bdirty[strip] = bottom; - bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8; - backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8; + bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->bytesPerPixel; + backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->bytesPerPixel; numLinesToProcess = bottom - top; if (numLinesToProcess) { if (_vm->isLightOn()) { - copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess); + copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess, vs->bytesPerPixel); } else { - clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess); + clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess, vs->bytesPerPixel); } } } @@ -2785,12 +2819,12 @@ void Gdi::drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int h int x = width; while (1) { if (!transpCheck || color != _transparentColor) - *dst = _roomPalette[color]; - dst++; + writeRoomColor(dst, color); + dst += _vm->_bitDepth; --x; if (x == 0) { x = width; - dst += dstPitch - width; + dst += dstPitch - width * _vm->_bitDepth; --height; if (height == 0) return; @@ -2874,8 +2908,8 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height, do { FILL_BITS; if (!transpCheck || color != _transparentColor) - *dst = _roomPalette[color] + _paletteMod; - dst++; + writeRoomColor(dst, color); + dst += _vm->_bitDepth; againPos: if (!READ_BIT) { @@ -2896,13 +2930,13 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height, do { if (!--x) { x = 8; - dst += dstPitch - 8; + dst += dstPitch - 8 * _vm->_bitDepth; if (!--height) return; } if (!transpCheck || color != _transparentColor) - *dst = _roomPalette[color] + _paletteMod; - dst++; + writeRoomColor(dst, color); + dst += _vm->_bitDepth; } while (--reps); bits >>= 8; bits |= (*src++) << (cl - 8); @@ -2910,7 +2944,7 @@ void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height, } } } while (--x); - dst += dstPitch - 8; + dst += dstPitch - 8 * _vm->_bitDepth; } while (--height); } @@ -2926,8 +2960,8 @@ void Gdi::drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height, do { FILL_BITS; if (!transpCheck || color != _transparentColor) - *dst = _roomPalette[color] + _paletteMod; - dst++; + writeRoomColor(dst, color); + dst += _vm->_bitDepth; if (!READ_BIT) { } else if (!READ_BIT) { FILL_BITS; @@ -2942,7 +2976,7 @@ void Gdi::drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height, color += inc; } } while (--x); - dst += dstPitch - 8; + dst += dstPitch - 8 * _vm->_bitDepth; } while (--height); } @@ -2959,7 +2993,7 @@ void Gdi::drawStripBasicV(byte *dst, int dstPitch, const byte *src, int height, do { FILL_BITS; if (!transpCheck || color != _transparentColor) - *dst = _roomPalette[color] + _paletteMod; + writeRoomColor(dst, color); dst += dstPitch; if (!READ_BIT) { } else if (!READ_BIT) { @@ -3027,7 +3061,7 @@ void Gdi::drawStripRaw(byte *dst, int dstPitch, const byte *src, int height, con for (x = 0; x < 8; x ++) { byte color = *src++; if (!transpCheck || color != _transparentColor) - dst[x] = _roomPalette[color] + _paletteMod; + writeRoomColor(dst + x * _vm->_bitDepth, color); } dst += dstPitch; } while (--height); @@ -3150,6 +3184,14 @@ void Gdi::unkDecode11(byte *dst, int dstPitch, const byte *src, int height) cons #undef NEXT_ROW #undef READ_BIT_256 +void Gdi16Bit::writeRoomColor(byte *dst, byte color) const { + WRITE_UINT16(dst, READ_LE_UINT16(_vm->_hePalettes + 2048 + color * 2)); +} + +void Gdi::writeRoomColor(byte *dst, byte color) const { + *dst = _roomPalette[color] + _paletteMod; +} + #pragma mark - #pragma mark --- Transition effects --- diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h index e4c1054450..0910d9bc59 100644 --- a/engines/scumm/gfx.h +++ b/engines/scumm/gfx.h @@ -155,11 +155,11 @@ struct VirtScreen : Graphics::Surface { } byte *getPixels(int x, int y) const { - return (byte *)pixels + xstart + y * pitch + x; + return (byte *)pixels + y * pitch + (xstart + x) * bytesPerPixel; } byte *getBackPixels(int x, int y) const { - return (byte *)backBuf + xstart + y * pitch + x; + return (byte *)backBuf + y * pitch + (xstart + x) * bytesPerPixel; } }; @@ -215,6 +215,7 @@ protected: void drawStrip3DO(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const; void drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int height, const bool transpCheck) const; + virtual void writeRoomColor(byte *dst, byte color) const; /* Mask decompressors */ void decompressTMSK(byte *dst, const byte *tmsk, const byte *src, int height) const; @@ -361,6 +362,13 @@ public: virtual void roomChanged(byte *roomptr); }; +class Gdi16Bit : public Gdi { +protected: + virtual void writeRoomColor(byte *dst, byte color) const; +public: + Gdi16Bit(ScummEngine *vm); +}; + } // End of namespace Scumm #endif diff --git a/engines/scumm/gfxARM.s b/engines/scumm/gfxARM.s index f3a1f20303..e78487d777 100644 --- a/engines/scumm/gfxARM.s +++ b/engines/scumm/gfxARM.s @@ -116,7 +116,8 @@ end: @ extern "C" void asmCopy8Col(byte *dst, @ int dstPitch, @ const byte *src, - @ int height); + @ int height, + @ uint8 bitdepth); @ @ In addition, we assume that src and dst are both word (4 byte) @ aligned. This is the same assumption that the old 'inline' version @@ -126,9 +127,13 @@ asmCopy8Col: @ r1 = dstPitch @ r2 = src @ r3 = height - STMFD r13!,{r14} - SUB r1,r1,#4 + @ <> = bitdepth (badly named, should be bytedepth, 1 or 2) + LDR r12,[r13] + STR r14,[r13,#-4]! + CMP r12,#1 + BNE copy8Col16 + SUB r1,r1,#4 TST r3,#1 ADDNE r3,r3,#1 BNE roll2 @@ -145,4 +150,33 @@ roll2: STR r14,[r0],r1 BNE yLoop2 - LDMFD r13!,{PC} + LDR PC,[r13],#4 + +copy8Col16: + STMFD r13!,{r4-r5} + SUB r1,r1,#12 + TST r3,#1 + ADDNE r3,r3,#1 + BNE roll3 +yLoop3: + LDR r4, [r2],#4 + LDR r5, [r2],#4 + LDR r12,[r2],#4 + LDR r14,[r2],r1 + STR r4, [r0],#4 + STR r5, [r0],#4 + STR r12,[r0],#4 + STR r14,[r0],r1 +roll3: + LDR r4, [r2],#4 + LDR r5, [r2],#4 + LDR r12,[r2],#4 + LDR r14,[r2],r1 + SUBS r3,r3,#2 + STR r4, [r0],#4 + STR r5, [r0],#4 + STR r12,[r0],#4 + STR r14,[r0],r1 + BNE yLoop3 + + LDMFD r13!,{r4,r5,PC} diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp index 2ca17161db..cf071fc4aa 100644 --- a/engines/scumm/he/animation_he.cpp +++ b/engines/scumm/he/animation_he.cpp @@ -66,6 +66,41 @@ int MoviePlayer::load(const char *filename, int flags, int image) { return 0; } +void MoviePlayer::copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint pitch) { + uint h = getHeight(); + uint w = getWidth(); + + byte *src = _videoFrameBuffer; + + if (_vm->_game.features & GF_16BIT_COLOR) { + dst += y * pitch + x * 2; + do { + for (uint i = 0; i < w; i++) { + uint16 color = READ_LE_UINT16(_vm->_hePalettes + _vm->_hePaletteSlot + 768 + src[i] * 2); + switch (dstType) { + case kDstScreen: + WRITE_UINT16(dst + i * 2, color); + break; + case kDstResource: + WRITE_LE_UINT16(dst + i * 2, color); + break; + default: + error("copyFrameToBuffer: Unknown dstType %d", dstType); + } + } + dst += pitch; + src += w; + } while (--h); + } else { + dst += y * pitch + x; + do { + memcpy(dst, src, w); + dst += pitch; + src += w; + } while (--h); + } +} + void MoviePlayer::handleNextFrame() { if (!isVideoLoaded()) { return; @@ -80,14 +115,14 @@ void MoviePlayer::handleNextFrame() { assert(dstPtr); uint8 *dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0); assert(dst); - copyFrameToBuffer(dst, 0, 0, _vm->_screenWidth); + copyFrameToBuffer(dst, kDstResource, 0, 0, _vm->_screenWidth * _vm->_bitDepth); } else if (_flags & 1) { - copyFrameToBuffer(pvs->getBackPixels(0, 0), 0, 0, _vm->_screenWidth); + copyFrameToBuffer(pvs->getBackPixels(0, 0), kDstScreen, 0, 0, pvs->pitch); Common::Rect imageRect(getWidth(), getHeight()); _vm->restoreBackgroundHE(imageRect); } else { - copyFrameToBuffer(pvs->getPixels(0, 0), 0, 0, _vm->_screenWidth); + copyFrameToBuffer(pvs->getPixels(0, 0), kDstScreen, 0, 0, pvs->pitch); Common::Rect imageRect(getWidth(), getHeight()); _vm->markRectAsDirty(kMainVirtScreen, imageRect); diff --git a/engines/scumm/he/animation_he.h b/engines/scumm/he/animation_he.h index cf5d054ead..86ded31940 100644 --- a/engines/scumm/he/animation_he.h +++ b/engines/scumm/he/animation_he.h @@ -54,6 +54,7 @@ public: int getImageNum(); int load(const char *filename, int flags, int image = 0); + void copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint pitch); void handleNextFrame(); protected: diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index 9e905b0e79..2f7f539ee3 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -458,6 +458,7 @@ protected: uint8 *getHEPaletteIndex(int palSlot); int getHEPaletteColor(int palSlot, int color); int getHEPaletteSimilarColor(int palSlot, int red, int green, int start, int end); + int getHEPalette16BitColorComponent(int component, int type); int getHEPaletteColorComponent(int palSlot, int color, int component); void setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b); void setHEPaletteFromPtr(int palSlot, const uint8 *palData); @@ -466,7 +467,7 @@ protected: void setHEPaletteFromRoom(int palSlot, int resId, int state); void restoreHEPalette(int palSlot); void copyHEPalette(int dstPalSlot, int srcPalSlot); - void copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor); + void copyHEPaletteColor(int palSlot, uint8 dstColor, uint16 srcColor); protected: /* HE version 90 script opcodes */ diff --git a/engines/scumm/he/palette_he.cpp b/engines/scumm/he/palette_he.cpp index 7fe04f223e..ff29f9ecd0 100644 --- a/engines/scumm/he/palette_he.cpp +++ b/engines/scumm/he/palette_he.cpp @@ -40,7 +40,7 @@ void ScummEngine_v71he::remapHEPalette(const uint8 *src, uint8 *dst) { src += 30; if (_game.heversion >= 99) { - palPtr = _hePalettes + 1024 + 30; + palPtr = _hePalettes + _hePaletteSlot + 30; } else { palPtr = _currentPalette + 30; } @@ -75,9 +75,9 @@ void ScummEngine_v71he::remapHEPalette(const uint8 *src, uint8 *dst) { uint8 *ScummEngine_v90he::getHEPaletteIndex(int palSlot) { if (palSlot) { assert(palSlot >= 1 && palSlot <= _numPalettes); - return _hePalettes + palSlot * 1024; + return _hePalettes + palSlot * _hePaletteSlot; } else { - return _hePalettes + 1024; + return _hePalettes + _hePaletteSlot; } } @@ -86,7 +86,7 @@ int ScummEngine_v90he::getHEPaletteSimilarColor(int palSlot, int red, int green, assertRange(0, start, 255, "start palette slot"); assertRange(0, end, 255, "pend alette slot"); - uint8 *pal = _hePalettes + palSlot * 1024 + start * 3; + uint8 *pal = _hePalettes + palSlot * _hePaletteSlot + start * 3; int bestsum = 0x7FFFFFFF; int bestitem = start; @@ -107,39 +107,83 @@ int ScummEngine_v90he::getHEPaletteSimilarColor(int palSlot, int red, int green, return bestitem; } +int ScummEngine_v90he::getHEPalette16BitColorComponent(int component, int type) { + uint16 col; + if (type == 2) { + col = (((component & 0xFFFF) >> 0) & 0x1F) << 3;; + } else if (type == 1) { + col = (((component & 0xFFFF) >> 5) & 0x1F) << 3; + } else { + col = (((component & 0xFFFF) >> 10) & 0x1F) << 3; + } + return col; +} + int ScummEngine_v90he::getHEPaletteColorComponent(int palSlot, int color, int component) { assertRange(1, palSlot, _numPalettes, "palette"); assertRange(0, color, 255, "palette slot"); - return _hePalettes[palSlot * 1024 + color * 3 + component % 3]; + return _hePalettes[palSlot * _hePaletteSlot + color * 3 + component % 3]; } int ScummEngine_v90he::getHEPaletteColor(int palSlot, int color) { assertRange(1, palSlot, _numPalettes, "palette"); assertRange(0, color, 255, "palette slot"); - return _hePalettes[palSlot * 1024 + 768 + color]; + if (_game.features & GF_16BIT_COLOR) + return READ_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + color * 2); + else + return _hePalettes[palSlot * _hePaletteSlot + 768 + color]; } void ScummEngine_v90he::setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b) { debug(7, "setHEPaletteColor(%d, %d, %d, %d, %d)", palSlot, color, r, g, b); assertRange(1, palSlot, _numPalettes, "palette"); - uint8 *p = _hePalettes + palSlot * 1024 + color * 3; + + uint8 *p = _hePalettes + palSlot * _hePaletteSlot + color * 3; *(p + 0) = r; *(p + 1) = g; *(p + 2) = b; - _hePalettes[palSlot * 1024 + 768 + color] = color; + if (_game.features & GF_16BIT_COLOR) { + WRITE_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + color * 2, get16BitColor(r, g, b)); + } else { + _hePalettes[palSlot * _hePaletteSlot + 768 + color] = color; + } } void ScummEngine_v90he::setHEPaletteFromPtr(int palSlot, const uint8 *palData) { assertRange(1, palSlot, _numPalettes, "palette"); - uint8 *pc = _hePalettes + palSlot * 1024; + + uint8 *pc = _hePalettes + palSlot * _hePaletteSlot; uint8 *pi = pc + 768; - for (int i = 0; i < 256; ++i) { - *pc++ = *palData++; - *pc++ = *palData++; - *pc++ = *palData++; - *pi++ = i; + if (_game.features & GF_16BIT_COLOR) { + for (int i = 0; i < 256; ++i) { + uint8 r = *pc++ = *palData++; + uint8 g = *pc++ = *palData++; + uint8 b = *pc++ = *palData++; + WRITE_LE_UINT16(pi, get16BitColor(r, g, b)); pi += 2; + } + } else { + for (int i = 0; i < 256; ++i) { + *pc++ = *palData++; + *pc++ = *palData++; + *pc++ = *palData++; + *pi++ = i; + } + } + + int i; + uint8 *palPtr = _hePalettes + palSlot * _hePaletteSlot + 768; + if (_game.features & GF_16BIT_COLOR) { + for (i = 0; i < 10; ++i) + WRITE_LE_UINT16(palPtr + i * 2, i); + for (i = 246; i < 256; ++i) + WRITE_LE_UINT16(palPtr + i * 2, i); + } else { + for (i = 0; i < 10; ++i) + *(palPtr + i) = i; + for (i = 246; i < 256; ++i) + *(palPtr + i) = i; } } @@ -178,8 +222,9 @@ void ScummEngine_v90he::setHEPaletteFromRoom(int palSlot, int resId, int state) void ScummEngine_v90he::restoreHEPalette(int palSlot) { debug(7, "restoreHEPalette(%d)", palSlot); assertRange(1, palSlot, _numPalettes, "palette"); + if (palSlot != 1) { - memcpy(_hePalettes + palSlot * 1024, _hePalettes + 1024, 1024); + memcpy(_hePalettes + palSlot * _hePaletteSlot, _hePalettes + _hePaletteSlot, _hePaletteSlot); } } @@ -187,18 +232,27 @@ void ScummEngine_v90he::copyHEPalette(int dstPalSlot, int srcPalSlot) { debug(7, "copyHEPalette(%d, %d)", dstPalSlot, srcPalSlot); assert(dstPalSlot >= 1 && dstPalSlot <= _numPalettes); assert(srcPalSlot >= 1 && srcPalSlot <= _numPalettes); + if (dstPalSlot != srcPalSlot) { - memcpy(_hePalettes + dstPalSlot * 1024, _hePalettes + srcPalSlot * 1024, 1024); + memcpy(_hePalettes + dstPalSlot * _hePaletteSlot, _hePalettes + srcPalSlot * _hePaletteSlot, _hePaletteSlot); } } -void ScummEngine_v90he::copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor) { +void ScummEngine_v90he::copyHEPaletteColor(int palSlot, uint8 dstColor, uint16 srcColor) { debug(7, "copyHEPaletteColor(%d, %d, %d)", palSlot, dstColor, srcColor); assertRange(1, palSlot, _numPalettes, "palette"); - uint8 *dstPal = _hePalettes + palSlot * 1024 + dstColor * 3; - uint8 *srcPal = _hePalettes + 1024 + srcColor * 3; - memcpy(dstPal, srcPal, 3); - _hePalettes[palSlot * 1024 + 768 + dstColor] = srcColor; + + uint8 *dstPal = _hePalettes + palSlot * _hePaletteSlot + dstColor * 3; + uint8 *srcPal = _hePalettes + _hePaletteSlot + srcColor * 3; + if (_game.features & GF_16BIT_COLOR) { + dstPal[0] = (srcColor >> 10) << 3; + dstPal[1] = (srcColor >> 5) << 3; + dstPal[2] = (srcColor >> 0) << 3; + WRITE_LE_UINT16(_hePalettes + palSlot * _hePaletteSlot + 768 + dstColor * 2, srcColor); + } else { + memcpy(dstPal, srcPal, 3); + _hePalettes[palSlot * _hePaletteSlot + 768 + dstColor] = srcColor; + } } void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) { @@ -211,7 +265,7 @@ void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) { assertRange(0, numcolor, 256, "setPaletteFromPtr: numcolor"); - dest = _hePalettes + 1024; + dest = _hePalettes + _hePaletteSlot; for (i = 0; i < numcolor; i++) { r = *ptr++; @@ -222,48 +276,63 @@ void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) { *dest++ = r; *dest++ = g; *dest++ = b; - _hePalettes[1792 + i] = i; + + if (_game.features & GF_16BIT_COLOR) { + WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, get16BitColor(r, g, b)); + } else { + _hePalettes[1792 + i] = i; + } } else { dest += 3; } } - memcpy(_hePalettes, _hePalettes + 1024, 768); - - for (i = 0; i < 10; ++i) - _hePalettes[1792 + i] = i; - for (i = 246; i < 256; ++i) - _hePalettes[1792 + i] = i; + memcpy(_hePalettes, _hePalettes + _hePaletteSlot, 768); + if (_game.features & GF_16BIT_COLOR) { + for (i = 0; i < 10; ++i) + WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, i); + for (i = 246; i < 256; ++i) + WRITE_LE_UINT16(_hePalettes + 2048 + i * 2, i); + } else { + for (i = 0; i < 10; ++i) + _hePalettes[1792 + i] = i; + for (i = 246; i < 256; ++i) + _hePalettes[1792 + i] = i; + } setDirtyColors(0, numcolor - 1); } void ScummEngine_v99he::darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor) { uint8 *src, *dst; - int color, j; + int j, r, g, b; src = _hePalettes + startColor * 3; - dst = _hePalettes + 1024 + startColor * 3; + dst = _hePalettes + _hePaletteSlot + startColor * 3; for (j = startColor; j <= endColor; j++) { - color = *src++; - color = color * redScale / 0xFF; - if (color > 255) - color = 255; - *dst++ = color; - - color = *src++; - color = color * greenScale / 0xFF; - if (color > 255) - color = 255; - *dst++ = color; - - color = *src++; - color = color * blueScale / 0xFF; - if (color > 255) - color = 255; - *dst++ = color; - - _hePalettes[1792 + j] = j; + r = *src++; + r = r * redScale / 0xFF; + if (r > 255) + r = 255; + *dst++ = r; + + g = *src++; + g = g * greenScale / 0xFF; + if (g > 255) + g = 255; + *dst++ = g; + + b = *src++; + b = b * blueScale / 0xFF; + if (b > 255) + b = 255; + *dst++ = b; + + if (_game.features & GF_16BIT_COLOR) { + WRITE_LE_UINT16(_hePalettes + 2048 + j * 2, get16BitColor(r, g, b)); + } else { + _hePalettes[1792 + j] = j; + } setDirtyColors(j, endColor); } } @@ -274,26 +343,39 @@ void ScummEngine_v99he::copyPalColor(int dst, int src) { if ((uint) dst >= 256 || (uint) src >= 256) error("copyPalColor: invalid values, %d, %d", dst, src); - dp = &_hePalettes[1024 + dst * 3]; - sp = &_hePalettes[1024 + src * 3]; + dp = &_hePalettes[_hePaletteSlot + dst * 3]; + sp = &_hePalettes[_hePaletteSlot + src * 3]; dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2]; - _hePalettes[1792 + dst] = dst; + + if (_game.features & GF_16BIT_COLOR) { + WRITE_LE_UINT16(_hePalettes + 2048 + dst * 2, get16BitColor(sp[0], sp[1], sp[2])); + } else { + _hePalettes[1792 + dst] = dst; + } setDirtyColors(dst, dst); } void ScummEngine_v99he::setPalColor(int idx, int r, int g, int b) { - _hePalettes[1024 + idx * 3 + 0] = r; - _hePalettes[1024 + idx * 3 + 1] = g; - _hePalettes[1024 + idx * 3 + 2] = b; - _hePalettes[1792 + idx] = idx; + _hePalettes[_hePaletteSlot + idx * 3 + 0] = r; + _hePalettes[_hePaletteSlot + idx * 3 + 1] = g; + _hePalettes[_hePaletteSlot + idx * 3 + 2] = b; + + if (_game.features & GF_16BIT_COLOR) { + WRITE_LE_UINT16(_hePalettes + 2048 + idx * 2, get16BitColor(r, g, b)); + } else { + _hePalettes[1792 + idx] = idx; + } setDirtyColors(idx, idx); } void ScummEngine_v99he::updatePalette() { + if (_game.features & GF_16BIT_COLOR) + return; + if (_palDirtyMax == -1) return; diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index 44a38401ce..29f611a58f 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -629,6 +629,7 @@ void ScummEngine_v100he::o100_arrayOps() { } break; case 132: + debug(0, "o100_arrayOps: case 132"); // TODO: Used by Moonbase Commander fetchScriptWord(); fetchScriptWord(); @@ -1576,7 +1577,10 @@ void ScummEngine_v100he::o100_roomOps() { case 130: a = pop(); b = pop(); - copyPalColor(a, b); + if (_game.features & GF_16BIT_COLOR) + copyHEPaletteColor(1, a, b); + else + copyPalColor(a, b); break; case 131: // SO_ROOM_FADE @@ -2153,8 +2157,9 @@ void ScummEngine_v100he::o100_systemOps() { } void ScummEngine_v100he::o100_cursorCommand() { - int a, i; + int a, b, i; int args[16]; + byte subOp = fetchScriptByte(); switch (subOp) { @@ -2169,12 +2174,12 @@ void ScummEngine_v100he::o100_cursorCommand() { case 0x80: case 0x81: a = pop(); - _wiz->loadWizCursor(a); + _wiz->loadWizCursor(a, 0); break; case 0x82: - pop(); + b = pop(); a = pop(); - _wiz->loadWizCursor(a); + _wiz->loadWizCursor(a, b); break; case 0x86: // SO_CURSOR_ON Turn cursor on _cursor.state = 1; @@ -2577,7 +2582,8 @@ void ScummEngine_v100he::o100_getWizData() { } void ScummEngine_v100he::o100_getPaletteData() { - int b, c, d, e; + int c, d, e; + int r, g, b; int palSlot, color; byte subOp = fetchScriptByte(); @@ -2586,7 +2592,10 @@ void ScummEngine_v100he::o100_getPaletteData() { case 13: c = pop(); b = pop(); - push(getHEPaletteColorComponent(1, b, c)); + if (_game.features & GF_16BIT_COLOR) + push(getHEPalette16BitColorComponent(b, c)); + else + push(getHEPaletteColorComponent(1, b, c)); break; case 20: color = pop(); @@ -2597,20 +2606,26 @@ void ScummEngine_v100he::o100_getPaletteData() { e = pop(); d = pop(); palSlot = pop(); - pop(); - c = pop(); b = pop(); - push(getHEPaletteSimilarColor(palSlot, b, c, d, e)); + g = pop(); + r = pop(); + push(getHEPaletteSimilarColor(palSlot, r, g, d, e)); break; case 53: - pop(); - c = pop(); - c = MAX(0, c); - c = MIN(c, 255); b = pop(); b = MAX(0, b); b = MIN(b, 255); - push(getHEPaletteSimilarColor(1, b, c, 10, 245)); + g = pop(); + g = MAX(0, g); + g = MIN(g, 255); + r = pop(); + r = MAX(0, r); + r = MIN(r, 255); + if (_game.features & GF_16BIT_COLOR) { + push(get16BitColor(r, g, b)); + } else { + push(getHEPaletteSimilarColor(1, r, g, 10, 245)); + } break; case 73: c = pop(); diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp index 7c109b1dcd..4c01d3b15c 100644 --- a/engines/scumm/he/script_v60he.cpp +++ b/engines/scumm/he/script_v60he.cpp @@ -98,6 +98,13 @@ int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) { int len = resStrLen(dst); if (_game.platform == Common::kPlatformMacintosh) { + // Remove : prefix in HE71 games + if (dst[0] == ':') { + len -= 1; + memmove(dst, dst + 1, len); + dst[len] = 0; + } + // Switch all : to / for portablity for (int i = 0; i < len; i++) { if (dst[i] == ':') @@ -122,6 +129,8 @@ int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) { } else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path // The default game data path is set to './' by ScummVM r = 2; + } else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI + r = 13; } else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (HE72 - HE100) // The default save game path is set to '*/' by ScummVM r = 2; diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp index 1d73f0da76..3dd70a09c9 100644 --- a/engines/scumm/he/script_v72he.cpp +++ b/engines/scumm/he/script_v72he.cpp @@ -1398,11 +1398,6 @@ void ScummEngine_v72he::o72_openFile() { copyScriptString(buffer, sizeof(buffer)); debug(1, "Original filename %s", buffer); - // HACK: INI filename seems to get reset, corruption elsewhere? - if (_game.id == GID_MOONBASE && buffer[0] == 0) { - strcpy((char *)buffer, "moonbase.ini"); - } - const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer)); debug(1, "Final filename to %s", filename); @@ -1484,6 +1479,7 @@ void ScummEngine_v72he::o72_readFile() { fetchScriptByte(); size = pop(); slot = pop(); + assert(_hInFileTable[slot]); val = readFileToArray(slot, size); push(val); break; @@ -1573,7 +1569,7 @@ void ScummEngine_v72he::o72_rename() { } void ScummEngine_v72he::o72_getPixel() { - byte area; + uint16 area; int y = pop(); int x = pop(); @@ -1588,11 +1584,17 @@ void ScummEngine_v72he::o72_getPixel() { switch (subOp) { case 9: // HE 100 case 218: - area = *vs->getBackPixels(x, y - vs->topline); + if (_game.features & GF_16BIT_COLOR) + area = READ_UINT16(vs->getBackPixels(x, y - vs->topline)); + else + area = *vs->getBackPixels(x, y - vs->topline); break; case 8: // HE 100 case 219: - area = *vs->getPixels(x, y - vs->topline); + if (_game.features & GF_16BIT_COLOR) + area = READ_UINT16(vs->getPixels(x, y - vs->topline)); + else + area = *vs->getPixels(x, y - vs->topline); break; default: error("o72_getPixel: default case %d", subOp); @@ -1805,9 +1807,7 @@ void ScummEngine_v72he::o72_readINI() { switch (subOp) { case 43: // HE 100 case 6: // number - if (!strcmp((char *)option, "NoFontsInstalled")) { - push(1); - } else if (!strcmp((char *)option, "NoPrinting")) { + if (!strcmp((char *)option, "NoPrinting")) { push(1); } else if (!strcmp((char *)option, "TextOn")) { push(ConfMan.getBool("subtitles")); @@ -1818,7 +1818,12 @@ void ScummEngine_v72he::o72_readINI() { case 77: // HE 100 case 7: // string writeVar(0, 0); - if (!strcmp((char *)option, "SaveGamePath")) { + if (!strcmp((char *)option, "HE3File")) { + Common::String fileName = generateFilename(-3); + int len = resStrLen((const byte *)fileName.c_str()); + data = defineArray(0, kStringArray, 0, 0, 0, len); + memcpy(data, fileName.c_str(), len); + } else if (!strcmp((char *)option, "SaveGamePath")) { // We set SaveGamePath in order to detect where it used // in convertFilePath and to avoid warning about invalid // path in Macintosh verisons. diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp index 5b10944899..dd44180fa0 100644 --- a/engines/scumm/he/script_v80he.cpp +++ b/engines/scumm/he/script_v80he.cpp @@ -243,7 +243,7 @@ void ScummEngine_v80he::o80_writeConfigFile() { } void ScummEngine_v80he::o80_cursorCommand() { - int a, i; + int a, b, i; int args[16]; byte subOp = fetchScriptByte(); @@ -252,12 +252,12 @@ void ScummEngine_v80he::o80_cursorCommand() { case 0x13: case 0x14: a = pop(); - _wiz->loadWizCursor(a); + _wiz->loadWizCursor(a, 0); break; case 0x3C: - pop(); + b = pop(); a = pop(); - _wiz->loadWizCursor(a); + _wiz->loadWizCursor(a, b); break; case 0x90: // SO_CURSOR_ON Turn cursor on _cursor.state = 1; diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp index be20a229f0..e302af1144 100644 --- a/engines/scumm/he/script_v90he.cpp +++ b/engines/scumm/he/script_v90he.cpp @@ -1255,7 +1255,7 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() { void ScummEngine_v90he::o90_getWizData() { byte filename[4096]; - int state, resId; + int resId, state, type; int32 w, h; int32 x, y; @@ -1319,9 +1319,10 @@ void ScummEngine_v90he::o90_getWizData() { push(computeWizHistogram(resId, state, x, y, w, h)); break; case 139: - pop(); - pop(); - push(0); + type = pop(); + state = pop(); + resId = pop(); + push(_wiz->getWizImageData(resId, state, type)); break; case 141: pop(); @@ -2101,7 +2102,8 @@ void ScummEngine_v90he::o90_getObjectData() { } void ScummEngine_v90he::o90_getPaletteData() { - int b, c, d, e; + int c, d, e; + int r, g, b; int palSlot, color; byte subOp = fetchScriptByte(); @@ -2111,10 +2113,10 @@ void ScummEngine_v90he::o90_getPaletteData() { e = pop(); d = pop(); palSlot = pop(); - pop(); - c = pop(); b = pop(); - push(getHEPaletteSimilarColor(palSlot, b, c, d, e)); + g = pop(); + r = pop(); + push(getHEPaletteSimilarColor(palSlot, r, g, d, e)); break; case 52: c = pop(); @@ -2130,17 +2132,27 @@ void ScummEngine_v90he::o90_getPaletteData() { case 132: c = pop(); b = pop(); - push(getHEPaletteColorComponent(1, b, c)); + if (_game.features & GF_16BIT_COLOR) + push(getHEPalette16BitColorComponent(b, c)); + else + push(getHEPaletteColorComponent(1, b, c)); break; case 217: - pop(); - c = pop(); - c = MAX(0, c); - c = MIN(c, 255); b = pop(); b = MAX(0, b); b = MIN(b, 255); - push(getHEPaletteSimilarColor(1, b, c, 10, 245)); + g = pop(); + g = MAX(0, g); + g = MIN(g, 255); + r = pop(); + r = MAX(0, r); + r = MIN(r, 255); + + if (_game.features & GF_16BIT_COLOR) { + push(get16BitColor(r, g, b)); + } else { + push(getHEPaletteSimilarColor(1, r, g, 10, 245)); + } break; default: error("o90_getPaletteData: Unknown case %d", subOp); diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp index 01f29d5db9..477f3cf0ad 100644 --- a/engines/scumm/he/sound_he.cpp +++ b/engines/scumm/he/sound_he.cpp @@ -645,7 +645,11 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) Audio::AudioStream *voxStream = Audio::makeADPCMStream(&stream, false, size, Audio::kADPCMMSIma, rate, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign); sound = (char *)malloc(size * 4); - size = voxStream->readBuffer((int16*)sound, size * 2); + /* On systems where it matters, malloc will return + * even addresses, so the use of (void *) in the + * following cast shuts the compiler from warning + * unnecessarily. */ + size = voxStream->readBuffer((int16*)(void *)sound, size * 2); size *= 2; // 16bits. delete voxStream; diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index 549877090c..9ddc1ea22f 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -40,6 +40,7 @@ Wiz::Wiz(ScummEngine_v71he *vm) : _vm(vm) { _imagesNum = 0; memset(&_images, 0, sizeof(_images)); memset(&_polygons, 0, sizeof(_polygons)); + _cursorImage = false; _rectOverrideEnabled = false; } @@ -254,7 +255,9 @@ bool Wiz::polygonContains(const WizPolygon &pol, int x, int y) { return r; } -void Wiz::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch) { +void Wiz::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, uint8 bitDepth) { + assert(bitDepth == 1); + Common::Rect dstRect(srcx, srcy, srcx + srcw, srcy + srch); dstRect.clip(dstw, dsth); @@ -263,8 +266,8 @@ void Wiz::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int if (rh <= 0 || rw <= 0) return; - uint8 *dst1Ptr = dst1 + dstRect.left + dstRect.top * dstw; - uint8 *dst2Ptr = dst2 + dstRect.left + dstRect.top * dstw; + uint8 *dst1Ptr = dst1 + dstRect.top * dstw + dstRect.left; + uint8 *dst2Ptr = dst2 + dstRect.top * dstw + dstRect.left; const uint8 *dataPtr = src; while (rh--) { @@ -353,12 +356,25 @@ static bool calcClipRects(int dst_w, int dst_h, int src_x, int src_y, int src_w, return srcRect.isValidRect() && dstRect.isValidRect(); } -void Wiz::copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) { - // TODO: Compressed 16 bits in 555 format +void Wiz::writeColor(uint8 *dstPtr, int dstType, uint16 color) { + switch (dstType) { + case kDstScreen: + WRITE_UINT16(dstPtr, color); + break; + case kDstMemory: + case kDstResource: + WRITE_LE_UINT16(dstPtr, color); + break; + default: + error("writeColor: Unknown dstType %d", dstType); + } +} +#ifdef USE_RGB_COLOR +void Wiz::copy16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *xmapPtr) { Common::Rect r1, r2; if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) { - dst += r2.top * dstw + r2.left; + dst += r2.top * dstPitch + r2.left * 2; if (flags & kWIFFlipY) { const int dy = (srcy < 0) ? srcy : (srch - r1.height()); r1.translate(0, dy); @@ -368,17 +384,18 @@ void Wiz::copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, in r1.translate(dx, 0); } if (xmapPtr) { - decompress16BitWizImage<kWizXMap>(dst, dstw, src, r1, flags, palPtr, xmapPtr); + decompress16BitWizImage<kWizXMap>(dst, dstPitch, dstType, src, r1, flags, xmapPtr); } else { - decompress16BitWizImage<kWizCopy>(dst, dstw, src, r1, flags); + decompress16BitWizImage<kWizCopy>(dst, dstPitch, dstType, src, r1, flags); } } } +#endif -void Wiz::copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) { +void Wiz::copyWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth) { Common::Rect r1, r2; if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) { - dst += r2.left + r2.top * dstw; + dst += r2.top * dstPitch + r2.left * bitDepth; if (flags & kWIFFlipY) { const int dy = (srcy < 0) ? srcy : (srch - r1.height()); r1.translate(0, dy); @@ -388,11 +405,11 @@ void Wiz::copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int src r1.translate(dx, 0); } if (xmapPtr) { - decompressWizImage<kWizXMap>(dst, dstw, src, r1, flags, palPtr, xmapPtr); + decompressWizImage<kWizXMap>(dst, dstPitch, dstType, src, r1, flags, palPtr, xmapPtr, bitDepth); } else if (palPtr) { - decompressWizImage<kWizRMap>(dst, dstw, src, r1, flags, palPtr); + decompressWizImage<kWizRMap>(dst, dstPitch, dstType, src, r1, flags, palPtr, NULL, bitDepth); } else { - decompressWizImage<kWizCopy>(dst, dstw, src, r1, flags); + decompressWizImage<kWizCopy>(dst, dstPitch, dstType, src, r1, flags, NULL, NULL, bitDepth); } } } @@ -431,13 +448,102 @@ static void decodeWizMask(uint8 *&dst, uint8 &mask, int w, int maskType) { } } -void Wiz::copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP) { +#ifdef USE_RGB_COLOR +void Wiz::copyMaskWizImage(uint8 *dst, const uint8 *src, const uint8 *mask, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr) { + Common::Rect srcRect, dstRect; + if (!calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, srcRect, dstRect)) { + return; + } + dst += dstRect.top * dstPitch + dstRect.left * 2; + if (flags & kWIFFlipY) { + const int dy = (srcy < 0) ? srcy : (srch - srcRect.height()); + srcRect.translate(0, dy); + } + if (flags & kWIFFlipX) { + const int dx = (srcx < 0) ? srcx : (srcw - srcRect.width()); + srcRect.translate(dx, 0); + } + + const uint8 *dataPtr, *dataPtrNext; + const uint8 *maskPtr, *maskPtrNext; + uint8 code, *dstPtr, *dstPtrNext; + int h, w, dstInc; + + dataPtr = src; + dstPtr = dst; + maskPtr = mask; + + // Skip over the first 'srcRect->top' lines in the data + dataPtr += dstRect.top * dstPitch + dstRect.left * 2; + + h = dstRect.height(); + w = dstRect.width(); + if (h <= 0 || w <= 0) + return; + + dstInc = 2; + if (flags & kWIFFlipX) { + dstPtr += (w - 1) * 2; + dstInc = -2; + } + + while (h--) { + w = dstRect.width(); + uint16 lineSize = READ_LE_UINT16(maskPtr); maskPtr += 2; + dataPtrNext = dataPtr + dstPitch; + dstPtrNext = dstPtr + dstPitch; + maskPtrNext = maskPtr + lineSize; + if (lineSize != 0) { + while (w > 0) { + code = *maskPtr++; + if (code & 1) { + code >>= 1; + dataPtr += dstInc * code; + dstPtr += dstInc * code; + w -= code; + } else if (code & 2) { + code = (code >> 2) + 1; + w -= code; + if (w < 0) { + code += w; + } + while (code--) { + if (*maskPtr != 5) + write16BitColor<kWizCopy>(dstPtr, dataPtr, dstType, palPtr); + dataPtr += 2; + dstPtr += dstInc; + } + maskPtr++; + } else { + code = (code >> 2) + 1; + w -= code; + if (w < 0) { + code += w; + } + while (code--) { + if (*maskPtr != 5) + write16BitColor<kWizCopy>(dstPtr, dataPtr, dstType, palPtr); + dataPtr += 2; + dstPtr += dstInc; + maskPtr++; + } + } + } + } + dataPtr = dataPtrNext; + dstPtr = dstPtrNext; + maskPtr = maskPtrNext; + } +} +#endif + +void Wiz::copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstPitch, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP) { Common::Rect srcRect, dstRect; if (!calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, srcRect, dstRect)) { return; } - dstw = dstw / 8; - dst += dstRect.top * dstw + dstRect.left / 8; + dstPitch /= 8; + dst += dstRect.top * dstPitch + dstRect.left / 8; const uint8 *dataPtr, *dataPtrNext; uint8 code, mask, *dstPtr, *dstPtrNext; @@ -462,7 +568,7 @@ void Wiz::copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth, w = srcRect.width(); mask = revBitMask(dstRect.left & 7); off = READ_LE_UINT16(dataPtr); dataPtr += 2; - dstPtrNext = dstPtr + dstw; + dstPtrNext = dstPtr + dstPitch; dataPtrNext = dataPtr + off; if (off != 0) { while (w > 0) { @@ -520,7 +626,8 @@ void Wiz::copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth, } } -void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor) { +#ifdef USE_RGB_COLOR +void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, int transColor) { Common::Rect r1, r2; if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) { if (flags & kWIFFlipX) { @@ -537,19 +644,23 @@ void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int } int h = r1.height(); int w = r1.width(); - src += r1.left + r1.top * srcw; - dst += r2.left + r2.top * dstw; - if (palPtr) { - decompressRawWizImage<kWizRMap>(dst, dstw, src, srcw, w, h, transColor, palPtr); - } else { - decompressRawWizImage<kWizCopy>(dst, dstw, src, srcw, w, h, transColor); + src += (r1.top * srcw + r1.left) * 2; + dst += r2.top * dstPitch + r2.left * 2; + while (h--) { + for (int i = 0; i < w; ++ i) { + uint16 col = READ_LE_UINT16(src + 2 * i); + if (transColor == -1 || transColor != col) { + writeColor(dst + i * 2, dstType, col); + } + } + src += srcw * 2; + dst += dstPitch; } } } +#endif -void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor) { - // TODO: RAW 16 bits in 555 format - +void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor, uint8 bitDepth) { Common::Rect r1, r2; if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) { if (flags & kWIFFlipX) { @@ -566,38 +677,41 @@ void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, } int h = r1.height(); int w = r1.width(); - src += (r1.top * srcw + r1.left) * 2; - dst += r2.top * dstw + r2.left; - while (h--) { - for (int i = 0; i < w; ++i) { - uint16 col = READ_LE_UINT16(src + 2 * i); - uint8 r = ((col >> 10) & 0x1F) << 3; - uint8 g = ((col >> 5) & 0x1F) << 3; - uint8 b = ((col >> 0) & 0x1F) << 3; - uint8 color = _vm->convert16BitColor(col, r, g, b); - - if (transColor == -1 || transColor != col) { - dst[i] = color; - } - } - src += srcw * 2; - dst += dstw; + src += r1.top * srcw + r1.left; + dst += r2.top * dstPitch + r2.left * bitDepth; + if (palPtr) { + decompressRawWizImage<kWizRMap>(dst, dstPitch, dstType, src, srcw, w, h, transColor, palPtr, bitDepth); + } else { + decompressRawWizImage<kWizCopy>(dst, dstPitch, dstType, src, srcw, w, h, transColor, NULL, bitDepth); } } } +#ifdef USE_RGB_COLOR template <int type> -void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) { +void Wiz::write16BitColor(uint8 *dstPtr, const uint8 *dataPtr, int dstType, const uint8 *xmapPtr) { + uint16 col = READ_LE_UINT16(dataPtr); + if (type == kWizXMap) { + uint16 srcColor = (col >> 1) & 0x7DEF; + uint16 dstColor = (READ_UINT16(dstPtr) >> 1) & 0x7DEF; + uint16 newColor = srcColor + dstColor; + writeColor(dstPtr, dstType, newColor); + } + if (type == kWizCopy) { + writeColor(dstPtr, dstType, col); + } +} + +template <int type> +void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *xmapPtr) { const uint8 *dataPtr, *dataPtrNext; - uint8 code, *dstPtr, *dstPtrNext; + uint8 code; + uint8 *dstPtr, *dstPtrNext; int h, w, xoff, dstInc; if (type == kWizXMap) { assert(xmapPtr != 0); } - if (type == kWizRMap) { - assert(palPtr != 0); - } dstPtr = dst; dataPtr = src; @@ -616,10 +730,10 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co dstPtr += (h - 1) * dstPitch; dstPitch = -dstPitch; } - dstInc = 1; + dstInc = 2; if (flags & kWIFFlipX) { - dstPtr += w - 1; - dstInc = -1; + dstPtr += (w - 1) * 2; + dstInc = -2; } while (h--) { @@ -658,21 +772,10 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co code += w; } while (code--) { - uint16 col = READ_LE_UINT16(dataPtr); - uint8 r = ((col >> 10) & 0x1F) << 3; - uint8 g = ((col >> 5) & 0x1F) << 3; - uint8 b = ((col >> 0) & 0x1F) << 3; - col = _vm->convert16BitColor(col, r, g, b); - - if (type == kWizXMap) { - *dstPtr = xmapPtr[col * 256 + *dstPtr]; - } - if (type == kWizCopy) { - *dstPtr = col; - } + write16BitColor<type>(dstPtr, dataPtr, dstType, xmapPtr); dstPtr += dstInc; } - dataPtr+= 2; + dataPtr += 2; } else { code = (code >> 2) + 1; if (xoff > 0) { @@ -689,18 +792,7 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co code += w; } while (code--) { - uint16 col = READ_LE_UINT16(dataPtr); - uint8 r = ((col >> 10) & 0x1F) << 3; - uint8 g = ((col >> 5) & 0x1F) << 3; - uint8 b = ((col >> 0) & 0x1F) << 3; - col = _vm->convert16BitColor(col, r, g, b); - - if (type == kWizXMap) { - *dstPtr = xmapPtr[col * 256 + *dstPtr]; - } - if (type == kWizCopy) { - *dstPtr = col; - } + write16BitColor<type>(dstPtr, dataPtr, dstType, xmapPtr); dataPtr += 2; dstPtr += dstInc; } @@ -711,9 +803,39 @@ void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, co dstPtr = dstPtrNext; } } +#endif template <int type> -void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) { +void Wiz::write8BitColor(uint8 *dstPtr, const uint8 *dataPtr, int dstType, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth) { + if (bitDepth == 2) { + if (type == kWizXMap) { + uint16 color = READ_LE_UINT16(palPtr + *dataPtr * 2); + uint16 srcColor = (color >> 1) & 0x7DEF; + uint16 dstColor = (READ_UINT16(dstPtr) >> 1) & 0x7DEF; + uint16 newColor = srcColor + dstColor; + writeColor(dstPtr, dstType, newColor); + } + if (type == kWizRMap) { + writeColor(dstPtr, dstType, READ_LE_UINT16(palPtr + *dataPtr * 2)); + } + if (type == kWizCopy) { + writeColor(dstPtr, dstType, *dataPtr); + } + } else { + if (type == kWizXMap) { + *dstPtr = xmapPtr[*dataPtr * 256 + *dstPtr]; + } + if (type == kWizRMap) { + *dstPtr = palPtr[*dataPtr]; + } + if (type == kWizCopy) { + *dstPtr = *dataPtr; + } + } +} + +template <int type> +void Wiz::decompressWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth) { const uint8 *dataPtr, *dataPtrNext; uint8 code, *dstPtr, *dstPtrNext; int h, w, xoff, dstInc; @@ -742,10 +864,10 @@ void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const C dstPtr += (h - 1) * dstPitch; dstPitch = -dstPitch; } - dstInc = 1; + dstInc = bitDepth; if (flags & kWIFFlipX) { - dstPtr += w - 1; - dstInc = -1; + dstPtr += (w - 1) * bitDepth; + dstInc = -bitDepth; } while (h--) { @@ -784,15 +906,7 @@ void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const C code += w; } while (code--) { - if (type == kWizXMap) { - *dstPtr = xmapPtr[*dataPtr * 256 + *dstPtr]; - } - if (type == kWizRMap) { - *dstPtr = palPtr[*dataPtr]; - } - if (type == kWizCopy) { - *dstPtr = *dataPtr; - } + write8BitColor<type>(dstPtr, dataPtr, dstType, palPtr, xmapPtr, bitDepth); dstPtr += dstInc; } dataPtr++; @@ -812,15 +926,8 @@ void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const C code += w; } while (code--) { - if (type == kWizXMap) { - *dstPtr = xmapPtr[*dataPtr++ * 256 + *dstPtr]; - } - if (type == kWizRMap) { - *dstPtr = palPtr[*dataPtr++]; - } - if (type == kWizCopy) { - *dstPtr = *dataPtr++; - } + write8BitColor<type>(dstPtr, dataPtr, dstType, palPtr, xmapPtr, bitDepth); + dataPtr++; dstPtr += dstInc; } } @@ -832,12 +939,12 @@ void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const C } // NOTE: These templates are used outside this file. We don't want the compiler to optimize them away, so we need to explicitely instantiate them. -template void Wiz::decompressWizImage<kWizXMap>(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr); -template void Wiz::decompressWizImage<kWizRMap>(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr); -template void Wiz::decompressWizImage<kWizCopy>(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr); +template void Wiz::decompressWizImage<kWizXMap>(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth); +template void Wiz::decompressWizImage<kWizRMap>(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth); +template void Wiz::decompressWizImage<kWizCopy>(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth); template <int type> -void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr) { +void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr, uint8 bitDepth) { if (type == kWizRMap) { assert(palPtr != 0); } @@ -850,10 +957,18 @@ void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int uint8 col = src[i]; if (transColor == -1 || transColor != col) { if (type == kWizRMap) { - dst[i] = palPtr[col]; + if (bitDepth == 2) { + writeColor(dst + i * 2, dstType, READ_LE_UINT16(palPtr + col * 2)); + } else { + dst[i] = palPtr[col]; + } } if (type == kWizCopy) { - dst[i] = col; + if (bitDepth == 2) { + writeColor(dst + i * 2, dstType, col); + } else { + dst[i] = col; + } } } } @@ -943,7 +1058,7 @@ uint16 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint } if (bitDepth == 2) - return (READ_LE_UINT16(data) & 1) ? color : READ_LE_UINT16(data + 1); + return (READ_LE_UINT16(data) & 1) ? color : READ_LE_UINT16(data + 2); else return (data[0] & 1) ? color : data[1]; @@ -954,7 +1069,7 @@ uint16 Wiz::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, u return color; } if (bitDepth == 2) - return READ_LE_UINT16(data + y * w + x * 2); + return READ_LE_UINT16(data + (y * w + x) * 2); else return data[y * w + x]; } @@ -1043,6 +1158,25 @@ void Wiz::computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPi } } +#ifdef USE_RGB_COLOR +static int wizPackType2(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt) { + debug(9, "wizPackType2([%d,%d,%d,%d])", rCapt.left, rCapt.top, rCapt.right, rCapt.bottom); + int w = rCapt.width(); + int h = rCapt.height(); + int size = w * h * 2; + if (dst) { + src += rCapt.top * srcPitch + rCapt.left * 2; + while (h--) { + for (int i = 0; i < w; i++) + WRITE_LE_UINT16(dst + i * 2, READ_UINT16(src + i * 2)); + dst += w * 2; + src += srcPitch; + } + } + return size; +} +#endif + static int wizPackType1(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt, uint8 transColor) { debug(9, "wizPackType1(%d, [%d,%d,%d,%d])", transColor, rCapt.left, rCapt.top, rCapt.right, rCapt.bottom); src += rCapt.top * srcPitch + rCapt.left; @@ -1179,7 +1313,6 @@ static int wizPackType0(uint8 *dst, const uint8 *src, int srcPitch, const Common } void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, int compType) { - debug(5, "ScummEngine_v72he::captureWizImage(%d, %d, [%d,%d,%d,%d])", resNum, compType, r.left, r.top, r.right, r.bottom); uint8 *src = NULL; VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen]; if (backBuffer) { @@ -1187,12 +1320,17 @@ void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, in } else { src = pvs->getPixels(0, 0); } - Common::Rect rCapt(pvs->w, pvs->h); + captureImage(src, pvs->pitch, pvs->w, pvs->h, resNum, r, compType); +} + +void Wiz::captureImage(uint8 *src, int srcPitch, int srcw, int srch, int resNum, const Common::Rect& r, int compType) { + debug(0, "captureImage(%d, %d, [%d,%d,%d,%d])", resNum, compType, r.left, r.top, r.right, r.bottom); + Common::Rect rCapt(srcw, srch); if (rCapt.intersects(r)) { rCapt.clip(r); const uint8 *palPtr; if (_vm->_game.heversion >= 99) { - palPtr = _vm->_hePalettes + 1024; + palPtr = _vm->_hePalettes + _vm->_hePaletteSlot; } else { palPtr = _vm->_currentPalette; } @@ -1201,16 +1339,24 @@ void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, in int h = rCapt.height(); int transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : 5; + if (_vm->_game.features & GF_16BIT_COLOR) + compType = 2; + // compute compressed size int dataSize = 0; int headerSize = palPtr ? 1080 : 36; switch (compType) { case 0: - dataSize = wizPackType0(0, src, pvs->pitch, rCapt); + dataSize = wizPackType0(0, src, srcPitch, rCapt); break; case 1: - dataSize = wizPackType1(0, src, pvs->pitch, rCapt, transColor); + dataSize = wizPackType1(0, src, srcPitch, rCapt, transColor); + break; +#ifdef USE_RGB_COLOR + case 2: + dataSize = wizPackType2(0, src, srcPitch, rCapt); break; +#endif default: error("unhandled compression type %d", compType); break; @@ -1249,11 +1395,16 @@ void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, in // write compressed data switch (compType) { case 0: - wizPackType0(wizImg + headerSize, src, pvs->pitch, rCapt); + wizPackType0(wizImg + headerSize, src, srcPitch, rCapt); break; case 1: - wizPackType1(wizImg + headerSize, src, pvs->pitch, rCapt, transColor); + wizPackType1(wizImg + headerSize, src, srcPitch, rCapt, transColor); + break; +#ifdef USE_RGB_COLOR + case 2: + wizPackType2(wizImg + headerSize, src, srcPitch, rCapt); break; +#endif default: break; } @@ -1279,24 +1430,15 @@ void Wiz::displayWizImage(WizImage *pwi) { drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, 0, 0, 0); } else { const Common::Rect *r = NULL; - drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, 0); + drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, _vm->getHEPaletteSlot(0)); } } -uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, int palette) { - debug(3, "drawWizImage(resNum %d, x1 %d y1 %d flags 0x%X zorder %d shadow %d field_390 %d dstResNum %d palette %d)", resNum, x1, y1, flags, zorder, shadow, field_390, dstResNum, palette); +uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr) { + debug(3, "drawWizImage(resNum %d, state %d maskNum %d maskState %d x1 %d y1 %d flags 0x%X zorder %d shadow %d field_390 %d dstResNum %d)", resNum, state, maskNum, maskState, x1, y1, flags, zorder, shadow, field_390, dstResNum); uint8 *dataPtr; uint8 *dst = NULL; - const uint8 *palPtr = NULL; - if (_vm->_game.heversion >= 99) { - if (palette) { - palPtr = _vm->_hePalettes + palette * 1024 + 768; - } else { - palPtr = _vm->_hePalettes + 1792; - } - } - const uint8 *xmapPtr = NULL; if (shadow) { dataPtr = _vm->getResourceAddress(rtImage, shadow); @@ -1318,6 +1460,21 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); assert(wizd); + uint8 *mask = NULL; + if (maskNum) { + uint8 *maskPtr = _vm->getResourceAddress(rtImage, maskNum); + assert(maskPtr); + + wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), maskPtr, maskState, 0); + assert(wizh); + assert(comp == 2 && READ_LE_UINT32(wizh + 0x0) == 1); + width = READ_LE_UINT32(wizh + 0x4); + height = READ_LE_UINT32(wizh + 0x8); + + mask = _vm->findWrappedBlock(MKID_BE('WIZD'), maskPtr, maskState, 0); + assert(mask); + } + if (flags & kWIFHasPalette) { uint8 *pal = _vm->findWrappedBlock(MKID_BE('RGBS'), dataPtr, state, 0); assert(pal); @@ -1339,13 +1496,30 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int error("WizImage printing is unimplemented"); } - int32 cw, ch; + int32 dstPitch, dstType, cw, ch; if (flags & kWIFBlitToMemBuffer) { - dst = (uint8 *)malloc(width * height); + dst = (uint8 *)malloc(width * height * _vm->_bitDepth); int transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? (_vm->VAR(_vm->VAR_WIZ_TCOLOR)) : 5; - memset(dst, transColor, width * height); + + if (_vm->_bitDepth == 2) { + uint8 *tmpPtr = dst; + for (uint i = 0; i < height; i++) { + for (uint j = 0; j < width; j++) { + if (_cursorImage) { + WRITE_UINT16(tmpPtr + j * 2, transColor); + } else { + WRITE_LE_UINT16(tmpPtr + j * 2, transColor); + } + } + tmpPtr += width * 2; + } + } else { + memset(dst, transColor, width * height); + } cw = width; ch = height; + dstPitch = cw * _vm->_bitDepth; + dstType = kDstMemory; } else { if (dstResNum) { uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum); @@ -1353,6 +1527,8 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0); assert(dst); getWizImageDim(dstResNum, 0, cw, ch); + dstPitch = cw * _vm->_bitDepth; + dstType = kDstResource; } else { VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen]; if (flags & kWIFMarkBufferDirty) { @@ -1362,6 +1538,8 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int } cw = pvs->w; ch = pvs->h; + dstPitch = pvs->pitch; + dstType = kDstScreen; } } @@ -1381,7 +1559,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int } } - if (flags & kWIFRemapPalette) { + if (flags & kWIFRemapPalette && _vm->_bitDepth == 1) { palPtr = rmap + 4; } @@ -1393,29 +1571,36 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int switch (comp) { case 0: - copyRawWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor); + copyRawWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor, _vm->_bitDepth); break; case 1: if (flags & 0x80) { dst = _vm->getMaskBuffer(0, 0, 1); - copyWizImageWithMask(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, 0, 2); + dstPitch /= _vm->_bitDepth; + copyWizImageWithMask(dst, wizd, dstPitch, cw, ch, x1, y1, width, height, &rScreen, 0, 2); } else if (flags & 0x100) { dst = _vm->getMaskBuffer(0, 0, 1); - copyWizImageWithMask(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, 0, 1); + dstPitch /= _vm->_bitDepth; + copyWizImageWithMask(dst, wizd, dstPitch, cw, ch, x1, y1, width, height, &rScreen, 0, 1); } else { - copyWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr); + copyWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr, _vm->_bitDepth); } break; +#ifdef USE_RGB_COLOR case 2: - copyRaw16BitWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor); + if (maskNum) { + copyMaskWizImage(dst, wizd, mask, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr); + } else { + copyRaw16BitWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, transColor); + } break; case 4: // TODO: Unknown image type break; case 5: - // TODO: 16bit color compressed image - copy16BitWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr); + copy16BitWizImage(dst, wizd, dstPitch, dstType, cw, ch, x1, y1, width, height, &rScreen, flags, xmapPtr); break; +#endif default: error("drawWizImage: Unhandled wiz compression type %d", comp); } @@ -1517,6 +1702,74 @@ struct PolygonDrawData { } }; +void Wiz::captureWizPolygon(int resNum, int maskNum, int maskState, int id1, int id2, int compType) { + debug(0, "captureWizPolygon: resNum %d, maskNum %d maskState %d, id1 %d id2 %d compType %d", resNum, maskNum, maskState, id1, id2, compType); + + int i, j; + WizPolygon *wp; + + wp = NULL; + for (i = 0; i < ARRAYSIZE(_polygons); ++i) { + if (_polygons[i].id == id1) { + wp = &_polygons[i]; + break; + } + } + if (!wp) { + error("Polygon1 %d is not defined", id1); + } + if (wp->numVerts != 5) { + error("Invalid point count %d for Polygon1 %d", wp->numVerts, id1); + } + + wp = NULL; + for (i = 0; i < ARRAYSIZE(_polygons); ++i) { + if (_polygons[i].id == id2) { + wp = &_polygons[i]; + break; + } + } + if (!wp) { + error("Polygon2 %d is not defined", id2); + } + if (wp->numVerts != 5) { + error("Invalid point count %d for Polygon2 %d", wp->numVerts, id2); + } + + int32 dstw, dsth, dstpitch; + int32 srcw, srch; + uint8 *imageBuffer; + + assert(maskNum); + const Common::Rect *r = NULL; + const uint8 *src = drawWizImage(maskNum, maskState, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0); + getWizImageDim(maskNum, maskState, srcw, srch); + + dstw = wp->bound.width(); + dsth = wp->bound.height(); + dstpitch = dstw * _vm->_bitDepth; + imageBuffer = (uint8 *)malloc(dstw * dsth * _vm->_bitDepth); + assert(imageBuffer); + + const uint16 transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : 5; + if (_vm->_bitDepth == 2) { + uint8 *tmpPtr = imageBuffer; + for (i = 0; i < dsth; i++) { + for (j = 0; j < dstw; j++) + WRITE_UINT16(tmpPtr + j * 2, transColor); + tmpPtr += dstpitch; + } + } else { + memset(imageBuffer, transColor, dstw * dsth); + } + + Common::Rect bound; + drawWizPolygonImage(imageBuffer, src, NULL, dstpitch, kDstMemory, dstw, dsth, srcw, srch, bound, wp->vert, _vm->_bitDepth); + + captureImage(imageBuffer, dstpitch, dstw, dsth, resNum, wp->bound, compType); + free(imageBuffer); +} + void Wiz::drawWizComplexPolygon(int resNum, int state, int po_x, int po_y, int shadow, int angle, int scale, const Common::Rect *r, int flags, int dstResNum, int palette) { Common::Point pts[4]; @@ -1544,11 +1797,10 @@ void Wiz::drawWizPolygon(int resNum, int state, int id, int flags, int shadow, i } void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette) { - debug(3, "drawWizPolygonTransform(resNum %d, flags 0x%X, shadow %d dstResNum %d palette %d)", resNum, flags, shadow, dstResNum, palette); + debug(0, "drawWizPolygonTransform(resNum %d, flags 0x%X, shadow %d dstResNum %d palette %d)", resNum, flags, shadow, dstResNum, palette); const Common::Rect *r = NULL; uint8 *srcWizBuf = NULL; bool freeBuffer = true; - int i; if (_vm->_game.heversion >= 99) { if (getWizImageData(resNum, state, 0) != 0 || (flags & (kWIFRemapPalette | kWIFFlipX | kWIFFlipY)) || palette != 0) { @@ -1557,8 +1809,10 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int if (flags & 0x800000) { debug(0, "drawWizPolygonTransform() unhandled flag 0x800000"); } - srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, shadow, 0, r, flags, 0, palette); + + srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, flags, 0, _vm->getHEPaletteSlot(palette)); } else { + assert(_vm->_bitDepth == 1); uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum); assert(dataPtr); srcWizBuf = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); @@ -1567,7 +1821,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int } } else { if (getWizImageData(resNum, state, 0) != 0) { - srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, palette); + srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette)); } else { uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum); assert(dataPtr); @@ -1577,146 +1831,162 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int } } - if (srcWizBuf) { - uint8 *dst; - int32 dstw, dsth, dstpitch, wizW, wizH; - VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen]; - int transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : 5; + assert(srcWizBuf); - if (dstResNum) { - uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum); - assert(dstPtr); - dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0); - assert(dst); - getWizImageDim(dstResNum, 0, dstw, dsth); - dstpitch = dstw; + uint8 *dst; + int32 dstw, dsth, dstpitch, dstType, wizW, wizH; + VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen]; + + if (dstResNum) { + uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum); + assert(dstPtr); + dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0); + assert(dst); + getWizImageDim(dstResNum, 0, dstw, dsth); + dstpitch = dstw * _vm->_bitDepth; + dstType = kDstResource; + } else { + if (flags & kWIFMarkBufferDirty) { + dst = pvs->getPixels(0, 0); } else { - if (flags & kWIFMarkBufferDirty) { - dst = pvs->getPixels(0, 0); - } else { - dst = pvs->getBackPixels(0, 0); + dst = pvs->getBackPixels(0, 0); + } + dstw = pvs->w; + dsth = pvs->h; + dstpitch = pvs->pitch; + dstType = kDstScreen; + } + + Common::Rect bound; + getWizImageDim(resNum, state, wizW, wizH); + drawWizPolygonImage(dst, srcWizBuf, 0, dstpitch, dstType, dstw, dsth, wizW, wizH, bound, wp, _vm->_bitDepth); + + if (flags & kWIFMarkBufferDirty) { + _vm->markRectAsDirty(kMainVirtScreen, bound); + } else { + _vm->restoreBackgroundHE(bound); + } + + if (freeBuffer) + free(srcWizBuf); +} + +void Wiz::drawWizPolygonImage(uint8 *dst, const uint8 *src, const uint8 *mask, int dstpitch, int dstType, int dstw, int dsth, int wizW, int wizH, Common::Rect &bound, Common::Point *wp, uint8 bitDepth) { + int i, transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : 5; + + Common::Point bbox[4]; + bbox[0].x = 0; + bbox[0].y = 0; + bbox[1].x = wizW - 1; + bbox[1].y = 0; + bbox[2].x = wizW - 1; + bbox[2].y = wizH - 1; + bbox[3].x = 0; + bbox[3].y = wizH - 1; + + int16 xmin_p, xmax_p, ymin_p, ymax_p; + xmin_p = ymin_p = (int16)0x7FFF; + xmax_p = ymax_p = (int16)0x8000; + + for (i = 0; i < 4; ++i) { + xmin_p = MIN(wp[i].x, xmin_p); + xmax_p = MAX(wp[i].x, xmax_p); + ymin_p = MIN(wp[i].y, ymin_p); + ymax_p = MAX(wp[i].y, ymax_p); + } + + int16 xmin_b, xmax_b, ymin_b, ymax_b; + xmin_b = ymin_b = (int16)0x7FFF; + xmax_b = ymax_b = (int16)0x8000; + + for (i = 0; i < 4; ++i) { + xmin_b = MIN(bbox[i].x, xmin_b); + xmax_b = MAX(bbox[i].x, xmax_b); + ymin_b = MIN(bbox[i].y, ymin_b); + ymax_b = MAX(bbox[i].y, ymax_b); + } + + PolygonDrawData pdd(ymax_p - ymin_p + 1); + pdd.mat[0].x = xmin_p; + pdd.mat[0].y = ymin_p; + pdd.mat[1].x = xmax_p; + pdd.mat[1].y = ymax_p; + pdd.mat[2].x = xmin_b; + pdd.mat[2].y = ymin_b; + pdd.mat[3].x = xmax_b; + pdd.mat[3].y = ymax_b; + + // precompute the transformation which remaps 'bbox' pixels to 'wp' + for (i = 0; i < 3; ++i) { + pdd.transform(&wp[i], &wp[i + 1], &bbox[i], &bbox[i + 1]); + } + pdd.transform(&wp[3], &wp[0], &bbox[3], &bbox[0]); + + pdd.rAreasNum = 0; + PolygonDrawData::ResultArea *pra = &pdd.ra[0]; + int32 yoff = pdd.mat[0].y * dstpitch; + int16 y_start = pdd.mat[0].y; + for (i = 0; i < pdd.pAreasNum; ++i) { + PolygonDrawData::PolygonArea *ppa = &pdd.pa[i]; + if (y_start >= 0 && y_start < dsth) { + int16 x1 = ppa->xmin; + if (x1 < 0) { + x1 = 0; } - dstw = pvs->w; - dsth = pvs->h; - dstpitch = pvs->pitch; - } - - getWizImageDim(resNum, state, wizW, wizH); - - Common::Point bbox[4]; - bbox[0].x = 0; - bbox[0].y = 0; - bbox[1].x = wizW - 1; - bbox[1].y = 0; - bbox[2].x = wizW - 1; - bbox[2].y = wizH - 1; - bbox[3].x = 0; - bbox[3].y = wizH - 1; - - int16 xmin_p, xmax_p, ymin_p, ymax_p; - xmin_p = ymin_p = (int16)0x7FFF; - xmax_p = ymax_p = (int16)0x8000; - - for (i = 0; i < 4; ++i) { - xmin_p = MIN(wp[i].x, xmin_p); - xmax_p = MAX(wp[i].x, xmax_p); - ymin_p = MIN(wp[i].y, ymin_p); - ymax_p = MAX(wp[i].y, ymax_p); - } - - int16 xmin_b, xmax_b, ymin_b, ymax_b; - xmin_b = ymin_b = (int16)0x7FFF; - xmax_b = ymax_b = (int16)0x8000; - - for (i = 0; i < 4; ++i) { - xmin_b = MIN(bbox[i].x, xmin_b); - xmax_b = MAX(bbox[i].x, xmax_b); - ymin_b = MIN(bbox[i].y, ymin_b); - ymax_b = MAX(bbox[i].y, ymax_b); - } - - PolygonDrawData pdd(ymax_p - ymin_p + 1); - pdd.mat[0].x = xmin_p; - pdd.mat[0].y = ymin_p; - pdd.mat[1].x = xmax_p; - pdd.mat[1].y = ymax_p; - pdd.mat[2].x = xmin_b; - pdd.mat[2].y = ymin_b; - pdd.mat[3].x = xmax_b; - pdd.mat[3].y = ymax_b; - - // precompute the transformation which remaps 'bbox' pixels to 'wp' - for (i = 0; i < 3; ++i) { - pdd.transform(&wp[i], &wp[i + 1], &bbox[i], &bbox[i + 1]); - } - pdd.transform(&wp[3], &wp[0], &bbox[3], &bbox[0]); - - pdd.rAreasNum = 0; - PolygonDrawData::ResultArea *pra = &pdd.ra[0]; - int32 yoff = pdd.mat[0].y * dstpitch; - int16 y_start = pdd.mat[0].y; - for (i = 0; i < pdd.pAreasNum; ++i) { - PolygonDrawData::PolygonArea *ppa = &pdd.pa[i]; - if (y_start >= 0 && y_start < dsth) { - int16 x1 = ppa->xmin; - if (x1 < 0) { - x1 = 0; - } - int16 x2 = ppa->xmax; - if (x2 >= dstw) { - x2 = dstw - 1; - } - int16 w = x2 - x1 + 1; - if (w > 0) { - int16 width = ppa->xmax - ppa->xmin + 1; - pra->x_step = ((ppa->x2 - ppa->x1) << 16) / width; - pra->y_step = ((ppa->y2 - ppa->y1) << 16) / width; - pra->dst_offs = yoff + x1; - pra->w = w; - pra->x_s = ppa->x1 << 16; - pra->y_s = ppa->y1 << 16; - int16 tmp = x1 - ppa->xmin; - if (tmp != 0) { - pra->x_s += pra->x_step * tmp; - pra->y_s += pra->y_step * tmp; - } - ++pra; - ++pdd.rAreasNum; - } + int16 x2 = ppa->xmax; + if (x2 >= dstw) { + x2 = dstw - 1; } - ++ppa; - yoff += dstpitch; - ++y_start; - } - - pra = &pdd.ra[0]; - for (i = 0; i < pdd.rAreasNum; ++i, ++pra) { - uint8 *dstPtr = dst + pra->dst_offs; - int32 w = pra->w; - int32 x_acc = pra->x_s; - int32 y_acc = pra->y_s; - while (--w) { - int32 src_offs = (y_acc >> 16) * wizW + (x_acc >> 16); - assert(src_offs < wizW * wizH); - x_acc += pra->x_step; - y_acc += pra->y_step; - if (transColor == -1 || transColor != srcWizBuf[src_offs]) { - *dstPtr = srcWizBuf[src_offs]; + int16 w = x2 - x1 + 1; + if (w > 0) { + int16 width = ppa->xmax - ppa->xmin + 1; + pra->x_step = ((ppa->x2 - ppa->x1) << 16) / width; + pra->y_step = ((ppa->y2 - ppa->y1) << 16) / width; + pra->dst_offs = yoff + x1 * _vm->_bitDepth; + pra->w = w; + pra->x_s = ppa->x1 << 16; + pra->y_s = ppa->y1 << 16; + int16 tmp = x1 - ppa->xmin; + if (tmp != 0) { + pra->x_s += pra->x_step * tmp; + pra->y_s += pra->y_step * tmp; } - dstPtr++; + ++pra; + ++pdd.rAreasNum; } } - - Common::Rect bound(xmin_p, ymin_p, xmax_p + 1, ymax_p + 1); - if (flags & kWIFMarkBufferDirty) { - _vm->markRectAsDirty(kMainVirtScreen, bound); - } else { - _vm->restoreBackgroundHE(bound); + ++ppa; + yoff += dstpitch; + ++y_start; + } + + pra = &pdd.ra[0]; + for (i = 0; i < pdd.rAreasNum; ++i, ++pra) { + uint8 *dstPtr = dst + pra->dst_offs; + int32 w = pra->w; + int32 x_acc = pra->x_s; + int32 y_acc = pra->y_s; + while (--w) { + int32 src_offs = (y_acc >> 16) * wizW + (x_acc >> 16); + assert(src_offs < wizW * wizH); + x_acc += pra->x_step; + y_acc += pra->y_step; + if (bitDepth == 2) { + if (transColor == -1 || transColor != READ_LE_UINT16(src + src_offs * 2)) { + writeColor(dstPtr, dstType, READ_LE_UINT16(src + src_offs * 2)); + } + } else { + if (transColor == -1 || transColor != src[src_offs]) + *dstPtr = src[src_offs]; + } + dstPtr += bitDepth; } - - if (freeBuffer) - free(srcWizBuf); } + + bound.left = xmin_p; + bound.top = ymin_p; + bound.right = xmax_p + 1; + bound.bottom = ymax_p + 1; } void Wiz::flushWizBuffer() { @@ -1726,13 +1996,13 @@ void Wiz::flushWizBuffer() { drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, pwi->shadow, 0, pwi->palette); } else { const Common::Rect *r = NULL; - drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->field_390, r, pwi->flags, 0, pwi->palette); + drawWizImage(pwi->resNum, pwi->state, 0, 0, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->field_390, r, pwi->flags, 0, _vm->getHEPaletteSlot(pwi->palette)); } } _imagesNum = 0; } -void Wiz::loadWizCursor(int resId) { +void Wiz::loadWizCursor(int resId, int palette) { int32 x, y; getWizImageSpot(resId, 0, x, y); if (x < 0) { @@ -1747,11 +2017,14 @@ void Wiz::loadWizCursor(int resId) { } const Common::Rect *r = NULL; - uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0); + _cursorImage = true; + uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, _vm->getHEPaletteSlot(palette)); + _cursorImage = false; + int32 cw, ch; getWizImageDim(resId, 0, cw, ch); _vm->setCursorHotspot(x, y); - _vm->setCursorFromBuffer(cursor, cw, ch, cw); + _vm->setCursorFromBuffer(cursor, cw, ch, cw * _vm->_bitDepth); // Since we set up cursor palette for default cursor, disable it now CursorMan.disableCursorPalette(true); @@ -1763,7 +2036,7 @@ void Wiz::displayWizComplexImage(const WizParameters *params) { int sourceImage = 0; if (params->processFlags & kWPFMaskImg) { sourceImage = params->sourceImage; - debug(0, "displayWizComplexImage() unhandled flag kWPFMaskImg"); + debug(0, "displayWizComplexImage() flag kWPFMaskImg"); } int palette = 0; if (params->processFlags & kWPFPaletteNum) { @@ -1831,15 +2104,14 @@ void Wiz::displayWizComplexImage(const WizParameters *params) { ++_imagesNum; } else { if (sourceImage != 0) { - // TODO: Add support for kWPFMaskImg - drawWizImage(params->sourceImage, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, palette); + drawWizImage(params->sourceImage, 0, params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, _vm->getHEPaletteSlot(palette)); } else if (params->processFlags & (kWPFScaled | kWPFRotate)) { drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, shadow, rotationAngle, scale, r, flags, dstResNum, palette); } else { if (flags & kWIFIsPolygon) { drawWizPolygon(params->img.resNum, state, po_x, flags, shadow, dstResNum, palette); } else { - drawWizImage(params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, palette); + drawWizImage(params->img.resNum, state, 0, 0, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, _vm->getHEPaletteSlot(palette)); } } } @@ -1847,6 +2119,8 @@ void Wiz::displayWizComplexImage(const WizParameters *params) { void Wiz::createWizEmptyImage(int resNum, int img_x, int img_y, int img_w, int img_h) { const uint16 flags = 0xB; + const uint8 compType = (_vm->_game.features & GF_16BIT_COLOR) ? 2 : 0; + const uint8 bitDepth = (_vm->_game.features & GF_16BIT_COLOR) ? 2 : 1; int res_size = 0x1C; if (flags & 1) { res_size += 0x308; @@ -1857,11 +2131,11 @@ void Wiz::createWizEmptyImage(int resNum, int img_x, int img_y, int img_w, int i if (flags & 8) { res_size += 0x10C; } - res_size += 8 + img_w * img_h; + res_size += 8 + img_w * img_h * bitDepth; const uint8 *palPtr; if (_vm->_game.heversion >= 99) { - palPtr = _vm->_hePalettes + 1024; + palPtr = _vm->_hePalettes + _vm->_hePaletteSlot; } else { palPtr = _vm->_currentPalette; } @@ -1874,7 +2148,7 @@ void Wiz::createWizEmptyImage(int resNum, int img_x, int img_y, int img_w, int i WRITE_BE_UINT32(res_data, res_size); res_data += 4; WRITE_BE_UINT32(res_data, 'WIZH'); res_data += 4; WRITE_BE_UINT32(res_data, 0x14); res_data += 4; - WRITE_LE_UINT32(res_data, 0); res_data += 4; + WRITE_LE_UINT32(res_data, compType); res_data += 4; WRITE_LE_UINT32(res_data, img_w); res_data += 4; WRITE_LE_UINT32(res_data, img_h); res_data += 4; if (flags & 1) { @@ -1897,7 +2171,7 @@ void Wiz::createWizEmptyImage(int resNum, int img_x, int img_y, int img_w, int i } } WRITE_BE_UINT32(res_data, 'WIZD'); res_data += 4; - WRITE_BE_UINT32(res_data, 8 + img_w * img_h); res_data += 4; + WRITE_BE_UINT32(res_data, 8 + img_w * img_h * bitDepth); res_data += 4; } _vm->_res->setModified(rtImage, resNum); } @@ -1914,7 +2188,8 @@ void Wiz::fillWizRect(const WizParameters *params) { int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); int h = READ_LE_UINT32(wizh + 0x8); - assert(c == 0); + assert(c == 0 || c == 2); + uint8 bitDepth = (c == 2) ? 2 : 1; Common::Rect areaRect, imageRect(w, h); if (params->processFlags & kWPFClipBox) { if (!imageRect.intersects(params->box)) { @@ -1937,10 +2212,15 @@ void Wiz::fillWizRect(const WizParameters *params) { assert(wizd); int dx = areaRect.width(); int dy = areaRect.height(); - wizd += areaRect.top * w + areaRect.left; + wizd += (areaRect.top * w + areaRect.left) * bitDepth; while (dy--) { - memset(wizd, color, dx); - wizd += w; + if (bitDepth == 2) { + for (int i = 0; i < dx; i++) + WRITE_LE_UINT16(wizd + i * 2, color); + } else { + memset(wizd, color, dx); + } + wizd += w * bitDepth; } } } @@ -1950,14 +2230,19 @@ void Wiz::fillWizRect(const WizParameters *params) { struct drawProcP { Common::Rect *imageRect; uint8 *wizd; - int width; + int pitch; + int depth; }; static void drawProc(int x, int y, int c, void *data) { drawProcP *param = (drawProcP *)data; if (param->imageRect->contains(x, y)) { - *(param->wizd + y * param->width + x) = c; + uint32 offs = y * param->pitch + x * param->depth; + if (param->depth == 2) + WRITE_LE_UINT16(param->wizd + offs, c); + else + *(param->wizd + offs) = c; } } @@ -1974,7 +2259,8 @@ void Wiz::fillWizLine(const WizParameters *params) { int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); int h = READ_LE_UINT32(wizh + 0x8); - assert(c == 0); + assert(c == 0 || c == 2); + uint8 bitDepth = (c == 2) ? 2 : 1; Common::Rect imageRect(w, h); if (params->processFlags & kWPFClipBox) { if (!imageRect.intersects(params->box)) { @@ -1997,13 +2283,13 @@ void Wiz::fillWizLine(const WizParameters *params) { lineP.imageRect = &imageRect; lineP.wizd = wizd; - lineP.width = w; + lineP.pitch = w * bitDepth; + lineP.depth = bitDepth; if (params->processFlags & kWPFParams) { assert (params->params2 == 1); // Catch untested usage Graphics::drawThickLine(x1, y1, x2, y2, params->params1, color, drawProc, &lineP); } else { - Graphics::drawLine(x1, y1, x2, y2, color, drawProc, &lineP); } } @@ -2065,7 +2351,7 @@ void Wiz::remapWizImagePal(const WizParameters *params) { } void Wiz::processWizImage(const WizParameters *params) { - byte filename[260]; + byte buffer[260]; debug(3, "processWizImage: processMode %d", params->processMode); switch (params->processMode) { @@ -2080,18 +2366,28 @@ void Wiz::processWizImage(const WizParameters *params) { break; case 3: if (params->processFlags & kWPFUseFile) { - Common::File f; + Common::SeekableReadStream *f = NULL; + memcpy(buffer, params->filename, 260); + const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer)); - memcpy(filename, params->filename, 260); - _vm->convertFilePath(filename, sizeof(filename)); + if (!_vm->_saveFileMan->listSavefiles(filename).empty()) { + f = _vm->_saveFileMan->openForLoading(filename); + } else { + Common::File *nf = new Common::File(); + nf->open(filename); + if (!nf->isOpen()) + delete nf; + else + f = nf; + } - if (f.open((const char *)filename)) { - uint32 id = f.readUint32BE(); + if (f) { + uint32 id = f->readUint32BE(); if (id == MKID_BE('AWIZ') || id == MKID_BE('MULT')) { - uint32 size = f.readUint32BE(); - f.seek(0, SEEK_SET); + uint32 size = f->readUint32BE(); + f->seek(0, SEEK_SET); byte *p = _vm->_res->createResource(rtImage, params->img.resNum, size); - if (f.read(p, size) != size) { + if (f->read(p, size) != size) { _vm->_res->nukeResource(rtImage, params->img.resNum); error("i/o error when reading '%s'", filename); _vm->VAR(_vm->VAR_GAME_LOADED) = -2; @@ -2105,7 +2401,7 @@ void Wiz::processWizImage(const WizParameters *params) { _vm->VAR(_vm->VAR_GAME_LOADED) = -1; _vm->VAR(119) = -1; } - f.close(); + delete f; } else { _vm->VAR(_vm->VAR_GAME_LOADED) = -3; _vm->VAR(119) = -3; @@ -2115,7 +2411,9 @@ void Wiz::processWizImage(const WizParameters *params) { break; case 4: if (params->processFlags & kWPFUseFile) { - Common::DumpFile f; + Common::OutSaveFile *f; + memcpy(buffer, params->filename, 260); + const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer)); switch (params->fileWriteMode) { case 2: @@ -2125,22 +2423,20 @@ void Wiz::processWizImage(const WizParameters *params) { // TODO Write image to file break; case 0: - memcpy(filename, params->filename, 260); - _vm->convertFilePath(filename, sizeof(filename)); - - if (!f.open((const char *)filename)) { + if (!(f = _vm->_saveFileMan->openForSaving(filename))) { debug(0, "Unable to open for write '%s'", filename); _vm->VAR(119) = -3; } else { byte *p = _vm->getResourceAddress(rtImage, params->img.resNum); uint32 size = READ_BE_UINT32(p + 4); - if (f.write(p, size) != size) { - error("i/o error when writing '%s'", params->filename); + if (f->write(p, size) != size) { + error("i/o error when writing '%s'", filename); _vm->VAR(119) = -2; } else { _vm->VAR(119) = 0; } - f.close(); + f->finalize(); + delete f; } break; default: @@ -2153,9 +2449,7 @@ void Wiz::processWizImage(const WizParameters *params) { break; // HE 99+ case 7: - // Used in PuttsFunShop/SamsFunShop/soccer2004 - // TODO: Capture polygon - _vm->_res->setModified(rtImage, params->img.resNum); + captureWizPolygon(params->img.resNum, params->sourceImage, (params->processFlags & kWPFNewState) ? params->img.state : 0, params->polygonId1, params->polygonId2, params->compType); break; case 8: { int img_w = 640; @@ -2172,6 +2466,9 @@ void Wiz::processWizImage(const WizParameters *params) { img_x = params->img.x1; img_y = params->img.y1; } + if (params->processFlags & kWPFParams) { + debug(0, "Compression %d Color Depth %d", params->params1, params->params2); + } createWizEmptyImage(params->img.resNum, img_x, img_y, img_w, img_h); } break; @@ -2308,8 +2605,9 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags case 1: ret = isWizPixelNonTransparent(wizd, x, y, w, h, 1); break; +#ifdef USE_RGB_COLOR case 2: - ret = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0; + ret = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0; break; case 4: // TODO: Unknown image type @@ -2319,6 +2617,7 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags case 5: ret = isWizPixelNonTransparent(wizd, x, y, w, h, 2); break; +#endif default: error("isWizPixelNonTransparent: Unhandled wiz compression type %d", c); break; @@ -2349,6 +2648,7 @@ uint16 Wiz::getWizPixelColor(int resNum, int state, int x, int y) { case 1: color = getWizPixelColor(wizd, x, y, w, h, 1, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); break; +#ifdef USE_RGB_COLOR case 2: color = getRawWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); break; @@ -2359,6 +2659,7 @@ uint16 Wiz::getWizPixelColor(int resNum, int state, int x, int y) { case 5: color = getWizPixelColor(wizd, x, y, w, h, 2, _vm->VAR(_vm->VAR_WIZ_TCOLOR)); break; +#endif default: error("getWizPixelColor: Unhandled wiz compression type %d", c); break; diff --git a/engines/scumm/he/wiz_he.h b/engines/scumm/he/wiz_he.h index fe63457ead..1fa9564486 100644 --- a/engines/scumm/he/wiz_he.h +++ b/engines/scumm/he/wiz_he.h @@ -142,6 +142,12 @@ enum { kWizCopy }; +enum DstSurface { + kDstScreen = 0, + kDstMemory = 1, + kDstResource = 2 +}; + class ScummEngine_v71he; class Wiz { @@ -159,6 +165,7 @@ public: void clearWizBuffer(); Common::Rect _rectOverride; + bool _cursorImage; bool _rectOverrideEnabled; void polygonClear(); @@ -188,27 +195,43 @@ public: void flushWizBuffer(); void getWizImageSpot(int resId, int state, int32 &x, int32 &y); - void loadWizCursor(int resId); + void loadWizCursor(int resId, int palette); void captureWizImage(int resNum, const Common::Rect& r, bool frontBuffer, int compType); + void captureImage(uint8 *src, int srcPitch, int srcw, int srch, int resNum, const Common::Rect& r, int compType); + void captureWizPolygon(int resNum, int maskNum, int maskState, int id1, int id2, int compType); void displayWizComplexImage(const WizParameters *params); void displayWizImage(WizImage *pwi); void processWizImage(const WizParameters *params); - uint8 *drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, int palette); + uint8 *drawWizImage(int resNum, int state, int maskNum, int maskState, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, const uint8 *palPtr); void drawWizPolygon(int resNum, int state, int id, int flags, int shadow, int dstResNum, int palette); void drawWizComplexPolygon(int resNum, int state, int po_x, int po_y, int shadow, int angle, int zoom, const Common::Rect *r, int flags, int dstResNum, int palette); void drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette); + void drawWizPolygonImage(uint8 *dst, const uint8 *src, const uint8 *mask, int dstpitch, int dstType, int dstw, int dsth, int wizW, int wizH, Common::Rect &bound, Common::Point *wp, uint8 bitDepth); + +#ifdef USE_RGB_COLOR + static void copyMaskWizImage(uint8 *dst, const uint8 *src, const uint8 *mask, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr); +#endif + + static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, uint8 bitdepth); + static void copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstPitch, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP); + static void copyWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitdepth); + static void copyRawWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor, uint8 bitdepth); +#ifdef USE_RGB_COLOR + static void copy16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *xmapPtr); + static void copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstPitch, int dstType, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, int transColor); + template<int type> static void decompress16BitWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *xmapPtr = NULL); +#endif + template<int type> static void decompressWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitdepth); + template<int type> static void decompressRawWizImage(uint8 *dst, int dstPitch, int dstType, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr, uint8 bitdepth); + +#ifdef USE_RGB_COLOR + template<int type> static void write16BitColor(uint8 *dst, const uint8 *src, int dstType, const uint8 *xmapPtr); +#endif + template<int type> static void write8BitColor(uint8 *dst, const uint8 *src, int dstType, const uint8 *palPtr, const uint8 *xmapPtr, uint8 bitDepth); + static void writeColor(uint8 *dstPtr, int dstType, uint16 color); - static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch); - static void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL); - static void copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP); - void copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL); - static void copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor); - void copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor); - template<int type> static void decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL); - template<int type> void decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL); - template<int type> static void decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr = NULL); int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint8 bitdepth); uint16 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth, uint16 color); uint16 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 bitDepth, uint16 color); diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp index 1b531f6bab..2fe3f34530 100644 --- a/engines/scumm/palette.cpp +++ b/engines/scumm/palette.cpp @@ -33,6 +33,27 @@ namespace Scumm { +uint8 *ScummEngine::getHEPaletteSlot(uint16 palSlot) { + assertRange(0, palSlot, _numPalettes, "palette"); + + if (_game.heversion >= 99) { + if (palSlot) + return _hePalettes + palSlot * _hePaletteSlot + 768; + else + return _hePalettes + _hePaletteSlot + 768; + } + + return NULL; +} + +uint16 ScummEngine::get16BitColor(uint8 r, uint8 g, uint8 b) { + uint16 ar = (r >> 3) << 10; + uint16 ag = (g >> 3) << 5; + uint16 ab = (b >> 3) << 0; + uint16 col = ar | ag | ab; + return col; +} + void ScummEngine::resetPalette() { static const byte tableC64Palette[] = { 0x00, 0x00, 0x00, 0xFD, 0xFE, 0xFC, 0xBE, 0x1A, 0x24, 0x30, 0xE6, 0xC6, @@ -201,6 +222,8 @@ void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) { assertRange(0, numcolor, 256, "setPaletteFromPtr: numcolor"); dest = _currentPalette; + + // Test for Amiga Monkey Island and EGA Mode unset, if true then skip the first 16 colors. if ((_game.platform == Common::kPlatformAmiga) && _game.version == 4 && _renderMode != Common::kRenderEGA) { firstIndex = 16; dest += 3 * 16; @@ -240,9 +263,6 @@ void ScummEngine::setDirtyColors(int min, int max) { _palDirtyMin = min; if (_palDirtyMax < max) _palDirtyMax = max; - - if (_hePaletteCache) - memset(_hePaletteCache, -1, 65536); } void ScummEngine::initCycl(const byte *ptr) { @@ -729,16 +749,6 @@ void ScummEngine_v8::desaturatePalette(int hueScale, int satScale, int lightScal #endif -int ScummEngine::convert16BitColor(uint16 color, uint8 r, uint8 g, uint8 b) { - // HACK: Find the closest matching color, and store in - // cache for faster access. - if (_hePaletteCache[color] == -1) { - _hePaletteCache[color] = remapPaletteColor(r, g, b, -1); - } - - return _hePaletteCache[color]; -} - int ScummEngine::remapPaletteColor(int r, int g, int b, int threshold) { byte *pal; int ar, ag, ab, i; diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp index 67baff97b3..d3faa15c10 100644 --- a/engines/scumm/resource.cpp +++ b/engines/scumm/resource.cpp @@ -919,7 +919,11 @@ bool ScummEngine::isResourceInUse(int type, int i) const { case rtCostume: return isCostumeInUse(i); case rtSound: - return _sound->isSoundInUse(i); + // Sound resource 1 is used for queued speech + if (_game.heversion >= 60 && i == 1) + return true; + else + return _sound->isSoundInUse(i); case rtCharset: return _charset->getCurID() == i; case rtImage: diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index aa4dce470e..7bf61a8762 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1553,7 +1553,7 @@ void ScummEngine_v90he::saveOrLoad(Serializer *s) { void ScummEngine_v99he::saveOrLoad(Serializer *s) { ScummEngine_v90he::saveOrLoad(s); - s->saveLoadArrayOf(_hePalettes, (_numPalettes + 1) * 1024, sizeof(_hePalettes[0]), sleUint8); + s->saveLoadArrayOf(_hePalettes, (_numPalettes + 1) * _hePaletteSlot, sizeof(_hePalettes[0]), sleUint8); } void ScummEngine_v100he::saveOrLoad(Serializer *s) { diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index 4f6adc5570..fafb6b383f 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -50,7 +50,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 79 +#define CURRENT_VER 80 /** * An auxillary macro, used to specify savegame versions. We use this instead diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 9d6673d308..587e2a8abe 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -111,7 +111,9 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _currentScript(0xFF), // Let debug() work on init stage _messageDialog(0), _pauseDialog(0), _scummMenuDialog(0), _versionDialog(0) { - if (_game.platform == Common::kPlatformNES) { + if (_game.features & GF_16BIT_COLOR) { + _gdi = new Gdi16Bit(this); + } else if (_game.platform == Common::kPlatformNES) { _gdi = new GdiNES(this); } else if (_game.version <= 1) { _gdi = new GdiV1(this); @@ -252,6 +254,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _switchRoomEffect2 = 0; _switchRoomEffect = 0; + _bitDepth = 0; _doEffect = false; _snapScroll = false; _currentLights = 0; @@ -268,8 +271,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _palManipPalette = NULL; _palManipIntermediatePal = NULL; memset(gfxUsageBits, 0, sizeof(gfxUsageBits)); - _hePaletteCache = NULL; _hePalettes = NULL; + _hePaletteSlot = 0; _shadowPalette = NULL; _shadowPaletteSize = 0; memset(_currentPalette, 0, sizeof(_currentPalette)); @@ -525,9 +528,11 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _screenHeight = 200; } + _bitDepth = (_game.features & GF_16BIT_COLOR) ? 2 : 1; + // Allocate gfx compositing buffer (not needed for V7/V8 games). if (_game.version < 7) - _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight); + _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight * _bitDepth); else _compositeBuf = 0; @@ -829,7 +834,6 @@ ScummEngine_v90he::~ScummEngine_v90he() { delete _logicHE; } if (_game.heversion >= 99) { - free(_hePaletteCache); free(_hePalettes); } } @@ -1094,6 +1098,15 @@ Common::Error ScummEngine::init() { // CJK FT and DIG use usual NUT fonts, not FM-TOWNS ROM, so // there is no text surface for them. This takes that into account (_screenWidth * _textSurfaceMultiplier > 320)); + } else if (_game.features & GF_16BIT_COLOR) { +#ifdef USE_RGB_COLOR + Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); + initGraphics(_screenWidth, _screenHeight, _screenWidth > 320, &format); + if (format != _system->getScreenFormat()) + return Common::kUnsupportedColorMode; +#else + error("16bit color support is required for this game"); +#endif } else { initGraphics(_screenWidth, _screenHeight, _screenWidth > 320); } @@ -1197,7 +1210,7 @@ void ScummEngine::setupScumm() { int maxHeapThreshold = -1; if (_game.features & GF_16BIT_COLOR) { - // 16Bit color games require double the memory, due to increased resource sizes. + // 16bit color games require double the memory, due to increased resource sizes. maxHeapThreshold = 12 * 1024 * 1024; } else if (_game.features & GF_NEW_COSTUMES) { // Since the new costumes are very big, we increase the heap limit, to avoid having @@ -1219,7 +1232,7 @@ void ScummEngine::setupScumm() { } free(_compositeBuf); - _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier); + _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _bitDepth); } #ifdef ENABLE_SCUMM_7_8 @@ -1560,11 +1573,9 @@ void ScummEngine_v99he::resetScumm() { ScummEngine_v90he::resetScumm(); - _hePaletteCache = (int16 *)malloc(65536); - memset(_hePaletteCache, -1, 65536); - - _hePalettes = (uint8 *)malloc((_numPalettes + 1) * 1024); - memset(_hePalettes, 0, (_numPalettes + 1) * 1024); + _hePaletteSlot = (_game.features & GF_16BIT_COLOR) ? 1280 : 1024; + _hePalettes = (uint8 *)malloc((_numPalettes + 1) * _hePaletteSlot); + memset(_hePalettes, 0, (_numPalettes + 1) * _hePaletteSlot); // Array 129 is set to base name len = strlen(_filenamePattern.pattern); diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index f0f2521225..940ea512d5 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -667,9 +667,6 @@ public: } static Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot); - bool loadInfosFromSlot(int slot, InfoStuff *stuff) { - return loadInfosFromSlot(_targetName.c_str(), slot, stuff); - } static bool loadInfosFromSlot(const char *target, int slot, InfoStuff *stuff); protected: @@ -966,6 +963,7 @@ public: int _screenTop; Common::RenderMode _renderMode; + uint8 _bitDepth; protected: ColorCycle _colorCycle[16]; // Palette cycles @@ -985,7 +983,10 @@ protected: byte animate, animateIndex; int8 state; } _cursor; - byte _grabbedCursor[8192]; + + // HACK Double the array size to handle 16-bit images. + // this should be dynamically allocated based on game depth instead. + byte _grabbedCursor[16384]; byte _currentCursor; byte _newEffect, _switchRoomEffect2, _switchRoomEffect; @@ -1044,7 +1045,8 @@ protected: virtual void palManipulateInit(int resID, int start, int end, int time); void palManipulate(); public: - int convert16BitColor(uint16 color, uint8 r, uint8 g, uint8 b); + uint8 *getHEPaletteSlot(uint16 palSlot); + uint16 get16BitColor(uint8 r, uint8 g, uint8 b); int remapPaletteColor(int r, int g, int b, int threshold); // Used by Actor::remapActorPalette protected: void moveMemInPalRes(int start, int end, byte direction); @@ -1120,7 +1122,7 @@ public: // HE specific byte _HEV7ActorPalette[256]; uint8 *_hePalettes; - int16 *_hePaletteCache; + uint16 _hePaletteSlot; protected: int _shadowPaletteSize; diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index 07e2ce8bca..82ed2a62e6 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -86,7 +86,7 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer) Sound::~Sound() { stopCDTimer(); - AudioCD.destroy(); + AudioCD.stop(); delete _sfxFile; } diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp index 98e088365e..69da7f3e09 100644 --- a/engines/scumm/vars.cpp +++ b/engines/scumm/vars.cpp @@ -312,6 +312,7 @@ void ScummEngine_v80he::setupScummVars() { void ScummEngine_v90he::setupScummVars() { ScummEngine_v80he::setupScummVars(); + VAR_TIMER = 97; VAR_SCRIPT_CYCLE = 103; VAR_NUM_SCRIPT_CYCLES = 104; diff --git a/engines/tinsel/pcode.cpp b/engines/tinsel/pcode.cpp index 8646ad3267..a2661237b7 100644 --- a/engines/tinsel/pcode.cpp +++ b/engines/tinsel/pcode.cpp @@ -145,8 +145,8 @@ const WorkaroundEntry workaroundList[] = { // Present Outside Inn {TINSEL_V1, false, 352600876, 0, fragment2_size, fragment2}, - // DW1-GRA: Talking to palace guards in Act 2 gives !!!HIGH STRING||| - this happens if you initiate dialog - // with one of the guards, but not the other. So this fix routes the talk parameters of the broken one + // DW1-GRA: Talking to palace guards in Act 2 gives !!!HIGH STRING||| - this happens if you initiate dialog with + // one of the guards, but not the other. So these fragments provide the correct talk parameters where needed {TINSEL_V1, false, 310506872, 463, fragment4_size, fragment4}, {TINSEL_V1, false, 310506872, 485, fragment5_size, fragment5}, {TINSEL_V1, false, 310506872, 513, fragment6_size, fragment6}, @@ -164,7 +164,7 @@ const WorkaroundEntry workaroundList[] = { {TINSEL_V0, false, 0, 0, 0, NULL} }; -//310505453, x + //----------------- LOCAL GLOBAL DATA -------------------- /** diff --git a/engines/tinsel/polygons.cpp b/engines/tinsel/polygons.cpp index bb2daea206..825abc9a6b 100644 --- a/engines/tinsel/polygons.cpp +++ b/engines/tinsel/polygons.cpp @@ -1996,8 +1996,14 @@ void GetPolyNode(HPOLYGON hp, int *pNodeX, int *pNodeY) { Poly pp(LockMem(pHandle), Polys[hp]->pIndex); - *pNodeX = FROM_LE_32(pp.nodex); - *pNodeY = FROM_LE_32(pp.nodey); + // WORKAROUND: Invalid node adjustment for DW2 Cartwheel scene refer polygon + if (TinselV2 && (pHandle == 0x74191900) && (hp == 8)) { + *pNodeX = 480; + *pNodeY = 408; + } else { + *pNodeX = FROM_LE_32(pp.nodex); + *pNodeY = FROM_LE_32(pp.nodey); + } if (TinselV2) { *pNodeX += volatileStuff[hp].xoff; diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp index 5f056351b6..7586c5e749 100644 --- a/engines/tinsel/tinsel.cpp +++ b/engines/tinsel/tinsel.cpp @@ -888,6 +888,7 @@ TinselEngine::~TinselEngine() { if (MoviePlaying()) FinishBMV(); + AudioCD.stop(); delete _sound; delete _midiMusic; delete _pcmMusic; diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp index 2e71b548bc..0834760861 100644 --- a/graphics/cursorman.cpp +++ b/graphics/cursorman.cpp @@ -57,14 +57,14 @@ bool CursorManager::showMouse(bool visible) { return g_system->showMouse(visible); } -void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetScale) { - Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale); +void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) { + Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format); cur->_visible = isVisible(); _cursorStack.push(cur); if (buf) { - g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale); + g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format); } } @@ -77,7 +77,7 @@ void CursorManager::popCursor() { if (!_cursorStack.empty()) { cur = _cursorStack.top(); - g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale); + g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale, &cur->_format); } g_system->showMouse(isVisible()); @@ -100,15 +100,24 @@ void CursorManager::popAllCursors() { g_system->showMouse(isVisible()); } +void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) { -void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetScale) { if (_cursorStack.empty()) { - pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale); + pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format); return; } Cursor *cur = _cursorStack.top(); + +#ifdef USE_RGB_COLOR + uint size; + if (!format) + size = w * h; + else + size = w * h * format->bytesPerPixel; +#else uint size = w * h; +#endif if (cur->_size < size) { delete[] cur->_data; @@ -125,8 +134,14 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, cur->_hotspotY = hotspotY; cur->_keycolor = keycolor; cur->_targetScale = targetScale; +#ifdef USE_RGB_COLOR + if (format) + cur->_format = *format; + else + cur->_format = Graphics::PixelFormat::createFormatCLUT8(); +#endif - g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale); + g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format); } bool CursorManager::supportsCursorPalettes() { diff --git a/graphics/cursorman.h b/graphics/cursorman.h index f019e37b04..f5b60d76b9 100644 --- a/graphics/cursorman.h +++ b/graphics/cursorman.h @@ -28,6 +28,10 @@ #include "common/scummsys.h" #include "common/stack.h" #include "common/singleton.h" +#include "graphics/pixelformat.h" +#ifdef USE_RGB_COLOR +#include "common/system.h" +#endif namespace Graphics { @@ -59,18 +63,19 @@ public: * safely freed afterwards. * * @param buf the new cursor data - * @param w the width - * @param h the height + * @param w the width + * @param h the height * @param hotspotX the hotspot X coordinate * @param hotspotY the hotspot Y coordinate * @param keycolor the index for the transparent color * @param targetScale the scale for which the cursor is designed - * + * @param format a pointer to the pixel format which the cursor graphic uses, + * CLUT8 will be used if this is NULL or not specified. * @note It is ok for the buffer to be a NULL pointer. It is sometimes * useful to push a "dummy" cursor and modify it later. The * cursor will be added to the stack, but not to the backend. */ - void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1); + void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int targetScale = 1, const Graphics::PixelFormat *format = NULL); /** * Pop a cursor from the stack, and restore the previous one to the @@ -90,8 +95,10 @@ public: * @param hotspotY the hotspot Y coordinate * @param keycolor the index for the transparent color * @param targetScale the scale for which the cursor is designed + * @param format a pointer to the pixel format which the cursor graphic uses, + * CLUT8 will be used if this is NULL or not specified. */ - void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1); + void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int targetScale = 1, const Graphics::PixelFormat *format = NULL); /** * Pop all of the cursors and cursor palettes from their respective stacks. @@ -166,13 +173,24 @@ private: uint _height; int _hotspotX; int _hotspotY; - byte _keycolor; + uint32 _keycolor; + Graphics::PixelFormat _format; byte _targetScale; uint _size; - - Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1) { + Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 0xFFFFFFFF, int targetScale = 1, const Graphics::PixelFormat *format = NULL) { +#ifdef USE_RGB_COLOR + if (!format) + _format = Graphics::PixelFormat::createFormatCLUT8(); + else + _format = *format; + _size = w * h * _format.bytesPerPixel; + _keycolor &= ((1 << (_format.bytesPerPixel << 3)) - 1); +#else + _format = Graphics::PixelFormat::createFormatCLUT8(); _size = w * h; + _keycolor &= 0xFF; +#endif _data = new byte[_size]; if (data && _data) memcpy(_data, data, _size); @@ -180,7 +198,6 @@ private: _height = h; _hotspotX = hotspotX; _hotspotY = hotspotY; - _keycolor = keycolor; _targetScale = targetScale; } @@ -216,7 +233,6 @@ private: delete[] _data; } }; - Common::Stack<Cursor *> _cursorStack; Common::Stack<Palette *> _cursorPaletteStack; }; diff --git a/graphics/module.mk b/graphics/module.mk index 46ed564e1e..ed14051243 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -1,6 +1,7 @@ MODULE := graphics MODULE_OBJS := \ + conversion.o \ cursorman.o \ dither.o \ font.o \ @@ -11,6 +12,7 @@ MODULE_OBJS := \ fonts/scummfont.o \ iff.o \ imagedec.o \ + jpeg.o \ primitives.o \ scaler.o \ scaler/thumbnail_intern.o \ diff --git a/graphics/pixelformat.h b/graphics/pixelformat.h index f59650e5cc..b94ef41412 100644 --- a/graphics/pixelformat.h +++ b/graphics/pixelformat.h @@ -27,6 +27,7 @@ #define GRAPHICS_PIXELFORMAT_H #include "common/scummsys.h" +#include "common/list.h" namespace Graphics { @@ -50,6 +51,24 @@ struct PixelFormat { byte rLoss, gLoss, bLoss, aLoss; /**< Precision loss of each color component. */ byte rShift, gShift, bShift, aShift; /**< Binary left shift of each color component in the pixel value. */ + inline PixelFormat() { + bytesPerPixel = + rLoss = gLoss = bLoss = aLoss = + rShift = gShift = bShift = aShift = 0; + } + + inline PixelFormat(byte BytesPerPixel, + byte RBits, byte GBits, byte BBits, byte ABits, + byte RShift, byte GShift, byte BShift, byte AShift) { + bytesPerPixel = BytesPerPixel; + rLoss = 8 - RBits, gLoss = 8 - GBits, bLoss = 8 - BBits, aLoss = 8 - ABits; + rShift = RShift, gShift = GShift, bShift = BShift, aShift = AShift; + } + + static inline PixelFormat createFormatCLUT8() { + return PixelFormat(1, 0, 0, 0, 0, 0, 0, 0, 0); + } + inline bool operator==(const PixelFormat &fmt) const { // TODO: If aLoss==8, then the value of aShift is irrelevant, and should be ignored. return 0 == memcmp(this, &fmt, sizeof(PixelFormat)); @@ -129,6 +148,26 @@ struct PixelFormat { } }; +/** + * Determines the first matching format between two lists. + * + * @param backend The higher priority list, meant to be a list of formats supported by the backend + * @param frontend The lower priority list, meant to be a list of formats supported by the engine + * @return The first item on the backend list that also occurs on the frontend list + * or PixelFormat::createFormatCLUT8() if no matching formats were found. + */ +inline PixelFormat findCompatibleFormat(Common::List<PixelFormat> backend, Common::List<PixelFormat> frontend) { +#ifdef USE_RGB_COLOR + for (Common::List<PixelFormat>::iterator i = backend.begin(); i != backend.end(); ++i) { + for (Common::List<PixelFormat>::iterator j = frontend.begin(); j != frontend.end(); ++j) { + if (*i == *j) + return *i; + } + } +#endif + return PixelFormat::createFormatCLUT8(); +} + } // end of namespace Graphics #endif diff --git a/graphics/scaler.cpp b/graphics/scaler.cpp index a3aaaa121d..8c677cc083 100644 --- a/graphics/scaler.cpp +++ b/graphics/scaler.cpp @@ -30,18 +30,17 @@ int gBitFormat = 565; -static const Graphics::PixelFormat gPixelFormat555 = { +static const Graphics::PixelFormat gPixelFormat555( 2, 3, 3, 3, 8, 10, 5, 0, 0 - }; + ); -static const Graphics::PixelFormat gPixelFormat565 = { +static const Graphics::PixelFormat gPixelFormat565( 2, 3, 2, 3, 8, 11, 5, 0, 0 - }; - + ); #ifndef DISABLE_HQ_SCALERS diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp index 405d8622c2..9f5def8f10 100644 --- a/graphics/sjis.cpp +++ b/graphics/sjis.cpp @@ -280,6 +280,11 @@ const uint16 *FontSjisSVM::getCharData(uint16 c) const { if (index >= 0x3F) --index; + // Another check if the passed character was an + // correctly encoded SJIS character. + if (index < 0 || index >= 0xBC || base < 0) + return 0; + return _fontData + (base * 0xBC + index) * 16; } diff --git a/graphics/video/coktelvideo/coktelvideo.cpp b/graphics/video/coktelvideo/coktelvideo.cpp index 39aeca07bd..b69315cbae 100644 --- a/graphics/video/coktelvideo/coktelvideo.cpp +++ b/graphics/video/coktelvideo/coktelvideo.cpp @@ -362,6 +362,10 @@ void Imd::setDoubleMode(bool doubleMode) { } void Imd::enableSound(Audio::Mixer &mixer) { + // Sanity check + if (mixer.getOutputRate() == 0) + return; + // Only possible on the first frame if (_curFrame > 0) return; @@ -387,7 +391,7 @@ void Imd::disableSound() { } bool Imd::isSoundPlaying() const { - if (_audioStream && _mixer->isSoundHandleActive(_audioHandle)) + if (_audioStream && _mixer && _mixer->isSoundHandleActive(_audioHandle)) return true; return false; @@ -1706,9 +1710,12 @@ CoktelVideo::State Vmd::processFrame(uint16 frame) { } if (startSound && _soundEnabled) { - _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_audioHandle, _audioStream); - _skipFrames = 0; - _soundStage = 2; + if (_hasSound && _audioStream) { + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_audioHandle, _audioStream); + _skipFrames = 0; + _soundStage = 2; + } else + _soundStage = 0; } if ((_curFrame == (_framesCount - 1)) && (_soundStage == 2)) { diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp index 7551acac48..195256b66f 100644 --- a/gui/ListWidget.cpp +++ b/gui/ListWidget.cpp @@ -64,6 +64,7 @@ ListWidget::ListWidget(GuiObject *boss, const String &name, uint32 cmd) _editable = true; _quickSelect = true; + _editColor = ThemeEngine::kFontColorNormal; } ListWidget::ListWidget(GuiObject *boss, int x, int y, int w, int h, uint32 cmd) @@ -141,7 +142,17 @@ void ListWidget::setSelected(int item) { } } -void ListWidget::setList(const StringList &list) { +ThemeEngine::FontColor ListWidget::getSelectionColor() const { + if (_listColors.empty()) + return ThemeEngine::kFontColorNormal; + + if (_filter.empty()) + return _listColors[_selectedItem]; + else + return _listColors[_listIndex[_selectedItem]]; +} + +void ListWidget::setList(const StringList &list, const ColorList *colors) { if (_editMode && _caretVisible) drawCaret(true); @@ -150,6 +161,12 @@ void ListWidget::setList(const StringList &list) { _list = list; _filter.clear(); _listIndex.clear(); + _listColors.clear(); + + if (colors) { + _listColors = *colors; + assert(_listColors.size() == _dataList.size()); + } int size = list.size(); if (_currentPos >= size) @@ -162,7 +179,19 @@ void ListWidget::setList(const StringList &list) { scrollBarRecalc(); } -void ListWidget::append(const String &s) { +void ListWidget::append(const String &s, ThemeEngine::FontColor color) { + if (_dataList.size() == _listColors.size()) { + // If the color list has the size of the data list, we append the color. + _listColors.push_back(color); + } else if (!_listColors.size() && color != ThemeEngine::kFontColorNormal) { + // If it's the first entry to use a non default color, we will fill + // up all other entries of the color list with the default color and + // add the requested color for the new entry. + for (uint i = 0; i < _dataList.size(); ++i) + _listColors.push_back(ThemeEngine::kFontColorNormal); + _listColors.push_back(color); + } + _dataList.push_back(s); _list.push_back(s); @@ -431,17 +460,27 @@ void ListWidget::drawWidget() { int width; + ThemeEngine::FontColor color = ThemeEngine::kFontColorNormal; + + if (!_listColors.empty()) { + if (_filter.empty() || _selectedItem == -1) + color = _listColors[pos]; + else + color = _listColors[_listIndex[pos]]; + } + if (_selectedItem == pos && _editMode) { buffer = _editString; + color = _editColor; adjustOffset(); width = _w - r.left - _hlRightPadding - _leftPadding - scrollbarW; - g_gui.theme()->drawText(Common::Rect(_x + r.left, y, _x + r.left + width, y + fontHeight - 2), - buffer, _state, Graphics::kTextAlignLeft, inverted, pad, true); + g_gui.theme()->drawText(Common::Rect(_x + r.left, y, _x + r.left + width, y + fontHeight - 2), buffer, _state, + Graphics::kTextAlignLeft, inverted, pad, true, ThemeEngine::kFontStyleBold, color); } else { buffer = _list[pos]; width = _w - r.left - scrollbarW; - g_gui.theme()->drawText(Common::Rect(_x + r.left, y, _x + r.left + width, y + fontHeight - 2), - buffer, _state, Graphics::kTextAlignLeft, inverted, pad, true); + g_gui.theme()->drawText(Common::Rect(_x + r.left, y, _x + r.left + width, y + fontHeight - 2), buffer, _state, + Graphics::kTextAlignLeft, inverted, pad, true, ThemeEngine::kFontStyleBold, color); } _textWidth[i] = width; @@ -499,6 +538,14 @@ void ListWidget::startEditMode() { if (_editable && !_editMode && _selectedItem >= 0) { _editMode = true; setEditString(_list[_selectedItem]); + if (_listColors.empty()) { + _editColor = ThemeEngine::kFontColorNormal; + } else { + if (_filter.empty()) + _editColor = _listColors[_selectedItem]; + else + _editColor = _listColors[_listIndex[_selectedItem]]; + } draw(); g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); } diff --git a/gui/ListWidget.h b/gui/ListWidget.h index 203cd88fb6..23c12a38fc 100644 --- a/gui/ListWidget.h +++ b/gui/ListWidget.h @@ -28,6 +28,8 @@ #include "gui/editable.h" #include "common/str.h" +#include "gui/ThemeEngine.h" + namespace GUI { class ScrollBarWidget; @@ -51,9 +53,11 @@ class ListWidget : public EditableWidget { public: typedef Common::String String; typedef Common::StringList StringList; + typedef Common::Array<ThemeEngine::FontColor> ColorList; protected: StringList _list; StringList _dataList; + ColorList _listColors; Common::Array<int> _listIndex; bool _editable; bool _editMode; @@ -80,6 +84,8 @@ protected: uint32 _cmd; + ThemeEngine::FontColor _editColor; + public: ListWidget(GuiObject *boss, const String &name, uint32 cmd = 0); ListWidget(GuiObject *boss, int x, int y, int w, int h, uint32 cmd = 0); @@ -87,20 +93,33 @@ public: virtual Widget *findWidget(int x, int y); - void setList(const StringList &list); - void append(const String &s); + void setList(const StringList &list, const ColorList *colors = 0); const StringList &getList() const { return _dataList; } - int getSelected() const { return (_filter.empty() || _selectedItem == -1) ? _selectedItem : _listIndex[_selectedItem]; } + + void append(const String &s, ThemeEngine::FontColor color = ThemeEngine::kFontColorNormal); + void setSelected(int item); + int getSelected() const { return (_filter.empty() || _selectedItem == -1) ? _selectedItem : _listIndex[_selectedItem]; } + const String &getSelectedString() const { return _list[_selectedItem]; } + ThemeEngine::FontColor getSelectionColor() const; + void setNumberingMode(NumberingMode numberingMode) { _numberingMode = numberingMode; } - bool isEditable() const { return _editable; } - void setEditable(bool editable) { _editable = editable; } + void scrollTo(int item); void scrollToEnd(); + void enableQuickSelect(bool enable) { _quickSelect = enable; } String getQuickSelectString() const { return _quickSelectStr; } + bool isEditable() const { return _editable; } + void setEditable(bool editable) { _editable = editable; } + void setEditColor(ThemeEngine::FontColor color) { _editColor = color; } + + // Made startEditMode/endEditMode for SaveLoadChooser + void startEditMode(); + void endEditMode(); + void setFilter(const String &filter, bool redraw = true); virtual void handleTickle(); @@ -115,10 +134,6 @@ public: virtual bool wantsFocus() { return true; } - // Made startEditMode for SCUMM's SaveLoadChooser - void startEditMode(); - void endEditMode(); - protected: void drawWidget(); diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 1d9062f323..41447d2a88 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -1234,6 +1234,12 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int if (!cursor) return false; +#ifdef USE_RGB_COLOR + _cursorFormat.bytesPerPixel = 1; + _cursorFormat.rLoss = _cursorFormat.gLoss = _cursorFormat.bLoss = _cursorFormat.aLoss = 8; + _cursorFormat.rShift = _cursorFormat.gShift = _cursorFormat.bShift = _cursorFormat.aShift = 0; +#endif + // Set up the cursor parameters _cursorHotspotX = hotspotX; _cursorHotspotY = hotspotY; diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index cab5f9fd41..9e4bff5075 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -32,7 +32,7 @@ #include "graphics/surface.h" #include "graphics/fontman.h" -#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.7" +#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8" namespace Graphics { struct DrawStep; @@ -612,6 +612,9 @@ protected: ImagesMap _bitmaps; Graphics::PixelFormat _overlayFormat; +#ifdef USE_RGB_COLOR + Graphics::PixelFormat _cursorFormat; +#endif /** List of all the dirty screens that must be blitted to the overlay. */ Common::List<Common::Rect> _dirtyScreen; diff --git a/gui/credits.h b/gui/credits.h index 5ddae4ea37..9a9bd4deb5 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -180,6 +180,9 @@ static const char *credits[] = { "C1""iPhone", "C0""Oystein Eftevaag", "", +"C1""LinuxMoto", +"C0""Lubomyr Lisen", +"", "C1""Maemo", "C0""Frantisek Dufka", "", @@ -366,6 +369,8 @@ static const char *credits[] = { "C2""Daily Linux builds", "C0""Thomas Mayer", "C2""PSP port contributions", +"C0""Yotam Barnoy", +"C2""PSP port suspend/resume support", "C0""Sean Murray", "C2""ScummVM tools GUI application (GSoC 2007 task)", "C0""n0p", diff --git a/gui/saveload.cpp b/gui/saveload.cpp index ce700c181e..058911d43f 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -42,15 +42,15 @@ enum { }; SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel) - : Dialog("ScummSaveLoad"), _delSupport(0), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) { + : Dialog("SaveLoadChooser"), _delSupport(0), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) { _delSupport = _metaInfoSupport = _thumbnailSupport = _saveDateSupport = _playTimeSupport = false; _backgroundType = ThemeEngine::kDialogBackgroundSpecial; - new StaticTextWidget(this, "ScummSaveLoad.Title", title); + new StaticTextWidget(this, "SaveLoadChooser.Title", title); // Add choice list - _list = new GUI::ListWidget(this, "ScummSaveLoad.List"); + _list = new GUI::ListWidget(this, "SaveLoadChooser.List"); _list->setNumberingMode(GUI::kListNumberingZero); setSaveMode(false); @@ -61,11 +61,11 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel) _playtime = new StaticTextWidget(this, 0, 0, 10, 10, "No playtime saved", Graphics::kTextAlignCenter); // Buttons - new GUI::ButtonWidget(this, "ScummSaveLoad.Cancel", "Cancel", kCloseCmd, 0); - _chooseButton = new GUI::ButtonWidget(this, "ScummSaveLoad.Choose", buttonLabel, kChooseCmd, 0); + new GUI::ButtonWidget(this, "SaveLoadChooser.Cancel", "Cancel", kCloseCmd, 0); + _chooseButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Choose", buttonLabel, kChooseCmd, 0); _chooseButton->setEnabled(false); - _deleteButton = new GUI::ButtonWidget(this, "ScummSaveLoad.Delete", "Delete", kDelCmd, 0); + _deleteButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Delete", "Delete", kDelCmd, 0); _deleteButton->setEnabled(false); _delSupport = _metaInfoSupport = _thumbnailSupport = false; @@ -172,11 +172,11 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da } void SaveLoadChooser::reflowLayout() { - if (g_gui.xmlEval()->getVar("Globals.ScummSaveLoad.ExtInfo.Visible") == 1 && _thumbnailSupport) { + if (g_gui.xmlEval()->getVar("Globals.SaveLoadChooser.ExtInfo.Visible") == 1 && _thumbnailSupport) { int16 x, y; uint16 w, h; - if (!g_gui.xmlEval()->getWidgetData("ScummSaveLoad.Thumbnail", x, y, w, h)) + if (!g_gui.xmlEval()->getWidgetData("SaveLoadChooser.Thumbnail", x, y, w, h)) error("Error when loading position data for Save/Load Thumbnails."); int thumbW = kThumbnailWidth; @@ -278,8 +278,15 @@ void SaveLoadChooser::updateSelection(bool redraw) { // game is write protected _chooseButton->setEnabled(selItem >= 0 && !isWriteProtected); - if (startEditMode) + if (startEditMode) { _list->startEditMode(); + + if (_chooseButton->isEnabled() && _list->getSelectedString() == "Untitled savestate" && + _list->getSelectionColor() == ThemeEngine::kFontColorAlternate) { + _list->setEditString(""); + _list->setEditColor(ThemeEngine::kFontColorNormal); + } + } } else { // Disable the load button if nothing is selected, or if an empty // list item is selected. @@ -316,6 +323,7 @@ void SaveLoadChooser::updateSaveList() { int curSlot = 0; int saveSlot = 0; StringList saveNames; + ListWidget::ColorList colors; for (SaveStateList::const_iterator x = _saveList.begin(); x != _saveList.end(); ++x) { // Handle gaps in the list of save games saveSlot = atoi(x->save_slot().c_str()); @@ -324,6 +332,7 @@ void SaveLoadChooser::updateSaveList() { SaveStateDescriptor dummySave(curSlot, ""); _saveList.insert_at(curSlot, dummySave); saveNames.push_back(dummySave.description()); + colors.push_back(ThemeEngine::kFontColorNormal); curSlot++; } @@ -338,8 +347,12 @@ void SaveLoadChooser::updateSaveList() { Common::String description = x->description(); Common::String trimmedDescription = description; trimmedDescription.trim(); - if (trimmedDescription.empty()) + if (trimmedDescription.empty()) { description = "Untitled savestate"; + colors.push_back(ThemeEngine::kFontColorAlternate); + } else { + colors.push_back(ThemeEngine::kFontColorNormal); + } saveNames.push_back(description); curSlot++; @@ -351,9 +364,10 @@ void SaveLoadChooser::updateSaveList() { saveNames.push_back(emptyDesc); SaveStateDescriptor dummySave(i, ""); _saveList.push_back(dummySave); + colors.push_back(ThemeEngine::kFontColorNormal); } - _list->setList(saveNames); + _list->setList(saveNames, &colors); } } // End of namespace GUI diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 88ef801af5..d088f4181d 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1,4 +1,360 @@ "<?xml version = '1.0'?>" +"<render_info> " +"<palette> " +"<color name='black' " +"rgb='0,0,0' " +"/> " +"<color name='lightgrey' " +"rgb='104,104,104' " +"/> " +"<color name='darkgrey' " +"rgb='64,64,64' " +"/> " +"<color name='green' " +"rgb='32,160,32' " +"/> " +"<color name='green2' " +"rgb='0,255,0' " +"/> " +"</palette> " +"<fonts> " +"<font id='text_default' " +"file='default' " +"/> " +"<font id='text_button' " +"file='default' " +"/> " +"<font id='text_normal' " +"file='default' " +"/> " +"<text_color id='color_normal' " +"color='green' " +"/> " +"<text_color id='color_normal_inverted' " +"color='black' " +"/> " +"<text_color id='color_normal_hover' " +"color='green2' " +"/> " +"<text_color id='color_normal_disabled' " +"color='lightgrey' " +"/> " +"<text_color id='color_alternative' " +"color='lightgrey' " +"/> " +"<text_color id='color_alternative_inverted' " +"color='255,255,255' " +"/> " +"<text_color id='color_alternative_hover' " +"color='176,176,176' " +"/> " +"<text_color id='color_alternative_disabled' " +"color='darkgrey' " +"/> " +"<text_color id='color_button' " +"color='green' " +"/> " +"<text_color id='color_button_hover' " +"color='green2' " +"/> " +"<text_color id='color_button_disabled' " +"color='lightgrey' " +"/> " +"</fonts> " +"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> " +"<drawdata id='text_selection' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='text_selection_focus' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='mainmenu_bg' cache='false'> " +"<drawstep func='fill' " +"fill='foreground' " +"fg_color='black' " +"/> " +"</drawdata> " +"<drawdata id='special_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='separator' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"height='2' " +"ypos='center' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_base' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_handle_hover' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green2' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_handle_idle' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_button_idle' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green' " +"fill='foreground' " +"width='auto' " +"height='auto' " +"xpos='center' " +"ypos='center' " +"orientation='top' " +"/> " +"</drawdata> " +"<drawdata id='scrollbar_button_hover' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green2' " +"fill='foreground' " +"width='auto' " +"height='auto' " +"xpos='center' " +"ypos='center' " +"orientation='top' " +"/> " +"</drawdata> " +"<drawdata id='tab_active' cache='false'> " +"<text font='text_default' " +"text_color='color_normal_hover' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='tab' " +"bevel='2' " +"radius='0' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='tab_inactive' cache='false'> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='tab' " +"bevel='2' " +"radius='0' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='tab_background' cache='false'> " +"</drawdata> " +"<drawdata id='widget_slider' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='slider_disabled' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='slider_full' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='slider_hover' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='green2' " +"/> " +"</drawdata> " +"<drawdata id='widget_small' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='popup_idle' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='popup_disabled' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='lightgrey' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_default' " +"text_color='color_normal_disabled' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='popup_hover' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='triangle' " +"fg_color='green2' " +"fill='foreground' " +"width='height' " +"height='auto' " +"xpos='right' " +"ypos='center' " +"orientation='bottom' " +"/> " +"<text font='text_default' " +"text_color='color_normal_hover' " +"vertical_align='center' " +"horizontal_align='left' " +"/> " +"</drawdata> " +"<drawdata id='widget_textedit' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='plain_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='caret' cache='false'> " +"<drawstep func='square' " +"fill='foreground' " +"fg_color='lightgrey' " +"/> " +"</drawdata> " +"<drawdata id='default_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"<drawdata id='button_idle' cache='false'> " +"<text font='text_button' " +"text_color='color_button' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='button_hover' cache='false'> " +"<text font='text_button' " +"text_color='color_button_hover' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='button_disabled' cache='false'> " +"<text font='text_button' " +"text_color='color_button_disabled' " +"vertical_align='center' " +"horizontal_align='center' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_disabled' cache='false'> " +"<text font='text_default' " +"text_color='color_normal_disabled' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_selected' cache='false'> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"<drawstep func='cross' " +"fill='foreground' " +"stroke='2' " +"fg_color='green' " +"/> " +"</drawdata> " +"<drawdata id='checkbox_default' cache='false'> " +"<text font='text_default' " +"text_color='color_normal' " +"vertical_align='top' " +"horizontal_align='left' " +"/> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='none' " +"/> " +"</drawdata> " +"<drawdata id='widget_default' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"/> " +"</drawdata> " +"</render_info> " "<layout_info resolution='320xY,256x240,Xx272'> " "<globals> " "<def var='Line.Height' value='12' /> " @@ -8,7 +364,7 @@ "<def var='ShowLauncherLogo' value='0'/> " "<def var='ShowGlobalMenuLogo' value='0'/> " "<def var='ShowSearchPic' value='0'/> " -"<def var='ScummSaveLoad.ExtInfo.Visible' value='0'/> " +"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> " "<def var='KeyMapper.Spacing' value='5'/> " "<def var='KeyMapper.LabelWidth' value='80'/> " "<def var='KeyMapper.ButtonWidth' value='60'/> " @@ -668,7 +1024,7 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='ScummSaveLoad' overlays='screen' inset='8' shading='dim'> " +"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> " "<layout type='vertical' padding='8,8,8,8' center='true'> " "<widget name='Title' height='Globals.Line.Height'/> " "<widget name='List' /> " @@ -765,7 +1121,7 @@ "<def var='ShowLauncherLogo' value='0'/> " "<def var='ShowGlobalMenuLogo' value='0'/> " "<def var='ShowSearchPic' value='0'/> " -"<def var='ScummSaveLoad.ExtInfo.Visible' value='1'/> " +"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> " "<def var='KeyMapper.Spacing' value='10'/> " "<def var='KeyMapper.LabelWidth' value='100'/> " "<def var='KeyMapper.ButtonWidth' value='80'/> " @@ -1413,7 +1769,7 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='ScummSaveLoad' overlays='screen' inset='8' shading='dim'> " +"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> " "<layout type='vertical' padding='8,8,8,32' center='true'> " "<widget name='Title' " "height='Globals.Line.Height' " @@ -1509,359 +1865,3 @@ "</layout> " "</dialog> " "</layout_info> " -"<render_info> " -"<palette> " -"<color name='black' " -"rgb='0,0,0' " -"/> " -"<color name='lightgrey' " -"rgb='104,104,104' " -"/> " -"<color name='darkgrey' " -"rgb='64,64,64' " -"/> " -"<color name='green' " -"rgb='32,160,32' " -"/> " -"<color name='green2' " -"rgb='0,255,0' " -"/> " -"</palette> " -"<fonts> " -"<font id='text_default' " -"file='default' " -"/> " -"<font id='text_button' " -"file='default' " -"/> " -"<font id='text_normal' " -"file='default' " -"/> " -"<text_color id='color_normal' " -"color='green' " -"/> " -"<text_color id='color_normal_inverted' " -"color='black' " -"/> " -"<text_color id='color_normal_hover' " -"color='green2' " -"/> " -"<text_color id='color_normal_disabled' " -"color='lightgrey' " -"/> " -"<text_color id='color_alternative' " -"color='green' " -"/> " -"<text_color id='color_alternative_inverted' " -"color='black' " -"/> " -"<text_color id='color_alternative_hover' " -"color='green2' " -"/> " -"<text_color id='color_alternative_disabled' " -"color='lightgrey' " -"/> " -"<text_color id='color_button' " -"color='green' " -"/> " -"<text_color id='color_button_hover' " -"color='green2' " -"/> " -"<text_color id='color_button_disabled' " -"color='lightgrey' " -"/> " -"</fonts> " -"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> " -"<drawdata id='text_selection' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='text_selection_focus' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='mainmenu_bg' cache='false'> " -"<drawstep func='fill' " -"fill='foreground' " -"fg_color='black' " -"/> " -"</drawdata> " -"<drawdata id='special_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='separator' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"height='2' " -"ypos='center' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_base' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_handle_hover' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green2' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_handle_idle' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_button_idle' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green' " -"fill='foreground' " -"width='auto' " -"height='auto' " -"xpos='center' " -"ypos='center' " -"orientation='top' " -"/> " -"</drawdata> " -"<drawdata id='scrollbar_button_hover' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green2' " -"fill='foreground' " -"width='auto' " -"height='auto' " -"xpos='center' " -"ypos='center' " -"orientation='top' " -"/> " -"</drawdata> " -"<drawdata id='tab_active' cache='false'> " -"<text font='text_default' " -"text_color='color_normal_hover' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='tab' " -"bevel='2' " -"radius='0' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='tab_inactive' cache='false'> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='tab' " -"bevel='2' " -"radius='0' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='tab_background' cache='false'> " -"</drawdata> " -"<drawdata id='widget_slider' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='slider_disabled' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='slider_full' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='slider_hover' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='green2' " -"/> " -"</drawdata> " -"<drawdata id='widget_small' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='popup_idle' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='popup_disabled' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='lightgrey' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_default' " -"text_color='color_normal_disabled' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='popup_hover' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='triangle' " -"fg_color='green2' " -"fill='foreground' " -"width='height' " -"height='auto' " -"xpos='right' " -"ypos='center' " -"orientation='bottom' " -"/> " -"<text font='text_default' " -"text_color='color_normal_hover' " -"vertical_align='center' " -"horizontal_align='left' " -"/> " -"</drawdata> " -"<drawdata id='widget_textedit' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='plain_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='caret' cache='false'> " -"<drawstep func='square' " -"fill='foreground' " -"fg_color='lightgrey' " -"/> " -"</drawdata> " -"<drawdata id='default_bg' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"<drawdata id='button_idle' cache='false'> " -"<text font='text_button' " -"text_color='color_button' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='button_hover' cache='false'> " -"<text font='text_button' " -"text_color='color_button_hover' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='button_disabled' cache='false'> " -"<text font='text_button' " -"text_color='color_button_disabled' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_disabled' cache='false'> " -"<text font='text_default' " -"text_color='color_normal_disabled' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_selected' cache='false'> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"<drawstep func='cross' " -"fill='foreground' " -"stroke='2' " -"fg_color='green' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_default' cache='false'> " -"<text font='text_default' " -"text_color='color_normal' " -"vertical_align='top' " -"horizontal_align='left' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='widget_default' cache='false'> " -"<drawstep func='bevelsq' " -"bevel='2' " -"/> " -"</drawdata> " -"</render_info> " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex c295002f9d..7009b217af 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC index 524141faf2..c913ff6078 100644 --- a/gui/themes/scummclassic/THEMERC +++ b/gui/themes/scummclassic/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.7:ScummVM Classic Theme:No Author] +[SCUMMVM_STX0.8:ScummVM Classic Theme:No Author] diff --git a/gui/themes/scummclassic/classic_gfx.stx b/gui/themes/scummclassic/classic_gfx.stx index ff2fadc577..ceb8aa8bf2 100644 --- a/gui/themes/scummclassic/classic_gfx.stx +++ b/gui/themes/scummclassic/classic_gfx.stx @@ -70,19 +70,19 @@ /> <text_color id = 'color_alternative' - color = 'green' + color = 'lightgrey' /> <text_color id = 'color_alternative_inverted' - color = 'black' + color = '255, 255, 255' /> <text_color id = 'color_alternative_hover' - color = 'green2' + color = '176, 176, 176' /> <text_color id = 'color_alternative_disabled' - color = 'lightgrey' + color = 'darkgrey' /> <text_color id = 'color_button' diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index 029c7479ac..40074640c8 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -35,7 +35,7 @@ <def var = 'ShowGlobalMenuLogo' value = '0'/> <def var = 'ShowSearchPic' value = '0'/> - <def var = 'ScummSaveLoad.ExtInfo.Visible' value = '1'/> + <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '1'/> <def var = 'KeyMapper.Spacing' value = '10'/> <def var = 'KeyMapper.LabelWidth' value = '100'/> @@ -710,7 +710,7 @@ </layout> </dialog> - <dialog name = 'ScummSaveLoad' overlays = 'screen' inset = '8' shading = 'dim'> + <dialog name = 'SaveLoadChooser' overlays = 'screen' inset = '8' shading = 'dim'> <layout type = 'vertical' padding = '8, 8, 8, 32' center = 'true'> <widget name = 'Title' height = 'Globals.Line.Height' diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx index da56f0178a..eb3a4ac326 100644 --- a/gui/themes/scummclassic/classic_layout_lowres.stx +++ b/gui/themes/scummclassic/classic_layout_lowres.stx @@ -36,7 +36,7 @@ <def var = 'ShowGlobalMenuLogo' value = '0'/> <def var = 'ShowSearchPic' value = '0'/> - <def var = 'ScummSaveLoad.ExtInfo.Visible' value = '0'/> + <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '0'/> <def var = 'KeyMapper.Spacing' value = '5'/> <def var = 'KeyMapper.LabelWidth' value = '80'/> @@ -723,7 +723,7 @@ </layout> </dialog> - <dialog name = 'ScummSaveLoad' overlays = 'screen' inset = '8' shading = 'dim'> + <dialog name = 'SaveLoadChooser' overlays = 'screen' inset = '8' shading = 'dim'> <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'> <widget name = 'Title' height = 'Globals.Line.Height'/> <widget name = 'List' /> diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex 7e693c3247..b24e888316 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC index 784f4fae50..34495f71fa 100644 --- a/gui/themes/scummmodern/THEMERC +++ b/gui/themes/scummmodern/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.7:ScummVM Modern Theme:No Author] +[SCUMMVM_STX0.8:ScummVM Modern Theme:No Author] diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx index 6a3ab0c233..05316b516f 100644 --- a/gui/themes/scummmodern/scummmodern_gfx.stx +++ b/gui/themes/scummmodern/scummmodern_gfx.stx @@ -130,15 +130,15 @@ /> <text_color id = 'color_alternative' - color = 'black' + color = '128, 128, 128' /> <text_color id = 'color_alternative_inverted' - color = 'black' + color = 'white' /> <text_color id = 'color_alternative_hover' - color = 'bgreen' + color = 'darkgray' /> <text_color id = 'color_alternative_disabled' diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx index 6582022fe1..33e0537a3c 100644 --- a/gui/themes/scummmodern/scummmodern_layout.stx +++ b/gui/themes/scummmodern/scummmodern_layout.stx @@ -42,7 +42,7 @@ <def var = 'ShowGlobalMenuLogo' value = '1'/> <def var = 'ShowSearchPic' value = '1'/> - <def var = 'ScummSaveLoad.ExtInfo.Visible' value = '1'/> + <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '1'/> <def var = 'KeyMapper.Spacing' value = '10'/> <def var = 'KeyMapper.LabelWidth' value = '100'/> @@ -723,7 +723,7 @@ </layout> </dialog> - <dialog name = 'ScummSaveLoad' overlays = 'screen' inset = '8' shading = 'dim'> + <dialog name = 'SaveLoadChooser' overlays = 'screen' inset = '8' shading = 'dim'> <layout type = 'vertical' padding = '8, 8, 8, 32' center = 'true'> <widget name = 'Title' height = 'Globals.Line.Height' diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx index c514ccc458..b756488279 100644 --- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx +++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx @@ -34,7 +34,7 @@ <def var = 'ShowGlobalMenuLogo' value = '0'/> <def var = 'ShowSearchPic' value = '0'/> - <def var = 'ScummSaveLoad.ExtInfo.Visible' value = '0'/> + <def var = 'SaveLoadChooser.ExtInfo.Visible' value = '0'/> <widget name = 'Button' size = '72, 16' @@ -712,7 +712,7 @@ </layout> </dialog> - <dialog name = 'ScummSaveLoad' overlays = 'screen' inset = '8' shading = 'dim'> + <dialog name = 'SaveLoadChooser' overlays = 'screen' inset = '8' shading = 'dim'> <layout type = 'vertical' padding = '8, 8, 8, 8' center = 'true'> <widget name = 'Title' height = 'Globals.Line.Height'/> <widget name = 'List' /> @@ -204,7 +204,21 @@ ifneq ($(DIST_FILES_ENGINEDATA),) endif $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip wiidist/scummvm/ -.PHONY: deb bundle osxsnap win32dist wiidist install uninstall +# +# Linuxmoto/motoezx specific +# + +# Special target to create a motoezx snapshot +motoezx: $(EXECUTABLE) + $(MKDIR) motoezx/scummvm + $(CP) $(EXECUTABLE) motoezx/scummvm/ + $(STRIP) motoezx/scummvm/$(EXECUTABLE) + $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) motoezx/scummvm/ + $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip motoezx/scummvm/ + $(CP) $(srcdir)/dists/motoezx/* motoezx/scummvm/ + tar -C motoezx -cvzf motoezx/ScummVM.pkg scummvm + +.PHONY: deb bundle osxsnap win32dist wiidist motoezx install uninstall # # ARM specific @@ -23,7 +23,7 @@ ifdef TOOL_EXECUTABLE ################################################ TOOL-$(MODULE) := $(MODULE)/$(TOOL_EXECUTABLE)$(EXEEXT) $(TOOL-$(MODULE)): $(MODULE_OBJS-$(MODULE)) - $(CXX) $(LDFLAGS) $+ -o $@ + $(QUIET_CXX)$(CXX) $(LDFLAGS) $+ -o $@ # Reset TOOL_EXECUTABLE var TOOL_EXECUTABLE:= @@ -42,8 +42,8 @@ ifdef PLUGIN ################################################ PLUGIN-$(MODULE) := plugins/$(PLUGIN_PREFIX)$(notdir $(MODULE))$(PLUGIN_SUFFIX) $(PLUGIN-$(MODULE)): $(MODULE_OBJS-$(MODULE)) $(PLUGIN_EXTRA_DEPS) - $(MKDIR) plugins - $(CXX) $(filter-out $(PLUGIN_EXTRA_DEPS),$+) $(PLUGIN_LDFLAGS) -o $@ + $(QUIET)$(MKDIR) plugins + $(QUIET_PLUGIN)$(CXX) $(filter-out $(PLUGIN_EXTRA_DEPS),$+) $(PLUGIN_LDFLAGS) -o $@ # Reset PLUGIN var PLUGIN:= @@ -69,9 +69,9 @@ OBJS += $(MODULE_LIB-$(MODULE)) # Convenience library target $(MODULE_LIB-$(MODULE)): $(MODULE_OBJS-$(MODULE)) - -$(RM) $@ - $(AR) $@ $+ - $(RANLIB) $@ + $(QUIET)-$(RM) $@ + $(QUIET_AR)$(AR) $@ $+ + $(QUIET_RANLIB)$(RANLIB) $@ # Pseudo target for comfort, allows for "make common", "make gui" etc. $(MODULE): $(MODULE_LIB-$(MODULE)) diff --git a/sound/audiocd.h b/sound/audiocd.h index 4c4ff26147..3ef4a1ac09 100644 --- a/sound/audiocd.h +++ b/sound/audiocd.h @@ -67,6 +67,14 @@ private: friend class Common::Singleton<SingletonBaseType>; AudioCDManager(); + // FIXME: It might make sense to stop CD playback, when the AudioCDManager singleton + // is destroyed. Currently we can not do this, since in worst case the OSystem and + // along with it the Mixer will be destroyed before the AudioCDManager, thus + // leading to invalid memory access. If we can fix up the code to destroy the + // AudioCDManager before OSystem in *all* cases, that is including calling + // OSystem::quit, we might be able to implement it via a simple "stop()" + // call in a custom destructor of AudioCDManager. + /* used for emulated CD music */ SoundHandle _handle; bool _emulating; diff --git a/sound/audiostream.cpp b/sound/audiostream.cpp index 57d2e097bf..783a5733b3 100644 --- a/sound/audiostream.cpp +++ b/sound/audiostream.cpp @@ -211,14 +211,14 @@ protected: int _audioBlockCount; ///< Number of blocks in _audioBlock int _currentBlock; ///< Current audio block number - int _beginLoop; ///< Loop parameter, currently not implemented - int _endLoop; ///< Loop parameter, currently not implemented - + int _beginLoop; ///< Loop start parameter + int _endLoop; ///< Loop end parameter, currently not implemented + bool _loop; ///< Determines if the stream should be looped when it finishes public: - LinearDiskStream(int rate, uint beginLoop, uint endLoop, bool disposeStream, Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, uint numBlocks) + LinearDiskStream(int rate, uint beginLoop, uint endLoop, bool disposeStream, Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, uint numBlocks, bool loop) : _rate(rate), _stream(stream), _beginLoop(beginLoop), _endLoop(endLoop), _disposeAfterUse(disposeStream), - _audioBlockCount(numBlocks) { + _audioBlockCount(numBlocks), _loop(loop) { // Allocate streaming buffer if (is16Bit) { @@ -296,7 +296,6 @@ int LinearDiskStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffe _diskLeft = _audioBlock[_currentBlock].len; } - // Now read more data from disk if there is more to be read if ((_bufferLeft == 0) && (_diskLeft > 0)) { int32 readAmount = MIN(_diskLeft, BUFFER_SIZE); @@ -315,6 +314,14 @@ int LinearDiskStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffe // original position. restoreFilePosition = true; } + + // Looping + if (_diskLeft == 0 && _loop) { + // Reset the stream + _currentBlock = 0; + _filePos = _audioBlock[_currentBlock].pos + _beginLoop; + _diskLeft = _audioBlock[_currentBlock].len; + } } // In case calling code relies on the position of this stream staying @@ -399,19 +406,19 @@ AudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate, byte f #define MAKE_LINEAR_DISK(STEREO, UNSIGNED) \ if (is16Bit) { \ if (isLE) \ - return new LinearDiskStream<STEREO, true, UNSIGNED, true>(rate, loopStart, loopEnd, takeOwnership, &stream, block, numBlocks); \ + return new LinearDiskStream<STEREO, true, UNSIGNED, true>(rate, loopStart, loopEnd, takeOwnership, stream, block, numBlocks, loop); \ else \ - return new LinearDiskStream<STEREO, true, UNSIGNED, false>(rate, loopStart, loopEnd, takeOwnership, &stream, block, numBlocks); \ + return new LinearDiskStream<STEREO, true, UNSIGNED, false>(rate, loopStart, loopEnd, takeOwnership, stream, block, numBlocks, loop); \ } else \ - return new LinearDiskStream<STEREO, false, UNSIGNED, false>(rate, loopStart, loopEnd, takeOwnership, &stream, block, numBlocks) + return new LinearDiskStream<STEREO, false, UNSIGNED, false>(rate, loopStart, loopEnd, takeOwnership, stream, block, numBlocks, loop) -AudioStream *makeLinearDiskStream(Common::SeekableReadStream& stream, LinearDiskStreamAudioBlock* block, int numBlocks, int rate, byte flags, bool takeOwnership, uint loopStart, uint loopEnd) { +AudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, int numBlocks, int rate, byte flags, bool takeOwnership, uint loopStart, uint loopEnd) { const bool isStereo = (flags & Audio::Mixer::FLAG_STEREO) != 0; const bool is16Bit = (flags & Audio::Mixer::FLAG_16BITS) != 0; const bool isUnsigned = (flags & Audio::Mixer::FLAG_UNSIGNED) != 0; const bool isLE = (flags & Audio::Mixer::FLAG_LITTLE_ENDIAN) != 0; - + const bool loop = (flags & Audio::Mixer::FLAG_LOOP) != 0; if (isStereo) { if (isUnsigned) { diff --git a/sound/audiostream.h b/sound/audiostream.h index 99e140608d..09b97374d5 100644 --- a/sound/audiostream.h +++ b/sound/audiostream.h @@ -133,7 +133,7 @@ struct LinearDiskStreamAudioBlock { * start position and length of each block of uncompressed audio in the stream. */ -AudioStream *makeLinearDiskStream(Common::SeekableReadStream& stream, LinearDiskStreamAudioBlock* block, int +AudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, int numBlocks, int rate, byte flags, bool disposeStream, uint loopStart, uint loopEnd); /** diff --git a/sound/mods/maxtrax.cpp b/sound/mods/maxtrax.cpp index 1cdbdcc24c..90ac3d55ca 100644 --- a/sound/mods/maxtrax.cpp +++ b/sound/mods/maxtrax.cpp @@ -983,7 +983,7 @@ allocError: if (!errorMsg) errorMsg = "Maxtrax: Could not allocate Memory"; - warning(errorMsg); + warning("%s", errorMsg); if (loadSamples) freePatches(); if (loadScores) diff --git a/sound/mods/tfmx.cpp b/sound/mods/tfmx.cpp index a7490c3f86..2ef7d79b7a 100644 --- a/sound/mods/tfmx.cpp +++ b/sound/mods/tfmx.cpp @@ -1097,7 +1097,7 @@ int Tfmx::doSfx(uint16 sfxIndex, bool unlockChannel) { // some debugging functions namespace { -#ifndef NDEBUG +#if !defined(NDEBUG) && 0 void displayMacroStep(const void *const vptr) { const char *tableMacros[] = { "DMAoff+Resetxx/xx/xx flag/addset/vol ", diff --git a/sound/shorten.h b/sound/shorten.h index c2a40280d3..bc9f229687 100644 --- a/sound/shorten.h +++ b/sound/shorten.h @@ -23,13 +23,15 @@ * */ -// The code in this file is currently only used in SAGA2 (in the -// SAGA engine), so if that engine isn't enabled, we will skip -// compiling it. If you plan to use this code in another engine, -// you will have to add the proper define check here. -// Also please add the define check at the comment after the -// matching #endif further down this file. -#if defined(ENABLE_SAGA2) +// The code in this file is currently only used in SAGA2. +// So when it is disabled, we will skip compiling it. +// We also enable this code for ScummVM builds including support +// for dynamic engine plugins. +// If you plan to use this code in another engine, you will have +// to add the proper define check here. +#if !(defined(ENABLE_SAGA2) || defined(DYNAMIC_MODULES)) + +#else #ifndef SOUND_SHORTEN_H #define SOUND_SHORTEN_H @@ -48,7 +50,7 @@ class AudioStream; * start of the audio data, and size, rate and flags contain information * necessary for playback. */ -extern byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, byte &flags); +byte *loadShortenFromStream(Common::ReadStream &stream, int &size, int &rate, byte &flags); /** * Try to load a Shorten file from the given stream and create an AudioStream @@ -62,6 +64,5 @@ AudioStream *makeShortenStream(Common::ReadStream &stream); #endif -#endif // defined(ENABLE_SAGA2) - +#endif // engine and dynamic plugins guard diff --git a/sound/voc.cpp b/sound/voc.cpp index a332477f3c..a5bab0af29 100644 --- a/sound/voc.cpp +++ b/sound/voc.cpp @@ -292,7 +292,7 @@ AudioStream *makeVOCDiskStream(Common::SeekableReadStream &stream, byte flags, b int numBlocks = parseVOCFormat(stream, block, rate, loops, begin_loop, end_loop); - AudioStream* audioStream = makeLinearDiskStream(stream, block, numBlocks, rate, flags, takeOwnership, begin_loop, end_loop); + AudioStream *audioStream = makeLinearDiskStream(&stream, block, numBlocks, rate, flags, takeOwnership, begin_loop, end_loop); delete[] block; diff --git a/test/module.mk b/test/module.mk index 64cb34c7ac..79a1a12023 100644 --- a/test/module.mk +++ b/test/module.mk @@ -22,7 +22,7 @@ TEST_LDFLAGS := test: test/runner ./test/runner test/runner: test/runner.cpp $(TEST_LIBS) - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TEST_LDFLAGS) $(TEST_CFLAGS) -o $@ $+ + $(QUIET_LINK)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TEST_LDFLAGS) $(TEST_CFLAGS) -o $@ $+ test/runner.cpp: $(TESTS) @mkdir -p test $(srcdir)/test/cxxtest/cxxtestgen.py $(TEST_FLAGS) -o $@ $+ diff --git a/tools/credits.pl b/tools/credits.pl index 2b1b93e87b..dbe098a652 100755 --- a/tools/credits.pl +++ b/tools/credits.pl @@ -646,6 +646,10 @@ begin_credits("Credits"); add_person("Oystein Eftevaag", "vinterstum", ""); end_section(); + begin_section("LinuxMoto"); + add_person("Lubomyr Lisen", "", ""); + end_section(); + begin_section("Maemo"); add_person("Frantisek Dufka", "fanoush", ""); end_section(); @@ -832,6 +836,7 @@ begin_credits("Credits"); add_person("Andreas Karlsson", "Sprawl", "Initial port for SymbianOS"); add_person("Claudio Matsuoka", "", "Daily Linux builds"); add_person("Thomas Mayer", "", "PSP port contributions"); + add_person("Yotam Barnoy", "bluddy", "PSP port suspend/resume support"); add_person("Sean Murray", "lightcast", "ScummVM tools GUI application (GSoC 2007 task)"); add_person("", "n0p", "Windows CE port aspect ratio correction scaler and right click input method"); add_person("Mikesch Nepomuk", "mnepomuk", "MI1 VGA floppy patches"); diff --git a/tools/module.mk b/tools/module.mk index 9ad972f477..4c1ea57da6 100644 --- a/tools/module.mk +++ b/tools/module.mk @@ -33,16 +33,16 @@ clean-tools: # tools/convbdf$(EXEEXT): $(srcdir)/tools/convbdf.c - $(MKDIR) tools/$(DEPDIR) - $(CC) $(CFLAGS) -Wall -o $@ $< + $(QUIET)$(MKDIR) tools/$(DEPDIR) + $(QUIET_LINK)$(CC) $(CFLAGS) -Wall -o $@ $< tools/md5table$(EXEEXT): $(srcdir)/tools/md5table.c - $(MKDIR) tools/$(DEPDIR) - $(CC) $(CFLAGS) -Wall -o $@ $< + $(QUIET)$(MKDIR) tools/$(DEPDIR) + $(QUIET_LINK)$(CC) $(CFLAGS) -Wall -o $@ $< tools/make-scumm-fontdata$(EXEEXT): $(srcdir)/tools/make-scumm-fontdata.c - $(MKDIR) tools/$(DEPDIR) - $(CC) $(CFLAGS) -Wall -o $@ $< + $(QUIET)$(MKDIR) tools/$(DEPDIR) + $(QUIET_LINK)$(CC) $(CFLAGS) -Wall -o $@ $< # # Rules to explicitly rebuild the credits / MD5 tables. diff --git a/tools/skycpt/Makefile b/tools/skycpt/Makefile index bfa9937519..b907e6782d 100644 --- a/tools/skycpt/Makefile +++ b/tools/skycpt/Makefile @@ -9,10 +9,10 @@ OBJS=AsciiCptCompile.o cptcompiler.o cpthelp.o idFinder.o KmpSearch.o stdafx.o T all: $(TARGET) clean: - rm -f $(TARGET) $(OBJS) + $(QUIET)$(RM) $(TARGET) $(OBJS) $(TARGET): $(OBJS) - $(CC) $(OBJS) $(LDFLAGS) -o $(TARGET) + $(QUIET_CXX)$(CXX) $(OBJS) $(LDFLAGS) -o $(TARGET) %.o: %.cpp - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
\ No newline at end of file + $(QUIET_CXX)$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ |