140 lines
3.2 KiB
C++
140 lines
3.2 KiB
C++
#include "stdafx.h"
|
|
#include "Msu1.h"
|
|
#include "Spc.h"
|
|
#include "../Utilities/Serializer.h"
|
|
#include "../Utilities/FolderUtilities.h"
|
|
|
|
Msu1* Msu1::Init(VirtualFile romFile, Spc* spc)
|
|
{
|
|
string romFolder = romFile.GetFolderPath();
|
|
string romName = FolderUtilities::GetFilename(romFile.GetFileName(), false);
|
|
if (ifstream(FolderUtilities::CombinePath(romFolder, romName + ".msu")))
|
|
{
|
|
return new Msu1(romFile, spc);
|
|
}
|
|
else if (ifstream(FolderUtilities::CombinePath(romFolder, "msu1.rom")))
|
|
{
|
|
return new Msu1(romFile, spc);
|
|
}
|
|
else
|
|
{
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
Msu1::Msu1(VirtualFile romFile, Spc* spc)
|
|
{
|
|
_spc = spc;
|
|
_romFolder = romFile.GetFolderPath();
|
|
_romName = FolderUtilities::GetFilename(romFile.GetFileName(), false);
|
|
_dataFile.open(FolderUtilities::CombinePath(_romFolder, _romName) + ".msu", ios::binary);
|
|
if (_dataFile)
|
|
{
|
|
_trackPath = FolderUtilities::CombinePath(_romFolder, _romName);
|
|
}
|
|
else
|
|
{
|
|
_dataFile.open(FolderUtilities::CombinePath(_romFolder, "msu1.rom"), ios::binary);
|
|
_trackPath = FolderUtilities::CombinePath(_romFolder, "track");
|
|
}
|
|
|
|
if (_dataFile)
|
|
{
|
|
_dataFile.seekg(0, ios::end);
|
|
_dataSize = (uint32_t)_dataFile.tellg();
|
|
}
|
|
else
|
|
{
|
|
_dataSize = 0;
|
|
}
|
|
}
|
|
|
|
void Msu1::Write(uint16_t addr, uint8_t value)
|
|
{
|
|
switch (addr)
|
|
{
|
|
case 0x2000: _tmpDataPointer = (_tmpDataPointer & 0xFFFFFF00) | value;
|
|
break;
|
|
case 0x2001: _tmpDataPointer = (_tmpDataPointer & 0xFFFF00FF) | (value << 8);
|
|
break;
|
|
case 0x2002: _tmpDataPointer = (_tmpDataPointer & 0xFF00FFFF) | (value << 16);
|
|
break;
|
|
case 0x2003:
|
|
_tmpDataPointer = (_tmpDataPointer & 0x00FFFFFF) | (value << 24);
|
|
_dataPointer = _tmpDataPointer;
|
|
_dataFile.seekg(_dataPointer, ios::beg);
|
|
break;
|
|
|
|
case 0x2004: _trackSelect = (_trackSelect & 0xFF00) | value;
|
|
break;
|
|
case 0x2005:
|
|
_trackSelect = (_trackSelect & 0xFF) | (value << 8);
|
|
LoadTrack();
|
|
break;
|
|
|
|
case 0x2006: _volume = value;
|
|
break;
|
|
case 0x2007:
|
|
if (!_audioBusy)
|
|
{
|
|
_repeat = (value & 0x02) != 0;
|
|
_paused = (value & 0x01) == 0;
|
|
_pcmReader.SetLoopFlag(_repeat);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
uint8_t Msu1::Read(uint16_t addr)
|
|
{
|
|
switch (addr)
|
|
{
|
|
case 0x2000:
|
|
//status
|
|
return (_dataBusy << 7) | (_audioBusy << 6) | (_repeat << 5) | ((!_paused) << 4) | (_trackMissing << 3) | 0x01;
|
|
|
|
case 0x2001:
|
|
//data
|
|
if (!_dataBusy && _dataPointer < _dataSize)
|
|
{
|
|
_dataPointer++;
|
|
return (uint8_t)_dataFile.get();
|
|
}
|
|
return 0;
|
|
|
|
case 0x2002: return 'S';
|
|
case 0x2003: return '-';
|
|
case 0x2004: return 'M';
|
|
case 0x2005: return 'S';
|
|
case 0x2006: return 'U';
|
|
case 0x2007: return '1';
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Msu1::MixAudio(int16_t* buffer, size_t sampleCount, uint32_t sampleRate)
|
|
{
|
|
if (!_paused)
|
|
{
|
|
_pcmReader.SetSampleRate(sampleRate);
|
|
_pcmReader.ApplySamples(buffer, sampleCount, _spc->IsMuted() ? 0 : _volume);
|
|
}
|
|
}
|
|
|
|
void Msu1::LoadTrack(uint32_t startOffset)
|
|
{
|
|
_trackMissing = !_pcmReader.Init(_trackPath + "-" + std::to_string(_trackSelect) + ".pcm", _repeat, startOffset);
|
|
}
|
|
|
|
void Msu1::Serialize(Serializer& s)
|
|
{
|
|
uint32_t offset = _pcmReader.GetOffset();
|
|
s.Stream(_trackSelect, _tmpDataPointer, _dataPointer, _repeat, _paused, _volume, _trackMissing, _audioBusy,
|
|
_dataBusy, offset);
|
|
if (!s.IsSaving())
|
|
{
|
|
_dataFile.seekg(_dataPointer, ios::beg);
|
|
LoadTrack(offset);
|
|
}
|
|
}
|