Jabbah / irFFB

ACC force feedback utility based on irFFB
23 stars 2 forks source link

FFB lost when leaving ACC session #1

Open gpo123 opened 2 years ago

gpo123 commented 2 years ago

The software used: OS Win10 20H2 vjoy 1.9.1, second device of vjoy driver used for ACCFFB, x-axis, no buttons, all FFB efects, is reliabely detected by ACCFFB ACCFFB, all versions until 0.1.2 Beta (0.1.1 and 0.1.2 both released and self compiled versions ACC 1.7.6 VRS direct force pro DD Wheel: no windows driver, FBB is handled directly by wheel firmware (AFAIK)

TL;DR: I am loosing FFB totally when using ACCFFB when leaving a session. Does not matter if I am going to setup a device or changing the session type e.g. from practice to quick race. I can not regain FFB by restarting ACCFBB. Steering itself works though. FFB on the vjoy device seems to work by sending FFB events via Wheelcheck. The latter was tested in the situation where ACC has lost the FFB.

I started to look around in the code and a little debugging (not a real windows programmer here, only a long time dumb PLC programmer). First thing I noticed is that the "on track" display never changed when I left the track. That is clear because I often left the track not being in the pit. Which you can not do in Hotlap mode anyway. That lead to "resetForces();". So I changed your code from: if (onTrack && pfGfx->isInPit) { debug(L"No longer on track"); onTrack = false; setOnTrackStatus(onTrack); resetForces(); clippingReport(); } else if (!onTrack && !pfGfx->isInPit) { debug(L"Now on track"); onTrack = true; setOnTrackStatus(onTrack); } to

if (onTrack && (pfPhys->rpms < 20)) { debug(L"No longer on track"); onTrack = false; setOnTrackStatus(onTrack); resetForces(); clippingReport(); } else if (!onTrack && (pfPhys->rpms > 100)) { debug(L"Now on track"); onTrack = true; setOnTrackStatus(onTrack); }

Obviously a quick hack, but at least kinda working for me. I also played around with "ignitionOn" and "isEngineRunning" by populating SharedFileOut.h. But that did not work reliable. I think that is due to the fact that there are more fields now in shared memory than the header file reflects.

Debugging session was kind of interesting. I set two breakpoints right into the two threads "readWheelThread" and "directFFBThread". Both breakpoints were passed when ACC started and the first session was active. After closing and restarting the next session the breakpoint in "directFBBThread" was never reached. Closing and restarting ACCFFB lead to passing the breakpoint exactly one time. Seems the whole "directFBBThread" was hanging.

For me it seems that the very first line in this thread is the culprit: // Signalled when force has been updated WaitForSingleObject(ffbEvent, INFINITE); This is the event that is synchronized with ACC. I quote the Microsoft documentation for this function: If this handle is closed while the wait is still pending, the function's behavior is undefined.

Can it be that ACC closes the handle on its side and therefore the thread is dead ?

I will recheck the behaviour with a Logitech wheel to see if that makes a difference. Otherwise I have to dig into the vjoy SDK source code to understand how this device driver thing works.

I would really like to get this apllication running reliably because its the only way to tune the ACC FFB to my liking. Do you recommend a vjoy version ? (Sorry for the wall of text)

gpo123 commented 2 years ago

Did a retest with an old Logitech Driving Force GT. ACCFFB seemed to be working fine. I could switch sessions without issues. By chance I found a temporary workaround for me: If I start ACCFFB after ACC and consequently wait until ACCFFB shows "Not on track" by shutting off the engine (implemented with the changes above) I can change sessions and setups just fine.

gpo123 commented 2 years ago

Can be closed. I am working on getting the "directFBBThread" more reentrant safe. Maybe I will file a pull request when done.