Mercurial > audlegacy
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) |
