Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flipper issues on WOF (was: Lamps above 400 on Wheel of Fortune) #196

Closed
francisdb opened this issue Jan 18, 2024 · 35 comments · Fixed by #255
Closed

Flipper issues on WOF (was: Lamps above 400 on Wheel of Fortune) #196

francisdb opened this issue Jan 18, 2024 · 35 comments · Fixed by #255

Comments

@francisdb
Copy link
Contributor

First, is there a better place to ask these questions?

This table used to play without issues but Controller.ChangedLamps now seems to return lamps over 400 where the table code has only 400 entries in the arrays. Is this expected as it might break more tables?

2024-01-18 09:46:07.837 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 580 state 255'
2024-01-18 09:46:07.847 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 583 state 255'
2024-01-18 09:46:07.866 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 581 state 255'
2024-01-18 09:46:07.886 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 582 state 255'
2024-01-18 09:46:11.757 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 580 state 0'
2024-01-18 09:46:11.788 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 583 state 0'
2024-01-18 09:46:11.916 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 581 state 0'
2024-01-18 09:46:12.167 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 582 state 0'
2024-01-18 09:46:40.307 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 601 state 0'
2024-01-18 09:46:36.137 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 609 state 255'
2024-01-18 09:46:40.317 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 595 state 247'
2024-01-18 09:46:40.338 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 595 state 121'
2024-01-18 09:46:40.357 INFO  [28830] [DebuggerModule::Print@4232] Script.Print 'lamp 588 state 0'

PINMAME_SHA beec0c3

@vbousquet
Copy link
Contributor

This is intended and is only for WOF and WPT. It happens that these tables have LED matrices which seem to be PWMed so I added them as such.

@francisdb
Copy link
Contributor Author

francisdb commented Jan 19, 2024

Ok, I guess it's then up to the table writers to account for these new lamps.

For reference the required diff to fix this (along with some other standalone fixes)

--- "Wheel of Fortune (Stern 2007) 1.0.vbs.original.tmp"        2024-01-19 10:24:05.222749595 +0100
+++ "Wheel of Fortune (Stern 2007) 1.0.vbs"     2024-01-19 10:23:58.334543589 +0100
@@ -10,6 +10,8 @@
 If Err Then MsgBox "You need the controller.vbs in order to run this table, available in the vp10 package"
 On Error Goto 0
 
+Const cGameName = "wof_500"
+
 Const Ballsize = 52
 Const BallMass = 1.5
 
@@ -43,8 +45,6 @@
 '                                               INIT TABLE
 '************************************************************************
 
-Const cGameName = "wof_500"
-
 Dim bsTrough, PlungerIM, DTBank
 
 Sub Table1_Init
@@ -567,8 +567,8 @@
 ' SetLamp 1 is On
 ' fading for non opacity objects is 4 steps
 '***************************************************
-Dim LampState(400), FadingLevel(400)
-Dim FlashSpeedUp(400), FlashSpeedDown(400), FlashMin(400), FlashMax(400), FlashLevel(400)
+Dim LampState(610), FadingLevel(610)
+Dim FlashSpeedUp(610), FlashSpeedDown(610), FlashMin(610), FlashMax(610), FlashLevel(610)
 
 InitLamps()             ' turn off the lights and flashers and reset them to the default parameters
 LampTimer.Interval = 10 'lamp fading speed
@@ -913,7 +913,7 @@
 
 Function Vol(ball) ' Calculates the Volume of the sound based on the ball speed
     Vol = Csng(BallVel(ball) ^2 / 5000)
-       Debug.Print Vol
+       'Debug.Print Vol
 End Function
 
 Function Pan(ball) ' Calculates the pan for a ball based on the X position on the table. "table1" is the name of the table

@toxieainc
Copy link
Member

@vbousquet Is this something that should also be added to the whatsnew?

@toxieainc
Copy link
Member

Sidenote: As mentioned above, a similar patch is needed for WPT.

@francisdb
Copy link
Contributor Author

@vbousquet I also have issues with the flippers on WOF, sometimes they don't react or are stuck in the up position. Looks like some events get lost. Does that ring a bell?

