*.VBS content (as of v3.46)

1.        Classes

a.  cvpmTimer class for switch pulsing and easy timer handling.

b.  cvpmTrough class for tracking balls in troughs and subways.

c.  cvpmSaucer class for automating playfield saucers.

d.  cvpmBallStack class for ball tracking in stacks or saucers.  ## DEPRECATED ##

e.  cvpmDropTarget class for easy drop target bank handling

f.  cvpmNudge class for Tilt handling

g.  cvpmMagnet class for playfield Magnets

h.  cvpmTurntable class for playfield turntables

i.   cvpmCaptiveBall class for captive balls

j.   cvpmMech class for handling playfield mechanics

k.  cvpmVLock class for visible ball locks

l.   cvpmImpulseP class for Impulse Plungers using triggers

2.        Solenoid callback functions

a.  Flippers

b.  Diverters

c.  Walls

d.  Auto Plungers (kicker based)

e.  Gates

f.  Sound

g.  Flashers

h. Generic for any object

3.        Constants

a.  Common switches/Solenoids

4.        User interface

a.  Open options window (F1)

b.  Show keys help (F2)

c.  Reset emulation (F3)

d.  Toggle display lock status (F4)

Using the *.VBS files

To use the *.VBS files the file must be in the same directory as the table file. Add the following code at the top of the script

‘ Load VPinMAME and *.VBS file, check versions

LoadVPM "02000000", "S11.VBS", 2.4

Sub LoadVPM(VPMver, VBSfile, VBSver)

     On Error Resume Next

          If ScriptEngineMajorVersion < 5 Then MsgBox "VB Script Engine 5.0 or higher required"

          ExecuteGlobal GetTextFile(VBSfile, 1).ReadAll

          If Err Then MsgBox "Unable to open " & VBSfile & ". Ensure that it is in the Scripts folder of Visual Pinball. " & vbNewLine & Err.Description

          Set Controller = CreateObject("VPinMAME.Controller")

          If Err Then MsgBox "Can't Load VPinMAME." & vbNewLine & Err.Description

          If VPMver>"" Then If Controller.Version < VPMver Or Err Then MsgBox "VPinMAME ver " & VPMver & " required."

          If VPinMAMEDriverVer < VBSver Or Err Then MsgBox VBSFile & " ver " & VBSver & " or higher required."

     On Error Goto 0

End Sub

 

Class cvpmTimer

This class is used to simplify timed events required for VPinMAME.

A single instance of this class is available as “vpmTimer”.

·         Method: .PulseSwitch switch, time, command

·         Method: .PulseSw sw

Pulses (quick on-off) switch and then execute command after time has elapsed.

switch:                      switch to pulse

time:                         time until callback is called in ms (1/1000s)

command:                Execute this string when timer expires.
switch number will be added at the end

Example:

              1. Walls do not have UnHit events.

Sub Wall10_Hit : vpmTimer.PulseSw 10 : End Sub

              2. Under playfield handling. Trigger switch 8, wait 0.5s and then call
              SubwayHandler

vpmTimer.PulseSwitch 8,500,”SubwayHandler”

Sub SubwayHandler(swNo)

     If swNo = 8 Then ...

 

·         Method: .AddTimer time, command

Execute command after time has elapsed

time:                                   Time until callback is called 1/1000s

command:                Execute this string when timer expires.
switch number “0” will be added at the end

Example:

              1. Call “delayedSub” after 1 second

vpmTimer.AddTimer 1000,”DelayedSub”

Sub DelayedSub(swNo)  ‘swNo is always 0 for AddTimer events

              2. Kick out the ball from a kicker after 2 seconds

‘Note the “’” at the end to ignore the added “0”

vpmTimer.AddTimer 2000,”Kicker.Kick 90,10 ’”

Class cvpmTrough

This class implements ball troughs and subways.  It takes over for the older cvpmBallStack class in “trough mode”.

 

cvpmTrough uses “slots” for each ball, such that Slot 0 is the exit, Slot 1 is the next ball back, and so on.  Each slot may have one switch associated with it – a ball occupying that slot will activate the corresponding switch.  As balls move through the trough, switches will flip on and off, avoiding “stuck switch” conditions.

 

Example:

Set bsTrough = New cvpmTrough

 

·         Property: .IsTrough true/false

Set or clear this trough as the default trough for the table (vpmTrough object).  This is used for clearing up lost balls, etc.  Note: The first trough created on a table will automatically set itself as the default trough, but you can use this property to override that behavior.

 

·         Property: .IsTrough (get)

Returns true if this trough is the default trough for the table.

 

·         Property: .Size newSize

Set the total number of balls this trough can hold before balls begin stacking up at the entrance.  The larger this value, the more balls the trough can hold (and the more switches can be placed into it), but balls may also take longer to travel through the trough.  (Default size is determined by conMaxBalls.)

 

·         Method: .InitSwitches Array(sw0, sw1, sw2, …)

Initialize the main trough switches using an array, starting at Slot 0.  If the number of switches specified is less than the size of the trough, all remaining slots are left unassociated (switch number is 0).  Set any switch to 0 to specify no switch at that location.

 

·         Method: .AddSw slot, swNo

Set a switch number at a specific slot.  You can use this as an alternative to .InitSwitches

              slot:                      The slot at which to place the switch.  Slot 0 is the slot closest to the exit.

              swNo:                  The switch to activate in this slot.  Set to 0 to remove a switch.

 

·         Property: .EntrySw swNo

Set the switch number to be triggered when a ball enters the trough (e.g. an outhole).  If swNo is greater than 0, balls will keep the switch activated until the entry solenoid is fired.  If set to 0, balls will enter the trough immediately.

 

·         Method: .InitExit kicker, dir, force

Setup the exit kicker for the trough.  Assigns a kicker object, direction and base force.

              kicker:                  The table kicker that will eject balls from the trough

              dir:                       The direction in which to kick the ball (0-360)

              force:                   The force at which to kick the ball (minimum 1)

 

·         Method: .InitExitVariance dirVar, forceVar

Set the amount by which the exit kicker direction and force can vary on each kick.

              dirVar:                 Vary the exit direction by this many degrees (+/-)

              forceVar:             Vary the exit force by this many force units (+/-, resulting force will not go below 1)

 

·         Property: .MaxBallsPerKick = n

Set the maximum number of balls that can be ejected in one kick. (Default = 1)

 

·         Property: .StackExitBalls = n

Set the number of balls to be automatically stacked up on the exit kicker from inside.  This applies to balls that come into the trough from an entrance. (Default = 1)

 

Example: A playfield subway where the exit kicker is at the same level as the trough, but balls can fall in from the exit.

                   subway.MaxBallsPerKick = 2

                   subway.StackExitBalls = 1

 

Example: Twilight Zone Slot Machine: Two balls are kicked out no matter where the second ball came in from (Slot, Piano, Camera, Skill Shot, etc.).  Kicker is below trough level.

                   slotTrough.MaxBallsPerKick = 2

                   slotTrough.StackExitBalls = 2

 

·         Method: .InitEntrySounds addSound, entrySound, entrySoundBall

Set the sounds to be played when a ball enters the trough.

              addSound:           Plays when the ball hits the entry kicker (eg. outhole) or falls into the trough.

              entrySound:         Plays when the entry kicker solenoid fires and no ball is present.

              entrySoundBall:   Plays when the entry kicker solenoid fires and a ball is present.

 

·         Method: .InitExitSounds exitSound, exitSoundBall

Set the sounds to be played when the exit kicker fires.

              exitSound:            Plays when the exit kicker solenoid fires and the trough is empty.

              exitSoundBall:     Plays when the exit kicker solenoid fires and at least one ball is ejected.

 

·         Property: .Balls = n

Set the number of balls to start the trough with.  Any existing balls in the trough are cleared.  If StackExitBalls is greater than 1, balls are stacked in the exit slot automatically.

 

·         Property: .Balls (get)

Gets the number of balls currently in the trough, including those stacked at the exit.  Does not include balls queued up at the entrance.

 

·         Property: .BallsPending (get)

Gets the number of balls queued up at the entrance.

 

·         Method: CreateEvents troughName, kicker(s)

Auto-generate hit events for the specified kicker(s), so that these kickers will automatically add a ball to the trough.

              troughName:       The variable name of this trough

              kicker(s):              The kicker object(s) to associate with this trough.  Can be a single kicker or an Array or Collection of kickers.

 

Example:

                   subway.createEvents “subway”, Array(subwayEntrance1, subwayEntrance2, subwayExit)

                   ‘ Note: Can include the exit kicker – the AddBall method knows how to handle this.

 

·         Method: Reset

Called by vpmTimer to perform a reset.  In this case, this ensures that all trough and entry switches are in the correct state.

 

·         Method: Update

Called by vpmTimer to update the ballstack state.  Advances balls through trough and updates switches.  If (a) there is at least one ball queued at the entrance, (b) there is no entry switch, and (c) the trough is not full, then one ball will be added at the trough entrance and will begin advancing.

 

·         Method: AddBall fromKicker

Add a ball to the trough.  If a kicker is specified, this destroys the ball in that kicker.  If that kicker happens to be the exit kicker, this causes the ball to stack up on the exit slot, even if that slot is already occupied.  Otherwise, the ball is queued at the trough entrance, and the entry switch is activated if one is set.

 

Example:

                   Sub subwayEntrance1_Hit : subway.AddBall Me : End Sub

Solenoid handlers

·         Method: .SolIn enabled

·         Method: .EntrySol_On

Kicks a ball waiting on the entry Switch into the trough.  SolIn can be specified as a solenoid handler.

Example:

              1. Directly from solenoid callback

SolCallback(sOuthole) = “bsTrough.SolIn”

              2. From procedure

SolCallback(sOuthole) = “SolOuthole”

Sub SolOuthole(enabled)

     If enabled Then

           bsTrough.EntrySol_On

 

·         Method: .SolOut enabled

·         Method; .ExitSol_On

Kicks out a ball from the trough.  SolOut can be specified as a solenoid handler.

Example:

              1. Directly from solenoid callback

SolCallback(sBallRelease) = “bsTrough.SolOut”

              2. From procedure

SolCallback(sBallRelease) = “SolBallRelease”

Sub SolBallRelease(enabled)

     If enabled Then

           bsTrough.ExitSol_On

 

Class cvpmSaucer

This class implements table saucers, in which a ball can be captured, stays visible, triggers a switch and can be kicked out in up to two directions.  It takes over for the older cvpmBallStack class in “saucer mode”.

 

Example:

