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 }