Option Explicit
'*****************************************************************************************************
' CREDITS
' Initial table created by fuzzel, jimmyfingers, jpsalas, toxie & unclewilly (in alphabetical order)
' Flipper primitives by zany
' Ball rolling sound script by jpsalas
' Ball shadow by ninuzzu
' Ball control by rothbauerw
' DOF by arngrim
' Positional sound helper functions by djrobx
' Plus a lot of input from the whole community (sorry if we forgot you :/)
'*****************************************************************************************************
'First, try to load the Controller.vbs (DOF), which helps controlling additional hardware like lights, gears, knockers, bells and chimes (to increase realism)
'This table uses DOF via the 'SoundFX' calls that are inserted in some of the PlaySound commands, which will then fire an additional event, instead of just playing a sample/sound effect
On Error Resume Next
ExecuteGlobal GetTextFile("controller.vbs")
If Err Then MsgBox "You need the Controller.vbs file in order to run this table (installed with the VPX package in the scripts folder)"
On Error Goto 0
'If using Visual PinMAME (VPM), place the ROM/game name in the constant below,
'both for VPM, and DOF to load the right DOF config from the Configtool, whether it's a VPM or an Original table
'Const cGameName = ""
If Table1.ShowDT = false then
Scoretext.Visible = false
End If
Dim EnableBallControl
EnableBallControl = false 'Change to true to enable manual ball control (or press C in-game) via the arrow keys and B (boost movement) keys
Const BallSize = 25 'Ball radius
Sub Table1_KeyDown(ByVal keycode)
If keycode = PlungerKey Then
Plunger.PullBack
PlaySound "plungerpull",0,1,AudioPan(Plunger),0.25,0,0,1,AudioFade(Plunger)
End If
If keycode = LeftFlipperKey Then
LeftFlipper.RotateToEnd
PlaySound SoundFX("fx_flipperup",DOFFlippers), 0, .67, AudioPan(LeftFlipper), 0.05,0,0,1,AudioFade(LeftFlipper)
End If
If keycode = RightFlipperKey Then
RightFlipper.RotateToEnd
PlaySound SoundFX("fx_flipperup",DOFFlippers), 0, .67, AudioPan(RightFlipper), 0.05,0,0,1,AudioFade(RightFlipper)
End If
If keycode = LeftTiltKey Then
Nudge 90, 2
End If
If keycode = RightTiltKey Then
Nudge 270, 2
End If
If keycode = CenterTiltKey Then
Nudge 0, 2
End If
' Manual Ball Control
If keycode = 46 Then ' C Key
If EnableBallControl = 1 Then
EnableBallControl = 0
Else
EnableBallControl = 1
End If
End If
If EnableBallControl = 1 Then
If keycode = 48 Then ' B Key
If BCboost = 1 Then
BCboost = BCboostmulti
Else
BCboost = 1
End If
End If
If keycode = 203 Then BCleft = 1 ' Left Arrow
If keycode = 200 Then BCup = 1 ' Up Arrow
If keycode = 208 Then BCdown = 1 ' Down Arrow
If keycode = 205 Then BCright = 1 ' Right Arrow
End If
End Sub
Sub Table1_KeyUp(ByVal keycode)
If keycode = PlungerKey Then
Plunger.Fire
PlaySound "plunger",0,1,AudioPan(Plunger),0.25,0,0,1,AudioFade(Plunger)
End If
If keycode = LeftFlipperKey Then
LeftFlipper.RotateToStart
PlaySound SoundFX("fx_flipperdown",DOFFlippers), 0, 1, AudioPan(LeftFlipper), 0.05,0,0,1,AudioFade(LeftFlipper)
End If
If keycode = RightFlipperKey Then
RightFlipper.RotateToStart
PlaySound SoundFX("fx_flipperdown",DOFFlippers), 0, 1, AudioPan(RightFlipper), 0.05,0,0,1,AudioFade(RightFlipper)
End If
'Manual Ball Control
If EnableBallControl = 1 Then
If keycode = 203 Then BCleft = 0 ' Left Arrow
If keycode = 200 Then BCup = 0 ' Up Arrow
If keycode = 208 Then BCdown = 0 ' Down Arrow
If keycode = 205 Then BCright = 0 ' Right Arrow
End If
End Sub
Sub playfield_mesh_Hit()
msgbox "ball has hit playfield"
end Sub
Sub Drain_Hit()
PlaySound "drain",0,1,AudioPan(Drain),0.25,0,0,1,AudioFade(Drain)
Drain.DestroyBall
BIP = BIP - 1
If BIP = 0 then
'Plunger.CreateBall
BallRelease.CreateBall
BallRelease.Kick 90, 7
PlaySound SoundFX("ballrelease",DOFContactors), 0,1,AudioPan(BallRelease),0.25,0,0,1,AudioFade(BallRelease)
BIP = BIP + 1
End If
End Sub
Dim BIP
BIP = 0
Sub Plunger_Init()
PlaySound SoundFX("ballrelease",DOFContactors), 0,1,AudioPan(BallRelease),0.25,0,0,1,AudioFade(BallRelease)
'Plunger.CreateBall
BallRelease.CreateBall
BallRelease.Kick 90, 7
BIP = BIP + 1
End Sub
Sub Gate_Hit
Kicker1.Kick 190, 10
End Sub
Sub Bumper1_Hit
PlaySound SoundFX("fx_bumper4",DOFContactors), 0,1,AudioPan(Bumper1),0,0,0,1,AudioFade(Bumper1)
B1L1.State = 1:B1L2. State = 1
Me.TimerEnabled = 1
End Sub
Sub Bumper1_Timer
B1L1.State = 0:B1L2. State = 0
Me.Timerenabled = 0
End Sub
Sub Bumper2_Hit
PlaySound SoundFX("fx_bumper4",DOFContactors), 0,1,AudioPan(Bumper2),0,0,0,1,AudioFade(Bumper2)
B2L1.State = 1:B2L2. State = 1
Me.TimerEnabled = 1
End Sub
Sub Bumper2_Timer
B2L1.State = 0:B2L2. State = 0
Me.Timerenabled = 0
End Sub
Sub Bumper3_Hit
PlaySound SoundFX("fx_bumper4",DOFContactors), 0,1,AudioPan(Bumper3),0,0,0,1,AudioFade(Bumper3)
B3L1.State = 1:B3L2. State = 1
Me.TimerEnabled = 1
End Sub
Sub Bumper3_Timer
B3L1.State = 0:B3L2. State = 0
Me.Timerenabled = 0
End Sub
Sub Bumper4_Hit
PlaySound SoundFX("fx_bumper4",DOFContactors), 0,1,AudioPan(Bumper4),0,0,0,1,AudioFade(Bumper4)
B4L1.State = 1:B4L2. State = 1
Me.TimerEnabled = 1
End Sub
Sub Bumper4_Timer
B4L1.State = 0:B4L2. State = 0
Me.Timerenabled = 0
End Sub
Sub Bumper5_Hit
PlaySound SoundFX("fx_bumper4",DOFContactors), 0,1,AudioPan(Bumper5),0,0,0,1,AudioFade(Bumper5)
B5L1.State = 1:B5L2. State = 1
Me.TimerEnabled = 1
End Sub
Sub Bumper5_Timer
B5L1.State = 0:B5L2. State = 0
Me.Timerenabled = 0
End Sub
Sub sw9_Hit
If L9.State = 1 then
L9.State = 0
else
L9.State = 1
end if
End Sub
Sub sw8_Hit
If L8.State = 1 then
L8.State = 0
else
L8.State = 1
end if
End Sub
Sub sw7_Hit
If L7.State = 1 then
L7.State = 0
else
L7.State = 1
end if
End Sub
Sub sw6_Hit
If L6.State = 1 then
L6.State = 0
else
L6.State = 1
end if
End Sub
'****Targets
Sub sw1_Hit
If L1.State = 1 then
L1.State = 0
else
L1.State = 1
end if
Me.TimerEnabled = 1
End Sub
Sub sw1_Timer
sw1.isDropped=0
Me.TimerEnabled = 0
End Sub
Sub sw2_Hit
If L2.State = 1 then
L2.State = 0
else
L2.State = 1
end if
Me.TimerEnabled = 1
End Sub
Sub sw2_Timer
sw2.isDropped=0
Me.TimerEnabled = 0
End Sub
Sub sw3_Hit
If L3.State = 1 then
L3.State = 0
else
L3.State = 1
end if
ME.TimerEnabled = 1
End Sub
Sub sw3_Timer
sw3.isDropped = 0
Me.TimerEnabled = 0
End Sub
Sub sw11_Hit
If L11.State = 1 then
L11.State = 0
else
L11.State = 1
end if
End Sub
Sub sw12_Hit
If L12.State = 1 then
L12.State = 0
else
L12.State = 1
end if
End Sub
Sub sw13_Hit
If L13.State = 1 then
L13.State = 0
else
L13.State = 1
end if
End Sub
Sub Kicker1_Hit
PlaySound "kicker_enter_center", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
'Plunger.CreateBall
PlaySound SoundFX("ballrelease",DOFContactors), 0,0.5,AudioPan(BallRelease),0.25,0,0,1,AudioFade(BallRelease)
BallRelease.CreateBall
BallRelease.Kick 90, 8
BIP = BIP +1
End Sub
Sub Kicker1_UnHit
PlaySound "popper_ball",0,.75,AudioPan(Kicker1),0.25,0,0,1,AudioFade(Kicker1)
End Sub
'*****GI Lights On
dim xx
For each xx in GI:xx.State = 1: Next
'**********Sling Shot Animations
' Rstep and Lstep are the variables that increment the animation
'****************
Dim RStep, Lstep
Sub RightSlingShot_Slingshot
PlaySound SoundFX("right_slingshot",DOFContactors), 0,1, 0.05,0.05 '0,1, AudioPan(RightSlingShot), 0.05,0,0,1,AudioFade(RightSlingShot)
RSling.Visible = 0
RSling1.Visible = 1
sling1.rotx = 20
RStep = 0
RightSlingShot.TimerEnabled = 1
gi1.State = 0:Gi2.State = 0
End Sub
Sub RightSlingShot_Timer
Select Case RStep
Case 3:RSLing1.Visible = 0:RSLing2.Visible = 1:sling1.rotx = 10
Case 4:RSLing2.Visible = 0:RSLing.Visible = 1:sling1.rotx = 0:RightSlingShot.TimerEnabled = 0:gi1.State = 1:Gi2.State = 1
End Select
RStep = RStep + 1
End Sub
Sub LeftSlingShot_Slingshot
PlaySound SoundFX("left_slingshot",DOFContactors), 0,1, -0.05,0.05 '0,1, AudioPan(LeftSlingShot), 0.05,0,0,1,AudioFade(LeftSlingShot)
LSling.Visible = 0
LSling1.Visible = 1
sling2.rotx = 20
LStep = 0
LeftSlingShot.TimerEnabled = 1
gi3.State = 0:Gi4.State = 0
End Sub
Sub LeftSlingShot_Timer
Select Case LStep
Case 3:LSLing1.Visible = 0:LSLing2.Visible = 1:sling2.rotx = 10
Case 4:LSLing2.Visible = 0:LSLing.Visible = 1:sling2.rotx = 0:LeftSlingShot.TimerEnabled = 0:gi3.State = 1:Gi4.State = 1
End Select
LStep = LStep + 1
End Sub
'*********************************************************************
' Positional Sound Playback Functions
'*********************************************************************
' Play a sound, depending on the X,Y position of the table element (especially cool for surround speaker setups, otherwise stereo panning only)
' parameters (defaults): loopcount (1), volume (1), randompitch (0), pitch (0), useexisting (0), restart (1))
' Note that this will not work (currently) for walls/slingshots as these do not feature a simple, single X,Y position
Sub PlayXYSound(soundname, tableobj, loopcount, volume, randompitch, pitch, useexisting, restart)
PlaySound soundname, loopcount, volume, AudioPan(tableobj), randompitch, pitch, useexisting, restart, AudioFade(tableobj)
End Sub
' Similar subroutines that are less complicated to use (e.g. simply use standard parameters for the PlaySound call)
Sub PlaySoundAt(soundname, tableobj)
PlaySound soundname, 1, 1, AudioPan(tableobj), 0,0,0, 1, AudioFade(tableobj)
End Sub
Sub PlaySoundAtBall(soundname)
PlaySoundAt soundname, ActiveBall
End Sub
'*********************************************************************
' Supporting Ball & Sound Functions
'*********************************************************************
Function AudioFade(tableobj) ' Fades between front and back of the table (for surround systems or 2x2 speakers, etc), depending on the Y position on the table. "table1" is the name of the table
Dim tmp
tmp = tableobj.y * 2 / table1.height-1
If tmp > 0 Then
AudioFade = Csng(tmp ^10)
Else
AudioFade = Csng(-((- tmp) ^10) )
End If
End Function
Function AudioPan(tableobj) ' Calculates the pan for a tableobj based on the X position on the table. "table1" is the name of the table
Dim tmp
tmp = tableobj.x * 2 / table1.width-1
If tmp > 0 Then
AudioPan = Csng(tmp ^10)
Else
AudioPan = Csng(-((- tmp) ^10) )
End If
End Function
Function Vol(ball) ' Calculates the Volume of the sound based on the ball speed
Vol = Csng(BallVel(ball) ^2 / 2000)
End Function
Function Pitch(ball) ' Calculates the pitch of the sound based on the ball speed
Pitch = BallVel(ball) * 20
End Function
Function BallVel(ball) 'Calculates the ball speed
BallVel = INT(SQR((ball.VelX ^2) + (ball.VelY ^2) ) )
End Function
'*****************************************
' rothbauerw's Manual Ball Control
'*****************************************
Dim BCup, BCdown, BCleft, BCright
Dim ControlBallInPlay, ControlActiveBall
Dim BCvel, BCyveloffset, BCboostmulti, BCboost
BCboost = 1 'Do Not Change - default setting
BCvel = 4 'Controls the speed of the ball movement
BCyveloffset = -0.01 'Offsets the force of gravity to keep the ball from drifting vertically on the table, should be negative
BCboostmulti = 3 'Boost multiplier to ball veloctiy (toggled with the B key)
ControlBallInPlay = false
Sub StartBallControl_Hit()
Set ControlActiveBall = ActiveBall
ControlBallInPlay = true
End Sub
Sub StopBallControl_Hit()
ControlBallInPlay = false
End Sub
Sub BallControlTimer_Timer()
If EnableBallControl and ControlBallInPlay then
If BCright = 1 Then
ControlActiveBall.velx = BCvel*BCboost
ElseIf BCleft = 1 Then
ControlActiveBall.velx = -BCvel*BCboost
Else
ControlActiveBall.velx = 0
End If
If BCup = 1 Then
ControlActiveBall.vely = -BCvel*BCboost
ElseIf BCdown = 1 Then
ControlActiveBall.vely = BCvel*BCboost
Else
ControlActiveBall.vely = bcyveloffset
End If
End If
End Sub
'*****************************************
' JP's VP10 Rolling Sounds
'*****************************************
Const tnob = 5 ' total number of balls
ReDim rolling(tnob)
InitRolling
Sub InitRolling
Dim i
For i = 0 to tnob
rolling(i) = False
Next
End Sub
Sub RollingTimer_Timer()
Dim BOT, b
BOT = GetBalls
' stop the sound of deleted balls
For b = UBound(BOT) + 1 to tnob
rolling(b) = False
StopSound("fx_ballrolling" & b)
Next
' exit the sub if no balls on the table
If UBound(BOT) = -1 Then Exit Sub
' play the rolling sound for each ball
For b = 0 to UBound(BOT)
If BallVel(BOT(b) ) > 1 AND BOT(b).z < 30 Then
rolling(b) = True
PlaySound("fx_ballrolling" & b), -1, Vol(BOT(b)), AudioPan(BOT(b)), 0, Pitch(BOT(b)), 1, 0, AudioFade(BOT(b))
Else
If rolling(b) = True Then
StopSound("fx_ballrolling" & b)
rolling(b) = False
End If
End If
Next
End Sub
'**********************
' Ball Collision Sound
'**********************
Sub OnBallBallCollision(ball1, ball2, velocity)
PlaySound("fx_collide"), 0, Csng(velocity) ^2 / 2000, AudioPan(ball1), 0, Pitch(ball1), 0, 0, AudioFade(ball1)
End Sub
'*****************************************
' ninuzzu's FLIPPER SHADOWS
'*****************************************
sub FlipperTimer_Timer()
FlipperLSh.RotZ = LeftFlipper.currentangle
FlipperRSh.RotZ = RightFlipper.currentangle
End Sub
'*****************************************
' ninuzzu's BALL SHADOW
'*****************************************
Dim BallShadow
BallShadow = Array (BallShadow1,BallShadow2,BallShadow3,BallShadow4,BallShadow5)
Sub BallShadowUpdate_timer()
Dim BOT, b
BOT = GetBalls
' hide shadow of deleted balls
If UBound(BOT)<(tnob-1) Then
For b = (UBound(BOT) + 1) to (tnob-1)
BallShadow(b).visible = 0
Next
End If
' exit the Sub if no balls on the table
If UBound(BOT) = -1 Then Exit Sub
' render the shadow for each ball
For b = 0 to UBound(BOT)
If BOT(b).X < Table1.Width/2 Then
BallShadow(b).X = ((BOT(b).X) - (Ballsize/6) + ((BOT(b).X - (Table1.Width/2))/7)) + 6
Else
BallShadow(b).X = ((BOT(b).X) + (Ballsize/6) + ((BOT(b).X - (Table1.Width/2))/7)) - 6
End If
ballShadow(b).Y = BOT(b).Y + 12
If BOT(b).Z > 20 Then
BallShadow(b).visible = 1
Else
BallShadow(b).visible = 0
End If
Next
End Sub
'************************************
' What you need to add to your table
'************************************
' a timer called RollingTimer. With a fast interval, like 10
' one collision sound, in this script is called fx_collide
' as many sound files as max number of balls, with names ending with 0, 1, 2, 3, etc
' for ex. as used in this script: fx_ballrolling0, fx_ballrolling1, fx_ballrolling2, fx_ballrolling3, etc
'******************************************
' Explanation of the rolling sound routine
'******************************************
' sounds are played based on the ball speed and position
' the routine checks first for deleted balls and stops the rolling sound.
' The For loop goes through all the balls on the table and checks for the ball speed and
' if the ball is on the table (height lower than 30) then then it plays the sound
' otherwise the sound is stopped, like when the ball has stopped or is on a ramp or flying.
' The sound is played using the VOL, AUDIOPAN, AUDIOFADE and PITCH functions, so the volume and pitch of the sound
' will change according to the ball speed, and the AUDIOPAN & AUDIOFADE functions will change the stereo position
' according to the position of the ball on the table.
'**************************************
' Explanation of the collision routine
'**************************************
' The collision is built in VP.
' You only need to add a Sub OnBallBallCollision(ball1, ball2, velocity) and when two balls collide they
' will call this routine. What you add in the sub is up to you. As an example is a simple Playsound with volume and paning
' depending of the speed of the collision.
Sub Pins_Hit (idx)
PlaySound "pinhit_low", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 0, 0, AudioFade(ActiveBall)
End Sub
Sub Targets_Hit (idx)
PlaySound "target", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 0, 0, AudioFade(ActiveBall)
End Sub
Sub Metals_Thin_Hit (idx)
PlaySound "metalhit_thin", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
End Sub
Sub Metals_Medium_Hit (idx)
PlaySound "metalhit_medium", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
End Sub
Sub Metals2_Hit (idx)
PlaySound "metalhit2", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
End Sub
Sub Gates_Hit (idx)
PlaySound "gate4", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
End Sub
Sub Spinner_Spin
PlaySound "fx_spinner", 0, .25, AudioPan(Spinner), 0.25, 0, 0, 1, AudioFade(Spinner)
End Sub
Sub Rubbers_Hit(idx)
dim finalspeed
finalspeed=SQR(activeball.velx * activeball.velx + activeball.vely * activeball.vely)
If finalspeed > 20 then
PlaySound "fx_rubber2", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
End if
If finalspeed >= 6 AND finalspeed <= 20 then
RandomSoundRubber()
End If
End Sub
Sub Posts_Hit(idx)
dim finalspeed
finalspeed=SQR(activeball.velx * activeball.velx + activeball.vely * activeball.vely)
If finalspeed > 16 then
PlaySound "fx_rubber2", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
End if
If finalspeed >= 6 AND finalspeed <= 16 then
RandomSoundRubber()
End If
End Sub
Sub RandomSoundRubber()
Select Case Int(Rnd*3)+1
Case 1 : PlaySound "rubber_hit_1", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
Case 2 : PlaySound "rubber_hit_2", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
Case 3 : PlaySound "rubber_hit_3", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
End Select
End Sub
Sub LeftFlipper_Collide(parm)
RandomSoundFlipper()
End Sub
Sub RightFlipper_Collide(parm)
RandomSoundFlipper()
End Sub
Sub RandomSoundFlipper()
Select Case Int(Rnd*3)+1
Case 1 : PlaySound "flip_hit_1", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
Case 2 : PlaySound "flip_hit_2", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
Case 3 : PlaySound "flip_hit_3", 0, Vol(ActiveBall), AudioPan(ActiveBall), 0, Pitch(ActiveBall), 1, 0, AudioFade(ActiveBall)
End Select
End Sub