a. cvpmTimer class for switch pulsing and easy
timer handling.
b. cvpmBallStack class for ball tracking
in stacks or saucers.
c. cvpmDropTarget class for easy drop
target bank handling
d. cvpmNudge class for Tilt handling
e. cvpmMagnet class for playfield Magnets
f. cvpmTurntable class for playfield
turntables
g. cvpmCaptiveBall class for captive
balls
h. cvpmMech class for handling playfield
mechanics
i. cvpmVLock class for visible ball locks
j. cvpmImpulseP class for Impulse
Plungers using triggers
a. Flippers
b. Diverters
c. Walls
d. Auto Plungers (kicker based)
e. Gates
f. Sound
g. Flashers
h. Generic
for any object
a. Common switches/Solenoids
a. Open options window (F1)
b. Show keys help (F2)
c. Reset emulation (F3)
d. Toggle display lock status (F4)
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 same folder as this table. " & 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
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 ’”
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.
Example:
Set bsTrough = New cvpmBallStack
Set bsSaucer = New cvpmBallStack
· 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”
· 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
·
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
· 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
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,”
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”
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
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
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)
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
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”
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”
Sub Test1(swNo)
vpmTimer.PulseSwitch 1, 500, ”Test2”
End Sub
Sub Test2(swNo)
vpmTimer.PulseSwitch 2, 500, ”Test1”
End Sub
Sub Test(newSw, lastSw)
vpmTimer.PulseSwitch newSw,500,”Test “ & lastSw & “,”
End Sub
‘ The last ‘ is to ignore the switch number added at the end
vpmTimer.AddTimer 5000,”MsgBox “”5 seconds””’”
Dim bsTrough
Set bsTrough = New cvpmBallStack : With bsTrough
.InitSw
swOutHole,swTrough1,swTrough2,swTrough3,0,0,0,0
.InitKick kickBallRelease,90,4
.InitEntrySound “SolenoidOn”,
“SolenoidOn”
.InitExitSound “BallRelease”,
“SolenoidOn”
.Balls = 3
.CreateEvents “bsTrough”,
Outhole
End With
SolCallback(sOuthole) =
“bsTrough.SolIn”
SolCallback(sBallRelease) = “bsTrough.SolOut”
Dim bsLock
Set bsLock = New cvpmBallStack : With bsLock
.InitSw
0,swLock1,swLock2,0,0,0,0,0
.InitKick
kickLock,90,4
.InitExitSound “LockRelease”,
“SolenoidOn”
.KickBalls = 2
.CreateEvents “bsLock”, Lock
End With
SolCallback(sLockRelease) = “bsLock.SolOut”
Dim bsHole
Set bsHole = New cvpmBallStack : With bsHole
.InitSaucer
holeKicker,swHole,180,8
.InitForceVar = 2 ‘ force 6-10
.InitAngleVar = 5 ‘ 175-185
.InitExitSound “SolenoidOn”,
“SolenoidOn”
.CreateEvents “bsHole”, Hole
End With
SolCallback(sHoleKickout) = “bsHole.SolOut”
Dim bsVUK
Set bsVUK = New cvpmBallStack : With bsVUK
.InitSaucer
topVUKKicker,swVUK,180,8
.InitExitSound “VUKSound”,
“SolenoidOn”
.CreateEvents “bsVUK”,
bottomVUKKicker
End With
SolCallback(sVUKKickout) = “bsVUK.SolOut”
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”
vpmNudge.TiltSwitch = swTilt
vpmNudge.Sensitivity = 5
vpmNudge.TiltObj = Array(Bumper1,Bumper2,Bumper3,LeftSling,RightSling)
SolCallback(sGameOn) = “VpmNudge.SolGameOn”
Dim mMagnaSave
Set mMagnaSave = New cvpmMagnet : With mMagnaSave
.InitMagnet MagnaSave, 12
.CreateEvents “mMagnaSave”
.Solenoid = sMagnaSave
End With
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,”
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
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
· 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
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
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 cvpmBallStack : With bsTrough
.InitNoTrough BallRelease,10,160,4 ‘ Single ball game
.InitExitSnd "BallRelease","SolOn"
.CreateEvents “bsTrough”,OutHole
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 cvpmBallStack : With bsDogHouse
.InitSaucer doghousekicker,22,180,20
.InitExitSnd "BallRelease","SolOn"
.CreateEvents “bsDogHouse”, DogHouseKicker
End With
SolCallback(sDogHouse) = "bsDogHouse.SolOut"
' TrashCan
Set bsTrashCan = New cvpmBallStack : With bsTrashCan
.InitSaucer TrashCan,24,95,15
.InitExitSnd "BallRelease","SolOn"
.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
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 cvpmBallStack : With bsTrough
.InitNoTrough Feed,5,90,2
.CreateEvents “bsTrough”, Drain
End With
SolCallback(sBallRelease) = "bsTrough.SolOut"
Set bsPacMan = New cvpmBallStack : With bsPacMan
.InitSaucer PacManSaucer,8,170,5
.InitExitSnd "Saucer","Saucer"
.CreateEvents
”bsPacMan”,0
End With
SolCallback(sRSaucer) = "bsPacMan.SolOut"
Set bsEject = New cvpmBallStack : With bsEject
.initSaucer EjectHole,7,260,10 'Default down
.InitAltKick 80,10
.InitExitSnd "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
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).
All lights (and
bumpers) on the playfield can be automatically mapped to the VPinMAME output.
vpmMapLights AllLamps
Almost all
switches can be automatically mapped to VPinMAME. It works a bit different
depending on the type of switch.
vpmCreateEvents AllSwitches
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.
dtLeft = New cvpmDropTarget
dtLeft.InitDrop LeftBank,0
deLeft.CreateEvents “dtLeft”
Advanced
case: Multiple walls per drop target
dtLeft = New cvpmDropTarget
dtLeft.InitDrop Array(LeftBank1,LeftBank2,LeftBank3),0
deLeft.CreateEvents “dtLeft”
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”
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:
Almost all
solenoid handlers can work with multiple objects. The objects can be specified
using both arrays and collections.
“VpmFlasher Array(flasher1,flasher2,flasher3),”
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