diff options
author | Norbert Lange | 2009-08-11 22:35:56 +0000 |
---|---|---|
committer | Norbert Lange | 2009-08-11 22:35:56 +0000 |
commit | 0836cf6d9b9222255273a9c6f9d91203b13c3bd9 (patch) | |
tree | 714c59161aaf7dbc36d7cb6b4e8fcaa9c467e8f9 | |
parent | 8cb42dd6896925106282abd23ce23812d6031989 (diff) | |
parent | 65e9ae163ff757ca15af78da4a753a7ee1d25a16 (diff) | |
download | scummvm-rg350-0836cf6d9b9222255273a9c6f9d91203b13c3bd9.tar.gz scummvm-rg350-0836cf6d9b9222255273a9c6f9d91203b13c3bd9.tar.bz2 scummvm-rg350-0836cf6d9b9222255273a9c6f9d91203b13c3bd9.zip |
merged from trunk (Amiga LoK supposedly completeable!)
fixed a bug I introduced in one of the last cleanups
svn-id: r43291
125 files changed, 3214 insertions, 1747 deletions
@@ -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 ffdcd675e6..1192c1abff 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/platform/sdl/graphics.cpp @@ -358,12 +358,54 @@ void OSystem_SDL::initSize(uint w, uint h) { _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; @@ -374,11 +416,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 // @@ -392,7 +434,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 8972234f9e..7b3cf4eaa1 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 7498f48b08..2a5fda30bd 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: @@ -268,12 +280,14 @@ protected: bool fullscreen; bool aspectRatioCorrection; + AspectRatio desiredAspectRatio; int mode; int scaleFactor; int screenWidth, screenHeight; int overlayWidth, overlayHeight; + int hardwareWidth, hardwareHeight; }; VideoState _videoMode, _oldVideoMode; diff --git a/backends/platform/symbian/BuildPackageUpload_AllVersions.pl b/backends/platform/symbian/BuildPackageUpload_AllVersions.pl index ba8afe5084..fbfdaeeeef 100644 --- a/backends/platform/symbian/BuildPackageUpload_AllVersions.pl +++ b/backends/platform/symbian/BuildPackageUpload_AllVersions.pl @@ -59,6 +59,7 @@ $ftp_url = "FTP://$FTP_User\@$FTP_Host/$FTP_Dir/"; # these macros are always defined: $ExtraMacros = "MACRO NONSTANDARD_PORT\n"; +$ExtraMacros .= "MACRO ENABLE_VKEYBD\n"; $ExtraMacros .= "MACRO DISABLE_FANCY_THEMES\n"; $ExtraMacros .= "MACRO DISABLE_SCALERS\n"; $ExtraMacros .= "MACRO DISABLE_HQ_SCALERS\n"; diff --git a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg index a6f1b03327..fe82cb7b4e 100644 --- a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg +++ b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg @@ -63,6 +63,8 @@ "..\..\..\..\dists\engine-data\igor.tbl"-"c:\data\scummvm\igor.tbl" "..\..\..\..\dists\engine-data\lure.dat"-"c:\data\scummvm\lure.dat" "..\..\..\..\dists\engine-data\drascula.dat"-"c:\data\scummvm\drascula.dat" +"..\..\..\..\dists\engine-data\m4.dat"-"c:\data\scummvm\m4.dat" +"..\..\..\vkeybd\packs\vkeybd_default.zip"-"c:\data\scummvm\vkeybd_default.zip" ; Config/log files: 'empty' will automagically be removed on uninstall ""-"c:\data\scummvm\scummvm.ini",FILENULL diff --git a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg index 2289cd435e..5a8d317fbc 100644 --- a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg +++ b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg @@ -60,7 +60,8 @@ "..\..\..\..\dists\engine-data\igor.tbl"-"c:\shared\scummvm\igor.tbl" "..\..\..\..\dists\engine-data\lure.dat"-"c:\shared\scummvm\lure.dat" "..\..\..\..\dists\engine-data\drascula.dat"-"c:\shared\scummvm\drascula.dat" - +"..\..\..\..\dists\engine-data\m4.dat"-"c:\shared\scummvm\m4.dat" +"..\..\..\vkeybd\packs\vkeybd_default.zip"-"c:\shared\scummvm\vkeybd_default.zip" ; Config/log files: 'empty' will automagically be removed on uninstall ""-"c:\shared\scummvm\scummvm.ini",FILENULL ""-"c:\shared\scummvm\scummvm.stdout.txt",FILENULL diff --git a/backends/platform/symbian/mmp/scummvm_base.mmp.in b/backends/platform/symbian/mmp/scummvm_base.mmp.in index 4f6ca6ec8f..57f4fe6008 100644 --- a/backends/platform/symbian/mmp/scummvm_base.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_base.mmp.in @@ -117,4 +117,9 @@ SOURCE backends\keymapper\action.cpp SOURCE backends\keymapper\keymap.cpp SOURCE backends\keymapper\keymapper.cpp SOURCE backends\keymapper\remap-dialog.cpp - +// Source files for virtual keyboard +SOURCE backends\vkeybd\image-map.cpp +SOURCE backends\vkeybd\polygon.cpp +SOURCE backends\vkeybd\virtual-keyboard-gui.cpp +SOURCE backends\vkeybd\virtual-keyboard-parser.cpp +SOURCE backends\vkeybd\virtual-keyboard.cpp diff --git a/backends/platform/symbian/src/SymbianActions.cpp b/backends/platform/symbian/src/SymbianActions.cpp index 995b03f200..5f5551422e 100644 --- a/backends/platform/symbian/src/SymbianActions.cpp +++ b/backends/platform/symbian/src/SymbianActions.cpp @@ -163,7 +163,9 @@ void SymbianActions::initInstanceGame() { bool is_drascula = (strncmp(gameid.c_str(), "drascula",8) == 0); bool is_tucker = (gameid == "tucker"); bool is_groovie = (gameid == "groovie"); + bool is_tinsel = (gameid == "tinsel"); bool is_cruise = (gameid == "cruise"); + bool is_made = (gameid == "made"); Actions::initInstanceGame(); @@ -194,6 +196,8 @@ void SymbianActions::initInstanceGame() { _key_action[ACTION_SAVE].setKey(Common::ASCII_ESCAPE, Common::KEYCODE_ESCAPE); } else if (is_parallaction) { _key_action[ACTION_SAVE].setKey('s', Common::KEYCODE_s); + } else if (is_tinsel) { + _key_action[ACTION_SAVE].setKey(Common::ASCII_F1, SDLK_F1); } else { _key_action[ACTION_SAVE].setKey(Common::ASCII_F5, Common::KEYCODE_F5); // F5 key } @@ -202,9 +206,9 @@ void SymbianActions::initInstanceGame() { _action_enabled[ACTION_QUIT] = true; // Skip text - if (!is_cine && !is_parallaction && !is_groovie) + if (!is_cine && !is_parallaction && !is_groovie && !is_cruise && !is_made) _action_enabled[ACTION_SKIP_TEXT] = true; - if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || + if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || is_tinsel || is_saga || is_kyra || is_touche || is_lure || is_feeble || is_drascula || is_tucker) _key_action[ACTION_SKIP_TEXT].setKey(Common::KEYCODE_ESCAPE, Common::KEYCODE_ESCAPE); // Escape key else { 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/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); @@ -70,8 +70,9 @@ add_engine scumm "SCUMM" yes "scumm_7_8 he" add_engine scumm_7_8 "v7 & v8 games" yes add_engine he "HE71+ games" yes add_engine agi "AGI" yes -add_engine agos "AGOS" yes "pn" +add_engine agos "AGOS" yes "pn agos2" add_engine pn "Personal Nightmare" no +add_engine agos2 "AGOS 2 games" yes add_engine cine "Cinematique evo 1" yes add_engine cruise "Cinematique evo 2" yes add_engine drascula "Drascula: The Vampire Strikes Back" yes diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex 7911a2e549..da57e2ce2a 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat diff --git a/dists/msvc8/ScummVM_Global.vsprops b/dists/msvc8/ScummVM_Global.vsprops index 7ba00aac7b..b1f6315d03 100644 --- a/dists/msvc8/ScummVM_Global.vsprops +++ b/dists/msvc8/ScummVM_Global.vsprops @@ -10,7 +10,7 @@ Name="VCCLCompilerTool" DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996" AdditionalIncludeDirectories="../..;../../engines" - PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE" + PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_PN;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE" ExceptionHandling="0" RuntimeTypeInfo="false" WarningLevel="4" diff --git a/dists/msvc9/ScummVM_Global.vsprops b/dists/msvc9/ScummVM_Global.vsprops index cb86477c21..2fe13f5cc4 100644 --- a/dists/msvc9/ScummVM_Global.vsprops +++ b/dists/msvc9/ScummVM_Global.vsprops @@ -9,7 +9,7 @@ <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../..;../../engines" - PreprocessorDefinitions="USE_NASM;USE_ZLIB;ENABLE_KYRA;ENABLE_LOL;ENABLE_SCUMM;ENABLE_SCUMM_7_8;ENABLE_HE" + PreprocessorDefinitions="USE_NASM;USE_ZLIB;ENABLE_AGOS2;ENABLE_PN;ENABLE_KYRA;ENABLE_LOL;ENABLE_SCUMM;ENABLE_SCUMM_7_8;ENABLE_HE" ExceptionHandling="0" RuntimeTypeInfo="false" WarningLevel="4" diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 0e53698b59..a786882630 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -59,6 +59,7 @@ static const GameSpecificSettings puzzlepack_settings = { "MUSIC", // speech_filename }; +#ifdef ENABLE_AGOS2 AGOSEngine_PuzzlePack::AGOSEngine_PuzzlePack(OSystem *system) : AGOSEngine_Feeble(system) { @@ -72,6 +73,7 @@ AGOSEngine_PuzzlePack::AGOSEngine_PuzzlePack(OSystem *system) _startSecondCount = 0; _tSecondCount = 0; } +#endif AGOSEngine_Simon2::AGOSEngine_Simon2(OSystem *system) : AGOSEngine_Simon1(system) { @@ -696,6 +698,7 @@ static const uint16 initialVideoWindows_PN[20] = { 3, 2, 14, 129, }; +#ifdef ENABLE_AGOS2 void AGOSEngine_PuzzlePack::setupGame() { gss = &puzzlepack_settings; _numVideoOpcodes = 85; @@ -712,6 +715,7 @@ void AGOSEngine_PuzzlePack::setupGame() { AGOSEngine::setupGame(); } +#endif void AGOSEngine_Simon2::setupGame() { gss = &simon2_settings; diff --git a/engines/agos/agos.h b/engines/agos/agos.h index ac1f33428b..a0730deaea 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -34,14 +34,13 @@ #include "common/stack.h" #include "common/util.h" +#ifdef ENABLE_AGOS2 #include "agos/animation.h" +#endif #include "agos/midi.h" #include "agos/sound.h" #include "agos/vga.h" -// TODO: Replace with more portable code -#include <setjmp.h> - namespace AGOS { uint fileReadItemID(Common::SeekableReadStream *in); @@ -892,6 +891,7 @@ public: void vc19_loop(); void vc20_setRepeat(); void vc21_endRepeat(); + virtual void vc22_setPalette(); void vc23_setPriority(); void vc24_setSpriteXY(); void vc25_halt_sprite(); @@ -904,7 +904,7 @@ public: void vc33_setMouseOn(); void vc34_setMouseOff(); void vc35_clearWindow(); - void vc36_setWindowImage(); + virtual void vc36_setWindowImage(); void vc38_ifVarNotZero(); void vc39_setVar(); void vc40_scrollRight(); @@ -924,7 +924,6 @@ public: // Video Script Opcodes, Elvira 1 void vc17_waitEnd(); - void vc22_setPaletteOld(); void vc32_saveScreen(); void vc37_pokePalette(); @@ -962,10 +961,9 @@ public: void vc45_setSpriteX(); void vc46_setSpriteY(); void vc47_addToVar(); - void vc48_setPathFinder(); + virtual void vc48_setPathFinder(); void vc59_ifSpeech(); void vc61_setMaskImage(); - void vc22_setPaletteNew(); // Video Script Opcodes, Simon 2 void vc56_delayLong(); @@ -1366,9 +1364,6 @@ protected: int _tagOfActiveDoline; ///< tag of the active doline "instance" int _dolineReturnVal; - jmp_buf _loadfail; - - byte *_dataBase, *_textBase; uint32 _dataBaseSize, _textBaseSize; @@ -1771,6 +1766,8 @@ public: virtual void executeOpcode(int opcode); + virtual void vc22_setPalette(); + // Opcodes, Simon 1 void os1_animate(); void os1_pauseGame(); @@ -1875,6 +1872,7 @@ protected: virtual char *genSaveName(int slot); }; +#ifdef ENABLE_AGOS2 class AGOSEngine_Feeble : public AGOSEngine_Simon2 { public: AGOSEngine_Feeble(OSystem *system); @@ -1886,6 +1884,9 @@ public: virtual void executeOpcode(int opcode); + virtual void vc36_setWindowImage(); + virtual void vc48_setPathFinder(); + void off_chance(); void off_jumpOut(); void off_addTextBox(); @@ -2092,6 +2093,7 @@ protected: virtual char *genSaveName(int slot); }; +#endif } // End of namespace AGOS diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp index 36399a7b2f..2e7eb9cb5e 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -27,6 +27,7 @@ #include "common/endian.h" #include "common/events.h" +#include "common/file.h" #include "common/system.h" #include "graphics/cursorman.h" diff --git a/engines/agos/animation.h b/engines/agos/animation.h index 4ebcb3d4b3..3ce6aa9ab2 100644 --- a/engines/agos/animation.h +++ b/engines/agos/animation.h @@ -26,9 +26,6 @@ #ifndef AGOS_ANIMATION_H #define AGOS_ANIMATION_H -#include "common/file.h" -#include "common/stream.h" - #include "graphics/video/dxa_decoder.h" #include "graphics/video/smk_decoder.h" #include "sound/mixer.h" diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp index 5b0a694312..fb012a89dd 100644 --- a/engines/agos/charset.cpp +++ b/engines/agos/charset.cpp @@ -34,6 +34,7 @@ namespace AGOS { +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::doOutput(const byte *src, uint len) { if (_textWindow == NULL) return; @@ -64,6 +65,7 @@ void AGOSEngine_Feeble::doOutput(const byte *src, uint len) { } } } +#endif void AGOSEngine::doOutput(const byte *src, uint len) { uint idx; @@ -573,6 +575,7 @@ void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) { } } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) { if (_noOracleScroll == 0) { if (window->height < window->textRow + 30) { @@ -603,6 +606,7 @@ void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) { window->textColumnOffset = 0; window->textLength = 0; } +#endif void AGOSEngine::windowNewLine(WindowBlock *window) { window->textColumn = 0; diff --git a/engines/agos/cursor.cpp b/engines/agos/cursor.cpp index c279fbd335..1304ca7ca4 100644 --- a/engines/agos/cursor.cpp +++ b/engines/agos/cursor.cpp @@ -348,6 +348,7 @@ static const byte _mouseOffs[29 * 32] = { 0,0,10,7,10,6,10,5,10,4,10,3,10,4,10,5,10,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; +#ifdef ENABLE_AGOS2 void AGOSEngine_PuzzlePack::handleMouseMoved() { uint x; @@ -379,6 +380,7 @@ void AGOSEngine_PuzzlePack::handleMouseMoved() { drawMousePointer(); } +#endif void AGOSEngine_Simon1::handleMouseMoved() { uint x; @@ -638,6 +640,7 @@ void AGOSEngine::mouseOn() { _videoLockOut &= ~1; } +#ifdef ENABLE_AGOS2 void AGOSEngine_PuzzlePack::initMouse() { if (getGameId() == GID_DIMP) { AGOSEngine_Simon1::initMouse(); @@ -652,48 +655,12 @@ void AGOSEngine_FeebleDemo::initMouse() { // TODO: Add larger cursor AGOSEngine_Simon1::initMouse(); } - -static const byte mouseCursorPalette[] = { - 0x00, 0x00, 0x00, 0x00, // Black - 0xFF, 0xFF, 0xFF, 0x00, // White -}; - void AGOSEngine_Feeble::initMouse() { _maxCursorWidth = 40; _maxCursorHeight = 40; _mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1); } -void AGOSEngine_Simon1::initMouse() { - AGOSEngine::initMouse(); - - const uint16 *src = _common_mouseInfo; - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - if (src[0] & (1 << (15 - (j % 16)))) { - if (src[1] & (1 << (15 - (j % 16)))) { - _mouseData[16 * i + j] = 1; - } else { - _mouseData[16 * i + j] = 0; - } - } - } - src += 2; - } - - CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); -} - -void AGOSEngine::initMouse() { - _maxCursorWidth = 16; - _maxCursorHeight = 16; - _mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1); - - memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight); - - CursorMan.replaceCursorPalette(mouseCursorPalette, 0, ARRAYSIZE(mouseCursorPalette) / 4); -} - void AGOSEngine_PuzzlePack::loadMouseImage() { loadZone(_variableArray[500]); VgaPointersEntry *vpe = &_vgaBufferPointers[_variableArray[500]]; @@ -793,6 +760,42 @@ void AGOSEngine_Feeble::drawMousePointer() { CursorMan.replaceCursor(_mouseData, _maxCursorWidth, _maxCursorHeight, hotspotX, hotspotY, 0); } } +#endif + +void AGOSEngine_Simon1::initMouse() { + AGOSEngine::initMouse(); + + const uint16 *src = _common_mouseInfo; + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if (src[0] & (1 << (15 - (j % 16)))) { + if (src[1] & (1 << (15 - (j % 16)))) { + _mouseData[16 * i + j] = 1; + } else { + _mouseData[16 * i + j] = 0; + } + } + } + src += 2; + } + + CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); +} + +static const byte mouseCursorPalette[] = { + 0x00, 0x00, 0x00, 0x00, // Black + 0xFF, 0xFF, 0xFF, 0x00, // White +}; + +void AGOSEngine::initMouse() { + _maxCursorWidth = 16; + _maxCursorHeight = 16; + _mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1); + + memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight); + + CursorMan.replaceCursorPalette(mouseCursorPalette, 0, ARRAYSIZE(mouseCursorPalette) / 4); +} void AGOSEngine::drawMousePointer() { if (getGameType() == GType_SIMON2) { diff --git a/engines/agos/debug.cpp b/engines/agos/debug.cpp index 8bdb35d3ae..519dfc344c 100644 --- a/engines/agos/debug.cpp +++ b/engines/agos/debug.cpp @@ -26,6 +26,8 @@ // AGOS debug functions +#include "common/file.h" + #include "agos/debug.h" #include "agos/agos.h" #include "agos/intern.h" @@ -323,6 +325,7 @@ void AGOSEngine::dumpAllVgaScriptFiles() { } } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::dumpVgaFile(const byte *vga) { const byte *pp; const byte *p; @@ -352,6 +355,7 @@ void AGOSEngine_Feeble::dumpVgaFile(const byte *vga) { p += sizeof(ImageHeader_Feeble); } } +#endif void AGOSEngine_Simon1::dumpVgaFile(const byte *vga) { const byte *pp; diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp index 7877e19646..a7b5b91602 100644 --- a/engines/agos/detection.cpp +++ b/engines/agos/detection.cpp @@ -66,17 +66,21 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = { }; static const PlainGameDescriptor simonGames[] = { +#ifdef ENABLE_PN {"pn", "Personal Nightmare"}, +#endif {"elvira1", "Elvira - Mistress of the Dark"}, {"elvira2", "Elvira II - The Jaws of Cerberus"}, {"waxworks", "Waxworks"}, {"simon1", "Simon the Sorcerer 1"}, {"simon2", "Simon the Sorcerer 2"}, +#ifdef ENABLE_AGOS2 {"feeble", "The Feeble Files"}, {"dimp", "Demon in my Pocket"}, {"jumble", "Jumble"}, {"puzzle", "NoPatience"}, {"swampy", "Swampy Adventures"}, +#endif {0, 0} }; @@ -158,6 +162,7 @@ bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame case AGOS::GType_SIMON2: *engine = new AGOS::AGOSEngine_Simon2(syst); break; +#ifdef ENABLE_AGOS2 case AGOS::GType_FF: if (gd->features & GF_DEMO) *engine = new AGOS::AGOSEngine_FeebleDemo(syst); @@ -167,6 +172,7 @@ bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame case AGOS::GType_PP: *engine = new AGOS::AGOSEngine_PuzzlePack(syst); break; +#endif default: res = false; error("AGOS engine: unknown gameType"); diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h index 0c672aef52..2a6cf4f752 100644 --- a/engines/agos/detection_tables.h +++ b/engines/agos/detection_tables.h @@ -32,6 +32,7 @@ using Common::GUIO_NOSPEECH; using Common::GUIO_NOSUBTITLES; static const AGOSGameDescription gameDescriptions[] = { +#ifdef ENABLE_PN // Personal Nightmare 1.1 - English Amiga { { @@ -123,6 +124,7 @@ static const AGOSGameDescription gameDescriptions[] = { GID_PN, GF_OLD_BUNDLE | GF_CRUNCHED | GF_EGA | GF_PLANAR }, +#endif // Elvira 1 - English Amiga Floppy Demo { @@ -1600,7 +1602,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1625,7 +1627,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1675,7 +1677,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::HB_ISR, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1700,7 +1702,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1726,7 +1728,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformWindows, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -1751,7 +1753,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO_NOSUBTITLES + GUIO_NONE }, GType_SIMON1, @@ -2335,6 +2337,7 @@ static const AGOSGameDescription gameDescriptions[] = { GF_TALKIE }, +#ifdef ENABLE_AGOS2 // The Feeble Files - English DOS Demo { { @@ -2807,6 +2810,7 @@ static const AGOSGameDescription gameDescriptions[] = { GID_SWAMPY, GF_OLD_BUNDLE | GF_TALKIE }, +#endif { AD_TABLE_END_MARKER, 0, 0, 0 } }; diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index 368da5db83..35023885cc 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -46,6 +46,7 @@ byte *AGOSEngine::getScaleBuf() { return (byte *)_scaleBuf->pixels; } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::animateSpritesByY() { VgaSprite *vsp; VgaPointersEntry *vpe; @@ -147,6 +148,7 @@ void AGOSEngine_Feeble::animateSprites() { _displayScreen = true; } +#endif void AGOSEngine::animateSprites() { VgaSprite *vsp; diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index cbb09e1ec7..0c7c1feb51 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -552,6 +552,7 @@ void AGOSEngine::delay(uint amount) { } while (cur < start + amount && !shouldQuit()); } +#ifdef ENABLE_AGOS2 void AGOSEngine_PuzzlePack::timerProc() { _lastTickCount = _system->getMillis(); @@ -609,6 +610,7 @@ void AGOSEngine_Feeble::timerProc() { _videoLockOut &= ~2; } +#endif #ifdef ENABLE_PN void AGOSEngine_PN::timerProc() { @@ -677,6 +679,7 @@ void AGOSEngine::timerProc() { _videoLockOut &= ~2; } +#ifdef ENABLE_AGOS2 void AGOSEngine_PuzzlePack::dimpIdle() { int z, n; @@ -758,5 +761,6 @@ void AGOSEngine_PuzzlePack::dimpIdle() { } } } +#endif } // End of namespace AGOS diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp index 1b5a820260..a7bd1895c5 100644 --- a/engines/agos/gfx.cpp +++ b/engines/agos/gfx.cpp @@ -226,6 +226,7 @@ bool AGOSEngine::drawImage_clip(VC10_state *state) { return (state->draw_width != 0 && state->draw_height != 0); } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) { Common::Rect srcRect, dstRect; float factor, xscale; @@ -461,6 +462,7 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) { } while (--state->draw_height); } } +#endif void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) { if (getGameType() == GType_SIMON1 && (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10)) { diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp index 2fd93e64f2..cb37cf3841 100644 --- a/engines/agos/icons.cpp +++ b/engines/agos/icons.cpp @@ -374,6 +374,7 @@ void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { _videoLockOut &= ~0x8000; } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::drawIconArray(uint num, Item *itemRef, int line, int classMask) { Item *item_ptr_org = itemRef; WindowBlock *window; @@ -477,6 +478,7 @@ l1:; itemRef = derefItem(itemRef->next); window->iconPtr->upArrow = _scrollUpHitArea; window->iconPtr->downArrow = _scrollDownHitArea; } +#endif void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) { Item *item_ptr_org = itemRef; @@ -581,6 +583,7 @@ void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) } } +#ifdef ENABLE_AGOS2 uint AGOSEngine_Feeble::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *itemPtr) { HitArea *ha = findEmptyHitArea(); @@ -596,6 +599,7 @@ uint AGOSEngine_Feeble::setupIconHitArea(WindowBlock *window, uint num, uint x, return ha - _hitAreas; } +#endif uint AGOSEngine_Simon2::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *itemPtr) { HitArea *ha = findEmptyHitArea(); @@ -683,6 +687,7 @@ uint AGOSEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, return ha - _hitAreas; } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::addArrows(WindowBlock *window, uint8 num) { HitArea *ha; @@ -712,6 +717,7 @@ void AGOSEngine_Feeble::addArrows(WindowBlock *window, uint8 num) { ha->window = window; ha->verb = 1; } +#endif void AGOSEngine_Simon2::addArrows(WindowBlock *window, uint8 num) { HitArea *ha; @@ -860,16 +866,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 +887,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 +962,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 +991,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/module.mk b/engines/agos/module.mk index a7042fa2ad..41305620f8 100644 --- a/engines/agos/module.mk +++ b/engines/agos/module.mk @@ -2,7 +2,6 @@ MODULE := engines/agos MODULE_OBJS := \ agos.o \ - animation.o \ charset.o \ charset-fontdata.o \ contain.o \ @@ -12,7 +11,6 @@ MODULE_OBJS := \ detection.o \ draw.o \ event.o \ - feeble.o \ gfx.o \ icons.o \ input.o \ @@ -20,8 +18,6 @@ MODULE_OBJS := \ menus.o \ midi.o \ midiparser_s1d.o \ - oracle.o \ - pn.o \ res.o \ res_ami.o \ res_snd.o \ @@ -30,26 +26,38 @@ MODULE_OBJS := \ script.o \ script_e1.o \ script_e2.o \ - script_pn.o \ script_ww.o \ script_s1.o \ script_s2.o \ - script_ff.o \ - script_pp.o \ sound.o \ string.o \ subroutine.o \ verb.o \ vga.o \ vga_e2.o \ - vga_pn.o \ vga_ww.o \ vga_s1.o \ vga_s2.o \ - vga_ff.o \ window.o \ zones.o +ifdef ENABLE_PN +MODULE_OBJS += \ + pn.o \ + script_pn.o \ + vga_pn.o +endif + +ifdef ENABLE_AGOS2 +MODULE_OBJS += \ + animation.o \ + feeble.o \ + oracle.o \ + script_ff.o \ + script_pp.o \ + vga_ff.o +endif + # This module can be built as a plugin ifeq ($(ENABLE_AGOS), DYNAMIC_PLUGIN) PLUGIN := 1 diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp index 4278ed11e6..e7e9920ced 100644 --- a/engines/agos/res.cpp +++ b/engines/agos/res.cpp @@ -39,25 +39,27 @@ using Common::File; namespace AGOS { +#ifdef ENABLE_AGOS2 uint16 AGOSEngine_Feeble::to16Wrapper(uint value) { return TO_LE_16(value); } -uint16 AGOSEngine::to16Wrapper(uint value) { - return TO_BE_16(value); -} - uint16 AGOSEngine_Feeble::readUint16Wrapper(const void *src) { return READ_LE_UINT16(src); } -uint16 AGOSEngine::readUint16Wrapper(const void *src) { - return READ_BE_UINT16(src); -} - uint32 AGOSEngine_Feeble::readUint32Wrapper(const void *src) { return READ_LE_UINT32(src); } +#endif + +uint16 AGOSEngine::to16Wrapper(uint value) { + return TO_BE_16(value); +} + +uint16 AGOSEngine::readUint16Wrapper(const void *src) { + return READ_BE_UINT16(src); +} uint32 AGOSEngine::readUint32Wrapper(const void *src) { return READ_BE_UINT32(src); diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index e3052e7d2f..d5146ae408 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -25,6 +25,8 @@ +#include "common/file.h" + #include "agos/agos.h" #include "agos/intern.h" diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index 3787617be7..0d31c0353d 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -23,6 +23,7 @@ * */ +#include "common/file.h" #include "common/savefile.h" #include "common/system.h" @@ -72,6 +73,7 @@ int AGOSEngine::countSaveGames() { return i; } +#ifdef ENABLE_AGOS2 char *AGOSEngine_PuzzlePack::genSaveName(int slot) { static char buf[20]; @@ -88,6 +90,7 @@ char *AGOSEngine_Feeble::genSaveName(int slot) { sprintf(buf, "feeble.%.3d", slot); return buf; } +#endif char *AGOSEngine_Simon2::genSaveName(int slot) { static char buf[20]; @@ -283,7 +286,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 +315,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/string.cpp b/engines/agos/string.cpp index 3773b1fa10..6fa0b5d97f 100644 --- a/engines/agos/string.cpp +++ b/engines/agos/string.cpp @@ -25,6 +25,8 @@ +#include "common/file.h" + #include "agos/agos.h" #include "agos/intern.h" @@ -560,6 +562,7 @@ void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *strin } } +#ifdef ENABLE_AGOS2 // The Feeble Files specific void AGOSEngine_Feeble::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) { char convertedString[320]; @@ -693,6 +696,7 @@ void AGOSEngine_Feeble::sendInteractText(uint16 num, const char *fmt, ...) { printInteractText(num, string); } +#endif // Waxworks specific uint16 AGOSEngine_Waxworks::getBoxSize() { diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp index 70ad3404f5..a4aa81a171 100644 --- a/engines/agos/subroutine.cpp +++ b/engines/agos/subroutine.cpp @@ -25,6 +25,8 @@ +#include "common/file.h" + #include "agos/agos.h" #include "agos/intern.h" diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp index 8376ebb28e..8e425e0b64 100644 --- a/engines/agos/verb.cpp +++ b/engines/agos/verb.cpp @@ -203,6 +203,7 @@ static const char *const czech_verb_prep_names[] = { "", "", "", "komu ?" }; +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::clearName() { stopAnimateSimon2(2, 6); _lastNameOn = NULL; @@ -210,6 +211,7 @@ void AGOSEngine_Feeble::clearName() { _mouseAnim = 1; return; } +#endif void AGOSEngine_Simon2::clearName() { if (getBitFlag(79)) { @@ -530,6 +532,7 @@ void AGOSEngine::defineBox(int id, int x, int y, int width, int height, int flag _needHitAreaRecalc++; } +#ifdef ENABLE_AGOS2 void AGOSEngine_PuzzlePack::resetVerbs() { _verbHitArea = 300; } @@ -559,6 +562,7 @@ void AGOSEngine_Feeble::resetVerbs() { setVerb(NULL); } } +#endif void AGOSEngine::resetVerbs() { if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) @@ -590,6 +594,7 @@ void AGOSEngine::resetVerbs() { } } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::setVerb(HitArea *ha) { int cursor = _mouseCursor; if (_noRightClick) @@ -616,6 +621,7 @@ void AGOSEngine_Feeble::setVerb(HitArea *ha) { _needHitAreaRecalc++; _verbHitArea = cursor + 300; } +#endif void AGOSEngine::setVerb(HitArea *ha) { HitArea *tmp = _currentVerbBox; @@ -654,9 +660,11 @@ void AGOSEngine::setVerb(HitArea *ha) { _currentVerbBox = ha; } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::hitarea_leave(HitArea *ha, bool state) { invertBox(ha, state); } +#endif void AGOSEngine::hitarea_leave(HitArea *ha, bool state) { if (getGameType() == GType_SIMON2) { @@ -917,6 +925,7 @@ void AGOSEngine::displayName(HitArea *ha) { _lastNameOn = ha; } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::invertBox(HitArea *ha, bool state) { if (getBitFlag(205) || getBitFlag(206)) { if (state != 0) { @@ -959,6 +968,7 @@ void AGOSEngine_Feeble::invertBox(HitArea *ha, bool state) { } } } +#endif void AGOSEngine::invertBox(HitArea *ha, byte a, byte b, byte c, byte d) { byte *src, color; diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index d37681508e..1344be6b3a 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -106,7 +106,7 @@ void AGOSEngine_Elvira1::setupVideoOpcodes(VgaOpcodeProc *op) { op[20] = &AGOSEngine::vc19_loop; op[21] = &AGOSEngine::vc20_setRepeat; op[22] = &AGOSEngine::vc21_endRepeat; - op[23] = &AGOSEngine::vc22_setPaletteOld; + op[23] = &AGOSEngine::vc22_setPalette; op[24] = &AGOSEngine::vc23_setPriority; op[25] = &AGOSEngine::vc24_setSpriteXY; op[26] = &AGOSEngine::vc25_halt_sprite; @@ -918,7 +918,7 @@ static const uint8 iconPalette[64] = { 0x77, 0x55, 0x00, }; -void AGOSEngine::vc22_setPaletteOld() { +void AGOSEngine::vc22_setPalette() { byte *offs, *palptr, *src; uint16 b, num; @@ -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]); @@ -1302,12 +1302,7 @@ void AGOSEngine::vc36_setWindowImage() { _displayScreen = false; uint16 vga_res = vcReadNextWord(); uint16 windowNum = vcReadNextWord(); - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - fillBackGroundFromFront(); - } else { - setWindowImage(windowNum, vga_res); - } + setWindowImage(windowNum, vga_res); } void AGOSEngine::vc37_pokePalette() { diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp index de3cb55963..1bbc7f4849 100644 --- a/engines/agos/vga_e2.cpp +++ b/engines/agos/vga_e2.cpp @@ -40,7 +40,7 @@ void AGOSEngine_Elvira2::setupVideoOpcodes(VgaOpcodeProc *op) { op[17] = &AGOSEngine::vc17_waitEnd; op[19] = &AGOSEngine::vc19_loop; - op[22] = &AGOSEngine::vc22_setPaletteOld; + op[22] = &AGOSEngine::vc22_setPalette; op[28] = &AGOSEngine::vc28_playSFX; op[32] = &AGOSEngine::vc32_saveScreen; op[37] = &AGOSEngine::vc37_pokePalette; diff --git a/engines/agos/vga_ff.cpp b/engines/agos/vga_ff.cpp index 14451a3dbe..694aa3ba28 100644 --- a/engines/agos/vga_ff.cpp +++ b/engines/agos/vga_ff.cpp @@ -68,6 +68,57 @@ int AGOSEngine::getScale(int16 y, int16 x) { } } +void AGOSEngine_Feeble::vc36_setWindowImage() { + _displayScreen = false; + vcReadNextWord(); + vcReadNextWord(); + fillBackGroundFromFront(); +} + +void AGOSEngine_Feeble::vc48_setPathFinder() { + uint16 a = (uint16)_variableArrayPtr[12]; + const uint16 *p = _pathFindArray[a - 1]; + + VgaSprite *vsp = findCurSprite(); + int16 x, y, ydiff; + int16 x1, y1, x2, y2; + uint pos = 0; + + x = vsp->x; + while (x >= (int16)readUint16Wrapper(p + 2)) { + p += 2; + pos++; + } + + x1 = readUint16Wrapper(p); + y1 = readUint16Wrapper(p + 1); + x2 = readUint16Wrapper(p + 2); + y2 = readUint16Wrapper(p + 3); + + if (x2 != 9999) { + ydiff = y2 - y1; + if (ydiff < 0) { + ydiff = -ydiff; + x = vsp->x & 7; + ydiff *= x; + ydiff /= 8; + ydiff = -ydiff; + } else { + x = vsp->x & 7; + ydiff *= x; + ydiff /= 8; + } + y1 += ydiff; + } + + y = vsp->y; + vsp->y = y1; + checkScrollY(y1 - y, y1); + + _variableArrayPtr[11] = x1; + _variableArrayPtr[13] = pos; +} + void AGOSEngine::vc75_setScale() { _baseY = vcReadNextWord(); _scale = vcReadNextWord() / 1000000.0f; diff --git a/engines/agos/vga_pn.cpp b/engines/agos/vga_pn.cpp index 12846b08f1..de0b53f2e6 100644 --- a/engines/agos/vga_pn.cpp +++ b/engines/agos/vga_pn.cpp @@ -57,7 +57,9 @@ void AGOSEngine_PN::setupVideoOpcodes(VgaOpcodeProc *op) { op[20] = &AGOSEngine::vc19_loop; op[21] = &AGOSEngine::vc20_setRepeat; op[22] = &AGOSEngine::vc21_endRepeat; - op[23] = &AGOSEngine::vc22_setPaletteOld; + // FIXME: This has been "vc22_setPaletteOld" before, but that does not seem to exist. + // Please check whether "vc22_setPalette" is fine to be used here. + op[23] = &AGOSEngine::vc22_setPalette; op[24] = &AGOSEngine::vc23_setPriority; op[25] = &AGOSEngine::vc24_setSpriteXY; op[26] = &AGOSEngine::vc25_halt_sprite; diff --git a/engines/agos/vga_s1.cpp b/engines/agos/vga_s1.cpp index b1ae26437e..bb13d211fe 100644 --- a/engines/agos/vga_s1.cpp +++ b/engines/agos/vga_s1.cpp @@ -36,7 +36,7 @@ void AGOSEngine_Simon1::setupVideoOpcodes(VgaOpcodeProc *op) { op[11] = &AGOSEngine::vc11_clearPathFinder; op[17] = &AGOSEngine::vc17_setPathfinderItem; - op[22] = &AGOSEngine::vc22_setPaletteNew; + op[22] = &AGOSEngine::vc22_setPalette; op[32] = &AGOSEngine::vc32_copyVar; op[37] = &AGOSEngine::vc37_addToSpriteY; op[48] = &AGOSEngine::vc48_setPathFinder; @@ -96,7 +96,7 @@ static const uint8 customPalette[96] = { 0xFF, 0xFF, 0x77, }; -void AGOSEngine::vc22_setPaletteNew() { +void AGOSEngine_Simon1::vc22_setPalette() { byte *offs, *palptr = 0, *src; uint16 a = 0, b, num, palSize = 0; @@ -186,73 +186,32 @@ void AGOSEngine::vc48_setPathFinder() { uint16 a = (uint16)_variableArrayPtr[12]; const uint16 *p = _pathFindArray[a - 1]; - if (getGameType() == GType_FF || getGameType() == GType_PP) { - VgaSprite *vsp = findCurSprite(); - int16 x, y, ydiff; - int16 x1, y1, x2, y2; - uint pos = 0; - - x = vsp->x; - while (x >= (int16)readUint16Wrapper(p + 2)) { - p += 2; - pos++; - } - - x1 = readUint16Wrapper(p); - y1 = readUint16Wrapper(p + 1); - x2 = readUint16Wrapper(p + 2); - y2 = readUint16Wrapper(p + 3); - - if (x2 != 9999) { - ydiff = y2 - y1; - if (ydiff < 0) { - ydiff = -ydiff; - x = vsp->x & 7; - ydiff *= x; - ydiff /= 8; - ydiff = -ydiff; - } else { - x = vsp->x & 7; - ydiff *= x; - ydiff /= 8; - } - y1 += ydiff; - } - - y = vsp->y; - vsp->y = y1; - checkScrollY(y1 - y, y1); - - _variableArrayPtr[11] = x1; - _variableArrayPtr[13] = pos; - } else { - uint b = (uint16)_variableArray[13]; - p += b * 2 + 1; - int c = _variableArray[14]; + uint b = (uint16)_variableArray[13]; + p += b * 2 + 1; + int c = _variableArray[14]; - int step; - int y1, y2; - int16 *vp; + int step; + int y1, y2; + int16 *vp; - step = 2; - if (c < 0) { - c = -c; - step = -2; - } + step = 2; + if (c < 0) { + c = -c; + step = -2; + } - vp = &_variableArray[20]; + vp = &_variableArray[20]; - do { - y2 = readUint16Wrapper(p); - p += step; - y1 = readUint16Wrapper(p) - y2; + do { + y2 = readUint16Wrapper(p); + p += step; + y1 = readUint16Wrapper(p) - y2; - vp[0] = y1 / 2; - vp[1] = y1 - (y1 / 2); + vp[0] = y1 / 2; + vp[1] = y1 - (y1 / 2); - vp += 2; - } while (--c); - } + vp += 2; + } while (--c); } void AGOSEngine::vc59_ifSpeech() { diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp index a578568a03..8bf4102067 100644 --- a/engines/agos/window.cpp +++ b/engines/agos/window.cpp @@ -122,6 +122,7 @@ void AGOSEngine::clearWindow(WindowBlock *window) { window->scrollY = 0; } +#ifdef ENABLE_AGOS2 void AGOSEngine_Feeble::colorWindow(WindowBlock *window) { byte *dst; uint16 h, w; @@ -140,6 +141,7 @@ void AGOSEngine_Feeble::colorWindow(WindowBlock *window) { _videoLockOut &= ~0x8000; } +#endif void AGOSEngine::colorWindow(WindowBlock *window) { uint16 y, h; 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/engines.mk b/engines/engines.mk index 8d7d8de9ff..ff2b7c0a3e 100644 --- a/engines/engines.mk +++ b/engines/engines.mk @@ -24,6 +24,10 @@ MODULES += engines/agos ifdef ENABLE_PN DEFINES += -DENABLE_PN endif + +ifdef ENABLE_AGOS2 +DEFINES += -DENABLE_AGOS2 +endif endif ifdef ENABLE_CINE 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/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 4624aced90..e9c71f511d 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; @@ -204,9 +208,29 @@ void GUI_LoK::createScreenThumbnail(Graphics::Surface &dst) { uint8 *screen = new uint8[Screen::SCREEN_W*Screen::SCREEN_H]; if (screen) { _screen->queryPageFromDisk("SEENPAGE.TMP", 0, screen); - uint8 screenPal[768]; - _screen->getRealPalette(2, screenPal); + + if (_vm->gameFlags().platform == Common::kPlatformAmiga) { + _screen->getRealPalette(0, &screenPal[ 0]); + _screen->getRealPalette(1, &screenPal[96]); + + // Set the interface palette text color to white + screenPal[96 + 16 * 3 + 0] = 0xFF; + screenPal[96 + 16 * 3 + 1] = 0xFF; + screenPal[96 + 16 * 3 + 2] = 0xFF; + + if (_screen->isInterfacePaletteEnabled()) { + for (int y = 0; y < 64; ++y) { + for (int x = 0; x < 320; ++x) { + screen[(y + 136) * Screen::SCREEN_W + x] += 32; + } + } + } + + } else { + _screen->getRealPalette(2, screenPal); + } + ::createThumbnail(&dst, screen, Screen::SCREEN_W, Screen::SCREEN_H, screenPal); } delete[] screen; @@ -365,6 +389,13 @@ void GUI_LoK::setGUILabels() { offsetOptions = 10; offsetOn = 0; walkspeedGarbageOffset = 0; + } else if (_vm->gameFlags().platform == Common::kPlatformAmiga) { + // English Amiga version + offset = 23; + offsetOn = 23; + offsetOptions = 32; + walkspeedGarbageOffset = 2; + offsetMainMenu = 23; } assert(offset + 27 < _vm->_guiStringsSize); @@ -448,8 +479,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; @@ -639,12 +676,12 @@ int GUI_LoK::loadGameMenu(Button *button) { } void GUI_LoK::redrawTextfield() { - _screen->fillRect(38, 91, 287, 102, 250); + _screen->fillRect(38, 91, 287, 102, _vm->gameFlags().platform == Common::kPlatformAmiga ? 18 : 250); _text->printText(_savegameName, 38, 92, 253, 0, 0); _screen->_charWidth = -2; int width = _screen->getTextWidth(_savegameName); - _screen->fillRect(39 + width, 93, 45 + width, 100, 254); + _screen->fillRect(39 + width, 93, 45 + width, 100, _vm->gameFlags().platform == Common::kPlatformAmiga ? 31 : 254); _screen->_charWidth = 0; _screen->updateScreen(); @@ -923,6 +960,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/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 3863cad251..fc19b2fb65 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -368,6 +368,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(); @@ -669,7 +672,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 4d99ed11af..2783e92aee 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); @@ -523,35 +525,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; @@ -573,13 +575,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; @@ -617,16 +619,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; @@ -649,6 +651,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..e3d28163a8 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -160,7 +160,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _flyingObjects = 0; _monsters = 0; _lastMouseRegion = 0; - _objectLastDirection = _monsterCountUnk = _monsterShiftAlt = 0; + _objectLastDirection = _monsterStepCounter = _monsterStepMode = 0; _monsterCurBlock = 0; _seqWindowX1 = _seqWindowY1 = _seqWindowX2 = _seqWindowY2 = _seqTrigger = 0; _spsWindowX = _spsWindowY = _spsWindowW = _spsWindowH = 0; @@ -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/lol.h b/engines/kyra/lol.h index f4ac597b5c..06950779b1 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -1296,8 +1296,8 @@ private: uint8 _monsterAnimType[3]; uint16 _monsterCurBlock; int _objectLastDirection; - int _monsterCountUnk; - int _monsterShiftAlt; + int _monsterStepCounter; + int _monsterStepMode; const uint16 *_monsterModifiers; int _monsterModifiersSize; diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp index c59f2bebf6..13f08715fd 100644 --- a/engines/kyra/saveload_lok.cpp +++ b/engines/kyra/saveload_lok.cpp @@ -177,15 +177,32 @@ 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); - _animator->setBrandonAnimSeqSize(3, 48); + + // Will-O-Wisp uses a different shape size than Brandon's usual + // shape, thus we need to setup the correct size depending on + // his state over here. This fixes graphics glitches when loading + // saves, where Brandon is transformed into the Will-O-Wisp. + if (_brandonStatusBit & 2) + _animator->setBrandonAnimSeqSize(5, 48); + else + _animator->setBrandonAnimSeqSize(3, 48); + redrawInventory(0); - _brandonPosX = brandonX; - _brandonPosY = brandonY; + + _brandonPosX = _brandonPosY = -1; + + // Unlike the original we did restore Brandon's position in the scene screen on load. + // This appereantly caused graphics gliches in some scenes. For example bug #2835715 + // ("KYRA: GFX glitch in Amiga version at the bridge") is caused by this feature. + // Thus we disable that for now. + //_brandonPosX = brandonX; + //_brandonPosY = brandonY; + enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); _animator->animRefreshNPC(0); 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..8d4ea7e022 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; @@ -80,6 +79,7 @@ bool Screen::init() { _useOverlays = false; _useSJIS = false; _use16ColorMode = _vm->gameFlags().use16ColorMode; + _isAmiga = (_vm->gameFlags().platform == Common::kPlatformAmiga); if (_vm->gameFlags().useHiResOverlay) { _useOverlays = true; @@ -103,7 +103,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,8 +111,10 @@ bool Screen::init() { memset(_shapePages, 0, sizeof(_shapePages)); - const int paletteCount = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 12 : 4; - const int numColors = _use16ColorMode ? 16 : ((_vm->gameFlags().platform == Common::kPlatformAmiga) ? 32 : 256); + const int paletteCount = _isAmiga ? 13 : 4; + const int numColors = _use16ColorMode ? 16 : (_isAmiga ? 32 : 256); + + _interfacePaletteEnabled = false; _screenPalette = new Palette(numColors); assert(_screenPalette); @@ -205,6 +206,8 @@ void Screen::setResolution() { void Screen::updateScreen() { if (_useOverlays) updateDirtyRectsOvl(); + else if (_isAmiga && _interfacePaletteEnabled) + updateDirtyRectsAmiga(); else updateDirtyRects(); @@ -232,6 +235,77 @@ void Screen::updateDirtyRects() { _dirtyRects.clear(); } +void Screen::updateDirtyRectsAmiga() { + if (_forceFullUpdate) { + _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 { + const byte *page0 = getCPagePtr(0); + Common::List<Common::Rect>::iterator it; + + for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) { + if (it->bottom <= 136) { + _system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height()); + } else { + // Check whether the rectangle is part of both the screen and the interface + if (it->top < 136) { + // The rectangle covers both screen part and interface part + + const int screenHeight = 136 - it->top; + const int interfaceHeight = it->bottom - 136; + + const int width = it->width(); + const int lineAdd = SCREEN_W - width; + + // Copy the screen part verbatim + _system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, width, screenHeight); + + // Adjust the interface part + copyRegion(it->left, 136, 0, 0, width, interfaceHeight, 0, 8, Screen::CR_NO_P_CHECK); + + uint8 *dst = getPagePtr(8); + for (int y = 0; y < interfaceHeight; ++y) { + for (int x = 0; x < width; ++x) + *dst++ += 32; + dst += lineAdd; + } + + _system->copyRectToScreen(getCPagePtr(8), SCREEN_W, it->left, 136, width, interfaceHeight); + } else { + // The rectangle only covers the interface part + + const int width = it->width(); + const int height = it->height(); + const int lineAdd = SCREEN_W - width; + + copyRegion(it->left, it->top, 0, 0, width, height, 0, 8, Screen::CR_NO_P_CHECK); + + uint8 *dst = getPagePtr(8); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) + *dst++ += 32; + dst += lineAdd; + } + + _system->copyRectToScreen(getCPagePtr(8), SCREEN_W, it->left, it->top, width, height); + } + } + } + } + + _forceFullUpdate = false; + _dirtyRects.clear(); +} + void Screen::updateDirtyRectsOvl() { if (_forceFullUpdate) { const byte *src = getCPagePtr(0); @@ -591,7 +665,7 @@ void Screen::setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue) { } void Screen::getRealPalette(int num, uint8 *dst) { - const int colors = (_vm->gameFlags().platform == Common::kPlatformAmiga ? 32 : 256); + const int colors = _isAmiga ? 32 : 256; const uint8 *palData = getPalette(num).getData(); if (!palData) { @@ -622,6 +696,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 (!_isAmiga) + 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 +1057,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 (_isAmiga) + 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 +1130,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 +1184,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; + Font *fnt = _fonts[_currentFont]; + assert(fnt); - uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x; - - uint16 bitmapOffset = READ_LE_UINT16(fnt->fontData + fnt->charBitmapOffset + c * 2); - if (bitmapOffset == 0) - return; - - 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 +2091,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 +2826,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; @@ -2811,11 +2844,11 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette error("Unhandled bitmap compression %d", compType); } - if (_vm->gameFlags().platform == Common::kPlatformAmiga) { + if (_isAmiga) { if (!scumm_stricmp(ext, "MSC")) Screen::convertAmigaMsc(dstData); else - Screen::convertAmigaGfx(dstData, 320, 200, false); + Screen::convertAmigaGfx(dstData, 320, 200); } if (skip) @@ -2832,7 +2865,7 @@ bool Screen::loadPalette(const char *filename, Palette &pal) { debugC(3, kDebugLevelScreen, "Screen::loadPalette('%s', %p)", filename, (const void *)&pal); - if (_vm->gameFlags().platform == Common::kPlatformAmiga) + if (_isAmiga) pal.loadAmigaPalette(*stream, 0, stream->size() / Palette::kAmigaBytesPerColor); else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode) pal.loadPC98Palette(*stream, 0, stream->size() / Palette::kPC98BytesPerColor); @@ -2851,7 +2884,7 @@ bool Screen::loadPaletteTable(const char *filename, int firstPalette) { debugC(3, kDebugLevelScreen, "Screen::loadPaletteTable('%s', %d)", filename, firstPalette); - if (_vm->gameFlags().platform == Common::kPlatformAmiga) { + if (_isAmiga) { const int numColors = getPalette(firstPalette).getNumColors(); const int palSize = getPalette(firstPalette).getNumColors() * Palette::kAmigaBytesPerColor; const int numPals = stream->size() / palSize; @@ -2874,7 +2907,7 @@ bool Screen::loadPaletteTable(const char *filename, int firstPalette) { void Screen::loadPalette(const byte *data, Palette &pal, int bytes) { Common::MemoryReadStream stream(data, bytes, false); - if (_vm->gameFlags().platform == Common::kPlatformAmiga) + if (_isAmiga) pal.loadAmigaPalette(stream, 0, stream.size() / Palette::kAmigaBytesPerColor); else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode) pal.loadPC98Palette(stream, 0, stream.size() / Palette::kPC98BytesPerColor); @@ -3026,6 +3059,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 +3306,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 +3318,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..73a29ee2c7 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,11 @@ public: void setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue); virtual void setScreenPalette(const Palette &pal); + // AMIGA version only + bool isInterfacePaletteEnabled() const { return _interfacePaletteEnabled; } + 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,12 +446,13 @@ 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: uint8 *getPagePtr(int pageNum); void updateDirtyRects(); + void updateDirtyRectsAmiga(); void updateDirtyRectsOvl(); void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h); @@ -374,6 +479,7 @@ protected: bool _useOverlays; bool _useSJIS; bool _use16ColorMode; + bool _isAmiga; Graphics::FontSJIS *_sjisFont; uint8 _sjisInvisibleColor; @@ -382,7 +488,7 @@ protected: Common::Array<Palette *> _palettes; Palette *_internFadePalette; - Font _fonts[FID_NUM]; + Font *_fonts[FID_NUM]; uint8 _textColorsMap[16]; uint8 *_decodeShapeBuffer; @@ -469,6 +575,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..ed7bef0178 100644 --- a/engines/kyra/screen_lok.cpp +++ b/engines/kyra/screen_lok.cpp @@ -80,6 +80,9 @@ const ScreenDim *Screen_LoK::getScreenDim(int dim) { } void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { + if (_vm->gameFlags().platform == Common::kPlatformAmiga) + return; + assert(_vm->palTable1()[palIndex]); Palette tempPal(getPalette(0).getNumColors()); @@ -240,6 +243,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..a778a2066b 100644 --- a/engines/kyra/script_lok.cpp +++ b/engines/kyra/script_lok.cpp @@ -231,12 +231,13 @@ 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)); + _screen->getPalette(0).copy(_screen->getPalette(4), 12, 1); + _screen->fadePalette(_screen->getPalette(0), 2); } } 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 +580,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; } @@ -1081,7 +1092,9 @@ int KyraEngine_LoK::o1_specialEventDisplayBrynnsNote(EMCState *script) { _screen->copyRegion(63, 8, 63, 8, 194, 128, 2, 0); _screen->updateScreen(); _screen->showMouse(); - _screen->setFont(Screen::FID_6_FNT); + + if (_flags.platform != Common::kPlatformAmiga && !_flags.isTalkie) + _screen->setFont(Screen::FID_6_FNT); return 0; } @@ -1092,7 +1105,9 @@ int KyraEngine_LoK::o1_specialEventRemoveBrynnsNote(EMCState *script) { _screen->loadPageFromDisk("HIDPAGE.TMP", 2); _screen->updateScreen(); _screen->showMouse(); - _screen->setFont(Screen::FID_8_FNT); + + if (_flags.platform != Common::kPlatformAmiga && !_flags.isTalkie) + _screen->setFont(Screen::FID_8_FNT); return 0; } @@ -1213,37 +1228,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 +1310,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 +1332,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 +1344,8 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) { } _screen->showMouse(); } + + delete amulet; setGameFlag(0x2D); return 0; } @@ -1335,7 +1394,7 @@ int KyraEngine_LoK::o1_waitForConfirmationMouseClick(EMCState *script) { updateInput(); - int input = checkInput(_buttonList, false) & 0xFF; + int input = checkInput(0, false) & 0xFF; removeInputTop(); if (input == 200) break; diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index aeac4ce9df..4086d06c00 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 b5ae7a50ec..206f8f0a87 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -555,7 +555,9 @@ void KyraEngine_LoK::seq_winterScroll1() { _animator->sprites()[0].active = 0; _sprites->_anims[1].play = true; _animator->sprites()[1].active = 1; - setGameFlag(0xA2); + + if (_flags.platform != Common::kPlatformAmiga) + setGameFlag(0xA2); } for (int i = midpoint; i < 123 + numFrames; ++i) { @@ -569,10 +571,15 @@ void KyraEngine_LoK::seq_winterScroll1() { _sprites->_anims[i].play = false; _animator->sprites()[i].active = 0; } - _screen->getPalette(0).copy(palTable2()[0], 0, 20, 228); - _screen->fadePalette(_screen->getPalette(0), 72); - _screen->setScreenPalette(_screen->getPalette(0)); - setGameFlag(0xB3); + + if (_flags.platform == Common::kPlatformAmiga) { + _screen->copyPalette(0, 11); + } else { + _screen->getPalette(0).copy(palTable2()[0], 0, 20, 228); + _screen->fadePalette(_screen->getPalette(0), 72); + _screen->setScreenPalette(_screen->getPalette(0)); + setGameFlag(0xB3); + } } else { delayWithTicks(120); } @@ -673,7 +680,7 @@ void KyraEngine_LoK::seq_makeBrandonNormal2() { _animator->animRefreshNPC(0); delayWithTicks(8); } - _animator->setBrandonAnimSeqSize(4, 48); + _animator->setBrandonAnimSeqSize(3, 48); _currentCharacter->currentAnimFrame = 7; _animator->animRefreshNPC(0); @@ -718,10 +725,16 @@ void KyraEngine_LoK::seq_makeBrandonWisp() { _animator->animRefreshNPC(0); _animator->updateAllObjectShapes(); - if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) - _screen->fadeSpecialPalette(30, 234, 13, 4); - else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) - _screen->fadeSpecialPalette(14, 228, 15, 4); + if (_flags.platform == Common::kPlatformAmiga) { + if ((_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) || + (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186)) + _screen->fadePalette(_screen->getPalette(10), 0x54); + } else { + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) + _screen->fadeSpecialPalette(30, 234, 13, 4); + else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) + _screen->fadeSpecialPalette(14, 228, 15, 4); + } freeShapes123(); _screen->showMouse(); @@ -770,6 +783,7 @@ void KyraEngine_LoK::seq_dispelMagicAnimation() { void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) { int newItem = -1; + static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C }; static const uint8 flaskTable2[] = { 0x47, 0x49, 0x4B, 0x4D }; @@ -791,63 +805,135 @@ void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) { setMouseItem(newItem); _screen->showMouse(); _itemInHand = newItem; + assert(_fullFlask); assert(type < _fullFlask_Size && type >= 0); + static const uint16 voiceEntries[] = { 0x1F40, 0x1F41, 0x1F42, 0x1F45 }; assert(type < ARRAYSIZE(voiceEntries)); + characterSays(voiceEntries[type], _fullFlask[type], 0, -2); } void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) { - uint8 red, green, blue; + if (_flags.platform == Common::kPlatformAmiga) { + uint8 r, g, b; + + switch (item) { + case 60: case 61: + // 0xC22 + r = 50; + g = 8; + b = 8; + break; - switch (item) { - case 60: - case 61: - red = 63; - green = blue = 6; - break; - case 62: - case 63: - red = green = 0; - blue = 67; - break; - case 64: - case 65: - red = 84; - green = 78; - blue = 14; - break; - case 66: - red = blue = 0; - green = 48; - break; - case 67: - red = 100; - green = 48; - blue = 23; - break; - case 68: - red = 73; - green = 0; - blue = 89; - break; - case 69: - red = green = 73; - blue = 86; - break; - default: - red = 33; - green = 66; - blue = 100; - } - red = (uint8)((double)red * 0.63); - green = (uint8)((double)green * 0.63); - blue = (uint8)((double)blue * 0.63); + case 62: case 63: case 76: + case 77: + // 0x00E + r = 0; + g = 0; + b = 58; + break; + + case 64: case 65: + // 0xFF5 + r = 63; + g = 63; + b = 21; + break; + + case 66: + // 0x090 + r = 0; + g = 37; + b = 0; + break; + + case 67: + // 0xC61 + r = 50; + g = 25; + b = 4; + break; + + case 68: + // 0xE2E + r = 58; + g = 8; + b = 58; + break; + + case 69: + // 0xBBB + r = 46; + g = 46; + b = 46; + break; + + default: + // 0xFFF + r = 63; + g = 63; + b = 63; + } + + _screen->setPaletteIndex(16, r, g, b); + } else { + uint8 red, green, blue; + + switch (item) { + case 60: case 61: + red = 63; + green = blue = 6; + break; + + case 62: case 63: + red = green = 0; + blue = 67; + break; + + case 64: case 65: + red = 84; + green = 78; + blue = 14; + break; + + case 66: + red = blue = 0; + green = 48; + break; + + case 67: + red = 100; + green = 48; + blue = 23; + break; + + case 68: + red = 73; + green = 0; + blue = 89; + break; - _screen->setPaletteIndex(0xFE, red, green, blue); + case 69: + red = green = 73; + blue = 86; + break; + + default: + red = 33; + green = 66; + blue = 100; + } + + red = red * 0x3F / 100; + green = green * 0x3F / 100; + blue = blue * 0x3F / 100; + + _screen->setPaletteIndex(0xFE, red, green, blue); + } _screen->hideMouse(); checkAmuletAnimFlags(); @@ -862,7 +948,9 @@ void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) { _animator->animRefreshNPC(0); delayWithTicks(5); } + snd_playSoundEffect(0x34); + for (int i = 0; i < 2; ++i) { _currentCharacter->currentAnimFrame = 130; _animator->animRefreshNPC(0); @@ -886,7 +974,10 @@ void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) { _currentCharacter->currentAnimFrame = 7; _animator->animRefreshNPC(0); freeShapes123(); - _screen->setPaletteIndex(0xFE, 30, 30, 30); + + if (_flags.platform != Common::kPlatformAmiga) + _screen->setPaletteIndex(0xFE, 30, 30, 30); + _screen->showMouse(); } @@ -901,20 +992,25 @@ 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); + _screen->_curPage = 0; _beadStateVar = 0; _malcolmFlag = 0; _unkEndSeqVar2 = _system->getMillis() + 600 * _tickLength; + _screen->copyRegion(312, 0, 312, 0, 8, 136, 0, 2); } @@ -943,17 +1039,25 @@ int KyraEngine_LoK::seq_playEnd() { _endSequenceSkipFlag = 1; if (_text->printed()) _text->restoreTalkTextMessageBkgd(2, 0); + _screen->_curPage = 0; _screen->hideMouse(); - _screen->fadeSpecialPalette(32, 228, 20, 60); + + if (_flags.platform != Common::kPlatformAmiga) + _screen->fadeSpecialPalette(32, 228, 20, 60); + delay(60 * _tickLength); + _screen->loadBitmap("GEMHEAL.CPS", 3, 3, &_screen->getPalette(0)); _screen->setScreenPalette(_screen->getPalette(0)); _screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0); + uint32 nextTime = _system->getMillis() + 120 * _tickLength; - _finalA = new WSAMovie_v1(this); + + _finalA = createWSAMovie(); assert(_finalA); _finalA->open("finald.wsa", 1, 0); + delayUntil(nextTime); snd_playSoundEffect(0x40); for (int i = 0; i < 22; ++i) { @@ -967,6 +1071,7 @@ int KyraEngine_LoK::seq_playEnd() { _screen->updateScreen(); } delete _finalA; + _finalA = 0; seq_playEnding(); return 1; @@ -985,11 +1090,13 @@ void KyraEngine_LoK::seq_brandonToStone() { assert(_brandonStoneTable); setupShapes123(_brandonStoneTable, 14, 0); _animator->setBrandonAnimSeqSize(5, 51); + for (int i = 123; i <= 136; ++i) { _currentCharacter->currentAnimFrame = i; _animator->animRefreshNPC(0); delayWithTicks(8); } + _animator->resetBrandonAnimSeqSize(); freeShapes123(); _screen->showMouse(); @@ -1001,8 +1108,17 @@ void KyraEngine_LoK::seq_playEnding() { _screen->hideMouse(); _screen->_curPage = 0; _screen->fadeToBlack(); - _screen->loadBitmap("REUNION.CPS", 3, 3, &_screen->getPalette(0)); - _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + + if (_flags.platform == Common::kPlatformAmiga) { + _screen->loadBitmap("GEMCUT.CPS", 3, 3, &_screen->getPalette(0)); + _screen->copyRegion(232, 136, 176, 56, 56, 56, 2, 2); + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK); + } else { + _screen->loadBitmap("REUNION.CPS", 3, 3, &_screen->getPalette(0)); + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + } + _screen->_curPage = 0; // XXX assert(_homeString); @@ -1035,8 +1151,10 @@ void KyraEngine_LoK::seq_playCredits() { memset(strings, 0, sizeof(strings)); + _screen->enableInterfacePalette(false); + _screen->hideMouse(); - if (!_flags.isTalkie) { + if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga) { _screen->loadFont(Screen::FID_CRED6_FNT, "CREDIT6.FNT"); _screen->loadFont(Screen::FID_CRED8_FNT, "CREDIT8.FNT"); } else @@ -1056,7 +1174,8 @@ void KyraEngine_LoK::seq_playCredits() { uint8 *buffer = 0; uint32 size = 0; - if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) { + if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98 + || _flags.platform == Common::kPlatformAmiga) { int sizeTmp = 0; const uint8 *bufferTmp = _staticres->loadRawData(k1CreditsStrings, sizeTmp); buffer = new uint8[sizeTmp]; @@ -1094,12 +1213,12 @@ void KyraEngine_LoK::seq_playCredits() { if (*currentString == 1) { currentString++; - if (!_flags.isTalkie) + if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga) _screen->setFont(Screen::FID_CRED6_FNT); } else { if (*currentString == 2) currentString++; - if (!_flags.isTalkie) + if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga) _screen->setFont(Screen::FID_CRED8_FNT); } strings[i].font = _screen->_currentFont; @@ -1122,6 +1241,9 @@ void KyraEngine_LoK::seq_playCredits() { _screen->getPalette(2).clear(); _screen->setScreenPalette(_screen->getPalette(2)); + if (_flags.platform == Common::kPlatformAmiga) + _screen->setPaletteIndex(16, 63, 63, 63); + _screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 0, Screen::CR_NO_P_CHECK); _screen->fadePalette(_screen->getPalette(0), 0x5A); @@ -1473,7 +1595,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 +1785,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 +1804,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/sound_amiga.cpp b/engines/kyra/sound_amiga.cpp index 3d552fda0e..6c4c2b19a5 100644 --- a/engines/kyra/sound_amiga.cpp +++ b/engines/kyra/sound_amiga.cpp @@ -156,8 +156,8 @@ void SoundAmiga::playTrack(uint8 track) { case kFileGame: if (track >= 11 && track < ARRAYSIZE(tempoIngame) + 11) { score = track - 11; - loop = loopIngame[track] != 0; - tempo = tempoIngame[track]; + loop = loopIngame[score] != 0; + tempo = tempoIngame[score]; } break; diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp index f644feeb65..9877ceebc4 100644 --- a/engines/kyra/sprites_lol.cpp +++ b/engines/kyra/sprites_lol.cpp @@ -496,9 +496,8 @@ int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int _monsterCurBlock = block; if (testWallFlag(block, -1, wallFlag)) return 1; - } - - _monsterCurBlock = 0; + _monsterCurBlock = 0; + } if (!(testFlag & 2)) return 0; @@ -1372,12 +1371,12 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) { static const int8 walkMonsterTable1[] = { 7, -6, 5, -4, 3, -2, 1, 0 }; static const int8 walkMonsterTable2[] = { -7, 6, -5, 4, -3, 2, -1, 0 }; - if (++_monsterCountUnk > 10) { - _monsterCountUnk = 0; - _monsterShiftAlt ^= 1; + if (++_monsterStepCounter > 10) { + _monsterStepCounter = 0; + _monsterStepMode ^= 1; } - const int8 *tbl = _monsterShiftAlt ? walkMonsterTable2 : walkMonsterTable1; + const int8 *tbl = _monsterStepMode ? walkMonsterTable2 : walkMonsterTable1; int sx = monster->x; int sy = monster->y; @@ -1411,8 +1410,10 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) { uint8 w = _levelBlockProperties[_monsterCurBlock].walls[(s >> 1) ^ 2]; if (_wllWallFlags[w] & 0x20) { - if (_wllBuffer3[w] == 5) + if (_wllBuffer3[w] == 5) { openCloseDoor(_monsterCurBlock, 1); + return -1; + } } if (_wllWallFlags[w] & 8) @@ -1423,10 +1424,10 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) { } int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) { - int8 b1x = block1 & 0x1f; - int8 b1y = block1 >> 5; - int8 b2x = block2 & 0x1f; - int8 b2y = block2 >> 5; + int b1x = block1 & 0x1f; + int b1y = block1 >> 5; + int b2x = block2 & 0x1f; + int b2y = block2 >> 5; uint8 dy = ABS(b2y - b1y); uint8 dx = ABS(b2x - b1x); @@ -1434,7 +1435,7 @@ int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) { if (dx > dy) SWAP(dx, dy); - return (dx << 1) + dy; + return (dx >> 1) + dy; } int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction, int distance, uint16 curBlock) { @@ -1444,7 +1445,7 @@ int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction return 5; int dir = calcMonsterDirection(monsterBlock & 0x1f, monsterBlock >> 5, curBlock & 0x1f, curBlock >> 5); - if ((dir & 1) || (dir != direction << 1)) + if ((dir & 1) || (dir != (direction << 1))) return 5; if (((monsterBlock & 0x1f) != (curBlock & 0x1f)) && ((monsterBlock & 0xffe0) != (curBlock & 0xffe0))) diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index c7bef26d61..83f4b22b6d 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -44,7 +44,7 @@ namespace Kyra { -#define RESFILE_VERSION 48 +#define RESFILE_VERSION 49 namespace { bool checkKyraDat(Common::SeekableReadStream *file) { @@ -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..20094a45ab 100644 --- a/engines/kyra/text.cpp +++ b/engines/kyra/text.cpp @@ -179,7 +179,7 @@ void TextDisplayer::calcWidestLineBounds(int &x1, int &x2, int w, int cx) { void TextDisplayer::restoreTalkTextMessageBkgd(int srcPage, int dstPage) { if (_talkMessagePrinted) { _talkMessagePrinted = false; - _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage); + _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage, Screen::CR_NO_P_CHECK); } } @@ -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..6a275a9adb 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -402,12 +402,6 @@ List *lookup_list(EngineState *s, reg_t addr); #define _K_SOUND_STATUS_PLAYING 3 - -/* Kernel optimization flags */ -#define KERNEL_OPT_FLAG_GOT_EVENT (1<<0) -#define KERNEL_OPT_FLAG_GOT_2NDEVENT (1<<1) - - /******************** Kernel functions ********************/ // New kernel functions @@ -540,6 +534,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/kevent.cpp b/engines/sci/engine/kevent.cpp index c4b3f5d71a..5ac09e6c76 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -42,12 +42,6 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { int oldx, oldy; int modifier_mask = s->_version <= SCI_VERSION_0 ? SCI_EVM_ALL : SCI_EVM_NO_FOOLOCK; - if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_2NDEVENT) { - // Penalty time- too many requests to this function without waiting! - int delay = s->script_000->locals_block->_locals[SCI_VARIABLE_GAME_SPEED].offset; - gfxop_sleep(s->gfx_state, delay * 1000 / 60); - } - // If there's a simkey pending, and the game wants a keyboard event, use the // simkey instead of a normal event if (g_debug_simulated_key && (mask & SCI_EVT_KEYBOARD)) { @@ -71,15 +65,6 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { //gfxop_set_pointer_position(s->gfx_state, Common::Point(s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y)); - if (e.type) - s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT); - else { - if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_EVENT) - s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_2NDEVENT; - else - s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_EVENT; - } - switch (e.type) { case SCI_EVT_QUIT: quit_vm(); diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index c7086ddef7..915b07e8a3 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -664,12 +664,13 @@ reg_t kWait(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->r_acc = make_reg(0, ((long)time - (long)s->last_wait_time) * 60 / 1000); s->last_wait_time = time; - // Reset optimization flags: Game is playing along nicely anyway - s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT); - sleep_time *= g_debug_sleeptime_factor; GFX_ASSERT(gfxop_sleep(s->gfx_state, sleep_time * 1000 / 60)); + // Reset speed throttler: Game is playing along nicely anyway + if (sleep_time > 0) + s->speedThrottler->reset(); + return s->r_acc; } 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/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 11dd56f2aa..0341ecb73d 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -311,13 +311,15 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod void script_debug(EngineState *s, bool bp) { // Do we support a separate console? - /* if (sci_debug_flags & _DEBUG_FLAG_LOGGING) { */ +#if 0 + if (sci_debug_flags & _DEBUG_FLAG_LOGGING) { printf("%d: acc=%04x:%04x ", script_step_counter, PRINT_REG(s->r_acc)); disassemble(s, scriptState.xs->addr.pc, 0, 1); if (scriptState.seeking == kDebugSeekGlobal) printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial, scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial])); - /* } */ + } +#endif #if 0 if (!scriptState.debugging) diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 38320c29cc..f0e9863068 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -114,9 +114,12 @@ EngineState::EngineState(ResourceManager *res, sci_version_t version, uint32 fla gc_countdown = 0; successor = 0; + + speedThrottler = new SpeedThrottler(version); } EngineState::~EngineState() { + delete speedThrottler; } uint16 EngineState::currentRoomNumber() const { @@ -172,15 +175,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..a814a20df8 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -119,12 +119,53 @@ public: bool isOpen() const; }; + +class SpeedThrottler { +public: + enum { + kSegmentLength = 20 /**< Time segment length in ms */ + }; + + SpeedThrottler(sci_version_t version) { + if (version >= SCI_VERSION_1_1) + _maxInstructions = 3300; + else if (version >= SCI_VERSION_1) + _maxInstructions = 2200; + else + _maxInstructions = 1100; + reset(); + } + + void postInstruction() { + if (++_curInstructions >= _maxInstructions) { + uint32 time = g_system->getMillis(); + uint32 elapsed = time - _timestamp; + + if (elapsed < kSegmentLength) + g_system->delayMillis(kSegmentLength - elapsed); + + reset(); + } + } + + void reset() { + _timestamp = g_system->getMillis(); + _curInstructions = 0; + } + +private: + uint32 _timestamp; /**< Timestamp of current time segment */ + uint32 _maxInstructions; /**< Maximum amount of instructions per time segment */ + uint32 _curInstructions; /**< Amount of instructions executed in current time segment */ +}; + struct EngineState : public Common::Serializable { public: EngineState(ResourceManager *res, sci_version_t version, uint32 flags); virtual ~EngineState(); virtual void saveLoadWithSerializer(Common::Serializer &ser); + kLanguage getLanguage(); public: int widget_serial_counter; /**< Used for savegames */ @@ -257,6 +298,8 @@ public: MessageState _msgState; + SpeedThrottler *speedThrottler; + EngineState *successor; /**< Successor of this state: Used for restoring */ private: diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 0f8fee0876..ae07c314d4 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; @@ -1424,6 +1424,8 @@ void run_vm(EngineState *s, int restoring) { } //#endif ++script_step_counter; + + s->speedThrottler->postInstruction(); } } 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/gfx.cpp b/engines/scumm/gfx.cpp index 18cba0ab4a..fa5d2011b0 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -671,6 +671,16 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i width -= 16; if (width <= 0) return; + + // HACK: In this way we won't get a screen with dirty side strips when + // loading a narrow room in a full screen room. + if (width == 224 && height == 240 && x == 16) { + char blackbuf[16 * 240]; + memset(blackbuf, 0, 16 * 240); // Prepare a buffer 16px wide and 240px high, to fit on a lateral strip + + width = 240; // Fix right strip + _system->copyRectToScreen((const byte *)blackbuf, 16, 0, 0, 16, 240); // Fix left strip + } } } 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 d1676772a8..07e2ce8bca 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/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 3cf64809fc..1d9062f323 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); } @@ -1260,6 +1318,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 c2b6db7119..cab5f9fd41 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; 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/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' /> diff --git a/sound/adpcm.cpp b/sound/adpcm.cpp index 37b14140b7..5cf1171fcb 100644 --- a/sound/adpcm.cpp +++ b/sound/adpcm.cpp @@ -302,11 +302,13 @@ int ADPCMInputStream::readBufferMS(int channels, int16 *buffer, const int numSam for (i = 0; i < channels; i++) _status.ch[i].sample1 = _stream->readSint16LE(); - for (i = 0; i < channels; i++) - buffer[samples++] = _status.ch[i].sample2 = _stream->readSint16LE(); + for (i = 0; i < channels; i++) { + _status.ch[i].sample2 = _stream->readSint16LE(); + buffer[samples++] = TO_LE_16(_status.ch[i].sample2); + } for (i = 0; i < channels; i++) - buffer[samples++] = _status.ch[i].sample1; + buffer[samples++] = TO_LE_16(_status.ch[i].sample1); _blockPos = channels * 7; } diff --git a/tools/create_kyradat/amiga.h b/tools/create_kyradat/amiga.h index 26fcddf614..3b3aa2d5a5 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 }, @@ -39,8 +39,8 @@ const ExtractEntry kyra1AmigaEng[] = { { kBranStoneShapes, 0x00039C32, 0x00039CA0 }, { kWispJewelStrings, 0x00004A54, 0x00004AAA }, { kMagicJewelStrings, 0x00004AAA, 0x00004ABE }, - { kFlaskFullString, 0x00017B04, 0x00017B9E }, - { kFullFlaskString, 0x00017B9E, 0x00017BBA }, + { kFlaskFullString, 0x00017B9E, 0x00017BBA }, + { kFullFlaskString, 0x00017B04, 0x00017B9E }, { kOutroReunionSeq, 0x00030A4A, 0x00030F94 }, { kOutroHomeString, 0x0000C6FA, 0x0000C6FF }, { kVeryCleverString, 0x0000B322, 0x0000B354 }, diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp index ead0c232b1..780282bab2 100644 --- a/tools/create_kyradat/create_kyradat.cpp +++ b/tools/create_kyradat/create_kyradat.cpp @@ -31,7 +31,7 @@ #include "md5.h" enum { - kKyraDatVersion = 48, + kKyraDatVersion = 49, kIndexSize = 12 }; @@ -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] && !(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] && !(i & 1)) { + 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 |