diff options
112 files changed, 2967 insertions, 1687 deletions
diff --git a/Makefile.common b/Makefile.common index cea30a5f9f..824139b0bd 100644 --- a/Makefile.common +++ b/Makefile.common @@ -148,25 +148,6 @@ endif ###################################################################### -# Create the files that depend on the version -###################################################################### - -VERSION_FILES = \ - $(srcdir)/dists/iphone/Info.plist \ - $(srcdir)/dists/macosx/Info.plist - -$(VERSION_FILES): %: %.in - @echo "Creating $@" - @cat $< | sed \ - -e "s/@VER_MAJOR@/$(VER_MAJOR)/g" \ - -e "s/@VER_MINOR@/$(VER_MINOR)/g" \ - -e "s/@VER_PATCH@/$(VER_PATCH)/g" \ - -e "s/@VER_EXTRA@/$(VER_EXTRA)/g" \ - -e "s/@VERSION@/$(VERSION)/g" \ - > $@ - - -###################################################################### # Distribution settings ###################################################################### @@ -58,6 +58,11 @@ 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. + WinCE port: + - Speed optimized versions of low-res Smartphone and 2x scalers. + - New aspect correction scaler for VGA (or higher) devices. + - Dropped support for MPEG-2 and FLAC. + 0.13.1 (2009-04-27) AGOS: - Fixed crash after OmniTV video is played in The Feeble Files. diff --git a/backends/platform/gp2x/events.cpp b/backends/platform/gp2x/events.cpp index 8cd034d2d5..bc9a4ff26c 100644 --- a/backends/platform/gp2x/events.cpp +++ b/backends/platform/gp2x/events.cpp @@ -93,7 +93,7 @@ void OSystem_GP2X::fillMouseEvent(Common::Event &event, int x, int y) { if (!_overlayVisible) { event.mouse.x /= _videoMode.scaleFactor; event.mouse.y /= _videoMode.scaleFactor; - if (_videoMode.aspectRatio) + if (_videoMode.aspectRatioCorrection) event.mouse.y = aspect2Real(event.mouse.y); } } diff --git a/backends/platform/gp2x/gp2x-common.h b/backends/platform/gp2x/gp2x-common.h index 7341b0646f..4e6421f353 100644 --- a/backends/platform/gp2x/gp2x-common.h +++ b/backends/platform/gp2x/gp2x-common.h @@ -42,18 +42,7 @@ namespace Audio { } enum { - GFX_NORMAL = 0, - GFX_DOUBLESIZE = 1, - GFX_TRIPLESIZE = 2, - GFX_2XSAI = 3, - GFX_SUPER2XSAI = 4, - GFX_SUPEREAGLE = 5, - GFX_ADVMAME2X = 6, - GFX_ADVMAME3X = 7, - GFX_HQ2X = 8, - GFX_HQ3X = 9, - GFX_TV2X = 10, - GFX_DOTMATRIX = 11 + GFX_NORMAL = 0 }; @@ -248,7 +237,7 @@ protected: bool setup; bool fullscreen; - bool aspectRatio; + bool aspectRatioCorrection; int mode; int scaleFactor; @@ -274,16 +263,11 @@ protected: bool _modeChanged; int _screenChangeCount; - /** True if aspect ratio correction is enabled. */ - bool _adjustAspectRatio; - - /** True if zoom on mouse is enabled. (only set by > 240 high games) */ + /* True if zoom on mouse is enabled. (only set by > 240 high games) */ bool _adjustZoomOnMouse; - //_adjustZoomOnMouse = false; enum { NUM_DIRTY_RECT = 100, - MAX_MOUSE_W = 80, MAX_MOUSE_H = 80, MAX_SCALING = 3 @@ -332,7 +316,7 @@ protected: // mouse KbdMouse _km; bool _mouseVisible; - bool _mouseDrawn; + bool _mouseNeedsRedraw; byte *_mouseData; SDL_Rect _mouseBackup; MousePos _mouseCurState; @@ -419,7 +403,7 @@ protected: bool saveScreenshot(const char *filename); int effectiveScreenHeight() const { - return (_videoMode.aspectRatio ? real2Aspect(_videoMode.screenHeight) : _videoMode.screenHeight) + return (_videoMode.aspectRatioCorrection ? real2Aspect(_videoMode.screenHeight) : _videoMode.screenHeight) * _videoMode.scaleFactor; } diff --git a/backends/platform/gp2x/gp2x-hw.cpp b/backends/platform/gp2x/gp2x-hw.cpp index 38799ea7ad..2dc5b4f579 100644 --- a/backends/platform/gp2x/gp2x-hw.cpp +++ b/backends/platform/gp2x/gp2x-hw.cpp @@ -56,7 +56,7 @@ enum { VOLUME_UP = 2, VOLUME_CHANGE_RATE = 8, VOLUME_MIN = 0, - VOLUME_INITIAL = 70, + VOLUME_INITIAL = 60, VOLUME_MAX = 100 }; diff --git a/backends/platform/gp2x/gp2x-mem.cpp b/backends/platform/gp2x/gp2x-mem.cpp index ec73922bf7..97a34ffb6a 100644 --- a/backends/platform/gp2x/gp2x-mem.cpp +++ b/backends/platform/gp2x/gp2x-mem.cpp @@ -37,7 +37,7 @@ #include <unistd.h> #include <string.h> -#include "gp2x-mem.h" +#include "backends/platform/gp2x/gp2x-mem.h" void SetClock (unsigned c) { diff --git a/backends/platform/gp2x/gp2x-mem.h b/backends/platform/gp2x/gp2x-mem.h index 2b64cdb802..24b2a3f569 100644 --- a/backends/platform/gp2x/gp2x-mem.h +++ b/backends/platform/gp2x/gp2x-mem.h @@ -35,7 +35,6 @@ extern "C" { #endif - // Use Squidge's MMU patch rather then myown (his is neater). // The effect if not that great but cacheing the upper RAM is no bad thing (tm) ;). diff --git a/backends/platform/gp2x/gp2x.cpp b/backends/platform/gp2x/gp2x.cpp index 3d416f8415..21a047b345 100644 --- a/backends/platform/gp2x/gp2x.cpp +++ b/backends/platform/gp2x/gp2x.cpp @@ -131,8 +131,6 @@ void OSystem_GP2X::initBackend() { ConfMan.registerDefault("savepath", savePath); - _savefile = new DefaultSaveFileManager(savePath); - #ifdef DUMP_STDOUT // The GP2X has a serial console but most users do not use this so we // output all our STDOUT and STDERR to files for debug purposes. @@ -186,9 +184,9 @@ void OSystem_GP2X::initBackend() { ConfMan.registerDefault("aspect_ratio", true); /* Up default volume values as we use a seperate system level volume anyway. */ - ConfMan.registerDefault("music_volume", 220); - ConfMan.registerDefault("sfx_volume", 220); - ConfMan.registerDefault("speech_volume", 220); + ConfMan.registerDefault("music_volume", 192); + ConfMan.registerDefault("sfx_volume", 192); + ConfMan.registerDefault("speech_volume", 192); ConfMan.registerDefault("autosave_period", 3 * 60); // Trigger autosave every 3 minutes - On low batts 4 mins is about your warning time. memset(&_oldVideoMode, 0, sizeof(_oldVideoMode)); @@ -199,7 +197,7 @@ void OSystem_GP2X::initBackend() { _videoMode.mode = GFX_NORMAL; _videoMode.scaleFactor = 1; _scalerProc = Normal1x; - _videoMode.aspectRatio = ConfMan.getBool("aspect_ratio"); + _videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio"); _scalerType = 0; _modeFlags = 0; _adjustZoomOnMouse = false; @@ -210,17 +208,13 @@ void OSystem_GP2X::initBackend() { _joystick = SDL_JoystickOpen(joystick_num); } + _savefile = new DefaultSaveFileManager(); // Create and hook up the mixer, if none exists yet (we check for this to // allow subclasses to provide their own). if (_mixer == 0) { setupMixer(); } - // Setup the keymapper with backend's set of keys - // NOTE: must be done before creating TimerManager - // to avoid race conditions in creating EventManager - setupKeymapper(); - // Create and hook up the timer manager, if none exists yet (we check for // this to allow subclasses to provide their own). if (_timer == 0) { @@ -241,27 +235,6 @@ void OSystem_GP2X::initBackend() { /* Set Default hardware mixer volume to a preset level (VOLUME_INITIAL). This is done to 'reset' volume level if set by other apps. */ GP2X_HW::mixerMoveVolume(0); - // Set Default hardware mixer volume to a plesent level. - // This is done to 'reset' volume level if set by other apps. - - //if (SDL_GP2X_MouseType() == 0) { - // // No mouse, F100 default state. - // _gp2xInputType = 0; - // displayMessageOnOSD("F100 GP2X Found"); - //} - - //if (SDL_GP2X_MouseType() == 1) { - // // USB mouse found. - // _gp2xInputType = 1; - // displayMessageOnOSD("USB Mouse Found"); - //} - - //if (SDL_GP2X_MouseType() == 2) { - // // F200 touch screen found. - F200 default state. - // _gp2xInputType = 2; - // displayMessageOnOSD("Touch Screen Found"); - //} - OSystem::initBackend(); _inited = true; @@ -275,7 +248,7 @@ OSystem_GP2X::OSystem_GP2X() _overlayscreen(0), _tmpscreen2(0), _samplesPerSec(0), _cdrom(0), _scalerProc(0), _modeChanged(false), _screenChangeCount(0), _dirtyChecksums(0), - _mouseVisible(false), _mouseDrawn(false), _mouseData(0), _mouseSurface(0), + _mouseVisible(false), _mouseNeedsRedraw(false), _mouseData(0), _mouseSurface(0), _mouseOrigSurface(0), _cursorTargetScale(1), _cursorPaletteDisabled(true), _joystick(0), _currentShakePos(0), _newShakePos(0), @@ -434,7 +407,7 @@ bool OSystem_GP2X::getFeatureState(Feature f) { case kFeatureFullscreenMode: return false; case kFeatureAspectRatioCorrection: - return _videoMode.aspectRatio; + return _videoMode.aspectRatioCorrection; case kFeatureAutoComputeDirtyRects: return _modeFlags & DF_WANT_RECT_OPTIM; default: @@ -458,12 +431,12 @@ void OSystem_GP2X::quit() { free(_cursorPalette); free(_mouseData); - delete _savefile; delete _timer; SDL_ShowCursor(SDL_ENABLE); SDL_Quit(); delete getEventManager(); + delete _savefile; #ifdef DUMP_STDOUT printf("%s\n", "Debug: STDOUT and STDERR text files closed."); @@ -610,7 +583,7 @@ void OSystem_GP2X::setupMixer() { _samplesPerSec = SAMPLES_PER_SEC; //Quick EVIL Hack - DJWillis - _samplesPerSec = 11025; +// _samplesPerSec = 11025; // Determine the sample buffer size. We want it to store enough data for // about 1/16th of a second. Note that it must be a power of two. diff --git a/backends/platform/gp2x/graphics.cpp b/backends/platform/gp2x/graphics.cpp index a77afd88b7..229f840d11 100644 --- a/backends/platform/gp2x/graphics.cpp +++ b/backends/platform/gp2x/graphics.cpp @@ -37,7 +37,7 @@ #include "graphics/surface.h" static const OSystem::GraphicsMode s_supportedGraphicsModes[] = { - {"GP2X Graphics Mode", "1x", GFX_NORMAL}, + {"Fullscreen", "1x", GFX_NORMAL}, {0, 0, 0} }; @@ -50,14 +50,7 @@ static ScalerProc *scalersMagn[3][3] = { }; static const int s_gfxModeSwitchTable[][4] = { - { GFX_NORMAL, GFX_DOUBLESIZE, GFX_TRIPLESIZE, -1 }, - { GFX_NORMAL, GFX_ADVMAME2X, GFX_ADVMAME3X, -1 }, - { GFX_NORMAL, GFX_HQ2X, GFX_HQ3X, -1 }, - { GFX_NORMAL, GFX_2XSAI, -1, -1 }, - { GFX_NORMAL, GFX_SUPER2XSAI, -1, -1 }, - { GFX_NORMAL, GFX_SUPEREAGLE, -1, -1 }, - { GFX_NORMAL, GFX_TV2X, -1, -1 }, - { GFX_NORMAL, GFX_DOTMATRIX, -1, -1 } + { GFX_NORMAL } }; static int cursorStretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY); @@ -95,10 +88,10 @@ OSystem::TransactionError OSystem_GP2X::endGFXTransaction(void) { errors |= kTransactionFullscreenFailed; _videoMode.fullscreen = _oldVideoMode.fullscreen; - } else if (_videoMode.aspectRatio != _oldVideoMode.aspectRatio) { + } else if (_videoMode.aspectRatioCorrection != _oldVideoMode.aspectRatioCorrection) { errors |= kTransactionAspectRatioFailed; - _videoMode.aspectRatio = _oldVideoMode.aspectRatio; + _videoMode.aspectRatioCorrection = _oldVideoMode.aspectRatioCorrection; } else if (_videoMode.mode != _oldVideoMode.mode) { errors |= kTransactionModeSwitchFailed; @@ -114,7 +107,7 @@ OSystem::TransactionError OSystem_GP2X::endGFXTransaction(void) { } if (_videoMode.fullscreen == _oldVideoMode.fullscreen && - _videoMode.aspectRatio == _oldVideoMode.aspectRatio && + _videoMode.aspectRatioCorrection == _oldVideoMode.aspectRatioCorrection && _videoMode.mode == _oldVideoMode.mode && _videoMode.screenWidth == _oldVideoMode.screenWidth && _videoMode.screenHeight == _oldVideoMode.screenHeight) { @@ -190,45 +183,6 @@ bool OSystem_GP2X::setGraphicsMode(int mode) { case GFX_NORMAL: newScaleFactor = 1; break; -#ifndef DISABLE_SCALERS - case GFX_DOUBLESIZE: - newScaleFactor = 2; - break; - case GFX_TRIPLESIZE: - newScaleFactor = 3; - break; - - case GFX_2XSAI: - newScaleFactor = 2; - break; - case GFX_SUPER2XSAI: - newScaleFactor = 2; - break; - case GFX_SUPEREAGLE: - newScaleFactor = 2; - break; - case GFX_ADVMAME2X: - newScaleFactor = 2; - break; - case GFX_ADVMAME3X: - newScaleFactor = 3; - break; -#ifndef DISABLE_HQ_SCALERS - case GFX_HQ2X: - newScaleFactor = 2; - break; - case GFX_HQ3X: - newScaleFactor = 3; - break; -#endif - case GFX_TV2X: - newScaleFactor = 2; - break; - case GFX_DOTMATRIX: - newScaleFactor = 2; - break; -#endif // DISABLE_SCALERS - default: warning("unknown gfx mode %d", mode); return false; @@ -246,7 +200,6 @@ bool OSystem_GP2X::setGraphicsMode(int mode) { return true; } - void OSystem_GP2X::setGraphicsModeIntern() { Common::StackLock lock(_graphicsMutex); ScalerProc *newScalerProc = 0; @@ -255,44 +208,6 @@ void OSystem_GP2X::setGraphicsModeIntern() { case GFX_NORMAL: newScalerProc = Normal1x; break; -#ifndef DISABLE_SCALERS - case GFX_DOUBLESIZE: - newScalerProc = Normal2x; - break; - case GFX_TRIPLESIZE: - newScalerProc = Normal3x; - break; - - case GFX_2XSAI: - newScalerProc = _2xSaI; - break; - case GFX_SUPER2XSAI: - newScalerProc = Super2xSaI; - break; - case GFX_SUPEREAGLE: - newScalerProc = SuperEagle; - break; - case GFX_ADVMAME2X: - newScalerProc = AdvMame2x; - break; - case GFX_ADVMAME3X: - newScalerProc = AdvMame3x; - break; -#ifndef DISABLE_HQ_SCALERS - case GFX_HQ2X: - newScalerProc = HQ2x; - break; - case GFX_HQ3X: - newScalerProc = HQ3x; - break; -#endif - case GFX_TV2X: - newScalerProc = TV2x; - break; - case GFX_DOTMATRIX: - newScalerProc = DotMatrix; - break; -#endif // DISABLE_SCALERS default: error("Unknown gfx mode %d", _videoMode.mode); @@ -353,18 +268,28 @@ bool OSystem_GP2X::loadGFXMode() { _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor; if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400) - _videoMode.aspectRatio = false; + _videoMode.aspectRatioCorrection = false; - if (_videoMode.aspectRatio) + if (_videoMode.aspectRatioCorrection) _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight); hwW = _videoMode.screenWidth * _videoMode.scaleFactor; - hwH = effectiveScreenHeight(); + + if (_videoMode.screenHeight == 200) { + hwH = 240; + } else if (_videoMode.screenHeight == 400) { + hwH = 480; + } else { + hwH = _videoMode.screenHeight; + } + + printf ("Game Screen Height: %d\n", hwH); // - // Create the surface that contains the 8 bit game data + // Create the surface that contains the game data // - _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0); + + _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, hwH, 8, 0, 0, 0, 0); if (_screen == NULL) error("allocating _screen failed"); @@ -372,9 +297,7 @@ bool OSystem_GP2X::loadGFXMode() { // Create the surface that contains the scaled graphics in 16 bit mode // - _hwscreen = SDL_SetVideoMode(hwW, hwH, 16, - _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE - ); + _hwscreen = SDL_SetVideoMode(hwW, hwH, 16, SDL_SWSURFACE | SDL_NOFRAME | SDL_FULLSCREEN); if (_hwscreen == NULL) { // DON'T use error(), as this tries to bring up the debug // console, which WON'T WORK now that _hwscreen is hosed. @@ -395,12 +318,6 @@ bool OSystem_GP2X::loadGFXMode() { // Create the surface used for the graphics in 16 bit before scaling, and also the overlay // - // Distinguish 555 and 565 mode - if (_hwscreen->format->Rmask == 0x7C00) - InitScalers(555); - else - InitScalers(565); - // Need some extra bytes around when using 2xSaI _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3, 16, @@ -462,6 +379,12 @@ bool OSystem_GP2X::loadGFXMode() { _km.delay_time = 25; _km.last_time = 0; + // Distinguish 555 and 565 mode + if (_hwscreen->format->Rmask == 0x7C00) + InitScalers(555); + else + InitScalers(565); + return true; } @@ -571,7 +494,7 @@ void OSystem_GP2X::internUpdateScreen() { if (_currentShakePos != _newShakePos) { SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor}; - if (_videoMode.aspectRatio && !_overlayVisible) + if (_videoMode.aspectRatioCorrection && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwscreen, &blackrect, 0); @@ -627,6 +550,11 @@ void OSystem_GP2X::internUpdateScreen() { scale1 = 1; } + // Add the area covered by the mouse cursor to the list of dirty rects if + // we have to redraw the mouse. + if (_mouseNeedsRedraw) + undrawMouse(); + // Force a full redraw if requested if (_forceFull) { _numDirtyRects = 1; @@ -634,12 +562,10 @@ void OSystem_GP2X::internUpdateScreen() { _dirtyRectList[0].y = 0; _dirtyRectList[0].w = width; _dirtyRectList[0].h = height; - } else - undrawMouse(); + } // Only draw anything if necessary - if (_numDirtyRects > 0) { - + if (_numDirtyRects > 0 || _mouseNeedsRedraw) { SDL_Rect *r; SDL_Rect dst; uint32 srcPitch, dstPitch; @@ -647,7 +573,7 @@ void OSystem_GP2X::internUpdateScreen() { for (r = _dirtyRectList; r != lastRect; ++r) { dst = *r; - dst.x++; // Shift rect by one since 2xSai needs to acces the data around + dst.x++; // Shift rect by one since 2xSai needs to access the data around dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0) @@ -674,7 +600,7 @@ void OSystem_GP2X::internUpdateScreen() { orig_dst_y = dst_y; dst_y = dst_y * scale1; - if (_videoMode.aspectRatio && !_overlayVisible) + if (_videoMode.aspectRatioCorrection && !_overlayVisible) dst_y = real2Aspect(dst_y); assert(scalerProc != NULL); @@ -687,10 +613,8 @@ void OSystem_GP2X::internUpdateScreen() { r->w = r->w * scale1; r->h = dst_h * scale1; -#ifndef DISABLE_SCALERS - if (_videoMode.aspectRatio && orig_dst_y < height && !_overlayVisible) + if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible) r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); -#endif } SDL_UnlockSurface(srcSurf); SDL_UnlockSurface(_hwscreen); @@ -710,14 +634,11 @@ void OSystem_GP2X::internUpdateScreen() { // Finally, blit all our changes to the screen SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); - } else { - drawMouse(); - if (_numDirtyRects) - SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); } _numDirtyRects = 0; _forceFull = false; + _mouseNeedsRedraw = false; } bool OSystem_GP2X::saveScreenshot(const char *filename) { @@ -740,18 +661,14 @@ void OSystem_GP2X::setFullscreenMode(bool enable) { } void OSystem_GP2X::setAspectRatioCorrection(bool enable) { - if ((_videoMode.screenHeight == 200 && _videoMode.aspectRatio != enable) || - _transactionMode == kTransactionActive) { - - Common::StackLock lock(_graphicsMutex); + Common::StackLock lock(_graphicsMutex); - if (_oldVideoMode.setup && _oldVideoMode.aspectRatio == enable) - return; + if (_oldVideoMode.setup && _oldVideoMode.aspectRatioCorrection == enable) + return; - if (_transactionMode == kTransactionActive) { - _videoMode.aspectRatio = enable; - _transactionDetails.needHotswap = true; - } + if (_transactionMode == kTransactionActive) { + _videoMode.aspectRatioCorrection = enable; + _transactionDetails.needHotswap = true; } } @@ -776,12 +693,12 @@ void OSystem_GP2X::copyRectToScreen(const byte *src, int pitch, int x, int y, in Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends -// assert(x >= 0 && x < _screenWidth); -// assert(y >= 0 && y < _screenHeight); -// assert(h > 0 && y + h <= _screenHeight); -// assert(w > 0 && x + w <= _screenWidth); + assert(x >= 0 && x < _videoMode.screenWidth); + assert(y >= 0 && y < _videoMode.screenHeight); + assert(h > 0 && y + h <= _videoMode.screenHeight); + assert(w > 0 && x + w <= _videoMode.screenWidth); - if (((long)src & 3) == 0 && pitch == _videoMode.screenWidth && x == 0 && y == 0 && + if (IS_ALIGNED(src, 4) && pitch == _videoMode.screenWidth && x == 0 && y == 0 && w == _videoMode.screenWidth && h == _videoMode.screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) { /* Special, optimized case for full screen updates. * It tries to determine what areas were actually changed, @@ -923,7 +840,7 @@ void OSystem_GP2X::addDirtyRect(int x, int y, int w, int h, bool realCoordinates h = height - y; } - if (_videoMode.aspectRatio && !_overlayVisible && !realCoordinates) { + if (_videoMode.aspectRatioCorrection && !_overlayVisible && !realCoordinates) { makeRectStretchable(x, y, w, h); } @@ -982,7 +899,7 @@ void OSystem_GP2X::makeChecksums(const byte *buf) { void OSystem_GP2X::addDirtyRgnAuto(const byte *buf) { assert(buf); - assert(((long)buf & 3) == 0); + assert(IS_ALIGNED(buf, 4)); /* generate a table of the checksums */ makeChecksums(buf); @@ -1115,7 +1032,7 @@ void OSystem_GP2X::showOverlay() { // Since resolution could change, put mouse to adjusted position // Fixes bug #1349059 x = _mouseCurState.x * _videoMode.scaleFactor; - if (_videoMode.aspectRatio) + if (_videoMode.aspectRatioCorrection) y = real2Aspect(_mouseCurState.y) * _videoMode.scaleFactor; else y = _mouseCurState.y * _videoMode.scaleFactor; @@ -1139,7 +1056,7 @@ void OSystem_GP2X::hideOverlay() { // Fixes bug #1349059 x = _mouseCurState.x / _videoMode.scaleFactor; y = _mouseCurState.y / _videoMode.scaleFactor; - if (_videoMode.aspectRatio) + if (_videoMode.aspectRatioCorrection) y = aspect2Real(y); warpMouse(x, y); @@ -1172,7 +1089,7 @@ void OSystem_GP2X::clearOverlay() { (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _videoMode.screenWidth, _videoMode.screenHeight); #ifndef DISABLE_SCALERS - if (_videoMode.aspectRatio) + if (_videoMode.aspectRatioCorrection) stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch, _videoMode.overlayWidth, _videoMode.screenHeight * _videoMode.scaleFactor, 0, 0, 0); #endif @@ -1259,12 +1176,14 @@ bool OSystem_GP2X::showMouse(bool visible) { bool last = _mouseVisible; _mouseVisible = visible; + _mouseNeedsRedraw = true; return last; } void OSystem_GP2X::setMousePos(int x, int y) { if (x != _mouseCurState.x || y != _mouseCurState.y) { + _mouseNeedsRedraw = true; _mouseCurState.x = x; _mouseCurState.y = y; } @@ -1273,7 +1192,7 @@ void OSystem_GP2X::setMousePos(int x, int y) { void OSystem_GP2X::warpMouse(int x, int y) { int y1 = y; - if (_adjustAspectRatio && !_overlayVisible) + if (_videoMode.aspectRatioCorrection && !_overlayVisible) y1 = real2Aspect(y); if (_mouseCurState.x != x || _mouseCurState.y != y) { @@ -1342,6 +1261,8 @@ void OSystem_GP2X::blitCursor() { if (!_mouseOrigSurface || !_mouseData) return; + _mouseNeedsRedraw = true; + w = _mouseCurState.w; h = _mouseCurState.h; @@ -1422,7 +1343,7 @@ void OSystem_GP2X::blitCursor() { int rH1 = rH; // store original to pass to aspect-correction function later - if (_videoMode.aspectRatio && _cursorTargetScale == 1) { + if (_videoMode.aspectRatioCorrection && _cursorTargetScale == 1) { rH = real2Aspect(rH - 1) + 1; _mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY); } @@ -1453,20 +1374,17 @@ void OSystem_GP2X::blitCursor() { ScalerProc *scalerProc; - // If possible, use the same scaler for the cursor as for the rest of - // the game. This only works well with the non-blurring scalers so we - // actually only use the 1x, 1.5x, 2x and AdvMame scalers. - - if (_cursorTargetScale == 1 && (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE)) - scalerProc = _scalerProc; - else + if (_cursorTargetScale == 1 && _videoMode.screenWidth > 320) { + scalerProc = scalersMagn[_cursorTargetScale + 1][_videoMode.scaleFactor + 1]; + } else { scalerProc = scalersMagn[_cursorTargetScale - 1][_videoMode.scaleFactor - 1]; + } scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2, _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch, _mouseCurState.w, _mouseCurState.h); - if (_videoMode.aspectRatio && _cursorTargetScale == 1) + if (_videoMode.aspectRatioCorrection && _cursorTargetScale == 1) cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0); SDL_UnlockSurface(_mouseSurface); @@ -1506,9 +1424,8 @@ void OSystem_GP2X::undrawMouse() { // When we switch bigger overlay off mouse jumps. Argh! // This is intended to prevent undrawing offscreen mouse - if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight)) { + if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight)) return; - } if (_mouseBackup.w != 0 && _mouseBackup.h != 0) addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h); @@ -1575,7 +1492,7 @@ void OSystem_GP2X::drawMouse() { dst.y += _currentShakePos; } - if (_videoMode.aspectRatio && !_overlayVisible) + if (_videoMode.aspectRatioCorrection && !_overlayVisible) dst.y = real2Aspect(dst.y); dst.x = scale * dst.x - _mouseCurState.rHotX; @@ -1584,7 +1501,6 @@ void OSystem_GP2X::drawMouse() { dst.h = _mouseCurState.rH; // Hacking about with the zoom around mouse pointer stuff. - if (_adjustZoomOnMouse == true){ zoomdst.w = (tmpScreenWidth / 2); @@ -1623,7 +1539,6 @@ void OSystem_GP2X::drawMouse() { SDL_GP2X_Display(&zoomdst); }; - // Note that SDL_BlitSurface() and addDirtyRect() will both perform any // clipping necessary @@ -1730,10 +1645,10 @@ void OSystem_GP2X::handleScalerHotkeys(const SDL_KeyboardEvent &key) { // Ctrl-Alt-a toggles aspect ratio correction if (key.keysym.sym == 'a') { beginGFXTransaction(); - setFeatureState(kFeatureAspectRatioCorrection, !_videoMode.aspectRatio); + setFeatureState(kFeatureAspectRatioCorrection, !_videoMode.aspectRatioCorrection); endGFXTransaction(); char buffer[128]; - if (_videoMode.aspectRatio) + if (_videoMode.aspectRatioCorrection) sprintf(buffer, "Enabled aspect ratio correction\n%d x %d -> %d x %d", _videoMode.screenWidth, _videoMode.screenHeight, _hwscreen->w, _hwscreen->h diff --git a/backends/platform/gp2x/module.mk b/backends/platform/gp2x/module.mk index 58dfd24ee6..50a771219a 100644 --- a/backends/platform/gp2x/module.mk +++ b/backends/platform/gp2x/module.mk @@ -6,8 +6,6 @@ MODULE_OBJS := \ events.o \ graphics.o \ gp2x.o \ -# gp2x-options.o \ -# overload_help.o \ MODULE_DIRS += \ backends/platform/gp2x/ diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp index 8768dd90d4..efcade834d 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/platform/sdl/graphics.cpp @@ -475,12 +475,54 @@ void OSystem_SDL::initSize(uint w, uint h, const Graphics::PixelFormat *format) _dirtyChecksums = (uint32 *)calloc(_cksumNum * 2, sizeof(uint32)); } + +static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &width, int &height) { + assert(&width != &height); + + if (desiredAspectRatio.isAuto()) + return; + + int kw = desiredAspectRatio.kw(); + int kh = desiredAspectRatio.kh(); + + const int w = width; + const int h = height; + + SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_SWSURFACE); //TODO : Maybe specify a pixel format + assert(availableModes); + + const SDL_Rect *bestMode = NULL; + uint bestMetric = (uint)-1; // Metric is wasted space + while (const SDL_Rect *mode = *availableModes++) { + if (mode->w < w) + continue; + if (mode->h < h) + continue; + if (mode->h * kw != mode->w * kh) + continue; + //printf("%d %d\n", mode->w, mode->h); + + uint metric = mode->w * mode->h - w * h; + if (metric > bestMetric) + continue; + + bestMetric = metric; + bestMode = mode; + } + + if (!bestMode) { + warning("Unable to enforce the desired aspect ratio!"); + return; + } + //printf("%d %d\n", bestMode->w, bestMode->h); + width = bestMode->w; + height = bestMode->h; +} + bool OSystem_SDL::loadGFXMode() { assert(_inited); _forceFull = true; - int hwW, hwH; - #if !defined(__MAEMO__) && !defined(GP2XWIZ) _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor; _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor; @@ -491,11 +533,11 @@ bool OSystem_SDL::loadGFXMode() { if (_videoMode.aspectRatioCorrection) _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight); - hwW = _videoMode.screenWidth * _videoMode.scaleFactor; - hwH = effectiveScreenHeight(); + _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor; + _videoMode.hardwareHeight = effectiveScreenHeight(); #else - hwW = _videoMode.overlayWidth; - hwH = _videoMode.overlayHeight; + _videoMode.hardwareWidth = _videoMode.overlayWidth; + _videoMode.hardwareHeight = _videoMode.overlayHeight; #endif // @@ -521,7 +563,11 @@ bool OSystem_SDL::loadGFXMode() { // Create the surface that contains the scaled graphics in 16 bit mode // - _hwscreen = SDL_SetVideoMode(hwW, hwH, 16, + if(_videoMode.fullscreen) { + fixupResolutionForAspectRatio(_videoMode.desiredAspectRatio, _videoMode.hardwareWidth, _videoMode.hardwareHeight); + } + + _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16, _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE ); if (_hwscreen == NULL) { diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 5abeff3902..b6b46af9d7 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -85,6 +85,31 @@ static Uint32 timer_handler(Uint32 interval, void *param) { return interval; } +AspectRatio::AspectRatio(int w, int h) { + // TODO : Validation and so on... + // Currently, we just ensure the program don't instantiate non-supported aspect ratios + _kw = w; + _kh = h; +} + +static const size_t AR_COUNT = 4; +static const char* desiredAspectRatioAsStrings[AR_COUNT] = { "auto", "4/3", "16/9", "16/10" }; +static const AspectRatio desiredAspectRatios[AR_COUNT] = { AspectRatio(0, 0), AspectRatio(4,3), AspectRatio(16,9), AspectRatio(16,10) }; +static AspectRatio getDesiredAspectRatio() { + //TODO : We could parse an arbitrary string, if we code enough proper validation + Common::String desiredAspectRatio = ConfMan.get("desired_screen_aspect_ratio"); + + for (size_t i = 0; i < AR_COUNT; i++) { + assert(desiredAspectRatioAsStrings[i] != NULL); + + if (!scumm_stricmp(desiredAspectRatio.c_str(), desiredAspectRatioAsStrings[i])) { + return desiredAspectRatios[i]; + } + } + // TODO : Report a warning + return AspectRatio(0, 0); +} + void OSystem_SDL::initBackend() { assert(!_inited); @@ -124,6 +149,7 @@ void OSystem_SDL::initBackend() { _videoMode.mode = GFX_DOUBLESIZE; _videoMode.scaleFactor = 2; _videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio"); + _videoMode.desiredAspectRatio = getDesiredAspectRatio(); _scalerProc = Normal2x; #else // for small screen platforms _videoMode.mode = GFX_NORMAL; diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 3e074a884a..6c8a721701 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -70,6 +70,18 @@ enum { GFX_DOTMATRIX = 11 }; +class AspectRatio { + int _kw, _kh; +public: + AspectRatio() { _kw = _kh = 0; } + AspectRatio(int w, int h); + + bool isAuto() const { return (_kw | _kh) == 0; } + + int kw() const { return _kw; } + int kh() const { return _kh; } +}; + class OSystem_SDL : public BaseBackend { public: @@ -284,6 +296,7 @@ protected: bool fullscreen; bool aspectRatioCorrection; + AspectRatio desiredAspectRatio; int mode; int scaleFactor; @@ -293,6 +306,7 @@ protected: #ifdef ENABLE_RGB_COLOR Graphics::PixelFormat format; #endif + int hardwareWidth, hardwareHeight; }; VideoState _videoMode, _oldVideoMode; diff --git a/backends/platform/wii/osystem_events.cpp b/backends/platform/wii/osystem_events.cpp index f28e5b547b..0967db1625 100644 --- a/backends/platform/wii/osystem_events.cpp +++ b/backends/platform/wii/osystem_events.cpp @@ -316,13 +316,13 @@ bool OSystem_Wii::pollEvent(Common::Event &event) { #endif if (bd || bu) { - PAD_EVENT(PADS_Z, Common::KEYCODE_RETURN, Common::ASCII_RETURN, 0); - PAD_EVENT(PADS_X, Common::KEYCODE_ESCAPE, Common::ASCII_ESCAPE, 0); - PAD_EVENT(PADS_Y, Common::KEYCODE_PERIOD, '.', 0); - PAD_EVENT(PADS_START, Common::KEYCODE_F5, Common::ASCII_F5, 0); - PAD_EVENT(PADS_UP, Common::KEYCODE_F5, Common::ASCII_F5, Common::KBD_CTRL); - PAD_EVENT(PADS_DOWN, Common::KEYCODE_F7, Common::ASCII_F7, 0); - //PAD_EVENT(PADS_LEFT, Common::KEYCODE_F8, Common::ASCII_F8, 0); + byte flags = 0; + + if (bh & PADS_UP) { + PAD_EVENT(PADS_START, Common::KEYCODE_F5, Common::ASCII_F5, Common::KBD_CTRL); + + flags = Common::KBD_SHIFT; + } if (bd & PADS_RIGHT) { event.type = Common::EVENT_PREDICTIVE_DIALOG; @@ -330,6 +330,14 @@ bool OSystem_Wii::pollEvent(Common::Event &event) { return true; } + PAD_EVENT(PADS_Z, Common::KEYCODE_RETURN, Common::ASCII_RETURN, flags); + PAD_EVENT(PADS_X, Common::KEYCODE_ESCAPE, Common::ASCII_ESCAPE, flags); + PAD_EVENT(PADS_Y, Common::KEYCODE_PERIOD, '.', flags); + PAD_EVENT(PADS_START, Common::KEYCODE_F5, Common::ASCII_F5, flags); + PAD_EVENT(PADS_UP, Common::KEYCODE_LSHIFT, 0, flags); + PAD_EVENT(PADS_DOWN, Common::KEYCODE_F7, Common::ASCII_F7, flags); + //PAD_EVENT(PADS_LEFT, Common::KEYCODE_F8, Common::ASCII_F8, 0); + if ((bd | bu) & (PADS_A | PADS_B)) { if (bd & PADS_A) event.type = Common::EVENT_LBUTTONDOWN; diff --git a/backends/platform/wince/Makefile b/backends/platform/wince/Makefile index acade8ac9a..49101dcb27 100644 --- a/backends/platform/wince/Makefile +++ b/backends/platform/wince/Makefile @@ -50,10 +50,10 @@ ENABLE_MADE = STATIC_PLUGIN ## Pick which libraries you want to use here USE_MAD = 1 -USE_MPEG2 = 1 +#USE_MPEG2 = 1 #USE_TREMOR = 1 USE_TREMOLO = 1 -USE_FLAC = 1 +#USE_FLAC = 1 USE_ZLIB = 1 ######################################################################## diff --git a/backends/platform/wince/README-WinCE.txt b/backends/platform/wince/README-WinCE.txt index 5b3215e34e..21c62fb47f 100644 --- a/backends/platform/wince/README-WinCE.txt +++ b/backends/platform/wince/README-WinCE.txt @@ -1,6 +1,6 @@ ScummVM Windows CE FAQ Last updated: $Date$ -Release version: 0.13.0 +Release version: 1.0.0rc1 ------------------------------------------------------------------------ New in this version @@ -20,6 +20,18 @@ Be aware that Discworld 2 tries to allocate a big chunk of memory (10 MB) and this will fail on many devices (file under the not enough memory category). +From this version on, we're dropping support for FLAC and MPEG-2. The first +is a pain to maintain, while the second has been gradually phased out in +scummvm. Be sure to update your add-on packs and/or recompress your sound. + +This is still a 2-binary distribution. Here's what engines are compiled in +the two executables: +scummvm1.exe: + - scumm, sword1, sword2, queen, sky, lure, agi, touche, tinsel, cruise +scummvm2.exe: + - gob, cine, saga, kyra, agos, parallaction, drascula, groovie, tucker, made + + ------------------------------------------------------------------------ This document is intended to give common answers to specific ScummVM diff --git a/backends/platform/wince/missing/missing.cpp b/backends/platform/wince/missing/missing.cpp index ac93e8f714..2d9765b0f2 100644 --- a/backends/platform/wince/missing/missing.cpp +++ b/backends/platform/wince/missing/missing.cpp @@ -42,6 +42,7 @@ #endif #include "time.h" #include "dirent.h" +#include "common/debug.h" char *strdup(const char *strSource); @@ -182,11 +183,19 @@ int _access(const char *path, int mode) { HANDLE h = FindFirstFile(fname, &ffd); FindClose(h); - if (h == INVALID_HANDLE_VALUE) - return -1; //Can't find file + if (h == INVALID_HANDLE_VALUE) { + // WORKAROUND: WinCE 3.0 doesn't find paths ending in '\' + if (path[strlen(path)-1] == '\\') { + char p2[MAX_PATH]; + strncpy(p2, path, strlen(path)-1); + p2[strlen(path) - 1]= '\0'; + return _access(p2, mode); + } else + return -1; //Can't find file + } - if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) { - // WORKAROUND: WinCE (or the emulator) sometimes returns bogus direcotry + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + // WORKAROUND: WinCE (or the emulator) sometimes returns bogus directory // hits for files that don't exist. TRIPLE checking for the same fname // seems to weed out those false positives. // Exhibited in kyra engine. @@ -206,7 +215,7 @@ int _access(const char *path, int mode) { return 0; case 06: //Check Read & Write permission case 02: //Check Write permission - return ffd.dwFileAttributes&FILE_ATTRIBUTE_READONLY?-1:0; + return ffd.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? -1 : 0; case 04: //Check Read permission return 0; //Assume always have read permission } diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp index 5d75b76805..65082014da 100644 --- a/backends/platform/wince/wince-sdl.cpp +++ b/backends/platform/wince/wince-sdl.cpp @@ -1934,8 +1934,7 @@ void OSystem_WINCE3::setMouseCursor(const byte *buf, uint w, uint h, int hotspot _mouseData = (byte *) malloc(w * h); memcpy(_mouseData, buf, w * h); - if (w > _mouseBackupDim || h > _mouseBackupDim) - { + if (w > _mouseBackupDim || h > _mouseBackupDim) { // mouse has been undrawn, adjust sprite backup area free(_mouseBackupOld); free(_mouseBackupToolbar); @@ -2050,7 +2049,6 @@ void OSystem_WINCE3::undrawMouse() { if (_mouseNeedsRedraw) return; - _mouseNeedsRedraw = true; int old_mouse_x = _mouseCurState.x - _mouseHotspotX; int old_mouse_y = _mouseCurState.y - _mouseHotspotY; @@ -2101,6 +2099,22 @@ void OSystem_WINCE3::undrawMouse() { addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h); SDL_UnlockSurface(_overlayVisible ? _overlayscreen : _screen); + + _mouseNeedsRedraw = true; +} + +bool OSystem_WINCE3::showMouse(bool visible) { + if (_mouseVisible == visible) + return visible; + + if (visible == false) + undrawMouse(); + + bool last = _mouseVisible; + _mouseVisible = visible; + _mouseNeedsRedraw = true; + + return last; } void OSystem_WINCE3::drawToolbarMouse(SDL_Surface *surf, bool draw) { @@ -2457,9 +2471,12 @@ bool OSystem_WINCE3::pollEvent(Common::Event &event) { } if (_toolbarHandler.action(event.mouse.x, event.mouse.y, false)) { - if (!_toolbarHandler.drawn()) + if (!_toolbarHandler.drawn()) { _toolbarHighDrawn = false; internUpdateScreen(); + } + return false; + } return true; diff --git a/backends/platform/wince/wince-sdl.h b/backends/platform/wince/wince-sdl.h index cc2948f93d..deafde6d80 100644 --- a/backends/platform/wince/wince-sdl.h +++ b/backends/platform/wince/wince-sdl.h @@ -94,6 +94,7 @@ public: void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); // overloaded by CE backend void undrawMouse(); void blitCursor(); + bool showMouse(bool visible); void setMousePos(int x, int y); void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME) void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 890d14db92..086093ed9b 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -157,6 +157,7 @@ void registerDefaults() { ConfMan.registerDefault("aspect_ratio", false); ConfMan.registerDefault("gfx_mode", "normal"); ConfMan.registerDefault("render_mode", "default"); + ConfMan.registerDefault("desired_screen_aspect_ratio", "auto"); // Sound & Music ConfMan.registerDefault("music_volume", 192); diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex 7911a2e549..c945b7863b 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat diff --git a/dists/iphone/Info.plist b/dists/iphone/Info.plist new file mode 100644 index 0000000000..1a0a8bf0b6 --- /dev/null +++ b/dists/iphone/Info.plist @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>ScummVM</string> + <key>CFBundleIdentifier</key> + <string>org.scummvm.scummvm</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>ScummVM</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleShortVersionString</key> + <string>1.1.0svn</string> + <key>CFBundleVersion</key> + <string>svn</string> + <key>CFBundleIconFile</key> + <string>icon.png</string> + <key>UIPrerenderedIcon</key> + <true/> +</dict> +</plist> diff --git a/dists/macosx/Info.plist b/dists/macosx/Info.plist new file mode 100644 index 0000000000..5600084eae --- /dev/null +++ b/dists/macosx/Info.plist @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleDisplayName</key> + <string>ScummVM</string> + <key>CFBundleExecutable</key> + <string>scummvm</string> + <key>CFBundleGetInfoString</key> + <string>1.1.0svn, Copyright 2001-2008 The ScummVM team</string> + <key>CFBundleIconFile</key> + <string>scummvm.icns</string> + <key>CFBundleIdentifier</key> + <string>org.scummvm.scummvm</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>ScummVM</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.1.0svn</string> + <key>CFBundleVersion</key> + <string>1.1.0svn</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright 2001-2008 The ScummVM team</string> +</dict> +</plist> diff --git a/dists/wii/READMII b/dists/wii/READMII index b9460a9863..32f97b5425 100644 --- a/dists/wii/READMII +++ b/dists/wii/READMII @@ -44,10 +44,9 @@ CONTROLS plus: "." (skip current line of text) 2: enter home: f5 (scummvm menu) - dpad up: shift (mass add for the gui) - dpad down: "0" - dpad left: "y" - dpad right: "n" + dpad up: shift (mass add for the gui, combined with home: GMM) + dpad down: virtual keyboard + dpad right: predictive dialog (only in AGI games) gamecube pad @@ -58,10 +57,9 @@ CONTROLS y: "." (skip current line of text) z: enter start: f5 (scummvm menu) - dpad up: shift (mass add for the gui) - dpad down: "0" - dpad left: "y" - dpad right: "n" + dpad up: shift (mass add for the gui, combined with start: GMM) + dpad down: virtual keyboard + dpad right: predictive dialog (only in AGI games) DISPLAY SETUP diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h index 0c672aef52..533f35d304 100644 --- a/engines/agos/detection_tables.h +++ b/engines/agos/detection_tables.h @@ -1600,7 +1600,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1625,7 +1625,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1675,7 +1675,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::HB_ISR, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1700,7 +1700,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1726,7 +1726,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformWindows, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1751,7 +1751,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp index 2fd93e64f2..d06e4ec6fc 100644 --- a/engines/agos/icons.cpp +++ b/engines/agos/icons.cpp @@ -860,16 +860,16 @@ void AGOSEngine::addArrows(WindowBlock *window, uint8 num) { x = 30; y = 151; if (num != 2) { - y = window->height * 4 + window->y - 19; - x = window->width + window->x; + y = window->y + window->height * 4 - 19; + x = window->x + window->width; } drawArrow(x, y, 16); ha = findEmptyHitArea(); _scrollUpHitArea = ha - _hitAreas; - ha->x = 30 * 8; - ha->y = 151; + ha->x = x * 8; + ha->y = y; ha->width = 16; ha->height = 19; ha->flags = kBFBoxInUse; @@ -881,16 +881,16 @@ void AGOSEngine::addArrows(WindowBlock *window, uint8 num) { x = 30; y = 170; if (num != 2) { - y = window->height * 4; - x = window->width + window->x; + y = window->y + window->height * 4; + x = window->x + window->width; } drawArrow(x, y, -16); ha = findEmptyHitArea(); _scrollDownHitArea = ha - _hitAreas; - ha->x = 30 * 8; - ha->y = 170; + ha->x = x * 8; + ha->y = y; ha->width = 16; ha->height = 19; ha->flags = kBFBoxInUse; @@ -956,7 +956,8 @@ void AGOSEngine::drawArrow(uint16 x, uint16 y, int8 dir) { for (h = 0; h < 19; h++) { for (w = 0; w < 16; w++) { - dst[w] = src[w] + 16; + if (src[w]) + dst[w] = src[w] + 16; } src += dir; @@ -984,8 +985,8 @@ void AGOSEngine_Elvira2::removeArrows(WindowBlock *window, uint num) { void AGOSEngine::removeArrows(WindowBlock *window, uint num) { if (num != 2) { - uint y = window->height * 4 + window->y - 19; - uint x = window->width + window->x; + uint y = window->y + window->height * 4 - 19; + uint x = (window->x + window->width) * 8; restoreBlock(x, y, x + 16, y + 38); } else { colorBlock(window, 240, 151, 16, 38); diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index 3787617be7..77b503b2e3 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -283,7 +283,7 @@ void AGOSEngine::userGame(bool load) { const char *message1; int i = 0, numSaveGames; char *name; - char buf[8]; + char buf[10]; numSaveGames = countSaveGames(); @@ -312,7 +312,7 @@ restart: for (; *message1; message1++) windowPutChar(window, *message1); - memset(buf, 0, 8); + memset(buf, 0, 10); name = buf; _saveGameNameLen = 0; diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index d37681508e..7855d0e805 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -1258,7 +1258,7 @@ void AGOSEngine::clearVideoWindow(uint16 num, uint16 color) { dst += screen->pitch; } _system->unlockScreen(); - } else if (num == 4) { + } else { const uint16 *vlut = &_videoWindows[num * 4]; uint16 xoffs = (vlut[0] - _videoWindows[16]) * 16; uint16 yoffs = (vlut[1] - _videoWindows[17]); diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp index 7abf83f054..1286c38ff3 100644 --- a/engines/cruise/cruise.cpp +++ b/engines/cruise/cruise.cpp @@ -124,18 +124,6 @@ void CruiseEngine::initialize() { // another bit of video init readVolCnf(); - - // Setup mixer -// _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); -// _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); - - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - _mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - _adlib = (midiDriver == MD_ADLIB); - - _driver = MidiDriver::createMidi(midiDriver); - if (_mt32) - _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); } void CruiseEngine::deinitialise() { diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h index af098b4997..574017dfc7 100644 --- a/engines/cruise/cruise.h +++ b/engines/cruise/cruise.h @@ -56,9 +56,7 @@ class CruiseEngine: public Engine { private: bool _preLoad; Debugger *_debugger; - MidiDriver *_driver; PCSound *_sound; - bool _mt32, _adlib; Common::StringList _langStrings; CursorType _savedCursor; uint32 lastTick, lastTickDebug; @@ -89,8 +87,6 @@ public: Common::Language getLanguage() const; Common::Platform getPlatform() const; PCSound &sound() { return *_sound; } - bool mt32() const { return _mt32; } - bool adlib() const { return _adlib; } virtual GUI::Debugger *getDebugger() { return _debugger; } virtual void pauseEngine(bool pause); const char *langString(LangStringId langId) { return _langStrings[(int)langId].c_str(); } diff --git a/engines/cruise/staticres.cpp b/engines/cruise/staticres.cpp index 595ac5a38b..fa77555314 100644 --- a/engines/cruise/staticres.cpp +++ b/engines/cruise/staticres.cpp @@ -182,7 +182,7 @@ int16 spanish_fontCharacterTable[256] = { -1, -1, -1, 0x72, 0x80 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x7f, 0x79, 0x7b, 0x81, 0x82, 0x83, -1, -1, 0x7d, @@ -218,7 +218,7 @@ int16 spanish_fontCharacterTable[256] = { 0x67, -1, 0x68, - -1, -1, -1, -1 + -1, -1, -1 }; // diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index 99cf7c1193..3b7a61d485 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -35,21 +35,22 @@ namespace Gob { DataStream::DataStream(DataIO &io, int16 handle, uint32 dSize, bool dispose) { _io = &io; - _handle = handle; - _size = dSize; + + _handle = handle; + _size = dSize; _dispose = dispose; - _data = 0; + _data = 0; _stream = 0; } DataStream::DataStream(byte *buf, uint32 dSize, bool dispose) { - _data = buf; - _size = dSize; - _stream = new Common::MemoryReadStream(_data, _size); + _data = buf; + _size = dSize; + _stream = new Common::MemoryReadStream(_data, _size); _dispose = dispose; - _io = 0; + _io = 0; _handle = -1; } @@ -84,7 +85,7 @@ int32 DataStream::size() const { bool DataStream::seek(int32 offset, int whence) { if (_stream) return _stream->seek(offset, whence); - else if ((_handle < 50) || (_handle >= 128)) + else if (!_io->isDataFileChunk(_handle)) return _io->file_getHandle(_handle)->seek(offset, whence); else { _io->seekChunk(_handle, offset, whence); @@ -103,7 +104,7 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) { if (_stream) return _stream->read(dataPtr, dataSize); - if ((_handle < 50) || (_handle >= 128)) + if (!_io->isDataFileChunk(_handle)) return _io->file_getHandle(_handle)->read((byte *) dataPtr, dataSize); byte *data = (byte *) dataPtr; @@ -111,7 +112,7 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) { while (dataSize > 0x3FFF) { _io->readChunk(_handle, (byte *) data, 0x3FFF); dataSize -= 0x3FFF; - data += 0x3FFF; + data += 0x3FFF; haveRead += 0x3FFF; } _io->readChunk(_handle, (byte *) data, dataSize); @@ -121,11 +122,10 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) { DataIO::DataIO(GobEngine *vm) : _vm(vm) { for (int i = 0; i < MAX_DATA_FILES; i++) { - _dataFiles[i] = 0; - _numDataChunks[i] = 0; + _dataFiles[i] = 0; + _numDataChunks[i] = 0; _dataFileHandles[i] = -1; } - _packedSize = 0; } DataIO::~DataIO() { @@ -136,6 +136,46 @@ DataIO::~DataIO() { } } +bool DataIO::isDataFileChunk(int16 handle) const { + return (handle >= 50) && (handle < 128); +} + +bool DataIO::isPacked(int16 handle) const { + if (!isDataFileChunk(handle)) + return false; + + return _chunk[getIndex(handle)]->packed != 0; +} + +int DataIO::getFile(int16 handle) const { + if (!isDataFileChunk(handle)) + return -1; + + return (handle - 50) / 10; +} + +int DataIO::getSlot(int16 handle) const { + if (!isDataFileChunk(handle)) + return -1; + + return (handle - 50) % 10; +} + +int DataIO::getIndex(int16 handle) const { + if (!isDataFileChunk(handle)) + return -1; + + return getIndex(getFile(handle), getSlot(handle)); +} + +int DataIO::getIndex(int file, int slot) const { + return file * MAX_SLOT_COUNT + slot; +} + +int16 DataIO::getHandle(int file, int slot) const { + return file * 10 + slot + 50; +} + int32 DataIO::unpackData(byte *src, byte *dest) { uint32 realSize; uint32 counter; @@ -222,13 +262,11 @@ int16 DataIO::file_open(const char *path) { } int16 DataIO::getChunk(const char *chunkName) { - int16 slot; - struct ChunkDesc *dataDesc; - for (int16 file = 0; file < MAX_DATA_FILES; file++) { if (_dataFiles[file] == 0) return -1; + int16 slot; for (slot = 0; slot < MAX_SLOT_COUNT; slot++) if (_chunkPos[file * MAX_SLOT_COUNT + slot] == -1) break; @@ -238,59 +276,55 @@ int16 DataIO::getChunk(const char *chunkName) { return -1; } - dataDesc = _dataFiles[file]; + ChunkDesc *dataDesc = _dataFiles[file]; for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0) continue; - _isCurrentSlot[file * MAX_SLOT_COUNT + slot] = false; - _chunkSize[file * MAX_SLOT_COUNT + slot] = dataDesc->size; - _chunkOffset[file * MAX_SLOT_COUNT + slot] = dataDesc->offset; - _chunkPos[file * MAX_SLOT_COUNT + slot] = 0; - return file * 10 + slot + 50; + int index = getIndex(file, slot); + + _isCurrentSlot[index] = false; + _chunk [index] = dataDesc; + _chunkPos [index] = 0; + + return getHandle(file, slot); } } return -1; } char DataIO::freeChunk(int16 handle) { - if ((handle >= 50) && (handle < 128)) { - handle -= 50; - _chunkPos[(handle / 10) * MAX_SLOT_COUNT + (handle % 10)] = -1; + if (isDataFileChunk(handle)) { + _chunkPos[getIndex(handle)] = -1; return 0; } return 1; } int32 DataIO::readChunk(int16 handle, byte *buf, uint16 size) { - int16 file; - int16 slot; - int16 i; - int32 offset; - - if ((handle < 50) || (handle >= 128)) + if (!isDataFileChunk(handle)) return -2; - file = (handle - 50) / 10; - slot = (handle - 50) % 10; - int index = file * MAX_SLOT_COUNT + slot; + int file = getFile(handle); + int slot = getSlot(handle); + int index = getIndex(file, slot); - _chunkPos[index] = CLIP<int32>(_chunkPos[index], 0, _chunkSize[index]); + _chunkPos[index] = CLIP<int32>(_chunkPos[index], 0, _chunk[index]->size); if (!_isCurrentSlot[index]) { - for (i = 0; i < MAX_SLOT_COUNT; i++) + for (int16 i = 0; i < MAX_SLOT_COUNT; i++) _isCurrentSlot[file * MAX_SLOT_COUNT + i] = false; - offset = _chunkOffset[index] + _chunkPos[index]; + int32 offset = _chunk[index]->offset + _chunkPos[index]; - debugC(7, kDebugFileIO, "seek: %d, %d", _chunkOffset[index], _chunkPos[index]); + debugC(7, kDebugFileIO, "seek: %d, %d", _chunk[index]->offset, _chunkPos[index]); file_getHandle(_dataFileHandles[file])->seek(offset, SEEK_SET); } _isCurrentSlot[index] = true; - if ((_chunkPos[index] + size) > (_chunkSize[index])) - size = _chunkSize[index] - _chunkPos[index]; + if ((_chunkPos[index] + size) > (int32) (_chunk[index]->size)) + size = _chunk[index]->size - _chunkPos[index]; file_getHandle(_dataFileHandles[file])->read(buf, size); _chunkPos[index] += size; @@ -298,15 +332,12 @@ int32 DataIO::readChunk(int16 handle, byte *buf, uint16 size) { } int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) { - int16 file; - int16 slot; - - if ((handle < 50) || (handle >= 128)) + if (!isDataFileChunk(handle)) return -1; - file = (handle - 50) / 10; - slot = (handle - 50) % 10; - int index = file * MAX_SLOT_COUNT + slot; + int file = getFile(handle); + int slot = getSlot(handle); + int index = getIndex(file, slot); _isCurrentSlot[index] = false; if (from == SEEK_SET) @@ -314,50 +345,45 @@ int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) { else if (from == SEEK_CUR) _chunkPos[index] += pos; else if (from == SEEK_END) - _chunkPos[index] = _chunkSize[index] - pos; + _chunkPos[index] = _chunk[index]->size - pos; return _chunkPos[index]; } uint32 DataIO::getChunkPos(int16 handle) const { - int16 file; - int16 slot; - - if ((handle < 50) || (handle >= 128)) + if (!isDataFileChunk(handle)) return 0xFFFFFFFF; - file = (handle - 50) / 10; - slot = (handle - 50) % 10; + int file = getFile(handle); + int slot = getSlot(handle); return _chunkPos[file * MAX_SLOT_COUNT + slot]; } -int32 DataIO::getChunkSize(const char *chunkName) { - int16 file; - struct ChunkDesc *dataDesc; - int16 slot; - int32 realSize; - - for (file = 0; file < MAX_DATA_FILES; file++) { +int32 DataIO::getChunkSize(const char *chunkName, int32 &packSize) { + for (int16 file = 0; file < MAX_DATA_FILES; file++) { if (_dataFiles[file] == 0) return -1; - dataDesc = _dataFiles[file]; + ChunkDesc *dataDesc = _dataFiles[file]; for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0) continue; if (dataDesc->packed == 0) { - _packedSize = -1; + packSize = -1; return dataDesc->size; } - for (slot = 0; slot < MAX_SLOT_COUNT; slot++) + for (int16 slot = 0; slot < MAX_SLOT_COUNT; slot++) _isCurrentSlot[slot] = false; + int32 realSize; + file_getHandle(_dataFileHandles[file])->seek(dataDesc->offset, SEEK_SET); realSize = file_getHandle(_dataFileHandles[file])->readUint32LE(); - _packedSize = dataDesc->size; + packSize = dataDesc->size; + return realSize; } } @@ -365,10 +391,7 @@ int32 DataIO::getChunkSize(const char *chunkName) { } void DataIO::openDataFile(const char *src, bool itk) { - ChunkDesc *dataDesc; char path[128]; - int16 file; - char *fakeTotPtr; strncpy0(path, src, 127); if (!strchr(path, '.')) { @@ -376,6 +399,7 @@ void DataIO::openDataFile(const char *src, bool itk) { strcat(path, ".stk"); } + int16 file; for (file = 0; file < MAX_DATA_FILES; file++) if (_dataFiles[file] == 0) break; @@ -388,17 +412,17 @@ void DataIO::openDataFile(const char *src, bool itk) { if (_dataFileHandles[file] == -1) error("DataIO::openDataFile(): Can't open data file \"%s\"", path); - _dataFileItk[file] = itk; + _dataFileItk [file] = itk; _numDataChunks[file] = file_getHandle(_dataFileHandles[file])->readUint16LE(); debugC(7, kDebugFileIO, "DataChunks: %d [for %s]", _numDataChunks[file], path); - dataDesc = new ChunkDesc[_numDataChunks[file]]; + ChunkDesc *dataDesc = new ChunkDesc[_numDataChunks[file]]; _dataFiles[file] = dataDesc; for (int i = 0; i < _numDataChunks[file]; i++) { file_getHandle(_dataFileHandles[file])->read(dataDesc[i].chunkName, 13); - dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE(); + dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE(); dataDesc[i].offset = file_getHandle(_dataFileHandles[file])->readUint32LE(); dataDesc[i].packed = file_getHandle(_dataFileHandles[file])->readByte(); @@ -410,7 +434,7 @@ void DataIO::openDataFile(const char *src, bool itk) { Util::replaceChar(dataDesc[i].chunkName, (char) 0x92, 'T'); // Geisha use 0ot files, which are compressed TOT files without the packed byte set. - fakeTotPtr = strstr(dataDesc[i].chunkName, "0OT"); + char *fakeTotPtr = strstr(dataDesc[i].chunkName, "0OT"); if (fakeTotPtr != 0) { strncpy(fakeTotPtr, "TOT", 3); dataDesc[i].packed = 1; @@ -436,33 +460,29 @@ void DataIO::closeDataFile(bool itk) { } byte *DataIO::getUnpackedData(const char *name) { - int32 realSize; - int16 chunk; - byte *unpackBuf; - byte *packBuf; - byte *ptr; - int32 sizeLeft; - - realSize = getChunkSize(name); - if ((_packedSize == -1) || (realSize == -1)) + int32 realSize, packSize; + + realSize = getChunkSize(name, packSize); + + if ((packSize == -1) || (realSize == -1)) return 0; - chunk = getChunk(name); + int16 chunk = getChunk(name); if (chunk == -1) return 0; - unpackBuf = new byte[realSize]; + byte *unpackBuf = new byte[realSize]; assert(unpackBuf); - packBuf = new byte[_packedSize]; + byte *packBuf = new byte[packSize]; assert(packBuf); - sizeLeft = _packedSize; - ptr = packBuf; + int32 sizeLeft = packSize; + byte *ptr = packBuf; while (sizeLeft > 0x4000) { readChunk(chunk, ptr, 0x4000); sizeLeft -= 0x4000; - ptr += 0x4000; + ptr += 0x4000; } readChunk(chunk, ptr, sizeLeft); freeChunk(chunk); @@ -478,9 +498,7 @@ void DataIO::closeData(int16 handle) { } int16 DataIO::openData(const char *path) { - int16 handle; - - handle = getChunk(path); + int16 handle = getChunk(path); if (handle >= 0) return handle; @@ -492,7 +510,6 @@ bool DataIO::existData(const char *path) { return false; int16 handle = openData(path); - if (handle < 0) return false; @@ -510,9 +527,7 @@ DataStream *DataIO::openAsStream(int16 handle, bool dispose) { } uint32 DataIO::getPos(int16 handle) { - uint32 resPos; - - resPos = getChunkPos(handle); + uint32 resPos = getChunkPos(handle); if (resPos != 0xFFFFFFFF) return resPos; @@ -520,9 +535,7 @@ uint32 DataIO::getPos(int16 handle) { } void DataIO::seekData(int16 handle, int32 pos, int16 from) { - int32 resPos; - - resPos = seekChunk(handle, pos, from); + int32 resPos = seekChunk(handle, pos, from); if (resPos != -1) return; @@ -530,9 +543,7 @@ void DataIO::seekData(int16 handle, int32 pos, int16 from) { } int32 DataIO::readData(int16 handle, byte *buf, uint16 size) { - int32 res; - - res = readChunk(handle, buf, size); + int16 res = readChunk(handle, buf, size); if (res >= 0) return res; @@ -541,45 +552,42 @@ int32 DataIO::readData(int16 handle, byte *buf, uint16 size) { int32 DataIO::getDataSize(const char *name) { char buf[128]; - int32 chunkSz; - Common::File file; strncpy0(buf, name, 127); - chunkSz = getChunkSize(buf); - if (chunkSz >= 0) - return chunkSz; + int32 chunkSize, packSize; + + chunkSize = getChunkSize(buf, packSize); + if (chunkSize >= 0) + return chunkSize; + Common::File file; if (!file.open(buf)) error("DataIO::getDataSize(): Can't find data \"%s\"", name); - chunkSz = file.size(); + chunkSize = file.size(); file.close(); - return chunkSz; + return chunkSize; } byte *DataIO::getData(const char *path) { - byte *data; - byte *ptr; - int32 size; - int16 handle; - - data = getUnpackedData(path); + byte *data = getUnpackedData(path); if (data) return data; - size = getDataSize(path); + int32 size = getDataSize(path); + data = new byte[size]; assert(data); - handle = openData(path); + int16 handle = openData(path); - ptr = data; + byte *ptr = data; while (size > 0x4000) { readData(handle, ptr, 0x4000); size -= 0x4000; - ptr += 0x4000; + ptr += 0x4000; } readData(handle, ptr, size); closeData(handle); @@ -588,12 +596,26 @@ byte *DataIO::getData(const char *path) { DataStream *DataIO::getDataStream(const char *path) { if (!existData(path)) + return 0; + + int16 handle = openData(path); + if (handle < 0) return 0; - uint32 size = getDataSize(path); - byte *data = getData(path); + if (isDataFileChunk(handle) && isPacked(handle)) { + // It's a packed chunk in the data files, packed, + // so we have to read it in completely and unpack it + + closeData(handle); + + uint32 size = getDataSize(path); + byte *data = getData(path); + + return new DataStream(data, size); - return new DataStream(data, size); + } else + // Otherwise, we can just return a stream + return openAsStream(handle, true); } } // End of namespace Gob diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h index 1f55cac90d..6a86667e1b 100644 --- a/engines/gob/dataio.h +++ b/engines/gob/dataio.h @@ -26,16 +26,14 @@ #ifndef GOB_DATAIO_H #define GOB_DATAIO_H - #include "common/endian.h" - #include "common/file.h" namespace Gob { -#define MAX_FILES 30 -#define MAX_DATA_FILES 8 -#define MAX_SLOT_COUNT 8 +#define MAX_FILES 30 +#define MAX_DATA_FILES 8 +#define MAX_SLOT_COUNT 8 class DataIO; @@ -56,20 +54,20 @@ public: private: DataIO *_io; - int16 _handle; - uint32 _size; - byte *_data; + int16 _handle; + uint32 _size; + byte *_data; + bool _dispose; Common::MemoryReadStream *_stream; - bool _dispose; }; class DataIO { public: struct ChunkDesc { - char chunkName[13]; + char chunkName[13]; uint32 size; uint32 offset; - byte packed; + byte packed; ChunkDesc() : size(0), offset(0), packed(0) { chunkName[0] = 0; } }; @@ -77,10 +75,13 @@ public: void openDataFile(const char *src, bool itk = 0); void closeDataFile(bool itk = 0); + byte *getUnpackedData(const char *name); - void closeData(int16 handle); + + void closeData(int16 handle); int16 openData(const char *path); - bool existData(const char *path); + bool existData(const char *path); + DataStream *openAsStream(int16 handle, bool dispose = false); int32 getDataSize(const char *name); @@ -92,34 +93,47 @@ public: protected: Common::File _filesHandles[MAX_FILES]; - struct ChunkDesc *_dataFiles[MAX_DATA_FILES]; - uint16 _numDataChunks[MAX_DATA_FILES]; - int16 _dataFileHandles[MAX_DATA_FILES]; - bool _dataFileItk[MAX_DATA_FILES]; - int32 _chunkPos[MAX_SLOT_COUNT * MAX_DATA_FILES]; - int32 _chunkOffset[MAX_SLOT_COUNT * MAX_DATA_FILES]; - int32 _chunkSize[MAX_SLOT_COUNT * MAX_DATA_FILES]; - bool _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES]; - int32 _packedSize; + + ChunkDesc *_dataFiles [MAX_DATA_FILES]; + uint16 _numDataChunks [MAX_DATA_FILES]; + int16 _dataFileHandles[MAX_DATA_FILES]; + bool _dataFileItk [MAX_DATA_FILES]; + + ChunkDesc *_chunk [MAX_SLOT_COUNT * MAX_DATA_FILES]; + int32 _chunkPos [MAX_SLOT_COUNT * MAX_DATA_FILES]; + bool _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES]; class GobEngine *_vm; + bool isDataFileChunk(int16 handle) const; + bool isPacked (int16 handle) const; + + int getFile (int16 handle) const; + int getSlot (int16 handle) const; + int getIndex(int16 handle) const; + + int getIndex (int file, int slot) const; + int16 getHandle(int file, int slot) const; + int16 file_open(const char *path); Common::File *file_getHandle(int16 handle); const Common::File *file_getHandle(int16 handle) const; int16 getChunk(const char *chunkName); - char freeChunk(int16 handle); + char freeChunk(int16 handle); int32 readChunk(int16 handle, byte *buf, uint16 size); int16 seekChunk(int16 handle, int32 pos, int16 from); + uint32 getChunkPos(int16 handle) const; - int32 getChunkSize(const char *chunkName); + + int32 getChunkSize(const char *chunkName, int32 &packSize); uint32 getPos(int16 handle); - void seekData(int16 handle, int32 pos, int16 from); + void seekData(int16 handle, int32 pos, int16 from); + int32 readData(int16 handle, byte *buf, uint16 size); -friend class DataStream; + friend class DataStream; }; } // End of namespace Gob diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index a1074d7ecb..486b12b022 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -46,6 +46,8 @@ Draw_v2::Draw_v2(GobEngine *vm) : Draw_v1(vm) { } void Draw_v2::initScreen() { + _vm->_game->_preventScroll = false; + _scrollOffsetX = 0; _scrollOffsetY = 0; diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 4e2bd223b7..af9f03ecbf 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -181,10 +181,12 @@ Game::Game(GobEngine *vm) : _vm(vm) { _handleMouse = 0; _forceHandleMouse = 0; - _menuLevel = 0; _noScroll = true; _preventScroll = false; - _scrollHandleMouse = false; + + _wantScroll = false; + _wantScrollX = 0; + _wantScrollY = 0; _tempStr[0] = 0; @@ -360,9 +362,7 @@ void Game::playTot(int16 skipPlay) { _vm->_scenery->_pCaptureCounter = oldCaptureCounter; _script->seek(_script->getFunctionOffset(skipPlay + 1)); - _menuLevel++; _vm->_inter->callSub(2); - _menuLevel--; if (_vm->_inter->_terminate != 0) _vm->_inter->_terminate = 2; @@ -439,22 +439,27 @@ void Game::freeSoundSlot(int16 slot) { _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot)); } -void Game::evaluateScroll(int16 x, int16 y) { - if (_preventScroll || !_scrollHandleMouse || (_menuLevel > 0)) +void Game::wantScroll(int16 x, int16 y) { + _wantScroll = true; + _wantScrollX = x; + _wantScrollY = y; +} + +void Game::evaluateScroll() { + if (_noScroll || _preventScroll || !_wantScroll) return; - if (_noScroll || - ((_vm->_global->_videoMode != 0x14) && (_vm->_global->_videoMode != 0x18))) + if ((_vm->_global->_videoMode != 0x14) && (_vm->_global->_videoMode != 0x18)) return; - if ((x == 0) && (_vm->_draw->_scrollOffsetX > 0)) { + if ((_wantScrollX == 0) && (_vm->_draw->_scrollOffsetX > 0)) { uint16 off; off = MIN(_vm->_draw->_cursorWidth, _vm->_draw->_scrollOffsetX); off = MAX(off / 2, 1); _vm->_draw->_scrollOffsetX -= off; _vm->_video->dirtyRectsAll(); - } else if ((y == 0) && (_vm->_draw->_scrollOffsetY > 0)) { + } else if ((_wantScrollY == 0) && (_vm->_draw->_scrollOffsetY > 0)) { uint16 off; off = MIN(_vm->_draw->_cursorHeight, _vm->_draw->_scrollOffsetY); @@ -463,9 +468,9 @@ void Game::evaluateScroll(int16 x, int16 y) { _vm->_video->dirtyRectsAll(); } - int16 cursorRight = x + _vm->_draw->_cursorWidth; - int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width; - int16 cursorBottom = y + _vm->_draw->_cursorHeight; + int16 cursorRight = _wantScrollX + _vm->_draw->_cursorWidth; + int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width; + int16 cursorBottom = _wantScrollY + _vm->_draw->_cursorHeight; int16 screenBottom = _vm->_draw->_scrollOffsetY + _vm->_height; if ((cursorRight >= _vm->_width) && @@ -479,7 +484,7 @@ void Game::evaluateScroll(int16 x, int16 y) { _vm->_draw->_scrollOffsetX += off; _vm->_video->dirtyRectsAll(); - _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, y); + _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, _wantScrollY); } else if ((cursorBottom >= (_vm->_height - _vm->_video->_splitHeight2)) && (screenBottom < _vm->_video->_surfHeight)) { uint16 off; @@ -491,11 +496,13 @@ void Game::evaluateScroll(int16 x, int16 y) { _vm->_draw->_scrollOffsetY += off; _vm->_video->dirtyRectsAll(); - _vm->_util->setMousePos(x, _vm->_height - _vm->_video->_splitHeight2 - - _vm->_draw->_cursorHeight); + _vm->_util->setMousePos(_wantScrollX, + _vm->_height - _vm->_video->_splitHeight2 - _vm->_draw->_cursorHeight); } _vm->_util->setScrollOffset(); + + _wantScroll = false; } int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY, diff --git a/engines/gob/game.h b/engines/gob/game.h index d3a758f014..8b8be90ef4 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -82,7 +82,10 @@ public: bool _noScroll; bool _preventScroll; - bool _scrollHandleMouse; + + bool _wantScroll; + int16 _wantScrollX; + int16 _wantScrollY; byte _handleMouse; char _forceHandleMouse; @@ -99,7 +102,8 @@ public: void freeSoundSlot(int16 slot); - void evaluateScroll(int16 x, int16 y); + void wantScroll(int16 x, int16 y); + void evaluateScroll(); int16 checkKeys(int16 *pMousex = 0, int16 *pMouseY = 0, MouseButtons *pButtons = 0, char handleMouse = 0); @@ -109,8 +113,6 @@ public: void switchTotSub(int16 index, int16 skipPlay); protected: - uint32 _menuLevel; - char _tempStr[256]; // Capture diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index b218634d4e..d21eb906ee 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -628,8 +628,6 @@ bool Hotspots::checkHotspotChanged() { } uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index) { - _vm->_game->_scrollHandleMouse = handleMouse != 0; - if (delay >= -1) { _currentKey = 0; _currentId = 0; @@ -679,6 +677,9 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index _vm->_video->waitRetrace(); } + if (handleMouse) + _vm->_game->evaluateScroll(); + // Update keyboard and mouse state key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, handleMouse); diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 19cac86465..b4e5bf7623 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -935,6 +935,8 @@ void Inter_v2::o2_setScrollOffset() { offsetY = _vm->_game->_script->readValExpr(); if (offsetX == -1) { + _vm->_game->_preventScroll = !_vm->_game->_preventScroll; + WRITE_VAR(2, _vm->_draw->_scrollOffsetX); WRITE_VAR(3, _vm->_draw->_scrollOffsetY); } else { @@ -996,11 +998,8 @@ void Inter_v2::o2_playImd() { close = false; } - if (startFrame >= 0) { - _vm->_game->_preventScroll = true; + if (startFrame >= 0) _vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0); - _vm->_game->_preventScroll = false; - } if (close) _vm->_vidPlayer->primaryClose(); @@ -1306,8 +1305,14 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) { char *file = _vm->_game->_script->getResultStr(); + // WORKAROUND: In some games (at least all the Playtoons), some files are + // read on CD (and only on CD). "@:\" is replaced by the CD drive letter. + // As the files are copied on the HDD, those characters are skipped. + if (strncmp(file, "@:\\", 3) ==0 ) + file += 3; + // WORKAROUND: For some reason, the variable indicating which TOT to load next - // is overwritten in the guard house card game in Woodruff + // is overwritten in the guard house card game in Woodruff. if ((_vm->getGameType() == kGameTypeWoodruff) && !scumm_stricmp(file, "6.TOT")) strcpy(file, "EMAP2011.TOT"); diff --git a/engines/gob/inter_v4.cpp b/engines/gob/inter_v4.cpp index 48378a5987..1f6899d85c 100644 --- a/engines/gob/inter_v4.cpp +++ b/engines/gob/inter_v4.cpp @@ -233,11 +233,8 @@ void Inter_v4::o4_playVmdOrMusic() { return; } - if (startFrame >= 0) { - _vm->_game->_preventScroll = true; + if (startFrame >= 0) _vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0); - _vm->_game->_preventScroll = false; - } if (close) _vm->_vidPlayer->primaryClose(); diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp index aa4721ff0a..4e2ec69cf2 100644 --- a/engines/gob/inter_v6.cpp +++ b/engines/gob/inter_v6.cpp @@ -164,12 +164,9 @@ void Inter_v6::o6_playVmdOrMusic() { return; } - if (startFrame >= 0) { - _vm->_game->_preventScroll = true; + if (startFrame >= 0) _vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0, -1, false, -1, true); - _vm->_game->_preventScroll = false; - } if (close) _vm->_vidPlayer->primaryClose(); diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 135c50c92c..bad4723159 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -1105,8 +1105,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir, int16 baseFrame, palFrame, lastFrame; uint16 flags; - _vm->_game->_preventScroll = true; - if (_vm->_draw->_renderFlags & 0x100) { x = VAR(55); y = VAR(56); @@ -1115,7 +1113,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir, if (key.imdFile == -1) { _vm->_vidPlayer->primaryClose(); - _vm->_game->_preventScroll = false; return; } @@ -1131,15 +1128,12 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir, if ((palFrame != -1) && (lastFrame != -1)) if ((lastFrame - palFrame) < startFrame) if (!(key.flags & 0x4000)) { - _vm->_game->_preventScroll = false; _vm->_vidPlayer->primaryClose(); return; } - if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags)) { - _vm->_game->_preventScroll = false; + if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags)) return; - } if (palFrame == -1) palFrame = 0; @@ -1265,9 +1259,6 @@ void Mult_v2::advanceObjects(int16 index) { } } - if (!hasImds && (_vm->_draw->_showCursor == 3)) - _vm->_game->_preventScroll = false; - doSoundAnim(stop, frame); WRITE_VAR(22, frame); diff --git a/engines/gob/save/saveload_playtoons.cpp b/engines/gob/save/saveload_playtoons.cpp index 97da909e7c..3014e3f2bf 100644 --- a/engines/gob/save/saveload_playtoons.cpp +++ b/engines/gob/save/saveload_playtoons.cpp @@ -47,6 +47,8 @@ SaveLoad_Playtoons::SaveFile SaveLoad_Playtoons::_saveFiles[] = { { "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}, + { "dan.itk", kSaveModeNone, 0, 0}, + { "did.inf", kSaveModeSave, 0, 0}, }; SaveLoad::SaveMode SaveLoad_Playtoons::getSaveMode(const char *fileName) const { diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 1a8668b1c2..d51cbad6b3 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -141,7 +141,8 @@ void Util::processInput(bool scroll) { y -= _vm->_video->_screenDeltaY; _vm->_util->setMousePos(x, y); - _vm->_game->evaluateScroll(x, y); + + _vm->_game->wantScroll(x, y); } } diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp index 1a1de92156..797290a6f3 100644 --- a/engines/groovie/music.cpp +++ b/engines/groovie/music.cpp @@ -35,7 +35,7 @@ namespace Groovie { MusicPlayer::MusicPlayer(GroovieEngine *vm) : _vm(vm), _isPlaying(false), _backgroundFileRef(0), _gameVolume(100), - _prevCDtrack(0) { + _prevCDtrack(0), _backgroundDelay(0) { } void MusicPlayer::playSong(uint32 fileref) { @@ -56,6 +56,18 @@ void MusicPlayer::setBackgroundSong(uint32 fileref) { _backgroundFileRef = fileref; } +void MusicPlayer::frameTick() { + if (_backgroundDelay > 0) { + _backgroundDelay--; + if (_backgroundDelay == 0) + playSong(_backgroundFileRef); + } +} + +void MusicPlayer::setBackgroundDelay(uint16 delay) { + _backgroundDelay = delay; +} + void MusicPlayer::playCD(uint8 track) { int startms = 0; diff --git a/engines/groovie/music.h b/engines/groovie/music.h index db50930c37..9909c8a185 100644 --- a/engines/groovie/music.h +++ b/engines/groovie/music.h @@ -44,6 +44,9 @@ public: void playCD(uint8 track); void startBackground(); + void frameTick(); + void setBackgroundDelay(uint16 delay); + // Volume void setUserVolume(uint16 volume); void setGameVolume(uint16 volume, uint16 time); @@ -55,6 +58,8 @@ private: uint32 _backgroundFileRef; uint8 _prevCDtrack; + uint16 _backgroundDelay; + // Volume fading uint32 _fadingStartTime; uint16 _fadingStartVolume; diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp index 86713ee3e6..d58bb78607 100644 --- a/engines/groovie/script.cpp +++ b/engines/groovie/script.cpp @@ -579,6 +579,7 @@ bool Script::playvideofromref(uint32 fileref) { // Video available, play one frame if (_videoFile) { bool endVideo = _vm->_videoPlayer->playFrame(); + _vm->_musicPlayer->frameTick(); if (endVideo) { // Close the file @@ -1506,6 +1507,14 @@ void Script::o_playcd() { _vm->_musicPlayer->playCD(val); } +void Script::o_musicdelay() { + uint16 delay = readScript16bits(); + + debugScript(1, true, "MUSICDELAY %d", delay); + + _vm->_musicPlayer->setBackgroundDelay(delay); +} + void Script::o_hotspot_outrect() { uint16 left = readScript16bits(); uint16 top = readScript16bits(); @@ -1687,7 +1696,7 @@ Script::OpcodeFunc Script::_opcodesT7G[NUM_OPCODES] = { &Script::o_nop8, &Script::o_getcd, // 0x4C &Script::o_playcd, - &Script::o_nop16, + &Script::o_musicdelay, &Script::o_nop16, &Script::o_nop16, // 0x50 &Script::o_nop16, diff --git a/engines/groovie/script.h b/engines/groovie/script.h index 4ff79b36b6..9e35d6fcde 100644 --- a/engines/groovie/script.h +++ b/engines/groovie/script.h @@ -220,6 +220,7 @@ private: void o_sethotspotleft(); void o_getcd(); void o_playcd(); + void o_musicdelay(); void o_hotspot_outrect(); void o_stub56(); void o_stub59(); diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index d9924d233b..cc1add9ce7 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -95,7 +95,8 @@ void GUI::initMenu(Menu &menu) { if (_vm->gameFlags().gameID == GI_LOL) { printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 9); } else { - printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0); + if (_vm->gameFlags().platform != Common::kPlatformAmiga) + printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0); printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0); } @@ -142,7 +143,9 @@ void GUI::initMenu(Menu &menu) { else printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8); } else { - printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0); + if (_vm->gameFlags().platform != Common::kPlatformAmiga) + printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0); + if (i == menu.highlightedItem) printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0); else @@ -158,7 +161,8 @@ void GUI::initMenu(Menu &menu) { menu.item[i].labelY = menu.item[i].y + 3; printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 10); } else { - printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0); + if (_vm->gameFlags().platform != Common::kPlatformAmiga) + printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0); printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0); } } @@ -253,7 +257,8 @@ void GUI::redrawText(const Menu &menu) { textY++; printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8); } else { - printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0); + if (_vm->gameFlags().platform != Common::kPlatformAmiga) + printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0); printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0); } } @@ -278,7 +283,8 @@ void GUI::redrawHighlight(const Menu &menu) { textY++; printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8); } else { - printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0); + if (_vm->gameFlags().platform != Common::kPlatformAmiga) + printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0); printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0); } } @@ -324,7 +330,10 @@ int GUI::redrawButtonCallback(Button *button) { return 0; _screen->hideMouse(); - _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8); + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17); + else + _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8); _screen->showMouse(); return 0; @@ -335,7 +344,10 @@ int GUI::redrawShadedButtonCallback(Button *button) { return 0; _screen->hideMouse(); - _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA); + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18); + else + _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA); _screen->showMouse(); return 0; diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp index 9f42697ec7..9ef20ba8a3 100644 --- a/engines/kyra/gui_lok.cpp +++ b/engines/kyra/gui_lok.cpp @@ -56,10 +56,10 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) { return 0; } else { _screen->hideMouse(); - _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12); + _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12); snd_playSoundEffect(0x35); setMouseItem(inventoryItem); - updateSentenceCommand(_itemList[inventoryItem], _takenList[0], 179); + updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179); _itemInHand = inventoryItem; _screen->showMouse(); _currentCharacter->inventoryItems[itemOffset] = 0xFF; @@ -68,10 +68,14 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) { if (inventoryItem != 0xFF) { snd_playSoundEffect(0x35); _screen->hideMouse(); - _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12); + _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12); _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); setMouseItem(inventoryItem); - updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179); + // TODO: Proper support for both taken strings in Amiga version + if (_flags.platform == Common::kPlatformAmiga) + updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179); + else + updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[1], 179); _screen->showMouse(); _currentCharacter->inventoryItems[itemOffset] = _itemInHand; _itemInHand = inventoryItem; @@ -80,7 +84,7 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) { _screen->hideMouse(); _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); _screen->setMouseCursor(1, 1, _shapes[0]); - updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179); + updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _placedList[0], 179); _screen->showMouse(); _currentCharacter->inventoryItems[itemOffset] = _itemInHand; _itemInHand = -1; @@ -365,6 +369,10 @@ void GUI_LoK::setGUILabels() { offsetOptions = 10; offsetOn = 0; walkspeedGarbageOffset = 0; + } else if (_vm->gameFlags().platform == Common::kPlatformAmiga) { + // English Amiga version + offsetOptions = 8; + walkspeedGarbageOffset = 2; } assert(offset + 27 < _vm->_guiStringsSize); @@ -448,8 +456,14 @@ int GUI_LoK::buttonMenuCallback(Button *caller) { _vm->snd_playSoundEffect(0x36); return 0; } - // XXX - _screen->setPaletteIndex(0xFE, 60, 60, 0); + + if (_vm->gameFlags().platform == Common::kPlatformAmiga) { + _screen->setPaletteIndex(0x10, 0x3F, 0x3F, 0x3F); + _screen->setInterfacePalette(_screen->getPalette(1), 0x3F, 0x3F, 0x3F); + } else { + _screen->setPaletteIndex(0xFE, 60, 60, 0); + } + for (int i = 0; i < 6; i++) { _menuButtonData[i].data0Val1 = _menuButtonData[i].data1Val1 = _menuButtonData[i].data2Val1 = 4; _menuButtonData[i].data0Callback = _redrawShadedButtonFunctor; @@ -681,6 +695,7 @@ void GUI_LoK::updateSavegameString() { } int GUI_LoK::saveGame(Button *button) { + g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); updateMenuButton(button); _vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot; @@ -729,6 +744,7 @@ int GUI_LoK::saveGame(Button *button) { } } + g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); return 0; } @@ -921,6 +937,9 @@ void GUI_LoK::setupControls(Menu &menu) { menu.item[3].itemString = "ERROR"; } } else { + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + clickableOffset = 5; + menu.item[4].enabled = 0; menu.item[4].labelString = 0; } diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index e5c8637fb5..3633a546e7 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -661,7 +661,9 @@ int GUI_v2::clickSaveSlot(Button *caller) { initMenu(_savenameMenu); _screen->fillRect(0x26, 0x5B, 0x11F, 0x66, textFieldColor2()); + g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); const char *desc = nameInputProcess(_saveDescription, 0x27, 0x5C, textFieldColor1(), textFieldColor2(), textFieldColor3(), 0x50); + g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); restorePage1(_vm->_screenBuffer); backUpPage1(_vm->_screenBuffer); if (desc) { diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp index aef5ba5f13..bc490d9764 100644 --- a/engines/kyra/items_lok.cpp +++ b/engines/kyra/items_lok.cpp @@ -414,7 +414,7 @@ int KyraEngine_LoK::processItemDrop(uint16 sceneId, uint8 item, int x, int y, in if (unk1 == 0 && unk2 != 0) { assert(_itemList && _droppedList); - updateSentenceCommand(_itemList[item], _droppedList[0], 179); + updateSentenceCommand(_itemList[getItemListIndex(item)], _droppedList[0], 179); } return 1; @@ -434,7 +434,7 @@ void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { setMouseItem(_itemInHand); assert(_itemList && _takenList); - updateSentenceCommand(_itemList[_itemInHand], _takenList[1], 179); + updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[1], 179); _screen->showMouse(); clickEventHandler2(); } @@ -693,7 +693,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) { if (itemPos != -1) { restoreItemRect1(x, y); - _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); + _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0); backUpItemRect1(x, y); } @@ -715,7 +715,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) { } else { _characterList[0].inventoryItems[itemPos] = 0xFF; _screen->hideMouse(); - _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); + _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0); _screen->showMouse(); } _screen->showMouse(); @@ -879,7 +879,7 @@ void KyraEngine_LoK::redrawInventory(int page) { _screen->_curPage = page; _screen->hideMouse(); for (int i = 0; i < 10; ++i) { - _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page); + _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, page); if (_currentCharacter->inventoryItems[i] != 0xFF) { uint8 item = _currentCharacter->inventoryItems[i]; _screen->drawShape(page, _shapes[216+item], _itemPosX[i], _itemPosY[i], 0, 0); @@ -910,5 +910,62 @@ void KyraEngine_LoK::restoreItemRect1(int xpos, int ypos) { _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); } +int KyraEngine_LoK::getItemListIndex(uint16 item) { + if (_flags.platform != Common::kPlatformAmiga) + return item; + + // "Unknown item" is at 81. + if (item == 0xFFFF || item == 0xFF) + return 81; + // The first item names are mapped directly + else if (item <= 28) + return item; + // There's only one string for "Fireberries" + else if (item >= 29 && item <= 33) + return 29; + // Correct offsets + else if (item >= 34 && item <= 59) + return item - 4; + // There's only one string for "Red Potion" + else if (item >= 60 && item <= 61) + return 56; + // There's only one string for "Blue Potion" + else if (item >= 62 && item <= 63) + return 57; + // There's only one string for "Yellow Potion" + else if (item >= 64 && item <= 65) + return 58; + // Correct offsets + else if (item >= 66 && item <= 69) + return item - 7; + // There's only one string for "Fresh Water" + else if (item >= 70 && item <= 71) + return 63; + // There's only one string for "Salt Water" + else if (item >= 72 && item <= 73) + return 64; + // There's only one string for "Mineral Water" + else if (item >= 74 && item <= 75) + return 65; + // There's only one string for "Magical Water" + else if (item >= 76 && item <= 77) + return 66; + // There's only one string for "Empty Flask" + else if (item >= 78 && item <= 79) + return 67; + // There's only one string for "Scroll" + else if (item >= 80 && item <= 89) + return 68; + // There's only one string for "Parchment scrap" + else if (item >= 90 && item <= 94) + return 69; + // Correct offsets + else if (item >= 95) + return item - 25; + + // This should never happen, but still GCC warns about it. + return 81; +} + } // end of namespace Kyra diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp index a3a249de18..36f134d9e4 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -363,6 +363,9 @@ void KyraEngine_LoK::startup() { loadMainScreen(); _screen->loadPalette("PALETTE.COL", _screen->getPalette(0)); + if (_flags.platform == Common::kPlatformAmiga) + _screen->loadPaletteTable("PALETTE.DAT", 6); + // XXX _animator->initAnimStateList(); setCharactersInDefaultScene(); @@ -664,7 +667,7 @@ int KyraEngine_LoK::processInputHelper(int xpos, int ypos) { currentRoom->itemsTable[item] = 0xFF; setMouseItem(item2); assert(_itemList && _takenList); - updateSentenceCommand(_itemList[item2], _takenList[0], 179); + updateSentenceCommand(_itemList[getItemListIndex(item2)], _takenList[0], 179); _itemInHand = item2; _screen->showMouse(); clickEventHandler2(); diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h index a905c5521b..e22cc0d997 100644 --- a/engines/kyra/kyra_lok.h +++ b/engines/kyra/kyra_lok.h @@ -289,6 +289,8 @@ protected: void removeHandItem(); void setMouseItem(uint16 item); + int getItemListIndex(uint16 item); + // -> graphics effects void wipeDownMouseItem(int xpos, int ypos); void itemSpecialFX(int x, int y, int item); @@ -520,35 +522,35 @@ protected: const uint8 *_seq_Demo4; const uint8 *_seq_Reunion; - const char * const*_seq_WSATable; - const char * const*_seq_CPSTable; - const char * const*_seq_COLTable; - const char * const*_seq_textsTable; + const char * const *_seq_WSATable; + const char * const *_seq_CPSTable; + const char * const *_seq_COLTable; + const char * const *_seq_textsTable; int _seq_WSATable_Size; int _seq_CPSTable_Size; int _seq_COLTable_Size; int _seq_textsTable_Size; - const char * const*_itemList; - const char * const*_takenList; - const char * const*_placedList; - const char * const*_droppedList; - const char * const*_noDropList; - const char * const*_putDownFirst; - const char * const*_waitForAmulet; - const char * const*_blackJewel; - const char * const*_poisonGone; - const char * const*_healingTip; - const char * const*_thePoison; - const char * const*_fluteString; - const char * const*_wispJewelStrings; - const char * const*_magicJewelString; - const char * const*_flaskFull; - const char * const*_fullFlask; - const char * const*_veryClever; - const char * const*_homeString; - const char * const*_newGameString; + const char * const *_itemList; + const char * const *_takenList; + const char * const *_placedList; + const char * const *_droppedList; + const char * const *_noDropList; + const char * const *_putDownFirst; + const char * const *_waitForAmulet; + const char * const *_blackJewel; + const char * const *_poisonGone; + const char * const *_healingTip; + const char * const *_thePoison; + const char * const *_fluteString; + const char * const *_wispJewelStrings; + const char * const *_magicJewelString; + const char * const *_flaskFull; + const char * const *_fullFlask; + const char * const *_veryClever; + const char * const *_homeString; + const char * const *_newGameString; int _itemList_Size; int _takenList_Size; @@ -570,13 +572,13 @@ protected: int _homeString_Size; int _newGameString_Size; - const char * const*_characterImageTable; + const char * const *_characterImageTable; int _characterImageTableSize; - const char * const*_guiStrings; + const char * const *_guiStrings; int _guiStringsSize; - const char * const*_configStrings; + const char * const *_configStrings; int _configStringsSize; Shape *_defaultShapeTable; @@ -614,16 +616,16 @@ protected: Room *_roomTable; int _roomTableSize; - const char * const*_roomFilenameTable; + const char * const *_roomFilenameTable; int _roomFilenameTableSize; const uint8 *_amuleteAnim; - const uint8 * const*_specialPalettes; + const uint8 * const *_specialPalettes; - const char *const *_soundFiles; + const char * const *_soundFiles; int _soundFilesSize; - const char *const *_soundFilesIntro; + const char * const *_soundFilesIntro; int _soundFilesIntroSize; const int32 *_cdaTrackTable; int _cdaTrackTableSize; @@ -646,6 +648,9 @@ protected: static const uint16 _amuletY[]; static const uint16 _amuletX2[]; static const uint16 _amuletY2[]; + + // special palette handling for AMIGA + void setupZanthiaPalette(int pal); protected: void setupOpcodeTable(); diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index d2c8be9556..f102e92802 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -730,7 +730,7 @@ int LoLEngine::mainMenu() { // 16 color mode { { 0, 0, 0, 0, 0 }, - { 0x01, 0x04, 0x0C, 0x03, 0x00, 0xC1, 0xE1 }, + { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xC1, 0xE1 }, { 0xCC, 0xDD, 0xDD, 0xDD }, Screen::FID_9_FNT, 1 } @@ -738,6 +738,9 @@ int LoLEngine::mainMenu() { int dataIndex = _flags.use16ColorMode ? 1 : 0; + if (!_flags.isTalkie) + --data[dataIndex].menuTable[3]; + if (hasSave) ++data[dataIndex].menuTable[3]; diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp index c59f2bebf6..3c92b8f2d4 100644 --- a/engines/kyra/saveload_lok.cpp +++ b/engines/kyra/saveload_lok.cpp @@ -177,8 +177,8 @@ Common::Error KyraEngine_LoK::loadGameState(int slot) { seq_createAmuletJewel(i-0x55, 10, 1, 1); } } - _screen->copyRegion(0, 0, 0, 0, 320, 200, 10, 8); - _screen->copyRegion(0, 0, 0, 0, 320, 200, 8, 0); + + _screen->copyRegion(8, 8, 8, 8, 304, 212, 10, 0); } setHandItem(_itemInHand); diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp index fc1ca41189..e7f4ecbae0 100644 --- a/engines/kyra/scene_lok.cpp +++ b/engines/kyra/scene_lok.cpp @@ -778,10 +778,10 @@ void KyraEngine_LoK::initSceneScreen(int brandonAlive) { if (_unkScreenVar2 == 1) _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); else - _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK); if (_unkScreenVar1 && !queryGameFlag(0xA0)) { - if (_currentCharacter->sceneId == 45 && _paletteChanged) + if (_currentCharacter->sceneId == 45 && _cauldronState) _screen->getPalette(0).copy(_screen->getPalette(4), 12, 1); if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1)) @@ -1203,6 +1203,66 @@ bool KyraEngine_LoK::lineIsPassable(int x, int y) { #pragma mark - +void KyraEngine_LoK::setupZanthiaPalette(int pal) { + uint8 r, g, b; + + switch (pal - 17) { + case 0: + // 0x88F + r = 33; + g = 33; + b = 63; + break; + + case 1: + // 0x00F + r = 0; + g = 0; + b = 63; + break; + + case 2: + // 0xF88 + r = 63; + g = 33; + b = 33; + break; + + case 3: + // 0xF00 + r = 63; + g = 0; + b = 0; + break; + + case 4: + // 0xFF9 + r = 63; + g = 63; + b = 37; + break; + + case 5: + // 0xFF1 + r = 63; + g = 63; + b = 4; + break; + + default: + // 0xFFF + r = 63; + g = 63; + b = 63; + } + + _screen->getPalette(4)[12 * 3 + 0] = r; + _screen->getPalette(4)[12 * 3 + 1] = g; + _screen->getPalette(4)[12 * 3 + 2] = b; +} + +#pragma mark - + void KyraEngine_LoK::setupSceneResource(int sceneId) { if (!_flags.isTalkie) return; diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 7a7544a589..97ecbcfb28 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -48,6 +48,7 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system) _drawShapeVar5 = 0; _sjisFont = 0; + memset(_fonts, 0, sizeof(_fonts)); } Screen::~Screen() { @@ -56,10 +57,8 @@ Screen::~Screen() { delete[] _pagePtrs[0]; - for (int f = 0; f < ARRAYSIZE(_fonts); ++f) { - delete[] _fonts[f].fontData; - _fonts[f].fontData = NULL; - } + for (int f = 0; f < ARRAYSIZE(_fonts); ++f) + delete _fonts[f]; delete _sjisFont; delete _screenPalette; @@ -103,7 +102,6 @@ bool Screen::init() { } } - _curPage = 0; uint8 *pagePtr = new uint8[SCREEN_PAGE_SIZE * 8]; for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2) @@ -112,9 +110,11 @@ bool Screen::init() { memset(_shapePages, 0, sizeof(_shapePages)); - const int paletteCount = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 12 : 4; + const int paletteCount = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 13 : 4; const int numColors = _use16ColorMode ? 16 : ((_vm->gameFlags().platform == Common::kPlatformAmiga) ? 32 : 256); + _interfacePaletteEnabled = false; + _screenPalette = new Palette(numColors); assert(_screenPalette); @@ -219,8 +219,23 @@ void Screen::updateScreen() { } void Screen::updateDirtyRects() { - if (_forceFullUpdate) { - _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); + // TODO: Enable dirty rect handling for the AMIGA version + if (_forceFullUpdate || _vm->gameFlags().platform == Common::kPlatformAmiga) { + if (_interfacePaletteEnabled) { + _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, 136); + + // Page 8 is not used by Kyra 1 AMIGA, thus we can use it to adjust the colors + copyRegion(0, 136, 0, 0, 320, 64, 0, 8, CR_NO_P_CHECK); + + uint8 *dst = getPagePtr(8); + for (int y = 0; y < 64; ++y) + for (int x = 0; x < 320; ++x) + *dst++ += 32; + + _system->copyRectToScreen(getCPagePtr(8), SCREEN_W, 0, 136, SCREEN_W, 64); + } else { + _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); + } } else { const byte *page0 = getCPagePtr(0); Common::List<Common::Rect>::iterator it; @@ -622,6 +637,41 @@ void Screen::setScreenPalette(const Palette &pal) { _system->setPalette(screenPal, 0, pal.getNumColors()); } +void Screen::enableInterfacePalette(bool e) { + _interfacePaletteEnabled = e; + + _forceFullUpdate = true; + _dirtyRects.clear(); + + // TODO: We might need to reset the mouse cursor + + updateScreen(); +} + +void Screen::setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b) { + if (_vm->gameFlags().platform != Common::kPlatformAmiga) + return; + + uint8 screenPal[32 * 4]; + + assert(32 <= pal.getNumColors()); + + for (int i = 0; i < pal.getNumColors(); ++i) { + if (i != 0x10) { + screenPal[4 * i + 0] = (pal[i * 3 + 0] * 0xFF) / 0x3F; + screenPal[4 * i + 1] = (pal[i * 3 + 1] * 0xFF) / 0x3F; + screenPal[4 * i + 2] = (pal[i * 3 + 2] * 0xFF) / 0x3F; + } else { + screenPal[4 * i + 0] = (r * 0xFF) / 0x3F; + screenPal[4 * i + 1] = (g * 0xFF) / 0x3F; + screenPal[4 * i + 2] = (b * 0xFF) / 0x3F; + } + screenPal[4 * i + 3] = 0; + } + + _system->setPalette(screenPal, 32, pal.getNumColors()); +} + void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) { assert(y + h <= SCREEN_H); const uint8 *src = getPagePtr(page) + y * SCREEN_W; @@ -948,81 +998,52 @@ void Screen::setTextColor(const uint8 *cmap, int a, int b) { } bool Screen::loadFont(FontId fontId, const char *filename) { - Font *fnt = &_fonts[fontId]; - - // FIXME: add font support for amiga version - if (_vm->gameFlags().platform == Common::kPlatformAmiga) - return true; - - if (!fnt) - error("fontId %d is invalid", fontId); - - if (fnt->fontData) - delete[] fnt->fontData; - - uint32 sz = 0; - uint8 *fontData = fnt->fontData = _vm->resource()->fileData(filename, &sz); - - if (!fontData || !sz) - error("Couldn't load font file '%s'", filename); + Font *&fnt = _fonts[fontId]; - uint16 fontSig = READ_LE_UINT16(fontData + 2); - - if (fontSig != 0x500) - error("Invalid font data (file '%s', fontSig: %.04X)", filename, fontSig); + if (!fnt) { + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + fnt = new AMIGAFont(); + else + fnt = new DOSFont(); - fnt->charWidthTable = fontData + READ_LE_UINT16(fontData + 8); - fnt->fontDescOffset = READ_LE_UINT16(fontData + 4); - fnt->charBitmapOffset = READ_LE_UINT16(fontData + 6); - fnt->charWidthTableOffset = READ_LE_UINT16(fontData + 8); - fnt->charHeightTableOffset = READ_LE_UINT16(fontData + 0xC); + assert(fnt); + } - fnt->lastGlyph = *(fnt->fontData + fnt->fontDescOffset + 3); + Common::SeekableReadStream *file = _vm->resource()->createReadStream(filename); + if (!file) + error("Font file '%s' is missing", filename); - return true; + bool ret = fnt->load(*file); + fnt->setColorMap(_textColorsMap); + delete file; + return ret; } Screen::FontId Screen::setFont(FontId fontId) { FontId prev = _currentFont; _currentFont = fontId; + + assert(_fonts[_currentFont]); + return prev; } int Screen::getFontHeight() const { - // FIXME: add font support for amiga version - if (_vm->gameFlags().platform == Common::kPlatformAmiga) - return 0; - - return *(_fonts[_currentFont].fontData + _fonts[_currentFont].fontDescOffset + 4); + return _fonts[_currentFont]->getHeight(); } int Screen::getFontWidth() const { - // FIXME: add font support for amiga version - if (_vm->gameFlags().platform == Common::kPlatformAmiga) - return 0; - - return *(_fonts[_currentFont].fontData + _fonts[_currentFont].fontDescOffset + 5); + return _fonts[_currentFont]->getWidth(); } int Screen::getCharWidth(uint16 c) const { - // FIXME: add font support for amiga version - if (_vm->gameFlags().platform == Common::kPlatformAmiga) - return 0; - if ((c & 0xFF00) && _sjisFont) return _sjisFont->getFontWidth() >> 1; - if (_fonts[_currentFont].lastGlyph < c) - return 0; - else - return (int)_fonts[_currentFont].charWidthTable[c] + _charWidth; + return _fonts[_currentFont]->getCharWidth(c) + _charWidth; } int Screen::getTextWidth(const char *str) const { - // FIXME: add font support for amiga version - if (_vm->gameFlags().platform == Common::kPlatformAmiga) - return 0; - int curLineLen = 0; int maxLineLen = 0; while (1) { @@ -1050,9 +1071,6 @@ int Screen::getTextWidth(const char *str) const { } void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2) { - // FIXME: add font support for amiga version - if (_vm->gameFlags().platform == Common::kPlatformAmiga) - return; uint8 cmap[2]; cmap[0] = color2; cmap[1] = color1; @@ -1107,73 +1125,19 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2 } void Screen::drawCharANSI(uint8 c, int x, int y) { - Font *fnt = &_fonts[_currentFont]; - - if (c > fnt->lastGlyph) - return; - - uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x; - - uint16 bitmapOffset = READ_LE_UINT16(fnt->fontData + fnt->charBitmapOffset + c * 2); - if (bitmapOffset == 0) - return; + Font *fnt = _fonts[_currentFont]; + assert(fnt); - uint8 charWidth = *(fnt->fontData + fnt->charWidthTableOffset + c); - if (!charWidth || charWidth + x > SCREEN_W) - return; + const int charWidth = fnt->getCharWidth(c); + const int charHeight = fnt->getHeight(); - uint8 charH0 = getFontHeight(); - if (!charH0 || charH0 + y > SCREEN_H) + if (x + charWidth > SCREEN_W || y + charHeight > SCREEN_H) return; - uint8 charH1 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2); - uint8 charH2 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2 + 1); - - charH0 -= charH1 + charH2; - - const uint8 *src = fnt->fontData + bitmapOffset; - const int pitch = SCREEN_W - charWidth; - - while (charH1--) { - uint8 col = _textColorsMap[0]; - for (int i = 0; i < charWidth; ++i) { - if (col != 0) - *dst = col; - ++dst; - } - dst += pitch; - } - - while (charH2--) { - uint8 b = 0; - for (int i = 0; i < charWidth; ++i) { - uint8 col; - if (i & 1) { - col = _textColorsMap[b >> 4]; - } else { - b = *src++; - col = _textColorsMap[b & 0xF]; - } - if (col != 0) { - *dst = col; - } - ++dst; - } - dst += pitch; - } - - while (charH0--) { - uint8 col = _textColorsMap[0]; - for (int i = 0; i < charWidth; ++i) { - if (col != 0) - *dst = col; - ++dst; - } - dst += pitch; - } + fnt->drawChar(c, getPagePtr(_curPage) + y * SCREEN_W + x, SCREEN_W); if (_curPage == 0 || _curPage == 1) - addDirtyRect(x, y, charWidth, getFontHeight()); + addDirtyRect(x, y, charWidth, charHeight); } void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) { @@ -2068,85 +2032,94 @@ void Screen::decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch, bool wrapped_decodeFrameDeltaPage<false>(dst, src, pitch); } -void Screen::convertAmigaGfx(uint8 *data, int w, int h, bool offscreen) { - static uint8 tmp[320*200]; - - if (offscreen) { - uint8 *curLine = tmp; - const uint8 *src = data; - int hC = h; - while (hC--) { - uint8 *dst1 = curLine; - uint8 *dst2 = dst1 + 8000; - uint8 *dst3 = dst2 + 8000; - uint8 *dst4 = dst3 + 8000; - uint8 *dst5 = dst4 + 8000; - - int width = w >> 3; - while (width--) { - *dst1++ = *src++; - *dst2++ = *src++; - *dst3++ = *src++; - *dst4++ = *src++; - *dst5++ = *src++; - } - - curLine += 40; +void Screen::convertAmigaGfx(uint8 *data, int w, int h, int depth, bool wsa, int bytesPerPlane) { + const int planeWidth = (bytesPerPlane == -1) ? (w + 7) / 8 : bytesPerPlane; + const int planeSize = planeWidth * h; + const uint imageSize = planeSize * depth; + + // Our static buffer which holds the plane data. We need this + // because the "data" pointer is both source and destination pointer. + // The buffer has enough space to fit the AMIGA MSC files, which are + // the biggest graphics files found in the AMIGA version. + static uint8 temp[40320]; + assert(imageSize <= sizeof(temp)); + + // WSA files store their graphics data in a little different format, than + // the usual AMIGA graphics format used in BitMaps. Thus we need to do + // some special handling for them here. Means we convert them into + // the usual format. + // + // TODO: We might think of moving this conversion into the WSAMovieAmiga + // class. + if (wsa) { + const byte *src = data; + for (int y = 0; y < h; ++y) { + for (int x = 0; x < planeWidth; ++x) + for (int i = 0; i < depth; ++i) + temp[y * planeWidth + x + planeSize * i] = *src++; } } else { - memcpy(tmp, data, w*h); + memcpy(temp, data, imageSize); } for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { - int bytePos = x/8+y*40; - int bitPos = 7-(x&7); - - byte colorIndex = 0; - colorIndex |= (((tmp[bytePos + 8000 * 0] & (1 << bitPos)) >> bitPos) & 0x1) << 0; - colorIndex |= (((tmp[bytePos + 8000 * 1] & (1 << bitPos)) >> bitPos) & 0x1) << 1; - colorIndex |= (((tmp[bytePos + 8000 * 2] & (1 << bitPos)) >> bitPos) & 0x1) << 2; - colorIndex |= (((tmp[bytePos + 8000 * 3] & (1 << bitPos)) >> bitPos) & 0x1) << 3; - colorIndex |= (((tmp[bytePos + 8000 * 4] & (1 << bitPos)) >> bitPos) & 0x1) << 4; - *data++ = colorIndex; + const int bytePos = x / 8 + y * planeWidth; + const int bitPos = 7 - (x & 7); // x & 7 == x % 8 + + byte col = 0; + + for (int i = 0; i < depth; ++i) + col |= ((temp[bytePos + planeSize * i] >> bitPos) & 1) << i; + + *data++ = col; } } } void Screen::convertAmigaMsc(uint8 *data) { - byte *plane1 = data + 5760 * 1; - byte *plane2 = data + 5760 * 2; - byte *plane3 = data + 5760 * 3; - byte *plane4 = data + 5760 * 4; - byte *plane5 = data + 5760 * 5; - byte *plane6 = data + 5760 * 6; - for (int i = 0; i < 5760; ++i) { - byte d = plane6[i]; - d = (plane5[i] |= d); - d = (plane4[i] |= d); - d = (plane3[i] |= d); - d = (plane2[i] |= d); - d = (plane1[i] |= d); - } - byte dst[320*144]; - memset(dst, 0, sizeof(dst)); - static const byte flagTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; - for (int y = 0; y < 144; ++y) { - for (int x = 0; x < 320; ++x) { - if (!(flagTable[x&7] & data[y*40+(x>>3)])) - dst[y*320+x] |= 0x80; - - int layer = 0; - for (int i = 0; i < 7; ++i) { - if (flagTable[x&7] & data[y*40+(x>>3)+i*5760]) - layer = i; - } + // MSC files are always 320x144, thus we can safely assume + // this to be correct. Also they contain 7 planes instead + // of the normal 5 planes, which is used in 32 color mode. + // The need for 7 planes can be explained, because the MSC + // files have 6 bits for the layer number (bits 1 to 6) + // and one bit for the "blocked" flag (bit 0), and every + // plane contains one bit per pixel. + convertAmigaGfx(data, 320, 144, 7); + + // We need to do some post conversion, since + // the AMIGA MSC format is different from the DOS + // one we use internally for our code.That is even + // after converting it from the AMIGA plane based + // approach to one byte per pixel approach. + for (int i = 0; i < 320 * 144; ++i) { + // The lowest bit indicates, whether the position + // is walkable or not. If the bit is set, the + // position is walkable, elsewise it is blocked. + if (data[i] & 1) + data[i] &= 0xFE; + else + data[i] |= 0x80; - if (layer) - dst[y*320+x] |= (layer+1); - } + // The graphics layer for the pixel is saved + // in the following format: + // The highest bit set indicates the number of + // the graphics layer. We count the first + // bit as 0 here, thus we need to add one, + // to get the correct number. + // + // Funnily since the first bit (bit 0) is + // resevered for testing whether the position + // is walkable or not, there is no possibility + // for layer 1 to be present. + int layer = 0; + for (int k = 0; k < 7; ++k) + if (data[i] & (1 << k)) + layer = k + 1; + + data[i] &= 0x80; + data[i] |= layer; } - memcpy(data, dst, 320*144); } template<bool noXor> @@ -2794,6 +2767,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette uint8 *srcPtr = srcData + 10 + palSize; uint8 *dstData = getPagePtr(dstPage); + memset(dstData, 0, SCREEN_PAGE_SIZE); if (dstPage == 0 || tempPage == 0) _forceFullUpdate = true; @@ -2815,7 +2789,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette if (!scumm_stricmp(ext, "MSC")) Screen::convertAmigaMsc(dstData); else - Screen::convertAmigaGfx(dstData, 320, 200, false); + Screen::convertAmigaGfx(dstData, 320, 200); } if (skip) @@ -3026,6 +3000,230 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) { #pragma mark - +DOSFont::DOSFont() { + _data = _widthTable = _heightTable = 0; + _colorMap = 0; + _width = _height = _numGlyphs = 0; + _bitmapOffsets = 0; +} + +bool DOSFont::load(Common::SeekableReadStream &file) { + unload(); + + _data = new uint8[file.size()]; + assert(_data); + + file.read(_data, file.size()); + if (file.err()) + return false; + + const uint16 fontSig = READ_LE_UINT16(_data + 2); + + if (fontSig != 0x0500) { + warning("DOSFont: invalid font: %.04X)", fontSig); + return false; + } + + const uint16 descOffset = READ_LE_UINT16(_data + 4); + + _width = _data[descOffset + 5]; + _height = _data[descOffset + 4]; + _numGlyphs = _data[descOffset + 3] + 1; + + _bitmapOffsets = (uint16 *)(_data + READ_LE_UINT16(_data + 6)); + _widthTable = _data + READ_LE_UINT16(_data + 8); + _heightTable = _data + READ_LE_UINT16(_data + 12); + + for (int i = 0; i < _numGlyphs; ++i) + _bitmapOffsets[i] = READ_LE_UINT16(&_bitmapOffsets[i]); + + return true; +} + +int DOSFont::getCharWidth(uint8 c) const { + if (c >= _numGlyphs) + return 0; + return _widthTable[c]; +} + +void DOSFont::drawChar(uint8 c, byte *dst, int pitch) const { + if (c >= _numGlyphs) + return; + + if (!_bitmapOffsets[c]) + return; + + const uint8 *src = _data + _bitmapOffsets[c]; + const uint8 charWidth = _widthTable[c]; + + if (!charWidth) + return; + + pitch -= charWidth; + + uint8 charH1 = _heightTable[c * 2 + 0]; + uint8 charH2 = _heightTable[c * 2 + 1]; + uint8 charH0 = _height - (charH1 + charH2); + + while (charH1--) { + uint8 col = _colorMap[0]; + for (int i = 0; i < charWidth; ++i) { + if (col != 0) + *dst = col; + ++dst; + } + dst += pitch; + } + + while (charH2--) { + uint8 b = 0; + for (int i = 0; i < charWidth; ++i) { + uint8 col; + if (i & 1) { + col = _colorMap[b >> 4]; + } else { + b = *src++; + col = _colorMap[b & 0xF]; + } + if (col != 0) { + *dst = col; + } + ++dst; + } + dst += pitch; + } + + while (charH0--) { + uint8 col = _colorMap[0]; + for (int i = 0; i < charWidth; ++i) { + if (col != 0) + *dst = col; + ++dst; + } + dst += pitch; + } +} + +void DOSFont::unload() { + delete[] _data; + _data = _widthTable = _heightTable = 0; + _colorMap = 0; + _width = _height = _numGlyphs = 0; + _bitmapOffsets = 0; +} + + +AMIGAFont::AMIGAFont() { + _width = _height = 0; + memset(_chars, 0, sizeof(_chars)); +} + +bool AMIGAFont::load(Common::SeekableReadStream &file) { + const uint16 dataSize = file.readUint16BE(); + if (dataSize + 2 != file.size()) + return false; + + _width = file.readByte(); + _height = file.readByte(); + + // Read the character definition offset table + uint16 offsets[ARRAYSIZE(_chars)]; + for (int i = 0; i < ARRAYSIZE(_chars); ++i) + offsets[i] = file.readUint16BE() + 4; + + if (file.err()) + return false; + + for (int i = 0; i < ARRAYSIZE(_chars); ++i) { + file.seek(offsets[i], SEEK_SET); + + _chars[i].yOffset = file.readByte(); + _chars[i].xOffset = file.readByte(); + _chars[i].width = file.readByte(); + file.readByte(); // unused + + // If the y offset is 255, then the character + // does not have any bitmap representation + if (_chars[i].yOffset != 255) { + Character::Graphics &g = _chars[i].graphics; + + g.width = file.readUint16BE(); + g.height = file.readUint16BE(); + + int depth = file.readByte(); + int specialWidth = file.readByte(); + int flags = file.readByte(); + int bytesPerPlane = file.readByte(); + + assert(depth != 0 && specialWidth == 0 && flags == 0 && bytesPerPlane != 0); + + // Allocate a temporary buffer to store the plane data + const int planesSize = bytesPerPlane * g.height * depth; + uint8 *tempData = new uint8[MAX(g.width * g.height, planesSize)]; + assert(tempData); + + file.read(tempData, planesSize); + + // Convert the plane based graphics to our graphic format + Screen::convertAmigaGfx(tempData, g.width, g.height, depth, false, bytesPerPlane); + + // Create a buffer perfectly fitting the character + g.bitmap = new uint8[g.width * g.height]; + assert(g.bitmap); + + memcpy(g.bitmap, tempData, g.width * g.height); + delete[] tempData; + } + + if (file.err()) + return false; + } + + return !file.err(); +} + +int AMIGAFont::getCharWidth(uint8 c) const { + if (c >= 255) + return 0; + return _chars[c].width; +} + +void AMIGAFont::drawChar(uint8 c, byte *dst, int pitch) const { + if (c >= 255) + return; + + if (_chars[c].yOffset == 255) + return; + + dst += _chars[c].yOffset * pitch; + dst += _chars[c].xOffset; + + pitch -= _chars[c].graphics.width; + + const uint8 *src = _chars[c].graphics.bitmap; + assert(src); + + for (int y = 0; y < _chars[c].graphics.height; ++y) { + for (int x = 0; x < _chars[c].graphics.width; ++x) { + if (*src) + *dst = *src; + ++src; + ++dst; + } + + dst += pitch; + } +} + +void AMIGAFont::unload() { + _width = _height = 0; + for (int i = 0; i < ARRAYSIZE(_chars); ++i) + delete[] _chars[i].graphics.bitmap; + memset(_chars, 0, sizeof(_chars)); +} + +#pragma mark - + Palette::Palette(const int numColors) : _palData(0), _numColors(numColors) { _palData = new uint8[numColors * 3]; assert(_palData); @@ -3049,9 +3247,9 @@ void Palette::loadAmigaPalette(Common::ReadStream &stream, int startIndex, int c for (int i = 0; i < colors; ++i) { uint16 col = stream.readUint16BE(); - _palData[(i + startIndex) * 3 + 2] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4; - _palData[(i + startIndex) * 3 + 1] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4; - _palData[(i + startIndex) * 3 + 0] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4; + _palData[(i + startIndex) * 3 + 2] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4; + _palData[(i + startIndex) * 3 + 1] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4; + _palData[(i + startIndex) * 3 + 0] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4; } } @@ -3061,9 +3259,9 @@ void Palette::loadPC98Palette(Common::ReadStream &stream, int startIndex, int co for (int i = 0; i < colors; ++i) { const byte g = stream.readByte(), r = stream.readByte(), b = stream.readByte(); - _palData[(i + startIndex) * 3 + 0] = ((r & 0x0F) * 0x3F) / 0x0F; - _palData[(i + startIndex) * 3 + 1] = ((g & 0x0F) * 0x3F) / 0x0F; - _palData[(i + startIndex) * 3 + 2] = ((b & 0x0F) * 0x3F) / 0x0F; + _palData[(i + startIndex) * 3 + 0] = ((r & 0xF) * 0x3F) / 0xF; + _palData[(i + startIndex) * 3 + 1] = ((g & 0xF) * 0x3F) / 0xF; + _palData[(i + startIndex) * 3 + 2] = ((b & 0xF) * 0x3F) / 0xF; } } diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index d8380d104d..41837c90e3 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -56,15 +56,114 @@ struct ScreenDim { uint16 unkE; }; -struct Font { - uint8 *fontData; - uint8 *charWidthTable; - uint16 fontDescOffset; - uint16 charBitmapOffset; - uint16 charWidthTableOffset; - uint16 charHeightTableOffset; - - uint8 lastGlyph; +/** + * A class that handles KYRA fonts. + */ +class Font { +public: + virtual ~Font() {} + + /** + * Tries to load a file from the given stream + */ + virtual bool load(Common::SeekableReadStream &file) = 0; + + /** + * The font height. + */ + virtual int getHeight() const = 0; + + /** + * The font width, this is the maximal character + * width. + */ + virtual int getWidth() const = 0; + + /** + * Gets the width of a specific character. + */ + virtual int getCharWidth(uint8 c) const = 0; + + /** + * Sets a text palette map. The map contains 16 entries. + */ + virtual void setColorMap(const uint8 *src) = 0; + + /** + * Draws a specific character. + * + * TODO/FIXME: Replace this with a nicer API. Currently + * the user has to assure that the character fits. + * We use this API, since it's hard to assure dirty rect + * handling from outside Screen. + */ + virtual void drawChar(uint8 c, byte *dst, int pitch) const = 0; +}; + +/** + * Implementation of the Font interface for DOS fonts. + * + * TODO: Clean up the implementation. For example we might be able + * to not to keep the whole font in memory. + */ +class DOSFont : public Font { +public: + DOSFont(); + ~DOSFont() { unload(); } + + bool load(Common::SeekableReadStream &file); + int getHeight() const { return _height; } + int getWidth() const { return _width; } + int getCharWidth(uint8 c) const; + void setColorMap(const uint8 *src) { _colorMap = src; } + void drawChar(uint8 c, byte *dst, int pitch) const; + +private: + void unload(); + + const uint8 *_colorMap; + + uint8 *_data; + + int _width, _height; + + uint8 _numGlyphs; + + uint8 *_widthTable; + uint8 *_heightTable; + uint16 *_bitmapOffsets; +}; + +/** + * Implementation of the Font interface for AMIGA fonts. + */ +class AMIGAFont : public Font { +public: + AMIGAFont(); + ~AMIGAFont() { unload(); } + + bool load(Common::SeekableReadStream &file); + int getHeight() const { return _height; } + int getWidth() const { return _width; } + int getCharWidth(uint8 c) const; + void setColorMap(const uint8 *src) {} + void drawChar(uint8 c, byte *dst, int pitch) const; + +private: + void unload(); + + int _width, _height; + + struct Character { + uint8 yOffset, xOffset, width; + + struct Graphics { + uint16 width, height; + uint8 *bitmap; + } graphics; + }; + + Character _chars[255]; }; /** @@ -256,6 +355,10 @@ public: void setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue); virtual void setScreenPalette(const Palette &pal); + // AMIGA version only + void enableInterfacePalette(bool e); + void setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b); + void getRealPalette(int num, uint8 *dst); Palette &getPalette(int num); void copyPalette(const int dst, const int src); @@ -342,7 +445,7 @@ public: static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false); static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch, bool noXor); - static void convertAmigaGfx(uint8 *data, int w, int h, bool offscreen = true); + static void convertAmigaGfx(uint8 *data, int w, int h, int depth = 5, bool wsa = false, int bytesPerPlane = -1); static void convertAmigaMsc(uint8 *data); protected: @@ -382,7 +485,7 @@ protected: Common::Array<Palette *> _palettes; Palette *_internFadePalette; - Font _fonts[FID_NUM]; + Font *_fonts[FID_NUM]; uint8 _textColorsMap[16]; uint8 *_decodeShapeBuffer; @@ -469,6 +572,9 @@ protected: int _drawShapeVar4; int _drawShapeVar5; + // AMIGA version + bool _interfacePaletteEnabled; + // debug bool _debugEnabled; }; diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp index 9fdeae1398..feddb29dd2 100644 --- a/engines/kyra/screen_lok.cpp +++ b/engines/kyra/screen_lok.cpp @@ -240,6 +240,22 @@ int Screen_LoK::getRectSize(int x, int y) { return ((x*y) << 3); } +void Screen_LoK::postProcessCursor(uint8 *data, int width, int height, int pitch) { + if (_vm->gameFlags().platform == Common::kPlatformAmiga && _interfacePaletteEnabled) { + pitch -= width; + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + if (*data != _cursorColorKey) + *data += 32; + ++data; + } + + data += pitch; + } + } +} + #pragma mark - Screen_LoK_16::Screen_LoK_16(KyraEngine_LoK *vm, OSystem *system) : Screen_LoK(vm, system) { diff --git a/engines/kyra/screen_lok.h b/engines/kyra/screen_lok.h index 4eb22df374..ae1d85c0a7 100644 --- a/engines/kyra/screen_lok.h +++ b/engines/kyra/screen_lok.h @@ -59,6 +59,9 @@ public: void addBitBlitRect(int x, int y, int w, int h); void bitBlitRects(); + // AMIGA specific + virtual void postProcessCursor(uint8 *data, int width, int height, int pitch); + protected: enum { kNumBitBlitRects = 10 diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp index 849c6b776d..929fbae1eb 100644 --- a/engines/kyra/script_lok.cpp +++ b/engines/kyra/script_lok.cpp @@ -231,12 +231,11 @@ int KyraEngine_LoK::o1_fadeSpecialPalette(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); if (_currentCharacter->sceneId != 45) { if (stackPos(0) == 13) { - // TODO: Check this! _screen->copyPalette(0, 12); _screen->setScreenPalette(_screen->getPalette(0)); } } else { - warning("KyraEngine_LoK::o1_fadeSpecialPalette not implemented"); + setupZanthiaPalette(stackPos(0)); } } else { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); @@ -579,7 +578,17 @@ int KyraEngine_LoK::o1_restoreAllObjectBackgrounds(EMCState *script) { int KyraEngine_LoK::o1_setCustomPaletteRange(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); - _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1)); + if (_flags.platform == Common::kPlatformAmiga) { + if (_currentCharacter->sceneId == 45) { + setupZanthiaPalette(stackPos(0)); + } else if (stackPos(0) == 29) { + _screen->copyPalette(0, 11); + } else if (stackPos(0) == 13) { + _screen->copyPalette(0, 12); + } + } else { + _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1)); + } return 0; } @@ -1213,37 +1222,77 @@ int KyraEngine_LoK::o1_findBrightestFireberry(EMCState *script) { int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); - int palIndex = 0; - switch (stackPos(0)) { - case 0x1E: - palIndex = 9; - break; - case 0x1F: - palIndex = 10; - break; + if (_flags.platform == Common::kPlatformAmiga) { + int palIndex = 0; + + switch (stackPos(0)) { + case -1: + // The original seemed to draw some lines on page 2 here, which looks strange... + //if (!(_brandonStatusBit & 2)) + // warning("Unimplemented case for o1_setFireberryGlowPalette"); + palIndex = 9; + break; - case 0x20: - palIndex = 11; - break; + case 30: + palIndex = 7; + break; - case 0x21: - case -1: - palIndex = 12; - break; + case 31: + palIndex = 8; + break; - default: - palIndex = 8; - } - if (_brandonStatusBit & 2) { - if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 && - _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 && - (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) { - palIndex = 14; + case 32: + case 33: + palIndex = 9; + break; + + case 28: case 29: default: + palIndex = 6; + } + + if (_brandonStatusBit & 2) { + if (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198) + palIndex = 10; } + + _screen->copyPalette(0, palIndex); + } else { + int palIndex = 0; + + switch (stackPos(0)) { + case 0x1E: + palIndex = 9; + break; + + case 0x1F: + palIndex = 10; + break; + + case 0x20: + palIndex = 11; + break; + + case 0x21: + case -1: + palIndex = 12; + break; + + default: + palIndex = 8; + } + + if (_brandonStatusBit & 2) { + if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 && + _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 && + (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) { + palIndex = 14; + } + } + + _screen->getPalette(1).copy(_specialPalettes[palIndex], 0, 15, 228); } - _screen->getPalette(1).copy(_specialPalettes[palIndex], 0, 15, 228); return 0; } @@ -1255,9 +1304,11 @@ int KyraEngine_LoK::o1_drinkPotionAnimation(EMCState *script) { int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_makeAmuletAppear(%p) ()", (const void *)script); - WSAMovie_v1 amulet(this); - amulet.open("AMULET.WSA", 1, 0); - if (amulet.opened()) { + Movie *amulet = createWSAMovie(); + assert(amulet); + amulet->open("AMULET.WSA", 1, 0); + + if (amulet->opened()) { assert(_amuleteAnim); _screen->hideMouse(); snd_playSoundEffect(0x70); @@ -1275,7 +1326,7 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) { if (code == 14) snd_playSoundEffect(0x73); - amulet.displayFrame(code, 0, 224, 152, 0, 0, 0); + amulet->displayFrame(code, 0, 224, 152, 0, 0, 0); _animator->_updateScreen = true; while (_system->getMillis() < nextTime) { @@ -1287,6 +1338,8 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) { } _screen->showMouse(); } + + delete amulet; setGameFlag(0x2D); return 0; } diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index 2145591c03..38d1b90e7a 100644 --- a/engines/kyra/seqplayer.cpp +++ b/engines/kyra/seqplayer.cpp @@ -389,7 +389,8 @@ void SeqPlayer::s1_copyRegionSpecial() { const int x = (Screen::SCREEN_W - _screen->getTextWidth(copyStr)) / 2; const int y = 179; _screen->setTextColorMap(colorMap); - _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC); + if (_vm->gameFlags().platform != Common::kPlatformAmiga) + _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC); _screen->printText(copyStr, x, y, 0xF, 0xC); } break; diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index 0279831c9d..3c953ef1d4 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -901,13 +901,13 @@ int KyraEngine_LoK::seq_playEnd() { if (_endSequenceNeedLoading) { snd_playWanderScoreViaMap(50, 1); setupPanPages(); - _finalA = new WSAMovie_v1(this); + _finalA = createWSAMovie(); assert(_finalA); _finalA->open("finala.wsa", 1, 0); - _finalB = new WSAMovie_v1(this); + _finalB = createWSAMovie(); assert(_finalB); _finalB->open("finalb.wsa", 1, 0); - _finalC = new WSAMovie_v1(this); + _finalC = createWSAMovie(); assert(_finalC); _endSequenceNeedLoading = 0; _finalC->open("finalc.wsa", 1, 0); @@ -1473,7 +1473,7 @@ int KyraEngine_LoK::handleBeadState() { _beadStateVar = 0; } } else { - _screen->copyBlockToPage(_screen->_curPage, beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect); _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); beadState1.x = x; beadState1.y = y; @@ -1663,6 +1663,14 @@ void KyraEngine_LoK::closeFinalWsa() { } void KyraEngine_LoK::updateKyragemFading() { + if (_flags.platform == Common::kPlatformAmiga) { + // The AMIGA version seems to have no fading for the Kyragem. The code does not + // alter the screen palette. + // + // TODO: Check this in the original. + return; + } + static const uint8 kyraGemPalette[0x28] = { 0x3F, 0x3B, 0x38, 0x34, 0x32, 0x2F, 0x2C, 0x29, 0x25, 0x22, 0x1F, 0x1C, 0x19, 0x16, 0x12, 0x0F, 0x0C, 0x0A, 0x06, 0x03, @@ -1674,14 +1682,17 @@ void KyraEngine_LoK::updateKyragemFading() { return; _kyragemFadingState.timerCount = _system->getMillis() + 4 * _tickLength; + int palPos = 684; for (int i = 0; i < 20; ++i) { _screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset]; _screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset]; _screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset]; } + _screen->setScreenPalette(_screen->getPalette(0)); _animator->_updateScreen = true; + switch (_kyragemFadingState.nextOperation) { case 0: --_kyragemFadingState.bOffset; diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 86680a7b76..2062b9e88a 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -1598,10 +1598,15 @@ void KyraEngine_LoK::loadMainScreen(int page) { else warning("no main graphics file found"); - if (_flags.platform == Common::kPlatformAmiga) + _screen->copyRegion(0, 0, 0, 0, 320, 200, page, 0, Screen::CR_NO_P_CHECK); + + if (_flags.platform == Common::kPlatformAmiga) { _screen->copyPalette(1, 0); + _screen->setInterfacePalette(_screen->getPalette(1), 0x3F, 0x3F, 0x3F); - _screen->copyRegion(0, 0, 0, 0, 320, 200, page, 0); + // TODO: Move this to a better place + _screen->enableInterfacePalette(true); + } } void KyraEngine_HoF::initStaticResource() { @@ -2249,6 +2254,22 @@ void GUI_LoK::initStaticResource() { _menu[5].item[2].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeWalk); _menu[5].item[4].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeText); _menu[5].item[5].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsApply); + + // The AMIGA version uses different colors, due to its 32 color nature. We did setup the 256 color version + // colors above, so we need to overwrite those with the correct values over here. + if (_vm->gameFlags().platform == Common::kPlatformAmiga) { + for (int i = 0; i < 6; ++i) { + _menu[i].bkgdColor = 17; + _menu[i].color1 = 31; + _menu[i].color2 = 18; + + for (int j = 0; j < _menu[i].numberOfItems; ++j) { + _menu[i].item[j].bkgdColor = 17; + _menu[i].item[j].color1 = 31; + _menu[i].item[j].color2 = 18; + } + } + } } void KyraEngine_LoK::setupButtonData() { diff --git a/engines/kyra/text.cpp b/engines/kyra/text.cpp index 4d511eae01..6965dbc985 100644 --- a/engines/kyra/text.cpp +++ b/engines/kyra/text.cpp @@ -200,37 +200,15 @@ void TextDisplayer::printTalkTextMessage(const char *text, int x, int y, uint8 c _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage, Screen::CR_NO_P_CHECK); int curPage = _screen->_curPage; _screen->_curPage = srcPage; - for (int i = 0; i < lineCount; ++i) { - top = i * 10 + _talkMessageY; - char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN]; - int left = getCenterStringX(msg, x1, x2); - printText(msg, left, top, color, 0xC, 0); - } - _screen->_curPage = curPage; - _talkMessagePrinted = true; -} -void TextDisplayer::printIntroTextMessage(const char *text, int x, int y, uint8 col1, uint8 col2, uint8 col3, int dstPage, Screen::FontId font) { - char *str = preprocessString(text); - int lineCount = buildMessageSubstrings(str); - int top = y - lineCount * 10; - if (top < 0) { - top = 0; - } - _talkMessageY = top; - _talkMessageH = lineCount * 10; - int w = getWidestLineWidth(lineCount); - int x1, x2; - calcWidestLineBounds(x1, x2, w, x); - _talkCoords.x = x1; - _talkCoords.w = w + 2; - int curPage = _screen->setCurPage(dstPage); + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + setTextColor(color); for (int i = 0; i < lineCount; ++i) { top = i * 10 + _talkMessageY; char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN]; int left = getCenterStringX(msg, x1, x2); - printText(msg, left, top, col1, col2, col3, font); + printText(msg, left, top, color, 0xC, 0); } _screen->_curPage = curPage; _talkMessagePrinted = true; @@ -248,7 +226,7 @@ void TextDisplayer::printText(const char *str, int x, int y, uint8 c0, uint8 c1, } void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX) { - uint8 colorTable[] = {0x0F, 0x9, 0x0C9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a}; + uint8 colorTable[] = {0x0F, 0x09, 0xC9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a}; int top, left, x1, x2, w, x; char *msg; @@ -259,6 +237,9 @@ void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX x = charX; calcWidestLineBounds(x1, x2, w, x); + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + setTextColor(color); + for (int i = 0; i < lineCount; ++i) { top = i * 10 + _talkMessageY; msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN]; @@ -266,4 +247,91 @@ void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX printText(msg, left, top, color, 0xC, 0); } } + +void TextDisplayer::setTextColor(uint8 color) { + byte r, g, b; + + switch (color) { + case 4: + // 0x09E + r = 0; + g = 37; + b = 58; + break; + + case 5: + // 0xFF5 + r = 63; + g = 63; + b = 21; + break; + + case 27: + // 0x5FF + r = 21; + g = 63; + b = 63; + break; + + case 34: + // 0x8E5 + r = 33; + g = 58; + b = 21; + break; + + case 58: + // 0x9FB + r = 37; + g = 63; + b = 46; + break; + + case 85: + // 0x7CF + r = 29; + g = 50; + b = 63; + break; + + case 114: + case 117: + // 0xFAF + r = 63; + g = 42; + b = 63; + break; + + case 128: + case 129: + // 0xFCC + r = 63; + g = 50; + b = 50; + break; + + case 201: + // 0xFD8 + r = 63; + g = 54; + b = 33; + break; + + case 216: + // 0xFC6 + r = 63; + g = 50; + b = 25; + break; + + default: + // 0xEEE + r = 58; + g = 58; + b = 58; + } + + _screen->setPaletteIndex(0x10, r, g, b); +} + } // end of namespace Kyra diff --git a/engines/kyra/text.h b/engines/kyra/text.h index d45e5f9242..73d77dcb4c 100644 --- a/engines/kyra/text.h +++ b/engines/kyra/text.h @@ -50,8 +50,6 @@ public: virtual void calcWidestLineBounds(int &x1, int &x2, int w, int cx); virtual void restoreTalkTextMessageBkgd(int srcPage, int dstPage); void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage); - void printIntroTextMessage(const char *text, int x, int y, uint8 col1, uint8 col2, uint8 col3, - int dstPage, Screen::FontId font=Screen::FID_8_FNT); virtual void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT); void printCharacterText(const char *text, int8 charNum, int charX); @@ -66,6 +64,9 @@ protected: uint16 y, x, w; }; + // TODO: AMIGA and LoK specific, move to a better location + void setTextColor(uint8 color); + enum { TALK_SUBSTRING_LEN = 80, TALK_SUBSTRING_NUM = 6 @@ -76,6 +77,7 @@ protected: TalkCoords _talkCoords; bool _talkMessagePrinted; }; + } // end of namespace Kyra #endif diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp index 3f4bfb65ac..d2128b7037 100644 --- a/engines/kyra/text_lok.cpp +++ b/engines/kyra/text_lok.cpp @@ -322,18 +322,27 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) { _screen->hideMouse(); - _screen->fillRect(8, 143, 311, 152, 12); + _screen->fillRect(8, 143, 311, 152, _flags.platform == Common::kPlatformAmiga ? 19 : 12); - if (_startSentencePalIndex != color || _fadeText != false) { - _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color*3]; + if (_flags.platform == Common::kPlatformAmiga) { + if (color != 19) { + _currSentenceColor[0] = 0x3F; + _currSentenceColor[1] = 0x3F; + _currSentenceColor[2] = 0x3F; + + _screen->setInterfacePalette(_screen->getPalette(1), + _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]); + } + } else if (_startSentencePalIndex != color || _fadeText != false) { + _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color*3+0]; _currSentenceColor[1] = _screen->getPalette(0)[766] = _screen->getPalette(0)[color*3+1]; _currSentenceColor[2] = _screen->getPalette(0)[767] = _screen->getPalette(0)[color*3+2]; _screen->setScreenPalette(_screen->getPalette(0)); - _startSentencePalIndex = 0; + _startSentencePalIndex = color; } - _text->printText(sentence, 8, 143, 0xFF, 12, 0); + _text->printText(sentence, 8, 143, 0xFF, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0); _screen->showMouse(); setTextFadeTimerCountdown(15); _fadeText = false; @@ -364,10 +373,15 @@ void KyraEngine_LoK::updateTextFade() { } } - _screen->getPalette(0)[765] = _currSentenceColor[0]; - _screen->getPalette(0)[766] = _currSentenceColor[1]; - _screen->getPalette(0)[767] = _currSentenceColor[2]; - _screen->setScreenPalette(_screen->getPalette(0)); + if (_flags.platform == Common::kPlatformAmiga) { + _screen->setInterfacePalette(_screen->getPalette(1), + _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]); + } else { + _screen->getPalette(0)[765] = _currSentenceColor[0]; + _screen->getPalette(0)[766] = _currSentenceColor[1]; + _screen->getPalette(0)[767] = _currSentenceColor[2]; + _screen->setScreenPalette(_screen->getPalette(0)); + } if (finished) { _fadeText = false; diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index ef3fd1a966..b221f869b7 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -75,11 +75,10 @@ int WSAMovie_v1::open(const char *filename, int offscreenDecode, Palette *palBuf } if (_numFrames & 0x8000) { - // This is used in the Amiga version, the wsa playing code - // doesn't include any handling of it though, so we disable - // this warning for now. - //warning("Unhandled wsa flags 0x80"); - _flags |= 0x80; + // This is used in the Amiga version. + if (_vm->gameFlags().platform != Common::kPlatformAmiga) + warning("Unhandled wsa flags 0x8000"); + _flags |= WF_FLIPPED; _numFrames &= 0x7FFF; } _currentFrame = _numFrames; @@ -262,7 +261,7 @@ void WSAMovieAmiga::displayFrame(int frameNum, int pageNum, int x, int y, uint16 if (_currentFrame == _numFrames) { if (!(_flags & WF_NO_FIRST_FRAME)) { Screen::decodeFrameDelta(dst, _deltaBuffer, true); - Screen::convertAmigaGfx(dst, _width, _height); + Screen::convertAmigaGfx(dst, _width, _height, 5, (_flags & WF_FLIPPED) != 0); if (_flags & WF_OFFSCREEN_DECODE) { dst = _offscreenBuffer; @@ -341,7 +340,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) { const uint8 *src = _frameData + _frameOffsTable[frameNum]; Screen::decodeFrame4(src, _deltaBuffer, _deltaBufferSize); Screen::decodeFrameDelta(dst, _deltaBuffer, true); - Screen::convertAmigaGfx(dst, _width, _height); + Screen::convertAmigaGfx(dst, _width, _height, 5, (_flags & WF_FLIPPED) != 0); src = dst; dst = 0; diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index 49ac5a28fe..957ee386ef 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -85,6 +85,7 @@ public: WF_OFFSCREEN_DECODE = 0x10, WF_NO_LAST_FRAME = 0x20, WF_NO_FIRST_FRAME = 0x40, + WF_FLIPPED = 0x80, WF_HAS_PALETTE = 0x100, WF_XOR = 0x200 }; diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 2ddc6979c9..eacae8e697 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -120,8 +120,11 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { #endif // Segments DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable)); + DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias DCmd_Register("segment_info", WRAP_METHOD(Console, cmdSegmentInfo)); + DCmd_Register("seginfo", WRAP_METHOD(Console, cmdSegmentInfo)); // alias DCmd_Register("segment_kill", WRAP_METHOD(Console, cmdKillSegment)); + DCmd_Register("segkill", WRAP_METHOD(Console, cmdKillSegment)); // alias // Garbage collection DCmd_Register("gc", WRAP_METHOD(Console, cmdGCInvoke)); DCmd_Register("gc_objects", WRAP_METHOD(Console, cmdGCObjects)); @@ -157,7 +160,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { DCmd_Register("go", WRAP_METHOD(Console, cmdGo)); // Breakpoints DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList)); + DCmd_Register("bplist", WRAP_METHOD(Console, cmdBreakpointList)); // alias DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete)); + DCmd_Register("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias DCmd_Register("bp_exec_method", WRAP_METHOD(Console, cmdBreakpointExecMethod)); DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointExecMethod)); // alias DCmd_Register("bp_exec_function", WRAP_METHOD(Console, cmdBreakpointExecFunction)); @@ -165,7 +170,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { // VM DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps)); DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist)); + DCmd_Register("vmvarlist", WRAP_METHOD(Console, cmdVMVarlist)); // alias DCmd_Register("vm_vars", WRAP_METHOD(Console, cmdVMVars)); + DCmd_Register("vmvars", WRAP_METHOD(Console, cmdVMVars)); // alias DCmd_Register("stack", WRAP_METHOD(Console, cmdStack)); DCmd_Register("value_type", WRAP_METHOD(Console, cmdValueType)); DCmd_Register("view_listnode", WRAP_METHOD(Console, cmdViewListNode)); @@ -300,9 +307,9 @@ bool Console::cmdHelp(int argc, const char **argv) { #endif DebugPrintf("\n"); DebugPrintf("Segments:\n"); - DebugPrintf(" segment_table - Lists all segments\n"); - DebugPrintf(" segment_info - Provides information on the specified segment\n"); - DebugPrintf(" segment_kill - Deletes the specified segment\n"); + DebugPrintf(" segment_table / segtable - Lists all segments\n"); + DebugPrintf(" segment_info / seginfo - Provides information on the specified segment\n"); + DebugPrintf(" segment_kill / segkill - Deletes the specified segment\n"); DebugPrintf("\n"); DebugPrintf("Garbage collection:\n"); DebugPrintf(" gc - Invokes the garbage collector\n"); @@ -335,15 +342,15 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" go - Executes the script\n"); DebugPrintf("\n"); DebugPrintf("Breakpoints:\n"); - DebugPrintf(" bp_list - Lists the current breakpoints\n"); - DebugPrintf(" bp_del - Deletes a breakpoint with the specified index\n"); + DebugPrintf(" bp_list / bplist - Lists the current breakpoints\n"); + DebugPrintf(" bp_del / bpdel - Deletes a breakpoint with the specified index\n"); DebugPrintf(" bp_exec_method / bpx - Sets a breakpoint on the execution of the specified method\n"); DebugPrintf(" bp_exec_function / bpe - Sets a breakpoint on the execution of the specified exported function\n"); DebugPrintf("\n"); DebugPrintf("VM:\n"); DebugPrintf(" script_steps - Shows the number of executed SCI operations\n"); - DebugPrintf(" vm_varlist - Shows the addresses of variables in the VM\n"); - DebugPrintf(" vm_vars - Displays or changes variables in the VM\n"); + DebugPrintf(" vm_varlist / vmvarlist - Shows the addresses of variables in the VM\n"); + DebugPrintf(" vm_vars / vmvars - Displays or changes variables in the VM\n"); DebugPrintf(" stack - Lists the specified number of stack elements\n"); DebugPrintf(" value_type - Determines the type of a value\n"); DebugPrintf(" view_listnode - Examines the list node at the given address\n"); @@ -1713,7 +1720,7 @@ bool Console::cmdVMVarlist(int argc, const char **argv) { } bool Console::cmdVMVars(int argc, const char **argv) { - if (argc < 2) { + if (argc < 3) { DebugPrintf("Displays or changes variables in the VM\n"); DebugPrintf("Usage: %s <type> <varnum> [<value>]\n", argv[0]); DebugPrintf("First parameter is either g(lobal), l(ocal), t(emp) or p(aram).\n"); @@ -1747,10 +1754,10 @@ bool Console::cmdVMVars(int argc, const char **argv) { } switch (argc) { - case 2: + case 3: DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(scriptState.variables[vartype][idx])); break; - case 3: + case 4: if (parse_reg_t(_vm->_gamestate, argv[3], &scriptState.variables[vartype][idx])) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 7118eb682d..d0b3919c60 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -569,6 +569,20 @@ static const struct SciGameDescription SciGameDescriptions[] = { SCI_VERSION_1 }, + // 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, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1 + }, + // Eco Quest 2 - English DOS Non-Interactive Demo // SCI interpreter version 1.001.055 {{"ecoquest2", "Demo", { @@ -591,6 +605,17 @@ static const struct SciGameDescription SciGameDescriptions[] = { SCI_VERSION_1_1 }, + // 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, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1_1 + }, + // Freddy Pharkas - English DOS demo (from FRG) // SCI interpreter version 1.001.069 {{"freddypharkas", "Demo", { diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index 0a74ac32e4..fa64957bec 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -497,6 +497,9 @@ int game_init(EngineState *s) { if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND) game_init_sound(s, 0); + // Load game language into printLang property of game object + s->getLanguage(); + return 0; } diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 4133f4cb3b..2ccd88b709 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -320,6 +320,7 @@ SciKernelFunction kfunct_mappers[] = { /*(?)*/ DEFUN("Lock", kLock, "iii*"), /*(?)*/ DEFUN("Palette", kPalette, "i.*"), /*(?)*/ DEFUN("IsItSkip", kIsItSkip, "iiiii"), + /*7b*/ DEFUN("StrSplit", kStrSplit, "rrZr"), // Non-experimental Functions without a fixed ID DEFUN("CosMult", kTimesCos, "ii"), @@ -345,7 +346,6 @@ SciKernelFunction kfunct_mappers[] = { DEFUN("MemorySegment", kStub, ".*"), DEFUN("ListOps", kStub, ".*"), DEFUN("ATan", kStub, ".*"), - DEFUN("StrSplit", kStub, ".*"), DEFUN("MergePoly", kStub, ".*"), DEFUN("AssertPalette", kStub, ".*"), DEFUN("TextColors", kStub, ".*"), diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 15f7c9fcf3..83b43542d4 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -540,6 +540,7 @@ reg_t kResCheck(EngineState *s, int funct_nr, int argc, reg_t *argv); reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv); reg_t kShowMovie(EngineState *s, int funct_nr, int argc, reg_t *argv); reg_t kSetVideoMode(EngineState *s, int funct_nr, int argc, reg_t *argv); +reg_t kStrSplit(EngineState *s, int funct_nr, int argc, reg_t *argv); reg_t k_Unknown(EngineState *s, int funct_nr, int argc, reg_t *argv); // The Unknown/Unnamed kernel function diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index c693009b35..2f0072ec67 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -251,7 +251,7 @@ reg_t kStub(EngineState *s, int funct_nr, int argc, reg_t *argv) { } strcat(tmpbuf, ")"); - warning(tmpbuf); + warning("%s", tmpbuf); return NULL_REG; } diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index b6bb404d5b..6e5a19bba9 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -812,4 +812,21 @@ reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv) { return s->r_acc; } +reg_t kStrSplit(EngineState *s, int funct_nr, int argc, reg_t *argv) { + const char *format = kernel_dereference_char_pointer(s, argv[1], 0); + const char *sep = !argv[2].isNull() ? kernel_dereference_char_pointer(s, argv[2], 0) : NULL; + Common::String str = s->strSplit(format, sep); + + // Make sure target buffer is large enough + char *buf = kernel_dereference_char_pointer(s, argv[0], str.size() + 1); + + if (buf) { + strcpy(buf, str.c_str()); + return argv[0]; + } else { + warning("StrSplit: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(argv[0]), str.size() + 1, str.c_str()); + return NULL_REG; + } +} + } // End of namespace Sci diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp index c019f7a3bc..a55d692afe 100644 --- a/engines/sci/engine/message.cpp +++ b/engines/sci/engine/message.cpp @@ -33,7 +33,7 @@ MessageTuple MessageState::getTuple() { t.noun = *(_engineCursor.index_record + 0); t.verb = *(_engineCursor.index_record + 1); - if (_version == 2101) { + if (_version == 2) { t.cond = 0; t.seq = 1; } else { @@ -47,7 +47,7 @@ MessageTuple MessageState::getTuple() { MessageTuple MessageState::getRefTuple() { MessageTuple t; - if (_version == 2101) { + if (_version == 2) { t.noun = 0; t.verb = 0; t.cond = 0; @@ -68,7 +68,7 @@ void MessageState::initCursor() { } void MessageState::advanceCursor(bool increaseSeq) { - _engineCursor.index_record += ((_version == 2101) ? 4 : 11); + _engineCursor.index_record += ((_version == 2) ? 4 : 11); _engineCursor.index++; if (increaseSeq) @@ -142,7 +142,7 @@ int MessageState::getMessage() { } int MessageState::getTalker() { - return (_version == 2101) ? -1 : *(_engineCursor.index_record + 4); + return (_version == 2) ? -1 : *(_engineCursor.index_record + 4); } MessageTuple &MessageState::getLastTuple() { @@ -154,7 +154,7 @@ int MessageState::getLastModule() { } Common::String MessageState::getText() { - char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5)); + char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2) ? 2 : 5)); Common::String strippedStr; Common::String skippedSubstr; @@ -215,7 +215,7 @@ void MessageState::gotoNext() { } int MessageState::getLength() { - int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5)); + int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2) ? 2 : 5)); char *stringptr = (char *)_currentResource->data + offset; return strlen(stringptr); } @@ -244,8 +244,12 @@ int MessageState::loadRes(ResourceManager *resmgr, int module, bool lock) { _locked = lock; _version = READ_LE_UINT16(_currentResource->data); + debug(5, "Message: reading resource %d.msg, version %d.%03d", _module, _version / 1000, _version % 1000); - int offs = (_version == 2101) ? 0 : 4; + // We assume for now that storing the major version is sufficient + _version /= 1000; + + int offs = (_version == 2) ? 0 : 4; _recordCount = READ_LE_UINT16(_currentResource->data + 4 + offs); _indexRecords = _currentResource->data + 6 + offs; diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 38320c29cc..405c9ec66f 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -172,15 +172,62 @@ Common::String EngineState::getLanguageString(const char *str, kLanguage lang) c return Common::String(str); } +kLanguage EngineState::getLanguage() { + kLanguage lang = K_LANG_ENGLISH; + + if (((SciEngine*)g_engine)->getKernel()->_selectorMap.printLang != -1) { + EngineState *s = this; + + lang = (kLanguage)GET_SEL32V(s->game_obj, printLang); + + if ((_version == SCI_VERSION_1_1) || (lang == K_LANG_NONE)) { + // If language is set to none, we use the language from the game detector. + // SSCI reads this from resource.cfg (early games do not have a language + // setting in resource.cfg, but instead have the secondary language number + // hardcoded in the game script). + // SCI1.1 games always use the language setting from the config file + // (essentially disabling runtime language switching). + // Note: only a limited number of multilanguage games have been tested + // so far, so this information may not be 100% accurate. + switch (((Sci::SciEngine*)g_engine)->getLanguage()) { + case Common::FR_FRA: + lang = K_LANG_FRENCH; + break; + case Common::ES_ESP: + lang = K_LANG_SPANISH; + break; + case Common::IT_ITA: + lang = K_LANG_ITALIAN; + break; + case Common::DE_DEU: + lang = K_LANG_GERMAN; + break; + case Common::JA_JPN: + lang = K_LANG_JAPANESE; + break; + case Common::PT_BRA: + lang = K_LANG_PORTUGUESE; + break; + default: + lang = K_LANG_ENGLISH; + } + + // Store language in printLang selector + PUT_SEL32V(s->game_obj, printLang, lang); + } + } + + return lang; +} + Common::String EngineState::strSplit(const char *str, const char *sep) { EngineState *s = this; - kLanguage lang = (kLanguage)GET_SEL32V(s->game_obj, printLang); - kLanguage subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang); + kLanguage lang = getLanguage(); + kLanguage subLang = K_LANG_NONE; - // Use English when no language settings are present in the game - if (lang == K_LANG_NONE) - lang = K_LANG_ENGLISH; + if (((SciEngine*)g_engine)->getKernel()->_selectorMap.subtitleLang != -1) + subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang); Common::String retval = getLanguageString(str, lang); diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index b41e9e383a..3db926ab3d 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -125,6 +125,7 @@ public: virtual ~EngineState(); virtual void saveLoadWithSerializer(Common::Serializer &ser); + kLanguage getLanguage(); public: int widget_serial_counter; /**< Used for savegames */ diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 0f8fee0876..02c287a99a 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -126,9 +126,9 @@ static int validate_variable(reg_t *r, reg_t *stack_base, int type, int max, int } if (g_debug_weak_validations) - warning(txt); + warning("%s", txt); else - error(txt); + error("%s", txt); #ifdef STRICT_READ return 1; diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index 5054bffd30..99a28153c4 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -413,6 +413,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "maniac", "Maniac Mansion (SW).prg", kGenUnchanged, Common::SE_SWE, Common::kPlatformNES, "NES" }, { "maniac", "Maniac Mansion (U).prg", kGenUnchanged, Common::EN_USA, Common::kPlatformNES, "NES" }, { "maniac", "Maniac Mansion (G).prg", kGenUnchanged, Common::DE_DEU, Common::kPlatformNES, "NES" }, + { "maniac", "Maniac Mansion (I).prg", kGenUnchanged, Common::IT_ITA, Common::kPlatformNES, "NES" }, { "maniac", "Maniac Mansion (Sp).prg", kGenUnchanged, Common::ES_ESP, Common::kPlatformNES, "NES" }, { "zak", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 }, diff --git a/engines/scumm/file_nes.cpp b/engines/scumm/file_nes.cpp index 444b117037..e2604039a4 100644 --- a/engines/scumm/file_nes.cpp +++ b/engines/scumm/file_nes.cpp @@ -113,6 +113,16 @@ static const ScummNESFile::Resource res_roomgfx_esp[40] = { { 0x07CA4, 0x02D6 }, { 0x10001, 0x06A3 }, { 0x106A4, 0x091F }, { 0x10FC3, 0x0361 }, { 0x11324, 0x0489 }, { 0x117AD, 0x0437 }, { 0x11BE4, 0x086E }, { 0x12452, 0x0199 }, { 0x125EB, 0x0947 }, { 0x12F32, 0x037A } }; +static const ScummNESFile::Resource res_roomgfx_ita[40] = { + { 0x04001, 0x03EF }, { 0x043F0, 0x069E }, { 0x04A8E, 0x0327 }, { 0x04DB5, 0x053B }, { 0x052F0, 0x06BE }, + { 0x059AE, 0x0682 }, { 0x06030, 0x0778 }, { 0x067A8, 0x0517 }, { 0x06CBF, 0x07FB }, { 0x074BA, 0x07BE }, + { 0x08001, 0x07A5 }, { 0x087A6, 0x06DD }, { 0x08E83, 0x04EA }, { 0x0936D, 0x07E2 }, { 0x09B4F, 0x0791 }, + { 0x0A2E0, 0x07B5 }, { 0x0AA95, 0x0515 }, { 0x0AFAA, 0x0799 }, { 0x0B743, 0x04BB }, { 0x0BBFE, 0x0319 }, + { 0x0C001, 0x0464 }, { 0x0C465, 0x072C }, { 0x0CB91, 0x0827 }, { 0x0D3B8, 0x0515 }, { 0x0D8CD, 0x064E }, + { 0x0DF1B, 0x0775 }, { 0x0E690, 0x06DD }, { 0x0ED6D, 0x0376 }, { 0x0F0E3, 0x05F7 }, { 0x0F6DA, 0x0787 }, + { 0x07C78, 0x02D6 }, { 0x10001, 0x06A3 }, { 0x106A4, 0x0921 }, { 0x10FC5, 0x0361 }, { 0x11326, 0x0489 }, + { 0x117AF, 0x0437 }, { 0x11BE6, 0x0863 }, { 0x12449, 0x0199 }, { 0x125E2, 0x0947 }, { 0x12F29, 0x037A } +}; const ScummNESFile::ResourceGroup res_roomgfx = { ScummNESFile::NES_ROOMGFX, @@ -123,6 +133,7 @@ const ScummNESFile::ResourceGroup res_roomgfx = { res_roomgfx_fra, res_roomgfx_ger, res_roomgfx_esp, + res_roomgfx_ita, } }; @@ -132,6 +143,7 @@ static const ScummNESFile::Resource res_costumegfx_swe[2] = { { 0x2EFE1, 0x0EB8 static const ScummNESFile::Resource res_costumegfx_fra[2] = { { 0x30001, 0x0EB8 }, { 0x2F608, 0x0340 } }; static const ScummNESFile::Resource res_costumegfx_ger[2] = { { 0x30001, 0x0EB8 }, { 0x2F4CE, 0x0340 } }; static const ScummNESFile::Resource res_costumegfx_esp[2] = { { 0x30001, 0x0EB8 }, { 0x2F0F6, 0x0340 } }; +static const ScummNESFile::Resource res_costumegfx_ita[2] = { { 0x30001, 0x0EB8 }, { 0x2F4A0, 0x0340 } }; const ScummNESFile::ResourceGroup res_costumegfx = { ScummNESFile::NES_COSTUMEGFX, @@ -142,6 +154,7 @@ const ScummNESFile::ResourceGroup res_costumegfx = { res_costumegfx_fra, res_costumegfx_ger, res_costumegfx_esp, + res_costumegfx_ita, } }; @@ -223,6 +236,19 @@ static const ScummNESFile::Resource res_rooms_esp[55] = { { 0x289BE, 0x058E }, { 0x2A418, 0x0201 }, { 0x2A6BE, 0x0325 }, { 0x23D84, 0x01FC }, { 0x2AC46, 0x02A9 }, { 0x2AEEF, 0x02C9 }, { 0x2B2C0, 0x03D2 }, { 0x27D12, 0x0207 }, { 0x2B7FC, 0x0168 }, { 0x2BD06, 0x0169 } }; +static const ScummNESFile::Resource res_rooms_ita[55] = { + { 0x00000, 0x0000 }, { 0x14001, 0x0D70 }, { 0x132A3, 0x04EA }, { 0x15423, 0x086E }, { 0x1378D, 0x06B1 }, + { 0x15D16, 0x070F }, { 0x16658, 0x04DB }, { 0x16B33, 0x0AEF }, { 0x18001, 0x06DF }, { 0x17991, 0x03E1 }, + { 0x18C5C, 0x065E }, { 0x19316, 0x04AF }, { 0x199EA, 0x0448 }, { 0x1A09D, 0x0479 }, { 0x1A516, 0x0445 }, + { 0x1A95B, 0x03A7 }, { 0x1AD02, 0x0826 }, { 0x1B588, 0x0693 }, { 0x1C001, 0x0B92 }, { 0x1CD70, 0x0484 }, + { 0x1D4E3, 0x0598 }, { 0x1DFCB, 0x0538 }, { 0x1E9C9, 0x05D1 }, { 0x1F052, 0x0394 }, { 0x1F70D, 0x0741 }, + { 0x20001, 0x04C2 }, { 0x2053F, 0x0528 }, { 0x21718, 0x05F6 }, { 0x21EB5, 0x0486 }, { 0x223E8, 0x048C }, + { 0x228DA, 0x093A }, { 0x24001, 0x037A }, { 0x247EE, 0x03CA }, { 0x24BB8, 0x050D }, { 0x25289, 0x0346 }, + { 0x1BCAC, 0x01CA }, { 0x255CF, 0x045F }, { 0x25A2E, 0x0552 }, { 0x25F80, 0x0651 }, { 0x26B93, 0x024B }, + { 0x26DDE, 0x01FA }, { 0x270D6, 0x0217 }, { 0x275E4, 0x02F4 }, { 0x28001, 0x045C }, { 0x284CE, 0x08BD }, + { 0x28DDF, 0x05DF }, { 0x27AC9, 0x0201 }, { 0x2A8A3, 0x0325 }, { 0x27D6F, 0x01FC }, { 0x2AE66, 0x02A9 }, + { 0x2B10F, 0x02E7 }, { 0x2B4F9, 0x03DE }, { 0x2BA31, 0x0206 }, { 0x2C001, 0x0168 }, { 0x17DC0, 0x0169 } +}; const ScummNESFile::ResourceGroup res_rooms = { ScummNESFile::NES_ROOM, @@ -233,6 +259,7 @@ const ScummNESFile::ResourceGroup res_rooms = { res_rooms_fra, res_rooms_ger, res_rooms_esp, + res_rooms_ita, } }; @@ -464,6 +491,44 @@ static const ScummNESFile::Resource res_scripts_esp[179] = { { 0x2A2C7, 0x0005 }, { 0x2A2CC, 0x0005 }, { 0x2A2D1, 0x0005 }, { 0x2A2D6, 0x0005 }, { 0x216E8, 0x0033 }, { 0x2A2DB, 0x0005 }, { 0x00000, 0x0000 }, { 0x2A2E0, 0x009C }, { 0x2A37C, 0x009C } }; +static const ScummNESFile::Resource res_scripts_ita[179] = { + { 0x00000, 0x0000 }, { 0x293BE, 0x046B }, { 0x29829, 0x020C }, { 0x29A35, 0x00AA }, { 0x29ADF, 0x03FD }, + { 0x29EDC, 0x01A1 }, { 0x00000, 0x0000 }, { 0x2A07D, 0x005C }, { 0x00000, 0x0000 }, { 0x2A0D9, 0x0005 }, + { 0x2C169, 0x000D }, { 0x2C176, 0x000D }, { 0x186E0, 0x0040 }, { 0x18720, 0x0016 }, { 0x1B528, 0x0046 }, + { 0x1EF9A, 0x00B8 }, { 0x21D0E, 0x0056 }, { 0x17622, 0x0027 }, { 0x1FE4E, 0x0027 }, { 0x1FE75, 0x0027 }, + { 0x1BC1B, 0x0022 }, { 0x15C91, 0x0085 }, { 0x2233B, 0x001E }, { 0x22359, 0x008F }, { 0x192BA, 0x002B }, + { 0x1CB93, 0x0065 }, { 0x1CBF8, 0x003F }, { 0x1CC37, 0x004E }, { 0x1CC85, 0x0055 }, { 0x204C3, 0x007C }, + { 0x16425, 0x0035 }, { 0x1645A, 0x001C }, { 0x16476, 0x0014 }, { 0x1648A, 0x001C }, { 0x164A6, 0x0027 }, + { 0x164CD, 0x018B }, { 0x1D1F4, 0x009B }, { 0x1D28F, 0x010A }, { 0x1D399, 0x001C }, { 0x1D3B5, 0x0056 }, + { 0x1D40B, 0x0072 }, { 0x1E503, 0x0028 }, { 0x1E52B, 0x01AA }, { 0x1E6D5, 0x0233 }, { 0x2845D, 0x0071 }, + { 0x17D72, 0x004E }, { 0x13E3E, 0x0039 }, { 0x18736, 0x02C8 }, { 0x189FE, 0x00BB }, { 0x18AB9, 0x019E }, + { 0x00000, 0x0000 }, { 0x19E32, 0x00F8 }, { 0x21D64, 0x00F7 }, { 0x1E908, 0x00B0 }, { 0x21E5B, 0x0047 }, + { 0x2C183, 0x004D }, { 0x13E77, 0x0024 }, { 0x14D71, 0x0014 }, { 0x17649, 0x0058 }, { 0x176A1, 0x010A }, + { 0x177AB, 0x0009 }, { 0x14D85, 0x01B7 }, { 0x2ABC8, 0x029E }, { 0x23214, 0x070B }, { 0x2C1D0, 0x001A }, + { 0x2C1EA, 0x0021 }, { 0x2C20B, 0x0022 }, { 0x2C22D, 0x0023 }, { 0x2C250, 0x0016 }, { 0x2C266, 0x001E }, + { 0x2C284, 0x0016 }, { 0x2C29A, 0x0027 }, { 0x00000, 0x0000 }, { 0x2C2C1, 0x000E }, { 0x177B4, 0x00AA }, + { 0x22874, 0x0066 }, { 0x14F3C, 0x007B }, { 0x1F3E6, 0x0126 }, { 0x1FE9C, 0x001D }, { 0x1F50C, 0x00B4 }, + { 0x1F5C0, 0x00AA }, { 0x1785E, 0x006D }, { 0x178CB, 0x003F }, { 0x1F66A, 0x00A3 }, { 0x2C2CF, 0x00AF }, + { 0x2C37E, 0x00BD }, { 0x2C43B, 0x0085 }, { 0x20A67, 0x01AA }, { 0x20C11, 0x016A }, { 0x20D7B, 0x0073 }, + { 0x20DEE, 0x003B }, { 0x20E29, 0x00F0 }, { 0x20F19, 0x0047 }, { 0x20F60, 0x00FD }, { 0x2105D, 0x00FF }, + { 0x2115C, 0x0157 }, { 0x212B3, 0x0195 }, { 0x21448, 0x002E }, { 0x21476, 0x00A9 }, { 0x2437B, 0x011F }, + { 0x1BC3D, 0x006F }, { 0x1CCDA, 0x0096 }, { 0x28D8B, 0x0054 }, { 0x19F2A, 0x00B8 }, { 0x19FE2, 0x0071 }, + { 0x14FB7, 0x0057 }, { 0x272ED, 0x02F7 }, { 0x1DA7B, 0x021C }, { 0x1DC97, 0x00FA }, { 0x1DD91, 0x0053 }, + { 0x1DDE4, 0x01CF }, { 0x1500E, 0x004D }, { 0x26FD8, 0x00FE }, { 0x21EA2, 0x0013 }, { 0x2A0DE, 0x00F0 }, + { 0x2449A, 0x00DC }, { 0x2151F, 0x00E7 }, { 0x24576, 0x0022 }, { 0x2B8D7, 0x00FE }, { 0x24598, 0x00BB }, + { 0x250C5, 0x0188 }, { 0x1B56E, 0x000D }, { 0x1B57B, 0x000D }, { 0x2391F, 0x0182 }, { 0x278D8, 0x01F1 }, + { 0x23AA1, 0x0150 }, { 0x23BF1, 0x01C2 }, { 0x23DB3, 0x0016 }, { 0x2B9D5, 0x005C }, { 0x23DC9, 0x0020 }, + { 0x27CCA, 0x00A5 }, { 0x2A1CE, 0x0384 }, { 0x1505B, 0x00FA }, { 0x2B3F6, 0x005E }, { 0x00000, 0x0000 }, + { 0x2524D, 0x003C }, { 0x1E9B8, 0x0011 }, { 0x13E9B, 0x0018 }, { 0x265D1, 0x001F }, { 0x265F0, 0x0054 }, + { 0x26644, 0x0155 }, { 0x26799, 0x004B }, { 0x267E4, 0x017C }, { 0x26960, 0x0027 }, { 0x26987, 0x0041 }, + { 0x269C8, 0x01CB }, { 0x13EB3, 0x001F }, { 0x24653, 0x002A }, { 0x15155, 0x01A4 }, { 0x192E5, 0x0031 }, + { 0x1790A, 0x0087 }, { 0x21606, 0x00DF }, { 0x1D47D, 0x0018 }, { 0x1D495, 0x004E }, { 0x18C57, 0x0005 }, + { 0x152F9, 0x011F }, { 0x15418, 0x000B }, { 0x2467D, 0x0136 }, { 0x247B3, 0x0014 }, { 0x1DFB3, 0x0018 }, + { 0x247C7, 0x0027 }, { 0x1A053, 0x004A }, { 0x00000, 0x0000 }, { 0x2B454, 0x00A5 }, { 0x2A552, 0x00BB }, + { 0x2A60D, 0x0140 }, { 0x197C5, 0x00C6 }, { 0x1988B, 0x014D }, { 0x199D8, 0x0012 }, { 0x2A74D, 0x0005 }, + { 0x2A752, 0x0005 }, { 0x2A757, 0x0005 }, { 0x2A75C, 0x0005 }, { 0x2A761, 0x0005 }, { 0x216E5, 0x0033 }, + { 0x2A766, 0x0005 }, { 0x00000, 0x0000 }, { 0x2A76B, 0x009C }, { 0x2A807, 0x009C } +}; const ScummNESFile::ResourceGroup res_scripts = { ScummNESFile::NES_SCRIPT, @@ -474,6 +539,7 @@ const ScummNESFile::ResourceGroup res_scripts = { res_scripts_fra, res_scripts_ger, res_scripts_esp, + res_scripts_ita, } }; @@ -591,6 +657,25 @@ static const ScummNESFile::Resource res_sounds_esp[82] = { { 0x36320, 0x0E56 }, { 0x37176, 0x0C70 }, { 0x38001, 0x0DEC }, { 0x38DED, 0x0B77 }, { 0x33B4F, 0x042F }, { 0x39964, 0x0AC5 }, { 0x3A429, 0x0BE4 } }; +static const ScummNESFile::Resource res_sounds_ita[82] = { + { 0x0BF54, 0x000A }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 }, + { 0x30ECA, 0x0832 }, { 0x0BF5E, 0x0011 }, { 0x1FEB9, 0x0073 }, { 0x0BF6F, 0x0011 }, { 0x13F57, 0x0011 }, + { 0x23EFE, 0x0056 }, { 0x1BF37, 0x001F }, { 0x13F68, 0x0011 }, { 0x0FF76, 0x000A }, { 0x17F64, 0x000A }, + { 0x1BF56, 0x0019 }, { 0x1FF2C, 0x004B }, { 0x17F6E, 0x000A }, { 0x1BF6F, 0x000F }, { 0x23F54, 0x001D }, + { 0x2BE61, 0x0045 }, { 0x23F71, 0x000F }, { 0x2BEA6, 0x001B }, { 0x2BEC1, 0x0033 }, { 0x27F6B, 0x0011 }, + { 0x2BEF4, 0x000F }, { 0x2BF03, 0x0075 }, { 0x2F7F1, 0x0014 }, { 0x0BF54, 0x000A }, { 0x2F805, 0x00FF }, + { 0x2F904, 0x000F }, { 0x2F913, 0x000F }, { 0x2F922, 0x0092 }, { 0x2F922, 0x0092 }, { 0x2F9B4, 0x002D }, + { 0x2F9E1, 0x00F8 }, { 0x2FAD9, 0x0016 }, { 0x2FAEF, 0x0011 }, { 0x2FB00, 0x004B }, { 0x2FB4B, 0x0011 }, + { 0x2FB5C, 0x003B }, { 0x2FB97, 0x008A }, { 0x2FC21, 0x0011 }, { 0x2FC32, 0x000F }, { 0x2FC41, 0x00A2 }, + { 0x2FCE3, 0x00D3 }, { 0x2FDB6, 0x0097 }, { 0x2BEF4, 0x000F }, { 0x2FC41, 0x00A2 }, { 0x316FC, 0x05D1 }, + { 0x316FC, 0x05D1 }, { 0x2FE4D, 0x0011 }, { 0x0BF54, 0x000A }, { 0x2BF03, 0x0075 }, { 0x1BF37, 0x001F }, + { 0x31CCD, 0x098E }, { 0x2FB00, 0x004B }, { 0x2FE5E, 0x0011 }, { 0x30ECA, 0x0832 }, { 0x2FE6F, 0x000F }, + { 0x2FE7E, 0x002F }, { 0x2FEAD, 0x001D }, { 0x2FECA, 0x0018 }, { 0x2FEE2, 0x0016 }, { 0x2FEF8, 0x001B }, + { 0x3265B, 0x0088 }, { 0x2FF13, 0x0065 }, { 0x326E3, 0x0065 }, { 0x32748, 0x0073 }, { 0x327BB, 0x00F9 }, + { 0x328B4, 0x049E }, { 0x32D52, 0x0EA8 }, { 0x34001, 0x0B18 }, { 0x34B19, 0x0B9C }, { 0x356B5, 0x0C6B }, + { 0x36320, 0x0E56 }, { 0x37176, 0x0C70 }, { 0x38001, 0x0DEC }, { 0x38DED, 0x0B77 }, { 0x39964, 0x042F }, + { 0x39D93, 0x0AC5 }, { 0x3A858, 0x0BE4 } +}; const ScummNESFile::ResourceGroup res_sounds = { ScummNESFile::NES_SOUND, @@ -601,6 +686,7 @@ const ScummNESFile::ResourceGroup res_sounds = { res_sounds_fra, res_sounds_ger, res_sounds_esp, + res_sounds_ita, } }; @@ -646,6 +732,13 @@ static const ScummNESFile::Resource res_costumes_esp[25] = { { 0x0FEF1, 0x0055 }, { 0x13F28, 0x003B }, { 0x0FEF1, 0x0055 }, { 0x17F2A, 0x0045 }, { 0x1FE71, 0x0040 }, { 0x1FEB1, 0x003C }, { 0x13EEE, 0x003A }, { 0x13EEE, 0x003A }, { 0x0FEF1, 0x0055 }, { 0x13EA3, 0x004B } }; +static const ScummNESFile::Resource res_costumes_ita[25] = { + { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, + { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x13ED2, 0x004B }, { 0x0FEEB, 0x0055 }, + { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FF40, 0x0036 }, { 0x13F1D, 0x003A }, { 0x13F1D, 0x003A }, + { 0x0FEEB, 0x0055 }, { 0x17F29, 0x003B }, { 0x0FEEB, 0x0055 }, { 0x1BE76, 0x0045 }, { 0x1BEBB, 0x0040 }, + { 0x1BEFB, 0x003C }, { 0x13F1D, 0x003A }, { 0x13F1D, 0x003A }, { 0x0FEEB, 0x0055 }, { 0x13ED2, 0x004B } +}; const ScummNESFile::ResourceGroup res_costumes = { ScummNESFile::NES_COSTUME, @@ -656,6 +749,7 @@ const ScummNESFile::ResourceGroup res_costumes = { res_costumes_fra, res_costumes_ger, res_costumes_esp, + res_costumes_ita, } }; @@ -665,6 +759,7 @@ static const ScummNESFile::Resource res_globdata_swe[1] = { { 0x2C001, 0x0307 } static const ScummNESFile::Resource res_globdata_fra[1] = { { 0x2C628, 0x0307 } }; static const ScummNESFile::Resource res_globdata_ger[1] = { { 0x2C4EE, 0x0307 } }; static const ScummNESFile::Resource res_globdata_esp[1] = { { 0x2C001, 0x0307 } }; +static const ScummNESFile::Resource res_globdata_ita[1] = { { 0x2C4C0, 0x0307 } }; const ScummNESFile::ResourceGroup res_globdata = { ScummNESFile::NES_GLOBDATA, @@ -675,6 +770,7 @@ const ScummNESFile::ResourceGroup res_globdata = { res_globdata_fra, res_globdata_ger, res_globdata_esp, + res_globdata_ita, } }; @@ -685,6 +781,7 @@ static const ScummNESFile::Resource res_sprpals_swe[2] = { { 0x07F55, 0x0010 }, static const ScummNESFile::Resource res_sprpals_fra[2] = { { 0x07ED8, 0x0010 }, { 0x07EE8, 0x0010 } }; static const ScummNESFile::Resource res_sprpals_ger[2] = { { 0x07F6B, 0x0010 }, { 0x0BF17, 0x0010 } }; static const ScummNESFile::Resource res_sprpals_esp[2] = { { 0x0BF15, 0x0010 }, { 0x0BF25, 0x0010 } }; +static const ScummNESFile::Resource res_sprpals_ita[2] = { { 0x07F54, 0x0010 }, { 0x07F64, 0x0010 } }; const ScummNESFile::ResourceGroup res_sprpals = { ScummNESFile::NES_SPRPALS, @@ -695,6 +792,7 @@ const ScummNESFile::ResourceGroup res_sprpals = { res_sprpals_fra, res_sprpals_ger, res_sprpals_esp, + res_sprpals_ita, } }; @@ -705,6 +803,7 @@ static const ScummNESFile::Resource res_sprdesc_swe[2] = { { 0x0BF1B, 0x0031 }, static const ScummNESFile::Resource res_sprdesc_fra[2] = { { 0x07EF8, 0x0031 }, { 0x07F29, 0x0009 } }; static const ScummNESFile::Resource res_sprdesc_ger[2] = { { 0x0BF27, 0x0031 }, { 0x0BF58, 0x0009 } }; static const ScummNESFile::Resource res_sprdesc_esp[2] = { { 0x0BF35, 0x0031 }, { 0x0BF66, 0x0009 } }; +static const ScummNESFile::Resource res_sprdesc_ita[2] = { { 0x0BF17, 0x0031 }, { 0x07F74, 0x0009 } }; const ScummNESFile::ResourceGroup res_sprdesc = { ScummNESFile::NES_SPRDESC, @@ -715,6 +814,7 @@ const ScummNESFile::ResourceGroup res_sprdesc = { res_sprdesc_fra, res_sprdesc_ger, res_sprdesc_esp, + res_sprdesc_ita, } }; @@ -725,6 +825,7 @@ static const ScummNESFile::Resource res_sprlens_swe[2] = { { 0x13E6A, 0x0115 }, static const ScummNESFile::Resource res_sprlens_fra[2] = { { 0x0FE61, 0x0115 }, { 0x07ED2, 0x0006 } }; static const ScummNESFile::Resource res_sprlens_ger[2] = { { 0x2BE1A, 0x0115 }, { 0x07F65, 0x0006 } }; static const ScummNESFile::Resource res_sprlens_esp[2] = { { 0x2EFE1, 0x0115 }, { 0x07F7A, 0x0006 } }; +static const ScummNESFile::Resource res_sprlens_ita[2] = { { 0x23DE9, 0x0115 }, { 0x07F4E, 0x0006 } }; const ScummNESFile::ResourceGroup res_sprlens = { ScummNESFile::NES_SPRLENS, @@ -735,6 +836,7 @@ const ScummNESFile::ResourceGroup res_sprlens = { res_sprlens_fra, res_sprlens_ger, res_sprlens_esp, + res_sprlens_ita, } }; @@ -745,6 +847,7 @@ static const ScummNESFile::Resource res_sproffs_swe[2] = { { 0x2BCE0, 0x022A }, static const ScummNESFile::Resource res_sproffs_fra[2] = { { 0x2F959, 0x022A }, { 0x07F32, 0x000C } }; static const ScummNESFile::Resource res_sproffs_ger[2] = { { 0x2F81F, 0x022A }, { 0x0BF61, 0x000C } }; static const ScummNESFile::Resource res_sproffs_esp[2] = { { 0x2F447, 0x022A }, { 0x0BF6F, 0x000C } }; +static const ScummNESFile::Resource res_sproffs_ita[2] = { { 0x2BC37, 0x022A }, { 0x0BF48, 0x000C } }; const ScummNESFile::ResourceGroup res_sproffs = { ScummNESFile::NES_SPROFFS, @@ -755,6 +858,7 @@ const ScummNESFile::ResourceGroup res_sproffs = { res_sproffs_fra, res_sproffs_ger, res_sproffs_esp, + res_sproffs_ita, } }; @@ -765,6 +869,7 @@ static const ScummNESFile::Resource res_sprdata_swe[2] = { { 0x2C401, 0x2BE0 }, static const ScummNESFile::Resource res_sprdata_fra[2] = { { 0x2CA28, 0x2BE0 }, { 0x07E48, 0x008A } }; static const ScummNESFile::Resource res_sprdata_ger[2] = { { 0x2C8EE, 0x2BE0 }, { 0x0FE61, 0x008A } }; static const ScummNESFile::Resource res_sprdata_esp[2] = { { 0x2C401, 0x2BE0 }, { 0x0FE67, 0x008A } }; +static const ScummNESFile::Resource res_sprdata_ita[2] = { { 0x2C8C0, 0x2BE0 }, { 0x0FE61, 0x008A } }; const ScummNESFile::ResourceGroup res_sprdata = { ScummNESFile::NES_SPRDATA, @@ -775,6 +880,7 @@ const ScummNESFile::ResourceGroup res_sprdata = { res_sprdata_fra, res_sprdata_ger, res_sprdata_esp, + res_sprdata_ita, } }; @@ -784,6 +890,7 @@ static const ScummNESFile::Resource res_charset_swe[1] = { { 0x3F739, 0x0090 } } static const ScummNESFile::Resource res_charset_fra[1] = { { 0x3F739, 0x0090 } }; static const ScummNESFile::Resource res_charset_ger[1] = { { 0x3F739, 0x0090 } }; static const ScummNESFile::Resource res_charset_esp[1] = { { 0x3F739, 0x0090 } }; +static const ScummNESFile::Resource res_charset_ita[1] = { { 0x3F739, 0x0090 } }; const ScummNESFile::ResourceGroup res_charset = { ScummNESFile::NES_CHARSET, @@ -794,6 +901,7 @@ const ScummNESFile::ResourceGroup res_charset = { res_charset_fra, res_charset_ger, res_charset_esp, + res_charset_ita, } }; @@ -803,6 +911,7 @@ static const ScummNESFile::Resource res_preplist_swe[1] = { { 0x3FBA9, 0x000E } static const ScummNESFile::Resource res_preplist_fra[1] = { { 0x3FBAF, 0x0010 } }; static const ScummNESFile::Resource res_preplist_ger[1] = { { 0x3FBAB, 0x000F } }; static const ScummNESFile::Resource res_preplist_esp[1] = { { 0x3FBAE, 0x000F } }; +static const ScummNESFile::Resource res_preplist_ita[1] = { { 0x3FBAA, 0x0010 } }; const ScummNESFile::ResourceGroup res_preplist = { ScummNESFile::NES_PREPLIST, @@ -813,6 +922,7 @@ const ScummNESFile::ResourceGroup res_preplist = { res_preplist_fra, res_preplist_ger, res_preplist_esp, + res_preplist_ita, } }; @@ -1281,6 +1391,9 @@ bool ScummNESFile::open(const Common::String &filename) { } else if (!strcmp(md5str, "f163cf53f7850e43fb482471e5c52e1a")) { _ROMset = kROMsetSpain; debug(2, "ROM contents verified as Maniac Mansion (Spain)"); + } else if (!strcmp(md5str, "54a68a5f5e3c86da42b7ca5f51e79b1d")) { + _ROMset = kROMsetItaly; + debug(2, "ROM contents verified as Maniac Mansion (Italy)"); } else { error("Unsupported Maniac Mansion ROM, md5: %s", md5str); return false; diff --git a/engines/scumm/file_nes.h b/engines/scumm/file_nes.h index b255705922..274ec02ed0 100644 --- a/engines/scumm/file_nes.h +++ b/engines/scumm/file_nes.h @@ -41,6 +41,7 @@ public: kROMsetFrance, kROMsetGermany, kROMsetSpain, + kROMsetItaly, kROMsetNum }; diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index cb7f906f13..9a1d6485e2 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Thu Jul 30 10:23:41 2009 + This file was generated by the md5table tool on Mon Aug 10 19:27:14 2009 DO NOT EDIT MANUALLY! */ @@ -46,6 +46,7 @@ static const MD5Table md5table[] = { { "0b3222aaa7efcf283eb621e0cefd26cc", "puttputt", "HE 60", "", -1, Common::RU_RUS, Common::kPlatformPC }, { "0be88565f734b1e9e77ccaaf3bb14b29", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC }, { "0bf1a3eb198ca1bd2ebe104825cec770", "puttrace", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, + { "0c331637580950aea2346e012ef2a868", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformAtariST }, { "0c45eb4baff0c12c3d9dfa889c8070ab", "pajama3", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "0cccfa5223099a60e76cfcca57a1a141", "freddi3", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformPC }, @@ -425,7 +426,7 @@ static const MD5Table md5table[] = { { "a525c1753c1db5011c00417da37887ef", "PuttTime", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "a561d2e2413cc1c71d5a1bf87bf493ea", "lost", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "a56e8d9d4281c53c3f63c9bd22a59e21", "catalog", "HE CUP", "Preview", 10978342, Common::EN_ANY, Common::kPlatformUnknown }, - { "a570381b028972d891052ee1e51dc011", "maniac", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformAtariST }, + { "a570381b028972d891052ee1e51dc011", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformAtariST }, { "a5c5388da9bf0e6662fdca8813a79d13", "farm", "", "", 86962, Common::EN_ANY, Common::kPlatformWindows }, { "a654fb60c3b67d6317a7894ffd9f25c5", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, { "a7cacad9c40c4dc9e1812abf6c8af9d5", "puttcircus", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, @@ -563,6 +564,7 @@ static const MD5Table md5table[] = { { "e144f5f49d9241d2a9dee2576b3d09cb", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "e17db1ddf91b39ca6bbc8ad3ed19e883", "monkey", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns }, { "e246e02db9630533a40d99c9f54a8e01", "monkey2", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, + { "e28bc6dbec750bced1b7c98d6caa32ce", "maniac", "NES", "", 262144, Common::IT_ITA, Common::kPlatformNES }, { "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 61", "", -1, Common::HB_ISR, Common::kPlatformPC }, { "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", "HE 100", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows }, { "e44ea295a3f8fe4f41983080dab1e9ce", "freddi", "HE 90", "Updated", -1, Common::FR_FRA, Common::kPlatformMacintosh }, diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index 2362427779..528cceb0cc 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -391,8 +391,8 @@ void Sound::playSound(int soundID) { 000070: 01 18 5a 00 10 00 02 28 5f 00 01 00 00 00 00 00 |..Z....(_.......| */ } - else if ((_vm->_game.platform == Common::kPlatformMacintosh) && (_vm->_game.id == GID_INDY3) && (ptr[26] == 0)) { - // Sound fomat as used in Indy3 EGA Mac. + else if ((_vm->_game.platform == Common::kPlatformMacintosh) && (_vm->_game.id == GID_INDY3) && READ_BE_UINT16(ptr + 8) == 0x1C) { + // Sound format as used in Indy3 EGA Mac. // It seems to be closely related to the Amiga format, see player_v3a.cpp // The following is known: // offset 0, 16 LE: total size @@ -411,8 +411,8 @@ void Sound::playSound(int soundID) { flags = Audio::Mixer::FLAG_AUTOFREE; size = READ_BE_UINT16(ptr + 12); - if (size == 0) // WORKAROUND bug #1852635: Sound 54 has size 0. - return; + assert(size); + rate = 3579545 / READ_BE_UINT16(ptr + 20); sound = (char *)malloc(size); int vol = ptr[24] * 4; diff --git a/engines/tinsel/background.cpp b/engines/tinsel/background.cpp index 94525e33dd..583b9817a9 100644 --- a/engines/tinsel/background.cpp +++ b/engines/tinsel/background.cpp @@ -249,6 +249,8 @@ void DrawBackgnd(void) { UpdateScreenRect(*r); } + g_system->updateScreen(); + // delete all the clipping rectangles ResetClipRect(); } diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp index 1df932f1af..1e9693542e 100644 --- a/engines/tinsel/bmv.cpp +++ b/engines/tinsel/bmv.cpp @@ -1118,6 +1118,7 @@ void CopyMovieToScreen(void) { BmvDrawText(true); PalettesToVideoDAC(); // Keep palette up-to-date UpdateScreenRect(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + g_system->updateScreen(); BmvDrawText(false); } diff --git a/engines/tinsel/dw.h b/engines/tinsel/dw.h index 826c0e38ba..943d728354 100644 --- a/engines/tinsel/dw.h +++ b/engines/tinsel/dw.h @@ -100,7 +100,7 @@ typedef int HPOLYGON; #define NO_ENTRY_NUM (-3458) // Magic unlikely number -#define SAMPLETIMEOUT (15*ONE_SECOND) +#define SAMPLETIMEOUT (20*ONE_SECOND) // Language for the resource strings enum LANGUAGE { diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp index cb334d96b0..0b3f2e6e24 100644 --- a/engines/tinsel/graphics.cpp +++ b/engines/tinsel/graphics.cpp @@ -713,7 +713,6 @@ void UpdateScreenRect(const Common::Rect &pClip) { byte *pSrc = (byte *)_vm->screen().getBasePtr(pClip.left, pClip.top); g_system->copyRectToScreen(pSrc, _vm->screen().pitch, pClip.left, pClip.top + yOffset, pClip.width(), pClip.height()); - g_system->updateScreen(); } /** diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp index 12d9f0393a..6ce1ea7288 100644 --- a/engines/tinsel/music.cpp +++ b/engines/tinsel/music.cpp @@ -189,7 +189,7 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) { } // the index and length of the last tune loaded - static uint32 dwLastMidiIndex; + static uint32 dwLastMidiIndex = 0; //static uint32 dwLastSeqLen; uint32 dwSeqLen = 0; // length of the sequence @@ -256,6 +256,23 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) { midiStream.close(); + // WORKAROUND for bug #2820054 "DW1: No intro music at first start on Wii", + // which actually affects all ports, since it's specific to the GRA version. + // + // The GRA version does not seem to set the channel volume at all for the first + // intro track, thus we need to do that here. We only initialize the channels + // used in that sequence. And we are using 127 as default channel volume. + // + // Only in the GRA version dwFileOffset can be "38888", just to be sure, we + // check for the SCN files feature flag not being set though. + if (_vm->getGameID() == GID_DW1 && dwFileOffset == 38888 && !(_vm->getFeatures() & GF_SCNFILES)) { + _vm->_midiMusic->send(0x7F07B0 | 3); + _vm->_midiMusic->send(0x7F07B0 | 5); + _vm->_midiMusic->send(0x7F07B0 | 8); + _vm->_midiMusic->send(0x7F07B0 | 10); + _vm->_midiMusic->send(0x7F07B0 | 13); + } + _vm->_midiMusic->playXMIDI(midiBuffer.pDat, dwSeqLen, bLoop); // Store the length @@ -303,6 +320,8 @@ int GetMidiVolume() { return volMusic; } +static int priorVolMusic = 0; + /** * Sets the volume of the MIDI music. * @param vol New volume - 0..MAXMIDIVOL @@ -310,23 +329,24 @@ int GetMidiVolume() { void SetMidiVolume(int vol) { assert(vol >= 0 && vol <= Audio::Mixer::kMaxChannelVolume); - if (vol == 0 && volMusic == 0) { + if (vol == 0 && priorVolMusic == 0) { // Nothing to do - } else if (vol == 0 && volMusic != 0) { + } else if (vol == 0 && priorVolMusic != 0) { // Stop current midi sequence StopMidi(); - } else if (vol != 0 && volMusic == 0) { + _vm->_midiMusic->setVolume(vol); + } else if (vol != 0 && priorVolMusic == 0) { // Perhaps restart last midi sequence - if (currentLoop) { + if (currentLoop) PlayMidiSequence(currentMidi, true); - _vm->_midiMusic->setVolume(vol); - } - } else if (vol != 0 && volMusic != 0) { + + _vm->_midiMusic->setVolume(vol); + } else if (vol != 0 && priorVolMusic != 0) { // Alter current volume _vm->_midiMusic->setVolume(vol); } - volMusic = vol; + priorVolMusic = vol; } /** @@ -374,6 +394,7 @@ void DeleteMidiBuffer() { MidiMusicPlayer::MidiMusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false) { memset(_channel, 0, sizeof(_channel)); + memset(_channelVolume, 0, sizeof(_channelVolume)); _masterVolume = 0; this->open(); _xmidiParser = MidiParser::createParser_XMIDI(); diff --git a/engines/tinsel/palette.cpp b/engines/tinsel/palette.cpp index 8df9e9a375..84e88fe06b 100644 --- a/engines/tinsel/palette.cpp +++ b/engines/tinsel/palette.cpp @@ -133,7 +133,6 @@ void psxPaletteMapper(PALQ *originalPal, uint8 *psxClut, byte *mapperTable) { void PalettesToVideoDAC(void) { PALQ *pPalQ; // palette Q iterator VIDEO_DAC_Q *pDACtail = vidDACdata; // set tail pointer - bool needUpdate = false; // while Q is not empty while (pDAChead != pDACtail) { @@ -162,9 +161,6 @@ void PalettesToVideoDAC(void) { pColours = pDACtail->pal.pRGBarray; } - if (pDACtail->numColours > 0) - needUpdate = true; - // update the system palette g_system->setPalette((byte *)pColours, pDACtail->destDACindex, pDACtail->numColours); @@ -179,9 +175,6 @@ void PalettesToVideoDAC(void) { // clear all palette moved bits for (pPalQ = palAllocData; pPalQ < palAllocData + NUM_PALETTES; pPalQ++) pPalQ->posInDAC &= ~PALETTE_MOVED; - - if (needUpdate) - g_system->updateScreen(); } /** diff --git a/engines/tinsel/pcode.cpp b/engines/tinsel/pcode.cpp index 1d73411e13..e6ed9df5c9 100644 --- a/engines/tinsel/pcode.cpp +++ b/engines/tinsel/pcode.cpp @@ -120,6 +120,12 @@ const byte fragment2[] = {OP_LIBCALL | OPSIZE8, 110}; const int fragment2_size = 2; const byte fragment3[] = {OP_ZERO, OP_GSTORE | OPSIZE16, 490 % 256, 490 / 256}; const int fragment3_size = 4; +const byte fragment4[] = {OP_IMM | OPSIZE16, 900 % 256, 900 / 256, OP_JUMP, 466 % 256, 466 / 256}; +const int fragment4_size = 6; +const byte fragment5[] = {OP_IMM | OPSIZE16, 901 % 256, 901 / 256, OP_JUMP, 488 % 256, 488 / 256}; +const int fragment5_size = 6; +const byte fragment6[] = {OP_IMM | OPSIZE16, 903 % 256, 903 / 256, OP_JUMP, 516 % 256, 516 / 256}; +const int fragment6_size = 6; const WorkaroundEntry workaroundList[] = { // DW1-SCN: Global 206 is whether Rincewind is trying to take the book back to the present. @@ -135,6 +141,12 @@ 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 + {TINSEL_V1, false, 310506872, 463, fragment4_size, fragment4}, + {TINSEL_V1, false, 310506872, 485, fragment5_size, fragment5}, + {TINSEL_V1, false, 310506872, 513, fragment6_size, fragment6}, + // DW2: In the garden, global #490 is set when the bees begin their 'out of hive' animation, and reset when done. // But if the game is saved/restored during it, the animation sequence is reset without the global being cleared. // This causes bugs in several actions which try to disable the bees animation, since they wait indefinitely for @@ -636,6 +648,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { case OP_JUMP: // unconditional jump ip = Fetch(opcode, ic->code, wkEntry, ip); + wkEntry = NULL; // In case a jump occurs from a workaround break; case OP_JMPFALSE: // conditional jump @@ -644,6 +657,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { if (ic->stack[ic->sp--] == 0) { // condition satisfied - do the jump ip = tmp; + wkEntry = NULL; // In case a jump occurs from a workaround } break; @@ -653,6 +667,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) { if (ic->stack[ic->sp--] != 0) { // condition satisfied - do the jump ip = tmp; + wkEntry = NULL; // In case a jump occurs from a workaround } break; diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp index 4b5e0ce450..957c4f7626 100644 --- a/engines/tinsel/tinlib.cpp +++ b/engines/tinsel/tinlib.cpp @@ -2196,6 +2196,10 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo, _ctx->bSample = false; } } + + // Decrement the subtitles timeout counter + if (_ctx->ticks > 0) --_ctx->ticks; + } else { // No sample - just depends on time if (_ctx->ticks-- <= 0) @@ -2327,6 +2331,10 @@ static void PrintObjNonPointed(CORO_PARAM, const SCNHANDLE text, const OBJECT *p _ctx->bSample = false; } } + + // Decrement the subtitles timeout counter + if (_ctx->ticks > 0) --_ctx->ticks; + } else { // No sample - just depends on time if (_ctx->ticks-- <= 0) @@ -3437,6 +3445,10 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x _ctx->bSample = false; } } + + // Decrement the subtitles timeout counter + if (_ctx->ticks > 0) --_ctx->ticks; + } else { // No sample - just depends on time if (_ctx->ticks-- <= 0) diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 81453be356..417a1f714c 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -56,10 +56,10 @@ const char * const ThemeEngine::kImageSearch = "search.bmp"; struct TextDrawData { const Graphics::Font *_fontPtr; +}; - struct { - uint8 r, g, b; - } _color; +struct TextColorData { + int r, g, b; }; struct WidgetDrawData { @@ -67,6 +67,7 @@ struct WidgetDrawData { Common::List<Graphics::DrawStep> _steps; TextData _textDataId; + TextColor _textColorId; Graphics::TextAlign _textAlignH; GUI::ThemeEngine::TextAlignVertical _textAlignV; @@ -116,16 +117,17 @@ protected: class ThemeItemTextData : public ThemeItem { public: - ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const Common::Rect &area, const Common::String &text, + ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::String &text, Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, bool ellipsis, bool restoreBg, int deltaX) : - ThemeItem(engine, area), _data(data), _text(text), _alignH(alignH), _alignV(alignV), + ThemeItem(engine, area), _data(data), _color(color), _text(text), _alignH(alignH), _alignV(alignV), _ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX) {} void drawSelf(bool draw, bool restore); protected: const TextDrawData *_data; + const TextColorData *_color; Common::String _text; Graphics::TextAlign _alignH; GUI::ThemeEngine::TextAlignVertical _alignV; @@ -180,7 +182,7 @@ static const DrawDataInfo kDrawDataDefaults[] = { {kDDSliderFull, "slider_full", false, kDDNone}, {kDDSliderHover, "slider_hover", false, kDDNone}, - {kDDSliderDisabled, "slider_disabled", true, kDDNone}, + {kDDSliderDisabled, "slider_disabled", false, kDDNone}, {kDDCheckboxDefault, "checkbox_default", true, kDDNone}, {kDDCheckboxDisabled, "checkbox_disabled", true, kDDNone}, @@ -232,7 +234,7 @@ void ThemeItemTextData::drawSelf(bool draw, bool restore) { _engine->restoreBackground(_area); if (draw) { - _engine->renderer()->setFgColor(_data->_color.r, _data->_color.g, _data->_color.b); + _engine->renderer()->setFgColor(_color->r, _color->g, _color->b); _engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis); } @@ -277,6 +279,10 @@ ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) : _texts[i] = 0; } + for (int i = 0; i < kTextColorMAX; ++i) { + _textColors[i] = 0; + } + // We currently allow two different ways of theme selection in our config file: // 1) Via full path // 2) Via a basename, which will need to be translated into a full path @@ -532,20 +538,21 @@ void ThemeEngine::addDrawStep(const Common::String &drawDataId, const Graphics:: _widgets[id]->_steps.push_back(step); } -bool ThemeEngine::addTextData(const Common::String &drawDataId, TextData textId, Graphics::TextAlign alignH, TextAlignVertical alignV) { +bool ThemeEngine::addTextData(const Common::String &drawDataId, TextData textId, TextColor colorId, Graphics::TextAlign alignH, TextAlignVertical alignV) { DrawData id = parseDrawDataId(drawDataId); - if (id == -1 || textId == -1 || !_widgets[id]) + if (id == -1 || textId == -1 || colorId == kTextColorMAX || !_widgets[id]) return false; _widgets[id]->_textDataId = textId; + _widgets[id]->_textColorId = colorId; _widgets[id]->_textAlignH = alignH; _widgets[id]->_textAlignV = alignV; return true; } -bool ThemeEngine::addFont(TextData textId, const Common::String &file, int r, int g, int b) { +bool ThemeEngine::addFont(TextData textId, const Common::String &file) { if (textId == -1) return false; @@ -569,13 +576,26 @@ bool ThemeEngine::addFont(TextData textId, const Common::String &file, int r, in } } - _texts[textId]->_color.r = r; - _texts[textId]->_color.g = g; - _texts[textId]->_color.b = b; return true; } +bool ThemeEngine::addTextColor(TextColor colorId, int r, int g, int b) { + if (colorId >= kTextColorMAX) + return false; + + if (_textColors[colorId] != 0) + delete _textColors[colorId]; + + _textColors[colorId] = new TextColorData; + + _textColors[colorId]->r = r; + _textColors[colorId]->g = g; + _textColors[colorId]->b = b; + + return true; +} + bool ThemeEngine::addBitmap(const Common::String &filename) { // Nothing has to be done if the bitmap already has been loaded. Graphics::Surface *surf = _bitmaps[filename]; @@ -656,6 +676,11 @@ void ThemeEngine::unloadTheme() { _texts[i] = 0; } + for (int i = 0; i < kTextColorMAX; ++i) { + delete _textColors[i]; + _textColors[i] = 0; + } + _themeEval->reset(); _themeOk = false; } @@ -771,7 +796,7 @@ void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic, } } -void ThemeEngine::queueDDText(TextData type, const Common::Rect &r, const Common::String &text, bool restoreBg, +void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg, bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) { if (_texts[type] == 0) @@ -780,7 +805,7 @@ void ThemeEngine::queueDDText(TextData type, const Common::Rect &r, const Common Common::Rect area = r; area.clip(_screen.w, _screen.h); - ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], area, text, alignH, alignV, ellipsis, restoreBg, deltax); + ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, text, alignH, alignV, ellipsis, restoreBg, deltax); if (_buffering) { _screenQueue.push_back(q); @@ -824,7 +849,7 @@ void ThemeEngine::drawButton(const Common::Rect &r, const Common::String &str, W dd = kDDButtonDisabled; queueDD(dd, r, 0, hints & WIDGET_CLEARBG); - queueDDText(getTextData(dd), r, str, false, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV); + queueDDText(getTextData(dd), getTextColor(dd), r, str, false, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV); } void ThemeEngine::drawLineSeparator(const Common::Rect &r, WidgetStateInfo state) { @@ -847,7 +872,6 @@ void ThemeEngine::drawCheckbox(const Common::Rect &r, const Common::String &str, if (state == kStateDisabled) dd = kDDCheckboxDisabled; - TextData td = (state == kStateHighlight) ? kTextDataHover : getTextData(dd); const int checkBoxSize = MIN((int)r.height(), getFontHeight()); r2.bottom = r2.top + checkBoxSize; @@ -858,7 +882,7 @@ void ThemeEngine::drawCheckbox(const Common::Rect &r, const Common::String &str, r2.left = r2.right + checkBoxSize; r2.right = r.right; - queueDDText(td, r2, str, false, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV); + queueDDText(getTextData(dd), getTextColor(dd), r2, str, false, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV); } void ThemeEngine::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) { @@ -958,7 +982,7 @@ void ThemeEngine::drawPopUpWidget(const Common::Rect &r, const Common::String &s if (!sel.empty()) { Common::Rect text(r.left + 3, r.top + 1, r.right - 10, r.bottom); - queueDDText(getTextData(dd), text, sel, true, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax); + queueDDText(getTextData(dd), getTextColor(dd), text, sel, true, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax); } } @@ -1004,7 +1028,7 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co Common::Rect tabRect(r.left + i * tabWidth, r.top, r.left + (i + 1) * tabWidth, r.top + tabHeight); queueDD(kDDTabInactive, tabRect); - queueDDText(getTextData(kDDTabInactive), tabRect, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV); + queueDDText(getTextData(kDDTabInactive), getTextColor(kDDTabInactive), tabRect, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV); } if (active >= 0) { @@ -1012,64 +1036,98 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co const uint16 tabLeft = active * tabWidth; const uint16 tabRight = MAX(r.right - tabRect.right, 0); queueDD(kDDTabActive, tabRect, (tabLeft << 16) | (tabRight & 0xFFFF)); - queueDDText(getTextData(kDDTabActive), tabRect, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV); + queueDDText(getTextData(kDDTabActive), getTextColor(kDDTabActive), tabRect, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV); } } -void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font) { +void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color) { if (!ready()) return; + TextColor colorId = kTextColorMAX; + + switch (color) { + case kFontColorNormal: + if (inverted) { + colorId = kTextColorNormalInverted; + } else { + switch (state) { + case kStateDisabled: + colorId = kTextColorNormalDisabled; + break; + + case kStateHighlight: + colorId = kTextColorNormalHover; + break; + + case kStateEnabled: + colorId = kTextColorNormal; + break; + } + } + break; + + case kFontColorAlternate: + if (inverted) { + colorId = kTextColorAlternativeInverted; + } else { + switch (state) { + case kStateDisabled: + colorId = kTextColorAlternativeDisabled; + break; + + case kStateHighlight: + colorId = kTextColorAlternativeHover; + break; + + case kStateEnabled: + colorId = kTextColorAlternative; + break; + } + } + break; + + default: + return; + } + + TextData textId = kTextDataNone; + if (font == kFontStyleNormal) + textId = kTextDataNormalFont; + else + textId = kTextDataDefault; + + bool restore = true; + switch (inverted) { case kTextInversion: queueDD(kDDTextSelectionBackground, r); - queueDDText(kTextDataInverted, r, str, false, useEllipsis, align, kTextAlignVCenter, deltax); - return; + restore = false; + break; case kTextInversionFocus: queueDD(kDDTextSelectionFocusBackground, r); - queueDDText(kTextDataInverted, r, str, false, useEllipsis, align, kTextAlignVCenter, deltax); - return; - - default: + restore = false; break; - } - - switch (font) { - case kFontStyleNormal: - queueDDText(kTextDataNormalFont, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); - return; default: break; } - switch (state) { - case kStateDisabled: - queueDDText(kTextDataDisabled, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); - return; - - case kStateHighlight: - queueDDText(kTextDataHover, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); - return; - - case kStateEnabled: - queueDDText(kTextDataDefault, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax); - return; - } + queueDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax); } -void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state) { +void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state, FontColor color) { if (!ready()) return; Common::Rect charArea = r; charArea.clip(_screen.w, _screen.h); - uint32 color = _overlayFormat.RGBToColor(_texts[kTextDataDefault]->_color.r, _texts[kTextDataDefault]->_color.g, _texts[kTextDataDefault]->_color.b); + uint32 rgbColor = _overlayFormat.RGBToColor(_textColors[color]->r, _textColors[color]->g, _textColors[color]->b); restoreBackground(charArea); - font->drawChar(&_screen, ch, charArea.left, charArea.top, color); + font->drawChar(&_screen, ch, charArea.left, charArea.top, rgbColor); addDirtyRect(charArea); } @@ -1266,6 +1324,9 @@ TextData ThemeEngine::getTextData(DrawData ddId) const { return _widgets[ddId] ? (TextData)_widgets[ddId]->_textDataId : kTextDataNone; } +TextColor ThemeEngine::getTextColor(DrawData ddId) const { + return _widgets[ddId] ? _widgets[ddId]->_textColorId : kTextColorMAX; +} DrawData ThemeEngine::parseDrawDataId(const Common::String &name) const { for (int i = 0; i < kDrawDataMAX; ++i) diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index d7527b61dd..4cd5d827e3 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.6" +#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.7" namespace Graphics { struct DrawStep; @@ -45,6 +45,7 @@ struct WidgetDrawData; struct DrawDataInfo; struct TextDataInfo; struct TextDrawData; +struct TextColorData; class Dialog; class GuiObject; class ThemeEval; @@ -105,15 +106,26 @@ enum DrawData { enum TextData { kTextDataNone = -1, kTextDataDefault = 0, - kTextDataHover, - kTextDataDisabled, - kTextDataInverted, kTextDataButton, - kTextDataButtonHover, kTextDataNormalFont, kTextDataMAX }; +enum TextColor { + kTextColorNormal = 0, + kTextColorNormalInverted, + kTextColorNormalHover, + kTextColorNormalDisabled, + kTextColorAlternative, + kTextColorAlternativeInverted, + kTextColorAlternativeHover, + kTextColorAlternativeDisabled, + kTextColorButton, + kTextColorButtonHover, + kTextColorButtonDisabled, + kTextColorMAX +}; + class ThemeEngine { protected: typedef Common::HashMap<Common::String, Graphics::Surface*> ImagesMap; @@ -183,6 +195,13 @@ public: kFontStyleMax }; + //! Font color selector + enum FontColor { + kFontColorNormal = 0, //!< The default color of the theme + kFontColorAlternate = 1, //!< Alternative font color + kFontColorMax + }; + //! Function used to process areas other than the current dialog enum ShadingStyle { kShadingNone, //!< No special post processing @@ -310,9 +329,9 @@ public: void drawDialogBackground(const Common::Rect &r, DialogBackground type, WidgetStateInfo state = kStateEnabled); - void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold); + void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal); - void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled); + void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled, FontColor color = kFontColorNormal); //@} @@ -340,6 +359,7 @@ public: DrawData parseDrawDataId(const Common::String &name) const; TextData getTextData(DrawData ddId) const; + TextColor getTextColor(DrawData ddId) const; /** @@ -354,7 +374,7 @@ public: void addDrawStep(const Common::String &drawDataId, const Graphics::DrawStep &step); /** - * Interfacefor the ThemeParser class: Parsed DrawData sets are added via this function. + * Interface for the ThemeParser class: Parsed DrawData sets are added via this function. * The goal of the function is to initialize each DrawData set before their DrawSteps can * be added, hence this must be called for each DD set before addDrawStep() can be called * for that given set. @@ -371,9 +391,16 @@ public: * * @param fontName Identifier name for the font. * @param file Name of the font file. - * @param r, g, b Color of the font. */ - bool addFont(TextData textId, const Common::String &file, int r, int g, int b); + bool addFont(TextData textId, const Common::String &file); + + /** + * Interface for the ThemeParser class: adds a text color value. + * + * @param colorId Identifier for the color type. + * @param r, g, b Color of the font. + */ + bool addTextColor(TextColor colorId, int r, int g, int b); /** @@ -388,7 +415,7 @@ public: * Adds a new TextStep from the ThemeParser. This will be deprecated/removed once the * new Font API is in place. FIXME: Is that so ??? */ - bool addTextData(const Common::String &drawDataId, TextData textId, Graphics::TextAlign alignH, TextAlignVertical alignV); + bool addTextData(const Common::String &drawDataId, TextData textId, TextColor id, Graphics::TextAlign alignH, TextAlignVertical alignV); protected: /** @@ -511,7 +538,7 @@ protected: * This function is called from all the Widget Drawing methods. */ void queueDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool restore = false); - void queueDDText(TextData type, const Common::Rect &r, const Common::String &text, bool restoreBg, + void queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg, bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0); void queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha); @@ -580,6 +607,9 @@ protected: /** Array of all the text fonts that can be drawn. */ TextDrawData *_texts[kTextDataMAX]; + /** Array of all font colors available. */ + TextColorData *_textColors[kTextColorMAX]; + ImagesMap _bitmaps; Graphics::PixelFormat _overlayFormat; #ifdef ENABLE_RGB_COLOR diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 8897eef9d7..e30e759e66 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -38,13 +38,9 @@ struct TextDataInfo { }; static const TextDataInfo kTextDataDefaults[] = { - {kTextDataDefault, "text_default"}, - {kTextDataHover, "text_hover"}, - {kTextDataDisabled, "text_disabled"}, - {kTextDataInverted, "text_inverted"}, - {kTextDataButton, "text_button"}, - {kTextDataButtonHover, "text_button_hover"}, - {kTextDataNormalFont, "text_normal"} + { kTextDataDefault, "text_default" }, + { kTextDataButton, "text_button" }, + { kTextDataNormalFont, "text_normal" } }; @@ -56,6 +52,33 @@ static TextData parseTextDataId(const Common::String &name) { return kTextDataNone; } +struct TextColorDataInfo { + TextColor id; + const char *name; +}; + +static const TextColorDataInfo kTextColorDefaults[] = { + { kTextColorNormal, "color_normal" }, + { kTextColorNormalInverted, "color_normal_inverted" }, + { kTextColorNormalHover, "color_normal_hover" }, + { kTextColorNormalDisabled, "color_normal_disabled" }, + { kTextColorAlternative, "color_alternative" }, + { kTextColorAlternativeInverted, "color_alternative_inverted" }, + { kTextColorAlternativeHover, "color_alternative_hover" }, + { kTextColorAlternativeDisabled, "color_alternative_disabled" }, + { kTextColorButton, "color_button" }, + { kTextColorButtonHover, "color_button_hover" }, + { kTextColorButtonDisabled, "color_button_disabled" } +}; + +static TextColor parseTextColorId(const Common::String &name) { + for (int i = 0; i < kTextColorMAX; ++i) + if (name.compareToIgnoreCase(kTextColorDefaults[i].name) == 0) + return kTextColorDefaults[i].id; + + return kTextColorMAX; +} + static Graphics::TextAlign parseTextHAlign(const Common::String &val) { if (val == "left") return Graphics::kTextAlignLeft; @@ -148,21 +171,32 @@ bool ThemeParser::parserCallback_defaults(ParserNode *node) { } bool ThemeParser::parserCallback_font(ParserNode *node) { - int red, green, blue; - if (resolutionCheck(node->values["resolution"]) == false) { node->ignore = true; return true; } + TextData textDataId = parseTextDataId(node->values["id"]); + if (!_theme->addFont(textDataId, node->values["file"])) + return parserError("Error loading Font in theme engine."); + + return true; +} + +bool ThemeParser::parserCallback_text_color(ParserNode *node) { + int red, green, blue; + + TextColor colorId = parseTextColorId(node->values["id"]); + if (colorId == kTextColorMAX) + return parserError("Error text color is not defined."); + if (_palette.contains(node->values["color"])) getPaletteColor(node->values["color"], red, green, blue); else if (!parseIntegerKey(node->values["color"].c_str(), 3, &red, &green, &blue)) - return parserError("Error parsing color value for font definition."); + return parserError("Error parsing color value for text color definition."); - TextData textDataId = parseTextDataId(node->values["id"]); - if (!_theme->addFont(textDataId, node->values["file"], red, green, blue)) - return parserError("Error loading Font in theme engine."); + if (!_theme->addTextColor(colorId, red, green, blue)) + return parserError("Error while adding text color information."); return true; } @@ -215,8 +249,9 @@ bool ThemeParser::parserCallback_text(ParserNode *node) { Common::String id = getParentNode(node)->values["id"]; TextData textDataId = parseTextDataId(node->values["font"]); + TextColor textColorId = parseTextColorId(node->values["text_color"]); - if (!_theme->addTextData(id, textDataId, alignH, alignV)) + if (!_theme->addTextData(id, textDataId, textColorId, alignH, alignV)) return parserError("Error adding Text Data for '%s'.", id.c_str()); return true; diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index e261b6b842..92734fa421 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -67,9 +67,13 @@ protected: XML_KEY(font) XML_PROP(id, true) XML_PROP(file, true) - XML_PROP(color, true) XML_PROP(resolution, false) KEY_END() + + XML_KEY(text_color) + XML_PROP(id, true); + XML_PROP(color, true); + KEY_END() KEY_END() XML_KEY(bitmaps) @@ -143,6 +147,7 @@ protected: XML_KEY(text) XML_PROP(font, true) + XML_PROP(text_color, true) XML_PROP(vertical_align, true) XML_PROP(horizontal_align, true) KEY_END() @@ -211,6 +216,7 @@ protected: bool parserCallback_render_info(ParserNode *node); bool parserCallback_defaults(ParserNode *node); bool parserCallback_font(ParserNode *node); + bool parserCallback_text_color(ParserNode *node); bool parserCallback_fonts(ParserNode *node); bool parserCallback_text(ParserNode *node); bool parserCallback_palette(ParserNode *node); diff --git a/gui/options.cpp b/gui/options.cpp index 0d2d6e0120..e941cd6244 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -48,6 +48,7 @@ enum { kMidiGainChanged = 'mgch', kMusicVolumeChanged = 'muvc', kSfxVolumeChanged = 'sfvc', + kMuteAllChanged = 'mute', kSubtitleToggle = 'sttg', kSubtitleSpeedChanged = 'stsc', kSpeechVolumeChanged = 'vcvc', @@ -454,6 +455,10 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data _speechVolumeLabel->setValue(_speechVolumeSlider->getValue()); _speechVolumeLabel->draw(); break; + case kMuteAllChanged: + // 'true' because if control is disabled then event do not pass + setVolumeSettingsState(true); + break; case kSubtitleToggle: if (_subMode < 2) _subMode++; @@ -535,7 +540,7 @@ void OptionsDialog::setVolumeSettingsState(bool enabled) { _enableVolumeSettings = enabled; - ena = enabled; + ena = enabled && !_muteCheckbox->getState(); if (_guioptions & Common::GUIO_NOMUSIC) ena = false; @@ -543,7 +548,7 @@ void OptionsDialog::setVolumeSettingsState(bool enabled) { _musicVolumeSlider->setEnabled(ena); _musicVolumeLabel->setEnabled(ena); - ena = enabled; + ena = enabled && !_muteCheckbox->getState(); if (_guioptions & Common::GUIO_NOSFX) ena = false; @@ -551,7 +556,7 @@ void OptionsDialog::setVolumeSettingsState(bool enabled) { _sfxVolumeSlider->setEnabled(ena); _sfxVolumeLabel->setEnabled(ena); - ena = enabled; + ena = enabled && !_muteCheckbox->getState(); if (_guioptions & Common::GUIO_NOSPEECH) ena = false; @@ -701,7 +706,7 @@ void OptionsDialog::addVolumeControls(GuiObject *boss, const String &prefix) { _musicVolumeSlider->setMaxValue(Audio::Mixer::kMaxMixerVolume); _musicVolumeLabel->setFlags(WIDGET_CLEARBG); - _muteCheckbox = new CheckboxWidget(boss, prefix + "vcMuteCheckbox", "Mute All", 0, 0); + _muteCheckbox = new CheckboxWidget(boss, prefix + "vcMuteCheckbox", "Mute All", kMuteAllChanged, 0); _sfxVolumeDesc = new StaticTextWidget(boss, prefix + "vcSfxText", "SFX volume:"); diff --git a/gui/saveload.cpp b/gui/saveload.cpp index 09b4401cca..f859c706fb 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -345,7 +345,14 @@ void SaveLoadChooser::updateSaveList() { } } - saveNames.push_back(x->description()); + // Show "Untitled savestate" for empty/whitespace savegame descriptions + Common::String description = x->description(); + Common::String trimmedDescription = description; + trimmedDescription.trim(); + if (trimmedDescription.empty()) + description = "Untitled savestate"; + + saveNames.push_back(description); curSlot++; } diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 64fb0e517a..88ef801af5 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1,41 +1,38 @@ "<?xml version = '1.0'?>" -"<layout_info resolution='-320xY,-256x240,-Xx272'> " +"<layout_info resolution='320xY,256x240,Xx272'> " "<globals> " -"<def var='Line.Height' value='16' /> " -"<def var='Font.Height' value='16' /> " -"<def var='About.OuterBorder' value='80'/> " -"<def var='Layout.Spacing' value='8' /> " +"<def var='Line.Height' value='12' /> " +"<def var='Font.Height' value='10' /> " +"<def var='About.OuterBorder' value='10'/> " +"<def var='Layout.Spacing' value='8'/> " "<def var='ShowLauncherLogo' value='0'/> " "<def var='ShowGlobalMenuLogo' value='0'/> " "<def var='ShowSearchPic' value='0'/> " -"<def var='ScummSaveLoad.ExtInfo.Visible' value='1'/> " -"<def var='KeyMapper.Spacing' value='10'/> " -"<def var='KeyMapper.LabelWidth' value='100'/> " -"<def var='KeyMapper.ButtonWidth' value='80'/> " +"<def var='ScummSaveLoad.ExtInfo.Visible' value='0'/> " +"<def var='KeyMapper.Spacing' value='5'/> " +"<def var='KeyMapper.LabelWidth' value='80'/> " +"<def var='KeyMapper.ButtonWidth' value='60'/> " +"<widget name='Button' " +"size='72,16' " +"/> " +"<widget name='Slider' " +"size='85,12' " +"/> " "<widget name='OptionsLabel' " "size='110,Globals.Line.Height' " "textalign='right' " "/> " "<widget name='SmallLabel' " -"size='24,Globals.Line.Height' " -"/> " -"<widget name='ShortOptionsLabel' " -"size='60,Globals.Line.Height' " -"/> " -"<widget name='Button' " -"size='108,24' " -"/> " -"<widget name='Slider' " -"size='128,18' " +"size='18,Globals.Line.Height' " "/> " "<widget name='PopUp' " -"size='-1,19' " +"size='-1,15' " "/> " "<widget name='Checkbox' " -"size='-1,14' " +"size='-1,Globals.Line.Height' " "/> " "<widget name='ListWidget' " -"padding='5,0,8,0' " +"padding='5,0,0,0' " "/> " "<widget name='PopUpWidget' " "padding='7,5,0,0' " @@ -47,25 +44,25 @@ "padding='7,5,5,5' " "/> " "<widget name='Scrollbar' " -"size='15,0' " +"size='9,0' " "/> " "<widget name='TabWidget.Tab' " -"size='75,27' " -"padding='0,0,8,0' " +"size='45,16' " +"padding='0,0,2,0' " "/> " "<widget name='TabWidget.NavButton' " -"size='15,18' " +"size='32,18' " "padding='0,3,4,0' " "/> " "</globals> " "<dialog name='Launcher' overlays='screen'> " -"<layout type='vertical' center='true' padding='16,16,8,8'> " +"<layout type='vertical' center='true' padding='8,8,4,4'> " "<widget name='Version' " "height='Globals.Line.Height' " "/> " "<layout type='horizontal' spacing='5' padding='10,0,0,0'> " "<widget name='SearchDesc' " -"width='60' " +"width='50' " "height='Globals.Line.Height' " "textalign='right' " "/> " @@ -82,37 +79,36 @@ "<widget name='GameList'/> " "<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='LoadGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='AddGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='EditGameButton' " -"height='20' " +"height='12' " "/> " "<widget name='RemoveGameButton' " -"height='20' " +"height='12' " "/> " "</layout> " -"<space size='4'/> " "<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='QuitButton' " -"height='20' " +"height='12' " "/> " "<widget name='AboutButton' " -"height='20' " +"height='12' " "/> " "<widget name='OptionsButton' " -"height='20' " +"height='12' " "/> " "<widget name='StartButton' " -"height='20' " +"height='12' " "/> " "</layout> " "</layout> " "</dialog> " -"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " +"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> " +"<layout type='vertical' padding='8,8,0,4'> " "<widget name='Headline' " "height='Globals.Line.Height' " "/> " @@ -120,7 +116,7 @@ "height='Globals.Line.Height' " "/> " "<widget name='List'/> " -"<layout type='horizontal' padding='0,0,16,0'> " +"<layout type='horizontal' padding='0,0,8,0'> " "<widget name='Up' " "type='Button' " "/> " @@ -134,10 +130,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> " "<layout type='vertical' padding='0,0,0,0'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='16,16,16,16'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -150,7 +146,7 @@ "</dialog> " "<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='grModePopupDesc' " "type='OptionsLabel' " "/> " @@ -158,7 +154,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='grRenderPopupDesc' " "type='OptionsLabel' " "/> " @@ -176,7 +172,7 @@ "</dialog> " "<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auMidiPopupDesc' " "type='OptionsLabel' " "/> " @@ -184,7 +180,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -192,7 +188,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='auSampleRatePopupDesc' " "type='OptionsLabel' " "/> " @@ -200,16 +196,16 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " "<widget name='subToggleButton' " -"width='150' " +"width='128' " "height='Globals.Slider.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -223,9 +219,8 @@ "</layout> " "</dialog> " "<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='horizontal' padding='16,16,16,16' spacing='8'> " -"<layout type='vertical' padding='0,0,0,0' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -236,7 +231,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -247,7 +242,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -258,8 +253,8 @@ "type='SmallLabel' " "/> " "</layout> " -"</layout> " -"<layout type='vertical' padding='24,0,24,0' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<space size='110' /> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " "/> " @@ -268,7 +263,7 @@ "</dialog> " "<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='mcFontButton' " "type='Button' " "/> " @@ -289,7 +284,7 @@ "<widget name='mcGSCheckbox' " "type='Checkbox' " "/> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='mcMidiGainText' " "type='OptionsLabel' " "/> " @@ -305,7 +300,7 @@ "</dialog> " "<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='SaveButton' " "type='Button' " "/> " @@ -313,7 +308,7 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -321,7 +316,7 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ExtraButton' " "type='Button' " "/> " @@ -341,7 +336,7 @@ "</dialog> " "<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -349,17 +344,21 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='RendererPopupDesc' " -"type='OptionsLabel' " +"width='80' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='RendererPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='AutosavePeriodPopupDesc' " -"type='OptionsLabel' " +"width='80' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='AutosavePeriodPopup' " "type='PopUp' " @@ -394,10 +393,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> " "<layout type='vertical' padding='0,0,0,0' spacing='16'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='16,16,16,4'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -409,7 +408,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -417,7 +416,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -425,7 +424,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -433,7 +432,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='8,8,8,8' spacing='6'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -441,34 +440,43 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='16,16,16,16'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='Id' " -"type='OptionsLabel' " +"width='35' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='Domain' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='Name' " -"type='OptionsLabel' " +"width='35' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='Desc' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<space size='8'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='LangPopupDesc' " -"type='OptionsLabel' " +"width='60' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='LangPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='PlatformPopupDesc' " -"type='OptionsLabel' " +"width='60' " +"height='Globals.Line.Height' " +"textalign='right' " "/> " "<widget name='PlatformPopup' " "type='PopUp' " @@ -477,8 +485,8 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='16,16,16,16'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Savepath' " "type='Button' " "/> " @@ -486,7 +494,7 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Extrapath' " "type='Button' " "/> " @@ -494,7 +502,7 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " "<widget name='Gamepath' " "type='Button' " "/> " @@ -505,81 +513,86 @@ "</layout> " "</dialog> " "<dialog name='GlobalMenu' overlays='screen_center'> " -"<layout type='vertical' padding='16,16,16,16' center='true'> " +"<layout type='vertical' padding='8,8,4,6' center='true'> " "<widget name='Title' " -"width='210' " -"height='Globals.Line.Height' " +"width='160' " +"height='4' " "/> " "<widget name='Version' " -"width='210' " -"height='Globals.Line.Height' " -"/> " -"<widget name='Resume' " -"width='150' " -"height='Globals.Button.Height' " +"width='160' " +"height='4' " "/> " -"<space size='10'/> " +"<space size='1'/> " "<widget name='Load' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='Save' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " -"<space size='10'/> " +"<space size='1'/> " "<widget name='Options' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='About' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " +"/> " +"<space size='1'/> " +"<widget name='Resume' " +"width='120' " +"height='12' " "/> " -"<space size='10'/> " "<widget name='RTL' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "<widget name='Quit' " -"width='150' " -"height='Globals.Button.Height' " +"width='120' " +"height='12' " "/> " "</layout> " "</dialog> " "<dialog name='ScummMain' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " "<widget name='Resume' " -"type='Button' " +"width='Globals.Button.Width' " +"height='14' " "/> " -"<space size='15'/> " +"<space size='2'/> " "<widget name='Load' " -"type='Button' " +"width='Globals.Button.Width' " +"height='14' " "/> " "<widget name='Save' " -"type='Button' " +"width='Globals.Button.Width' " +"height='14' " "/> " -"<space size='15'/> " +"<space size='2'/> " "<widget name='Options' " -"type='Button' " +"width='Globals.Button.Width' " +"height='14' " "/> " "<widget name='Help' " -"type='Button' " +"width='Globals.Button.Width' " +"height='14' " "/> " "<widget name='About' " -"type='Button' " +"width='Globals.Button.Width' " +"height='14' " "/> " -"<space size='15'/> " +"<space size='2'/> " "<widget name='Quit' " -"type='Button' " +"width='Globals.Button.Width' " +"height='14' " "/> " "</layout> " "</dialog> " "<dialog name='ScummConfig' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0'> " -"<layout type='vertical' padding='0,0,0,0' center='true'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -590,7 +603,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -601,7 +614,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -612,25 +625,24 @@ "type='SmallLabel' " "/> " "</layout> " -"</layout> " -"<layout type='vertical' padding='24,24,24,24' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<space size='110' /> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " -"width='80' " +"width='80' " "/> " "</layout> " -"</layout> " -"<space size='8' /> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<space size='4' /> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " "<widget name='subToggleButton' " -"width='158' " +"width='128' " "height='Globals.Slider.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -641,8 +653,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<space size='60'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " +"<space size='20'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='4'> " "<widget name='Keys' " "type='Button' " "/> " @@ -657,23 +669,15 @@ "</layout> " "</dialog> " "<dialog name='ScummSaveLoad' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,8,32' center='true'> " -"<widget name='Title' " -"height='Globals.Line.Height' " -"/> " -"<layout type='horizontal' padding='0,0,0,16' spacing='16'> " +"<layout type='vertical' padding='8,8,8,8' center='true'> " +"<widget name='Title' height='Globals.Line.Height'/> " "<widget name='List' /> " -"<widget name='Thumbnail' " -"width='180' " -"height='200' " -"/> " -"</layout> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,16,0'> " "<space/> " "<widget name='Delete' " "type='Button' " "/> " -"<space size='32'/> " +"<space size='16'/> " "<widget name='Cancel' " "type='Button' " "/> " @@ -683,16 +687,16 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='ScummHelp' overlays='screen_center'> " -"<layout type='vertical' padding='8,8,8,8' center='true'> " +"<dialog name='ScummHelp' overlays='screen'> " +"<layout type='vertical' padding='8,8,8,8'> " "<widget name='Title' " -"width='320' " +"width='180' " "height='Globals.Line.Height' " "/> " "<widget name='HelpText' " -"height='200' " +"height='140' " "/> " -"<layout type='horizontal' padding='0,0,16,0'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='Prev' " "type='Button' " "/> " @@ -707,20 +711,20 @@ "</layout> " "</dialog> " "<dialog name='MassAdd' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,32,8' center='true'> " +"<layout type='vertical' padding='4,4,16,4' center='true'> " "<widget name='DirProgressText' " -"width='250' " +"width='240' " "height='Globals.Line.Height' " "/> " "<widget name='GameProgressText' " -"width='250' " +"width='240' " "height='Globals.Line.Height' " "/> " "<widget name='GameList' " -"width='480' " -"height='250' " +"width='280' " +"height='100' " "/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='4,4,4,4'> " "<widget name='Ok' " "type='Button' " "/> " @@ -731,20 +735,20 @@ "</layout> " "</dialog> " "<dialog name='KeyMapper' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PopupDesc' " "type='OptionsLabel' " "/> " "<widget name='Popup' " "type='PopUp' " -"width='400' " +"width='150' " "height='Globals.Line.Height' " "/> " "</layout> " "<widget name='KeymapArea' " -"width='600' " -"height='280' " +"width='300' " +"height='120' " "/> " "<widget name='Close' " "type='Button' " @@ -752,371 +756,43 @@ "</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' " -"color='green' " -"/> " -"<font id='text_hover' " -"file='default' " -"color='green2' " -"/> " -"<font id='text_disabled' " -"file='default' " -"color='lightgrey' " -"/> " -"<font id='text_inverted' " -"file='default' " -"color='black' " -"/> " -"<font id='text_button' " -"file='default' " -"color='green' " -"/> " -"<font id='text_button_hover' " -"file='default' " -"color='green2' " -"/> " -"<font id='text_normal' " -"file='default' " -"color='green' " -"/> " -"</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_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' " -"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' " -"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_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_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' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='button_hover' cache='false'> " -"<text font='text_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_disabled' " -"vertical_align='center' " -"horizontal_align='center' " -"/> " -"<drawstep func='bevelsq' " -"bevel='2' " -"fill='none' " -"/> " -"</drawdata> " -"<drawdata id='checkbox_disabled' cache='false'> " -"<text font='text_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' " -"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' " -"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'> " +"<layout_info resolution='-320xY,-256x240,-Xx272'> " "<globals> " -"<def var='Line.Height' value='12' /> " -"<def var='Font.Height' value='10' /> " -"<def var='About.OuterBorder' value='10'/> " -"<def var='Layout.Spacing' value='8'/> " +"<def var='Line.Height' value='16' /> " +"<def var='Font.Height' value='16' /> " +"<def var='About.OuterBorder' value='80'/> " +"<def var='Layout.Spacing' value='8' /> " "<def var='ShowLauncherLogo' value='0'/> " "<def var='ShowGlobalMenuLogo' value='0'/> " "<def var='ShowSearchPic' value='0'/> " -"<def var='ScummSaveLoad.ExtInfo.Visible' value='0'/> " -"<def var='KeyMapper.Spacing' value='5'/> " -"<def var='KeyMapper.LabelWidth' value='80'/> " -"<def var='KeyMapper.ButtonWidth' value='60'/> " -"<widget name='Button' " -"size='72,16' " -"/> " -"<widget name='Slider' " -"size='85,12' " -"/> " +"<def var='ScummSaveLoad.ExtInfo.Visible' value='1'/> " +"<def var='KeyMapper.Spacing' value='10'/> " +"<def var='KeyMapper.LabelWidth' value='100'/> " +"<def var='KeyMapper.ButtonWidth' value='80'/> " "<widget name='OptionsLabel' " "size='110,Globals.Line.Height' " "textalign='right' " "/> " "<widget name='SmallLabel' " -"size='18,Globals.Line.Height' " +"size='24,Globals.Line.Height' " +"/> " +"<widget name='ShortOptionsLabel' " +"size='60,Globals.Line.Height' " +"/> " +"<widget name='Button' " +"size='108,24' " +"/> " +"<widget name='Slider' " +"size='128,18' " "/> " "<widget name='PopUp' " -"size='-1,15' " +"size='-1,19' " "/> " "<widget name='Checkbox' " -"size='-1,Globals.Line.Height' " +"size='-1,14' " "/> " "<widget name='ListWidget' " -"padding='5,0,0,0' " +"padding='5,0,8,0' " "/> " "<widget name='PopUpWidget' " "padding='7,5,0,0' " @@ -1128,25 +804,25 @@ "padding='7,5,5,5' " "/> " "<widget name='Scrollbar' " -"size='9,0' " +"size='15,0' " "/> " "<widget name='TabWidget.Tab' " -"size='45,16' " -"padding='0,0,2,0' " +"size='75,27' " +"padding='0,0,8,0' " "/> " "<widget name='TabWidget.NavButton' " -"size='32,18' " +"size='15,18' " "padding='0,3,4,0' " "/> " "</globals> " "<dialog name='Launcher' overlays='screen'> " -"<layout type='vertical' center='true' padding='8,8,4,4'> " +"<layout type='vertical' center='true' padding='16,16,8,8'> " "<widget name='Version' " "height='Globals.Line.Height' " "/> " "<layout type='horizontal' spacing='5' padding='10,0,0,0'> " "<widget name='SearchDesc' " -"width='50' " +"width='60' " "height='Globals.Line.Height' " "textalign='right' " "/> " @@ -1163,36 +839,37 @@ "<widget name='GameList'/> " "<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='LoadGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='AddGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='EditGameButton' " -"height='12' " +"height='20' " "/> " "<widget name='RemoveGameButton' " -"height='12' " +"height='20' " "/> " "</layout> " +"<space size='4'/> " "<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='QuitButton' " -"height='12' " +"height='20' " "/> " "<widget name='AboutButton' " -"height='12' " +"height='20' " "/> " "<widget name='OptionsButton' " -"height='12' " +"height='20' " "/> " "<widget name='StartButton' " -"height='12' " +"height='20' " "/> " "</layout> " "</layout> " "</dialog> " -"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,0,4'> " +"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> " +"<layout type='vertical' padding='8,8,8,8'> " "<widget name='Headline' " "height='Globals.Line.Height' " "/> " @@ -1200,7 +877,7 @@ "height='Globals.Line.Height' " "/> " "<widget name='List'/> " -"<layout type='horizontal' padding='0,0,8,0'> " +"<layout type='horizontal' padding='0,0,16,0'> " "<widget name='Up' " "type='Button' " "/> " @@ -1214,10 +891,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> " +"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " "<layout type='vertical' padding='0,0,0,0'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='16,16,16,16'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -1230,7 +907,7 @@ "</dialog> " "<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='grModePopupDesc' " "type='OptionsLabel' " "/> " @@ -1238,7 +915,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='grRenderPopupDesc' " "type='OptionsLabel' " "/> " @@ -1256,7 +933,7 @@ "</dialog> " "<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auMidiPopupDesc' " "type='OptionsLabel' " "/> " @@ -1264,7 +941,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auOPLPopupDesc' " "type='OptionsLabel' " "/> " @@ -1272,7 +949,7 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='auSampleRatePopupDesc' " "type='OptionsLabel' " "/> " @@ -1280,16 +957,16 @@ "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " "<widget name='subToggleButton' " -"width='128' " +"width='150' " "height='Globals.Slider.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -1303,8 +980,9 @@ "</layout> " "</dialog> " "<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='16,16,16,16' spacing='8'> " +"<layout type='vertical' padding='0,0,0,0' spacing='8'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -1315,7 +993,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -1326,7 +1004,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -1337,8 +1015,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " -"<space size='110' /> " +"</layout> " +"<layout type='vertical' padding='24,0,24,0' center='true'> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " "/> " @@ -1347,7 +1025,7 @@ "</dialog> " "<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='mcFontButton' " "type='Button' " "/> " @@ -1368,7 +1046,7 @@ "<widget name='mcGSCheckbox' " "type='Checkbox' " "/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " "<widget name='mcMidiGainText' " "type='OptionsLabel' " "/> " @@ -1384,7 +1062,7 @@ "</dialog> " "<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='SaveButton' " "type='Button' " "/> " @@ -1392,7 +1070,7 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -1400,7 +1078,7 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ExtraButton' " "type='Button' " "/> " @@ -1420,7 +1098,7 @@ "</dialog> " "<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> " "<layout type='vertical' padding='16,16,16,16' spacing='8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='ThemeButton' " "type='Button' " "/> " @@ -1428,21 +1106,17 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='RendererPopupDesc' " -"width='80' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='RendererPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='AutosavePeriodPopupDesc' " -"width='80' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='AutosavePeriodPopup' " "type='PopUp' " @@ -1477,10 +1151,10 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> " +"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> " "<layout type='vertical' padding='0,0,0,0' spacing='16'> " "<widget name='TabWidget'/> " -"<layout type='horizontal' padding='8,8,8,8'> " +"<layout type='horizontal' padding='16,16,16,4'> " "<space/> " "<widget name='Cancel' " "type='Button' " @@ -1492,7 +1166,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1500,7 +1174,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1508,7 +1182,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1516,7 +1190,7 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> " -"<layout type='vertical' padding='8,8,8,8' spacing='6'> " +"<layout type='vertical' padding='16,16,16,16' spacing='8'> " "<widget name='EnableTabCheckbox' " "type='Checkbox' " "/> " @@ -1524,43 +1198,34 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='vertical' padding='16,16,16,16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Id' " -"width='35' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='Domain' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Name' " -"width='35' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='Desc' " "type='PopUp' " "/> " "</layout> " -"<space size='8'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='LangPopupDesc' " -"width='60' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='LangPopup' " "type='PopUp' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PlatformPopupDesc' " -"width='60' " -"height='Globals.Line.Height' " -"textalign='right' " +"type='OptionsLabel' " "/> " "<widget name='PlatformPopup' " "type='PopUp' " @@ -1569,8 +1234,8 @@ "</layout> " "</dialog> " "<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='vertical' padding='16,16,16,16'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Savepath' " "type='Button' " "/> " @@ -1578,7 +1243,7 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Extrapath' " "type='Button' " "/> " @@ -1586,7 +1251,7 @@ "height='Globals.Line.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='Gamepath' " "type='Button' " "/> " @@ -1597,86 +1262,81 @@ "</layout> " "</dialog> " "<dialog name='GlobalMenu' overlays='screen_center'> " -"<layout type='vertical' padding='8,8,4,6' center='true'> " +"<layout type='vertical' padding='16,16,16,16' center='true'> " "<widget name='Title' " -"width='160' " -"height='4' " +"width='210' " +"height='Globals.Line.Height' " "/> " "<widget name='Version' " -"width='160' " -"height='4' " +"width='210' " +"height='Globals.Line.Height' " "/> " -"<space size='1'/> " +"<widget name='Resume' " +"width='150' " +"height='Globals.Button.Height' " +"/> " +"<space size='10'/> " "<widget name='Load' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='Save' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " -"<space size='1'/> " +"<space size='10'/> " "<widget name='Options' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='About' " -"width='120' " -"height='12' " -"/> " -"<space size='1'/> " -"<widget name='Resume' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " +"<space size='10'/> " "<widget name='RTL' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "<widget name='Quit' " -"width='120' " -"height='12' " +"width='150' " +"height='Globals.Button.Height' " "/> " "</layout> " "</dialog> " "<dialog name='ScummMain' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " "<widget name='Resume' " -"width='Globals.Button.Width' " -"height='14' " +"type='Button' " "/> " -"<space size='2'/> " +"<space size='15'/> " "<widget name='Load' " -"width='Globals.Button.Width' " -"height='14' " +"type='Button' " "/> " "<widget name='Save' " -"width='Globals.Button.Width' " -"height='14' " +"type='Button' " "/> " -"<space size='2'/> " +"<space size='15'/> " "<widget name='Options' " -"width='Globals.Button.Width' " -"height='14' " +"type='Button' " "/> " "<widget name='Help' " -"width='Globals.Button.Width' " -"height='14' " +"type='Button' " "/> " "<widget name='About' " -"width='Globals.Button.Width' " -"height='14' " +"type='Button' " "/> " -"<space size='2'/> " +"<space size='15'/> " "<widget name='Quit' " -"width='Globals.Button.Width' " -"height='14' " +"type='Button' " "/> " "</layout> " "</dialog> " "<dialog name='ScummConfig' overlays='screen_center'> " "<layout type='vertical' padding='8,8,8,8'> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='vertical' padding='0,0,0,0' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcMusicText' " "type='OptionsLabel' " "/> " @@ -1687,7 +1347,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcSfxText' " "type='OptionsLabel' " "/> " @@ -1698,7 +1358,7 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='8'> " "<widget name='vcSpeechText' " "type='OptionsLabel' " "/> " @@ -1709,24 +1369,25 @@ "type='SmallLabel' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " -"<space size='110' /> " +"</layout> " +"<layout type='vertical' padding='24,24,24,24' center='true'> " "<widget name='vcMuteCheckbox' " "type='Checkbox' " -"width='80' " +"width='80' " "/> " "</layout> " -"<space size='4' /> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"</layout> " +"<space size='8' /> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subToggleDesc' " "type='OptionsLabel' " "/> " "<widget name='subToggleButton' " -"width='128' " +"width='158' " "height='Globals.Slider.Height' " "/> " "</layout> " -"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='subSubtitleSpeedDesc' " "type='OptionsLabel' " "/> " @@ -1737,8 +1398,8 @@ "type='SmallLabel' " "/> " "</layout> " -"<space size='20'/> " -"<layout type='horizontal' padding='0,0,0,0' spacing='4'> " +"<space size='60'/> " +"<layout type='horizontal' padding='0,0,0,0' spacing='10'> " "<widget name='Keys' " "type='Button' " "/> " @@ -1753,15 +1414,23 @@ "</layout> " "</dialog> " "<dialog name='ScummSaveLoad' overlays='screen' inset='8' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8' center='true'> " -"<widget name='Title' height='Globals.Line.Height'/> " +"<layout type='vertical' padding='8,8,8,32' center='true'> " +"<widget name='Title' " +"height='Globals.Line.Height' " +"/> " +"<layout type='horizontal' padding='0,0,0,16' spacing='16'> " "<widget name='List' /> " -"<layout type='horizontal' padding='0,0,16,0'> " +"<widget name='Thumbnail' " +"width='180' " +"height='200' " +"/> " +"</layout> " +"<layout type='horizontal' padding='0,0,0,0'> " "<space/> " "<widget name='Delete' " "type='Button' " "/> " -"<space size='16'/> " +"<space size='32'/> " "<widget name='Cancel' " "type='Button' " "/> " @@ -1771,16 +1440,16 @@ "</layout> " "</layout> " "</dialog> " -"<dialog name='ScummHelp' overlays='screen'> " -"<layout type='vertical' padding='8,8,8,8'> " +"<dialog name='ScummHelp' overlays='screen_center'> " +"<layout type='vertical' padding='8,8,8,8' center='true'> " "<widget name='Title' " -"width='180' " +"width='320' " "height='Globals.Line.Height' " "/> " "<widget name='HelpText' " -"height='140' " +"height='200' " "/> " -"<layout type='horizontal' padding='0,0,0,0'> " +"<layout type='horizontal' padding='0,0,16,0'> " "<widget name='Prev' " "type='Button' " "/> " @@ -1795,20 +1464,20 @@ "</layout> " "</dialog> " "<dialog name='MassAdd' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='4,4,16,4' center='true'> " +"<layout type='vertical' padding='8,8,32,8' center='true'> " "<widget name='DirProgressText' " -"width='240' " +"width='250' " "height='Globals.Line.Height' " "/> " "<widget name='GameProgressText' " -"width='240' " +"width='250' " "height='Globals.Line.Height' " "/> " "<widget name='GameList' " -"width='280' " -"height='100' " +"width='480' " +"height='250' " "/> " -"<layout type='horizontal' padding='4,4,4,4'> " +"<layout type='horizontal' padding='8,8,8,8'> " "<widget name='Ok' " "type='Button' " "/> " @@ -1819,20 +1488,20 @@ "</layout> " "</dialog> " "<dialog name='KeyMapper' overlays='screen_center' shading='dim'> " -"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> " +"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> " "<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> " "<widget name='PopupDesc' " "type='OptionsLabel' " "/> " "<widget name='Popup' " "type='PopUp' " -"width='150' " +"width='400' " "height='Globals.Line.Height' " "/> " "</layout> " "<widget name='KeymapArea' " -"width='300' " -"height='120' " +"width='600' " +"height='280' " "/> " "<widget name='Close' " "type='Button' " @@ -1840,3 +1509,359 @@ "</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 0e1d8c539d..c295002f9d 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC index 4dc5cc5982..524141faf2 100644 --- a/gui/themes/scummclassic/THEMERC +++ b/gui/themes/scummclassic/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.6:ScummVM Classic Theme:No Author] +[SCUMMVM_STX0.7:ScummVM Classic Theme:No Author] diff --git a/gui/themes/scummclassic/classic_gfx.stx b/gui/themes/scummclassic/classic_gfx.stx index f6c06e2c80..ff2fadc577 100644 --- a/gui/themes/scummclassic/classic_gfx.stx +++ b/gui/themes/scummclassic/classic_gfx.stx @@ -45,32 +45,57 @@ <fonts> <font id = 'text_default' file = 'default' - color = 'green' /> - <font id = 'text_hover' + <font id = 'text_button' file = 'default' - color = 'green2' /> - <font id = 'text_disabled' + <font id = 'text_normal' file = 'default' - color = 'lightgrey' /> - <font id = 'text_inverted' - file = 'default' + + <text_color id = 'color_normal' + color = 'green' + /> + + <text_color id = 'color_normal_inverted' color = 'black' /> - <font id = 'text_button' - file = 'default' + + <text_color id = 'color_normal_hover' + color = 'green2' + /> + + <text_color id = 'color_normal_disabled' + color = 'lightgrey' + /> + + <text_color id = 'color_alternative' color = 'green' /> - <font id = 'text_button_hover' - file = 'default' + + <text_color id = 'color_alternative_inverted' + color = 'black' + /> + + <text_color id = 'color_alternative_hover' color = 'green2' /> - <font id = 'text_normal' - file = 'default' + + <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'/> @@ -164,7 +189,8 @@ </drawdata> <drawdata id = 'tab_active' cache = 'false'> - <text font = 'text_hover' + <text font = 'text_default' + text_color = 'color_normal_hover' vertical_align = 'center' horizontal_align = 'center' /> @@ -177,6 +203,7 @@ <drawdata id = 'tab_inactive' cache = 'false'> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'center' horizontal_align = 'center' /> @@ -240,6 +267,7 @@ orientation = 'bottom' /> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'center' horizontal_align = 'left' /> @@ -259,7 +287,8 @@ ypos = 'center' orientation = 'bottom' /> - <text font = 'text_disabled' + <text font = 'text_default' + text_color = 'color_normal_disabled' vertical_align = 'center' horizontal_align = 'left' /> @@ -279,7 +308,8 @@ ypos = 'center' orientation = 'bottom' /> - <text font = 'text_hover' + <text font = 'text_default' + text_color = 'color_normal_hover' vertical_align = 'center' horizontal_align = 'left' /> @@ -313,6 +343,7 @@ <drawdata id = 'button_idle' cache = 'false'> <text font = 'text_button' + text_color = 'color_button' vertical_align = 'center' horizontal_align = 'center' /> @@ -323,7 +354,8 @@ </drawdata> <drawdata id = 'button_hover' cache = 'false'> - <text font = 'text_button_hover' + <text font = 'text_button' + text_color = 'color_button_hover' vertical_align = 'center' horizontal_align = 'center' /> @@ -334,7 +366,8 @@ </drawdata> <drawdata id = 'button_disabled' cache = 'false'> - <text font = 'text_disabled' + <text font = 'text_button' + text_color = 'color_button_disabled' vertical_align = 'center' horizontal_align = 'center' /> @@ -345,7 +378,8 @@ </drawdata> <drawdata id = 'checkbox_disabled' cache = 'false'> - <text font = 'text_disabled' + <text font = 'text_default' + text_color = 'color_normal_disabled' vertical_align = 'top' horizontal_align = 'left' /> @@ -357,6 +391,7 @@ <drawdata id = 'checkbox_selected' cache = 'false'> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'top' horizontal_align = 'left' /> @@ -373,6 +408,7 @@ <drawdata id = 'checkbox_default' cache = 'false'> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'top' horizontal_align = 'left' /> diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex fb3a0b1c2d..beff0131f4 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC index 3fbbdf8d46..784f4fae50 100644 --- a/gui/themes/scummmodern/THEMERC +++ b/gui/themes/scummmodern/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.6:ScummVM Modern Theme:No Author] +[SCUMMVM_STX0.7:ScummVM Modern Theme:No Author] diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx index f74d0f0d2f..6a3ab0c233 100644 --- a/gui/themes/scummmodern/scummmodern_gfx.stx +++ b/gui/themes/scummmodern/scummmodern_gfx.stx @@ -105,31 +105,56 @@ <fonts> <font id = 'text_default' file = 'default' - color = 'black' /> - <font id = 'text_hover' + <font id = 'text_button' file = 'default' + /> + <font id = 'text_normal' + file = 'helvr12-l1.bdf' + /> + + <text_color id = 'color_normal' + color = 'black' + /> + + <text_color id = 'color_normal_inverted' + color = 'black' + /> + + <text_color id = 'color_normal_hover' color = 'bgreen' /> - <font id = 'text_disabled' - file = 'default' + + <text_color id = 'color_normal_disabled' color = '192, 192, 192' /> - <font id = 'text_inverted' - file = 'default' + + <text_color id = 'color_alternative' color = 'black' /> - <font id = 'text_button' - file = 'default' + + <text_color id = 'color_alternative_inverted' + color = 'black' + /> + + <text_color id = 'color_alternative_hover' + color = 'bgreen' + /> + + <text_color id = 'color_alternative_disabled' + color = '192, 192, 192' + /> + + <text_color id = 'color_button' color = 'white' /> - <font id = 'text_button_hover' - file = 'default' + + <text_color id = 'color_button_hover' color = '255, 214, 84' /> - <font id = 'text_normal' - file = 'helvr12-l1.bdf' - color = 'black' + + <text_color id = 'color_button_disabled' + color = '192, 192, 192' /> </fonts> @@ -263,6 +288,7 @@ <!-- Active tab in the tabs list --> <drawdata id = 'tab_active' cache = 'false'> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'center' horizontal_align = 'center' /> @@ -279,6 +305,7 @@ <!-- Inactive tab in the tabs list --> <drawdata id = 'tab_inactive' cache = 'false'> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'center' horizontal_align = 'center' /> @@ -370,6 +397,7 @@ orientation = 'bottom' /> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'center' horizontal_align = 'left' /> @@ -392,7 +420,8 @@ ypos = 'center' orientation = 'bottom' /> - <text font = 'text_disabled' + <text font = 'text_default' + text_color = 'color_normal_disabled' vertical_align = 'center' horizontal_align = 'left' /> @@ -418,7 +447,8 @@ ypos = 'center' orientation = 'bottom' /> - <text font = 'text_hover' + <text font = 'text_default' + text_color = 'color_normal_hover' vertical_align = 'center' horizontal_align = 'left' /> @@ -472,6 +502,7 @@ <!-- Idle button --> <drawdata id = 'button_idle' cache = 'false'> <text font = 'text_button' + text_color = 'color_button' vertical_align = 'center' horizontal_align = 'center' /> @@ -490,7 +521,8 @@ <!-- Hovered button --> <drawdata id = 'button_hover' cache = 'false'> - <text font = 'text_button_hover' + <text font = 'text_button' + text_color = 'color_button_hover' vertical_align = 'center' horizontal_align = 'center' /> @@ -509,7 +541,8 @@ <!-- Disabled button --> <drawdata id = 'button_disabled' cache = 'false'> - <text font = 'text_disabled' + <text font = 'text_button' + text_color = 'color_button_disabled' vertical_align = 'center' horizontal_align = 'center' /> @@ -528,7 +561,8 @@ <!-- Disabled checkbox --> <drawdata id = 'checkbox_disabled' cache = 'false'> - <text font = 'text_disabled' + <text font = 'text_default' + text_color = 'color_normal_disabled' vertical_align = 'top' horizontal_align = 'left' /> @@ -540,6 +574,7 @@ <!-- Selected checkbox --> <drawdata id = 'checkbox_selected' cache = 'false'> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'top' horizontal_align = 'left' /> @@ -551,6 +586,7 @@ <!-- Idle checkbox --> <drawdata id = 'checkbox_default' cache = 'false'> <text font = 'text_default' + text_color = 'color_normal' vertical_align = 'top' horizontal_align = 'left' /> @@ -42,7 +42,7 @@ deb: # Special target to create a application wrapper for Mac OS X bundle_name = ScummVM.app -bundle: scummvm-static $(srcdir)/dists/macosx/Info.plist +bundle: scummvm-static mkdir -p $(bundle_name)/Contents/MacOS mkdir -p $(bundle_name)/Contents/Resources echo "APPL????" > $(bundle_name)/Contents/PkgInfo @@ -57,7 +57,7 @@ bundle: scummvm-static $(srcdir)/dists/macosx/Info.plist chmod 755 $(bundle_name)/Contents/MacOS/scummvm $(STRIP) $(bundle_name)/Contents/MacOS/scummvm -iphonebundle: iphone $(srcdir)/dists/iphone/Info.plist +iphonebundle: iphone mkdir -p $(bundle_name) cp $(srcdir)/dists/iphone/Info.plist $(bundle_name)/ cp $(DIST_FILES_DOCS) $(bundle_name)/ diff --git a/sound/midiparser_xmidi.cpp b/sound/midiparser_xmidi.cpp index f7d5e9c32a..343ca34659 100644 --- a/sound/midiparser_xmidi.cpp +++ b/sound/midiparser_xmidi.cpp @@ -115,6 +115,8 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) { byte *pos = _position._play_pos; if (_loopCount < ARRAYSIZE(_loop) - 1) _loopCount++; + else + warning("XMIDI: Exceeding maximum loop count %d", ARRAYSIZE(_loop)); _loop[_loopCount].pos = pos; _loop[_loopCount].repeat = info.basic.param2; @@ -127,11 +129,14 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) { // End the current loop. _loopCount--; } else { - _position._play_pos = _loop[_loopCount].pos; // Repeat 0 means "loop forever". if (_loop[_loopCount].repeat) { if (--_loop[_loopCount].repeat == 0) _loopCount--; + else + _position._play_pos = _loop[_loopCount].pos; + } else { + _position._play_pos = _loop[_loopCount].pos; } } } @@ -155,7 +160,6 @@ void MidiParser_XMIDI::parseNextEvent(EventInfo &info) { warning("Unsupported XMIDI controller %d (0x%2x)", info.basic.param1, info.basic.param1); } - break; } // Should we really keep passing the XMIDI controller events to diff --git a/tools/create_kyradat/amiga.h b/tools/create_kyradat/amiga.h index 26fcddf614..4dbc404d28 100644 --- a/tools/create_kyradat/amiga.h +++ b/tools/create_kyradat/amiga.h @@ -14,7 +14,7 @@ const ExtractEntry kyra1AmigaEng[] = { { kCharacterImageFilenames, 0x0000C814, 0x0000C904 }, { kDefaultShapes, 0x00039230, 0x000396BA }, { kItemNames, 0x0001A3B8, 0x0001A738 }, - { kTakenStrings, 0x0000F9F4, 0x0000FAF0 }, + { kTakenStrings, 0x0000FAE8, 0x0000FAF0 }, { kPlacedStrings, 0x0000FAF0, 0x0000FAFA }, { kDroppedStrings, 0x000101F2, 0x000101FC }, { kNoDropStrings, 0x0000C98E, 0x0000C9D6 }, diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp index ead0c232b1..2e53efbaff 100644 --- a/tools/create_kyradat/create_kyradat.cpp +++ b/tools/create_kyradat/create_kyradat.cpp @@ -498,7 +498,11 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32 for (uint32 i = 0; i < size; ++i) { if (!data[i]) { if (g->special == kAmigaVersion) { - if (!((i + 1) & 0x1)) + if (i + 1 >= size) + ++entries; + else if (!data[i+1]) + continue; + else ++entries; } else { ++entries; @@ -554,6 +558,7 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32 uint8 *buffer = new uint8[targetsize]; assert(buffer); + memset(buffer, 0, targetsize); uint8 *output = buffer; const uint8 *input = (const uint8*) data; @@ -561,7 +566,7 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32 if (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ || g->special == k2TownsFile1E || g->special == k2TownsFile1J || g->special == k2TownsFile2E || g->special == k2TownsFile2J || fmtPatch == 5) { - const byte * c = data + size; + const byte *c = data + size; do { if (fmtPatch == 2 && input - data == 0x3C0 && input[0x10] == 0x32) { memcpy(output, input, 0x0F); @@ -611,8 +616,13 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32 // we need to strip some aligment zeros out here int dstPos = 0; for (uint32 i = 0; i < size; ++i) { - if (!data[i] && ((i+1) & 0x1)) - continue; + if (!data[i]) { + if (i + 1 > size) + continue; + else if (i + 1 < size && !data[i+1]) + continue; + } + *output++ = data[i]; ++dstPos; } diff --git a/tools/scumm-md5.txt b/tools/scumm-md5.txt index 2b937136ad..1459156170 100644 --- a/tools/scumm-md5.txt +++ b/tools/scumm-md5.txt @@ -62,7 +62,8 @@ maniac Maniac Mansion 3905799e081b80a61d4460b7b733c206 262144 us NES NES - - 81bbfa181184cb494e7a81dcfa94fbd9 262144 fr NES NES - - 257f8c14d8c584f7ddd601bcb00920c7 262144 de NES NES - - - f163cf53f7850e43fb482471e5c52e1a 262144 es NES NES - - + f163cf53f7850e43fb482471e5c52e1a 262144 es NES NES - - + e28bc6dbec750bced1b7c98d6caa32ce 262144 it NES NES - - 22d07d6c386c9c25aca5dac2a0c0d94b 262144 se NES NES - - 17f7296f63c78642724f057fd8e736a7 -1 gb NES NES extracted - 91d5db93187fab54d823f73bd6441cb6 -1 us NES NES extracted - @@ -74,7 +75,8 @@ maniac Maniac Mansion e781230da44a44e2f0770edb2b3b3633 -1 en Amiga V2 V2 - dhewg, Andrea Petrucci ce7733f185b838e248927c7ba1a04204 -1 fr Amiga V2 V2 - Tobias Fleischer 9bc548e179cdb0767009401c094d0895 -1 de Amiga V2 V2 - Norbert Lange - a570381b028972d891052ee1e51dc011 -1 en Atari V2 V2 - Andreas Bylund + a570381b028972d891052ee1e51dc011 1988 en Atari V2 V2 SS Andreas Bylund + 0c331637580950aea2346e012ef2a868 1988 en Atari V2 V2 DS Petr Maruska dd30a53035393baa5a5e222e716559af -1 fr Atari V2 V2 - Andreas Bylund be83e882b44f2767bc08d4f766ebc347 -1 de Atari V2 V2 - Joachim Eberhard 15240c59d3681ed53f714f8d925cb2d6 -1 es Atari V2 V2 - VooD diff --git a/tools/update-version.pl b/tools/update-version.pl index ec0249c872..406f8bf045 100755 --- a/tools/update-version.pl +++ b/tools/update-version.pl @@ -35,6 +35,8 @@ my @subs_files = qw( dists/redhat/scummvm.spec dists/scummvm.rc dists/slackware/scummvm.SlackBuild + dists/macosx/Info.plist + dists/iphone/Info.plist dists/wii/meta.xml backends/platform/psp/README.PSP ); |