That does not mean we won't try to provide a solution for that: we think the main problem is related to multiscreen/multicards/vsync (for example, try to get all of your screen at the same refresh rate, aka 60Hz).
Wouldnt be directb2s a solution for the cabs ? Unit is only doing the playfield and the backglass is done by directb2s ? Then you also have a solution for dof since db2s is calling dof ..
Bout the lights. It would be nice to have some info how much lights really needed on the tables since its a performance eater
Correct: performance is the main reason why we finally want to support B2S: DOF comes of course with it (but we then depend on it for output and cannot create our owns).
Correct also about lights: the slider should be updated. Moreover, we should provide ways to setup a light as "important" (per pixel computation) or "not important" (per vertex computation): note that this is already doable by script...
Billbox , Lou
Can you give us any more info about original game building?
From what I can gather atm I can't run a FP table without having the script enable pinmame. Everyone has their different uses for programs but for me (and probably a few others) we basicaly would love a FP but with good physics. Which is in a nutshell what this is, plus a lot more. Not to say I don't care about playing recreations but I personally am not bothered, I'd rather play real tables.
- Scripting Documentation
=> 
Haha, script doc is a huge task, even if of course we already did it on the way. I saw with peepi for UltraDMD support for original table, this will come later. To start scripting an original table, just change the main class inheritance in your script from "BxVPMTableManager" to "BxTableManager": VPM will then not be launched
. We should provide you at least our script for "test" table which does not use VPM. Here is a very dirty version of it:
using UnityEngine;
using System.Collections;
public class Script
{
public void Init()
{
GameObject table = GameObject.Find("TABLE");
test_TableManager behaviour = table.AddComponent<test_TableManager>();
behaviour.PreInit(); // Call pre-initialization steps
behaviour.Init(); // Script initialization
behaviour.PostInit(); // Call poste-initialization steps
}
}
public class test_TableManager : BxTableManager
{
//////////////////////////////////////////////////////////////
///////////////////// DropTarget4 dropped ?///////////////////
public bool dt41=false;
public bool dt42=false;
public bool dt43=false;
public bool dt44=false;
public bool dt45=false;
public bool dt46=false;
/////////////////////////////////////////////////////////////////////////////////////////
// Unity Callback Functions
bool m_autokick = true;
//! Use this for initialization
public override void Init ()
{
base.Init(); // Call BxVPMTableManager Start (Display version and default controller options
InitArrays(255,255,10,255); // 89 Lamps, 65 Solenoids/Flashers (10 by default for GIs) and 255 Switches...)
SetDMDObject("DMD","BxVPMDMD"); // Link the Vpm driven Dmd Update Component to the object "DMD"
InitSubwaySystem(); // Initialize Subway System
AddPlungerBehaviour("Plunger"); // Add plunger behaviour
BxBumperKick.s_AutoKickBumperMode = true; // Bumpers automatically kick
GameObject ball=GameObject.Find("Shop/ball");
ball.renderer.material.mainTexture=Resources.Load("BITMAP/amigaball") as Texture;////affect amigaball
ball.renderer.material.color=Color.white; //// so that amigaball can be seen
GameObject vari1=GameObject.Find("VariTargets/TargetVari1");
if(vari1!=null)
{
BxVariTarget v1behaviour=vari1.AddComponent<BxVariTarget>();
v1behaviour.Init(0);
}
GameObject vari2=GameObject.Find("VariTargets/TargetVari2");
if(vari2!=null)
{
BxVariTarget v2behaviour=vari2.AddComponent<BxVariTarget>();
v2behaviour.Init(0);
}
GameObject vari3=GameObject.Find("VariTargets/TargetVari3");
if(vari3!=null)
{
BxVariTarget v3behaviour=vari3.AddComponent<BxVariTarget>();
v3behaviour.Init(0);
}
}
//! Initialize table driver
public override void InitDriver()
{
m_driver = new BxDriver_wpc();
}
public override void LateUpdate ()
{
base.LateUpdate();
if(Input.GetKeyDown(KeyCode.K))
{
// BxKicker kicker = (BxKicker)GameObject.Find ("TABLE/Kickers/PlungerKicker").GetComponent("BxKicker");
// kicker.EjectBall();
SetSolenoid(4, true); // todo => switch off (will not work when not using changedSolenoidsCallback)
try
{
for(int i=1;i<=10;i++)
GameObject.Find("Kickers/Kicker"+i).GetComponent<BxKicker>().EjectBall();
}catch{}
}
if(Input.GetKeyDown(KeyCode.L))
{
m_autokick = !m_autokick;
if(m_autokick)
{
SetSolenoid(2, true);
SetSolenoid(3, true);
}
}
////////////////////// Testif all DropTarget4 ar dropped
testDT4();
}
//! Initialize Subway System (redefinition)
public override void InitSubwaySystem()
{
// Getting Objects
base.InitSubwaySystem();
GameObject subway = GameObject.Find ("TABLE/SUBWAY");
if(subway==null)
{
Debug.LogError("Unable to find SUBWAY object");
return;
}
BxSwManager subManager = (BxSwManager)subway.GetComponent("BxSwManager");
if(subManager==null) subManager = (BxSwManager)subway.GetComponent("BxSwVisualManager");
if(subManager==null)
{
Debug.LogError("Unable to find the Subway manager component in SUBWAY object");
return;
}
//////////////////////////////////////////////////////////////////////////////
// Subway System building
float swL = Global.Physics.g_BallDiameter; // length of switches in mm
// Main through
BxSwNode drain = subManager.AddEntrance("Drain",5); // Main drain node used as subway entrance
BxSwNode pkick = subManager.AddExit("PlungerKicker",4); // Exit plunger kicker Node
pkick.m_swicthSlot = 52; // Node switch number
BxSwEdge mainThrough = subManager.LinkNodes(drain,pkick,1.5f); // main Through edge link (1.5 seconds for a ball to cross it)
mainThrough.AddSwitch(50, mainThrough.m_length-swL*1.5f, swL*0.9f); // First switch on the edge
mainThrough.AddSwitch(51, mainThrough.m_length-swL*0.5f , swL*0.9f); // Second switch on the edge (making 3 in total with the pkick node switch)
try
{
// Diverter system
BxSwNode n1 = subManager.AddEntrance("Kicker1",1); // Top kicker used as subway entrance
BxSwNode n2 = subManager.AddExit("Kicker2",2); // Left kicker node (subway exit)
n2.m_swicthSlot = 40;
BxSwNode n3 = subManager.AddExit("Kicker3",3); // Right kicker node (subway exit)
n3.m_swicthSlot = 41;
BxSwDiverterNode mid = subManager.AddNode<BxSwDiverterNode>("Middle",0.0f,1); // Diverter central node
mid.m_swicthSlot = 42;
mid.m_solenoidSlot = 6; // Solenoid slot activating the diverter
mid.m_position = new Vector3(-235.5f,(n1.m_position.y + n2.m_position.y)*0.5f,504.6607f);
BxSwEdge e1 = subManager.LinkNodes(n1,mid,1.0f); // First edge (from entrance to diverter)
// 3 siwtches on the edge (linked to lights
e1.AddSwitch(11, swL*0.5f, swL);
e1.AddSwitch(12, e1.m_length * 0.5f - swL*0.5f, swL);
e1.AddSwitch(13, e1.m_length-swL*1.5f, swL);
BxSwEdge e2 = subManager.LinkNodes(mid,n2,1.0f); // Left edge (from diverter to left kicker)
// 3 siwtches on the edge (linked to lights
e2.AddSwitch(21, swL*0.5f, swL);
e2.AddSwitch(22, e2.m_length * 0.5f - swL*0.5f, swL);
e2.AddSwitch(23, e2.m_length-swL*1.5f, swL);
BxSwEdge e3 = subManager.LinkNodes(mid,n3,1.0f); // Right edge (from diverter to right kicker)
// 3 siwtches on the edge (linked to lights
e3.AddSwitch(31, swL*0.5f, swL);
e3.AddSwitch(32, e3.m_length * 0.5f - swL*0.5f, swL);
e3.AddSwitch(33, e3.m_length-swL*1.5f, swL);
}catch
{
}
try{
BxSwNode saucer = subManager.AddEntrance("Kicker10",70,false);
saucer = subManager.AddExit("Kicker10",70,0.0f);
}catch{
}
// build the subway system
subManager.Build();
// Insert 10 balls in the main through
for(int i=0;i<10;i++)
{
BxSwVirtualBall b = new BxSwVirtualBall();
drain.InsertBall(b);
subManager.ReportNewBall(b);
subManager.DoStep();
}
SetSolenoid(90, true);
SetSolenoid(91, true);
SetSolenoid(92, true);
}
//! Link lamp array to Unity objects (called by InitArrays)
public override void InitLampsObjects()
{
base.InitLampsObjects(); // call ancestor's function
// Test scene By BilboX
// ---------------------------------------------------------------
AddLamp("Bulb1",11); // common 1
AddLamp("Bulb2",12); // common 2
AddLamp("Bulb3",13); // common 3
AddLamp("Light1",21); // left 1
AddLamp("Light2",22); // left 2
AddLamp("Light3",23); // left 3
AddLamp("Light4",31); // right 1
AddLamp("Light5",32); // right 2
AddLamp("Light6",33); // right 3
AddLamp ("ShootAgainLight",73); // Shoot Again
AddLamp("Bumper1" , 61,"BxBumperLamp");
AddLamp("Bumper2" , 62,"BxBumperLamp");
AddLamp("Bumper3" , 63,"BxBumperLamp");
AddLamp("Bumper4" , 64,"BxBumperLamp");
AddLamp("Bumper5" , 65,"BxBumperLamp");
AddLamp("Bumper6" , 66,"BxBumperLamp");
AddLamp("Bumper7" , 67,"BxBumperLamp");
AddLamp("Bumper8" , 68,"BxBumperLamp");
}
//! Link solenoid array to Unity objects (called by InitArrays)
public override void InitSolenoidsObjects()
{
base.InitSolenoidsObjects(); // call ancestor's function
AddSolenoid("Kicker1" , 1,"BxKicker");
AddSolenoid("Kicker2" , 2,"BxKicker");
AddSolenoid("Kicker3" , 3,"BxKicker");
AddSolenoid("Kicker4" , 3,"BxKicker");
AddSolenoid("Kicker5" , 3,"BxKicker");
AddSolenoid("Kicker6" , 3,"BxKicker");
AddSolenoid("Kicker7" , 3,"BxKicker");
AddSolenoid("Kicker8" , 3,"BxKicker");
AddSolenoid("Kicker9" , 3,"BxKicker");
AddSolenoid("Kicker10" , 3,"BxKicker");
/* AddSolenoid("PlungerKicker" , 4,"BxKicker"); // Ball release
AddSolenoid("Drain" , 5,"BxKicker"); // Outhole
*/
AddSolenoid("Bumper1" , 61,"BxBumperKick");
AddSolenoid("Bumper2" , 62,"BxBumperKick");
AddSolenoid("Bumper3" , 63,"BxBumperKick");
AddSolenoid("Bumper4" , 64,"BxBumperKick");
AddSolenoid("Bumper5" , 65,"BxBumperKick");
AddSolenoid("Bumper6" , 66,"BxBumperKick");
AddSolenoid("Bumper7" , 67,"BxBumperKick");
AddSolenoid("Bumper8" , 68,"BxBumperKick");
AddSolenoid("LeftSlingshotRubber" , 80,"BxSlingshotKick");
AddSolenoid("RightSlingshotRubber" , 81,"BxSlingshotKick");
AddSolenoid("Rubber2" , 82,"BxSlingshotKick");
AddSolenoid("Rubber3" , 83,"BxSlingshotKick");
AddSolenoid("1", 90, "BxCoilMagnet");
AddSolenoid("2", 91, "BxCoilMagnet");
AddSolenoid("3", 92, "BxCoilMagnet");
////////////////// Testing DropTarget4
AddSolenoid("DropTarget4-1", 93, "BxDropTargetSolenoid");
AddSolenoid("DropTarget4-2", 93, "BxDropTargetSolenoid");
AddSolenoid("DropTarget4-3", 93, "BxDropTargetSolenoid");
AddSolenoid("DropTarget4-4", 93, "BxDropTargetSolenoid");
AddSolenoid("DropTarget4-5", 93, "BxDropTargetSolenoid");
AddSolenoid("DropTarget4-6", 93, "BxDropTargetSolenoid");
//! Flipper solenoid slots (all games => move into BxVPMTableManager????)
//! sLRFlipper = 46
//! sLLFlipper = 48
//! sURFlipper = 34
//! sULFlipper = 36
AddSolenoid("Flippers/RightFlipper" , 46, "BxBasicFlip"); // Right Flipper
AddSolenoid("Flippers/LeftFlipper" , 48, "BxBasicFlip"); // Left Flipper
}
//! Link solenoid array to Unity objects (called by InitArrays)
//! (Must be inherited and use AddSolenoid)
public override void InitSwitchesObjects()
{
base.InitSwitchesObjects(); // call ancestor's function
AddSwitchCallBack(70, TestSwitchCallBack);
AddSwitch("Target1", 41, "BxLeafTargetSwitch"); // Entrance
AddSwitch("Target2", 42, "BxLeafTargetSwitch"); // Entrance
AddSwitch("Target3", 43, "BxLeafTargetSwitch"); // Entrance
AddSwitch("Target4", 44, "BxLeafTargetSwitch"); // Entrance
AddSwitch("Target5", 45, "BxLeafTargetSwitch"); // Entrance
AddSwitch("Bumper1" , 61);
AddSwitch("Bumper2" , 62);
AddSwitch("Bumper3" , 63);
AddSwitch("Bumper4" , 64);
AddSwitch("Bumper5" , 65);
AddSwitch("Bumper6" , 66);
AddSwitch("Bumper7" , 67);
AddSwitch("Bumper8" , 68);
AddSwitch("LeftSlingshotRubber" , 80 ,"BxSlingshotSwitch");
AddSwitch("RightSlingshotRubber", 81 ,"BxSlingshotSwitch");
AddSwitch("Rubber2" , 82 ,"BxSlingshotSwitch");
AddSwitch("Rubber3" , 83 ,"BxSlingshotSwitch");
AddSwitch("DropTarget4-1" , 85 ,"BxDropTargetSwitch");
AddSwitch("DropTarget4-2" , 86 ,"BxDropTargetSwitch");
AddSwitch("DropTarget4-3" , 87 ,"BxDropTargetSwitch");
AddSwitch("DropTarget4-4" , 88 ,"BxDropTargetSwitch");
AddSwitch("DropTarget4-5" , 89 ,"BxDropTargetSwitch");
AddSwitch("DropTarget4-6" , 90 ,"BxDropTargetSwitch");
}
void TestSwitchCallBack(int slot, bool state)
{
Debug.Log ("Switch CallBack " + slot + (state?" On":" Off"));
}
//! ROM Simulation (from input signals to output actions)
public override void SetSwitch (int slot, bool state)
{
base.SetSwitch (slot, state);
switch(slot)
{
case 40: // Left exit kicker switch
if(m_autokick && state)
SetSolenoid(2, true); // Autokick (todo switch off)
break;
case 41: // Right exit kicker switch
if(m_autokick && state)
SetSolenoid(3, true); // Autokick (todo switch off)
break;
case 42: // Diverter switch
if(state)
SetSolenoid(6, !GetSolenoid(6)); // Change diverter solenoid state
break;
case 52: // Plunger Kicker switch
// if(state && GetSwitch(50) && GetSwitch(51))
// SetSolenoid(4, true); // todo switch off
break;
case 70:
if(state)
SetSolenoid(70,state);
break;
case 80:
case 81:
case 82:
case 83:
if(state)SetSolenoid(slot,state);break;
///////////////////////DropTarget 4
case 85: dt41=true;break;
case 86: dt42=true;break;
case 87: dt43=true;break;
case 88: dt44=true;break;
case 89: dt45=true;break;
case 90: dt46=true;break;
default:
if(slot<40)
SetLamp (slot,state); // Works as switch slot is the same as the lamps slots...
/* else
if(slot>=60 && slot <70) // Bumper
{
//if(state) SetLamp(slot,state);
SetSolenoid(slot,state);
}
*/
break;
}
}
//////////////////// Test if all DropTarget4 are dropped->then reset them
void testDT4()
{
if(dt41 & dt42 & dt43 & dt44 & dt45 & dt46)
{
SetSolenoid(93,true);
dt41=false;
dt42=false;
dt43=false;
dt44=false;
dt45=false;
dt46=false;
}
}
}
Please also note taht we did not used it a lot: I will improve API when making "Abracadabra" which does not have rom yet. Main lack is DMD/Segment LCD/ Mechanical counters... to come
.
Have fun decypher it waiting for doc 
EDIT: small hint for original tables:
We designed it to be "compatible" with VPM tables, aka with the same "architecture": Lamps/Solenoids/Gis/Switches slots. So, the same functions applyies, excpet these are not VPM driven but.. chepas driven
. Good luck!
Edited by BilboX, 24 February 2014 - 09:46 AM.