Root Main


Once it has found the root main module, Torque compiles it into a special binary version containing byte code, a machine-readable format. The game engine then begins executing the instructions in the module. The root package can be used to do anything you like, but the convention established with the GarageGames code is that the root package performs the following functions:

  • Performs generic initialization

  • Performs the command line parameter parsing and dispatch

  • Defines the command line help package

  • Invokes packages and add-ons (Mods)

Here is the root main.cs module. Type it in and save it as Emaga4\main.cs. You can skip the comments if you like, in order to minimize your typing.

 //------------------------------------------------------------------------ // ./main.cs // // root main module for 3DGPAI1 emaga4 tutorial game // // Copyright (c) 2003 by Kenneth C. Finney. //------------------------------------------------------------------------ // ======================================================================== // ========================= Initializations ============================== // ======================================================================== $usageFlag = false; //help won't be displayed unless the command line                       //switch ( -h ) is used $logModeEnabled = true; //track the logging state we set in the next line. SetLogMode(2); // overwrites existing log file & closes log file at exit. // ======================================================================== // ======================= Function Definitions =========================== // ======================================================================== function OnExit() //------------------------------------------------------------------------ // This is called from the common code modules. Any last gasp exit // activities we might want to perform can be put in this function. // We need to provide a stub to prevent warnings in the log file. //------------------------------------------------------------------------ { } function ParseArgs() //------------------------------------------------------------------------ // handle the command line arguments // // this function is called from the common code // //------------------------------------------------------------------------ {    for($i = 1; $i < $Game::argc ; $i++) //loop thru all command line args    {      $currentarg    = $Game::argv[$i]; // get current arg from the list      $nextArgument       = $Game::argv[$i+1]; // get arg after the current one      $nextArgExists = $Game::argc-$i > 1;// if there *is* a next arg, note that      $logModeEnabled = false;             // turn this off; let the args dictate                                    // if logging should be enabled.      switch$($currentarg)      {        case "-?": // the user wants command line help, so this causes the          $usageFlag = true;   // Usage function to be run, instead of the game          $argumentFlag[$i] = true;                 // adjust the argument count        case "-h":          // exactly the same as "-?"          $usageFlag = true;          $argumentFlag[$i] = true;      }   } } function Usage() //------------------------------------------------------------------------ // Display the command line usage help //------------------------------------------------------------------------ { // NOTE: any logging entries are written to the file 'console.log'   Echo("\n\nemaga4 command line options:\n\n" @          " -h,                  -? display this message\n" ); } function LoadAddOns(%list) //------------------------------------------------------------------------ // Exec each of the startup scripts for add-ons. //------------------------------------------------------------------------ {   if (%list $= "")     return;   %list = NextToken(%list, token, ";");   LoadAddOns(%list);   Exec(%token @ "/main.cs"); } // ======================================================================== // ================ Module Body - Inline Statements ======================= // ======================================================================== //  Parse the command line arguments ParseArgs(); // Either display the help message or start the program. if ($usageFlag) {   EnableWinConsole(true);// send logging output to a Windows console window   Usage();   EnableWinConsole(false);   Quit(); } else {   // scan argument list, and log an Error message for each unused argument   for ($i = 1; $i < $Game::argc; $i++)   {      if (!$argumentFlag[$i])         Error("Error: Unknown command line argument: " @ $Game::argv[$i]);   }   if (!$logModeEnabled)   {      SetLogMode(6); // Default to a new log file each session.   }   // Set the add-on path list to specify the folders that will be   // available to the scripts and engine. Note that *all* required   // folder trees are included: common and control as well as the   // user add-ons.   $pathList = $addonList !$= "" ? $addonList @ ";control;common" : "control;common";   SetModPaths($pathList);   // Execute startup script for the common code modules   Exec("common/main.cs");   // Execute startup script for the control specific code modules   Exec("control/main.cs");   // Execute startup scripts for all user add-ons   Echo("--------- Loading Add-ons ---------");   LoadAddOns($addonList);   Echo("Engine initialization complete.");   OnStart(); } 

This is a fairly robust root main module. Let's take a closer look at it.

In the Initializations section, the $usageFlag variable is used to trigger a simple Help display for command line use of tge.exe. It is set to false here; if the user specifies the -? or -h flags on the command line, then this flag will be set to false.

After the usage flag, we set the log mode and enable logging. Logging allows us to track what is happening within the code. When we use the Echo(), Warn(), or Error() functions, their output is sent to the console.log file, in the root game folder.

The stub routine OnExit() is next. A stub routine is a function that is defined but actually does nothing. The common code modules have a call to this routine, but we have nothing for it to do. We could just leave it out, but a good policy is to provide an empty stub to avoid warning messages from appearing in our log file—when the Torque Engine tries to call a nonexistent function, it generates a warning.

Then there is the ParseArgs() function. Its job is to step through the list of command line arguments, or parameters, and perform whatever tasks you want based upon what arguments the user provided. In this case we'll just include code to provide a bare-bones usage, or Help, display.

Next is the actual Usage() function that displays the Help information.

This is followed by the LoadAddOns() routine. Its purpose is to walk through the list of addons specified by the user on the command line and to load the code for each. In Emaga4 there is no way for the user to specify add-ons or Mods, but (you knew there was a but coming, didn't you?) we still need this function, because we treat our common and control modules as if they were add-ons. They are always added to the list in such a way that they get loaded first. So this function is here to look after them.

After the function definitions we move into the in-line program statements. These statements are executed at load time—when the module is loaded into memory with the Exec() statement. When Torque runs, after the engine gets itself sorted out, it always loads the root main module (this module) with an Exec() statement. All of the other script modules are loaded as a result of what this module does.

The first thing that happens is a call to the ParseArgs() function, which we saw earlier. It sets the $usageFlag variable for us, you will recall.

Next is the block of code that examines the $usageFlag and decides what to do: either display the usage Help information or continue to run the game program. If we are not displaying the usage information, we move into the code block after the else.

The first thing we do in here is check to see if there are any unused arguments from the command line. If there are, that means the program doesn't understand the arguments and there was some kind of error, which we indicate with the Error() function and a useful message.

After that we set the log mode, if logging has been enabled.

Next, we build the lists that help Torque find our add-ons. We notify Torque about the required folder paths by passing the list to the SetModPaths() function.

Then we call the main module for the common code. This will proceed to load all the required common modules into memory, initialize the common functions, and basically get the ball rolling over there. We will talk about the common code modules in a later chapter.

After that we do the same thing for the control code modules, the details of which we will cover later in this chapter.

Then we actually start loading the add-ons using the previously defined LoadAddOns() function.

Finally, we make a call to OnStart(). This will call all versions of OnStart() that appear in the add-on packages in order of their appearance in $addonList, with common being first, control next, and finally this root main module. If there is an OnStart() defined in common, then it gets called. Then the one in control, and so on.

When we get to the end of the module, the various threads initiated by the OnStart() calls are ticking over, doing their own things.

So now what? Well, our next point of interest is the control/main.cs module, which we called with the Exec() function just before we started loading the add-ons.




3D Game Programming All in One
3D Game Programming All in One (Course Technology PTR Game Development Series)
ISBN: 159200136X
EAN: 2147483647
Year: 2006
Pages: 197

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net