Set leftSaucer = New cvpmSaucer

 

·         Method: .InitKicker kicker, swNo, dir, force, zForce

Setup the kicker for this saucer.  Assigns a kicker object, the switch to be triggered, and the primary exit direction and force (including vertical force if desired).

              kicker:                  The table kicker that will receive and eject balls.

              swNo:                  The switch to activate when a ball is captured.

              dir:                       The direction in which to kick the ball (0-360)

              force:                   The force at which to kick the ball (minimum 1)

              zForce:                The vertical force at which to kick the ball (minimum 0)

 

·         Method: .InitExitVariance dirVar, forceVar

Set the amount by which the exit kicker direction and force can vary on each kick.  (Vertical force does not vary.)

              dirVar:                 Vary the exit direction by this many degrees (+/-)

              forceVar:             Vary the exit force by this many force units (+/-, resulting force will not go below 1)

 

·         Method: .InitAltKick dir, force, zForce

Set a secondary direction and force to kick the ball.  This is for saucers that can kick in two different directions (eg. Spectrum outhole) or can kick at two different speeds.

              dir:                       The alternate direction in which to kick the ball (0-360)

              force:                   The alternate force at which to kick the ball (minimum 1)

              zForce:                The alternate vertical force at which to kick the ball (minimum 0)

 

·         Method: .InitSounds addSound, exitSound, exitSoundBall

Set the sounds to play when a ball enters the saucer or one of the kicker solenoids fires.

              addSound:           Plays when a ball falls into the saucer.

              exitSound:            Plays when an exit kicker fires and the saucer is not occupied.

              exitSoundBall:     Plays when an exit kicker fires and a ball is ejected.

 

·         Method: CreateEvents saucerName, kicker(s)

Auto-generate hit events for the specified kicker(s), so that these kickers will automatically add a ball to the saucer.

              saucerName:       The variable name of this saucer

              kicker(s):              The kicker object(s) to associate with this saucer.  Can be a single kicker or an Array or Collection of kickers.

 

Example:

                   leftSaucer.createEvents “leftSaucer”, kickLeftSaucer

 

·         Method: AddBall fromKicker

Add a ball to the saucer.  If a kicker is specified, that kicker is disabled.  The kicker does not have to be the same kicker as the one that will kick the ball out – you can use this to simulate a Vertical Up-Kicker (VUK).

 

Example:

                   Sub kickLeftSaucer_Hit : leftSaucer.AddBall Me : End Sub

Solenoid handlers

·         Method: .SolOut enabled

·         Method; .ExitSol_On

Kicks a ball out of the saucer in the primary direction.  SolOut can be specified as a solenoid handler.

Example:

              1. Directly from solenoid callback

SolCallback(sExitSol1) = “leftSaucer.SolOut”

              2. From procedure

SolCallback(sExitSol1) = “solExit1”

Sub SolExit1(enabled)

     If enabled Then

           leftSaucer.ExitSol_On

 

·         Method: .SolOutAlt enabled

·         Method; .ExitAltSol_On

Kicks a ball out of the saucer in the secondary (alternative) direction.  SolOutAlt can be specified as a solenoid handler.

Example:

              1. Directly from solenoid callback

SolCallback(sExitSol2) = “leftSaucer.SolOutAlt”

              2. From procedure

SolCallback(sExitSol2) = “solExit2”

Sub SolExit2(enabled)

     If enabled Then

           leftSaucer.ExitAltSol_On

 

See .InitAltKick method

 

 

Class cvpmBallStack (DEPRECATED)

This class implements all kind of ball handling where kickers are involved.

It can be used in two different ways:

Stack     Balls are destroyed as they enter the stack and created when leaving.
              Up to 10 balls can be in the stack at the same time.

Saucer    Balls are not destroyed (i.e stays visible) and only one ball can be in the stack at any point in time.

 

NOTE: This class is now DEPRECATED.  You should consider using cvpmTrough or cvpmSaucer, depending on which functionality you need.

 

Example:

Set bsTrough = New cvpmBallStack

Set bsSaucer = New cvpmBallStack

 

Stack version

·         Method: .InitSw entrySw,sw1,sw2,sw3,sw4,sw5,sw6,sw7

Initialize the switches used in the stack.

entrySw:                   switch triggered when a ball enters the stack (e.g. an outhole)
If an entry switch is specified, balls will keep the switch activated until the entry solnoid is fired.
If entry switch is 0 balls will go directly into the stack.

sw1-sw7:                  Switches activated when balls are in the stack. Next ball to leave the stack will activate sw1, second ball sw2 etc

 

Example:

              1. A Trough with an outhole switch and 3 switches

bsTrough.InitSw swOutHole, swRTrough, swCTrough,_
swLTrough,0,0,0,0

              2. A Lock with 2 switches

bsLock.InitSw 0,swLock1,swLock2,0,0,0,0,0

 

·         Method: .InitKick kicker, direction, force

Initialise the kicker used to kick out balls from the stack.

If the kicker is not initialized the stack work as normal but no ball will be kicked out (It is still removed from the stack)

kicker:                                kicker object

direction:                  kickout direction

force:                                  kickout force

Example:

              Kickout from the “BallRelease” kicker direction 90 and power 5

bsTrough.InitKick BallRelease, 90, 5

 

·         Method: .InitNoTrough kicker, switch, direction, force

Simplified init function for single ball games without a trough. Number of balls is automatically set to 1

kicker:                                kicker object

switch:                      outhole switch

direction:                  kickout direction

force:                                  kickout force

Example:

              Single ball game

bsTrough.InitNoTrough BallRelease, swOuthole, 90, 5

 

·         Property: .KickBalls = x

Specifies the maximum number of balls that can be kicked out at the same time. Default = 1.

First ball will be kicked out with 100% power, 2nd with 80%, 3rd with 64%…

Example:

              Kick out maximum 2 balls at a time

bsLock.KickBalls = 2

 

·         Method: .InitEntrySnd ballSound, sound

Specify the sound used when the entry solenoid is fired.

ballSound:                sound to play if a ball is kicked

sound:                                sound to play if no ball is kicked

Example:

bsTrough.InitEntrySnd “Outhole”, “SolenoidOn”

 

 

Saucer version

·         Method: .InitSaucer kicker, sw, direction, force

Initialize a saucer

kicker:                      kicker object used for the saucer

sw:                            switch activated when a ball is in the saucer

direction:                  direction of kickout

force:                        force of kickout

Example:

bsSaucer.InitSaucer saucerkicker, swSaucer, 90, 10

 

Common to Stacks and Saucers

·         Property: .KickForceVar = forceVar

·         Property: .KickAngleVar = angleVar

Randomly vary the kickout force and angle by “var” units (default 0)

Example:

              Kick out balls with force 10 +/- 2 (i.e. 8-12) and angle 85-95

bsLock.InitKick lockKicker, 90, 10

bsLock.KickForceVar = 2

bsLock.KickAngleVar = 5

 

·         Property: .KickZ = angle

Specify the vertical angle for kickout

angle:                                 vertical angle in radians (PI/2 = vertical)

Example:

              Kickout ball in a 45 degree angle towards the playfield

bsTrough.KickZ = 3.1415926/4

 

·         Method: .InitAltKick direction, force

Specify an alternative kickout direction and force. Used mainly with saucers that can kick the ball out in two different directions.

direction:                  direction of kickout

force:                        force of kickout

Example:

              Kickout ball either up or down

bsSaucer.InitSaucer saucerKicker, swSaucer, 0, 5

bsSaucer.InitAltKick 180,5

SolCallback(sSaucerUp) = ”bsSaucer.SolOut”

SolCallback(sSaucerDown) = ”bsSaucer.SolOutAlt”

 

·         Method: .InitExitSnd ballSound, sound

Same as .InitEntrySnd but for the Exit solenoid

ballSound:                sound to play if a ball is kicked

sound:                       sound to play if no ball is kicked

Example:

bsTrough.InitExitSound “BallRelease”, “SolenoidOn”

 

·         Method: .AddBall kicker

Add a ball into the Stack or Saucer. If a kicker is specified the ball will be destroyed for a Stack (not for Saucers*).  If an entry switch is specified balls will not be put into the stack until the entry solenoid is fired (see .SolIn)

* Balls are always kicked out from the kicker specified with the .InitSaucer method. If a different kicker is specified in the .AddBall method the ball will be moved (destroyed and created with the same properties) to the normal kicker at kickout. This can be used to simulate a vertical up kicker (VUK).

kicker:                      Kicker where ball is

Example:

              1. Add a ball currently in the outhole kicker

Sub Outhole_Hit : bsTrough.AddBall Me : End Sub

              2. Add a ball in a Saucer

Sub Saucer_Hit : bsSaucer.AddBall 0 : End Sub

 

·         Property: .Balls = x

Fill stack with balls. Any existing balls will disappear.

Example:

              Put 3 balls in Trough

bsTrough.Balls = 3

 

Solenoid handlers

·         Method: .SolIn enabled

·         Method: .EntrySol_On

Kicks a ball waiting on the entry Switch into the stack (not applicable for Saucers).

SolIn can be specified as a solenoid handler.

Example:

              1. Directly from solenoid callback

SolCallback(sOuthole) = “bsTrough.SolIn”

              2. From procedure

SolCallback(sOuthole) = “SolOuthole”

Sub SolOuthole(enabled)

     If enabled Then

           bsTrough.EntrySol_On

 

·         Method: .SolOut enabled

·         Method; .ExitSol_On

Kicks out a ball from the stack or saucer .

SolOut can be specified as a solenoid handler.

Example:

              1. Directly from solenoid callback

SolCallback(sBallRelease) = “bsTrough.SolOut”

              2. From procedure

SolCallback(sBallRelease) = “SolBallRelease”

Sub SolBallRelease(enabled)

     If enabled Then

           bsTrough.ExitSol_On

·         Method: .SolOutAlt enabled

·         Method; .ExitAltSol_On

Kicks out a ball from the stack or saucer in the alternative direction.

SolOutAlt can be specified as a solenoid handler.

Example:

              See .InitAltKick method

Class cvpmDropTarget

This class is used to handle drop target banks.

 

·         Method: .InitDrop targets, switches

Initializes the targets and the switches for the drop targets.

targets:                     Droppable walls. Arrays/Collections can be used if each target consists of more than one wall.

switches:                   Switches connected to each target. If Nothing the switches will be taken from the TimerInterval property of the targets.

Example:

              1. Single target

dtDrop.InitDrop Target, swTarget

              2. Multiple targtes

