UE1PreProcessorCommandlet

From Oldunreal-Wiki
Jump to: navigation, search

About

This is preprocessor in form of ucc commandlet. Right now it's implemented in Unreal 227 and available for UT1. From unknown reasons it gives me lots of errors on Unreal 1 224 sources.

Install

Unreal 227:
implemented already.

UnrealTournament:
Copy files in the archive to your <UTdir> folder.

Download UT Version

link: http://turniej.unreal.pl/files/UEnginePPC.zip (~93 kb)

Usage

In order to use preprocessor you have to call ucc with following parameters: <uscript>ucc uengineppc.parse project=[<project_dir>/<project_file>] [-option...] [-globals...]</uscript>

Parameters

  • <project_dir> - relative project directory.
  • <project_file> - file (.upc extension) conaining all options. If file is detected, no fuhrer modifiers are checked

Options

option description override by project file
-clean deletes preprocessor directives from .uc file yes
-debug turns on debug mode (prints every operation on parsed .uc file) yes
-printglobals prints all global variables yes
-normalizeeol tries to find \r and \n and change them into \r\n yes
-bIsPackage when defining <project_dir> you can type only name of package. Path will be detected automatically. yes
-bIniVersion macro __UENGINEVERSION__ will return uengine version saved in INI (FirstRun param), if false, it'll return version saved in engine. yes
-deletelog scans UScript source for log functions and deletes it yes

Globals

Each other parameter will be concidered as global variable. If = is not detected, global variable is equal null. Example:

   val1=1 val val2=3 

Directives

Currently supported directives are:

directive description
`process should be in the first line of .uc file. Tells preprocessor to parse file
`include(file) embade file in the currently opened .uc (do not parses it)
`include(file,false) embade file in the currently opened .uc (do not parses it)
`include(file,true) embade file in the currently opened .uc and parses it
`require(file) embade file in the currently opened .uc (do not parses it). If required file doesn't exists, it stops parsing current file and produce error.
`require(file,false) embade file in the currently opened .uc (do not parses it). If required file doesn't exists, it stops parsing current file and produce error.
`require(file,true) embade file in the currently opened .uc and parses it. If required file doesn't exists, it stops parsing current file and produce error.
`define(name) defines variable name (used in `ifdef and `ifndef directives)
`define(name,value) defines variable name with specified value (used in `if and ternary operation)
`undef(name) removes name from local definitions
`error(name1,true) produces error message and exits commandlet
`error(name1) produces error message and stops parsing current file
`warn(name1) produces warning message
`log(name1) produces message
`ifdef(name) evaluates to true if variable name is defined
`ifndef(name) evaluates to true if variable name is not defined
`if ([expression1] [operator] [expression2]) checks to see if the first condition is true by comparing expression1 to expression2 using the operator.
`else if ([expression1] [operator] [expression2]) checks to see if the first condition is true by comparing expression1 to expression2 using the operator, only if first condition is false..
`else part of conditional statement
`endif ends conditional statement
`write(name) writes defined variable name
`write(name1==name2option1:option2) if statemente evaluate to true (variable name1 equals variable name2) writes option1 otherwise writes option 2
`write(name1<>name2?option1:option2) if statemente evaluate to true (variable name1 does not match variable name2) writes option1 otherwise writes option 2
`write(name1>name2?option1:option2) if statemente evaluate to true (variable name1 is greater then variable name2) writes option1 otherwise writes option 2
`write(name1<name2?option1:option2) if statemente evaluate to true (variable name1 is less then variable name2) writes option1 otherwise writes option 2
`write(name1?option1:option2) if statemente evaluate to true (variable name1 is defined) writes option1 otherwise writes option 2
`import(directory,extension,type,group,lodset,flags,package) can be used to import textures/sounds from chosen directory
`namespace(name,value) defines namespace name with specified value. It's combination of `define and `write. If namespace will be detected, it'll be replaced by value, without need of using `write

Notice that all variables used in directive `if and trenary operation are parsed in following order:

  1. Returns value from global variables if correct name is found, otherwise...
  2. Returns value from local variables if correct name is found, otherwise...
  3. Assumes that name is value.

`import details:

As type you can use only TEXTURE and SOUND. If extension will be uax or utx preprocessor will create #exec obj load instead of #exec type import. For example code below:

<uscript>`import(tex,pcx,TEXTURE,HUD)</uscript>

Will make preprocessor iterate through all files in folder <UT>/<Project>/tex in search for all *.pcx files. When file with extension pcx will be found, preprocessor will create UScript #exec directive to import texture into group HUD. Group, LodStet, Flags and Package parameters are optional. Result will look like:

<uscript>#exec TEXTURE IMPORT NAME=Tex001 FILE="tex/Tex001.pcx"

  1. exec TEXTURE IMPORT NAME=Tex002 FILE="tex/Tex002.pcx"
  2. exec TEXTURE IMPORT NAME=Tex003 FILE="tex/Tex003.pcx"</uscript>

`namespacedetails:

Namespace can be useful to replace large parts of text, without need of use `write and `define directives. For example if you write directive:

<uscript>`namespace(__SOMECLASS__,class'SomeClass'.static)</uscript>

and use it in code:

<uscript>__SOMECLASS__.SomeFunction();</uscript>

parsed code will change to:

<uscript>class'SomeClass'.static.SomeFunction();</uscript>

You can also use macros:

<uscript>`namespace(__SOMECLASS__,class'__SELF__.SomeClass'.static)</uscript>

assuming that your package is MyPackege this directive means:

<uscript>`namespace(__SOMECLASS__,class'MyPackege.SomeClass'.static)</uscript>

Operators in conditional statement and write directive

operator description type
== equal string, float, integer, bool
<> not equal string, float, integer, bool
>= greater or equal float, integer
<= less or equal float, integer
< less float, integer
> greater float, integer
! negation, works as `ifndef

Unreal Engine version

Since 0.2.106 UE1PreProcessorCommandlet can check Unreal Engine version. This will be useful once preprocessor will be stable and compiled to U1.

<uscript>`if(__UENGINEVERSION__==436) //some UT436 specific code `endif</uscript>

Macros

Macros are in fact hardcoded constants. Each macro will write something in currently parsed .uc file. Currently supported macros are:

  • __FILE__ - will write name of currently parsed file, usable in conditional statements
  • __CLASS__ - will write name of currently parsed class, usable in conditional statements
  • __DATE__ - will write time
  • __SELF__ - will write current package, usable in conditional statements
  • __UENGINEVERSION__ - will write Unrean Engine version, usable in conditional statements

Project file

Project file must have upc extension, and 'path' must be relative to ucc.exe location. Default location to files with preprocessor Unreal Script files is:

<uscript><project_folder>/classes/preprocessor</uscript>

parsed .uc files will be stored in:

<uscript><project_folder>/classes</uscript>

Here's all commands for project file.

<uscript>[project] - project informations path=path - path to project debug=true - turns on debug mode (prints every operation on parsed .uc) make=true - if true ucc commandlet will run make after parsing all files make_ini=make.ini - ini used in ucc make commandlet clean=true - if true will delete preprocessor directives output=folder - override default output folder where parsed .uc files are written input=folder - override default input folder where parsed .uc files are stored bIsPackage=true - when defining path you can type only name of package. Path will be detected automatically. bIniVersion=true - if true, macro __UENGINEVERSION__ will return uengine version saved in INI (FirstRun param), if false, it'll return version saved in engine. bDeleteLog=true - scans UScript source for log functions and deletes it

[globals] - group contatin global variables for whole project someglobal=somevalue - global variable (sample)</uscript>

example:

<uscript>[project] path=../MyProject/ debug=true make=true make_ini=make.ini clean=true output=classes input=classes/preprocessor bIsPackage=false

[globals] global_value1=test1 global_value2=test2</uscript>

Example

Let's say you have project file in <UDir>/system called REmitter.upc with content:

<uscript>[project] path=../REmitter/ debug=true make=false make_ini=make.ini clean=true output=classes input=classes/preprocessor printglobals=true

[globals] __NUM_NATIVES__=1</uscript>

and classes:

REmitterBase.uc <uscript>`process `include(classes/includes/default_header.uc,true) // Base class for emitter related actors. // Quaternion implementation originally written by UsAaR33. class REmitterBase extends Actor native;

struct Quat { var() config float W, X, Y, Z; }; //converts rotator to quaternion native`write(__NUM_NATIVES__==1?(2330):) static final function Quat RotationToQuat( rotator R, bool bHighPrecision);</uscript>

default_header.uc <uscript>//10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)admin 10:04, 12 February 2009 (UTC) // Copyright 2005-2008 Dead Cow Studios. All Rights Reserved. // 10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)admin // Coder: Raven // 10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)admin // Last revision: __DATE__ // 10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)admin</uscript>

You run preprocessor and:

  1. directive `process is found, so preprocessor knows that this class has to be parsed.
  2. directive `include is found. Preprocessor embade file default_header.uc and parses it
  3. macro __DATE__ is found and current date is inserted at its place
  4. directive `write is found. Because expression evaluates to ture first value - (2330) - is inserted at it's place

output .uc file will look like this:

<uscript>//10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)admin 10:04, 12 February 2009 (UTC) // Copyright 2005-2008 Dead Cow Studios. All Rights Reserved. // 10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)admin // Coder: Raven // 10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)admin // Last revision: 21-9-2008 20:1 // 10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)10:04, 12 February 2009 (UTC)admin // Base class for emitter related actors. // Quaternion implementation originally written by UsAaR33. class REmitterBase extends Actor native;

struct Quat { var() config float W, X, Y, Z; }; //converts rotator to quaternion native(2330) static final function Quat RotationToQuat( rotator R, bool bHighPrecision);</uscript>

Changelog

  • v 0.3.150
    • added option to delete log calls out of UScript source
  • v 0.3.144
    • added bIniVersion to commandline and project file (changes the way macro __UENGINEVERSION__ works)
  • v 0.2.123
    • new directive `else if
  • v 0.2.106
    • new directive `namespace
    • new macro __UENGINEVERSION__
    • new macro __SELF__
    • macros can be used in conditional statements
  • v 0.2.56
    • new directive `import used to create #exec directive for large number of textures/sounds
  • v 0.1.35
    • fixed directive `write bug (now it doesn't ignore defined variables)
  • v 0.1.5
    • added new option bIsPackage
  • v 0.1.4
    • fixed bug with inline `write directive
  • v 0.1.1
    • initial release