====================================================================
 Helper scripts for the VPinMAME driver core (aka core vbs/scripts)
====================================================================

Basic documentation on how to use the VPM core scripts shipped with VPX.

Please also check core.vbs' actual functions for more help in their comments and the respective machine .vbs files functions, too.
In addition there is the pretty aged "vbsdoc_outdated.html", too, which may still be useful in some cases though!

There is also https://docs.orbitalpin.com/welcome for some more detailed help

And CommandReference.txt for some overview of (the majority of) the VPX scripting commands to connect both worlds, etc.

Also use e.g. https://web.archive.org/web/20090419182113/ssuet.edu.pk/taimoor/books/1-57521-124-6/index.htm for a (detailed) intro to VBScripting


============
Basic usage:
============

Put this at the top of the table file:
======================================================================================================== SNIP

Option Explicit  ' Optional, recommended
Randomize        ' Optional, recommended

' Though shall not declare a custom LoadVPM anymore, BUT use this instead:
On Error Resume Next
ExecuteGlobal GetTextFile("Controller.vbs")
If Err Then MsgBox "Unable to open Controller.vbs. Ensure that it is in the Scripts folder of Visual Pinball."
On Error Goto 0

Dim UseVPMDMD  ' Or UseVPMColoredDMD if a colorization of the game exists
UseVPMDMD = 1  ' Optional, only use this if the VPX table will directly render the DMD via textbox or flasher, otherwise set to 0

LoadVPM "02000000", "xxx.VBS", 3.58 ' adapt 02000000 and 3.58 to the actually required minimum VPinMAME- and core scripts versions, replace xxx with the machine generations vbs name

Const cGameName    = "xxxx"         ' PinMAME short game name
Const UseSolenoids = 2              ' 2 enables Fast Flips, if this does not work for the machine in question, use True instead
Const UseLamps     = True
'Standard sound
Const SSolenoidOn  = "SolOn"        ' Solenoid activates
Const SSolenoidOff = "SolOff"       ' Solenoid deactivates
Const SFlipperOn   = "FlipperUp"    ' Flipper activated
Const SFlipperOff  = "FlipperDown"  ' Flipper deactivated
Const SCoin        = "Quarter"      ' Coin inserted
'Callbacks
Set LampCallback   = GetRef("UpdateMultipleLamps")
Set GICallback     = GetRef("UpdateGI")  ' Original GI Callback (returns boolean on and off values only)
Set GICallback2    = GetRef("UpdateGI")  ' New GI Callback supports Newer VPM Dimming GI and returns values numeric 0-8)
Set MotorCallback  = GetRef("UpdateMotors")

Sub Table_KeyDown(ByVal keycode)
   If vpmKeyDown(keycode) Then Exit Sub
   If keycode = PlungerKey Then Plunger.Pullback
End Sub
Sub Table_KeyUp(ByVal keycode)
   If vpmKeyUp(keycode) Then Exit Sub
   If keycode = PlungerKey Then Plunger.Fire
End Sub

Const cCredits = ""
Sub Table_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
           .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,LeftslingShot,RightslingShot)
' Map switches and lamps
   vpmCreateEvents colSwObjects ' collection of triggers etc
   vpmMapLights    colLamps     ' collection of all lamps
' Trough handler
   Set bsTrough = New cvpmBallStack
   bsTrough.InitNoTrough BallRelease, swOuthole, 90, 2
   'or
   bsTrough.InitSw swOuthole,swTrough1,swTrough2,0,0,0,0

======================================================================================================== SNIP



==========================================
Now some partially outdated documentation:    :/
==========================================


These helper functions require the following objects on the table:
  PinMAMETimer : Timer object
  PulseTimer   : Timer object


Available classes:
------------------

cvpmDictionary (Must usually not be used directly, also deprecated as just a simple wrapper nowadays)

cvpmTimer (Object = vpmTimer)
  (Public)  .PulseSwitch  - pulse switch and call callback after delay (default)
  (Public)  .PulseSw      - pulse switch
  (Public)  .AddTimer     - call callback after delay
  (Public)  .Reset        - Re-set all ballStacks
  (Friend)  .InitTimer    - initialise fast or slow timer
  (Friend)  .EnableUpdate - Add/remove automatic update for an instance
  (Private) .Update       - called from slow timer
  (Private) .FastUpdate   - called from fast timer
  (Friend)  .AddResetObj  - Add object that needs to catch reset