dtDrop.InitDrop Array(Target1, Target2, Target3), Array(sw1,sw2,sw3)

              3. Multiple targets with two walls for each target

dtDrop.InitDrop Array(Array(T1Front,T1Back),Array(T2Front,T2Back)), Array(sw1,sw2)

              4. Targets where switch number is set in the TimerInterval property

dtDrop.InitDrop Array(Target1,Target2,Array(T3Front,T3Back)),Nothing

 

·         Method: .CreateEvents instance

Creates the events for the drop targets.Sub Target_Hit …”

instance:                   The name of the cvpmDropTarget object.

Example:

dtDrop.InitDrop Array(Target1, Target2, Target3), Array(sw1,sw2,sw3)

dtDrop.CreateEvents “dtDrop”

 

·         Property: .AnyUpSw = switch

·         Property: .AllDownSw = switch

·         Property: .LinkedTo = dropTargetBanks

Some drop target banks have switches indication if all targets are up or down. Use these properties to specify the switches.

Sometimes games have common swicthes for several drop target banks. The .LinkedTo property specifies drop target banks that have a common AnyUpSw or AllDownSw. (note that drop target banks must be linked both ways)

DropTargetBanks    Drop target bank (or array) which share an AnyUp or AllDn switch

Example:

              1. Normal drop target bank

dtDrop.AnyUpSw = 25

dtDrop.AllDownSw = 30

              2. Three banks with a common AllDownSw

dtLDrop.AllDownSw = 34

dtLDrop.LinkedTo = Array(dtCDrop,dtRDrop)

dtCDrop.LinkedTo = Array(dtLDrop,dtRDrop)

dtRDrop.LinkedTo = Array(dtLDrop,dtCDrop)

 

·         Method: .InitSound drop, raise

Specify sound connected to drop targets

drop:                        sound when a target is hit

raise:                        sound when targets are raised

Example:

dtDrop.InitSound “DropTarget”,”RaiseTarget”

 

·         Method: .Hit targetNo

·         Method: .SolHit targetNo, enabled

A drop target has been hit. .SolHit can be specified as a solenoid handler.

targetNo:                  The target that has been hit (1,2,3...)

Example:

              1. Target 2 has been hit

Sub Target2_Hit : dtDrop.Hit 2 : End Sub

              2. Solenoid for target 3

SolCallback(sTarget2) = “dtDrop.SolHit 3,”

 

·         Method: .SolDropUp enabled

·         Method: .DropSol_On

Raise target handler. Restores all drop targets and switches in the bank

.SolDropUp can be specified as a solenoid handler

Example:

              1. Directly from solenoid callback

SolCallback(sRaiseDrop) = “dtDrop.SolDropUp”

              2. From procedure

SolCallback(sRaiseDrop) = “SolRaiseDrop”

Sub SolRaiseDrop(enabled)

     If enabled Then

           dtDrop.DropSol_On

 

·         Method: .SolDropDown enabled

Drop all targets. Can be specified as a solenoid handler

Example:

SolCallback(sDropDown) = “dtDrop.SolDropDown”

 

·         Method: .SolUnhit targetNo, enabled

Raise one target. Can be specified as a solenoid handler

targetNo:                  The target that should be raised (1,2,3...)

Example:

SolCallback(sRaiseDrop3) = “dtDrop.SolUnhit 3,”

 

Class cvpmNudge

This class is used to handle nudging and Tilts.

 

·         Property: .TiltSwitch = swNo

Specifies switch to be triggered when a Tilt occurs.

Example:

vpmNudge.TiltSwitch = swTilt

 

·         Property: .Sensitivity = sens

Specifies the tilt sensitivity between 0 (low) – 10 (high).

Example:

vpmNudge.Sensitivity = 5

 

·         Property: .TiltObj = Objects

Specifiy objects (bumpers and slingshots) affected by a tilt.

Example:

vpmNudge.TiltObj = Array(Bumper1, Bumper2,LeftSling,RightSling)

 

·         Method: .DoNudge direction, force

Nudge the table

direction:                  Direction of nudge.

force:                        Nudge force

Example:

vpmNudge.DoNudge 85, 2

 

·         Method: .SolGameOn enabled

Activates or deactivates bumpers and slingshots

Example:

SolCallback(sGameOn) = “VpmNudge.SolGameOn”

Class cvpmMagnet

This class is used to handle playfield magnets. The magnet itself is one or more triggers covering the area where the magnet can affect the ball. By default the magnet use vpmTimer for updates. On slow computers this might cause erratic switch behaviour. Performance can be improved by adding an extra timer called “vpmFastTimer”. Magnets will automatically use “vpmFastTimer” if it exists.

 

·         Method: .InitMagnet trigger, strength

Initializes the magnet.

trigger:                     Trigger(s) used to simulate the magnet

strength:                   Magnet strength at center

Example:

MLeft.InitMagnet LeftMagnet, 10

MLeft.InitMagnet Array(LeftMagnet1, LeftMagnet2), 14

 

·         Method: .CreateEvents instance

Creates the magnet events “Sub Magnet_Hit …”

instance:                   The name of the cvpmMagnet object.

Example:

MLeft.InitMagnet LeftMagnet, 10

MLeft.CreateEvents “MLeft”

 

·         Property: .Solenoid = sol

Specifies the solenoid that controls the magnet. If not set or set to 0 the magnet is controlled with the .MagnetOn property.

sol:                           Solenoid number

Example:

MLeft.Solenoid = sLeftMagnet

 

·         Property: .X = xPos

·         Property: .Y = yPos

·         Property: .Strength = strength

·         Property: .Size = radius

Changes the magnet properties. Note that the trigger is not moved so the new magnet position must remain within the area covered by the trigger(s).

xPos, yPos:              Playfield coordinates

strength:                   Magnet strength at center

radius:                      Magnet reach

Example:

MLeft.X = MLeft.X + 5

Mleft.Strength = 12

 

·         Property: .GrabCenter = True/False

The cvpmMagnet class updates the ball based on a timer. This might cause the ball to “vibrate” at the center of the magnet. .GrabCenter forces the ball to stop immediately on the center.

Example:

MLeft.GrabCenter = False

 

·         Method: .AddBall ball

A ball has entered the magnets reach. Usuall called from the magnet trigger’s hit event.

ball:                          Ball object

Example:

Sub LeftMagnet_Hit : MLeft.AddBall ActiveBall : End Sub

 

·         Method: .RemoveBall ball

A ball has left the magnets reach. Usuall called from the magnet trigger’s unhit event.

ball:                          Ball object

Example:

Sub LeftMagnet_UnHit : MLeft.RemoveBall ActiveBall : End Sub

 

·         Property: .Balls

An array of all balls currently in the magnets reach.

Example:

BallsOnMagnet = Ubound(mLeft.Balls)

 

·         Property: .MagnetOn enabled

Turn the magnet on or off. Only works if no solenoid is specified.

enabled:                   True to turn magnet on

Example:

MLeft.MagnetOn = True

SolCallback(sLeftMagnet) = “MLeft.MagnetOn=”

 

·         Method: .AttractBall ball

Calculate and perform a magnets effect on a specific ball.

ball:                          Ball object

Example:

MLeft.AttractBall ActiveBall

 

Class cvpmTurnTable

This class is used to handle rotating objects like turntables. The turntable itself is a trigger covering the area where of the turntable. By default the turntables use vpmTimer class for updates. On slow computers this might cause erratic switch behaviour. Performance can be improved by adding an extra timer called “vpmFastTimer”. Turntables will automatically use the “vpmFastTimer” if it exists.

 

·         Method: .InitTurntable trigger, maxSpeed

Initializes the turntable.

trigger:                     Trigger used to simulate the turnTable

maxSpeed:                Maximum turntable speed

Example:

ttCenter.InitTurnTable CenterTable, 40

 

·         Method: .CreateEvents instance

Creates the turntable events “Sub TurnTable_Hit …”

instance:                   The name of the cvpmTurnTable object.

Example:

ttCenter.InitTurnTable CenterTable, 40

ttCenter.CreateEvents “ttCenter”

 

·         Property: .MaxSpeed = maxSpeed

·         Property: .Speed = speed

·         Property: .SpinUp = acc

·         Property: .SpinDown = ret

·         Property: .SpinCW = spinDir

Changes the turntables properties. Note that the acceleration and retardation will affect the speed. Set .SpinUp = 0 and .SpinDown = 0 to control speed directly.

maxSpeed:                Maximum turntable speed

speed                        Turntable speed

acc:                          Spin up acceleration [speed units/0.5s]

ret:                            Spin down retardation

spinDir:                    True for clockwise spin, false for counter clockwice (does not change motor state)

Example:

TtCenter.maxSpeed = 50

ttCenter.SpinUp = 20

ttCenter.SpinDown = 5

 

·         Method: .AddBall ball

A ball has entered the turntable reach. Usuall called from the turntable trigger’s hit event.

ball:                          Ball object

Example:

Sub CenterTable_Hit : ttCenter.AddBall ActiveBall : End Sub

 

·         Method: .RemoveBall ball

A ball has left the turntable. Usuall called from the tunrtable trigger’s unhit event.

ball:                          Ball object

Example:

Sub CenterTable_UnHit : ttCenter.RemoveBall ActiveBall : End Sub

 

·         Property: .Balls

An array of all balls currently in the turntables reach.

Example:

              Make all balls on the turntable red

For Each ball In ttCenter.Balls : ball.Color = vbRed : Next

 

·         Property: .MotorOn = enabled

·         Method: .SolMotorState clockWise, enabled

Control the motor status of the turntable.

clockWise:                True = Turntable spinning clockwise

enabled:                   True = Table motor is on

Example:

              1. Solenoid handlers

SolCallback(sCenterCW) = “ttCenter.SolMotorState True,”

SolCallback(sCenterCCW) = “ttCenter.SolMotorState False,”

              2. Direct control

ttCenter.MotorOn = False

 

 

·         Method: .AffectBall ball

Calculate and perform a turntable’s effect on a specific ball.

ball:                          Ball object

Example:

ttCenter.AffectBall ActiveBall

 

Class cvpmMech

This class is used to create a handler of playfield mechanics including motors. The class will calculate the position of the mechanics, update switches and call a user-defined function whenever the poosition changes.

 

·         Property: .MType = type

Specifies the mechanics type. The type is consists of four groups:

1. How the motor is controlled

vpmMechOneSol – A single solneoid controls the power to the motor. One direction only.

vpmMechOneDirSol – The first solenoid controls the power to the second solenoid controls the direction.

