xboxscene.org forums

Author Topic: Actionscript Clinic  (Read 312 times)

BenJeremy

  • Archived User
  • Hero Member
  • *
  • Posts: 5645
Actionscript Clinic
« on: September 29, 2003, 06:56:00 PM »

This will be a closed topic, and I'll add as I come up with new things.

Some questions answered in this thread.

Ask new questions in this thread (Fresher than the old thread)

This post has been edited by BenJeremy: Oct 15 2003, 04:58 PM
Logged

BenJeremy

  • Archived User
  • Hero Member
  • *
  • Posts: 5645
Actionscript Clinic
« Reply #1 on: September 29, 2003, 07:08:00 PM »

First topic: Internal.xml

Internal.xml is an XML configuration file used by MXM - using a Win32 tool called "BinTree" it's compiled into C/C++ source and built into MXM.

Why is it important to scripters? Because several default scripts are stored there, as well as context menu entries (or examples). The most important one might be the _CHECKPREP script, which gives MXM the ability to prepare a fresh hard drive and even copy over data form a prepared DVD-R, without much effort.

All of these internal scripts can be overriden by including the named equivalent in MXM.xml. You can override the _AutoExec script, for example.

We'll talk about context menus soon. These are user-definable menu items created with ActionScripts. Currently, they are accessable through the system menu, but eventually, the context menu will be assignable to a gamepad button.

Logged

BenJeremy

  • Archived User
  • Hero Member
  • *
  • Posts: 5645
Actionscript Clinic
« Reply #2 on: September 29, 2003, 07:16:00 PM »

Context Menus

ActionScripts can be setup for menu items, run as "Context options"

You may have noticed a new option under the system menu: "Game Options" - this opens up a menu of ActionScripts that can be run. These scripts have some awareness of the menu option that was active when the user selected the system menu.

