1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM 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 #ifndef AGOS_MIDI_H
24 #define AGOS_MIDI_H
25 
26 #include "audio/mididrv.h"
27 #include "audio/midiparser.h"
28 #include "common/mutex.h"
29 
30 namespace Common {
31 class File;
32 }
33 
34 namespace AGOS {
35 
36 enum kMusicMode {
37 	kMusicModeDisabled = 0,
38 	kMusicModeAccolade = 1,
39 	kMusicModeMilesAudio = 2,
40 	kMusicModeSimon1 = 3,
41 	kMusicModePC98 = 4
42 };
43 
44 struct MusicInfo {
45 	MidiParser *parser;
46 	byte *data;
47 	byte num_songs;           // For Type 1 SMF resources
48 	byte *songs[16];          // For Type 1 SMF resources
49 	uint32 song_sizes[16];    // For Type 1 SMF resources
50 
51 	MidiChannel *channel[16]; // Dynamic remapping of channels to resolve conflicts
52 	byte volume[16];          // Current channel volume
53 
MusicInfoMusicInfo54 	MusicInfo() { clear(); }
clearMusicInfo55 	void clear() {
56 		parser = 0; data = 0; num_songs = 0;
57 		memset(songs, 0, sizeof(songs));
58 		memset(song_sizes, 0, sizeof(song_sizes));
59 		memset(channel, 0, sizeof(channel));
60 	}
61 };
62 
63 class MidiPlayer : public MidiDriver_BASE {
64 protected:
65 	Common::Mutex _mutex;
66 	MidiDriver *_driver;
67 	bool _map_mt32_to_gm;
68 	bool _nativeMT32;
69 
70 	MusicInfo _music;
71 	MusicInfo _sfx;
72 	MusicInfo *_current; // Allows us to establish current context for operations.
73 
74 	// These are maintained for both music and SFX
75 	byte _masterVolume;    // 0-255
76 	byte _musicVolume;
77 	byte _sfxVolume;
78 	bool _paused;
79 
80 	// These are only used for music.
81 	byte _currentTrack;
82 	bool _loopTrack;
83 	byte _queuedTrack;
84 	bool _loopQueuedTrack;
85 
86 protected:
87 	static void onTimer(void *data);
88 	void clearConstructs();
89 	void clearConstructs(MusicInfo &info);
90 	void resetVolumeTable();
91 
92 public:
93 	bool _adLibMusic;
94 	bool _enable_sfx;
95 
96 public:
97 	MidiPlayer();
98 	~MidiPlayer() override;
99 
100 	void loadSMF(Common::SeekableReadStream *in, int song, bool sfx = false);
101 	void loadMultipleSMF(Common::SeekableReadStream *in, bool sfx = false);
102 	void loadXMIDI(Common::SeekableReadStream *in, bool sfx = false);
103 	void loadS1D(Common::SeekableReadStream *in, bool sfx = false);
104 
hasNativeMT32()105 	bool hasNativeMT32() const { return _nativeMT32; }
106 	void setLoop(bool loop);
107 	void startTrack(int track);
108 	void queueTrack(int track, bool loop);
109 	bool isPlaying(bool check_queued = false) { return (_currentTrack != 255 && (_queuedTrack != 255 || !check_queued)); }
110 
111 	void stop();
112 	void pause(bool b);
113 
getMusicVolume()114 	int  getMusicVolume() const { return _musicVolume; }
getSFXVolume()115 	int  getSFXVolume() const { return _sfxVolume; }
116 	void setVolume(int musicVol, int sfxVol);
117 
118 public:
119 	int open(int gameType, Common::Platform platform, bool isDemo);
120 
121 	// MidiDriver_BASE interface implementation
122 	void send(uint32 b) override;
123 	void metaEvent(byte type, byte *data, uint16 length) override;
124 
125 private:
126 	kMusicMode _musicMode;
127 	MusicType musicType;
128 
129 private:
130 	Common::SeekableReadStream *simon2SetupExtractFile(const Common::String &requestedFileName);
131 };
132 
133 } // End of namespace AGOS
134 
135 #endif
136