cvpmTrough (Create as many as needed)
  (Public) .IsTrough         - Get or Set whether this trough is the default trough (first trough sets this by default)
  (Public) .Size             - Get or Set total number of balls trough can hold
  (Public) .EntrySw          - Set switch number for trough entry (if any) - eg. Outhole
  (Public) .AddSw            - Assign a switch at a specific slot
  (Public) .InitSwitches     - Set trough switches using an array, from exit slot back toward entrance.
  (Public) .InitExit         - Setup exit kicker, force and direction
  (Public) .InitExitVariance - Modify exit kick direction and force (+/-, min force = 1)
  (Public) .InitEntrySounds  - Sounds to play when a ball enters the trough
  (Public) .InitExitSounds   - Sounds to play when the exit kicker fires
  (Public) .CreateEvents     - Auto-generate hit events for VP entry kicker(s) associated with this trough
  (Public) .MaxBallsPerKick  - Set maximum number of balls to kick out (default 1)
  (Public) .MaxSlotsPerKick  - Set maximum slots from which to get balls when kicking out (default 1)
  (Public) .Balls            - Get current balls in trough, or set initial number of balls in trough
  (Public) .BallsPending     - Get number of balls waiting in trough entry
  (Public) .Reset            - Reset and update all trough switches
  (Friend) .Update           - Called from vpmTimer to update ball positions and switches
  (Public) .AddBall          - Add a ball to the trough from a kicker.  If kicker is the exit kicker, stacks ball at exit.
  (Public) .SolIn            - Solenoid handler for entry solenoid
  (Public) .SolOut           - Solenoid handler for exit solenoid

cvpmSaucer (Create as many as needed)
  (Public) .InitKicker       - Setup main kicker, switch, exit direction and force (including Z force)
  (Public) .InitExitVariance - Modify kick direction and force (+/-, min force = 1)
  (Public) .InitAltKick      - Set alternate direction and force (including Z force) - for saucers with two kickers
  (Public) .InitSounds       - Sounds to play when a ball enters the saucer or the kicker fires
  (Public) .CreateEvents     - Auto-generate hit event for VP kicker(s) associated with this saucer
  (Public) .AddBall          - Add a ball to the saucer from a kicker.
  (Public) .HasBall          - True if the saucer is occupied.
  (Public) .solOut           - Fire the primary exit kicker.  Ejects ball if one is present.
  (Public) .solOutAlt        - Fire the secondary exit kicker.  Ejects ball with alternate forces if present.

cvpmBallStack (DEPRECATED/LEGACY, but create as many as needed)
  (Public) .InitSw        - init switches used in stack
  (Public) .InitSaucer    - init saucer
  (Public) .InitNoTrough  - init a single ball, no trough handler
  (Public) .InitKick      - init exit kicker
  (Public) .InitAltKick   - init second kickout direction
  (Public) .CreateEvents  - Create addball events for kickers
  (Public) .KickZ         - Z axis kickout angle (radians)
  (Public) .KickBalls     - Maximum number of balls kicked out at the same time
  (Public) .KickForceVar  - Initial ExitKicker Force value varies by this much (+/-, minimum force = 1)
  (Public) .KickAngleVar  - ExitKicker Angle value varies by this much (+/-)
  (Public) .BallColour    - Set ball colour
  (Public) .TempBallImage - Set ball image for next ball only
  (Public) .TempBallColour - Set ball colour for next ball only
  (Public) .BallImage     - Set ball image
  (Public) .InitAddSnd    - Sounds when ball enters stack
  (Public) .InitEntrySnd  - Sounds for Entry kicker
  (Public) .InitExitSnd   - Sounds for Exit kicker
  (Public) .AddBall       - add ball in "kicker" to stack
  (Public) .SolIn         - Solenoid handler for entry solenoid
  (Public) .EntrySol_On   - entry solenoid fired
  (Public) .SolOut        - Solenoid handler for exit solenoid
  (Public) .SolOutAlt     - Solenoid handler for exit solenoid 2nd direction
  (Public) .ExitSol_On    - exit solenoid fired
  (Public) .ExitAltSol_On - 2nd exit solenoid fired
  (Public) .Balls         - get/set number of balls in stack (default)
  (Public) .BallsPending  - get number of balls waiting to come in to stack
  (Public) .IsTrough      - Specify that this is the main ball trough
  (Public) .Reset         - reset and update all ballstack switches
  (Friend) .Update        - Update ball positions (from vpmTimer class)
 Obsolete
  (Public) .SolExit       - exit solenoid handler
  (Public) .SolEntry      - Entry solenoid handler
  (Public) .InitProxy     - Init proxy switch

