#include <iostream>
#include <fstream>
#include <string>
#include <map>
using namespace std;
unsigned long int get32le(fstream* input){
unsigned char b1=input->get();
unsigned char b2=input->get();
unsigned char b3=input->get();
unsigned char b4=input->get();
long int i1=b1;
long int i2=b2;
long int i3=b3;
long int i4=b4;
return i1 | (i2<<8) | (i3<<16) | (i4<<24);}
int main(int argc, char** argv){
if (argc <= 1){
cout << "Instrument Reorderer for FamiTracker\n"
<< "Usage: reinst [filename] ([listname])\n"
<< "Description: Reads a text file containing space-delimited hexadecimal numbers,\n"
<< " so that the ordering of the FamiTracker module's instruments,\n"
<< " including those not created, matches the text file.\n"
<< "Options:\n"
<< "[filename]: Name of the FTM\n"
<< "[listname]: Name of the reorder list. Defaults to \"reinst.txt\" if not present"
<< endl;}
else{
int version;
fstream instlist((argc >= 3) ? (argv[2]) : ("reinst.txt"), ios::in);
if (!instlist){
cerr << "Cannot open instrument list!" << endl;
exit(1);}
fstream ftm(argv[1], ios::in | ios::out | ios::binary);
if (!ftm){
cerr << "Cannot open FamiTracker module!" << endl;
exit(1);}
fstream* ftmP = &ftm;
int* permute = new int[65];
for (int i=0;i<=0x40;i++){
permute[i]=i;}
for (int i=0;i<0x40;i++){
if (instlist){
string str;
instlist >> str;
if (str!="") permute[stoi(str,NULL,16)]=i;}}
ftm.seekg(0x2A);
ftm.seekg(get32le(ftmP)+0x14,ios_base::cur);
ftm.seekg(get32le(ftmP)+0x14,ios_base::cur);
int pos=get32le(ftmP);
pos+=0x10+ftm.tellg();
int songs=ftm.get()+1;
int zero=0;
while (zero<songs) if (ftm.get()=='\0') zero++;
int headerpos=ftm.tellg();
ftm.seekg(pos); // seeks through "INSTRUMENT " for normally created FTMs
version=get32le(ftmP);
ftm.seekg(0x4,ios_base::cur);
int instcount=get32le(ftmP);
for (int i=0;i<instcount;i++){
int newinst=permute[ftm.peek()];
ftm.seekp(ftm.tellg(),ios_base::beg);
ftm.write(reinterpret_cast<char*>(&newinst),1);
ftm.seekg(0x3,ios_base::cur);
switch(ftm.get()){
case 1: // 2A03
ftm.seekg(0x9E+0x30*(version>=2)+0x60*(version>=6),ios_base::cur); break;
case 2: // VRC6
ftm.seekg(0xE,ios_base::cur); break;
case 3: // VRC7
ftm.seekg(0xC,ios_base::cur); break;
case 4: // FDS
ftm.seekg(0x6C,ios_base::cur);
for (int j=0;j<3;j++) ftm.seekg(ftm.get()+0xC,ios_base::cur); break;
case 5: // N163
ftm.seekg(0xE,ios_base::cur);
int wavecount=get32le(ftmP);
ftm.seekg(0x4,ios_base::cur);
ftm.seekg(wavecount*get32le(ftmP),ios_base::cur); break;}
ftm.seekg(get32le(ftmP),ios_base::cur);}
ftm.seekg(0x14,ios_base::cur);
ftm.seekg(get32le(ftmP)+0x14,ios_base::cur);
ftm.seekg(get32le(ftmP)+0x10,ios_base::cur); // seeks through "PATTERNS " for normally created FTMs
version=get32le(ftmP);
int patsize=get32le(ftmP)+ftm.tellg();
while (ftm.tellg()<patsize){
int track=get32le(ftmP);
int channel=get32le(ftmP);
ftm.seekg(0x4,ios_base::cur);
int rowcount=get32le(ftmP);
for(int i=0;i<rowcount;i++){
ftm.seekg(0x6,ios_base::cur);
int newinst2=permute[ftm.peek()];
ftm.seekp(ftm.tellg(),ios_base::beg);
ftm.write(reinterpret_cast<char*>(&newinst2),1);
int pos2=ftm.tellg();
ftm.seekg(headerpos+(songs+1)*channel+track+1);
ftm.seekg(pos2+3+2*ftm.get());}}}
return 0;}
Comments
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|0 👍
/0 👎