aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--README2
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp2
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp2
-rw-r--r--common/taskbar.h2
-rw-r--r--common/updates.h2
-rwxr-xr-xconfigure4
-rw-r--r--devtools/scumm-md5.txt3
-rw-r--r--dists/scummvm.62
-rw-r--r--engines/agos/animation.cpp12
-rw-r--r--engines/agos/animation.h5
-rw-r--r--engines/dreamweb/dreamweb.cpp23
-rw-r--r--engines/dreamweb/dreamweb.h44
-rw-r--r--engines/dreamweb/keypad.cpp23
-rw-r--r--engines/dreamweb/monitor.cpp13
-rw-r--r--engines/dreamweb/newplace.cpp5
-rw-r--r--engines/dreamweb/object.cpp2
-rw-r--r--engines/dreamweb/people.cpp16
-rw-r--r--engines/dreamweb/print.cpp24
-rw-r--r--engines/dreamweb/rain.cpp7
-rw-r--r--engines/dreamweb/saveload.cpp12
-rw-r--r--engines/dreamweb/sound.cpp144
-rw-r--r--engines/dreamweb/sound.h92
-rw-r--r--engines/dreamweb/sprite.cpp26
-rw-r--r--engines/dreamweb/stubs.cpp64
-rw-r--r--engines/dreamweb/talk.cpp32
-rw-r--r--engines/dreamweb/titles.cpp68
-rw-r--r--engines/dreamweb/use.cpp33
-rw-r--r--engines/dreamweb/vgafades.cpp5
-rw-r--r--engines/dreamweb/vgagrafx.cpp4
-rw-r--r--engines/gob/aniobject.cpp26
-rw-r--r--engines/gob/aniobject.h8
-rw-r--r--engines/gob/draw.cpp17
-rw-r--r--engines/gob/draw.h9
-rw-r--r--engines/gob/draw_v2.cpp39
-rw-r--r--engines/gob/inter.h11
-rw-r--r--engines/gob/inter_geisha.cpp10
-rw-r--r--engines/gob/inter_v7.cpp144
-rw-r--r--engines/gob/minigames/geisha/diving.cpp8
-rw-r--r--engines/gob/minigames/geisha/meter.cpp4
-rw-r--r--engines/gob/minigames/geisha/meter.h2
-rw-r--r--engines/gob/minigames/geisha/penetration.cpp451
-rw-r--r--engines/gob/minigames/geisha/penetration.h60
-rw-r--r--engines/gob/surface.cpp12
-rw-r--r--engines/gob/surface.h1
-rw-r--r--engines/gob/video.cpp6
-rw-r--r--engines/mohawk/video.cpp8
-rw-r--r--engines/mohawk/video.h4
-rw-r--r--engines/sci/detection_tables.h6
-rw-r--r--engines/sci/engine/kernel.h1
-rw-r--r--engines/sci/engine/kernel_tables.h7
-rw-r--r--engines/sci/engine/kfile.cpp6
-rw-r--r--engines/sci/engine/kmisc.cpp53
-rw-r--r--engines/sci/video/robot_decoder.cpp12
-rw-r--r--engines/sci/video/robot_decoder.h5
-rw-r--r--engines/scumm/detection.cpp10
-rw-r--r--engines/scumm/detection.h1
-rw-r--r--engines/scumm/detection_tables.h6
-rw-r--r--engines/scumm/he/script_v100he.cpp6
-rw-r--r--engines/scumm/he/script_v90he.cpp4
-rw-r--r--engines/scumm/script.cpp8
-rw-r--r--engines/scumm/scumm-md5.h5
-rw-r--r--engines/scumm/scumm.cpp7
-rw-r--r--engines/scumm/scumm.h1
-rw-r--r--engines/sword25/fmv/theora_decoder.cpp12
-rw-r--r--engines/sword25/fmv/theora_decoder.h3
-rw-r--r--gui/themes/translations.datbin311215 -> 312684 bytes
-rw-r--r--po/cs_CZ.po77
-rw-r--r--video/avi_decoder.cpp12
-rw-r--r--video/avi_decoder.h5
-rw-r--r--video/bink_decoder.cpp12
-rw-r--r--video/bink_decoder.h5
-rw-r--r--video/coktel_decoder.cpp24
-rw-r--r--video/coktel_decoder.h10
-rw-r--r--video/psx_decoder.cpp12
-rw-r--r--video/psx_decoder.h5
-rw-r--r--video/qt_decoder.cpp14
-rw-r--r--video/qt_decoder.h4
-rw-r--r--video/smk_decoder.cpp12
-rw-r--r--video/smk_decoder.h8
-rw-r--r--video/video_decoder.cpp14
-rw-r--r--video/video_decoder.h46
82 files changed, 1465 insertions, 442 deletions
diff --git a/NEWS b/NEWS
index 4b3203dc66..ed98cdc83f 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ For a more comprehensive changelog of the latest experimental code, see:
1.5.0 (????-??-??)
New Games:
+ - Added support for Backyard Baseball 2003.
- Added support for Blue Force.
- Added support for Darby the Dragon.
- Added support for Dreamweb.
diff --git a/README b/README
index 8afe8c9bc8..81b28830c2 100644
--- a/README
+++ b/README
@@ -272,6 +272,7 @@ Other Games:
SCUMM Games by Humongous Entertainment:
Backyard Baseball [baseball]
Backyard Baseball 2001 [baseball2001]
+ Backyard Baseball 2003 [baseball2003]
Backyard Football [football]
Big Thinkers First Grade [thinker1]
Big Thinkers Kindergarten [thinkerk]
@@ -342,7 +343,6 @@ these at your own risk, and please do not file bug reports about them.
If you want the latest updates on game compatibility, visit our web site
and view the compatibility chart.
- Backyard Baseball 2003 [baseball2003]
Backyard Football 2002 [football2002]
Backyard Soccer [soccer]
Backyard Soccer MLS [soccermls]
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index b37d631c6d..67041ae17b 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -160,7 +160,7 @@ void OpenGLSdlGraphicsManager::detectSupportedFormats() {
_hwscreen->format->Rshift, _hwscreen->format->Gshift,
_hwscreen->format->Bshift, _hwscreen->format->Ashift);
- // Workaround to MacOSX SDL not providing an accurate Aloss value.
+ // Workaround to SDL not providing an accurate Aloss value on Mac OS X.
if (_hwscreen->format->Amask == 0)
format.aLoss = 8;
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 9631c3c07e..e841ecb834 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -458,7 +458,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
_hwscreen->format->Rshift, _hwscreen->format->Gshift,
_hwscreen->format->Bshift, _hwscreen->format->Ashift);
- // Workaround to MacOSX SDL not providing an accurate Aloss value.
+ // Workaround to SDL not providing an accurate Aloss value on Mac OS X.
if (_hwscreen->format->Amask == 0)
format.aLoss = 8;
diff --git a/common/taskbar.h b/common/taskbar.h
index ba99d4e487..6f28028e74 100644
--- a/common/taskbar.h
+++ b/common/taskbar.h
@@ -34,7 +34,7 @@ namespace Common {
* The TaskbarManager allows interaction with the ScummVM application icon:
* - in the taskbar on Windows 7 and later
* - in the launcher for Unity
- * - in the dock on MacOSX
+ * - in the dock on Mac OS X
* - ...
*
* This allows GUI code and engines to display a progress bar, an overlay icon and/or count
diff --git a/common/updates.h b/common/updates.h
index 1e0babdf6d..4d58a216fb 100644
--- a/common/updates.h
+++ b/common/updates.h
@@ -30,7 +30,7 @@ namespace Common {
/**
* The UpdateManager allows configuring of the automatic update checking
* for systems that support it:
- * - using Sparkle on MacOSX
+ * - using Sparkle on Mac OS X
* - using WinSparkle on Windows
*
* Most of the update checking is completely automated and this class only
diff --git a/configure b/configure
index d310148f06..5905f408a0 100755
--- a/configure
+++ b/configure
@@ -835,8 +835,8 @@ Optional Libraries:
installed (optional)
--disable-fluidsynth disable fluidsynth MIDI driver [autodetect]
- --with-sparkle-prefix=DIR Prefix where sparkle is installed (MacOSX only - optional)
- --disable-sparkle disable sparkle automatic update support [MacOSX only - autodetect]
+ --with-sparkle-prefix=DIR Prefix where sparkle is installed (Mac OS X only - optional)
+ --disable-sparkle disable sparkle automatic update support [Mac OS X only - autodetect]
--with-sdl-prefix=DIR Prefix where the sdl-config script is
installed (optional)
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 7d2ea94f10..f08b7d29d2 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -540,8 +540,8 @@ freddi3 Freddi Fish 3: The Case of the Stolen Conch Shell
freddi4 Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch
4f580a021eee026f3b4589e17d130d78 -1 All All - - - Kirben, sev
14d48c95b43ddeb983254cf6c43851f1 -1 nl All - - - adutchguy, daniel9
+ 3b832f4a90740bf22e9b8ed42ca0128c -1 gb All HE 99 - - Reckless
d74122362a77ec24525fdd50297dfd82 -1 fr Mac - - - ThierryFR
- 3b832f4a90740bf22e9b8ed42ca0128c -1 gb Windows HE 99 - - Reckless
07b810e37be7489263f7bc7627d4765d -1 ru Windows unenc Unencrypted - sev
a336134914eaab4892d35625aa15ad1d -1 ru Windows HE 99 - - George Kormendi
b5298a5c15ffbe8b381d51ea4e26d35c -1 de All HE 99 - - Joachim Eberhard
@@ -841,6 +841,7 @@ spyfox SPY Fox 1: Dry Cereal
3de99ef0523f8ca7958faa3afccd035a -1 us All HE 100 Updated - Kirben
23394c8d29cc63c61313959431a12476 -1 en Windows HE 100 Updated - Jonathan
50b831f11b8c4b83784cf81f4dcc69ea -1 en Wii HE 100 - - sanguinehearts
+ 15878e3bee2e1e759184abee98589eaa -1 en iOS HE 100 - - clone2727
53e94115b55dd51d4b8ff0871aa1df1e 20103 en All - Demo - khalek, sev
fbdd947d21e8f5bac6d6f7a316af1c5a 15693 en All - Demo - sev
diff --git a/dists/scummvm.6 b/dists/scummvm.6
index b192104684..2075a5c8f5 100644
--- a/dists/scummvm.6
+++ b/dists/scummvm.6
@@ -37,7 +37,7 @@ Output using ALSA sequencer device
.It Em amidi
Use the MorphOS MIDI system, for MorphOS users
.It Em core
-CoreAudio sound, for MacOS X users
+CoreAudio sound, for Mac OS X users
.It Em mt32
MT-32 emulation
.It Em null
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index 29d1b36e19..10c01741ae 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -333,7 +333,7 @@ void MoviePlayerDXA::startSound() {
if (_bgSoundStream != NULL) {
_vm->_mixer->stopHandle(_bgSound);
- _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream);
+ _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream, -1, getVolume(), getBalance());
}
}
@@ -399,6 +399,16 @@ bool MoviePlayerDXA::processFrame() {
return false;
}
+void MoviePlayerDXA::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(_bgSound))
+ g_system->getMixer()->setChannelVolume(_bgSound, getVolume());
+}
+
+void MoviePlayerDXA::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(_bgSound))
+ g_system->getMixer()->setChannelBalance(_bgSound, getBalance());
+}
+
///////////////////////////////////////////////////////////////////////////////
// Movie player for Smacker movies
///////////////////////////////////////////////////////////////////////////////
diff --git a/engines/agos/animation.h b/engines/agos/animation.h
index 11936aa338..d1ff074b03 100644
--- a/engines/agos/animation.h
+++ b/engines/agos/animation.h
@@ -83,6 +83,11 @@ public:
void nextFrame();
virtual void stopVideo();
+protected:
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
private:
void handleNextFrame();
bool processFrame();
diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp
index 11e8e3f8cc..0ca98d5a7b 100644
--- a/engines/dreamweb/dreamweb.cpp
+++ b/engines/dreamweb/dreamweb.cpp
@@ -35,6 +35,7 @@
#include "graphics/palette.h"
#include "graphics/surface.h"
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -46,21 +47,15 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam
_roomDesc(kNumRoomTexts), _freeDesc(kNumFreeTexts),
_personText(kNumPersonTexts) {
- // Setup mixer
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
- _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
-
_vSyncInterrupt = false;
_console = 0;
+ _sound = 0;
DebugMan.addDebugChannel(kDebugAnimation, "Animation", "Animation Debug Flag");
DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Track Save/Load Function");
_speed = 1;
_turbo = false;
_oldMouseState = 0;
- _channel0 = 0;
- _channel1 = 0;
_datafilePrefix = "DREAMWEB.";
_speechDirName = "SPEECH";
@@ -85,16 +80,6 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam
_openChangeSize = kInventx+(4*kItempicsize);
_quitRequested = false;
- _currentSample = 0xff;
- _channel0Playing = 0;
- _channel0Repeat = 0;
- _channel1Playing = 0xff;
-
- _volume = 0;
- _volumeTo = 0;
- _volumeDirection = 0;
- _volumeCount = 0;
-
_speechLoaded = false;
_backdropBlocks = 0;
@@ -246,6 +231,7 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam
DreamWebEngine::~DreamWebEngine() {
DebugMan.clearAllDebugChannels();
delete _console;
+ delete _sound;
}
static void vSyncInterrupt(void *refCon) {
@@ -286,7 +272,7 @@ void DreamWebEngine::processEvents() {
return;
}
- soundHandler();
+ _sound->soundHandler();
Common::Event event;
int softKey, hardKey;
while (_eventMan->pollEvent(event)) {
@@ -382,6 +368,7 @@ void DreamWebEngine::processEvents() {
Common::Error DreamWebEngine::run() {
syncSoundSettings();
_console = new DreamWebConsole(this);
+ _sound = new DreamWebSound(this);
ConfMan.registerDefault("originalsaveload", "false");
ConfMan.registerDefault("bright_palette", true);
diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h
index 6744b53ebc..48d44c0380 100644
--- a/engines/dreamweb/dreamweb.h
+++ b/engines/dreamweb/dreamweb.h
@@ -99,10 +99,12 @@ enum {
};
struct DreamWebGameDescription;
+class DreamWebSound;
class DreamWebEngine : public Engine {
private:
DreamWebConsole *_console;
+ DreamWebSound *_sound;
bool _vSyncInterrupt;
protected:
@@ -142,7 +144,6 @@ public:
void quit();
- void loadSounds(uint bank, const Common::String &suffix);
bool loadSpeech(const Common::String &filename);
void enableSavingOrLoading(bool enable = true) { _enableSavingOrLoading = enable; }
@@ -151,15 +152,12 @@ public:
uint8 modifyChar(uint8 c) const;
Common::String modifyFileName(const char *);
- void stopSound(uint8 channel);
-
const Common::String& getDatafilePrefix() { return _datafilePrefix; };
+ const Common::String& getSpeechDirName() { return _speechDirName; };
private:
void keyPressed(uint16 ascii);
void setSpeed(uint speed);
- void soundHandler();
- void playSound(uint8 channel, uint8 id, uint8 loops);
const DreamWebGameDescription *_gameDescription;
Common::RandomSource _rnd;
@@ -171,22 +169,6 @@ private:
uint _oldMouseState;
bool _enableSavingOrLoading;
- struct Sample {
- uint offset;
- uint size;
- Sample(): offset(), size() {}
- };
-
- struct SoundData {
- Common::Array<Sample> samples;
- Common::Array<uint8> data;
- };
- SoundData _soundData[2];
- Common::Array<uint8> _speechData;
-
- Audio::SoundHandle _channelHandle[2];
- uint8 _channel0, _channel1;
-
protected:
GameVars _vars; // saved variables
@@ -327,16 +309,6 @@ public:
// sound related
uint8 _roomsSample;
- uint8 _currentSample;
- uint8 _channel0Playing;
- uint8 _channel0Repeat;
- uint8 _channel1Playing;
-
- uint8 _volume;
- uint8 _volumeTo;
- int8 _volumeDirection;
- uint8 _volumeCount;
-
bool _speechLoaded;
// misc variables
@@ -715,15 +687,6 @@ public:
void showSaveOps();
void showLoadOps();
- // from sound.cpp
- bool loadSpeech(byte type1, int idx1, byte type2, int idx2);
- void volumeAdjust();
- void cancelCh0();
- void cancelCh1();
- void loadRoomsSample();
- void playChannel0(uint8 index, uint8 repeat);
- void playChannel1(uint8 index);
-
// from sprite.cpp
void printSprites();
void printASprite(const Sprite *sprite);
@@ -1135,7 +1098,6 @@ public:
void frameOutBh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
void frameOutFx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
void doShake();
- void vSync();
void setMode();
void showPCX(const Common::String &suffix);
void showFrameInternal(const uint8 *pSrc, uint16 x, uint16 y, uint8 effectsFlag, uint8 width, uint8 height);
diff --git a/engines/dreamweb/keypad.cpp b/engines/dreamweb/keypad.cpp
index 2ab5835997..3580f8ad52 100644
--- a/engines/dreamweb/keypad.cpp
+++ b/engines/dreamweb/keypad.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -62,11 +63,11 @@ void DreamWebEngine::enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 d
readMouse();
showKeypad();
showPointer();
- vSync();
+ waitForVSync();
if (_pressCount == 0) {
_pressed = 255;
_graphicPress = 255;
- vSync();
+ waitForVSync();
} else
--_pressCount;
@@ -85,7 +86,7 @@ void DreamWebEngine::enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 d
if (_pressed == 11) {
if (isItRight(digit0, digit1, digit2, digit3))
_vars._lockStatus = 0;
- playChannel1(11);
+ _sound->playChannel1(11);
_lightCount = 120;
_pressPointer = 0;
}
@@ -180,7 +181,7 @@ void DreamWebEngine::buttonPress(uint8 buttonId) {
_graphicPress = buttonId + 21;
_pressCount = 40;
if (buttonId != 11)
- playChannel1(10);
+ _sound->playChannel1(10);
}
}
@@ -252,7 +253,7 @@ void DreamWebEngine::useMenu() {
showMenu();
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpMenu();
dumpTextLine();
@@ -311,7 +312,7 @@ void DreamWebEngine::viewFolder() {
delPointer();
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
checkFolderCoords();
@@ -508,7 +509,7 @@ void DreamWebEngine::enterSymbol() {
showSymbol();
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
dumpSymbol();
@@ -532,7 +533,7 @@ void DreamWebEngine::enterSymbol() {
_symbolGraphics.clear();
restoreReels();
workToScreenM();
- playChannel1(13);
+ _sound->playChannel1(13);
} else {
removeSetObject(46);
placeSetObject(43);
@@ -743,7 +744,7 @@ void DreamWebEngine::useDiary() {
readMouse();
showDiaryKeys();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpDiaryKeys();
dumpTextLine();
@@ -820,7 +821,7 @@ void DreamWebEngine::diaryKeyP() {
_pressCount)
return; // notkeyp
- playChannel1(16);
+ _sound->playChannel1(16);
_pressCount = 12;
_pressed = 'P';
_diaryPage--;
@@ -837,7 +838,7 @@ void DreamWebEngine::diaryKeyN() {
_pressCount)
return; // notkeyn
- playChannel1(16);
+ _sound->playChannel1(16);
_pressCount = 12;
_pressed = 'N';
_diaryPage++;
diff --git a/engines/dreamweb/monitor.cpp b/engines/dreamweb/monitor.cpp
index 25435ae0e9..4e9d8eecc1 100644
--- a/engines/dreamweb/monitor.cpp
+++ b/engines/dreamweb/monitor.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -97,7 +98,7 @@ void DreamWebEngine::useMon() {
_textFile3.clear();
_getBack = 1;
- playChannel1(26);
+ _sound->playChannel1(26);
_manIsOffScreen = 0;
restoreAll();
redrawMainScrn();
@@ -180,7 +181,7 @@ void DreamWebEngine::monitorLogo() {
printLogo();
//fadeUpMon(); // FIXME: Commented out in ASM
printLogo();
- playChannel1(26);
+ _sound->playChannel1(26);
randomAccess(20);
} else {
printLogo();
@@ -202,7 +203,7 @@ void DreamWebEngine::input() {
_cursLocY = _monAdY;
while (true) {
printCurs();
- vSync();
+ waitForVSync();
delCurs();
readKey();
if (_quitRequested)
@@ -288,7 +289,7 @@ void DreamWebEngine::scrollMonitor() {
printLogo();
printUnderMonitor();
workToScreen();
- playChannel1(25);
+ _sound->playChannel1(25);
}
void DreamWebEngine::showCurrentFile() {
@@ -318,8 +319,8 @@ void DreamWebEngine::accessLightOff() {
void DreamWebEngine::randomAccess(uint16 count) {
for (uint16 i = 0; i < count; ++i) {
- vSync();
- vSync();
+ waitForVSync();
+ waitForVSync();
uint16 v = _rnd.getRandomNumber(15);
if (v < 10)
accessLightOff();
diff --git a/engines/dreamweb/newplace.cpp b/engines/dreamweb/newplace.cpp
index 529c45bd4a..5b4b0260f5 100644
--- a/engines/dreamweb/newplace.cpp
+++ b/engines/dreamweb/newplace.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -55,7 +56,7 @@ void DreamWebEngine::selectLocation() {
_pointerFrame = 0;
showPointer();
workToScreen();
- playChannel0(9, 255);
+ _sound->playChannel0(9, 255);
_newLocation = 255;
while (_newLocation == 255) {
@@ -65,7 +66,7 @@ void DreamWebEngine::selectLocation() {
delPointer();
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
diff --git a/engines/dreamweb/object.cpp b/engines/dreamweb/object.cpp
index 443366561a..b42591ef91 100644
--- a/engines/dreamweb/object.cpp
+++ b/engines/dreamweb/object.cpp
@@ -147,7 +147,7 @@ void DreamWebEngine::examineOb(bool examineAgain) {
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
delPointer();
diff --git a/engines/dreamweb/people.cpp b/engines/dreamweb/people.cpp
index dfb5c62618..36a756a49b 100644
--- a/engines/dreamweb/people.cpp
+++ b/engines/dreamweb/people.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -149,7 +150,7 @@ void DreamWebEngine::madmanText() {
if (hasSpeech()) {
if (_speechCount > 15)
return;
- if (_channel1Playing != 255)
+ if (_sound->isChannel1Playing())
return;
origCount = _speechCount;
++_speechCount;
@@ -250,7 +251,7 @@ bool DreamWebEngine::checkSpeed(ReelRoutine &routine) {
void DreamWebEngine::sparkyDrip(ReelRoutine &routine) {
if (checkSpeed(routine))
- playChannel0(14, 0);
+ _sound->playChannel0(14, 0);
}
void DreamWebEngine::genericPerson(ReelRoutine &routine) {
@@ -430,7 +431,7 @@ void DreamWebEngine::drinker(ReelRoutine &routine) {
void DreamWebEngine::alleyBarkSound(ReelRoutine &routine) {
uint16 prevReelPointer = routine.reelPointer() - 1;
if (prevReelPointer == 0) {
- playChannel1(14);
+ _sound->playChannel1(14);
routine.setReelPointer(1000);
} else {
routine.setReelPointer(prevReelPointer);
@@ -523,7 +524,7 @@ void DreamWebEngine::gates(ReelRoutine &routine) {
if (checkSpeed(routine)) {
uint16 nextReelPointer = routine.reelPointer() + 1;
if (nextReelPointer == 116)
- playChannel1(17);
+ _sound->playChannel1(17);
if (nextReelPointer >= 110)
routine.period = 2;
if (nextReelPointer == 120) {
@@ -579,12 +580,12 @@ void DreamWebEngine::carParkDrip(ReelRoutine &routine) {
if (!checkSpeed(routine))
return; // cantdrip2
- playChannel1(14);
+ _sound->playChannel1(14);
}
void DreamWebEngine::foghornSound(ReelRoutine &routine) {
if (randomNumber() == 198)
- playChannel1(13);
+ _sound->playChannel1(13);
}
void DreamWebEngine::train(ReelRoutine &routine) {
@@ -1027,8 +1028,7 @@ void DreamWebEngine::endGameSeq(ReelRoutine &routine) {
fadeScreenDownHalf();
} else if (nextReelPointer == 324) {
fadeScreenDowns();
- _volumeTo = 7;
- _volumeDirection = 1;
+ _sound->volumeChange(7, 1);
}
if (nextReelPointer == 340)
diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp
index a6b93a5590..3a2c45e07b 100644
--- a/engines/dreamweb/print.cpp
+++ b/engines/dreamweb/print.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -197,7 +198,7 @@ uint8 DreamWebEngine::kernChars(uint8 firstChar, uint8 secondChar, uint8 width)
uint16 DreamWebEngine::waitFrames() {
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
delPointer();
return _mouseButton;
@@ -231,7 +232,7 @@ const char *DreamWebEngine::monPrint(const char *string) {
_cursLocY = _monAdY;
_mainTimer = 1;
printCurs();
- vSync();
+ waitForVSync();
lockMon();
delCurs();
} while (--count);
@@ -246,10 +247,9 @@ const char *DreamWebEngine::monPrint(const char *string) {
}
void DreamWebEngine::rollEndCreditsGameWon() {
- playChannel0(16, 255);
- _volume = 7;
- _volumeTo = 0;
- _volumeDirection = -1;
+ _sound->playChannel0(16, 255);
+ _sound->volumeSet(7);
+ _sound->volumeChange(0, -1);
multiGet(_mapStore, 75, 20, 160, 160);
@@ -261,9 +261,9 @@ void DreamWebEngine::rollEndCreditsGameWon() {
// then move it up one pixel until we shifted it by a complete
// line of text.
for (int j = 0; j < linespacing; ++j) {
- vSync();
+ waitForVSync();
multiPut(_mapStore, 75, 20, 160, 160);
- vSync();
+ waitForVSync();
// Output up to 18 lines of text
uint16 y = 10 - j;
@@ -273,7 +273,7 @@ void DreamWebEngine::rollEndCreditsGameWon() {
y += linespacing;
}
- vSync();
+ waitForVSync();
multiDump(75, 20, 160, 160);
}
@@ -300,9 +300,9 @@ void DreamWebEngine::rollEndCreditsGameLost() {
// then move it up one pixel until we shifted it by a complete
// line of text.
for (int j = 0; j < linespacing; ++j) {
- vSync();
+ waitForVSync();
multiPut(_mapStore, 25, 20, 160, 160);
- vSync();
+ waitForVSync();
// Output up to 18 lines of text
uint16 y = 10 - j;
@@ -312,7 +312,7 @@ void DreamWebEngine::rollEndCreditsGameLost() {
y += linespacing;
}
- vSync();
+ waitForVSync();
multiDump(25, 20, 160, 160);
if (_lastHardKey == 1)
diff --git a/engines/dreamweb/rain.cpp b/engines/dreamweb/rain.cpp
index 7db4744cbf..8e42e0c161 100644
--- a/engines/dreamweb/rain.cpp
+++ b/engines/dreamweb/rain.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -50,7 +51,7 @@ void DreamWebEngine::showRain() {
}
}
- if (_channel1Playing != 255)
+ if (_sound->isChannel1Playing())
return;
if (_realLocation == 2 && _vars._beenMugged != 1)
return;
@@ -61,11 +62,11 @@ void DreamWebEngine::showRain() {
return;
uint8 soundIndex;
- if (_channel0Playing != 6)
+ if (_sound->getChannel0Playing() != 6)
soundIndex = 4;
else
soundIndex = 7;
- playChannel1(soundIndex);
+ _sound->playChannel1(soundIndex);
}
uint8 DreamWebEngine::getBlockOfPixel(uint8 x, uint8 y) {
diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp
index d30bf754de..c8fb537fec 100644
--- a/engines/dreamweb/saveload.cpp
+++ b/engines/dreamweb/saveload.cpp
@@ -20,7 +20,9 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
+
#include "engines/metaengine.h"
#include "graphics/thumbnail.h"
#include "gui/saveload.h"
@@ -136,7 +138,7 @@ void DreamWebEngine::doLoad(int savegameId) {
delPointer();
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
RectWithCallback loadlist[] = {
@@ -181,7 +183,7 @@ void DreamWebEngine::doLoad(int savegameId) {
_saveGraphics.clear();
startLoading(g_madeUpRoomDat);
- loadRoomsSample();
+ _sound->loadRoomsSample(_roomsSample);
_roomLoaded = 1;
_newLocation = 255;
clearSprites();
@@ -227,7 +229,7 @@ void DreamWebEngine::saveGame() {
checkInput();
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
@@ -348,7 +350,7 @@ void DreamWebEngine::doSaveLoad() {
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
delPointer();
@@ -429,7 +431,7 @@ void DreamWebEngine::discOps() {
delPointer();
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
checkCoords(discOpsList);
diff --git a/engines/dreamweb/sound.cpp b/engines/dreamweb/sound.cpp
index b3d5db9e0d..76c734e932 100644
--- a/engines/dreamweb/sound.cpp
+++ b/engines/dreamweb/sound.cpp
@@ -20,28 +20,53 @@
*
*/
-#include "dreamweb/dreamweb.h"
-
-#include "audio/mixer.h"
#include "audio/decoders/raw.h"
-
#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/file.h"
+
+#include "dreamweb/dreamweb.h"
+#include "dreamweb/sound.h"
namespace DreamWeb {
-bool DreamWebEngine::loadSpeech(byte type1, int idx1, byte type2, int idx2) {
+DreamWebSound::DreamWebSound(DreamWebEngine *vm) : _vm(vm) {
+ _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+ _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+
+ _channel0 = 0;
+ _channel1 = 0;
+
+ _currentSample = 0xff;
+ _channel0Playing = 0;
+ _channel0Repeat = 0;
+ _channel0NewSound = false;
+ _channel1Playing = 255;
+
+ _volume = 0;
+ _volumeTo = 0;
+ _volumeDirection = 0;
+ _volumeCount = 0;
+}
+
+DreamWebSound::~DreamWebSound() {
+}
+
+bool DreamWebSound::loadSpeech(byte type1, int idx1, byte type2, int idx2) {
cancelCh1();
Common::String name = Common::String::format("%c%02d%c%04d.RAW", type1, idx1, type2, idx2);
- //debug("name = %s", name.c_str());
- bool result = loadSpeech(name);
-
- _speechLoaded = result;
- return result;
+ debug(2, "loadSpeech() name:%s", name.c_str());
+ return loadSpeech(name);
}
+void DreamWebSound::volumeChange(uint8 value, int8 direction) {
+ _volumeTo = value;
+ _volumeDirection = direction;
+}
-void DreamWebEngine::volumeAdjust() {
+void DreamWebSound::volumeAdjust() {
if (_volumeDirection == 0)
return;
if (_volume != _volumeTo) {
@@ -54,39 +79,41 @@ void DreamWebEngine::volumeAdjust() {
}
}
-void DreamWebEngine::playChannel0(uint8 index, uint8 repeat) {
+void DreamWebSound::playChannel0(uint8 index, uint8 repeat) {
debug(1, "playChannel0(index:%d, repeat:%d)", index, repeat);
- _channel0Playing = index;
- if (index >= 12)
- index -= 12;
+ if (index == _channel0Playing) {
+ warning("playChannel0(index: %d) already playing! Forcing restart...", index);
+ _channel0NewSound = true;
+ }
+
+ _channel0Playing = index;
_channel0Repeat = repeat;
}
-void DreamWebEngine::playChannel1(uint8 index) {
+void DreamWebSound::playChannel1(uint8 index) {
+ debug(1, "playChannel1(index:%d)", index);
if (_channel1Playing == 7)
return;
_channel1Playing = index;
- if (index >= 12)
- index -= 12;
}
-void DreamWebEngine::cancelCh0() {
+void DreamWebSound::cancelCh0() {
debug(1, "cancelCh0()");
- _channel0Repeat = 0;
_channel0Playing = 255;
+ _channel0Repeat = 0;
stopSound(0);
}
-void DreamWebEngine::cancelCh1() {
+void DreamWebSound::cancelCh1() {
+ debug(1, "cancelCh1()");
_channel1Playing = 255;
stopSound(1);
}
-void DreamWebEngine::loadRoomsSample() {
- debug(1, "loadRoomsSample() _roomsSample:%d", _roomsSample);
- uint8 sample = _roomsSample;
+void DreamWebSound::loadRoomsSample(uint8 sample) {
+ debug(1, "loadRoomsSample(sample:%d)", sample);
if (sample == 255 || _currentSample == sample)
return; // loaded already
@@ -104,13 +131,8 @@ void DreamWebEngine::loadRoomsSample() {
loadSounds(1, sampleSuffix.c_str());
}
-} // End of namespace DreamWeb
-
-
-namespace DreamWeb {
-
-void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) {
- debug(1, "playSound(%u, %u, %u)", channel, id, loops);
+void DreamWebSound::playSound(uint8 channel, uint8 id, uint8 loops) {
+ debug(1, "playSound(channel:%u, id:%u, loops:%u)", channel, id, loops);
int bank = 0;
bool speech = false;
@@ -140,47 +162,42 @@ void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) {
error("out of memory: cannot allocate memory for sound(%u bytes)", sample.size);
memcpy(buffer, data.data.begin() + sample.offset, sample.size);
- raw = Audio::makeRawStream(
- buffer,
- sample.size, 22050, Audio::FLAG_UNSIGNED);
+ raw = Audio::makeRawStream(buffer, sample.size, 22050, Audio::FLAG_UNSIGNED);
} else {
uint8 *buffer = (uint8 *)malloc(_speechData.size());
if (!buffer)
error("out of memory: cannot allocate memory for sound(%u bytes)", _speechData.size());
memcpy(buffer, _speechData.begin(), _speechData.size());
- raw = Audio::makeRawStream(
- buffer,
- _speechData.size(), 22050, Audio::FLAG_UNSIGNED);
-
+ raw = Audio::makeRawStream(buffer, _speechData.size(), 22050, Audio::FLAG_UNSIGNED);
}
Audio::AudioStream *stream;
if (loops > 1) {
- stream = new Audio::LoopingAudioStream(raw, loops < 255? loops: 0);
+ stream = new Audio::LoopingAudioStream(raw, (loops < 255) ? loops : 0);
} else
stream = raw;
- if (_mixer->isSoundHandleActive(_channelHandle[channel]))
- _mixer->stopHandle(_channelHandle[channel]);
- _mixer->playStream(type, &_channelHandle[channel], stream);
+ if (_vm->_mixer->isSoundHandleActive(_channelHandle[channel]))
+ _vm->_mixer->stopHandle(_channelHandle[channel]);
+ _vm->_mixer->playStream(type, &_channelHandle[channel], stream);
}
-void DreamWebEngine::stopSound(uint8 channel) {
+void DreamWebSound::stopSound(uint8 channel) {
debug(1, "stopSound(%u)", channel);
assert(channel == 0 || channel == 1);
- _mixer->stopHandle(_channelHandle[channel]);
+ _vm->_mixer->stopHandle(_channelHandle[channel]);
if (channel == 0)
_channel0 = 0;
else
_channel1 = 0;
}
-bool DreamWebEngine::loadSpeech(const Common::String &filename) {
- if (!hasSpeech())
+bool DreamWebSound::loadSpeech(const Common::String &filename) {
+ if (!_vm->hasSpeech())
return false;
Common::File file;
- if (!file.open(_speechDirName + "/" + filename))
+ if (!file.open(_vm->getSpeechDirName() + "/" + filename))
return false;
debug(1, "loadSpeech(%s)", filename.c_str());
@@ -192,13 +209,8 @@ bool DreamWebEngine::loadSpeech(const Common::String &filename) {
return true;
}
-void DreamWebEngine::soundHandler() {
- static uint8 volumeOld = 0, channel0Old = 0, channel0PlayingOld = 0;
- if (_volume != volumeOld || _channel0 != channel0Old || _channel0Playing != channel0PlayingOld)
- debug(1, "soundHandler() _volume: %d _channel0: %d _channel0Playing: %d", _volume, _channel0, _channel0Playing);
- volumeOld = _volume, channel0Old = _channel0, channel0PlayingOld = _channel0Playing;
-
- _subtitles = ConfMan.getBool("subtitles");
+void DreamWebSound::soundHandler() {
+ _vm->_subtitles = ConfMan.getBool("subtitles");
volumeAdjust();
uint volume = _volume;
@@ -215,7 +227,7 @@ void DreamWebEngine::soundHandler() {
if (volume >= 8)
volume = 7;
volume = (8 - volume) * Audio::Mixer::kMaxChannelVolume / 8;
- _mixer->setChannelVolume(_channelHandle[0], volume);
+ _vm->_mixer->setChannelVolume(_channelHandle[0], volume);
uint8 ch0 = _channel0Playing;
if (ch0 == 255)
@@ -225,8 +237,9 @@ void DreamWebEngine::soundHandler() {
ch1 = 0;
uint8 ch0loop = _channel0Repeat;
- if (_channel0 != ch0) {
+ if (_channel0 != ch0 || _channel0NewSound) {
_channel0 = ch0;
+ _channel0NewSound = false;
if (ch0) {
playSound(0, ch0, ch0loop);
}
@@ -237,20 +250,19 @@ void DreamWebEngine::soundHandler() {
playSound(1, ch1, 1);
}
}
- if (!_mixer->isSoundHandleActive(_channelHandle[0])) {
- if (_channel0Playing != 255 && _channel0 != 0)
- debug(1, "!_mixer->isSoundHandleActive _channelHandle[0] _channel0Playing:%d _channel0:%d", _channel0Playing, _channel0);
+
+ if (!_vm->_mixer->isSoundHandleActive(_channelHandle[0])) {
_channel0Playing = 255;
_channel0 = 0;
}
- if (!_mixer->isSoundHandleActive(_channelHandle[1])) {
+ if (!_vm->_mixer->isSoundHandleActive(_channelHandle[1])) {
_channel1Playing = 255;
_channel1 = 0;
}
}
-void DreamWebEngine::loadSounds(uint bank, const Common::String &suffix) {
- Common::String filename = getDatafilePrefix() + suffix;
+void DreamWebSound::loadSounds(uint bank, const Common::String &suffix) {
+ Common::String filename = _vm->getDatafilePrefix() + suffix;
debug(1, "loadSounds(%u, %s)", bank, filename.c_str());
Common::File file;
if (!file.open(filename)) {
@@ -258,9 +270,9 @@ void DreamWebEngine::loadSounds(uint bank, const Common::String &suffix) {
return;
}
- uint8 header[0x60];
+ uint8 header[96];
file.read(header, sizeof(header));
- uint tablesize = READ_LE_UINT16(header + 0x32);
+ uint tablesize = READ_LE_UINT16(header + 50);
debug(1, "table size = %u", tablesize);
SoundData &soundData = _soundData[bank];
@@ -270,8 +282,8 @@ void DreamWebEngine::loadSounds(uint bank, const Common::String &suffix) {
uint8 entry[6];
Sample &sample = soundData.samples[i];
file.read(entry, sizeof(entry));
- sample.offset = entry[0] * 0x4000 + READ_LE_UINT16(entry + 1);
- sample.size = READ_LE_UINT16(entry + 3) * 0x800;
+ sample.offset = entry[0] * 16384 + READ_LE_UINT16(entry + 1);
+ sample.size = READ_LE_UINT16(entry + 3) * 2048;
total += sample.size;
debug(1, "offset: %08x, size: %u", sample.offset, sample.size);
}
diff --git a/engines/dreamweb/sound.h b/engines/dreamweb/sound.h
new file mode 100644
index 0000000000..a38dbf3c1a
--- /dev/null
+++ b/engines/dreamweb/sound.h
@@ -0,0 +1,92 @@
+/* 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 DREAMWEB_SOUND_H
+#define DREAMWEB_SOUND_H
+
+#include "common/array.h"
+#include "common/str.h"
+#include "audio/mixer.h"
+
+namespace DreamWeb {
+
+class DreamWebEngine;
+
+class DreamWebSound {
+public:
+ DreamWebSound(DreamWebEngine *vm);
+ ~DreamWebSound();
+
+ bool loadSpeech(byte type1, int idx1, byte type2, int idx2);
+ void volumeSet(uint8 value) { _volume = value; }
+ void volumeChange(uint8 value, int8 direction);
+ void playChannel0(uint8 index, uint8 repeat);
+ void playChannel1(uint8 index);
+ uint8 getChannel0Playing() { return _channel0Playing; }
+ bool isChannel1Playing() { return _channel1Playing != 255; }
+ void cancelCh0();
+ void cancelCh1();
+ void loadRoomsSample(uint8 sample);
+ void soundHandler();
+ void loadSounds(uint bank, const Common::String &suffix);
+
+private:
+ DreamWebEngine *_vm;
+
+ struct Sample {
+ uint offset;
+ uint size;
+ Sample(): offset(), size() {}
+ };
+
+ struct SoundData {
+ Common::Array<Sample> samples;
+ Common::Array<uint8> data;
+ };
+
+ SoundData _soundData[2];
+ Common::Array<uint8> _speechData;
+
+ Audio::SoundHandle _channelHandle[2];
+
+ uint8 _channel0, _channel1;
+
+ uint8 _currentSample;
+ uint8 _channel0Playing;
+ uint8 _channel0Repeat;
+ bool _channel0NewSound;
+ uint8 _channel1Playing;
+
+ uint8 _volume;
+ uint8 _volumeTo;
+ int8 _volumeDirection;
+ uint8 _volumeCount;
+
+ void volumeAdjust();
+ void playSound(uint8 channel, uint8 id, uint8 loops);
+ void stopSound(uint8 channel);
+ bool loadSpeech(const Common::String &filename);
+};
+
+} // End of namespace DreamWeb
+
+#endif
diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp
index 3df324abe1..5b6cf6a6ac 100644
--- a/engines/dreamweb/sprite.cpp
+++ b/engines/dreamweb/sprite.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -298,7 +299,7 @@ void DreamWebEngine::doDoor(Sprite *sprite, SetObject *objData, Common::Rect che
soundIndex = 13;
else
soundIndex = 0;
- playChannel1(soundIndex);
+ _sound->playChannel1(soundIndex);
}
if (objData->frames[sprite->animFrame] == 255)
--sprite->animFrame;
@@ -315,7 +316,7 @@ void DreamWebEngine::doDoor(Sprite *sprite, SetObject *objData, Common::Rect che
soundIndex = 13;
else
soundIndex = 1;
- playChannel1(soundIndex);
+ _sound->playChannel1(soundIndex);
}
if (sprite->animFrame != 0)
--sprite->animFrame;
@@ -346,7 +347,7 @@ void DreamWebEngine::lockedDoorway(Sprite *sprite, SetObject *objData) {
if (openDoor) {
if (sprite->animFrame == 1) {
- playChannel1(0);
+ _sound->playChannel1(0);
}
if (sprite->animFrame == 6)
@@ -367,7 +368,7 @@ void DreamWebEngine::lockedDoorway(Sprite *sprite, SetObject *objData) {
// shut door
if (sprite->animFrame == 5) {
- playChannel1(1);
+ _sound->playChannel1(1);
}
if (sprite->animFrame != 0)
@@ -505,7 +506,7 @@ void DreamWebEngine::intro1Text() {
if (_introCount != 2 && _introCount != 4 && _introCount != 6)
return;
- if (hasSpeech() && _channel1Playing != 255) {
+ if (hasSpeech() && _sound->isChannel1Playing()) {
_introCount--;
} else {
if (_introCount == 2)
@@ -578,7 +579,7 @@ void DreamWebEngine::textForEnd() {
}
void DreamWebEngine::textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) {
- if (hasSpeech() && _channel1Playing != 255)
+ if (hasSpeech() && _sound->isChannel1Playing())
_introCount--;
else
setupTimedTemp(textIndex, voiceIndex, x, y, countToTimed, timeCount);
@@ -614,8 +615,7 @@ void DreamWebEngine::textForMonk() {
else if (_introCount == 53) {
fadeScreenDowns();
if (hasSpeech()) {
- _volumeTo = 7;
- _volumeDirection = 1;
+ _sound->volumeChange(7, 1);
}
}
}
@@ -905,14 +905,14 @@ void DreamWebEngine::soundOnReels(uint16 reelPointer) {
continue;
_lastSoundReel = r->_reelPointer;
if (r->_sample < 64) {
- playChannel1(r->_sample);
+ _sound->playChannel1(r->_sample);
return;
}
if (r->_sample < 128) {
- playChannel0(r->_sample & 63, 0);
+ _sound->playChannel0(r->_sample & 63, 0);
return;
}
- playChannel0(r->_sample & 63, 255);
+ _sound->playChannel0(r->_sample & 63, 255);
}
if (_lastSoundReel != reelPointer)
@@ -955,9 +955,9 @@ void DreamWebEngine::getRidOfReels() {
void DreamWebEngine::liftNoise(uint8 index) {
if (_realLocation == 5 || _realLocation == 21)
- playChannel1(13); // hiss noise
+ _sound->playChannel1(13); // hiss noise
else
- playChannel1(index);
+ _sound->playChannel1(index);
}
void DreamWebEngine::checkForExit(Sprite *sprite) {
diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp
index 750dafe7b4..4515939ebc 100644
--- a/engines/dreamweb/stubs.cpp
+++ b/engines/dreamweb/stubs.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
#include "common/config-manager.h"
@@ -578,7 +579,7 @@ void DreamWebEngine::dreamweb() {
readSetData();
_wonGame = false;
- loadSounds(0, "V99"); // basic sample
+ _sound->loadSounds(0, "V99"); // basic sample
bool firstLoop = true;
@@ -654,7 +655,7 @@ void DreamWebEngine::dreamweb() {
_vars._location = 255;
_vars._roomAfterDream = 1;
_newLocation = 35;
- _volume = 7;
+ _sound->volumeSet(7);
loadRoom();
clearSprites();
initMan();
@@ -664,8 +665,7 @@ void DreamWebEngine::dreamweb() {
initialInv();
_lastFlag = 32;
startup1();
- _volumeTo = 0;
- _volumeDirection = -1;
+ _sound->volumeChange(0, -1);
_commandType = 255;
}
@@ -754,7 +754,7 @@ void DreamWebEngine::screenUpdate() {
showPointer();
if ((_vars._watchingTime == 0) && (_newLocation != 0xff))
return;
- vSync();
+ waitForVSync();
uint16 mouseState = 0;
mouseState |= readMouseState();
dumpPointer();
@@ -769,7 +769,7 @@ void DreamWebEngine::screenUpdate() {
showPointer();
if (_wonGame)
return;
- vSync();
+ waitForVSync();
mouseState |= readMouseState();
dumpPointer();
@@ -781,7 +781,7 @@ void DreamWebEngine::screenUpdate() {
afterNewRoom();
showPointer();
- vSync();
+ waitForVSync();
mouseState |= readMouseState();
dumpPointer();
@@ -790,7 +790,7 @@ void DreamWebEngine::screenUpdate() {
delPointer();
showPointer();
- vSync();
+ waitForVSync();
_oldButton = _mouseButton;
mouseState |= readMouseState();
_mouseButton = mouseState;
@@ -871,7 +871,7 @@ void DreamWebEngine::loadTextSegment(TextFile &file, Common::File &inFile, unsig
void DreamWebEngine::hangOnCurs(uint16 frameCount) {
for (uint16 i = 0; i < frameCount; ++i) {
printCurs();
- vSync();
+ waitForVSync();
delCurs();
}
}
@@ -930,7 +930,7 @@ void DreamWebEngine::processTrigger() {
void DreamWebEngine::useTimedText() {
if (_previousTimedTemp._string) {
// TODO: It might be nice to make subtitles wait for the speech
- // to finish (_channel1Playing) when we're in speech+subtitles mode,
+ // to finish (_sound->isChannel1Playing()) when we're in speech+subtitles mode,
// instead of waiting the pre-specified amount of time.
@@ -967,9 +967,9 @@ void DreamWebEngine::useTimedText() {
void DreamWebEngine::setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) {
if (hasSpeech() && voiceIndex != 0) {
- if (loadSpeech('T', voiceIndex, 'T', textIndex)) {
- playChannel1(50+12);
- }
+ _speechLoaded = _sound->loadSpeech('T', voiceIndex, 'T', textIndex);
+ if (_speechLoaded)
+ _sound->playChannel1(62);
if (_speechLoaded && !_subtitles)
return;
@@ -1634,7 +1634,7 @@ bool DreamWebEngine::checkIfSet(uint8 x, uint8 y) {
void DreamWebEngine::hangOn(uint16 frameCount) {
while (frameCount) {
- vSync();
+ waitForVSync();
--frameCount;
if (_quitRequested)
break;
@@ -1647,7 +1647,7 @@ void DreamWebEngine::hangOnW(uint16 frameCount) {
readMouse();
animPointer();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
--frameCount;
if (_quitRequested)
@@ -1665,7 +1665,7 @@ void DreamWebEngine::hangOnP(uint16 count) {
readMouse();
animPointer();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
count *= 3;
@@ -1674,7 +1674,7 @@ void DreamWebEngine::hangOnP(uint16 count) {
readMouse();
animPointer();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
if (_quitRequested)
break;
@@ -1846,7 +1846,7 @@ void DreamWebEngine::loadRoom() {
_vars._location = _newLocation;
const Room &room = g_roomData[_newLocation];
startLoading(room);
- loadRoomsSample();
+ _sound->loadRoomsSample(_roomsSample);
switchRyanOn();
drawFlags();
@@ -2132,7 +2132,7 @@ void DreamWebEngine::workToScreenM() {
animPointer();
readMouse();
showPointer();
- vSync();
+ waitForVSync();
workToScreen();
delPointer();
}
@@ -2146,12 +2146,12 @@ void DreamWebEngine::atmospheres() {
continue;
if (a->_mapX != _mapX || a->_mapY != _mapY)
continue;
- if (a->_sound != _channel0Playing) {
+ if (a->_sound != _sound->getChannel0Playing()) {
if (_vars._location == 45 && _vars._reelToWatch == 45)
continue; // "web"
- playChannel0(a->_sound, a->_repeat);
+ _sound->playChannel0(a->_sound, a->_repeat);
// NB: The asm here reads
// cmp reallocation,2
@@ -2161,21 +2161,21 @@ void DreamWebEngine::atmospheres() {
// I'm interpreting this as if the cmp reallocation is below the jz
if (_mapY == 0) {
- _volume = 0; // "fullvol"
+ _sound->volumeSet(0); // "fullvol"
return;
}
if (_realLocation == 2 && _mapX == 22 && _mapY == 10)
- _volume = 5; // "louisvol"
+ _sound->volumeSet(5); // "louisvol"
if (hasSpeech() && _realLocation == 14) {
if (_mapX == 33) {
- _volume = 0; // "ismad2"
+ _sound->volumeSet(0); // "ismad2"
return;
}
if (_mapX == 22) {
- _volume = 5;
+ _sound->volumeSet(5);
return;
}
@@ -2184,19 +2184,19 @@ void DreamWebEngine::atmospheres() {
if (_realLocation == 2) {
if (_mapX == 22) {
- _volume = 5; // "louisvol"
+ _sound->volumeSet(5); // "louisvol"
return;
}
if (_mapX == 11) {
- _volume = 0; // "fullvol"
+ _sound->volumeSet(0); // "fullvol"
return;
}
}
return;
}
- cancelCh0();
+ _sound->cancelCh0();
}
void DreamWebEngine::readKey() {
@@ -2607,7 +2607,7 @@ void DreamWebEngine::decide() {
readMouse();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
delPointer();
@@ -2642,8 +2642,8 @@ void DreamWebEngine::showGun() {
_numToFade = 128;
hangOn(200);
_roomsSample = 34;
- loadRoomsSample();
- _volume = 0;
+ _sound->loadRoomsSample(_roomsSample);
+ _sound->volumeSet(0);
GraphicsFile graphics;
loadGraphicsFile(graphics, "G13");
createPanel2();
@@ -2653,7 +2653,7 @@ void DreamWebEngine::showGun() {
graphics.clear();
fadeScreenUp();
hangOn(160);
- playChannel0(12, 0);
+ _sound->playChannel0(12, 0);
loadTempText("T83");
rollEndCreditsGameLost();
getRidOfTempText();
diff --git a/engines/dreamweb/talk.cpp b/engines/dreamweb/talk.cpp
index 0f59cad895..2629c23355 100644
--- a/engines/dreamweb/talk.cpp
+++ b/engines/dreamweb/talk.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -52,7 +53,7 @@ void DreamWebEngine::talk() {
readMouse();
animPointer();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
_getBack = 0;
@@ -67,9 +68,8 @@ void DreamWebEngine::talk() {
redrawMainScrn();
workToScreenM();
if (_speechLoaded) {
- cancelCh1();
- _volumeDirection = -1;
- _volumeTo = 0;
+ _sound->cancelCh1();
+ _sound->volumeChange(0, -1);
}
}
@@ -99,12 +99,10 @@ void DreamWebEngine::startTalk() {
printDirect(&str, 66, &y, 241, true);
if (hasSpeech()) {
- _speechLoaded = false;
- loadSpeech('R', _realLocation, 'C', 64*(_character & 0x7F));
+ _speechLoaded = _sound->loadSpeech('R', _realLocation, 'C', 64*(_character & 0x7F));
if (_speechLoaded) {
- _volumeDirection = 1;
- _volumeTo = 6;
- playChannel1(50 + 12);
+ _sound->volumeChange(6, 1);
+ _sound->playChannel1(62);
}
}
}
@@ -155,9 +153,9 @@ void DreamWebEngine::doSomeTalk() {
printDirect(str, 164, 64, 144, false);
- loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos);
+ _speechLoaded = _sound->loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos);
if (_speechLoaded)
- playChannel1(62);
+ _sound->playChannel1(62);
_pointerMode = 3;
workToScreenM();
@@ -181,9 +179,9 @@ void DreamWebEngine::doSomeTalk() {
convIcons();
printDirect(str, 48, 128, 144, false);
- loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos);
+ _speechLoaded = _sound->loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos);
if (_speechLoaded)
- playChannel1(62);
+ _sound->playChannel1(62);
_pointerMode = 3;
workToScreenM();
@@ -211,7 +209,7 @@ bool DreamWebEngine::hangOnPQ() {
readMouse();
animPointer();
showPointer();
- vSync();
+ waitForVSync();
dumpPointer();
dumpTextLine();
checkCoords(quitList);
@@ -220,11 +218,11 @@ bool DreamWebEngine::hangOnPQ() {
// Quit conversation
delPointer();
_pointerMode = 0;
- cancelCh1();
+ _sound->cancelCh1();
return true;
}
- if (_speechLoaded && _channel1Playing == 255) {
+ if (_speechLoaded && !_sound->isChannel1Playing()) {
speechFlag++;
if (speechFlag == 40)
break;
@@ -237,7 +235,7 @@ bool DreamWebEngine::hangOnPQ() {
}
void DreamWebEngine::redes() {
- if (_channel1Playing != 255 || _talkMode != 2) {
+ if (_sound->isChannel1Playing() || _talkMode != 2) {
blank();
return;
}
diff --git a/engines/dreamweb/titles.cpp b/engines/dreamweb/titles.cpp
index f7486ce687..f005279ba0 100644
--- a/engines/dreamweb/titles.cpp
+++ b/engines/dreamweb/titles.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
#include "engines/util.h"
@@ -32,38 +33,36 @@ void DreamWebEngine::endGame() {
return;
gettingShot();
getRidOfTempText();
- _volumeTo = 7;
- _volumeDirection = 1;
+ _sound->volumeChange(7, 1);
hangOn(200);
}
void DreamWebEngine::monkSpeaking() {
_roomsSample = 35;
- loadRoomsSample();
+ _sound->loadRoomsSample(_roomsSample);
GraphicsFile graphics;
loadGraphicsFile(graphics, "G15");
clearWork();
showFrame(graphics, 160, 72, 0, 128); // show monk
workToScreen();
- _volume = 7;
- _volumeDirection = -1;
- _volumeTo = hasSpeech() ? 5 : 0;
- playChannel0(12, 255);
+ _sound->volumeSet(7);
+ _sound->volumeChange(hasSpeech() ? 5 : 0, -1);
+ _sound->playChannel0(12, 255);
fadeScreenUps();
hangOn(300);
// TODO: Subtitles+speech mode
if (hasSpeech()) {
for (int i = 40; i < 48; i++) {
- loadSpeech('T', 83, 'T', i);
+ _speechLoaded = _sound->loadSpeech('T', 83, 'T', i);
- playChannel1(50 + 12);
+ _sound->playChannel1(62);
do {
waitForVSync();
if (_quitRequested)
return;
- } while (_channel1Playing != 255);
+ } while (_sound->isChannel1Playing());
}
} else {
for (int i = 40; i <= 44; i++) {
@@ -83,8 +82,7 @@ void DreamWebEngine::monkSpeaking() {
}
}
- _volumeDirection = 1;
- _volumeTo = 7;
+ _sound->volumeChange(7, 1);
fadeScreenDowns();
hangOn(300);
graphics.clear();
@@ -95,8 +93,7 @@ void DreamWebEngine::gettingShot() {
clearPalette();
loadIntroRoom();
fadeScreenUps();
- _volumeTo = 0;
- _volumeDirection = -1;
+ _sound->volumeChange(0, -1);
runEndSeq();
clearBeforeLoad();
}
@@ -127,14 +124,14 @@ void DreamWebEngine::bibleQuote() {
return; // "biblequotearly"
}
- cancelCh0();
+ _sound->cancelCh0();
_lastHardKey = 0;
}
void DreamWebEngine::hangOne(uint16 delay) {
do {
- vSync();
+ waitForVSync();
if (_lastHardKey == 1)
return; // "hangonearly"
} while (--delay);
@@ -147,10 +144,9 @@ void DreamWebEngine::intro() {
_newLocation = 50;
clearPalette();
loadIntroRoom();
- _volume = 7;
- _volumeDirection = -1;
- _volumeTo = hasSpeech() ? 4 : 0;
- playChannel0(12, 255);
+ _sound->volumeSet(7);
+ _sound->volumeChange(hasSpeech() ? 4 : 0, -1);
+ _sound->playChannel0(12, 255);
fadeScreenUps();
runIntroSeq();
@@ -200,13 +196,13 @@ void DreamWebEngine::runIntroSeq() {
_getBack = 0;
do {
- vSync();
+ waitForVSync();
if (_lastHardKey == 1)
break;
spriteUpdate();
- vSync();
+ waitForVSync();
if (_lastHardKey == 1)
break;
@@ -216,14 +212,14 @@ void DreamWebEngine::runIntroSeq() {
reelsOnScreen();
afterIntroRoom();
useTimedText();
- vSync();
+ waitForVSync();
if (_lastHardKey == 1)
break;
dumpMap();
dumpTimedText();
- vSync();
+ waitForVSync();
if (_lastHardKey == 1)
break;
@@ -247,18 +243,18 @@ void DreamWebEngine::runEndSeq() {
_getBack = 0;
do {
- vSync();
+ waitForVSync();
spriteUpdate();
- vSync();
+ waitForVSync();
delEverything();
printSprites();
reelsOnScreen();
afterIntroRoom();
useTimedText();
- vSync();
+ waitForVSync();
dumpMap();
dumpTimedText();
- vSync();
+ waitForVSync();
} while (_getBack != 1 && !_quitRequested);
}
@@ -286,14 +282,14 @@ void DreamWebEngine::set16ColPalette() {
void DreamWebEngine::realCredits() {
_roomsSample = 33;
- loadRoomsSample();
- _volume = 0;
+ _sound->loadRoomsSample(_roomsSample);
+ _sound->volumeSet(0);
initGraphics(640, 480, true);
hangOn(35);
showPCX("I01");
- playChannel0(12, 0);
+ _sound->playChannel0(12, 0);
hangOne(2);
@@ -319,7 +315,7 @@ void DreamWebEngine::realCredits() {
}
showPCX("I02");
- playChannel0(12, 0);
+ _sound->playChannel0(12, 0);
hangOne(2);
if (_lastHardKey == 1) {
@@ -344,7 +340,7 @@ void DreamWebEngine::realCredits() {
}
showPCX("I03");
- playChannel0(12, 0);
+ _sound->playChannel0(12, 0);
hangOne(2);
if (_lastHardKey == 1) {
@@ -369,7 +365,7 @@ void DreamWebEngine::realCredits() {
}
showPCX("I04");
- playChannel0(12, 0);
+ _sound->playChannel0(12, 0);
hangOne(2);
if (_lastHardKey == 1) {
@@ -394,7 +390,7 @@ void DreamWebEngine::realCredits() {
}
showPCX("I05");
- playChannel0(12, 0);
+ _sound->playChannel0(12, 0);
hangOne(2);
if (_lastHardKey == 1) {
@@ -427,7 +423,7 @@ void DreamWebEngine::realCredits() {
return; // "realcreditsearly"
}
- playChannel0(13, 0);
+ _sound->playChannel0(13, 0);
hangOne(350);
if (_lastHardKey == 1) {
diff --git a/engines/dreamweb/use.cpp b/engines/dreamweb/use.cpp
index e59843539f..995eef04cd 100644
--- a/engines/dreamweb/use.cpp
+++ b/engines/dreamweb/use.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -201,13 +202,13 @@ void DreamWebEngine::edensCDPlayer() {
}
void DreamWebEngine::hotelBell() {
- playChannel1(12);
+ _sound->playChannel1(12);
showFirstUse();
putBackObStuff();
}
void DreamWebEngine::playGuitar() {
- playChannel1(14);
+ _sound->playChannel1(14);
showFirstUse();
putBackObStuff();
}
@@ -273,13 +274,13 @@ void DreamWebEngine::useHatch() {
}
void DreamWebEngine::wheelSound() {
- playChannel1(17);
+ _sound->playChannel1(17);
showFirstUse();
putBackObStuff();
}
void DreamWebEngine::callHotelLift() {
- playChannel1(12);
+ _sound->playChannel1(12);
showFirstUse();
_vars._countToOpen = 8;
_getBack = 1;
@@ -382,7 +383,7 @@ void DreamWebEngine::sitDownInBar() {
}
void DreamWebEngine::useDryer() {
- playChannel1(12);
+ _sound->playChannel1(12);
showFirstUse();
_getBack = 1;
}
@@ -887,7 +888,7 @@ void DreamWebEngine::usePlate() {
if (compare(_withObject, _withType, "SCRW")) {
// Unscrew plate
- playChannel1(20);
+ _sound->playChannel1(20);
showFirstUse();
placeSetObject(28);
placeSetObject(24);
@@ -992,7 +993,7 @@ void DreamWebEngine::useCart() {
removeSetObject(_command);
placeSetObject(_command + 1);
_vars._progressPoints++;
- playChannel1(17);
+ _sound->playChannel1(17);
showFirstUse();
_getBack = 1;
}
@@ -1035,7 +1036,7 @@ void DreamWebEngine::openHotelDoor() {
if (defaultUseHandler("KEYA"))
return;
- playChannel1(16);
+ _sound->playChannel1(16);
showFirstUse();
_vars._lockStatus = 0;
_getBack = 1;
@@ -1045,7 +1046,7 @@ void DreamWebEngine::openHotelDoor2() {
if (defaultUseHandler("KEYA"))
return;
- playChannel1(16);
+ _sound->playChannel1(16);
showFirstUse();
putBackObStuff();
}
@@ -1067,7 +1068,7 @@ void DreamWebEngine::usePoolReader() {
showSecondUse();
putBackObStuff();
} else {
- playChannel1(17);
+ _sound->playChannel1(17);
showFirstUse();
_vars._countToOpen = 6;
_getBack = 1;
@@ -1088,7 +1089,7 @@ void DreamWebEngine::useCardReader1() {
putBackObStuff();
} else {
// Get cash
- playChannel1(16);
+ _sound->playChannel1(16);
showPuzText(18, 300);
_vars._progressPoints++;
_vars._card1Money = 12432;
@@ -1113,7 +1114,7 @@ void DreamWebEngine::useCardReader2() {
showPuzText(22, 300);
putBackObStuff();
} else {
- playChannel1(18);
+ _sound->playChannel1(18);
showPuzText(19, 300);
placeSetObject(94);
_vars._gunPassFlag = 1;
@@ -1136,7 +1137,7 @@ void DreamWebEngine::useCardReader3() {
showPuzText(26, 300);
putBackObStuff();
} else {
- playChannel1(16);
+ _sound->playChannel1(16);
showPuzText(25, 300);
_vars._progressPoints++;
_vars._card1Money -= 8300;
@@ -1232,7 +1233,7 @@ void DreamWebEngine::useControl() {
}
if (compare(_withObject, _withType, "KEYA")) { // Right key
- playChannel1(16);
+ _sound->playChannel1(16);
if (_vars._location == 21) { // Going down
showPuzText(3, 300);
_newLocation = 30;
@@ -1257,7 +1258,7 @@ void DreamWebEngine::useControl() {
placeSetObject(30);
removeSetObject(16);
removeSetObject(17);
- playChannel1(14);
+ _sound->playChannel1(14);
showPuzText(10, 300);
_vars._progressPoints++;
_getBack = 1;
@@ -1375,7 +1376,7 @@ void DreamWebEngine::runTap() {
// Fill cup from tap
DynObject *exObject = getExAd(_withObject);
exObject->objId[3] = 'F'-'A'; // CUPE (empty cup) -> CUPF (full cup)
- playChannel1(8);
+ _sound->playChannel1(8);
showPuzText(57, 300);
putBackObStuff();
return;
diff --git a/engines/dreamweb/vgafades.cpp b/engines/dreamweb/vgafades.cpp
index e8999ab18c..c8f05641b5 100644
--- a/engines/dreamweb/vgafades.cpp
+++ b/engines/dreamweb/vgafades.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "dreamweb/sound.h"
#include "dreamweb/dreamweb.h"
namespace DreamWeb {
@@ -52,7 +53,7 @@ void DreamWebEngine::fadeDOS() {
return; // FIXME later
waitForVSync();
- //processEvents will be called from vsync
+ //processEvents will be called from waitForVSync
uint8 *dst = _startPal;
getPalette(dst, 0, 64);
for (int fade = 0; fade < 64; ++fade) {
@@ -123,7 +124,7 @@ void DreamWebEngine::fadeUpMonFirst() {
_colourPos = 0;
_numToFade = 128;
hangOn(64);
- playChannel1(26);
+ _sound->playChannel1(26);
hangOn(64);
}
diff --git a/engines/dreamweb/vgagrafx.cpp b/engines/dreamweb/vgagrafx.cpp
index a66f156a1d..ec306c4924 100644
--- a/engines/dreamweb/vgagrafx.cpp
+++ b/engines/dreamweb/vgagrafx.cpp
@@ -144,10 +144,6 @@ void DreamWebEngine::doShake() {
setShakePos(offset >= 0 ? offset : -offset);
}
-void DreamWebEngine::vSync() {
- waitForVSync();
-}
-
void DreamWebEngine::setMode() {
waitForVSync();
initGraphics(320, 200, false);
diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp
index 154f8e04ed..54534cd60b 100644
--- a/engines/gob/aniobject.cpp
+++ b/engines/gob/aniobject.cpp
@@ -167,19 +167,21 @@ bool ANIObject::isIn(const ANIObject &obj) const {
obj.isIn(frameX + frameWidth - 1, frameY + frameHeight - 1);
}
-void ANIObject::draw(Surface &dest, int16 &left, int16 &top,
+bool ANIObject::draw(Surface &dest, int16 &left, int16 &top,
int16 &right, int16 &bottom) {
if (!_visible)
- return;
+ return false;
if (_cmp)
- drawCMP(dest, left, top, right, bottom);
+ return drawCMP(dest, left, top, right, bottom);
else if (_ani)
- drawANI(dest, left, top, right, bottom);
+ return drawANI(dest, left, top, right, bottom);
+
+ return false;
}
-void ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top,
+bool ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top,
int16 &right, int16 &bottom) {
if (!_background) {
@@ -209,9 +211,11 @@ void ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top,
top = _backgroundTop;
right = _backgroundRight;
bottom = _backgroundBottom;
+
+ return true;
}
-void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top,
+bool ANIObject::drawANI(Surface &dest, int16 &left, int16 &top,
int16 &right, int16 &bottom) {
if (!_background) {
@@ -224,7 +228,7 @@ void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top,
const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation);
if (_frame >= animation.frameCount)
- return;
+ return false;
const ANIFile::FrameArea &area = animation.frameAreas[_frame];
@@ -244,13 +248,15 @@ void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top,
top = _backgroundTop;
right = _backgroundRight;
bottom = _backgroundBottom;
+
+ return true;
}
-void ANIObject::clear(Surface &dest, int16 &left, int16 &top,
+bool ANIObject::clear(Surface &dest, int16 &left, int16 &top,
int16 &right, int16 &bottom) {
if (!_drawn)
- return;
+ return false;
const int16 bgRight = _backgroundRight - _backgroundLeft;
const int16 bgBottom = _backgroundBottom - _backgroundTop;
@@ -263,6 +269,8 @@ void ANIObject::clear(Surface &dest, int16 &left, int16 &top,
top = _backgroundTop;
right = _backgroundRight;
bottom = _backgroundBottom;
+
+ return true;
}
void ANIObject::advance() {
diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h
index c101d747b7..bd4cf791a8 100644
--- a/engines/gob/aniobject.h
+++ b/engines/gob/aniobject.h
@@ -93,9 +93,9 @@ public:
bool lastFrame() const;
/** Draw the current frame onto the surface and return the affected rectangle. */
- void draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
+ bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
/** Draw the current frame from the surface and return the affected rectangle. */
- void clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom);
+ bool clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom);
/** Advance the animation to the next frame. */
virtual void advance();
@@ -123,8 +123,8 @@ private:
int16 _backgroundRight; ///< The right position of the saved background.
int16 _backgroundBottom; ///< The bottom position of the saved background.
- void drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
- void drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
+ bool drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
+ bool drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
};
} // End of namespace Gob
diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index 4b659f51de..fe59b11f76 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -117,6 +117,15 @@ Draw::Draw(GobEngine *vm) : _vm(vm) {
_cursorAnimDelays[i] = 0;
}
+ _cursorCount = 0;
+ _doCursorPalettes = 0;
+ _cursorPalettes = 0;
+ _cursorKeyColors = 0;
+ _cursorPaletteStarts = 0;
+ _cursorPaletteCounts = 0;
+ _cursorHotspotsX = 0;
+ _cursorHotspotsY = 0;
+
_palLoadData1[0] = 0;
_palLoadData1[1] = 17;
_palLoadData1[2] = 34;
@@ -134,6 +143,14 @@ Draw::Draw(GobEngine *vm) : _vm(vm) {
}
Draw::~Draw() {
+ delete[] _cursorPalettes;
+ delete[] _doCursorPalettes;
+ delete[] _cursorKeyColors;
+ delete[] _cursorPaletteStarts;
+ delete[] _cursorPaletteCounts;
+ delete[] _cursorHotspotsX;
+ delete[] _cursorHotspotsY;
+
for (int i = 0; i < kFontCount; i++)
delete _fonts[i];
}
diff --git a/engines/gob/draw.h b/engines/gob/draw.h
index 393822c33a..24c5550ea5 100644
--- a/engines/gob/draw.h
+++ b/engines/gob/draw.h
@@ -145,6 +145,15 @@ public:
int8 _cursorAnimHigh[40];
int8 _cursorAnimDelays[40];
+ int32 _cursorCount;
+ bool *_doCursorPalettes;
+ byte *_cursorPalettes;
+ byte *_cursorKeyColors;
+ uint16 *_cursorPaletteStarts;
+ uint16 *_cursorPaletteCounts;
+ int32 *_cursorHotspotsX;
+ int32 *_cursorHotspotsY;
+
int16 _palLoadData1[4];
int16 _palLoadData2[4];
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 78702f2ec9..ab9a90de8f 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -83,7 +83,7 @@ void Draw_v2::blitCursor() {
void Draw_v2::animateCursor(int16 cursor) {
int16 cursorIndex = cursor;
int16 newX = 0, newY = 0;
- uint16 hotspotX = 0, hotspotY = 0;
+ uint16 hotspotX, hotspotY;
_showCursor |= 1;
@@ -133,27 +133,42 @@ void Draw_v2::animateCursor(int16 cursor) {
}
// '------
- newX = _vm->_global->_inter_mouseX;
- newY = _vm->_global->_inter_mouseY;
+ hotspotX = 0;
+ hotspotY = 0;
+
if (_cursorHotspotXVar != -1) {
- newX -= hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar);
- newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar);
+ hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar);
+ hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar);
} else if (_cursorHotspotX != -1) {
- newX -= hotspotX = _cursorHotspotX;
- newY -= hotspotY = _cursorHotspotY;
+ hotspotX = _cursorHotspotX;
+ hotspotY = _cursorHotspotY;
+ } else if (_cursorHotspotsX != 0) {
+ hotspotX = _cursorHotspotsX[_cursorIndex];
+ hotspotY = _cursorHotspotsY[_cursorIndex];
}
+ newX = _vm->_global->_inter_mouseX - hotspotX;
+ newY = _vm->_global->_inter_mouseY - hotspotY;
+
_scummvmCursor->clear();
_scummvmCursor->blit(*_cursorSprites,
cursorIndex * _cursorWidth, 0,
(cursorIndex + 1) * _cursorWidth - 1,
_cursorHeight - 1, 0, 0);
- if ((_vm->getGameType() != kGameTypeAdibou2) &&
- (_vm->getGameType() != kGameTypeAdi2) &&
- (_vm->getGameType() != kGameTypeAdi4))
- CursorMan.replaceCursor(_scummvmCursor->getData(),
- _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat());
+ uint32 keyColor = 0;
+ if (_doCursorPalettes && _cursorKeyColors && _doCursorPalettes[cursorIndex])
+ keyColor = _cursorKeyColors[cursorIndex];
+
+ CursorMan.replaceCursor(_scummvmCursor->getData(),
+ _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat());
+
+ if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) {
+ CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3),
+ _cursorPaletteStarts[cursorIndex], _cursorPaletteCounts[cursorIndex]);
+ CursorMan.disableCursorPalette(false);
+ } else
+ CursorMan.disableCursorPalette(true);
if (_frontSurface != _backSurface) {
if (!_noInvalidated) {
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index c79b6e2260..1e6f74db4e 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -31,6 +31,10 @@
#include "gob/iniconfig.h"
#include "gob/databases.h"
+namespace Common {
+ class PEResources;
+}
+
namespace Gob {
class Cheater_Geisha;
@@ -648,7 +652,7 @@ private:
class Inter_v7 : public Inter_Playtoons {
public:
Inter_v7(GobEngine *vm);
- virtual ~Inter_v7() {}
+ virtual ~Inter_v7();
protected:
virtual void setupOpcodesDraw();
@@ -684,7 +688,12 @@ private:
INIConfig _inis;
Databases _databases;
+ Common::PEResources *_cursors;
+
Common::String findFile(const Common::String &mask);
+
+ bool loadCursorFile();
+ void resizeCursors(int16 width, int16 height, int16 count, bool transparency);
};
} // End of namespace Gob
diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp
index 7f21ceb91d..99f834d4d7 100644
--- a/engines/gob/inter_geisha.cpp
+++ b/engines/gob/inter_geisha.cpp
@@ -272,12 +272,12 @@ void Inter_Geisha::oGeisha_writeData(OpFuncParams &params) {
}
void Inter_Geisha::oGeisha_gamePenetration(OpGobParams &params) {
- uint16 var1 = _vm->_game->_script->readUint16();
- uint16 var2 = _vm->_game->_script->readUint16();
- uint16 var3 = _vm->_game->_script->readUint16();
- uint16 resultVar = _vm->_game->_script->readUint16();
+ uint16 hasAccessPass = _vm->_game->_script->readUint16();
+ uint16 hasMaxEnergy = _vm->_game->_script->readUint16();
+ uint16 testMode = _vm->_game->_script->readUint16();
+ uint16 resultVar = _vm->_game->_script->readUint16();
- bool result = _penetration->play(var1, var2, var3);
+ bool result = _penetration->play(hasAccessPass, hasMaxEnergy, testMode);
WRITE_VAR_UINT32(resultVar, result ? 1 : 0);
}
diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp
index 81547f7362..6cf69ed9df 100644
--- a/engines/gob/inter_v7.cpp
+++ b/engines/gob/inter_v7.cpp
@@ -22,8 +22,11 @@
#include "common/endian.h"
#include "common/archive.h"
+#include "common/winexe.h"
+#include "common/winexe_pe.h"
#include "graphics/cursorman.h"
+#include "graphics/wincursor.h"
#include "gob/gob.h"
#include "gob/global.h"
@@ -42,7 +45,11 @@ namespace Gob {
#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x)
#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x)
-Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm) {
+Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm), _cursors(0) {
+}
+
+Inter_v7::~Inter_v7() {
+ delete _cursors;
}
void Inter_v7::setupOpcodesDraw() {
@@ -86,27 +93,121 @@ void Inter_v7::o7_draw0x0C() {
WRITE_VAR(17, 0);
}
+void Inter_v7::resizeCursors(int16 width, int16 height, int16 count, bool transparency) {
+ if (width <= 0)
+ width = _vm->_draw->_cursorWidth;
+ if (height <= 0)
+ height = _vm->_draw->_cursorHeight;
+
+ width = MAX<uint16>(width , _vm->_draw->_cursorWidth);
+ height = MAX<uint16>(height, _vm->_draw->_cursorHeight);
+
+ _vm->_draw->_transparentCursor = transparency;
+
+ // Cursors sprite already big enough
+ if ((_vm->_draw->_cursorWidth >= width) && (_vm->_draw->_cursorHeight >= height) &&
+ (_vm->_draw->_cursorCount >= count))
+ return;
+
+ _vm->_draw->_cursorCount = count;
+ _vm->_draw->_cursorWidth = width;
+ _vm->_draw->_cursorHeight = height;
+
+ _vm->_draw->freeSprite(Draw::kCursorSurface);
+ _vm->_draw->_cursorSprites.reset();
+ _vm->_draw->_cursorSpritesBack.reset();
+ _vm->_draw->_scummvmCursor.reset();
+
+ _vm->_draw->initSpriteSurf(Draw::kCursorSurface, width * count, height, 2);
+
+ _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface];
+ _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack;
+
+ _vm->_draw->_scummvmCursor = _vm->_video->initSurfDesc(width, height, SCUMMVM_CURSOR);
+
+ for (int i = 0; i < 40; i++) {
+ _vm->_draw->_cursorAnimLow[i] = -1;
+ _vm->_draw->_cursorAnimDelays[i] = 0;
+ _vm->_draw->_cursorAnimHigh[i] = 0;
+ }
+ _vm->_draw->_cursorAnimLow[1] = 0;
+
+ delete[] _vm->_draw->_doCursorPalettes;
+ delete[] _vm->_draw->_cursorPalettes;
+ delete[] _vm->_draw->_cursorKeyColors;
+ delete[] _vm->_draw->_cursorPaletteStarts;
+ delete[] _vm->_draw->_cursorPaletteCounts;
+ delete[] _vm->_draw->_cursorHotspotsX;
+ delete[] _vm->_draw->_cursorHotspotsY;
+
+ _vm->_draw->_cursorPalettes = new byte[256 * 3 * count];
+ _vm->_draw->_doCursorPalettes = new bool[count];
+ _vm->_draw->_cursorKeyColors = new byte[count];
+ _vm->_draw->_cursorPaletteStarts = new uint16[count];
+ _vm->_draw->_cursorPaletteCounts = new uint16[count];
+ _vm->_draw->_cursorHotspotsX = new int32[count];
+ _vm->_draw->_cursorHotspotsY = new int32[count];
+
+ memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3);
+ memset(_vm->_draw->_doCursorPalettes , 0, count * sizeof(bool));
+ memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte));
+ memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16));
+ memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16));
+ memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32));
+ memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32));
+}
+
void Inter_v7::o7_loadCursor() {
int16 cursorIndex = _vm->_game->_script->readValExpr();
- Common::String cursorFile = _vm->_game->_script->evalString();
+ Common::String cursorName = _vm->_game->_script->evalString();
+
+ // Clear the cursor sprite at that index
+ _vm->_draw->_cursorSprites->fillRect(cursorIndex * _vm->_draw->_cursorWidth, 0,
+ cursorIndex * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1,
+ _vm->_draw->_cursorHeight - 1, 0);
+
+ // If the cursor name is empty, that cursor will be drawn by the scripts
+ if (cursorName.empty()) {
+ // Make sure the cursors sprite is big enough and set to non-extern palette
+ resizeCursors(-1, -1, cursorIndex + 1, true);
+ _vm->_draw->_doCursorPalettes[cursorIndex] = false;
+ return;
+ }
+
+ Graphics::WinCursorGroup *cursorGroup = 0;
+ Graphics::Cursor *defaultCursor = 0;
+
+ // Load the cursor file and cursor group
+ if (loadCursorFile())
+ cursorGroup = Graphics::WinCursorGroup::createCursorGroup(*_cursors, Common::WinResourceID(cursorName));
+
+ // If the requested cursor does not exist, create a default one
+ const Graphics::Cursor *cursor = 0;
+ if (!cursorGroup || cursorGroup->cursors.empty() || !cursorGroup->cursors[0].cursor) {
+ defaultCursor = Graphics::makeDefaultWinCursor();
+
+ cursor = defaultCursor;
+ } else
+ cursor = cursorGroup->cursors[0].cursor;
- warning("Addy Stub: Load cursor \"%s\" to %d", cursorFile.c_str(), cursorIndex);
+ // Make sure the cursors sprite it big enough
+ resizeCursors(cursor->getWidth(), cursor->getHeight(), cursorIndex + 1, true);
- byte cursor[9];
- byte palette[6];
+ Surface cursorSurf(cursor->getWidth(), cursor->getHeight(), 1, cursor->getSurface());
- cursor[0] = 0; cursor[1] = 0; cursor[2] = 0;
- cursor[3] = 0; cursor[4] = 1; cursor[5] = 0;
- cursor[6] = 0; cursor[7] = 0; cursor[8] = 0;
+ _vm->_draw->_cursorSprites->blit(cursorSurf, cursorIndex * _vm->_draw->_cursorWidth, 0);
- palette[0] = 0; palette[1] = 0; palette[2] = 0;
- palette[3] = 255; palette[4] = 255; palette[5] = 255;
+ memcpy(_vm->_draw->_cursorPalettes + cursorIndex * 256 * 3, cursor->getPalette(), cursor->getPaletteCount() * 3);
- CursorMan.pushCursorPalette(palette, 0, 2);
- CursorMan.disableCursorPalette(false);
- CursorMan.replaceCursor(cursor, 3, 3, 1, 1, 255);
+ _vm->_draw->_doCursorPalettes [cursorIndex] = true;
+ _vm->_draw->_cursorKeyColors [cursorIndex] = cursor->getKeyColor();
+ _vm->_draw->_cursorPaletteStarts[cursorIndex] = cursor->getPaletteStartIndex();
+ _vm->_draw->_cursorPaletteCounts[cursorIndex] = cursor->getPaletteCount();
+ _vm->_draw->_cursorHotspotsX [cursorIndex] = cursor->getHotspotX();
+ _vm->_draw->_cursorHotspotsY [cursorIndex] = cursor->getHotspotY();
- CursorMan.showMouse(true);
+ delete cursorGroup;
+ delete defaultCursor;
}
void Inter_v7::o7_displayWarning() {
@@ -529,4 +630,19 @@ Common::String Inter_v7::findFile(const Common::String &mask) {
return files.front()->getName();
}
+bool Inter_v7::loadCursorFile() {
+ if (_cursors)
+ return true;
+
+ _cursors = new Common::PEResources();
+
+ if (_cursors->loadFromEXE("cursor32.dll"))
+ return true;
+
+ delete _cursors;
+ _cursors = 0;
+
+ return false;
+}
+
} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/diving.cpp b/engines/gob/minigames/geisha/diving.cpp
index 6f4c6e168a..56c7b5213c 100644
--- a/engines/gob/minigames/geisha/diving.cpp
+++ b/engines/gob/minigames/geisha/diving.cpp
@@ -706,16 +706,16 @@ void Diving::updateAnims() {
for (Common::List<ANIObject *>::iterator a = _anims.reverse_begin();
a != _anims.end(); --a) {
- (*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom);
- _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+ if ((*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom))
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
}
// Draw the current animation frames
for (Common::List<ANIObject *>::iterator a = _anims.begin();
a != _anims.end(); ++a) {
- (*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
- _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+ if ((*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom))
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
(*a)->advance();
}
diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp
index e3b9bd1ccf..9dcc717e48 100644
--- a/engines/gob/minigames/geisha/meter.cpp
+++ b/engines/gob/minigames/geisha/meter.cpp
@@ -42,6 +42,10 @@ Meter::~Meter() {
delete _surface;
}
+int32 Meter::getMaxValue() const {
+ return _maxValue;
+}
+
int32 Meter::getValue() const {
return _value;
}
diff --git a/engines/gob/minigames/geisha/meter.h b/engines/gob/minigames/geisha/meter.h
index a9bdb14d0f..d3e82cb32e 100644
--- a/engines/gob/minigames/geisha/meter.h
+++ b/engines/gob/minigames/geisha/meter.h
@@ -44,6 +44,8 @@ public:
Direction direction);
~Meter();
+ /** Return the max value the meter is measuring. */
+ int32 getMaxValue() const;
/** Return the current value the meter is measuring. */
int32 getValue() const;
diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp
index 121a45bc40..35802e6733 100644
--- a/engines/gob/minigames/geisha/penetration.cpp
+++ b/engines/gob/minigames/geisha/penetration.cpp
@@ -25,9 +25,12 @@
#include "gob/draw.h"
#include "gob/video.h"
#include "gob/decfile.h"
+#include "gob/cmpfile.h"
#include "gob/anifile.h"
+#include "gob/aniobject.h"
#include "gob/minigames/geisha/penetration.h"
+#include "gob/minigames/geisha/meter.h"
namespace Gob {
@@ -52,27 +55,207 @@ static const byte kPalette[48] = {
0x15, 0x3F, 0x15
};
-Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _objects(0) {
+static const int kColorShield = 11;
+static const int kColorHealth = 15;
+static const int kColorBlack = 10;
+static const int kColorFloor = 13;
+
+enum Animation {
+ kAnimationDriveS = 4,
+ kAnimationDriveE = 5,
+ kAnimationDriveN = 6,
+ kAnimationDriveW = 7,
+ kAnimationDriveSE = 8,
+ kAnimationDriveNE = 9,
+ kAnimationDriveSW = 10,
+ kAnimationDriveNW = 11,
+ kAnimationShootS = 12,
+ kAnimationShootN = 13,
+ kAnimationShootW = 14,
+ kAnimationShootE = 15,
+ kAnimationShootNE = 16,
+ kAnimationShootSE = 17,
+ kAnimationShootSW = 18,
+ kAnimationShootNW = 19,
+ kAnimationExplodeN = 28,
+ kAnimationExplodeS = 29,
+ kAnimationExplodeW = 30,
+ kAnimationExplodeE = 31,
+ kAnimationExit = 32
+};
+
+static const int kMapTileWidth = 24;
+static const int kMapTileHeight = 24;
+
+static const int kPlayAreaX = 120;
+static const int kPlayAreaY = 7;
+static const int kPlayAreaWidth = 192;
+static const int kPlayAreaHeight = 113;
+
+static const int kPlayAreaBorderWidth = kPlayAreaWidth / 2;
+static const int kPlayAreaBorderHeight = kPlayAreaHeight / 2;
+
+const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = {
+ {
+ { // Real mode, floor 0
+ 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0,
+ 50, 50, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50,
+ 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50,
+ 50, 0, 0, 50, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 50, 0, 50,
+ 50, 0, 50, 0, 0, 50, 50, 50, 50, 0, 54, 55, 0, 0, 50, 0, 50,
+ 50, 0, 50, 49, 0, 50, 0, 52, 53, 0, 50, 50, 50, 0, 0, 0, 50,
+ 50, 57, 0, 50, 0, 0, 0, 50, 50, 50, 0, 0, 56, 50, 54, 55, 50,
+ 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 0, 50, 0, 0, 50, 0, 50,
+ 50, 51, 50, 0, 54, 55, 0, 0, 50, 50, 50, 50, 52, 53, 50, 0, 50,
+ 50, 0, 50, 0, 0, 0, 0, 0, 54, 55, 0, 0, 0, 50, 0, 0, 50,
+ 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50,
+ 50, 50, 0, 52, 53, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 50, 50,
+ 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0
+ },
+ { // Real mode, floor 1
+ 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0,
+ 50, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,
+ 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50,
+ 50, 0, 50, 51, 52, 53, 0, 0, 52, 53, 0, 0, 0, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 50, 0, 50, 0, 50, 0, 50, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 52, 53, 0, 0, 0, 0, 0, 52, 53, 0, 52, 53, 50,
+ 50, 57, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50,
+ 50, 0, 50, 52, 53, 0, 0, 52, 53, 0, 0, 0, 0, 0, 54, 55, 50,
+ 50, 0, 50, 0, 50, 0, 50, 50, 0, 50, 50, 0, 50, 0, 50, 50, 50,
+ 50, 0, 50, 49, 0, 0, 52, 53, 0, 52, 53, 0, 0, 0, 50, 56, 50,
+ 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50,
+ 50, 0, 0, 0, 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 0, 0, 50,
+ 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0
+ },
+ { // Real mode, floor 2
+ 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0,
+ 50, 52, 53, 0, 0, 0, 0, 50, 50, 50, 0, 0, 0, 0, 52, 53, 50,
+ 50, 0, 50, 50, 50, 0, 0, 0, 50, 0, 0, 0, 50, 50, 50, 0, 50,
+ 50, 0, 50, 52, 53, 50, 50, 52, 53, 0, 50, 50, 54, 55, 50, 0, 50,
+ 50, 0, 50, 0, 0, 0, 0, 50, 0, 50, 0, 0, 0, 0, 50, 0, 50,
+ 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 52, 53, 50,
+ 0, 50, 0, 50, 50, 50, 0, 57, 50, 51, 0, 50, 50, 50, 0, 50, 0,
+ 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 52, 53, 50, 0, 0, 0, 50,
+ 50, 0, 50, 0, 0, 0, 0, 50, 56, 50, 0, 0, 0, 0, 50, 0, 50,
+ 50, 0, 50, 54, 55, 50, 50, 0, 0, 0, 50, 50, 54, 55, 50, 0, 50,
+ 50, 0, 50, 50, 50, 0, 0, 0, 50, 0, 0, 0, 50, 50, 50, 0, 50,
+ 50, 52, 53, 0, 0, 0, 0, 50, 50, 50, 0, 0, 0, 0, 52, 53, 50,
+ 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0
+ }
+ },
+ {
+ { // Test mode, floor 0
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 56, 0, 50, 0, 0, 52, 53, 0, 0, 0, 0, 52, 53, 0, 51, 50,
+ 50, 0, 0, 50, 0, 0, 0, 50, 0, 54, 55, 50, 0, 50, 50, 50, 50,
+ 50, 52, 53, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 50, 0, 0, 50,
+ 50, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 50, 49, 50, 0, 0, 50,
+ 50, 0, 54, 55, 0, 50, 50, 54, 55, 0, 50, 50, 50, 0, 0, 0, 50,
+ 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 54, 55, 50,
+ 50, 0, 50, 0, 50, 0, 0, 50, 0, 0, 0, 50, 0, 0, 0, 0, 50,
+ 50, 0, 50, 0, 50, 54, 55, 50, 0, 50, 50, 50, 0, 50, 0, 0, 50,
+ 50, 50, 50, 50, 50, 0, 0, 50, 0, 0, 0, 0, 0, 50, 54, 55, 50,
+ 50, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 0, 0, 0, 50,
+ 50, 57, 0, 52, 53, 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 56, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50
+ },
+ { // Test mode, floor 1
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,
+ 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 54, 55, 0, 50,
+ 50, 0, 50, 52, 53, 0, 0, 50, 0, 0, 54, 55, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 0, 52, 53, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 50, 50, 50, 50, 49, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 50, 51, 0, 0, 52, 53, 50, 0, 50, 0, 50,
+ 50, 57, 50, 0, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50,
+ 50, 50, 50, 0, 50, 56, 0, 0, 0, 54, 55, 0, 0, 0, 50, 0, 50,
+ 50, 56, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50,
+ 50, 50, 50, 50, 0, 0, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50
+ },
+ { // Test mode, floor 2
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 57, 50, 54, 55, 0, 50, 54, 55, 0, 50, 0, 52, 53, 50, 51, 50,
+ 50, 0, 50, 0, 50, 0, 50, 0, 0, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 52, 53, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50,
+ 50, 0, 0, 0, 50, 0, 50, 0, 50, 0, 0, 0, 50, 0, 50, 0, 50,
+ 50, 0, 0, 0, 50, 52, 53, 0, 50, 52, 53, 56, 50, 0, 54, 55, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50
+ }
+ }
+};
+
+
+Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) {
+}
+
+
+Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0),
+ _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0),
+ _subTileX(0), _subTileY(0) {
+
_background = new Surface(320, 200, 1);
+
+ _shieldMeter = new Meter(11, 119, 92, 3, kColorShield, kColorBlack, 1020, Meter::kFillToRight);
+ _healthMeter = new Meter(11, 137, 92, 3, kColorHealth, kColorBlack, 1020, Meter::kFillToRight);
+
+ _map = new Surface(kMapWidth * kMapTileWidth + kPlayAreaWidth ,
+ kMapHeight * kMapTileHeight + kPlayAreaHeight, 1);
}
Penetration::~Penetration() {
deinit();
+ delete _map;
+
+ delete _shieldMeter;
+ delete _healthMeter;
+
delete _background;
}
-bool Penetration::play(uint16 var1, uint16 var2, uint16 var3) {
+bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) {
+ _hasAccessPass = hasAccessPass;
+ _hasMaxEnergy = hasMaxEnergy;
+ _testMode = testMode;
+
init();
initScreen();
_vm->_draw->blitInvalidated();
_vm->_video->retrace();
- while (!_vm->_util->keyPressed() && !_vm->shouldQuit())
- _vm->_util->longDelay(1);
+
+ while (!_vm->shouldQuit()) {
+ updateAnims();
+
+ // Draw and wait for the end of the frame
+ _vm->_draw->blitInvalidated();
+ _vm->_util->waitEndFrame();
+
+ // Handle input
+ _vm->_util->processInput();
+
+ int16 mouseX, mouseY;
+ MouseButtons mouseButtons;
+
+ int16 key = checkInput(mouseX, mouseY, mouseButtons);
+ // Aborting the game
+ if (key == kKeyEscape)
+ break;
+
+ // Handle the sub movement
+ handleSub(key);
+ }
deinit();
- return true;
+ return false;
}
void Penetration::init() {
@@ -80,13 +263,148 @@ void Penetration::init() {
_vm->_video->drawPackedSprite("hyprmef2.cmp", *_background);
+ _sprites = new CMPFile(_vm, "tcifplai.cmp", 320, 200);
_objects = new ANIFile(_vm, "tcite.ani", 320);
+
+ // The shield starts down
+ _shieldMeter->setValue(0);
+
+ // If we don't have the max energy tokens, the health starts at 1/3 strength
+ if (_hasMaxEnergy)
+ _healthMeter->setMaxValue();
+ else
+ _healthMeter->setValue(_healthMeter->getMaxValue() / 3);
+
+ _floor = 0;
+
+ createMap();
+
+ _sub = new ANIObject(*_objects);
+
+ _sub->setAnimation(kAnimationDriveN);
+ _sub->setPosition(kPlayAreaX + kPlayAreaBorderWidth, kPlayAreaY + kPlayAreaBorderHeight);
+ _sub->setVisible(true);
+
+ _anims.push_back(_sub);
}
void Penetration::deinit() {
+ _anims.clear();
+
+ delete _sub;
+
delete _objects;
+ delete _sprites;
_objects = 0;
+ _sprites = 0;
+
+ _sub = 0;
+}
+
+void Penetration::createMap() {
+ if (_floor >= kFloorCount)
+ error("Geisha: Invalid floor %d in minigame penetration", _floor);
+
+ // Copy the correct map
+ memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight);
+
+ _shields.clear();
+
+ _map->fill(kColorBlack);
+
+ // Draw the map tiles
+ for (int y = 0; y < kMapHeight; y++) {
+ for (int x = 0; x < kMapWidth; x++) {
+ byte *mapTile = _mapTiles + (y * kMapWidth + x);
+
+ const int posX = kPlayAreaBorderWidth + x * kMapTileWidth;
+ const int posY = kPlayAreaBorderHeight + y * kMapTileHeight;
+
+ switch (*mapTile) {
+ case 0: // Floor
+ _sprites->draw(*_map, 30, posX, posY);
+ break;
+
+ case 49: // Emergency exit (needs access pass)
+
+ if (_hasAccessPass) {
+ // Draw an exit. Now works like a regular exit
+ _sprites->draw(*_map, 29, posX, posY);
+ *mapTile = 51;
+ } else
+ // Draw a wall
+ _sprites->draw(*_map, 31, posX, posY);
+
+ break;
+
+ case 50: // Wall
+ _sprites->draw(*_map, 31, posX, posY);
+ break;
+
+ case 51: // Regular exit
+
+ if (!_testMode) {
+ // When we're not in test mode, the last exit only works with an access pass
+
+ if (_floor == 2) {
+ if (!_hasAccessPass) {
+ // It's now a wall
+ _sprites->draw(*_map, 31, posX, posY);
+ *mapTile = 50;
+ } else
+ _sprites->draw(*_map, 29, posX, posY);
+
+ } else
+ _sprites->draw(*_map, 29, posX, posY);
+
+ } else
+ // Always works in test mode
+ _sprites->draw(*_map, 29, posX, posY);
+
+ break;
+
+ case 52: // Left side of biting mouth
+ _sprites->draw(*_map, 32, posX, posY);
+ break;
+
+ case 53: // Right side of biting mouth
+ *mapTile = 0; // Works like a floor
+ break;
+
+ case 54: // Left side of kissing mouth
+ _sprites->draw(*_map, 33, posX, posY);
+ break;
+
+ case 55: // Right side of kissing mouth
+ *mapTile = 0; // Works like a floor
+ break;
+
+ case 56: // Shield lying on the floor
+ _sprites->draw(*_map, 30, posX , posY ); // Floor
+ _sprites->draw(*_map, 25, posX + 4, posY + 8); // Shield
+
+ _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield
+ _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield
+
+ _shields.push_back(Position(x, y));
+ break;
+
+ case 57: // Start position
+ _sprites->draw(*_map, 30, posX, posY);
+ *mapTile = 0;
+
+ _subTileX = x;
+ _subTileY = y;
+
+ _mapX = _subTileX * kMapTileWidth;
+ _mapY = _subTileY * kMapTileHeight;
+ break;
+ }
+ }
+ }
+
+ _mapUpdate = true;
}
void Penetration::initScreen() {
@@ -97,10 +415,133 @@ void Penetration::initScreen() {
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+ // Draw the shield meter
+ _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame
+ _sprites->draw(*_background, 271, 176, 282, 183, 9, 108, 0); // Shield
+
+ // Draw the health meter
+ _sprites->draw(*_background, 0, 0, 95, 6, 9, 135, 0); // Meter frame
+ _sprites->draw(*_background, 283, 176, 292, 184, 9, 126, 0); // Heart
+
_vm->_draw->_backSurface->blit(*_background);
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
}
+int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) {
+ _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons);
+
+ return _vm->_util->checkKey();
+}
+
+bool Penetration::isWalkable(byte tile) const {
+ // Only walls are nonwalkable
+
+ if (tile == 50)
+ return false;
+
+ return true;
+}
+
+void Penetration::handleSub(int16 key) {
+ if (key == kKeyLeft)
+ moveSub(-5, 0, kAnimationDriveW);
+ else if (key == kKeyRight)
+ moveSub( 5, 0, kAnimationDriveE);
+ else if (key == kKeyUp)
+ moveSub( 0, -5, kAnimationDriveN);
+ else if (key == kKeyDown)
+ moveSub( 0, 5, kAnimationDriveS);
+}
+
+void Penetration::moveSub(int x, int y, uint16 animation) {
+ // Limit the movement to walkable tiles
+
+ int16 minX = 0;
+ if ((_subTileX > 0) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX - 1)]))
+ minX = _subTileX * kMapTileWidth;
+
+ int16 maxX = kMapWidth * kMapTileWidth;
+ if ((_subTileX < (kMapWidth - 1)) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX + 1)]))
+ maxX = _subTileX * kMapTileWidth;
+
+ int16 minY = 0;
+ if ((_subTileY > 0) && !isWalkable(_mapTiles[(_subTileY - 1) * kMapWidth + _subTileX]))
+ minY = _subTileY * kMapTileHeight;
+
+ int16 maxY = kMapHeight * kMapTileHeight;
+ if ((_subTileY < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_subTileY + 1) * kMapWidth + _subTileX]))
+ maxY = _subTileY * kMapTileHeight;
+
+ _mapX = CLIP<int16>(_mapX + x, minX, maxX);
+ _mapY = CLIP<int16>(_mapY + y, minY, maxY);
+
+ // The tile the sub is on is where its mid-point is
+ _subTileX = (_mapX + (kMapTileWidth / 2)) / kMapTileWidth;
+ _subTileY = (_mapY + (kMapTileHeight / 2)) / kMapTileHeight;
+
+ _mapUpdate = true;
+
+ if (_sub->getAnimation() != animation)
+ _sub->setAnimation(animation);
+
+ checkShields();
+}
+
+void Penetration::checkShields() {
+ for (Common::List<Position>::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) {
+ if ((pos->x == _subTileX) && (pos->y == _subTileY)) {
+ // Charge shields
+ _shieldMeter->setMaxValue();
+
+ // Erase the shield from the map
+ const int mapX = kPlayAreaBorderWidth + pos->x * kMapTileWidth;
+ const int mapY = kPlayAreaBorderHeight + pos->y * kMapTileHeight;
+ _sprites->draw(*_map, 30, mapX, mapY);
+
+ _shields.erase(pos);
+ break;
+ }
+ }
+}
+
+void Penetration::updateAnims() {
+ int16 left = 0, top = 0, right = 0, bottom = 0;
+
+ // Clear the previous animation frames
+ for (Common::List<ANIObject *>::iterator a = _anims.reverse_begin();
+ a != _anims.end(); --a) {
+
+ if ((*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom))
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+ }
+
+ if (_mapUpdate) {
+ _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY,
+ _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY,
+ kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1);
+ }
+
+ _mapUpdate = false;
+
+ // Draw the current animation frames
+ for (Common::List<ANIObject *>::iterator a = _anims.begin();
+ a != _anims.end(); ++a) {
+
+ if ((*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom))
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+
+ (*a)->advance();
+ }
+
+ // Draw the meters
+ _shieldMeter->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+
+ _healthMeter->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+}
+
} // End of namespace Geisha
} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h
index c346a7bf5a..4d3455b638 100644
--- a/engines/gob/minigames/geisha/penetration.h
+++ b/engines/gob/minigames/geisha/penetration.h
@@ -24,34 +24,92 @@
#define GOB_MINIGAMES_GEISHA_PENETRATION_H
#include "common/system.h"
+#include "common/list.h"
namespace Gob {
class GobEngine;
class Surface;
+class CMPFile;
class ANIFile;
namespace Geisha {
+class Meter;
+
/** Geisha's "Penetration" minigame. */
class Penetration {
public:
Penetration(GobEngine *vm);
~Penetration();
- bool play(uint16 var1, uint16 var2, uint16 var3);
+ bool play(bool hasAccessPass, bool hasMaxEnergy, bool testMode);
private:
+ static const int kModeCount = 2;
+ static const int kFloorCount = 3;
+
+ static const int kMapWidth = 17;
+ static const int kMapHeight = 13;
+
+ static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight];
+
+ struct Position {
+ uint16 x;
+ uint16 y;
+
+ Position(uint16 pX, uint16 pY);
+ };
+
GobEngine *_vm;
+ bool _hasAccessPass;
+ bool _hasMaxEnergy;
+ bool _testMode;
+
Surface *_background;
+ CMPFile *_sprites;
ANIFile *_objects;
+ ANIObject *_sub;
+
+ Common::List<ANIObject *> _anims;
+
+ Meter *_shieldMeter;
+ Meter *_healthMeter;
+
+ uint8 _floor;
+
+ Surface *_map;
+ byte _mapTiles[kMapWidth * kMapHeight];
+
+ bool _mapUpdate;
+ uint16 _mapX;
+ uint16 _mapY;
+
+ uint8 _subTileX;
+ uint8 _subTileY;
+
+ Common::List<Position> _shields;
+
void init();
void deinit();
+ void createMap();
+
void initScreen();
+
+ void updateAnims();
+
+ int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons);
+
+ void handleSub(int16 key);
+ void moveSub(int x, int y, uint16 animation);
+
+ bool isWalkable(byte tile) const;
+
+ void checkShields();
};
} // End of namespace Geisha
diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp
index e294209ed7..3af19f891d 100644
--- a/engines/gob/surface.cpp
+++ b/engines/gob/surface.cpp
@@ -280,6 +280,18 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem) :
_ownVidMem = false;
}
+Surface::Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem) :
+ _width(width), _height(height), _bpp(bpp), _vidMem(0) {
+
+ assert((_width > 0) && (_height > 0));
+ assert((_bpp == 1) || (_bpp == 2));
+
+ _vidMem = new byte[_bpp * _width * _height];
+ _ownVidMem = true;
+
+ memcpy(_vidMem, vidMem, _bpp * _width * _height);
+}
+
Surface::~Surface() {
if (_ownVidMem)
delete[] _vidMem;
diff --git a/engines/gob/surface.h b/engines/gob/surface.h
index 866e63490f..5376603801 100644
--- a/engines/gob/surface.h
+++ b/engines/gob/surface.h
@@ -122,6 +122,7 @@ private:
class Surface {
public:
Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem = 0);
+ Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem);
~Surface();
uint16 getWidth () const;
diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp
index ee5ff4abff..3b1c6423bb 100644
--- a/engines/gob/video.cpp
+++ b/engines/gob/video.cpp
@@ -25,7 +25,6 @@
#include "engines/util.h"
#include "graphics/cursorman.h"
-#include "graphics/fontman.h"
#include "graphics/palette.h"
#include "graphics/surface.h"
@@ -226,10 +225,7 @@ void Video::setSize(bool defaultTo1XScaler) {
void Video::retrace(bool mouse) {
if (mouse)
- if ((_vm->getGameType() != kGameTypeAdibou2) &&
- (_vm->getGameType() != kGameTypeAdi2) &&
- (_vm->getGameType() != kGameTypeAdi4))
- CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0);
+ CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0);
if (_vm->_global->_primarySurfDesc) {
int screenX = _screenDeltaX;
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index 83fca9ac35..c10b986c60 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -315,7 +315,7 @@ VideoHandle VideoManager::playMovieRiven(uint16 id) {
for (uint16 i = 0; i < _mlstRecords.size(); i++)
if (_mlstRecords[i].code == id) {
debug(1, "Play tMOV %d (non-blocking) at (%d, %d) %s", _mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].loop != 0 ? "looping" : "non-looping");
- return createVideoHandle(_mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].loop != 0);
+ return createVideoHandle(_mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].loop != 0, _mlstRecords[i].volume);
}
return NULL_VID_HANDLE;
@@ -371,7 +371,7 @@ void VideoManager::disableAllMovies() {
_videoStreams[i].enabled = false;
}
-VideoHandle VideoManager::createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop) {
+VideoHandle VideoManager::createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop, byte volume) {
// First, check to see if that video is already playing
for (uint32 i = 0; i < _videoStreams.size(); i++)
if (_videoStreams[i].id == id)
@@ -381,6 +381,7 @@ VideoHandle VideoManager::createVideoHandle(uint16 id, uint16 x, uint16 y, bool
Video::QuickTimeDecoder *decoder = new Video::QuickTimeDecoder();
decoder->setChunkBeginOffset(_vm->getResourceOffset(ID_TMOV, id));
decoder->loadStream(_vm->getResource(ID_TMOV, id));
+ decoder->setVolume(volume);
VideoEntry entry;
entry.clear();
@@ -403,7 +404,7 @@ VideoHandle VideoManager::createVideoHandle(uint16 id, uint16 x, uint16 y, bool
return _videoStreams.size() - 1;
}
-VideoHandle VideoManager::createVideoHandle(const Common::String &filename, uint16 x, uint16 y, bool loop) {
+VideoHandle VideoManager::createVideoHandle(const Common::String &filename, uint16 x, uint16 y, bool loop, byte volume) {
// First, check to see if that video is already playing
for (uint32 i = 0; i < _videoStreams.size(); i++)
if (_videoStreams[i].filename == filename)
@@ -426,6 +427,7 @@ VideoHandle VideoManager::createVideoHandle(const Common::String &filename, uint
}
entry->loadStream(file);
+ entry->setVolume(volume);
// Search for any deleted videos so we can take a formerly used slot
for (uint32 i = 0; i < _videoStreams.size(); i++)
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index 8736782d7a..98bcadfb53 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -120,8 +120,8 @@ private:
// Keep tabs on any videos playing
Common::Array<VideoEntry> _videoStreams;
- VideoHandle createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop);
- VideoHandle createVideoHandle(const Common::String &filename, uint16 x, uint16 y, bool loop);
+ VideoHandle createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop, byte volume = 0xff);
+ VideoHandle createVideoHandle(const Common::String &filename, uint16 x, uint16 y, bool loop, byte volume = 0xff);
};
} // End of namespace Mohawk
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index ff78d4f18b..506f79b4d8 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -445,7 +445,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804},
{"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_MIDIGM) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS Floppy
// SCI interpreter version 1.000.510
@@ -1007,7 +1007,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878},
{"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO2(GUIO_MIDIGM, GAMEOPTION_JONES_CDAUDIO) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) },
// King's Quest 1 SCI Remake - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.003.007"
@@ -1221,7 +1221,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368},
{"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_MIDIGM) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS Floppy
// SCI interpreter version 1.000.060
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 42651ec4a5..664c97f7b5 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -475,6 +475,7 @@ reg_t kMoveToEnd(EngineState *s, int argc, reg_t *argv);
reg_t kGetWindowsOption(EngineState *s, int argc, reg_t *argv);
reg_t kWinHelp(EngineState *s, int argc, reg_t *argv);
reg_t kGetConfig(EngineState *s, int argc, reg_t *argv);
+reg_t kGetSierraProfileInt(EngineState *s, int argc, reg_t *argv);
reg_t kCelInfo(EngineState *s, int argc, reg_t *argv);
reg_t kSetLanguage(EngineState *s, int argc, reg_t *argv);
reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 1fa12b01fd..4ddf0534ea 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -239,6 +239,7 @@ static const SciKernelMapSubEntry kFileIO_subops[] = {
{ SIG_SCI32, 15, MAP_CALL(FileIOReadWord), "i", NULL },
{ SIG_SCI32, 16, MAP_CALL(FileIOWriteWord), "ii", NULL },
{ SIG_SCI32, 17, MAP_CALL(FileIOCreateSaveSlot), "ir", NULL },
+ { SIG_SCI32, 18, MAP_EMPTY(FileIOChangeDirectory), "r", NULL }, // for SQ6, when changing the savegame directory in the save/load dialog
{ SIG_SCI32, 19, MAP_CALL(Stub), "r", NULL }, // for Torin / Torin demo
#endif
SCI_SUBOPENTRY_TERMINATOR
@@ -560,6 +561,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(GetWindowsOption), SIG_EVERYWHERE, "i", NULL, NULL },
{ MAP_CALL(WinHelp), SIG_EVERYWHERE, "(.*)", NULL, NULL },
{ MAP_CALL(GetConfig), SIG_EVERYWHERE, "ro", NULL, NULL },
+ { MAP_CALL(GetSierraProfileInt), SIG_EVERYWHERE, "rri", NULL, NULL },
{ MAP_CALL(CelInfo), SIG_EVERYWHERE, "iiiiii", NULL, NULL },
{ MAP_CALL(SetLanguage), SIG_EVERYWHERE, "r", NULL, NULL },
{ MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "(.*)", NULL, NULL },
@@ -579,11 +581,6 @@ static SciKernelMapEntry s_kernelMap[] = {
// the game window in Phantasmagoria 2. We ignore these settings completely.
{ MAP_EMPTY(SetWindowsOption), SIG_EVERYWHERE, "ii", NULL, NULL },
- // Used by the Windows version of Phantasmagoria 1 to get the video speed setting. This is called after
- // kGetConfig and overrides the setting obtained by it. It is a dummy function in the DOS Version. We can
- // just use GetConfig and mark this one as empty, like the DOS version does.
- { MAP_EMPTY(GetSierraProfileInt), SIG_EVERYWHERE, "(.*)", NULL, NULL },
-
// Debug function called whenever the current room changes
{ MAP_EMPTY(NewRoom), SIG_EVERYWHERE, "(.*)", NULL, NULL },
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index af438bdaff..8d1b078697 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -812,7 +812,11 @@ reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv) {
FileHandle *f = getFileFromHandle(s, handle);
if (f) {
bytesRead = f->_in->read(buf, size);
- s->_segMan->memcpy(argv[1], (const byte*)buf, size);
+ // TODO: What happens if less bytes are read than what has
+ // been requested? (i.e. if bytesRead is non-zero, but still
+ // less than size)
+ if (bytesRead > 0)
+ s->_segMan->memcpy(argv[1], (const byte*)buf, size);
}
delete[] buf;
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index a32480c168..9a113bc5f9 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -356,10 +356,59 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) {
Common::String setting = s->_segMan->getString(argv[0]);
reg_t data = readSelector(s->_segMan, argv[1], SELECTOR(data));
- warning("Get config setting %s", setting.c_str());
- s->_segMan->strcpy(data, "");
+ // This function is used to get the benchmarked results stored in the
+ // resource.cfg configuration file in Phantasmagoria 1. Normally,
+ // the configuration file contains values stored by the installer
+ // regarding audio and video settings, which are then used by the
+ // executable. In Phantasmagoria, two extra executable files are used
+ // to perform system benchmarks:
+ // - CPUID for the CPU benchmarks, sets the cpu and cpuspeed settings
+ // - HDDTEC for the graphics and CD-ROM benchmarks, sets the videospeed setting
+ //
+ // These settings are then used by the game scripts directly to modify
+ // the game speed and graphics output. The result of this call is stored
+ // in global 178. The scripts check these values against the value 425.
+ // Anything below that makes Phantasmagoria awfully sluggish, so we're
+ // setting everything to 500, which makes the game playable.
+
+ setting.toLowercase();
+
+ if (setting == "videospeed") {
+ s->_segMan->strcpy(data, "500");
+ } else if (setting == "cpu") {
+ // We always return the fastest CPU setting that CPUID can detect
+ // (i.e. 586).
+ s->_segMan->strcpy(data, "586");
+ } else if (setting == "cpuspeed") {
+ s->_segMan->strcpy(data, "500");
+ } else if (setting == "language") {
+ Common::String languageId = Common::String::format("%d", g_sci->getSciLanguage());
+ s->_segMan->strcpy(data, languageId.c_str());
+ } else {
+ error("GetConfig: Unknown configuration setting %s", setting.c_str());
+ }
+
return argv[1];
}
+
+reg_t kGetSierraProfileInt(EngineState *s, int argc, reg_t *argv) {
+ Common::String category = s->_segMan->getString(argv[0]); // always "config"
+ category.toLowercase();
+ if (category != "config")
+ error("GetSierraProfileInt: category isn't 'config', it's '%s'", category.c_str());
+
+ Common::String setting = s->_segMan->getString(argv[1]);
+ setting.toLowercase();
+ if (setting != "videospeed")
+ error("GetSierraProfileInt: setting isn't 'videospeed', it's '%s'", setting.c_str());
+
+ // The game scripts pass 425 as the third parameter for some unknown reason,
+ // as after the call they compare the result to 425 anyway...
+
+ // We return the same fake value for videospeed as with kGetConfig
+ return make_reg(0, 500);
+}
+
#endif
// kIconBar is really a subop of kMacPlatform for SCI1.1 Mac
diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp
index 77f45e0788..95b3c2abc1 100644
--- a/engines/sci/video/robot_decoder.cpp
+++ b/engines/sci/video/robot_decoder.cpp
@@ -116,7 +116,7 @@ bool RobotDecoder::loadStream(Common::SeekableReadStream *stream) {
if (_header.hasSound) {
_audioStream = Audio::makeQueuingAudioStream(11025, false);
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_audioHandle, _audioStream);
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, &_audioHandle, _audioStream, -1, getVolume(), getBalance());
}
readPaletteChunk(_header.paletteDataSize);
@@ -361,6 +361,16 @@ void RobotDecoder::close() {
reset();
}
+void RobotDecoder::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelVolume(_audioHandle, getVolume());
+}
+
+void RobotDecoder::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelBalance(_audioHandle, getBalance());
+}
+
#endif
} // End of namespace Sci
diff --git a/engines/sci/video/robot_decoder.h b/engines/sci/video/robot_decoder.h
index 3f93582418..e9cefe7d91 100644
--- a/engines/sci/video/robot_decoder.h
+++ b/engines/sci/video/robot_decoder.h
@@ -71,6 +71,11 @@ public:
Common::Point getPos() const { return _pos; }
protected:
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
+ // FixedRateVideoDecoder API
Common::Rational getFrameRate() const { return Common::Rational(60, 10); }
private:
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 2da0abb5df..cd878b49ae 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -156,6 +156,7 @@ Common::String ScummEngine_v70he::generateFilename(const int room) const {
case kGenHEMac:
case kGenHEMacNoParens:
case kGenHEPC:
+ case kGenHEIOS:
if (_game.heversion >= 98 && room >= 0) {
int disk = 0;
if (_heV7DiskOffsets)
@@ -168,7 +169,11 @@ Common::String ScummEngine_v70he::generateFilename(const int room) const {
break;
case 1:
id = 'a';
- result = Common::String::format("%s.(a)", _filenamePattern.pattern);
+ // Some of the newer HE games for iOS use the ".hea" suffix instead
+ if (_filenamePattern.genMethod == kGenHEIOS)
+ result = Common::String::format("%s.hea", _filenamePattern.pattern);
+ else
+ result = Common::String::format("%s.(a)", _filenamePattern.pattern);
break;
default:
id = '0';
@@ -180,7 +185,7 @@ Common::String ScummEngine_v70he::generateFilename(const int room) const {
id = (room == 0) ? '0' : '1';
}
- if (_filenamePattern.genMethod == kGenHEPC) {
+ if (_filenamePattern.genMethod == kGenHEPC || _filenamePattern.genMethod == kGenHEIOS) {
// For HE >= 98, we already called snprintf above.
if (_game.heversion < 98 || room < 0)
result = Common::String::format("%s.he%c", _filenamePattern.pattern, id);
@@ -217,6 +222,7 @@ static Common::String generateFilenameForDetection(const char *pattern, Filename
break;
case kGenHEPC:
+ case kGenHEIOS:
result = Common::String::format("%s.he0", pattern);
break;
diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index b6dfa757bb..5ed6b5aab0 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -99,6 +99,7 @@ enum FilenameGenMethod {
kGenHEMac,
kGenHEMacNoParens,
kGenHEPC,
+ kGenHEIOS,
kGenUnchanged
};
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index e1989d5274..452a6f0960 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -382,7 +382,7 @@ static const GameSettings gameVariantsTable[] = {
{"pjgames", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added the use of bink videos
- {"Baseball2003", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"Baseball2003", 0, 0, GID_BASEBALL2003, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"football2002", 0, 0, GID_FOOTBALL, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
@@ -704,7 +704,8 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "freddi4", "Freddi 4 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "freddi4", "FreddiGS", kGenHEPC, Common::DE_DEU, UNK, 0 },
{ "freddi4", "FreddiGS", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 },
- { "freddi4", "FreddiHRBG", kGenHEPC, UNK_LANG, UNK, 0 },
+ { "freddi4", "FreddiHRBG", kGenHEPC, Common::EN_GRB, UNK, 0 },
+ { "freddi4", "FreddiHRBG", kGenHEMac, Common::EN_GRB, Common::kPlatformMacintosh, 0 },
{ "freddi4", "FreddiMini", kGenHEPC, UNK_LANG, UNK, 0 },
{ "freddi4", "Malice4", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 },
{ "freddi4", "MaliceMRC", kGenHEPC, Common::FR_FRA, UNK, 0 },
@@ -885,6 +886,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "spyfox", "Spy Fox", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "spyfox", "Spy Fox Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "spyfox", "JR-Demo", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 },
+ { "spyfox", "game", kGenHEIOS, Common::EN_ANY, Common::kPlatformIOS, 0 },
{ "spyfox2", "spyfox2", kGenHEPC, UNK_LANG, UNK, 0 },
{ "spyfox2", "sf2-demo", kGenHEPC, UNK_LANG, UNK, 0 },
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index 56ea10f507..d2e01a6564 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -2339,6 +2339,12 @@ void ScummEngine_v100he::o100_writeFile() {
}
void ScummEngine_v100he::o100_debugInput() {
+ // Backyard Basketball uses older code for this opcode
+ if (_game.id == GID_BASKETBALL) {
+ ScummEngine_v72he::o72_debugInput();
+ return;
+ }
+
byte subOp = fetchScriptByte();
switch (subOp) {
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index 0beebdb7a1..9e8ac7e2f2 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -2373,8 +2373,8 @@ void ScummEngine_v90he::o90_kernelSetFunctions() {
case 2001:
_logicHE->dispatch(args[1], num - 2, (int32 *)&args[2]);
break;
- case 201102:
- // Used in puttzoo iOS
+ case 201102: // Used in puttzoo iOS
+ case 20111014: // Used in spyfox iOS
break;
default:
error("o90_kernelSetFunctions: default case %d (param count %d)", args[0], num);
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 39420ee974..d8c4948ea8 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -250,7 +250,7 @@ void ScummEngine::stopScript(int script) {
if (vm.nest[i].number == script &&
(vm.nest[i].where == WIO_GLOBAL || vm.nest[i].where == WIO_LOCAL)) {
nukeArrays(vm.nest[i].slot);
- vm.nest[i].number = 0xFF;
+ vm.nest[i].number = 0;
vm.nest[i].slot = 0xFF;
vm.nest[i].where = 0xFF;
}
@@ -284,7 +284,7 @@ void ScummEngine::stopObjectScript(int script) {
if (vm.nest[i].number == script &&
(vm.nest[i].where == WIO_ROOM || vm.nest[i].where == WIO_INVENTORY || vm.nest[i].where == WIO_FLOBJECT)) {
nukeArrays(vm.nest[i].slot);
- vm.nest[i].number = 0xFF;
+ vm.nest[i].number = 0;
vm.nest[i].slot = 0xFF;
vm.nest[i].where = 0xFF;
}
@@ -318,7 +318,7 @@ void ScummEngine::runScriptNested(int script) {
nest = &vm.nest[vm.numNestedScripts];
if (_currentScript == 0xFF) {
- nest->number = 0xFF;
+ nest->number = 0;
nest->where = 0xFF;
} else {
// Store information about the currently running script
@@ -338,7 +338,7 @@ void ScummEngine::runScriptNested(int script) {
if (vm.numNestedScripts != 0)
vm.numNestedScripts--;
- if (nest->number != 0xFF) {
+ if (nest->number) {
// Try to resume the script which called us, if its status has not changed
// since it invoked us. In particular, we only resume it if it hasn't been
// stopped in the meantime, and if it did not already move on.
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 3957c7c42d..946e954a46 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 Tue Apr 24 03:50:58 2012
+ This file was generated by the md5table tool on Tue May 29 00:49:03 2012
DO NOT EDIT MANUALLY!
*/
@@ -73,6 +73,7 @@ static const MD5Table md5table[] = {
{ "151071053a1d0021198216713939521d", "freddi2", "HE 80", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "15240c59d3681ed53f714f8d925cb2d6", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformAtariST },
{ "157367c3c21e0d03a0cba44361b4cf65", "indy3", "No AdLib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST },
+ { "15878e3bee2e1e759184abee98589eaa", "spyfox", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformIOS },
{ "15e03ffbfeddb9c2aebc13dcb2a4a8f4", "monkey", "VGA", "VGA", 8357, Common::EN_ANY, Common::kPlatformPC },
{ "15f588e887e857e8c56fe6ade4956168", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "16542a7342a918bfe4ba512007d36c47", "FreddisFunShop", "HE 99L", "", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -173,7 +174,7 @@ static const MD5Table md5table[] = {
{ "3ae7f002d9256b8bdf76aaf8a3a069f8", "freddi", "HE 100", "", 34837, Common::EN_GRB, Common::kPlatformWii },
{ "3af61c5edf8e15b43dbafd285b2e9777", "puttcircus", "", "Demo", -1, Common::HE_ISR, Common::kPlatformWindows },
{ "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
- { "3b832f4a90740bf22e9b8ed42ca0128c", "freddi4", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows },
+ { "3b832f4a90740bf22e9b8ed42ca0128c", "freddi4", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformUnknown },
{ "3c4c471342bd95505a42334367d8f127", "puttmoon", "HE 70", "", 12161, Common::RU_RUS, Common::kPlatformWindows },
{ "3cce1913a3bc586b51a75c3892ff18dd", "indy3", "VGA", "VGA", -1, Common::RU_RUS, Common::kPlatformPC },
{ "3d219e7546039543307b55a91282bf18", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index fc46f88df4..d0f46f3e56 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1917,6 +1917,13 @@ void ScummEngine::syncSoundSettings() {
if (VAR_CHARINC != 0xFF)
VAR(VAR_CHARINC) = _defaultTalkDelay;
}
+
+ // Backyard Baseball 2003 uses a unique subtitle variable,
+ // rather than VAR_SUBTITLES
+ if (_game.id == GID_BASEBALL2003) {
+ _scummVars[632] = ConfMan.getBool("subtitles");
+ }
+
}
void ScummEngine::setTalkSpeed(int talkspeed) {
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index cacf8c214e..8c0070b5f5 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -245,6 +245,7 @@ enum ScummGameId {
GID_SOCCERMLS,
GID_SOCCER2004,
GID_BASEBALL2001,
+ GID_BASEBALL2003,
GID_BASKETBALL,
GID_MOONBASE,
GID_HECUP // CUP demos
diff --git a/engines/sword25/fmv/theora_decoder.cpp b/engines/sword25/fmv/theora_decoder.cpp
index 082c569fda..d38f5a26cf 100644
--- a/engines/sword25/fmv/theora_decoder.cpp
+++ b/engines/sword25/fmv/theora_decoder.cpp
@@ -289,7 +289,7 @@ bool TheoraDecoder::loadStream(Common::SeekableReadStream *stream) {
}
if (_audStream)
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _audHandle, _audStream);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _audHandle, _audStream, -1, getVolume(), getBalance());
} else {
// tear down the partial vorbis setup
vorbis_info_clear(&_vorbisInfo);
@@ -550,6 +550,16 @@ void TheoraDecoder::translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer) {
Graphics::convertYUV420ToRGB(&_surface, YUVBuffer[kBufferY].data, YUVBuffer[kBufferU].data, YUVBuffer[kBufferV].data, YUVBuffer[kBufferY].width, YUVBuffer[kBufferY].height, YUVBuffer[kBufferY].stride, YUVBuffer[kBufferU].stride);
}
+void TheoraDecoder::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(*_audHandle))
+ g_system->getMixer()->setChannelVolume(*_audHandle, getVolume());
+}
+
+void TheoraDecoder::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(*_audHandle))
+ g_system->getMixer()->setChannelBalance(*_audHandle, getBalance());
+}
+
} // End of namespace Sword25
#endif
diff --git a/engines/sword25/fmv/theora_decoder.h b/engines/sword25/fmv/theora_decoder.h
index 4fd7cc0f03..739040024f 100644
--- a/engines/sword25/fmv/theora_decoder.h
+++ b/engines/sword25/fmv/theora_decoder.h
@@ -87,6 +87,9 @@ public:
bool endOfVideo() const;
protected:
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
void pauseVideoIntern(bool pause);
private:
diff --git a/gui/themes/translations.dat b/gui/themes/translations.dat
index a9645f226a..1463b70212 100644
--- a/gui/themes/translations.dat
+++ b/gui/themes/translations.dat
Binary files differ
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index f6005d02f1..dd13e78f1b 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: ScummVM 1.4.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.sf.net\n"
"POT-Creation-Date: 2012-05-20 22:39+0100\n"
-"PO-Revision-Date: 2012-03-17 19:07+0100\n"
+"PO-Revision-Date: 2012-05-22 21:02+0100\n"
"Last-Translator: Zbyněk Schwarz <zbynek.schwarz@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -194,9 +194,8 @@ msgid "Platform:"
msgstr "Platforma:"
#: gui/launcher.cpp:231
-#, fuzzy
msgid "Engine"
-msgstr "Prohlédnout"
+msgstr "Jádro"
#: gui/launcher.cpp:239 gui/options.cpp:1062 gui/options.cpp:1079
msgid "Graphics"
@@ -1250,12 +1249,12 @@ msgstr "Přesto spustit"
#: engines/agi/detection.cpp:145 engines/dreamweb/detection.cpp:47
#: engines/sci/detection.cpp:390
msgid "Use original save/load screens"
-msgstr ""
+msgstr "Použít původní obrazovky načtení/uložení"
#: engines/agi/detection.cpp:146 engines/dreamweb/detection.cpp:48
#: engines/sci/detection.cpp:391
msgid "Use the original save/load screens, instead of the ScummVM ones"
-msgstr ""
+msgstr "Použít původní obrazovky načtení/uložení místo ze ScummVM"
#: engines/agi/saveload.cpp:827 engines/sci/engine/kfile.cpp:674
msgid "Restore game:"
@@ -1266,78 +1265,76 @@ msgid "Restore"
msgstr "Obnovit"
#: engines/dreamweb/detection.cpp:57
-#, fuzzy
msgid "Use bright palette mode"
-msgstr "Položka vpravo nahoře"
+msgstr "Použít režim jasné palety"
#: engines/dreamweb/detection.cpp:58
msgid "Display graphics using the game's bright palette"
-msgstr ""
+msgstr "Zobrazit grafiku pomocí jasné palety hry"
#: engines/sci/detection.cpp:370
msgid "EGA undithering"
msgstr "Nerozkládání EGA"
#: engines/sci/detection.cpp:371
-#, fuzzy
msgid "Enable undithering in EGA games"
-msgstr "Povolit nerozkládání v EGA hrách, které to podporují"
+msgstr "Povolit nerozkládání v EGA hrách"
#: engines/sci/detection.cpp:380
-#, fuzzy
msgid "Prefer digital sound effects"
-msgstr "Hlasitost speciálních zvukových efektů"
+msgstr "Upřednostňovat digitální zvukové efekty"
#: engines/sci/detection.cpp:381
msgid "Prefer digital sound effects instead of synthesized ones"
-msgstr ""
+msgstr "Upřednostňovat digitální zvukové efekty před syntetizovanými"
#: engines/sci/detection.cpp:400
msgid "Use IMF/Yahama FB-01 for MIDI output"
-msgstr ""
+msgstr "Použít IMF/Yahama FB-01 pro výstup MIDI"
#: engines/sci/detection.cpp:401
msgid ""
"Use an IBM Music Feature card or a Yahama FB-01 FM synth module for MIDI "
"output"
msgstr ""
+"Použít kartu IBM Music Feature nebo modul syntetizátoru Yahama FB-01 FM pro "
+"výstup MIDI"
#: engines/sci/detection.cpp:411
msgid "Use CD audio"
-msgstr ""
+msgstr "Použít zvuky na CD"
#: engines/sci/detection.cpp:412
msgid "Use CD audio instead of in-game audio, if available"
-msgstr ""
+msgstr "Použít zvuky na CD místo ve hře, pokud je dostupné"
#: engines/sci/detection.cpp:422
msgid "Use Windows cursors"
-msgstr ""
+msgstr "Použít kurzory Windows"
#: engines/sci/detection.cpp:423
msgid ""
"Use the Windows cursors (smaller and monochrome) instead of the DOS ones"
-msgstr ""
+msgstr "Použít kurzory Windows (menší a černobílé) místo kurzorů z DOS"
#: engines/sci/detection.cpp:433
-#, fuzzy
msgid "Use silver cursors"
-msgstr "Obyčejný kurzor"
+msgstr "Použít stříbrné kurzory"
#: engines/sci/detection.cpp:434
msgid ""
"Use the alternate set of silver cursors, instead of the normal golden ones"
-msgstr ""
+msgstr "Použít alternativní sadu stříbrných kurzorů místo standardních zlatých"
#: engines/scumm/dialogs.cpp:175
#, c-format
msgid "Insert Disk %c and Press Button to Continue."
-msgstr "Vložte Disk %c a Stiskněte Tlačítko Pro Poračování."
+msgstr "Vložte Disk %c a Stiskněte Tlačítko Pro Pokračování."
#: engines/scumm/dialogs.cpp:176
#, c-format
msgid "Unable to Find %s, (%c%d) Press Button."
-msgstr "Nelze Najít %s, (%c%d) Stsikěte Tlačítko."
+msgstr "Nelze Najít %s, (%c%d) Stiskněte Tlačítko."
#: engines/scumm/dialogs.cpp:177
#, c-format
@@ -2080,61 +2077,59 @@ msgstr "Nelze uložit hru."
#. Malcolm makes a joke.
#: engines/kyra/detection.cpp:62
msgid "Studio audience"
-msgstr ""
+msgstr "Publikum ve studiu"
#: engines/kyra/detection.cpp:63
msgid "Enable studio audience"
-msgstr ""
+msgstr "Povolit publikum ve studiu"
#. I18N: This option allows the user to skip text and cutscenes.
#: engines/kyra/detection.cpp:73
msgid "Skip support"
-msgstr ""
+msgstr "Podpora přeskočení"
#: engines/kyra/detection.cpp:74
msgid "Allow text and cutscenes to be skipped"
-msgstr ""
+msgstr "Umožnit, aby text a videa mohly být přeskočeny"
#. I18N: Helium mode makes people sound like they've inhaled Helium.
#: engines/kyra/detection.cpp:84
msgid "Helium mode"
-msgstr ""
+msgstr "Héliový režim"
#: engines/kyra/detection.cpp:85
-#, fuzzy
msgid "Enable helium mode"
-msgstr "Zapnout režim Roland GS"
+msgstr "Zapnout héliový režim"
#. I18N: When enabled, this option makes scrolling smoother when
#. changing from one screen to another.
#: engines/kyra/detection.cpp:99
msgid "Smooth scrolling"
-msgstr ""
+msgstr "Plynulé posunování"
#: engines/kyra/detection.cpp:100
msgid "Enable smooth scrolling when walking"
-msgstr ""
+msgstr "Povolit plynulé posunování při chůzi"
#. I18N: When enabled, this option changes the cursor when it floats to the
#. edge of the screen to a directional arrow. The player can then click to
#. walk towards that direction.
#: engines/kyra/detection.cpp:112
-#, fuzzy
msgid "Floating cursors"
-msgstr "Obyčejný kurzor"
+msgstr "Plovoucí kurzory"
#: engines/kyra/detection.cpp:113
msgid "Enable floating cursors"
-msgstr ""
+msgstr "Povolit plovoucí kurzory"
#. I18N: HP stands for Hit Points
#: engines/kyra/detection.cpp:127
msgid "HP bar graphs"
-msgstr ""
+msgstr "Sloupcový indikátor zdraví"
#: engines/kyra/detection.cpp:128
msgid "Enable hit point bar graphs"
-msgstr ""
+msgstr "Povolit sloupcový indikátor zdraví"
#: engines/kyra/lol.cpp:478
msgid "Attack 1"
@@ -2200,11 +2195,11 @@ msgstr ""
#: engines/queen/queen.cpp:59 engines/sky/detection.cpp:44
msgid "Floppy intro"
-msgstr ""
+msgstr "Úvod z diskety"
#: engines/queen/queen.cpp:60 engines/sky/detection.cpp:45
msgid "Use the floppy version's intro (CD version only)"
-msgstr ""
+msgstr "Použít verzi úvodu z diskety (Pouze verze CD)"
#: engines/sky/compact.cpp:130
msgid ""
@@ -2286,11 +2281,11 @@ msgstr "Videa PSX nalezena, ale ScummVM byl sestaven bez podpory barev RGB"
#: engines/sword2/sword2.cpp:79
msgid "Show object labels"
-msgstr ""
+msgstr "Zobrazit jmenovky objektů"
#: engines/sword2/sword2.cpp:80
msgid "Show labels for objects on mouse hover"
-msgstr ""
+msgstr "Zobrazit jmenovky objektů při najetí myši"
#: engines/parallaction/saveload.cpp:133
#, c-format
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 28fa712d4f..2ea7e8d90e 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -262,7 +262,7 @@ bool AviDecoder::loadStream(Common::SeekableReadStream *stream) {
// Initialize the video stuff too
_audStream = createAudioStream();
if (_audStream)
- _mixer->playStream(_soundType, _audHandle, _audStream);
+ _mixer->playStream(_soundType, _audHandle, _audStream, -1, getVolume(), getBalance());
debug (0, "Frames = %d, Dimensions = %d x %d", _header.totalFrames, _header.width, _header.height);
debug (0, "Frame Rate = %d", _vidsHeader.rate / _vidsHeader.scale);
@@ -451,4 +451,14 @@ void AviDecoder::queueAudioBuffer(uint32 chunkSize) {
}
}
+void AviDecoder::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(*_audHandle))
+ g_system->getMixer()->setChannelVolume(*_audHandle, getVolume());
+}
+
+void AviDecoder::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(*_audHandle))
+ g_system->getMixer()->setChannelBalance(*_audHandle, getBalance());
+}
+
} // End of namespace Video
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index edd08c42a0..fb4dae6711 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -202,6 +202,11 @@ public:
bool hasDirtyPalette() const { return _dirtyPalette; }
protected:
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
+ // FixedRateVideoDecoder API
Common::Rational getFrameRate() const { return Common::Rational(_vidsHeader.rate, _vidsHeader.scale); }
private:
diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp
index 4738c3c8c0..538487f067 100644
--- a/video/bink_decoder.cpp
+++ b/video/bink_decoder.cpp
@@ -120,7 +120,7 @@ void BinkDecoder::startAudio() {
const AudioTrack &audio = _audioTracks[_audioTrack];
_audioStream = Audio::makeQueuingAudioStream(audio.outSampleRate, audio.outChannels == 2);
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream, -1, getVolume(), getBalance());
} // else no audio
}
@@ -1647,4 +1647,14 @@ void BinkDecoder::IDCTPut(DecodeContext &ctx, int16 *block) {
}
}
+void BinkDecoder::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelVolume(_audioHandle, getVolume());
+}
+
+void BinkDecoder::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelBalance(_audioHandle, getBalance());
+}
+
} // End of namespace Video
diff --git a/video/bink_decoder.h b/video/bink_decoder.h
index f1eadc6f17..a5e1b10270 100644
--- a/video/bink_decoder.h
+++ b/video/bink_decoder.h
@@ -78,7 +78,12 @@ public:
// Bink specific
bool loadStream(Common::SeekableReadStream *stream, const Graphics::PixelFormat &format);
+
protected:
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
static const int kAudioChannelsMax = 2;
static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11);
diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index ae0c35cd76..be36874db4 100644
--- a/video/coktel_decoder.cpp
+++ b/video/coktel_decoder.cpp
@@ -1292,7 +1292,7 @@ void IMDDecoder::processFrame() {
// Start the audio stream if necessary
if (startSound && _soundEnabled) {
_mixer->playStream(_soundType, &_audioHandle, _audioStream,
- -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ -1, getVolume(), getBalance(), DisposeAfterUse::NO);
_soundStage = kSoundPlaying;
}
@@ -1474,6 +1474,16 @@ Graphics::PixelFormat IMDDecoder::getPixelFormat() const {
return Graphics::PixelFormat::createFormatCLUT8();
}
+void IMDDecoder::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelVolume(_audioHandle, getVolume());
+}
+
+void IMDDecoder::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelBalance(_audioHandle, getBalance());
+}
+
VMDDecoder::File::File() {
offset = 0;
@@ -2161,7 +2171,7 @@ void VMDDecoder::processFrame() {
if (startSound && _soundEnabled) {
if (_hasSound && _audioStream) {
_mixer->playStream(_soundType, &_audioHandle, _audioStream,
- -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ -1, getVolume(), getBalance(), DisposeAfterUse::NO);
_soundStage = kSoundPlaying;
} else
_soundStage = kSoundNone;
@@ -2687,6 +2697,16 @@ bool VMDDecoder::isPaletted() const {
return _isPaletted;
}
+void VMDDecoder::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelVolume(_audioHandle, getVolume());
+}
+
+void VMDDecoder::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelBalance(_audioHandle, getBalance());
+}
+
} // End of namespace Video
#endif // VIDEO_COKTELDECODER_H
diff --git a/video/coktel_decoder.h b/video/coktel_decoder.h
index b99a44f332..68696d5ff3 100644
--- a/video/coktel_decoder.h
+++ b/video/coktel_decoder.h
@@ -284,6 +284,11 @@ public:
Graphics::PixelFormat getPixelFormat() const;
+protected:
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
private:
enum Command {
kCommandNextSound = 0xFF00,
@@ -388,6 +393,11 @@ public:
Graphics::PixelFormat getPixelFormat() const;
+protected:
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
private:
enum PartType {
kPartTypeSeparator = 0,
diff --git a/video/psx_decoder.cpp b/video/psx_decoder.cpp
index 74f740f614..df91a2badd 100644
--- a/video/psx_decoder.cpp
+++ b/video/psx_decoder.cpp
@@ -385,7 +385,7 @@ void PSXStreamDecoder::queueAudioFromSector(Common::SeekableReadStream *sector)
uint rate = (format & (1 << 2)) ? 18900 : 37800;
_audStream = Audio::makeQueuingAudioStream(rate, stereo);
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audHandle, _audStream);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audHandle, _audStream, -1, getVolume(), getBalance());
}
sector->seek(24);
@@ -694,4 +694,14 @@ void PSXStreamDecoder::decodeBlock(Common::BitStream *bits, byte *block, int pit
}
}
+void PSXStreamDecoder::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(_audHandle))
+ g_system->getMixer()->setChannelVolume(_audHandle, getVolume());
+}
+
+void PSXStreamDecoder::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(_audHandle))
+ g_system->getMixer()->setChannelBalance(_audHandle, getBalance());
+}
+
} // End of namespace Video
diff --git a/video/psx_decoder.h b/video/psx_decoder.h
index 3695cb0f42..4364ec4bbb 100644
--- a/video/psx_decoder.h
+++ b/video/psx_decoder.h
@@ -81,6 +81,11 @@ public:
Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
bool endOfVideo() const { return _stream->pos() >= _stream->size(); }
+protected:
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
private:
void initCommon();
Common::SeekableReadStream *_stream;
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 585f5927a1..aba545abc0 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -97,7 +97,7 @@ void QuickTimeDecoder::startAudio() {
updateAudioBuffer();
for (uint32 i = 0; i < _audioTracks.size(); i++) {
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandles[i], _audioTracks[i], -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandles[i], _audioTracks[i], -1, getVolume(), getBalance(), DisposeAfterUse::NO);
// Pause the audio again if we're still paused
if (isPaused())
@@ -236,6 +236,18 @@ bool QuickTimeDecoder::loadStream(Common::SeekableReadStream *stream) {
return true;
}
+void QuickTimeDecoder::updateVolume() {
+ for (uint32 i = 0; i < _audioHandles.size(); i++)
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandles[i]))
+ g_system->getMixer()->setChannelVolume(_audioHandles[i], getVolume());
+}
+
+void QuickTimeDecoder::updateBalance() {
+ for (uint32 i = 0; i < _audioHandles.size(); i++)
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandles[i]))
+ g_system->getMixer()->setChannelBalance(_audioHandles[i], getBalance());
+}
+
void QuickTimeDecoder::init() {
Audio::QuickTimeAudioDecoder::init();
diff --git a/video/qt_decoder.h b/video/qt_decoder.h
index 1f614df18b..ce32562d64 100644
--- a/video/qt_decoder.h
+++ b/video/qt_decoder.h
@@ -133,6 +133,10 @@ protected:
Common::QuickTimeParser::SampleDesc *readSampleDesc(Track *track, uint32 format);
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
private:
void init();
diff --git a/video/smk_decoder.cpp b/video/smk_decoder.cpp
index 439fe9027d..359f4cb9bd 100644
--- a/video/smk_decoder.cpp
+++ b/video/smk_decoder.cpp
@@ -667,7 +667,7 @@ void SmackerDecoder::handleAudioTrack(byte track, uint32 chunkSize, uint32 unpac
}
if (!_audioStarted) {
- _mixer->playStream(_soundType, &_audioHandle, _audioStream, -1, 255);
+ _mixer->playStream(_soundType, &_audioHandle, _audioStream, -1, getVolume(), getBalance());
_audioStarted = true;
}
} else {
@@ -819,4 +819,14 @@ void SmackerDecoder::unpackPalette() {
free(chunk);
}
+void SmackerDecoder::updateVolume() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelVolume(_audioHandle, getVolume());
+}
+
+void SmackerDecoder::updateBalance() {
+ if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
+ g_system->getMixer()->setChannelBalance(_audioHandle, getBalance());
+}
+
} // End of namespace Video
diff --git a/video/smk_decoder.h b/video/smk_decoder.h
index fd5d658bdd..516882e7c8 100644
--- a/video/smk_decoder.h
+++ b/video/smk_decoder.h
@@ -77,9 +77,15 @@ public:
virtual void handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize);
protected:
- Common::Rational getFrameRate() const { return _frameRate; }
Common::SeekableReadStream *_fileStream;
+ // VideoDecoder API
+ void updateVolume();
+ void updateBalance();
+
+ // FixedRateVideoDecoder API
+ Common::Rational getFrameRate() const { return _frameRate; }
+
protected:
void unpackPalette();
// Possible runs of blocks
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index ae82a3374c..44d7917652 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -22,6 +22,8 @@
#include "video/video_decoder.h"
+#include "audio/mixer.h" // for kMaxChannelVolume
+
#include "common/rational.h"
#include "common/file.h"
#include "common/system.h"
@@ -61,6 +63,8 @@ void VideoDecoder::reset() {
_curFrame = -1;
_startTime = 0;
_pauseLevel = 0;
+ _audioVolume = Audio::Mixer::kMaxChannelVolume;
+ _audioBalance = 0;
}
bool VideoDecoder::endOfVideo() const {
@@ -94,6 +98,16 @@ void VideoDecoder::resetPauseStartTime() {
_pauseStartTime = g_system->getMillis();
}
+void VideoDecoder::setVolume(byte volume) {
+ _audioVolume = volume;
+ updateVolume();
+}
+
+void VideoDecoder::setBalance(int8 balance) {
+ _audioBalance = balance;
+ updateBalance();
+}
+
uint32 FixedRateVideoDecoder::getTimeToNextFrame() const {
if (endOfVideo() || _curFrame < 0)
return 0;
diff --git a/video/video_decoder.h b/video/video_decoder.h
index 2b99a2b1bf..3bb75ade09 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -185,6 +185,40 @@ public:
*/
bool isPaused() const { return _pauseLevel != 0; }
+ /**
+ * Get the current volume at which the audio in the video is being played
+ * @return the current volume at which the audio in the video is being played
+ */
+ virtual byte getVolume() const { return _audioVolume; }
+
+ /**
+ * Set the volume at which the audio in the video should be played.
+ * This setting remains until reset() is called (which may be called
+ * from loadStream() or close()). The default volume is the maximum.
+ *
+ * @note This function calls updateVolume() by default.
+ *
+ * @param volume The volume at which to play the audio in the video
+ */
+ virtual void setVolume(byte volume);
+
+ /**
+ * Get the current balance at which the audio in the video is being played
+ * @return the current balance at which the audio in the video is being played
+ */
+ virtual int8 getBalance() const { return _audioBalance; }
+
+ /**
+ * Set the balance at which the audio in the video should be played.
+ * This setting remains until reset() is called (which may be called
+ * from loadStream() or close()). The default balance is 0.
+ *
+ * @note This function calls updateBalance() by default.
+ *
+ * @param balance The balance at which to play the audio in the video
+ */
+ virtual void setBalance(int8 balance);
+
protected:
/**
* Resets _curFrame and _startTime. Should be called from every close() function.
@@ -207,12 +241,24 @@ protected:
*/
void resetPauseStartTime();
+ /**
+ * Update currently playing audio tracks with the new volume setting
+ */
+ virtual void updateVolume() {}
+
+ /**
+ * Update currently playing audio tracks with the new balance setting
+ */
+ virtual void updateBalance() {}
+
int32 _curFrame;
int32 _startTime;
private:
uint32 _pauseLevel;
uint32 _pauseStartTime;
+ byte _audioVolume;
+ int8 _audioBalance;
};
/**