Up until now, that support was limited to graphic replacement, but with that mostly being done, I decided to give audio replacement a go, too.
HDNes has a tool to create conditions to instruct the emulator on when to replace music, but I figured making this flexible enough to work on all games would be a lot of work. So I decided to go in another direction, similar to byuu's MSU1.
This is what I came up with:
Code: Select all
switch(addr) {
//Playback Options
//Bit 0: Loop BGM
//Bit 1-7: Unused, reserved - must be 0
case 0x4FF9: _oggMixer->SetPlaybackOptions(value); 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 0x4FFA: ProcessControlFlags(value); break;
//BGM Volume: 0 = mute, 255 = max
//Also has an immediate effect on currently playing BGM
case 0x4FFB: _oggMixer->SetBgmVolume(value); break;
//SFX Volume: 0 = mute, 255 = max
//Also has an immediate effect on all currently playing SFX
case 0x4FFC: _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 0x4FFD: _album = value; break;
//Play BGM track (0-255 = track number)
//Stop the current BGM and starts a new track
case 0x4FFE: _trackError = PlayBgmTrack(value); break;
//Play sound effect (0-255 = sfx number)
//Plays a new sound effect (no limit to the number of simultaneous sound effects)
case 0x4FFF: _trackError = PlaySfx(value); break;
}
Only 1 bgm (looped or not) can play at a time, along with any number of sound effects. The bgm can be paused, but not sound effects (maybe they should?)
BGM & sound effect volume is independent, but all sound effects share the same volume setting.
Obviously the downside to this is that the game needs to be patched (IPS/BPS patches can be bundled with the audio files in Mesen's case). The upside is that it can be made to work with pretty much any game.
Does anyone see anything weird, missing or outright bad with this?
e.g:
-Mapper-wise, as far as I know, no major mapper uses this address range, I think?
-There is no seek capability, just play/pause/stop - I couldn't really find any scenarios where seeking would be useful, but I'm not a game dev. Would it be useful to have?
-Does the API make sense from the point of view of someone coding a game in 6502 assembly? I did hack up SMB1 to use this and replaced a few BGMs and some sound effects in a short amount of time (video). The fully disassembled & commented version of the code definitely helped make this easy, though.
-Would using these registers on an actual cart make sense?
I have no intention of actually designing a chip that would support this, but at the very least, I'd like to make it so that it would technically be possible to make one.