Initial commit
This commit is contained in:
283
engines/scumm/he/sound_he.h
Normal file
283
engines/scumm/he/sound_he.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SCUMM_HE_SOUND_HE_H
|
||||
#define SCUMM_HE_SOUND_HE_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/mutex.h"
|
||||
#include "scumm/sound.h"
|
||||
#include "scumm/he/mixer_he.h"
|
||||
#include "audio/audiostream.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
#define HSND_DYN_SOUND_CHAN -1
|
||||
#define HSND_TALKIE_SLOT 1
|
||||
#define HSND_SOUND_STOPPED 1
|
||||
#define HSND_SOUND_ENDED 2
|
||||
#define HSND_SOUND_TIMEOUT 3
|
||||
#define HSND_TIMER_SLOT 4
|
||||
#define HSND_MAX_CALLBACK_SCRIPTS 20
|
||||
#define HSND_MAX_CHANNELS 8
|
||||
#define HSND_CHANNEL_0 10000
|
||||
#define HSND_CHANNEL_1 10001
|
||||
#define HSND_CHANNEL_2 10002
|
||||
#define HSND_CHANNEL_3 10003
|
||||
#define HSND_CHANNEL_4 10004
|
||||
#define HSND_CHANNEL_5 10005
|
||||
#define HSND_CHANNEL_6 10006
|
||||
#define HSND_CHANNEL_7 10007
|
||||
#define HSND_MAX_SOUND_VARS 26
|
||||
#define HSND_DEFAULT_FREQUENCY 11025
|
||||
#define HSND_BASE_FREQ_FACTOR 1024
|
||||
#define HSND_SOUND_FREQ_BASE 1024
|
||||
#define HSND_MAX_VOLUME 255
|
||||
#define HSND_SOUND_PAN_LEFT 0
|
||||
#define HSND_SOUND_PAN_CENTER 64
|
||||
#define HSND_SOUND_PAN_RIGHT 127
|
||||
#define HSND_FIRST_SPOOLING_SOUND 4000
|
||||
#define HSND_MAX_FREQ_RATIO 4
|
||||
|
||||
#define HSND_MAX_SPOOLING_CODE_SIZE 16384
|
||||
|
||||
#define HSND_SBNG_TYPE_ALL 0xF8
|
||||
#define HSND_SBNG_DATA_ALL 0x07
|
||||
|
||||
#define HSND_SBNG_MAGIC_NUMBER 0x2000
|
||||
#define HSND_SBNG_MAGIC_MASK 0xF000
|
||||
|
||||
#define HSND_SBNG_END 0x00
|
||||
#define HSND_SBNG_FACE 0x10
|
||||
#define HSND_SBNG_SET_SET 0x20
|
||||
#define HSND_SBNG_SET_ADD 0x30
|
||||
#define HSND_SBNG_SET_SUB 0x38
|
||||
#define HSND_SBNG_SET_MUL 0x40
|
||||
#define HSND_SBNG_SET_DIV 0x50
|
||||
#define HSND_SBNG_SET_INC 0x60
|
||||
#define HSND_SBNG_SET_DEC 0x68
|
||||
#define HSND_SBNG_VARORVAL 0x03
|
||||
#define HSND_SBNG_VARVAL 0x02
|
||||
|
||||
#define HSND_SNDVAR_TOKENS 26
|
||||
|
||||
#define XSH2_FLAG_HAS_PRIORITY 0x01
|
||||
|
||||
#define WAVE_FORMAT_PCM 1
|
||||
#define WAVE_FORMAT_IMA_ADPCM 17
|
||||
#define WAVE_RIFF_HEADER_LEN 44
|
||||
|
||||
#define HSND_RES_OFFSET_ID1 0 // uint32, DIGI or MIDI header
|
||||
#define HSND_RES_OFFSET_LEN1 4 // uint32
|
||||
#define HSND_RES_OFFSET_ID 8 // uint32, HSHD header
|
||||
#define HSND_RES_OFFSET_LEN2 12 // uint32
|
||||
#define HSND_RES_OFFSET_COMPRESSED 16 // uint8, header data
|
||||
#define HSND_RES_OFFSET_FORMATTED 17 // uint8
|
||||
#define HSND_RES_OFFSET_KILL_PRIO 18 // uint8
|
||||
#define HSND_RES_OFFSET_DEAD_PRIO 19 // uint8
|
||||
#define HSND_RES_OFFSET_LEFT_VOLUME 20 // uint8
|
||||
#define HSND_RES_OFFSET_RIGHT_VOLUME 21 // uint8
|
||||
#define HSND_RES_OFFSET_FREQUENCY 22 // uint16
|
||||
#define HSND_RES_OFFSET_MONDO_OFFSET 24 // uint32
|
||||
#define HSND_RES_OFFSET_BITS_PER_SAMPLE 28 // uint8
|
||||
#define HSND_RES_OFFSET_SAMPLE_CHANNELS 29 // uint8
|
||||
#define HSND_RES_OFFSET_UNUSED3 30 // uint8
|
||||
#define HSND_RES_OFFSET_UNUSED4 31 // uint8
|
||||
#define HSND_RES_OFFSET_ID3 32 // uint32, SDAT header
|
||||
#define HSND_RES_OFFSET_LEN3 36 // uint32
|
||||
#define HSND_RES_OFFSET_SOUND_DATA 40
|
||||
|
||||
// Used both in SoundHE and HEMixer
|
||||
struct HESoundModifiers {
|
||||
HESoundModifiers(int mFrequencyShift, int mPan, int mVolume) {
|
||||
// Hey, turns out Moonbase Commander just LOVES sending out invalid modifiers :-)
|
||||
/*
|
||||
assert(mFrequencyShift >= HSND_SOUND_FREQ_BASE / HSND_MAX_FREQ_RATIO);
|
||||
assert(mFrequencyShift <= HSND_SOUND_FREQ_BASE * HSND_MAX_FREQ_RATIO);
|
||||
assert(mPan >= HSND_SOUND_PAN_LEFT && mPan <= HSND_SOUND_PAN_RIGHT);
|
||||
assert(mVolume >= 0 && mVolume <= HSND_MAX_VOLUME);
|
||||
*/
|
||||
|
||||
frequencyShift = mFrequencyShift;
|
||||
pan = mPan;
|
||||
volume = mVolume;
|
||||
}
|
||||
|
||||
HESoundModifiers() {
|
||||
frequencyShift = HSND_SOUND_FREQ_BASE;
|
||||
pan = HSND_SOUND_PAN_CENTER;
|
||||
volume = HSND_MAX_VOLUME;
|
||||
}
|
||||
|
||||
int frequencyShift;
|
||||
int pan;
|
||||
int volume;
|
||||
};
|
||||
|
||||
|
||||
struct HESpoolingMusicItem {
|
||||
int32 song;
|
||||
int32 offset;
|
||||
int32 size;
|
||||
|
||||
char filename[128];
|
||||
};
|
||||
|
||||
class ScummEngine_v60he;
|
||||
class HEMixer;
|
||||
|
||||
class SoundHE : public Sound {
|
||||
friend class HEMixer;
|
||||
|
||||
protected:
|
||||
ScummEngine_v60he *_vm;
|
||||
|
||||
int _overrideFreq;
|
||||
Common::Mutex *_mutex;
|
||||
HEMixer *_heMixer;
|
||||
|
||||
struct HESoundCallbackItem {
|
||||
int32 sound;
|
||||
int32 channel;
|
||||
int32 whatFrame;
|
||||
};
|
||||
HESoundCallbackItem _soundCallbackScripts[HSND_MAX_CALLBACK_SCRIPTS];
|
||||
|
||||
HESpoolingMusicItem *_heSpoolingMusicTable;
|
||||
|
||||
struct PCMWaveFormat {
|
||||
uint16 wFormatTag;
|
||||
uint16 wChannels;
|
||||
uint32 dwSamplesPerSec;
|
||||
uint32 dwAvgBytesPerSec;
|
||||
uint16 wBlockAlign;
|
||||
uint16 wBitsPerSample;
|
||||
};
|
||||
|
||||
int32 _heSpoolingMusicCount;
|
||||
Common::File _heSpoolingMusicFile;
|
||||
byte _heSpoolingCodeBuffer[HSND_MAX_SPOOLING_CODE_SIZE];
|
||||
|
||||
public: // Used by createSound()
|
||||
struct {
|
||||
int sound;
|
||||
int codeOffset;
|
||||
byte *codeBuffer;
|
||||
int priority;
|
||||
int frequency;
|
||||
int timeout;
|
||||
bool hasSoundTokens;
|
||||
int soundVars[HSND_MAX_SOUND_VARS];
|
||||
int age;
|
||||
|
||||
void clearChannel() {
|
||||
sound = 0;
|
||||
codeOffset = 0;
|
||||
codeBuffer = nullptr;
|
||||
priority = 0;
|
||||
frequency = 0;
|
||||
timeout = 0;
|
||||
hasSoundTokens = false;
|
||||
memset(soundVars, 0, sizeof(soundVars));
|
||||
age = 0;
|
||||
}
|
||||
|
||||
} _heChannel[HSND_MAX_CHANNELS];
|
||||
|
||||
// Used throughout script functions
|
||||
int32 _createSndId;
|
||||
int32 _createSndLastAppend;
|
||||
int32 _createSndLastPos;
|
||||
int32 _baseSndSize;
|
||||
|
||||
public:
|
||||
SoundHE(ScummEngine *parent, Audio::Mixer *mixer, Common::Mutex *mutex);
|
||||
~SoundHE() override;
|
||||
|
||||
void startSound(int sound, int heOffset = 0, int heChannel = 0, int heFlags = 0, int heFreq = 0, int hePan = 0, int heVol = 0) override;
|
||||
void addSoundToQueue(int sound, int heOffset = 0, int heChannel = 0, int heFlags = 0, int heFreq = 0, int hePan = 0, int heVol = 0) override;
|
||||
void modifySound(int sound, int offset, int frequencyShift, int pan, int volume, int flags) override;
|
||||
|
||||
int isSoundRunning(int sound) const override;
|
||||
bool isSoundInUse(int sound) const override;
|
||||
void stopSound(int sound) override;
|
||||
void stopAllSounds() override;
|
||||
int hsFindSoundChannel(int sound) const;
|
||||
void setupSound() override;
|
||||
void pauseSounds(bool pause) override;
|
||||
|
||||
bool getHEMusicDetails(int id, int &musicOffs, int &musicSize);
|
||||
int getNextDynamicChannel();
|
||||
bool isSoundCodeUsed(int sound);
|
||||
int getSoundPosition(int sound);
|
||||
int getSoundVar(int sound, int var);
|
||||
void setSoundVar(int sound, int var, int val);
|
||||
void setSoundVolume(int sound, int volume);
|
||||
void triggerSound(int soundId, int heOffset, int heChannel, int heFlags, HESoundModifiers modifiers);
|
||||
void triggerSpoolingSound(int soundId, int heOffset, int heChannel, int heFlags, HESoundModifiers modifiers);
|
||||
void triggerDigitalSound(int soundId, int heOffset, int heChannel, int heFlags);
|
||||
void triggerMidiSound(int soundId, int heOffset);
|
||||
void triggerRIFFSound(int soundId, int heOffset, int heChannel, int heFlags, HESoundModifiers modifiers);
|
||||
void triggerXSOUSound(int soundId, int heOffset, int heChannel, int heFlags);
|
||||
|
||||
void hsStartDigitalSound(int sound, int offset, byte *addr, int sound_data, int globType, int globNum,
|
||||
int sampleCount, int frequency, int channel, int priority, int soundCode,
|
||||
int flags, int bitsPerSample, int soundChannelCount, HESoundModifiers modifiers);
|
||||
void hsStopDigitalSound(int sound);
|
||||
|
||||
void handleSoundFrame();
|
||||
void feedMixer();
|
||||
void unqueueSoundCallbackScripts();
|
||||
void checkSoundTimeouts();
|
||||
void digitalSoundCallback(int message, int channel, bool earlyCallback = false);
|
||||
void queueSoundCallbackScript(int sound, int channel, int message);
|
||||
void runSoundCode();
|
||||
void processSoundOpcodes(int sound, byte *codePtr, int *soundVars);
|
||||
void setOverrideFreq(int freq);
|
||||
void setupHEMusicFile();
|
||||
void playVoice(uint32 offset, uint32 length);
|
||||
void playVoiceFile(char *filename);
|
||||
void stopDigitalSound(int sound);
|
||||
void createSound(int snd1id, int snd2id);
|
||||
int getChannelPosition(int channel);
|
||||
|
||||
const byte *findWavBlock(uint32 tag, const byte *block);
|
||||
int getCurrentSpeechOffset();
|
||||
bool is3DOSound(int sound) const;
|
||||
|
||||
protected:
|
||||
void processSoundQueues() override;
|
||||
|
||||
private:
|
||||
int _heTalkOffset = 0;
|
||||
bool _stopActorTalkingFlag = false;
|
||||
bool _inSoundCallbackFlag = false;
|
||||
int _soundCallbacksQueueSize = 0;
|
||||
int _soundAlreadyInQueueCount = 0;
|
||||
int _inUnqueueCallbackScripts = 0;
|
||||
int _soundsDebugFrameCounter = 0;
|
||||
int _dynamicSoundAgeCounter = 0;
|
||||
};
|
||||
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user