diff options
Diffstat (limited to 'modules/chibi/cp_loader_xm.cpp')
| -rw-r--r-- | modules/chibi/cp_loader_xm.cpp | 1001 |
1 files changed, 487 insertions, 514 deletions
diff --git a/modules/chibi/cp_loader_xm.cpp b/modules/chibi/cp_loader_xm.cpp index 65c7bc7ee..9f743904b 100644 --- a/modules/chibi/cp_loader_xm.cpp +++ b/modules/chibi/cp_loader_xm.cpp @@ -30,705 +30,683 @@ #include "cp_loader_xm.h" #include "cp_tables.h" -#define ABORT_LOAD { file->close(); return FILE_CORRUPTED; } - - - +#define ABORT_LOAD \ + { \ + file->close(); \ + return FILE_CORRUPTED; \ + } -CPLoader::Error CPLoader_XM::load_song(const char *p_file,CPSong *p_song,bool p_sampleset) { +CPLoader::Error CPLoader_XM::load_song(const char *p_file, CPSong *p_song, bool p_sampleset) { - song=p_song; + song = p_song; - if (file->open(p_file,CPFileAccessWrapper::READ)) { + if (file->open(p_file, CPFileAccessWrapper::READ)) { return FILE_CANNOT_OPEN; - }; - + }; - /************************************** + /************************************** LOAD HEADER ***************************************/ - file->get_byte_array(header.idtext,17); - header.idtext[17]=0; + file->get_byte_array(header.idtext, 17); + header.idtext[17] = 0; - file->get_byte_array(header.songname,20); - + file->get_byte_array(header.songname, 20); + header.songname[20] = 0; + header.hex1a = file->get_byte(); + if (header.hex1a != 0x1A) { //XM "magic" byte.. this sucks :) - header.songname[20]=0; - header.hex1a=file->get_byte(); - if (header.hex1a!=0x1A) { //XM "magic" byte.. this sucks :) - - file->close(); + file->close(); return FILE_UNRECOGNIZED; - - } + } + + //magic byte sucks, but can't do much about it.. - - //magic byte sucks, but can't do much about it.. - song->reset(); //must reset the song - song->set_name( (const char*)header.songname ); - - file->get_byte_array(header.trackername,20); - header.trackername[20]=0; + song->set_name((const char *)header.songname); + + file->get_byte_array(header.trackername, 20); + header.trackername[20] = 0; + header.version = file->get_word(); - header.version=file->get_word(); + header.headersize = file->get_dword(); - header.headersize=file->get_dword(); + header.songlength = file->get_word(); - header.songlength=file->get_word(); + header.restart_pos = file->get_word(); - header.restart_pos=file->get_word(); + header.channels_used = file->get_word(); - header.channels_used=file->get_word(); + header.patterns_used = file->get_word(); - header.patterns_used=file->get_word(); + header.instruments_used = file->get_word(); - header.instruments_used=file->get_word(); + song->set_linear_slides(file->get_word()); - song->set_linear_slides( file->get_word() ); + song->set_speed(file->get_word()); - song->set_speed( file->get_word() ); + song->set_tempo(file->get_word()); + song->set_instruments(true); - song->set_tempo( file->get_word() ); - song->set_instruments( true ); + file->get_byte_array(header.orderlist, 256); - file->get_byte_array(header.orderlist,256); - - for (int i=0;i<header.songlength;i++) { + for (int i = 0; i < header.songlength; i++) { - if (i>199) + if (i > 199) break; - song->set_order(i,header.orderlist[i]); + song->set_order(i, header.orderlist[i]); } - /************************************** + /************************************** LOAD PATTERNS ***************************************/ - for (int i=0;i<header.patterns_used;i++) { + for (int i = 0; i < header.patterns_used; i++) { - uint32_t aux,rows; + uint32_t aux, rows; - aux=file->get_dword(); //length - aux=file->get_byte(); //packing type - rows=aux=file->get_word(); //rows! + aux = file->get_dword(); //length + aux = file->get_byte(); //packing type + rows = aux = file->get_word(); //rows! - song->get_pattern(i)->set_length( aux ); + song->get_pattern(i)->set_length(aux); - aux=file->get_word(); //packed size - if (aux==0) - continue; - //unpaaack! - for(int j=0;j<(int)rows;j++) - for(int k=0;k<header.channels_used;k++) { + aux = file->get_word(); //packed size + if (aux == 0) + continue; + //unpaaack! + for (int j = 0; j < (int)rows; j++) + for (int k = 0; k < header.channels_used; k++) { CPNote aux_note; - uint8_t aux_byte; + uint8_t aux_byte; //uint8_t field; - aux_byte=file->get_byte(); //packing type - if (!(aux_byte&0x80)) { - - aux_note.note=aux_byte; - aux_byte=0xFE; //if bit 7 not set, read all of them except the note - } - - if (aux_byte&1) aux_note.note=file->get_byte(); - if (aux_byte&2) aux_note.instrument=file->get_byte(); - if (aux_byte&4) aux_note.volume=file->get_byte(); - if (aux_byte&8) aux_note.command=file->get_byte(); - if (aux_byte&16) aux_note.parameter=file->get_byte(); - - if (aux_note.note!=CPNote::EMPTY) { - - if (aux_note.note==97) aux_note.note=CPNote::OFF; - else { - aux_note.note+=11; //octave minus one (XM C-0 is 1, not zero ) - } - } - if (aux_note.instrument!=CPNote::EMPTY) { + aux_byte = file->get_byte(); //packing type + if (!(aux_byte & 0x80)) { - if ((aux_note.instrument>0) && (aux_note.instrument<100)) - aux_note.instrument--; - else - aux_note.instrument=CPNote::EMPTY; - } - if (aux_note.volume!=CPNote::EMPTY) { - - if (aux_note.volume<0x10) {} - else if (aux_note.volume<0x50) { + aux_note.note = aux_byte; + aux_byte = 0xFE; //if bit 7 not set, read all of them except the note + } - aux_note.volume-=0x10; + if (aux_byte & 1) aux_note.note = file->get_byte(); + if (aux_byte & 2) aux_note.instrument = file->get_byte(); + if (aux_byte & 4) aux_note.volume = file->get_byte(); + if (aux_byte & 8) aux_note.command = file->get_byte(); + if (aux_byte & 16) aux_note.parameter = file->get_byte(); - } else if (aux_note.volume<0x60) { - // - aux_note.volume=CPNote::EMPTY; + if (aux_note.note != CPNote::EMPTY) { - } else if (aux_note.volume<0x70) { - //60 -- volume slide down - aux_note.volume-=0x60; - if (aux_note.volume>9) aux_note.volume=9; - aux_note.volume+=95; - - } else if (aux_note.volume<0x80) { - //70 -- volume slide up - aux_note.volume-=0x70; - if (aux_note.volume>9) aux_note.volume=9; - aux_note.volume+=85; + if (aux_note.note == 97) + aux_note.note = CPNote::OFF; + else { + aux_note.note += 11; //octave minus one (XM C-0 is 1, not zero ) + } + } + if (aux_note.instrument != CPNote::EMPTY) { + if ((aux_note.instrument > 0) && (aux_note.instrument < 100)) + aux_note.instrument--; + else + aux_note.instrument = CPNote::EMPTY; + } + if (aux_note.volume != CPNote::EMPTY) { - } else if (aux_note.volume<0x90) { - //80 -- fine volume slide down - aux_note.volume-=0x80; - if (aux_note.volume>9) aux_note.volume=9; - aux_note.volume+=75; + if (aux_note.volume < 0x10) { + } else if (aux_note.volume < 0x50) { + aux_note.volume -= 0x10; - } else if (aux_note.volume<0xA0) { - //9 -- fine volume slide up + } else if (aux_note.volume < 0x60) { + // + aux_note.volume = CPNote::EMPTY; - aux_note.volume-=0x90; - if (aux_note.volume>9) aux_note.volume=9; + } else if (aux_note.volume < 0x70) { + //60 -- volume slide down + aux_note.volume -= 0x60; + if (aux_note.volume > 9) aux_note.volume = 9; + aux_note.volume += 95; - aux_note.volume+=65; + } else if (aux_note.volume < 0x80) { + //70 -- volume slide up + aux_note.volume -= 0x70; + if (aux_note.volume > 9) aux_note.volume = 9; + aux_note.volume += 85; + } else if (aux_note.volume < 0x90) { + //80 -- fine volume slide down + aux_note.volume -= 0x80; + if (aux_note.volume > 9) aux_note.volume = 9; + aux_note.volume += 75; + } else if (aux_note.volume < 0xA0) { + //9 -- fine volume slide up - } else if (aux_note.volume<0xB0) { - //A -- set vibrato speed - aux_note.volume=CPNote::EMPTY; + aux_note.volume -= 0x90; + if (aux_note.volume > 9) aux_note.volume = 9; - } else if (aux_note.volume<0xC0) { - //B -- vibrato - aux_note.volume-=0xB0; - if (aux_note.volume>9) aux_note.volume=9; - aux_note.volume+=203; + aux_note.volume += 65; + } else if (aux_note.volume < 0xB0) { + //A -- set vibrato speed + aux_note.volume = CPNote::EMPTY; - } else if (aux_note.volume<0xD0) { - //C -- set panning - int aux=aux_note.volume-=0xC0; - aux=aux*65/0xF; - aux_note.volume=128+aux; + } else if (aux_note.volume < 0xC0) { + //B -- vibrato + aux_note.volume -= 0xB0; + if (aux_note.volume > 9) aux_note.volume = 9; + aux_note.volume += 203; - } else if (aux_note.volume<0xE0) { - aux_note.volume=CPNote::EMPTY; + } else if (aux_note.volume < 0xD0) { + //C -- set panning + int aux = aux_note.volume -= 0xC0; + aux = aux * 65 / 0xF; + aux_note.volume = 128 + aux; + } else if (aux_note.volume < 0xE0) { + aux_note.volume = CPNote::EMPTY; - } else if (aux_note.volume<0xF0) { - aux_note.volume=CPNote::EMPTY; + } else if (aux_note.volume < 0xF0) { + aux_note.volume = CPNote::EMPTY; + } else { + //F -- tone porta + aux_note.volume -= 0xF0; + aux_note.volume *= 9; + aux_note.volume /= 0xF; + aux_note.volume += 193; + } + } + if (aux_note.command != CPNote::EMPTY) { - } else { - //F -- tone porta - aux_note.volume-=0xF0; - aux_note.volume*=9; - aux_note.volume/=0xF; - aux_note.volume+=193; - } - } - if (aux_note.command!=CPNote::EMPTY) { + switch (aux_note.command) { - switch(aux_note.command) { + case 0x0: + aux_note.command = 'J' - 'A'; + break; + case 0x1: + aux_note.command = 'F' - 'A'; + break; + case 0x2: + aux_note.command = 'E' - 'A'; + break; + case 0x3: + aux_note.command = 'G' - 'A'; + break; + case 0x4: + aux_note.command = 'H' - 'A'; + break; + case 0x5: + aux_note.command = 'L' - 'A'; + break; + case 0x6: + aux_note.command = 'K' - 'A'; + break; + case 0x7: + aux_note.command = 'R' - 'A'; + break; + case 0x8: + aux_note.command = 'X' - 'A'; + break; + case 0x9: + aux_note.command = 'O' - 'A'; + break; + case 0xa: + aux_note.command = 'D' - 'A'; + break; + case 0xb: + aux_note.command = 'B' - 'A'; + break; + case 0xc: + //printf("XM Import: Warning! effect C (set volume) not implemented!\n"); + break; + case 0xd: + aux_note.command = 'C' - 'A'; + break; - case 0x0: - aux_note.command='J'-'A'; - break; - case 0x1: - aux_note.command='F'-'A'; - break; - case 0x2: - aux_note.command='E'-'A'; - break; - case 0x3: - aux_note.command='G'-'A'; - break; - case 0x4: - aux_note.command='H'-'A'; - break; - case 0x5: - aux_note.command='L'-'A'; - break; - case 0x6: - aux_note.command='K'-'A'; - break; - case 0x7: - aux_note.command='R'-'A'; - break; - case 0x8: - aux_note.command='X'-'A'; - break; - case 0x9: - aux_note.command='O'-'A'; - break; - case 0xa: - aux_note.command='D'-'A'; - break; - case 0xb: - aux_note.command='B'-'A'; - break; - case 0xc: - //printf("XM Import: Warning! effect C (set volume) not implemented!\n"); - break; - case 0xd: - aux_note.command='C'-'A'; - break; + case 0xe: /* Extended effects */ - case 0xe: /* Extended effects */ + aux_note.command = 'S' - 'A'; + switch (aux_note.parameter >> 4) { + case 0x1: /* XM fine porta up */ + if (!(aux_note.parameter & 0xF)) { + aux_note.command = CPNote::EMPTY; + aux_note.parameter = 0; + break; + } + aux_note.command = 'F' - 'A'; + aux_note.parameter = 0xF0 | (aux_note.parameter & 0xF); + break; + case 0x2: /* XM fine porta down */ + if (!(aux_note.parameter & 0xF)) { + aux_note.command = CPNote::EMPTY; + aux_note.parameter = 0; + break; + } + aux_note.command = 'E' - 'A'; + aux_note.parameter = 0xF0 | (aux_note.parameter & 0xF); + break; + case 0xa: /* XM fine volume up */ + if (!(aux_note.parameter & 0xF)) { + aux_note.command = CPNote::EMPTY; + aux_note.parameter = 0; + break; + } + aux_note.command = 'D' - 'A'; + aux_note.parameter = 0x0F | ((aux_note.parameter & 0xF) << 4); - aux_note.command='S'-'A'; - switch(aux_note.parameter>>4) { - case 0x1: /* XM fine porta up */ - if (!(aux_note.parameter&0xF)) { aux_note.command=CPNote::EMPTY; aux_note.parameter=0; break; } - aux_note.command='F'-'A'; - aux_note.parameter=0xF0|(aux_note.parameter&0xF); - break; - case 0x2: /* XM fine porta down */ - if (!(aux_note.parameter&0xF)) { aux_note.command=CPNote::EMPTY; aux_note.parameter=0; break; } - aux_note.command='E'-'A'; - aux_note.parameter=0xF0|(aux_note.parameter&0xF); - break; - case 0xa: /* XM fine volume up */ - if (!(aux_note.parameter&0xF)) { aux_note.command=CPNote::EMPTY; aux_note.parameter=0; break; } - aux_note.command='D'-'A'; - aux_note.parameter=0x0F|((aux_note.parameter&0xF)<<4); + break; + case 0xb: /* XM fine volume down */ + if (!(aux_note.parameter & 0xF)) { + aux_note.command = CPNote::EMPTY; + aux_note.parameter = 0; + break; + } + aux_note.command = 'D' - 'A'; + aux_note.parameter = 0xF0 | (aux_note.parameter & 0xF); - break; - case 0xb: /* XM fine volume down */ - if (!(aux_note.parameter&0xF)) { aux_note.command=CPNote::EMPTY; aux_note.parameter=0; break; } - aux_note.command='D'-'A'; - aux_note.parameter=0xF0|(aux_note.parameter&0xF); + break; + case 0x9: /* XM fine volume down */ + if (!(aux_note.parameter & 0xF)) { + aux_note.command = CPNote::EMPTY; + aux_note.parameter = 0; + break; + } + aux_note.command = 'Q' - 'A'; + aux_note.parameter = 0x00 | (aux_note.parameter & 0xF); + break; - break; - case 0x9: /* XM fine volume down */ - if (!(aux_note.parameter&0xF)) { aux_note.command=CPNote::EMPTY; aux_note.parameter=0; break; } - aux_note.command='Q'-'A'; - aux_note.parameter=0x00|(aux_note.parameter&0xF); - break; + case 0xc: //notecut - case 0xc: //notecut - - aux_note.parameter=0xC0|(aux_note.parameter&0xF); - break; + aux_note.parameter = 0xC0 | (aux_note.parameter & 0xF); + break; - case 0xd: //notedelay - - aux_note.parameter=0xD0|(aux_note.parameter&0xF); - break; + case 0xd: //notedelay - case 0xe: //patterndelay - - aux_note.parameter=0xE0|(aux_note.parameter&0xF); - break; - } + aux_note.parameter = 0xD0 | (aux_note.parameter & 0xF); + break; - break; - case 0xf: - if (aux_note.parameter<32) { - aux_note.command='A'-'A'; - } else { - aux_note.command='T'-'A'; - } - break; - case 'G'-55: - aux_note.command='V'-'A'; - break; - case 'H'-55: - aux_note.command='W'-'A'; - break; - case 'K'-55: - if (aux_note.note!=CPNote::EMPTY) break; - aux_note.note=CPNote::OFF; - break; - case 'P'-55: - aux_note.command='P'-'A'; - break; - case 'R'-55: - aux_note.command='Q'-'A'; - break; - case 'T'-55: - aux_note.command='I'-'A'; - break; - default: { + case 0xe: //patterndelay - aux_note.command=CPNote::EMPTY; - } - } + aux_note.parameter = 0xE0 | (aux_note.parameter & 0xF); + break; + } + break; + case 0xf: + if (aux_note.parameter < 32) { + aux_note.command = 'A' - 'A'; + } else { + aux_note.command = 'T' - 'A'; + } + break; + case 'G' - 55: + aux_note.command = 'V' - 'A'; + break; + case 'H' - 55: + aux_note.command = 'W' - 'A'; + break; + case 'K' - 55: + if (aux_note.note != CPNote::EMPTY) break; + aux_note.note = CPNote::OFF; + break; + case 'P' - 55: + aux_note.command = 'P' - 'A'; + break; + case 'R' - 55: + aux_note.command = 'Q' - 'A'; + break; + case 'T' - 55: + aux_note.command = 'I' - 'A'; + break; + default: { + aux_note.command = CPNote::EMPTY; + } + } } - song->get_pattern( i)->set_note( k,j,aux_note ); - } + song->get_pattern(i)->set_note(k, j, aux_note); + } } - /************************************** + /************************************** LOAD INSTRUMENTS! ***************************************/ - for (int i=0;i<header.instruments_used;i++) { + for (int i = 0; i < header.instruments_used; i++) { + uint32_t aux; + int sampnum; - uint32_t aux; - int sampnum; - - CPInstrument &instrument=*song->get_instrument(i); - uint32_t cpos=file->get_pos(); + CPInstrument &instrument = *song->get_instrument(i); + uint32_t cpos = file->get_pos(); //printf("pos is %i\n",cpos); - - -/* +4 */ uint32_t hsize=file->get_dword(); //header length + /* +4 */ uint32_t hsize = file->get_dword(); //header length char instrname[23]; - instrname[22]=0; - - file->get_byte_array((uint8_t*)instrname,22); -//XM_LOAD_DEBUG printf("name is %s\n",instrname); + instrname[22] = 0; -/* +27 */ aux=file->get_byte(); //byte that must be ignored -//XM_LOAD_DEBUG printf("header size is %i\n",hsize); + file->get_byte_array((uint8_t *)instrname, 22); + //XM_LOAD_DEBUG printf("name is %s\n",instrname); -/* +29 */ sampnum=file->get_word(); + /* +27 */ aux = file->get_byte(); //byte that must be ignored + //XM_LOAD_DEBUG printf("header size is %i\n",hsize); -//XM_LOAD_DEBUG printf("samples %i\n",sampnum); + /* +29 */ sampnum = file->get_word(); + //XM_LOAD_DEBUG printf("samples %i\n",sampnum); - instrument.set_name( instrname ); -// printf("Header Len: %i, CPInstrument %i, %i samples , name: s,\n",hsize,i,sampnum,instrname); - - if (sampnum==0) { + instrument.set_name(instrname); + // printf("Header Len: %i, CPInstrument %i, %i samples , name: s,\n",hsize,i,sampnum,instrname); + + if (sampnum == 0) { //aux=file->get_dword(); //Why is this for? -- for nothing, skipped if (hsize) { - - file->seek( cpos+hsize ); //skip header if size has been specified + + file->seek(cpos + hsize); //skip header if size has been specified } continue; } -/* +33 */ file->get_dword(); + /* +33 */ file->get_dword(); - if (Error result=load_instrument_internal(&instrument,false,cpos,hsize,sampnum)) { + if (Error result = load_instrument_internal(&instrument, false, cpos, hsize, sampnum)) { CP_PRINTERR("Error loading instrument"); file->close(); return result; } - } -// + // file->close(); return FILE_OK; } -CPLoader::Error CPLoader_XM::load_instrument_internal(CPInstrument *p_instr,bool p_xi,int p_cpos, int p_hsize, int p_sampnum) { +CPLoader::Error CPLoader_XM::load_instrument_internal(CPInstrument *p_instr, bool p_xi, int p_cpos, int p_hsize, int p_sampnum) { - int sampnum; - uint32_t aux; - uint8_t notenumb[96]; - uint16_t panenv[24],volenv[24]; - int volpoints,panpoints; - int vol_loop_begin,vol_loop_end,vol_sustain_loop; - int pan_loop_begin,pan_loop_end,pan_sustain_loop; - char instrname[23]; - int sample_index[16]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; //-1 means no index! + int sampnum; + uint32_t aux; + uint8_t notenumb[96]; + uint16_t panenv[24], volenv[24]; + int volpoints, panpoints; + int vol_loop_begin, vol_loop_end, vol_sustain_loop; + int pan_loop_begin, pan_loop_end, pan_sustain_loop; + char instrname[23]; + int sample_index[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; //-1 means no index! - instrname[22]=0; + instrname[22] = 0; + /* +129 */ file->get_byte_array((uint8_t *)notenumb, 96); + for (int j = 0; j < 24; j++) { + volenv[j] = file->get_word(); + } + for (int j = 0; j < 24; j++) { + panenv[j] = file->get_word(); + } -/* +129 */ file->get_byte_array((uint8_t*)notenumb,96); - for (int j=0;j<24;j++) { - volenv[j]=file->get_word(); - } - for (int j=0;j<24;j++) { - panenv[j]=file->get_word(); - } + /* +177 */ + /* +225 */ + /* +226 */ volpoints = file->get_byte(); + /* +227 */ panpoints = file->get_byte(); + /* +230 */ vol_sustain_loop = file->get_byte(); + /* +228 */ vol_loop_begin = file->get_byte(); + /* +229 */ vol_loop_end = file->get_byte(); + + //XM_LOAD_DEBUG printf("1- volpoints: %i, panpoints: %i, susloop: %i, loop begin: %i, loop end %i\n",volpoints,panpoints,vol_sustain_loop,vol_loop_begin,vol_loop_end); + pan_sustain_loop = file->get_byte(); + /* +231 */ pan_loop_begin = file->get_byte(); + /* +232 */ pan_loop_end = file->get_byte(); + + /* +234 */ aux = file->get_byte(); + p_instr->get_volume_envelope()->reset(); + p_instr->get_volume_envelope()->set_enabled(aux & 1); + p_instr->get_volume_envelope()->set_sustain_loop_enabled((aux & 2) ? true : false); + p_instr->get_volume_envelope()->set_loop_enabled((aux & 4) ? true : false); + /* +235 */ aux = file->get_byte(); + p_instr->get_pan_envelope()->reset(); + p_instr->get_pan_envelope()->set_enabled(aux & 1); + p_instr->get_pan_envelope()->set_sustain_loop_enabled((aux & 2) ? true : false); + p_instr->get_pan_envelope()->set_loop_enabled((aux & 4) ? true : false); + + /* +239 */ aux = file->get_dword(); // sadly, cant use those + /* +241 */ p_instr->set_volume_fadeout(file->get_word() >> 4); + /* +243 */ aux = file->get_word(); // reserved! + + for (int j = 0; j < volpoints; j++) { + int ofs = volenv[j * 2]; + int val = volenv[j * 2 + 1]; + p_instr->get_volume_envelope()->add_position(ofs, val); + } -/* +177 */ -/* +225 */ -/* +226 */ volpoints=file->get_byte(); -/* +227 */ panpoints=file->get_byte(); -/* +230 */ vol_sustain_loop=file->get_byte(); -/* +228 */ vol_loop_begin=file->get_byte(); -/* +229 */ vol_loop_end=file->get_byte(); + //make sure minimum is 2 + while (p_instr->get_volume_envelope()->get_node_count() < 2) { -//XM_LOAD_DEBUG printf("1- volpoints: %i, panpoints: %i, susloop: %i, loop begin: %i, loop end %i\n",volpoints,panpoints,vol_sustain_loop,vol_loop_begin,vol_loop_end); - pan_sustain_loop=file->get_byte(); -/* +231 */ pan_loop_begin=file->get_byte(); -/* +232 */ pan_loop_end=file->get_byte(); + p_instr->get_volume_envelope()->add_position(p_instr->get_volume_envelope()->get_node_count() * 20, 64); + } + for (int j = 0; j < panpoints; j++) { + int ofs = panenv[j * 2]; + int val = panenv[j * 2 + 1]; + p_instr->get_pan_envelope()->add_position(ofs, val - 32); + } + //make sure minimum is 2 + while (p_instr->get_pan_envelope()->get_node_count() < 2) { -/* +234 */ aux=file->get_byte(); - p_instr->get_volume_envelope()->reset(); - p_instr->get_volume_envelope()->set_enabled(aux&1); - p_instr->get_volume_envelope()->set_sustain_loop_enabled((aux&2)?true:false); - p_instr->get_volume_envelope()->set_loop_enabled((aux&4)?true:false); -/* +235 */ aux=file->get_byte(); - p_instr->get_pan_envelope()->reset(); - p_instr->get_pan_envelope()->set_enabled(aux&1); - p_instr->get_pan_envelope()->set_sustain_loop_enabled((aux&2)?true:false); - p_instr->get_pan_envelope()->set_loop_enabled((aux&4)?true:false); + p_instr->get_pan_envelope()->add_position(p_instr->get_pan_envelope()->get_node_count() * 20, 0); + } -/* +239 */ aux=file->get_dword(); // sadly, cant use those -/* +241 */ p_instr->set_volume_fadeout( file->get_word() >> 4 ); -/* +243 */ aux=file->get_word(); // reserved! + p_instr->get_volume_envelope()->set_loop_begin(vol_loop_begin); + p_instr->get_volume_envelope()->set_loop_end(vol_loop_end); + p_instr->get_volume_envelope()->set_sustain_loop_end(vol_sustain_loop); + p_instr->get_volume_envelope()->set_sustain_loop_begin(vol_sustain_loop); + p_instr->get_pan_envelope()->set_loop_begin(pan_loop_begin); + p_instr->get_pan_envelope()->set_loop_end(pan_loop_end); + p_instr->get_pan_envelope()->set_sustain_loop_end(pan_sustain_loop); + p_instr->get_pan_envelope()->set_sustain_loop_begin(pan_sustain_loop); + if (!p_xi) { + if ((file->get_pos() - p_cpos) < p_hsize) { - for (int j=0;j<volpoints;j++) { - int ofs=volenv[j*2]; - int val=volenv[j*2+1]; - p_instr->get_volume_envelope()->add_position(ofs,val); + uint8_t junkbuster[500]; + //printf("extra junk XM instrument in header! hsize is %i, extra junk: %i\n",p_hsize,(file->get_pos()-p_cpos)); + //printf("extra: %i\n",p_hsize-(file->get_pos()-p_cpos)); + file->get_byte_array((uint8_t *)junkbuster, p_hsize - (file->get_pos() - p_cpos)); } - //make sure minimum is 2 - while (p_instr->get_volume_envelope()->get_node_count()<2) { - - p_instr->get_volume_envelope()->add_position( p_instr->get_volume_envelope()->get_node_count()*20,64 ); - } - - for (int j=0;j<panpoints;j++) { - int ofs=panenv[j*2]; - int val=panenv[j*2+1]; - p_instr->get_pan_envelope()->add_position(ofs,val-32); - } - - //make sure minimum is 2 - while (p_instr->get_pan_envelope()->get_node_count()<2) { - - p_instr->get_pan_envelope()->add_position( p_instr->get_pan_envelope()->get_node_count()*20,0 ); - } - - - p_instr->get_volume_envelope()->set_loop_begin(vol_loop_begin); - p_instr->get_volume_envelope()->set_loop_end(vol_loop_end); - p_instr->get_volume_envelope()->set_sustain_loop_end(vol_sustain_loop); - p_instr->get_volume_envelope()->set_sustain_loop_begin(vol_sustain_loop); - p_instr->get_pan_envelope()->set_loop_begin(pan_loop_begin); - p_instr->get_pan_envelope()->set_loop_end(pan_loop_end); - p_instr->get_pan_envelope()->set_sustain_loop_end(pan_sustain_loop); - p_instr->get_pan_envelope()->set_sustain_loop_begin(pan_sustain_loop); + sampnum = p_sampnum; + } else { + uint8_t junkbuster[500]; + file->get_byte_array((uint8_t *)junkbuster, 20); //14 bytes? - if (!p_xi) { + sampnum = file->get_word(); + } - if ((file->get_pos()-p_cpos)<p_hsize) { + CPSampleManager *sm = CPSampleManager::get_singleton(); - uint8_t junkbuster[500]; + /*SAMPLE!!*/ - //printf("extra junk XM instrument in header! hsize is %i, extra junk: %i\n",p_hsize,(file->get_pos()-p_cpos)); - //printf("extra: %i\n",p_hsize-(file->get_pos()-p_cpos)); - file->get_byte_array((uint8_t*)junkbuster,p_hsize-(file->get_pos()-p_cpos)); - } - - sampnum=p_sampnum; - } else { + for (int j = 0; j < sampnum; j++) { - uint8_t junkbuster[500]; - file->get_byte_array((uint8_t*)junkbuster,20); //14 bytes? + if (j > 16) ABORT_LOAD; - sampnum=file->get_word(); + int s_idx = -1; + for (int s = 0; s < CPSong::MAX_SAMPLES; s++) { + if (song->get_sample(s)->get_sample_data().is_null()) { + //empty sample! + s_idx = s; + break; + } } + if (s_idx == -1) ABORT_LOAD; + //printf("free sample: %i\n",s_idx); - CPSampleManager *sm=CPSampleManager::get_singleton(); + CPSample &sample = *song->get_sample(s_idx); - /*SAMPLE!!*/ + int sample_size = file->get_dword(); + int tmp_loop_begin = file->get_dword(); - for (int j=0;j<sampnum;j++) { + int tmp_loop_end = file->get_dword(); - if (j>16) ABORT_LOAD; + sample.set_default_volume(file->get_byte()); - - int s_idx=-1; - for (int s=0;s<CPSong::MAX_SAMPLES;s++) { - - if (song->get_sample(s)->get_sample_data().is_null()) { - //empty sample! - s_idx=s; - break; - } - } - - if (s_idx==-1) ABORT_LOAD; - //printf("free sample: %i\n",s_idx); - + uint8_t ftb = file->get_byte(); + int8_t *fts = (int8_t *)&ftb; + int finetune = *fts; + uint32_t flags = file->get_byte(); - CPSample& sample=*song->get_sample(s_idx); - - int sample_size=file->get_dword(); - int tmp_loop_begin=file->get_dword(); + if (flags & 16) { // is 16 bits.. at flag 16.. fun :) - int tmp_loop_end=file->get_dword(); - - sample.set_default_volume(file->get_byte()); + tmp_loop_end /= 2; + tmp_loop_begin /= 2; + sample_size /= 2; + } - uint8_t ftb=file->get_byte(); - int8_t *fts=(int8_t*)&ftb; - int finetune=*fts; - uint32_t flags=file->get_byte(); - - if (flags&16) { // is 16 bits.. at flag 16.. fun :) - - tmp_loop_end/=2; - tmp_loop_begin/=2; - sample_size/=2; - } - - - CPSample_ID sample_data=sm->create( flags&16, false, sample_size ); - - sample.set_sample_data(sample_data); - sm->set_loop_begin(sample_data,tmp_loop_begin); - sm->set_loop_end(sample_data,tmp_loop_end+tmp_loop_begin); - - sm->set_loop_type( sample_data, (flags&3)?( (flags&2) ? CP_LOOP_BIDI : CP_LOOP_FORWARD ):CP_LOOP_NONE ); - - + CPSample_ID sample_data = sm->create(flags & 16, false, sample_size); - sample.set_pan_enabled(true); - sample.set_pan(file->get_byte()*64/255); - uint8_t noteb=file->get_byte(); - int8_t *notes=(int8_t*)¬eb; - int note_offset=*notes; - note_offset+=48; - //note_offset+=60; - - - - //int linear_period=10*12*16*4 - (note_offset)*16*4 - finetune/2; - //int freq=(int)(8363*pow(2.0,(double)(6*12*16*4 - linear_period) / (double)(12*16*4))); - - //sm->set_c5_freq( sample_data, freq); - sm->set_c5_freq( sample_data, CPTables::get_linear_frequency(CPTables::get_linear_period(note_offset<<1,finetune)) ); - //printf("NOTE %i,fine %i\n",note_offset,finetune); + sample.set_sample_data(sample_data); + sm->set_loop_begin(sample_data, tmp_loop_begin); + sm->set_loop_end(sample_data, tmp_loop_end + tmp_loop_begin); - char auxb; - auxb=file->get_byte(); //reserved? - file->get_byte_array((uint8_t*)instrname,22); - sample.set_name(instrname); + sm->set_loop_type(sample_data, (flags & 3) ? ((flags & 2) ? CP_LOOP_BIDI : CP_LOOP_FORWARD) : CP_LOOP_NONE); - sample_index[j]=s_idx; - } + sample.set_pan_enabled(true); + sample.set_pan(file->get_byte() * 64 / 255); + uint8_t noteb = file->get_byte(); + int8_t *notes = (int8_t *)¬eb; + int note_offset = *notes; + note_offset += 48; + //note_offset+=60; - /*SAMPLE __DATA__!!*/ + //int linear_period=10*12*16*4 - (note_offset)*16*4 - finetune/2; + //int freq=(int)(8363*pow(2.0,(double)(6*12*16*4 - linear_period) / (double)(12*16*4))); - for (int j=0;j<sampnum;j++) { + //sm->set_c5_freq( sample_data, freq); + sm->set_c5_freq(sample_data, CPTables::get_linear_frequency(CPTables::get_linear_period(note_offset << 1, finetune))); + //printf("NOTE %i,fine %i\n",note_offset,finetune); - if (sample_index[j]==-1) continue; + char auxb; + auxb = file->get_byte(); //reserved? + file->get_byte_array((uint8_t *)instrname, 22); + sample.set_name(instrname); - CPSample *sample=song->get_sample(sample_index[j]); - CPSample_ID sid=sample->get_sample_data(); + sample_index[j] = s_idx; + } - sm->lock_data(sid); + /*SAMPLE __DATA__!!*/ - void*dataptr=sm->get_data(sid); + for (int j = 0; j < sampnum; j++) { - if (sm->is_16bits( sid)) { + if (sample_index[j] == -1) continue; - int16_t old=0; + CPSample *sample = song->get_sample(sample_index[j]); + CPSample_ID sid = sample->get_sample_data(); + sm->lock_data(sid); - for (int k=0;k<sm->get_size(sid);k++) { + void *dataptr = sm->get_data(sid); - int16_t newsample; - int16_t sampleval=file->get_word(); - newsample=sampleval+old; - old=newsample; + if (sm->is_16bits(sid)) { - ((int16_t*)dataptr)[k]=newsample; - //sm->set_data( sid, k, newsample ); - } - } else { + int16_t old = 0; - int8_t old=0; + for (int k = 0; k < sm->get_size(sid); k++) { + int16_t newsample; + int16_t sampleval = file->get_word(); + newsample = sampleval + old; + old = newsample; - for (int k=0;k<sm->get_size(sid);k++) { + ((int16_t *)dataptr)[k] = newsample; + //sm->set_data( sid, k, newsample ); + } + } else { - int8_t newsample; - int8_t sampleval=file->get_byte(); - newsample=sampleval+old; - old=newsample; - - ((int8_t*)dataptr)[k]=newsample; + int8_t old = 0; - //sm->set_data( sid, k, (int16_t)newsample << 8 ); - - } - } + for (int k = 0; k < sm->get_size(sid); k++) { + + int8_t newsample; + int8_t sampleval = file->get_byte(); + newsample = sampleval + old; + old = newsample; - sm->unlock_data(sid); + ((int8_t *)dataptr)[k] = newsample; + //sm->set_data( sid, k, (int16_t)newsample << 8 ); + } } - for (int j=0;j<96;j++) { + sm->unlock_data(sid); + } - int val=notenumb[j]; - if ((val<0) || (val>15)) continue; - else val=sample_index[val]; - if (val==-1) continue; - p_instr->set_sample_number( 12+j,val ); - } + for (int j = 0; j < 96; j++) { + int val = notenumb[j]; + if ((val < 0) || (val > 15)) + continue; + else + val = sample_index[val]; + if (val == -1) continue; + p_instr->set_sample_number(12 + j, val); + } return FILE_OK; } +CPLoader::Error CPLoader_XM::load_sample(const char *p_file, CPSample *p_sample) { - -CPLoader::Error CPLoader_XM::load_sample(const char *p_file,CPSample *p_sample) { - return FILE_UNRECOGNIZED; } - /* Compute CPInstrument Info */ -CPLoader::Error CPLoader_XM::load_instrument(const char *p_file,CPSong *p_song,int p_instr_idx) { +CPLoader::Error CPLoader_XM::load_instrument(const char *p_file, CPSong *p_song, int p_instr_idx) { - if ( file->open(p_file,CPFileAccessWrapper::READ) ) return FILE_CANNOT_OPEN; + if (file->open(p_file, CPFileAccessWrapper::READ)) return FILE_CANNOT_OPEN; //int i; - song=p_song; - CPInstrument& instr=*p_song->get_instrument( p_instr_idx ); - int aux; - + song = p_song; + CPInstrument &instr = *p_song->get_instrument(p_instr_idx); + int aux; - char buffer[500]; - file->get_byte_array((uint8_t*)buffer,0x15); - buffer[8]=0; - if ( buffer[0]!='E' || - buffer[1]!='x' || - buffer[2]!='t' || - buffer[3]!='e' || - buffer[4]!='n' || - buffer[5]!='d' || - buffer[6]!='e' || - buffer[7]!='d') { + char buffer[500]; + file->get_byte_array((uint8_t *)buffer, 0x15); + buffer[8] = 0; + if (buffer[0] != 'E' || + buffer[1] != 'x' || + buffer[2] != 't' || + buffer[3] != 'e' || + buffer[4] != 'n' || + buffer[5] != 'd' || + buffer[6] != 'e' || + buffer[7] != 'd') { file->close(); return FILE_UNRECOGNIZED; - } + } - file->get_byte_array((uint8_t*)buffer,0x16); - buffer[0x16]=0; + file->get_byte_array((uint8_t *)buffer, 0x16); + buffer[0x16] = 0; instr.set_name(buffer); - aux=file->get_byte(); //says ignore ti + aux = file->get_byte(); //says ignore ti /*if(aux!=0x1a) { I'm not sure. this is supposed to be ignored... file->close(); return FILE_UNRECOGNIZED; } */ - file->get_byte_array((uint8_t*)buffer,0x14); //somethingaboutthename - aux=file->get_word(); //version or blahblah - - if (load_instrument_internal(&instr,true,0,0)) { + file->get_byte_array((uint8_t *)buffer, 0x14); //somethingaboutthename + aux = file->get_word(); //version or blahblah + + if (load_instrument_internal(&instr, true, 0, 0)) { file->close(); return FILE_CORRUPTED; @@ -736,17 +714,12 @@ CPLoader::Error CPLoader_XM::load_instrument(const char *p_file,CPSong *p_song,i file->close(); //ook, we got it.. - return FILE_OK; - } +CPLoader_XM::CPLoader_XM(CPFileAccessWrapper *p_file) { - -CPLoader_XM::CPLoader_XM(CPFileAccessWrapper *p_file){ - - file=p_file; + file = p_file; } -CPLoader_XM::~CPLoader_XM(){ +CPLoader_XM::~CPLoader_XM() { } - |