vpmMechTwoDirSol – The first solenoid controls clockwise movement and the second solenoid controls counter-clockwise movement.

vpmMechStepSol – Two solenoids control a step motor

2. How the mechanic controlled by the motor moves

vpmMechCircle – The mechanic moves in a circle and comes back to the starting point

vpmMechReverse – The mechanic moves from one end to the other and then moves back without the motor changing direction

vpmMechStopEnd – The mechanics stops when it reaches either end point.

3. The speed of the mechanic

vpmMechLiner – The mechanic moves at a constant speed from one end to the other (default)

vpmMechNonLinear – The mechanics speed is slow at the endpoints and fast in the middle

4. Mech handler properties

vpmMechSlow – Normal handler. Updated ~60 times per second. (default)

vpmMechFast – A fast handler. Sometimes required for very fast puls controlled mechanics (e.g. step motors). Update speed is ~240 times per second.

vpmMechStepSw – The switches are updated based on mechanincs “step” value (default)

vpmMechLengthSw – The switches are updated based on mechanics “length” value.

 

The type field is a combination of the above values

Example:

              Terminator 2 Gun

mGun.Type = vpmMechOneSol + vpmMechReverse + vpmMechNonLinear

 

·         Property: .Sol1 = solNol

·         Property: .Sol2 = solNol

Specifies the solenoids used to control the playfield mechanics.

Example:

              Monster Bash Dracula

mDracula.Sol1 = 41

mDracula.Sol2 = 42

 

·         Property: .Length = x

Specifies the length from one end to the other or a full circle (vpmMechCircle). The length parameter is the number 1/60th second the motor must be on.

Example:

              Terminator 2 Gun. ~3.5s at full speed.

mGun.Length = 200

 

·         Property: .Steps = x

The number of the positions reported back by the mechanic handler.

Example:

              Terminator 2 Gun. 20 different positions

MGun.Steps = 20 ‘one position for every 10 “length” units

 

·         Property: .Acc = acc

·         Property: .Ret = ret

Specifies the acceleration and retardation of the mechanic.

acc:                           “Length” units required to reach full speed

ret:                            number of times slower retardation is than acceleration

Example:

              World Cup Soccer ’94 Soccer ball. Takes 3 seconds to speed up and the same to stop

mSoccerBall.Acc = 180

mSoccerBall.Ret = 1

 

·         Method: .AddSw = swNo, startStep, endStep

Specifies a switch to be automatically updated by the mechanics handler.

swNo                        switch number

startStep                   First step position where the switch is activated

endstep                     Last step position where the switch is activated

Example: Terminator 2 Gun. Home position at 0, Mark position at 8-9

mGun.AddSw swGunHome, 0, 0

mGun.AddSw swGunMark, 8, 9

 

·         Method: .AddPulseSw = swNo, interval, length

Specifies a switch to be automatically pulsed when mech is moving.

swNo                        switch number

interval                     Length between pulses (in steps)

length                       Length of each pulse (in steps)

Example: Pulse switch every 5 steps

mGun.AddPulseSw swMech, 5, 1

 

·         Property: .Callback = callback

Specifies function called whenever the position of the mechanic changes. The function must take three argument.

NewPos                    Current position (step) of mechanics

Speed                        Current speed of mechanic

LastPos                    Previous position (step) of mechanics

Example:

mGun.Callback = GetRef(”UpdateGun”)

Sub UpdateGun(aNewPos, aSpeed, aLastPos)

     GunWalls(aLastPos\2).IsDropped = True

     GunWalls(aNewPos\2).IsDropped = False

End Sub

 

·         Property: .Start

Sets up the mechnics handler and starts it.

Example:

Set GunMech = New cvpmMech

With gunMech

     .Sol1 = sGunMotor

     .Length = 200

     .Steps = 58 ' 29 walls

     .MType = vpmMechOneSol + vpmMechReverse + vpmMechNonLinear

     .AddSw swGunHome, 0, 1

     .AddSw swGunMark, 20, 21

     .Callback = GetRef("UpdateGun")

     .Start

End With

 

·         Property: .Position

·         Property: .Speed

The current position and speed of the mechanic.

The position is in the range 0 to Steps-1 (e.g. ,Steps = 58 means position is 0-57).

Speed is 0 (stopped) to .Acc (full speed) (e.g. .Acc=10 means speed is 0-10)

Class cvpmCaptiveBall

This class is used to handle captive balls on the playfield. The handler takes the hitting balls velocity and angle into account when moving captive ball.

The Captive Ball requires the following elements:

1. One or two kickers for the moving ball. (If two kickers are specified the ball will rest in the first and the second will be used to kick out the ball)

2. A wall that holds the captive ball back

3. A trigger in front of the wall. (To estimate the ball speed).

 

·         Method: .InitCaptive trigger, wall, kickers, ballAngle

Initialises the captive ball obejcts (Does not create the ball).

trigger                      Trigger placed in front of the captive ball. (optional but operation will be much better if it there)

wall                          Wall holding the captive ball back.

kickers                      One or two kickers for the normal captive ball + kickers for “nailed” balls.

ballAngle                  The angle the captive ball should move.

Example:

cbCaptive = New cvpmCaptiveBall

cbCaptive.InitCaptive CaptiveTrigger, CaptiveWall, Array(Captive1,Cative2)

·         Property: .NailedBalls = nailedballs

Specify the number of nailed balls. (default 0). One extra kicker must have been specified in the InitCaptive method for each nailed ball.

nailedBalls:              0-n

 

·         Method: .Start

Start the captive ball handler, i.e. create the moving ball. Note that if “nailed” ball is used, the actual ball must be created manually

Example:

              Captive Ball with a red “nailed” ball

cbCaptive.InitCaptive CaptiveTrigger, CaptiveWall, Array(Captive1,Cative2,Captive3)

cbCaptive.Start

Captive1.CreateBall.Color = vbRed

 

·         Property: .ForceTrans = fTrans

·         Property: .MinForce = minForce

Controls the movement of the captive ball.

fTrans                       The amount of the hitting balls speed that is transferred to the captive ball (0-1). Note that the hitting ball’s speed is not reduced. Use the elasticity of the wall to control the hitting balls speed.

minForce                  The minimum force applied to the captive ball. If set to low the captive ball might not return to its resting position. (depends on the distance between the moving ball’s kickers and table slope.)

Example:

cbCaptive.ForceTrans = 0.4

cbCaptive.MinForce = 3.5

 

·         Property: .RestSwitch = swNo

Switch activated when the ball is in the resting position

Example:

cbCaptive.RestSwitch = swCaptiveResting

 

·         Method: .CreateEvents instance

Creates the events required for the captive ball

instance:                   The name of the cvpmCaptiveBall object.

Example:

cbCaptive.CreateEvents “cbCaptive”

 

·         Method: .TrigHit ball

·         Method: .BallHit ball

·         Method: .BallReturn kicker

Called from the events of captive ball objects. All these event are automatically generated with the .CreateEvents method.

Example:

Sub CaptiveTrigger_Hit : cbCaptive.TrigHit ActiveBall : End Sub

Sub CaptiveTrigger_UnHit : cbCaptive.TrigHit 0 : End Sub

Sub CaptiveWall_Hit : cbCaptive.BallHit ActiveBall : End Sub

Sub Captive2_Hit : cbCaptive.BallReturn Me : End Sub

 

Class cvpmVLock

This class is used to create a ball lock where the balls are visible. The balls are kept in kickers and can be either be kicked out at the top (entrance) or be let out through the bottom.

The setup is a combination of kickers and triggers. One kicker is required for each ball that can enter the lock and each kicker must be covered by a trigger. A kicker has radius 25 so the trigger must have a radius of at least 26. The trigger/kicker pairs should be placed as closed to each other without overlapping but if the lock can release one ball at a time some distance between the trigger/kicker pairs might be needed for the timing.

 

·         Method: .InitLock triggers, kickers, switches

Initialises the visible lock.

triggers                     Triggers for the lock from bottom to top

wall                          Kickers for the lock matching the triggers

Switches                   Switches activated at each lock position. If 0 or Nothing the switches will be fetched from the triggers TimerInterval property

Example:

Set Lock = New cvpmVLock

Lock.InitVLock Array(LTrig1,LTrig2,LTrig3),         Array(LKick1,LKick2,LKick3), Array(swLock1,swLock2,swLock3)

 

·         Method: .InitSnd ball, noBall

Initialises the sounds to play when exit solenoid is actiavted.

ball                           Sound to play when at least one ball is in the lock

noBall                       Sound to play when the lock is empty

Example:

Lock.InitSnd ”BallKick”, ”Solenoid”

 

·         Method: .CreateEvents instance

Creates all events for triggers and kickers required for the lock

Example:

              Single ball lock (stupid example)

Lock.InitVLock LTrigger, LKicker, swLock

Lock.CreateEvents ”Lock”

 

·         Method: .TrigHit ball, no

·         Method: .TrigUnHit ball,no

·         Method: .KickHit no

Called from the events of the lock triggers and kickers. All these event are automatically generated with the .CreateEvents method.

Example:

Sub LTrigger_Hit : Lock.TrigHit ActiveBall, 1 : End Sub

Sub LTrigger_UnHit : Lock.TrigUnHit ActiveBall, 1 : End Sub

Sub LKicker_Hit : Lock.KickHit 1 : End Sub

 

·         Property: .ExitDir = direction

·         Property: .ExitForce = force

·         Property: .KickForceVar = var

Specifies the kickout for the lock.

direction                   Angle for kickout

force                         Force of kickout. If 0 the balls will roll out the bottom (default)

var                            Variation in kickout force

Example:

Lock.ExitDir = 10 ’ slightly to the right

Lock.ExitForce = 20

Lock.KickForceVar = 3 ‘ vary between 17-23

 

·         Property: .Balls

Number of balls currently in the lock (read-only)

Example:

     If Lock.Balls = 3 Then MsgBox “3 balls in lock”

 

·         Method: .SolExit enabled

Kicks balls out of lock. Can be specified as a solenoid handler.

Example:

SolCallback(sLockKickout) = “Lock.SolExit”

 

 

Class cvpmImpulseP

This class is used to replace the default VP plunger object in order to increase plunger resolution and allow more possible trajectories. It can function as both an autoplunger or a manual plunger.  It can be used with any visual representation you wish to provide including using the VP plunger object for the visible animation (do not allow it to actually touch the ball, though).  The plunger itself is a VP trigger covering the area where the plunger is to affect the ball.  Typically, that will be a normal 25 sized round trigger, but it can be reshaped for other effects (e.g. to provide a buffer zone for a kickback plunger in order to give VPM time to syncronize itself).  This trigger can also be defined to trip a switch when the ball rolls over it, thus elminating the need for a separate shooter lane type rollover switch.  Unlike the kicker-based plungers out there, this plunger object allows the ball to move freely as it sits in the plunger lane.

 

