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();
|
||||
}
|
||||
|
||||
// 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
|
||||
for (int i=0; i<ds.insLen; i++) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
|
|
|
@ -271,6 +271,15 @@ String SafeReader::readStringWithEncoding(DivStringEncoding encoding, size_t stl
|
|||
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 {
|
||||
ret.push_back(c);
|
||||
}
|
||||
|
@ -297,6 +306,15 @@ String SafeReader::readStringWithEncoding(DivStringEncoding encoding) {
|
|||
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 {
|
||||
ret.push_back(c);
|
||||
}
|
||||
|
@ -320,6 +338,14 @@ String SafeReader::readStringLatin1(size_t 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 ret;
|
||||
unsigned char c;
|
||||
|
|
|
@ -33,6 +33,7 @@ enum DivStringEncoding {
|
|||
DIV_ENCODING_NONE=0,
|
||||
DIV_ENCODING_UTF8,
|
||||
DIV_ENCODING_LATIN1,
|
||||
DIV_ENCODING_LATIN1_SPECIAL,
|
||||
DIV_ENCODING_SHIFT_JIS
|
||||
};
|
||||
|
||||
|
@ -77,6 +78,8 @@ class SafeReader {
|
|||
String readString(size_t len);
|
||||
String readStringLatin1();
|
||||
String readStringLatin1(size_t len);
|
||||
String readStringLatin1Special();
|
||||
String readStringLatin1Special(size_t len);
|
||||
String readStringLine();
|
||||
String readStringToken(unsigned char delim, bool stripContiguous);
|
||||
String readStringToken();
|
||||
|
|
Loading…
Reference in a new issue