bool ChscPlayer::load(const std::string &filename, const CFileProvider &fp) { binistream *f = fp.open(filename); int i; // file validation section if ( !f || !fp.extension(filename, ".hsc") || fp.filesize(f) > (59187 + 1) // +1 is for some files that have a trailing 0x00 on the end || fp.filesize(f) < (1587 + 1152) // no 0x00 byte here as this is the smallest possible size ) { AdPlug_LogWrite("ChscPlayer::load(\"%s\"): Not a HSC file!\n", filename.c_str()); fp.close(f); return false; } int total_patterns_in_hsc = (fp.filesize(f) - 1587) / 1152; // load section for(i=0;i<128*12;i++) // load instruments *((unsigned char *)instr + i) = f->readInt(1); for (i=0;i<128;i++) { // correct instruments instr[i][2] ^= (instr[i][2] & 0x40) << 1; instr[i][3] ^= (instr[i][3] & 0x40) << 1; instr[i][11] >>= 4; // slide } for(i=0;i<51;i++) { // load tracklist song[i] = f->readInt(1); // if out of range, song ends here if ( ((song[i] & 0x7F) > 0x31) || ((song[i] & 0x7F) >= total_patterns_in_hsc) ) song[i] = 0xFF; } for(i=0;i<50*64*9;i++) // load patterns *((char *)patterns + i) = f->readInt(1); fp.close(f); rewind(0); // rewind module return true; }
bool ChspLoader::load(const char *filename, const CFileProvider &fp) { binistream *f = fp.open(filename); if(!f) return false; unsigned long i, j, orgsize, filesize; unsigned char *cmp, *org; // file validation section if(!fp.extension(filename, ".hsp")) { fp.close(f); return false; } filesize = fp.filesize(f); orgsize = f->readInt(2); if(orgsize > 59187) { fp.close(f); return false; } // load section cmp = new unsigned char[filesize]; for(i = 0; i < filesize; i++) cmp[i] = f->readInt(1); fp.close(f); org = new unsigned char[orgsize]; for(i = 0, j = 0; i < filesize; j += cmp[i], i += 2) { // RLE decompress if(j >= orgsize) break; // memory boundary check memset(org + j, cmp[i + 1], j + cmp[i] < orgsize ? cmp[i] : orgsize - j - 1); } delete [] cmp; memcpy(instr, org, 128 * 12); // instruments for(i = 0; i < 128; i++) { // correct instruments instr[i][2] ^= (instr[i][2] & 0x40) << 1; instr[i][3] ^= (instr[i][3] & 0x40) << 1; instr[i][11] >>= 4; // slide } memcpy(song, org + 128 * 12, 51); // tracklist memcpy(patterns, org + 128 * 12 + 51, orgsize - 128 * 12 - 51); // patterns delete [] org; rewind(0); return true; }
bool CdmoLoader::load(const std::string &filename, const CFileProvider &fp) { int i,j; binistream *f; // check header dmo_unpacker *unpacker = new dmo_unpacker; unsigned char chkhdr[16]; if(!fp.extension(filename, ".dmo")) return false; f = fp.open(filename); if(!f) return false; f->readString((char *)chkhdr, 16); if (!unpacker->decrypt(chkhdr, 16)) { delete unpacker; fp.close(f); return false; } // get file size long packed_length = fp.filesize(f); f->seek(0); unsigned char *packed_module = new unsigned char [packed_length]; // load file f->readString((char *)packed_module, packed_length); fp.close(f); // decrypt unpacker->decrypt(packed_module,packed_length); long unpacked_length = 0x2000 * ARRAY_AS_WORD(packed_module, 12); unsigned char *module = new unsigned char [unpacked_length]; // unpack if (!unpacker->unpack(packed_module+12,module,unpacked_length)) { delete unpacker; delete [] packed_module; delete [] module; return false; } delete unpacker; delete [] packed_module; // "TwinTeam" - signed ? if (memcmp(module,"TwinTeam Module File""\x0D\x0A",22)) { delete module; return false; } // load header binisstream uf(module, unpacked_length); uf.setFlag(binio::BigEndian, false); uf.setFlag(binio::FloatIEEE); memset(&header,0,sizeof(s3mheader)); uf.ignore(22); // ignore DMO header ID string uf.readString(header.name, 28); uf.ignore(2); // _unk_1 header.ordnum = uf.readInt(2); header.insnum = uf.readInt(2); header.patnum = uf.readInt(2); uf.ignore(2); // _unk_2 header.is = uf.readInt(2); header.it = uf.readInt(2); memset(header.chanset,0xFF,32); for (i=0;i<9;i++) header.chanset[i] = 0x10 + i; uf.ignore(32); // ignore panning settings for all 32 channels // load orders for(i = 0; i < 256; i++) orders[i] = uf.readInt(1); orders[header.ordnum] = 0xFF; // load pattern lengths unsigned short my_patlen[100]; for(i = 0; i < 100; i++) my_patlen[i] = uf.readInt(2); // load instruments for (i = 0; i < header.insnum; i++) { memset(&inst[i],0,sizeof(s3minst)); uf.readString(inst[i].name, 28); inst[i].volume = uf.readInt(1); inst[i].dsk = uf.readInt(1); inst[i].c2spd = uf.readInt(4); inst[i].type = uf.readInt(1); inst[i].d00 = uf.readInt(1); inst[i].d01 = uf.readInt(1); inst[i].d02 = uf.readInt(1); inst[i].d03 = uf.readInt(1); inst[i].d04 = uf.readInt(1); inst[i].d05 = uf.readInt(1); inst[i].d06 = uf.readInt(1); inst[i].d07 = uf.readInt(1); inst[i].d08 = uf.readInt(1); inst[i].d09 = uf.readInt(1); inst[i].d0a = uf.readInt(1); /* * Originally, riven sets d0b = d0a and ignores 1 byte in the * stream, but i guess this was a typo, so i read it here. */ inst[i].d0b = uf.readInt(1); } // load patterns for (i = 0; i < header.patnum; i++) { long cur_pos = uf.pos(); for (j = 0; j < 64; j++) { while (1) { unsigned char token = uf.readInt(1); if (!token) break; unsigned char chan = token & 31; // note + instrument ? if (token & 32) { unsigned char bufbyte = uf.readInt(1); pattern[i][j][chan].note = bufbyte & 15; pattern[i][j][chan].oct = bufbyte >> 4; pattern[i][j][chan].instrument = uf.readInt(1); } // volume ? if (token & 64) pattern[i][j][chan].volume = uf.readInt(1); // command ? if (token & 128) { pattern[i][j][chan].command = uf.readInt(1); pattern[i][j][chan].info = uf.readInt(1); } } } uf.seek(cur_pos + my_patlen[i]); }
bool CadtrackLoader::load(const std::string &filename, const CFileProvider &fp) { binistream *f = fp.open(filename); if(!f) return false; binistream *instf; char note[2]; unsigned short rwp; unsigned char chp, octave, pnote = 0; int i,j; AdTrackInst myinst; // file validation if(!fp.extension(filename, ".sng") || fp.filesize(f) != 36000) { fp.close(f); return false; } // check for instruments file std::string instfilename(filename, 0, filename.find_last_of('.')); instfilename += ".ins"; AdPlug_LogWrite("CadtrackLoader::load(,\"%s\"): Checking for \"%s\"...\n", filename.c_str(), instfilename.c_str()); instf = fp.open(instfilename); if(!instf || fp.filesize(instf) != 468) { fp.close(f); return false; } // give CmodPlayer a hint on what we're up to realloc_patterns(1,1000,9); realloc_instruments(9); realloc_order(1); init_trackord(); flags = NoKeyOn; (*order) = 0; length = 1; restartpos = 0; bpm = 120; initspeed = 3; // load instruments from instruments file for(i=0;i<9;i++) { for(j=0;j<2;j++) { myinst.op[j].appampmod = instf->readInt(2); myinst.op[j].appvib = instf->readInt(2); myinst.op[j].maintsuslvl = instf->readInt(2); myinst.op[j].keybscale = instf->readInt(2); myinst.op[j].octave = instf->readInt(2); myinst.op[j].freqrisevollvldn = instf->readInt(2); myinst.op[j].softness = instf->readInt(2); myinst.op[j].attack = instf->readInt(2); myinst.op[j].decay = instf->readInt(2); myinst.op[j].release = instf->readInt(2); myinst.op[j].sustain = instf->readInt(2); myinst.op[j].feedback = instf->readInt(2); myinst.op[j].waveform = instf->readInt(2); } convert_instrument(i, &myinst); } fp.close(instf); // load file for(rwp=0;rwp<1000;rwp++) for(chp=0;chp<9;chp++) { // read next record f->readString(note, 2); octave = f->readInt(1); f->ignore(); switch(*note) { case 'C': if(note[1] == '#') pnote = 2; else pnote = 1; break; case 'D': if(note[1] == '#') pnote = 4; else pnote = 3; break; case 'E': pnote = 5; break; case 'F': if(note[1] == '#') pnote = 7; else pnote = 6; break; case 'G': if(note[1] == '#') pnote = 9; else pnote = 8; break; case 'A': if(note[1] == '#') pnote = 11; else pnote = 10; break; case 'B': pnote = 12; break; case '\0': if(note[1] == '\0') tracks[chp][rwp].note = 127; else { fp.close(f); return false; } break; default: fp.close(f); return false; } if((*note) != '\0') { tracks[chp][rwp].note = pnote + (octave * 12); tracks[chp][rwp].inst = chp + 1; } } fp.close(f); rewind(0); return true; }
bool CldsPlayer::load(const std::string &filename, const CFileProvider &fp) { binistream *f; unsigned int i, j; SoundBank *sb; // file validation section (actually just an extension check) if(!fp.extension(filename, ".lds")) return false; f = fp.open(filename); if(!f) return false; // file load section (header) mode = f->readInt(1); if(mode > 2) { fp.close(f); return false; } speed = f->readInt(2); tempo = f->readInt(1); pattlen = f->readInt(1); for(i = 0; i < 9; i++) chandelay[i] = f->readInt(1); regbd = f->readInt(1); // load patches numpatch = f->readInt(2); soundbank = new SoundBank[numpatch]; for(i = 0; i < numpatch; i++) { sb = &soundbank[i]; sb->mod_misc = f->readInt(1); sb->mod_vol = f->readInt(1); sb->mod_ad = f->readInt(1); sb->mod_sr = f->readInt(1); sb->mod_wave = f->readInt(1); sb->car_misc = f->readInt(1); sb->car_vol = f->readInt(1); sb->car_ad = f->readInt(1); sb->car_sr = f->readInt(1); sb->car_wave = f->readInt(1); sb->feedback = f->readInt(1); sb->keyoff = f->readInt(1); sb->portamento = f->readInt(1); sb->glide = f->readInt(1); sb->finetune = f->readInt(1); sb->vibrato = f->readInt(1); sb->vibdelay = f->readInt(1); sb->mod_trem = f->readInt(1); sb->car_trem = f->readInt(1); sb->tremwait = f->readInt(1); sb->arpeggio = f->readInt(1); for(j = 0; j < 12; j++) sb->arp_tab[j] = f->readInt(1); sb->start = f->readInt(2); sb->size = f->readInt(2); sb->fms = f->readInt(1); sb->transp = f->readInt(2); sb->midinst = f->readInt(1); sb->midvelo = f->readInt(1); sb->midkey = f->readInt(1); sb->midtrans = f->readInt(1); sb->middum1 = f->readInt(1); sb->middum2 = f->readInt(1); } // load positions numposi = f->readInt(2); positions = new Position[9 * numposi]; for(i = 0; i < numposi; i++) for(j = 0; j < 9; j++) { /* * patnum is a pointer inside the pattern space, but patterns are 16bit * word fields anyway, so it ought to be an even number (hopefully) and * we can just divide it by 2 to get our array index of 16bit words. */ positions[i * 9 + j].patnum = f->readInt(2) / 2; positions[i * 9 + j].transpose = f->readInt(1); } AdPlug_LogWrite("CldsPlayer::load(\"%s\",fp): loading LOUDNESS file: mode = " "%d, pattlen = %d, numpatch = %d, numposi = %d\n", filename.c_str(), mode, pattlen, numpatch, numposi); // load patterns f->ignore(2); // ignore # of digital sounds (not played by this player) patterns = new unsigned short[(fp.filesize(f) - f->pos()) / 2 + 1]; for(i = 0; !f->eof(); i++) patterns[i] = f->readInt(2); fp.close(f); rewind(0); return true; }