scummvm/engines/scumm/player_sid.h
2010-03-22 20:28:08 +00:00

281 lines
7.0 KiB
C++

/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef SCUMM_PLAYER_SID_H
#define SCUMM_PLAYER_SID_H
#include "common/mutex.h"
#include "common/scummsys.h"
#include "scumm/music.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
#include "sound/softsynth/sid.h"
namespace Scumm {
// the "channel" parameters seem to be in fact SID register
// offsets. Should be replaced.
enum sid_reg_t {
FREQ_VOICE1,
FREQ_VOICE2,
FREQ_VOICE3,
FREQ_FILTER,
PULSE_VOICE1,
PULSE_VOICE2,
PULSE_VOICE3
};
enum VideoStandard {
PAL,
NTSC
};
class ScummEngine;
class Player_SID : public Audio::AudioStream, public MusicEngine {
public:
Player_SID(ScummEngine *scumm, Audio::Mixer *mixer);
virtual ~Player_SID();
virtual void setMusicVolume(int vol) { _maxvol = vol; }
void startMusic(int songResIndex);
virtual void startSound(int sound);
virtual void stopSound(int sound);
virtual void stopAllSounds();
virtual int getSoundStatus(int sound) const;
virtual int getMusicTimer();
// AudioStream API
int readBuffer(int16 *buffer, const int numSamples);
bool isStereo() const { return false; }
bool endOfData() const { return false; }
int getRate() const { return _sampleRate; }
private:
Resid::SID *_sid;
void SID_Write(int reg, uint8 data);
void initSID();
uint8 *getResource(int resID);
// number of cpu cycles until next frame update
Resid::cycle_count _cpuCyclesLeft;
ScummEngine *_vm;
Audio::Mixer *_mixer;
Audio::SoundHandle _soundHandle;
int _sampleRate;
int _maxvol;
Common::Mutex _mutex;
VideoStandard _videoSystem;
int _music_timer;
uint8* _music;
private:
void initMusic(int songResIndex); // $7de6
int initSound(int soundResID); // $4D0A
void stopSound_intern(int soundResID); // $5093
void stopAllSounds_intern(); // $4CAA
void resetSID(); // $48D8
void update(); // $481B
void handleMusicBuffer();
int setupSongFileData(); // $36cb
void func_3674(int channel); // $3674
void resetPlayerState(); // $48f7
void processSongData(int channel); // $4939
void readSetSIDFilterAndProps(int *offset, uint8* dataPtr); // $49e7
void saveSongPos(int y, int channel);
void updateFreq(int channel);
void resetFreqDelta(int channel);
void readSongChunk(int channel); // $4a6b
void setSIDFreqAS(int channel); // $4be6
void setSIDWaveCtrlReg(int channel); // $4C0D
int setupSongPtr(int channel); // $4C1C
void unlockResource(int chanResIndex); // $4CDA
void countFreeChannels(); // $4f26
void func_4F45(int channel); // $4F45
void safeUnlockResource(int resIndex); // $4FEA
void releaseResource(int resIndex); // $5031
void releaseResChannels(int resIndex); // $5070
void releaseResourceUnk(int resIndex); // $50A4
void releaseChannel(int channel);
void clearSIDWaveform(int channel);
void stopChannel(int channel);
void swapVars(int channel, int swapIndex); // $51a5
void resetSwapVars(); // $52d0
void prepareSwapVars(int channel); // $52E5
void useSwapVars(int channel); // $5342
void lockResource(int resIndex); // $4ff4
void reserveChannel(int channel, uint8 prioValue, int chanResIndex); // $4ffe
void unlockCodeLocation(); // $513e
void lockCodeLocation(); // $514f
void func_7eae(int channel, uint8* songFileDataPtr); // $7eae
void func_819b(int channel); // $819b
void buildStepTbl(int step); // $82B4
int reserveSoundFilter(uint8 value, uint8 chanResIndex); // $4ED0
int reserveSoundVoice(uint8 value, uint8 chanResIndex); // $4EB8
void findLessPrioChannels(uint8 soundPrio); // $4ED8
void releaseResourceBySound(int resID); // $5088
void readVec6Data(int x, int *offset, uint8 *songFilePtr, int chanResID); // $4E99
void unused1(); // $50AF
uint8 chanBuffer[3][45];
int resID_song;
// statusBits1A/1B are always equal
uint8 statusBits1A;
uint8 statusBits1B;
uint8 busyChannelBits;
uint8 SIDReg23;
uint8 SIDReg23Stuff;
uint8 SIDReg24;
uint8* chanFileData[3];
uint16 chanDataOffset[3];
uint8* songPosPtr[7];
// 0..2: freq value voice1/2/3
// 3: filter freq
// 4..6: pulse width
uint16 freqReg[7];
// start offset[i] for songFileOrChanBufData to obtain songPosPtr[i]
// vec6[0..2] = 0x0008;
// vec6[4..6] = 0x0019;
uint16 vec6[7];
// current offset[i] for songFileOrChanBufData to obtain songPosPtr[i] (starts with vec6[i], increased later)
uint16 songFileOrChanBufOffset[7];
uint16 freqDelta[7];
int freqDeltaCounter[7];
uint8* swapSongPosPtr[3];
uint8* swapVec5[3];
uint16 swapVec8[3];
uint16 swapVec10[3];
uint16 swapFreqReg[3];
int swapVec11[3];
// never read
//uint8* vec5[7];
// never read
//uint8 vec19[7];
// never read (needed by scumm engine?)
//bool curChannelActive;
uint8* vec20[7];
uint8* swapVec20[3];
// resource status (never read)
// bit7: some flag
// bit6..0: counter (use-count?), maybe just bit0 as flag (used/unused?)
uint8 resStatus[70];
uint8* songFileOrChanBufData;
uint8* actSongFileData;
uint16 stepTbl[33];
bool initializing;
bool _soundInQueue;
bool isVoiceChannel;
bool isMusicPlaying;
bool swapVarLoaded;
bool bgSoundActive;
bool filterUsed;
uint8 bgSoundResID;
uint8 freeChannelCount;
// seems to be used for managing the three voices
// bit[0..2]: 0 -> unused, 1 -> already in use
uint8 usedChannelBits;
uint8 attackReg[3];
uint8 sustainReg[3];
// -1/0/1
int var481A;
// bit-array: 00000cba
// a/b/c: channel1/2/3
uint8 songChannelBits;
bool pulseWidthSwapped;
bool swapPrepared;
// never read
//uint8 var5163;
bool filterSwapped;
uint8 SIDReg24_HiNibble;
bool keepSwapVars;
uint8 phaseBit[3];
bool releasePhase[3];
// values: a resID or -1
// resIDs: 3, 4, 5 or song-number
int _soundQueue[7];
// values: a resID or 0
// resIDs: 3, 4, 5 or song-number
int channelMap[7];
uint8 songPosUpdateCounter[7];
// priortity of channel contents
// MM: 1: lowest .. 120: highest (1,2,A,64,6E,73,78)
// Zak: -???: lowest .. 120: highest (5,32,64,65,66,6E,78, A5,A6,AF,D7)
uint8 chanPrio[7];
// only [0..2] used?
uint8 waveCtrlReg[7];
uint8 swapAttack[2];
uint8 swapSustain[2];
uint8 swapSongPrio[3];
int swapVec479C[3];
uint8 swapVec19[3];
uint8 swapSongPosUpdateCounter[3];
uint8 swapWaveCtrlReg[3];
bool actFilterHasLowerPrio;
uint8 chansWithLowerPrioCount;
uint8 minChanPrio;
uint8 minChanPrioIndex;
};
} // End of namespace Scumm
#endif