mirror of https://github.com/stella-emu/stella.git
added WAV playing and adapted KidVid code accordingly
This commit is contained in:
parent
162921b9f3
commit
ba6b32aa21
|
@ -72,6 +72,10 @@ SoundSDL2::~SoundSDL2()
|
||||||
{
|
{
|
||||||
ASSERT_MAIN_THREAD;
|
ASSERT_MAIN_THREAD;
|
||||||
|
|
||||||
|
stopWav();
|
||||||
|
if(myWavDevice)
|
||||||
|
SDL_CloseAudioDevice(myWavDevice);
|
||||||
|
|
||||||
if (!myIsInitializedFlag) return;
|
if (!myIsInitializedFlag) return;
|
||||||
|
|
||||||
SDL_CloseAudioDevice(myDevice);
|
SDL_CloseAudioDevice(myDevice);
|
||||||
|
@ -194,6 +198,7 @@ void SoundSDL2::open(shared_ptr<AudioQueue> audioQueue,
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL2::close()
|
void SoundSDL2::close()
|
||||||
{
|
{
|
||||||
|
stopWav();
|
||||||
if(!myIsInitializedFlag) return;
|
if(!myIsInitializedFlag) return;
|
||||||
|
|
||||||
mute(true);
|
mute(true);
|
||||||
|
@ -209,6 +214,8 @@ bool SoundSDL2::mute(bool state)
|
||||||
const bool oldstate = SDL_GetAudioDeviceStatus(myDevice) == SDL_AUDIO_PAUSED;
|
const bool oldstate = SDL_GetAudioDeviceStatus(myDevice) == SDL_AUDIO_PAUSED;
|
||||||
if(myIsInitializedFlag)
|
if(myIsInitializedFlag)
|
||||||
SDL_PauseAudioDevice(myDevice, state ? 1 : 0);
|
SDL_PauseAudioDevice(myDevice, state ? 1 : 0);
|
||||||
|
if(myWavDevice)
|
||||||
|
SDL_PauseAudioDevice(myWavDevice, state ? 1 : 0);
|
||||||
|
|
||||||
return oldstate;
|
return oldstate;
|
||||||
}
|
}
|
||||||
|
@ -395,4 +402,57 @@ void SoundSDL2::callback(void* udata, uInt8* stream, int len)
|
||||||
SDL_memset(stream, 0, len);
|
SDL_memset(stream, 0, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool SoundSDL2::playWav(const char* fileName, uInt32 position, uInt32 length)
|
||||||
|
{
|
||||||
|
// ToDos:
|
||||||
|
// - volume (requires callback using SDL_MixAudio)
|
||||||
|
// - (un)mute
|
||||||
|
SDL_AudioSpec wavSpec;
|
||||||
|
uInt32 wavLength;
|
||||||
|
|
||||||
|
// Stop any playing WAVs
|
||||||
|
stopWav();
|
||||||
|
|
||||||
|
// Load WAV file
|
||||||
|
SDL_AudioSpec* result = SDL_LoadWAV(fileName, &wavSpec, &myWavBuffer, &wavLength);
|
||||||
|
if(result == NULL || position > wavLength)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
length = length
|
||||||
|
? std::min(length, wavLength - position)
|
||||||
|
: wavLength;
|
||||||
|
|
||||||
|
// Open audio device
|
||||||
|
const char* device = myDeviceId ? myDevices.at(myDeviceId).first.c_str() : nullptr;
|
||||||
|
|
||||||
|
myWavDevice = SDL_OpenAudioDevice(device, 0, &wavSpec, NULL, 0);
|
||||||
|
if(!myWavDevice)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Play audio
|
||||||
|
int success = SDL_QueueAudio(myWavDevice, myWavBuffer + position, length);
|
||||||
|
SDL_PauseAudioDevice(myWavDevice, 0);
|
||||||
|
|
||||||
|
return success == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void SoundSDL2::stopWav()
|
||||||
|
{
|
||||||
|
if(myWavBuffer)
|
||||||
|
{
|
||||||
|
// Clean up
|
||||||
|
SDL_CloseAudioDevice(myWavDevice);
|
||||||
|
SDL_FreeWAV(myWavBuffer);
|
||||||
|
|
||||||
|
myWavBuffer = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uInt32 SoundSDL2::wavSize() const
|
||||||
|
{
|
||||||
|
return myWavBuffer ? SDL_GetQueuedAudioSize(myWavDevice) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // SOUND_SUPPORT
|
#endif // SOUND_SUPPORT
|
||||||
|
|
|
@ -107,6 +107,29 @@ class SoundSDL2 : public Sound
|
||||||
*/
|
*/
|
||||||
string about() const override;
|
string about() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Play a WAV file.
|
||||||
|
|
||||||
|
@param fileName The name of the WAV file
|
||||||
|
@param position The position to start playing
|
||||||
|
@param length The played length
|
||||||
|
|
||||||
|
@return True, if the WAV file can be played
|
||||||
|
*/
|
||||||
|
bool playWav(const char* fileName, uInt32 position = 0, uInt32 length = 0) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Stop any currently playing WAV file.
|
||||||
|
*/
|
||||||
|
void stopWav() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the size of the WAV file which remains to be played.
|
||||||
|
|
||||||
|
@return The remaining number of bytes
|
||||||
|
*/
|
||||||
|
uInt32 wavSize() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
This method is called to query the audio devices.
|
This method is called to query the audio devices.
|
||||||
|
@ -161,6 +184,9 @@ class SoundSDL2 : public Sound
|
||||||
|
|
||||||
AudioSettings& myAudioSettings;
|
AudioSettings& myAudioSettings;
|
||||||
|
|
||||||
|
SDL_AudioDeviceID myWavDevice{0};
|
||||||
|
uInt8* myWavBuffer{nullptr};
|
||||||
|
|
||||||
string myAboutString;
|
string myAboutString;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1028,7 +1028,8 @@ unique_ptr<Controller> Console::getControllerPort(const Controller::Type type,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Controller::Type::KidVid:
|
case Controller::Type::KidVid:
|
||||||
controller = make_unique<KidVid>(port, myEvent, *mySystem, myOSystem.baseDir().getPath(), romMd5);
|
controller = make_unique<KidVid>(port, myEvent, *mySystem, myOSystem.baseDir().getPath(),
|
||||||
|
myOSystem.sound(), romMd5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Controller::Type::MindLink:
|
case Controller::Type::MindLink:
|
||||||
|
|
|
@ -16,14 +16,16 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "Event.hxx"
|
#include "Event.hxx"
|
||||||
|
#include "Sound.hxx"
|
||||||
#include "KidVid.hxx"
|
#include "KidVid.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
KidVid::KidVid(Jack jack, const Event& event, const System& system,
|
KidVid::KidVid(Jack jack, const Event& event, const System& system,
|
||||||
const string& baseDir, const string& romMd5)
|
const string& baseDir, Sound& sound, const string& romMd5)
|
||||||
: Controller(jack, event, system, Controller::Type::KidVid),
|
: Controller(jack, event, system, Controller::Type::KidVid),
|
||||||
myEnabled{myJack == Jack::Right},
|
myEnabled{myJack == Jack::Right},
|
||||||
myBaseDir{baseDir}
|
myBaseDir{baseDir},
|
||||||
|
mySound{sound}
|
||||||
{
|
{
|
||||||
// Right now, there are only two games that use the KidVid
|
// Right now, there are only two games that use the KidVid
|
||||||
if(romMd5 == "ee6665683ebdb539e89ba620981cb0f6")
|
if(romMd5 == "ee6665683ebdb539e89ba620981cb0f6")
|
||||||
|
@ -59,7 +61,8 @@ void KidVid::update()
|
||||||
if(myEvent.get(Event::ConsoleReset))
|
if(myEvent.get(Event::ConsoleReset))
|
||||||
{
|
{
|
||||||
myTape = 0; // rewind Kid Vid tape
|
myTape = 0; // rewind Kid Vid tape
|
||||||
closeSampleFiles();
|
myFilesFound = mySongPlaying = false;
|
||||||
|
mySound.stopWav();
|
||||||
}
|
}
|
||||||
if(!myTape)
|
if(!myTape)
|
||||||
{
|
{
|
||||||
|
@ -71,9 +74,8 @@ void KidVid::update()
|
||||||
myTape = myGame == BBears ? 4 : 1; // Berenstain Bears or Smurfs Save The Day?
|
myTape = myGame == BBears ? 4 : 1; // Berenstain Bears or Smurfs Save The Day?
|
||||||
if(myTape)
|
if(myTape)
|
||||||
{
|
{
|
||||||
//cerr << "myTape = " << myTape << endl;0
|
myIdx = myGame == BBears ? NumBlockBits : 0;
|
||||||
myIdx = myGame == BBears ? BlockBits : 0;
|
myBlockIdx = NumBlockBits;
|
||||||
myBlockIdx = BlockBits;
|
|
||||||
myBlock = 0;
|
myBlock = 0;
|
||||||
openSampleFiles();
|
openSampleFiles();
|
||||||
}
|
}
|
||||||
|
@ -92,49 +94,58 @@ void KidVid::update()
|
||||||
if(!myBlockIdx)
|
if(!myBlockIdx)
|
||||||
{
|
{
|
||||||
if(!myBlock)
|
if(!myBlock)
|
||||||
myIdx = ((myTape * 6) + 12 - Blocks) * 8; //KVData00-KVData=12
|
myIdx = ((myTape * 6) + 12 - NumBlocks) * 8; //KVData00-KVData=12
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(myGame == Smurfs)
|
const uInt32 lastBlock = myGame == Smurfs
|
||||||
{
|
? ourBlocks[myTape - 1]
|
||||||
if(myBlock >= ourBlocks[myTape - 1])
|
: ourBlocks[myTape + 2 - 1];
|
||||||
myIdx = 42 * 8; //KVData80-KVData=42
|
if(myBlock >= lastBlock)
|
||||||
else
|
myIdx = 42 * 8; //KVData80-KVData=42
|
||||||
{
|
|
||||||
myIdx = 36 * 8;//KVPause-KVData=36
|
|
||||||
setNextSong();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(myBlock >= ourBlocks[myTape + 2 - 1])
|
myIdx = 36 * 8;//KVPause-KVData=36
|
||||||
myIdx = 42 * 8; //KVData80-KVData=42
|
setNextSong();
|
||||||
else
|
|
||||||
{
|
|
||||||
myIdx = 36 * 8;//KVPause-KVData=36
|
|
||||||
setNextSong();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++myBlock;
|
++myBlock;
|
||||||
myBlockIdx = BlockBits;
|
myBlockIdx = NumBlockBits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(myFilesFound)
|
||||||
|
{
|
||||||
|
if(mySongPlaying)
|
||||||
|
{
|
||||||
|
myTapeBusy = (mySound.wavSize() > 262 * 48) || !myBeep;
|
||||||
|
// Check for end of played sample
|
||||||
|
if(mySound.wavSize() == 0)
|
||||||
|
{
|
||||||
|
mySongPlaying = false;
|
||||||
|
myTapeBusy = !myBeep;
|
||||||
|
if(!myBeep)
|
||||||
|
setNextSong();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(mySongLength)
|
||||||
|
{
|
||||||
|
--mySongLength;
|
||||||
|
myTapeBusy = (mySongLength > 48);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// emulate playing the songs (but MUCH faster!)
|
|
||||||
// TODO: this has to be done by an Audio class
|
|
||||||
for(int i = mySongCounter / 8; i >= 0; --i)
|
|
||||||
getNextSampleByte();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void KidVid::openSampleFiles()
|
void KidVid::openSampleFiles()
|
||||||
{
|
{
|
||||||
#ifdef KID_TAPE
|
|
||||||
static constexpr const char* fileNames[6] = {
|
static constexpr const char* fileNames[6] = {
|
||||||
"KVS3.WAV", "KVS1.WAV", "KVS2.WAV",
|
"KVS3.WAV", "KVS1.WAV", "KVS2.WAV",
|
||||||
"KVB3.WAV", "KVB1.WAV", "KVB2.WAV"
|
"KVB3.WAV", "KVB1.WAV", "KVB2.WAV"
|
||||||
};
|
};
|
||||||
static constexpr uInt32 startSong[6] = {
|
static constexpr uInt32 firstSongPointer[6] = {
|
||||||
44 + 38,
|
44 + 38,
|
||||||
0,
|
0,
|
||||||
44,
|
44,
|
||||||
|
@ -143,114 +154,62 @@ void KidVid::openSampleFiles()
|
||||||
44 + 38 + 42 + 62
|
44 + 38 + 42 + 62
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!myFilesOpened)
|
if(!myFilesFound)
|
||||||
{
|
{
|
||||||
int i = myGame == Smurfs ? myTape - 1 : myTape + 2;
|
int i = myGame == Smurfs ? myTape - 1 : myTape + 2;
|
||||||
if(myTape == 4) i = 3;
|
if(myTape == 4) i = 3;
|
||||||
|
|
||||||
mySampleFile.open(myBaseDir + fileNames[i], std::ios::binary);
|
mySampleFile = myBaseDir + fileNames[i];
|
||||||
if(mySampleFile.is_open())
|
|
||||||
{
|
std::ifstream f1, f2;
|
||||||
cerr << "opened file: " << fileNames[i] << endl;
|
f1.open(mySampleFile, std::ios::binary);
|
||||||
mySharedSampleFile.open(myBaseDir + "KVSHARED.WAV", std::ios::binary);
|
f2.open(myBaseDir + "KVSHARED.WAV", std::ios::binary);
|
||||||
if(!mySharedSampleFile.is_open())
|
|
||||||
mySampleFile.close();
|
myFilesFound = f1.is_open() && f2.is_open();
|
||||||
else
|
|
||||||
{
|
if(myFilesFound)
|
||||||
cerr << "opened file: " << "kvshared.wav" << endl;
|
cerr << "found file: " << fileNames[i] << endl
|
||||||
mySampleFile.seekg(45);
|
<< "found file: " << "KVSHARED.WAV" << endl;
|
||||||
myFilesOpened = true;
|
|
||||||
}
|
mySongLength = 0;
|
||||||
}
|
mySongPointer = firstSongPointer[i];
|
||||||
mySongCounter = 0;
|
|
||||||
myFilePointer = startSong[i];
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
myTapeBusy = false;
|
myTapeBusy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void KidVid::closeSampleFiles()
|
|
||||||
{
|
|
||||||
#ifdef KID_TAPE
|
|
||||||
if(mySampleFile.is_open())
|
|
||||||
mySampleFile.close();
|
|
||||||
if(mySharedSampleFile.is_open())
|
|
||||||
mySharedSampleFile.close();
|
|
||||||
|
|
||||||
myFilesOpened = false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void KidVid::setNextSong()
|
void KidVid::setNextSong()
|
||||||
{
|
{
|
||||||
#ifdef KID_TAPE
|
if(myFilesFound)
|
||||||
if(myFilesOpened)
|
|
||||||
{
|
{
|
||||||
//cerr << endl << std::dec << mySongCounter << ", " << myFilePointer << endl;
|
myBeep = (ourSongPositions[mySongPointer] & 0x80) == 0;
|
||||||
myBeep = (ourSongPositions[myFilePointer] & 0x80) == 0;
|
|
||||||
|
|
||||||
const uInt8 temp = ourSongPositions[myFilePointer] & 0x7f;
|
const uInt8 temp = ourSongPositions[mySongPointer] & 0x7f;
|
||||||
mySharedData = (temp < 10);
|
mySongLength = ourSongStart[temp+1] - ourSongStart[temp];
|
||||||
mySongCounter = ourSongStart[temp+1] - ourSongStart[temp];
|
|
||||||
|
|
||||||
if(mySharedData)
|
// Play the WAV file
|
||||||
mySharedSampleFile.seekg(ourSongStart[temp]);
|
const string fileName = (temp < 10) ? myBaseDir + "KVSHARED.WAV" : mySampleFile;
|
||||||
else
|
mySound.playWav(fileName.c_str(), ourSongStart[temp], mySongLength);
|
||||||
mySampleFile.seekg(ourSongStart[temp]);
|
|
||||||
|
|
||||||
++myFilePointer;
|
mySongPlaying = myTapeBusy = true;
|
||||||
myTapeBusy = true;
|
++mySongPointer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
myBeep = true;
|
myBeep = true;
|
||||||
myTapeBusy = true;
|
myTapeBusy = true;
|
||||||
mySongCounter = 10 * 80*262; /* delay needed for Harmony without tape */
|
mySongLength = 80; /* delay needed for Harmony without tape */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void KidVid::getNextSampleByte()
|
const std::array<uInt8, KidVid::NumBlocks> KidVid::ourBlocks = {
|
||||||
{
|
|
||||||
static bool oddeven = false;
|
|
||||||
|
|
||||||
if(mySongCounter == 0)
|
|
||||||
{
|
|
||||||
#ifdef KID_TAPE
|
|
||||||
mySampleByte = 0x80;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oddeven = !oddeven;
|
|
||||||
if(oddeven)
|
|
||||||
{
|
|
||||||
mySongCounter--;
|
|
||||||
myTapeBusy = (mySongCounter > 262 * 48) || !myBeep;
|
|
||||||
|
|
||||||
#ifdef KID_TAPE
|
|
||||||
mySampleByte = myFilesOpened
|
|
||||||
? (mySharedData ? mySharedSampleFile.get() : mySampleFile.get())
|
|
||||||
: 0x80;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!myBeep && (mySongCounter == 0))
|
|
||||||
setNextSong();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
const std::array<uInt8, KidVid::Blocks> KidVid::ourBlocks = {
|
|
||||||
2+40, 2+21, 2+35, /* Smurfs tapes 3, 1, 2 */
|
2+40, 2+21, 2+35, /* Smurfs tapes 3, 1, 2 */
|
||||||
42+60, 42+78, 42+60 /* BBears tapes 1, 2, 3 (40 extra blocks for intro) */
|
42+60, 42+78, 42+60 /* BBears tapes 1, 2, 3 (40 extra blocks for intro) */
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
const std::array<uInt8, KidVid::BlockBits> KidVid::ourData = {
|
const std::array<uInt8, KidVid::NumBlockBits> KidVid::ourData = {
|
||||||
/* KVData44 */
|
/* KVData44 */
|
||||||
0x7b, // 0111 1011b ; (1)0
|
0x7b, // 0111 1011b ; (1)0
|
||||||
0x1e, // 0001 1110b ; 1
|
0x1e, // 0001 1110b ; 1
|
||||||
|
@ -409,7 +368,7 @@ const std::array<uInt32, KidVid::SongStartSize> KidVid::ourSongStart = {
|
||||||
3720920,
|
3720920,
|
||||||
|
|
||||||
/* kvb1 */
|
/* kvb1 */
|
||||||
44, /* 3 */
|
44, /* 3 */ // can be one too late!
|
||||||
592749, /* 5 */
|
592749, /* 5 */
|
||||||
936142, /* 2 */
|
936142, /* 2 */
|
||||||
1465343, /* 4 */
|
1465343, /* 4 */
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
#ifndef KIDVID_HXX
|
#ifndef KIDVID_HXX
|
||||||
#define KIDVID_HXX
|
#define KIDVID_HXX
|
||||||
|
|
||||||
//#define KID_TAPE
|
|
||||||
|
|
||||||
class Event;
|
class Event;
|
||||||
|
class Sound;
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Control.hxx"
|
#include "Control.hxx"
|
||||||
|
@ -48,7 +47,7 @@ class KidVid : public Controller
|
||||||
@param romMd5 The md5 of the ROM using this controller
|
@param romMd5 The md5 of the ROM using this controller
|
||||||
*/
|
*/
|
||||||
KidVid(Jack jack, const Event& event, const System& system,
|
KidVid(Jack jack, const Event& event, const System& system,
|
||||||
const string& baseDir, const string& romMd5);
|
const string& baseDir, Sound& sound, const string& romMd5);
|
||||||
~KidVid() override = default;
|
~KidVid() override = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -76,21 +75,16 @@ class KidVid : public Controller
|
||||||
private:
|
private:
|
||||||
// Open/close a WAV sample file
|
// Open/close a WAV sample file
|
||||||
void openSampleFiles();
|
void openSampleFiles();
|
||||||
void closeSampleFiles();
|
|
||||||
|
|
||||||
// Jump to next song in the sequence
|
// Jump to next song in the sequence
|
||||||
void setNextSong();
|
void setNextSong();
|
||||||
|
|
||||||
// Generate next sample byte
|
|
||||||
// TODO - rework this, perhaps send directly to sound class
|
|
||||||
void getNextSampleByte();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uInt32
|
static constexpr uInt32
|
||||||
Smurfs = 0x44,
|
Smurfs = 0x44,
|
||||||
BBears = 0x48,
|
BBears = 0x48,
|
||||||
Blocks = 6, // number of bytes / block
|
NumBlocks = 6, // number of bytes / block
|
||||||
BlockBits = Blocks*8, // number of bits / block
|
NumBlockBits = NumBlocks*8, // number of bits / block
|
||||||
SongPosSize = 44+38+42+62+80+62,
|
SongPosSize = 44+38+42+62+80+62,
|
||||||
SongStartSize = 104
|
SongStartSize = 104
|
||||||
;
|
;
|
||||||
|
@ -100,28 +94,27 @@ class KidVid : public Controller
|
||||||
bool myEnabled{false};
|
bool myEnabled{false};
|
||||||
|
|
||||||
string myBaseDir;
|
string myBaseDir;
|
||||||
#ifdef KID_TAPE
|
Sound& mySound;
|
||||||
// The file streams for the WAV files
|
|
||||||
std::ifstream mySampleFile, mySharedSampleFile;
|
|
||||||
// Indicates if sample files have been successfully opened
|
|
||||||
bool myFilesOpened{false};
|
|
||||||
|
|
||||||
uInt32 myFilePointer{0};
|
// Path and name of the current sample file
|
||||||
bool mySharedData{false};
|
string mySampleFile;
|
||||||
uInt8 mySampleByte{0};
|
// Indicates if the sample files have been found
|
||||||
#endif
|
bool myFilesFound{false};
|
||||||
|
|
||||||
|
uInt32 mySongPointer{0};
|
||||||
|
|
||||||
// Is the tape currently 'busy' / in use?
|
// Is the tape currently 'busy' / in use?
|
||||||
bool myTapeBusy{false};
|
bool myTapeBusy{false};
|
||||||
|
|
||||||
uInt32 mySongCounter{0};
|
bool mySongPlaying{false};
|
||||||
|
uInt32 mySongLength{0};
|
||||||
bool myBeep{false};
|
bool myBeep{false};
|
||||||
uInt32 myGame{0}, myTape{0};
|
uInt32 myGame{0}, myTape{0};
|
||||||
uInt32 myIdx{0}, myBlock{0}, myBlockIdx{0};
|
uInt32 myIdx{0}, myBlock{0}, myBlockIdx{0};
|
||||||
|
|
||||||
// Number of blocks and data on tape
|
// Number of blocks and data on tape
|
||||||
static const std::array<uInt8, Blocks> ourBlocks;
|
static const std::array<uInt8, NumBlocks> ourBlocks;
|
||||||
static const std::array<uInt8, BlockBits> ourData;
|
static const std::array<uInt8, NumBlockBits> ourData;
|
||||||
|
|
||||||
static const std::array<uInt8, SongPosSize> ourSongPositions;
|
static const std::array<uInt8, SongPosSize> ourSongPositions;
|
||||||
static const std::array<uInt32, SongStartSize> ourSongStart;
|
static const std::array<uInt32, SongStartSize> ourSongStart;
|
||||||
|
|
|
@ -23,6 +23,7 @@ class AudioQueue;
|
||||||
class EmulationTiming;
|
class EmulationTiming;
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
#include "Variant.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class is an abstract base class for the various sound objects.
|
This class is an abstract base class for the various sound objects.
|
||||||
|
@ -104,6 +105,29 @@ class Sound
|
||||||
*/
|
*/
|
||||||
const VariantList& supportedDevices() const {return myDevices;}
|
const VariantList& supportedDevices() const {return myDevices;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Play a WAV file.
|
||||||
|
|
||||||
|
@param fileName The name of the WAV file
|
||||||
|
@param position The position to start playing
|
||||||
|
@param length The played length
|
||||||
|
|
||||||
|
@return True, if the WAV file can be played
|
||||||
|
*/
|
||||||
|
virtual bool playWav(const char* fileName, uInt32 position = 0, uInt32 length = 0) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Stop any currently playing WAV file.
|
||||||
|
*/
|
||||||
|
virtual void stopWav() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the size of the WAV file which remains to be played.
|
||||||
|
|
||||||
|
@return The remaining number of bytes
|
||||||
|
*/
|
||||||
|
virtual uInt32 wavSize() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
This method is called to query the audio devices.
|
This method is called to query the audio devices.
|
||||||
|
@ -112,6 +136,7 @@ class Sound
|
||||||
*/
|
*/
|
||||||
virtual void queryHardware(VariantList& devices) = 0;
|
virtual void queryHardware(VariantList& devices) = 0;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// The OSystem for this sound object
|
// The OSystem for this sound object
|
||||||
OSystem& myOSystem;
|
OSystem& myOSystem;
|
||||||
|
|
Loading…
Reference in New Issue