IT import: comments, channel names and pat names
the latter two are MPT extensions this may not work on songs with MIDI macro setup info
This commit is contained in:
parent
7709640aa0
commit
d0c4fb0b42
|
@ -363,6 +363,103 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
||||||
patPtr[i]=reader.readI();
|
patPtr[i]=reader.readI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip edit history if present
|
||||||
|
if (special&2) {
|
||||||
|
logD("skipping edit history...");
|
||||||
|
unsigned short editHistSize=reader.readS();
|
||||||
|
if (editHistSize>0) {
|
||||||
|
if (!reader.seek(editHistSize*8,SEEK_CUR)) {
|
||||||
|
logV("what? I wasn't expecting that from you.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read extension blocks, if any
|
||||||
|
logD("looking for extensions...");
|
||||||
|
bool hasExtensions=true;
|
||||||
|
while (hasExtensions) {
|
||||||
|
char extType[4];
|
||||||
|
unsigned int extSize=0;
|
||||||
|
memset(extType,0,4);
|
||||||
|
|
||||||
|
reader.read(extType,4);
|
||||||
|
extSize=reader.readI();
|
||||||
|
|
||||||
|
if (memcmp(extType,"PNAM",4)==0) {
|
||||||
|
logV("found MPT extension: pattern names");
|
||||||
|
// check whether this block is valid
|
||||||
|
if (extSize>patCount*32) {
|
||||||
|
logV("block may not be valid");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// read pattern names
|
||||||
|
logV("reading pattern names...");
|
||||||
|
for (unsigned int i=0; i<(extSize>>5); i++) {
|
||||||
|
DivPattern* p=ds.subsong[0]->pat[0].getPattern(i,true);
|
||||||
|
p->name=reader.readStringLatin1(32);
|
||||||
|
}
|
||||||
|
} else if (memcmp(extType,"CNAM",4)==0) {
|
||||||
|
logV("found MPT extension: channel names");
|
||||||
|
// check whether this block is valid
|
||||||
|
if (extSize>DIV_MAX_CHANS*20) {
|
||||||
|
logV("block may not be valid");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// read channel names
|
||||||
|
logV("reading channel names...");
|
||||||
|
for (unsigned int i=0; i<(extSize>>5); i++) {
|
||||||
|
String chanName=reader.readStringLatin1(20);
|
||||||
|
for (DivSubSong* j: ds.subsong) {
|
||||||
|
j->chanName[i]=chanName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (memcmp(extType,"CHFX",4)==0) {
|
||||||
|
logV("found MPT extension: channel effects");
|
||||||
|
// skip (stop if we cannot seek)
|
||||||
|
if (!reader.seek(extSize,SEEK_CUR)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
extType[0]=='F' &&
|
||||||
|
(extType[1]=='X' || (extType[1]>='0' && extType[1]<='9')) &&
|
||||||
|
(extType[2]>='0' && extType[2]<='9') &&
|
||||||
|
(extType[3]>='0' && extType[3]<='9')
|
||||||
|
) { // effect slot
|
||||||
|
logV("found MPT extension: effect slot");
|
||||||
|
// skip (stop if we cannot seek)
|
||||||
|
if (!reader.seek(extSize,SEEK_CUR)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logV("no further extensions found... %.2x%.2x%.2x%.2x",extType[0],extType[1],extType[2],extType[3]);
|
||||||
|
hasExtensions=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read song comment
|
||||||
|
logD("reading song comment...");
|
||||||
|
if (reader.seek(commentPtr,SEEK_SET)) {
|
||||||
|
try {
|
||||||
|
String comment=reader.readStringLatin1Special(commentLen);
|
||||||
|
|
||||||
|
ds.notes="";
|
||||||
|
ds.notes.reserve(comment.size());
|
||||||
|
|
||||||
|
for (char& i: comment) {
|
||||||
|
if (i=='\r') {
|
||||||
|
ds.notes+='\n';
|
||||||
|
} else {
|
||||||
|
ds.notes+=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (EndOfFileException& e) {
|
||||||
|
logW("couldn't read song comment due to premature end of file.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logW("couldn't seek to comment!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// read instruments
|
// read instruments
|
||||||
for (int i=0; i<ds.insLen; i++) {
|
for (int i=0; i<ds.insLen; i++) {
|
||||||
DivInstrument* ins=new DivInstrument;
|
DivInstrument* ins=new DivInstrument;
|
||||||
|
|
|
@ -271,6 +271,15 @@ String SafeReader::readStringWithEncoding(DivStringEncoding encoding, size_t stl
|
||||||
ret.push_back(c);
|
ret.push_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (encoding==DIV_ENCODING_LATIN1_SPECIAL) {
|
||||||
|
if (c&0x80) {
|
||||||
|
if (c>=0xa0) {
|
||||||
|
ret.push_back(0xc0|(c>>6));
|
||||||
|
ret.push_back(0x80|(c&63));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret.push_back(c);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret.push_back(c);
|
ret.push_back(c);
|
||||||
}
|
}
|
||||||
|
@ -297,6 +306,15 @@ String SafeReader::readStringWithEncoding(DivStringEncoding encoding) {
|
||||||
ret.push_back(c);
|
ret.push_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (encoding==DIV_ENCODING_LATIN1_SPECIAL) {
|
||||||
|
if (c&0x80) {
|
||||||
|
if (c>=0xa0) {
|
||||||
|
ret.push_back(0xc0|(c>>6));
|
||||||
|
ret.push_back(0x80|(c&63));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret.push_back(c);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret.push_back(c);
|
ret.push_back(c);
|
||||||
}
|
}
|
||||||
|
@ -320,6 +338,14 @@ String SafeReader::readStringLatin1(size_t stlen) {
|
||||||
return readStringWithEncoding(DIV_ENCODING_LATIN1,stlen);
|
return readStringWithEncoding(DIV_ENCODING_LATIN1,stlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String SafeReader::readStringLatin1Special() {
|
||||||
|
return readStringWithEncoding(DIV_ENCODING_LATIN1_SPECIAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
String SafeReader::readStringLatin1Special(size_t stlen) {
|
||||||
|
return readStringWithEncoding(DIV_ENCODING_LATIN1_SPECIAL,stlen);
|
||||||
|
}
|
||||||
|
|
||||||
String SafeReader::readStringLine() {
|
String SafeReader::readStringLine() {
|
||||||
String ret;
|
String ret;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
|
|
@ -33,6 +33,7 @@ enum DivStringEncoding {
|
||||||
DIV_ENCODING_NONE=0,
|
DIV_ENCODING_NONE=0,
|
||||||
DIV_ENCODING_UTF8,
|
DIV_ENCODING_UTF8,
|
||||||
DIV_ENCODING_LATIN1,
|
DIV_ENCODING_LATIN1,
|
||||||
|
DIV_ENCODING_LATIN1_SPECIAL,
|
||||||
DIV_ENCODING_SHIFT_JIS
|
DIV_ENCODING_SHIFT_JIS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,6 +78,8 @@ class SafeReader {
|
||||||
String readString(size_t len);
|
String readString(size_t len);
|
||||||
String readStringLatin1();
|
String readStringLatin1();
|
||||||
String readStringLatin1(size_t len);
|
String readStringLatin1(size_t len);
|
||||||
|
String readStringLatin1Special();
|
||||||
|
String readStringLatin1Special(size_t len);
|
||||||
String readStringLine();
|
String readStringLine();
|
||||||
String readStringToken(unsigned char delim, bool stripContiguous);
|
String readStringToken(unsigned char delim, bool stripContiguous);
|
||||||
String readStringToken();
|
String readStringToken();
|
||||||
|
|
Loading…
Reference in a new issue