aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2017-01-15 23:05:56 +0100
committerWalter van Niftrik2017-01-15 23:17:46 +0100
commit9f5004ceda75e17e4d42e4fc57979c26c8679902 (patch)
tree96a96c70f7e26b26e058b512b7816667593d1868
parent89de1549ca267c137c23f2fd88b9fc7256b23194 (diff)
downloadscummvm-rg350-9f5004ceda75e17e4d42e4fc57979c26c8679902.tar.gz
scummvm-rg350-9f5004ceda75e17e4d42e4fc57979c26c8679902.tar.bz2
scummvm-rg350-9f5004ceda75e17e4d42e4fc57979c26c8679902.zip
ADL: Implement hires5 'win game' opcode
-rw-r--r--engines/adl/adl.cpp6
-rw-r--r--engines/adl/adl.h2
-rw-r--r--engines/adl/hires5.cpp42
3 files changed, 48 insertions, 2 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e92cd690c8..3b5ebfb3ca 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -468,10 +468,14 @@ void AdlEngine::bell(uint count) const {
tones.push_back(Tone(940.0, 100.0));
+ playTones(tones, false);
+}
+
+void AdlEngine::playTones(const Tones &tones, bool isMusic) const {
Audio::SoundHandle handle;
Audio::AudioStream *stream = new Sound(tones);
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &handle, stream);
+ g_system->getMixer()->playStream((isMusic ? Audio::Mixer::kMusicSoundType : Audio::Mixer::kSFXSoundType), &handle, stream);
while (!g_engine->shouldQuit() && g_system->getMixer()->isSoundHandleActive(handle)) {
Common::Event event;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index c9b97237c4..8883416fd3 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -39,6 +39,7 @@
#include "adl/console.h"
#include "adl/disk.h"
+#include "adl/sound.h"
namespace Common {
class ReadStream;
@@ -311,6 +312,7 @@ protected:
// Sound
void bell(uint count = 1) const;
+ void playTones(const Tones &tones, bool isMusic) const;
// Game state functions
const Region &getRegion(uint i) const;
diff --git a/engines/adl/hires5.cpp b/engines/adl/hires5.cpp
index c1ada9e7d3..ffcd2fb04c 100644
--- a/engines/adl/hires5.cpp
+++ b/engines/adl/hires5.cpp
@@ -31,6 +31,7 @@
#include "adl/display.h"
#include "adl/graphics.h"
#include "adl/disk.h"
+#include "adl/sound.h"
namespace Adl {
@@ -51,6 +52,8 @@ private:
// AdlEngine_v4
bool isInventoryFull();
+ void loadSong(Common::ReadStream &stream);
+
int o_checkItemTimeLimits(ScriptEnv &e);
int o_startAnimation(ScriptEnv &e);
int o_winGame(ScriptEnv &e);
@@ -60,6 +63,7 @@ private:
Common::Array<byte> _itemTimeLimits;
Common::String _itemTimeLimitMsg;
+ Tones _song;
struct {
Common::String itemTimeLimit;
@@ -154,6 +158,38 @@ bool HiRes5Engine::isInventoryFull() {
return false;
}
+void HiRes5Engine::loadSong(Common::ReadStream &stream) {
+ while (true) {
+ const byte period = stream.readByte();
+
+ if (stream.err() || stream.eos())
+ error("Error loading song");
+
+ if (period == 0xff)
+ return;
+
+ byte length = stream.readByte();
+
+ if (stream.err() || stream.eos())
+ error("Error loading song");
+
+ const uint kClock = 1022727; // Apple II CPU clock rate
+ const uint kLoopCycles = 20; // Delay loop cycles
+
+ double freq = 0.0;
+
+ // This computation ignores CPU cycles spent on overflow handling and
+ // speaker control. As a result, our tone frequencies will be slightly
+ // higher than those on original hardware.
+ if (period != 0)
+ freq = kClock / 2.0 / (period * kLoopCycles);
+
+ const double len = (length > 0 ? length - 1 : 255) * 256 * kLoopCycles * 1000 / (double)kClock;
+
+ _song.push_back(Tone(freq, len));
+ }
+}
+
int HiRes5Engine::o_checkItemTimeLimits(ScriptEnv &e) {
OP_DEBUG_1("\tCHECK_ITEM_TIME_LIMITS(VARS[%d])", e.arg(1));
@@ -191,7 +227,8 @@ int HiRes5Engine::o_startAnimation(ScriptEnv &e) {
int HiRes5Engine::o_winGame(ScriptEnv &e) {
OP_DEBUG_0("\tWIN_GAME()");
- // TODO: draws room and plays music
+ showRoom();
+ playTones(_song, true);
return o1_quit(e);
}
@@ -277,6 +314,9 @@ void HiRes5Engine::init() {
stream.reset(_disk->createReadStream(0x8, 0x7, 0x02));
_gameStrings.carryingTooMuch = readString(*stream);
+
+ stream.reset(_disk->createReadStream(0xc, 0xb, 0x20));
+ loadSong(*stream);
}
void HiRes5Engine::initGameState() {