mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-01 15:55:45 +00:00
added basic support for sounds playback in Amiga versions (only tested with the demos)
svn-id: r26837
This commit is contained in:
parent
e6ef2348a4
commit
b5aa521a75
@ -395,6 +395,18 @@ void loadSpl(const char *resourceName) {
|
||||
strcpy(animDataTable[entry].name, currentPartName);
|
||||
}
|
||||
|
||||
void loadSplAbs(const char *resourceName, uint16 idx) {
|
||||
int16 foundFileIdx;
|
||||
byte *dataPtr;
|
||||
int16 entry;
|
||||
|
||||
foundFileIdx = findFileInBundle(resourceName);
|
||||
dataPtr = readBundleFile(foundFileIdx);
|
||||
|
||||
entry = reserveFrame((uint16) partBuffer[foundFileIdx].unpackedSize, 1, 0, idx);
|
||||
memcpy(animDataTable[entry].ptr1, dataPtr, partBuffer[foundFileIdx].unpackedSize);
|
||||
}
|
||||
|
||||
void loadMsk(const char *resourceName) {
|
||||
int16 foundFileIdx;
|
||||
byte *dataPtr;
|
||||
@ -877,6 +889,7 @@ void loadAbs(const char *resourceName, uint16 idx) {
|
||||
loadSeqAbs(resourceName, idx);
|
||||
return;
|
||||
} else if (strstr(resourceName, ".SPL")) {
|
||||
loadSplAbs(resourceName, idx);
|
||||
return;
|
||||
} else if (strstr(resourceName, ".AMI")) {
|
||||
return;
|
||||
|
@ -95,10 +95,15 @@ int CineEngine::init() {
|
||||
_system->initSize(320, 200);
|
||||
_system->endGFXTransaction();
|
||||
|
||||
if (g_cine->getGameType() == GType_FW) {
|
||||
g_soundDriver = new AdlibSoundDriverINS(_mixer);
|
||||
if (g_cine->getPlatform() == Common::kPlatformPC) {
|
||||
if (g_cine->getGameType() == GType_FW) {
|
||||
g_soundDriver = new AdlibSoundDriverINS(_mixer);
|
||||
} else {
|
||||
g_soundDriver = new AdlibSoundDriverADL(_mixer);
|
||||
}
|
||||
} else {
|
||||
g_soundDriver = new AdlibSoundDriverADL(_mixer);
|
||||
// Paula chipset for Amiga and Atari versions
|
||||
g_soundDriver = new PaulaSoundDriver(_mixer);
|
||||
}
|
||||
g_sfxPlayer = new SfxPlayer(g_soundDriver);
|
||||
g_saveFileMan = _saveFileMan;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "cine/sfx_player.h"
|
||||
#include "cine/various.h"
|
||||
#include "cine/bg_list.h"
|
||||
#include "cine/sound_driver.h"
|
||||
|
||||
namespace Cine {
|
||||
|
||||
@ -156,6 +157,7 @@ void manageEvents(int count) {
|
||||
if (i % 2)
|
||||
g_system->updateScreen();
|
||||
g_system->delayMillis(10);
|
||||
g_soundDriver->update();
|
||||
manageEvents(0);
|
||||
}
|
||||
}
|
||||
|
@ -356,9 +356,9 @@ void setupOpcodes() {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
o1_playSample,
|
||||
o2_playSample,
|
||||
/* 78 */
|
||||
o2_op78,
|
||||
o2_playSampleAlt,
|
||||
o1_disableSystemMenu,
|
||||
o1_loadMask5,
|
||||
o1_unloadMask5,
|
||||
@ -1702,16 +1702,31 @@ void o1_loadMusic() {
|
||||
|
||||
void o1_playMusic() {
|
||||
debugC(5, kCineDebugScript, "Line: %d: playMusic()", _currentLine);
|
||||
if (g_cine->getPlatform() == Common::kPlatformAmiga ||
|
||||
g_cine->getPlatform() == Common::kPlatformAtariST) {
|
||||
warning("STUB: o1_playMusic");
|
||||
return;
|
||||
}
|
||||
g_sfxPlayer->play();
|
||||
}
|
||||
|
||||
void o1_fadeOutMusic() {
|
||||
debugC(5, kCineDebugScript, "Line: %d: fadeOutMusic()", _currentLine);
|
||||
if (g_cine->getPlatform() == Common::kPlatformAmiga ||
|
||||
g_cine->getPlatform() == Common::kPlatformAtariST) {
|
||||
warning("STUB: o1_fadeOutMusic");
|
||||
return;
|
||||
}
|
||||
g_sfxPlayer->fadeOut();
|
||||
}
|
||||
|
||||
void o1_stopSample() {
|
||||
debugC(5, kCineDebugScript, "Line: %d: stopSample()", _currentLine);
|
||||
if (g_cine->getPlatform() == Common::kPlatformAmiga ||
|
||||
g_cine->getPlatform() == Common::kPlatformAtariST) {
|
||||
warning("STUB: o1_stopSample");
|
||||
return;
|
||||
}
|
||||
g_sfxPlayer->stop();
|
||||
}
|
||||
|
||||
@ -1737,9 +1752,46 @@ void o1_op73() {
|
||||
getNextWord();
|
||||
}
|
||||
|
||||
void o1_playSampleAmiga() {
|
||||
int num = getNextByte();
|
||||
int channel = getNextByte();
|
||||
int freq = getNextWord();
|
||||
int repeat = getNextByte();
|
||||
int volume = getNextWord();
|
||||
int size = getNextWord();
|
||||
|
||||
if (size == 0xFFFF) {
|
||||
size = animDataTable[num].width * animDataTable[num].height;
|
||||
}
|
||||
|
||||
if (channel < 10) { // || _currentOpcode == 0x78
|
||||
int channel1, channel2;
|
||||
if (channel == 0) {
|
||||
channel1 = 0;
|
||||
channel2 = 1;
|
||||
} else {
|
||||
channel1 = 2;
|
||||
channel2 = 3;
|
||||
}
|
||||
((PaulaSoundDriver *)g_soundDriver)->queueSound(channel1, freq, animDataTable[num].ptr1, size, -1, volume, 63, repeat);
|
||||
((PaulaSoundDriver *)g_soundDriver)->queueSound(channel2, freq, animDataTable[num].ptr1, size, 1, volume, 0, repeat);
|
||||
} else {
|
||||
channel -= 10;
|
||||
if (volume > 63) {
|
||||
volume = 63;
|
||||
}
|
||||
((PaulaSoundDriver *)g_soundDriver)->queueSound(channel, freq, animDataTable[num].ptr1, size, 0, 0, volume, repeat);
|
||||
}
|
||||
}
|
||||
|
||||
void o1_playSample() {
|
||||
debugC(5, kCineDebugScript, "Line: %d: playSample()", _currentLine);
|
||||
|
||||
if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) {
|
||||
o1_playSampleAmiga();
|
||||
return;
|
||||
}
|
||||
|
||||
byte anim = getNextByte();
|
||||
byte channel = getNextByte();
|
||||
|
||||
@ -1749,12 +1801,6 @@ void o1_playSample() {
|
||||
int16 volume = getNextWord();
|
||||
uint16 flag = getNextWord();
|
||||
|
||||
if (g_cine->getPlatform() == Common::kPlatformAmiga ||
|
||||
g_cine->getPlatform() == Common::kPlatformAtariST) {
|
||||
warning("STUB: o1_playSample");
|
||||
return;
|
||||
}
|
||||
|
||||
if (volume > 63)
|
||||
volume = 63;
|
||||
if (volume < 0)
|
||||
@ -1771,7 +1817,7 @@ void o1_playSample() {
|
||||
g_sfxPlayer->stop();
|
||||
|
||||
if (flag == 0xFFFF) {
|
||||
g_soundDriver->playSound(animDataTable[anim].ptr1, channel, volume);
|
||||
g_soundDriver->playSound(animDataTable[anim].ptr1, 0, channel, volume);
|
||||
} else {
|
||||
g_soundDriver->resetChannel(channel);
|
||||
}
|
||||
@ -1809,12 +1855,37 @@ void o2_loadPart() {
|
||||
debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _currentLine, param);
|
||||
}
|
||||
|
||||
void o2_op78() {
|
||||
warning("STUB: o2_op78()");
|
||||
// This is probably wrong, but preserve the old behaviour for now.
|
||||
void o2_playSample() {
|
||||
if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) {
|
||||
// no-op in these versions
|
||||
_currentPosition += 9;
|
||||
return;
|
||||
}
|
||||
o1_playSample();
|
||||
}
|
||||
|
||||
void o2_playSampleAlt() {
|
||||
int num = getNextByte();
|
||||
int channel = getNextByte();
|
||||
int freq = getNextWord();
|
||||
getNextByte();
|
||||
getNextWord();
|
||||
int size = getNextWord();
|
||||
|
||||
if (size == 0xFFFF) {
|
||||
size = animDataTable[num].width * animDataTable[num].height;
|
||||
}
|
||||
if (animDataTable[num].ptr1) {
|
||||
if (g_cine->getPlatform() == Common::kPlatformPC) {
|
||||
// if speaker output is enabled, play sound on it
|
||||
// if it's another device, don't play anything
|
||||
} else {
|
||||
g_soundDriver->setChannelFrequency(channel, freq);
|
||||
g_soundDriver->playSound(animDataTable[num].ptr1, size, channel, 63);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void o2_addSeqListElement() {
|
||||
byte param1 = getNextByte();
|
||||
byte param2 = getNextByte();
|
||||
|
@ -146,7 +146,8 @@ void o1_unloadMask5();
|
||||
void o2_loadPart();
|
||||
void o2_addSeqListElement();
|
||||
void o2_removeSeq();
|
||||
void o2_op78();
|
||||
void o2_playSample();
|
||||
void o2_playSampleAlt();
|
||||
void o2_op81();
|
||||
void o2_op82();
|
||||
void o2_isSeqRunning();
|
||||
|
@ -283,7 +283,7 @@ void AdlibSoundDriverINS::setChannelFrequency(int channel, int frequency) {
|
||||
}
|
||||
}
|
||||
|
||||
void AdlibSoundDriverINS::playSound(const byte *data, int channel, int volume) {
|
||||
void AdlibSoundDriverINS::playSound(const byte *data, int size, int channel, int volume) {
|
||||
assert(channel < 4);
|
||||
_channelsVolumeTable[channel] = 127;
|
||||
resetChannel(channel);
|
||||
@ -356,7 +356,7 @@ void AdlibSoundDriverADL::setChannelFrequency(int channel, int frequency) {
|
||||
}
|
||||
}
|
||||
|
||||
void AdlibSoundDriverADL::playSound(const byte *data, int channel, int volume) {
|
||||
void AdlibSoundDriverADL::playSound(const byte *data, int size, int channel, int volume) {
|
||||
assert(channel < 4);
|
||||
_channelsVolumeTable[channel] = 127;
|
||||
setupInstrument(data, channel);
|
||||
@ -429,4 +429,71 @@ const int AdlibSoundDriver::_voiceOperatorsTable[] = {
|
||||
|
||||
const int AdlibSoundDriver::_voiceOperatorsTableCount = ARRAYSIZE(_voiceOperatorsTable);
|
||||
|
||||
|
||||
PaulaSoundDriver::PaulaSoundDriver(Audio::Mixer *mixer)
|
||||
: _mixer(mixer) {
|
||||
memset(_channelsFreqTable, 0, sizeof(_channelsFreqTable));
|
||||
memset(_soundsQueue, 0, sizeof(_soundsQueue));
|
||||
}
|
||||
|
||||
void PaulaSoundDriver::setupChannel(int channel, const byte *data, int instrument, int volume) {
|
||||
}
|
||||
|
||||
void PaulaSoundDriver::setChannelFrequency(int channel, int frequency) {
|
||||
assert(frequency > 0);
|
||||
_channelsFreqTable[channel] = PAULA_FREQ / frequency;
|
||||
}
|
||||
|
||||
void PaulaSoundDriver::stopChannel(int channel) {
|
||||
_mixer->stopHandle(_channelsTable[channel]);
|
||||
}
|
||||
|
||||
void PaulaSoundDriver::playSound(const byte *data, int size, int channel, int volume) {
|
||||
stopChannel(channel);
|
||||
size = MIN<int>(size - SPL_HDR_SIZE, READ_BE_UINT16(data + 4));
|
||||
data += SPL_HDR_SIZE;
|
||||
if (size > 0) {
|
||||
_mixer->playRaw(Audio::Mixer::kSFXSoundType, &_channelsTable[channel], const_cast<byte *>(data), size, _channelsFreqTable[channel], 0);
|
||||
_mixer->setChannelVolume(_channelsTable[channel], volume * Audio::Mixer::kMaxChannelVolume / 63);
|
||||
}
|
||||
}
|
||||
|
||||
void PaulaSoundDriver::stopSound() {
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
_mixer->stopHandle(_channelsTable[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void PaulaSoundDriver::queueSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat) {
|
||||
SoundQueue *sq = &_soundsQueue[channel];
|
||||
sq->freq = frequency;
|
||||
sq->data = data;
|
||||
sq->size = size;
|
||||
sq->volumeStep = volumeStep;
|
||||
sq->stepCount = stepCount;
|
||||
sq->step = stepCount;
|
||||
sq->repeat = repeat != 0;
|
||||
sq->volume = volume;
|
||||
}
|
||||
|
||||
void PaulaSoundDriver::update() {
|
||||
// process volume slides and start sound playback
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
SoundQueue *sq = &_soundsQueue[i];
|
||||
if (sq->data) {
|
||||
if (sq->step) {
|
||||
--sq->step;
|
||||
continue;
|
||||
}
|
||||
sq->step = sq->stepCount;
|
||||
sq->volume = CLIP(sq->volume + sq->volumeStep, 0, 63);
|
||||
setChannelFrequency(i, sq->freq);
|
||||
playSound(sq->data, sq->size, i, sq->volume);
|
||||
if (!sq->repeat) {
|
||||
sq->data = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Cine
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "sound/mixer.h"
|
||||
|
||||
namespace Cine {
|
||||
|
||||
|
||||
class SoundDriver {
|
||||
public:
|
||||
typedef void (*UpdateCallback)(void *);
|
||||
@ -40,9 +40,10 @@ public:
|
||||
virtual void setupChannel(int channel, const byte *data, int instrument, int volume) = 0;
|
||||
virtual void setChannelFrequency(int channel, int frequency) = 0;
|
||||
virtual void stopChannel(int channel) = 0;
|
||||
virtual void playSound(const byte *data, int channel, int volume) = 0;
|
||||
virtual void playSound(const byte *data, int size, int channel, int volume) = 0;
|
||||
virtual void stopSound() = 0;
|
||||
virtual const char *getInstrumentExtension() const = 0;
|
||||
virtual const char *getInstrumentExtension() const { return ""; }
|
||||
virtual void update() {}
|
||||
|
||||
void setUpdateCallback(UpdateCallback upCb, void *ref);
|
||||
void resetChannel(int channel);
|
||||
@ -123,7 +124,7 @@ public:
|
||||
virtual const char *getInstrumentExtension() const { return ".INS"; }
|
||||
virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi);
|
||||
virtual void setChannelFrequency(int channel, int frequency);
|
||||
virtual void playSound(const byte *data, int channel, int volume);
|
||||
virtual void playSound(const byte *data, int size, int channel, int volume);
|
||||
};
|
||||
|
||||
// Operation Stealth adlib driver
|
||||
@ -133,7 +134,45 @@ public:
|
||||
virtual const char *getInstrumentExtension() const { return ".ADL"; }
|
||||
virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi);
|
||||
virtual void setChannelFrequency(int channel, int frequency);
|
||||
virtual void playSound(const byte *data, int channel, int volume);
|
||||
virtual void playSound(const byte *data, int size, int channel, int volume);
|
||||
};
|
||||
|
||||
class PaulaSoundDriver : public SoundDriver {
|
||||
public:
|
||||
PaulaSoundDriver(Audio::Mixer *mixer);
|
||||
|
||||
virtual void setupChannel(int channel, const byte *data, int instrument, int volume);
|
||||
virtual void setChannelFrequency(int channel, int frequency);
|
||||
virtual void stopChannel(int channel);
|
||||
virtual void playSound(const byte *data, int size, int channel, int volume);
|
||||
virtual void stopSound();
|
||||
|
||||
// Future Wars specific
|
||||
void queueSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat);
|
||||
virtual void update();
|
||||
|
||||
enum {
|
||||
PAULA_FREQ = 7093789,
|
||||
NUM_CHANNELS = 4,
|
||||
SPL_HDR_SIZE = 22
|
||||
};
|
||||
|
||||
struct SoundQueue {
|
||||
int freq;
|
||||
const uint8 *data;
|
||||
int size;
|
||||
int volumeStep;
|
||||
int stepCount;
|
||||
int step;
|
||||
bool repeat;
|
||||
int volume;
|
||||
};
|
||||
|
||||
private:
|
||||
Audio::Mixer *_mixer;
|
||||
Audio::SoundHandle _channelsTable[NUM_CHANNELS];
|
||||
uint _channelsFreqTable[NUM_CHANNELS];
|
||||
SoundQueue _soundsQueue[NUM_CHANNELS];
|
||||
};
|
||||
|
||||
extern SoundDriver *g_soundDriver; // TEMP
|
||||
|
Loading…
x
Reference in New Issue
Block a user