- Added support for DRO version 2 files.

SVN r2349 (trunk)
This commit is contained in:
Randy Heit 2010-05-30 19:23:53 +00:00
parent 9716e1aea7
commit 14b71ede11
2 changed files with 91 additions and 25 deletions

View file

@ -66,7 +66,7 @@ OPLmusicFile::OPLmusicFile (FILE *file, BYTE *musiccache, int len)
{ {
if (fread (scoredata, 1, len, file) != (size_t)len) if (fread (scoredata, 1, len, file) != (size_t)len)
{ {
delete[] scoredata; fail: delete[] scoredata;
scoredata = NULL; scoredata = NULL;
return; return;
} }
@ -78,9 +78,7 @@ OPLmusicFile::OPLmusicFile (FILE *file, BYTE *musiccache, int len)
if (io->OPLinit (TwoChips + 1)) if (io->OPLinit (TwoChips + 1))
{ {
delete[] scoredata; goto fail;
scoredata = NULL;
return;
} }
// Check for RDosPlay raw OPL format // Check for RDosPlay raw OPL format
@ -96,12 +94,36 @@ OPLmusicFile::OPLmusicFile (FILE *file, BYTE *musiccache, int len)
} }
// Check for DosBox OPL dump // Check for DosBox OPL dump
else if (((DWORD *)scoredata)[0] == MAKE_ID('D','B','R','A') && else if (((DWORD *)scoredata)[0] == MAKE_ID('D','B','R','A') &&
((DWORD *)scoredata)[1] == MAKE_ID('W','O','P','L') && ((DWORD *)scoredata)[1] == MAKE_ID('W','O','P','L'))
((DWORD *)scoredata)[2] == MAKE_ID(0,0,1,0))
{ {
RawPlayer = DosBox; if (((DWORD *)scoredata)[2] == MAKE_ID(0,0,1,0))
{
RawPlayer = DosBox1;
SamplesPerTick = OPL_SAMPLE_RATE / 1000; SamplesPerTick = OPL_SAMPLE_RATE / 1000;
ScoreLen = MIN<int>(len - 24, LittleLong(((DWORD *)scoredata)[4])); ScoreLen = MIN<int>(len - 24, LittleLong(((DWORD *)scoredata)[4])) + 24;
}
else if (((DWORD *)scoredata)[2] == MAKE_ID(2,0,0,0))
{
if (scoredata[20] != 0)
{
Printf("Unsupported DOSBox Raw OPL format %d\n", scoredata[20]);
goto fail;
}
if (scoredata[21] != 0)
{
Printf("Unsupported DOSBox Raw OPL compression %d\n", scoredata[21]);
goto fail;
}
RawPlayer = DosBox2;
SamplesPerTick = OPL_SAMPLE_RATE / 1000;
int headersize = 0x1A + scoredata[0x19];
ScoreLen = MIN<int>(len - headersize, LittleLong(((DWORD *)scoredata)[3]) * 2) + headersize;
}
else
{
Printf("Unsupported DOSBox Raw OPL version %d.%d\n", LittleShort(((WORD *)scoredata)[4]), LittleShort(((WORD *)scoredata)[5]));
goto fail;
}
} }
// Check for modified IMF format (includes a header) // Check for modified IMF format (includes a header)
else if (((DWORD *)scoredata)[0] == MAKE_ID('A','D','L','I') && else if (((DWORD *)scoredata)[0] == MAKE_ID('A','D','L','I') &&
@ -131,6 +153,10 @@ OPLmusicFile::OPLmusicFile (FILE *file, BYTE *musiccache, int len)
ScoreLen = songlen + int(score - scoredata); ScoreLen = songlen + int(score - scoredata);
} }
} }
else
{
goto fail;
}
Restart (); Restart ();
} }
@ -159,18 +185,24 @@ void OPLmusicFile::Restart ()
{ {
OPLmusicBlock::Restart(); OPLmusicBlock::Restart();
WhichChip = 0; WhichChip = 0;
if (RawPlayer == RDosPlay) switch (RawPlayer)
{ {
case RDosPlay:
score = scoredata + 10; score = scoredata + 10;
SamplesPerTick = LittleShort(*(WORD *)(scoredata + 8)) / ADLIB_CLOCK_MUL; SamplesPerTick = LittleShort(*(WORD *)(scoredata + 8)) / ADLIB_CLOCK_MUL;
} break;
else if (RawPlayer == DosBox)
{ case DosBox1:
score = scoredata + 24; score = scoredata + 24;
SamplesPerTick = OPL_SAMPLE_RATE / 1000; SamplesPerTick = OPL_SAMPLE_RATE / 1000;
} break;
else if (RawPlayer == IMF)
{ case DosBox2:
score = scoredata + 0x1A + scoredata[0x19];
SamplesPerTick = OPL_SAMPLE_RATE / 1000;
break;
case IMF:
score = scoredata + 6; score = scoredata + 6;
// Skip track and game name // Skip track and game name
@ -183,6 +215,7 @@ void OPLmusicFile::Restart ()
{ {
score += 4; // Skip song length score += 4; // Skip song length
} }
break;
} }
io->SetClockRate(SamplesPerTick); io->SetClockRate(SamplesPerTick);
} }
@ -331,9 +364,11 @@ void OPLmusicBlock::OffsetSamples(float *buff, int count)
int OPLmusicFile::PlayTick () int OPLmusicFile::PlayTick ()
{ {
BYTE reg, data; BYTE reg, data;
WORD delay;
if (RawPlayer == RDosPlay) switch (RawPlayer)
{ {
case RDosPlay:
while (score < scoredata + ScoreLen) while (score < scoredata + ScoreLen)
{ {
data = *score++; data = *score++;
@ -379,9 +414,9 @@ int OPLmusicFile::PlayTick ()
break; break;
} }
} }
} break;
else if (RawPlayer == DosBox)
{ case DosBox1:
while (score < scoredata + ScoreLen) while (score < scoredata + ScoreLen)
{ {
reg = *score++; reg = *score++;
@ -420,11 +455,42 @@ int OPLmusicFile::PlayTick ()
io->OPLwriteReg(WhichChip, reg, data); io->OPLwriteReg(WhichChip, reg, data);
} }
} }
} break;
else if (RawPlayer == IMF)
{
WORD delay = 0;
case DosBox2:
{
BYTE *to_reg = scoredata + 0x1A;
BYTE to_reg_size = scoredata[0x19];
BYTE short_delay_code = scoredata[0x17];
BYTE long_delay_code = scoredata[0x18];
while (score < scoredata + ScoreLen)
{
BYTE code = *score++;
data = *score++;
// Which OPL chip to write to is encoded in the high bit of the code value.
int which = !!(code & 0x80);
code &= 0x7F;
if (code == short_delay_code)
{
return data + 1;
}
else if (code == long_delay_code)
{
return (data + 1) << 8;
}
else if (code < to_reg_size && (which = 0 || TwoChips))
{
io->OPLwriteReg(which, to_reg[code], data);
}
}
}
break;
case IMF:
delay = 0;
while (delay == 0 && score + 4 - scoredata <= ScoreLen) while (delay == 0 && score + 4 - scoredata <= ScoreLen)
{ {
if (*(DWORD *)score == 0xFFFFFFFF) if (*(DWORD *)score == 0xFFFFFFFF)

View file

@ -41,7 +41,7 @@ protected:
OPLmusicFile() {} OPLmusicFile() {}
int PlayTick(); int PlayTick();
enum { RDosPlay, IMF, DosBox } RawPlayer; enum { RDosPlay, IMF, DosBox1, DosBox2 } RawPlayer;
int ScoreLen; int ScoreLen;
int WhichChip; int WhichChip;
}; };