StepMania 5 has an xml converter inside it intended to assist authors who want
to convert the xml scripted background and foreground animations written for
StepMania 3.95 or OpenITG to work with StepMania 5.

The primary way to invoke the converter is to use the debug menu.
While on the Select Music screen, navigate to the song with xml that needs to
be converted.  Hold F3, press F6 to change to the theme section, then press 0
to convert the xml in the folder of the current song.

The other way is to use a theme that provides some interface to the
convert_xml_bgs lua function.


Since the converter recursively searches for all xml files in the folder
given, if you have foo/default.xml, it will be converted to foo/default.lua.
If foo/bar/default.xml exists, foo/bar/default.lua will be created.

When the converter finds an xml file, it parses it and attempts to create lua
that results in the same actors.  Some things are converted without problems,
others are beyond the scope of the converter and are not handled.

Do not run the converter on a song that you have already converted.  When it
finds the xml files, it will overwrite the lua files with new ones, which
means any fixes applied after conversion will be wiped out.

The converter does not delete the xml files after conversion because you
probably need them to double check things.



# Known working conversions

## Naming
Actors and conditions are assigned autogenerated unique names with the prefix
"xtl_actor_" or "xtl_cond_".  This is so that if some error message tells you
the name of an actor, you can find it in the code.  If an actor has a Name
field, that will be used instead of the autogenerated unique name.

## Type guessing

Typically, the Type or Class field is used, unless the File field points to
something that has to be a certain type.

* ActorFrames with children are handled.

* File field conditions:
  * Images and .sprite files are converted to Sprites.
  * .txt and .model files are converted to Models.
  * Folders are converted to use LoadActor, which has its own rules for
    guessing the actor type.
  * Sound files are converted to ActorSound.

* If there is a Text field, the actor is assumed to be a BitmapText.


## Field conversion

Any field that ends with "Command" is recognized as a command and passes
through command conversion.  
Anything else passes through unchanged, unless it's known to be a string
field.  String fields will be strings after conversion.  
This may cause syntax errors if a field is meant to be a string and it's not
a string after conversion.  This happens because in XML, all fields are
stored in strings and the only way to know which ones are supposed to be
strings after conversion is to keep a list of field names.  
String fields:
* AltText
* Bones
* File
* Font
* Materials
* Meshes
* Text
* Texture


## Command conversion

Commands that use the normal style are converted to use SM5's cmd syntax.
These commands are passed through a parser that looks for certain things that
require special handling:
* x coords are changed to use (SCREEN_CENTER_X + (x - 320)), to put them in
  the same position relative to the center.  This is only applied if the
  coord was a simple number, expressions are not changed.
* y coords are changed similarly to x coords.
* queuecommand, playcommand, and effectclock all have their arguments changed
  to strings.
* EffectMagnitude, ZoomToWidth, and ZoomToHeight are renamed to the lowercase
  names SM5 uses.
* blend and cullmode have their args converted to SM5's enum values.
* hidden is converted to visible, and its arg is converted to a bool.
* diffuse, effectcolor1, and effectcolor2 have their args converted to use
  the color function.


Commands that use lua functions are converted with the lua mostly unchanged.
A very short list of things in lua are recognized and replaced with their
SM5 equivalents.
* "hidden(0)" becomes "visible(true)"
* "hidden(1)" becomes "visible(false)"
* "effectdelay" becomes "effect_hold_at_full"
* "IsPlayerEnabled(0)" becomes "IsPlayerEnabled(PLAYER_1)"
* "IsPlayerEnabled(1)" becomes "IsPlayerEnabled(PLAYER_2)"

The list is short and the strings must match exactly because symbolically
parsing the lua into tokens to recognize other ways of doing the same thing
is beyond the scope of the converter.


## Condition conversion

Because conditions are lua code to execute, they are passed  through the same
converter as lua commands.  
It is common practice for many actors to have identical conditions, so all
conditions are collected in a list, so they can be evaluated once when the
file is loaded, and then the actors can just use the result.  
So after conversion you might see something like this:
```
xtl_cond_a_result= GAMESTATE:IsPlayerEnabled(PLAYER_1)
local function optional_actor(cond, actor)
  if cond then return actor end
  return Def.Actor{}
end
```
The optional_actor function is a convenient way to insert a blank, unrendered
actor instead of one that actually does something.  
You'll see it used like this:
```
    optional_actor(xtl_cond_a_result,
    Def.Sprite{
      Name= "xtl_actor_g",
      InitCommand= cmd(x,0;y,0),
      Texture= "foo 3x1.png",
    }),
```



# Known unhandled things

Some things like difficulty use strings as enum values in SM5.  Lua code that
uses GetDifficulty or other things that now return enum strings must be
edited after conversion to use the enum strings.

There are probably renamed functions that the converter does not handle.

GAMESTATE:ApplyGameCommand applies mods instantly, ignoring the tween
speeds.  Lua code that changes mods should use the PlayerOptions API instead.
This means fetching a PlayerOptions object and converting mod strings to
function names and args, which isn't hard with an editor with regex find and
replace.

Actor sizes are not changed, so if an actor is meant to be the size of the
screen, it will probably not cover the screen when Stepmania isn't a 4:3
aspect ratio.  Use SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_CENTER_X,
SCREEN_CENTER_Y, _screen.w, _screen.h, _screen.cx, or _screen.cy for
positioning and sizing.  Actor:FullScreen exists to stretch an actor to cover
the screen.
