Mesen/Core/BaseApuChannel.h

109 lines
1.9 KiB
C
Raw Normal View History

#pragma once
#include "stdafx.h"
#include "IMemoryHandler.h"
2015-07-17 20:58:57 -04:00
#include "EmulationSettings.h"
2015-07-19 22:24:56 -04:00
#include "Snapshotable.h"
#include "SoundMixer.h"
#include "Console.h"
2015-07-14 23:35:30 -04:00
class BaseApuChannel : public IMemoryHandler, public Snapshotable
{
private:
SoundMixer *_mixer;
uint32_t _previousCycle;
2015-07-17 20:58:57 -04:00
AudioChannel _channel;
2015-07-21 23:05:27 -04:00
NesModel _nesModel;
protected:
2017-08-30 18:31:27 -04:00
int8_t _lastOutput;
uint16_t _timer = 0;
uint16_t _period = 0;
shared_ptr<Console> _console;
2015-07-17 20:58:57 -04:00
AudioChannel GetChannel()
{
return _channel;
}
public:
virtual void Clock() = 0;
virtual bool GetStatus() = 0;
BaseApuChannel(AudioChannel channel, shared_ptr<Console> console, SoundMixer *mixer)
{
2015-07-17 20:58:57 -04:00
_channel = channel;
_mixer = mixer;
_console = console;
2018-01-07 09:44:43 -05:00
_nesModel = NesModel::NTSC;
2015-07-14 23:35:30 -04:00
Reset(false);
}
virtual void Reset(bool softReset)
{
2015-07-14 23:35:30 -04:00
_timer = 0;
_period = 0;
_lastOutput = 0;
_previousCycle = 0;
if(_mixer) {
//_mixer is null/not needed for MMC5 square channels
_mixer->Reset();
}
2015-07-14 23:35:30 -04:00
}
2016-12-17 23:14:47 -05:00
virtual void StreamState(bool saving) override
2015-07-14 23:35:30 -04:00
{
if(!saving) {
_previousCycle = 0;
}
Stream(_lastOutput, _timer, _period, _nesModel);
}
2015-07-21 23:05:27 -04:00
void SetNesModel(NesModel model)
{
_nesModel = model;
}
NesModel GetNesModel()
{
if(_nesModel == NesModel::NTSC || _nesModel == NesModel::Dendy) {
//Dendy APU works with NTSC timings
return NesModel::NTSC;
} else {
return _nesModel;
}
2015-07-21 23:05:27 -04:00
}
void Run(uint32_t targetCycle)
{
int32_t cyclesToRun = targetCycle - _previousCycle;
while(cyclesToRun > _timer) {
cyclesToRun -= _timer + 1;
_previousCycle += _timer + 1;
Clock();
_timer = _period;
}
_timer -= cyclesToRun;
_previousCycle = targetCycle;
}
2016-12-17 23:14:47 -05:00
uint8_t ReadRAM(uint16_t addr) override
{
return 0;
}
void AddOutput(int8_t output)
{
if(output != _lastOutput) {
_mixer->AddDelta(_channel, _previousCycle, output - _lastOutput);
_lastOutput = output;
}
}
void EndFrame()
{
_previousCycle = 0;
}
};