Holder: Use Holder for SoundMgr.
[gemrb.git] / gemrb / plugins / MUSImporter / MUSImporter.cpp
blob60ffda334c425b25f6a6fd710dcbab6a0c9509c8
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "win32def.h"
22 #include "MUSImporter.h"
23 #include "Interface.h"
24 #include "Audio.h"
25 #include "SoundMgr.h"
26 #include "GameData.h" // For ResourceHolder
28 static char musicsubfolder[6] = "music";
30 MUSImporter::MUSImporter()
32 Initialized = false;
33 Playing = false;
34 str = new FileStream();
35 PLpos = 0;
36 PLName[0] = '\0';
37 lastSound = 0xffffffff;
38 char path[_MAX_PATH];
39 PathJoin(path, core->GamePath, musicsubfolder, NULL);
40 manager.AddSource(path, "Music", PLUGIN_RESOURCE_DIRECTORY);
43 MUSImporter::~MUSImporter()
45 if (str) {
46 delete( str );
49 /** Initializes the PlayList Manager */
50 bool MUSImporter::Init()
52 Initialized = true;
53 return true;
55 /** Loads a PlayList for playing */
56 bool MUSImporter::OpenPlaylist(const char* name)
58 if (PLName[0] != '\0') {
59 int len = ( int ) strlen( PLName );
60 if (strnicmp( name, PLName, len ) == 0)
61 return true;
63 if (Playing) {
64 return false;
66 core->GetAudioDrv()->ResetMusics();
67 playlist.clear();
68 PLpos = 0;
69 if (name[0] == '*') {
70 return false;
72 char path[_MAX_PATH];
73 PathJoin(path, core->GamePath, musicsubfolder, name, NULL);
74 printMessage("MUSImporter", "", WHITE);
75 printf( "Loading %s...", path );
76 if (!str->Open( path, true )) {
77 printStatus("NOT FOUND", LIGHT_RED );
78 return false;
80 printStatus("FOUND", LIGHT_GREEN );
81 int c = str->ReadLine( PLName, 32 );
82 while (c > 0) {
83 if (( PLName[c - 1] == ' ' ) || ( PLName[c - 1] == '\t' ))
84 PLName[c - 1] = 0;
85 else
86 break;
87 c--;
89 char counts[5];
90 str->ReadLine( counts, 5 );
91 int count = atoi( counts );
92 while (count != 0) {
93 char line[64];
94 int len = str->ReadLine( line, 64 );
95 int i = 0;
96 int p = 0;
97 PLString pls;
98 while (i < len) {
99 if (( line[i] != ' ' ) && ( line[i] != '\t' ))
100 pls.PLFile[p++] = line[i++];
101 else {
102 while (i < len) {
103 if (( line[i] == ' ' ) || ( line[i] == '\t' ))
104 i++;
105 else
106 break;
108 break;
111 pls.PLFile[p] = 0;
112 p = 0;
113 if (line[i] != '@' && ( i < len )) {
114 while (i < len) {
115 if (( line[i] != ' ' ) && ( line[i] != '\t' ))
116 pls.PLTag[p++] = line[i++];
117 else
118 break;
120 pls.PLTag[p] = 0;
121 p = 0;
122 while (i < len) {
123 if (( line[i] == ' ' ) || ( line[i] == '\t' ))
124 i++;
125 else {
126 break;
129 if (line[i] == '@')
130 strcpy( pls.PLLoop, pls.PLTag );
131 else {
132 while (i < len) {
133 if (( line[i] != ' ' ) && ( line[i] != '\t' ))
134 pls.PLLoop[p++] = line[i++];
135 else
136 break;
138 pls.PLLoop[p] = 0;
140 while (i < len) {
141 if (( line[i] == ' ' ) || ( line[i] == '\t' ))
142 i++;
143 else
144 break;
146 p = 0;
147 } else {
148 pls.PLTag[0] = 0;
149 pls.PLLoop[0] = 0;
151 while (i < len) {
152 if (( line[i] != ' ' ) && ( line[i] != '\t' ))
153 i++;
154 else {
155 while (i < len) {
156 if (( line[i] == ' ' ) || ( line[i] == '\t' ))
157 i++;
158 else
159 break;
161 break;
164 while (i < len) {
165 if (( line[i] != ' ' ) && ( line[i] != '\t' ))
166 pls.PLEnd[p++] = line[i++];
167 else
168 break;
170 pls.PLEnd[p] = 0;
171 playlist.push_back( pls );
172 count--;
174 return true;
176 /** Start the PlayList Music Execution */
177 void MUSImporter::Start()
179 if (!Playing) {
180 PLpos = 0;
181 if (playlist.size() == 0)
182 return;
183 if (playlist[PLpos].PLLoop[0] != 0) {
184 for (unsigned int i = 0; i < playlist.size(); i++) {
185 if (stricmp( playlist[i].PLFile, playlist[PLpos].PLLoop ) == 0) {
186 PLnext = i;
187 break;
190 } else {
191 PLnext = PLpos + 1;
192 if ((unsigned int) PLnext >= playlist.size())
193 PLnext = -1;
195 PlayMusic( PLpos );
196 core->GetAudioDrv()->Play();
197 lastSound = playlist[PLpos].soundID;
198 Playing = true;
201 /** Ends the Current PlayList Execution */
202 void MUSImporter::End()
204 if (Playing) {
205 if (playlist.size() == 0)
206 return;
207 if (playlist[PLpos].PLEnd[0] != 0) {
208 if (stricmp( playlist[PLpos].PLEnd, "end" ) != 0)
209 PlayMusic( playlist[PLpos].PLEnd );
211 PLnext = -1;
215 void MUSImporter::HardEnd()
217 core->GetAudioDrv()->Stop();
218 Playing = false;
219 PLpos = 0;
222 /** Switches the current PlayList while playing the current one, return nonzero on error */
223 int MUSImporter::SwitchPlayList(const char* name, bool Hard)
225 //don't do anything if the requested song is already playing
226 //this fixed PST's infinite song start
227 if (Playing) {
228 int len = ( int ) strlen( PLName );
229 if (strnicmp( name, PLName, len ) == 0)
230 return 0;
231 if (Hard) {
232 HardEnd();
233 } else {
234 End();
237 if (OpenPlaylist( name )) {
238 Start();
239 return 0;
241 return -1;
243 /** Plays the Next Entry */
244 void MUSImporter::PlayNext()
246 if (!Playing) {
247 return;
249 if (PLnext != -1) {
250 PlayMusic( PLnext );
251 PLpos = PLnext;
252 if (playlist[PLpos].PLLoop[0] != 0) {
253 for (unsigned int i = 0; i < playlist.size(); i++) {
254 if (stricmp( playlist[i].PLFile, playlist[PLpos].PLLoop ) == 0) {
255 PLnext = i;
256 break;
259 } else {
260 if (stricmp( playlist[PLnext].PLEnd, "end" ) == 0)
261 PLnext = -1;
262 else
263 PLnext = PLpos + 1;
264 if ((unsigned int) PLnext >= playlist.size() ) {
265 PLnext = 0;
268 } else {
269 Playing = false;
270 core->GetAudioDrv()->Stop();
274 void MUSImporter::PlayMusic(int pos)
276 PlayMusic( playlist[pos].PLFile );
279 void MUSImporter::PlayMusic(char* name)
281 char FName[_MAX_PATH];
282 if (strnicmp( name, "mx9000", 6 ) == 0) { //iwd2
283 PathJoin(FName, "mx9000", name, NULL);
284 } else if (strnicmp( name, "mx0000", 6 ) == 0) { //iwd
285 PathJoin(FName, "mx0000", name, NULL);
286 } else if (strnicmp( name, "SPC", 3 ) != 0) { //bg2
287 char File[_MAX_PATH];
288 snprintf(File, _MAX_PATH, "%s%s", PLName, name);
289 PathJoin(FName, PLName, File, NULL);
290 } else {
291 strncpy(FName, name, _MAX_PATH);
294 ResourceHolder<SoundMgr> sound(FName, manager);
295 if (sound) {
296 int soundID = core->GetAudioDrv()->CreateStream( sound );
297 if (soundID == -1) {
298 core->GetAudioDrv()->Stop();
300 } else {
301 core->GetAudioDrv()->Stop();
303 printf( "Playing: %s\n", FName );
306 bool MUSImporter::CurrentPlayList(const char* name) {
307 int len = ( int ) strlen( PLName );
308 if (strnicmp( name, PLName, len ) == 0) return true;
309 return false;
313 #include "plugindef.h"
315 GEMRB_PLUGIN(0x2DCB9E8, "MUS File Importer")
316 PLUGIN_CLASS(IE_MUS_CLASS_ID, MUSImporter)
317 END_PLUGIN()