cvpmNudge (Object = vpmNudge)
  Hopefully we can add a real pendulum simulator in the future
  (Public)  .TiltSwitch   - Set tilt switch
  (Public)  .Senitivity   - Set tiltsensitivity (0-10)
  (Public)  .TiltObj      - Set objects affected by tilt
  (Public)  .DoNudge dir,power  - Nudge table
  (Public)  .SolGameOn    - Game On solenoid handler
  (Private) .Update       - Handle tilting

cvpmDropTarget (create as many as needed)
  (Public)  .InitDrop     - initialise DropTarget bank
  (Public)  .CreateEvents - Create Hit events
  (Public)  .InitSnd      - sound to use for targets
  (Public)  .AnyUpSw      - Set AnyUp switch
  (Public)  .AllDownSw    - Set all down switch
  (Public)  .AllDown      - All targets down?
  (Public)  .Hit          - A target had been hit
  (Public)  .SolHit       - Solenoid handler for dropping a target
  (Public)  .SolUnHit     - Solenoid handler for raising a target
  (Public)  .SolDropDown  - Solenoid handler for Bank down
  (Public)  .SolDropUp    - Solenoid handler for Bank reset
  (Public)  .DropSol_On   - Reset target bank
  (Friend)  .SetAllDn     - check alldown & anyup switches

cvpmMagnet (create as many as needed)
  (Public)  .InitMagnet   - initialise magnet
  (Public)  .CreateEvents - Create Hit/Unhit events
  (Public)  .Solenoid     - Set solenoid that controls magnet
  (Public)  .GrabCenter   - Magnet grabs ball at center
  (Public)  .MagnetOn     - Turn magnet on and off
  (Public)  .X            - Move magnet
  (Public)  .Y            - Move magnet
  (Public)  .Strength     - Change strength
  (Public)  .Size         - Change magnet reach
  (Public)  .AddBall      - A ball has come within range
  (Public)  .RemoveBall   - A ball is out of reach for the magnet
  (Public)  .Balls        - Balls currently within magnets reach
  (Public)  .AttractBall  - attract ball to magnet
  (Private) .Update       - update all balls (called from timer)
  (Private) .Reset        - handle emulation reset
 Obsolete
  (Public)  .Range        - Change magnet reach

cvpmTurnTable (create as many as needed)
  (Public)  .InitTurnTable - initialise turntable
  (Public)  .CreateEvents  - Create Hit/Unhit events
  (Public)  .MaxSpeed      - Maximum speed
  (Public)  .SpinUp        - Speedup acceleration
  (Public)  .SpinDown      - Retardation
  (Public)  .Speed         - Current speed
  (Public)  .MotorOn       - Motor On/Off
  (Public)  .SpinCW        - Control direction
  (Public)  .SolMotorState - Motor on/off solenoid handler
  (Public)  .AddBall       - A ball has come withing range
  (Public)  .RemoveBall    - A ball is out of reach for the magnet
  (Public)  .Balls         - Balls currently within magnets reach
  (Public)  .AffectBall    - affect a ball
  (Private) .Update        - update all balls (called from timer)
  (Private) .Reset         - handle emulation reset

cvpmMech (create as many as needed)
  (Public)  .Sol1, Sol2    - Controlling solenoids
  (Public)  .MType         - type of mechanics
  (Public)  .Length, Steps
  (Public)  .Acc, Ret      - Acceleration, retardation
  (Public)  .AddSw         - Automatically controlled switches
  (Public)  .AddPulseSw    - Automatically pulsed switches
  (Public)  .Callback      - Update graphics function
  (Public)  .Start         - Start mechanics handler
  (Public)  .Position      - Current position
  (Public)  .Speed         - Current Speed
  (Private) .Update
  (Private) .Reset

cvpmCaptiveBall (create as many as needed)
  (Public)  .InitCaptive  - Initialise captive balls
  (Public)  .CreateEvents - Create events for captive ball
  (Public)  .ForceTrans   - Amount of force tranferred to captive ball (0-1)
  (Public)  .MinForce     - Minimum force applied to the ball
  (Public)  .NailedBalls  - Number of "nailed" balls infront of captive ball
  (Public)  .RestSwitch   - Switch activated when ball is in rest position
  (Public)  .Start        - Create moving ball etc.
  (Public)  .TrigHit      - trigger in front of ball hit (or unhit)
  (Public)  .BallHit      - Wall in front of ball hit
  (Public)  .BallReturn   - Captive ball has returned to kicker
  (Private) .Reset

