From 3c86aa288b532ddf9370fdcf33f144b43ffab5cc Mon Sep 17 00:00:00 2001
From: uruk
Date: Sat, 24 May 2014 10:47:07 +0200
Subject: CGE2: Implement snSound().

Rework the whole Fx class during the process.
The intro animation is working now.
---
 engines/cge2/cge2.h    |  2 +-
 engines/cge2/snail.cpp | 20 ++++++++++++--
 engines/cge2/sound.cpp | 74 +++++++++++++-------------------------------------
 engines/cge2/sound.h   | 13 +++------
 4 files changed, 41 insertions(+), 68 deletions(-)

diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 8e45ba3ba7..d40d417ae8 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -173,7 +173,7 @@ public:
 	void snLight(int val);
 	void snWalk(Sprite *spr, int val);
 	void snReach(Sprite *spr, int val);
-	void snSound(Sprite *spr, int val, int cnt);
+	void snSound(Sprite *spr, int wav);
 	void snRoom(Sprite *spr, int val);
 	void snGhost(Bitmap *bmp);
 
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index edbc78c7ad..3de42ddfc0 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -29,6 +29,7 @@
 #include "cge2/fileio.h"
 #include "cge2/hero.h"
 #include "cge2/text.h"
+#include "cge2/sound.h"
 
 namespace CGE2 {
 
@@ -284,7 +285,7 @@ void CommandHandler::runCommand() {
 			_vm->snReach(spr, tailCmd._val);
 			break;
 		case kCmdSound:
-			_vm->snSound(spr, tailCmd._val, _count);
+			_vm->snSound(spr, tailCmd._val);
 			_count = 1;
 			break;
 		case kCmdMap:
@@ -462,8 +463,21 @@ void CGE2Engine::snReach(Sprite *spr, int val) {
 	warning("STUB: CGE2Engine::snReach()");
 }
 
-void CGE2Engine::snSound(Sprite *spr, int val, int cnt) {
-	warning("STUB: CGE2Engine::snSound()");
+void CGE2Engine::snSound(Sprite *spr, int wav) {
+	if (wav == -1)
+		_sound->stop();
+	else {
+		if (_sound->_smpinf._counter && wav < 20)
+			return;
+		if (_commandStat._wait && ((wav & 255) > 80))
+			return;
+
+		_commandStat._ref[1] = wav;
+		_commandStat._ref[0] = !_fx->exist(_commandStat._ref[1]);
+		_sound->play(_fx->load(_commandStat._ref[1], _commandStat._ref[0]),
+			(spr) ? (spr->_pos2D.x / (kScrWidth / 16)) : 8);
+	}
+	
 }
 
 void CGE2Engine::snRoom(Sprite *spr, int val) {
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index a3e866f05f..9f5ec2bb6c 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -61,7 +61,8 @@ void Sound::close() {
 
 void Sound::open() {
 	setRepeat(1);
-	play((*_vm->_fx)[30000], 8);
+	warning("STUB: Sound::open()");
+	play(_vm->_fx->load(99, 99));
 }
 
 void Sound::setRepeat(int16 count) {
@@ -111,60 +112,37 @@ void Sound::sndDigiStop(SmpInfo *PSmpInfo) {
 }
 
 Fx::Fx(CGE2Engine *vm, int size) : _current(NULL), _vm(vm) {
-	_cache = new Handler[size];
-	for (_size = 0; _size < size; _size++) {
-		_cache[_size]._ref = 0;
-		_cache[_size]._wav = NULL;
-	}
 }
 
 Fx::~Fx() {
 	clear();
-	delete[] _cache;
 }
 
 void Fx::clear() {
-	for (Handler *p = _cache, *q = p + _size; p < q; p++) {
-		if (p->_ref) {
-			p->_ref = 0;
-			delete p->_wav;
-			p->_wav = NULL;
-		}
-	}
+	if (_current)
+		delete _current;
 	_current = NULL;
 }
 
-int Fx::find(int ref) {
-	int i = 0;
-	for (Handler *p = _cache, *q = p + _size; p < q; p++) {
-		if (p->_ref == ref)
-			break;
-		else
-			++i;
-	}
-	return i;
+Common::String Fx::name(int ref, int sub) {
+	char name[] = "%.2dfx%.2d.WAV\0";
+	char subn[] = "%.2dfx%.2d?.WAV\0";
+	char *p = (sub) ? subn : name;
+	Common::String filename = Common::String::format(p, ref >> 8, ref & 0xFF);
+	if (sub)
+		filename.setChar('@' + sub, 6);
+	return filename;
 }
 
-void Fx::name(int ref, int sub) {
-	warning("STUB:  Fx::name()");
+bool Fx::exist(int ref, int sub) {
+	return _vm->_resman->exist(name(ref, sub).c_str());
 }
 
-DataCk *Fx::load(int idx, int ref) {
-	char filename[12];
-	warning("TODO: Implement Fx::load() with the use of Fx::name() properly in paralell with Snail! It just won't work this way.");
-	sprintf(filename, "FX%05d.WAV", ref);
-
-	EncryptedStream file(_vm, filename);
-	DataCk *wav = loadWave(&file);
-	if (wav) {
-		Handler *p = &_cache[idx];
-		delete p->_wav;
-		p->_wav = wav;
-		p->_ref = ref;
-	} else {
-		warning("Unable to load %s", filename);
-	}
-	return wav;
+DataCk *Fx::load(int ref, int sub) {
+	Common::String filename = name(ref, sub);
+	EncryptedStream file(_vm, filename.c_str());
+	clear();
+	return (_current = loadWave(&file));
 }
 
 DataCk *Fx::loadWave(EncryptedStream *file) {
@@ -178,20 +156,6 @@ DataCk *Fx::loadWave(EncryptedStream *file) {
 	return new DataCk(data, file->size());
 }
 
-DataCk *Fx::operator[](int ref) {
-	int i;
-	if ((i = find(ref)) < _size)
-		_current = _cache[i]._wav;
-	else {
-		if ((i = find(0)) >= _size) {
-			clear();
-			i = 0;
-		}
-		_current = load(i, ref);
-	}
-	return _current;
-}
-
 MusicPlayer::MusicPlayer(CGE2Engine *vm) : _vm(vm) {
 	_data = NULL;
 	_isGM = false;
diff --git a/engines/cge2/sound.h b/engines/cge2/sound.h
index c488c3fbba..6fa2b2a553 100644
--- a/engines/cge2/sound.h
+++ b/engines/cge2/sound.h
@@ -72,7 +72,7 @@ public:
 	~Sound();
 	void open();
 	void close();
-	void play(DataCk *wav, int pan);
+	void play(DataCk *wav, int pan = 8);
 	int16 getRepeat();
 	void setRepeat(int16 count);
 	void stop();
@@ -88,23 +88,18 @@ private:
 
 class Fx {
 	CGE2Engine *_vm;
-	struct Handler {
-		int _ref;
-		DataCk *_wav;
-	} *_cache;
 	int _size;
 
-	DataCk *load(int idx, int ref);
 	DataCk *loadWave(EncryptedStream *file);
-	int find(int ref);
+	Common::String name(int ref, int sub);
 public:
 	DataCk *_current;
 
 	Fx(CGE2Engine *vm, int size);
 	~Fx();
 	void clear();
-	void name(int ref, int sub);
-	DataCk *operator[](int ref);
+	bool exist(int ref, int sub = 0);
+	DataCk *load(int ref, int sub = 0);
 };
 
 class MusicPlayer: public Audio::MidiPlayer {
-- 
cgit v1.2.3