To create a context menu item, in the MXM.xml file, you create a context node (if it doesn't exist) and the appropriate Item nodes:

(From internal.xml)
CODE



DVD



HD



DVD



HD



CallScript _ClearGameSaves




In the above example, the context items are set up to call scripts already defined in the internal.xml file, or the mxm.xml file - and the last item performs an actual actionscript.

The following environment variables are defined for context action scripts:

  • _GameTitle
  • _GameDesc
  • _GameDir
  • _GameExe
  • _GameMedia
  • _GameThumbnail
  • _GameXBEID
  • _GameVerified

    These are filled with the info from the current selected menu item.

    You'll also notice the <Mode>DVD</Mode> and <Mode>HD</Mode> elements in the context entries... those will force the item to only appear when the selected item is run from the DVD or HD, respectively. If left out, the item will be displayed for either case.

  • Logged

    BenJeremy

    • Archived User
    • Hero Member
    • *
    • Posts: 5645
    Actionscript Clinic
    « Reply #3 on: September 29, 2003, 07:33:00 PM »

    Wildcard Searching  (This is a 0.9n.6 Feature)

    With ActionScripts, you can step through directory entries in a path. What can you use something like this for? Hmmmm... dunno, but we'll take a look:

    The functions:
  •    BEGINSEARCH <WildCardPath>
       - The local variables "search_name", "search_path", "search_arg", "search_size", "search_type", "search_active" (which equals "1" when the search values are OK) are updated during the search
  •    SEARCHITEM <VarName>   (Load VarName with current file/pathname)
  •    SEARCHSIZE <VarName>   (Load VarName with current file size)
  •    SEARCHTYPE <VarName>   (Load VarName with current type for entry - "file" or "dir")
  •    SEARCHNEXT
  •    ENDSEARCH

    We begin the search with, of course, BEGINSEARCH, feeding a wildcard path. This starts the search and loads finds the first item. if the SEARCHXXXX functions that return variables do not return anything, then the search failed to find anything. ENDSEARCH is used to close the search. If you do not do this on an active search, the next call to BEGINSEARCH will cause an error.

    Here's my test code, it searches all items in the MXM directory starting with "T":

    CODE

    BEGINSEARCH t*
    :TOP
    SEARCHTYPE s_type
    SEARCHITEM s_name
    SEARCHSIZE s_size
    IF %s_type% == "dir" GOTO SHOWDIR
    IF %s_type% == "file" GOTO SHOWFILE
    GOTO DONESEARCH
    :SHOWDIR
    CallsCript _DisplayMessageBox "Directory Found: %s_name%"
    SEARCHNEXT
    GOTO TOP
    :SHOWFILE
    CallsCript _DisplayMessageBox "File Found: %s_name%$eol$%s_size% bytes"
    SEARCHNEXT
    GOTO TOP
    :DONESEARCH
    ENDSEARCH


    While I loaded variables using the SEARCHXXXX functions, you also have local variables that are filled with these values automatically:

  • search_name
    - Name of the file, does not include the path

  • search_path
    - The path the search was performed on

  • search_arg
    - The wildcarded path argument you used on the search

  • search_size
    - Size of the current search item

  • search_type
    - type of the current search item, "dir" or "file"

  • search_active
    - "1" if BEGINSEARCH/SEARCHNEXT has found a file matching the search argument

    I hope this helps. Of course, at the moment, this set of functions are only available in the "WIP" release, but it should give non-WIP testers a leg up on writing future scripts.
  • Logged

    BenJeremy

    • Archived User
    • Hero Member
    • *
    • Posts: 5645
    Actionscript Clinic
    « Reply #4 on: October 15, 2003, 05:50:00 AM »

    XML Access in ActionScripting MXM 0.9n.6

    CODE

    XMLOPEN TestXML ::MXM
    XMLSetNodePtr TestXML !.FTPServer.User
    XMLGetNodePtr TestXML XMLPtr
    XMLGetValue TestXML User1Name !.FTPServer.User:0.Name
    XMLGetValue TestXML User2Name !.FTPServer.User:1.Name
    XMLGetValue TestXML User1Pass !.FTPServer.User:0.Password
    XMLGetValue TestXML User2Pass !.FTPServer.User:1.Password
    CallScript _DisplayMessageBox "XMLNode Pointer=(%XMLPtr%)$eol$1)%User1Name% / %User1Pass%$eol$2)%User2Name% / %User2Pass%"
    XMLSetNodePtr TestXML !.FTPServer
    XMLGetNodeCount TestXML NewUser
    XMLCreateNode TestXML User
    XMLSetValue TestXML !.FTPServer.User:%NewUser%.Name Action
    XMLSetValue TestXML !.FTPServer.User:%NewUser%.Password Script
    XMLSave TestXML Z:Check.xml
    XMLCLOSE TestXML



    Well, like file access, we have "handles" - names associated with our files. We open an XML file for operations using XMLOpen, which can access external files and "internal" XML nodes as well.

    CODE

    XMLOpen TestXML ::MXM


    In the aboe case, we are opening the MXM.xml configuration, as it is seen 'internally' by MXM. Here are the other "current" internal names:
  • ::MXM
  • ::Prefs
  • ::BIOSMD5
  • ::Menu
  • ::Menu_Cache

    These should be straight-forward to understand, so I'll dispense with the descriptions for now. You may also use a filename of an existing XML file.

    Once open, there are quite a few operations you can perform on the XML "tree" Part of the reason for the complicated set of commands is the XML format itself...

    XML consists of nodes and elements. An XML file will always have ONE MAIN NODE, a node consists of one or more nodes and elements, and may have a number of attributes. Elements have a textual value and may have a number of attributes, as well. Nodes and Elements do not require unique names, thus, there may be multiple nodes or elements with the same name. This complicates matters, since we need to have a consistent means to access different nodes or elements with the same name.

    If you are an avid MXM user, you've seen your share of XML files, so I won't recreate a sample XML file here...

    The primary workhorses we'll discuss in this clinic is XMLGetValue and XMLSetValue. For the most part, you can get away with using these exclusively, but in instances where you need to add non-unique nodes or elements, these functions may not do the job by themselves.

    CODE

    XMLGetValue TestXML User2Name !.FTPServer.User:1.Name


    The above example takes the SECOND "User" Node entry and gets the value of "Name" to put in environment variable %User2Name%. If it does not exist, it can put a default value there (lacking that, it sets the variable to "")

    You'll notice the notation... the "!" symbol denotes the main XML node (there is only one of these, remember) - the name is not important, since there is only one, so we can ignore it. The "." separates node/element names in the location, and the ":" denotes we want a specific index (when multiple non-unique names are used for nodes and elements) - this defaults to the first item, BTW.

    "Name" can be either an attribute of the "User" node, and element in the "User" node, or a "Value" attribute or element of a "Name" node. MXM is very sloppy with these names, to be forgiving of user's input.


    CODE

    XMLSetNodePtr TestXML !.FTPServer
    XMLGetNodeCount TestXML NewUser
    XMLCreateNode TestXML User


    Here, I set the current node pointer to the FTPServer node in the configuration file, then grabbed the count... why? Because when I create a new "User" node, the count I saved off becomes the index to the new node!

    XMLCreateNode does not take a fully qualified location - you must use a single name here.

    Only XMLSetNodePtr, XMLSetElementPtr, XMLSetValue and XMLGetValue accept fully qualified names. All other operations depend on the user setting up the location before hand with the XMLSetXXXPtr functions.

    XMLSetValue and XMLGetValue do not change the current node/element pointers, either.

    (OK, that should be as clear as mud, but hang in there, you'll understand after a while)

    CODE

    XMLSetValue TestXML !.FTPServer.User:%NewUser%.Name Action
    XMLSetValue TestXML !.FTPServer.User:%NewUser%.Password Script


    Here, we set new values in the User:2 node (Well, it's 2 on my system, as I have two User nodes in my configuration file)

    SetValue will create nodes/elements as needed, but sometimes it needs to make assumptions, so try to have things set up. It will NOT create indexed nodes, so have those already built (as I did in this example)

    We end up with:

    CODE


     :  :


    xbox
    xbox


    user2
    pass2


    Action
    Script


     :  :




    We've added a new node, and created new values in it!


    Now it's time to save our handiwork:

    CODE

    XMLSave TestXML Z:Check.xml


    This one should be easy to figure out... this is my test script, so I'm playing it safe and saving to a temporary file.

    CODE

    XMLCLOSE TestXML


    Now we close the XML. this is a formality, in some cases, since the XML file is closed (not saved, just the resources associated with it are freed up) when the ActionScript finishes execution.


    I hope that helps explain a few things... there are more commands, but work with these to start, and play with the others.

    This post has been edited by BenJeremy: Oct 15 2003, 12:50 PM
  • Logged

    BenJeremy

    • Archived User
    • Hero Member
    • *
    • Posts: 5645
    Actionscript Clinic
    « Reply #5 on: October 23, 2003, 11:44:00 AM »

    Environment and special variables in MXM's ActionScript:

    All variables are basically strings. There are some operations which may treat them as numbers; those situations should be fairly evident from the parameters taken by those commands/functions.

    Environment variables are basically replaced with the proper values when a name is encountered between two percent ('%') symbols. If the name is prefixed with an underscore ('_') it's a GLOBAL environment variable, and any changes will persist after the script has finished and accessable by other scripts that execute. LOCAL environment variables, on the other hand, exist only during the duration of a script, HOWEVER, so-called 'subscripts' executed using CALLSCRIPT or CALLSCRIPTFILE will inherit the parent script's local variables. Any changes the 'subscript' makes to these values is local only to THAT 'subscript' and its own called subscripts; when the 'subscript'exits, the local values of the parent script will be as they were before calling the 'subscript'. Subscripts requiring returned information will need to use GLOBAL environment space to do so.

    Also note: GLOBAL variables are handy for skinners - they can be retrieved using the Gadget String source "env" along with the variable name as the key. In this way, ActionScripts can be used to update information on the screen within the skin!

    Some commands require a <VarName> parameter - for these, you would use the name WITHOUT the percent signs - the idea is to pass the name in, and using it WITH percent signs means it would be evaluated into the VALUE, and pass THAT in, instead of the variable's name - the command would not know the proper place to assign the result to. If this seems confusing, I'm sorry... you'll just have to play around with the scripts and see the results; for advanced users, however, there are tricks you can apply, such as adding index values by tacking them into variable names:

    CODE

    SET Index 1
    SET Total 10
    :TOPLOOP
    IF# %Index% > %Total% GOTO DONELOOP
    SET MyList%Index% "Some Value %Index% out of %Total%"
    ADD Index 1
    GOTO TOPLOOP
    :DONELOOP



    This would generate a set of variables, MyList1 ... MyList10, each containing a unique string.

    One more note about Environment Variables: Keep the names alphanumeric. The names are case insensitive, but for clarity, you may prefer to with to maintain the case throughout your script.


    Special variables are replaced with special characters, and if not matching one of the 'specials' ($eol$, $gt$, $lt$, $formatresult$, $timer$, $lasterror$, $dvd_mode$, or $tab$), it attempts to match it up with a "Gadget String" - those text sources used by MXM Skinners to display information on the screen. Thus, fetching $ip$ will return the current IP address of the Xbox, or $TempSysF$ will return the system temperature in degrees farenheit.

    While these values may change, they cannot be assigned, nor can the ActionScript directly change them.

    This post has been edited by BenJeremy: Oct 23 2003, 06:45 PM
    Logged