comparison Plugins/Input/adplug/core/rix.cpp @ 1280:6ad7eb96dd26 trunk

[svn] Sync with upstream. This adds Westwood ADL format support.
author chainsaw
date Sat, 17 Jun 2006 16:17:51 -0700
parents 1cd8716972df
children c71e2ef2dcf4
comparison
equal deleted inserted replaced
1279:01d2aa561b53 1280:6ad7eb96dd26
19 * rix.cpp - Softstar RIX OPL Format Player by palxex <palxex.ys168.com> 19 * rix.cpp - Softstar RIX OPL Format Player by palxex <palxex.ys168.com>
20 * BSPAL <BSPAL.ys168.com> 20 * BSPAL <BSPAL.ys168.com>
21 */ 21 */
22 22
23 #include "rix.h" 23 #include "rix.h"
24 #include <binfile.h> 24 #include "debug.h"
25 25
26 const unsigned char CrixPlayer::adflag[] = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1}; 26 const unsigned char CrixPlayer::adflag[] = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1};
27 const unsigned char CrixPlayer::reg_data[] = {0,1,2,3,4,5,8,9,10,11,12,13,16,17,18,19,20,21}; 27 const unsigned char CrixPlayer::reg_data[] = {0,1,2,3,4,5,8,9,10,11,12,13,16,17,18,19,20,21};
28 const unsigned char CrixPlayer::ad_C0_offs[] = {0,1,2,0,1,2,3,4,5,3,4,5,6,7,8,6,7,8}; 28 const unsigned char CrixPlayer::ad_C0_offs[] = {0,1,2,0,1,2,3,4,5,3,4,5,6,7,8,6,7,8};
29 const unsigned char CrixPlayer::modify[] = {0,3,1,4,2,5,6,9,7,10,8,11,12,15,13,16,14,17,12,\ 29 const unsigned char CrixPlayer::modify[] = {0,3,1,4,2,5,6,9,7,10,8,11,12,15,13,16,14,17,12,\
51 { 51 {
52 return new CrixPlayer(newopl); 52 return new CrixPlayer(newopl);
53 } 53 }
54 54
55 CrixPlayer::CrixPlayer(Copl *newopl) 55 CrixPlayer::CrixPlayer(Copl *newopl)
56 : CPlayer(newopl),I(0),T(0),mus_block(0),ins_block(0),rhythm(0),mutex(0), 56 : CPlayer(newopl), buf_addr(0)
57 music_on(0),pause_flag(0),band(0),band_low(0),e0_reg_flag(0),bd_modify(0), 57 {
58 sustain(0),dro_end(0), mstotal(0), opl3_mode(0) 58 }
59 { 59
60 memset(dro, 0, 128000); 60 CrixPlayer::~CrixPlayer()
61 memset(buf_addr, 0, 327680); 61 {
62 if(buf_addr)
63 delete [] buf_addr;
64 }
65
66 bool CrixPlayer::load(const std::string &filename, const CFileProvider &fp)
67 {
68 binistream *f = fp.open(filename); if(!f) return false;
69 unsigned long i=0;
70
71 if(f->readInt(2)!=0x55aa) { fp.close(f);return false; }
72 buf_addr = new unsigned char [fp.filesize(f) + 1];
73 buf_addr[i++]=0xaa;buf_addr[i++]=0x55;
74 while(!f->eof())
75 buf_addr[i++]=f->readInt(1);
76 length=i;
77 fp.close(f);
78
79 rewind(0);
80 return true;
81 }
82
83 bool CrixPlayer::update()
84 {
85 if (delay>100) {
86 delay-=100;
87 return true;
88 } else delay=1;
89
90 int_08h_entry();
91 return !dro_end;
92 }
93
94 void CrixPlayer::rewind(int subsong)
95 {
96 I = 0; T = 0;
97 mus_block = 0;
98 ins_block = 0;
99 rhythm = 0;
100 mutex = 0;
101 music_on = 0;
102 pause_flag = 0;
103 band = 0;
104 band_low = 0;
105 e0_reg_flag = 0;
106 bd_modify = 0;
107 delay = 1;
108 sustain = 0;
109 dro_end = 0;
110 pos = index = 0;
111
62 memset(buffer, 0, sizeof(unsigned short) * 300); 112 memset(buffer, 0, sizeof(unsigned short) * 300);
63 memset(a0b0_data2, 0, sizeof(unsigned short) * 11); 113 memset(a0b0_data2, 0, sizeof(unsigned short) * 11);
64 memset(a0b0_data3, 0, 18); 114 memset(a0b0_data3, 0, 18);
65 memset(a0b0_data4, 0, 18); 115 memset(a0b0_data4, 0, 18);
66 memset(a0b0_data5, 0, 96); 116 memset(a0b0_data5, 0, 96);
67 memset(addrs_head, 0, 96); 117 memset(addrs_head, 0, 96);
68 memset(insbuf, 0, 28 * sizeof(unsigned short)); 118 memset(insbuf, 0, 28 * sizeof(unsigned short));
69 memset(displace, 0, 11 * sizeof(unsigned short)); 119 memset(displace, 0, 11 * sizeof(unsigned short));
70 memset(reg_bufs, 0, 18 * sizeof(ADDT)); 120 memset(reg_bufs, 0, 18 * sizeof(ADDT));
71 memset(for40reg, 0, 18); 121
72 122 opl->init();
73 if(opl->gettype() == Copl::TYPE_OPL2) 123 opl->write(1,32); // go to OPL2 mode
74 opl3_mode = 0;
75 else
76 opl3_mode = 1;
77 };
78
79 bool CrixPlayer::load(const std::string &filename, const CFileProvider &fp)
80 {
81 binistream *f = fp.open(filename); if(!f) return false;
82 unsigned long i=0;
83
84 if(f->readInt(2)!=0x55aa) {fp.close(f);return false; }
85 buf_addr[i++]=0xaa;buf_addr[i++]=0x55;
86 while(!f->eof())
87 buf_addr[i++]=f->readInt(1);
88 length=i;
89 fp.close(f);
90 set_new_int(); 124 set_new_int();
91 data_initial(); 125 data_initial();
92 while(!dro_end)
93 int_08h_entry();
94
95 length=T;
96 mode = (OplMode)1; // Type of opl data this can contain
97
98 // binofstream *g=new binofstream(filename+string(".dro"));
99 // g->writeString("DBRAWOPL",8);
100 // g->writeInt(mstotal,4);
101 // g->writeInt(length+1,4);
102 // g->writeInt(1,1);
103 // for(int t=0;t<length;t++)
104 // g->writeInt(dro[t],1);
105 // g->close();
106 // delete g;
107
108 rewind(0);
109 return true;
110 }
111
112 bool CrixPlayer::update()
113 {
114 if (delay>500) {
115 delay-=500;
116 return true;
117 } else delay=1;
118 while (pos < length)
119 {
120 unsigned char cmd = dro[pos++];
121 switch(cmd) {
122 case 0:
123 delay = 1 + dro[pos++];
124 return true;
125 case 1:
126 delay = 1 + dro[pos] + (dro[pos+1]<<8);
127 pos+=2;
128 return true;
129 case 2:
130 index = 0;
131 opl->setchip(0);
132 break;
133 case 3:
134 index = 1;
135 opl->setchip(1);
136 break;
137 default:
138 if(index == 0 || opl3_mode)
139 opl->write(cmd,dro[pos++]);
140 break;
141 }
142 }
143 return pos<length;
144 }
145
146 void CrixPlayer::rewind(int subsong)
147 {
148 delay=1;
149 pos = index = 0;
150 opl->init();
151 opl->write(1,32); // go to OPL2 mode
152 } 126 }
153 127
154 float CrixPlayer::getrefresh() 128 float CrixPlayer::getrefresh()
155 { 129 {
156 if (delay > 500) return 1000 / 500; 130 if (delay > 100) return 1000 / 100;
157 else return 1000 / (double)delay; 131 else return 1000.0 / (double)delay;
158 } 132 }
159 133
160 /*------------------Implemention----------------------------*/ 134 /*------------------Implemention----------------------------*/
161 inline void CrixPlayer::set_new_int() 135 inline void CrixPlayer::set_new_int()
162 { 136 {
237 mutex = 0; 211 mutex = 0;
238 } 212 }
239 /*----------------------------------------------------------*/ 213 /*----------------------------------------------------------*/
240 inline void CrixPlayer::ad_bop(unsigned short reg,unsigned short value) 214 inline void CrixPlayer::ad_bop(unsigned short reg,unsigned short value)
241 { 215 {
242 dro[T++]=reg;dro[T++]=value; 216 if(reg == 2 || reg == 3)
217 AdPlug_LogWrite("switch OPL2/3 mode!\n");
218 opl->write(reg & 0xff, value & 0xff);
243 } 219 }
244 /*------------------------------------------------------*/ 220 /*------------------------------------------------------*/
245 inline unsigned short CrixPlayer::ad_test() /* Test the SoundCard */ 221 inline unsigned short CrixPlayer::ad_test() /* Test the SoundCard */
246 { 222 {
247 ad_bop(0x04,0x60); 223 ad_bop(0x04,0x60);
252 ad_bop(0x04,0x80); 228 ad_bop(0x04,0x80);
253 return 1; 229 return 1;
254 } 230 }
255 /*--------------------------------------------------------------*/ 231 /*--------------------------------------------------------------*/
256 inline void CrixPlayer::int_08h_entry() 232 inline void CrixPlayer::int_08h_entry()
257 { 233 {
258 unsigned short band_sus = 1; 234 unsigned short band_sus = 1;
259 while(band_sus) 235 while(band_sus)
260 { 236 {
261 if(sustain <= 0 && mutex == 0) 237 if(sustain <= 0 && mutex == 0)
262 { 238 {
263 mutex++; 239 mutex++;
264 band_sus = rix_proc(); 240 band_sus = rix_proc();
265 if(band_sus) sustain += band_sus; 241 if(band_sus) sustain += band_sus;
266 mstotal+=sustain; 242 delay=sustain;
267 dro[T++]=(sustain>=0x100?1:0);
268 dro[T++]=sustain&0xff;
269 if(sustain>=0x100)
270 dro[T++]=(sustain>>8)&0xff;
271 mutex--; 243 mutex--;
272 if(band_sus == 0) 244 if(band_sus == 0)
273 { 245 {
274 dro_end=1; 246 dro_end=1;
275 break; 247 break;
276 } 248 }
277 } 249 }
278 else 250 else
279 { 251 {
280 if(band_sus) sustain -= 1; /* aging */ 252 if(band_sus) sustain -= 9; /* aging */
281 break; 253 break;
282 } 254 }
283 } 255 }
284 } 256 }
285 /*--------------------------------------------------------------*/ 257 /*--------------------------------------------------------------*/
286 inline unsigned short CrixPlayer::rix_proc() 258 inline unsigned short CrixPlayer::rix_proc()
287 { 259 {
288 unsigned char ctrl = 0; 260 unsigned char ctrl = 0;
289 if(music_on == 0||pause_flag == 1) return 0; 261 if(music_on == 0||pause_flag == 1) return 0;
310 return 0; 282 return 0;
311 } 283 }
312 /*--------------------------------------------------------------*/ 284 /*--------------------------------------------------------------*/
313 inline void CrixPlayer::rix_get_ins() 285 inline void CrixPlayer::rix_get_ins()
314 { 286 {
315 memcpy(insbuf,(&buf_addr[ins_block])+(band_low<<6),56); 287 int i;
288 unsigned char *baddr = (&buf_addr[ins_block])+(band_low<<6);
289
290 for(i = 0; i < 28; i++)
291 insbuf[i] = (baddr[i * 2 + 1] << 8) + baddr[i * 2];
292
293 // memcpy(insbuf,(&buf_addr[ins_block])+(band_low<<6),56);
316 } 294 }
317 /*--------------------------------------------------------------*/ 295 /*--------------------------------------------------------------*/
318 inline void CrixPlayer::rix_90_pro(unsigned short ctrl_l) 296 inline void CrixPlayer::rix_90_pro(unsigned short ctrl_l)
319 { 297 {
320 if(rhythm == 0 || ctrl_l < 6) 298 if(rhythm == 0 || ctrl_l < 6)