ramapcsx2 / gbs-control

GNU General Public License v3.0
793 stars 111 forks source link

Fix auto gain accidentally running in bypass mode #451

Closed nyanpasu64 closed 1 year ago

nyanpasu64 commented 1 year ago

Auto gain in bypass mode is useless because writing to ADC_GGCTRL has no effect in bypass mode. Additionally it's bugged because runAutoGain() assumes DEC_TEST_ENABLE=1, but during bypass mode with auto gain enabled, it's sometimes but not always set to 0:

I'm not sure what to write to DEC_TEST_ENABLE in bypass mode. As a minimum viable fix, in this commit we avoid observing the wrong value by not calling runAutoGain() in bypass mode.

Testing

Background

While practicing Super Monkey Ball 2 in Nintendont with 480p forced in Nintendont and enabled in-game, and deflicker disabled in Nintendont, I got around 1 second of black screen mid-gameplay. The GBS-C was loaded in a custom preset in passthrough mode. My web browser (running but my computer was locked) showed only unintended "auto gain during bypass mode" messages, but it's possible the GBS-C lost Wi-Fi connection due to passthrough mode and did not print messages to my browser. I did not have a serial console open at the time.

I may have been running #446, or #429, or another debug branch with local changes.

I do not know why the black screen appeared, whether it was my Wii's software/hardware, the GBS-C, an overheating TV5725, my monitor, or a static discharge. It may be related to auto gain in passthrough, or not. But this is a long-standing bug worth fixing.

Future improvements

In a well-designed program, the value of DEC_TEST_ENABLE (along with all other registers) should be consistent, determined by a memoryless function of current "source state" alone, rather than by modifying past state but allowing part of it to survive unchanged.

There are various strategies, like writing every register unconditionally, or writing all registers which could change given the diff from the previous state. I think GBS-C attempts the latter strategy, but misses many registers due to a lack of rigor in ensuring correctness, and no "correct by design" systematic structured change tracking (the StateTransaction pattern).

ramapcsx2 commented 1 year ago

Ehr wait, I don't remember what registers it affected, but if it's working on "ADC_GGCTRL", that should totally work in bypass modes, too. Anything on the ADC directly will affect the image, as the source is always sampled through the ADC. What may not work is some related thing though, I don't quite remember what was required.

nyanpasu64 commented 1 year ago

Ehr wait, I don't remember what registers it affected, but if it's working on "ADC_GGCTRL", that should totally work in bypass modes, too. Anything on the ADC directly will affect the image, as the source is always sampled through the ADC.

I was under the impression it didn't work, since enabling auto gain in fixed/custom passthrough mode didn't set the brightness to "deliberately clipping", and usually (not always) did not function properly due to DEC_TEST_ENABLE=0. Adjusting manual gain is a slow tedious process, but does appear to change image brightness.