aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorBenjamin Haisch2008-10-14 21:12:52 +0000
committerWillem Jan Palenstijn2011-11-20 22:43:07 +0100
commit4b13982116828453efd4a445328d455d9b820149 (patch)
tree1d94348ce56b4836dc0aa2d24bc43bd85284f01b /engines
parentf77960e81b5f0b17ebddd4b640cc315bcfc6ef78 (diff)
downloadscummvm-rg350-4b13982116828453efd4a445328d455d9b820149.tar.gz
scummvm-rg350-4b13982116828453efd4a445328d455d9b820149.tar.bz2
scummvm-rg350-4b13982116828453efd4a445328d455d9b820149.zip
TOLTECS: Implemented preliminary sound playback; some stuff is still missing (correct volumes etc.)
Diffstat (limited to 'engines')
-rw-r--r--engines/toltecs/module.mk1
-rw-r--r--engines/toltecs/movie.cpp4
-rw-r--r--engines/toltecs/screen.cpp12
-rw-r--r--engines/toltecs/screen.h3
-rw-r--r--engines/toltecs/script.cpp19
-rw-r--r--engines/toltecs/sound.cpp178
-rw-r--r--engines/toltecs/sound.h80
-rw-r--r--engines/toltecs/toltecs.cpp19
-rw-r--r--engines/toltecs/toltecs.h2
9 files changed, 304 insertions, 14 deletions
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
index 49d4e19f65..1d9d50ce85 100644
--- a/engines/toltecs/module.mk
+++ b/engines/toltecs/module.mk
@@ -14,6 +14,7 @@ MODULE_OBJS = \
screen.o \
script.o \
segmap.o \
+ sound.o \
sprite.o
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index b5665aaf47..6e59882efc 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -54,7 +54,7 @@ void MoviePlayer::playMovie(uint resIndex) {
memset(moviePalette, 0, sizeof(moviePalette));
- _vm->_screen->finishTextDrawItems();
+ _vm->_screen->finishTalkTextItems();
_vm->_screen->clearSprites();
_vm->_arc->openResource(resIndex);
@@ -154,7 +154,7 @@ void MoviePlayer::playMovie(uint resIndex) {
break;
case 8: // stop subtitles
_vm->_script->getSlotData(subtitleSlot)[0] = 0xFF;
- _vm->_screen->finishTextDrawItems();
+ _vm->_screen->finishTalkTextItems();
break;
default:
error("Unknown chunk type %d at %08X", chunkType, _vm->_arc->pos() - 5 - chunkSize);
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 8951c1eb6a..cde0138be3 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -496,12 +496,22 @@ int16 Screen::getTalkTextDuration() {
return _talkTextItems[_talkTextItemNum].duration;
}
-void Screen::finishTextDrawItems() {
+void Screen::finishTalkTextItems() {
for (int16 i = 0; i <= _talkTextItemNum; i++) {
_talkTextItems[i].duration = 0;
}
}
+void Screen::keepTalkTextItemsAlive() {
+ for (int16 i = 0; i <= _talkTextItemNum; i++) {
+ TalkTextItem *item = &_talkTextItems[i];
+ if (item->fontNum == -1)
+ item->duration = 0;
+ else if (item->duration > 0)
+ item->duration = 2;
+ }
+}
+
void Screen::registerFont(uint fontIndex, uint resIndex) {
_fontResIndexArray[fontIndex] = resIndex;
}
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 752d5a4c7c..ff27bb2ba5 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -197,7 +197,8 @@ public:
void addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item);
void addTalkTextItemsToRenderQueue();
int16 getTalkTextDuration();
- void finishTextDrawItems();
+ void finishTalkTextItems();
+ void keepTalkTextItemsAlive();
// Font/text
void registerFont(uint fontIndex, uint resIndex);
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 13cc0ea5e0..4f50ca265b 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -41,6 +41,7 @@
#include "toltecs/script.h"
#include "toltecs/screen.h"
#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
namespace Toltecs {
@@ -445,7 +446,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
debug(0, "o2_updateScreen()");
- // TODO? updateSamples();
+ _vm->_sound->updateSpeech();
_vm->_screen->updateShakeScreen();
@@ -592,6 +593,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
{
debug(0, "o2_loadScene(resIndex: %d; flag: %d)", arg16(4), arg8(3));
if (arg8(3) == 0) {
+ _vm->_sound->stopSpeech();
_vm->loadScene(arg16(4));
} else {
_vm->_screen->loadMouseCursor(arg16(4));
@@ -845,7 +847,10 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 54:// TODO
{
- debug(0, "o2_playSound2(%d, %d, %d)", arg16(7), arg16(5), arg16(3));
+ //debug(0, "o2_playSound2(%d, %d, %d)", arg16(7), arg16(5), arg16(3));
+
+ _vm->_sound->playSound(arg16(3), arg16(5), arg16(7));
+
break;
}
@@ -878,15 +883,13 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 59:// TODO
{
- debug(0, "o2_precacheResources(%04X)", arg16(3));
+ debug(0, "o2_precacheSprites(%04X)", arg16(3));
break;
}
case 60:// TODO
{
debug(0, "o2_precacheSounds1(%04X)", arg16(3));
- // CHECKME
- _vm->_screen->clearSprites();
break;
}
@@ -896,6 +899,12 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
break;
}
+ case 62:// TODO - this opcode was never executed while I completed the game
+ {
+ debug(0, "o2_precacheSounds2(%04X)", arg16(3));
+ break;
+ }
+
case 63:// ok
{
_regs.sp = _savedSp;
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
new file mode 100644
index 0000000000..a3e7a76fe8
--- /dev/null
+++ b/engines/toltecs/sound.cpp
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "graphics/cursorman.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/palette.h"
+#include "toltecs/render.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+#include "toltecs/script.h"
+#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
+
+namespace Toltecs {
+
+Sound::Sound(ToltecsEngine *vm) : _vm(vm) {
+ for (int i = 0; i < 4; i++) {
+ channels[i].type = 0;
+ channels[i].resIndex = -1;
+ }
+}
+
+Sound::~Sound() {
+}
+
+void Sound::playSpeech(int16 resIndex) {
+
+ // TODO
+
+ debug(0, "playSpeech(%d)", resIndex);
+
+ internalPlaySound(resIndex, -3, 50 /*TODO*/, 64);
+
+}
+
+void Sound::playSound(int16 resIndex, int16 type, int16 volume) {
+
+ // TODO: Use the right volumes
+
+ debug(0, "playSound(%d, %d, %d)", resIndex, type, volume);
+
+ if (volume == -1 || type == -2) {
+ if (type == -1) {
+ internalPlaySound(resIndex, type, 50 /*TODO*/, 64);
+ } else {
+ internalPlaySound(resIndex, type, 100 /*TODO*/, 64);
+ }
+ } else {
+ internalPlaySound(resIndex, type, 100 /*TODO*/, 64);
+ }
+
+}
+
+void Sound::playSoundAtPos(int16 resIndex, int16 x, int16 y) {
+
+ // TODO: Everything
+
+ debug(0, "playSoundAtPos(%d, %d, %d)", resIndex, x, y);
+
+ internalPlaySound(resIndex, 1, 50, 64);
+
+}
+
+void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning) {
+
+ // TODO
+
+ if (resIndex == -1) {
+ // Stop all sounds
+ _vm->_mixer->stopAll();
+ _vm->_screen->keepTalkTextItemsAlive();
+ for (int i = 0; i < 4; i++) {
+ channels[i].type = 0;
+ channels[i].resIndex = -1;
+ }
+ } else if (type == -2) {
+ // Stop sounds with specified resIndex
+ for (int i = 0; i < 4; i++) {
+ if (channels[i].resIndex == resIndex) {
+ _vm->_mixer->stopHandle(channels[i].handle);
+ channels[i].type = 0;
+ channels[i].resIndex = -1;
+ }
+ }
+ } else {
+
+ if (type == -3) {
+ // Stop sounds with type == -3 and play new sound
+ stopSpeech();
+ }
+
+ // Play new sound in empty channel
+
+ int freeChannel = -1;
+ for (int i = 0; i < 4; i++) {
+ if (channels[i].type == 0) {
+ freeChannel = i;
+ break;
+ }
+ }
+
+ // If all channels are in use no new sound will be played
+ if (freeChannel >= 0) {
+
+ byte *soundData = _vm->_res->load(resIndex);
+ uint32 soundSize = _vm->_res->getCurItemSize();
+
+ byte flags = Audio::Mixer::FLAG_UNSIGNED;
+ // Sounds with type == -1 loop
+ if (type == -1)
+ flags |= Audio::Mixer::FLAG_LOOP;
+ Audio::AudioStream *stream = Audio::makeLinearInputStream(soundData, soundSize, 22050, flags, 0, 0);
+
+ channels[freeChannel].type = type;
+ channels[freeChannel].resIndex = resIndex;
+
+ _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType/*TODO*/, &channels[freeChannel].handle,
+ stream, -1, volume, panning);
+
+ }
+
+ }
+
+}
+
+void Sound::updateSpeech() {
+ for (int i = 0; i < 4; i++) {
+ if (channels[i].type == -3 && _vm->_mixer->isSoundHandleActive(channels[i].handle)) {
+ _vm->_screen->keepTalkTextItemsAlive();
+ break;
+ }
+ }
+}
+
+void Sound::stopSpeech() {
+ for (int i = 0; i < 4; i++) {
+ if (channels[i].type == -3) {
+ _vm->_mixer->stopHandle(channels[i].handle);
+ _vm->_screen->keepTalkTextItemsAlive();
+ channels[i].type = 0;
+ channels[i].resIndex = -1;
+ }
+ }
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
new file mode 100644
index 0000000000..02f7a96eb3
--- /dev/null
+++ b/engines/toltecs/sound.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ *
+ */
+
+#ifndef TOLTECS_SOUND_H
+#define TOLTECS_SOUND_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+#include "toltecs/toltecs.h"
+
+namespace Toltecs {
+
+// 0x1219
+
+struct SoundChannel {
+ int16 resIndex;
+ int16 type;
+ Audio::SoundHandle handle;
+};
+
+class Sound {
+public:
+ Sound(ToltecsEngine *vm);
+ ~Sound();
+
+ void playSpeech(int16 resIndex);
+ void playSound(int16 resIndex, int16 type, int16 volume);
+ void playSoundAtPos(int16 resIndex, int16 x, int16 y);
+ void updateSpeech();
+ void stopSpeech();
+
+protected:
+ ToltecsEngine *_vm;
+
+ SoundChannel channels[4];
+
+ void internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning);
+
+};
+
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_SOUND_H */
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index a5c1caf89f..3aa160ac72 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -47,6 +47,7 @@
#include "toltecs/script.h"
#include "toltecs/screen.h"
#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
#include "toltecs/microtiles.h"
namespace Toltecs {
@@ -134,6 +135,8 @@ int ToltecsEngine::go() {
_segmap = new SegmentMap(this);
_moviePlayer = new MoviePlayer(this);
_menuSystem = new MenuSystem(this);
+
+ _sound = new Sound(this);
_system->showMouse(true);
@@ -141,7 +144,10 @@ int ToltecsEngine::go() {
#ifdef TEST_MOVIE
_screen->registerFont(0, 0x0D);
_screen->registerFont(1, 0x0E);
- _moviePlayer->playMovie(0x000012D8);
+ //_moviePlayer->playMovie(0x000012D8);
+ //_moviePlayer->playMovie(0x000012D7);
+ //_moviePlayer->playMovie(0x);
+ _moviePlayer->playMovie(0x000012E0);
#endif
//#define TEST_MENU
@@ -151,7 +157,7 @@ int ToltecsEngine::go() {
_screen->loadMouseCursor(12);
_palette->loadAddPalette(9, 224);
_palette->setDeltaPalette(_palette->getMainPalette(), 7, 0, 31, 224);
- _screen->finishTextDrawItems();
+ _screen->finishTalkTextItems();
_screen->clearSprites();
while (1) {
updateInput();
@@ -174,6 +180,8 @@ int ToltecsEngine::go() {
delete _segmap;
delete _moviePlayer;
delete _menuSystem;
+
+ delete _sound;
return 0;
}
@@ -335,7 +343,7 @@ void ToltecsEngine::setGuiHeight(int16 guiHeight) {
void ToltecsEngine::setCamera(int16 x, int16 y) {
- _screen->finishTextDrawItems();
+ _screen->finishTalkTextItems();
/*
// TODO: Fix checks; sometimes cameraY ended up being negative
@@ -401,14 +409,14 @@ void ToltecsEngine::updateCamera() {
//dirtyFullRefresh = -1;
_cameraX = _newCameraX;
_screen->_fullRefresh = true;
- _screen->finishTextDrawItems();
+ _screen->finishTalkTextItems();
}
if (_cameraY != _newCameraY) {
//dirtyFullRefresh = -1;
_cameraY = _newCameraY;
_screen->_fullRefresh = true;
- _screen->finishTextDrawItems();
+ _screen->finishTalkTextItems();
}
debug(0, "ToltecsEngine::updateCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
@@ -438,6 +446,7 @@ void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
if (_doSpeech) {
int16 resIndex = READ_LE_UINT16(scanData + 1);
debug(0, "ToltecsEngine::talk() playSound(resIndex: %d)", resIndex);
+ _sound->playSpeech(resIndex);
}
if (_doText) {
_screen->updateTalkText(slotIndex, slotOffset);
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index e0d64bda36..b9d08c3d59 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -59,6 +59,7 @@ class ResourceCache;
class ScriptInterpreter;
class Screen;
class SegmentMap;
+class Sound;
class ToltecsEngine : public ::Engine {
Common::KeyState _keyPressed;
@@ -112,6 +113,7 @@ public:
ScriptInterpreter *_script;
Screen *_screen;
SegmentMap *_segmap;
+ Sound *_sound;
uint _sceneResIndex;
int16 _sceneWidth, _sceneHeight;