Monthly Archives: February 2013

Starting Disaster Compiler

I came to the realization a couple weekends ago that I needed to write a compiler.  I was hoping to avoid it by simply reducing the type of commands that the pinball machine could run, but I keep coming back to the issue that I want this to be a generic pinball driving machine.  That being said, the pinball rule set must be able to handle all sorts of different instructions.  Some of the instructions will be high-bred instructions to make writing pinball rules easier for users, but many will simply be math like instructions.  I’ve spent a good deal of time trying to come up with a good number of these high-bred instructions, and a good amount of time on the architecture of the rules file.  I will eventually write a document on writing a pinball rules file, but doing a first cut for my simple pinball machine has really helped to make the ideas concrete.

Here is a link to the current rules file  (I’ll point this out so that people can find it more easily and not need to download the whole code base):

http://code.google.com/p/open-pinball-project/source/browse/trunk/Eclipse/1009-HostCtl/rules/simplerules.txt

The first section of the file is simply stating what hardware needs to exist for the pinball machine and names each of the solenoids, inputs, and LEDs.  This is so each used hardware pin can be identified by name.  Next section is variables and indexed variables.  This is going to be implemented as a simple array of integers with the dictionary (keyed off the name) handing back the offset into the array.  Next sections are sound and video clips.  These will be pre-allocated so they can quickly be switched between or even play multiple sounds at once.

The next section contains the processing chains.  This is the section that requires a compiler.  The input pins named in the above sections can be used to alter the operation of the machine.

A simple example would be kicking the ball into the shooter lane.  While it would be easiest to kick the solenoid, and just hope that the ball got onto the playfield, it might not necessarily happen.  The solenoid might not be working properly.  One way to deal with this is to kick the solenoid and check the switch if a ball shows up in the shooter lane (one of the input switches).  At the same time, if the ball doesn’t show up, you want to try to kick the ball another few times just in case the issue fixes itself.   (Maybe two of the balls were interfering with each other, or maybe the solenoid was a little sticky, and a second kick would work.)  If the maximum number of retries is exceeded, the pinball machine should display an error and not allow anybody else to put more money in the machine.  This simple action of the pinball shows that it needs to support timers, math functions (incrementing the retry count), comparisons, and reading switch inputs during the loop.  The process chains that implement this are Proc_Start_Ball_Init and Proc_Start_Ball_Start.  The init function is run once when a mode is entered, while the start routine is run after each tick.  At the end of this chain, the pinball machine will move to the Mode_Ball_In_Play or Mode_Error.

I originally thought that I could implement this with a simplified amount of functions, but during writing the rules file, I found it was much easier to assume that I had that ability to use anything that is available to me in any normal language.  That means that it is time to write a simple compiler.  (Luckily it is only the top end of the compiler to convert command lines into pseudo-code.  I don’t need to write the bottom end of the compiler.  Of course, if I would write the bottom half of the compiler, it would be much faster, but then I would need the parser to create code and then compile the generated code.  I currently believe it will be fast enough without doing this last step, but it is arguable that it would be a cleaner design using self generated code.)

This has taught me not to laugh at my friends when they were taking compiler theory in college, while I was taking fields and waves.  Maybe I should have taken it as an elective.  Somebody on the web wrote a article about how a pinball machine is the ultimate renaissance man machine.  It requires electrical engineering, mechanical engineering, graphics design, animation, and computer science disciplines.  I have certainly enjoyed the strange paths that it has taken me and allowed me to probe some new areas that I was not expecting.

Anyhow, there are also high-bred commands.  An example would be the LED_ROT_RIGHT/LED_ROT_LEFT commands.  These commands are very useful for implementing the “change lane” function.  In most modern pinball machines, when you hit the right flipper, the inlanes, or outlanes lights rotate to the right so that it makes it easier to complete all of the lights.  The left flipper sometimes does the same thing to the left.  (It actually freaks me out when playing early 70s machines where you actually have to shoot accurately instead of just rotating the lights to complete a set of lights.)  In the pinball machine, hitting the right flipper simple rotates the subset of lights.  The high-bred command rotates the group by using the LED_ROT_xxxx command, then providing the mask of bits to rotate, and the variable containing the currently lit bits.  The Proc_Flipper chain does this processing.  It is a high-bred command because it does a lot processing beneath the command, but the user just has to write a simple upper layer command to get it to happen.

If anybody has any comments on what they would need in a rules file, I would be glad to hear them.  Once the framework is finished, it will be simple to add more commands, but suggestions would be appreciated to make sure that I don’t miss major functionality that is required.  It is always best to plan for major features at the start to make sure that the architecture supports them.

Java, java, java and working on the language

So I drew up a simple pinball machine to verify the scripting language is working.  I always find it easier to try and implement a real example to make sure I have most of the functionality that I need to implement a machine.  Hopefully when you click on the picture, you can see enough of the writing to understand what I’m trying to do.

SimplePinballImage

Simple Pinball machine from three test cards

I populated three of the cards (a solenoid driver, an input card, and an LED driver card).  Here is the quick pinball machine that I drew up to make sure that the machine could be implemented with the “generic” scripting language.  I’ve spent the last few days trying to write up the script for this machine to make sure that I have everything that I need.

If you currently grab the newest stuff from the repository, the java code resides under the Eclipse directory.  VLC needs to be installed on the base machine, and in the build_notes.txt file it lists the flags that need to be handed into the VM and handed to the base class to start the pinball application.  Right now it simply runs two different movies, one after the other and repeats.  If you press the ‘s’ key, it swaps to the other movie.  If you press the ‘x’ key, it exits.  I did this to verify that I could swap between movies quickly enough during game play.  I’m happy with the response on my PC (which isn’t the zippiest in the world), but I’m pretty sure it will work well enough on the real hardware.  I will eventually put this all together in a single application.

The script file that I’m working on is named simplerules.txt.  I’m still adding functionality to the script language, but I’m pretty happy with how it is coming out.  Here is some general information about how it will work.

The scripting file is broken down into a couple different areas:  hardware identification,    variables,  modes,  and chains.  (Actually after popping it open, I need to convert all the tabs to spaces to make it look a lot more readable.)  I’ve made all keywords capitals.   (These are reserved words for the scripting  itself.)

Hardware identifies the number of cards in the system, their configurations, and the names used to refer to each of the hardware bits.

Variables are broken down to single variables (one per pinball machine) and indexed variables.  A good example of an indexed variable is the player’s score in a multi-player game.

Modes are the states of the pinball state machine.  When playing a game, the controller moves between these states and does things differently for each state.  One state might be attract mode which tries to get people to add coins.  Another mode would be press start mode which happens after they add credits.  Then of course there are tons of different modes when a game is being played depending if you are in a multi-ball mode, or a special scoring mode.  These are highly dependent on the game rule set.

Chains are processing chains.  They can alter the mode if something happens, or change LEDs on off, etc.  I’m planning on having multiple chains per mode.  These chains are the init chain, processing chain, video chain, audio chain, and LED chain.  The init chain happens once when the mode is entered.  The processing chain happens every tick (approx 10 or 20 ms).  The video chain allows videos to be streamed during each mode.  (Multiple videos can be in a chain, so it will play one, then the next, then the next, and repeat that chain.)  The audio chain allows songs to be streamed.  The LED chain allows a series of LEDs in a certain sequence.  All attract modes use something like this, and most modes like multi-ball would use something like this.

Well that is the idea behind the script.  Hopefully by the end of the weekend, I will have finished the rule-set for the simple pinball machine.  Next would be coding the java which shouldn’t be that hard, but will probably take a couple weeks.