@toxieainc
Copy link
Member

Is this with 10.8.0 or 10.8.1?

@francisdb
Copy link
Contributor Author

For now I can only reproduce it on standalone branch or 10.8.1 standalone, works fine on windows. And only for this table which is strange.

@jsm174
Copy link
Contributor

jsm174 commented Feb 6, 2024

Your windows pinmame is on the absolute latest?

@francisdb
Copy link
Contributor Author

Latest pre-release vpinmame downloaded yesterday.

@francisdb francisdb reopened this Feb 6, 2024
@francisdb
Copy link
Contributor Author

Can I test this in xpinmame without table?

@jsm174
Copy link
Contributor

jsm174 commented Feb 6, 2024

I'm at a loss, as to why this only a standalone issue. libpinmame is not doing anything to the data. (it was previously to support RGBs with VPE, but all that was reverted). Its running through all the same code as the win32com.

Maybe I missed a core_request_pwm_output_update();

Maybe a second set of eyes could compare:

PINMAMEAPI uint32_t PinmameGetSolenoidMask(const int low)
{
return vp_getSolMask(low);
}
/******************************************************
* PinmameSetSolenoidMask
******************************************************/
PINMAMEAPI void PinmameSetSolenoidMask(const int low, const uint32_t mask)
{
vp_setSolMask(low, mask);
}
/******************************************************
* PinmameGetModOutputType
******************************************************/
PINMAMEAPI PINMAME_MOD_OUTPUT_TYPE PinmameGetModOutputType(const int output, const int no)
{
return (PINMAME_MOD_OUTPUT_TYPE)vp_getModOutputType(output, no);
}
/******************************************************
* PinmameSetModOutputType
******************************************************/
PINMAMEAPI void PinmameSetModOutputType(const int output, const int no, const PINMAME_MOD_OUTPUT_TYPE type)
{
vp_setModOutputType(output, no, (int)type);
}
/******************************************************
* PinmameGetMaxSolenoids
******************************************************/
PINMAMEAPI int PinmameGetMaxSolenoids()
{
return CORE_MODOUT_SOL_MAX;
}
/******************************************************
* PinmameGetSolenoid
******************************************************/
PINMAMEAPI int PinmameGetSolenoid(const int solNo)
{
if (!_isRunning)
return 0;
core_request_pwm_output_update();
return vp_getSolenoid(solNo);
}
/******************************************************
* PinmameGetChangedSolenoids
******************************************************/
PINMAMEAPI int PinmameGetChangedSolenoids(PinmameSolenoidState* const p_changedStates)
{
if (!_isRunning)
return -1;
core_request_pwm_output_update();
vp_tChgSols chgSols;
const int count = vp_getChangedSolenoids(chgSols);
if (count > 0)
memcpy(p_changedStates, chgSols, count * sizeof(PinmameSolenoidState));
return count;
}
/******************************************************
* PinmameGetMaxLamps
******************************************************/
PINMAMEAPI int PinmameGetMaxLamps()
{
return CORE_MODOUT_LAMP_MAX;
}
/******************************************************
* PinmameGetLamp
******************************************************/
PINMAMEAPI int PinmameGetLamp(const int lampNo)
{
if (!_isRunning)
return 0;
core_request_pwm_output_update();
return vp_getLamp(lampNo);
}
/******************************************************
* PinmameGetChangedLamps
******************************************************/
PINMAMEAPI int PinmameGetChangedLamps(PinmameLampState* const p_changedStates)
{
if (!_isRunning)
return -1;
core_request_pwm_output_update();
vp_tChgLamps chgLamps;
const int count = vp_getChangedLamps(chgLamps);
if (count > 0)
memcpy(p_changedStates, chgLamps, count * sizeof(PinmameLampState));
return count;
}
/******************************************************
* PinmameGetMaxGIs
******************************************************/
PINMAMEAPI int PinmameGetMaxGIs()
{
return CORE_MODOUT_GI_MAX;
}
/******************************************************
* PinmameGetGI
******************************************************/
PINMAMEAPI int PinmameGetGI(const int giNo)
{
if (!_isRunning)
return 0;
core_request_pwm_output_update();
return vp_getGI(giNo);
}
/******************************************************
* PinmameGetChangedGIs
******************************************************/
PINMAMEAPI int PinmameGetChangedGIs(PinmameGIState* const p_changedStates)
{
if (!_isRunning)
return -1;
core_request_pwm_output_update();
vp_tChgGIs chgGIs;
const int count = vp_getChangedGI(chgGIs);
if (count > 0)
memcpy(p_changedStates, chgGIs, count * sizeof(PinmameGIState));
return count;
}
/******************************************************
* PinmameGetMaxLEDs
******************************************************/
PINMAMEAPI int PinmameGetMaxLEDs()
{
return CORE_MODOUT_SEG_MAX;
}
/******************************************************
* PinmameGetChangedLEDs
******************************************************/
PINMAMEAPI int PinmameGetChangedLEDs(const uint64_t mask, const uint64_t mask2, PinmameLEDState* const p_changedStates)
{
if (!_isRunning)
return -1;
core_request_pwm_output_update();
vp_tChgLED chgLEDs;
const int count = vp_getChangedLEDs(chgLEDs, mask, mask2);
if (count > 0)
memcpy(p_changedStates, chgLEDs, count * sizeof(PinmameLEDState));
return count;
}