·         Method: .InitImpulseP trigger, strength, time

Initializes the magnet.

trigger:                     Trigger used to simulate the impulse plunger

strength:                   Plunger strength at maximum

time:                         Total time for plunger to reach full strength (0 = AutoPlunger)

Example:

PlungerIM.InitImpulseP PlungerRight, 28, 0.6

 

·         Method: .CreateEvents instance

Creates the plunger events “Sub Plunger_Hit …”

instance:                   The name of the cvpmImpulseP object.

Example:

PlungerIM.InitImpulseP PlungerRight, 28

PlungerIM.CreateEvents “PlungerRight”

 

·         Method: .AddBall ball

A ball has entered the plunger’s reach. Usually called from the plunger trigger’s hit event.

ball:                          Ball object

Example:

Sub RightPlunger_Hit : PlungerIM.AddBall ActiveBall : End Sub

 

·         Method: .RemoveBall ball

A ball has left the plunger’s reach. Usually called from the plunger trigger’s unhit event.

ball:                          Ball object

Example:

Sub RightPlunger_UnHit : PlungerIM.RemoveBall ActiveBall : End Sub

 

·         Method: .Pullback

Pull the plunger back.  Usually called from the VP script KeyDown sub

 

Example:

  Sub TableName_KeyUp(ByVal keycode)

    If keycode = PlungerKey Then

        Plunger.Pullback : PlungerIM.Pullback

    End If

  End Sub

Note: Plunger.Pullback activates VP’s regular plunger to syncronize an animation with the plunger object.  It would not appear if you provide your own animation.  PlungerIM.Pullback activates the Impulse Plunger.

 

·         Method: .Fire

Fire the plunger.  Usually called from the VP script KeyUP sub.

 

Example:

  Sub TableName_KeyDown(ByVal keycode)

    If keycode = PlungerKey Then

        Plunger.Fire : PlungerIM.Fire

    End If

  End Sub

Note: Plunger.Fire activates VP’s regular plunger to syncronize an animation with the plunger object.  It would not appear if you provide your own animation.  PlungerIM.Fire activates the Impulse Plunger.

 

·         Method: .AutoFire

Fire the plunger as an AutoPlunger.  Usually called from a VP solenoid callback sub.  Note that this method fires the plunger at the maximum strength instantly (it can also be done by providing a timing value of zero when initating the impulse plunger and using the regular fire function).  This basically makes it easy to combine a manual and AutoPlunger into one object for tables that combine them together.  You don’t have to adjust the timing to use the plunger as an autoplunger.

 

Example:

 

SolCallback(1)      = "AutoFire"                        ' Auto Plunger

 

  Sub AutoFire(enabled)

    If enabled Then PlungerIM.AutoFire

  End Sub

 

·         Method: .Random Value

Randomize the plunger strength by this multiplier value.  A value of 1 will provide a small amount of random variation in the plunger’s behavior.  A value of 0 will result in no variance at all.  Values between 0 and 1 will provide even smaller variances.  Values over 1 will multiply the random variance to much larger levels (i.e. 2 = 2x the variance of 1 whereas 0.5 would be ½ the variance of 1). 

 

Example:

 

IMPlunger.Random 1

 

·         Method: .Switch Value

If a value is specified using this call, that VPM switch will be activated when a ball rolls onto the trigger and deactivated when it rolls off.  This basically replaces the need for separate lane switch.  

 

Example:

 

IMPlunger.Switch 27

 

·         Method: .InitEntrySnd  sound

Specify the sound used when the entry solenoid is fired.

sound:                                sound to play as plunger is pulled back

Example:

PlungerIM.InitEntrySnd “PlungerPullSound”

 

 

·         Method: .InitExitSnd ballSound, sound

Specify the sound used when the entry solenoid is fired.

ballSound:                sound to play if a ball is present on the trigger (ball hit)

sound:                                sound to play if no ball is present on the trigger  (no  ball hit)

Example:

PlungerIM.InitExitSnd “BallHitSnd”, “PlungerSpringSound”

 

 

Complete example: Timer

Alternate two switches

Sub Test1(swNo)

     vpmTimer.PulseSwitch 1, 500, ”Test2”

End Sub

Sub Test2(swNo)

     vpmTimer.PulseSwitch 2, 500, ”Test1”

End Sub

Or (Advanced version)

Sub Test(newSw, lastSw)

     vpmTimer.PulseSwitch newSw,500,”Test “ & lastSw & “,”

End Sub

Open a message box after 5 seconds

‘ The last ‘ is to ignore the switch number added at the end

vpmTimer.AddTimer 5000,”MsgBox “”5 seconds””’”

 

Complete example: Trough

 

Dim bsTrough

Set bsTrough = New cvpmTrough : With bsTrough

     .Size = 5

     .EntrySw = swOutHole

     .InitSwitches Array(swTrough1, swTrough2, swTrough3)

     .InitExit kickBallRelease, 90, 4

     .InitEntrySounds “BallInSaucer”, “SolenoidOn”, “TroughKickIn”

     .InitExitSounds “SolenoidOn”, “BallRelease”

     .Balls = 3

     .CreateEvents “bsTrough”, Outhole

End With

SolCallback(sOuthole)     = “bsTrough.SolIn”

SolCallback(sBallRelease) = “bsTrough.SolOut”

Complete example: Ball Lock (eg. Twilight Zone)

 

Dim bsLock

Set bsLock = New cvpmTrough : With bsLock

     .Size = 4

     .InitSwitches Array(swLock1, swLock2, swLock3)

     .InitExit kickLock, 90, 4

     .InitEntrySounds “BallInSaucer”, “”, “”

     .InitExitSounds “SolenoidOn”, “LockRelease”

     .MaxBallsPerKick = 2

     .CreateEvents “bsLock”, LockEntry

End With

SolCallback(sLockRelease) = “bsLock.SolOut”

Complete example: Saucer

 

Dim bsHole

Set bsHole = New cvpmSaucer : With bsHole

     .InitKicker holeKicker, swHole, 180, 8, 0   180 degrees, force 8, no vertical

     .InitExitVariance 5, 2   ‘ Dir 175-185, Force 6-10

     .InitSounds “BallInSaucer”, “SolenoidOn”, “LockRelease”

     .CreateEvents “bsHole”, Hole

End With

SolCallback(sHoleKickout) = “bsHole.SolOut”

Complete example: VUK

 

Dim bsVUK

Set bsVUK = New cvpmSaucer : With bsVUK

     .InitKicker topVUKKicker, swVUK, 180, 1, 30   ‘ Kicks vertically

     .InitSounds “BallInSaucer”, “SolenoidOn”, “VUKSound”

     .CreateEvents “bsVUK”, bottomVUKKicker

End With

SolCallback(sVUKKickout) = “bsVUK.SolOut”

Complete example: Drop target bank

 

Dim dtBank

Set dtBank = New cvpmDropTarget : With dtBank

     .InitDrop Array(Target1,Target2,Target3), Array(swTarget1,swTarget2,swTarget3)

     .InitSound “TargetDown”, “TargetUp”

     .CreateEvents “dtBank”

End With

SolCallback(sDropReset) = “dtBank.SolDropUp”

Complete example: Tilt handling

 

vpmNudge.TiltSwitch = swTilt

vpmNudge.Sensitivity = 5

vpmNudge.TiltObj = Array(Bumper1,Bumper2,Bumper3,LeftSling,RightSling)

SolCallback(sGameOn) = “VpmNudge.SolGameOn”

 

Complete example: Magnet

 

Dim mMagnaSave

Set mMagnaSave = New cvpmMagnet : With mMagnaSave

     .InitMagnet MagnaSave, 12

     .CreateEvents “mMagnaSave”

     .Solenoid = sMagnaSave

End With

 

Complete example: TurnTable

 

Dim ttSoccerBall

Set ttSoccerBall = New cvpmTurnTable : With ttSoccerBall

     .InitTurnTable SoccerBall, 50

     .CreateEvents “ttSoccerBall”

End With

 

SolCallback(sBallCW) = “ttSoccerBall.SolMotorState True,”

SolCallback(sBallCCW) = “ttSoccerBall.SolMotorState False,”

Complete example: Visible ball lock

Dim Lock

Set Lock = New cvpmVLock : With Lock

     .InitVLock Array(LockTrig1,LockTrig2),Array(LockKick1,LockKick2),0

     .InitSnd “Solenoid”, “Solenoid”

     .ExitForce = 20

     .CreateEvents “Lock”

End With

 

Generic Solenoid handlers

A set of generic functions that can be called directly from the solenoid handlers. All handlers can use arrays or collections except “vpmSolFlipper”, “vpmSolDiverter” and “vpmSolAutoPlunger”.

·         vpmSolFlipper flipper1, flipper2, enabled

“Flip” a flipper. Reduces speed on back stroke.

flipper1:                    flipper object

flipper2:                    second flipper object if more than one flipper is connected to the same solenoid handler

Example:

              1. Separate solenoid handlers for upper and lower flipper

SolCallback(sLLFlipper) = ”vpmSolFlipper LeftFlipper,Nothing,”

SolCallback(sULFlipper) = ”vpmSolFlipper ULeftFlipper,Nothing,”

              2. Same solenoid handler for upper and lower flipper

SolCallback(sLRFlipper) = ”vpmSolFlipper RightFlipper, URightFlipper,”

 

·         vpmSolDiverter diverter, sound, enabled

Move a diverter implemented with a flipper object

diverter:                    “flipper” diverter to move

sound:                      Sound to make, True for standard sound, False for no sound

Example:

SolCallback(sRampDiverter) = “vpmSolDiverter RampDiv,True,”

SolCallback(sRampDiverter) = “vpmSolDiverter RampDiv,””RampOpen””,”

 

 

·         vpmSolWall wall, sound, enabled

Raise or drop a wall(s). e.g. a diverter implemented as a wall.

wall:                         Wall(s) to raise/Drop

sound:                      Sound to make, True for standard sound, False for no sound

Example:

              1. Single wall

SolCallback(sDiverter) = “vpmSolWall diverterWall,True,”

‘ This does the same thing

SolCallback(sDiverter) = “diverterWall.IsDropped =”

              2. Multiple walls

