Initial commit
This commit is contained in:
222
engines/agos/sfxparser_accolade.h
Normal file
222
engines/agos/sfxparser_accolade.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/* 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 AGOS_SFXPARSER_ACCOLADE_H
|
||||
#define AGOS_SFXPARSER_ACCOLADE_H
|
||||
|
||||
#include "agos/drivers/accolade/adlib.h"
|
||||
#include "agos/drivers/accolade/mt32.h"
|
||||
|
||||
#include "common/mutex.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace AGOS {
|
||||
|
||||
class SfxParser_Accolade {
|
||||
public:
|
||||
// Size in bytes of MT-32 instrument data in the SFX data.
|
||||
static const byte INSTRUMENT_SIZE_MT32 = 0xF9;
|
||||
// Number of script ticks per second.
|
||||
static const uint16 SCRIPT_TIMER_FREQUENCY = 292;
|
||||
// Number of microseconds per script tick.
|
||||
static const uint16 SCRIPT_TIMER_RATE = 1000000 / SCRIPT_TIMER_FREQUENCY;
|
||||
|
||||
protected:
|
||||
// Size in bytes of AdLib instrument data in the SFX data.
|
||||
static const byte INSTRUMENT_SIZE_ADLIB = 0x09;
|
||||
// Maximum number of words in an SFX script.
|
||||
static const byte MAX_SCRIPT_SIZE = 0x30;
|
||||
// Maximum number of simultaneous sources for OPL2.
|
||||
static const byte OPL2_NUM_SOURCES = 2;
|
||||
// Maximum number of simultaneous sources for OPL3.
|
||||
static const byte OPL3_NUM_SOURCES = 4;
|
||||
|
||||
// Data for a single SFX. Taken from the game's SFX bank.
|
||||
struct SfxData {
|
||||
// The instrument data for the used sound device (OPL or MT-32).
|
||||
byte instrumentDefinition[INSTRUMENT_SIZE_MT32];
|
||||
// The SFX script.
|
||||
int16 scriptData[MAX_SCRIPT_SIZE];
|
||||
// The size in words of the SFX script.
|
||||
int scriptSize;
|
||||
};
|
||||
|
||||
// State data a SFX playback slot.
|
||||
struct SfxSlot {
|
||||
SfxSlot();
|
||||
|
||||
// The data of the SFX currently played by this slot.
|
||||
SfxData *sfxData;
|
||||
|
||||
// True if this slot has been allocated to playing a SFX.
|
||||
bool allocated;
|
||||
// True if SFX playback is active.
|
||||
bool active;
|
||||
// The source used to send data to the MIDI driver.
|
||||
int8 source;
|
||||
// Current position in the SFX script.
|
||||
byte scriptPos;
|
||||
|
||||
// Current playback time in microseconds.
|
||||
uint32 playTime;
|
||||
// The timestamp of the last processed script tick.
|
||||
uint32 lastEventTime;
|
||||
// The last MIDI note that was sent as a note on event.
|
||||
int16 lastPlayedNote;
|
||||
// The current MIDI note (upper byte) and note fraction (1/256th notes;
|
||||
// lower byte) value.
|
||||
uint16 currentNoteFraction;
|
||||
// True if the allocated channel on the MIDI device has been changed to
|
||||
// the SFX instrument.
|
||||
bool programChanged;
|
||||
|
||||
// Delta to the note fraction. This is added to/subtracted from the
|
||||
// note fraction every script tick.
|
||||
int16 noteFractionDelta;
|
||||
// The vibrato time. The number of script ticks it takes for the note
|
||||
// difference to go from lowest to highest (or the other way around).
|
||||
int16 vibratoTime;
|
||||
// The number of script ticks that have passed since the vibrato has
|
||||
// started.
|
||||
int16 vibratoCounter;
|
||||
// Vibrato delta to the note fraction. This is added to/subtracted
|
||||
// from the note fraction every script tick.
|
||||
int16 vibratoDelta;
|
||||
// The number of ticks that remain before the next script event is
|
||||
// processed.
|
||||
int16 waitCounter;
|
||||
// The script position at which the current loop has started.
|
||||
byte loopStart;
|
||||
// The number of times the looped section will be repeated (-1 for
|
||||
// infinite loop).
|
||||
int16 loopCounter;
|
||||
|
||||
// Completely clears the SFX slot data.
|
||||
void clear();
|
||||
// Resets the SFX slot data as needed by the reset opcode.
|
||||
void reset();
|
||||
// True if the current position is at the end of the script.
|
||||
bool atEndOfScript();
|
||||
// Reads the next script word. Specify the opCode flag to return a
|
||||
// valid opcode.
|
||||
int16 readScript(bool opCode);
|
||||
};
|
||||
|
||||
public:
|
||||
SfxParser_Accolade();
|
||||
virtual ~SfxParser_Accolade();
|
||||
|
||||
// Loads the specified sound effects bank (FXB file).
|
||||
void load(Common::SeekableReadStream *in, int32 size);
|
||||
|
||||
// Sets the MIDI driver that should be used to output the SFX.
|
||||
virtual void setMidiDriver(MidiDriver_Multisource *driver) = 0;
|
||||
// Sets the number of microseconds between timer callbacks.
|
||||
void setTimerRate(uint32 rate);
|
||||
|
||||
// Starts playback of the specified sound effect.
|
||||
void play(uint8 sfxNumber);
|
||||
// Stops all active SFX.
|
||||
void stopAll();
|
||||
// Pauses or unpauses all active SFX.
|
||||
void pauseAll(bool paused);
|
||||
|
||||
void onTimer();
|
||||
static void timerCallback(void *data);
|
||||
|
||||
protected:
|
||||
// Stops the sound effect playing in the specified slot.
|
||||
void stop(SfxSlot *sfxSlot);
|
||||
// Processes the specified opcode for the specified slot.
|
||||
void processOpCode(SfxSlot *sfxSlot, byte opCode);
|
||||
|
||||
// Returns the number of sources available for SFX playback.
|
||||
virtual byte getNumberOfSfxSources() = 0;
|
||||
// Reads the SFX instrument data into the specified SfxData from the
|
||||
// specified SFX bank data. This is positioned at the start of the data of
|
||||
// a sound effect in the bank; when the function returns is should be
|
||||
// positioned right after all instrument data for the sound effect.
|
||||
virtual void readInstrument(SfxData *sfxData, Common::SeekableReadStream *in) = 0;
|
||||
|
||||
// Loads the SFX instrument for the specified slot into the channel
|
||||
// allocated to the sound effect. Returns true if the channel needs to be
|
||||
// changed to the new instrument when the driver is ready.
|
||||
virtual bool loadInstrument(SfxSlot *sfxSlot) = 0;
|
||||
// Changes the channel allocated to the sound effect to the SFX instrument.
|
||||
virtual void changeInstrument(SfxSlot *sfxSlot) { };
|
||||
// Starts a note at the current note / note fraction for the slot.
|
||||
virtual void noteOn(SfxSlot *sfxSlot);
|
||||
// Stops the current note for the slot.
|
||||
virtual void noteOff(SfxSlot *sfxSlot);
|
||||
// Updates the note / note fraction for the slot.
|
||||
virtual void updateNote(SfxSlot *sfxSlot) { };
|
||||
|
||||
Common::Mutex _mutex;
|
||||
|
||||
MidiDriver_Multisource *_driver;
|
||||
uint32 _timerRate;
|
||||
|
||||
// Array of SFX data loaded from the SFX bank.
|
||||
SfxData *_sfxData;
|
||||
// The number of SFX data loaded.
|
||||
uint16 _numSfx;
|
||||
// The slots available for SFX playback.
|
||||
SfxSlot _sfxSlots[4];
|
||||
// The slot numbers allocated to the available SFX sources. -1 if no slot
|
||||
// is using the source.
|
||||
int8 _sourceAllocations[4];
|
||||
|
||||
// True if SFX playback is paused.
|
||||
bool _paused;
|
||||
};
|
||||
|
||||
class SfxParser_Accolade_AdLib : public SfxParser_Accolade {
|
||||
public:
|
||||
SfxParser_Accolade_AdLib() : _adLibDriver(nullptr) { }
|
||||
|
||||
protected:
|
||||
void setMidiDriver(MidiDriver_Multisource *driver) override;
|
||||
byte getNumberOfSfxSources() override;
|
||||
void readInstrument(SfxData *sfxData, Common::SeekableReadStream *in) override;
|
||||
bool loadInstrument(SfxSlot *sfxSlot) override;
|
||||
void noteOn(SfxSlot *sfxSlot) override;
|
||||
void updateNote(SfxSlot *sfxSlot) override;
|
||||
|
||||
MidiDriver_Accolade_AdLib *_adLibDriver;
|
||||
};
|
||||
|
||||
class SfxParser_Accolade_MT32 : public SfxParser_Accolade {
|
||||
public:
|
||||
SfxParser_Accolade_MT32() : _mt32Driver(nullptr) { }
|
||||
|
||||
protected:
|
||||
void setMidiDriver(MidiDriver_Multisource *driver) override;
|
||||
byte getNumberOfSfxSources() override;
|
||||
void readInstrument(SfxData *sfxData, Common::SeekableReadStream *in) override;
|
||||
bool loadInstrument(SfxSlot *sfxSlot) override;
|
||||
void changeInstrument(SfxSlot *sfxSlot) override;
|
||||
|
||||
MidiDriver_Accolade_MT32 *_mt32Driver;
|
||||
};
|
||||
|
||||
} // End of namespace AGOS
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user