Jump to content

Cactus Canyon PuP-Pack: PuPCapture (D) triggers never fire, switch (W) triggers work — "Error opening PinUP output" with dmdext x64*


Recommended Posts

Posted (edited)

**Cactus Canyon PuP-Pack: PuPCapture (D) triggers never fire, switch (W) triggers work — "Error opening PinUP output" with dmdext x64**
 

Hoping someone can tell me whether PuPCapture is supposed to work with the 64-bit dmdext, because everything else in my setup checks out and I've run out of things to test.
 

**Symptom**
 

The W (rom event) triggers in the pack fire correctly in game — "Quick Draw Is Lit" plays every time. None of the D (PuPCapture) triggers ever fire, which is 113 of the 121 unique triggers in the pack. So the vast majority of the pack is inert.
 

**Setup**
 

- Table: Cactus Canyon (& Continued) (Bally 1998) VPW Mod 1.1, Const PROC = 0
- ROM: cc_13, English, plays fine
- PuP-Pack: Cactus Canyon PuP Pack by classicradios, in PUPVideos\cc_13\, FullDMD .bat applied
- PinUP Popper via Baller Installer (updated to v2.0 via web updater)
- VPX x64 (VPinballX.exe), dmdext 2.5.1-CORE-r9 (x64), DmdDevice64.dll
- Displays: 4K playfield (leftmost), 4K backglass, 1080p FullDMD
- Original DMD, no colorization

**Files**


PuP Pack: 

