|
359
|
1 /*
|
|
|
2 Adplug - Replayer for many OPL2/OPL3 audio file formats.
|
|
|
3 Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp@gmx.net>, et al.
|
|
|
4
|
|
|
5 This library is free software; you can redistribute it and/or
|
|
|
6 modify it under the terms of the GNU Lesser General Public
|
|
|
7 License as published by the Free Software Foundation; either
|
|
|
8 version 2.1 of the License, or (at your option) any later version.
|
|
|
9
|
|
|
10 This library is distributed in the hope that it will be useful,
|
|
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
13 Lesser General Public License for more details.
|
|
|
14
|
|
|
15 You should have received a copy of the GNU Lesser General Public
|
|
|
16 License along with this library; if not, write to the Free Software
|
|
|
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
18
|
|
|
19 mad.cpp - MAD loader by Riven the Mage <riven@ok.ru>
|
|
|
20 */
|
|
|
21
|
|
|
22 #include "mad.h"
|
|
|
23
|
|
|
24 /* -------- Public Methods -------------------------------- */
|
|
|
25
|
|
|
26 CPlayer *CmadLoader::factory(Copl *newopl)
|
|
|
27 {
|
|
|
28 return new CmadLoader(newopl);
|
|
|
29 }
|
|
|
30
|
|
|
31 bool CmadLoader::load(const std::string &filename, const CFileProvider &fp)
|
|
|
32 {
|
|
|
33 binistream *f = fp.open(filename); if(!f) return false;
|
|
|
34 const unsigned char conv_inst[10] = { 2,1,10,9,4,3,6,5,8,7 };
|
|
|
35 unsigned int i, j, k, t = 0;
|
|
|
36
|
|
|
37 // 'MAD+' - signed ?
|
|
|
38 char id[4]; f->readString(id, 4);
|
|
|
39 if (strncmp(id,"MAD+",4)) { fp.close(f); return false; }
|
|
|
40
|
|
|
41 // load instruments
|
|
|
42 for(i = 0; i < 9; i++) {
|
|
|
43 f->readString(instruments[i].name, 8);
|
|
|
44 for(j = 0; j < 12; j++) instruments[i].data[j] = f->readInt(1);
|
|
|
45 }
|
|
|
46
|
|
|
47 f->ignore(1);
|
|
|
48
|
|
|
49 // data for Protracker
|
|
|
50 length = f->readInt(1); nop = f->readInt(1); timer = f->readInt(1);
|
|
|
51
|
|
|
52 // init CmodPlayer
|
|
|
53 realloc_instruments(9);
|
|
|
54 realloc_order(length);
|
|
|
55 realloc_patterns(nop,32,9);
|
|
|
56 init_trackord();
|
|
|
57
|
|
|
58 // load tracks
|
|
|
59 for(i = 0; i < nop; i++)
|
|
|
60 for(k = 0; k < 32; k++)
|
|
|
61 for(j = 0; j < 9; j++) {
|
|
|
62 t = i * 9 + j;
|
|
|
63
|
|
|
64 // read event
|
|
|
65 unsigned char event = f->readInt(1);
|
|
|
66
|
|
|
67 // convert event
|
|
|
68 if (event < 0x61)
|
|
|
69 tracks[t][k].note = event;
|
|
|
70 if (event == 0xFF) // 0xFF: Release note
|
|
|
71 tracks[t][k].command = 8;
|
|
|
72 if (event == 0xFE) // 0xFE: Pattern Break
|
|
|
73 tracks[t][k].command = 13;
|
|
|
74 }
|
|
|
75
|
|
|
76 // load order
|
|
|
77 for(i = 0; i < length; i++) order[i] = f->readInt(1) - 1;
|
|
|
78
|
|
|
79 fp.close(f);
|
|
|
80
|
|
|
81 // convert instruments
|
|
|
82 for(i = 0; i < 9; i++)
|
|
|
83 for(j = 0; j < 10; j++)
|
|
|
84 inst[i].data[conv_inst[j]] = instruments[i].data[j];
|
|
|
85
|
|
|
86 // data for Protracker
|
|
|
87 restartpos = 0;
|
|
|
88 initspeed = 1;
|
|
|
89
|
|
|
90 rewind(0);
|
|
|
91 return true;
|
|
|
92 }
|
|
|
93
|
|
|
94 void CmadLoader::rewind(int subsong)
|
|
|
95 {
|
|
|
96 CmodPlayer::rewind(subsong);
|
|
|
97
|
|
|
98 // default instruments
|
|
|
99 for (int i=0;i<9;i++)
|
|
|
100 {
|
|
|
101 channel[i].inst = i;
|
|
|
102
|
|
|
103 channel[i].vol1 = 63 - (inst[i].data[10] & 63);
|
|
|
104 channel[i].vol2 = 63 - (inst[i].data[9] & 63);
|
|
|
105 }
|
|
|
106 }
|
|
|
107
|
|
|
108 float CmadLoader::getrefresh()
|
|
|
109 {
|
|
|
110 return (float)timer;
|
|
|
111 }
|
|
|
112
|
|
|
113 std::string CmadLoader::gettype()
|
|
|
114 {
|
|
|
115 return std::string("Mlat Adlib Tracker");
|
|
|
116 }
|
|
|
117
|
|
|
118 std::string CmadLoader::getinstrument(unsigned int n)
|
|
|
119 {
|
|
|
120 return std::string(instruments[n].name,8);
|
|
|
121 }
|
|
|
122
|
|
|
123 unsigned int CmadLoader::getinstruments()
|
|
|
124 {
|
|
|
125 return 9;
|
|
|
126 }
|