bsnes/higan/gba/apu/sequencer.cpp

109 lines
2.4 KiB
C++
Raw Normal View History

auto APU::runsequencer() -> void {
auto& r = sequencer;
if(r.base == 0) { //512hz
if(r.step == 0 || r.step == 2 || r.step == 4 || r.step == 6) { //256hz
square1.clocklength();
square2.clocklength();
wave.clocklength();
noise.clocklength();
}
if(r.step == 2 || r.step == 6) { //128hz
square1.clocksweep();
}
if(r.step == 7) { //64hz
square1.clockenvelope();
square2.clockenvelope();
noise.clockenvelope();
}
r.step++;
}
r.base++;
Update to v096r07 release. byuu says: Changelog: - configuration files are now stored in localpath() instead of configpath() - Video gamma/saturation/luminance sliders are gone now, sorry - added Video Filter->Blur Emulation [1] - added Video Filter->Scanline Emulation [2] - improvements to GBA audio emulation (fixes Minish Cap) [Jonas Quinn] [1] For the Famicom, this does nothing. For the Super Famicom, this performs horizontal blending for proper pseudo-hires translucency. For the Game Boy, Game Boy Color, and Game Boy Advance, this performs interframe blending (each frame is the average of the current and previous frame), which is important for things like the GBVideoPlayer. [2] Right now, this only applies to the Super Famicom, but it'll come to the Famicom in the future. For the Super Famicom, this option doesn't just add scanlines, it simulates the phosphor decay that's visible in interlace mode. If you observe an interlaced game like RPM Racing on a real SNES, you'll notice that even on perfectly still screens, the image appears to shake. This option emulates that effect. Note 1: the buffering right now is a little sub-optimal, so there will be a slight speed hit with this new support. Since the core is now generating native ARGB8888 colors, it might as well call out to the interface to lock/unlock/refresh the video, that way it can render directly to the screen. Although ... that might not be such a hot idea, since the GBx interframe blending reads from the target buffer, and that tends to be a catastrophic option for performance. Note 2: the balanced and performance profiles for the SNES are completely busted again. This WIP took 6 1/2 hours, and I'm exhausted. Very much not looking forward to working on those, since those two have all kinds of fucked up speedup tricks for non-interlaced and/or non-hires video modes. Note 3: if you're on Windows and you saved your system folders somewhere else, now'd be a good time to move them to %localappdata%/higan
2016-01-15 10:06:51 +00:00
if(square1.enable) square1.run();
if(square2.enable) square2.run();
if(wave.enable) wave.run();
if(noise.enable) noise.run();
}
Update to v102r22 release. byuu says: Changelog: - higan: Emulator::Interface::videoSize() renamed to videoResolution() - higan: Emulator::Interface::rtcsync() renamed to rtcSynchronize() - higan: added video display rotation support to Video - GBA: substantially improved audio mixing - fixed bug with FIFO 50%/100% volume setting - now properly using SOUNDBIAS amplitude to control output frequencies - reduced quantization noise - corrected relative volumes between PSG and FIFO channels - both PSG and FIFO values cached based on amplitude; resulting in cleaner PCM samples - treating PSG volume=3 as 200% volume instead of 0% volume now (unverified: to match mGBA) - GBA: properly initialize ALL CPU state; including the vital prefetch.wait=1 (fixes Classic NES series games) - GBA: added video rotation with automatic key translation support - PCE: reduced output resolution scalar from 285x242 to 285x240 - the extra two scanlines won't be visible on most TVs; and they make all other cores look worse - this is because all other cores output at 240p or less; so they were all receiving black bars in windowed mode - tomoko: added "Rotate Display" hotkey setting - tomoko: changed hotkey multi-key logic to OR instead of AND - left support for flipping it back inside the core; for those so inclined; by uncommenting one line in input.hpp - tomoko: when choosing Settings→Configuration, it will automatically select the currently loaded system - for instance, if you're playing a Game Gear game, it'll take you to the Game Gear input settings - if no games are loaded, it will take you to the hotkeys panel instead - WS(C): merged "Hardware-Vertical", "Hardware-Horizontal" controls into combined "Hardware" - WS(C): converted rotation support from being inside the core to using Emulator::Video - this lets WS(C) video content scale larger now that it's not bounded by a 224x224 square box - WS(C): added automatic key rotation support - WS(C): removed emulator "Rotate" key (use the general hotkey instead; I recommend F8 for this) - nall: added serializer support for nall::Boolean (boolean) types - although I will probably prefer the usage of uint1 in most cases
2017-06-08 14:05:48 +00:00
auto APU::Sequencer::sample() -> void {
loutput = 0;
routput = 0;
if(!masterenable) return;
if(lenable[0]) loutput += apu.square1.output;
if(lenable[1]) loutput += apu.square2.output;
if(lenable[2]) loutput += apu.wave.output;
if(lenable[3]) loutput += apu.noise.output;
loutput *= 1 + lvolume;
loutput <<= 1;
loutput >>= 3 - volume;
if(renable[0]) routput += apu.square1.output;
if(renable[1]) routput += apu.square2.output;
if(renable[2]) routput += apu.wave.output;
if(renable[3]) routput += apu.noise.output;
routput *= 1 + rvolume;
routput <<= 1;
routput >>= 3 - volume;
}
auto APU::Sequencer::read(uint addr) const -> uint8 {
switch(addr) {
case 0: return (rvolume << 0) | (lvolume << 4);
case 1: return (
(renable[0] << 0)
| (renable[1] << 1)
| (renable[2] << 2)
| (renable[3] << 3)
| (lenable[0] << 4)
| (lenable[1] << 5)
| (lenable[2] << 6)
| (lenable[3] << 7)
);
Update to v096r07 release. byuu says: Changelog: - configuration files are now stored in localpath() instead of configpath() - Video gamma/saturation/luminance sliders are gone now, sorry - added Video Filter->Blur Emulation [1] - added Video Filter->Scanline Emulation [2] - improvements to GBA audio emulation (fixes Minish Cap) [Jonas Quinn] [1] For the Famicom, this does nothing. For the Super Famicom, this performs horizontal blending for proper pseudo-hires translucency. For the Game Boy, Game Boy Color, and Game Boy Advance, this performs interframe blending (each frame is the average of the current and previous frame), which is important for things like the GBVideoPlayer. [2] Right now, this only applies to the Super Famicom, but it'll come to the Famicom in the future. For the Super Famicom, this option doesn't just add scanlines, it simulates the phosphor decay that's visible in interlace mode. If you observe an interlaced game like RPM Racing on a real SNES, you'll notice that even on perfectly still screens, the image appears to shake. This option emulates that effect. Note 1: the buffering right now is a little sub-optimal, so there will be a slight speed hit with this new support. Since the core is now generating native ARGB8888 colors, it might as well call out to the interface to lock/unlock/refresh the video, that way it can render directly to the screen. Although ... that might not be such a hot idea, since the GBx interframe blending reads from the target buffer, and that tends to be a catastrophic option for performance. Note 2: the balanced and performance profiles for the SNES are completely busted again. This WIP took 6 1/2 hours, and I'm exhausted. Very much not looking forward to working on those, since those two have all kinds of fucked up speedup tricks for non-interlaced and/or non-hires video modes. Note 3: if you're on Windows and you saved your system folders somewhere else, now'd be a good time to move them to %localappdata%/higan
2016-01-15 10:06:51 +00:00
case 2: return (
(apu.square1.enable << 0)
| (apu.square2.enable << 1)
| (apu.wave.enable << 2)
| (apu.noise.enable << 3)
| (masterenable << 7)
);
}
}
auto APU::Sequencer::write(uint addr, uint8 byte) -> void {
switch(addr) {
case 0: //NR50
rvolume = byte >> 0;
lvolume = byte >> 4;
break;
case 1: //NR51
renable[0] = byte >> 0;
renable[1] = byte >> 1;
renable[2] = byte >> 2;
renable[3] = byte >> 3;
lenable[0] = byte >> 4;
lenable[1] = byte >> 5;
lenable[2] = byte >> 6;
lenable[3] = byte >> 7;
break;
case 2: //NR52
masterenable = byte >> 7;
break;
}
}
auto APU::Sequencer::power() -> void {
lvolume = 0;
rvolume = 0;
for(auto& n : lenable) n = 0;
for(auto& n : renable) n = 0;
masterenable = 0;
base = 0;
step = 0;
lsample = 0;
rsample = 0;
}