cvpmVLock (create as many as needed)
  (Public)  .InitVLock    - Initialise the visible ball stack
  (Public)  .ExitDir      - Balls exit angle (like kickers)
  (Public)  .ExitForce    - Force of balls kicked out
  (Public)  .KickForceVar - Vary kickout force
  (Public)  .InitSnd      - Sounds to make on kickout
  (Public)  .Balls        - Number of balls in Lock
  (Public)  .SolExit      - Solenoid event
  (Public)  .CreateEvents - Create events needed
  (Public)  .TrigHit      - called from trigger hit event
  (Public)  .TrigUnhit    - called from trigger unhit event
  (Public)  .KickHit      - called from kicier hit event

cvpmDips (create as many as needed) => (Dip Switch And/Or Table Options Menu)
  (Public)  .AddForm       - create a form (AKA dialogue)
  (Public)  .AddChk        - add a chckbox
  (Public)  .AddChkExtra   -   -  "" -     for non-dip settings
  (Public)  .AddFrame      - add a frame with checkboxes or option buttons
  (Public)  .AddFrameExtra -  - "" - for non-dip settings
  (Public)  .AddLabel      - add a label (text string)
  (Public)  .ViewDips      - Show form
  (Public)  .ViewDipsExtra -  - "" -  with non-dip settings

cvpmImpulseP (create as many as needed) => (Impulse Plunger Object using a Trigger to Plunge Manual/Auto)
  (Public)  .InitImpulseP - Initialise Impulse Plunger Object (Trigger, Plunger Power, Time to Full Plunge [0 = Auto])
  (Public)  .CreateEvents - Create Hit/Unhit events
  (Public)  .Strength     - Change plunger strength
  (Public)  .Time         - Change plunger time (in seconds) to full plunger strength (0 = Auto Plunger)
  (Public)  .Pullback     - Pull the plunger back
  (Public)  .Fire         - Fires / Releases the Plunger (Manual or Auto depending on Timing Value given)
  (Public)  .AutoFire     - Fires / Releases the Plunger at Maximum Strength +/- Random variation (i.e. Instant Auto)
  (Public)  .Switch       - Switch Number to activate when ball is sitting on plunger trigger (if any)
  (Public)  .Random       - Sets the multiplier level of random variance to add (0 = No Variance / Default)
  (Public)  .InitEntrySnd - Plays Sound as Plunger is Pulled Back
  (Public)  .InitExitSnd  - Plays Sound as Plunger is Fired (WithBall,WithoutBall)

cvpmFlips2 (Fast Flips support)
 Must not be used directly
 
Generic solenoid handlers:
--------------------------
vpmSolFlipper flipObj1, flipObj2          - "flips flippers". Set unused to Nothing
vpmSolFlip2   flipObj1, flipObj2, flipSpeedUp, flipSpeedDn, sndOn).  Set unused to Nothing
vpmSolDiverter divObj, sound              - open/close diverter (flipper) with/without sound
vpmSolWall wallObj, sound                 - Raise/Drop wall with/without sound
vpmSolToggleWall wall1, wall2, sound      - Toggle between two walls
vpmSolToggleObj obj1,obj2,sound           - Toggle any objects
vpmSolAutoPlunger plungerObj, var, enabled - Autoplunger/kickback
vpmSolAutoPlungeS plungerObj, sound, var, enabled - Autoplunger/kickback With Specified Sound To Play
vpmSolGate obj, sound                     - Open/close gate
vpmSolSound sound                         - Play sound only
vpmFlasher flashObj                       - Flashes flasher

Generating events:
------------------
vpmCreateEvents
cpmCreateLights

Variables declared (to be filled in):
---------------------------------------
SolCallback() - handler for each solenoid
Lights()      - Lamps

Constants used (must be defined):
---------------------------------
UseSolenoids  - Update solenoids
MotorCallback - Called once every update for mechanics or custom sol handler
UseLamps      - Update lamps
LampCallback  - Sub to call after lamps are updated
                (or every update if UseLamps is false)
GICallback    - Sub to call to update GI strings
GICallback2   - Sub to call to update GI strings
SFlipperOn    - Flipper activate sound
SFlipperOff   - Flipper deactivate sound
SSolenoidOn   - Solenoid activate sound
SSolenoidOff  - Solenoid deactivate sound
SCoin         - Coin Sound
ExtraKeyHelp  - Game specific keys in help window

Exported variables:
-------------------
vpmTimer      - Timer class for PulseSwitch etc
vpmNudge      - Class for table nudge handling