SolCallback(sDiverter) = “vpmSolWall Array(w1, w2),””Diverter””,”

 

·         vpmSolToggleWall wall1, wall2, sound, enabled

Toggle between walls (raise one and drop another)

wall1:                       Wall(s) to drop if enabled is True

wall2:                       Wall(s) to drop if enabled is False

sound:                      Sound to make, True for standard sound, False for no sound

Example:

SolCallback(sDiverter) = “vpmSolToggleWall Diverter,Array(div1,div2),False,”

 

·         vpmSolAutoPlunger plunger, variation, enabled

Plunge an automatic plunger or kickback

plunger:                    plunger object

variation:                  kick variation in % (i.e. 10 = ± 10%)

Example:

SolCallback(sKickBack) = ”vpmSolAutoPlunger kickback,10,”

 

·         vpmSolGate gate, sound, enabled

Open or close a one-way gate

gate:                         gate object

sound:                      Sound to make, True for standard sound, False for no sound

Example:

SolCallback(sGateOpen) = ”vpmSolGate gate,””GateOpen””,”

 

·         vpmSolSound sample, enabled

Play a sound when enabled is True

sample:                     Sound to play

Example:

SolCallback(sBumper) = “vpmSolSound “”Bumper””,”

 

·         vpmFlasher flasher, enabled

Light flasher(s)

flasher:                     flasher object to light

Example:

              1. Single flasher

SolCallback(sFlasher1) = “vpmFlasher Flasher1,”

              2. Multiple flashers

SolCallback(sFlasher1) = “vpmFlasher Array(Flash1,Flash2),”

 

·         vpmSolToggleObj obj1, obj2, sound, enabled

This is the big one! It will toggle almost any objects (Wall, Bumper, Light, Kicker, Trigger,Timer,Gate,Switch)

obj1:                         Object(s) to drop/enable/light if enabled is True

obj2:                         Object(s) to drop/enable/light if enabled is False

sound:                      Sound to make, True for standard sound, False for no sound

Objects are handled as:

Wall:                         Drop/Raise

Bumper                    Light/Unlight

Light                        Light/Unlight

Kicker                      Enable/Disable

Trigger                      Enabled/Disable

Timer                        Enabled/Disabled

Gate                         Open/Close

Switch                      Activate/Deactivate

 

Example:

              1. Drop Wall1 and light Flasher3 on flasher solenoid

SolCallback(sFlasher) = “vpmSolToggleObj Array(Wall1,Flasher3),Nothing,False,”

              2. Enable kicker1, kicker2, set switch 14 and raise Wall3

Sub Trigger_Hit

     VpmSolToggleObj Array(kicker1,kicker2,14),Wall3,”Noise”,True

End Sub

              3. All objects in one variable

objects = Array(Array(kicker1,kicker2,14),Array(Wall3))

vpmSolToggleObj objects,Nothing,False,True

Misc functions

·         vpmKeyUp(keyCode)

·         vpmKeyDown(keyCode)

Handles all general keys except the plunger. Returns True if the key was handled

Example:

              1. Manual Plunger

Sub Table_KeyUp(ByVal keycode)

     If vpmKeyUp(keycode) Then Exit Sub

     If keycode = PlungerKey Then Plunger.Fire

End Sub

Sub Table_KeyDown(ByVal keycode)

     If vpmKeyDown(keycode) Then Exit Sub

     If keycode = PlungerKey Then Plunger.Pullback

End Sub

              2. Automatic Plunger

Sub Table_KeyUp(ByVal keycode)

     If vpmKeyUp(keycode) Then Exit Sub

     If keycode = PlungerKey Then Controller.Switch(swPlunger) = False

End Sub

Sub Table_KeyDown(ByVal keycode)

     If vpmKeyDown(keycode) Then Exit Sub

     If keycode = PlungerKey Then Controller.Switch(swPlunger) = True

End Sub

·         vpmKeyName(keyCode)

Convert a keycode to a readable name of the key

Example:

MsgBox “key 5 = “ & vpmKeyName(5)

ExtraKeyHelp = vpmKeyName(keyBuyIn) & vbTab & “Buy In button”

 

·         vpmShowHelp

Display a window showing all keys defined for the game

Example:

VpmShowHelp

 

·         vpmMoveBall ball, fromKick, toKick

Moves a ball from a kicker to another preserving colour and image properties

Example:

Sub TeleportKick_Hit : vpmMoveBall ActiveBall, Me, TeleportEndKick : End Sub

Constants used

The following constants must be used for the *.VBS files to work properly.

·         UseSolenoids = True/False

Set to True to enable Solenoid callbacks via the SolCallback() variable

 

·         UseLamps = True/False

Set to True to enable Lamp updating. Lamps must be defined in Lights() variable. If UseLamps is set to false the “LampCallback” will be called on each update allowing a custom lamp handler.

 

·         SSolenoidOn, SSolenoidOff, SFlipperOn, SFlipperOff, SCoin

Standard sounds used by *:VBS files

SSolenoidOn/SSolenoidOff:Solenoid activated/deactivated.

Used in vpmSolDiverter, vpmSolWall, vpmSolToggleWall, vpmSolAutoPlunger.

SflipperOn/SflipperOff: Flipper activated/deactivated

Used in vpmSolFlipper

SCoin: Coin inserted

 

·         vpmMultiLights()

An array of lights that are updated together. The second, third… light is set to the same state as the first.

ReDim vpmMultiLights(2)

vpmMultiLights(0) = Array(Lamp22, Lamp22a, Lamp22b)

vpmMultiLights(1) = Array(Lamp23, Lamp23a)

vpmMultiLights(2) = Array(Lamp24, Lamp24a)

 

 

·         LampCallback

Function to call when at least one Lamp has changed state. Main purpose is to handle cases where more than one lamp is connected to a single output (UseLamps = True) or to implment a custom lamp handler (UseLamps = False).

 

Example;

              1. Two lamps connected to the same wire.

UseLamps = True

Set LampCallback = GetRef(“UpdateLamps”)

Sub UpdateLamps

     Lamp22a.State = Lamp22.State

End Sub

              2. A custom lamp handler is required to handle blending of two lights

UseLamps = False

Set LampCallback = GetRef(“MyLampHandler”)

Sub MyLampHandler

     Dim chgLamp, ii

     ChgLamp = Controller.ChangedLamps

     If IsEmpty(ChgLamp) Then Exit Sub

     On Error Resume Next

     For ii = 0 To UBound(ChgLamp)

           ‘Light 1 is red, light 2 is yellow

           ‘If both are lit light an orange light (65)

           If ChgLamp(ii, CHGNO) = 1 Or ChgLamp(ii, CHGNO) = 2 Then

                With Controller

                      Lights(65).State = .Lamp(1) And .Lamp(2)

                      Lights(1).State = .Lamp(1)

                      Lights(2).State = .Lamp(2)

                End With

           Else

                VpmDoLights ChgLamp(ii, CHGNO), ChgLamp(ii, CHGSTATE)

           End If

     Next

     On Error Goto 0

End Sub

 

·         GICallback

Function to update GI lamps. Only WPC games have special GI circuit

Callback function must take two arguments

StringNo:                  GIString that has changed state (0-4)

Status:                       New status of GI string

Example:

Set GICallback = GetRef(“UpdateGI”)

Sub GICallback(giNo, status)

     Select Case giNo

           Case 0     GI0.State = Abs(status)

           Case 1     GI1.State = Abs(status)

 

·         MotorCallback

Function called after every update of solenoids and lamps (i.e. as often as possible). Main purpose is to update table based on playfield motors.

It can also be used to override the standard solenoid callback handler. One reason is to handle multiplexed solenoids.

Note that this function may be called hundred of times per second. Keep it quick!

Example:

              1. Motor Update

Set MotorCallback = GetRef(“UpdateGun”)

Sub HandleGunMotor

     Dim newGunPos

     If Controller.Solenoid(sGunMotor) Then

              2. Multiplexed solenoid handling. (Solenoid 11 multiplexes solenoid 1-10)

UseSolenoids = False

Set MotorCallback = GetRef(“UpdateSolenoids”)

Sub UpdateSolenoids

     Dim Changed, Count, funcName, ii, sol11, solNo

     Changed = Controller.ChangedSolenoids

     If Not IsEmpty(Changed) Then

           sol11 = Controller.Solenoid(11)

           Count = UBound(Changed, 1)

           For ii = 0 To Count

                solNo = Changed(ii, CHGNO)

                If SolNo < 11 And sol11 Then solNo = solNo + 32

                vpmDoSolCallback solNo, Changed(ii, CHGSTATE)

           Next

     End If

End Sub

 

Full Table Example: BadCats

This example is taken from the BadCats table. Shows table with drop targets and kickouts. The constant declarations for switches and solenoids and the lamparray initialisation has been left out.

LoadVPM "00990400", "S11.VBS", 2.0

Const cGameName = "bcats_l5" ' PinMAME short game name

Const UseSolenoids    = True

Const UseLamps        = True

'Standard sound

Const SSolenoidOn   = "SolOn"  'Solenoid activates

Const SSolenoidOff  = "" 'Solenoid deactivates

Const SFlipperOn    = "FlipperUp"  'Flipper activated

Const SFlipperOff   = "FlipperDown" 'Flipper deactivated

Const SCoin         = "Quarter"    'Coin inserted

'Callbacks

Set LampCallback      = GetRef("UpdateMultipleLamps")

 

Sub LoadVPM(VPMver, VBSfile, VBSver)

     On Error Resume Next

           If ScriptEngineMajorVersion < 5 Then MsgBox "VB Script Engine 5.0 or higher required"

           ExecuteGlobal GetTextFile(VBSfile, 1).ReadAll

           If Err Then MsgBox "Unable to open " & VBSfile & ". Ensure that it is in the same folder as this table. " & vbNewLine & Err.Description

           Set Controller = CreateObject("VPinMAME.Controller")

           If Err Then MsgBox "Can't Load VPinMAME." & vbNewLine & Err.Description : Err.Clear

           If VPMver > "" Then If Controller.Version < VPMver Or Err Then MsgBox "VPinMAME ver " & VPMver & " required." : Err.Clear

           If VPinMAMEDriverVer < VBSver Or Err Then MsgBox VBSFile & " ver " & VBSver & " or higher required."

     On Error Goto 0

End Sub

 

Sub Badcats_KeyDown(ByVal keycode)

     If vpmKeyDown(keycode) Then Exit Sub

     If keycode = PlungerKey Then Plunger.Pullback

End Sub

