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 /**
24  * @file
25  * Sound decoder used in engines:
26  *  - gob
27  */
28 
29 #ifndef AUDIO_MODS_INFOGRAMES_H
30 #define AUDIO_MODS_INFOGRAMES_H
31 
32 #include "audio/mods/paula.h"
33 
34 namespace Common {
35 class SeekableReadStream;
36 }
37 
38 namespace Audio {
39 
40 /** A player for the Infogrames/RobHubbard2 format */
41 class Infogrames : public Paula {
42 public:
43 	class Instruments {
44 	public:
45 		Instruments();
Instruments(T ins)46 		template<typename T> Instruments(T ins) {
47 			init();
48 			bool result = load(ins);
49 			assert(result);
50 		}
51 		~Instruments();
52 
53 		bool load(Common::SeekableReadStream &ins);
54 		bool load(const char *ins);
55 		void unload();
56 
getCount()57 		uint8 getCount() const { return _count; }
58 
59 	protected:
60 		struct Sample {
61 			int8 *data;
62 			int8 *dataRepeat;
63 			uint32 length;
64 			uint32 lengthRepeat;
65 		} _samples[32];
66 
67 		uint8 _count;
68 		int8 *_sampleData;
69 
70 		void init();
71 
72 		friend class Infogrames;
73 	};
74 
75 	Infogrames(Instruments &ins, bool stereo = false, int rate = 44100,
76 			int interruptFreq = 0);
77 	~Infogrames();
78 
getInstruments()79 	Instruments *getInstruments() const { return _instruments; }
getRepeating()80 	bool getRepeating() const { return _repCount != 0; }
setRepeating(int32 repCount)81 	void setRepeating (int32 repCount) { _repCount = repCount; }
82 
83 	bool load(Common::SeekableReadStream &dum);
84 	bool load(const char *dum);
85 	void unload();
restart()86 	void restart() {
87 		if (_data) {
88 			// Use the mutex here to ensure we do not call init()
89 			// while data is being read by the mixer thread.
90 			_mutex.lock();
91 			init();
92 			startPlay();
93 			_mutex.unlock();
94 		}
95 	}
96 
97 protected:
98 	Instruments *_instruments;
99 
100 	static const uint8 tickCount[];
101 	static const uint16 periods[];
102 	byte *_data;
103 	int32 _repCount;
104 
105 	byte *_subSong;
106 	byte *_cmdBlocks;
107 	byte *_volSlideBlocks;
108 	byte *_periodSlideBlocks;
109 	uint8 _speedCounter;
110 	uint8 _speed;
111 
112 	uint16 _volume;
113 	int16 _period;
114 	uint8 _sample;
115 
116 	struct Slide {
117 		byte *data;
118 		int8 amount;
119 		uint8 dataOffset;
120 		int16 finetuneNeg;
121 		int16 finetunePos;
122 		uint8 curDelay1;
123 		uint8 curDelay2;
124 		uint8 flags; // 0: Apply finetune modifier, 2: Don't slide, 7: Continuous
125 	};
126 	struct Channel {
127 		byte *cmdBlockIndices;
128 		byte *cmdBlocks;
129 		byte *cmds;
130 		uint8 ticks;
131 		uint8 tickCount;
132 		Slide volSlide;
133 		Slide periodSlide;
134 		int16 period;
135 		int8 periodMod;
136 		uint8 flags; // 0: Need init, 5: Loop cmdBlocks, 6: Ignore channel
137 	} _chn[4];
138 
139 	void init();
140 	void reset();
141 	void getNextSample(Channel &chn);
142 	int16 tune(Slide &slide, int16 start) const;
143 	virtual void interrupt();
144 };
145 
146 } // End of namespace Audio
147 
148 #endif
149