My program doesn't have bugs. It just develops random features.

Difference between revisions of "UE1:UE1PreProcessorCommandlet"

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
m (Changelog)
m (spelling and grammar fixes)
 
(37 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
__TOC__
 
__TOC__
 
==About==
 
==About==
This is preprocessor in form of ucc commandlet.
+
This is a preprocessor in the form of a ucc commandlet. Right now it's only available for UT1, but I'm working on a version for Unreal 1. For unknown reasons it gives me lots of errors on Unreal 1 224 sources.
  
 
==Install==
 
==Install==
Line 7: Line 7:
  
 
==Download==
 
==Download==
'''link:''' http://turniej.unreal.pl/files/UEnginePPC.zip (~93 kb)
+
As always source code is included in zip file.
 +
 
 +
===Unreal Tournament===
 +
'''link:''' [http://turniej.unreal.pl/files/UEnginePPC.zip UEnginePPC v. 0.5.296 for UT(~103kb)]
 +
 
 +
===Rune===
 +
'''link:''' [http://turniej.unreal.pl/files/UEnginePPC_Rune.zip UEnginePPC v. 0.3.168 for Rune (~633kb)]
 +
 
 +
===Unreal===
 +
Preprocessor is already included in patch 227 for Unreal 1.
  
 
==Usage==
 
==Usage==
In order to use preprocessor you have to call ucc with following parameters:
+
In order to use the preprocessor you have to call ucc with the following parameters:
 
<uscript>ucc uengineppc.parse project=[<project_dir>/<project_file>]  [-option...] [-globals...]</uscript>
 
<uscript>ucc uengineppc.parse project=[<project_dir>/<project_file>]  [-option...] [-globals...]</uscript>
 
      
 
      
 
===Parameters===
 
===Parameters===
 
*<project_dir> - relative project directory.
 
*<project_dir> - relative project directory.
*<project_file> - file (.upc extension) conaining all options. If file is detected, no fuhrer modifiers are checked
+
*<project_file> - file (.upc extension) containing all options. If file is detected, no further modifiers are checked
 
====Options====
 
====Options====
*-clean - deletes preprocessor directives from .uc file
+
{| class="wikitable"
*-debug - turns on debug mode (prints every operation on parsed .uc file)
+
 
*-printglobals - prints all global variables
+
|-
*-normalizeeol - tries to find \r and \n and change them into \r\n
+
| '''option'''
*-bIsPackage - when defining <project_dir> you can type only name of package. Path will be detected automatically.
+
| '''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 may type only the package name. 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
 +
|-
 +
| -force
 +
| forces all source .uc files to be parsed
 +
| yes
 +
|}
  
 
====Globals====
 
====Globals====
Each other parameter will be concidered as global variable. If '''=''' is not detected, global variable is equal null. Example:
+
All other parameters will be considered to be global variables. If '''=''' is not detected, global variable is equal null. Example:
 
      
 
      
 
     val1=1 val val2=3  
 
     val1=1 val val2=3  
Line 40: Line 83:
 
|-
 
|-
 
|`include(file)
 
|`include(file)
|embade file in the currently opened .uc (do not parses it)
+
|embed file in the currently opened .uc (do not parse it)
 
|-
 
|-
 
|`include(file,false)
 
|`include(file,false)
| embade file in the currently opened .uc (do not parses it)
+
| embed file in the currently opened .uc (do not parse it)
 
|-
 
|-
 
|`include(file,true)
 
|`include(file,true)
| embade file in the currently opened .uc and parses it
+
| embed file in the currently opened .uc and parses it
 
|-
 
|-
 
|`require(file)
 
|`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.
+
| embed file in the currently opened .uc (do not parse it). If required file doesn't exist, it stops parsing current file and produce error.
 
|-
 
|-
 
|`require(file,false)
 
|`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.
+
| embed file in the currently opened .uc (do not parse it). If required file doesn't exist, it stops parsing current file and produce error.
 
|-
 
|-
 
|`require(file,true)
 
|`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.
+
| embed file in the currently opened .uc and parses it. If required file doesn't exist, it stops parsing current file and produce error.
 
|-
 
|-
 
|`define(name)
 
|`define(name)
Line 84: Line 127:
 
| evaluates to true if variable name is not defined
 
| evaluates to true if variable name is not defined
 
|-
 
|-
|`if(name1==name2)
+
|`if ([expression1] [operator] [expression2])
| evaluates to true if variable name1 equals variable name2. Used in strings, floats, integers.
+
| checks to see if the first condition is true by comparing expression1 to expression2 using the operator.
 
|-
 
|-
|`if(name1<name2)
+
|`else if ([expression1] [operator] [expression2])
| evaluates to true if variable name1 does not match variable name2. Used in strings, floats, integers.
+
| checks to see if the first condition is true by comparing expression1 to expression2 using the operator, only if first condition is false..
|-
+
|`if(name1>name2)
+
| evaluates to true if variable name1 is greater then variable name2. Used in floats, integers.
+
|-
+
|`if(name1<name2)
+
| evaluates to true if variable name1 is less then name2. Used in floats, integers.
+
 
|-
 
|-
 
|`else
 
|`else
Line 106: Line 143:
 
|-
 
|-
 
|`write(name1==name2option1:option2)
 
|`write(name1==name2option1:option2)
| if statemente evaluate to true (variable name1 equals variable name2) writes option1 otherwise writes option 2
+
| if statement evaluates to true (variable name1 equals variable name2) writes option1 otherwise writes option 2
 
|-
 
|-
 
|`write(name1<>name2?option1:option2)
 
|`write(name1<>name2?option1:option2)
| if statemente evaluate to true (variable name1 does not match variable name2) writes option1 otherwise writes option 2
+
| if statement evaluates to true (variable name1 does not match variable name2) writes option1 otherwise writes option 2
 
|-
 
|-
 
|`write(name1>name2?option1:option2)
 
|`write(name1>name2?option1:option2)
| if statemente evaluate to true (variable name1 is greater then variable name2) writes option1 otherwise writes option 2
+
| if statement evaluates to true (variable name1 is greater then variable name2) writes option1 otherwise writes option 2
 
|-
 
|-
 
|`write(name1<name2?option1:option2)
 
|`write(name1<name2?option1:option2)
| if statemente evaluate to true (variable name1 is less then variable name2) writes option1 otherwise writes option 2
+
| if statement evaluates to true (variable name1 is less than variable name2) writes option1 otherwise writes option 2
 
|-
 
|-
 
|`write(name1?option1:option2)
 
|`write(name1?option1:option2)
| if statemente evaluate to true (variable name1 is defined) writes option1 otherwise writes option 2
+
| if statement evaluates to true (variable name1 is defined) writes option1 otherwise writes option 2
 
|-
 
|-
 
|`import(directory,extension,type,group,lodset,flags,package)
 
|`import(directory,extension,type,group,lodset,flags,package)
Line 124: Line 161:
 
|-
 
|-
 
|`namespace(name,value)
 
|`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
+
|defines namespace name with specified value. It's a combination of `define and `write. If namespace is detected, it'll be replaced by value, without need of using `write
 +
|-
 +
|`remove.start
 +
| everything below this directive will be deleted
 +
|-
 +
|`remove.end
 +
| disables `remove.start
 
|}
 
|}
  
Notice that all variables used in directive `if and trenary operation are parsed in following order:
+
Notice that all variables used in directive `if and ternary operation are parsed in the following order:
  
 
#Returns value from global variables if correct name is found, otherwise...
 
#Returns value from global variables if correct name is found, otherwise...
Line 135: Line 178:
 
====`import details:====
 
====`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:
+
As '''type''' you can use only '''TEXTURE''' and '''SOUND'''. If the extension is '''uax''' or '''utx''' the preprocessor will create '''#exec obj load''' instead of '''#exec type import'''. For example code below:
  
 
<uscript>`import(tex,pcx,TEXTURE,HUD)</uscript>
 
<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:
+
will make the preprocessor iterate through all files in folder <UT>/<Project>/tex in search for all *.pcx files. When a file with extension pcx is found, the preprocessor will create a 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"
 
<uscript>#exec TEXTURE IMPORT NAME=Tex001 FILE="tex/Tex001.pcx"
Line 145: Line 188:
 
#exec TEXTURE IMPORT NAME=Tex003 FILE="tex/Tex003.pcx"</uscript>
 
#exec TEXTURE IMPORT NAME=Tex003 FILE="tex/Tex003.pcx"</uscript>
  
====`namespacedetails:====
+
====`namespace details:====
  
 
Namespace can be useful to replace large parts of text, without need of use `write and `define directives. For example if you write directive:
 
Namespace can be useful to replace large parts of text, without need of use `write and `define directives. For example if you write directive:
Line 166: Line 209:
  
 
<uscript>`namespace(__SOMECLASS__,class'MyPackege.SomeClass'.static)</uscript>
 
<uscript>`namespace(__SOMECLASS__,class'MyPackege.SomeClass'.static)</uscript>
 +
 +
Namespace works also in `require and `include directive.
  
 
====Operators in conditional statement and write directive====
 
====Operators in conditional statement and write directive====
Line 185: Line 230:
 
|-
 
|-
 
| '''>='''
 
| '''>='''
| greeter or equal
+
| greater or equal
 
| float, integer
 
| float, integer
 
|-
 
|-
Line 207: Line 252:
 
====Unreal Engine version====
 
====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.
+
Since 0.2.106 UE1PreProcessorCommandlet can check the Unreal Engine version. This will be useful once the preprocessor is stable and compiled to U1.
  
 
<uscript>`if(__UENGINEVERSION__==436)
 
<uscript>`if(__UENGINEVERSION__==436)
Line 214: Line 259:
  
 
===Macros===
 
===Macros===
Macros are in fact hardcoded constants. Each macro will write something in currently parsed .uc file. Currently supported macros are:
+
Macros are in fact hardcoded constants. Each macro will write something in the currently parsed .uc file. Currently supported macros are:
  
 
*__FILE__ - will write name of currently parsed file, usable in conditional statements
 
*__FILE__ - will write name of currently parsed file, usable in conditional statements
Line 220: Line 265:
 
*__DATE__ - will write time
 
*__DATE__ - will write time
 
*__SELF__ - will write current package, usable in conditional statements
 
*__SELF__ - will write current package, usable in conditional statements
*__UENGINEVERSION__ - will write Unrean Engine version, usable in conditional statements<br>
+
*__UENGINEVERSION__ - will write Unreal Engine version, usable in conditional statements
 +
*__NUMERATE_CPP__ - replaces itself with a number and increments a counter (used in native functions). It's value depends on '''native_offset'''
 +
*__LINE__ - will write current line (parsed output)
 +
*__RELATIVE_LINE__ - will write current line (unparsed input)
 +
 
 +
===Functions===
 +
 
 +
You can also define functions in new section of project file, eg.:
 +
 
 +
<uscript>
 +
[functions]
 +
`log($value)=log($value,'ResidualDecay')
 +
</uscript>
 +
 
 +
Now when you call in code:
 +
 
 +
`log("Log message");
 +
 
 +
the parser will change it to:
 +
 
 +
log("Log message",'ResidualDecay');
 +
 
 +
'''Tips:'''
 +
 
 +
* Avoid using functions with similar names - eg.: `log and `logx will screw up result code.
 +
* Avoid using parameters with similar names in one function - eg.: `log($value1, $value2); will not work too good :).
 +
* Functions can only be defined in project file.
 +
 
 +
Eventually all bugs listed above will be eliminated (current implementation was written in ~5-10 minutes).
  
 
===Project file===
 
===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:
+
Project file must have upc extension, and 'path' must be relative to ucc.exe location. Default location for files with preprocessor Unreal Script files is:
  
 
<uscript><project_folder>/classes/preprocessor</uscript>
 
<uscript><project_folder>/classes/preprocessor</uscript>
Line 233: Line 306:
 
Here's all commands for project file.
 
Here's all commands for project file.
  
<uscript>[project]                - project informations
+
<uscript>[project]                - project information
 
path=path                - path to project
 
path=path                - path to project
 
debug=true                - turns on debug mode (prints every operation on parsed .uc)
 
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=true                - if true, ucc commandlet will run make after parsing all files
 
make_ini=make.ini        - ini used in ucc make commandlet
 
make_ini=make.ini        - ini used in ucc make commandlet
clean=true                - if true will delete preprocessor directives
+
clean=true                - if true, will delete preprocessor directives
 
output=folder            - override default output folder where parsed .uc files are written
 
output=folder            - override default output folder where parsed .uc files are written
 
input=folder              - override default input folder where parsed .uc files are stored
 
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.
+
bIsPackage=true          - when defining path you may 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
 +
native_offset            - offset for __NUMERATE_CPP__ macro (starting number)
 +
bForce=true              - if true forces all source .uc files to be parsed
 +
printnamespace=true      - will print global namespace if true
 +
bClearOutput=true        - will delete all output files before parsing input
 +
printmacros=true          - will print all global macros if true
 +
native_offset=1600        - offset when using __NUMERATE_CPP__ macro
 +
 
 +
[globals]                - group containing global variables for whole project
 +
someglobal=somevalue      - global variable (sample)
 +
 
 +
[namespace]
 +
some_namespace=some_value - declares namespace 'some_namespace' with value equal 'some_value' (for usage see `namespace details)
  
[globals]                 - group contatin global variables for whole project
+
[functions]
someglobal=somevalue      - global variable (sample)</uscript>
+
`some_function($some_value)=log($some_value,'ResidualDecay') - declares function `some_function
 +
</uscript>
  
 
example:
 
example:
Line 307: Line 395:
  
 
#directive `process  is found, so preprocessor knows that this class has to be parsed.
 
#directive `process  is found, so preprocessor knows that this class has to be parsed.
#directive `include is found. Preprocessor embade file default_header.uc and parses it
+
#directive `include is found. Preprocessor embeds file default_header.uc and parses it
 
#macro __DATE__ is found and current date is inserted at its place
 
#macro __DATE__ is found and current date is inserted at its place
#directive `write is found. Because expression evaluates to ture first value - (2330) - is inserted at it's place
+
#directive `write is found. Because expression evaluates to true, first value - (2330) - is inserted at it's place
  
 
output .uc file will look like this:
 
output .uc file will look like this:
Line 332: Line 420:
  
 
==Changelog==
 
==Changelog==
 +
*'''v 0.5.296'''
 +
** Added two new macros
 +
*'''v 0.5.262'''
 +
** Added new advanced functions to define in new section of project file
 +
*'''v 0.4.194'''
 +
** Added new `remove.start and `remove.end directives to remove larger parts of code
 +
** Namespaces are now usable in `include and `require directives
 +
*'''v 0.4.194'''
 +
** Added new global namespace
 +
*'''v 0.3.185'''
 +
** Added new __NUMERATE_CPP__ macro
 +
** Added new commadline option -force
 +
** Added new project option bForce
 +
** Various updates and fixes
 +
*'''v 0.3.168'''
 +
** Fixed bug in GetVariable function. Variable search is aborted if name is NULL.
 +
*'''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'''
 
*'''v 0.2.106'''
 
**new directive `namespace
 
**new directive `namespace

Latest revision as of 09:02, 22 April 2016

About[edit]

This is a preprocessor in the form of a ucc commandlet. Right now it's only available for UT1, but I'm working on a version for Unreal 1. For unknown reasons it gives me lots of errors on Unreal 1 224 sources.

Install[edit]

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

Download[edit]

As always source code is included in zip file.

Unreal Tournament[edit]

link: UEnginePPC v. 0.5.296 for UT(~103kb)

Rune[edit]

link: UEnginePPC v. 0.3.168 for Rune (~633kb)

Unreal[edit]

Preprocessor is already included in patch 227 for Unreal 1.

Usage[edit]

In order to use the preprocessor you have to call ucc with the following parameters:

ucc uengineppc.parse project=[<project_dir>/<project_file>]  [-option...] [-globals...]

Parameters[edit]

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

Options[edit]

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 may type only the package name. 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
-force forces all source .uc files to be parsed yes

Globals[edit]

All other parameters will be considered to be global variables. If = is not detected, global variable is equal null. Example:

   val1=1 val val2=3 

Directives[edit]

Currently supported directives are:

directive description
`process should be in the first line of .uc file. Tells preprocessor to parse file
`include(file) embed file in the currently opened .uc (do not parse it)
`include(file,false) embed file in the currently opened .uc (do not parse it)
`include(file,true) embed file in the currently opened .uc and parses it
`require(file) embed file in the currently opened .uc (do not parse it). If required file doesn't exist, it stops parsing current file and produce error.
`require(file,false) embed file in the currently opened .uc (do not parse it). If required file doesn't exist, it stops parsing current file and produce error.
`require(file,true) embed file in the currently opened .uc and parses it. If required file doesn't exist, 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 statement evaluates to true (variable name1 equals variable name2) writes option1 otherwise writes option 2
`write(name1<>name2?option1:option2) if statement evaluates to true (variable name1 does not match variable name2) writes option1 otherwise writes option 2
`write(name1>name2?option1:option2) if statement evaluates to true (variable name1 is greater then variable name2) writes option1 otherwise writes option 2
`write(name1<name2?option1:option2) if statement evaluates to true (variable name1 is less than variable name2) writes option1 otherwise writes option 2
`write(name1?option1:option2) if statement evaluates 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 a combination of `define and `write. If namespace is detected, it'll be replaced by value, without need of using `write
`remove.start everything below this directive will be deleted
`remove.end disables `remove.start

Notice that all variables used in directive `if and ternary operation are parsed in the 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:[edit]

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

`import(tex,pcx,TEXTURE,HUD)

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

#exec TEXTURE IMPORT NAME=Tex001 FILE="tex/Tex001.pcx"
#exec TEXTURE IMPORT NAME=Tex002 FILE="tex/Tex002.pcx"
#exec TEXTURE IMPORT NAME=Tex003 FILE="tex/Tex003.pcx"

`namespace details:[edit]

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

`namespace(__SOMECLASS__,class'SomeClass'.static)

and use it in code:

__SOMECLASS__.SomeFunction();

parsed code will change to:

class'SomeClass'.static.SomeFunction();

You can also use macros:

`namespace(__SOMECLASS__,class'__SELF__.SomeClass'.static)

assuming that your package is MyPackege this directive means:

`namespace(__SOMECLASS__,class'MyPackege.SomeClass'.static)

Namespace works also in `require and `include directive.

Operators in conditional statement and write directive[edit]

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[edit]

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

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

Macros[edit]

Macros are in fact hardcoded constants. Each macro will write something in the 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 Unreal Engine version, usable in conditional statements
  • __NUMERATE_CPP__ - replaces itself with a number and increments a counter (used in native functions). It's value depends on native_offset
  • __LINE__ - will write current line (parsed output)
  • __RELATIVE_LINE__ - will write current line (unparsed input)

Functions[edit]

You can also define functions in new section of project file, eg.:

[functions]
`log($value)=log($value,'ResidualDecay')

Now when you call in code:

`log("Log message");

the parser will change it to:

log("Log message",'ResidualDecay');

Tips:

  • Avoid using functions with similar names - eg.: `log and `logx will screw up result code.
  • Avoid using parameters with similar names in one function - eg.: `log($value1, $value2); will not work too good :).
  • Functions can only be defined in project file.

Eventually all bugs listed above will be eliminated (current implementation was written in ~5-10 minutes).

Project file[edit]

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

<project_folder>/classes/preprocessor

parsed .uc files will be stored in:

<project_folder>/classes

Here's all commands for project file.

[project]                 - project information
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 may 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
native_offset             - offset for __NUMERATE_CPP__ macro (starting number)
bForce=true               - if true forces all source .uc files to be parsed
printnamespace=true       - will print global namespace if true
bClearOutput=true         - will delete all output files before parsing input
printmacros=true          - will print all global macros if true
native_offset=1600        - offset when using __NUMERATE_CPP__ macro
 
[globals]                 - group containing global variables for whole project
someglobal=somevalue      - global variable (sample)
 
[namespace]
some_namespace=some_value - declares namespace 'some_namespace' with value equal 'some_value' (for usage see `namespace details)
 
[functions]
`some_function($some_value)=log($some_value,'ResidualDecay') - declares function `some_function

example:

[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

Example[edit]

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

[project]
path=../REmitter/
debug=true
make=false
make_ini=make.ini
clean=true
output=classes
input=classes/preprocessor
printglobals=true
 
[globals]
__NUM_NATIVES__=1

and classes:

REmitterBase.uc

`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);

default_header.uc

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2005-2008 Dead Cow Studios. All Rights Reserved.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Coder: Raven
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Last revision: __DATE__
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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 embeds 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 true, first value - (2330) - is inserted at it's place

output .uc file will look like this:

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright 2005-2008 Dead Cow Studios. All Rights Reserved.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Coder: Raven
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Last revision: 21-9-2008 20:1
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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);

Changelog[edit]

  • v 0.5.296
    • Added two new macros
  • v 0.5.262
    • Added new advanced functions to define in new section of project file
  • v 0.4.194
    • Added new `remove.start and `remove.end directives to remove larger parts of code
    • Namespaces are now usable in `include and `require directives
  • v 0.4.194
    • Added new global namespace
  • v 0.3.185
    • Added new __NUMERATE_CPP__ macro
    • Added new commadline option -force
    • Added new project option bForce
    • Various updates and fixes
  • v 0.3.168
    • Fixed bug in GetVariable function. Variable search is aborted if name is NULL.
  • 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