mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- Added support for DRO version 2 files.
SVN r2349 (trunk)
This commit is contained in:
parent
9716e1aea7
commit
14b71ede11
2 changed files with 91 additions and 25 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue