Mame Hooker 3.5  by Howard Casto(Part of the MameInterop sdk)
================
(Note:  Turn OFF WordWrap)


What's New
==========
3.5
Added Png support for the displays. (Sorry no transparency.)
Added the ability to use full paths to images in .dis files.  
Added keep-aspect option to display files. (Not fully finished yet)
The "%rom%" flag now works inside display files.
Combine those four and it means you can easily make a default.dis that displays your artwork (marquees, flyers, ect) on a secondary display.
I've included two in the displays folder.  One displays the marquee fullscreen, and another displays the marquee, cabient image and flyer image.
Understand though that since I don't know where you keep your artwork you MUST modify these before they will work.

Added Generic HID support, meaning if you have the documentation you can control ANY HID device!
For those of you who like to screw around with stuff, I've included scripts that allow you to control the dream cheeky missile launchers!





3.0 
Fixed a bug which caused the "show supported devices" option to crash if a 360 controller is connected.
Vista and Win 7 ARE supported, but special install measures must be used... see the notes section at the bottom.
Added Xinput Support, allowing rumble to work on xbox 360 controllers.
Added Initial Dream Cheeky Missile Launcher Support (Only shows the device atm)
Added Initial Text to Speech Support (requires sapi 5.1 or later).
Fixed icon status!  You now have a greyed out icon when you disable mame hooker and the icon will kill itself upon exit!
Added Looping support for LWA scripts.  
Added Wiimote support for both rumble and leds.
I realized that in some instances you might not have every device connected at once.  For those cases I added a "refresh" command.
Fixed a bug that sometimes corrupted the autosort function of the default.ini (Thanks Popcorrin!)
Debug window now stretches when you resize it.



2.3
Added pac-drive detection in the show devices section. (May confuse pac-drive with io-warrior and vice-versa)
Removed the code that switches the icon when mh is disabled... it never worked properly anyway.




2.2
Fixed a few errors in the DDE documentation.  

Fixed error regarding how I had stupidly setup the "launch and wait" function so that it freezes mamehooker
and thus dde communicaton was impossible while the launched app is running.

Fixed an error with the "raw" command not allowing multiple strings.
Added Support for Lwa files.
Mame Hooker's icon has been updated to reflect the new MH logo on the site.




2.1 
Fixed even more bugs with the display function.
Fixed a horrible oversight on my part regarding command line options (a bar in windows represents piping... see command line section at the bottom).  
Updated the quick-refernce guide a little as it didn't have the appropriate syntax listed for ledwiz/iowarrior commands.
Put a trim function in the parsing... this should allow for a tad more user error.
Added Pac-Drive support!


2.0
Fixed Positioning bugs With Display Artwork Commands.
Added DDE/Command Line support so virtually anything can now send data to mamehooker! (See the Command Line Section at the bottom.)
Added ffa Command, which opens up all advanced options for force-feedback.
Added a Quit Command, so mamehooker can be killed via dde or command line.
Added MameHookerStart and MameHookerStop to the general options.  Useful for setting things up.
Added Command Line Wait command, which launches an app and waits until it closes before continuing.
Removed example ini files.  Hopefully everyone is getting the hang of it now.
Removed example display file.  These will soon be posted on the website.
Added Readme about tools in the tools folder and an updated presskey.exe.



1.3
Loadman fxed the mala numbering, so mala support is fully implemented now!


1.2 
Note:  Malal numbering is wrong!!!  Added dedicated commands for mala hardware and ledwiz hacks.
Added commands to kill all lights on the devices.
Note:  Note working yet!!  Added read buffer commands to iow based devices.
Added display commands, that let you control a graphical layout, similar to mame's artwork files.




1.1
Added Io Warrior Commands
Added Wait Command
Added Com Port Commands
Added Command Line App Commands
Added Universal Pause, which fires all scripts with the 0 state when paused.
Added the Ability to read scripts from an external file in the scripts folder.
Made the Test Box a little More User-friendly.
Added the "%rom%" tag, which lets you use the romname in a script.
Added the "%comma%" tag, which lets you insert commas.



1.0 - First Release  (Warning, docs not checked for spelling yet. :-) )


