请选择 进入手机版 | 继续访问电脑版

cronusmax

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 33552|回复: 0

克迈GPC脚本编写中英文完整教程

[复制链接]

346

主题

346

帖子

1154

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1154
发表于 2020-11-15 17:45:31 | 显示全部楼层 |阅读模式
                克迈GPC脚本编写中英文教程

可以加克迈官方QQ群1106395324讨论

学习编程
很多朋友問到,某些巨集的使用語法,其實所有語法都在這裡有詳列:  http://cronusmax.com/manual/basic_syntax.htm
另外這是 6種不同手把按鍵的定義名詞: http://cronusmax.com/manual/iden ... ct=MjQ5&mw=MzIw
當然天書就留給大神們去看了,這邊解說一下幾個最常用的簡單語法,足夠大家可以馬上套用的!  

1. #組合技! (只執行一次)
main {
      if(get_val(PS4_R3)) {                 //按下R3啟動指令一次
         combo_run(onetime);  //要執行的巨集, 隨便取名叫onetime
     }
}
combo onetime {       //以下巨集的動作, 以3oss為範例
     set_val(PS4_L1, 100);   // 按下L1
     wait(1000);            // 等一秒鐘! 這些秒數都可以自行再做調整
  set_val(PS4_L1, 100);      //這個表示同時按下L1+方塊
  set_val(PS4_SQUARE, 100);
  wait(650);
  set_val(PS4_L1, 100);
  set_val(PS4_TRIANGLE, 100);
  wait(1350);
  set_val(PS4_L1, 100);
  set_val(PS4_SQUARE, 100);
  wait(650);
}  //打完一次就結束收工

==============================
2. #單鍵無限重覆! 我們的連發和連發搖桿不同,連發搖桿要一直按著某個鍵能連發。我們的連發是只要按一下,就能一直連發,直到再按一下同一個鍵就會停止:
int onoff;
main {
      if(event_press(PS4_R3)) onoff=!onoff;   //按下R3後重覆執行
      if(onoff){
       combo_run(repeat);
       }
}
combo repeat {         //以下是要執行的動作,隨便取名為 repeat
      set_val(PS4_SQUARE,100);  //按下方塊鍵
      wait(40);                                  //等0.04秒
      set_val(PS4_SQUARE,100);
       wait(40); }                     //會再重頭執行指令無限次

因此若是您想無限執行某組合技,只要把組合技語法放到重覆執行的指令中(就是repeat 底下的位置) 就可以了
=======================
3. 如果您只想執行某指令5次6次呢? 那我們就需要以 #單次複式 的語法來處理。
main {
      if(get_val(PS4_R3)) {       //按下R3起動指令
          combo_run(nTimes);   //隨便取名叫 n Times
              }
}
combo nTimes {           //nTimes 動作如下  
call (oss1);    //執行另外設的 oss1動作
  wait(600);  //等0.6秒
  call (oss1);
  wait(600);
  call (oss1);    //想執行幾次就 call 幾次出來
  }

combo oss1 {                 //這裡當然就是把您的oss1寫在這裡
  set_val(PS4_L1, 100);
     wait(500);
  set_val(PS4_L1, 100);
  set_val(PS4_SQUARE, 100);
  wait(500);
  set_val(PS4_L1, 100);
  set_val(PS4_TRIANGLE, 100);
}
combo oss2{      //如果想多做幾個不同的指令就繼續編輯再call出來就行
set_val(PS4_L1, 100);
  set_val(PS4_TRIANGLE, 100);
}

                    Basic Syntax(基本语法)

1、Instruction Separation(指令分隔符)
As in C, GPC requires instructions to be terminated with a semicolon at the end of each statement. However, the closing tag of a block code automatically implies a semicolon, so a semicolon is not needed when terminating the last line of a GPC block.(与C中一样,GPC要求指令在每条语句的末尾以分号结束。但是,块代码的结束标记自动暗示分号,因此在结束GPC块的最后一行时不需要分号)
main {
    sensitivity(XB1_LY, NOT_USE, 80);
    a = b * ( c + 20 )
}
Although the semicolon is not required in the final line of a block, it is considered good practice to use one so it is not missed should you expand on the code at a later date.(虽然分号不需要出现在代码块的最后一行,但是使用分号被认为是一种良好的实践,因此在以后扩展代码时不会漏掉它。)
2、Nesting Code(嵌套代码)
Nesting code, or creating a logic block, binds code together.  A Block starts with a { and end with a }.  What this does is nest the code with the { and } meaning that the code is only executed when the statement before it is active.(嵌套代码,或创建逻辑块,将代码绑定在一起。块以{开始,以}结束。它所做的是用{和}嵌套代码,这意味着代码只在它前面的语句处于活动状态时执行。)
In this example;(在这个例子中;)
main
{ //Main Start
    if(get_val(PS4_R2))
    { //Block 1 Start
        if(get_val(PS4_L2))
        { //Block 2 Start
            combo_run(RAPID_FIRE_ADS);
        } //Block 2 End
        else
        { //Block 3 Start
            combo_run(RAPID_FIRE);
        } //Block 3 End
    } //Block 1 End
} //Main End
Blocks 2 & 3 are ignored unless Block 1 is active.  So if the R2 button is not pressed, nothing happens.  If R2 is pressed, then the CronusMAX looks at Block 2.  If L2 is pressed, it will run the combo RAPID_FIRE_ADS and ignore Block 3.  However, if L2 is not pressed, it will ignore Block 2 and instead execute the code in Block 3 and then run combo RAPID_FIRE.(块2和块3将被忽略,除非块1处于活动状态。所以如果没有按下R2按钮,什么也不会发生。如果R2被压下,CronusMAX就会查看Block 2。如果按下L2,它将运行组合RAPID_FIRE_ADS并忽略块3。但是,如果没有按下L2,它将忽略Block 2,而是执行Block 3中的代码,然后运行combo RAPID_FIRE。)
Nesting is implied if you only have one line of code after a statement.  As in this example;(如果语句后面只有一行代码,则隐含嵌套。就像这个例子一样;)
main {
    if(get_val(XB1_RT) > 95)
        combo_run(RAPID_FIRE);
}
When compiled, the line combo_run(RAPID_FIRE); will automatically be nested within the if statement.  If you wish for more than one line of code to only be executed when the statement before them is active, then you must use { and }.(编译时,行combo_run(RAPID_FIRE);将自动嵌套在if语句中。如果希望在前面的语句处于活动状态时执行多行代码,则必须使用{和}。)
3、Commenting Code(注释的代码)
A comment is text which is ignored by the compiler.  Comments are usually used to annotate code for future reference or to add notes for others looking at the code.  However, they can also be used to make certain lines of code inactive to aid when debugging scripts.  If you have programmed in C before then GPC comments will be familiar to you as it uses the same style.(注释是编译器会忽略的文本。注释通常用于对代码进行注释,以便将来参考,或者为查看代码的其他人添加注释。但是,它们也可以用于使某些代码行处于非活动状态,以帮助调试脚本。如果你以前用C编程过,那么GPC注释对你来说会很熟悉,因为它使用的是相同的风格。)
There are two types of comments, the Single Line Comment and the Multi Line Comment.(有两种类型的注释,单行注释和多行注释。)
Single Line Comment(单行注释)
The // (two slashes) characters creates a single line comment and can be followed by any sequence of character.  A new line terminates this form of comment. As shown below(//(两个斜杠)字符创建单行注释,可以后跟任何字符序列。一个新行终止这种形式的注释。如下所示)
main {
    // A single line comment
    if(get_val(XB1_RT) > 95)
        // Another single line comment
        combo_run(RAPID_FIRE);
}
Multi Line Comment(多行注释)
The /* (slash, asterisk) characters starts a multi line comment and can also be follow by any sequence of characters.  The multi line comment terminates when the first */ (asterisk, slash) is found. As shown below(/*(斜杠,星号)字符以多行注释开始,也可以跟在任何字符序列之后。当找到第一个*/(星号,斜杠)时,多行注释终止。如下所示)
main {
    /* A multi line comment
    if(get_val(XB1_RT) > 95)
        combo_run(RAPID_FIRE);
    */
}
As the comment terminates when a */ (asterisk, slash) is found, this style of commenting cannot be nested.  As shown below(由于在找到*/(星号,斜杠)时注释终止,所以这种风格的注释不能嵌套。如下所示)
main {
    /* A multi line comment
    if(get_val(XB1_RT) > 95)
        combo_run(RAPID_FIRE); /*This will cause a problem*/
    */
}
       A Simple Tutorial(开始新的教程)
This basic tutorial will show you how to create your first script (A basic Rapid Fire Script) and how it could be expanded on.(本教程将向您展示如何创建您的第一个脚本(一个基本的快速脚本),以及如何扩展它。)
Step 1(步骤1)
Load Cronus PRO and go to the File Dropdown menu and select New and then Empty File(加载Cronus PRO,进入文件下拉菜单,选择新建,然后是空文件)

Step 2(步骤2)
Either type or copy and paste the following code into the GPC code editor within Cronus PRO在Cronus PRO的GPC代码编辑器中键入或复制粘贴以下代码
main{
    if(get_val(XB1_RT)){
        combo_run(RAPID_FIRE);
    }
}
combo RAPID_FIRE{
    set_val(XB1_RT, 100);
    wait(40);
    set_val(XB1_RT, 0);
    wait(30);
    set_val(XB1_RT, 0);
}
Step 3(步骤3)
Compile the code to check for errors. To do this, either press on your keyboard or go to the Compiler dropdown menu in Cronus PRO and select compile编译代码以检查错误。要做到这一点,要么按下键盘上的F7,要么进入Cronus PRO中的编译器下拉菜单,选择compile

The Output window below the GPC editor should give you this message;(GPC编辑器下面的输出窗口应该会给你这个消息;)
------ GPC: Build started ------
   > 1: New* :
   > Bytecode size: 148 bytes (3.6%)
   > Stack memory: 3 words (2.7%)
   Build succeeded with 0 warnings...
If your CronusMAX PLUS is connected via the PC PROG port and you have controller connected, you can see this script in action by using the Build and Run option.  This is accessed by either pressing F5 or selecting Build and Run in the Compiler Dropdown menu.  This function will compile the code and then send it to your CronusMAX PLUS so you can test it.(如果你的CronusMAX PLUS是通过PC PROG端口连接的,并且你已经连接了控制器,你可以通过使用Build and Run选项看到这个脚本的运行效果。可以通过按F5或选择编译器下拉菜单中的Build和Run来访问。该函数将编译代码,然后将其发送到您的CronusMAX PLUS,以便您可以测试它。)
Script Breakdown(脚本分解)
What this script does is run the combo named RAPID_FIRE whenever the right trigger has a value or is pressed. If the Right Trigger is still held when the combo ends, it will be run again.(该脚本所做的是在右触发器有值或被按下时运行名为RAPID_FIRE的组合。如果组合结束时右触发器仍然持有,它将再次运行。)
To analyse how the CronusMAX PLUS is told how to do this we must first break the script down into its two sections, the main and combo sections.(要分析CronusMAX PLUS是如何被告知如何做到这一点的,我们必须首先将脚本分解为两个部分,主要部分和组合部分。)
The Main Section(主要部分)
main{
    if(get_val(XB1_RT)){
        combo_run(RAPID_FIRE);
    }
}
As explained here, the main section is run in a loop by the CronusMAX PLUS.  The Virtual Machine in the CronusMAX runs through the code in order and when it reaches the end of the code, data is sent to the console and then the Virtaul Machine starts the next loop.(正如这里所解释的,主节是由CronusMAX PLUS循环运行的。CronusMAX中的虚拟机按顺序运行代码,当到达代码末尾时,数据被发送到控制台,然后Virtaul机器开始下一个循环。)
if(get_val(XB1_RT))
The above line is telling the CronusMAX that if the statement is TRUE, run the nested code.  In this case, if XB1_RT (Right Trigger) has a value greater than 0 (Zero) so is pressed or not at rest.(上面的代码告诉CronusMAX,如果语句为真,就运行嵌套代码。在本例中,如果XB1_RT(右触发器)的值大于0(零),则按下或不按下。)
{
        combo_run(RAPID_FIRE);
    }
Above is the code nested within the if statement.  Nesting code creates a hierarchical structure.  An open curly bracket ( { )starts the nesting and a closed curly bracket ( } ) ends it.  By nesting code within the if statement we are telling the CronusMAX that we only wish for that code to be executed only when the if statement is TRUE.  More information on nesting code can be found here.(上面是嵌套在if语句中的代码。嵌套代码创建一个层次结构。左花括号({)开始嵌套,右花括号(})结束嵌套。通过在if语句中嵌套代码,我们是在告诉CronusMAX,只有当if语句为真时,我们才希望执行该代码。嵌套代码的更多信息可以在这里找到。)
combo_run(RAPID_FIRE);
This line simply tells the CronusMAX to run the combo named RAPID_FIRE.  It is important to note that if the CronusMAX receives this instruction and the combo is already running it will not do anything.  It will only run the combo again if it has finished.  This means that if you hold down the Right Trigger with this code active, the CronusMAX start the combo and then run it again as soon as it has ended.  Therefore running the combo in an indefinite loop or until such time as the Right Trigger is released.(这一行只是告诉CronusMAX运行名为RAPID_FIRE的组合。值得注意的是,如果CronusMAX接收到这个指令,并且这个组合已经在运行,它将不会做任何事情。它只会在完成时再次运行组合。这意味着,如果你按住右触发器并激活此代码,CronusMAX将启动组合,并在组合结束时再次运行它。因此,在不定循环中运行组合,或者直到释放正确的触发器。)
The Combo Section(组合部分)
combo RAPID_FIRE{
    set_val(XB1_RT, 100);
    wait(40);
    set_val(XB1_RT, 0);
    wait(30);
    set_val(XB1_RT, 0);
}
This is the combo which the CronusMAX is instructed to run when the Right Trigger is pressed.  When run, a combo runs through the code until it gets to a wait statement. The wait statement instructs combo to execute the commands above it for a set amount of time which is expressed in milliseconds.(当按下正确的扳机时,CronusMAX就会按照指令运行这个组合。当运行时,组合将遍历代码,直到它到达wait语句为止。wait语句指示combo在一段以毫秒为单位的时间内执行上面的命令。)
set_val(XB1_RT, 100);
    wait(40);
These lines instruct the combo to set the value of the Right Trigger to 100 (or fully pressed) for 40 milliseconds.(这些行指示组合将右触发器的值设置为100(或完全按下),持续40毫秒。)
set_val(XB1_RT, 0);
    wait(30);