Sub Badcats_KeyUp(ByVal keycode)

     If vpmKeyUp(keycode) Then Exit Sub

     If keycode = PlungerKey Then Plunger.Fire

End Sub

 

Const cCredits  = "Williams(R) Badcats(TM)”

Dim bsTrough,dtMilk,bsDogHouse,bsTrashCan,dtBird

Sub Badcats_Init

     VpmInit Me

     On Error Resume Next

     With Controller

           .GameName = cGameName

           If Err Then MsgBox "Can't start Game" & cGameName & vbNewLine & Err.Description : Exit Sub

           .SplashInfoLine = cCredits

           .HandleMechanics = 0

           .ShowDMDOnly = True : .ShowFrame = False : .ShowTitle = False

           .SetDisplayPosition 0,0,GetPlayerHWnd

           .Run

           If Err Then MsgBox Err.Description

     End With

     On Error Goto 0

     ' Nudging

     vpmNudge.TiltSwitch = swTilt

     vpmNudge.Sensitivity = 5

     vpmNudge.TiltObj = Array(Bumper1,Bumper2,Bumper3,LeftslingShot,RightslingShot)

 

     ' Ballstacks

     Set bsTrough = New cvpmTrough : With bsTrough

           .Size = 1                          ‘ Single ball game

           .AddSw 0, 10

           .InitExit BallRelease, 160, 4

           .InitExitSounds “SolOn”, “BallRelease”

           .CreateEvents “bsTrough”, OutHole

           .Balls = 1

     End With

     SolCallback(sBallRelease) = "bsTrough.SolOut"

 

     ' Milk targets

     Set dtMilk = New cvpmDropTarget : With dtMilk

           .InitDrop Array(Milk1,Milk2,Milk3),Array(37,38,39)

           .InitSnd "DropDown","DropUp"

           .CreateEvents “dtMilk”

     End With

     SolCallback(sMilkBank) = "dtMilk.SolDropUp"

 

     ' Doghouse

     Set bsDogHouse = New cvpmSaucer : With bsDogHouse

           .InitKicker doghouseKicker, 22, 180, 20, 0

           .InitSounds “”, “SolOn”, “BallRelease”

           .CreateEvents “bsDogHouse”, DogHouseKicker

     End With

     SolCallback(sDogHouse) = "bsDogHouse.SolOut"

 

     ' TrashCan

     Set bsTrashCan = New cvpmSaucer : With bsTrashCan

           .InitKicker TrashCan, 24, 95, 15, 0

           .InitSounds “”, “SolOn”, “BallRelease”

           .CreateEvents “bsTrashCan”, TrashCan

     End With

     SolCallback(sGarbageCan) = "bsTrashCan.SolOut"

 

     ' Birdie targets

     Set dtBird = New cvpmDropTarget : With dtBird

        .InitDrop Array(Birdie1,Birdie2,Birdie3,Birdie4,Birdie5),_ Array(25,26,27,28,29)

           .InitSnd "DropDown","DropUp"

           .CreateEvents “dtBird”

     End With

     SolCallback(sBirdBank) = "dtBird.SolDropUp"

 

     ' You can't set the bumper state to on in VP editor

     Bumper1.State = LightStateOn

     Bumper2.State = LightStateOn

     Bumper3.State = LightStateOn

End Sub

 

SolCallback(sKnocker)     = "vpmSolSound ""Knocker"","

SolCallback(sTLJet)       = "vpmSolSound ""Bumper"","

SolCallback(sLSling)      = "vpmSolSound ""Sling"","

SolCallback(sTRJet)       = "vpmSolSound ""Bumper"","

SolCallback(sRSling)      = "vpmSolSound ""Sling"","

SolCallback(sBJet)        = "vpmSolSound ""Bumper"","

SolCallback(sLRFlipper)   = "vpmSolFlipper RightFlipper,Nothing,"

SolCallback(sLLFlipper)   = "vpmSolFlipper LeftFlipper,Nothing,"

SolCallback(sGameOn)      = "vpmNudge.SolGameOn"

 

 

' Slow down balls on ramp

Sub kicker3_hit : Me.kick 180,1 : End sub

Sub kicker4_hit : Me.kick 180,1 : End Sub

 

'SWITCH HANDLING

Sub TriggerO_Hit : Controller.Switch(12) = True : End Sub

Sub TriggerO_UnHit : Controller.Switch(12) = False : End Sub

Sub TriggerT_Hit : Controller.Switch(11) = True : End Sub

Sub TriggerT_UnHit : Controller.Switch(11) = False : End Sub

Sub TriggerY_Hit : Controller.Switch(13) = True : End Sub

Sub TriggerY_UnHit : Controller.Switch(13) = False : End Sub

Sub Shooter_Hit : Controller.Switch(14) = True : End Sub

Sub Shooter_UnHit : Controller.Switch(14) = False : End Sub

Sub FishBowlEntrance_Hit : Controller.Switch(16) = True : End Sub

Sub FishBowlEntrance_UnHit : Controller.Switch(16) = False : End Sub

Sub FishBowlScore_Hit : Controller.Switch(43) = True : End Sub

Sub FishBowlScore_UnHit : Controller.Switch(43) = False : End Sub

Sub TigerEntrance_Hit : Controller.Switch(23) = True : End Sub

Sub TigerEntrance_UnHit : Controller.Switch(23) = False : End Sub

Sub TigerScore_Hit : Controller.Switch(41) = True : End Sub

Sub TigerScore_UnHit : Controller.Switch(41) = False : End Sub

Sub BoneUs1_Hit : Controller.Switch(19) = True : End Sub

Sub BoneUs1_UnHit : Controller.Switch(19) = False : End Sub

Sub LeftOutlane_Hit : Controller.Switch(35) = True : End Sub

Sub LeftOutlane_UnHit : Controller.Switch(35) = False : End Sub

Sub LeftInlane_Hit : Controller.Switch(30) = True : End Sub

Sub LeftInlane_UnHit : Controller.Switch(30) = False : End Sub

Sub RightInlane_Hit : Controller.Switch(31) = True : End Sub

Sub RightInlane_UnHit : Controller.Switch(31) = False : End Sub

Sub RightOutlane_Hit : Controller.Switch(36) = True : End Sub

Sub RightOutlane_UnHit : Controller.Switch(36) = False : End Sub

' Bumpers/Slingshots

Sub Bumper1_Hit : vpmTimer.PulseSw 60 : End Sub

Sub Bumper2_Hit : vpmTimer.PulseSw 61 : End Sub

Sub Bumper3_Hit : vpmTimer.PulseSw 62 : End Sub

Sub RightSlingshot_Slingshot : vpmTimer.PulseSw 64 : End Sub

Sub LeftSlingshot_Slingshot : vpmTimer.PulseSw 63 : End Sub

' Rubbers

Sub Wall1_Slingshot : vpmTimer.PulseSw 34 : End Sub

Sub OuterWall_Slingshot : vpmTimer.PulseSw 40 : End Sub

Sub Wall6_Slingshot : vpmTimer.PulseSw 33 : End Sub

 

Full Table Example: Mr. & Mrs. PacMan

This example is taken from the Mr. MrsBadCats table. Shows table with custom solenoid and lamp handler, solenoid controlled drop targets and saucer with two kickout directions.

The constant declarations for switches and solenoids and the lamp array initialisation has been left out.

 

Option Explicit

LoadVPM "00990400", "Bally.VBS", 2.0

 

Const cGameName     = "m_mpac"   ' PinMAME short name

Const UseSolenoids  = False ‘ Using motorcallback for custom handler

Const UseLamps      = False ‘ Using lampcallback for custom handler

Set LampCallback = GetRef("UpdateLamps")

Set MotorCallback = GetRef("UpdateSolenoids")

' Standard Sounds

Const SSolenoidOn   = ""

Const SSolenoidOff  = ""

Const SFlipperOn    = "FlipperUp"

Const SFlipperOff   = "FlipperDown"

Const SCoin         = "Coin"

 

SolCallback(sKnocker)     = "vpmSolSound ""Knocker"","

SolCallback(sLSling)      = "vpmSolSound ""SlingShot"","

SolCallback(sRSling)      = "vpmSolSound ""SlingShot"","

SolCallback(sLJet)        = "vpmSolSound ""Bumper"","

SolCallback(sRJet)        = "vpmSolSound ""Bumper"","

SolCallback(sEnable)      = "vpmNudge.SolGameOn"

SolCallback(sGate)        = "vpmSolDiverter SaveGate,""Gate"","

SolCallback(sLLFlipper)   = "vpmSolFlipper LeftFlipper, Nothing,"

SolCallback(sLRFlipper)   = "vpmSolFlipper RightFlipper, UpperFlipper,"

 

Dim bsTrough, dtLDrop, dt3Drop, dtRDrop, bsPacMan,bsEject,Matrix(128)

 

Sub MrMsPacMan_Init

     vpmInit Me

     With Controller

           .GameName = cGameName

           .SplashInfoLine = cCredits

           .ShowTitle = False : .ShowDMDOnly = True : .ShowTitle = False

           On Error Resume Next

                .Run

                If Err Then MsgBox Err.Description

           On Error Goto 0

     End With

     ' Nudging

     vpmNudge.TiltSwitch = 15

     vpmNudge.Sensitivity = 4

     vpmNudge.TiltObj = Array(Bumper1,Bumper2,LeftSlingshot,RightSlingShot)

     Set dtLDrop = New cvpmDropTarget : With dtLDrop

           .InitDrop Array(Wall13,Wall16,Wall15,Wall14), Array(1,2,3,4)

           .InitSnd "DropTarget","TargetReset"

           .CreateEvents “dtLDrop”

     End With

     SolCallback(sTargetResetL)= "dtLDrop.SolDropUp"

     SolCallback(sLReset1)     = "dtLDrop.SolHit 1,"

     SolCallback(sLReset2)     = "dtLDrop.SolHit 2,"

     SolCallback(sLReset3)     = "dtLDrop.SolHit 3,"

     SolCallback(sLReset4)     = "dtLDrop.SolHit 4,"

     Set dtRDrop = New cvpmDropTarget : With dtRDrop

           .InitDrop Array(Wall17,Wall20,Wall19,Wall18),_ Array(25,26,27,28)

           .InitSnd "DropTarget","TargetReset"

           .CreateEvents “dtRDrop”

     End With

     SolCallback(sTargetResetR)= "dtRDrop.SolDropUp"

     SolCallback(sRReset1)     = "dtRDrop.SolHit 1,"

     SolCallback(sRReset2)     = "dtRDrop.SolHit 2,"

     SolCallback(sRReset3)     = "dtRDrop.SolHit 3,"

     SolCallback(sRReset4)     = "dtRDrop.SolHit 4,"

     Set dt3Drop = New cvpmDropTarget : With dt3Drop

           .InitDrop Array(Wall10,Wall12,Wall11),Array(22,23,24)

           .InitSnd "DropTarget","TargetReset"

           .CreateEvents “dt3Drop”

     End With

     SolCallback(sTargetReset3)= "dt3Drop.SolDropUp"

 

     ' Trough (or really just an outhole)

     Set bsTrough = New cvpmTrough : With bsTrough

           .Size = 1

           .AddSw 0, 5

           .InitExit Feed, 90, 2

           .CreateEvents “bsTrough”, Drain

     End With

     SolCallback(sBallRelease) = "bsTrough.SolOut"

 

     Set bsPacMan = New cvpmSaucer : With bsPacMan

           .InitKicker PacManSaucer, 8, 170, 5, 0

           .InitSounds “”, “Saucer”, “Saucer”

           .CreateEvents “bsPacMan”, 0   ‘ Use this saucer’s kicker

     End With

     SolCallback(sRSaucer)     = "bsPacMan.SolOut"

 

     Set bsEject = New cvpmSaucer : With bsEject

           .InitKicker EjectHole, 7, 260, 10, 0

           .InitAltKick 80, 10, 0

           .InitSounds “”, “Saucer”, “Saucer”

           .CreateEvents “bsEject”, 0

     End With

     SolCallback(sLSaucerL)    = "bsEject.SolOut"

     SolCallback(sLSaucerR)    = "bsEject.SolOutAlt"