System Requirements:
====================
Visual Basic 6 Runtime Files
Direct Input 8 or higher (For force-feedback)
Xinput (Dll included to prevent errors, but to use it you need to install the 360 controller drivers.)
Sapi 5 or higher. (For speech recognition.)
CommIO.dll (Included)
inpout32.dll (Included)
iowkit.dll (Included)
LEDWIZM.OCX (Included)
Mame.dll (Included)


Overview
========
Arcade games have always had outputs.  Lights, sirens, motors, solenids scoreboards or what have you, cabinets Have always had ways to interact with the
player.  Until recently, mame had all but ignored this, with flashing keyboard lights as our only source of output.  Thankfully, Aaron Giles built us a 
whole new output system last summer, that allows mame to relay the states of various outputs to any windows application.  Unfortunately, knowing the state
doesn't magically make a device fire, thus the need for this app.  Mame Hooker keeps track of outputs and uses their state to control several output devices
including, but not limited to the keyboard leds, ledwiz, the parallel port and force feedback controllers.  More devices will be added as the project 
progresses.  

Basics
======
When you start mame hooker it will minimize to the taskbar.  Right clicking will give you a menu with choices that are fairly self-explainatory.  This app
is designed to be a "start and forget" app.  Start it up and let it do it's thing.  You can keep it running all the time as it uses next to no resources when
idle.  The app detects and manages mame automatically so you don't have to worry about special command line tags or what-not.  For mame cab users I suggest
simply placing a shortcut to the app in the startup folder.  There are no settings to speak of, the only thing you have to do is write scripts for the 
various outputs to tell them what to control.(Covered Later).

Ini files
=========
In the ini folder you'll find a default.ini.  This is the generic configuration file that all games will use unless overridden by an entry in a game-specific
ini file.  In either case, the typical file looks like this:

[General]
MameStart=
MameStop=
StateChange=
Pause=
MameHookerStart=
MameHookeStop=

[Outputs]
led0=
led1=
led3=
led4=

In the general section you can set scripts to run when mame starts, mame stops and any state is changed respectively. Also there is mamehooker start and 
stop, which are only ran when mamehooker starts up, and closes respectively.  These two are useful for setting up a mamehooker helper app.  Note that in the
case of these two functions, many devices (such as force feedback and the led controllers) aren't initalized and thus won't work.  It is mostly for launching
applications via cmd and cdw.  Also, there is the pause entry.  Whenever mame is paused, mamehooker automatically turns off everything turned on in the 
script.  The pause command allows you to do an additional task (such as launch a control viewer) whever a game is paused.  The outputs section lists various
outputs available that you can also bind scripts to.  whenever you play a new game with outputs, a ini file named after the rom is generated with blank 
entries and any new outputs are also added to the default.ini.  If you want a script to run on any game with that output, fill it out in the default.ini 
If you only want it to work for that game, fill it out in the game-specific one.


Explaination of scripting language:
===================================
In the default.ini and in individual game inis you can have various actions occur when a outputs value changes.
You do this via "scripts". Scripts can be a single one of the commands listed in the next section, or multiple commands.
You can have a single command (or set of commands) that is fired regardless of the new value, or setup different command(s) for all
the possible values that output can give. Examples are the easiest way to show this.  To bind the on/off state of a ledwiz led to the mame 
output "led0" we use the following syntax:

led0=lws 1 1 %s%

Notice the "%s%"?  This passes the current value or "state" of the output it is binded to.  Without it, the light would never change because
the ledwiz would always be sent the same value, regardless of what the outputs current value is.  Also note that variables for a command are seperated by a
SINGLE space.  STRAY SPACES WILL CORRUPT THE SCRIPT!!! Anyway...  Lets say there are two leds you want to bind to led0 though.  Well the script syntax allows 
for a near infinate amount of commands to be sent when a state changes, to add another command, we simply add a comma and the next function.  So to also bind
ledwiz output 2 we would type:

led0=lws 1 1 %s%,lws 1 2 %s%

Pretty easy huh?  Ok but what if the output value isn't enough data to tell the command what to do, like if you want to have a button one color when it's 
off and a totally different color when it's on.  Well we can do that to by adding a bar.  Each command(s) in a bar grouping represent that value. Led0 in 
mame can only have the values of 0 or 1 (off or on) so we need a single bar to seperate slot 0 (the left side) from slot 1 (the right side).  So to set a 
ledwiz rgb led to white when off and red when on we would use the script:

led0=lwc 1 1 48 48 48|lwc 1 1 48 0 0

Note that the %s% isn't used, but rather custom intensities to set white in slot 0 and red in slot 1.  Also note that when you use this method you MUST
have an entry for every possible value, or the app might crash.  You can always use a null command (see below) if need be.  Finally note that you can also 
use commas to do more than one command for each state like:

led0=lwc 1 1 48 48 48,lwc 1 4 48 48 48|lwc 1 1 48 0 0,lwc 1 4 48 0 0

Which would bind your first two rgb leds to led0 instead of just one.

Aside from %s% you have %b1%-%b10% available which will send the data in that buffer. (See buffer commands below).

When you set a value in default.ini it uses that script for all games unless the ini file for that game also has an entry for that output,
in which case the individual ini takes priority.  




Command Quick Reference:
======================================================================================================================
Function Description		syntax						example			explaination
======================================================================================================================
ledwiz set power level		lwp device# pin# intensity			lwp 1 01 48				sets the intensity of ouput 1 on ledwiz 1 to 48
ledwiz set state		lws device# pin# state				lws 1 01 1				turns on output 1 on ledwiz 1
ledwiz set color (rgb led)	lwc device# starting_output r g b		lwc 1 1 48 48 48			turns a rgb led hooked up to outputs 1 2 and 3 white
ledwiz kill all leds  		lwk device#					lwk 1					turns the whole device off

io warrior set state		iws device# pin# state				iws 1 01 1				turns on output 1 on ledwiz 1
io warrior set color (rgb led)	iwc device# starting_output r g b		iwc 1 1 1 1 1				turns a rgb led hooked up to outputs 1 2 and 3 white
io warrior read current states	iwr device#					iwr 1					reads the state of the entire device
io warrior kill all leds	iwk device#					iwk 1					turns the whole device off

mala hardware set state		mls device# pin# state				mls 1 01 1				turns on output 1 on mala 1
mala hardware set color		mlc device starting_output			mlc 1 1 1 1 1				turns a rgb led hooked up to outputs 1 2 and 3 white
mala read current states	mlr device#					mlr 1					reads the state of the entire device
mala hardware kill all leds	mlk device#					mlk 1					turns the whole device off

ledwiz hack set state		lhs device# pin# state				lhs 1 01 1				turns on output 1 on hacked ledwiz 1
ledwiz hack set color		lhc device starting_output			lhc 1 1 1 1 1				turns a rgb led hooked up to outputs 1 2 and 3 white
ledwiz hack read current states	iwr device#					lhr 1					reads the state of the entire device
ledwiz hack kill all leds	lhk device#					lhk 1					turns the whole device off

pac-drive set state		pds device# pin3 state				pds 1 1 1				turns on the first led on the first pacdrive.
pac-drive kill all leds		pdk device#					pdk 1					turns off all leds on the first pac-drive.

generic hid send data		ghd Device# Vendor# Product# ByteLength# Bytes	ghd 1 &HA81 &H701 2 0:&h20		Writes a two byte report (0 and &h20) to the specified device



set keyboard light		kbd led# state					kbd 1 1	t				turns on numlock light

say phrase via ttt		spk phrase					spk Hello World!			Makes computer say "hello world"

DirectX Force Feedback		dff joystick# state duration			dff 1 1 -1				rumbles joystick 1 infinately
DirectX Force Feedback Adv	dff joystick# state duration x y strength	ffa 1 1 -1 -2000 0 10000		rumbles joystick 1 infinately with a 2000 x offset to the left

Xinput (xb360) Force Feedback	xip joystick# state  				xip 1 1 				rumbles gamepad 1 infinately
Xinput (xb360) Feedback Adv	xia joystick# state Lstrength Rstrength 	xi1 1 1 30000 0	                        rumbles gamepad 1 infinately with 30000 strength sent to the left motor only

wiimote output			wii wiimote# output# state			wii 1 1 1				turns on led 1 on the first wiimote

lpt port send raw data		lpt port# data					lpt 1 453				sends 453 to lpt1
lpt port set output state	lpe port# output# state				lpe 1 1 1				turns on output 1

Com Port Open			cmo port# settings				cmo 1 baud=9600_parity=N_data=8_stop=1	Opens a port with the given settings
Com Port Close			cmc port#					cmc 1					closes the port
Com Port SetSettings		css port# settings				css 1 baud=9600_parity=N_data=8_stop=1  changes the settings of an existing opened port
Com Port SetLine		csl port# linebreak dtr rts			csl 0 1 1				Lets you setup the line settings.
Com Port Read			cmr port# buffer# length			cmr 1 1 255				Reads incoming port data into one of the buffers
com Port Write			cmw port# text					cmw 1 Hello_World!			Writes the text out to the com port

Load Display Artwork		lds display_name				lds seawolf				loads the seawolf.dis in the displays folder
Set Display Artwork Element	sds element# state				sds 1 1					sets element 1 to display image 1

set buffer		        sbf buffer# value				sbf 1 Hello_World!			makes buffer1 equal to "Hello World!"
edit buffer character		ibf buffer# position char			sbf 1 1 h				makes character 1 in buffer1 a h 
Null Command			nll (a space must be included)			nll 					does nothing
Wait Command			wat delay(in milliseconds)			wat 1000				waits that long before continuing.
Read From Script		rfs scriptName waitTime	state			rfs qbert  10 %s%			reads a mhs (mame hook script) from the scripts folder.
Read LWA Script			lwa scriptname device# state			lwa ledwiz 01 %s%			reads a lwa file from the lwa folder
Launch App			cmd path exe flags windowstate			cmd c:\j5\ j5.exe %rom%	4		launches the app (does not wait until finished) with the rom flag in a normal window
Launch App (And Wait Till Done)	cdw path exe flags windowstate			cdw c:\j5\ j5.exe %rom%	4		launches the app (waits until finished) with the rom flag in a normal window
Exit MameHooker			qut y						qut y					Exits MameHooker
Refresh Devices			ref a						ref a					Essentially the same as "show supported deivces" menu item.  
															Useful if you plug in a new controller.


Command Details:

========================================================================================================================
Ledwiz Commands: 
========================================================================================================================

The ledwiz is a popular usb output device with 32 outputs, each capable of 49 levels of intensity and 3 ramp effects.
A computer can have up to 16 ledwiz units installed at one time.  The three commands listed above are virutally identical to
the ledwiz commands lwp, lws and rgb as described in the ledwiz documentation.  Only the syntax has changed, the same values 
apply. Note that for the rgb command to work, your led must be hooked up in the order r, g, b. Also note that the lower digits
for lwp and lws need to start with a "0".  Possible intensity values for lwp and lwc are 0-48, 129(ramp up/down), 130(on/off), 
131(on/ramp down), and 132(ramp up/on).  The lwk command turns off all the lights on the device selected and sets the pluse speed to 1.

Note:  The read lwa script command is considered seperate and not a ledwiz command.  See the script section further down.


========================================================================================================================
Io Warrior Commands: 
========================================================================================================================

The io/warrior is a open-source chipset and test kit very similar to the ledwiz. You can actually swap the ledwiz chip with 
an io warrior 40 and it'll work! A computer can have up to 16 io warrior units installed at one time. The iowarrior chipset comes in a few flavors,
with up to 56 outputs supported depending upon the hardware.  For most people though the io 40 is the chip of choice with 40 outputs (32 if installed
on a ledwiz).  Note that the ouputs are digital, meaning that they can only be on or off, there are no intensity settings. With that being said, the
two commands work exactly the same as the similar ledwiz commands.  Just keep in mind that iwc(io warrior rgb) is digital, so you can't mix colors, rather
turn on/off different combinations of the r g and b leds.  So just to make things clear:


0 0 0=off
1 0 0=red
0 1 0=green
0 0 1=blue
1 1 0=yellow
0 1 1=blue green
1 0 1=purple
1 1 1=white

The iowarrior can only be set by sending the values of all the leds in the device at a time.  To do this, I've setup an internal buffer that you don't need
to worry about.  The only thing is, I can only keep track of the leds that mamehooker has changed, not any external device you might call.  So, after you set
the lights via an external app in your script, you need to call iwr, which will fill my internal buffer with the current states.

Also, because I don't know which type of device you are using, if you wish to clear the device, you must do so manually with the iwk command.

========================================================================================================================
Mala Hardware Commands: 
========================================================================================================================
The mala team built a special version of the iowarrior, the internals are slightly different so it needed it's own set of commands.
It works EXACTLY like the io warrior stuff though, so refer to the iowarrior section.


========================================================================================================================
Ledwiz Hack Commands: 
========================================================================================================================
The ledwiz's chip can be replaced with a iow 40 chip, thus making it an iowarrior, the internals are slightly different so it needed it's own set of commands.
It works EXACTLY like the io warrior stuff though, so refer to the iowarrior section.


========================================================================================================================
Pac-Drive Commands: 
========================================================================================================================
The pac-drive, again is a iowarrior-like device and uses the same commands.  Notable differences include support for only 4 devices 
(atm Andy only sells 4 id#s), as well as only 16 pins.  It works EXACTLY like the io warrior stuff though, so refer to the iowarrior section.


========================================================================================================================
Generic Hid Commands: 
========================================================================================================================
The pac drive, iowarrior, ledwiz and virtually every usb device supported by mamehooker is what is called a generic hid (Human Interface Device).
Although I try to add all the popular devices, there is a chance that I might miss one or that a new one comes out way after I've abandoned the project.
This is what the generic hid command is for.  All you need is documentation  on what data to send and you are good to go. 
Device Number is obviously the number to the device we want as you could have multiple instances of the device hooked up to your machine.
VendorID and ProductID are the two numbers that tell windows what the device is.  You'll find them with your device's spec sheets.
Byte Length is asking for the length of your report in bytes.  Again, this is dependant upon the device and can be found in it's spec sheets.
The actual data is the numeric value of the data you want to send, with each byte seperated by a ":"

Please note that if you want to send hex values, which are the standard, please put a "&h" in front of them instead of a "0x" as that is vb's preferred syntax.
You can use "&h" for the vendor and product id numbers as well.

Also note that because these devices are looked for ONLY when you send data to them, they won't show up in the debug menu when you show supported devices.



========================================================================================================================
Keyboard Light Command:
========================================================================================================================

This simply sets the keyboad led of led 1(numlock) led 2(caps lock) or led 3 (scroll lock).  It does this by pressing those keys,
so don't map them to anything in your game.  If this doesn't work for you then too bad.  Different oses require different hacks to
light the keyboard leds.


========================================================================================================================
Text to Speech Command:
========================================================================================================================

Use this commmand to have the computer say the phrase you provide via microsoft text to speech.  This requires sapi 5.1 or later to be installed.

========================================================================================================================
Force Feedback Commands:
========================================================================================================================

Dff sends a constant force effect, or "rumble effect" to the joystick specified for the amount of time specified in milliseconds. You can also 
set the duration to -1, which keeps the effect active until you turn it back off.  The state value turns the effect on or off (incase you set 
the duration to infinate.) Any joystick device in windows that supports force feedback is supported. To determine the id number, go into your 
control panel and look at the order of the joysticks.  The top one is 0, the next one is 1 and so on.  Most console controllers support force 
feedback if they are interfaced via usb.  The microsoft xbox controller is the only controller to support true dual axis (two motor) force feedback.  
Various hi-end flight/racing controllers for the pc also support true force feedback.

The extra advanced command simply add more options.  Every effect in ff has a "virtual position" which determines the strength of the various motors to
make it feel like the effect is coming from a direction. X and y simply let to set those, with negative numbers moving the effect to the left or top 
respectivly.  Strength effects how powerful the effect is, with 10000 being the highest. 

Note:  Xbox 360 controllers will show up as force-feedback enabled, but without custom drivers they will NOT WORK!  See the next section for using 360 controllers with the stock drivers. 


========================================================================================================================
XInput Force Feedback Commands (aka Xbox 360 controllers):
========================================================================================================================

These commands work essentially like regular force-feedback commands but with the following XNA-based limitations:
1.  The duration command has been removed.  All Settings are infinate.  To help with this problem I've added a "fake" state command (which also isn't supported)
    when you send a command with a 0 state, it will set both motors to 0 (and turn them off) regardless of your commands.
2.  Because 360 devices only have two motors, the x, y, strength commands have been consolidated into LStrength and RStrength, representing the left and right motors.
    Values for strength range from 0 to 65535.  Using the simpler "xip" command sets both to max when the state is 1.  

========================================================================================================================
Wiimote output Commands:
========================================================================================================================

The wii has 4 leds and a rumble motor.  You can switch them all off and on via the "wii" command.  The "output" section refers to which output you want to set.
1-4 are leds 1-4 and 5 is the rumble motor.  Please understand that setting one output does NOT effect the other outputs.

For example:

sending ...wii 1 1 1 followed by wii 1 2 1 ... would result in BOTH leds 1 and 2 being lit.  
If you wanted only led 2 to light you'd need to send wii 1 1 0 first to switch led 1 back off.

Also understand that mamehooker doesnt' aid in the pairing of a wiimote to your pc in any way.  The wiimotes should be connected BEFORE you start mamehooker.

Also there are two special output values you can use.... sending "l" (for "leds") instead of a number will set all 4 leds to the provided state.  
Sending "a" (for "all") will set all the leds AND the rumble motor. 


========================================================================================================================
Lpt(Parallel) Port Commands:
========================================================================================================================

The lpt commands are a way to send data to the output pins of the parallel port.  Lpt sends raw data, while lpe will set the
state of one of 8 possible outputs when using an "easy" parallel port interface. (See chart below.)  Note that this will
work on xp.  Also note that all the output pins are normally stuck in the on state during bootup, so a solenoid connection isn't
a good idea using the easy interface. Also the parallel port can only send about 4 volts, so it isn't suited for powerful lights 
without the use of relays.  For raw data manipulation you may need to also use the buffer commands explained further down.

Easy Interface:
=======================
lpt pin		output
=======================
2		led 1+
3		led 2+
4		led 3+
5		led 4+
6		led 5+
7		led 6+
8		led 7+
9		led 8+

18-25		common ground

