aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
authorDavid Corrales2007-08-05 19:34:20 +0000
committerDavid Corrales2007-08-05 19:34:20 +0000
commit6856535010bd2fa4449bcfde1c88dc06cd46e26f (patch)
treeb81a2234c2beff0312c93e039d6cafda4babeca6 /engines/scumm
parent1400d28bfb37fc94f3c44dec0a4d0cef65fb8fb7 (diff)
parentec1803f838d5efc7decf75c05a1fb4a9633751e5 (diff)
downloadscummvm-rg350-6856535010bd2fa4449bcfde1c88dc06cd46e26f.tar.gz
scummvm-rg350-6856535010bd2fa4449bcfde1c88dc06cd46e26f.tar.bz2
scummvm-rg350-6856535010bd2fa4449bcfde1c88dc06cd46e26f.zip
Merged fsnode with trunk: r27971:28460
svn-id: r28462
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/charset.cpp109
-rw-r--r--engines/scumm/detection.cpp7
-rw-r--r--engines/scumm/detection_tables.h4
-rw-r--r--engines/scumm/gfx.cpp317
-rwxr-xr-xengines/scumm/gfxARM.s120
-rw-r--r--engines/scumm/imuse_digi/dimuse.cpp47
-rw-r--r--engines/scumm/imuse_digi/dimuse.h2
-rw-r--r--engines/scumm/imuse_digi/dimuse_script.cpp10
-rw-r--r--engines/scumm/imuse_digi/dimuse_sndmgr.cpp284
-rw-r--r--engines/scumm/imuse_digi/dimuse_sndmgr.h70
-rw-r--r--engines/scumm/imuse_digi/dimuse_track.cpp31
-rw-r--r--engines/scumm/input.cpp5
-rw-r--r--engines/scumm/module.mk5
-rw-r--r--engines/scumm/scumm-md5.h6
-rw-r--r--engines/scumm/scumm.cpp28
-rw-r--r--engines/scumm/scumm.h4
-rw-r--r--engines/scumm/smush/smush_player.cpp7
-rw-r--r--engines/scumm/sound.cpp15
-rw-r--r--engines/scumm/string.cpp16
19 files changed, 742 insertions, 345 deletions
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 28012e5759..2271bf53a1 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -48,6 +48,11 @@ better separation of the various modules.
void ScummEngine::loadCJKFont() {
Common::File fp;
_useCJKMode = false;
+ _textSurfaceMultiplier = 1;
+
+ if (_game.platform == Common::kPlatformSegaCD)
+ return;
+
if (_language == Common::JA_JPN && _game.version <= 5) { // FM-TOWNS v3 / v5 Kanji
int numChar = 256 * 32;
_2byteWidth = 16;
@@ -60,6 +65,7 @@ void ScummEngine::loadCJKFont() {
fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
fp.close();
}
+ _textSurfaceMultiplier = 2;
} else if (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN) {
int numChar = 0;
const char *fontFile = NULL;
@@ -76,7 +82,7 @@ void ScummEngine::loadCJKFont() {
case Common::ZH_TWN:
if (_game.id == GID_CMI) {
fontFile = "chinese.fnt";
- numChar = 1; //FIXME
+ numChar = 13630;
}
break;
default:
@@ -85,9 +91,26 @@ void ScummEngine::loadCJKFont() {
if (fontFile && fp.open(fontFile)) {
debug(2, "Loading CJK Font");
_useCJKMode = true;
- fp.seek(2, SEEK_CUR);
- _2byteWidth = fp.readByte();
- _2byteHeight = fp.readByte();
+ _textSurfaceMultiplier = 1; // No multiplication here
+
+ switch (_language) {
+ case Common::KO_KOR:
+ fp.seek(2, SEEK_CUR);
+ _2byteWidth = fp.readByte();
+ _2byteHeight = fp.readByte();
+ break;
+ case Common::JA_JPN:
+ _2byteWidth = 16;
+ _2byteHeight = 16;
+ break;
+ case Common::ZH_TWN:
+ _2byteWidth = 16;
+ _2byteHeight = 15;
+ // 0xFE -> 0x21. also compared with 0x0d. perhaps a newline
+ break;
+ default:
+ break;
+ }
_2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar];
fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
@@ -183,7 +206,7 @@ static int SJIStoFMTChunk(int f, int s) { //converts sjis code to fmt font offse
}
byte *ScummEngine::get2byteCharPtr(int idx) {
- switch (_language) {
+ switch (_language) {
case Common::KO_KOR:
idx = ((idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1;
break;
@@ -191,6 +214,43 @@ byte *ScummEngine::get2byteCharPtr(int idx) {
idx = SJIStoFMTChunk((idx % 256), (idx / 256));
break;
case Common::ZH_TWN:
+ {
+ int base = 0;
+ byte low = idx % 256;
+ int high = 0;
+
+ if (low >= 0x20 && low <= 0x7e) {
+ base = (low + low * 2 + 81012) * 5;
+ } else {
+ if (low >= 0xa1 && low <= 0xa3) {
+ base = 392820;
+ low += 0x5f;
+ } else if (low >= 0xa4 && low <= 0xc6) {
+ base = 0;
+ low += 0x5c;
+ } else if (low >= 0xc9 && low <= 0xf9) {
+ base = 162030;
+ low += 0x37;
+ } else {
+ base = 392820;
+ low = 0xff;
+ }
+
+ if (low != 0xff) {
+ high = idx / 256;
+ if (high >= 0x40 && high <= 0x7e) {
+ high -= 0x40;
+ } else {
+ high -= 0x62;
+ }
+
+ base += (low * 0x9d + high) * 30;
+ }
+ }
+
+ return _2byteFontPtr + base;
+ break;
+ }
default:
idx = 0;
}
@@ -311,7 +371,7 @@ int CharsetRenderer::getStringWidth(int arg, const byte *text) {
break;
}
} else {
- if (chr == '@')
+ if (chr == '@' && _vm->_language != Common::ZH_TWN)
continue;
if (chr == 255 || (_vm->_game.version <= 6 && chr == 254)) {
chr = text[pos++];
@@ -337,6 +397,15 @@ int CharsetRenderer::getStringWidth(int arg, const byte *text) {
continue;
}
}
+
+ // Some localizations may override colors
+ // See credits in Chinese COMI
+ if (chr == '^' && pos == 1) {
+ if (text[pos] == 'c') {
+ pos += 4;
+ chr = text[pos++];
+ }
+ }
}
if ((chr & 0x80) && _vm->_useCJKMode) {
pos++;
@@ -1257,18 +1326,18 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
_hasMask = true;
_textScreenID = vs->number;
}
- if (ignoreCharsetMask || !vs->hasTwoBuffers) {
+ if ((ignoreCharsetMask || !vs->hasTwoBuffers) && !(_vm->_useCJKMode && _vm->_textSurfaceMultiplier == 2)) {
dst = vs->getPixels(_left, drawTop);
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
} else {
- dst = (byte *)_vm->_textSurface.pixels + _top * _vm->_textSurface.pitch + _left;
+ dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier);
drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
}
if (_str.left > _left)
_str.left = _left;
- _left += origWidth;
+ _left += origWidth / _vm->_textSurfaceMultiplier;
if (_str.right < _left) {
_str.right = _left;
@@ -1276,8 +1345,8 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
_str.right++;
}
- if (_str.bottom < _top + height)
- _str.bottom = _top + height;
+ if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier)
+ _str.bottom = _top + height / _vm->_textSurfaceMultiplier;
}
void CharsetRendererV3::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
@@ -1391,8 +1460,8 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) {
_top += offsY;
_left += offsX;
- if (_left + origWidth > _right + 1 || _left < 0) {
- _left += origWidth;
+ if (_left + origWidth / _vm->_textSurfaceMultiplier > _right + 1 || _left < 0) {
+ _left += origWidth / _vm->_textSurfaceMultiplier;
_top -= offsY;
return;
}
@@ -1424,7 +1493,7 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) {
printCharIntern(is2byte, charPtr, origWidth, origHeight, width, height, vs, ignoreCharsetMask);
- _left += origWidth;
+ _left += origWidth / _vm->_textSurfaceMultiplier;
if (_str.right < _left) {
_str.right = _left;
@@ -1432,8 +1501,8 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) {
_str.right++;
}
- if (_str.bottom < _top + height)
- _str.bottom = _top + height;
+ if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier)
+ _str.bottom = _top + height / _vm->_textSurfaceMultiplier;
_top -= offsY;
}
@@ -1473,12 +1542,12 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr,
} else {
Graphics::Surface dstSurface;
Graphics::Surface backSurface;
- if (ignoreCharsetMask || !vs->hasTwoBuffers) {
+ if ((ignoreCharsetMask || !vs->hasTwoBuffers) && !(_vm->_useCJKMode && _vm->_textSurfaceMultiplier == 2)) {
dstSurface = *vs;
dstPtr = vs->getPixels(_left, drawTop);
} else {
dstSurface = _vm->_textSurface;
- dstPtr = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch + _left;
+ dstPtr = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch * _vm->_textSurfaceMultiplier + _left * _vm->_textSurfaceMultiplier;
}
if (_blitAlso && vs->hasTwoBuffers) {
@@ -1717,6 +1786,10 @@ void CharsetRendererNut::printChar(int chr, bool ignoreCharsetMask) {
if (_str.left > _left)
_str.left = _left;
+ // Original keeps glyph width and character dimensions separately
+ if (_vm->_language == Common::ZH_TWN && width == 16)
+ width = 17;
+
_left += width;
if (_str.right < shadow.right)
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index e9430337ff..be830cab64 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -231,14 +231,21 @@ static Common::Language detectLanguage(const FSList &fslist, byte id) {
switch (size) {
case 439080: // 2daf3db71d23d99d19fc9a544fcf6431
return Common::EN_ANY;
+ case 322602: // caba99f4f5a0b69963e5a4d69e6f90af
+ return Common::ZH_TWN;
case 493252: // 5d59594b24f3f1332e7d7e17455ed533
return Common::DE_DEU;
case 461746: // 35bbe0e4d573b318b7b2092c331fd1fa
return Common::FR_FRA;
case 443439: // 4689d013f67aabd7c35f4fd7c4b4ad69
return Common::IT_ITA;
+ case 398613: // d1f5750d142d34c4c8f1f330a1278709
+ return Common::KO_KOR;
case 440586: // 5a1d0f4fa00917bdbfe035a72a6bba9d
return Common::PT_BRA;
+ case 454457: // 0e5f450ec474a30254c0e36291fb4ebd
+ case 394083: // ad684ca14c2b4bf4c21a81c1dbed49bc
+ return Common::RU_RUS;
case 449787: // 64f3fe479d45b52902cf88145c41d172
return Common::ES_ESP;
}
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 246126611e..acde4e5ad0 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -79,6 +79,7 @@ static const PlainGameDescriptor gameDescriptions[] = {
{ "comi", "The Curse of Monkey Island" },
#endif
+ { "brstorm", "Bear Stormin'" },
{ "fbear", "Fatty Bear's Birthday Surprise" },
{ "fbpack", "Fatty Bear's Fun Pack" },
{ "funpack", "Putt-Putt's Fun Pack" },
@@ -248,6 +249,7 @@ static const GameSettings gameVariantsTable[] = {
{"funpack", 0, 0, GID_FUNPACK, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
{"fbpack", 0, 0, GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
+ {"brstorm", 0, 0, GID_FBEAR, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
{"fbear", "HE 61", 0, GID_FBEAR, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
{"fbear", "HE 70", 0, GID_FBEAR, 6, 70, MDT_NONE, GF_USE_KEY, Common::kPlatformWindows},
@@ -461,6 +463,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "fbpack", "fbpack", kGenHEPC, UNK_LANG, UNK, 0 },
{ "funpack", "funpack", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "brstorm", "brstorm", kGenHEPC, UNK_LANG, UNK, 0 },
+
{ "fbear", "fbear", kGenHEPC, UNK_LANG, UNK, 0 },
{ "fbear", "fbdemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "fbear", "Fatty Bear Demo", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 3547986ce3..c1e06609b9 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -35,9 +35,12 @@
#include "scumm/usage_bits.h"
#include "scumm/he/wiz_he.h"
#include "scumm/util.h"
-#ifdef __DS__
-#include "blitters.h"
-#endif
+
+#ifdef USE_ARM_GFX_ASM
+extern "C" void DrawStripToScreenARM(int height, int width, byte const* text, byte const* src, byte* dst,
+ int vsPitch, int vmScreenWidth, int textSurfacePitch);
+extern "C" void Copy8ColARM(byte* dst, int dstPitch, const byte* src, int height);
+#endif /* USE_ARM_GFX_ASM */
namespace Scumm {
@@ -47,6 +50,7 @@ static void fill(byte *dst, int dstPitch, byte color, int w, int h);
static void copy8Col(byte *dst, int dstPitch, const byte *src, int height);
static void clear8Col(byte *dst, int dstPitch, int height);
+static void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height);
struct StripTable {
int offsets[160];
@@ -535,21 +539,18 @@ void ScummEngine::updateDirtyScreen(VirtScreenNumber slot) {
*/
void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int bottom) {
- if (bottom <= top)
+ // Short-circuit if nothing has to be drawn
+ if (bottom <= top || top >= vs->h)
return;
- if (top >= vs->h)
- return;
-
- assert(top >= 0 && bottom <= vs->h); // Paranoia checks
+ // Some paranoia checks
+ assert(top >= 0 && bottom <= vs->h);
assert(x >= 0 && width <= vs->pitch);
assert(_textSurface.pixels);
- assert(_compositeBuf);
+ // Perform some clipping
if (width > vs->w - x)
width = vs->w - x;
-
- // Clip to the visible part of the scene
if (top < _screenTop)
top = _screenTop;
if (bottom > _screenTop + _screenHeight)
@@ -559,64 +560,112 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
int y = vs->topline + top - _screenTop;
int height = bottom - top;
- if (height <= 0 || width <= 0)
+ if (width <= 0 || height <= 0)
return;
- // Compute screen etc. buffer pointers
const byte *src = vs->getPixels(x, top);
- byte *dst = _compositeBuf + x + y * _screenWidth;
+ int m = _textSurfaceMultiplier;
+ byte *dst;
+ int vsPitch;
+ int pitch = vs->pitch;
+
+ if (_useCJKMode && _textSurfaceMultiplier == 2) {
+ dst = _fmtownsBuf;
+
+ scale2x(dst, _screenWidth * m, src, vs->pitch, width, height);
+ src = dst;
+ vsPitch = _screenWidth * m - width * m;
+
+ } else {
+ vsPitch = vs->pitch - width;
+ }
+
+ dst = _compositeBuf;
+
if (_game.version < 7) {
- // Handle the text mask in older games; newer (V7/V8) games do not use it anymore.
- const byte *text = (byte *)_textSurface.getBasePtr(x, y);
-
-#ifdef __DS__
- DS::asmDrawStripToScreen(height, width, text, src, dst, vs->pitch, _screenWidth, _textSurface.pitch);
-#else
+ // For The Dig, FT and COMI, we just blit everything to the screen at once.
+ // For older games, things are more complicated. First off, we need to
+ // deal with the _textSurface, which needs to be composited over the
+ // screen contents. Secondly, a rendering mode might be active, which
+ // means a filter has to be applied.
+
+ // Compute pointer to the text surface
+ assert(_compositeBuf);
+ const byte *text = (byte *)_textSurface.getBasePtr(x * m, y * m);
+
+ // The values x, width, etc. are all multiples of 8 at this point,
+ // so loop unrolloing might be a good idea...
+ assert(0 == ((long)text & 3));
+ assert(0 == (width & 3));
+
// Compose the text over the game graphics
- for (int h = 0; h < height; ++h) {
- for (int w = 0; w < width; ++w) {
- if (text[w] == CHARSET_MASK_TRANSPARENCY)
- dst[w] = src[w];
- else
- dst[w] = text[w];
+
+ // TODO: Optimize this code. There are several things that come immediately to mind:
+ // (1) Loop unrolling: We could read 4 or even 8 pixels at once, since everything is
+ // a multiple of 8 here.
+ // (2) More ASM versions (in particular, the ARM code for the NDS could be used on
+ // all ARM systems, couldn't it?)
+ // (3) Better encoding of the text surface data. This is the one with the biggest
+ // potential.
+ // (a) Keep an "isEmpty" marker for each pixel row in the _textSurface. The idea
+ // is that most rows won't contain any text data, so we can just use memcpy.
+ // (b) RLE encode the _textSurface row-wise. This is an improved variant of (a),
+ // but also more complicated to implement, and incurs a bigger overhead when
+ // writing to the text surface.
+#ifdef ARM_USE_GFX_ASM
+ DrawStripToScreenARM(height, width, text, src, dst, vs->pitch, width, _textSurface.pitch);
+#else
+ for (int h = 0; h < height * m; ++h) {
+ for (int w = 0; w < width * m; ++w) {
+ byte tmp = *text++;
+ if (tmp == CHARSET_MASK_TRANSPARENCY)
+ tmp = *src;
+ *dst++ = tmp;
+ src++;
}
- src += vs->pitch;
- dst += _screenWidth;
- text += _textSurface.pitch;
+ src += vsPitch;
+ text += _textSurface.pitch - width * m;
}
#endif
- } else {
- // Just do a simple blit in V7/V8 games.
- blit(dst, _screenWidth, src, vs->pitch, width, height);
- }
-
- if (_renderMode == Common::kRenderCGA)
- ditherCGA(_compositeBuf + x + y * _screenWidth, _screenWidth, x, y, width, height);
+ src = _compositeBuf;
+ pitch = width;
+
+ if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
+ ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height);
+
+ src = _herculesBuf + x + y * Common::kHercW;
+ pitch = Common::kHercW;
+
+ // center image on the screen
+ x += (Common::kHercW - _screenWidth * 2) / 2; // (720 - 320*2)/2 = 40
+ } else if (_useCJKMode && m == 2) {
+ pitch *= m;
+ x *= m;
+ y *= m;
+ width *= m;
+ height *= m;
+ } else {
+ if (_renderMode == Common::kRenderCGA)
+ ditherCGA(_compositeBuf, width, x, y, width, height);
+
+ // HACK: This is dirty hack which renders narrow NES rooms centered
+ // NES can address negative number strips and that poses problem for
+ // our code. So instead of adding zillions of fixes and potentially
+ // breaking other games, we shift it right at the rendering stage.
+ if ((_game.platform == Common::kPlatformNES) && (((_NESStartStrip > 0) && (vs->number == kMainVirtScreen)) || (vs->number == kTextVirtScreen))) {
+ x += 16;
+ while (x + width >= _screenWidth)
+ width -= 16;
+ if (width < 0)
+ return;
+ }
- if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- ditherHerc(_compositeBuf + x + y * _screenWidth, _herculesBuf, _screenWidth, &x, &y, &width, &height);
- // center image on the screen
- _system->copyRectToScreen(_herculesBuf + x + y * Common::kHercW,
- Common::kHercW, x + (Common::kHercW - _screenWidth * 2) / 2, y, width, height);
- } else {
- // Finally blit the whole thing to the screen
- int x1 = x;
-
- // HACK: This is dirty hack which renders narrow NES rooms centered
- // NES can address negative number strips and that poses problem for
- // our code. So instead of adding zillions of fixes and potentially
- // breaking other games, we shift it right at the rendering stage.
- if ((_game.platform == Common::kPlatformNES) && (((_NESStartStrip > 0) && (vs->number == kMainVirtScreen)) || (vs->number == kTextVirtScreen))) {
- x += 16;
- while (x + width >= _screenWidth)
- width -= 16;
- if (width < 0)
- return;
}
-
- _system->copyRectToScreen(_compositeBuf + x1 + y * _screenWidth, _screenWidth, x, y, width, height);
}
+
+ // Finally blit the whole thing to the screen
+ _system->copyRectToScreen(src, pitch, x, y, width, height);
}
// CGA
@@ -644,10 +693,10 @@ void ScummEngine::ditherCGA(byte *dst, int dstPitch, int x, int y, int width, in
for (int y1 = 0; y1 < height; y1++) {
ptr = dst + y1 * dstPitch;
- idx1 = (y + y1) % 2;
-
if (_game.version == 2)
idx1 = 0;
+ else
+ idx1 = (y + y1) % 2;
for (int x1 = 0; x1 < width; x1++) {
idx2 = (x + x1) % 2;
@@ -666,39 +715,52 @@ void ScummEngine::ditherCGA(byte *dst, int dstPitch, int x, int y, int width, in
// dd cccc0
// cccc1
// dddd0
-void ScummEngine::ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height) const {
+void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height) {
byte *srcptr, *dstptr;
- int xo = *x, yo = *y, widtho = *width, heighto = *height;
- int idx1, idx2, dsty = 0, y1;
+ const int xo = *x, yo = *y, widtho = *width, heighto = *height;
+ int dsty = yo*2 - yo/4;
- // calculate dsty
- for (y1 = 0; y1 < yo; y1++) {
- dsty += 2;
- if (y1 % 4 == 3)
- dsty--;
- }
- *y = dsty;
- *x *= 2;
- *width *= 2;
- *height = 0;
+ for (int y1 = 0; y1 < heighto;) {
+ assert(dsty < Common::kHercH);
- for (y1 = 0; y1 < heighto;) {
srcptr = src + y1 * srcPitch;
dstptr = hercbuf + dsty * Common::kHercW + xo * 2;
- assert(dstptr < hercbuf + Common::kHercW * Common::kHercH + widtho * 2);
-
- idx1 = (dsty % 7) % 2;
+ const int idx1 = (dsty % 7) % 2;
for (int x1 = 0; x1 < widtho; x1++) {
- idx2 = (xo + x1) % 2;
- *dstptr++ = cgaDither[idx1][idx2][*srcptr & 0xF] >> 1;
- *dstptr++ = cgaDither[idx1][idx2][*srcptr & 0xF] & 0x1;
+ const int idx2 = (xo + x1) % 2;
+ const byte tmp = cgaDither[idx1][idx2][*srcptr & 0xF];
+ *dstptr++ = tmp >> 1;
+ *dstptr++ = tmp & 0x1;
srcptr++;
}
if (idx1 || dsty % 7 == 6)
y1++;
dsty++;
- (*height)++;
+ }
+
+ *x *= 2;
+ *y = yo*2 - yo/4;
+ *width *= 2;
+ *height = dsty - *y;
+}
+
+void ScummEngine::scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
+ byte *dstL1 = dst;
+ byte *dstL2 = dst + dstPitch;
+
+ int dstAdd = dstPitch * 2 - w * 2;
+ int srcAdd = srcPitch - w;
+
+ while (h--) {
+ for (int x = 0; x < w; ++x, dstL1 += 2, dstL2 += 2) {
+ uint16 col = *src++;
+ col |= col << 8;
+ *(uint16*)(dstL1) = col;
+ *(uint16*)(dstL2) = col;
+ }
+ dstL1 += dstAdd; dstL2 += dstAdd;
+ src += srcAdd;
}
}
@@ -1004,11 +1066,14 @@ static void fill(byte *dst, int dstPitch, byte color, int w, int h) {
}
}
+#ifdef ARM_USE_GFX_ASM
+
+#define copy8Col(A,B,C,D) copy8ColARM(A,B,C,D)
+
+#else
+
static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) {
-#ifndef __DS__
-
-
do {
#if defined(SCUMM_NEED_ALIGNMENT)
memcpy(dst, src, 8);
@@ -1019,12 +1084,10 @@ static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) {
dst += dstPitch;
src += dstPitch;
} while (--height);
-#else
- DS::asmCopy8Col(dst, dstPitch, src, height);
-#endif
-
}
+#endif /* ARM_USE_GFX_ASM */
+
static void clear8Col(byte *dst, int dstPitch, int height) {
do {
#if defined(SCUMM_NEED_ALIGNMENT)
@@ -1098,8 +1161,8 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) {
error("can only copy bg to main window");
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
if (_charset->_hasMask) {
- byte *mask = (byte *)_textSurface.getBasePtr(x, y - _screenTop);
- fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
+ byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop) * _textSurfaceMultiplier);
+ fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier);
}
} else if (_game.heversion >= 71) {
// Flags are used for different methods in HE games
@@ -3343,7 +3406,17 @@ void ScummEngine::dissolveEffect(int width, int height) {
for (i = 0; i < w * h; i++) {
x = offsets[i] % vs->pitch;
y = offsets[i] / vs->pitch;
- _system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height);
+
+ if (_useCJKMode && _textSurfaceMultiplier == 2) {
+ int m = _textSurfaceMultiplier;
+ byte *dst = _fmtownsBuf + x * m + y * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, vs->getPixels(x, y), vs->pitch, width, height);
+
+ _system->copyRectToScreen(dst, _screenWidth * m, x * m, (y + vs->topline) * m, width * m, height * m);
+ } else {
+ _system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height);
+ }
+
if (++blits >= blits_before_refresh) {
blits = 0;
@@ -3372,16 +3445,30 @@ void ScummEngine::scrollEffect(int dir) {
step = (step * delay) / kScrolltime;
+ byte *src;
+ int m = _textSurfaceMultiplier;
+ int vsPitch = vs->pitch;
+
switch (dir) {
case 0:
//up
y = 1 + step;
while (y < vs->h) {
moveScreen(0, -step, vs->h);
- _system->copyRectToScreen(vs->getPixels(0, y - step),
- vs->pitch,
- 0, vs->h - step,
- vs->w, step);
+
+ src = vs->getPixels(0, y - step);
+ if (_useCJKMode && m == 2) {
+ int x1 = 0, y1 = vs->h - step;
+ byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, src, vs->pitch, vs->w, step);
+ src = dst;
+ vsPitch = _screenWidth * 2;
+ }
+
+ _system->copyRectToScreen(src,
+ vsPitch,
+ 0 * m, (vs->h - step) * m,
+ vs->w * m, step * m);
_system->updateScreen();
waitForTimer(delay);
@@ -3393,10 +3480,18 @@ void ScummEngine::scrollEffect(int dir) {
y = 1 + step;
while (y < vs->h) {
moveScreen(0, step, vs->h);
- _system->copyRectToScreen(vs->getPixels(0, vs->h - y),
- vs->pitch,
+ src = vs->getPixels(0, vs->h - y);
+ if (_useCJKMode && m == 2) {
+ int x1 = 0, y1 = 0;
+ byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, src, vs->pitch, vs->w, step);
+ src = dst;
+ vsPitch = _screenWidth * 2;
+ }
+ _system->copyRectToScreen(src,
+ vsPitch,
0, 0,
- vs->w, step);
+ vs->w * m, step * m);
_system->updateScreen();
waitForTimer(delay);
@@ -3408,10 +3503,18 @@ void ScummEngine::scrollEffect(int dir) {
x = 1 + step;
while (x < vs->w) {
moveScreen(-step, 0, vs->h);
- _system->copyRectToScreen(vs->getPixels(x - step, 0),
- vs->pitch,
- vs->w - step, 0,
- step, vs->h);
+ src = vs->getPixels(x - step, 0);
+ if (_useCJKMode && m == 2) {
+ int x1 = vs->w - step, y1 = 0;
+ byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, src, vs->pitch, step, vs->h);
+ src = dst;
+ vsPitch = _screenWidth * 2;
+ }
+ _system->copyRectToScreen(src,
+ vsPitch,
+ (vs->w - step) * m, 0,
+ step * m, vs->h * m);
_system->updateScreen();
waitForTimer(delay);
@@ -3423,8 +3526,16 @@ void ScummEngine::scrollEffect(int dir) {
x = 1 + step;
while (x < vs->w) {
moveScreen(step, 0, vs->h);
- _system->copyRectToScreen(vs->getPixels(vs->w - x, 0),
- vs->pitch,
+ src = vs->getPixels(vs->w - x, 0);
+ if (_useCJKMode && m == 2) {
+ int x1 = 0, y1 = 0;
+ byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+ scale2x(dst, _screenWidth * m, src, vs->pitch, step, vs->h);
+ src = dst;
+ vsPitch = _screenWidth * 2;
+ }
+ _system->copyRectToScreen(src,
+ vsPitch,
0, 0,
step, vs->h);
_system->updateScreen();
diff --git a/engines/scumm/gfxARM.s b/engines/scumm/gfxARM.s
new file mode 100755
index 0000000000..fa2457fb29
--- /dev/null
+++ b/engines/scumm/gfxARM.s
@@ -0,0 +1,120 @@
+@ ScummVM Scumm Interpreter
+@ Copyright (C) 2007 The ScummVM project
+@
+@ This program is free software@ you can redistribute it and/or
+@ modify it under the terms of the GNU General Public License
+@ as published by the Free Software Foundation@ either version 2
+@ of the License, or (at your option) any later version.
+@
+@ This program is distributed in the hope that it will be useful,
+@ but WITHOUT ANY WARRANTY; without even the implied warranty of
+@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+@ GNU General Public License for more details.
+@
+@ You should have received a copy of the GNU General Public License
+@ along with this program@ if not, write to the Free Software
+@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+@
+@ $URL: $
+@ $Id: $
+@
+@ @author Robin Watts (robin@wss.co.uk)
+
+ .text
+
+ .global asmDrawStripToScreen
+
+ @ ARM implementation of asmDrawStripToScreen.
+ @
+ @ C prototype would be:
+ @
+ @ extern "C" void asmDrawStripToScreen(int height,
+ @ int width,
+ @ byte const *text,
+ @ byte const *src,
+ @ byte *dst,
+ @ int vsPitch,
+ @ int vsScreenWidth,
+ @ int textSurfacePitch);
+ @
+ @ In addition, we assume that text, src and dst are all word (4 byte)
+ @ aligned. This is the same assumption that the old 'inline' version
+ @ made.
+asmDrawStripToScreen:
+ @ r0 = height
+ @ r1 = width
+ @ r2 = text
+ @ r3 = src
+ MOV r12,r13
+ STMFD r13!,{r4-r7,r9-r11,R14}
+ LDMIA r12,{r4,r5,r6,r7}
+ @ r4 = dst
+ @ r5 = vsPitch
+ @ r6 = vmScreenWidth
+ @ r7 = textSurfacePitch
+
+ CMP r0,#0 @ If height<=0
+ MOVLE r0,#1 @ height=1
+ CMP r1,#4 @ If width<4
+ BLT end @ return
+
+ @ Width &= ~4 ? What's that about then? Width &= ~3 I could have
+ @ understood...
+ BIC r1,r1,#4
+
+ SUB r5,r5,r1 @ vsPitch -= width
+ SUB r6,r6,r1 @ vmScreenWidth -= width
+ SUB r7,r7,r1 @ textSurfacePitch -= width
+ MOV r10,#253
+ ORR r10,r10,r10,LSL #8
+ ORR r10,r10,r10,LSL #16 @ r10 = mask
+yLoop:
+ MOV r14,r1 @ r14 = width
+xLoop:
+ LDR r12,[r2],#4 @ r12 = [text]
+ LDR r11,[r3],#4 @ r11 = [src]
+ CMP r12,r10
+ BNE singleByteCompare
+ SUBS r14,r14,#4
+ STR r11,[r4], #4 @ r4 = [dst]
+ BGT xLoop
+
+ ADD r2,r2,r7 @ text += textSurfacePitch
+ ADD r3,r3,r5 @ src += vsPitch
+ ADD r4,r4,r6 @ dst += vmScreenWidth
+ SUBS r0,r0,#1
+ BGT yLoop
+ LDMFD r13!,{r4-r7,r9-r11,PC}
+
+singleByteCompare:
+ MOV r9,r12,LSR #24 @ r9 = 1st byte of [text]
+ CMP r9,r10,LSR #24 @ if (r9 == mask)
+ MOVEQ r9,r11,LSR #24 @ r9 = 1st byte of [src]
+ ORR r12,r9,r12,LSL #8 @ r12 = combine r9 and r12
+
+ MOV r9,r12,LSR #24 @ r9 = 1st byte of [text]
+ CMP r9,r10,LSR #24 @ if (r9 == mask)
+ MOVEQ r9,r11,LSR #24 @ r9 = 1st byte of [src]
+ ORR r12,r9,r12,LSL #8 @ r12 = combine r9 and r12
+
+ MOV r9,r12,LSR #24 @ r9 = 1st byte of [text]
+ CMP r9,r10,LSR #24 @ if (r9 == mask)
+ MOVEQ r9,r11,LSR #24 @ r9 = 1st byte of [src]
+ ORR r12,r9,r12,LSL #8 @ r12 = combine r9 and r12
+
+ MOV r9,r12,LSR #24 @ r9 = 1st byte of [text]
+ CMP r9,r10,LSR #24 @ if (r9 == mask)
+ MOVEQ r9,r11,LSR #24 @ r9 = 1st byte of [src]
+ ORR r12,r9,r12,LSL #8 @ r12 = combine r9 and r12
+
+ STR r12,[r4],#4
+ SUBS r14,r14,#4
+ BGT xLoop
+
+ ADD r2,r2,r7 @ text += textSurfacePitch
+ ADD r3,r3,r5 @ src += vsPitch
+ ADD r4,r4,r6 @ dst += vmScreenWidth
+ SUBS r0,r0,#1
+ BGT yLoop
+end:
+ LDMFD r13!,{r4-r7,r9-r11,PC}
diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp
index 0221657966..6d2e7dd217 100644
--- a/engines/scumm/imuse_digi/dimuse.cpp
+++ b/engines/scumm/imuse_digi/dimuse.cpp
@@ -166,10 +166,10 @@ void IMuseDigital::saveOrLoad(Serializer *ser) {
continue;
}
- track->soundHandle = _sound->openSound(track->soundId,
+ track->soundDesc = _sound->openSound(track->soundId,
track->soundName, track->soundType,
track->volGroupId, -1);
- if (!track->soundHandle) {
+ if (!track->soundDesc) {
warning("IMuseDigital::saveOrLoad: Can't open sound so will not be resumed, propably on diffrent CD");
track->streamSou = NULL;
track->stream = NULL;
@@ -180,14 +180,14 @@ void IMuseDigital::saveOrLoad(Serializer *ser) {
if (track->sndDataExtComp) {
track->regionOffset = 0;
}
- track->sndDataExtComp = _sound->isSndDataExtComp(track->soundHandle);
+ track->sndDataExtComp = _sound->isSndDataExtComp(track->soundDesc);
if (track->sndDataExtComp) {
track->regionOffset = 0;
}
- track->dataOffset = _sound->getRegionOffset(track->soundHandle, track->curRegion);
- int bits = _sound->getBits(track->soundHandle);
- int channels = _sound->getChannels(track->soundHandle);
- int freq = _sound->getFreq(track->soundHandle);
+ track->dataOffset = _sound->getRegionOffset(track->soundDesc, track->curRegion);
+ int bits = _sound->getBits(track->soundDesc);
+ int channels = _sound->getChannels(track->soundDesc);
+ int freq = _sound->getFreq(track->soundDesc);
track->feedSize = freq * channels;
track->mixerFlags = 0;
if (channels == 2)
@@ -221,6 +221,7 @@ void IMuseDigital::saveOrLoad(Serializer *ser) {
type = Audio::Mixer::kMusicSoundType;
_mixer->playInputStream(type, &track->mixChanHandle, track->stream, -1, vol, pan, false);
+ _mixer->pauseHandle(track->mixChanHandle, true);
}
}
}
@@ -284,8 +285,8 @@ void IMuseDigital::callback() {
continue;
}
- int bits = _sound->getBits(track->soundHandle);
- int channels = _sound->getChannels(track->soundHandle);
+ int bits = _sound->getBits(track->soundDesc);
+ int channels = _sound->getChannels(track->soundDesc);
int32 feedSize = track->feedSize / _callbackFps;
@@ -316,12 +317,12 @@ void IMuseDigital::callback() {
track->dataMod12Bit = feedSize - tmpLength12Bits;
int32 tmpOffset = (track->regionOffset * 3) / 4;
- int tmpFeedSize = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &tmpPtr, tmpOffset, tmpFeedSize12Bits);
+ int tmpFeedSize = _sound->getDataFromRegion(track->soundDesc, track->curRegion, &tmpPtr, tmpOffset, tmpFeedSize12Bits);
curFeedSize = BundleCodecs::decode12BitsSample(tmpPtr, &tmpSndBufferPtr, tmpFeedSize);
free(tmpPtr);
} else if (bits == 16) {
- curFeedSize = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &tmpSndBufferPtr, track->regionOffset, feedSize);
+ curFeedSize = _sound->getDataFromRegion(track->soundDesc, track->curRegion, &tmpSndBufferPtr, track->regionOffset, feedSize);
if (channels == 1) {
curFeedSize &= ~1;
}
@@ -329,7 +330,7 @@ void IMuseDigital::callback() {
curFeedSize &= ~3;
}
} else if (bits == 8) {
- curFeedSize = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &tmpSndBufferPtr, track->regionOffset, feedSize);
+ curFeedSize = _sound->getDataFromRegion(track->soundDesc, track->curRegion, &tmpSndBufferPtr, track->regionOffset, feedSize);
if (channels == 2) {
curFeedSize &= ~1;
}
@@ -346,7 +347,7 @@ void IMuseDigital::callback() {
} else
delete[] tmpSndBufferPtr;
- if (_sound->isEndOfRegion(track->soundHandle, track->curRegion)) {
+ if (_sound->isEndOfRegion(track->soundDesc, track->curRegion)) {
switchToNextRegion(track);
if (track->toBeRemoved)
break;
@@ -379,7 +380,7 @@ void IMuseDigital::switchToNextRegion(Track *track) {
return;
}
- int num_regions = _sound->getNumRegions(track->soundHandle);
+ int num_regions = _sound->getNumRegions(track->soundDesc);
if (++track->curRegion == num_regions) {
track->toBeRemoved = true;
@@ -387,22 +388,22 @@ void IMuseDigital::switchToNextRegion(Track *track) {
return;
}
- ImuseDigiSndMgr::soundStruct *soundHandle = track->soundHandle;
- int jumpId = _sound->getJumpIdByRegionAndHookId(soundHandle, track->curRegion, track->curHookId);
+ ImuseDigiSndMgr::SoundDesc *soundDesc = track->soundDesc;
+ int jumpId = _sound->getJumpIdByRegionAndHookId(soundDesc, track->curRegion, track->curHookId);
if (jumpId == -1)
- jumpId = _sound->getJumpIdByRegionAndHookId(soundHandle, track->curRegion, 0);
+ jumpId = _sound->getJumpIdByRegionAndHookId(soundDesc, track->curRegion, 0);
if (jumpId != -1) {
- int region = _sound->getRegionIdByJumpId(soundHandle, jumpId);
+ int region = _sound->getRegionIdByJumpId(soundDesc, jumpId);
assert(region != -1);
- int sampleHookId = _sound->getJumpHookId(soundHandle, jumpId);
+ int sampleHookId = _sound->getJumpHookId(soundDesc, jumpId);
assert(sampleHookId != -1);
- int fadeDelay = (60 * _sound->getJumpFade(soundHandle, jumpId)) / 1000;
+ int fadeDelay = (60 * _sound->getJumpFade(soundDesc, jumpId)) / 1000;
if (sampleHookId != 0) {
if (track->curHookId == sampleHookId) {
if (fadeDelay != 0) {
Track *fadeTrack = cloneToFadeOutTrack(track, fadeDelay);
if (fadeTrack) {
- fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundHandle, fadeTrack->curRegion);
+ fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundDesc, fadeTrack->curRegion);
fadeTrack->regionOffset = 0;
debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
fadeTrack->curHookId = 0;
@@ -416,7 +417,7 @@ void IMuseDigital::switchToNextRegion(Track *track) {
if (fadeDelay != 0) {
Track *fadeTrack = cloneToFadeOutTrack(track, fadeDelay);
if (fadeTrack) {
- fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundHandle, fadeTrack->curRegion);
+ fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundDesc, fadeTrack->curRegion);
fadeTrack->regionOffset = 0;
debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
}
@@ -427,7 +428,7 @@ void IMuseDigital::switchToNextRegion(Track *track) {
}
debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
- track->dataOffset = _sound->getRegionOffset(soundHandle, track->curRegion);
+ track->dataOffset = _sound->getRegionOffset(soundDesc, track->curRegion);
track->regionOffset = 0;
}
diff --git a/engines/scumm/imuse_digi/dimuse.h b/engines/scumm/imuse_digi/dimuse.h
index 1b088298df..dca9baac60 100644
--- a/engines/scumm/imuse_digi/dimuse.h
+++ b/engines/scumm/imuse_digi/dimuse.h
@@ -98,7 +98,7 @@ private:
int32 dataMod12Bit; // value used between all callback to align 12 bit source of data
int32 mixerFlags; // flags for sound mixer's channel (kFlagStereo, kFlag16Bits, kFlagReverseStereo, kFlagUnsigned, kFlagLittleEndian)
- ImuseDigiSndMgr::soundStruct *soundHandle; // sound handle used by iMuse sound manager
+ ImuseDigiSndMgr::SoundDesc *soundDesc; // sound handle used by iMuse sound manager
Audio::SoundHandle mixChanHandle; // sound mixer's channel handle
Audio::AppendableAudioStream *stream; // sound mixer's audio stream handle for *.la1 and *.bun
Audio::AudioStream *streamSou; // sound mixer's audio stream handle for *.sou
diff --git a/engines/scumm/imuse_digi/dimuse_script.cpp b/engines/scumm/imuse_digi/dimuse_script.cpp
index 186d04483e..ddc0cd5107 100644
--- a/engines/scumm/imuse_digi/dimuse_script.cpp
+++ b/engines/scumm/imuse_digi/dimuse_script.cpp
@@ -179,8 +179,8 @@ void IMuseDigital::flushTracks() {
_mixer->stopHandle(track->mixChanHandle);
delete track->stream;
track->stream = NULL;
- _sound->closeSound(track->soundHandle);
- track->soundHandle = NULL;
+ _sound->closeSound(track->soundDesc);
+ track->soundDesc = NULL;
track->used = false;
}
} else if (track->streamSou) {
@@ -245,7 +245,7 @@ void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width
for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
Track *track = _track[l];
if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- _sound->getSyncSizeAndPtrById(track->soundHandle, syncId, sync_size, &sync_ptr);
+ _sound->getSyncSizeAndPtrById(track->soundDesc, syncId, sync_size, &sync_ptr);
if ((sync_size != 0) && (sync_ptr != NULL)) {
sync_size /= 4;
while (sync_size--) {
@@ -396,8 +396,8 @@ void IMuseDigital::stopAllSounds() {
_mixer->stopHandle(track->mixChanHandle);
delete track->stream;
track->stream = NULL;
- _sound->closeSound(track->soundHandle);
- track->soundHandle = NULL;
+ _sound->closeSound(track->soundDesc);
+ track->soundDesc = NULL;
} else if (track->streamSou) {
_mixer->stopHandle(track->mixChanHandle);
delete track->streamSou;
diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
index ce963eaeea..be80cb73e8 100644
--- a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/util.h"
+#include "sound/flac.h"
#include "sound/voc.h"
#include "sound/vorbis.h"
#include "sound/mp3.h"
@@ -40,7 +41,7 @@ namespace Scumm {
ImuseDigiSndMgr::ImuseDigiSndMgr(ScummEngine *scumm) {
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
- memset(&_sounds[l], 0, sizeof(soundStruct));
+ memset(&_sounds[l], 0, sizeof(SoundDesc));
}
_vm = scumm;
_disk = 0;
@@ -88,7 +89,7 @@ void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, i
} while (tag != MKID_BE('DATA'));
}
-void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::File *file, soundStruct *sound, int32 offset, int32 size) {
+void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::File *file, SoundDesc *sound, int32 offset, int32 size) {
int l;
file->seek(offset, SEEK_SET);
@@ -104,11 +105,11 @@ void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::File *file, soundStruct *soun
sound->numRegions = file->readUint32BE();
sound->numJumps = file->readUint32BE();
sound->numSyncs = file->readUint32BE();
- sound->region = (_region *)malloc(sizeof(_region) * sound->numRegions);
+ sound->region = new Region[sound->numRegions];
assert(sound->region);
- sound->jump = (_jump *)malloc(sizeof(_jump) * sound->numJumps);
+ sound->jump = new Jump[sound->numJumps];
assert(sound->jump);
- sound->sync = (_sync *)malloc(sizeof(_sync) * sound->numSyncs);
+ sound->sync = new Sync[sound->numSyncs];
assert(sound->sync);
for (l = 0; l < sound->numRegions; l++) {
sound->region[l].offset = file->readUint32BE();
@@ -127,7 +128,7 @@ void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::File *file, soundStruct *soun
}
}
-void ImuseDigiSndMgr::prepareSound(byte *ptr, soundStruct *sound) {
+void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) {
if (READ_BE_UINT32(ptr) == MKID_BE('Crea')) {
bool quit = false;
int len;
@@ -135,10 +136,16 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, soundStruct *sound) {
int32 offset = READ_LE_UINT16(ptr + 20);
int16 code = READ_LE_UINT16(ptr + 24);
- sound->region = (_region *)malloc(sizeof(_region) * 70);
+ sound->numRegions = 0;
+ sound->region = new Region[70];
assert(sound->region);
- sound->jump = (_jump *)malloc(sizeof(_jump));
+
+ sound->numJumps = 0;
+ sound->jump = new Jump[1];
assert(sound->jump);
+
+ sound->numSyncs = 0;
+
sound->resPtr = ptr;
sound->bits = 8;
sound->channels = 1;
@@ -205,11 +212,11 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, soundStruct *sound) {
sound->numJumps = 0;
sound->numSyncs = 0;
countElements(ptr, sound->numRegions, sound->numJumps, sound->numSyncs);
- sound->region = (_region *)malloc(sizeof(_region) * sound->numRegions);
+ sound->region = new Region[sound->numRegions];
assert(sound->region);
- sound->jump = (_jump *)malloc(sizeof(_jump) * sound->numJumps);
+ sound->jump = new Jump[sound->numJumps];
assert(sound->jump);
- sound->sync = (_sync *)malloc(sizeof(_sync) * sound->numSyncs);
+ sound->sync = new Sync[sound->numSyncs];
assert(sound->sync);
do {
@@ -260,7 +267,7 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, soundStruct *sound) {
}
}
-ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::allocSlot() {
+ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::allocSlot() {
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
if (!_sounds[l].inUse) {
_sounds[l].inUse = true;
@@ -271,7 +278,7 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::allocSlot() {
return NULL;
}
-bool ImuseDigiSndMgr::openMusicBundle(soundStruct *sound, int disk) {
+bool ImuseDigiSndMgr::openMusicBundle(SoundDesc *sound, int disk) {
bool result = false;
sound->bundle = new BundleMgr(_cacheBundleDir);
@@ -306,7 +313,7 @@ bool ImuseDigiSndMgr::openMusicBundle(soundStruct *sound, int disk) {
return result;
}
-bool ImuseDigiSndMgr::openVoiceBundle(soundStruct *sound, int disk) {
+bool ImuseDigiSndMgr::openVoiceBundle(SoundDesc *sound, int disk) {
bool result = false;
sound->bundle = new BundleMgr(_cacheBundleDir);
@@ -341,11 +348,11 @@ bool ImuseDigiSndMgr::openVoiceBundle(soundStruct *sound, int disk) {
return result;
}
-ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk) {
+ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk) {
assert(soundId >= 0);
assert(soundType);
- soundStruct *sound = allocSlot();
+ SoundDesc *sound = allocSlot();
if (!sound) {
error("ImuseDigiSndMgr::openSound() can't alloc free sound slot");
}
@@ -423,99 +430,97 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch
return sound;
}
-void ImuseDigiSndMgr::closeSound(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
+void ImuseDigiSndMgr::closeSound(SoundDesc *soundDesc) {
+ assert(checkForProperHandle(soundDesc));
- if (soundHandle->resPtr) {
+ if (soundDesc->resPtr) {
bool found = false;
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
- if ((_sounds[l].soundId == soundHandle->soundId) && (&_sounds[l] != soundHandle))
+ if ((_sounds[l].soundId == soundDesc->soundId) && (&_sounds[l] != soundDesc))
found = true;
}
if (!found)
- _vm->_res->unlock(rtSound, soundHandle->soundId);
+ _vm->_res->unlock(rtSound, soundDesc->soundId);
}
- if (soundHandle->compressedStream)
- delete soundHandle->compressedStream;
-
- delete soundHandle->bundle;
+ delete soundDesc->compressedStream;
+ delete soundDesc->bundle;
- for (int r = 0; r < soundHandle->numSyncs; r++)
- free(soundHandle->sync[r].ptr);
- free(soundHandle->region);
- free(soundHandle->jump);
- free(soundHandle->sync);
- memset(soundHandle, 0, sizeof(soundStruct));
+ for (int r = 0; r < soundDesc->numSyncs; r++)
+ free(soundDesc->sync[r].ptr);
+ delete[] soundDesc->region;
+ delete[] soundDesc->jump;
+ delete[] soundDesc->sync;
+ memset(soundDesc, 0, sizeof(SoundDesc));
}
-ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::cloneSound(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
+ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::cloneSound(SoundDesc *soundDesc) {
+ assert(checkForProperHandle(soundDesc));
- return openSound(soundHandle->soundId, soundHandle->name, soundHandle->type, soundHandle->volGroupId, soundHandle->disk);
+ return openSound(soundDesc->soundId, soundDesc->name, soundDesc->type, soundDesc->volGroupId, soundDesc->disk);
}
-bool ImuseDigiSndMgr::checkForProperHandle(soundStruct *soundHandle) {
- if (!soundHandle)
+bool ImuseDigiSndMgr::checkForProperHandle(SoundDesc *soundDesc) {
+ if (!soundDesc)
return false;
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
- if (soundHandle == &_sounds[l])
+ if (soundDesc == &_sounds[l])
return true;
}
return false;
}
-bool ImuseDigiSndMgr::isSndDataExtComp(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->compressed;
+bool ImuseDigiSndMgr::isSndDataExtComp(SoundDesc *soundDesc) {
+ assert(checkForProperHandle(soundDesc));
+ return soundDesc->compressed;
}
-int ImuseDigiSndMgr::getFreq(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->freq;
+int ImuseDigiSndMgr::getFreq(SoundDesc *soundDesc) {
+ assert(checkForProperHandle(soundDesc));
+ return soundDesc->freq;
}
-int ImuseDigiSndMgr::getBits(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->bits;
+int ImuseDigiSndMgr::getBits(SoundDesc *soundDesc) {
+ assert(checkForProperHandle(soundDesc));
+ return soundDesc->bits;
}
-int ImuseDigiSndMgr::getChannels(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->channels;
+int ImuseDigiSndMgr::getChannels(SoundDesc *soundDesc) {
+ assert(checkForProperHandle(soundDesc));
+ return soundDesc->channels;
}
-bool ImuseDigiSndMgr::isEndOfRegion(soundStruct *soundHandle, int region) {
- assert(checkForProperHandle(soundHandle));
- assert(region >= 0 && region < soundHandle->numRegions);
- return soundHandle->endFlag;
+bool ImuseDigiSndMgr::isEndOfRegion(SoundDesc *soundDesc, int region) {
+ assert(checkForProperHandle(soundDesc));
+ assert(region >= 0 && region < soundDesc->numRegions);
+ return soundDesc->endFlag;
}
-int ImuseDigiSndMgr::getNumRegions(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->numRegions;
+int ImuseDigiSndMgr::getNumRegions(SoundDesc *soundDesc) {
+ assert(checkForProperHandle(soundDesc));
+ return soundDesc->numRegions;
}
-int ImuseDigiSndMgr::getNumJumps(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->numJumps;
+int ImuseDigiSndMgr::getNumJumps(SoundDesc *soundDesc) {
+ assert(checkForProperHandle(soundDesc));
+ return soundDesc->numJumps;
}
-int ImuseDigiSndMgr::getRegionOffset(soundStruct *soundHandle, int region) {
+int ImuseDigiSndMgr::getRegionOffset(SoundDesc *soundDesc, int region) {
debug(5, "getRegionOffset() region:%d", region);
- assert(checkForProperHandle(soundHandle));
- assert(region >= 0 && region < soundHandle->numRegions);
- return soundHandle->region[region].offset;
+ assert(checkForProperHandle(soundDesc));
+ assert(region >= 0 && region < soundDesc->numRegions);
+ return soundDesc->region[region].offset;
}
-int ImuseDigiSndMgr::getJumpIdByRegionAndHookId(soundStruct *soundHandle, int region, int hookId) {
+int ImuseDigiSndMgr::getJumpIdByRegionAndHookId(SoundDesc *soundDesc, int region, int hookId) {
debug(5, "getJumpIdByRegionAndHookId() region:%d, hookId:%d", region, hookId);
- assert(checkForProperHandle(soundHandle));
- assert(region >= 0 && region < soundHandle->numRegions);
- int32 offset = soundHandle->region[region].offset;
- for (int l = 0; l < soundHandle->numJumps; l++) {
- if (offset == soundHandle->jump[l].offset) {
- if (soundHandle->jump[l].hookId == hookId)
+ assert(checkForProperHandle(soundDesc));
+ assert(region >= 0 && region < soundDesc->numRegions);
+ int32 offset = soundDesc->region[region].offset;
+ for (int l = 0; l < soundDesc->numJumps; l++) {
+ if (offset == soundDesc->jump[l].offset) {
+ if (soundDesc->jump[l].hookId == hookId)
return l;
}
}
@@ -523,25 +528,25 @@ int ImuseDigiSndMgr::getJumpIdByRegionAndHookId(soundStruct *soundHandle, int re
return -1;
}
-void ImuseDigiSndMgr::getSyncSizeAndPtrById(soundStruct *soundHandle, int number, int32 &sync_size, byte **sync_ptr) {
- assert(checkForProperHandle(soundHandle));
+void ImuseDigiSndMgr::getSyncSizeAndPtrById(SoundDesc *soundDesc, int number, int32 &sync_size, byte **sync_ptr) {
+ assert(checkForProperHandle(soundDesc));
assert(number >= 0);
- if (number < soundHandle->numSyncs) {
- sync_size = soundHandle->sync[number].size;
- *sync_ptr = soundHandle->sync[number].ptr;
+ if (number < soundDesc->numSyncs) {
+ sync_size = soundDesc->sync[number].size;
+ *sync_ptr = soundDesc->sync[number].ptr;
} else {
sync_size = 0;
*sync_ptr = NULL;
}
}
-int ImuseDigiSndMgr::getRegionIdByJumpId(soundStruct *soundHandle, int jumpId) {
+int ImuseDigiSndMgr::getRegionIdByJumpId(SoundDesc *soundDesc, int jumpId) {
debug(5, "getRegionIdByJumpId() jumpId:%d", jumpId);
- assert(checkForProperHandle(soundHandle));
- assert(jumpId >= 0 && jumpId < soundHandle->numJumps);
- int32 dest = soundHandle->jump[jumpId].dest;
- for (int l = 0; l < soundHandle->numRegions; l++) {
- if (dest == soundHandle->region[l].offset) {
+ assert(checkForProperHandle(soundDesc));
+ assert(jumpId >= 0 && jumpId < soundDesc->numJumps);
+ int32 dest = soundDesc->jump[jumpId].dest;
+ for (int l = 0; l < soundDesc->numRegions; l++) {
+ if (dest == soundDesc->region[l].offset) {
return l;
}
}
@@ -549,89 +554,110 @@ int ImuseDigiSndMgr::getRegionIdByJumpId(soundStruct *soundHandle, int jumpId) {
return -1;
}
-int ImuseDigiSndMgr::getJumpHookId(soundStruct *soundHandle, int number) {
+int ImuseDigiSndMgr::getJumpHookId(SoundDesc *soundDesc, int number) {
debug(5, "getJumpHookId() number:%d", number);
- assert(checkForProperHandle(soundHandle));
- assert(number >= 0 && number < soundHandle->numJumps);
- return soundHandle->jump[number].hookId;
+ assert(checkForProperHandle(soundDesc));
+ assert(number >= 0 && number < soundDesc->numJumps);
+ return soundDesc->jump[number].hookId;
}
-int ImuseDigiSndMgr::getJumpFade(soundStruct *soundHandle, int number) {
+int ImuseDigiSndMgr::getJumpFade(SoundDesc *soundDesc, int number) {
debug(5, "getJumpFade() number:%d", number);
- assert(checkForProperHandle(soundHandle));
- assert(number >= 0 && number < soundHandle->numJumps);
- return soundHandle->jump[number].fadeDelay;
+ assert(checkForProperHandle(soundDesc));
+ assert(number >= 0 && number < soundDesc->numJumps);
+ return soundDesc->jump[number].fadeDelay;
}
-int32 ImuseDigiSndMgr::getDataFromRegion(soundStruct *soundHandle, int region, byte **buf, int32 offset, int32 size) {
- debug(5, "getDataFromRegion() region:%d, offset:%d, size:%d, numRegions:%d", region, offset, size, soundHandle->numRegions);
- assert(checkForProperHandle(soundHandle));
+int32 ImuseDigiSndMgr::getDataFromRegion(SoundDesc *soundDesc, int region, byte **buf, int32 offset, int32 size) {
+ debug(5, "getDataFromRegion() region:%d, offset:%d, size:%d, numRegions:%d", region, offset, size, soundDesc->numRegions);
+ assert(checkForProperHandle(soundDesc));
assert(buf && offset >= 0 && size >= 0);
- assert(region >= 0 && region < soundHandle->numRegions);
+ assert(region >= 0 && region < soundDesc->numRegions);
- int32 region_offset = soundHandle->region[region].offset;
- int32 region_length = soundHandle->region[region].length;
- int32 offset_data = soundHandle->offsetData;
+ int32 region_offset = soundDesc->region[region].offset;
+ int32 region_length = soundDesc->region[region].length;
+ int32 offset_data = soundDesc->offsetData;
int32 start = region_offset - offset_data;
if (offset + size + offset_data > region_length) {
size = region_length - offset;
- soundHandle->endFlag = true;
+ soundDesc->endFlag = true;
} else {
- soundHandle->endFlag = false;
+ soundDesc->endFlag = false;
}
- int header_size = soundHandle->offsetData;
+ int header_size = soundDesc->offsetData;
bool header_outside = ((_vm->_game.id == GID_CMI) && !(_vm->_game.features & GF_DEMO));
- if ((soundHandle->bundle) && (!soundHandle->compressed)) {
- size = soundHandle->bundle->decompressSampleByCurIndex(start + offset, size, buf, header_size, header_outside);
- } else if (soundHandle->resPtr) {
+ if ((soundDesc->bundle) && (!soundDesc->compressed)) {
+ size = soundDesc->bundle->decompressSampleByCurIndex(start + offset, size, buf, header_size, header_outside);
+ } else if (soundDesc->resPtr) {
*buf = new byte[size];
assert(*buf);
- memcpy(*buf, soundHandle->resPtr + start + offset + header_size, size);
- } else if ((soundHandle->bundle) && (soundHandle->compressed)) {
+ memcpy(*buf, soundDesc->resPtr + start + offset + header_size, size);
+ } else if ((soundDesc->bundle) && (soundDesc->compressed)) {
*buf = new byte[size];
assert(*buf);
char fileName[24];
- sprintf(fileName, "%s_reg%03d", soundHandle->name, region);
- if (scumm_stricmp(fileName, soundHandle->lastFileName) != 0) {
+ sprintf(fileName, "%s_reg%03d", soundDesc->name, region);
+ if (scumm_stricmp(fileName, soundDesc->lastFileName) != 0) {
int32 offs = 0, len = 0;
Common::File *cmpFile;
- bool oggMode = false;
- sprintf(fileName, "%s_reg%03d.mp3", soundHandle->name, region);
- cmpFile = soundHandle->bundle->getFile(fileName, offs, len);
-#ifndef USE_MAD
- if (len)
- error("Mad library compiled support needed!");
+ uint8 soundMode = 0;
+
+ sprintf(fileName, "%s_reg%03d.fla", soundDesc->name, region);
+ cmpFile = soundDesc->bundle->getFile(fileName, offs, len);
+ if (len) {
+#ifndef USE_FLAC
+ error("FLAC library compiled support needed!");
#endif
+ soundMode = 3;
+ }
if (!len) {
- sprintf(fileName, "%s_reg%03d.ogg", soundHandle->name, region);
- cmpFile = soundHandle->bundle->getFile(fileName, offs, len);
+ sprintf(fileName, "%s_reg%03d.ogg", soundDesc->name, region);
+ cmpFile = soundDesc->bundle->getFile(fileName, offs, len);
+ if (len) {
#ifndef USE_VORBIS
- if (len)
error("Vorbis library compiled support needed!");
#endif
- assert(len);
- oggMode = true;
+ soundMode = 2;
+ }
+ }
+ if (!len) {
+ sprintf(fileName, "%s_reg%03d.mp3", soundDesc->name, region);
+ cmpFile = soundDesc->bundle->getFile(fileName, offs, len);
+ if (len) {
+#ifndef USE_MAD
+ error("Mad library compiled support needed!");
+#endif
+ soundMode = 1;
+ }
}
- if (!soundHandle->compressedStream) {
+ assert(len);
+
+ if (!soundDesc->compressedStream) {
+ Common::MemoryReadStream *tmp = cmpFile->readStream(len);
+ assert(tmp);
+#ifdef USE_FLAC
+ if (soundMode == 3)
+ soundDesc->compressedStream = Audio::makeFlacStream(tmp, true);
+#endif
#ifdef USE_VORBIS
- if (oggMode)
- soundHandle->compressedStream = Audio::makeVorbisStream(cmpFile, len);
+ if (soundMode == 2)
+ soundDesc->compressedStream = Audio::makeVorbisStream(tmp, true);
#endif
#ifdef USE_MAD
- if (!oggMode)
- soundHandle->compressedStream = Audio::makeMP3Stream(cmpFile, len);
+ if (soundMode == 1)
+ soundDesc->compressedStream = Audio::makeMP3Stream(tmp, true);
#endif
- assert(soundHandle->compressedStream);
+ assert(soundDesc->compressedStream);
}
- strcpy(soundHandle->lastFileName, fileName);
+ strcpy(soundDesc->lastFileName, fileName);
}
- size = soundHandle->compressedStream->readBuffer((int16 *)*buf, size / 2) * 2;
- if (soundHandle->compressedStream->endOfData()) {
- delete soundHandle->compressedStream;
- soundHandle->compressedStream = NULL;
- soundHandle->lastFileName[0] = 0;
+ size = soundDesc->compressedStream->readBuffer((int16 *)*buf, size / 2) * 2;
+ if (soundDesc->compressedStream->endOfData()) {
+ delete soundDesc->compressedStream;
+ soundDesc->compressedStream = NULL;
+ soundDesc->lastFileName[0] = 0;
}
}
diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.h b/engines/scumm/imuse_digi/dimuse_sndmgr.h
index 5d2f8c88ba..e4e2e795a2 100644
--- a/engines/scumm/imuse_digi/dimuse_sndmgr.h
+++ b/engines/scumm/imuse_digi/dimuse_sndmgr.h
@@ -48,35 +48,39 @@ public:
#define IMUSE_VOLGRP_MUSIC 3
private:
- struct _region {
+ struct Region {
int32 offset; // offset of region
int32 length; // lenght of region
};
- struct _jump {
+ struct Jump {
int32 offset; // jump offset position
int32 dest; // jump to dest position
byte hookId; // id of hook
int16 fadeDelay; // fade delay in ms
};
- struct _sync {
+ struct Sync {
int32 size; // size of sync
byte *ptr; // pointer to sync
};
public:
- struct soundStruct {
+ struct SoundDesc {
uint16 freq; // frequency
byte channels; // stereo or mono
byte bits; // 8, 12, 16
+
int numJumps; // number of Jumps
+ Region *region;
+
int numRegions; // number of Regions
+ Jump *jump;
+
int numSyncs; // number of Syncs
- _region *region;
- _jump *jump;
- _sync *sync;
+ Sync *sync;
+
bool endFlag;
bool inUse;
byte *allData;
@@ -95,19 +99,19 @@ public:
private:
- soundStruct _sounds[MAX_IMUSE_SOUNDS];
+ SoundDesc _sounds[MAX_IMUSE_SOUNDS];
- bool checkForProperHandle(soundStruct *soundHandle);
- soundStruct *allocSlot();
- void prepareSound(byte *ptr, soundStruct *sound);
- void prepareSoundFromRMAP(Common::File *file, soundStruct *sound, int32 offset, int32 size);
+ bool checkForProperHandle(SoundDesc *soundDesc);
+ SoundDesc *allocSlot();
+ void prepareSound(byte *ptr, SoundDesc *sound);
+ void prepareSoundFromRMAP(Common::File *file, SoundDesc *sound, int32 offset, int32 size);
ScummEngine *_vm;
byte _disk;
BundleDirCache *_cacheBundleDir;
- bool openMusicBundle(soundStruct *sound, int disk);
- bool openVoiceBundle(soundStruct *sound, int disk);
+ bool openMusicBundle(SoundDesc *sound, int disk);
+ bool openVoiceBundle(SoundDesc *sound, int disk);
void countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs);
@@ -116,25 +120,25 @@ public:
ImuseDigiSndMgr(ScummEngine *scumm);
~ImuseDigiSndMgr();
- soundStruct *openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk);
- void closeSound(soundStruct *soundHandle);
- soundStruct *cloneSound(soundStruct *soundHandle);
-
- bool isSndDataExtComp(soundStruct *soundHandle);
- int getFreq(soundStruct *soundHandle);
- int getBits(soundStruct *soundHandle);
- int getChannels(soundStruct *soundHandle);
- bool isEndOfRegion(soundStruct *soundHandle, int region);
- int getNumRegions(soundStruct *soundHandle);
- int getNumJumps(soundStruct *soundHandle);
- int getRegionOffset(soundStruct *soundHandle, int region);
- int getJumpIdByRegionAndHookId(soundStruct *soundHandle, int region, int hookId);
- int getRegionIdByJumpId(soundStruct *soundHandle, int jumpId);
- int getJumpHookId(soundStruct *soundHandle, int number);
- int getJumpFade(soundStruct *soundHandle, int number);
- void getSyncSizeAndPtrById(soundStruct *soundHandle, int number, int32 &sync_size, byte **sync_ptr);
-
- int32 getDataFromRegion(soundStruct *soundHandle, int region, byte **buf, int32 offset, int32 size);
+ SoundDesc *openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk);
+ void closeSound(SoundDesc *soundDesc);
+ SoundDesc *cloneSound(SoundDesc *soundDesc);
+
+ bool isSndDataExtComp(SoundDesc *soundDesc);
+ int getFreq(SoundDesc *soundDesc);
+ int getBits(SoundDesc *soundDesc);
+ int getChannels(SoundDesc *soundDesc);
+ bool isEndOfRegion(SoundDesc *soundDesc, int region);
+ int getNumRegions(SoundDesc *soundDesc);
+ int getNumJumps(SoundDesc *soundDesc);
+ int getRegionOffset(SoundDesc *soundDesc, int region);
+ int getJumpIdByRegionAndHookId(SoundDesc *soundDesc, int region, int hookId);
+ int getRegionIdByJumpId(SoundDesc *soundDesc, int jumpId);
+ int getJumpHookId(SoundDesc *soundDesc, int number);
+ int getJumpFade(SoundDesc *soundDesc, int number);
+ void getSyncSizeAndPtrById(SoundDesc *soundDesc, int number, int32 &sync_size, byte **sync_ptr);
+
+ int32 getDataFromRegion(SoundDesc *soundDesc, int region, byte **buf, int32 offset, int32 size);
};
} // End of namespace Scumm
diff --git a/engines/scumm/imuse_digi/dimuse_track.cpp b/engines/scumm/imuse_digi/dimuse_track.cpp
index 75dde5e60f..987e1bc3c9 100644
--- a/engines/scumm/imuse_digi/dimuse_track.cpp
+++ b/engines/scumm/imuse_digi/dimuse_track.cpp
@@ -117,20 +117,20 @@ void IMuseDigital::startSound(int soundId, const char *soundName, int soundType,
track->feedSize = 0;
track->souStreamUsed = true;
track->soundName[0] = 0;
- track->soundHandle = NULL;
+ track->soundDesc = NULL;
} else {
track->souStreamUsed = false;
strcpy(track->soundName, soundName);
- track->soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId, -1);
+ track->soundDesc = _sound->openSound(soundId, soundName, soundType, volGroupId, -1);
- if (track->soundHandle == NULL)
+ if (track->soundDesc == NULL)
return;
- track->sndDataExtComp = _sound->isSndDataExtComp(track->soundHandle);
+ track->sndDataExtComp = _sound->isSndDataExtComp(track->soundDesc);
- bits = _sound->getBits(track->soundHandle);
- channels = _sound->getChannels(track->soundHandle);
- freq = _sound->getFreq(track->soundHandle);
+ bits = _sound->getBits(track->soundDesc);
+ channels = _sound->getChannels(track->soundDesc);
+ freq = _sound->getFreq(track->soundDesc);
if ((soundId == kTalkSoundID) && (soundType == IMUSE_BUNDLE)) {
if (_vm->_actorToPrintStrFor != 0xFF && _vm->_actorToPrintStrFor != 0) {
@@ -325,15 +325,12 @@ IMuseDigital::Track *IMuseDigital::cloneToFadeOutTrack(const Track *track, int f
// Clone the settings of the given track
memcpy(fadeTrack, track, sizeof(Track));
- // Clone the soundhandle
- // FIXME: Shouldn't we check here whether track->soundHandle is NULL, resp. whether stream2
- // is being used (as in, we are using compressed data)...
- //
- // -- aquadran -- nope :) this is called only for bundle files and sound data in *.la1
- // from switchToNextRegion and fadeOutMusic func.
- // stream2 is used only for sou VOICE type sound data (FT) --
- fadeTrack->soundHandle = _sound->cloneSound(track->soundHandle);
- assert(fadeTrack->soundHandle);
+ // Clone the sound.
+ // According to aquadran, this is only called for bundle files and sound
+ // data in *.la1 from switchToNextRegion and fadeOutMusic func. Henc we
+ // know that track->soundDesc != NULL.
+ fadeTrack->soundDesc = _sound->cloneSound(track->soundDesc);
+ assert(fadeTrack->soundDesc);
// Set the volume fading parameters to indicate a fade out
fadeTrack->volFadeDelay = fadeDelay;
@@ -357,7 +354,7 @@ IMuseDigital::Track *IMuseDigital::cloneToFadeOutTrack(const Track *track, int f
type = Audio::Mixer::kPlainSoundType;
break;
}
- fadeTrack->stream = Audio::makeAppendableAudioStream(_sound->getFreq(fadeTrack->soundHandle), makeMixerFlags(fadeTrack->mixerFlags));
+ fadeTrack->stream = Audio::makeAppendableAudioStream(_sound->getFreq(fadeTrack->soundDesc), makeMixerFlags(fadeTrack->mixerFlags));
_mixer->playInputStream(type, &fadeTrack->mixChanHandle, fadeTrack->stream, -1, fadeTrack->vol / 1000, fadeTrack->pan, false);
fadeTrack->mixerStreamRunning = true;
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index ffcb7d03f2..6647e9fe8d 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -162,8 +162,11 @@ void ScummEngine::parseEvents() {
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
_mouse.x -= (Common::kHercW - _screenWidth * 2) / 2;
- _mouse.x /= 2;
+ _mouse.x >>= 1;
_mouse.y = _mouse.y * 4 / 7;
+ } else if (_useCJKMode && _textSurfaceMultiplier == 2) {
+ _mouse.x >>= 1;
+ _mouse.y >>= 1;
}
break;
case Common::EVENT_LBUTTONUP:
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index d8ef669410..a340f564b3 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -90,6 +90,11 @@ endif
endif
+ifdef USE_ARM_GFX_ASM
+MODULE_OBJS += \
+ gfxARM.o
+endif
+
ifndef DISABLE_HE
MODULE_OBJS += \
he/animation_he.o \
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index cd48ef4d02..4f6b2477c6 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Mon Jul 2 22:44:41 2007
+ This file was generated by the md5table tool on Fri Jul 20 21:25:14 2007
DO NOT EDIT MANUALLY!
*/
@@ -25,10 +25,12 @@ static const MD5Table md5table[] = {
{ "04687cdf7f975a89d2474929f7b80946", "indy3", "FM-TOWNS", "", 7552, Common::EN_ANY, Common::kPlatformFMTowns },
{ "0557df19f046a84c2fdc63507c6616cb", "farm", "HE 72", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "055ffe4f47753e47594ac67823220c54", "puttrace", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
+ { "057c9b456dedcc4d71b991a3072a20b3", "monkey", "SEGA", "", 9465, Common::JA_JPN, Common::kPlatformSegaCD },
{ "0650e8ab1432564607cd651c0fa3f344", "loom", "PC-Engine", "", -1, Common::EN_ANY, Common::kPlatformPCEngine },
{ "06b187468113f9ae5a400b148a847fac", "atlantis", "", "Floppy", 12075, Common::EN_ANY, Common::kPlatformMacintosh },
{ "06c3cf4f31daad8b1cd93153491db9e6", "pajama3", "", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "07433205acdca3bc553d0e731588b35f", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
+ { "07a1eefd8ca95d77310311446c0f53d0", "brstorm", "", "Demo", 5433, Common::EN_ANY, Common::kPlatformUnknown },
{ "07b810e37be7489263f7bc7627d4765d", "freddi4", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "084ed0fa98a6d1e9368d67fe9cfbd417", "freddi", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "0855496dde35356b1a9691e22ba84cdc", "freddi", "HE 73", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -320,6 +322,7 @@ static const MD5Table md5table[] = {
{ "86be8ada36371d4fdc35659d0e912a26", "indy3", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC },
{ "86c9902b7bec1a17926d4dae85beaa45", "airport", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "870d1e3c86bc50846d808d14a36b4e08", "monkey", "VGA", "VGA", -1, Common::ES_ESP, Common::kPlatformAmiga },
+ { "8776caed014c321272af407c1502a2df", "monkey", "CD", "", 8955, Common::EN_ANY, Common::kPlatformMacintosh },
{ "87f6e8037b7cc996e13474b491a7a98e", "maniac", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC },
{ "8801fb4a1200b347f7a38523339526dd", "jungle", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "883af4b0af4f77a92f1dcf1d0a283140", "tentacle", "", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
@@ -444,6 +447,7 @@ static const MD5Table md5table[] = {
{ "c8575e0b973ff1723aba6cd92c642db2", "puttrace", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "c8aac5e3e701874e2fa4117896f9e1b1", "freddi", "HE 73", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "c8c5baadcbfc8d0372ed4335abace8a7", "pajama3", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
+ { "c9717ee6059f1e43b768b464493d2fba", "fbpack", "", "", -1, Common::JA_JPN, Common::kPlatform3DO },
{ "cb1559e8405d17a5a278a6b5ad9338d1", "freddi3", "", "Demo", 22718, Common::EN_ANY, Common::kPlatformUnknown },
{ "cc04a076779379524ed4d9c5ee3c6fb1", "tentacle", "", "CD", 282467632, Common::EN_ANY, Common::kPlatformMacintosh },
{ "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", "", "Demo", 7485, Common::DE_DEU, Common::kPlatformPC },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 2140b15544..e54060c9e1 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -480,7 +480,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_renderMode = Common::kRenderDefault;
}
- // Do some render mode restirctions
+ // Check some render mode restrictions
if (_game.version <= 1)
_renderMode = Common::kRenderDefault;
@@ -521,7 +521,11 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_screenHeight = 200;
}
- _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight);
+ // Allocate gfx compositing buffer (not needed for V7/V8 games).
+ if (_game.version < 7)
+ _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight);
+ else
+ _compositeBuf = 0;
_herculesBuf = 0;
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
@@ -583,6 +587,7 @@ ScummEngine::~ScummEngine() {
free(_compositeBuf);
free(_herculesBuf);
+ free(_fmtownsBuf);
delete _debugger;
@@ -1074,12 +1079,19 @@ int ScummEngine::init() {
_fileHandle = new ScummFile();
}
+ // Load CJK font, if present
+ // Load it earlier so _useCJKMode variable could be set
+ loadCJKFont();
+
// Initialize backend
_system->beginGFXTransaction();
bool defaultTo1XScaler = false;
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
_system->initSize(Common::kHercW, Common::kHercH);
defaultTo1XScaler = true;
+ } else if (_useCJKMode) {
+ _system->initSize(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier);
+ defaultTo1XScaler = true;
} else {
_system->initSize(_screenWidth, _screenHeight);
defaultTo1XScaler = (_screenWidth > 320);
@@ -1131,14 +1143,11 @@ void ScummEngine::setupScumm() {
// Load localization data, if present
loadLanguageBundle();
- // Load CJK font, if present
- loadCJKFont();
-
// Create the charset renderer
setupCharsetRenderer();
// Create and clear the text surface
- _textSurface.create(_screenWidth, _screenHeight, 1);
+ _textSurface.create(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, 1);
clearTextSurface();
// Create the costume renderer
@@ -1206,6 +1215,13 @@ void ScummEngine::setupScumm() {
#if (defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
Graphics::initfonts();
#endif
+
+ _fmtownsBuf = 0;
+ if (_game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN) {
+ _fmtownsBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
+ }
+
+ _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
}
#ifndef DISABLE_SCUMM_7_8
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 4146846856..18c2275029 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1026,11 +1026,12 @@ protected:
// Screen rendering
byte *_compositeBuf;
byte *_herculesBuf;
+ byte *_fmtownsBuf;
virtual void drawDirtyScreenParts();
void updateDirtyScreen(VirtScreenNumber slot);
void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
- void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height) const;
+ void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
public:
VirtScreen *findVirtScreen(int y);
@@ -1152,6 +1153,7 @@ public:
* drawStripToScreen() composits it over the game graphics.
*/
Graphics::Surface _textSurface;
+ int _textSurfaceMultiplier;
protected:
byte _charsetColor;
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 2c744a16e2..ce39302e25 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -1178,12 +1178,15 @@ void SmushPlayer::tryCmpFile(const char *filename) {
char fname[260];
#endif
Common::File *file = new Common::File();
+
+ // FIXME: How about using AudioStream::openStreamFile instead of the code below?
+
#ifdef USE_VORBIS
memcpy(fname, filename, i - filename);
strcpy(fname + (i - filename), ".ogg");
if (file->open(fname)) {
_compressedFileMode = true;
- _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_compressedFileSoundHandle, Audio::makeVorbisStream(file, true, 0, 0));
+ _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_compressedFileSoundHandle, Audio::makeVorbisStream(file, true));
return;
}
#endif
@@ -1192,7 +1195,7 @@ void SmushPlayer::tryCmpFile(const char *filename) {
strcpy(fname + (i - filename), ".mp3");
if (file->open(fname)) {
_compressedFileMode = true;
- _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_compressedFileSoundHandle, Audio::makeMP3Stream(file, true, 0, 0));
+ _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_compressedFileSoundHandle, Audio::makeMP3Stream(file, true));
return;
}
#endif
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index e5720a013f..62f65c22c1 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -607,24 +607,31 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
if (!_soundsPaused && _mixer->isReady()) {
Audio::AudioStream *input = NULL;
+ Common::MemoryReadStream *tmp = NULL;
switch (_soundMode) {
case kMP3Mode:
#ifdef USE_MAD
assert(size > 0);
- input = Audio::makeMP3Stream(_sfxFile, size);
+ tmp = _sfxFile->readStream(size);
+ assert(tmp);
+ input = Audio::makeMP3Stream(tmp, true);
#endif
break;
case kVorbisMode:
#ifdef USE_VORBIS
assert(size > 0);
- input = Audio::makeVorbisStream(_sfxFile, size);
+ tmp = _sfxFile->readStream(size);
+ assert(tmp);
+ input = Audio::makeVorbisStream(tmp, true);
#endif
break;
case kFlacMode:
#ifdef USE_FLAC
assert(size > 0);
- input = Audio::makeFlacStream(_sfxFile, size);
+ tmp = _sfxFile->readStream(size);
+ assert(tmp);
+ input = Audio::makeFlacStream(tmp, true);
#endif
break;
default:
@@ -831,7 +838,7 @@ void Sound::soundKludge(int *list, int num) {
}
void Sound::talkSound(uint32 a, uint32 b, int mode, int channel) {
- if (_vm->_game.version >= 6 && ConfMan.getBool("speech_mute"))
+ if (_vm->_game.version >= 5 && ConfMan.getBool("speech_mute"))
return;
if (mode == 1) {
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index 44e727b5d3..32fdf0e04e 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -172,6 +172,20 @@ void ScummEngine_v6::drawBlastTexts() {
if (c == 0x0B)
continue;
+ // Some localizations may override colors
+ // See credits in Chinese COMI
+ if (c == '^' && (buf == _blastTextQueue[i].text + 1)) {
+ int color;
+ switch (*buf) {
+ case 'c':
+ color = buf[3] - '0' + 10 *(buf[2] - '0');
+ _charset->setColor(color);
+
+ buf += 4;
+ c = *buf++;
+ }
+ }
+
if (c != 0 && c != 0xFF && c != '\n') {
if (c & 0x80 && _useCJKMode) {
if (_language == Common::JA_JPN && !checkSJISCode(c)) {
@@ -1060,7 +1074,7 @@ int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize)
num += (_game.version == 8) ? 4 : 2;
}
} else {
- if (!(chr == '@' && _game.heversion <= 71)) {
+ if (!(chr == '@' && _game.heversion <= 71) || _language == Common::ZH_TWN) {
*dst++ = chr;
}
}