End Sub

 

Sub MrMsPacMan_KeyUp(ByVal keycode)

     If vpmKeyUp(keycode) Then Exit Sub

     If keycode = PlungerKey Then PlaySound "Plunger" : Plunger.Fire

End Sub

 

Sub MrMsPacMan_KeyDown(ByVal keycode)

     If vpmKeyDown(keycode) Then Exit Sub

     If keycode = PlungerKey Then Plunger.Pullback

End Sub

 

‘ Lamp 87 is used to mux solenoids 9-16. remap them to 32-

Sub UpdateSolenoids

     Dim Changed, Count, funcName, ii, sel, solNo

     Changed = Controller.ChangedSolenoids

     If Not IsEmpty(Changed) Then

           sel = Controller.Lamp(87)

           Count = UBound(Changed, 1)

           For ii = 0 To Count

                solNo = Changed(ii, CHGNO)

                If SolNo >= 9 And SolNo <= 15 And sel Then solNo = solNo + 24

                funcName = SolCallback(solNo)

                If funcName <> "" Then Execute funcName & " CBool(" & Changed(ii, CHGSTATE) &")"

           Next

     End If

End Sub

‘ Handle blending in matrix

Sub UpdateLamps

     dim ii, Lamp1, Lamp2, stat1, stat2, chgLamp

     ChgLamp = Controller.ChangedLamps

     If IsEmpty(ChgLamp) Then Exit Sub

     On Error Resume Next

     For ii = 0 To UBound(ChgLamp)

           Lights(ChgLamp(ii, CHGNO)).State = ChgLamp(ii, CHGSTATE)

     Next

     On Error Goto 0

     Light8a.state = Light8.state

     Light9a.state = Light9.state

     Light10a.state = Light10.state

     Light25a.state = Light25.state

     Light41a.state = Light41.state

     Light42a.state = Light42.state

     Light57a.state = Light57.state

     Light71a.state = Light71.state

     For ii = 0 To UBound(ChgLamp)

           If IsObject(Matrix(ChgLamp(ii,CHGNO))) Then

                lamp1 = chgLamp(ii, CHGNO) And 63 : stat1 = Controller.Lamp(lamp1)

                lamp2 = lamp1 + 64 : stat2 = Controller.Lamp(lamp2)

                Matrix(lamp2+8).State = Abs(stat1 And stat2)

                If stat2 Then

                      If Not stat1 Then Matrix(lamp1).state = 0 : Matrix(lamp2).state = 1

                Else

                      Matrix(lamp2).state = 0 : Matrix(lamp1).state = 1

                      If Not stat1 Then Matrix(lamp1).state = 0

                End If

           End If

     Next

End Sub

 

‘ Targets

Sub Wall22_Hit : vpmTimer.PulseSw 34 : End Sub

Sub Wall24_Hit : vpmTimer.PulseSw 35 : End Sub

Sub Wall23_Hit : vpmTimer.PulseSw 36 : End Sub

Sub Wall25_Hit : vpmTimer.PulseSw 38 : End Sub

Sub Wall27_Hit : vpmTimer.PulseSw 39 : End Sub

Sub Wall26_Hit : vpmTimer.PulseSw 40 : End Sub

Sub OuterWall_Slingshot : vpmTimer.PulseSw 29 : End Sub

 ‘ Triggers

Sub LeftInlane_Hit     : Controller.Switch(12) = True  : End Sub

Sub LeftInlane_UnHit   : Controller.Switch(12) = False : End Sub

Sub RightOutlane_Hit   : Controller.Switch(12) = True  : End Sub

Sub RightOutlane_UnHit : Controller.Switch(12) = False : End Sub

Sub RightInlane_Hit    : Controller.Switch(13) = True  : End Sub

Sub RightInlane_UnHit  : Controller.Switch(13) = False : End Sub

Sub LeftOutlane_Hit    : Controller.Switch(14) = True  : End Sub

Sub LeftOutlane_UnHit  : Controller.Switch(14) = False : End Sub

Sub Trigger1_Hit       : Controller.Switch(21) = True  : End Sub

Sub Trigger1_UnHit     : Controller.Switch(21) = False : End Sub

‘ Bumpers/Slingshots etc

Sub Bumper2_Hit : vpmTimer.PulseSw 17 : End Sub

Sub Bumper1_Hit : vpmTimer.PulseSw 18 : End Sub

Sub LeftSlingshot_Slingshot  : vpmTimer.PulseSw 19 : End Sub

Sub RightSlingshot_Slingshot : vpmTimer.PulseSw 20 : End Sub

Sub Spinner1_Spin : vpmTimer.PulseSw 30 : End Sub

Sub Spinner2_Spin : vpmTimer.PulseSw 30 : End Sub

 

Simplifying the script

If you want to minimize the coding required for a table there are several functions in the vbs files that can be used.

Using the functions described below is not necessary but they will simplify many tasks and they also eliminate many common errors such as misspelled and missing events. They also move a lot of work from the script to the Visual Pinball editor. Playfield objects such as lamps and triggers can be added/deleted/renamed in the editor without the need to change the script.

 

Note that bumpers can only be mapped automatically for lights or switches (unless they have the same switch and lamp number).

Automatic light mapping

All lights (and bumpers) on the playfield can be automatically mapped to the VPinMAME output.

  1. Put the lamp number for each playfield lamp in the “TimerInterval” field. Several lamps can have the same number.
  2. Put all lamps into a collection (e.g. a collection named “AllLamps”)
  3. Put the following line in the script

vpmMapLights AllLamps

Automatic switches

Almost all switches can be automatically mapped to VPinMAME. It works a bit different depending on the type of switch.

Bumpers, Triggers, Spinners, Targets (not Drop Targets), Gates and Slingshots

  1. Put the switch number of each object in the “TimerInterval” field. Several objects can have the same switch number
  2. Put all objects into all collection (e.g. “AllSwitches”)
  3. Put the following line in the script

vpmCreateEvents AllSwitches

Drop Targets

Normally a drop target consists of a single wall object but sometimes it is necessary to build it from several wall objects. Unfortunatly Visual Pinball can’t create collections of collections so if multiple walls are used for each drop target the implementation will be slight different.

Drop targets using the “SlingShot” event can’t be handled this way.

 

Simple case: A single wall per drop target.

  1. Put the switch number for the drop target in the “TimerInterval” field.
  2. Create a collection of all drop targets in the same bank (e.g. “LeftBank”)
  3. Use the cvpmDropTarget class for the handling

dtLeft = New cvpmDropTarget

dtLeft.InitDrop LeftBank,0

deLeft.CreateEvents “dtLeft”

  1. Don’t forget the solenoid handler for raising the drop targets.

 

Advanced case: Multiple walls per drop target

  1. Put the switch number for the drop target in the “TimerInterval” field. Several wall objects can have the same switch number. Make sure that wall objects not used doesn’t have the “Has hit event” checked.
  2. Create a collection for each drop target (e.g. “LeftBank1”, “LeftBank2”)
  3. Use the cvpmDropTarget class for the handling

dtLeft = New cvpmDropTarget

dtLeft.InitDrop Array(LeftBank1,LeftBank2,LeftBank3),0

deLeft.CreateEvents “dtLeft”

Magnets, TurnTables, Captive Balls and Visible locks

The events for magnets, turntables, captive balls and visible locks are very simple but they can also be generated automatically with the .CreateEvents method.

mMagnaSave = New cvpmMagnet

mMagnaSave.initMagnet magnetTrigger,10

mMagnaSave.Solenoid = sMagnaSave

mmagnaSave.CreateEvents “mMagnaSave”

Solenoid Handlers

The vbs files contains predefined functions for almost all playfield objects controlled by solenoids. There is no need to have more than one or two custom solenoid handler on a normal table. A few points to remember:

Multiple Objects

Almost all solenoid handlers can work with multiple objects. The objects can be specified using both arrays and collections.

“VpmFlasher Array(flasher1,flasher2,flasher3),”

Generic Function

There is very powerful function that can handle almost any object “vpmSolToggleObj”. The function takes two arguments where the first is an array (or collection) of objects to turn on/enable etc and the second argument is objects to turn off/disable etc. The objects can be mixed in any way.

 

Object                  On Action            Off Action

Wall                     Drop                    Raise

Bumper                Light on               Light off

Light                    Light on               Light off

Kicker                  Enable                  Disable

Trigger                 Enable                  Disable

Timer                   Enable                  Disable

Gate                     Open                    Close

Switch Number   Activate               Deactivate

 

This means that a single function call can drop 2 walls, turn off a light, light up a bumper, disable a kicker and activate a switch.

VpmToggleObj Array(Wall1,Wall2,Bumper1,32),Array(Light1,Kicker1),True

Or

AllObj = Array(Array(Wall1,Wall2,Bumper1,32),Array(Light1,Kicker1))

VpmToggleObj AllObj,Nothing,True