nyanpasu64 / j0CC-FamiTracker

(Archived, see https://github.com/Dn-Programming-Core-Management/Dn-FamiTracker) Numerous bugfixes for 0CC-FamiTracker (based off 0.3.14.5).
https://github.com/Dn-Programming-Core-Management/Dn-FamiTracker
GNU General Public License v2.0
15 stars 2 forks source link

VRC7: If FM Channel 1 uses a normal patch and any other FM Channel using a custom patch calls the Ixx effect, the Ixx effect doesn't work [j0CC-Dev-67] #53

Closed teimoso closed 6 years ago

teimoso commented 6 years ago

This issue does not occur in 0CC-FamiTracker 0.3.15.1, but does occur in 0.3.14.5

Description

If a note is played on FM Channel 1, the Ixx effect stops working on all channels. FM channels 2, 3, 4, 5, and 6 don't seem to cause this issue.

What doesn't appear to affect the issue
What appears to bypass the issue

Example

vrc7_i00_issue.0cc.gz is a gzip archive file containing a .0cc project which (partially) demonstrates the issue in j0CC. (I tried to attach a .zip file, but it was denied for some reason) Experimenting with patches/instruments/muting/etc. might help in narrowing down the problem further. (Note: the D00 frame skipping is likely unnecessary, but it's 2 am and i don't feel like taking it out)

A brief text description

A note with instrument 02 (custom patch) plays on FM Channel 6. Two rows after it, a note with instrument 00 (normal patch) plays on FM Channel 1. Two rows after that, the I00 effect is called on FM Channel 6. Nothing happens on FM Channel 6.

Two notes, from FM Channel 1 and 6, are played at the same time, and use the same instrument (thus, patch). Shortly after, FM Channel 6 calls effect I00. The effect goes through normally, and continues to do so even after the previous events are repeated, but with FM Channel 1 swapped for 2. After the module loops and FM Channel 1 plays again, Ixx breaks and the cycle repeats.

Reproduction

The attached file and/or example should (hopefully) be enough to reproduce, or figure out how to reproduce, the issue. Let me know if anything else is needed.

Operating System        Windows 7 (64-bit, Home Premium)
nyanpasu64 commented 6 years ago

I'm busy and won't be looking at this for a while. You can bisect using Git and Visual Studio between https://github.com/HertzDevil/0CC-FamiTracker tags v0.3.14.5 and v0.3.15.1 yourself (use git bisect old/new, since this is a bugfix and good/bad are backwards), if you want it fixed soon.

nyanpasu64 commented 6 years ago

Can you test the build at https://ci.appveyor.com/api/buildjobs/lvt3k3x4pr2gtevg/artifacts/Release%2Fj0CC-PR59-vrc7-ixx-fix-build36.exe ?

All 6 channels first call HandleEffect when effects are found. Then RefreshChannel (render to VRC7 chip) is called from left to right.

If anywhere Ixx writes to custom instruments, and Channel 1 calls RefreshChannel() with a preset instrument, RefreshChannel skips writing to registers, but erroneously marks registers as unmodified (since the unmodified flag is shared between all channels).

i do not know why this bug was fixed in 0.3.15.1 (october 2017). The bugfix (https://github.com/HertzDevil/0CC-FamiTracker/commit/9bc3dfada3ac31764bff1473d54bd72246811ee8) occurred in february 2018.

Anyway I cherry-picked that commit which seems to have fixed the bug locally.

Also hertzdevil changed the thing afterwards, moving the custom instrument handling code to CChipHandlerVRC7, which is shared across all channels. The "modified/dirty" flag is set whenever Ixx is used, and Ixx is written/reset at some point (possibly after RefreshChannel?). https://github.com/HertzDevil/0CC-FamiTracker/commit/ad8bc10f15b6785fca3a79b92665c5fdbf0df2a6#diff-fd999b9e377460ab38f1bd3912bc45c8

teimoso commented 6 years ago

That build appears to fix the issue without any side-effects; with it, the Ixx effect works as expected on two different modules (including this issue's example). Thanks for looking into it! Strange how it got fixed between 0.3.14.5 and 0.3.15.1 before breaking again...