2d0468eff5
Added option in HD pack builder to save screen information when tiles are first shown. User can look up which screen the tiles are added in the tileIndex.csv and open the screen_XXX.csv and screen_XXX.png to see the actual usage of the tiles. Added playback option and volume option to <bgm> tag. Use 1 for looping playback, 0 for single playback, -1 for no change. Use 0 to 128 for volume control and -1 for no volume change.
177 lines
4.8 KiB
C++
177 lines
4.8 KiB
C++
#include "stdafx.h"
|
|
#include "HdAudioDevice.h"
|
|
#include "HdData.h"
|
|
#include "Console.h"
|
|
|
|
HdAudioDevice::HdAudioDevice(shared_ptr<Console> console, HdPackData* hdData)
|
|
{
|
|
_hdData = hdData;
|
|
_album = 0;
|
|
_playbackOptions = 0;
|
|
_trackError = false;
|
|
_sfxVolume = 128;
|
|
_bgmVolume = 128;
|
|
|
|
_oggMixer = console->GetSoundMixer()->GetOggMixer();
|
|
_oggMixer->SetBgmVolume(_bgmVolume);
|
|
_oggMixer->SetSfxVolume(_sfxVolume);
|
|
}
|
|
|
|
void HdAudioDevice::StreamState(bool saving)
|
|
{
|
|
int32_t trackOffset = 0;
|
|
if(saving) {
|
|
trackOffset = _oggMixer->GetBgmOffset();
|
|
if(trackOffset < 0) {
|
|
_lastBgmTrack = -1;
|
|
}
|
|
Stream(_album, _lastBgmTrack, trackOffset, _sfxVolume, _bgmVolume, _playbackOptions);
|
|
} else {
|
|
Stream(_album, _lastBgmTrack, trackOffset, _sfxVolume, _bgmVolume, _playbackOptions);
|
|
if(_lastBgmTrack != -1 && trackOffset > 0) {
|
|
PlayBgmTrack(_lastBgmTrack, trackOffset);
|
|
}
|
|
_oggMixer->SetBgmVolume(_bgmVolume);
|
|
_oggMixer->SetSfxVolume(_sfxVolume);
|
|
_oggMixer->SetPlaybackOptions(_playbackOptions);
|
|
}
|
|
}
|
|
|
|
bool HdAudioDevice::PlayBgmTrack(uint8_t track, uint32_t startOffset)
|
|
{
|
|
int trackId = _album * 256 + track;
|
|
auto result = _hdData->BgmFilesById.find(trackId);
|
|
if(result != _hdData->BgmFilesById.end()) {
|
|
if(_oggMixer->Play(result->second.File, false, startOffset, result->second.LoopPoint)) {
|
|
_lastBgmTrack = trackId;
|
|
if (result->second.PlaybackOptions != -1) {
|
|
_oggMixer->SetPlaybackOptions(result->second.PlaybackOptions);
|
|
}
|
|
if (result->second.Volume != -1) {
|
|
_oggMixer->SetBgmVolume(result->second.Volume);
|
|
}
|
|
return true;
|
|
}
|
|
} else {
|
|
MessageManager::Log("[HDPack] Invalid album+track combination: " + std::to_string(_album) + ":" + std::to_string(track));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool HdAudioDevice::PlaySfx(uint8_t sfxNumber)
|
|
{
|
|
auto result = _hdData->SfxFilesById.find(_album * 256 + sfxNumber);
|
|
if(result != _hdData->SfxFilesById.end()) {
|
|
return !_oggMixer->Play(result->second, true, 0, 0);
|
|
} else {
|
|
MessageManager::Log("[HDPack] Invalid album+sfx number combination: " + std::to_string(_album) + ":" + std::to_string(sfxNumber));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void HdAudioDevice::ProcessControlFlags(uint8_t flags)
|
|
{
|
|
_oggMixer->SetPausedFlag((flags & 0x01) == 0x01);
|
|
if(flags & 0x02) {
|
|
_oggMixer->StopBgm();
|
|
}
|
|
if(flags & 0x04) {
|
|
_oggMixer->StopSfx();
|
|
}
|
|
}
|
|
|
|
void HdAudioDevice::GetMemoryRanges(MemoryRanges & ranges)
|
|
{
|
|
bool useAlternateRegisters = (_hdData->OptionFlags & (int)HdPackOptions::AlternateRegisterRange) == (int)HdPackOptions::AlternateRegisterRange;
|
|
ranges.SetAllowOverride();
|
|
|
|
if(useAlternateRegisters) {
|
|
for(int i = 0; i < 7; i++) {
|
|
ranges.AddHandler(MemoryOperation::Write, 0x3002 + i * 0x10);
|
|
}
|
|
ranges.AddHandler(MemoryOperation::Read, 0x4018);
|
|
ranges.AddHandler(MemoryOperation::Read, 0x4019);
|
|
} else {
|
|
ranges.AddHandler(MemoryOperation::Any, 0x4100, 0x4106);
|
|
}
|
|
}
|
|
|
|
void HdAudioDevice::WriteRAM(uint16_t addr, uint8_t value)
|
|
{
|
|
//$4100/$3002: Playback Options
|
|
//$4101/$3012: Playback Control
|
|
//$4102/$3022: BGM Volume
|
|
//$4103/$3032: SFX Volume
|
|
//$4104/$3042: Album Number
|
|
//$4105/$3052: Play BGM Track
|
|
//$4106/$3062: Play SFX Track
|
|
int regNumber = addr > 0x4100 ? (addr & 0xF) : ((addr & 0xF0) >> 4);
|
|
|
|
switch(regNumber) {
|
|
//Playback Options
|
|
//Bit 0: Loop BGM
|
|
//Bit 1-7: Unused, reserved - must be 0
|
|
case 0:
|
|
_playbackOptions = value;
|
|
_oggMixer->SetPlaybackOptions(_playbackOptions);
|
|
break;
|
|
|
|
//Playback Control
|
|
//Bit 0: Toggle Pause/Resume (only affects BGM)
|
|
//Bit 1: Stop BGM
|
|
//Bit 2: Stop all SFX
|
|
//Bit 3-7: Unused, reserved - must be 0
|
|
case 1: ProcessControlFlags(value); break;
|
|
|
|
//BGM Volume: 0 = mute, 255 = max
|
|
//Also has an immediate effect on currently playing BGM
|
|
case 2:
|
|
_bgmVolume = value;
|
|
_oggMixer->SetBgmVolume(value);
|
|
break;
|
|
|
|
//SFX Volume: 0 = mute, 255 = max
|
|
//Also has an immediate effect on all currently playing SFX
|
|
case 3:
|
|
_sfxVolume = value;
|
|
_oggMixer->SetSfxVolume(value);
|
|
break;
|
|
|
|
//Album number: 0-255 (Allows for up to 64k BGM and SFX tracks)
|
|
//No immediate effect - only affects subsequent $4FFE/$4FFF writes
|
|
case 4: _album = value; break;
|
|
|
|
//Play BGM track (0-255 = track number)
|
|
//Stop the current BGM and starts a new track
|
|
case 5: _trackError = PlayBgmTrack(value, 0); break;
|
|
|
|
//Play sound effect (0-255 = sfx number)
|
|
//Plays a new sound effect (no limit to the number of simultaneous sound effects)
|
|
case 6: _trackError = PlaySfx(value); break;
|
|
}
|
|
}
|
|
|
|
uint8_t HdAudioDevice::ReadRAM(uint16_t addr)
|
|
{
|
|
//$4100/$4018: Status
|
|
//$4101/$4019: Revision
|
|
//$4102: 'N' (signature to help detection)
|
|
//$4103: 'E'
|
|
//$4103: 'A'
|
|
switch(addr & 0x7) {
|
|
case 0:
|
|
//Status
|
|
return (
|
|
(_oggMixer->IsBgmPlaying() ? 1 : 0) |
|
|
(_oggMixer->IsSfxPlaying() ? 2 : 0) |
|
|
(_trackError ? 4 : 0)
|
|
);
|
|
|
|
case 1: return 1; //Revision
|
|
case 2: return 'N'; //NES
|
|
case 3: return 'E'; //Enhanced
|
|
case 4: return 'A'; //Audio
|
|
}
|
|
|
|
return 0;
|
|
}
|