aboutsummaryrefslogtreecommitdiff
path: root/scumm/smush
diff options
context:
space:
mode:
authorPaweł Kołodziejski2003-01-18 13:54:26 +0000
committerPaweł Kołodziejski2003-01-18 13:54:26 +0000
commit4c5c59c1985aa82d41b7cbaeb5edf66982ac2b95 (patch)
tree86ad48153304bd202a29f0ce82148fedf2a03f08 /scumm/smush
parent0b4830e80aedde1f62d63ba1343ed3a7387b67e2 (diff)
downloadscummvm-rg350-4c5c59c1985aa82d41b7cbaeb5edf66982ac2b95.tar.gz
scummvm-rg350-4c5c59c1985aa82d41b7cbaeb5edf66982ac2b95.tar.bz2
scummvm-rg350-4c5c59c1985aa82d41b7cbaeb5edf66982ac2b95.zip
implementation of comi smush audio
svn-id: r6493
Diffstat (limited to 'scumm/smush')
-rw-r--r--scumm/smush/player.cpp92
-rw-r--r--scumm/smush/player.h4
2 files changed, 92 insertions, 4 deletions
diff --git a/scumm/smush/player.cpp b/scumm/smush/player.cpp
index c450c0ccb5..a03b6f9354 100644
--- a/scumm/smush/player.cpp
+++ b/scumm/smush/player.cpp
@@ -23,7 +23,9 @@
#include "common/file.h"
#include "common/util.h"
#include "common/engine.h" // for debug, warning, error
+#include "common/engine.h" // for debug, warning, error
#include "scumm/scumm.h"
+#include "sound/mixer.h"
#include "player.h"
@@ -209,6 +211,8 @@ SmushPlayer::SmushPlayer(Renderer * renderer, bool wait, bool sound) :
_curBuffer(0) {
_fr[0] = _fr[1] = _fr[2] = _fr[3] = 0;
assert(_renderer != 0);
+ _IACTchannel = -1;
+ _IACTrest = 0;
}
SmushPlayer::~SmushPlayer() {
@@ -315,8 +319,89 @@ void SmushPlayer::handleImuseAction8(Chunk & b, int32 flags, int32 unknown, int3
int32 nbframes = b.getWord();
int32 size = b.getDword();
int32 bsize = b.getSize() - 18;
- handleImuseBuffer(track_id, index, nbframes, size, unknown, track_flags, b, bsize);
-
+ if (g_scumm->_gameId != GID_CMI) {
+ handleImuseBuffer(track_id, index, nbframes, size, unknown, track_flags, b, bsize);
+ } else {
+ byte output_data[4096];
+ byte * src = (byte*)malloc(bsize);
+ b.read(src, bsize);
+ byte * d_src = src;
+ byte value;
+
+ do {
+ if (bsize == 0)
+ break;
+ if (_IACTrest >= 2) {
+ int32 len = READ_BE_UINT16(_IACToutput) + 2;
+ len -= _IACTrest;
+ if (len > bsize) {
+ memcpy(_IACToutput + _IACTrest, d_src, bsize);
+ _IACTrest += bsize;
+ bsize = 0;
+ } else {
+ memcpy(_IACToutput + _IACTrest, d_src, len);
+ byte * dst = output_data;
+ byte * d_src2 = _IACToutput;
+ d_src2 += 2;
+ int32 count = 1024;
+ byte variable1 = *(d_src2++);
+ byte variable2 = variable1 >> 4;
+ variable1 &= 0x0f;
+ do {
+ value = *(d_src2++);
+ if (value == 0x80) {
+ *(dst++) = *(d_src2++);
+ *(dst++) = *(d_src2++);
+ } else {
+ int16 val = (int8)value << variable2;
+ *(dst++) = val>> 8;
+ *(dst++) = (byte)(val);
+ }
+ value = *(d_src2++);
+ if (value == 0x80) {
+ *(dst++) = *(d_src2++);
+ *(dst++) = *(d_src2++);
+ } else {
+ int16 val = (int8)value << variable1;
+ *(dst++) = val>> 8;
+ *(dst++) = (byte)(val);
+ }
+ } while (--count);
+
+ if (_IACTchannel == -1) {
+ _IACTchannel = g_scumm->_mixer->playStream(NULL, -1, output_data, 0x1000, 22050,
+ SoundMixer::FLAG_STEREO | SoundMixer::FLAG_16BITS);
+ } else {
+ g_scumm->_mixer->append(_IACTchannel, output_data, 0x1000, 22050,
+ SoundMixer::FLAG_STEREO | SoundMixer::FLAG_16BITS);
+ }
+
+ bsize -= len;
+ d_src += len;
+ _IACTrest = 0;
+ }
+ } else {
+ if (bsize == 1) {
+ if (_IACTrest != 0) {
+ *(byte*)(_IACToutput + 1) = *(byte*)d_src++;
+ _IACTrest = 2;
+ bsize--;
+ }
+ bsize = 0;
+ *(byte*)(_IACToutput + 0) = *(byte*)d_src;
+ _IACTrest = 1;
+ } else if (_IACTrest == 0) {
+ *(byte*)(_IACToutput + 0) = *(byte*)d_src++;
+ bsize--;
+ *(byte*)(_IACToutput + 1) = *(byte*)d_src++;
+ _IACTrest = 2;
+ bsize--;
+ }
+ }
+ } while (bsize != 0);
+
+ free(src);
+ }
}
void SmushPlayer::handleImuseAction(Chunk & b) {
@@ -566,8 +651,7 @@ void SmushPlayer::handleFrame(Chunk & b) {
handleDeltaPalette(*sub);
break;
case TYPE_IACT:
- if (g_scumm->_gameId != GID_CMI)
- handleImuseAction(*sub);
+ handleImuseAction(*sub);
break;
case TYPE_STOR:
handleStore(*sub);
diff --git a/scumm/smush/player.h b/scumm/smush/player.h
index 76d8e52804..7d181086d0 100644
--- a/scumm/smush/player.h
+++ b/scumm/smush/player.h
@@ -70,6 +70,10 @@ private:
bool _voices; //!< should the player output the voice ?
bool _skips[37]; //!< mapping of frame object identifier to show or hide
char * _curBuffer; //!< pointer to the current frame
+ int32 _IACTchannel;
+ byte _IACToutput[4096];
+ int32 _IACTrest;
+
public:
SmushPlayer(Renderer *, bool wait = true, bool output_sound = true);
virtual ~SmushPlayer();