From 5af782c5d279b0b3b54ee041bb50c8fec2d35fd3 Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Tue, 5 Oct 2010 19:04:52 +0000 Subject: SCUMM/FM-TOWNS: disable new graphics code in DS port svn-id: r53033 --- engines/scumm/actor.cpp | 2 + engines/scumm/charset.cpp | 46 +++++- engines/scumm/charset.h | 3 + engines/scumm/cursor.cpp | 2 + engines/scumm/gfx.cpp | 67 ++++++-- engines/scumm/gfx.h | 3 +- engines/scumm/gfx_towns.cpp | 4 + engines/scumm/palette.cpp | 12 ++ engines/scumm/player_towns.cpp | 345 +++++++++++++++++++++-------------------- engines/scumm/player_towns.h | 77 +++++---- engines/scumm/room.cpp | 2 + engines/scumm/saveload.cpp | 2 + engines/scumm/script_v4.cpp | 2 + engines/scumm/script_v5.cpp | 2 + engines/scumm/scumm.cpp | 34 +++- engines/scumm/scumm.h | 17 +- engines/scumm/string.cpp | 6 + engines/scumm/verbs.cpp | 6 +- 18 files changed, 409 insertions(+), 223 deletions(-) (limited to 'engines/scumm') diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 7c1f401e67..1bcb065b25 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -2159,9 +2159,11 @@ void ScummEngine::stopTalk() { ((ScummEngine_v7 *)this)->clearSubtitleQueue(); #endif } else { +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) towns_restoreCharsetBg(); else +#endif restoreCharsetBg(); } } diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp index 38b85f6fbd..6bf6238386 100644 --- a/engines/scumm/charset.cpp +++ b/engines/scumm/charset.cpp @@ -52,6 +52,9 @@ void ScummEngine::loadCJKFont() { _newLineCharacter = 0; if (_game.version <= 5 && _game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN) { // FM-TOWNS v3 / v5 Kanji +#ifdef DISABLE_TOWNS_DUAL_LAYER_MODE + error("FM-Towns Kanji font drawing requires dual graphics layer support which is disabled in this build"); +#endif int numChar = 256 * 32; _2byteWidth = 16; _2byteHeight = 16; @@ -655,11 +658,13 @@ void CharsetRendererV3::setColor(byte color) { } else useShadow = false; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_vm->_game.platform == Common::kPlatformFMTowns) { _color = (_color & 0x0f) | ((_color & 0x0f) << 4); if (_color == 0) _color = 0x88; } +#endif enableShadow(useShadow); @@ -678,7 +683,12 @@ void CharsetRendererPCE::setColor(byte color) { void CharsetRendererCommon::enableShadow(bool enable) { if (enable) { if (_vm->_game.platform == Common::kPlatformFMTowns) { - _shadowColor = _vm->_game.version == 5 ? _vm->_townsCharsetColorMap[0] : 0x88; + _shadowColor = +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + _vm->_game.version == 5 ? _vm->_townsCharsetColorMap[0] : 0x88; +#else + 8; +#endif _shadowMode = kFMTOWNSShadowMode; } else { _shadowColor = 0; @@ -750,7 +760,11 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { _textScreenID = vs->number; } - if ((_vm->_game.platform != Common::kPlatformFMTowns || (_vm->_game.id == GID_LOOM && !is2byte)) && (ignoreCharsetMask || !vs->hasTwoBuffers)) { + if ( +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + (_vm->_game.platform != Common::kPlatformFMTowns || (_vm->_game.id == GID_LOOM && !is2byte)) && +#endif + (ignoreCharsetMask || !vs->hasTwoBuffers)) { dst = vs->getPixels(_left, drawTop); drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->bytesPerPixel); } else { @@ -807,6 +821,7 @@ void CharsetRenderer::translateColor() { } } +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE void CharsetRenderer::processTownsCharsetColors(uint8 bytesPerPixel) { if (_vm->_game.platform == Common::kPlatformFMTowns) { for (int i = 0; i < (1 << bytesPerPixel); i++) { @@ -827,6 +842,7 @@ void CharsetRenderer::processTownsCharsetColors(uint8 bytesPerPixel) { } } } +#endif void CharsetRenderer::saveLoadWithSerializer(Serializer *ser) { static const SaveLoadEntry charsetRendererEntries[] = { @@ -863,7 +879,9 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { _vm->_charsetColorMap[1] = _color; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE processTownsCharsetColors(_bytesPerPixel); +#endif if (is2byte) { enableShadow(true); @@ -936,7 +954,11 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { // This check for kPlatformFMTowns and kMainVirtScreen is at least required for the chat with // the navigator's head in front of the ghost ship in Monkey Island 1 - if (!ignoreCharsetMask || (_vm->_game.platform == Common::kPlatformFMTowns && vs->number == kMainVirtScreen)) { + if (!ignoreCharsetMask +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + || (_vm->_game.platform == Common::kPlatformFMTowns && vs->number == kMainVirtScreen) +#endif + ) { _hasMask = true; _textScreenID = vs->number; } @@ -992,7 +1014,11 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, } else { Graphics::Surface dstSurface; Graphics::Surface backSurface; - if (_vm->_game.platform != Common::kPlatformFMTowns && (ignoreCharsetMask || !vs->hasTwoBuffers) && !(_vm->_useCJKMode && _vm->_textSurfaceMultiplier == 2)) { + if ( +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + _vm->_game.platform != Common::kPlatformFMTowns && +#endif + (ignoreCharsetMask || !vs->hasTwoBuffers) && !(_vm->_useCJKMode && _vm->_textSurfaceMultiplier == 2)) { dstSurface = *vs; dstPtr = vs->getPixels(_left, drawTop); } else { @@ -1095,7 +1121,11 @@ void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, co assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8); bits = *src++; numbits = 8; - byte *cmap = (_vm->_game.platform == Common::kPlatformFMTowns) ? _vm->_townsCharsetColorMap : _vm->_charsetColorMap; + byte *cmap = +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + (_vm->_game.platform == Common::kPlatformFMTowns) ? _vm->_townsCharsetColorMap : +#endif + _vm->_charsetColorMap; for (y = 0; y < height && y + drawTop < s.h; y++) { for (x = 0; x < width; x++) { @@ -1119,7 +1149,11 @@ void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, co void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth) { int y, x; byte bits = 0; - uint8 col = (_vm->_game.platform == Common::kPlatformFMTowns && _vm->_game.version == 5) ? _vm->_townsCharsetColorMap[1] : _color; + uint8 col = +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + (_vm->_game.platform == Common::kPlatformFMTowns && _vm->_game.version == 5) ? _vm->_townsCharsetColorMap[1] : +#endif + _color; for (y = 0; y < height && y + drawTop < s.h; y++) { for (x = 0; x < width; x++) { diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h index e072f3ed5f..b925f7fa7a 100644 --- a/engines/scumm/charset.h +++ b/engines/scumm/charset.h @@ -79,7 +79,10 @@ public: int getStringWidth(int a, const byte *str); void addLinebreaks(int a, byte *str, int pos, int maxwidth); void translateColor(); + +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE void processTownsCharsetColors(uint8 bytesPerPixel); +#endif virtual void setCurID(int32 id) = 0; int getCurID() { return _curId; } diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp index 3ea6891f05..ec10407f9a 100644 --- a/engines/scumm/cursor.cpp +++ b/engines/scumm/cursor.cpp @@ -559,9 +559,11 @@ void ScummEngine_v5::setBuiltinCursor(int idx) { byte r, g, b; colorPCEToRGB(default_pce_cursor_colors[idx], &r, &g, &b); color = get16BitColor(r, g, b); +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE } else if (_game.platform == Common::kPlatformFMTowns) { byte *palEntry = &_textPalette[default_cursor_colors[idx] * 3]; color = get16BitColor(palEntry[0], palEntry[1], palEntry[2]); +#endif } else { color = _16BitPalette[default_cursor_colors[idx]]; } diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index a3977a9fee..e7c81bd418 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -322,6 +322,7 @@ void ScummEngine::initScreens(int b, int h) { _res->nukeResource(rtBuffer, i + 5); } +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) { if (!_townsClearLayerFlag && (h - b != _virtscr[kMainVirtScreen].h)) _townsScreen->clearLayer(0); @@ -331,6 +332,7 @@ void ScummEngine::initScreens(int b, int h) { _townsScreen->clearLayer(1); } } +#endif if (!getResourceAddress(rtBuffer, 4)) { // Since the size of screen 3 is fixed, there is no need to reallocate @@ -643,10 +645,13 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i #ifdef USE_ARM_GFX_ASM asmDrawStripToScreen(height, width, text, src, _compositeBuf, vs->pitch, width, _textSurface.pitch); #else +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { towns_drawStripToScreen(vs, x, y, x, top, width, height); return; - } else if (_bytesPerPixelOutput == 2) { + } else +#endif + if (_bytesPerPixelOutput == 2) { const byte *srcPtr = (const byte *)src; const byte *textPtr = (byte *)_textSurface.getBasePtr(x * m, y * m); byte *dstPtr = _compositeBuf; @@ -1009,8 +1014,10 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) { if (rect.left > vs->w) return; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns && _game.id == GID_MONKEY && vs->number == kVerbVirtScreen && rect.bottom <= 154) rect.right = 320; +#endif // Convert 'rect' to local (virtual screen) coordinates rect.top -= vs->topline; @@ -1031,20 +1038,25 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) { if (vs->hasTwoBuffers && _currentRoom != 0 && isLightOn()) { blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height, vs->bytesPerPixel); if (vs->number == kMainVirtScreen && _charset->_hasMask) { +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { byte *mask = (byte *)_textSurface.getBasePtr(rect.left * _textSurfaceMultiplier, (rect.top + vs->topline) * _textSurfaceMultiplier); fill(mask, _textSurface.pitch, 0, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); - } else { + } else +#endif + { byte *mask = (byte *)_textSurface.getBasePtr(rect.left, rect.top - _screenTop); fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); } } } else { +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { backColor |= (backColor << 4); byte *mask = (byte *)_textSurface.getBasePtr(rect.left * _textSurfaceMultiplier, (rect.top + vs->topline) * _textSurfaceMultiplier); fill(mask, _textSurface.pitch, backColor, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); } +#endif if (_game.features & GF_16BIT_COLOR) fill(screenBuf, vs->pitch, _16BitPalette[backColor], width, height, vs->bytesPerPixel); @@ -1097,10 +1109,16 @@ void ScummEngine::clearCharsetMask() { } void ScummEngine::clearTextSurface() { +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) _townsScreen->fillLayerRect(1, 0, 0, _textSurface.w, _textSurface.h, 0); +#endif - fill((byte*)_textSurface.pixels, _textSurface.pitch, _game.platform == Common::kPlatformFMTowns ? 0 : CHARSET_MASK_TRANSPARENCY, _textSurface.w, _textSurface.h, _textSurface.bytesPerPixel); + fill((byte*)_textSurface.pixels, _textSurface.pitch, +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + _game.platform == Common::kPlatformFMTowns ? 0 : +#endif + CHARSET_MASK_TRANSPARENCY, _textSurface.w, _textSurface.h, _textSurface.bytesPerPixel); } byte *ScummEngine::getMaskBuffer(int x, int y, int z) { @@ -1258,13 +1276,20 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) { // is definitely not capable of passing a parameter of -1 (color range is 0 - 255). // Just to make sure I don't break anything I restrict the code change to FM-Towns // version 5 games where this change is necessary to fix certain long standing bugs. - if (color == -1 || (color >= 254 && _game.platform == Common::kPlatformFMTowns && (_game.id == GID_MONKEY2 || _game.id == GID_INDY4))) { + if (color == -1 +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + || (color >= 254 && _game.platform == Common::kPlatformFMTowns && (_game.id == GID_MONKEY2 || _game.id == GID_INDY4)) +#endif + ) { +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { if (color == 254) { color = color; towns_setupPalCycleField(x, y, x2, y2); } - } else { + } else +#endif + { if (vs->number != kMainVirtScreen) error("can only copy bg to main window"); @@ -1306,6 +1331,7 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) { if (_game.features & GF_16BIT_COLOR) { fill(backbuff, vs->pitch, _16BitPalette[color], width, height, vs->bytesPerPixel); } else { +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { color = ((color & 0x0f) << 4) | (color & 0x0f); byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop + vs->topline) * _textSurfaceMultiplier); @@ -1314,6 +1340,7 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) { if (_game.id == GID_MONKEY2 || _game.id == GID_INDY4 || ((_game.id == GID_INDY3 || _game.id == GID_ZAK) && vs->number != kTextVirtScreen) || (_game.id == GID_LOOM && vs->number == kMainVirtScreen)) return; } +#endif fill(backbuff, vs->pitch, color, width, height, vs->bytesPerPixel); } @@ -1723,10 +1750,12 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const warning("Gdi::drawBitmap, strip drawn to %d below window bottom %d", y + height, vs->h); } +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_vm->_townsPaletteFlags & 2) { int cx = (x - _vm->_screenStartStrip) << 3; _vm->_textSurface.fillRect(Common::Rect(cx * _vm->_textSurfaceMultiplier, y * _vm->_textSurfaceMultiplier, (cx + width - 1) * _vm->_textSurfaceMultiplier, (y + height - 1) * _vm->_textSurfaceMultiplier), 0); } +#endif _vertStripNextInc = height * vs->pitch - 1 * vs->bytesPerPixel; @@ -3678,8 +3707,10 @@ void ScummEngine::fadeOut(int effect) { if (_game.version < 7) camera._last.x = camera._cur.x; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.version == 3 && _game.platform == Common::kPlatformFMTowns) _textSurface.fillRect(Common::Rect(0, vs->topline * _textSurfaceMultiplier, _textSurface.pitch, (vs->topline + vs->h) * _textSurfaceMultiplier), 0); +#endif // TheDig can disable fadeIn(), and may call fadeOut() several times // successively. Disabling the _screenEffectFlag check forces the screen @@ -3883,9 +3914,11 @@ void ScummEngine::dissolveEffect(int width, int height) { x = offsets[i] % vs->pitch; y = offsets[i] / vs->pitch; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) towns_drawStripToScreen(vs, x, y + vs->topline, x, y, width, height); else +#endif _system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height); @@ -3926,10 +3959,12 @@ void ScummEngine::scrollEffect(int dir) { y = 1 + step; while (y < vs->h) { moveScreen(0, -step, vs->h); - +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) { towns_drawStripToScreen(vs, 0, vs->topline + vs->h - step, 0, y - step, vs->w, step); - } else { + } else +#endif + { src = vs->getPixels(0, y - step); _system->copyRectToScreen(src, vsPitch, @@ -3947,10 +3982,12 @@ void ScummEngine::scrollEffect(int dir) { y = 1 + step; while (y < vs->h) { moveScreen(0, step, vs->h); - +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) { towns_drawStripToScreen(vs, 0, vs->topline, 0, vs->h - y, vs->w, step); - } else { + } else +#endif + { src = vs->getPixels(0, vs->h - y); _system->copyRectToScreen(src, vsPitch, @@ -3968,10 +4005,13 @@ void ScummEngine::scrollEffect(int dir) { x = 1 + step; while (x < vs->w) { moveScreen(-step, 0, vs->h); - + +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) { towns_drawStripToScreen(vs, vs->w - step, vs->topline, x - step, 0, step, vs->h); - } else { + } else +#endif + { src = vs->getPixels(x - step, 0); _system->copyRectToScreen(src, vsPitch, @@ -3990,9 +4030,12 @@ void ScummEngine::scrollEffect(int dir) { while (x < vs->w) { moveScreen(step, 0, vs->h); +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) { towns_drawStripToScreen(vs, 0, vs->topline, vs->w - x, 0, step, vs->h); - } else { + } else +#endif + { src = vs->getPixels(vs->w - x, 0); _system->copyRectToScreen(src, vsPitch, diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h index 9b628f6264..c6062ef9be 100644 --- a/engines/scumm/gfx.h +++ b/engines/scumm/gfx.h @@ -424,9 +424,9 @@ public: }; #endif +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE // Helper class for FM-Towns output (required for specific hardware effects like // switching graphics layers on and off). - class TownsScreen { public: TownsScreen(OSystem *system, int width, int height, int bpp); @@ -482,6 +482,7 @@ private: Common::List _dirtyRects; OSystem *_system; }; +#endif // DISABLE_TOWNS_DUAL_LAYER_MODE } // End of namespace Scumm diff --git a/engines/scumm/gfx_towns.cpp b/engines/scumm/gfx_towns.cpp index 7198e103fc..33b1779b0b 100644 --- a/engines/scumm/gfx_towns.cpp +++ b/engines/scumm/gfx_towns.cpp @@ -29,6 +29,8 @@ #include "scumm/util.h" #include "scumm/resource.h" +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + namespace Scumm { void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, int srcX, int srcY, int width, int height) { @@ -516,3 +518,5 @@ uint16 TownsScreen::calc16BitColor(const uint8 *palEntry) { #undef FULL_REDRAW } // End of namespace Scumm + +#endif // DISABLE_TOWNS_DUAL_LAYER_MODE diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp index 38577cd0c4..5c0c58595b 100644 --- a/engines/scumm/palette.cpp +++ b/engines/scumm/palette.cpp @@ -141,6 +141,7 @@ void ScummEngine::resetPalette() { }; #ifdef USE_RGB_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE static const byte tableTownsV3Palette[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x00, 0xA0, 0xA0, 0xA0, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0xA0, 0x60, 0x00, 0xA0, 0xA0, 0xA0, @@ -154,6 +155,7 @@ void ScummEngine::resetPalette() { 0x57, 0x3F, 0x57, 0x57, 0x57, 0xFF, 0x57, 0xFF, 0x57, 0x57, 0xFF, 0xFF, 0xFF, 0x57, 0x57, 0xD6, 0x94, 0x40, 0xFF, 0xFF, 0x57, 0xFF, 0xFF, 0xFF }; +#endif #endif if (_game.version <= 1) { @@ -215,6 +217,7 @@ void ScummEngine::resetPalette() { // else we initialise and then lock down the first 16 colors. if (_renderMode != Common::kRenderEGA) setPaletteFromTable(tableAmigaMIPalette, sizeof(tableAmigaMIPalette) / 3); +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE } else if (_game.platform == Common::kPlatformFMTowns) { if (_game.id == GID_INDY4 || _game.id == GID_MONKEY2) _townsClearLayerFlag = 0; @@ -226,6 +229,7 @@ void ScummEngine::resetPalette() { #endif _townsScreen->toggleLayers(_townsActiveLayerFlags); +#endif // DISABLE_TOWNS_DUAL_LAYER_MODE } setDirtyColors(0, 255); } @@ -493,8 +497,10 @@ void ScummEngine::cyclePalette() { int valueToAdd; int i, j; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns && (!_townsPaletteFlags & 1)) return; +#endif valueToAdd = VAR(VAR_TIMER); if (valueToAdd < VAR(VAR_TIMER_NEXT)) @@ -537,8 +543,10 @@ void ScummEngine::moveMemInPalRes(int start, int end, byte direction) { } void ScummEngine::palManipulateInit(int resID, int start, int end, int time) { +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns && (!_townsPaletteFlags & 1)) return; +#endif byte *string1 = getStringAddress(resID); byte *string2 = getStringAddress(resID + 1); @@ -1008,8 +1016,10 @@ void ScummEngine::setCurrentPalette(int palindex) { if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) { setPCEPaletteFromPtr(pals); #ifdef USE_RGB_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE } else if (_game.platform == Common::kPlatformFMTowns) { towns_setPaletteFromPtr(pals); +#endif #endif } else { setPaletteFromPtr(pals); @@ -1111,6 +1121,7 @@ void ScummEngine::updatePalette() { _palDirtyMin = 256; #ifdef USE_RGB_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { p = palette_colors; for (i = first; i < first + num; ++i) { @@ -1119,6 +1130,7 @@ void ScummEngine::updatePalette() { } return; } +#endif #endif _system->setPalette(palette_colors, first, num); diff --git a/engines/scumm/player_towns.cpp b/engines/scumm/player_towns.cpp index 871bd67546..bb7985f6da 100644 --- a/engines/scumm/player_towns.cpp +++ b/engines/scumm/player_towns.cpp @@ -29,15 +29,159 @@ namespace Scumm { -Player_Towns::Player_Towns(ScummEngine *vm, Audio::Mixer *mixer) : _vm(vm) { +Player_Towns::Player_Towns(ScummEngine *vm) : _vm(vm) { + memset(_pcmCurrentSound, 0, sizeof(_pcmCurrentSound)); + memset(&_ovrCur, 0, sizeof(SoundOvrParameters)); + _soundOverride = 0; + _unkFlags = 0x33; + _intf = 0; +} + +void Player_Towns::saveLoadWithSerializer(Serializer *ser) { + static const SaveLoadEntry pcmEntries[] = { + MKLINE(PcmCurrentSound, index, sleInt16, VER(81)), + MKLINE(PcmCurrentSound, chan, sleInt16, VER(81)), + MKLINE(PcmCurrentSound, note, sleUint8, VER(81)), + MKLINE(PcmCurrentSound, velo, sleUint8, VER(81)), + MKLINE(PcmCurrentSound, pan, sleUint8, VER(81)), + MKLINE(PcmCurrentSound, paused, sleUint8, VER(81)), + MKLINE(PcmCurrentSound, looping, sleUint8, VER(81)), + MKLINE(PcmCurrentSound, priority, sleUint32, VER(81)), + MKEND() + }; + + for (int i = 1; i < 9; i++) { + if (!_pcmCurrentSound[i].index) + continue; + + if (_intf->callback(40, i + 0x3f)) + continue; + + _intf->callback(39, i + 0x3f); + + _pcmCurrentSound[i].index = 0; + } + + ser->saveLoadArrayOf(_pcmCurrentSound, 9, sizeof(PcmCurrentSound), pcmEntries); +} + +void Player_Towns::restoreAfterLoad() { + for (int i = 1; i < 9; i++) { + if (!_pcmCurrentSound[i].index) + continue; + + uint8 *ptr = _vm->getResourceAddress(rtSound, _pcmCurrentSound[i].index); + if (!ptr) + continue; + + if (_vm->_game.version != 3) + ptr += 2; + + if (ptr[13]) + continue; + + playPcmTrack(_pcmCurrentSound[i].index, ptr + 6, _pcmCurrentSound[i].velo, _pcmCurrentSound[i].pan, _pcmCurrentSound[i].note); + } +} + +void Player_Towns::playPcmTrack(int sound, const uint8 *data, int velo, int pan, int note) { + const uint8 *ptr = data; + const uint8 *sfxData = ptr + 16; + + int note2, velocity; + + if (velo) + velocity = velo; + else if (_ovrCur.vLeft + _ovrCur.vRight) + velocity = (_ovrCur.vLeft + _ovrCur.vRight) >> 2; + else + velocity = ptr[8] >> 1; + + int numChan = ptr[14]; + for (int i = 0; i < numChan; i++) { + int chan = getNextFreePcmChannel(sound, i); + if (!chan) + return; + + _intf->callback(70, _unkFlags); + _intf->callback(3, chan + 0x3f, pan); + + if (note) + note2 = note; + else if (_ovrCur.note) + note2 = _ovrCur.note; + else + note2 = sfxData[28]; + + _intf->callback(37, chan + 0x3f, note2, velocity, sfxData); + + _pcmCurrentSound[chan].note = note2; + _pcmCurrentSound[chan].velo = velocity; + _pcmCurrentSound[chan].pan = pan; + _pcmCurrentSound[chan].paused = 0; + _pcmCurrentSound[chan].looping = READ_LE_UINT32(&sfxData[20]) ? 1 : 0; + + sfxData += (READ_LE_UINT32(&sfxData[12]) + 32); + } +} + +void Player_Towns::stopPcmTrack(int sound) { + for (int i = 1; i < 9; i++) { + if (sound == _pcmCurrentSound[i].index || !sound) { + _intf->callback(39, i + 0x3f); + _pcmCurrentSound[i].index = 0; + } + } +} + +int Player_Towns::getNextFreePcmChannel(int sound, int sfxChanRelIndex) { + int chan = 0; + for (int i = 8; i; i--) { + if (!_pcmCurrentSound[i].index) { + chan = i; + continue; + } + + if (_intf->callback(40, i + 0x3f)) + continue; + + chan = i; + _vm->_sound->stopSound(_pcmCurrentSound[chan].index); + } + + if (!chan) { + uint16 l = 0xffff; + uint8 *ptr = 0; + for (int i = 8; i; i--) { + ptr = _vm->getResourceAddress(rtSound, _pcmCurrentSound[i].index) + 6; + uint16 a = READ_LE_UINT16(ptr + 10); + if (a <= l) { + chan = i; + l = a; + } + } + + ptr = _vm->getResourceAddress(rtSound, sound) + 6; + if (l <= READ_LE_UINT16(ptr + 10)) + _vm->_sound->stopSound(_pcmCurrentSound[chan].index); + else + chan = 0; + } + + if (chan) { + _pcmCurrentSound[chan].index = sound; + _pcmCurrentSound[chan].chan = sfxChanRelIndex; + } + + return chan; +} + +Player_Towns_v1::Player_Towns_v1(ScummEngine *vm, Audio::Mixer *mixer) : Player_Towns(vm) { _cdaCurrentSound = _eupCurrentSound = _cdaNumLoops = 0; _cdaForceRestart = 0; - memset(_pcmCurrentSound, 0, sizeof(_pcmCurrentSound)); _cdaVolLeft = _cdaVolRight = 0; _eupVolLeft = _eupVolRight = 0; - memset(&_ovrCur, 0, sizeof(SoundOvrParameters)); - _soundOverride = 0; if (_vm->_game.version == 3) { _soundOverride = new SoundOvrParameters[200]; @@ -45,17 +189,16 @@ Player_Towns::Player_Towns(ScummEngine *vm, Audio::Mixer *mixer) : _vm(vm) { } _eupLooping = false; - _unkFlags = 0x33; _driver = new TownsEuphonyDriver(mixer); } -Player_Towns::~Player_Towns() { +Player_Towns_v1::~Player_Towns_v1() { delete[] _soundOverride; delete _driver; } -bool Player_Towns::init() { +bool Player_Towns_v1::init() { if (!_driver) return false; @@ -63,26 +206,27 @@ bool Player_Towns::init() { return false; _driver->reserveSoundEffectChannels(8); + _intf = _driver->intf(); // Treat all 6 fm channels and all 8 pcm channels as sound effect channels // since music seems to exist as CD audio only in the games which use this // MusicEngine implementation. - _driver->intf()->setSoundEffectChanMask(-1); + _intf->setSoundEffectChanMask(-1); setVolumeCD(255, 255); return true; } -void Player_Towns::setMusicVolume(int vol) { +void Player_Towns_v1::setMusicVolume(int vol) { _driver->setMusicVolume(vol); } -void Player_Towns::setSfxVolume(int vol) { +void Player_Towns_v1::setSfxVolume(int vol) { _driver->setSoundEffectVolume(vol); } -void Player_Towns::startSound(int sound) { +void Player_Towns_v1::startSound(int sound) { uint8 *ptr = _vm->getResourceAddress(rtSound, sound); if (_vm->_game.version != 3) { ptr += 2; @@ -103,7 +247,7 @@ void Player_Towns::startSound(int sound) { memset(&_ovrCur, 0, sizeof(SoundOvrParameters)); } -void Player_Towns::stopSound(int sound) { +void Player_Towns_v1::stopSound(int sound) { if (sound == 0 || sound == _cdaCurrentSound) { _cdaCurrentSound = 0; _vm->_sound->stopCD(); @@ -119,7 +263,7 @@ void Player_Towns::stopSound(int sound) { stopPcmTrack(sound); } -void Player_Towns::stopAllSounds() { +void Player_Towns_v1::stopAllSounds() { _cdaCurrentSound = 0; _vm->_sound->stopCD(); _vm->_sound->stopCDTimer(); @@ -131,7 +275,7 @@ void Player_Towns::stopAllSounds() { stopPcmTrack(0); } -int Player_Towns::getSoundStatus(int sound) const { +int Player_Towns_v1::getSoundStatus(int sound) const { if (sound == _cdaCurrentSound) return _vm->_sound->pollCD(); if (sound == _eupCurrentSound) @@ -143,7 +287,7 @@ int Player_Towns::getSoundStatus(int sound) const { return 0; } -int32 Player_Towns::doCommand(int numargs, int args[]) { +int32 Player_Towns_v1::doCommand(int numargs, int args[]) { int32 res = 0; switch (args[0]) { @@ -176,40 +320,40 @@ int32 Player_Towns::doCommand(int numargs, int args[]) { break; default: - warning("Player_Towns::doCommand: Unknown command %d", args[0]); + warning("Player_Towns_v1::doCommand: Unknown command %d", args[0]); break; } return res; } -void Player_Towns::setVolumeCD(int left, int right) { +void Player_Towns_v1::setVolumeCD(int left, int right) { _cdaVolLeft = left & 0xff; _cdaVolRight = right & 0xff; _driver->setOutputVolume(1, left >> 1, right >> 1); } -void Player_Towns::setSoundVolume(int sound, int left, int right) { +void Player_Towns_v1::setSoundVolume(int sound, int left, int right) { if (_soundOverride && sound > 0 && sound < 200) { _soundOverride[sound].vLeft = left; _soundOverride[sound].vRight = right; } } -void Player_Towns::setSoundNote(int sound, int note) { +void Player_Towns_v1::setSoundNote(int sound, int note) { if (_soundOverride && sound > 0 && sound < 200) _soundOverride[sound].note = note; } -void Player_Towns::saveLoadWithSerializer(Serializer *ser) { +void Player_Towns_v1::saveLoadWithSerializer(Serializer *ser) { _cdaCurrentSoundTemp = (_vm->_sound->pollCD() && _cdaNumLoops > 1) ? _cdaCurrentSound & 0xff : 0; _cdaNumLoopsTemp = _cdaNumLoops & 0xff; static const SaveLoadEntry cdEntries[] = { - MKLINE(Player_Towns, _cdaCurrentSoundTemp, sleUint8, VER(81)), - MKLINE(Player_Towns, _cdaNumLoopsTemp, sleUint8, VER(81)), - MKLINE(Player_Towns, _cdaVolLeft, sleUint8, VER(81)), - MKLINE(Player_Towns, _cdaVolRight, sleUint8, VER(81)), + MKLINE(Player_Towns_v1, _cdaCurrentSoundTemp, sleUint8, VER(81)), + MKLINE(Player_Towns_v1, _cdaNumLoopsTemp, sleUint8, VER(81)), + MKLINE(Player_Towns_v1, _cdaVolLeft, sleUint8, VER(81)), + MKLINE(Player_Towns_v1, _cdaVolRight, sleUint8, VER(81)), MKEND() }; @@ -219,43 +363,19 @@ void Player_Towns::saveLoadWithSerializer(Serializer *ser) { _eupCurrentSound = 0; static const SaveLoadEntry eupEntries[] = { - MKLINE(Player_Towns, _eupCurrentSound, sleUint8, VER(81)), - MKLINE(Player_Towns, _eupLooping, sleUint8, VER(81)), - MKLINE(Player_Towns, _eupVolLeft, sleUint8, VER(81)), - MKLINE(Player_Towns, _eupVolRight, sleUint8, VER(81)), + MKLINE(Player_Towns_v1, _eupCurrentSound, sleUint8, VER(81)), + MKLINE(Player_Towns_v1, _eupLooping, sleUint8, VER(81)), + MKLINE(Player_Towns_v1, _eupVolLeft, sleUint8, VER(81)), + MKLINE(Player_Towns_v1, _eupVolRight, sleUint8, VER(81)), MKEND() }; ser->saveLoadEntries(this, eupEntries); - static const SaveLoadEntry pcmEntries[] = { - MKLINE(PcmCurrentSound, index, sleInt16, VER(81)), - MKLINE(PcmCurrentSound, chan, sleInt16, VER(81)), - MKLINE(PcmCurrentSound, note, sleUint8, VER(81)), - MKLINE(PcmCurrentSound, velo, sleUint8, VER(81)), - MKLINE(PcmCurrentSound, pan, sleUint8, VER(81)), - MKLINE(PcmCurrentSound, paused, sleUint8, VER(81)), - MKLINE(PcmCurrentSound, looping, sleUint8, VER(81)), - MKLINE(PcmCurrentSound, priority, sleUint32, VER(81)), - MKEND() - }; - - for (int i = 1; i < 9; i++) { - if (!_pcmCurrentSound[i].index) - continue; - - if (_driver->soundEffectIsPlaying(i + 0x3f)) - continue; - - _driver->stopSoundEffect(i + 0x3f); - - _pcmCurrentSound[i].index = 0; - } - - ser->saveLoadArrayOf(_pcmCurrentSound, 9, sizeof(PcmCurrentSound), pcmEntries); + Player_Towns::saveLoadWithSerializer(ser); } -void Player_Towns::restoreAfterLoad() { +void Player_Towns_v1::restoreAfterLoad() { setVolumeCD(_cdaVolLeft, _cdaVolRight); if (_cdaCurrentSoundTemp) { @@ -281,67 +401,12 @@ void Player_Towns::restoreAfterLoad() { } } - for (int i = 1; i < 9; i++) { - if (!_pcmCurrentSound[i].index) - continue; - - uint8 *ptr = _vm->getResourceAddress(rtSound, _pcmCurrentSound[i].index); - if (!ptr) - continue; - - if (_vm->_game.version != 3) - ptr += 2; - - if (ptr[13]) - continue; - - playPcmTrack(_pcmCurrentSound[i].index, ptr + 6, _pcmCurrentSound[i].velo, _pcmCurrentSound[i].pan, _pcmCurrentSound[i].note); - } + Player_Towns::restoreAfterLoad(); } -int Player_Towns::getNextFreePcmChannel(int sound, int sfxChanRelIndex) { - int chan = 0; - for (int i = 8; i; i--) { - if (!_pcmCurrentSound[i].index) { - chan = i; - continue; - } - - if (_driver->soundEffectIsPlaying(i + 0x3f)) - continue; - - chan = i; - _vm->_sound->stopSound(_pcmCurrentSound[chan].index); - } - - if (!chan) { - uint16 l = 0xffff; - uint8 *ptr = 0; - for (int i = 8; i; i--) { - ptr = _vm->getResourceAddress(rtSound, _pcmCurrentSound[i].index) + 6; - uint16 a = READ_LE_UINT16(ptr + 10); - if (a <= l) { - chan = i; - l = a; - } - } - - ptr = _vm->getResourceAddress(rtSound, sound) + 6; - if (l <= READ_LE_UINT16(ptr + 10)) - _vm->_sound->stopSound(_pcmCurrentSound[chan].index); - else - chan = 0; - } - - if (chan) { - _pcmCurrentSound[chan].index = sound; - _pcmCurrentSound[chan].chan = sfxChanRelIndex; - } - return chan; -} -void Player_Towns::restartLoopingSounds() { +void Player_Towns_v1::restartLoopingSounds() { if (_cdaNumLoops && !_cdaForceRestart) _cdaForceRestart = 1; @@ -368,7 +433,7 @@ void Player_Towns::restartLoopingSounds() { _driver->intf()->callback(73, 1); } -void Player_Towns::startSoundEx(int sound, int velo, int pan, int note) { +void Player_Towns_v1::startSoundEx(int sound, int velo, int pan, int note) { uint8 *ptr = _vm->getResourceAddress(rtSound, sound) + 2; if (pan > 99) @@ -405,7 +470,7 @@ void Player_Towns::startSoundEx(int sound, int velo, int pan, int note) { } } -void Player_Towns::stopSoundSuspendLooping(int sound) { +void Player_Towns_v1::stopSoundSuspendLooping(int sound) { if (!sound) { return; } else if (sound == _cdaCurrentSound) { @@ -426,7 +491,7 @@ void Player_Towns::stopSoundSuspendLooping(int sound) { } } -void Player_Towns::playEuphonyTrack(int sound, const uint8 *data) { +void Player_Towns_v1::playEuphonyTrack(int sound, const uint8 *data) { const uint8 *pos = data + 16; const uint8 *src = pos + data[14] * 48; const uint8 *trackData = src + 150; @@ -474,48 +539,7 @@ void Player_Towns::playEuphonyTrack(int sound, const uint8 *data) { _eupCurrentSound = sound; } -void Player_Towns::playPcmTrack(int sound, const uint8 *data, int velo, int pan, int note) { - const uint8 *ptr = data; - const uint8 *sfxData = ptr + 16; - - int note2, velocity; - - if (velo) - velocity = velo; - else if (_ovrCur.vLeft + _ovrCur.vRight) - velocity = (_ovrCur.vLeft + _ovrCur.vRight) >> 2; - else - velocity = ptr[8] >> 1; - - int numChan = ptr[14]; - for (int i = 0; i < numChan; i++) { - int chan = getNextFreePcmChannel(sound, i); - if (!chan) - return; - - _driver->intf()->callback(70, _unkFlags); - _driver->chanPanPos(chan + 0x3f, pan); - - if (note) - note2 = note; - else if (_ovrCur.note) - note2 = _ovrCur.note; - else - note2 = sfxData[28]; - - _driver->playSoundEffect(chan + 0x3f, note2, velocity, sfxData); - - _pcmCurrentSound[chan].note = note2; - _pcmCurrentSound[chan].velo = velocity; - _pcmCurrentSound[chan].pan = pan; - _pcmCurrentSound[chan].paused = 0; - _pcmCurrentSound[chan].looping = READ_LE_UINT32(&sfxData[20]) ? 1 : 0; - - sfxData += (READ_LE_UINT32(&sfxData[12]) + 32); - } -} - -void Player_Towns::playCdaTrack(int sound, const uint8 *data, bool skipTrackVelo) { +void Player_Towns_v1::playCdaTrack(int sound, const uint8 *data, bool skipTrackVelo) { const uint8 *ptr = data; if (!sound) @@ -543,14 +567,5 @@ void Player_Towns::playCdaTrack(int sound, const uint8 *data, bool skipTrackVelo _cdaCurrentSound = sound; } -void Player_Towns::stopPcmTrack(int sound) { - for (int i = 1; i < 9; i++) { - if (sound == _pcmCurrentSound[i].index || !sound) { - _driver->stopSoundEffect(i + 0x3f); - _pcmCurrentSound[i].index = 0; - } - } -} - } // End of namespace Scumm diff --git a/engines/scumm/player_towns.h b/engines/scumm/player_towns.h index 6d87c93c09..3a36ea5daf 100644 --- a/engines/scumm/player_towns.h +++ b/engines/scumm/player_towns.h @@ -32,10 +32,50 @@ namespace Scumm { -class Player_Towns : public MusicEngine { +class Player_Towns { public: - Player_Towns(ScummEngine *vm, Audio::Mixer *mixer); - virtual ~Player_Towns(); + Player_Towns(ScummEngine *vm); + virtual ~Player_Towns() {} + + virtual void saveLoadWithSerializer(Serializer *ser); + virtual void restoreAfterLoad(); + +protected: + void playPcmTrack(int sound, const uint8 *data, int velo = 0, int pan = 64, int note = 0); + void stopPcmTrack(int sound); + + int getNextFreePcmChannel(int sound, int sfxChanRelIndex); + + struct PcmCurrentSound { + uint16 index; + uint16 chan; + uint8 note; + uint8 velo; + uint8 pan; + uint8 paused; + uint8 looping; + uint32 priority; + } _pcmCurrentSound[9]; + + struct SoundOvrParameters { + uint8 vLeft; + uint8 vRight; + uint8 note; + }; + + uint8 _unkFlags; + + SoundOvrParameters *_soundOverride; + SoundOvrParameters _ovrCur; + + TownsAudioInterface *_intf; + ScummEngine *_vm; +}; + +class Player_Towns_v1 : public Player_Towns, public MusicEngine { +public: + Player_Towns_v1(ScummEngine *vm, Audio::Mixer *mixer); + virtual ~Player_Towns_v1(); bool init(); @@ -49,7 +89,7 @@ public: int getCurrentCdaSound() { return _cdaCurrentSound; } int getCurrentCdaVolume() { return (_cdaVolLeft + _cdaVolRight + 1) >> 1; } - virtual int32 doCommand(int numargs, int args[]); + int32 doCommand(int numargs, int args[]); void setVolumeCD(int left, int right); void setSoundVolume(int sound, int left, int right); @@ -60,45 +100,17 @@ public: TownsEuphonyDriver *driver() { return _driver; } -protected: - virtual int getNextFreePcmChannel(int sound, int sfxChanRelIndex); - private: void restartLoopingSounds(); void startSoundEx(int sound, int velo, int pan, int note); void stopSoundSuspendLooping(int sound); void playEuphonyTrack(int sound, const uint8 *data); - void playPcmTrack(int sound, const uint8 *data, int velo = 0, int pan = 64, int note = 0); void playCdaTrack(int sound, const uint8 *data, bool skipTrackVelo = false); - void stopPcmTrack(int sound); - uint8 _cdaVolLeft; uint8 _cdaVolRight; - - struct SoundOvrParameters { - uint8 vLeft; - uint8 vRight; - uint8 note; - }; - - SoundOvrParameters *_soundOverride; - SoundOvrParameters _ovrCur; - uint8 _unkFlags; - - struct PcmCurrentSound { - uint16 index; - uint16 chan; - uint8 note; - uint8 velo; - uint8 pan; - uint8 paused; - uint8 looping; - uint32 priority; - } _pcmCurrentSound[9]; - uint8 _eupCurrentSound; uint8 _eupLooping; uint8 _eupVolLeft; @@ -112,7 +124,6 @@ private: uint8 _cdaNumLoopsTemp; TownsEuphonyDriver *_driver; - ScummEngine *_vm; }; } // End of namespace Scumm diff --git a/engines/scumm/room.cpp b/engines/scumm/room.cpp index 35d6d25548..02b2482e40 100644 --- a/engines/scumm/room.cpp +++ b/engines/scumm/room.cpp @@ -195,7 +195,9 @@ void ScummEngine::startScene(int room, Actor *a, int objectNr) { _egoPositioned = false; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE towns_resetPalCycleFields(); +#endif runEntryScript(); if (_game.version >= 1 && _game.version <= 2) { diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index a1747db690..28ec6c182f 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1298,6 +1298,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { s->saveLoadArrayOf(_16BitPalette, 512, sizeof(_16BitPalette[0]), sleUint16); } +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE // FM-Towns specific (extra palette data, color cycle data, etc.) if (s->getVersion() >= VER(82)) { const SaveLoadEntry townsFields[] = { @@ -1323,6 +1324,7 @@ void ScummEngine::saveOrLoad(Serializer *s) { s->saveLoadArrayOf(_townsCharsetColorMap, 16, sizeof(_townsCharsetColorMap[0]), sleUint8); s->saveLoadEntries(this, townsExtraEntries); } +#endif if (_shadowPaletteSize) { s->saveLoadArrayOf(_shadowPalette, _shadowPaletteSize, 1, sleByte); diff --git a/engines/scumm/script_v4.cpp b/engines/scumm/script_v4.cpp index 8e1feb7388..b6e5834acc 100644 --- a/engines/scumm/script_v4.cpp +++ b/engines/scumm/script_v4.cpp @@ -114,8 +114,10 @@ void ScummEngine_v4::o4_oldRoomEffect() { if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) { if (a == 4) { _textSurface.fillRect(Common::Rect(0, 0, _textSurface.w * _textSurfaceMultiplier, _textSurface.h * _textSurfaceMultiplier), 0); +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) _townsScreen->clearLayer(1); +#endif return; } } diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 56c9f11445..bc88a0a800 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -1712,6 +1712,7 @@ void ScummEngine_v5::o5_roomOps() { case 10: // SO_ROOM_FADE a = getVarOrDirectWord(PARAM_1); if (a) { + #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { switch (a) { case 8: @@ -1762,6 +1763,7 @@ void ScummEngine_v5::o5_roomOps() { return; } } +#endif // DISABLE_TOWNS_DUAL_LAYER_MODE _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); } else { diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index f33ca74b12..e0c044a52d 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -278,7 +278,9 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _hePalettes = NULL; _hePaletteSlot = 0; _16BitPalette = NULL; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE _townsScreen = 0; +#endif _shadowPalette = NULL; _shadowPaletteSize = 0; memset(_currentPalette, 0, sizeof(_currentPalette)); @@ -319,12 +321,14 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _skipDrawObject = 0; +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE _townsPaletteFlags = 0; _townsClearLayerFlag = 1; _townsActiveLayerFlags = 3; memset(&_curStringRect, -1, sizeof(Common::Rect)); memset(&_cyclRects, 0, 16 * sizeof(Common::Rect)); _numCyclRects = 0; +#endif // // Init all VARS to 0xFF @@ -544,8 +548,10 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _bytesPerPixelOutput = _bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1; #ifdef USE_RGB_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) _bytesPerPixelOutput = 2; +#endif #endif // Allocate gfx compositing buffer (not needed for V7/V8 games). @@ -622,7 +628,9 @@ ScummEngine::~ScummEngine() { free(_16BitPalette); +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE delete _townsScreen; +#endif delete _debugger; @@ -1130,7 +1138,11 @@ Common::Error ScummEngine::init() { screenWidth *= _textSurfaceMultiplier; screenHeight *= _textSurfaceMultiplier; } - if (_game.features & GF_16BIT_COLOR || _game.platform == Common::kPlatformFMTowns) { + if (_game.features & GF_16BIT_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + || _game.platform == Common::kPlatformFMTowns +#endif + ) { #ifdef USE_RGB_COLOR Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); initGraphics(screenWidth, screenHeight, screenWidth > 320, &format); @@ -1145,6 +1157,10 @@ Common::Error ScummEngine::init() { } #endif } else { +#ifdef DISABLE_TOWNS_DUAL_LAYER_MODE + if (_game.platform == Common::kPlatformFMTowns && _game.version == 5) + error("This game requires dual graphics layer support which is disabled in this build"); +#endif initGraphics(screenWidth, screenHeight, (screenWidth > 320)); } } @@ -1340,16 +1356,22 @@ void ScummEngine::resetScumm() { debug(9, "resetScumm"); #ifdef USE_RGB_COLOR - if (_game.features & GF_16BIT_COLOR || _game.platform == Common::kPlatformFMTowns) + if (_game.features & GF_16BIT_COLOR +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + || _game.platform == Common::kPlatformFMTowns +#endif + ) _16BitPalette = (uint16 *)calloc(512, sizeof(uint16)); #endif +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { delete _townsScreen; _townsScreen = new TownsScreen(_system, _screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, _bytesPerPixelOutput); _townsScreen->setupLayer(0, _screenWidth, _screenHeight, (_bytesPerPixelOutput == 2) ? 32767 : 256); _townsScreen->setupLayer(1, _screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, 16, _textPalette); } +#endif if (_game.version == 0) { initScreens(8, 144); @@ -1789,7 +1811,7 @@ void ScummEngine::setupMusic(int midi) { } else if (_game.platform == Common::kPlatform3DO && _game.heversion <= 62) { // 3DO versions use digital music and sound samples. } else if (_game.platform == Common::kPlatformFMTowns && (_game.version == 3 || _game.id == GID_MONKEY)) { - _musicEngine = _townsPlayer = new Player_Towns(this, _mixer); + _musicEngine = _townsPlayer = new Player_Towns_v1(this, _mixer); if (!_townsPlayer->init()) error("Failed to initialize FM-Towns audio driver"); } else if (_game.version >= 3 && _game.heversion <= 62) { @@ -1953,8 +1975,10 @@ void ScummEngine::waitForTimer(int msec_delay) { _sound->updateCD(); // Loop CD Audio if needed parseEvents(); +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) _townsScreen->update(); +#endif _system->updateScreen(); if (_system->getMillis() >= start_time + msec_delay) @@ -2083,7 +2107,9 @@ load_game: goto load_game; } +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE towns_processPalCycleField(); +#endif if (_currentRoom == 0) { if (_game.version > 3) @@ -2473,8 +2499,10 @@ void ScummEngine::pauseEngineIntern(bool pause) { // Update the screen to make it less likely that the player will see a // brief cursor palette glitch when the GUI is disabled. +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) _townsScreen->update(); +#endif _system->updateScreen(); diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index d161c698c4..53456be166 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -43,6 +43,17 @@ #include "sound/mididrv.h" +#ifdef __DS__ +/* This disables the dual layer mode which is used in FM-Towns versions + * of SCUMM games and which emulates the behaviour of the original code. + * The only purpose is code size reduction for certain backends. + * SCUMM 3 (FM-Towns) games will run in normal (DOS VGA) mode, which should + * work just fine in most situations. Some glitches might occur. SCUMM 5 games + * will not work without dual layer (and 16 bit color) support. + */ +#define DISABLE_TOWNS_DUAL_LAYER_MODE +#endif + namespace GUI { class Dialog; } @@ -70,7 +81,7 @@ class CharsetRenderer; class IMuse; class IMuseDigital; class MusicEngine; -class Player_Towns; +class Player_Towns_v1; class ScummEngine; class ScummDebugger; class Serializer; @@ -427,7 +438,7 @@ public: IMuse *_imuse; IMuseDigital *_imuseDigital; MusicEngine *_musicEngine; - Player_Towns *_townsPlayer; + Player_Towns_v1 *_townsPlayer; Sound *_sound; VerbSlot *_verbs; @@ -1401,6 +1412,7 @@ public: byte VAR_NUM_GLOBAL_OBJS; // FM-Towns specific +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE public: bool towns_isRectInStringBox(int x1, int y1, int x2, int y2); byte _townsPaletteFlags; @@ -1429,6 +1441,7 @@ protected: static const uint8 _townsLayer2Mask[]; TownsScreen *_townsScreen; +#endif // DISABLE_TOWNS_DUAL_LAYER_MODE }; } // End of namespace Scumm diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp index b1e645be3e..5eb2b9d159 100644 --- a/engines/scumm/string.cpp +++ b/engines/scumm/string.cpp @@ -508,8 +508,10 @@ void ScummEngine::CHARSET_1() { if (_game.version >= 5) memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4); +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_keepText && _game.platform == Common::kPlatformFMTowns) memcpy(&_charset->_str, &_curStringRect, sizeof(Common::Rect)); +#endif if (_talkDelay) return; @@ -542,9 +544,11 @@ void ScummEngine::CHARSET_1() { _nextTop = _string[0].ypos + _screenTop; #endif } else { +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) towns_restoreCharsetBg(); else +#endif restoreCharsetBg(); } } @@ -666,8 +670,10 @@ void ScummEngine::CHARSET_1() { } } +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns && (c == 0 || c == 2 || c == 3)) memcpy(&_curStringRect, &_charset->_str, sizeof(Common::Rect)); +#endif #ifdef ENABLE_SCUMM_7_8 if (_game.version >= 7 && subtitleLine != subtitleBuffer) { diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 5135fd94a2..77181c0b55 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -1451,7 +1451,11 @@ void ScummEngine::restoreVerbBG(int verb) { VerbSlot *vs; vs = &_verbs[verb]; - uint8 col = ((_game.platform == Common::kPlatformFMTowns) && (_game.id == GID_MONKEY2 || _game.id == GID_INDY4) && (vs->bkcolor == _townsOverrideShadowColor)) ? 0 : vs->bkcolor; + uint8 col = +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE + ((_game.platform == Common::kPlatformFMTowns) && (_game.id == GID_MONKEY2 || _game.id == GID_INDY4) && (vs->bkcolor == _townsOverrideShadowColor)) ? 0 : +#endif + vs->bkcolor; if (vs->oldRect.left != -1) { restoreBackground(vs->oldRect, col); -- cgit v1.2.3