SCUMM/FM-TOWNS: disable new graphics code in DS port
svn-id: r53033
This commit is contained in:
parent
b749b28c09
commit
5af782c5d2
18 changed files with 519 additions and 333 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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]];
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
@ -3969,9 +4006,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, 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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -29,205 +29,15 @@
|
|||
|
||||
namespace Scumm {
|
||||
|
||||
Player_Towns::Player_Towns(ScummEngine *vm, Audio::Mixer *mixer) : _vm(vm) {
|
||||
_cdaCurrentSound = _eupCurrentSound = _cdaNumLoops = 0;
|
||||
_cdaForceRestart = 0;
|
||||
Player_Towns::Player_Towns(ScummEngine *vm) : _vm(vm) {
|
||||
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];
|
||||
memset(_soundOverride, 0, 200 * sizeof(SoundOvrParameters));
|
||||
}
|
||||
|
||||
_eupLooping = false;
|
||||
_unkFlags = 0x33;
|
||||
|
||||
_driver = new TownsEuphonyDriver(mixer);
|
||||
}
|
||||
|
||||
Player_Towns::~Player_Towns() {
|
||||
delete[] _soundOverride;
|
||||
delete _driver;
|
||||
}
|
||||
|
||||
bool Player_Towns::init() {
|
||||
if (!_driver)
|
||||
return false;
|
||||
|
||||
if (!_driver->init())
|
||||
return false;
|
||||
|
||||
_driver->reserveSoundEffectChannels(8);
|
||||
|
||||
// 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);
|
||||
|
||||
setVolumeCD(255, 255);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player_Towns::setMusicVolume(int vol) {
|
||||
_driver->setMusicVolume(vol);
|
||||
}
|
||||
|
||||
void Player_Towns::setSfxVolume(int vol) {
|
||||
_driver->setSoundEffectVolume(vol);
|
||||
}
|
||||
|
||||
void Player_Towns::startSound(int sound) {
|
||||
uint8 *ptr = _vm->getResourceAddress(rtSound, sound);
|
||||
if (_vm->_game.version != 3) {
|
||||
ptr += 2;
|
||||
} else if (_soundOverride && sound > 0 && sound < 200) {
|
||||
memcpy(&_ovrCur, &_soundOverride[sound], sizeof(SoundOvrParameters));
|
||||
memset(&_soundOverride[sound], 0, sizeof(SoundOvrParameters));
|
||||
}
|
||||
|
||||
int type = ptr[13];
|
||||
|
||||
if (type == 0) {
|
||||
playPcmTrack(sound, ptr + 6);
|
||||
} else if (type == 1) {
|
||||
playEuphonyTrack(sound, ptr + 6);
|
||||
} else if (type == 2) {
|
||||
playCdaTrack(sound, ptr + 6);
|
||||
}
|
||||
memset(&_ovrCur, 0, sizeof(SoundOvrParameters));
|
||||
}
|
||||
|
||||
void Player_Towns::stopSound(int sound) {
|
||||
if (sound == 0 || sound == _cdaCurrentSound) {
|
||||
_cdaCurrentSound = 0;
|
||||
_vm->_sound->stopCD();
|
||||
_vm->_sound->stopCDTimer();
|
||||
}
|
||||
|
||||
if (sound != 0 && sound == _eupCurrentSound) {
|
||||
_eupCurrentSound = 0;
|
||||
_eupLooping = false;
|
||||
_driver->stopParser();
|
||||
}
|
||||
|
||||
stopPcmTrack(sound);
|
||||
}
|
||||
|
||||
void Player_Towns::stopAllSounds() {
|
||||
_cdaCurrentSound = 0;
|
||||
_vm->_sound->stopCD();
|
||||
_vm->_sound->stopCDTimer();
|
||||
|
||||
_eupCurrentSound = 0;
|
||||
_eupLooping = false;
|
||||
_driver->stopParser();
|
||||
|
||||
stopPcmTrack(0);
|
||||
}
|
||||
|
||||
int Player_Towns::getSoundStatus(int sound) const {
|
||||
if (sound == _cdaCurrentSound)
|
||||
return _vm->_sound->pollCD();
|
||||
if (sound == _eupCurrentSound)
|
||||
return _driver->parserIsPlaying() ? 1 : 0;
|
||||
for (int i = 1; i < 9; i++) {
|
||||
if (_pcmCurrentSound[i].index == sound)
|
||||
return _driver->soundEffectIsPlaying(i + 0x3f) ? 1 : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Player_Towns::doCommand(int numargs, int args[]) {
|
||||
int32 res = 0;
|
||||
|
||||
switch (args[0]) {
|
||||
case 2:
|
||||
_driver->intf()->callback(73, 0);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
restartLoopingSounds();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
startSound(args[1]);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
_vm->_sound->stopSound(args[1]);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
stopPcmTrack(0);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
startSoundEx(args[1], args[2], args[3], args[4]);
|
||||
break;
|
||||
|
||||
case 15:
|
||||
stopSoundSuspendLooping(args[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
warning("Player_Towns::doCommand: Unknown command %d", args[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Player_Towns::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) {
|
||||
if (_soundOverride && sound > 0 && sound < 200) {
|
||||
_soundOverride[sound].vLeft = left;
|
||||
_soundOverride[sound].vRight = right;
|
||||
}
|
||||
}
|
||||
|
||||
void Player_Towns::setSoundNote(int sound, int note) {
|
||||
if (_soundOverride && sound > 0 && sound < 200)
|
||||
_soundOverride[sound].note = note;
|
||||
_intf = 0;
|
||||
}
|
||||
|
||||
void Player_Towns::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)),
|
||||
MKEND()
|
||||
};
|
||||
|
||||
ser->saveLoadEntries(this, cdEntries);
|
||||
|
||||
if (!_eupLooping && !_driver->parserIsPlaying())
|
||||
_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)),
|
||||
MKEND()
|
||||
};
|
||||
|
||||
ser->saveLoadEntries(this, eupEntries);
|
||||
|
||||
static const SaveLoadEntry pcmEntries[] = {
|
||||
MKLINE(PcmCurrentSound, index, sleInt16, VER(81)),
|
||||
MKLINE(PcmCurrentSound, chan, sleInt16, VER(81)),
|
||||
|
@ -244,10 +54,10 @@ void Player_Towns::saveLoadWithSerializer(Serializer *ser) {
|
|||
if (!_pcmCurrentSound[i].index)
|
||||
continue;
|
||||
|
||||
if (_driver->soundEffectIsPlaying(i + 0x3f))
|
||||
if (_intf->callback(40, i + 0x3f))
|
||||
continue;
|
||||
|
||||
_driver->stopSoundEffect(i + 0x3f);
|
||||
_intf->callback(39, i + 0x3f);
|
||||
|
||||
_pcmCurrentSound[i].index = 0;
|
||||
}
|
||||
|
@ -256,31 +66,6 @@ void Player_Towns::saveLoadWithSerializer(Serializer *ser) {
|
|||
}
|
||||
|
||||
void Player_Towns::restoreAfterLoad() {
|
||||
setVolumeCD(_cdaVolLeft, _cdaVolRight);
|
||||
|
||||
if (_cdaCurrentSoundTemp) {
|
||||
uint8 *ptr = _vm->getResourceAddress(rtSound, _cdaCurrentSoundTemp) + 6;
|
||||
if (_vm->_game.version != 3)
|
||||
ptr += 2;
|
||||
|
||||
if (ptr[7] == 2) {
|
||||
playCdaTrack(_cdaCurrentSoundTemp, ptr, true);
|
||||
_cdaCurrentSound = _cdaCurrentSoundTemp;
|
||||
_cdaNumLoops = _cdaNumLoopsTemp;
|
||||
}
|
||||
}
|
||||
|
||||
if (_eupCurrentSound) {
|
||||
uint8 *ptr = _vm->getResourceAddress(rtSound, _eupCurrentSound) + 6;
|
||||
if (_vm->_game.version != 3)
|
||||
ptr += 2;
|
||||
|
||||
if (ptr[7] == 1) {
|
||||
setSoundVolume(_eupCurrentSound, _eupVolLeft, _eupVolRight);
|
||||
playEuphonyTrack(_eupCurrentSound, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 1; i < 9; i++) {
|
||||
if (!_pcmCurrentSound[i].index)
|
||||
continue;
|
||||
|
@ -299,6 +84,56 @@ void Player_Towns::restoreAfterLoad() {
|
|||
}
|
||||
}
|
||||
|
||||
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--) {
|
||||
|
@ -307,7 +142,7 @@ int Player_Towns::getNextFreePcmChannel(int sound, int sfxChanRelIndex) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (_driver->soundEffectIsPlaying(i + 0x3f))
|
||||
if (_intf->callback(40, i + 0x3f))
|
||||
continue;
|
||||
|
||||
chan = i;
|
||||
|
@ -341,7 +176,237 @@ int Player_Towns::getNextFreePcmChannel(int sound, int sfxChanRelIndex) {
|
|||
return chan;
|
||||
}
|
||||
|
||||
void Player_Towns::restartLoopingSounds() {
|
||||
Player_Towns_v1::Player_Towns_v1(ScummEngine *vm, Audio::Mixer *mixer) : Player_Towns(vm) {
|
||||
_cdaCurrentSound = _eupCurrentSound = _cdaNumLoops = 0;
|
||||
_cdaForceRestart = 0;
|
||||
_cdaVolLeft = _cdaVolRight = 0;
|
||||
|
||||
_eupVolLeft = _eupVolRight = 0;
|
||||
|
||||
if (_vm->_game.version == 3) {
|
||||
_soundOverride = new SoundOvrParameters[200];
|
||||
memset(_soundOverride, 0, 200 * sizeof(SoundOvrParameters));
|
||||
}
|
||||
|
||||
_eupLooping = false;
|
||||
|
||||
_driver = new TownsEuphonyDriver(mixer);
|
||||
}
|
||||
|
||||
Player_Towns_v1::~Player_Towns_v1() {
|
||||
delete[] _soundOverride;
|
||||
delete _driver;
|
||||
}
|
||||
|
||||
bool Player_Towns_v1::init() {
|
||||
if (!_driver)
|
||||
return false;
|
||||
|
||||
if (!_driver->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.
|
||||
_intf->setSoundEffectChanMask(-1);
|
||||
|
||||
setVolumeCD(255, 255);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player_Towns_v1::setMusicVolume(int vol) {
|
||||
_driver->setMusicVolume(vol);
|
||||
}
|
||||
|
||||
void Player_Towns_v1::setSfxVolume(int vol) {
|
||||
_driver->setSoundEffectVolume(vol);
|
||||
}
|
||||
|
||||
void Player_Towns_v1::startSound(int sound) {
|
||||
uint8 *ptr = _vm->getResourceAddress(rtSound, sound);
|
||||
if (_vm->_game.version != 3) {
|
||||
ptr += 2;
|
||||
} else if (_soundOverride && sound > 0 && sound < 200) {
|
||||
memcpy(&_ovrCur, &_soundOverride[sound], sizeof(SoundOvrParameters));
|
||||
memset(&_soundOverride[sound], 0, sizeof(SoundOvrParameters));
|
||||
}
|
||||
|
||||
int type = ptr[13];
|
||||
|
||||
if (type == 0) {
|
||||
playPcmTrack(sound, ptr + 6);
|
||||
} else if (type == 1) {
|
||||
playEuphonyTrack(sound, ptr + 6);
|
||||
} else if (type == 2) {
|
||||
playCdaTrack(sound, ptr + 6);
|
||||
}
|
||||
memset(&_ovrCur, 0, sizeof(SoundOvrParameters));
|
||||
}
|
||||
|
||||
void Player_Towns_v1::stopSound(int sound) {
|
||||
if (sound == 0 || sound == _cdaCurrentSound) {
|
||||
_cdaCurrentSound = 0;
|
||||
_vm->_sound->stopCD();
|
||||
_vm->_sound->stopCDTimer();
|
||||
}
|
||||
|
||||
if (sound != 0 && sound == _eupCurrentSound) {
|
||||
_eupCurrentSound = 0;
|
||||
_eupLooping = false;
|
||||
_driver->stopParser();
|
||||
}
|
||||
|
||||
stopPcmTrack(sound);
|
||||
}
|
||||
|
||||
void Player_Towns_v1::stopAllSounds() {
|
||||
_cdaCurrentSound = 0;
|
||||
_vm->_sound->stopCD();
|
||||
_vm->_sound->stopCDTimer();
|
||||
|
||||
_eupCurrentSound = 0;
|
||||
_eupLooping = false;
|
||||
_driver->stopParser();
|
||||
|
||||
stopPcmTrack(0);
|
||||
}
|
||||
|
||||
int Player_Towns_v1::getSoundStatus(int sound) const {
|
||||
if (sound == _cdaCurrentSound)
|
||||
return _vm->_sound->pollCD();
|
||||
if (sound == _eupCurrentSound)
|
||||
return _driver->parserIsPlaying() ? 1 : 0;
|
||||
for (int i = 1; i < 9; i++) {
|
||||
if (_pcmCurrentSound[i].index == sound)
|
||||
return _driver->soundEffectIsPlaying(i + 0x3f) ? 1 : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Player_Towns_v1::doCommand(int numargs, int args[]) {
|
||||
int32 res = 0;
|
||||
|
||||
switch (args[0]) {
|
||||
case 2:
|
||||
_driver->intf()->callback(73, 0);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
restartLoopingSounds();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
startSound(args[1]);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
_vm->_sound->stopSound(args[1]);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
stopPcmTrack(0);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
startSoundEx(args[1], args[2], args[3], args[4]);
|
||||
break;
|
||||
|
||||
case 15:
|
||||
stopSoundSuspendLooping(args[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
warning("Player_Towns_v1::doCommand: Unknown command %d", args[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
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_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_v1::setSoundNote(int sound, int note) {
|
||||
if (_soundOverride && sound > 0 && sound < 200)
|
||||
_soundOverride[sound].note = note;
|
||||
}
|
||||
|
||||
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_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()
|
||||
};
|
||||
|
||||
ser->saveLoadEntries(this, cdEntries);
|
||||
|
||||
if (!_eupLooping && !_driver->parserIsPlaying())
|
||||
_eupCurrentSound = 0;
|
||||
|
||||
static const SaveLoadEntry eupEntries[] = {
|
||||
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);
|
||||
|
||||
Player_Towns::saveLoadWithSerializer(ser);
|
||||
}
|
||||
|
||||
void Player_Towns_v1::restoreAfterLoad() {
|
||||
setVolumeCD(_cdaVolLeft, _cdaVolRight);
|
||||
|
||||
if (_cdaCurrentSoundTemp) {
|
||||
uint8 *ptr = _vm->getResourceAddress(rtSound, _cdaCurrentSoundTemp) + 6;
|
||||
if (_vm->_game.version != 3)
|
||||
ptr += 2;
|
||||
|
||||
if (ptr[7] == 2) {
|
||||
playCdaTrack(_cdaCurrentSoundTemp, ptr, true);
|
||||
_cdaCurrentSound = _cdaCurrentSoundTemp;
|
||||
_cdaNumLoops = _cdaNumLoopsTemp;
|
||||
}
|
||||
}
|
||||
|
||||
if (_eupCurrentSound) {
|
||||
uint8 *ptr = _vm->getResourceAddress(rtSound, _eupCurrentSound) + 6;
|
||||
if (_vm->_game.version != 3)
|
||||
ptr += 2;
|
||||
|
||||
if (ptr[7] == 1) {
|
||||
setSoundVolume(_eupCurrentSound, _eupVolLeft, _eupVolRight);
|
||||
playEuphonyTrack(_eupCurrentSound, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
Player_Towns::restoreAfterLoad();
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue