The files in the common directory provide a library of generic pinball functions that can be reused from game to game. Some of the more important ones are described in detail in this chapter.
FreeWPC implements a weak form of coin switch handling. It is not very robust and does not time the coins as it should.
If FREE_ONLY is defined, it will build a ROM that doesn't require
coins.
This module tracks lit and collected extra balls. Lit extra balls can be easy (lit until end of game) or hard (lit only until end of ball).
In the machine config file, you should tag the lamp that indicates
an extra ball is lit as extra-ball, and the shoot again lamp
as shoot-again.  Then the lamps will automatically update for you
when these APIs are called.
     
light_easy_extra_balllight_hard_extra_balleb_light_adjustablecollect_extra_ballcan_award_extra_ballThere is also an API special_award to award a special, but
it does not manage any lamps automatically.  It just obeys the adjustment
to award whatever has been configured for special, and fires the knocker.
FreeWPC implements a tournament mode module. Note this is what newer Stern games refer to as competition mode.
Tournament mode can be enabled globally in the adjustments menu, or it can be enabled by holding down the left flipper button briefly before starting the game. A message will indicate that tournament mode has been enabled. It affects all players in the game.
Software should check the tournament_mode_enabled boolean variable
to determine if tournament is in effect.
Machines don't need to do much to produce a working ball search function. 
The common code knows how to pulse all of the regular solenoids. 
It also knows not to fire anything marked as a motor
or flasher. 
You can mark a solenoid in the machine description with nosearch
to ignore other solenoids as well.
   
Machines that need to handle a particular power driver in a non-standard
way (by using a template driver) should implement a ball_search
event handler, and mark the
associated solenoid as nosearch. 
The ball_search handlers will be called along with the automatic
pulsing.
   
For example, on Funhouse, the Rudy saucer eject needs to make sure that the mouth is open before kicking.
Solenoids associated with ball devices will be skipped unless they are empty, except after several ball searches have failed. The chase ball/lost ball recovery feature is also implemented and can be enabled by menu adjustment.
Game code can call ball_search_timeout_set to set the amount of
idle time that must expire before a ball search will occur.  The default
is 15 seconds.  The timer resets anytime a playfield switch (one marked
with the SW_PLAYFIELD flag) triggers.  You can also manually reset it
manually using ball_search_timer_reset.
Call knocker_fire to fire the knocker.  If a coin meter is attached
to the knocker coil, it will not be pulsed.  If the machine defines a sound
effect for knock, that will be played instead of pulsing a solenoid.
Adjustments are 8-bit variables kept in persistent storage. Each group of related adjustments is checksummed to verify integrity. Adjustments can be checked by just reading the variable; there is no special API to do so.
Machines can define their own feature adjustments in the machine config.
Audits are 16-bit variables kept in the non-volatile area of memory.  They
are generally incremented via the audit_increment API, which adds 1. 
They can also be incremented by an arbitrary value, via audit_add; or
they can be assigned via audit_assign.  They will not overflow if the
maximum value is reached, but instead will just stop counting up.
   
Machines can define their own feature audits in the machine config.
A global playfield multiplier is supported; use score_multiplier_set to
change it.  It is automatically set to 1 at the beginning of each ball.
   
Scores can be stated in two ways: as a 5-byte, binary-coded decimal value, or as an 8-bit "score code". The long values allow for arbitrary values up to 10 billion points. The short values are more compact and index a table of common score values, which are listed in the machine config.
The first set of APIs operate on arbitary BCD score buffers:
score_zeroscore_copyscore_addscore_subscore_mulscore_compareThe second group of APIs increment the current player's score by a fixed value.
scorescore_longscore_multiplescore(), but also takes a multiplier argument.  This multiplier
and the global score multiplier are taken into account. 
score_long_multiplescore_long and score_multiple.  This is the most
low-level API; all others ultimately call it. 
score_long_unmultipliedThe third group of APIs, called the ladder APIs, add score according to some rule.
A fixed ladder rule tracks the current value of a shot, and defines a base value, an increment, and a maximum value.
fixed_ladder_resetfixed_ladder_advancefixed_ladder_scorefixed_ladder_scorexfixed_ladder_score_and_advancefixed_ladder_scorex_and_advanceA lamp timer is a countdown timer which is tied to a playfield lamp. The amount of time remaining controls how fast the lamp flashes. When the timer reaches zero, the effect stops.
You declare a structure of type struct lamptimer_args, which
names the lamp and the initial timer value, in seconds.
   
The lamp is modified as part of an internally generated lamp effect (meaning that it behaves just like a leff, but it does not have a lamp effect ID); thus, the basic state of the lamp is retained. While the lamp timer runs, the basic state is overriden by the effect.
lamp_timer_startlamp_timer_findlamp_timer_stopThe score rank module is optional, based on the value of CONFIG_SCORE_RANK. 
When enabled, the system will
monitor the relative changes in players' scores over the course of a multi-
player game, and throw a rank_change event whenever the current player
moves into a new place.  It is up to each game to decide how to handle it.
To write a timed mode, you need to do two things:
First, create a structure of type struct timed_mode_ops and fill out
all of the required information.  Use the DEFAULT_MODE macro in the initializer
to set suitable values before declaring your own values.  The fields are:
     
GID. 
This field is mandatory and has no default.  When the mode is started, a task will be created with this group ID. 
system_timer_pause when the mode should pause for the "usual cases" only. 
Use null_false_function if the mode should not pause at all.  You can also
supply your own function if you need custom behavior. 
You must make sure that the structure and all of the functions that it references are in the same .c file, otherwise ROM paging will not work.
Second, handle several system events which affect the mode's operation:
timed_mode_music_refresh.music_refresh handler, passing it a pointer to the mode ops struct. 
timed_mode_display_update.display_update handler, passing it a pointer to the mode ops struct. 
From outside the mode itself, other modules call these APIs to interact with your mode. The mode ops struct is part of the public interface.
timed_mode_begintimed_mode_endtimed_mode_reset.timed_mode_add.timed_mode_get_timer.timed_mode_running_ptimed_mode_effect_running_ptimed_mode_device_running_pdevice_update
function. 
The ball serve module is the preferred API for adding balls to play. It uses the ball tracking APIs to program the ball trough, but adds support for autoplunging and multiball logic.
The system supports games with autoplungers or manual plungers. Auto launch support requires that the machine defines three things: the launch button switch, the launch solenoid, and a shooter switch.
The base API serve_ball simply kicks a ball out of the trough. 
It also resets the valid playfield flag and refreshes background effects. 
This is the same call made by the game state machine during start ball.
   
Use serve_ball_auto instead if you want the ball to be autolaunched
as soon as it is served successfully.  Otherwise, it is identical to
serve_ball.  If
a ball is served without autolaunch, it can be launched later by calling
launch_ball.  This happens automatically when the launch button is
pressed and a ball is detected in the shooter lane.
   
You normally do not need to call either of those APIs, except in some rare cases.
The preferred way to start multiballs is to use set_ball_count,
which sets the number of balls in play, or add_ball_count if you
want to say how many balls to be added.  These use serve_ball_auto
to do the work.  They work on manual plunger games too.  Only one ball
will ever be placed in the shooter at a time.
     
serve_ballserve_ball_autolaunch_ballset_ball_countadd_ball_count
Multiball modes can be implemented by defining a structure of type
struct mb_mode_ops.  They are modeled after the way that timed
modes are constructed.  Use the DEFAULT_MBMODE macro in the initializer
to set suitable values before declaring your own values.
   
The key difference is how the mode ends; here, we examine the number of balls in play and end the mode when it reduces to 1.
FreeWPC implements the Mute and Pause feature that was included in the Twilight Zone home ROM. It is optional at compile-time. The machine must have an extra-ball buyin button for it to work.
When compiled in, and the adjustment "MUTE/PAUSE" is set to YES, then pressing buyin during a game will hold the flippers, disable ball kickouts, pause timers, and turn off the background music. To continue, press the button again. It will also timeout automatically after 15 minutes.
A default status report is builtin which shows basic game information. To activate it in a game, hold in either flipper button for about 5 seconds.
Machines can customize the report by defining their own status pages. 
Modules should declare a handler for the status_report event.