1 /* ResidualVM - A 3D game interpreter
2  *
3  * ResidualVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "engines/grim/debug.h"
24 
25 #include "engines/grim/imuse/imuse.h"
26 #include "engines/grim/imuse/imuse_tables.h"
27 
28 namespace Grim {
29 
setMusicState(int stateId)30 void Imuse::setMusicState(int stateId) {
31 	int l, num = -1;
32 
33 	if (stateId == 0)
34 		stateId = 1000;
35 
36 	for (l = 0; _stateMusicTable[l].soundId != -1; l++) {
37 		if (_stateMusicTable[l].soundId == stateId) {
38 			num = l;
39 			break;
40 		}
41 	}
42 	assert(num != -1);
43 
44 	Debug::debug(Debug::Sound, "Imuse::setMusicState(): SoundId %d, filename: %s", _stateMusicTable[l].soundId, _stateMusicTable[l].filename);
45 
46 	if (_curMusicState == num)
47 		return;
48 
49 	if (!_curMusicSeq) {
50 		playMusic(&_stateMusicTable[num], num, false);
51 	}
52 
53 	_curMusicState = num;
54 }
55 
setMusicSequence(int seqId)56 int Imuse::setMusicSequence(int seqId) {
57 	int l, num = -1;
58 
59 	if (seqId == -1)
60 		return _seqMusicTable[_curMusicSeq].soundId;
61 
62 	if (seqId == 0)
63 		seqId = 2000;
64 
65 	for (l = 0; _seqMusicTable[l].soundId != -1; l++) {
66 		if (_seqMusicTable[l].soundId == seqId) {
67 			num = l;
68 			break;
69 		}
70 	}
71 
72 	assert(num != -1);
73 
74 	Debug::debug(Debug::Sound, "Imuse::setMusicSequence(): SoundId %d, filename: %s", _seqMusicTable[l].soundId, _seqMusicTable[l].filename);
75 
76 	if (_curMusicSeq == num)
77 		return _seqMusicTable[_curMusicSeq].soundId;
78 
79 	if (num) {
80 		playMusic(&_seqMusicTable[num], 0, true);
81 	} else {
82 		playMusic(&_stateMusicTable[_curMusicState], _curMusicState, true);
83 		num = 0;
84 	}
85 
86 	_curMusicSeq = num;
87 	return _seqMusicTable[_curMusicSeq].soundId;
88 }
89 
playMusic(const ImuseTable * table,int atribPos,bool sequence)90 void Imuse::playMusic(const ImuseTable *table, int atribPos, bool sequence) {
91 	int hookId = 0;
92 
93 	if (atribPos) {
94 		if (table->atribPos)
95 			atribPos = table->atribPos;
96 		hookId = _attributes[atribPos];
97 		if (table->hookId) {
98 			if (hookId && table->hookId > 1) {
99 				_attributes[atribPos] = 2;
100 			} else {
101 				_attributes[atribPos] = hookId + 1;
102 				if (table->hookId < hookId + 1)
103 					_attributes[atribPos] = 1;
104 			}
105 		}
106 	}
107 	if (hookId == 0)
108 		hookId = 100;
109 
110 	if (table->opcode == 0) {
111 		fadeOutMusic(120);
112 		return;
113 	}
114 
115 	if (table->opcode == 2 || table->opcode == 3) {
116 		if (table->filename[0] == 0) {
117 			fadeOutMusic(60);
118 			return;
119 		}
120 		char *soundName = getCurMusicSoundName();
121 		int pan;
122 
123 		if (table->pan == 0)
124 			pan = 64;
125 		else
126 			pan = table->pan;
127 		if (!soundName) {
128 			startMusic(table->filename, hookId, 0, pan);
129 			setVolume(table->filename, 0);
130 			setFadeVolume(table->filename, table->volume, table->fadeOut60TicksDelay);
131 			return;
132 		}
133 		int old_pan = getCurMusicPan();
134 		int old_vol = getCurMusicVol();
135 		if (old_pan == -1)
136 			old_pan = 64;
137 		if (old_vol == -1)
138 			old_vol = 127;
139 
140 		if (table->opcode == 2) {
141 			fadeOutMusic(table->fadeOut60TicksDelay);
142 			startMusic(table->filename, hookId, table->volume, pan);
143 			setVolume(table->filename, 0);
144 			setFadeVolume(table->filename, table->volume, table->fadeOut60TicksDelay);
145 			setFadePan(table->filename, pan, table->fadeOut60TicksDelay);
146 			return;
147 		}
148 		if (strcmp(soundName, table->filename) == 0) {
149 			setFadeVolume(soundName, table->volume, table->fadeOut60TicksDelay);
150 			setFadePan(soundName, pan, table->fadeOut60TicksDelay);
151 			return;
152 		}
153 
154 		if (!sequence && table->atribPos && table->atribPos == _stateMusicTable[_curMusicState].atribPos) {
155 			fadeOutMusicAndStartNew(table->fadeOut60TicksDelay, table->filename, hookId, old_vol, old_pan);
156 			setVolume(table->filename, 0);
157 			setFadeVolume(table->filename, table->volume, table->fadeOut60TicksDelay);
158 			setFadePan(table->filename, pan, table->fadeOut60TicksDelay);
159 		} else {
160 			fadeOutMusic(table->fadeOut60TicksDelay);
161 			startMusic(table->filename, hookId, table->volume, pan);
162 			setVolume(table->filename, 0);
163 			setFadeVolume(table->filename, table->volume, table->fadeOut60TicksDelay);
164 		}
165 	}
166 }
167 
168 } // end of namespace Grim
169