Table:

 

 **DMDDevice.log**

 

 INFO | Starting DmdDevice API 2.5.1-CORE-r9 (8805bd6) (x64) through VPinballX.exe. 
 INFO | Assembly located at C:\vPinball\VisualPinball\VPinMAME\DmdDevice64.dll 
 INFO | Running in C:\vPinball\visualpinball\Tables 
 INFO | Successfully loaded config from C:\vPinball\VisualPinball\VPinMAME\DmdDevice.ini. 
 INFO | [serum] Determined altcolor path from assembly path: C:\vPinball\VisualPinball\VPinMAME\altcolor 
 INFO | [dll] Open(0) 
 INFO | [dll] PM_GameSettings(0, cc_13, 0) 
 INFO | Disabling game colorization 
 INFO | Setting game name: cc_13 
 INFO | Setting color: #FFFF5820 
 INFO | Opening virtual display... 
 INFO | Added VirtualDMD renderer. 
 INFO | [pinup] Starting cc_13... 
 WARN | Error opening PinUP output: External component has thrown an exception. 
 INFO | Transformation options: Resize=Fit, HFlip=False, VFlip=False 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551700, 66%:#FFAA2E00, 100%:#FFFF4500) 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551700, 66%:#FFAA2E00, 100%:#FFFF4500) 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551700, 66%:#FFAA2E00, 100%:#FFFF4500) 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551700, 66%:#FFAA2E00, 100%:#FFFF4500) 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551700, 66%:#FFAA2E00, 100%:#FFFF4500) 
 INFO | Applying default color to render graphs (#FFFF5820). 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551D0B, 66%:#FFAA3B15, 100%:#FFFF5820) 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551D0B, 66%:#FFAA3B15, 100%:#FFFF5820) 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551D0B, 66%:#FFAA3B15, 100%:#FFFF5820) 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551D0B, 66%:#FFAA3B15, 100%:#FFFF5820) 
 INFO | [RenderGraph] SetColor(0%: #FF000000, 33%:#FF551D0B, 66%:#FFAA3B15, 100%:#FFFF5820) 
 INFO | Setting up 2-bit Passthrough Graph for 1 destination(s) [ Virtual DMD ] 
 INFO |   -> Connecting DmdDevice 2-bit Source to Virtual DMD (Gray2 -> Gray2) - deduped 
 INFO | Setting up 4-bit Passthrough Graph for 1 destination(s) [ Virtual DMD ] 
 INFO |   -> Connecting DmdDevice 4-bit Source to Virtual DMD (Gray4 -> Gray4) - deduped 
 INFO | Setting up 8-bit Passthrough Graph for 1 destination(s) [ Virtual DMD ] 
 INFO |   -> Connecting DmdDevice 8-bit Source to Virtual DMD (Gray8 -> Gray8) 
 INFO | Setting up RGB24 Passthrough Graph for 1 destination(s) [ Virtual DMD ] 
 INFO |   -> Connecting DmdDevice RGB24 Source to Virtual DMD (Rgb24 -> Rgb24) 
 INFO | Setting up Alphanumeric Passthrough Graph for 1 destination(s) [ Virtual DMD ] 
DEBUG | DMD position: No registry because it's ignored. 
 INFO | Creating FBOs for 128x32 
 INFO | [DMD] Shared dmdext OpenGL renderer initialized. 
 INFO | [dll] Close(0) 
 INFO | Closing up. 
DEBUG | Disposing 2-bit Passthrough Graph... 
 INFO | Source for 1 renderer(s) stopped. 
DEBUG | Disposing 4-bit Passthrough Graph... 
 INFO | Source for 1 renderer(s) stopped. 
DEBUG | Disposing 8-bit Passthrough Graph... 
 INFO | Source for 1 renderer(s) stopped. 
DEBUG | Disposing RGB24 Passthrough Graph... 
 INFO | Source for 1 renderer(s) stopped. 
DEBUG | Disposing Alphanumeric Passthrough Graph... 

 

The PinUP output throws on open, and after that every render graph has only the Virtual DMD as a destination. So no frames ever reach the matcher.

 

**My DmdDevice.ini, relevant sections**

 

[pinup]
enabled = true

[video]
enabled = false

[cc_13]
virtualdmd left = 8027
virtualdmd top = 712
virtualdmd width = 1229
virtualdmd height = 331
colorize = false

 

The pin2color plugin lines in [global] are commented out and colorize = false globally, purely for testing.

 

**PuPCapture itself initialises cleanly** (puplog.txt)
 

Open called
Set Game Name thread cc_13
Start Thread Matching
create PuPCap
Init Game name:cc_13
Create Object Display
imagedir:C:\vPinball\PinUPSystem\PuPVideos\cc_13\PuPCapture
num images 114


 

**What I've already checked or ruled out**
 

- [pinup] enabled = true is set in the DmdDevice.ini in the root of the VPinMAME folder, and the log confirms that's the one being loaded
- "Use External DMD" is enabled via F1 in VPinMAME
- PuPCapture folder present with 114 files including ExactColorMatch.txt
- No colorization active — Disabling game colorization confirmed in the log. (I do have cc_13H and cc_13D folders in altcolor, but nothing for cc_13 itself is being applied.)
- No scalers on this table. 
- Ran PinUPPlayerRegister.bat as administrator — no change, byte-identical error
- Tried dmdext 2.4.0 and 2.5.1, both x64 — identical error in both
- I did have a directb2s active for this table. I've since disabled it — no change to the error.
- Pack media is fine: firing D1 manually in the PuP-Pack Editor plays the drain videos correctly on screens 12, 14 and 16
 

**My question**
 

Is PuPCapture expected to work with the 64-bit dmdext at all? "External component has thrown an exception" reads like a COM failure, and as far as I know PinUP Player is 32-bit, so I'm wondering whether the x64 build simply can't open that output.


If that's the case: what's the recommended setup? Both VPinballX.exe and VPinballX64.exe in my install appear to be 64-bit, so I don't currently have a 32-bit VPX to fall back on. Is a separate 32-bit install alongside the x64 one the accepted approach, or is there another way?


And if it *should* work on x64, any pointers on what else could be throwing on the PinUP output would be very welcome.


Thanks.

Edited by ThijsFTW
add pinup v2.0 info
Posted

Update — I found the actual failure.
 

Enabling "Show DMD / Display Window" in the VPinMAME settings for this ROM makes the PinUP output open successfully:
 

INFO | [pinup] Starting cc_13...
INFO | Added PinUP renderer.
INFO | Setting up 4-bit Passthrough Graph for 2 destination(s) [ Virtual DMD, PinUP Writer ]
INFO |   -> Connecting DmdDevice 4-bit Source to PinUP Writer (Gray4 -> Gray4) - not deduped
INFO | Creating FBOs for 128x32
INFO | Resizing virtual DMD to 256x64


 

No more "Error opening PinUP output". But VPX now crashes the moment the first frame is written — on screen: ROM boots, DMD shows "switch scanning", VPX disappears, PuP-Pack keeps running. The log ends at the line above.

 

Event Viewer:
 

Exception Info: System.AccessViolationException
   at LibDmd.Output.PinUp.PinUpOutput.RenderGray4(LibDmd.Frame.DmdFrame)
   at System.Reactive.AnonymousSafeObserver`1[...].OnNext(System.__Canon)
   at System.Reactive.ScheduledObserver`1[...].Dispatch(...)
   at System.Threading.ThreadHelper.ThreadStart()

Faulting application name: VPinballX.exe, version: 10.8.0.2058
Faulting module name: dmddevicePUP64.DLL, version: 1.4.7.1, time stamp: 0x6446b67b
Exception code: 0xc0000005
Fault offset: 0x0000000000007d51
Faulting module path: C:\vPinball\VisualPinball\VPinMAME\dmddevicePUP64.DLL


 

So the two states are the same problem seen from either side: with the setting off the PinUP output never opens (no D triggers), with it on it opens and then crashes on the first Gray4 frame.

 

Also worth noting: alongside Gray4 -> Gray4, the graphs feed the PinUP Writer with Gray8 -> Gray4 and Rgb24 -> Gray4 conversions, in case that's relevant to the access violation.

 

PinUPDater says everything is up to date, and I couldn't find a dmddevicePUP64.DLL in the beta 2026 files either, so 1.4.7.1 seems to be the latest available.

 

So my questions become:

 

1. Is 1.4.7.1 really the latest dmddevicePUP64.DLL, or is there a newer build somewhere?
2. Is PuPCapture expected to work on the 64-bit chain at all? Both VPinballX.exe and VPinballX64.exe in my install are 64-bit, so I have no 32-bit VPX to fall back on — is a separate 32-bit install the accepted approach for PuPCapture packs?

 

Happy to upload the WER dump if that's useful.

Posted

# UPDATE — narrowed down: crash is triggered by concurrent PuPCapture matches, not by the pack or the setup


Since my original post I've done a lot of further testing. Summary up front: PuPCapture works

correctly on my 64-bit chain — but only as long as exactly one capture can match. As soon as a

second trigger fires while another is still being handled, dmddevicePUP64.dll throws an access

violation. I can now reproduce both the working and the failing case on demand.


## The decisive experiment


Working case. I emptied PUPVideos\cc_13\PuPCapture down to two files:

- ExactColorMatch.txt

- 1.bmp (D1 = Ball Drain)


Result: table boots, plays and exits normally. Draining the ball fires D1 and the drain videos

play on screens 12, 14 and 16 exactly as intended. No crash, no errors in DmdDevice.log.

So the whole chain — VPinMAME → dmdext → PinUP Writer → dmddevicePUP64.dll → frame matching →

trigger → video — is functional on x64.


Failing case. Put the full set of 114 BMPs back: VPX dies within seconds during attract mode.


In between. With ~99 BMPs the table survived boot and attract, played the Launch Ball video

correctly, and crashed immediately afterwards. With BMPs 1–57 only, it froze while "Lock Is Lit"

was playing: the first audio cue played about half way, another trigger fired, the remainder of the

first cue then played, and the table locked up for a few seconds. After that I could keep playing

but all D triggers were dead — dmdext had caught the exception and disabled the PinUP output.


That last observation is the clearest clue I have: the failure happens where **two matches overlap

in time**, and the split audio cue makes the re-entrancy visible.


## The exception


After a clean reboot (see "stale processes" below) initialisation succeeds and PuPCapture starts

properly:
 

[pinup] Starting cc_13...

Added PinUP renderer.

Setting up 4-bit Passthrough Graph for 2 destination(s) [ Virtual DMD, PinUP Writer ]

  -> Connecting DmdDevice 4-bit Source to PinUP Writer (Gray4 -> Gray4) - not deduped

Creating FBOs for 128x32


puplog.txt confirms the capture side is initialised:
 

create PuPCap

Init Game name:cc_13

imagedir:C:\vPinball\PinUPSystem\PuPVideos\cc_13\PuPCapture

num images 114


Then, on matching:

 

ERROR | [pinup] Error sending frame to PinUp, disabling.

System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.

   at LibDmd.Output.PinUp.PinUpOutput.RenderGray4(DmdFrame frame)


Depending on timing this is either caught by dmdext (PinUP output disabled, table keeps running)

or takes VPX down completely:
 

Faulting application name: VPinballX.exe, version: 10.8.0.2058

Faulting module name: dmddevicePUP64.DLL, version: 1.4.7.1

Exception code: 0xc0000005


---


## Things that turned out to matter (and might help others)


Stale PinUP processes. After a hard crash, PinUpDisplay.exe keeps running. Every subsequent

launch then logs WARN | Error opening PinUP output: External component has thrown an exception.

and the PinUP renderer is never added at all — so the pack silently does nothing. This wasted

hours of my testing, because tests I ran in that state were meaningless. Killing all PinUp

processes (or rebooting) before each test is essential.


RestSeconds does not help. I set RestSeconds = 5 on all 246 triggers in triggers.pup.

No effect — which suggests the crash happens inside the DLL before PinUP Player's own

rate-limiting logic gets a say.


Two capture images in this pack are pixel-identical. 98.bmp and 112.bmp are both the

"PRESS ENTER FOR TEST REPORT" screen, so that DMD frame matches two captures at once. 100.bmp

and 105.bmp are near-empty frames (about 1–2% lit pixels), which are prone to matching

unintended frames. Removing these delayed the crash but did not prevent it.


---


## Verified / ruled out


- Capture assets are clean. All 114 BMPs are exactly 128×32, 24-bit, uncompressed, standard

  40-byte DIB header, identical file size to the byte. Colours are black, FF4500 and the

  FD00FD wildcard. No corrupt files.

- Not a general x64 or dmdext incompatibility. Other packs (fs_lx5, Hook_501) stream frames

  to the PinUP Writer through the same DLL for minutes without any error.

- Not colorization, DMD colour, or scaling. Colorization disabled and confirmed in the log;

  DMD colour set to FF4500 to match the captures — no change. scalermode off, frames stay 128×32.

- Not ExactColorMatch. Renaming it changes nothing.

- Not permissions, elevation or COM registration. File ACLs are correct, no RUNASADMIN flags

  anywhere, PinUPPlayerRegister.bat / PinUPPopperRegister.bat re-run as admin.

  (Note: running PuPRegister_64bit.bat from the v1.5.2 beta zip on my install *broke* Popper with

  "Server execution failed, ClassID {88919FAC-…}" — it adds an AppID with an empty DllSurrogate

  under WOW6432Node. Deleting those two keys fixed it. Worth a warning for anyone else.)

- Not screen layout. Moving the pack to the backglass makes no difference — matching happens on

  the frame data, before anything is displayed.

- Not the table script. PuPCapture requires no script changes; W triggers work fine throughout.

 


## Setup

Table: Cactus Canyon (Continued) VPW Mod 1.1, Const PROC = 0

ROM: cc_13

PuP-Pack: Cactus Canyon by classicradios, PuPCapture, 114 images

Frontend: PinUP Popper 2.0 (Baller Installer)

VPX: 10.8.0.2058 x64

dmdext: 2.5.1-CORE-r9 (x64), DmdDevice64.dll

PuP bridge: dmddevicePUP64.dll 1.4.7.1

B2S plugin: PinUPPlayer Display Driver 0.5.8351.33321 (2022.11.12), the same version shipped in PinUpDisplay_v150_beta_3.zip


---


## Questions


1. Is dmddevicePUP64.dll 1.4.7.1 the current build? I cannot find a newer one — not via

   PinUPDater, not in any of the manual update zips.

2. Is there a known issue with two PuPCapture triggers firing on the same or on closely

   consecutive frames? Everything I see points to a re-entrancy problem in the trigger handling

   rather than to frame transfer itself, since a single-capture set works flawlessly.

3. Is there any pack-side setting that serialises trigger handling? RestSeconds and

   SkipSamePrty do not prevent it.


Happy to run any test build or produce further logs — I can reproduce both states within a minute.

Posted (edited)

FINAL UPDATE — my earlier diagnosis was wrong. Short version, because this topic has grown.

 

Two corrections to my first post:

 

1. PuPCapture does work on 64-bit. With only ExactColorMatch.txt and 1.bmp (D1 = Ball Drain) in the PuPCapture folder, the drain videos play perfectly on all three screens, every time. The chain is fine.

 

2. The "Error opening PinUP output" was self-inflicted. After a hard crash PinUpDisplay.exe keeps running, and every launch after that fails to initialise the PinUP renderer, so the pack silently does nothing. Half my early testing was done in that state and was worthless. Kill all PinUp processes before every test.

 

What actually happens: with a full capture set the matcher dies. Sometimes it takes VPX with it (SEHException 0xc0000005 in PinUpOutput.RenderGray4, faulting module dmddevicePUP64.dll 1.4.7.1), sometimes dmdext catches it and just disables the PinUP output, so the table keeps playing with all D triggers dead.

 

The key point is that it is NOT reproducible. Three consecutive runs, identical setup, exactly 28 captures: run 1 crashed as the first ball became available, run 2 played 2+ minutes with D triggers firing repeatedly and exited cleanly, run 3 died when Quick Draw is Lit and Ball Lost fired close together. Fewer captures doesn't fix it, it only makes it less likely per minute. So this looks like a timing/re-entrancy problem, not a bad file and not a hard limit on image count — I chased both of those theories for hours and neither holds up.

The interesting part is the control case. The Flintstones pack (fs_lx5) on the same machine, same DLL, same dmdext, runs 95 captures across four screens for three minutes straight without a single error, with D triggers firing constantly (attract, launch, skill shot, three drains, dino frenzy, bowling, game over) and a clean shutdown. Cactus Canyon dies with 28 captures on two screens. So it isn't a limit on image count, and it isn't the number of simultaneous screens either.

 

Useful side finding for pack authors: dmddevicePUP64.dll only loads the unbroken run starting at 1.bmp. With 28.bmp missing, puplog reported "num images 27" while 111 files were present. So deleting one capture to disable a trigger silently kills every trigger numbered above it.

 

Ruled out along the way: capture assets (all 114 BMPs verified 128x32, 24-bit, uncompressed, identical size), colorization, DMD colour, scaling (fs_lx5 runs with colorize and doubler on and matches fine), ExactColorMatch, screen layout, table script, permissions, elevation, COM registration, RestSeconds and priorities.

 

Questions:
1. Is dmddevicePUP64.dll 1.4.7.1 the current build? I can't find a newer one anywhere.
2. Is there a known thread-safety issue in the capture matching? A single-capture set is rock solid; the failure rate scales with the number of captures, not with any particular one.
3. Anything pack-side that serialises trigger handling? RestSeconds, priorities and SkipSamePrty make no difference.

 

Happy to run a test build or produce more logs.

Edited by ThijsFTW
Update with flintstones pup pack compare

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...