Mercurial > audlegacy-plugins
comparison src/adplug/core/rat.cxx @ 955:4709ce4e209e trunk
[svn] Run indent -ts4 -nut -bli0 -cdw on this messy lot. Upstream is not consistent with whitespace anyway, no loss there.
author | chainsaw |
---|---|
date | Sat, 14 Apr 2007 15:23:50 -0700 |
parents | 3da1b8942b8b |
children |
comparison
equal
deleted
inserted
replaced
954:d7a6fd179cd2 | 955:4709ce4e209e |
---|---|
30 */ | 30 */ |
31 | 31 |
32 #include "rat.h" | 32 #include "rat.h" |
33 #include "debug.h" | 33 #include "debug.h" |
34 | 34 |
35 const unsigned char CxadratPlayer::rat_adlib_bases[18] = | 35 const unsigned char |
36 { | 36 CxadratPlayer::rat_adlib_bases[18] = { |
37 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12, | 37 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12, |
38 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15 | 38 0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15 |
39 }; | 39 }; |
40 | 40 |
41 const unsigned short CxadratPlayer::rat_notes[16] = | 41 const unsigned short |
42 { | 42 CxadratPlayer::rat_notes[16] = { |
43 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, | 43 0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, |
44 0x000, 0x000, 0x000, 0x000 // by riven | 44 0x287, |
45 0x000, 0x000, 0x000, 0x000 // by riven | |
45 }; | 46 }; |
46 | 47 |
47 CPlayer *CxadratPlayer::factory(Copl *newopl) | 48 CPlayer * |
48 { | 49 CxadratPlayer::factory (Copl * newopl) |
49 return new CxadratPlayer(newopl); | 50 { |
50 } | 51 return new CxadratPlayer (newopl); |
51 | 52 } |
52 bool CxadratPlayer::xadplayer_load() | 53 |
53 { | 54 bool |
54 if(xad.fmt != RAT) | 55 CxadratPlayer::xadplayer_load () |
56 { | |
57 if (xad.fmt != RAT) | |
55 return false; | 58 return false; |
56 | 59 |
57 // load header | 60 // load header |
58 memcpy(&rat.hdr, &tune[0], sizeof(rat_header)); | 61 memcpy (&rat.hdr, &tune[0], sizeof (rat_header)); |
59 | 62 |
60 // is 'RAT'-signed ? | 63 // is 'RAT'-signed ? |
61 if (strncmp(rat.hdr.id,"RAT",3)) | 64 if (strncmp (rat.hdr.id, "RAT", 3)) |
62 return false; | 65 return false; |
63 | 66 |
64 // is version 1.0 ? | 67 // is version 1.0 ? |
65 if (rat.hdr.version != 0x10) | 68 if (rat.hdr.version != 0x10) |
66 return false; | 69 return false; |
67 | 70 |
68 // load order | 71 // load order |
69 rat.order = &tune[0x40]; | 72 rat.order = &tune[0x40]; |
70 | 73 |
71 // load instruments | 74 // load instruments |
72 rat.inst = (rat_instrument *)&tune[0x140]; | 75 rat.inst = (rat_instrument *) & tune[0x140]; |
73 | 76 |
74 // load pattern data | 77 // load pattern data |
75 unsigned short patseg = (rat.hdr.patseg[1] << 8) + rat.hdr.patseg[0]; | 78 unsigned short patseg = (rat.hdr.patseg[1] << 8) + rat.hdr.patseg[0]; |
76 unsigned char *event_ptr = &tune[patseg << 4]; | 79 unsigned char *event_ptr = &tune[patseg << 4]; |
77 | 80 |
78 for(int i=0;i<rat.hdr.numpat;i++) | 81 for (int i = 0; i < rat.hdr.numpat; i++) |
79 for(int j=0;j<64;j++) | 82 for (int j = 0; j < 64; j++) |
80 for(int k=0;k<rat.hdr.numchan;k++) | 83 for (int k = 0; k < rat.hdr.numchan; k++) |
81 { | 84 { |
82 memcpy(&rat.tracks[i][j][k], event_ptr, sizeof(rat_event)); | 85 memcpy (&rat.tracks[i][j][k], event_ptr, sizeof (rat_event)); |
83 | 86 |
84 event_ptr += sizeof(rat_event); | 87 event_ptr += sizeof (rat_event); |
85 } | 88 } |
86 | 89 |
87 return true; | 90 return true; |
88 } | 91 } |
89 | 92 |
90 void CxadratPlayer::xadplayer_rewind(int subsong) | 93 void |
94 CxadratPlayer::xadplayer_rewind (int subsong) | |
91 { | 95 { |
92 int i; | 96 int i; |
93 | 97 |
94 rat.order_pos = rat.hdr.order_start; | 98 rat.order_pos = rat.hdr.order_start; |
95 rat.pattern_pos = 0; | 99 rat.pattern_pos = 0; |
96 rat.volume = rat.hdr.volume; | 100 rat.volume = rat.hdr.volume; |
97 | 101 |
98 plr.speed = rat.hdr.speed; | 102 plr.speed = rat.hdr.speed; |
99 | 103 |
100 // clear channel data | 104 // clear channel data |
101 memset(&rat.channel, 0, sizeof(rat.channel[0])*9); | 105 memset (&rat.channel, 0, sizeof (rat.channel[0]) * 9); |
102 | 106 |
103 // init OPL | 107 // init OPL |
104 opl_write(0x01, 0x20); | 108 opl_write (0x01, 0x20); |
105 opl_write(0x08, 0x00); | 109 opl_write (0x08, 0x00); |
106 opl_write(0xBD, 0x00); | 110 opl_write (0xBD, 0x00); |
107 | 111 |
108 // set default frequencies | 112 // set default frequencies |
109 for(i=0;i<9;i++) | 113 for (i = 0; i < 9; i++) |
110 { | 114 { |
111 opl_write(0xA0+i, 0x00); | 115 opl_write (0xA0 + i, 0x00); |
112 opl_write(0xA3+i, 0x00); | 116 opl_write (0xA3 + i, 0x00); |
113 opl_write(0xB0+i, 0x00); | 117 opl_write (0xB0 + i, 0x00); |
114 opl_write(0xB3+i, 0x00); | 118 opl_write (0xB3 + i, 0x00); |
115 } | 119 } |
116 | 120 |
117 // set default volumes | 121 // set default volumes |
118 for(i=0;i<0x1F;i++) | 122 for (i = 0; i < 0x1F; i++) |
119 opl_write(0x40+i, 0x3F); | 123 opl_write (0x40 + i, 0x3F); |
120 } | 124 } |
121 | 125 |
122 void CxadratPlayer::xadplayer_update() | 126 void |
127 CxadratPlayer::xadplayer_update () | |
123 { | 128 { |
124 int i; | 129 int i; |
125 | 130 |
126 rat_event event; | 131 rat_event event; |
127 | 132 |
128 // process events | 133 // process events |
129 for(i=0;i<rat.hdr.numchan;i++) | 134 for (i = 0; i < rat.hdr.numchan; i++) |
130 { | 135 { |
131 memcpy(&event,&rat.tracks[rat.order[rat.order_pos]][rat.pattern_pos][i],sizeof(rat_event)); | 136 memcpy (&event, &rat.tracks[rat.order[rat.order_pos]][rat.pattern_pos][i], |
137 sizeof (rat_event)); | |
132 #ifdef DEBUG | 138 #ifdef DEBUG |
133 AdPlug_LogWrite("order %02X, pattern %02X, row %02X, channel %02X, event %02X %02X %02X %02X %02X:\n", | 139 AdPlug_LogWrite |
134 rat.order_pos, rat.order[rat.order_pos], rat.pattern_pos, i, event.note, event.instrument, event.volume, event.fx, event.fxp | 140 ("order %02X, pattern %02X, row %02X, channel %02X, event %02X %02X %02X %02X %02X:\n", |
135 ); | 141 rat.order_pos, rat.order[rat.order_pos], rat.pattern_pos, i, |
142 event.note, event.instrument, event.volume, event.fx, event.fxp); | |
136 #endif | 143 #endif |
137 | 144 |
138 // is instrument ? | 145 // is instrument ? |
139 if (event.instrument != 0xFF) | 146 if (event.instrument != 0xFF) |
140 { | 147 { |
148 | 155 |
149 // is note ? | 156 // is note ? |
150 if (event.note != 0xFF) | 157 if (event.note != 0xFF) |
151 { | 158 { |
152 // mute channel | 159 // mute channel |
153 opl_write(0xB0+i, 0x00); | 160 opl_write (0xB0 + i, 0x00); |
154 opl_write(0xA0+i, 0x00); | 161 opl_write (0xA0 + i, 0x00); |
155 | 162 |
156 // if note != 0xFE then play | 163 // if note != 0xFE then play |
157 if (event.note != 0xFE) | 164 if (event.note != 0xFE) |
158 { | 165 { |
159 unsigned char ins = rat.channel[i].instrument; | 166 unsigned char ins = rat.channel[i].instrument; |
160 | 167 |
161 // synthesis/feedback | 168 // synthesis/feedback |
162 opl_write(0xC0+i, rat.inst[ins].connect); | 169 opl_write (0xC0 + i, rat.inst[ins].connect); |
163 | 170 |
164 // controls | 171 // controls |
165 opl_write(0x20+rat_adlib_bases[i], rat.inst[ins].mod_ctrl); | 172 opl_write (0x20 + rat_adlib_bases[i], rat.inst[ins].mod_ctrl); |
166 opl_write(0x20+rat_adlib_bases[i+9], rat.inst[ins].car_ctrl); | 173 opl_write (0x20 + rat_adlib_bases[i + 9], rat.inst[ins].car_ctrl); |
167 | 174 |
168 // volumes | 175 // volumes |
169 opl_write(0x40+rat_adlib_bases[i], __rat_calc_volume(rat.inst[ins].mod_volume,rat.channel[i].volume,rat.volume)); | 176 opl_write (0x40 + rat_adlib_bases[i], |
170 opl_write(0x40+rat_adlib_bases[i+9], __rat_calc_volume(rat.inst[ins].car_volume,rat.channel[i].volume,rat.volume)); | 177 __rat_calc_volume (rat.inst[ins].mod_volume, |
178 rat.channel[i].volume, rat.volume)); | |
179 opl_write (0x40 + rat_adlib_bases[i + 9], | |
180 __rat_calc_volume (rat.inst[ins].car_volume, | |
181 rat.channel[i].volume, rat.volume)); | |
171 | 182 |
172 // attack/decay | 183 // attack/decay |
173 opl_write(0x60+rat_adlib_bases[i], rat.inst[ins].mod_AD); | 184 opl_write (0x60 + rat_adlib_bases[i], rat.inst[ins].mod_AD); |
174 opl_write(0x60+rat_adlib_bases[i+9], rat.inst[ins].car_AD); | 185 opl_write (0x60 + rat_adlib_bases[i + 9], rat.inst[ins].car_AD); |
175 | 186 |
176 // sustain/release | 187 // sustain/release |
177 opl_write(0x80+rat_adlib_bases[i], rat.inst[ins].mod_SR); | 188 opl_write (0x80 + rat_adlib_bases[i], rat.inst[ins].mod_SR); |
178 opl_write(0x80+rat_adlib_bases[i+9], rat.inst[ins].car_SR); | 189 opl_write (0x80 + rat_adlib_bases[i + 9], rat.inst[ins].car_SR); |
179 | 190 |
180 // waveforms | 191 // waveforms |
181 opl_write(0xE0+rat_adlib_bases[i], rat.inst[ins].mod_wave); | 192 opl_write (0xE0 + rat_adlib_bases[i], rat.inst[ins].mod_wave); |
182 opl_write(0xE0+rat_adlib_bases[i+9], rat.inst[ins].car_wave); | 193 opl_write (0xE0 + rat_adlib_bases[i + 9], rat.inst[ins].car_wave); |
183 | 194 |
184 // octave/frequency | 195 // octave/frequency |
185 unsigned short insfreq = (rat.inst[ins].freq[1] << 8) + rat.inst[ins].freq[0]; | 196 unsigned short insfreq = |
197 (rat.inst[ins].freq[1] << 8) + rat.inst[ins].freq[0]; | |
186 unsigned short freq = insfreq * rat_notes[event.note & 0x0F] / 0x20AB; | 198 unsigned short freq = insfreq * rat_notes[event.note & 0x0F] / 0x20AB; |
187 | 199 |
188 opl_write(0xA0+i, freq & 0xFF); | 200 opl_write (0xA0 + i, freq & 0xFF); |
189 opl_write(0xB0+i, (freq >> 8) | ((event.note & 0xF0) >> 2) | 0x20); | 201 opl_write (0xB0 + i, (freq >> 8) | ((event.note & 0xF0) >> 2) | 0x20); |
190 } | 202 } |
191 } | 203 } |
192 | 204 |
193 // is effect ? | 205 // is effect ? |
194 if (event.fx != 0xFF) | 206 if (event.fx != 0xFF) |
200 | 212 |
201 // next row | 213 // next row |
202 rat.pattern_pos++; | 214 rat.pattern_pos++; |
203 | 215 |
204 // process effects | 216 // process effects |
205 for(i=0;i<rat.hdr.numchan;i++) | 217 for (i = 0; i < rat.hdr.numchan; i++) |
206 { | 218 { |
207 unsigned char old_order_pos = rat.order_pos; | 219 unsigned char old_order_pos = rat.order_pos; |
208 | 220 |
209 switch (rat.channel[i].fx) | 221 switch (rat.channel[i].fx) |
210 { | 222 { |
211 case 0x01: // 0x01: Set Speed | 223 case 0x01: // 0x01: Set Speed |
212 plr.speed = rat.channel[i].fxp; | 224 plr.speed = rat.channel[i].fxp; |
213 break; | 225 break; |
214 case 0x02: // 0x02: Position Jump | 226 case 0x02: // 0x02: Position Jump |
215 if (rat.channel[i].fxp < rat.hdr.order_end) | 227 if (rat.channel[i].fxp < rat.hdr.order_end) |
216 rat.order_pos = rat.channel[i].fxp; | 228 rat.order_pos = rat.channel[i].fxp; |
217 else | 229 else |
218 rat.order_pos = 0; | 230 rat.order_pos = 0; |
219 | 231 |
220 // jumpback ? | 232 // jumpback ? |
221 if (rat.order_pos <= old_order_pos) | 233 if (rat.order_pos <= old_order_pos) |
222 plr.looping = 1; | 234 plr.looping = 1; |
223 | 235 |
224 rat.pattern_pos = 0; | 236 rat.pattern_pos = 0; |
225 break; | 237 break; |
226 case 0x03: // 0x03: Pattern Break (?) | 238 case 0x03: // 0x03: Pattern Break (?) |
227 rat.pattern_pos = 0x40; | 239 rat.pattern_pos = 0x40; |
228 break; | 240 break; |
229 } | 241 } |
230 | 242 |
231 rat.channel[i].fx = 0; | 243 rat.channel[i].fx = 0; |
232 } | 244 } |
233 | 245 |
246 plr.looping = 1; | 258 plr.looping = 1; |
247 } | 259 } |
248 } | 260 } |
249 } | 261 } |
250 | 262 |
251 float CxadratPlayer::xadplayer_getrefresh() | 263 float |
264 CxadratPlayer::xadplayer_getrefresh () | |
252 { | 265 { |
253 return 60.0f; | 266 return 60.0f; |
254 } | 267 } |
255 | 268 |
256 std::string CxadratPlayer::xadplayer_gettype() | 269 std::string CxadratPlayer::xadplayer_gettype () |
257 { | 270 { |
258 return (std::string("xad: rat player")); | 271 return (std::string ("xad: rat player")); |
259 } | 272 } |
260 | 273 |
261 std::string CxadratPlayer::xadplayer_gettitle() | 274 std::string CxadratPlayer::xadplayer_gettitle () |
262 { | 275 { |
263 return (std::string(rat.hdr.title,32)); | 276 return (std::string (rat.hdr.title, 32)); |
264 } | 277 } |
265 | 278 |
266 unsigned int CxadratPlayer::xadplayer_getinstruments() | 279 unsigned int |
280 CxadratPlayer::xadplayer_getinstruments () | |
267 { | 281 { |
268 return rat.hdr.numinst; | 282 return rat.hdr.numinst; |
269 } | 283 } |
270 | 284 |
271 /* -------- Internal Functions ---------------------------- */ | 285 /* -------- Internal Functions ---------------------------- */ |
272 | 286 |
273 unsigned char CxadratPlayer::__rat_calc_volume(unsigned char ivol, unsigned char cvol, unsigned char gvol) | 287 unsigned char |
288 CxadratPlayer::__rat_calc_volume (unsigned char ivol, unsigned char cvol, | |
289 unsigned char gvol) | |
274 { | 290 { |
275 #ifdef DEBUG | 291 #ifdef DEBUG |
276 AdPlug_LogWrite("volumes: instrument %02X, channel %02X, global %02X:\n", ivol, cvol, gvol); | 292 AdPlug_LogWrite ("volumes: instrument %02X, channel %02X, global %02X:\n", |
293 ivol, cvol, gvol); | |
277 #endif | 294 #endif |
278 unsigned short vol; | 295 unsigned short vol; |
279 | 296 |
280 vol = ivol; | 297 vol = ivol; |
281 vol &= 0x3F; | 298 vol &= 0x3F; |
282 vol ^= 0x3F; | 299 vol ^= 0x3F; |
283 vol *= cvol; | 300 vol *= cvol; |
284 vol >>= 6; | 301 vol >>= 6; |
285 vol *= gvol; | 302 vol *= gvol; |
286 vol >>= 6; | 303 vol >>= 6; |
287 vol ^= 0x3F; | 304 vol ^= 0x3F; |
288 | 305 |
289 vol |= ivol & 0xC0; | 306 vol |= ivol & 0xC0; |
290 | 307 |
291 return vol; | 308 return vol; |
292 } | 309 } |