Once the 40 milliseconds has passed, these lines instruct the combo to set the Right Trigger to 0 (Release) for 30 milliseconds.(一旦40毫秒过去,这些行指示组合将右触发器设置为0 (Release),持续30毫秒。)
Additional detail on how a combo operates can be found here.(关于组合如何运作的更多细节可以在这里找到。)
Expanding the code(扩展的代码)
Now that you understand how this script works, we will make it more complex and change when the combo is run.(现在您已经了解了这个脚本的工作原理,我们将使其更加复杂,并在运行组合时进行更改。)
Look at this line in the main section;(看看主部分的这一行;)
if(get_val(XB1_RT)){
and change it to;(并将其改为;)
if(get_val(XB1_RT) && !get_val(XB1_LT)){
by introducing && !get_val(XB1_LT) in to the if statement we are telling the CronusMAX to only run the combo if the Right Trigger has a value and the Left Trigger does not.(通过在if语句中引入&& !get_val(XB1_LT),我们告诉CronusMAX只在右触发器有值而左触发器没有值的情况下运行组合。)
&& means 'and' in GPC and ! means not.  So the if statement now reads 'if Right Trigger has a value and Left Trigger does not'. Which means when using this code in game the CronusMAX will only Rapid Fire your gun when you are not aiming down the sights. (“&&”在GPC意味着“和”“!”意味着“没有”。所以if语句现在读作“如果右触发器有一个值,左触发器没有”。这意味着当在游戏中使用这个代码时,CronusMAX只会在你没有瞄准时快速开火。)
You can use the build and run function to see this code in action.(您可以使用build and run函数查看这些代码的实际运行情况。)
             Basic GPC Structure(基本的GPC结构)
A GPC script can be split into sections.  There can be a total of 8 different sections and, in any user made script, they should be laid out in the order shown in the example below.  Only the main section is mandatory as it is the heart of any script and is run in a constant loop.(GPC脚本可以被分成几个部分。总共可以有8个不同的部分,在任何用户制作的脚本中,它们应该按照下面示例中所示的顺序排列。只有main部分是必须的,因为它是任何脚本的核心,并且在一个常量循环中运行。)
You can download this script here or search 'Basic GPC' in the GPC library should you wish to load it in Cronus PRO.(您可以在这里下载此脚本,或在GPC库中搜索“基础GPC”,如果您希望在Cronus PRO中加载它。)

1、Definitions Section (Optional)(定义部分(可选))

The definition section is used to assign values to words thus creating a named constant. Definitions must be placed before the main section.(definition section用于给单词赋值,从而创建一个命名常量。定义必须放在主要部分之前。)
In this example we define zero, one and two to the values 0, 1, 2 respectively.  These are static values which cannot be altered during run time.(在本例中,我们分别定义0,1和2的值为0,1,2。这些是静态值,在运行时不能更改。)
So, should we use the word 'one' at any point in the script it is the same as typing the number 1.(所以,我们应该在脚本的任何地方使用‘one’这个词,这和输入数字1是一样的。)
The next chapter for more detail on Definitions(下一章Definitions更多的定义细节)
2、Data Section (Optional)(数据部分(可选))

The data section is an array of bytes (8 bit unsigned integer) which is placed at the start of the Virtual Address Space in GPC bytecode.  The values are read only and cannot be altered at run time.(数据段是一个字节数组(8位无符号整数),它位于GPC字节码中虚拟地址空间的开始。这些值是只读的,不能在运行时更改。)
The user can access these values via the zero based data array.(用户可以通过基于零的数据数组访问这些值。)
For example in this script we could do this to access the array:(例如,在这个脚本中,我们可以这样做来访问数组:)
example4 = dbyte(4);  //example4 = 128
The next chapter for more detail on the data array.(下两章Data Section更多关于数据数组的细节。)
3、Remapping Section (Optional)(重新映射部分(可选))

In this section we can alter the behavior of the controls. In this example we are telling the Virtual Machine that an value assigned to the Left Bumper should be sent to the Right Bumper instead and vice versa.(在本节中,我们可以改变控件的行为。在这个例子中,我们告诉虚拟机分配给左缓冲器的值应该被发送给右缓冲器,反之亦然。)
It is important to note that button remaps are applied once the main has finished and just before the output report is sent to the console.  This means scripting should be programmed without considering the remapping.(重要的是要注意,按钮重映射是在主程序完成后,并且就在输出报告发送到控制台之前应用的。这意味着应该在不考虑重新映射的情况下编写脚本。)
For example, if at some point in this script we were to set the Left Bumper to 100 like so;(例如,如果在这个脚本的某个点,我们将左缓冲器设置为100,就像这样;)
set_val(XB1_LB, 100);
When the main procedure finishes, the output report would initially contain a value of 100 for the left bumper.  When the remaps are processed, this value would then instead be assigned to the Right Bumper and the output report would be modified.  When the final output report is sent to the console, it would contain a value of 100 for the Right Bumper instead of the Left.(当主过程完成时,输出报告最初将包含左保险杠的值100。当重新映射被处理时,这个值将被赋给正确的缓冲器,输出报告将被修改。当最终的输出报告被发送到控制台时,它将包含一个值为100的右缓冲器,而不是左缓冲器。)
The next chapter for more detail on button Remapping.(下一章Remapping查看按钮重映射的更多细节。)
4、Variable Initialization Section (Optional)(变量初始化部分(可选))

This is where the user can create variables.  A variable is a point in the stack memory where a value can be placed and they can only be created before the main or init sections.  These variables are global and GPC and can be accessed at any point within the script.  Variables are not static and can be altered during run time.(用户可以在这里创建变量。变量是堆栈内存中的一个点,在这里可以放置值,它们只能在main或init节之前创建。这些变量是全局的GPC,可以在脚本中的任何位置访问。变量不是静态的,可以在运行时更改。)
If a variable is not assigned a value in this section, it is initialized with the value 0.  Such as the variables example2 and example3 in this script.(如果变量在本节中没有赋值,则用0初始化它。例如脚本中的变量example2和example3。)
The next chapter for more detail on variables.(下一章variables查看变量的更多细节。)
5、GPC Initialisation Section (Optional)(GPC初始化组(可选))

The init section is similar to the main with the exception that it is only run once when the script is loaded in to the virtual machine.  It can run the same commands and functions as the main section such as combos and user created functions.(init部分与main类似,唯一的区别是当脚本加载到虚拟机中时,它只运行一次。它可以运行与主部分相同的命令和函数,如组合和用户创建的函数。)  
It is generally used to populate variables/arrays and set up the script.  In this example, if the CronusMAX PLUS has a PS4 controller connected when the script is first loaded, example2 is assigned a value of 27.  Otherwise it is assigned a value of 1.(它通常用于填充变量/数组和设置脚本。在本例中,如果在脚本首次加载时,CronusMAX PLUS连接了一个PS4控制器,那么example2就被赋值27。否则,它被赋值为1。)
The next chapter for more detail on the init section.(下一章init section查看更多细节。)
6、GPC Main Section (Mandatory)(GPC主要组别(强制性))

The main section is the heart and sole of any GPC script, all functions/combos are initailly executed from this function.   It is the only mandatory section and every GPC must have one.  Unlike combos and user created functions, a GPC may only have one main section.   It is run in a loop.   The Virtual Machine runs through the code in order and generates an output report as it goes.  When the Virtual Machine gets to the end of the main section, the output report is then ready to be sent to the console.  Once the console requests new data, the output report is sent and the main starts another run.(主部分是任何GPC脚本的核心和唯一,所有的函数/组合都从这个函数初始执行。这是唯一的强制性部分,每个GPC都必须有一个。与组合和用户创建的功能不同,GPC只能有一个主要部分。它是循环运行的。虚拟机按顺序运行代码,并在运行过程中生成输出报告。当虚拟机到达主部分的末尾时,输出报告就可以发送到控制台了。一旦控制台请求新的数据,输出报告就被发送,主程序开始另一次运行。)
As commands are run through in order, setting the value of a button in more than one place means that only the last command is sent.(由于命令是按顺序运行的,在多个地方设置按钮的值意味着只发送最后一个命令。)
For example, in this script;(例如,在这个脚本中;)

A value of -100 will be sent to the console.  The console will not see the LY axis set to 100 because the output report for that control is modified again before it is sent to the console.(值-100将被发送到控制台。控制台将不会看到LY轴设置为100,因为该控件的输出报告在发送到控制台之前再次被修改。)
The next chapter more detail on the main section.(下一章main section查看更多关于主要部分的细节。)
7、Combo Section (Optional)(组合组别(可选))

A combo (which is short for Combination)  is a function that will perform a set of instructions in order and for the amount of time assigned to the wait command directly after the commands.(组合(是组合的缩写)是一个函数,它将按顺序执行一组指令,并在命令之后直接分配给等待命令的时间量。)
In this script, when the combo is run, it will set identifier 20 (X on an Xbox controller or Square on a PlayStation controller) to 100% (Fully pressed) for the time set in the variable example1 (10 milliseconds in this case) and then do nothing for 100 milliseconds.(在这个脚本中,当组合运行时,它将把identifier 20 (Xbox控制器上的X或PlayStation控制器上的Square)设置为100%(完全按下),在变量example1中设置的时间(在本例中是10毫秒),然后在100毫秒内不做任何事情。)
You can assign multiple commands before a single wait statement.  For example, in the following combo, both the Left Bumper and Right Trigger will be pressed for 500 milliseconds (half a second) when the combo is run.  It will then do nothing for 500 milliseconds.(您可以在单个wait语句之前分配多个命令。例如,在下面的组合中,当组合运行时,左保险杠和右触发器都将被按下500毫秒(半秒)。然后在500毫秒内,它什么也不做。)

The next chapter more detail on Combos and Wait times.(下一章Combos将更详细地介绍组合和等待时间)
8、Function Section (Optional)(功能部分(可选))

A user created function is similar to the main section.  Commands are processed in order and any GPC which is valid in the main section can be used here.  Functions must be placed at the end of the of a GPC script.(用户创建的函数类似于main部分。命令按顺序处理,在主部分中有效的任何GPC都可以在这里使用。函数必须放在GPC脚本的末尾。)
The main difference with functions is they are only run when called and can return a value.  When a value is returned from a function, the function is terminated and any code beyond that point is not executed.(主要部分mail与函数functions的主要区别是它们只在调用时运行,并且可以返回值。当从函数返回值时,该函数终止,任何超出该点的代码都不执行。)
GPC user functions are global, this means that can be called from the init, main and combo sections.  A function can even be called from within another function.(GPC用户函数是全局的,这意味着可以从init、main和combo部分调用。甚至可以从另一个函数中调用一个函数。)
The next chapter more detail on User Created Functions.(下一章User Created Functions查看更多用户创建函数的细节。)
             Definitions(定义)
The sole purpose of a definition is assign a value to a word and therefore make a script easier for a human to read. They do not use utilize any bytecode space in a script as they are not sent to the CronusMAX PLUS.  When a script is compiled the words are changed to their assigned value.(定义的唯一目的是给单词赋值,从而使脚本更易于人类阅读。他们不使用任何字节码空间在一个脚本,因为他们没有发送到CronusMAX PLUS。当一个脚本被编译时,单词被改变为它们的赋值。)
Syntax
define <name> = <value>;
<name>
:    The name of the constant.
<value>
:    The value assigned to the constant.  Note only Integer values can be used.(赋给常量的值。注意,只能使用整数值。)
Once a word is defined and given a value, that word can be used anywhere in the script where a value is valid, as shown below;(一旦定义了单词并给出了一个值,该单词就可以在脚本中任何值有效的地方使用,如下所示;)
define my_value = 50;
int myvar;
main {
    set_val(XB1_RT, my_value);  //Set RT / R2 to 50
    myvar = my_value;           //myvar equals 50
    if(myvar >= my_value) {     //If myvar is greater than or equal to 50
        //Do Something
    }
    if(get_val(XB1_LT) > my_value) {  //If LT / L2 is greater than 50
        //Do Something
    }
}
A define is a static value and therefore cannot be changed during run time, as shown below;(定义是静态值,因此在运行时不能更改,如下所示;)
define my_value = 50;
main {
    my_value = 70;  //This will produce a compiler error
}
If you wished to assign a value to a word and change its value during runtime, you would use a variable instead of a define.(如果希望给单词赋值并在运行时更改它的值,可以使用变量而不是定义。)
        Data Section(数据部分)
The data section is located at the first portion of the virtual address space within the GPC bytecode and contains static values which cannot be altered during run time. (数据部分位于GPC字节码内虚拟地址空间的第一部分,包含运行时不能更改的静态值。)
The main purpose for the data section is to store static information and the size of it is determined by the values within it.   The static values can be accessed in a GPC through the use of an indexer and definitions can also be used if they are placed before the data section, as shown below.(数据段的主要目的是存储静态信息,它的大小由其中的值决定。静态值可以通过使用索引器在GPC中访问,如果定义放置在数据部分之前,也可以使用它们,如下所示。)

The values placed within the data section are expressed in bytes (8 bit unsigned integer).   The index is zero based. As you can see above, the first value is index point 0 (zero) and the 11th value would be index point 10.(放置在数据段中的值以字节表示(8位无符号整数)。索引是零为基础的。正如您在上面看到的,第一个值是索引点0(0),第11个值是索引点10。)
1、dbyte function(dbyte函数)

This function returns a byte value (8 bit unsigned integer) from the selected index within the array.(这个函数返回数组中所选索引的一个字节值(8位无符号整数)。)
Syntax
dbyte ( <Index> );
Parameters
<index> : The index of an element within the data section(数据部分内一个元素的索引)
2、dchar function(dchar函数)

This function returns a char value (8 bit signed integer) from the selected index within the array.(这个函数返回数组中所选索引的一个char值(8位有符号整数)。)
Syntax
dchar ( <Index> );
Parameters
<index> : The index of an element within the data section
3、dword function(双字函数)

This function returns a word value (16 bit signed integer) from the selected index within the array.(这个函数从数组中选择的索引返回一个字值(16位有符号整数)。)
Syntax
dword ( <Index> );
Parameters
<index> : The index of an element within the data section
           Remapping(重新映射)
Remappings are defined at the beginning of a script and must be done before the main procedure.  They cannot be executed during run time. (重映射是在脚本开始时定义的,必须在主过程之前完成。它们不能在运行时执行。)
Although they are defined at the beginning of a script, the Virtual Machine does not execute the remaps until the main section has finished its current iteration.  This means that any scripting operations on the remapped entries for inputs should be programmed for the original buttons and without considering the remappings.(虽然它们是在脚本的开头定义的,但是虚拟机在主部分完成当前迭代之前不会执行重新映射。这意味着输入的重映射条目上的任何脚本操作都应该针对原始按钮进行编程,而不考虑重映射。)
For example, if you used the remap command to swap the PS4_CIRCLE button with the PS4_TRIANGLE button and wished for the CIRCLE button on the controller to start a combo, you would still use the CIRCLE button in your code, like so;(例如,如果你使用remap命令将PS4_CIRCLE按钮与PS4_TRIANGLE按钮进行交换,并希望控制器上的CIRCLE按钮开始组合,你仍然可以在代码中使用CIRCLE按钮,就像这样;)
remap PS4_CIRCLE -> PS4_TRIANGLE;
remap PS4_TRIANGLE -> PS4_CIRCLE;
main {
    if(get_val(PS4_CIRCLE)) {   //Input commands are not affected by remaps.输入命令不受重新映射的影响。
        combo_run(My_Combo);    //So to run this combo, you would physically press the CIRCLE button.所以要运行这个组合,你需要按下圆圈按钮。
    }
}
combo My_Combo{
    set_val(PS4_L3, 100);
    wait(200);
    set_val(PS4_L3, 0);
    wait(190);
}
However, as remaps are evaluated after the main procedure is finished, any output commands should consider the remappings.  So if you wished for the CIRCLE button to turbo the TRIANGLE button (which it is remapped to) when pressed.  You would ignore the remaps for the get_val command but would consider them when creating the output, like so;(但是,由于重新映射是在主过程完成之后进行计算的,因此任何输出命令都应该考虑重新映射。所以如果你想让圆圈按钮在按压三角形按钮时加快(它已经被重新映射到三角形按钮)。您可以忽略get_val命令的重新映射,但在创建输出时要考虑它们,如下所示;)
remap PS4_CIRCLE -> PS4_TRIANGLE;
remap PS4_TRIANGLE -> PS4_CIRCLE;
main {
    if(get_val(PS4_CIRCLE)) {   //Input commands are not affected by remaps.输入命令不受重新映射的影响。
        combo_run(My_Combo);    //So to run this combo, you would physically press the CIRCLE button.所以要运行这个组合,你需要按下圆圈按钮。
    }
}
combo My_Combo{
    set_val(PS4_CIRCLE, 100);   //When this combo is run, it will turbo the CIRCLE button. 当这个组合运行时,它将加速循环按钮。
    wait(40);                   //However, when the main section has finished its current iteration,然而,当主部分完成当前的重复时
    set_val(PS4_CIRCLE, 0);     //the Virtual Machine will evaluate the REMAPS and will reassign these虚拟机将评估重新映射并重新分配这些映射
    wait(30);                   //commands to the TRIANGLE button.命令到三角形按钮。
}
Remaps assign the value of the input to the selected output.  So you can have one input controlling several outputs.  This also means that unless something else is remapped to the input, it will still also output its original function.(将输入的值赋给选定的输出。所以你可以用一个输入控制多个输出。这也意味着除非有其他东西被重新映射到输入,否则它仍然会输出它的原始函数。)
For example, if you were to do this;(例如,如果你要这样做;)
remap PS4_CROSS -> PS4_SQUARE;
remap PS4_CROSS -> PS4_TRIANGLE;
main {
}
The CROSS button would output as CROSS, SQUARE and TRIANGLE simultaneously.  The SQUARE and TRIANGLE buttons would not output anything.(交叉键会同时输出交叉键、方块键和三角键。方块键和三角键不会输出任何东西。)
Commands and Syntax(命令和语法)
There are two remapping commands;(有两个重新映射命令;)
remap
Assigns the value of the input identifier to the output identifier(将输入标识符的值赋给输出标识符)
Syntax(语法)
remap <input identifier> -> <output identifier>;

Remaps are based on the output identifier so any subsequent remaps to the same output identifier will override the previous remap.(重新映射基于输出标识符,因此对相同输出标识符的任何后续重新映射都将覆盖之前的重新映射。)

Due how remap alter the output report to the console, they do not consume any additional CPU runtime.(因此重新映射输出报告到控制台,它们不消耗任何额外的CPU运行时。)

unmap

Disconnects an input from the output report.  This means that although the Virtual Machine can still see the value of the button/axis on the input report, it will not pass its value onto the console in the output report.  You can therefore still use an unmapped button to run code or start combos in your GPC script without worrying about its original function being sent to the console.  For example;(从输出报告断开输入。这意味着尽管虚拟机仍然可以在输入报告中看到按钮/轴的值,但它不会将其值传递到输出报告中的控制台。因此,您仍然可以使用一个未映射按钮来运行代码或在GPC脚本中启动连击,而不必担心它的原始函数被发送到控制台。例如;)

unmap PS4_TRIANGLE;
main {
    if(get_val(PS4_TRIANGLE)){
        combo_run(MyCombo);
    }
}
Syntax(语法)
unmap <output identifier>;

You can also use the constant ALL_REMAPS to unmap all remappings in a single operation, like so;(你也可以使用常量ALL_REMAPS在单个操作中取消所有的重映射,就像这样;)
unmap ALL_REMAPS;
            Variables(变量)
All variables in GPC are 16 bit signed integers.  An integer (from the Latin 'integer' which means 'whole') is a number which can be written without a fractional component.   For example, 0, 20, 128 and -1000 are all integers while 4.2, 5.6 or -110.9 are not.  Therefore, GPC does not support fractions and will round down any decimal to a zero. Meaning 3.4 would become 3.(GPC中的所有变量都是16位带符号整数。整数(源自拉丁语“integer”,意思是“整体”)是一种不需要小数部分就可以写成的数字。例如,0、20、128和-1000都是整数,而4.2、5.6或-110.9不是整数。因此,GPC不支持分数,并将任何小数四舍五入到零。3。4变成3。)
16 bit signed means the variables can store an integer ranging from -32768 to +32767(16位signed表示变量可以存储一个范围从-32768到+32767的整数)
The following sections on variables can be found within this page;(以下关于变量的章节可以在本页中找到;)

Declaring Variables(声明变量)
Boolean Variables(布尔变量)
Arrays(数组)
Accessing any variable via an array(通过数组访问任何变量)
1、Declaring Variables(声明变量)
A variable is a place where data can be stored in the Virtual Machines memory.  A variables name can start with either an underscore ( _ ) or a letter and can be followed by any combination of letters, digits or underscores.   They are however case sensitive, so cronusmax, Cronusmax and CRONUSMAX would specify three different variables.(变量是可以在虚拟机内存中存储数据的地方。变量名可以以下划线(_)或字母开头,后面可以跟着字母、数字或下划线的任何组合。但是它们是大小写敏感的,所以cronusmax, Cronusmax和CRONUSMAX会指定三个不同的变量。)
Variables defined this way in GPC are global, this means they can accessed and modified within the init or main sections as well as a combo or function.  Only variables assigned to user created functions are local.  Details of how variables operate within user functions can be found here.(GPC中以这种方式定义的变量是全局的,这意味着它们可以在init或main部分以及组合或函数中访问和修改。只有分配给用户创建函数的变量才是局部变量。关于变量如何在用户函数中操作的细节可以在这里找到。)
Global variables must be declared before the main or init sections and therefore cannot be declared after or in either of those sections. As shown below;(全局变量必须在main或init节之前声明,因此不能在main或init节之后或其中任何一个节中声明。如下所示;)
int myVar = 100, MYVar;
int MYVAR = -40;
init {
    int incorrect; //This will cause an error这将导致一个错误
}
int Incorrect; //This will also cause an error这也会导致错误
main {
    int INCORRECT; //This will again cause an error这将再次导致错误
}
Variables are always assigned a value.  If no value is assigned when they are declared, then they are initialized with a value of 0 (zero).  The value assigned to a variable can be altered during runtime, as shown below;(变量总是被赋值的。如果声明时没有赋值,则用0(0)初始化它们。赋值给一个变量的值可以在运行时改变,如下所示;)
int myVar = 100, MYVar; // myVar initial value is 100, MYVar initial value is 0
int MYVAR = -40;        // MYVAR initial value is -40
main {
    MYVar = myVAR - MYVAR;  // MYVar value is now 60
}
2、Boolean Variables(布尔变量)
Unlike other programming languages, such as C# for example, GPC does not require a separate variable type for Boolean values.  The integers in GPC have been designed to support Boolean expressions.  The keywords TRUE and FALSE have been assigned the values 1 and 0 respectively as shown in the example below;(与其他编程语言(例如c#)不同,GPC不要求布尔值有单独的变量类型。GPC中的整数被设计为支持布尔表达式。将关键字TRUE和FALSE分别赋值为1和0,如下例所示;)
int myvar, MYVAR;
main {
    myvar = TRUE;   //myvar = 1
    MYVAR = FALSE;  //MYVAR = 0;
}
You can therefore use integers in your code to create a toggle switch which enables or disables sections of code, like so;(因此,你可以在你的代码中使用整数来创建一个切换开关,启用或禁用代码段,就像这样;)
int myvar;
main {
    if(event_press(XB360_A)) {   //If A / Cross is pressed on the controller如果按下XB360的A键
        myvar = !myvar;         //myvar equals not myvar.  So if myvar is TRUE or has a value it will be made FALSE / assigned the value of 0 (zero)这时myvar不等于myvar.因此如果myvar是1或者有其它数值时,它将会被赋值为FALSE或者0
                                //If myvar is FALSE or has a value of 0 (zero) it will be made TRUE / assigned the value of 1如果myvar是0它将被赋值为TRUE或者1
    }
    if(myvar) {                 //If myvar has a value other than 0 (zero)如果myvar的值不是0
        //Do something执行
    }
}
As seen in the above example, a variable will return TRUE in an if statement if it has any value other than 0 (zero).  You can however use operators should you wish for your nested code to only be active if a variable is a certain value;(如上例所示,如果变量的值不是0(0),那么它将在if语句中返回TRUE。但是,如果您希望嵌套代码仅在变量为特定值时才激活,则可以使用操作符;)
int myvar;
main {
    if(event_press(XB360_A)) {   //If A / Cross is pressed on the controller当按下XB360的A键时
        myvar = myvar + 1;      //myvar equals myvar plus 1. 这时myvar等于myvar加1
    }
    if(event_press(XB360_X)) {   //If X / Square is pressed on the controller当按下XB360的X键时
        myvar = myvar - 1;       //myvar equals myvar minus 1.这时myvar等于myvar减1
    }
    if(myvar == 2) {            //If mvar has a value of 2.如果myvar等于2
        //Do something执行
    }
    if(myvar >= 4) {            //If mvar has a value of greater than or equal to 4.如果myvar大于等于4
        //Do something执行
    }
    if(myvar < 2) {            //If mvar has a value less than 2.如果myvar小于2
        //Do something执行
    }
}
3、Arrays(数组)
An array is a method for creating multiple variables in a single command. Arrays are 0 (zero) based so creating a 5 dimensional array will create 5 variables which can be accessed with the indexes 0 through 4, as shown below;(数组是在单个命令中创建多个变量的方法。数组是基于0(零)的,因此创建一个5维数组将创建5个变量,这些变量可以通过索引0到4访问,如下所示;)
int myvar[5];
main {
    //int myvar[5] creates 5 variables
    myvar[0];   //1st Variable
    myvar[1];   //2nd Variable
    myvar[2];   //3rd Variable
    myvar[3];   //4th Variable
    myvar[4];   //5th Variable
}
Arrays are assigned a value of 0 (zero) when initialized and cannot be assigned a different value before the init section.  They are also global and can be assigned a value or modified at any point during run time in your script, like so;(数组在初始化时被赋值为0(零),不能在init节之前赋值。它们也是全局的,可以在脚本运行时的任何时候赋值或修改,就像这样;)
int myvar[5];
init {
    myvar[0] = 20;  //myvar[0] equals 20
    myvar[1] = 10;  //myvar[1] equals 10
}
main {
    myvar[2] = myvar[0] + myvar[1];     //myvar[2] equals 30 (20 + 10)
    myvar[3] = 15;  //myvar[3] equals 15
    myvar[4] = add_two_variables(myvar[2], myvar[3]);   //myvar[4] equals 45 (30 + 15)
}
function add_two_variables(_1st_variable, _2nd_variable) {
    return _1st_variable + _2nd_variable;
}
4、Accessing any variable via an array(通过数组访问任何变量)
When a script is compiled, all global variables are placed within an array.  You can therefore use an array call to access subsequent variables from a variable which has not be initialized as an array, as shown below;(编译脚本时,所有全局变量都放在数组中。因此,你可以使用数组调用来访问未初始化为数组的变量的后续变量,如下所示;)
int myvar;
int _1st = 10;
int _2nd = 20;
int _3rd = 30;
int _4th = 40, _5th = 50;
int var_to_place_value_into;
main {
    var_to_place_value_into = myvar[1]; //var_to_place_value_into equals 10 (_1st)
    var_to_place_value_into = myvar[2]; //var_to_place_value_into equals 20 (_2nd)
    var_to_place_value_into = (myvar[4] + myvar[5]) - myvar[3];  //var_to_place_value_into equals 60 ((40 + 50) - 30)
    var_to_place_value_into = _2nd[1];  //var_to_place_value_into equars 30 (_3rd)
}
          Init Section(初始化部分)
The initialization or init section of a GPC is identical to the main section other than it is not run in a loop.  The init section is run once before the first iteration of the main section when a script is first loaded and can run any combo or call any function.  You can even modify the value of variables within it, just as you would in the main section.(GPC的初始化或初始化部分与主部分相同,只是它不是在循环中运行。当脚本首次加载时,init部分在main部分的第一次迭代之前运行一次,它可以运行任何组合或调用任何函数。甚至可以修改其中变量的值,就像在主部分中那样。)
The init section is used to setup your script.  For example, say you wished to use the same Rapid Fire script on a PlayStation 3 and Xbox One but your PlayStation 3 game uses the bumper to shoot where as your Xbox One game uses the trigger, you could use the init section to automatically adjust your script on when it is loaded as shown in the following example;(init部分用于设置脚本。例如,假设您希望使用相同的速射脚本在ps3和 Xbox one上。但你的PlayStation 3游戏已使用L1键作为射击键,那当你在Xbox one游戏使用R1可以使用init部分自动调整脚本加载,如以下示例所示;)
int FIRE_BTN;
init {
    if(get_console() == PIO_PS3) {  //If connected to a PS3 when loaded
        FIRE_BTN = 3;   //3 = LB/L1
    } else {                        //If connected to any other console
        FIRE_BTN = 4;   //4 = RT/R1
    }
}
main {
    if(get_val(FIRE_BTN)) {
        combo_run(Rapid_Fire);
    }
}
combo Rapid_Fire {
    set_val(FIRE_BTN, 100);
    wait(50);
    set_val(FIRE_BTN, 0);
    wait(40);
    set_val(FIRE_BTN, 0);
}
The init section is very useful when you are using persistent variables as you do not want to constantly recall the values stored in them during run time.  Information on Persistent Variables and how they can be recalled in the init section can be found here.(当您在使用持久变量时,init部分非常有用,因为您不想在运行时不断地收回存储在持久变量中的值。关于持久化变量以及如何在init部分中调用它们的信息可以在这里找到。)
        Main Section(主要部分)
The main section is the heart and sole of any GPC script.  It is run in a constant loop and any code executed during run time can be traced back to it.  Therefore, the main section is mandatory and a GPC script is not valid without one.(主要部分是任何GPC脚本的核心和基础。它在一个常量循环中运行,运行期间执行的任何代码都可以追溯到它。因此,主部分是必须的,没有主部分的GPC脚本是无效的。)
Just as with any nested code, the main section start and finish points are denoted with a { or } respectively, like so;(就像任何嵌套代码一样,主要部分的开始点和结束点分别用{或}表示,就像这样;)
main
{   //Main Start
}   //Main End
When the main section reaches the End point, the output report to the console is created, any remaps are evaluated and the report is sent to the console.  The main section is then restarted from the beginning.(当主部分到达终点时,将创建控制台的输出报告,评估任何重新映射,并将报告发送到控制台。然后,主要部分从开始重新启动。)
Code within the main section is executed in the order it is written.  It is important to remember this when building your own GPC scripts as the output report to the console is created at the end of the main section, so it is possible to create code which would cancel each other out and result in a different output to the console than you expected. For example;(主部分中的代码按照编写的顺序执行。重要的是要记住这在构建自己的GPC创建脚本作为输出到控制台报告结束时的主要部分,所以可以创建代码哪些可以抵消哪些可以输出,结果可以按照你的预期不同输出到控制台。例如;)
int press_lt;
main{
    if(get_val(XB1_RT)){        //If RT/R2 is pressed..
        press_lt = TRUE;        //Variable 'press_lt' is set to TRUE
    }
    press_lt = FALSE;           //Variable 'press_lt' is set to FALSE
    if(press_lt) {              //This line of code will never see 'press_lt'
        set_val(XB1_LT, 100);   //as TRUE so the code nested within the if
    }                           //Statement will never be active
}
As you can see above, the variable 'press_lt' is set to TRUE when the RT/R2 button is pressed but is immediately set to FALSE in the next line of code. Therefore the if(press_lt) statement will always be FALSE and the code nested within the if statement will never be executed.(正如您在上面看到的,当按下RT/R2按钮时,变量'press_lt'被设置为TRUE,但在下一行代码中立即被设置为FALSE。因此if(press_lt)语句将始终为FALSE,嵌套在if语句中的代码将永远不会执行。)

However, if we were to move the code around, then we would get the expected output;(然而,如果我们移动代码,那么我们将得到预期的输出;)
int press_lt;
main{
    press_lt = FALSE;           //Variable 'press_lt' is set to FALSE
    if(get_val(XB1_RT)){        //If RT/R2 is pressed..
        press_lt = TRUE;        //Variable 'press_lt' is set to TRUE
    }
    if(press_lt) {              //This line of code will see if 'press_lt'
        set_val(XB1_LT, 100);   //is TRUE so the code nested within the if
    }                           //Statement could be activated
}
If RT/R2 is pressed then  'press_lt' is set to TRUE after it has been set to FALSE, the if(press_lt) statement will see that it is TRUE and the nested code will be run.  If RT/R2 isn't being pressed then 'press_lt' is not set to TRUE after is has been set to FALSE and the nested code is not run.(如果RT/R2被按下,那么'press_lt'在它被设为FALSE后被设为TRUE, If (press_lt)语句将看到它为TRUE,嵌套代码将运行。如果RT/R2没有被按下,那么在is被设置为FALSE并且嵌套代码不运行之后,'press_lt'不会被设置为真。)
If 'press_lt = FALSE;' was nested within an else statement, which is a better way to do it, then it could be placed after the 'press_lt = TRUE;' line, like so;(如果'press_lt = FALSE;'嵌套在else语句中,这是一种更好的方法,那么它可以放在'press_lt = TRUE;'行之后,像这样;)
int press_lt;
main{
    if(get_val(XB1_RT)){        //If RT/R2 is pressed..
        press_lt = TRUE;        //Variable 'press_lt' is set to TRUE
    } else {
        press_lt = FALSE;       //Variable 'press_lt' is set to FALSE
    }
    if(press_lt) {              //This line of code will see if 'press_lt'
        set_val(XB1_LT, 100);   //is TRUE so the code nested within the if
    }                           //Statement could be activated
}
The above code will operate as expected because the else statement will only be TRUE if RT/R2 is not being pressed.  Therefore, 'press_lt' is only set to false when RT/R2 is not pressed.(上面的代码将按照预期运行,因为else语句只有在没有按下RT/R2时才为真。因此,'press_lt'仅在没有按下RT/R2时被设置为false。)
So, as you can see in the above examples, it is important to remember that code is executed in the order it is written and simply moving the placement of a line can have a significant effect of the output to the console.(因此,正如您在上面的示例中看到的,一定要记住,代码是按照编写的顺序执行的,只需移动一行的位置,就会对输出到控制台产生显著的影响。)
         Combo Section(组合部分)
A combo (short for combination) is a combination of preprogrammed instructions which are executed in sequence.  Just like the main section, commands within a combo are performed in the order they are written.  You can run any code you can run in the main section within a combo such as calling functions or setting variables, although this is generally unnecessary and usually results in nothing more than a waste of stack memory and bytecode space.  A combo is ideal suited to setting the output of a button for a specific length of time which is done using the wait command, a command that is unique to combos and cannot be used elsewhere.(组合(组合的缩写)是按顺序执行的预编程指令的组合。就像主部分一样,组合中的命令是按照它们编写的顺序执行的。您可以在组合中的主部分中运行任何代码,比如调用函数或设置变量,尽管这通常是不必要的,而且通常只会浪费堆栈内存和字节码空间。组合非常适合设置特定时间长度的按钮输出,这是使用等待命令完成的,这是组合中唯一的命令,不能在其他地方使用。)
Just as with variables, a combos name can start with either an underscore ( _ ) or a letter and can be followed by any combination of letters, digits or underscores.(就像变量一样,组合名可以以下划线(_)或字母开头,后面可以跟着字母、数字或下划线的任何组合。)

1、combo_run(运行组合)

combo_run does precisely what the name suggests and runs a combo.  However, unlike the combo_restart command, it has no effect if the combo is currently running. It will only start a combo is it is not already running.(combo_run顾名思义,运行一个组合。但是,与combo_restart命令不同的是,如果组合当前正在运行,它没有作用。它只会启动一个没有正在运行的组合。)
Syntax(语法)
combo_run ( <Combo Name> );
Parameters(参数)
<Combo Name> : The name assigned to a combo.
2、combo_running(正在运行的组合)
combo_running is a function which can be used in your code to check is a combo is running is not.  If the combo named in its parameter is running, then it will return TRUE.  If not, it will return .(combo_running是一个函数,可以在你的代码中用来检查一个组合是否正在运行。如果参数中指定的组合正在运行,那么它将返回TRUE。如果没有,则返回FALSE。)
Syntax
combo_running ( <Combo Name> );
Parameters
<Combo Name> : The name assigned to a combo.
Returns
TRUE if the combo is running, FALSE if it is not
combo_running is particularly useful if you only want certain lines of code executed when the combo has finished.  For example, if you want to run a combo 5 times from a single button press, with a combination of combo_running and a variable you can do so as shown in the example below;(如果您只想在组合完成后执行某些行代码,那么combo_running特别有用。例如,如果你想通过单个按钮按下运行组合5次,结合combo_running和一个变量,你可以如下面的例子所示;)
int run_combo = 0;
main {
    if(event_press(19)) {       //If A / Cross is pressed...
        run_combo = 5;          //Variable 'run_combo' equals 5
    }
    if(run_combo && !combo_running(mycombo)) {  //If 'run_combo' has a value and mycombo is not running...
        run_combo = run_combo - 1;              //'run_combo' equals 'run_combo' minus 1
        combo_restart(mycombo);                 //restart mycombo
    }
}
combo mycombo {
    set_val(3, 100);    //set RB / R1 to 100
    wait(200);          //wait 200 milliseconds
    wait(200);          //wait 200 milliseconds
}
Device monitor output from the above code;(设备监视器输出由上面的代码;)

As you can see, the output from the above code will press the RB / R1 button 5 times from a single press of the A / Cross Button.  As you can see, when using the combo_running function and a variable, it is possible to produce multiple button presses with a small amount of code.  You could change the line 'run_combo = 5;'  to any value above 0 (zero) and below 32767.  The combo would be executed however many times you stipulated.(如您所见,以上代码的输出将按下RB / R1按钮5次,每次按下a / Cross按钮。如您所见,在使用combo_running函数和一个变量时,可以用少量代码生成多个按钮按下。您可以将'run_combo = 5;'行更改为0(零)以上和32767以下的任何值。组合将执行多少次您规定的。)
3、combo_stop(组合停止)

As the name suggests, combo_stop will stop a combo if it is currently running.  As with combo_run, it has no effect if the combo is not currently running.(顾名思义,如果组合当前正在运行,combo_stop将停止该组合。与combo_run一样,如果组合当前没有运行,则它没有作用。)
Syntax
combo_stop ( <Combo Name> );
Parameters
<Combo Name> : The name assigned to a combo.
combo_stop is particularly useful when you only wish for your combo to run when a button is held. To achieve this, you would use it in combination with an else statement as shown below;(当你只希望你的组合在按下按钮时运行时,combo_stop特别有用。为了实现这一点,你可以将它与如下所示的else语句结合使用;)
int run_combo = 0;
main {
    if(get_val(19)) {           //If A / Cross is held..
        combo_run(mycombo);     //run mycombo
    } else {                    //If A / Cross is not pressed/held...
        combo_stop(mycombo);    //stop mycombo
    }
}
combo mycombo {
    set_val(3, 100);    //set RB / R1 to 100
    wait(2000);         //wait 2000 milliseconds
    wait(2000);         //wait 2000 milliseconds
}
4、combo_restart(重启组合)

As the name suggests, combo_restart will restart a running combo.  If the combo stated within it's parameters is currently running, it will be restarted from the beginning.  If the combo is not currently running, it will be run.(顾名思义,combo_restart将重新启动一个正在运行的组合。如果在它的参数中声明的组合当前正在运行,它将从头重新启动。如果组合当前没有运行,则会运行它。)
Syntax
combo_restart ( <Combo Name> );
Parameters
<Combo Name> : The name assigned to a combo.
5、Wait Command(等待命令)

The wait command instructs the Virtual Machine within the CronusMAX on how long the last set of commands should be executed for.  The length of time they instruct the VM to execute the commands for is represented in milliseconds and can rand from 1ms to 32767ms (That's 1 millisecond to just over 32 seconds).(wait命令指示CronusMAX中的虚拟机最后一组命令应该执行多长时间。它们指示VM执行命令的时间长度以毫秒为单位,可以从1毫秒到32767毫秒(也就是1毫秒到32秒多一点)。)
The commands executed during the wait time are those placed between the current wait and the previous wait time, the current wait time and previous call command or the start of the combo, whichever comes first.  As shown in the example below;9在等待时间内执行的命令位于当前等待时间和前一个等待时间之间、当前等待时间和前一个调用命令之间或组合的开始之间,以先出现的为准。如下例所示;)
combo mycombo {
    set_val(19, 100);//¯¯|
    set_val(18, 100);//  | These two buttons will be held
    wait(1000);      //←_| for 1000 milliseconds (1 second)
    set_val(3, 100);//¯¯|
    set_val(7, 100);//  | These two buttons will be held
    wait(1500);     //←_| for 1500 milliseconds (1.5 seconds)
    set_val(9, -100);//¯¯| This axis will be held
    wait(2000);      //←_| for 2000 milliseconds (2 seconds)
}
The wait command can only be used within a combo and must be at the first level of the combo block, it cannot be nested. The example below shows correct and incorrect usage of the wait command;(wait命令只能在组合中使用,并且必须位于组合块的第一层,不能嵌套。下面的例子显示了wait命令的正确和错误用法;)
main {
    wait(100);  //Incorrect - Will produce an error as this command is错误-将产生一个错误
                //not permitted outside of a combo不允许在组合之外
}
combo mycombo {
    if(get_console() == PIO_PS4) {
        wait(200);  //Incorrect - Although this wait command is within a combo,错误-虽然这个等待命令是在一个组合中
                    //is is not permitted beyond the first level of the combo block不允许超出组合模块的第一级
    }
    wait(400);      //Correct - This wait command is at the first level of the正确,在第一级
                    //combo block.
}
function myfunction() {
    wait(300);      //Incorrect - Will again produce an error as this command is错误
                    //not permitted outside of a combo不允许在组合外面
}
Syntax
wait ( <Time> );

Parameters

<Time> : The length of time the last commands should be executed for. Represented in milliseconds - range 10 ~ 4000(应执行最后一个命令的时间长度。以毫秒表示-范围为10 ~ 4000)
6、Call command(呼叫命令)

Like the wait command, call is unique to combos and it is not permitted outside of the first level of a combo. (和wait命令一样,call是组合中唯一的命令,不允许在组合的第一级之外使用。)

When the call command is used, the current combo it is placed in is paused and the combo within the call commands parameters is executed.  Once the called combo has finished, the combo the call command was executed in is then resumed.  For example;(当使用call命令时,它所在的当前组合将暂停,并执行call命令参数中的组合。调用的组合完成后,在其中执行调用命令的组合将被恢复。例如;)
combo _1st_combo {
    set_val(XB1_B, 100);
    wait(100);
    wait(200);
    call(_2nd_combo);   //_1st_combo is paused until _2nd_combo is finished
    set_val(XB1_Y, 100);
    wait(100);
    wait(200);
}
combo _2nd_combo {
    set_val(XB1_RB, 100);
    wait(100);
    wait(200);
}   //Once this combo has ended, the combo is was called from can resume
In the above example, when _1st_combo is run, the sequence of commands sent to the console would be;(在上面的例子中,当运行_1st_combo时,发送到控制台的命令序列将是;)
B / Circle is pressed for 100 milliseconds(B / Circle被按100毫秒)
No buttons are pressed by the Virtual Machine for 200 milliseconds(在200毫秒内没有按下任何按钮)
RB / R1 is pressed for 100 milliseconds(RB / R1按下100毫秒)
No buttons are pressed by the Virtual Machine for 200 milliseconds(在200毫秒内没有按下任何按钮)
Y / Triangle is pressed for 100 milliseconds(Y / Triangle被按100毫秒)
No buttons are pressed by the Virtual Machine for 200 milliseconds(在200毫秒内没有按下任何按钮)

As you can see, using the call command injects a combo into a combo at a set point.  This is particularly useful when you have two combos which perform identical actions at a point and wish to save space in your script. (如您所见,使用call命令将一个组合注入到一个设置点的组合中。当你有两个组合在一点上执行相同的动作,并且希望节省脚本的空间时,这一点特别有用。)
Syntax
call ( <Combo Name> );
Parameters
<Combo Name> : The name of the combo to be called.
     User Created Functions(用户创建的函数)
As well as having a significant number of built in functions, GPC allows the user to create their own custom functions. A function can run any code valid in the main section and code is also executed in the order it is written.(GPC除了具有大量内建函数外,还允许用户创建自己的自定义函数。函数可以在主节中运行任何有效的代码,并且代码也按照编写的顺序执行。)

1、Calling a function(调用一个函数)

To call (or run) a function, you simply type its name and put any parameters it requires in between ( and ).(要调用(或运行)一个函数,只需键入它的名称,并把它需要的任何参数放在( and )之间。)
When a function is called, the code within it is executed and the return value is sent back to where it was called from. (当调用一个函数时,将执行其中的代码,并将返回值发送回调用该函数的地方。)
User functions are what is known as global scope, this means they can be called from the init, main and combo sections.  They can even be called from within another function, however, GPC does not support recursive calls of functions.  This means a function cannot be called from within itself.(用户函数就是所谓的全局作用域,这意味着它们可以从init、main和combo部分调用。甚至可以从另一个函数中调用它们,但是,GPC不支持函数的递归调用。这意味着函数不能从自身内部调用。)
2、Function name and declaration(函数名称和声明)

To declare a function type function followed by a name and ().  Within the brackets () you place the names of any parameters you would like the function to have, if any.  Function names and parameters follow the same rules as a variable, they can start with either an underscore ( _ ) or a letter and can be followed by any combination of letters, digits or underscores.(要声明一个函数类型,函数后面跟着一个名称和()。在方括号()中,您可以放置希望函数具有的任何参数的名称(如果有的话)。函数名和参数遵循与变量相同的规则,它们可以以下划线(_)或字母开头,后面可以跟着字母、数字或下划线的任何组合。)
Functions must be declared last in a GPC script though, after the main and any combo section.(函数必须在GPC脚本的最后声明,在main和任何组合部分之后。)
Syntax
function ( <arameter(s)> );
Parameters
<arameter(s)> : Optional parameters. You can use as many as you wish or none at all. Each one must be separated with a comma (,)(可选参数。你想用多少就用多少,也可以一个也不用。每一个都必须用逗号(,)隔开)
3、Function Parameters(函数参数)

Function parameters can be thought of like local variables as they cannot be accessed outside of the function they are defined within.  A value can be passed to them and they can be used within the function just like a variable could.(函数形参可以看作是局部变量,因为它们不能在函数内部定义的外部访问。值可以传递给它们,它们可以像变量一样在函数中使用。)
As GPC only supports the one data type (16bit Integers) you do not need to specify the data type of parameters within a function and the name of a parameter follows the same rules as a function or variable, they can start with either an underscore ( _ ) or a letter and can be followed by any combination of letters, digits or underscores.(GPC只支持一个数据类型(16位整数)你不需要指定数据类型的参数在函数和参数的名称作为一个函数或者变量遵循相同的规则,他们可以从一个下划线(_)或一个字母,可以紧随其后的任何组合字母,数字或下划线。)
Function parameters are optional.  You are not required to have any at all.  For example, function myfunction() { }  is perfectly valid.(函数参数是可选的。你不需要设置所有。例如,function myfunction(){}是完全有效的。)
4、Returning from a function(从函数返回)

return is a command unique to functions.  It is not mandatory for each user function to have a return value though.   If there is no return in a function, then 0 (zero) will be automatically returned.(return是函数特有的命令。但是并不是每个用户函数都必须有返回值。如果函数中没有返回值,那么将自动返回0(零))
You can have multiple return points within a function.  Once the first return command is executed, the function returns a value to where is was called and the function is terminated.  The code beyond that point in the function will not be run.(在一个函数中可以有多个返回点。一旦执行了第一个return命令,函数将返回一个值,该值指向被调用的位置,函数将终止。函数中超出该点的代码将不运行。)
Returning a value is one of the single most useful commands within a function as it can be used as a boolean value to enable or disable sections of code, to set parameters in other functions or to set a variable to a desired value.  In the following example, you will see a couple of uses for the return command;(返回值是函数中最有用的命令之一,因为它可以用作布尔值,用于启用或禁用代码段、设置其他函数中的参数或将变量设置为所需的值。在下面的例子中,你将看到return命令的几种用法;)
int RF_HOLD = 40;
int RF_NULL = 30;
main {
    if(myfunction()) { //If myfunction returns a value other than 0(zero)...如果myfunction返回的值不是0(0)…
        if(get_val(XB1_RT)) { //If we get a value from RT / R2 other than 0
如果我们从RT / R2中得到的值不是0
            combo_run(Rapid_Fire);  //Run combo Rapid_Fire
        }
    }
}
combo Rapid_Fire {
    set_val(XB1_RT, 100);
    wait(RF_HOLD);
    set_val(XB1_RT, 0);
    wait(RF_NULL);
    set_val(XB1_RT, 0);
}
function myfunction() {
    if(get_val(XB1_VIEW)) { //If we get a value from View other than 0如果我们从View键中获得的值不是0
        if(get_val(XB1_A))
            RF_HOLD = adjust_speed(RF_HOLD, 10, 1000, 10);
        if(get_val(XB1_B))
            RF_NULL = adjust_speed(RF_NULL, 10, 1000, 10);
        set_val(XB1_A, 0);
        set_val(XB1_B, 0);
        set_val(XB1_LB, 0);
        set_val(XB1_RB, 0);
        set_val(XB1_VIEW, 0);
        set_val(TRACE_1, RF_HOLD / 10);
        set_val(TRACE_2, RF_NULL / 10);
        return 0; //Return 0
    }
    return 1; //If we do not get a value from View, return 1如果我们没有从View键中获得一个值,返回1
}
function adjust_speed(var, min_value, max_value, adjustment_increment) {
    if(event_press(XB1_RB) && var < max_value)
        var = var + adjustment_increment;
    if(event_press(XB1_LB) && var > min_value)
        var = var - adjustment_increment;
    return var;
}
Understanding how the example works(理解示例如何工作)
When the GPC script is first loaded, the two variables RF_HOLD and RF_NULL are created with a value of 40 and 30 respectively.(当首次加载GPC脚本时,将创建两个变量RF_HOLD和RF_NULL,它们的值分别为40和30。)
The main section then starts its first iteration (run).   When it gets to the line;(然后main部分开始它的第一个迭代(run)。当它到达终点线时;)
if(myfunction()) {
the function 'myfunction()' is executed.(执行函数'myfunction()'。)

The code in 'myfunction()' is then run.  If XB1_VIEW is not being pressed, the code nested in the statement;(然后运行'myfunction()'中的代码。如果XB1_VIEW没有被按下,则代码嵌套在语句中;)
if(get_val(XB1_VIEW)) { //If we get a value from View other than 0
is ignored as the if statement is FALSE. So the next line executed in the function is;(被忽略,因为if语句为FALSE。函数中执行的下一行是;)
return 1; //If we do not get a value from View, return 1
at which point the value of 1 is returned to the statement;(此时将值1返回给语句;)
if(myfunction()) {
Thus making the above statement TRUE and the code;(从而使上述语句为TRUE和代码;)
if(get_val(XB1_RT)) { //If we get a value from RT / R2 other than 0
            combo_run(Rapid_Fire);  //Run combo Rapid_Fire
        }
is executed. The main section carries on until it reaches its end point and loops.(被执行。主要部分继续进行,直到到达它的终点和循环。)
However, if XB1_VIEW is being held when 'myfunction()' is executed, then the following code is run;(但是,如果执行'myfunction()'时XB1_VIEW被按住,则运行以下代码;)
  if(get_val(XB1_A))
            RF_HOLD = adjust_speed(RF_HOLD, 10, 1000, 10);
        if(get_val(XB1_B))
            RF_NULL = adjust_speed(RF_NULL, 10, 1000, 10);
        set_val(XB1_A, 0);
        set_val(XB1_B, 0);
        set_val(XB1_LB, 0);
        set_val(XB1_RB, 0);
        set_val(XB1_VIEW, 0);
        set_val(TRACE_1, RF_HOLD / 10);
        set_val(TRACE_2, RF_NULL / 10);
        return 0; //Return 0
As you can see, if XB1_A or XB1_B are not also held down, the code set a few buttons to 0, writes the value of our two variables to TRACE values and then most importantly, reaches the line;(如你所见,如果XB1_A或XB1_B没有按下,代码将几个按钮设置为0,将两个变量的值写入跟踪值TRACE,然后最重要的是,到达该行;)
return 0; //Return 0
at which point a value of 0 is returned to the statement;(此时将值0返回给语句;)
if(myfunction()) {
making it FALSE, so the code;(使它FALES失效,所以这个代码)
if(get_val(XB1_RT)) { //If we get a value from RT / R2 other than 0
            combo_run(Rapid_Fire);  //Run combo Rapid_Fire
        }
which is nested within that statement is ignored and not executed.(嵌套在该语句中的语句将被忽略且不执行。)
If XB1_VIEW and XB1_A are both held when 'myfunction()' is executed, then the following line of code is reached and run;(如果XB1_VIEW和XB1_A在'myfunction()'执行时都按住,则到达并运行以下代码行;)
RF_HOLD = adjust_speed(RF_HOLD, 10, 1000, 10);
what the above line means is the variable RF_HOLD equals the return value of the function 'adjust_speed' or you could say the return value from 'adjust_speed' is stored in RF_HOLD.  So lets take a look at how that function returns a value.(上面这一行的意思是变量RF_HOLD等于函数'adjust_speed'的返回值,或者你可以说从'adjust_speed'的返回值存储在RF_HOLD中。那么让我们来看看这个函数是如何返回一个值的。)
As you can see above, four values are being sent to the function 'adjust_speed'.  The value of RF_HOLD, 10, 1000 and 10. So lets take a look at the declaration of the function 'adjust_speed';(正如你在上面看到的,四个值被发送给函数'adjust_speed'。RF_HOLD、10、1000和10的值。那么让我们看一下函数'adjust_speed'的声明;)
function adjust_speed(var, min_value, max_value, adjustment_increment) {
function 'adjust_speed' requires 4 arguments, the variable to be adjusted, the minimum value you want it to be, the maximum value you wish for it to be and how much to adjust it by each increment.(函数'adjust_speed'需要4个参数,要调整的变量,你想要的最小值,你希望它是最大的值,以及每增加多少调整它。)
To manipulate the variable, the function executes the following code;(为了操作变量,函数执行以下代码;)
  if(event_press(XB1_RB) && var < max_value)
        var = var + adjustment_increment;
    if(event_press(XB1_LB) && var > min_value)
        var = var - adjustment_increment;
    return var;
In the first part of this code, if XB1_RB is pressed and the variable value passed to the function is less than the maximum value allowed, the value passed in the forth parameter (10 in this case) is added to the value of var.  The value of var is the returned to where the function is called.  Therefore making RF_HOLD equal 10 more than it did before.(在这段代码的第一部分,如果XB1_RB被按住和传递给函数的变量值小于允许的最大值,提出参数中传递的值(在本例中数值10)被添加到var的价值。var的价值函数被调用的返回。因此,使RF_HOLD比以前多10。)
If XB1_LB is pressed and the variable value passed to the function is greater than the minimum value allowed, the value passed in the forth parameter is subtracted from the value of var.  The value of var is the returned to where the function is called.  Therefore making RF_HOLD equal 10 less than it did before.(如果按下XB1_LB且传递给函数的变量值大于允许的最小值,则第四个参数传递的值将从var的值中减去。var的值将返回到调用函数的位置。因此,使RF_HOLD比以前少10。)
An identical process is carried out if XB1_VIEW and XB1_B are pressed when 'myfunction()' is executed with the exception being that RF_NULL is adjusted rather than RF_HOLD.(如果执行'myfunction()'时按下XB1_VIEW和XB1_B,则执行相同的过程,唯一的例外是调整RF_NULL而不是RF_HOLD。)
       I/O Functions(I / O功能)
I/O stands for Input / Output.  The two main sources of input into the virtual machine are from the connected controller and the console.  As well as receiving inputs from these two sources, the Virtual Machine also outputs to both of them.  Within this section of the manual you will find the GPC functions which either receive data from the outside world or affect the data being sent to it.(I/O代表输入/输出。虚拟机的两个主要输入源来自已连接的控制器和控制台。除了从这两个源接收输入外,虚拟机还向这两个源输出。在手册的这一节中,你会发现GPC的功能,既可以接收外部世界的数据,也可以影响发送给它的数据。)
The contents of I/O Functions(I/O函数的内容)
Controller I/O Functions(控制器的I / O功能)
Console I/O Functions(控制台的I / O功能)
LEDs(灯光)
Rumble(震动)
Identifiers标识符
    Controller I/O Functions(控制器的I / O功能)
A controller is mainly an input device, however, the CronusMAX PLUS also sends data to them to control the rumble motors and LEDs.  Below are the GPC commands related to this data(控制器主要是一个输入设备,但CronusMAX PLUS也会向控制器发送数据来控制隆隆声电机和led灯。下面是与此数据相关的GPC命令)

Function Name(功能名称)Description(描述)
get_val
Returns the current value of a controller entry(返回控制器项的当前值)
get_lval
Returns the previous value of a controller entry(返回控制器项的前一个值)
get_ptime
Returns the elapsed time of a controller entries state change(返回控制器条目状态更改经过的时间)
get_controller
Returns the type of controller currently connected to the input port(返回当前连接到输入端口的控制器类型)
get_battery
Returns the current status of the battery for a wireless controller(返回无线控制器电池的当前状态)
set_led
Sets the LED state of the controller connected to the input port(设置连接到输入端口的控制器的LED状态)
set_rumble
Sets the rumble motors to a set speed in %(设置震动到一个设定的幅度(%))
event_press
Returns TRUE when a controller entry has been pressed(当控制器条目按下时返回TRUE)
event_release
Returns TRUE when a controller entry has been released(当控制器条目被释放时返回TRUE)
block
Blocks the output of a controller entry for a set amount of time(在设定的时间内阻止控制器条目的输出)
swap
swaps the output of two controller entries(交换两个控制器条目的输出)
sensitivity
Adjusts the sensitivity of an analogue controller entry(调整模拟控制器入口的灵敏度)
deadzone
Adjusts the deadzone of two controller entries(调整两个控制器项的死区)
stickize
Transforms the values of a mouse or Wiimote IR input to an analog stick(将鼠标或鼠标红外输入的值转换为模拟棒)
ps4_touchpad
Returns detailed information on the DualShock 4 touchpad state(返回DualShock 4触摸板状态的详细信息)
ps4_set_touchpad
Touches the DualShock 4 touchpad in a specific (X, Y) position(以特定的(X, Y)位置触摸DualShock 4触摸板)
turn_off
Turns off a wireless controller connected to the input port(关闭连接到输入端口的无线控制器)
wiir_offscreen
Returns TRUE if the IR sensor on a Wiimote is off screen(如果Wiimote上的红外传感器不在屏幕上,返回TRUE)
1、get_val
get_val returns the current value of a controller entry in the form of an int.  This means it returns a number which represents a percentage %.(get_val以int的形式返回控制器条目的当前值,这意味着它返回一个表示百分比%的数字。)
As GPC supports treating an int as a boolean value, the get_val command can be used to see if a controller entry simply has a value.  For example;(因为GPC支持将int作为布尔值处理,所以可以使用get_val命令来查看控制器条目是否有一个值。例如;)
if(get_val(PS4_R1))
would return TRUE if R1 / RB had a value other than 0 (zero).(如果R1 / RB的值不是0(零),则返回TRUE。)
It can also be used to check the specific value if a controller entry. For Example;(如果控制器输入值,它还可以用来检查特定的值。例如;)
if(get_val(PS4_R2) > 50)
would return TRUE if the R2 / RT axis was at a value greater than 50 %(如果R2 / RT轴的值大于50%,是否返回TRUE)
As get_val returns an int, you can also pass its return value in to a variable, like so;(当get_val返回int类型时,你也可以将它的返回值传递给变量,如下所示;)
int myvar;
main {
    myvar = get_val(XB1_LT);
}
Syntax语法
get_val ( <identifier> );
Parameters参数
<identifier> : the identifier of a controller entry
Returns
The current value of the specified identifier.  Can range from - 100 to + 100 deepening on the entry type(指定标识符的当前值。输入类型可以从- 100到+ 100之间)
2、get_lval
get_lval is similar to get_val with the exception that it returns the value of the specified identifier in the previous iteration (run) of the main loop. This value is also returned as a int and represents a percentage %.(get_lval类似于get_val,只是它在主循环的上一次迭代(运行)中返回指定标识符的值。该值也作为整数返回,表示百分数%。)
However, get_lval gets its data from the input report so, unlike get_val,  is not affected by any code before it.  For example, if you were to use the set_val command to overwrite the output of an identifier, get_lval would still return the previous value of said identifier.  You can see this in action by running the following command on your CronusMAX PLUS;(但是,get_lval从输入报告中获取数据,因此与get_val不同,它不受之前任何代码的影响。例如,如果要使用set_val命令覆盖标识符的输出,get_lval仍然会返回该标识符之前的值。你可以通过在你的CronusMAX PLUS上运行以下命令看到这一点;)
main {
    set_val(XB1_RT, 0);  // Set the value of RT / R2 to 0将RT / R2的值设置为0  
    set_val(TRACE_1, get_lval(XB1_RT));     // Even though RT / R2 has been set to 0 (zero) before this line of code即使RT / R2在这行代码之前被设置为0(零)
                                            // it will still return a value if the trigger is pressed如果触发器被按下,它仍然返回一个值
    set_val(TRACE_2, get_val(XB1_RT));      // This will always return 0 because RT / R2 has been set to 0 (zero)这个总是返回0,因为RT / R2被设置为0 (0)
                                            // before this line of code在这行代码之前
}
Syntax
get_lval ( <identifier> );
Parameters
<identifier> : the identifier of a controller entry
Returns
The previous value of the specified identifier.  Can range from - 100 to + 100 deepening on the entry type(指定标识符的前一个值。输入类型可以从- 100到+ 100范围)
3、get_ptime
get_ptime returns the value in milliseconds of an identifiers state change in the form of a int.  What his means is when an identifiers value changes from FALSE to TRUE  or vice versa, the counter for get_ptime on that identifier is reset to 0.(当一个标识符的值从FALSE变为TRUE或反之,该标识符上的get_ptime计数器将重置为0。)
Therefore the clock is always running for this function so it should be used with another command, such as get_val.(因此,该函数的时钟总是在运行,因此应该与另一个命令(如get_val)一起使用它。)
For example, using get_ptime in an if statement on its own like so;(例如,在if语句中单独使用get_ptime;)
if(get_ptime(XB360_A) > 200)
would give an undesired result as the statement would be TRUE is the button was pressed or not for greater than 200 milliseconds.(会给出一个反向结果,该语句为TRUE,当按钮被按下不超过200毫秒。)
Using get_ptime in combination with the command get_val would modify the statement to only return TRUE if the button had been pressed for longer than 200 milliseconds, as shown below;(将get_ptime与get_val命令结合使用将修改该语句,使其只在按钮被按下时间超过200毫秒时返回TRUE,如下所示;)
if(get_val(XB360_A) && get_ptime(XB360_A) > 200)
Syntax
get_ptime ( <identifier> );
Parameters
<identifier> : the identifier of a controller entry
Returns
The elapsed time of a controller entries state change. Value returned is in milliseconds with a range of 0 ~ 4000(控制器条目状态改变的经过时间。返回值以毫秒为单位,范围为0 ~ 4000)
4、get_controller
get_controller returns a value in the form of a int which represents the controller type currently connected to the input port of the CronusMAX PLUS.(get_controller返回一个int形式的值,该值表示当前连接到CronusMAX PLUS输入端口的控制器类型。)
0 (zero) is returned if no controller is connected and a value of 1 ~ 5 is returned if a controller is connected depending on the type of controller is connected.(如果没有连接控制器,返回0(零);如果连接控制器,返回1 ~ 5,这取决于连接控制器的类型。)
To save you from remembering which value relates to which type of controller, 5 constants have been created.  They are;(为了避免您记住哪个值与哪个类型的控制器相关,我们创建了5个常量。他们是;)
Name                Description             Value
PIO_PS3      PlayStation 3 Controller        1
PIO_XB360      Xbox 360 Controller           2
PIO_WII           Wii Controller             3
PIO_PS4      PlayStation 4 Controller        4
PIO_XB1        Xbox One Controller           5
Example of usage:(使用的例子:)
main {
    if(get_controller() == PIO_XB1) {
        // Do Something
    }
}
Syntax
get_controller (  );
Parameters
None
Returns
A value which represents which type of controller is currently connected(一个值,表示当前连接的控制器类型)
5、get_battery
get_battery returns the battery level, if applicable, of the connected controller in the form on an int ranging from 0 ~ 10.  With 0 being discharged and 10 being fully charged.(get_battery返回表单中连接的控制器的电池级别(如果适用的话),值范围为0 ~ 10。0指无电,10指充满电。)
If no battery is connected, for example a wired controller is connected, then it returns 10.(如果没有电池连接,例如有线控制器连接,则返回10。)
Example of usage:(使用的例子:)
main {
    if(get_battery() <= 2) {
        // Do Something
    }
}
Syntax
get_battery (  );
Parameters
None
Returns
A value ranging from 0 (Discharged) ~ 10 (Fully Charged)(数值范围为0(放电)~ 10(充满电))
6、set_led
set_led sets the state of an LED on the controller.(set_led设置控制器上LED的状态。)
The LEDs range from 0 ~ 3.  Four constants have been created to make it easier to remember which value is assigned to which LED;(led的范围是0 ~ 3。创建了四个常量,以便更容易记住哪个值赋给了哪个LED;)
Name             Description               Value
LED_1     LED 1 / Xbox 360 Quadrant 1        0
LED_2     LED 2 / Xbox 360 Quadrant 2        1
LED_3     LED 3 / Xbox 360 Quadrant 3        2
LED_4     LED 4 / Xbox 360 Quadrant 4        3
An LED can be set to one of four states using this function which range from 0 ~ 3, as shown in the table below;(使用此功能,LED可以设置为0 ~ 3范围内的四种状态之一,如下表所示;)
Value       Description
0            LED Off
1             LED On
2          LED Blink Fast
3         LED Blink Slowly
Example of usage:(使用的例子:)
set_led(LED_1, 3);  // Make LED 1 blink slowly使LED 1闪烁缓慢
Syntax
set_led ( <led_identifier> , <state> );
Parameters
<led_identifier> : the identifier of an LED(LED的标识符)
<state>          : Numeric value which represents the state, as shown in the table above(代表状态的数值,如上表所示)
The next chapter more information on setting LED states(下一章LEDS更多关于设置LED状态的信息)
7、set_rumble
set_rumble sets the speed of the chosen rumble motor on the controller.

The rumble motors are numbered 0 ~ 3.  To make it easier to remember which motor is which, four constants have been created;

Name               Description                 Value
RUMBLE_A       Strong Rumble Motor                0
            (Usually the Left Motor)               
RUMBLE_B       Weak Rumble Motor                  1
           (Usually the Right Motor)
RUMBLE_RT      Right Trigger Motor                2
           (Xbox One controllers only)
RUMBLE_LT      Left Trigger Motor                 3
           (Xbox One controllers only)
Example of usage:(使用的例子:)
set_rumble(RUMBLE_A, 50);
Syntax
set_rumble ( <rumble_identifier> , <speed as %> );
Parameters
<rumble_identifier> : the identifier of a Rumble Motor(震动的标识符)
<speed as %>        : Numerical value, range 0 ~ 100(数值范围0 ~ 100)
The next chapter more information on setting Rumble Motors(下一章Rumble更多关于设置震动的信息)
8、event_press
event_press returns TRUE in the main iteration when a control changes from FALSE to TRUE.  Therefore, even if a button is pressed and held down, event_press would only return TRUE at the moment it is pressed and not while the button was held.  This makes it perfect for combos you only wish to run once when a button is pressed.(当控件从FALSE更改为TRUE时,event_press在主迭代中返回TRUE。因此,即使一个按钮被按下并按住,event_press只会在按下时返回TRUE,而不是在按钮被按住时返回TRUE。这使它完美的运行组合时,你只希望运行一次按下一个按钮的要求。)
For example, if you were playing a first person shooter, using a sniper rifle and you wanted the CronusMAX PLUS to automatically scope when you aimed down you sights.  You could do this;(例如,如果你在玩第一人称射击游戏,使用狙击步枪,你想让CronusMAX PLUS在瞄准时自动开镜。你可以这样做;)
main {
    if(event_press(XB1_LT)){ // If LT / L2 is pressed...
        combo_run(scope_in);    // Run combo scope_in
    }
}
combo scope_in {
    wait(400);  // Wait for the ADS animation to finish
    set_val(XB1_RS, 100); // Press Right Stick to Zoom scope
    wait(200);  // Press RS / R3 for 200ms
}
Syntax
event_press ( <identifier> );
Parameters
<identifier> : the identifier of a controller entry(控制器条目的标识符)
9、event_release
event_release is the opposite of event_press, it returns TRUE in the main iteration when a control changes from TRUE to FALSE.  This makes it ideally suited to run code you which you only want run once when a button is released.(event_release与event_press相反,当控件从TRUE更改为FALSE时,它在主迭代中返回TRUE。这使得它非常适合运行你只希望在按钮释放时运行一次的代码。)
For example, if you were playing a shooter game and wanted the gun to be automatically reloaded whenever you stopped shooting, you could do this;(举个例子来说吧,如果你正在玩一款射击游戏,并希望当你停止射击时枪支能够自动重新装弹,你便可以这么做;)
main {
    if(event_release(XB1_RT)){ // If RT / R2 is pressed...
        combo_run(reload);    // Run combo reload
    }
}
combo reload {
    wait(200);  // Wait for the gun animation to finished
    set_val(XB1_X, 100); // Press X / Square to reload
    wait(200);  // Press X / Square for 200ms
}
Syntax
event_release ( <identifier> );
Parameters
<identifier> : the identifier of a controller entry(控制器条目的标识符)
10、block
block prevents the forwarding of a controller entry for a set period of time which is set in milliseconds.  This time can range from 20 to 4000 milliseconds.  It it is extremely useful when you wish to get two uses from a single button.(阻止在设定的以毫秒为单位的时间内转发控制器条目。这段时间从20毫秒到4000毫秒不等。它是非常有用的,当你希望从一个按钮得到两个用途。)
For example, if you were playing a platform game and wished for the CronusMAX PLUS to automatically perform a double jump for you if you held the button down, you could do this;(例如,如果你正在玩一款平台游戏,并希望CronusMAX PLUS能够在你按住按键时自动执行两次跳跃,你便可以这么做;)
main {
    if(get_val(XB1_A)){  // If A / Cross is held...如果A / Cross被按住…
        if(event_press(XB1_A)){  // When first pressed....当按下A/Cross
            combo_run(single_jump); // Run combo single jump运行combo
        }
        block(XB1_A, 500); // Block the forwarding of A / Cross from the controller for 500 ms阻止从控制器触发A / Cross 500 ms
    }
}
combo single_jump {
    set_val(XB1_A, 100);
    wait(300);
}
The above code will run the combo single_jump as soon at the button is pressed.  If the button is released within 500 milliseconds then there is no further output to the console.  However, if the button is held for longer than 500 milliseconds then the normal output of that button resumes.(上面的代码将在按下按钮时立即运行组合single_jump。如果按钮在500毫秒内释放,则不会再输出到控制台。但是,如果按钮被按住的时间超过500毫秒,则该按钮的正常输出将恢复。)
Output with a quick tap of the button;(快速点击按钮输出;)

Output when the button is held;(按住按钮时输出;)

Syntax
block ( <identifier> , <milliseconds> );
Parameters
<identifier>   : the identifier of a controller entry
<milliseconds> : Length of time in milliseconds to block forwarding for.  Allowed range 20 ~ 4000(要阻止转发的时间长度(毫秒)。允许范围20 ~ 4000)
11、swap
swap does as the name implies, it swaps the values of two controller entries. This makes it useful for remapping buttons on the fly.(swap顾名思义,它交换两个控制器条目的值。这使得它在动态地重新映射按钮时非常有用。)
For example, if you were playing a shooter game which zooms the scope with a Right Stick Click when you Aim Down the Sights but you wished to move that function to the Right Bumper Button so it does not interfere with your aiming, you could do this;(举个例子来说吧,如果你正在玩一款射击游戏,即当你瞄准瞄准时,你需要通过右键点击摇杆来缩放范围,但是你希望将该功能移到右边的R1键上,这样它便不会影响你的瞄准,你便可以这么做;)
main {
    if(get_val(XB1_LT)) { // If LT / L2 is pressed...当按住LT/L2键时,
        swap(XB1_RS, XB1_RB); // Swap RS /R3 and RB / R2交换RS /R3和RB / R1
    }
}
With the above code, whenever LT / L2 is pressed, RB / R2 will press the Right Stick click and vice versa.(使用上面的代码,当LT / L2被按下时,按RB / R1将表现按右摇杆R3,反之亦然。)
Syntax
swap ( <identifier1> , <identifier2> );
Parameters
<identifier1>   : the identifier of a controller entry
<identifier2>   : the identifier of a controller entry
12、sensitivity
sensitivity adjusts the sensitivity of an analogue controller entry, usually this is an axis.(灵敏度调节模拟控制器输入的灵敏度,通常这是一个轴。)
The function takes three parameters, the control to be modified, the midpoint and the sensitivity multiplier.(该函数有三个参数,要修改的控制,中点midpoint和灵敏度倍增器。)
Midpoint sets the midpoint value of the controller entry.  The default value is 50%.  By changing this value, you are setting two sensitivity ranges.  With a value lower than 50% a high senstivity range is created closer to the rest position and a low sensitivity range when far from the rest position.  A value above 50% creates the opposite effect.(Midpoint设置控制器项的中点值。默认值为50%。通过更改这个值,可以设置两个灵敏度范围。当值低于50%时,靠近静止位置创建高灵敏度范围,远离静止位置创建低灵敏度范围。如果数值高于50%则会产生相反的效果。)
The Sensitivity multiplier is the amount the input vale is multiplied by.  The parameter is passed in percentage.  So 40 would mean multiply by 0.40, 100 means multiply by 1.00 and 140 means multiply by 1.40.(灵敏度倍增器是输入值乘以的量。参数以百分比传递。40表示乘以0.40 。100表示乘以1.00。 140表示乘以1.40。)
How these translate into the difference between the input into the CronusMAX PLUS and the output to the console can be seen below.(下面可以看到这些转换成CronusMAX PLUS的输入和控制台的输出之间的差异。)
With a midpoint of 35% and a sensitivity of 100 using the command - sensitivity(XB1_LX, 35, 100);(使用命令灵敏度(XB1_LX, 35, 100),中点为35%,灵敏度为100;)

With a midpoint of 70% and a sensitivity of 140 using the command - sensitivity(XB1_LX, 70, 140);(使用命令灵敏度(XB1_LX, 70, 140),中点为70%,灵敏度为140;)

Syntax
sensitivity ( <identifier> , <midpoint> , <sensitivity> );
Parameters
<identifier>   : the identifier of a controller entry标识符
<midpoint>     : sets the midpoint value中点值
<sensitivity>  : the ratio of the sensitivity adjustment灵敏度
13、deadzone
deadzone adjusts the values of the output to alter the deadzone of two axis.   The default deadzone programmed into consoles is 20%, this means a console will ignore any signal from an analogue stick which is below 20%.  The CronusMAX PLUS can adjust the output signals relative to the input.(死区调整输出值以改变两轴的死区。控制台默认的死区是20%,这意味着控制台将忽略任何来自低于20%的模拟操纵杆的信号。CronusMAX PLUS可以根据输入信号调整输出信号。)
For example, if you wished to remove 10% of the deadzone, the CronusMAX PLUS will output and additional 10% on both axis with the command;(例如,如果您希望删除10%的死区,CronusMAX PLUS将输出,并在两个轴上附加10%的命令;)
deadzone(XB1_LX, XB1_LY , 10, 10);
With the above command, a physical movement of 10% on the Left stick of either the Horizontal or Vertical Axis would output as 20%.  An additional 10% is added to the output up until 90%.  Any movement from 90% or greater will output 100%, as shown on the graph below;(使用上面的命令,在水平轴或垂直轴的左侧杆上物理移动10%将输出为20%。额外的10%被添加到输出,直到90%。如下图所示,任何从90%或更高的移动将输出100%;)

The above code will create a square deadzone, that means 10% will be applied to both sticks at all times.  However, the deadzone function can also be used to create a circular deadzone using the predefined constant, DZ_CIRLCE (which equals 101).(上面的代码将创建一个正方形的死区,这意味着10%将一直应用于两根棍子。但是,死区函数还可以使用预定义的常量DZ_CIRLCE(等于101)创建循环死区。)
When you use DZ_CIRCLE (or 101) in the third parameter instead of a value, the forth parameter then sets the radius of the circle instead of the value for the Y axis.(当您在第三个参数中使用DZ_CIRCLE(或101)而不是值时,第四个参数将设置圆的半径而不是Y轴的值。)
Example when using the DZ_CIRCLE constant;(使用DZ_CIRCLE常量时的示例;)
deadzone(XB1_LX, XB1_LY , DZ_CIRCLE , 10);
Syntax
deadzone ( <identifier_x> , <identifier_y> , <dzone_x> / DZ_CIRCLE , <dzone_y> / <radius> );
Parameters
<identifier_x>        : a controller entry which represents an X axis
<identifier_y>        : a controller entry which represents a Y axis
<dzone_x> / DZ_CIRCLE : X axis deadzone value / DZ_CIRCLE constant
<dzone_y> / <radius>  : Y axis deadzone value / The radius value of the circle
14、stickize
stickize transforms the values of a Wiimote IR or mouse input to an analog stick.  It does this by setting the radial output of the translation from their movements to the analogue stick, as shown in the diagram below;(stickize将鼠标或鼠标输入的值转换为模拟棒。它通过设置从他们的运动到模拟杆的径向输出来做到这一点,如下图所示;)
<TODO>  Insert Diagram
As the PS3 has a square output for its analogue sticks, we recommend a value of 129 is used on that console.  The Xbox 360, Xbox One and PS4 all use a radial output so we recommend a value of 113 is used on those consoles.(由于PS3的模拟摇杆有一个方形输出,我们建议在该主机上使用129的值。Xbox 360、Xbox One和PS4都使用径向输出,所以我们建议在这些主机上使用113的值。)
Syntax
stickize ( <identifier_x> , <identifier_y> ,  <radius> );
Parameters
<identifier_x>        : a controller entry which represents an X axis
<identifier_y>        : a controller entry which represents a Y axis
<radius>              : The radius value of the circle半径
15、ps4_touchpad
ps4_touchpad returns detailed information on the current state of the touchpad.  Like get_val, it returns an int.  ps4_touchpad can give you information on where two fingers are positioned on the touchpad and their X / Y coordinates.(ps4_touchpad返回关于touchpad当前状态的详细信息。像get_val一样,它返回一个int_touchpad。ps4_touchpad可以给你两个手指在touchpad上的位置和它们的X / Y坐标的信息。)
This is done via six constants;(这是通过6个常量实现的;)
PS4T_ Constant    Value      Returns
PS4T_P1           1          TRUE if at least one finger is on the touchpad,               
                             FALSE if none(如果至少有一个手指在触摸板上,则为TRUE;如果没有,则为FALSE)
PS4T_P1X          2          X axis value of the first finger on the touchpad(第一个手指在触摸板上的X轴值)
PS4T_P1Y          3          Y axis value of the first finger on the touchpad(第一个手指在触摸板上的Y轴值)
PS4T_P2           16         TRUE if two fingers are on the touchpad, FALSE if
                             less than two.(如果两个手指在触摸板上,则为TRUE;如果少于两个,则为FALSE。)
PS4T_P2X          32         X axis value of the second finger on the touchpad(触控板上第二个手指的X轴值)
PS4T_P2Y          48         Y axis value of the second finger on the touchpad(触控板上第二个手指的Y轴值)
To get the value of a one of the above constants, simply use it in the ps4_touchpad parameter.  For example, to read the state of all the constants, you could do this;(要获得上述常量之一的值,只需在ps4_touchpad参数中使用它。例如,要读取所有常量的状态,你可以这样做;)
main {
    if(ps4_touchpad(PS4T_P1)) {  // If at least one finger is on touchpad...
        set_val(TRACE_1, 1); // Set TRACE_1 to 1
        set_val(TRACE_2, ps4_touchpad(PS4T_P1X)); // Set TRACE_2 to X coordinate of touchpoint 1
        set_val(TRACE_3, ps4_touchpad(PS4T_P1Y)); // Set TRACE_3 to Y coordinate of touchpoint 1
    } else { // If no fingers are on the touchpad...
        set_val(TRACE_1, 0); // Set TRACE_1 to 0
    }
    if(ps4_touchpad(PS4T_P2)) { // If two fingers is on touchpad...
        set_val(TRACE_4, 1); // Set TRACE_4 to 1
        set_val(TRACE_5, ps4_touchpad(PS4T_P2X)); // Set TRACE_5 to X coordinate of touchpoint 2
        set_val(TRACE_6, ps4_touchpad(PS4T_P2Y)); // Set TRACE_6 to Y coordinate of touchpoint 2
    } else { // If less than two fingers on the touchpad...
        set_val(TRACE_4, 0); // Set TRACE_4 to 0
    }
}
Syntax
ps4_touchpad ( <S4T_constant> );
Parameters
<S4T_constant> : A constant from the table above
Returns
An int value related to the PS4T_ constant used
16、ps4_set_touchpad
ps4_set_touchpad will touch the DualShock 4 touchpad in a specific (X, Y) position(ps4_set_touchpad将在一个特定的(X, Y)位置触摸DualShock 4 touchpad)
Syntax
ps4_set_touchpad ( <X Value>, <Y Value> )
Parameters
<X Value> : X position in the DualShock 4 touchpad, ranging from -100 to 100.
<Y Value> : Y position in the DualShock 4 touchpad, ranging from -100 to 100.
Returns
None
combo Touch_And_Click_DS4Touchpad {

    ps4_set_touchpad(90, 45);
    set_val(PS4_TOUCH, 100);
    wait(80);
}
17、turn_off
turn_off will switch off a wireless controller connected to the CronusMAX PLUS input port.(turn_off将关闭无线控制器连接到CronusMAX PLUS输入端口。)
Example of usage:(使用的例子:)
main {
    if(event_press(XB1_RS)) { // If RS / R3 is pressed...当按下R3
        turn_off(); // Turn off wireless controller关闭无线控制器
    }
}
Syntax
turn_off ( );
Parameters
None
18、wiir_offscreen
wii_offscreen checks to see if the Wiimote controller is pointing off screen.(wii_offscreen检查Wiimote控制器是否指向屏幕外。)
Example of usage:(使用的例子:)
main {
    if(wii_offscreen()) {
        // Do Something
    }
}
Syntax
wii_offscreen ( );
Parameters
None
Returns
TRUE if the Wiimote IR is pointing off screen, FALSE if it is not(如果鼠标的IR指向屏幕外,为TRUE;如果不指向屏幕外,为FALSE)
Console I/O Functions(控制台的I / O功能)
The CronusMAX PLUS mainly outputs data to a console, however, it does receive data such as rumble and led states which we can read in GPC scripts.  Below are the GPC commands related to this data(CronusMAX PLUS主要将数据输出到控制台,但它确实接收诸如震动和led状态等数据,我们可以在GPC脚本中读取这些数据。下面是与此数据相关的GPC命令)


Function Name                     Description
set_val                 Overwrites the current value of a controller entry(重写控制器项的当前值)
get_console             Returns the current type of console connected to the
                        output port(返回连接到输出端口的控制台的当前类型)
output_reconnection     Disconnects and Reconnects the USB connection on the
                        output port(断开并重新连接输出端口上的USB连接)
ps4_authtimeout         Returns the PS4 authentication timeout state(返回PS4身份验证超时状态)
get_led                 Returns the current state of a specified LED(返回指定LED的当前状态)
get_rumble              Returns the current vale of a rumble motor(返回震动的当前阀值)
1、set_val
set_val overwrites the current value of a controller entry with the value that is specified in its second parameter.  What this means is whatever the output is from the controller for the specified button/axis, the set_val command will overwrite that value with the value you specify.(set_val用它的第二个参数中指定的值覆盖控制器条目的当前值。这意味着无论控制器为指定的按钮/轴输出什么,set_val命令将用您指定的值覆盖该值。)
It is mainly used in combos to set buttons in sequence, however, it can also be used in the main or user created function.(它主要用于连击中按顺序设置按钮,但也可以用于主功能或用户自定义功能。)
For example, if you were playing a shooter game and wished to create Hair Triggers.  A combo would not be suitable for such a function as you would want the output constant for however long the triggers are held down.  You could use the set_val command within the main section to achieve that function, like so;(举个例子来说吧,如果你正在玩一款射击游戏并希望缩短键程。combo并不适合这样的函数,因为无论触发器按住多长时间,您都希望输出常量。你可以在main部分中使用set_val命令来实现这个功能,就像这样;)
main {
    if(get_val(XB1_LT)) { // If LT / L2 is pressed按住LT/L2时
        set_val(XB1_LT, 100); // Set LT / L2 to 100 (Fully Pressed)设置为完全按下
    }
    if(get_val(XB1_RT)) { // If RT / R2 is pressed按住RT/R2时
        set_val(XB1_RT, 100); // Set RT / R2 to 100 (Fully Pressed)设置为完全按下
    }
}
Syntax
set_val ( <identifier> );
Parameters
<identifier> : the identifier of a controller entry
2、get_console
get_console returns a value in the form of a int which represents the type of console currently connected to the output port of the CronusMAX PLUS.(get_console返回一个int形式的值,该值表示当前连接到CronusMAX PLUS输出端口的控制台类型。)
0 (zero) is returned if no console is connected and a value of 1, 2, 4 or 5 is returned if a console is connected, depending on the type of console connected.(如果没有连接控制台,则返回0(零);如果连接控制台,则返回值1、2、4或5,这取决于所连接控制台的类型。)
To save you from remembering which value relates to which type of controller, 4 constants have been created.  They are;(为了避免您记住哪个值与哪个类型的控制器相关,我们创建了4个常量。他们是;)
Name         Description            Value
PIO_PS3      PlayStation 3           1
PIO_XB360     Xbox 360               2
PIO_PS4      PlayStation 4           4
PIO_XB1       Xbox One               5
Example of usage:(使用的例子:)

main {
    if(get_console() == PIO_XB1) {
        // Do Something
    }
}
Syntax
get_console (  );
Parameters
None
Returns
A value which represents which type of console is currently connected.(一个值,表示当前连接的控制台类型。)
3、output_reconnection
output_reconnection forces the CronusMAX PLUS to electronically disconnect the output port from the console and then reconnect again.  This function was mainly used to reset the authentication timeout on the PS4, however, it is redundant now as there is no timeout when using a USB HUB on Firmware 1.20 and above.  It has been left in for legacy CronusMAX Users.(output_reconnection强制CronusMAX PLUS以电子方式断开输出端口与控制台的连接,然后重新连接。这个功能主要用于重置PS4上的身份验证超时,然而,现在它是多余的,因为在固件1.20及以上版本上使用USB集线器时没有超时。它留给了CronusMAX的遗留用户。)
Example of usage:(使用的例子:)
main {
    if(get_val(XB1_MENU) && event_press(XB1_XBOX)) {  // If MENU / OPTIONS / START is held and XBOX / PS button is pressed...
        output_reconnection();  // Disconnect & Reconnect to console断开连接并重新连接到控制台
        set_val(XB1_XBOX, 0); // Zero XBOX / PS button to prevent it interfering with game 松开XBOX / PS按钮,以防止它干扰游戏
    }
}
Syntax
output_reconnection (  );
Parameters
None
4、ps4_authtimeout
ps4_authtimeout returns the authentications timeout status on the PS4 in the form of an int.  As with output_reconnection, this function is redundant since Firmware 1.20 and above as Partial PS4 cross over support is no longer required.  However, the function has not been removed as legacy CronusMAX users and those not using a USB Hub would still require it.(ps4_authtimeout以int的形式返回PS4上的验证超时状态。与output_reconnection一样,这个功能是多余的,因为固件1.20及以上版本不再需要部分PS4交叉支持。不过,作为CronusMAX的遗留用户,该功能并没有被移除,那些不使用USB集线器的用户仍然需要它。)
The main function of ps4_authtimeout is to enable you to script a warning when the CronusMAX PLUS is close to automatically disconnecting and reconnecting to the console when the authentication times out on a PS4.  This could be achieved using a script from our online library;(ps4_authtimeout的主要功能是,当在PS4上的身份验证超时时,当CronusMAX PLUS接近自动断开并重新连接到控制台时,使您能够编写一个警告脚本。这可以通过我们的在线图书馆的脚本实现;)
int authcount;
int NOTIFY = 3; //1 = 30 secs 2 = 1 min 3 = 1 min 30 secs and so on up to 16.

main{
    //PS4 Cross Over Gaming Section
    if(get_console() == PIO_PS4  && get_controller() != PIO_PS4){
        authcount = ps4_authtimeout();
        swap(1,27);                     // Swap Back/Select with Touchpad Press
        if(get_val(27) && get_val(5)) { // Press Back/Select and press RS/R3 to press share.
            set_val(27, 0);
            set_val(5, 0);
            set_val(1, 100);
        }      
        if(get_val(27)) {             // Hold Back/Select and Press A/Cross to reset Auth Timeout.
            if(event_press(19)){
                output_reconnection();
            }
            set_val(19, 0);
        }
        if(authcount <= NOTIFY + 1) {
            combo_run(notify);
        }
    }
    //PS4 Cross Over Gaming Section End
}
combo notify{
    set_rumble(RUMBLE_A, 100);
    set_rumble(RUMBLE_B, 100);
    wait(150);
    reset_rumble();
    wait(250*authcount);
}
Syntax
ps4_authtimeout (  );
Parameters
None
Returns
The PS4 authentication timeout status.  This is a decedent count down with 1 being the last value returned before an Automatic Reconnection is performed by the CronusMAX PLUS.(PS4身份验证超时状态。这是一个递减计数,1是CronusMAX PLUS执行自动重连之前的最后一个返回值。)
5、get_led
get_led returns a value in the form of an int which represents the current state of the chosen LED.(get_led接收到一个int形式的值,该值表示所选LED的当前状态。)
The LEDs range from 0 ~ 3.  Four constants have been created to make it easier to remember which value is assigned to which LED;(led的范围是0 ~ 3。创建了四个常量,以便更容易记住哪个值赋给了哪个LED;)
Name             Description               Value
LED_1     LED 1 / Xbox 360 Quadrant 1        0
LED_2     LED 2 / Xbox 360 Quadrant 2        1
LED_3     LED 3 / Xbox 360 Quadrant 3        2
LED_4     LED 4 / Xbox 360 Quadrant 4        3
The return value from this function informs you of the current state of the selected LED.  The function returns a value ranging from 0 ~ 3;(这个函数的返回值告诉您所选LED的当前状态。函数返回一个范围为0 ~ 3的值;)
ReturnValue     Description
0                 LED Off
1                 LED On
2              LED Blink Fast
3              LED Blink Slowly
Example of usage使用的例子
main {
    if(get_led(LED_2) == 1) { // If LED 2 is On
        // Do Something
    }
}
Syntax
get_led ( <Led_Identifier>  );
Parameters
<Led_Identifier> : The identifier of an LED
Returns
An int ranging from 0 ~ 3 which represents the current state(一个取值范围为0 ~ 3的整数,表示当前状态)

The next chapter more information on LED states(下一章更多关于LED状态的信息)
6、get_rumble
get_rumble returns the speed of the chosen rumble motor on the controller in the form of an int.  The value returned can range from 0 ~ 100 which represents the speed in a percentage ( % ).(get_rumble以int的形式返回控制器上选定的rumble电机的强度,返回的值范围为0 ~ 100,以百分比(%)表示强度。)
The rumble motors are numbered 0 ~ 3.  To make it easier to remember which motor is which, four constants have been created;(rumble电机编号0 ~ 3。为了更容易记住哪个是哪个,我们创建了四个常量;)
Name                      Description                            Value
RUMBLE_A     Strong Rumble Motor (Usually the Left Motor)          0
RUMBLE_B     Weak Rumble Motor (Usually the Right Motor)           1
RUMBLE_RT    Right Trigger Motor (Xbox One controllers only)       2
RUMBLE_LT    Left Trigger Motor (Xbox One controllers only)        3
Example of usage:(使用的例子:)
main {
    if(get_rumble(RUMBLE_A) > 50) {  // If Rumble Motor A is running greater than 50% speed...
        // Do Something
    }
}
Syntax
get_rumble ( <rumble_identifier> );
Parameters
<rumble_identifier> : the identifier of a Rumble Motor
Returns
An int ranging from 0 ~ 100 which represents the current speed of the chosen motor(取值范围为0 ~ 100的整数,表示所选电机的当前强度)
The next chapter more information on setting Rumble Motors(下一章更多关于设置震动的信息)
              LEDs(信息灯)
The CronusMAX PLUS allows you to control the LEDs on your controller if the controller supports it.  Setting the LEDs is useful when you wish to create a visual indicator of an active function in your scripts.(CronusMAX PLUS允许您控制控制器上的led,如果控制器支持它。当您希望在脚本中创建活动函数的可视指示器时,设置led非常有用。)
On a PS3, Wii and Xbox 360 controller, you have 4 leds which can be controlled independently although note that Xbox 360 controllers only allow one led to be lit at any time.  The PS4's native controller, the DS4, has one lightbar which supports and array of colors.  The Xbox One official controller does not support LED functions at this time.(在PS3、Wii和Xbox 360控制器上,你有4个led灯,它们可以独立控制,但要注意Xbox 360控制器在任何时候只允许一个led亮起。PS4的本机控制器DS4有一个支持颜色和数组的灯条。Xbox One官方控制器目前不支持LED功能。)

Functions related to LEDs(led相关功能)
Function Name                   Description
get_led            Returns the current value of a LED state接收到LED状态当前值
set_led            Set the state of a LED设置LED的状态
set_ledx           Blinks a LED a certain number of times使LED闪烁一定次数
get_ledx           Checks if a LED is being blinked by the set_ledx function检查LED是否被set_ledx函数闪烁
reset_leds         Reset the LEDs state to what was set by the console将led状态重置初始的状态
     LED Constants(LED灯的常量)
Controllable LEDs range from 0 ~ 3.  To make it easier to remember which value relates to which LED, the following Constants are available;(可控led的范围是0 ~ 3。为了更容易地记住哪个值与哪个LED相关,可以使用以下常量;)
Name             Description               Value
LED_1     LED 1 / Xbox 360 Quadrant 1        0
LED_2     LED 2 / Xbox 360 Quadrant 2        1
LED_3     LED 3 / Xbox 360 Quadrant 3        2
LED_4     LED 4 / Xbox 360 Quadrant 4        3
1、get_led
get_led returns a value in the form of an int which represents the current state of the chosen LED.(get_led接收到一个int形式的值,该值表示所选LED的当前状态。)
The LEDs range from 0 ~ 3.  Four constants have been created to make it easier to remember which value is assigned to which LED;(led的范围是0 ~ 3。创建了四个常量,以便更容易记住哪个值赋给了哪个LED;)
Name             Description               Value
LED_1     LED 1 / Xbox 360 Quadrant 1        0
LED_2     LED 2 / Xbox 360 Quadrant 2        1
LED_3     LED 3 / Xbox 360 Quadrant 3        2
LED_4     LED 4 / Xbox 360 Quadrant 4        3
The return value from this function informs you of the current state of the selected LED.  The function returns a value ranging from 0 ~ 3;(这个函数的返回值告诉您所选LED的当前状态。函数返回一个范围为0 ~ 3的值;)
ReturnValue     Description
0                 LED Off
1                 LED On
2              LED Blink Fast
3              LED Blink Slowly
Example of usage使用的例子
main {
    if(get_led(LED_2) == 1) { // If LED 2 is On
        // Do Something
    }
}
Syntax
get_led ( <Led_Identifier>  );
Parameters
<Led_Identifier> : The identifier of an LED
Returns
An int ranging from 0 ~ 3 which represents the current state(一个取值范围为0 ~ 3的整数,表示当前状态)
2、set_led
set_led sets the state of an LED on the controller. When an led state is set, it remains set until such time as the LEDs are reset, it is set again in your GPC script or the script is unloaded.(set_led设置控制器上LED的状态。当一个led状态被设置,它一直保持设置,直到led重置,它被再次设置在您的GPC脚本或脚本被卸载。)
An LED can be set to one of four states using this function which range from 0 ~ 3, as shown in the table below;(使用此功能,LED可以设置为0 ~ 3范围内的四种状态之一,如下表所示;)
Value       Description
0            LED Off
1             LED On
2          LED Blink Fast
3         LED Blink Slowly
Example of usage:(使用的例子:)
set_led(LED_1, 3);  // Make LED 1 blink slowly使LED 1闪烁缓慢
Syntax
set_led ( <led_identifier> , <state> );
Parameters
<led_identifier> : the identifier of an LED(LED的标识符)
<state>          : Numeric value which represents the state, as shown in the table above(代表状态的数值,如上表所示)
3、set_ledx
set_ledx is used to Blink and LED a set amount of times.  You can blink an led from 0 to 255 times.  0 sets the LED to on.(set_ledx用于闪烁和LED设定的次数。led可以从0闪烁到255次。0设置LED为on。)
Example of usage使用的例子
main {
    if(!get_ledx()) { // If the leds are not blinking...如果led不闪烁…
        set_led(LED_1, 10);  // Blink LED 1 10 timesLED 1闪烁10次
    }
}
Syntax
set_ledx ( <led_identifier> , <no_of_blinks> );
Parameters
<led_identifier> : the identifier of an LED
<no_of_blinks>   : The number of times to blink the LED(LED闪烁的次数)
4、get_ledx
get_ledx checks to see if an LED is currently being blinked by the set_ledx function.(检查LED当前是否被set_ledx函数闪烁。)

Example of usage:
main {
    if(get_ledx()) { // If the leds are blinking...
        // Do Something
    }
}
Syntax
get_ledx (  );
Parameters
None
Returns
TRUE is the LEDs are being blinked by the set_ledx function, FALSE if they are not(如果set_ledx函数使led闪烁,则为TRUE,否则为FALSE)
5、reset_leds
reset_leds returns control of the LEDs to the console and disables any current LED states which are being set by the Virtual Machine.(将LED的恢复到初始状态,并禁用克麦正在设置的任何当前LED状态。)
Example of usage:
main {
    if(event_press(XB1_A)) { // If A / Cross is Pressed...
        reset_leds();  // Reset Leds
    }
}
Syntax
reset_leds (  );
Parameters
None
6、Setting DS4 lightbar(设置DS4手柄排灯)
The Dualshock 4 controller has one lightbar instead of four LEDs.   The color of the lightbar can be controlled by setting all four led states simultaneously.(Dualshock 4控制器只有一个灯条,而不是四个led。通过同时设置所有四种led状态,可以控制灯条的颜色。)
For example, the following code will set the lightbar to green;(例如,下面的代码将灯条设置为绿色;)
main {
    if(event_press(PS4_CROSS)) {
        set_led(LED_1, 0);
        set_led(LED_2, 0);
        set_led(LED_3, 2);
        set_led(LED_4, 0);
    }
}
To save you from remembering all the different combinations, we have created this script which simplifies the task of setting the color with a custom function. You can add your own code to this and use the function to create visual notifications in your GPC script;(为了避免您记住所有不同的组合,我们创建了这个脚本,它简化了使用自定义函数设置颜色的任务。您可以添加自己的代码,并使用该函数在您的GPC脚本中创建可视化通知;)
// Dualshock 4 lightbar custom function
//
// Written by the CronusMAX Team
//
// For the CronusMAX PLUS manual www.cronusmax.com/manual/leds.htm#id_6
define Off = 0;
define Dim_Blue = 1;
define Dim_Red = 2;
define Dim_Green = 3;
define Dim_Pink = 4;
define Dim_SkyBlue = 5;
define Dim_Yellow = 6;
define Dim_White = 7;
define Blue = 8;
define Red = 9;
define Green = 10;
define Pink = 11;
define SkyBlue = 12;
define Yellow = 13;
define White = 14;
define Bright_Blue = 15;
define Bright_Red = 16;
define Bright_Green = 17;
define Bright_Pink = 18;
define Bright_SkyBlue = 19;
define Bright_Yellow = 20;
define Bright_White = 21;
data (
0,0,0,0, // Off
1,0,0,0, // Dim Blue
0,1,0,0, // Dim Red
0,0,1,0, // Dim Green
0,0,0,1, // Dim Pink
1,0,1,0, // Dim SkyBlue
0,1,1,0, // Dim Yellow
1,1,1,1, // Dim White
2,0,0,0, // Blue
0,2,0,0, // Red
0,0,2,0, // Green
0,0,0,2, // Pink
2,0,2,0, // SkyBlue
0,2,2,0, // Yellow
2,2,2,2, // White
3,0,0,0, // Bright Blue
0,3,0,0, // Bright Red
0,0,3,0, // Bright Green
0,0,0,3, // Bright Pink
3,0,3,0, // Bright SkyBlue
0,3,3,0, // Bright Yellow
3,3,3,3  // Bright white
);
main {
    //Examples of usage
    if(event_press(PS4_CROSS)) {  // If Cross is pressed...按下X键
        set_ds4_led(Green);  // Set the lightbar to Green设置成绿色
    }
    if(event_press(PS4_CIRCLE)) {  // If Circle is pressed...按下圆圈键
        set_ds4_led(Red);  // Set the lightbar to Red设置成红色
    }
    if(event_press(PS4_OPTIONS)) { // If Options is pressed...按下OPTION键
        reset_leds():  // Reset the LEDs重置LEDS设置
    }
}
function set_ds4_led(colour) {
    set_led(LED_1, dbyte(colour * 4));
    set_led(LED_2, dbyte((colour * 4) + 1));
    set_led(LED_3, dbyte((colour * 4) + 2));
    set_led(LED_4, dbyte((colour * 4) + 3));
}
            Rumble(震动)
The CronusMAX PLUS allows you to completely control the Rumble Motors on your controller, including the Trigger Rumble motors on an Xbox One controller.  Below are the GPC commands relating to these motors.(CronusMAX PLUS允许你完全控制控制器上的震动,包括Xbox One控制器上的触发震动。下面是与这些电机相关的GPC命令。)


Function Name            Description
get_rumble          Returns the current value of a Rumble Motor接收到当前震动
set_rumble          Set the speed of a Rumble Motor设置震动的强度
block_rumble        Blocks any rumble signals from the console阻止任何从机器来的震动
reset_rumble        Resets the rumble state and returns control of the motors to the console重置震动状态,并把震动的控制返回到机器
Rumble Constants(震动常量)
Rumble motors are numbered from 0 ~ 3. To make it easier to remember which Motor relates to which number, the following Constants are available;(Rumble电机编号从0到3。为了更容易地记住哪个电机与哪个数字相关联,可以使用以下常量;)
Name                      Description                            Value
RUMBLE_A     Strong Rumble Motor (Usually the Left Motor)          0
RUMBLE_B     Weak Rumble Motor (Usually the Right Motor)           1
RUMBLE_RT    Right Trigger Motor (Xbox One controllers only)       2
RUMBLE_LT    Left Trigger Motor (Xbox One controllers only)        3
1、get_rumble
get_rumble returns the speed of the chosen rumble motor on the controller in the form of an int.  The value returned can range from 0 ~ 100 which represents the speed in a percentage ( % ).(get_rumble以int的形式返回控制器上选定的rumble电机的速度,返回的值范围为0 ~ 100,以百分比(%)表示速度。)
Example of usage:
main {
    if(get_rumble(RUMBLE_A) > 50) {  // If Rumble Motor A is running greater than 50% speed...
        // Do Something
    }
}
Syntax
get_rumble ( <rumble_identifier> );
Parameters
<rumble_identifier> : the identifier of a Rumble Motor
Returns
An int ranging from 0 ~ 100 which represents the current speed of the chosen motor(取值范围为0 ~ 100的整数,表示所选电机的当前速度)
2、set_rumble
set_rumble sets the speed of the chosen rumble motor on the controller.  Once a rumble has been activated by a script, it will remain at the speed set until such time as the script sets it again, rumble is reset or the script is unloaded.(set_rumble设置控制器上选定的rumble电机的速度。一旦脚本激活了震动,它将保持在设定的速度,直到脚本再次设置,震动被重置或脚本被卸载。)
Example of usage:(使用的例子:)
main {
    if(event_press(XB1_A)) {  // If A / Cross is pressed...
        set_rumble(RUMBLE_A, 50);  // Set rumble motor A to 50% speed
    }
}
Syntax
set_rumble ( <rumble_identifier> , <speed as %> );
Parameters
<rumble_identifier> : the identifier of a Rumble Motor
<speed as %>        : Numerical value, range 0 ~ 100
3、block_rumble
block_rumble does as it implies and blocks any rumble signals to the controller.  Once this function is used, it remains active until such time as it is reset in the script or the script is unloaded.(block_rumble运行时像它所标注的,并阻止任何rumble信号到控制器。一旦这个函数被使用,它将一直处于活动状态,直到在脚本中重置或脚本被卸载。)
Example of usage:使用的例子:
main {
    if(event_press(XB1_A)) {  // If A / Cross is pressed...如果A / Cross被按下…
        block_rumble();  // Block rumble signals to the controller阻止震动信号发给控制器
    }
}
Syntax
block_rumble ( );
Parameters
None
4、reset_rumble
reset_rumble returns control of the rumble motors to the console.  It also deactivates block_rumble if it is active.(reset_rumble将rumble电机的控制返回到控制台。如果block_rumble是激活的,它也会禁用它。)
Example of usage:(使用的例子:)
main {
    if(event_press(XB1_A)) {  // If A / Cross is pressed...
        reset_rumble();  // Reset the rumble state
    }
}
Syntax
reset_rumble ( );
Parameters
None
         Identifiers(标识符)
The table below lists all the controller identifiers in GPC, the index value they relate to and the readable range from each one;(下表列出了GPC中的所有控制器标识符、与它们相关的索引值以及每个标识符的可读范围;)

Accelerometers(加速度): 25% represents(表示) 1G; 100% == 4G
Internal Functions & Commands(内部功能和命令)
Within this section of the manual you will find the functions and commands the Virtual Machine uses to handle data in GPC scripts.(在这一节中,您将找到克麦用来处理GPC脚本中的数据的函数和命令。)
The contents of Internal Functions & Commands(内部功能和命令的内容)
Flow Control Commands(流控制命令)
Math Functions       (数学函数)
Bit Operations       (位运算)
Persistent Variables (永久变量)
Miscellaneous Functions(其它函数)

        Flow Control Commands(流控制命令)


Flow control commands are integral to most GPC scripts as they allow you control the flow of executed code and tell the GPC how and when to make decisions.   Without any flow control commands in place, all your combos would run at once and you would have probably end up with a useless script.  Below are the GPC commands you can use to control the flow of code;(流控制命令是大多数GPC脚本所不可或缺的,因为它们允许您控制执行代码的流,并告诉GPC如何以及何时做出决策。如果没有任何流控制命令,你的所有组合将同时运行,你可能会得到一个无用的脚本。下面是你可以用来控制代码流的GPC命令;)

Command                Description
if       Evaluates an expression to its boolean value(计算表达式为其布尔值)
else     Executes alternative code when an if statement is FALSE(当if语
         句为FALSE时执行替代代码)
else if     Executes alternative code when an if statement is FALSE and its
            expression is TRUE(当if语句为假而其表达式为真时执行替代代码)
while      Loops code until its expression is FALSE or the break command is
           used(循环代码,直到表达式为FALSE或使用break命令为止)
1、if
The if command is one of the single most useful tools for your GPC scripting needs.  It allows you to control when certain blocks of code are run and it takes any expression, function or code which returns or has a value. It can also be used in the init, main, combo and function sections of your code.(if命令是满足GPC脚本需求的最有用的工具之一。它允许您控制特定代码块何时运行,并接受返回值或具有值的任何表达式、函数或代码。它还可以用于代码的init、main、combo和函数部分。)
The if command works by evaluating the expression within it to its boolean value.(if命令的工作原理是将其中的表达式求值为布尔值。)  
An expression is anything which has a value. Such as a function call which returns a value, a variable, a mathematical sum. literal values and comparisons.(表达式是任何有值的东西。例如返回值、变量、数学和的函数调用文字和类比赋值。)
In computer programming languages, a Boolean is a data type with only the two possible values, TRUE or FALSE.  In GPC, FALSE means 0 and TRUE is a value other than 0 be it a negative or positive value.(在计算机编程语言中,布尔值是一种数据类型,只有两种可能的值,真或假。在GPC中,FALSE表示0,TRUE是一个不等于0的值,无论它是负值还是正值)

If the expression placed within an if commands brackets is TRUE, then the code nested within it is executed, as sown below;(如果If命令括号内的表达式为TRUE,那么嵌套在该表达式中的代码将被执行,如下所示;)
// |¯¯¯¯¯¯¯¯¯¯¯¯|
// | If this is |
// ↓    true    ↓
if ( expression )
{   //←¯¯¯¯¯¯¯¯¯|
    //          | Run code placed here
}   //←_________|
If the expression is FALSE, then the code contained within the block is ignored.(如果表达式为FALSE,则忽略包含在块中的代码。)

You can also nest an if command within another if command in as many times as the bytecode limit will allow in your script. As shown below with other examples of if command usage;(您还可以将一个if命令嵌套在另一个if命令中,嵌套的次数是脚本中字节码限制所允许的。如下所示,还有其他if命令使用的例子;)
int x = 5, y = 10, z = 20;
init {
    if(get_console() == PIO_PS4)//如果接的是PS4主机
        x = 30;
}
main {
    if(get_val(7)) {//按住L2的时候
        if(x < y) {//如果x<y
            if(get_val(9) < -50)//如果右摇杆上推小于50%
                x = y + z;
            if(get_val(9) > 50)//如果右摇杆下推大于50%
                x = y + 20;
        }
    }
    if(x <= (z - y)) {
        z = y;
        x = 6;
    }
}
2、else
Should you wish to execute a different block of code when an if command does not return TRUE then you would use the else command.(如果您希望在if命令没有返回TRUE时执行不同的代码块,那么您可以使用else命令。)
An else command must have an if command preceding it.  The code block contained within an else command will be executed if the expression in the if statement returns FALSE, as shown below;(else命令之前必须有一个if命令。如果if语句中的表达式返回FALSE,则包含在else命令中的代码块将被执行,如下所示;)
int ADS;
main {
    if(get_val(XB1_LT)) // if LT / L2 is pressed...按住LT时
        ADS = TRUE;
    else               // else (If LT / L2 is not pressed)没有按住LT时
        ADS = FALSE;
}
The above code will set the variable ADS to TRUE if LT / L2 is pressed and will set it to FALSE if it is not.(如果LT / L2被按下,上面的代码将把变量ADS设置为TRUE,如果没有被按下,则设置为FALSE。)
3、else if
else if is a combination of else and if.  Just like the else command it allows for a different block of code to be executed when the statement within the if command returns FALSE.  However, it will only execute the code block when the statement within its parameter returns TRUE.(else if是else和if的组合。就像else命令一样,当if命令中的语句返回FALSE时,它允许执行不同的代码块。但是,它只会在其参数内的语句返回TRUE时执行代码块。)
For example, if you were playing a first person shooter game and wished for rapid fire to be disabled when you aim down the sights but wanted the CronusMAX PLUS to automatically hold breath in the game to steady your aim while aiming down the sights, the following code would do this for you;(举个例子,如果你玩第一人称射击游戏,希望当瞄准时连射被禁用,但希望CronusMAX 在瞄准时可以自动保持呼吸稳定,下面的代码将为你这样做;)
main {
    if(get_val(XB1_LT)) // if LT / L2 is pressed...按住L2的时候
        combo_run(Auto_HB);
    else if(get_val(XB1_RT)) // else if LT / L2 is not pressed and RT / R2 is hold如果LT / L2没有按下,但是按住RT / R2时
        combo_run(Rapid_Fire);
}
combo Auto_HB {
    wait(400);
    set_val(XB1_LS, 100);
    wait(100);
    wait(2000);
}
combo Rapid_Fire {
    set_val(XB1_RT, 100);
    wait(40);
    set_val(XB1_RT, 0);
    wait(30);
    set_val(XB1_RT, 0);
}
You can also extend an else if command with an else command or another else if statement.(您还可以使用else命令或其他else if语句扩展一个else if命令。)
main {
    if(get_val(XB1_LT)) // if LT / L2 is pressed...
        combo_run(Auto_HB);
    else if(get_val(XB1_RT)) // else if LT / L2 is not pressed and RT / R2 is....
        combo_run(Rapid_Fire);
    else {
        sensitivity(XB1_RX, 50, 125);
        sensitivity(XB1_RY, 50, 125);
    }
}
4、while
Other than the main section, the while command is the only loop function in GPC.  As the main function runs in a loop, there really isn't a need to use this command.  If you do choose to use it, although it can be used in the main section, it is recommended to only use it within a function so as not to temporarily halt the execution of a main iteration.(除了主程序之外,while命令是GPC中惟一的循环函数。由于主函数在循环中运行,实际上不需要使用这个命令。如果您选择使用它,尽管它可以在主部分中使用,但建议只在函数中使用它,以免暂时停止主程序的执行。)
The operation of the while command is straight forward, it will execute code nested within it until the expression contained in its parameter is no longer TRUE;(while命令的操作很简单,它将执行嵌套在其中的代码,直到参数中包含的表达式不再为真;)
main {
    if(event_press(XB1_A))
        _myfunction(10);
}
function _myfunction(var) {
    while(var) {
        var = var - 1;
    }
}
5、break
Should you wish to be able to end the while loop early, the break command has been created to make this possible.  You would simply create a condition, which when TRUE, would call the break command thus ending the while loop, like so;(如果您希望能够提前结束while循环,那么创建break命令就是为了实现这一点。你只需创建一个条件,当条件为TRUE时,将调用break命令,从而结束while循环,如下所示;)
main {
    if(event_press(XB1_A))
        _myfunction(10);
}
function _myfunction(var) {
    while(var) {
        var = var - 1;
        if(event_press(XB1_B))
            break;
    }
}
         Math Functions(数学函数)

In this section are the GPC functions used to perform specify mathematical operations.  Two important things to note when working with perform math task in GPC is that it is a signed 16bit environment so all operations must work within that range which is -32768 to +32767 and that GPC only supports integer values which means any fractions will be rounded down to a whole value.  For example 7 / 3 = 3.(在本节中是用于执行指定数学运算的GPC函数。两个重要的事情要注意使用执行数学任务时在GPC是签署了16位环境所以这个范围内的所有操作必须是-32768 + 32767,GPC只支持整数值这意味着任何分数将被四舍五入值。例如7 / 3 = 3。)
Function           Description
abs         Returns an absolute value(返回绝对值)
inv         Returns an inverted value(返回一个反向值)
pow         Raise and value to the specified power(提高并赋值到指定的幂)
isqrt       Calculates an integer square root(计算一个整数的平方根)
1、abs(绝对值)
The abs command returns the absolute value of an expression.  An absolute value is a number without regard for its sign, for example the absolute value of 8 and -8 is 8.  An absolute value can also be thought of as its distance from zero which is always a positive value.(abs命令返回表达式的绝对值。绝对值是一个数,不考虑其符号,例如8和-8的绝对值是8。绝对值也可以认为是它到零的距离,它总是一个正值。)

One of the popular uses for the abs command is when working with axis to start combos.  Such as in fighting games where many users tend to use the right stick to start a combo.  So if you wished for the same combo ro be run if for example the right stick was pushed left or right, instead of using an or ( || ) operator or using two if commands you could just do this;(abs命令的一个流行用法是当使用摇杆开始连招时。比如在格斗游戏中,许多用户倾向于使用右摇杆开始连击。所以,如果你想要运行相同的组合ro,例如右摇杆被推左或右,而不是使用或(||)操作符或使用两个if命令,你可以这样做;)
main {
    if( abs(get_val(XB1_RX)) > 70 ) // if RX is greater than 70 or less than -70...右摇杆左或右推动超过70%
        combo_run(my_combo);
}
combo my_combo {
    //Do something执行连招
}
Syntax
abs ( <expression> );
Parameters
<expression> : any expression which has a value
Returns
The absolute value of the expression(表达式的绝对值)
2、inv(负值)
inv returns the inverted value of an expression or number.  This means a positive value will be turned in to a negative value and vice versa, which is the same as multiplying the value by -1.  For example;(inv返回表达式或数字的负值。这意味着一个正值将转化为负值,反之亦然,这与将值乘以-1是相同的。例如;)
int a = 100;
int b = -50;
main {
    a = inv(a);  // a = -100
    b = inv(b);  // b = 50
}
One of the popular uses for this command is to invert the right sticks Y axis.  For example, if you prefere to play with an inverted aim but come across a game which doesn't support it, with one line of code you can have the CronusMAX PLUS invert the axis for you.   Like so;(这个命令的一个常用用途是将右摇杆的Y轴反转。例如,如果你想玩一个倒转的瞄准,但遇到一款游戏不支持它,只需一行代码,你就可以让CronusMAX PLUS为你倒转轴。像这样;)
main {
    set_val(XB1_RY, inv(get_val(XB1_RY)) ); // Set RY to the inverse of its current value设置RY为其当前值的反向
}
Syntax
inv ( <expression> );
Parameters
<expression> : any expression which has a value
Returns
The inverted value of the expression(表达式的反向值/负值)
3、pow(次方)
pow raises the given value to the power specified.  What this means is a value will be multiple by itself X amount of times.  For example;(pow将给定值提升为次方数。这意味着一个值将被自身乘以X次。例如;)
int a;
main {
    a = pow(5, 3); // a = 125 (5³) or (5 * 5 * 5)
}
This function must be used with caution as there is a risk of an integer overflow when using it.  This would occur when the function attempts to return a value greater than 32767 which is the maximum value for a signed 16 bit integer.(必须谨慎使用此函数,因为在使用它时存在整数溢出的风险。当函数试图返回大于32767(有符号16位整数的最大值)的值时,就会发生这种情况。)
Syntax
pow ( <expression1> , <expression1> );
Parameters
<expression1> :any expression which has a value
<expression2> :
any expression which has a value
Returns
the power specified of the expression
4、isqrt
isqrt returns the square root of a given value.  The square root of a value is the value which when multiplied by itself equals the given value.  For example, the square root of 25 is 5  (5 * 5 = 25). The return value is an integer which means any fractions will be dropped.  As shown below;(isqrt返回给定值的平方根。一个值的平方根等于给定值。例如,25的平方根是5(5 * 5 = 25)。返回值是一个整数,这意味着任何分数都将被删除。如下所示;)
int a;
main {
    a = isqrt(10);  // a = 3.  The square root of 10 is 3.16...
                    // GPC supports integer values only so the fraction is dropped.
}
Syntax
isqrt ( <expression> );
Parameters
<expression> : any expression which has a value
Returns
The square root of the given expression(给定表达式的平方根整数)
        Bit Operations(位运算)

GPC allows you to manipulate the bits of a given variable.  Bit operations are quite complicated, however, there is not really much call for them in the GPC environment and most users will never need them.  Therefore, this section will assume you have an understanding of bits, bit masks, how they correlate with bytes and the binary system.(GPC允许您操作给定变量的位。位操作是相当复杂的,然而,在GPC环境中并没有真正需要它们,大多数用户永远不会需要它们。因此,本节假设您已经了解位、位掩码,以及它们如何与字节和二进制系统相关联。)
Function       Description
set_bit      Sets one bit集一点
clear_bit    Clears one bit清除一点
test_bit     Tests a bit测试一点
set_bits     Stores a value into a bit index将一个值存储到位索引中
get_bits     Gets a value from a bit index从位索引获取值
1、set_bit

Sets one bit of a variable based on its bit index(根据变量的位索引设置变量的一位)
Syntax
set_bit ( <variable> , <bit_index> );
Parameters
<variable>  :any defined variable
<bit_index> :index point of the bit to be set, range 0~15
2、clear_bit

Clears one bit of a variable based on its bit index(根据变量的位索引清除该变量的一位)
Syntax
clear_bit ( <variable> , <bit_index> );
Parameters
<variable>  :any defined variable
<bit_index> :index point of the bit to be set, range 0~15
3、test_bit

Tests a bit index point in a variable to check if it is TRUE or FALSE ( 1 or 0 )(测试变量中的位索引点,检查它是真还是假(1还是0))
Syntax
test_bit ( <variable> , <bit_index> );
Parameters
<variable>  :any defined variable
<bit_index> :index point of the bit to be set, range 0~15
Returns
TRUE is the bit is set, FALSE if it is not.
4、set_bits


Stores a value in to a variable based on its bit index and a bit mask.(根据变量的位索引和位掩码将值存储到变量中。)
Syntax
set_bits ( <variable>, <value>, <bit_index>, <bit_mask> );
Parameters
<variable>  :any defined variable(任何定义的变量)
<value>     :anything that has a value (constants, variables, functions, expressions, etc...)(任何有值的东西(常量、变量、函数、表达式等))
<bit_index> :index point of the bit to be set, range 0~15(要设置的位的索引点,范围0~15)
<bit_mask>  :bit mask corresponding to the size, in bits, of the value to store (without shifting)(位掩码对应于要存储的值的大小(以位为单位)(不移位)
5、get_bits

Extracts a balue from a variable based on a bit index and bit mask(根据位索引和位掩码从变量中提取balue)
Syntax
get_bits ( <variable>, <bit_index>, <bit_mask> );
Parameters
<variable>  :any defined variable
<bit_index> :position of the less significant bit in the value to extract, range 0~15(待提取值中较低有效位的位置,范围为0~15)
<bit_mask>  :bit mask corresponding to the size, in bits, of the value to store (without shifting)(位掩码对应于要存储的值的大小(以位为单位)(不移位))
Returns
An integer value.
     Persistent Variables(永久变量)
Persistence in programming terms means a state which remains after the process that created it has ended.  A word processor or Paint application achieves this by saving the document to a file for example.  The CronusMAX PLUS does this by writing variable values to its EEPROM (Electrically Erasable Programmable Read-Only Memory).  This allows you to save the value of a variable so it can be recalled the next time the script is loaded.  There is space on the CronusMAX PLUS for a total of 160 persistent variables, 16 Global Variables and 144 Private Variables (16 for each slot).(在编程术语中,持久性是指在创建它的进程结束后仍然保留的状态。例如,文字处理程序或绘图应用程序通过将文档保存到文件中来实现这一点。CronusMAX PLUS通过将变量值写入其EEPROM(电可擦可编程只读存储器)来实现这一点。这允许您保存变量的值,以便下次加载脚本时可以调用它。CronusMAX PLUS上共有160个持久变量、16个全局变量和144个私有变量(每个插槽16个)。)
Global variables can be accessed and set from any slot. They are generally used to pass values between scripts.  16 constants have been created for use with the get and set commands for persistent variables, they are;(可以从任何插槽访问和设置全局变量。它们通常用于在脚本之间传递值。已经创建了16个常量用于get和set命令的持久变量,它们是;)
PVAR_1, PVAR_5,PVAR_9, PVAR_13,
PVAR_2,PVAR_6,PVAR_10,PVAR_14,
PVAR_3,PVAR_7,PVAR_11,PVAR_15,
PVAR_4,PVAR_8,PVAR_12,PVAR_16,
Private variables are private to a specific slot, each of the 9 slots has 16 private variables which are used to save specific values for one script.  For example Slot 1 has 16 private variables which no other Slot can access, you cannot read or set the value of Slot 1's variables from Slot 4 and setting the private variables in Slot 1 have any affect on the private variables in any other slot.  16 constants have been created for use with the get and set commands for persistent variables, they are;(私有变量是特定插槽的私有变量,9个插槽中的每个插槽都有16个私有变量,用于为一个脚本保存特定的值。例如,槽1有16个私有变量,其他槽不能访问这些私有变量,你不能从槽4中读取或设置槽1的变量值,而在槽1中设置私有变量对其他槽中的私有变量没有任何影响。已经创建了16个常量用于get和set命令的持久变量,它们是;)
SPVAR_1, SPVAR_5,SPVAR_9, SPVAR_13,
SPVAR_2,SPVAR_6,SPVAR_10,SPVAR_14,
SPVAR_3,SPVAR_7,SPVAR_11,SPVAR_15,
SPVAR_4,SPVAR_8,SPVAR_12,SPVAR_16,
To retrieve the value stored in a persistent variable or to set the value of one, the following functions are available;(要检索存储在持久变量中的值或设置持久变量的值,可以使用以下函数;)
Function    Description
get_pvar   Returns the value stored within a Persistent Variable(获取存储在持久变量中的值)
set_pvar   Stores a value in to a Persistent Variable(将值存储到持久变量中)
1、get_pvar
get_pvar returns the value stored in a Persistent Variable while allowing you to specify the minimum and maximum permissible value and a default value should the value stored be outside of that range.  The min, max and default parameters are mainly intended for when you are retrieving values from a Global variable, however, they must still be specified when reading the value of a private variable.(get_pvar获取存储在持久变量中的值,同时允许您指定允许的最小值和最大值,以及存储在该范围之外的默认值。min、max和默认参数主要用于从全局变量中检索值,但是,在读取私有变量的值时仍然必须指定它们。)
Example of usage:(使用的例子:)
int a, b , c;
init {
    a = get_pvar(SPVAR_1,  0, 10,  5);
    b = get_pvar(SPVAR_2, 20, 40, 30);
    c = get_pvar(PVAR_1, -30,400,100);
}
main {
}
Syntax
get_pvar ( <pvar_constant> , <min_value> , <max_value>, <default_value> );
Parameters
<pvar_constant>  :A global or private persistent variable constant(全局或私有的持久变量常量)
<min_value>      :The minimum permissible value(最小允许值)
<max_value>      :The maximum permissible value(最大允许值)
<default_value>  :The default value to return should the retrieved value be less then the min_value or greater than the max_value(如果检索到的值小于min_value或大于max_value,则返回的默认值)
Returns
The stored value or the default value if the stored one is out of range(存储值或存储值超出范围时的默认值)
2、set_pvar
set_pvar stores the specified value in to a Persistent Variable.(set_pvar将指定的值存储到一个持久变量中)
It is important to remember that each time this function is called, data is written to the EEPROM on the CronusMAX PLUS.  The life of an EEPROM is typically rated in the amount of read/write cycles that can be performed and although the EEPROM in the CronusMAX is rated for 1000's of these, you should still ensure that this function is NOT going to called in every iteration of the main loop.  Never use it at the base level of the main and always ensure it is nested within an if statement which will only return TRUE for one iteration, such as event_press;(重要的是要记住,每次这个函数被调用时,数据被写入到CronusMAX PLUS上的EEPROM。EEPROM的生命周期通常由可执行的读/写周期来决定,尽管CronusMAX中的EEPROM的生命周期为1000次,你仍然应该确保这个函数不会在主循环的每次迭代中都被调用。永远不要在main的基础级别使用它,并始终确保它嵌套在一个if语句中,该语句只在一次迭代中返回TRUE,如event_press;)
int a, b , c;
init {
    a = get_pvar(SPVAR_1,  0, 10,  5);
    b = get_pvar(SPVAR_2, 20, 40, 30);
    c = get_pvar(PVAR_1, -30,400,100);
}
main {
    if(event_press(XB1_VIEW)){
        set_pvar(SPVAR_1, a);
        set_pvar(SPVAR_2, b);
        set_pvar(PVAR_1,  c);
    }
}
Syntax
set_pvar ( <pvar_constant> , <value> );
Parameters
<pvar_constant>  :A global or private persistent variable constant
<value>          :A value to be stored要存储的值
Miscellaneous Functions(其它函数)

In this section are the commands which do not fit elsewhere.(在本节中列出了在其他地方不适用的命令。)

Function      Description
get_rtime    Returns the elapsed time in milliseconds between main iterations(返回主程序之间经过的时间,以毫秒为单位)
get_slot     Returns the active slot number(返回运行的槽位)
load_slot    Loads a specified slot(加载指定插槽)
get_ctrlbutton  Returns the identifier of the controller button(获取控制器按钮的标识符)
vm_tctrl     Sets the vm timeout for the next iteration(为下一次运行设置vm超时)
1、get_rtime
get_rtime returns the elapsed time between the current and previous iteration of the main function.  The value returned is in milliseconds.(get_rtime返回主函数的当前程序和前一次程序之间经过的时间。返回的值以毫秒为单位。)
You can see this function in action by using this counter script;(你可以通过使用这个计数器脚本看到这个函数的实际操作;)
int days;
int hours;
int minutes;
int seconds;
int milliseconds;
main {
    milliseconds = milliseconds + get_rtime();
    if(milliseconds >= 1000) {
        milliseconds = milliseconds - 1000
        seconds = seconds + 1;
        if(seconds == 60) {
            seconds = 0;
            minutes = minutes + 1;
            if(minutes == 60) {
                minutes = 0;
                hours = hours + 1;
                if(hours == 24) {
                    hours = 0;
                    days = days + 1;
                }
            }
        }
    }
    set_val(TRACE_1, days);
    set_val(TRACE_2, hours);
    set_val(TRACE_3, minutes);
    set_val(TRACE_4, seconds);
    set_val(TRACE_5, milliseconds / 10);
}
Syntax
get_rtime (  );
Parameters
None
Returns
The elapsed time, in milliseconds, between main iterations(主迭代之间经过的时间,以毫秒为单位)
2、get_slot
get_slot returns an int which represents the number of the currently active slot.(get_slot获取一个int值,表示当前活动槽的数量。)
Example of usage:(使用的例子:)
int _currentSlot;
init {
    _currentSlot = get_slot();
}
main {
}
Syntax
get_slot (  );
Parameters
None
Returns
The number of the currently active slot(当前活动插槽的数量)
3、load_slot
load_slot will attempt to load the slot number specified within its parameter.  If there is no script current stored in the specified slot, then it will unload the current slot and load slot 0.(oad_slot将尝试加载在其参数内指定的槽号。如果指定的插槽中没有存储脚本当前,那么它将卸载当前插槽并加载插槽0。)
Example of usage使用的例子:)
main {
    if(event_press(XB1_RB))     // if RB / R2 is pressed...
        load_slot(5);           // Load slot 5
    if(event_press(XB1_LB))     // if LB / L2 is pressed...
        load_slot(0);           // Unload current slot and load slot 0
}
Syntax
load_slot ( <slot_number> );
Parameters
<slot_number> :A value while represents a slot number to load, range 0~9(需要加载的槽号,范围为0~9)
4、get_ctrlbutton
get_ctrlbutton returns the current control button. (获取当前控件按钮。)
The control button is set in the Device tab within Cronus PRO's Options window.  The enable remote control of slow switch on device dictates which button it is set to(控制按钮设置在Cronus PRO的选项窗口中的设备选项卡中。remote control of slow switch选项使能遥控指示它被设置到哪个按钮)

If enable remote control is disabled, then the control button is 0 (The Xbox / Guide / PS button)(如果enable remote control被禁用,那么控制按钮为0 (Xbox / Guide / PS按钮))
If enable remote control is enabled and G8 Alternate is disabled, then the control button is 1 (Back / View / Select / Share)(如果启用remote control,并且禁用了G8 Alternate,那么控制按钮是1(后退/查看/选择/分享键))
If both remote control and G8 Alternate are enabled, then the control button is 8 (LS / L3)(如果remote control和G8 Alternate都启用,那么控制按钮为8 (LS / L3))
Syntax
get_ctrlbutton (  );
Parameters
None
Returns
0, 1 or 8 depending on the Remote slot settings in device options(0、1或8取决于设备选项中的远程插槽设置)
5、vm_tctrl
vm_tctrl sets the virtual machine timeout for the next iteration.  By default, the virtual machine runs the main loop every 10 milliseconds as it aids stability. You can however adjust how often each main iteration is run.  Just be aware than changing this setting may cause instability within your script.(vm_tctrl为下一次迭代设置虚拟机超时。默认情况下,克麦每10毫秒运行一次主循环,因为它有助于稳定性。但是,您可以调整每个主迭代的运行频率。请注意,更改此设置可能会在脚本中导致不稳定。)
Example of usage:
main {
    vm_tctrl(-5); // Run the VM every 5ms
}
Syntax
vm_tctrl ( <Value> );
Parameters
<Value> :Numeric value to add to the VM base time. Range -9 ~ 10(要添加到VM基本时间的数值。范围-9 ~ 10)
            Operators(运算符)

An operator is a symbol which tells the interpreter to perform specific mathematical, relational or logical operation and produce final result. This section details the operators available in GPC.(运算符是一种符号,它告诉解释器执行特定的数学运算、关系运算或逻辑运算并产生最终结果。本节详细介绍GPC中可用的操作符。)

Assignment Operator赋值运算符
Arithmetic Operators算术运算符
Logical Operators逻辑运算符
Relational Operators关系运算符
1、Assignment赋值
'=' is the assignment operator.  Think of this as get sets to rather than equal to.  When '=' is used, the left operand gets set to the value of the right operand.('='是赋值操作符。把它看成是设置为,而不是等于。当使用'='时,左操作数被设置为右操作数的值。)
Operator            Description                  Example
=          Sets the left operand to
        the value of the right operand       a = 5; //a is set to 5
2、Arithmetic算术
It is often necessary to perform arithmetic on two values.  The following table lists the arithmetic operators available in GPC.(通常需要对两个值进行算术运算。下表列出了GPC中可用的算术运算符。)
In the examples, assume 'a' holds a value of 10 and 'b' holds a value of 5.(在示例中,假设'a'的值为10,'b'的值为5。)
Operator            Description                    Example
+               Adds two operands 加法        a + b will give a value of 15
-            Subtracts right operand 减法
              from the left operand           a - b will give a value of 5
*            Multiples both operands乘法      a * b will give a value of 50
/              Divides left operand 除法
                 by right operand             a / b will give a value of 2
%          Modulus, gives the remainder模数,给出整数除法的余数
              of an integer division          a % b will give a value of 0
Note, GPC does not support fractions so the division operator ( / ) will drop any fractions.  For example, 10 / 3 = 3 as the fraction is dropped.  It also does not round, so 3 / 4 = 0 and not 1.(注意,GPC不支持分数,所以除法操作符(/)将删除任何分数。例如,当分数下降时,10 / 3 = 3。它也不四舍五入,所以3 / 4 = 0,而不是1。)
3、Logical(逻辑)
Logical operators are important in any programming language as they allow to tell the interpreter to make decisions based on certain conditions.  The following table lists the logical operators within the GPC languauge.(逻辑运算符在任何编程语言中都很重要,因为它们允许解释器根据特定条件做出决策。下表列出了GPC语言中的逻辑运算符。)
In the examples, assume 'a' holds a value of 1 and 'b' holds a value of 0.(在示例中,假设'a'的值为1,'b'的值为0。)
Operator             Description                           Example
&&      AND operator, if both operators are(如果两个运算符都为真,则条件为真)
        TRUE then the condition becomes TRUE            (a && b) is FALSE
||      OR operator, if either operand (如果任意一个操作数为真,则条件为真 )
        is TRUE then the condition becomes TRUE         (a || b) is TRUE
^^      XOR operator, if either operand(如果任意一个操作数为真,但不是两个操  
                                        作数都为真,则条件为真)
  is TRUE but not both then the condition becomes TRUE  (a ^^ b) is TRUE
!     NOT operator. Reverses the logical(否,反转操作数的逻辑状态)
              state of an operand.                     !b is TRUE !a is FALSE
4、Relational(关系)
Relational operators produce boolean results (TRUE or FALSE) while comparing two operands.  The following tables list the relational operands which are available in GPC.(关系操作符在比较两个操作数时产生布尔结果(真或假)。下表列出了GPC中可用的关系操作数。)
In the examples, assume 'a' holds a value of 30 and 'b' holds a value of 10.(在示例中,假设'a'的值为30,'b'的值为10。)
Operator              Description                         Example
==        Equal to, if the left operand(如果左操作数与右操作数持有相同的
                                         值,则条件为真)
          holds the same value as the right
          then the condition becomes TRUE           (a == b) is FALSE
!=       Not equal to, if the left operand(不等于,如果左操作数与右操作数
                                            的值不相同,则条件为真)
         does not hold the same value as
         the right then the condition becomes TRUE    (a != b) is TRUE
>        Greater than, if the left operand(大于,如果左操作数持有的值大于左
                                            操作数,则条件为真
         holds a value greater than the left
         then the condition becomes TRUE              (a > b) is TRUE
<        Less than, if the left operand(小于,如果左操作数持有的值小于左操作
                                        数,则条件为真)
         holds a value less than the left
         then the condition becomes TRUE             (a < b) is FALSE
>=      Greater than or equal to, if the(大于或等于,如果左操作数持有的值大                    
                                          于或等于右,则条件为真)
       left operand holds a value which is
       greater than or equal to the right
       then the condition becomes TRUE               (a >= b) is TRUE
<=     Less than or equal to, if the left
      operand holds a value which is less
      than or equal to the right then the
      condition becomes TRUE                         (a <= b) is FALSE

    List of GPC Keywords(GPC命令符列表)
1.abs                    -- Math Functions
2.block                  -- I/O Functions
3.block_rumble           -- Rumble
4.break                  -- Flow Control
5.call                   -- Combos
6.clear_bit              -- Bit Operations
7.comb                   -- Combos
8.combo_restart          -- Combos
9.combo_run             -- Combos
10.combo_running        -- Combos
11.combo_stop           -- Combos
12.data                 -- Data Segment

13.dbyte                -- Data Segment
14.dchar                -- Data Segment
15.deadzone             -- I/O Functions
16.define               -- Basic Syntax
17.dword               -- Data Segment
18.else                -- Flow Control
19.event_press         -- I/O Functions
20.event_release       -- I/O Functions
21.get_bits            -- Bit Operations
22.get_battery         -- Misc Functions and Constants
23.get_console         -- Misc Functions and Constants
24.get_controller      -- Misc Functions and Constants
25.get_ctrlbutton      -- Misc Functions and Constants
26.get_led             -- LEDs
27.get_ledx            -- LEDs
28.get_lval            -- I/O Functions
29.get_ptime           -- I/O Functions
30.get_pvar            -- Persistent Variables
31.get_rtime           -- Misc Functions and Constants
32.get_rumble          -- Rumble
33.get_slot            -- Misc Functions and Constants
34.get_val             -- I/O Functions
35.if                  -- Flow Control
36.init                -- Initialization
37.int                 -- Variables, Types and Arrays
38.inv                 -- Math Functions
39.isqrt               -- Math Functions
40.load_slot           -- Misc Functions and Constants
41.main                -- A Simple Tutorial
42.output_reconnection -- Misc Functions and Constants
43.pow                 -- Math Functions
44.ps4_authtimeout     -- Misc Functions and Constants
45.ps4_touchpad        -- Misc Functions and Constants
46.remap               -- Remapping
47.reset_leds          -- LEDs
48.reset_rumble        -- Rumble
49.sensitivity         -- I/O Functions
50.stickize            -- I/O Functions
51.set_bit             -- Bit Operations
52.set_bits            -- Bit Operations
53.set_led             -- LEDs
54.set_ledx            -- LEDs
55.set_pvar            -- Persistent Variables
56.set_rumble          -- Rumble
57.set_val             -- I/O Functions
58.swap                -- I/O Functions
59.test_bit            -- Bit Operations
60.turn_off            -- Misc Functions and Constants
61.unmap               -- Remapping
62.vm_tctrl            -- Misc Functions and Constants
63.wait               -- Combos
64.while              -- Flow Control
65.wiir_offscreen     -- Misc Functions and Constants







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|cronusmax

GMT+8, 2023-9-23 09:10 , Processed in 0.099017 second(s), 24 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表