(In case you can't tell from above, simply wire the positive ends of your leds directly to pins 2-9 and ground them all to 18-25.)


========================================================================================================================
Com (Serial/Modem) Port Commands:
========================================================================================================================

These functions allow for raw communication with any device attached to the com ports.  This is useful for communication to a home-built
serial device or an app running on another computer. This is an advanced set of functions and all communication must be done manually.

Open and Close are pretty Obvious.  SetSettings simply lets you reset an open port without having to close it first.  Set line basically lets you 
setup the formatting.  You call:

csl port# linebreak dtr rts

Port is, of course the port number, linebreak dtr and rts are integer values (0 or 1) to tell the app if these options should be turned on or off.

Read is fairly obvious, except keep in mind that you can only read to a buffer.  If you wish to do something with the data, you need to use this command to
fill a buffer and then run the command to use it.  Write, again is fairly obvious, just write some text.  

NOTE: As with any of the functions, spaces are not allowed for variables.  Use an underscore instead like the examples above and it will be converted 
internally.  Please also note that you have to use the commands properly as they are manual.  So you can't write some data until you first open a com port
and set it's format settings, which should probably be done on mamestart.  You'll also need to close the com port manually upon mamestop or whenever appropriate.


========================================================================================================================
Display Artwork Commands:
========================================================================================================================
Ever seen those bezels in mame with lights on them like for gorf?  Well display files are a similar artwork file designed to display on a secondary monitor.
Just like in mame, you have a main image and various sub-images on top of it that can be turned on and off.  The load display command loads up a display file,
while the set display command sets the image state of a particular element.  For info on display files look at the readme in your displays folder.


========================================================================================================================
Buffer Commands:
========================================================================================================================

Buffer commands are for advanced scripting, which might require you to store data of multiple states, and format it before you
send it to a device.  You always want to run set buffer first.  It'll let to setup a template and the maximum length of your buffer.
You could setup a buffer to hold a highscore (built by pieceing together various digits in segmented display outputs) by sending the value:
"High_Score:__________", which sets you up a header and 10 digits to play with.  Note that spaces aren't allowed so we use underscores.
Edit buffer allows you to replace a single character in your buffer. So to set the score to 1 I would send:  "ibf 1 21 1" which Sets position
21 to "1". The resulting buffer would be: "High_Score:_________1" Don't worry about these commands as you'll probably never need them.


========================================================================================================================
Null and Wait Commands:
========================================================================================================================
When using the optional "case per state" syntax of the scripting langauge, you must have an entry for every possible state.
You might not actually want to do anything in cetain states though, thus this null command, which does nothing.  Also you might
want to override a setting in the default.ini in an individual game, so you can set the command to "nll " inside the game's ini file.
Note that you MUST have a space after nll for it to work.

The wait command literally waits however long you specify before doing anything else.  This is useful for doing animations with multiple
commands per state.  A rather long example is:

MameStart=lwc 1 1 8 8 8,lwc 1 4 8 8 8,wat 5,lwc 1 1 18 18 18,lwc 1 4 18 18 18,wat 5,lwc 1 1 28 28 28,lwc 1 4 28 28 28,wat 5,lwc 1 1 38 38 38,lwc 1 4 38 38 38,wat 5,lwc 1 1 48 48 48,lwc 1 4 48 48 48,wat 5

Looking carefully at the command, it is doing a manual gradient up in brightness to a full white on the fist two rgb leds by gradually ramping up the 
intensity.  So the effect can be seen, a wait of 5 milliseconds is placed between each ramping.

========================================================================================================================
Read From Script Command:
========================================================================================================================
Ok, in case you haven't noticed yet, complicated scripts get hard to read due to their length.  On top of this, the parser can only read a finite number of
characters.  To solve this issue you can make externalized mame hook script files and save them in your scripts folder.  You call a script by giving it's name
minus the ".mhs" extension.  Yes that means all files you make must end in .mhs and yes that means they must be in your scripts folder.  Also no spaces in 
filenames allowed.  

By now you are probably wondering about the format, well it is essentially the same as internal script entries, except commas are replaced by a new line, and
bars are replaced with a line with "BREAK" on it.  So converting our past example:

led0=lwc 1 1 48 48 48,lwc 1 4 48 48 48|lwc 1 1 48 0 0,lwc 1 4 48 0 0

Would become:

led0=rfs whiteOred 0 %s%


(Inside whiteOred.mhs)
lwc 1 1 48 48 48
lwc 1 4 48 48 48
BREAK
lwc 1 1 48 0 0
lwc 1 4 48 0 0
(end of whiteOred.mhs)

Note that there are No stray spaces and no stray lines.  Also note that you can use this function multiple times, as in one file for off and one for on.
For example:

led0=rfs white 0 %s%|rfs red 0 %s% 

would load white.mhs when it's off and red.mhs when it's on.  Of course if you are crafty you can also do this with the "%s%" command.
For example:

led0=rfs state%s% 0 %s%

Would load state0.mhs or state1.mhs depending upon the value.

Want to get even craftier?  Well if you aren't using the buffers for anything, you can set them to various script names on mamestart and point to them with a 
double tag.  Like:

digit0=rfs %b%s%% 0 %s%

First the %s% will get replaced by the current state (lets say it's 1) so it becomes "rfs %b1% 0 1".  Well now we have a valid buffer number, so we read it 
(lets say you set it to "red" on mamestart) to get "rfs red 0 1" Bamm-o!  We can now automatically select script files with totally different names.  

The waitTime is a way to keep from constantly adding a wait command when your script file is an animation.  Set the wait to something other than 0 and it'll
wait that many milliseconds between each command. Note the %s% command tacked on the end of every single rfs command example.  It MUST be there and it MUST
be the %s% command.  This is due to a formatting limitation on my part (oops) and it passes the current state back through the loop once the script is read.

IMPORTANT NOTE!!!!  Do NOT nest rfs commands inside a script file.  It could cause a infinate loop and crash your machine.

=====================================================================================================================
Read LWA Script Command:
=====================================================================================================================

Lwa files are used by various ledwiz software to control lights, the lwa command works almost exactly like the rfs command.  Please be aware though that 
while mamehooker has support for the "%s%" tag in lwa files, most ledwiz applications do not.  It is reccomended to use mhs files instead whenever possible.
Also note that afaik lwa files only support the first device, but the added device# flag allows you to run it on any ledwiz. Note that if your LWA file loops or repeats
it will continue to loop or repeat until the repeat amount has expired or a new lwa file is read.  Changing the state of the output will NOT stop the script.

Put your lwa files in the "lwa" folder.




Command line/DDE Commands:
==========================

MameHooker shouldn't be limited to mame's system, so I've added dde and command-line support.  Developers of other emulators and applications can either use
the mame method (well documented in mame's source code) or this method to send outputs to mamehooker.  Basically you can send a regular command line string,
either by launching mamehooker again with command line flags, or by sending via dde.  

The DDE info is:

ServerName: MHServer
TopicName: MH

You have two methods of using dde with mamehooker, either the traditional way (using mame_start, mame_stop and state_change events) or the basic way 
(sending raw script commands). The tranditional way is reccommeneded, but in certain instances (such as a controls.dat viewer) it might make more sense to
use the basic method.  

The possible command lines are as follows:

raw|any script command
mamestart|rom
mamestop|rom
statechange|id|name|state

Note the bars, which are required.  Also note that when using the command line and not dde, it might be necessary to enclose the commands in quotes.  For 
example:

mamehook.exe "raw|lds seawolf" 

Is the correct command line to load a seawolf display.

mamehook.exe raw|lds seawolf 

Will make windows complain, as it thinks you are trying to "pipe" something.  Quotes aren't required for dde communication, but they don't hurt!

The raw flag runs the script function on the other side of the bar, this is used for basic communication.  
Mamestart allows mame to set itself up for a new game.  The romname (or whatever) should be sent on the other side of the bar. MameStop kills 
the current session and should be sent whenver the emulator or app exits or quits the game. Note that mamestart and stop must be used even in basic
communication as these functions setup devices such as force-feedback.  Simply send a dummy rom name if needed.  StateChange sends a command telling mh that
a virtual output just changed it's value.  The id number, and name of the output (which should remain constant the duration of the game) and the new value,
or state, should be sent.  Note the bars and lack of spaces, those are important.  Also note that the special name "pause" can be sent and mamehooker's pause
event fires.

*********IMPORTANT NOTE TO DEVELOPERS!*****
DDE communication is very efficient, but if commands are sent too rapidly, this application might not be able to keep up.  This results in a over-filling 
buffer that will eventually crash both the external app and mamehooker.  The solution is quite simple though.  Most dde functions (using any api or language)
offer a timeout option.  You want to always set this timeout at or lower than the maximum refresh rate of the outputs you are changing.  This ensures that if
mamehooker does get behind, it'll simply drop the command.  This is merely a safety precaution though, so don't worry about rapid sends!
*******************************************

NOTES:
=========================

Vista/ Windows 7 install instructions:

This program will run on vista and windows 7 in both 32 and 64 bit flavors, but due to the crazy stupid UAC, special procedures must be done manually.

Step 1.  Download and install the visual basic 6 runtime files.  Ignore any incompatability warnings from the UAC.
Step 2.  Ocx's no longer automatically register and to make things worse regsvr32 doesn't work right anymore. First go to start/all programs/accessores and locate cmd.exe
Step 3.  Right click on the cmd.exe and select "run as administrator"... yes even if you logged in as admin, you MUST do this.
step 4.  In the command line browse to the mamehooker directory and type "regsvr32 ledwizm.ocx" and you should get a successfully installed message.
Step 5.  Make sure you are running an administrator account and launch mamehooker, but do NOT right click and run as admin like you did with cmd.  Yes, it makes no sense, but the program needs
	to be ran on an admin account but won't work properly if you use the right-click method.  

Xbox 360 controller notes:

The 360 controller does NOT support force feedback!!!!  Yes it has rumble motors, but 360 contollers use a new input method called Xinput instead of directinput.  If you have the official 360 
drivers installed use the xip and xia commands instead.  That being said it is possible to have the 360 controller simulate "real" force feedback via the XBCD drivers, but they are a pain in 
the butt to install n win7/vista and installing them usually means rumble will no longer work on the newer windows live games.  


Wiimote notes:

Wiimotes must be synced by some other program... mamehooker just reads them once they are connected.  Since you'll be using them as controllers anyway, this shouldn't be a problem.


Future Plans:
=======================
Add "play sound" option, mainly to send sound to the xbox 360 headsets. Perhaps sending a sound to a specific windows soundcard/soundevice would work as a headset shows up as a sound device.
Add "play sound" option, for the wiimote.  Will require specially created sound files, but it IS possible.
Add support for the rock band stage kit, which is ripe for hacking.  I need to buy one first though.  ;)
Add actual support for dream cheeky devices.








