6c97c3fff4140404021e609ea129628987ef69b5
Two related bugs in the user-facing fceumm_apu_1..5 channel disable
toggles. Pre-existing since commit 448a231 (set_apu_channels) and at
least as far back as the LQ rewrite for the second one.
set_apu_channels (libretro.c)
-----------------------------
The bitmask built by check_variables uses bit i for fceumm_apu_(i+1)
enabled, ordered SQ1, SQ2, Triangle, Noise, DMC. The old code:
FSettings.SquareVolume[1] = (chan & 1) ? 256 : 0;
FSettings.SquareVolume[0] = (chan & 2) ? 256 : 0;
FSettings.TriangleVolume = (chan & 3) ? 256 : 0;
FSettings.NoiseVolume = (chan & 4) ? 256 : 0;
FSettings.PCMVolume = (chan & 5) ? 256 : 0;
crossed SQ1/SQ2 and used non-power-of-two masks for the remaining
three. Practical effect: apu_1 muted SQ2 and apu_2 muted SQ1; apu_3
through apu_5 left their channels audible in any normal config (the
masks happened to be true any time another bit was set).
Fixed to read each channel's own bit:
FSettings.SquareVolume[0] = (chan & 0x01) ? 256 : 0; /* SQ1 */
FSettings.SquareVolume[1] = (chan & 0x02) ? 256 : 0; /* SQ2 */
FSettings.TriangleVolume = (chan & 0x04) ? 256 : 0; /* Tri */
FSettings.NoiseVolume = (chan & 0x08) ? 256 : 0; /* Nse */
FSettings.PCMVolume = (chan & 0x10) ? 256 : 0; /* DMC */
RDoTriangleNoisePCMLQ (sound.c)
-------------------------------
The combined Triangle/Noise/DMC LQ mix uses a non-linear lookup
table:
totalout = wlookup2[lq_tcout + noiseout + RawDALatch];
The old code took the noise envelope (EnvUnits[2], not Triangle -
Triangle has no envelope; EnvUnits[0]=SQ1, [1]=SQ2, [2]=Noise) and
scaled it by FSettings.TriangleVolume, despite the comment claiming
to modify Triangle. Meanwhile lq_tcout (Triangle) and RawDALatch
(DMC) went into wlookup2 unscaled, so neither TriangleVolume nor
PCMVolume had any effect in LQ mode.
Fixed:
* amptab[0] (noise envelope) is now scaled by FSettings.NoiseVolume.
* lq_tcout is scaled by FSettings.TriangleVolume into a local
scaled_tcout fed to wlookup2.
* RawDALatch is scaled by FSettings.PCMVolume into scaled_dmc.
The volume scalars are loop-invariant within this function, so the
Triangle volume is cached once in tri_vol at function entry to keep
the inner loops tight; the != 256 fast paths preserve byte-exact
behavior at full volume.
Verification
------------
Built per-channel-only test ROMs (test_sq1_only, test_sq2_only,
test_tri_only, test_nse_only, test_dmc_only) and an apu_test
runner that measures output RMS with each fceumm_apu_N toggle.
After the fix, in both LQ and HQ modes, each apu_N toggle mutes
exactly the channel whose ROM is the only sound source, and no
other toggle has any effect on it.
Default (all-on) audio output is bit-exact identical to the
baseline across the existing test_silent / test_idle / test_active /
test_stress ROMs (1500 frames each), so games and homebrew that
never touch the apu_N options see no change. No performance
regression in the default path; the != 256 guards skip the multiplies.
FCE Ultra mappers modified
FCEU "mappers modified" is an unofficial build of FCEU Ultra by CaH4e3, which supports a lot of new mappers including some obscure mappers such as one for unlicensed NES ROM's.
Sequential targets Light Guns support added
Support for Sequential targets Light Guns has been added. "Gun Aux A" serves as light sensor logic input.
Description
Languages
C
97.7%
Python
2%
C++
0.2%