to

/**************************************************************************
* IController.GIString property (read-only): returns state of a GI String
**************************************************************************/
STDMETHODIMP CController::get_GIString(int nString, int *pVal) {
if (!pVal) return S_FALSE;
if (WaitForSingleObject(m_hEmuIsRunning, 0) == WAIT_TIMEOUT)
*pVal = 0;
else {
core_request_pwm_output_update();
*pVal = vp_getGI(nString);
}
return S_OK;
}
/***************************************************************
* IController.ChangedGIString property: returns a list of the
* numbers of GIStrings which state has changed since the last call
* number is in the first, state in the second part
***************************************************************/
STDMETHODIMP CController::get_ChangedGIStrings(VARIANT *pVal) {
vp_tChgGIs chgGI;
if (!pVal) return S_FALSE;
if (WaitForSingleObject(m_hEmuIsRunning, 0) == WAIT_TIMEOUT)
{ pVal->vt = 0; return S_OK; }
/*-- Request an update that will be processed asynchronously --*/
core_request_pwm_output_update();
int uCount = vp_getChangedGI(chgGI);
if (uCount == 0)
{ pVal->vt = 0; return S_OK; }
/*-- Create array --*/
SAFEARRAYBOUND Bounds[] = {{(ULONG)uCount,0}, {2,0}};
SAFEARRAY *psa = SafeArrayCreate(VT_VARIANT, 2, Bounds);
long ix[2];
VARIANT GIState;
GIState.vt = VT_I4;
/*-- add changed to array --*/
for (ix[0] = 0; ix[0] < uCount; ix[0]++) {
ix[1] = 0; // GI Number
GIState.lVal = chgGI[ix[0]].giNo;
SafeArrayPutElement(psa, ix, &GIState);
ix[1] = 1; // GI status
GIState.lVal = chgGI[ix[0]].currStat;
SafeArrayPutElement(psa, ix, &GIState);
}
pVal->vt = VT_ARRAY | VT_VARIANT;
pVal->parray = psa;
return S_OK;
}
/****************************************************************************
* IController.ChangedSolenoids property (read-only): gets the state of all
* solenoids
* (also gets the information, if at least one solenoid has changed after
* last call; element 0 state if TRUE if at least one solenoid has changed
* state sice last call)
****************************************************************************/
STDMETHODIMP CController::get_ChangedSolenoids(VARIANT *pVal)
{
vp_tChgSols chgSol;
if (!pVal) return S_FALSE;
if (WaitForSingleObject(m_hEmuIsRunning, 0) == WAIT_TIMEOUT)
{ pVal->vt = 0; return S_OK; }
/*-- Request an update that will be processed asynchronously --*/
core_request_pwm_output_update();
/*-- Count changed solenoids --*/
int uCount = vp_getChangedSolenoids(chgSol);
if (uCount == 0)
{ pVal->vt = 0; return S_OK; }
/*-- Create array --*/
SAFEARRAYBOUND Bounds[] = {{(ULONG)uCount,0}, {2,0}};
SAFEARRAY *psa = SafeArrayCreate(VT_VARIANT, 2, Bounds);
long ix[2];
VARIANT varValue;
varValue.vt = VT_I4;
/*-- add changed solenoids to the array --*/
for (ix[0] = 0; ix[0] < uCount; ix[0]++) {
ix[1] = 0; // Solenoid number
varValue.lVal = chgSol[ix[0]].solNo;
SafeArrayPutElement(psa, ix, &varValue);
ix[1] = 1; // Solenoid status
varValue.lVal = chgSol[ix[0]].currStat;
SafeArrayPutElement(psa, ix, &varValue);
}
pVal->vt = VT_ARRAY | VT_VARIANT;
pVal->parray = psa;
return S_OK;
}
/****************************************************************************
* IController.SplashInfoLine property: sets the value of the user setable
* text in the splash screen
****************************************************************************/
STDMETHODIMP CController::get_SplashInfoLine(BSTR *pVal)
{
CComBSTR strValue(m_szSplashInfoLine);
*pVal = strValue.Detach();
return S_OK;
}
STDMETHODIMP CController::put_SplashInfoLine(BSTR newVal)
{
WideCharToMultiByte(CP_ACP, 0, newVal, -1, m_szSplashInfoLine, sizeof m_szSplashInfoLine, NULL, NULL);
return S_OK;
}
/****************************************************************************
* IController.Solenoids property (read-only): returns the state of all
* solenoids at once
****************************************************************************/
STDMETHODIMP CController::get_Solenoids(VARIANT *pVal)
{
if ( !pVal )
return S_FALSE;
/*-- Request an update that will be processed asynchronously --*/
core_request_pwm_output_update();
SAFEARRAY *psa = SafeArrayCreateVector(VT_VARIANT, 0, 65);
VARIANT* pData;
SafeArrayAccessData(psa, (void**)&pData);
const bool timeout = (WaitForSingleObject(m_hEmuIsRunning, 0) == WAIT_TIMEOUT);
for (int i = 0; i < 65; ++i)
{
pData[i].vt = VT_BOOL;
pData[i].boolVal = timeout ? VARIANT_FALSE : (vp_getSolenoid(i) ? VARIANT_TRUE : VARIANT_FALSE);
}
SafeArrayUnaccessData(psa);
pVal->vt = VT_ARRAY|VT_VARIANT;
pVal->parray = psa;
return S_OK;
}
/****************************************************************************
* IController.Dip property: gets/sets the value of a dip bank
****************************************************************************/
STDMETHODIMP CController::get_Dip(int nNo, int *pVal)
{
// TODO: Add your implementation code here. DONE
if (!pVal) return S_FALSE;
*pVal = vp_getDIP(nNo);
return S_OK;
}
STDMETHODIMP CController::put_Dip(int nNo, int newVal)
{
// TODO: Add your implementation code here. DONE
vp_setDIP(nNo, newVal);
return S_OK;
}
/****************************************************************************
* IController.GIStrings property (read-only): gets the value of all GI
* strings at once
****************************************************************************/
STDMETHODIMP CController::get_GIStrings(VARIANT *pVal)
{
if ( !pVal )
return S_FALSE;
/*-- Request an update that will be processed asynchronously --*/
core_request_pwm_output_update();
SAFEARRAY *psa = SafeArrayCreateVector(VT_VARIANT, 0, CORE_MAXGI);
VARIANT* pData;
SafeArrayAccessData(psa, (void**)&pData);
const bool timeout = (WaitForSingleObject(m_hEmuIsRunning, 0) == WAIT_TIMEOUT);
for (int i = 0; i < CORE_MAXGI; ++i)
{
pData[i].vt = VT_I4;
pData[i].lVal = timeout ? 0 : vp_getGI(i);
}
SafeArrayUnaccessData(psa);
pVal->vt = VT_ARRAY|VT_VARIANT;
pVal->parray = psa;
return S_OK;
}
/****************************************************************************
* IController.LockDisplay property: If the display is locked, anytime the
* video window will receive the focus the focus will immediatly be returned
* to the window which had it before
****************************************************************************/
STDMETHODIMP CController::get_LockDisplay(VARIANT_BOOL *pVal)
{
if (pVal)
*pVal = m_fDisplayLocked?VARIANT_TRUE:VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP CController::put_LockDisplay(VARIANT_BOOL newVal)
{
m_fDisplayLocked = newVal;
return S_OK;
}
/****************************************************************************
* IController.SolMask property: gets/sets a mask for the solenoids, i.e.
* which solenoid state should be reported by ChangedSolenoids
****************************************************************************/
STDMETHODIMP CController::get_SolMask(int nLow, long *pVal)
{
if ( !pVal)
return S_FALSE;
*pVal = vp_getSolMask(nLow);
return S_OK;
}
STDMETHODIMP CController::put_SolMask(int nLow, long newVal)
{
// TODO B2S hack, see vp_setSolMask()
if (!((0 <= nLow && nLow <= 2) || (1000 <= nLow && nLow < 2999)))
return S_FALSE;
vp_setSolMask(nLow, newVal);
return S_OK;
}
/****************************************************************************
* IController.ModOutputType property: gets/sets modulated output type, i.e.
* how the output behaves when it is modulated
****************************************************************************/
STDMETHODIMP CController::get_ModOutputType(int output, int no, int* pVal)
{
if (output != VP_OUT_SOLENOID)
return S_FALSE;
*pVal = vp_getModOutputType(output, no);
return S_OK;
}
STDMETHODIMP CController::put_ModOutputType(int output, int no, int newVal)
{
if (output != VP_OUT_SOLENOID)
return S_FALSE;
vp_setModOutputType(output, no, newVal);
return S_OK;
}

@francisdb
Copy link
Contributor Author

Can you reproduce the issue on mac? Haven't tried that yet.

@toxieainc
Copy link
Member

I think that we still have some issues/regressions here and there with 10.8.1, compared to 10.8.0, so maybe this is related??

@toxieainc toxieainc changed the title Lamps above 400 on Wheel of Fortune Flipper issues on WOF (was: Lamps above 400 on Wheel of Fortune) Feb 7, 2024
@toxieainc
Copy link
Member

@vbousquet Any idea maybe??

@francisdb
Copy link
Contributor Author

francisdb commented Feb 7, 2024

Made some progress as to find the cause of the issue

Commenting out Controller.ChangedLamps in the LampTimer_Timer solves the flipper issue. (with of course lamps no longer working).

@francisdb
Copy link
Contributor Author

Should I move this over to a new issue?

@mazjohn
Copy link

mazjohn commented Feb 20, 2024

WOF -Table lighting/ lamps do not work or flash at all in vpinmame latest builds. Flippers erratic/get stuck - cannot isolate. Tested with 10.73 x86 final and 10.8 rc1 with same results...intermittant script errors:
Runtime error

Line: 593
Subscript out of range: 'chgLamp(...)'

Edit/ Update: reverted back to build 720 dated DEC31 release and the issues are gone. I'm not a programmer- So dumb question: will all table scripts that do not get updated be broken moving forwards or will this below fix make its way into a future build to ensure backwards compatibility? respect// thank you for bringing these amazing works to this hobby.

@francisdb
Copy link
Contributor Author

francisdb commented Feb 20, 2024

That specific issue is fixed by changing the array declarations from capacity 400 to 610 in the script.

See jsm174/vpx-standalone-scripts#251

@toxieainc
Copy link
Member

Flipper issues could be fixed now, please test @francisdb

@toxieainc
Copy link
Member

Doesn't work for me yet, so far, so reopening. @vbousquet for vis

@toxieainc toxieainc reopened this Feb 24, 2024
@francisdb
Copy link
Contributor Author

Probably stupid question: what do you mean with "for vis"?

@toxieainc
Copy link
Member

I'm never 100% sure if Vince gets the PinMAME issue mails, so pinging him explicitly for stuff that is related to his changes.

@vbousquet
Copy link
Contributor

I keep an eye on Github only (I also have a look from time to time to discord / VPF but the feedback is usually too largely spread and not enough cleanly reported to be usable) but I miss things. There are just too much. So no problem.

Regarding the SAM emulation issues. I have just pushed a new PR for these bugs which improves flipper emulation (lower latency, hack designed around IJ4 emulation bug only). The original implementation also used some nasty hacks to keep things running so it is a bit difficult to identify what should be removed since some hacks were only needed due to the lack of PWM support, other are needed due to emulation issue (like IJ4).

For WOF, I was not able to reproduce the issue (on the latest with teh latest fix), so I would need some more hints to have a look.

@francisdb
Copy link
Contributor Author

I'm never 100% sure if Vince gets the PinMAME issue mails, so pinging him explicitly for stuff that is related to his changes.

Got that part but I suppose that's some kind of abbreviation?

Screenshot_20240224-103847

@toxieainc
Copy link
Member

Simpler.. _vis_ibility

@toxieainc
Copy link
Member

WOF flippers now seem to consistently work with the latest commit 544085b, @francisdb please also verify

@francisdb
Copy link
Contributor Author

francisdb commented Feb 24, 2024

Issue still there for me with latest pinmame on standalone linux 10.8.1 and 7b0aafb
Still fixes itself by commenting out Controller.ChangedLamps

    ' chgLamp = Controller.ChangedLamps
    ' If Not IsEmpty(chgLamp) Then
    '     For ii = 0 To UBound(chgLamp)
    '         LampState(chgLamp(ii, 0) ) = chgLamp(ii, 1)       'keep the real state in an array
    '         FadingLevel(chgLamp(ii, 0) ) = chgLamp(ii, 1) + 4 'actual fading step
    '     Next
    ' End If

@francisdb
Copy link
Contributor Author

@toxieainc why can't I reopen this issue?

@toxieainc
Copy link
Member

No clue, reopening

@toxieainc toxieainc reopened this Feb 26, 2024
@vbousquet
Copy link
Contributor

This is the latest issue (beside improving filtering) following the PWM changes but I still can't reproduce it.
Reading from the above, I'm not sure:

  • if it happens on regular Window's version of VPX or if it only on standalone,
  • if it still there following the latest script changes inside VPX (and especially cleanups of SAM flipper code).

@francisdb could you confirm if the bug is still there for you ? If so, could you provide a link to the offending table (to check if it is maybe a table script bug) ?

@francisdb
Copy link
Contributor Author

For now I can only reproduce it on standalone branch or 10.8.1 standalone, works fine on windows. And only for this table which is strange.

https://vpuniverse.com/files/file/5501-wheel-of-fortune-stern-2007/

With patched script from https://github.com/jsm174/vpx-standalone-scripts/tree/master/Wheel%20of%20Fortune%20(Stern%202007)%201.0 (increased array sizes)

Still have flippers not always reacting or being stuck in up position with latest 10.8.1 branch but happens less often than before.

Not calling Controller.ChangedLamps still fixes the issue or makes it much less likely to happen.

@jsm174 can you reproduce this one on mac/linux?

@toxieainc
Copy link
Member

@francisdb Can you please test again with the latest build?

@francisdb
Copy link
Contributor Author

Issue persists with b06d8d4
Do we have anybody else who can reproduce this issue?

@embryodead
Copy link

As previous user say lastest vpx 10.8 build on windows with the lastest vpinmame build from yesterday.
wpt, wof and also big buck hunter, no insert on playfield even with the fix in the script and flipper stuck on wof(flippers are fine in indy and wpt).

@francisdb
Copy link
Contributor Author

Confirming this is fixed. Thanks @vbousquet !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants