aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
authorFlorian Kagerer2010-10-05 19:04:52 +0000
committerFlorian Kagerer2010-10-05 19:04:52 +0000
commit5af782c5d279b0b3b54ee041bb50c8fec2d35fd3 (patch)
tree7683aa03db7a7406d0c4e192a8b161e0ba04069b /engines/scumm
parentb749b28c09cd2972e130b14260ee4925ef6bec72 (diff)
downloadscummvm-rg350-5af782c5d279b0b3b54ee041bb50c8fec2d35fd3.tar.gz
scummvm-rg350-5af782c5d279b0b3b54ee041bb50c8fec2d35fd3.tar.bz2
scummvm-rg350-5af782c5d279b0b3b54ee041bb50c8fec2d35fd3.zip
SCUMM/FM-TOWNS: disable new graphics code in DS port
svn-id: r53033
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/actor.cpp2
-rw-r--r--engines/scumm/charset.cpp46
-rw-r--r--engines/scumm/charset.h3
-rw-r--r--engines/scumm/cursor.cpp2
-rw-r--r--engines/scumm/gfx.cpp67
-rw-r--r--engines/scumm/gfx.h3
-rw-r--r--engines/scumm/gfx_towns.cpp4
-rw-r--r--engines/scumm/palette.cpp12
-rw-r--r--engines/scumm/player_towns.cpp345
-rw-r--r--engines/scumm/player_towns.h77
-rw-r--r--engines/scumm/room.cpp2
-rw-r--r--engines/scumm/saveload.cpp2
-rw-r--r--engines/scumm/script_v4.cpp2
-rw-r--r--engines/scumm/script_v5.cpp2
-rw-r--r--engines/scumm/scumm.cpp34
-rw-r--r--engines/scumm/scumm.h17
-rw-r--r--engines/scumm/string.cpp6
-rw-r--r--engines/scumm/verbs.cpp6
18 files changed, 409 insertions, 223 deletions
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<Common::Rect> _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,
@@ -155,6 +156,7 @@ void ScummEngine::resetPalette() {
0xFF, 0x57, 0x57, 0xD6, 0x94, 0x40, 0xFF, 0xFF, 0x57, 0xFF, 0xFF, 0xFF
};
#endif
+#endif
if (_game.version <= 1) {
if (_game.platform == Common::kPlatformApple2GS) {
@@ -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,9 +1016,11 @@ 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) {
@@ -1120,6 +1131,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,9 +548,11 @@ 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).
if (_game.version < 7)
@@ -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);