website logo
Buy CronusGPC LibraryGamePacks (16bit)YouTubeForumsDiscord
📘Cronus Zen Guide
📗GamePacks (32bit)
📗GPC Script Guide
Navigate through spaces
⌘K
📑GPC SCRIPTING
What's New in 32bit?
Introduction
Variables
Basic GPC Structure
Definitions
Data Section
Remapping
Const Arrays
Init Section
Main Section
Combo Section
User Created Functions
Identifiers
Flow Control
Constants
Functions
Device Functions
Remapping
Advanced Samples
API Samples
Docs powered by archbee 

What's New in 32bit?

If you are not experienced with scripting, go ahead and skip straight to the Introduction👍

If you are experienced with GPC (or C) you will be happy to know that Cronus has finally added 32bit support for scripts!

GPC scripting is now available in both 16bit and 32bit flavors. Coding in 32bit allows for a much larger address space, which means more memory can be accessed and used by the GamePack. This can be hugely beneficial for programs that require large amounts of memory. Additionally, 32-bit systems also support more advanced features, enabling an infinitely higher accuracy in calculations - directly benefiting MODs such as Anti-Recoil and Aim Assist.



16bit has a maximum of 2^16 possible values and 32bit has a maximum of 2^32 possible values. 



16bit: 0000 0000 0000 0000

32bit: 0000 0000 0000 0000 0000 0000 0000 0000



The default compiler mode of Zen Studio is now 32bit. If you wish to compile an older 16bit script (every script ever released before Cronus Zen v1.2.0), you must use the 16bit compiler.

What is 32bit?



32bit scripting support allows for vastly greater calculations, enabling more precision, more accuracy, and more automation - especially for MODS such as Aim Assist and Anti-Recoil.

Previously, the variable calculation range with 16bit (-32768 to 32767), but now with 32bit that range has increased to a massive (−2,147,483,648 to 2,147,483,647), allowing for much more complex calculations that can be scaled up then back down while retaining a high level of accuracy, enabling a degree of precision not previously available.

Size

Minimum Value

Maximum Value

8-bits

-(2^8) = -128

2^8 - 1 = 127

16-bits

-(2^16) = -32,768

2^16 - 1 = 32,767

32-bits

-(2^32) = -2,147,483,648

2^32 - 1 = 2,147,483,647

We've also added three new incredibly powerful GPC functions, get_polar , get_ipolar and get_info

The default compiler mode of Zen Studio is now 32bit. If you wish to compile an older 16bit script (every script ever released before Cronus Zen v1.2.0), you must use the 16bit compiler. Older scripts may also break due to using deprecated code. If you know what you are doing, you will know how to fix these issues from the information on this page.

Document image


New Functions



⚙ get_ipolar

get_ipolar() is the latest brand new function that can be used to gain information to retrieve the unmodified input value of the analog stick. It can be used with both left and right analog sticks, get_ipolar() uses 2 parameters in the function, 1st is the stick you want to use and the 2nd parameter is either Angle or Radius. Only Angle or Radius can be retrieved at once.

  • The POLAR_ANGLE can be within the range of 0 - 359 and this depends on the current direction the stick has been pushed.
  • The POLAR_RADIUS has a range of 0 - 32767 and this represents how far from the center the stick is pushed.
GPC
|
main {

    get_ipolar(POLAR_LS,POLAR_RADIUS);   //retrieves current unmodified radius of an analog stick
    get_ipolar(POLAR_RS,POLAR_ANGLE);    //retrieves current unmodified angle of an analog stick

}


🔴 Syntax

get_ipolar(POLAR_LS,POLAR_RADIUS);
get_ipolar(POLAR_RS,POLAR_ANGLE);

⚪ Parameters

<POLAR_ANGLE> : Returns the unmodified Angle on an analog stick POLAR_LS or POLAR_RS (0-359)

<POLAR_RADIUS> : Returns the unmodified radius of an analog stick POLAR_LS or POLAR_RS (0 - 32767)

🔵 Returns

Either the unmodified angle or radius will be returned depending on the given parameter.



⚙ get_polar

get_polaris a brand new function that can be used to gain information on the current angle or radius of the analog stick. It can be used with both left and right analog sticks, get_polar() uses 2 parameters in the function, 1st is the stick you want to use and the 2nd parameter is either Angle or Radius. Only Angle or Radius can be retrieved at once.

  • The POLAR_ANGLE can be within the range of 0 - 359 and this depends on the current direction the stick has been pushed.
  • The POLAR_RADIUS has a range of 0 - 32767 and this represents how far from the center the stick is pushed.
GPC
|
main {

    get_polar(POLAR_LS,POLAR_RADIUS);   //retrieves current radius of an analog stick
    get_polar(POLAR_RS,POLAR_ANGLE);    //retrieves current angle of an analog stick

}


🔴 Syntax

get_polar(POLAR_LS,POLAR_RADIUS);
get_polar(POLAR_RS,POLAR_ANGLE);

⚪ Parameters

<POLAR_ANGLE> : Returns the Angle on an analog stick POLAR_LS or POLAR_RS (0-359)

<POLAR_RADIUS> : Returns the radius of an analog stick POLAR_LS or POLAR_RS (0 - 32767)

🔵 Returns

Either the angle or radius will be returned depending on the given parameter



⚙ set_polar2

set_polar2is a virtual stick that you can use to quickly calculate values without the hassle of time-consuming trigonometry functions.

  • POLAR_GHOST is the virtual stick where an angle and radius can be assigned using set_polar2.
  • ANALOG_GHOSTX is the virtual X AXIS to be used with both math and trigonometry functions.
  • ANALOG_GHOSTY is the virtual Y AXIS to be used with both math and trigonometry functions.
GPC
|
main {
	set_val(TRACE_1, PolarToCartesian(60, 10000, X_AXIS)); // 4999
	set_val(TRACE_2, PolarToCartesian(60, 10000, Y_AXIS)); // -8660
}

define X_AXIS = 0;
define Y_AXIS = 1;
function PolarToCartesian(angle, radius, axis) {
  set_polar2(POLAR_GHOST, angle, radius);
 
  if (axis == X_AXIS) {
  	return get_val(ANALOG_GHOSTX);
  }
  
  return get_val(ANALOG_GHOSTY);
}



⚙ get_info

get_info is a new function that checks the active state of the MK Profile. A MK Profile has upto 6 different states as follows (0 = HIP, 1 = ADS, 2 = AUX1, 3 = AUX2, 4 = AUX3, 5 = AUX4). With this information, you are able to script for any specific state and take action accordingly. For example, you can have mods automatically toggle ON/OFF based on if you are HIP firing, Aiming Down Sights (ADS), or using any of the 4 Auxiliary MK profiles. Think of the possibilities.......

GPC
|
// Show usage for PENDING_CONFIG and ACTIVE_CONFIG
// Check traces with mouse and keyboard, click activator to see the trace values
// 0 = HIP, 1 = ADS, 2 = AUX1, 3 = AUX2, 4 = AUX3, 5 = AUX4
// If a config has delay activation it will show up in the traces after the activation time

main {
    set_val(TRACE_1, get_info(PENDING_CONFIG))
    set_val(TRACE_2, get_info(ACTIVE_CONFIG))

    if(get_info(ACTIVE_CONFIG) == 1 && get_ival(XB1_LT)){ //If aiming down sights and Left Trigger is held
        set_val(XB1_LS,100);                              //Hold LS / L3 
    }
}


🔴 Syntax

get_info(PENDING_CONFIG);
get_info(ACTIVE_CONFIG);

⚪ Parameters

<PENDING_CONFIG> : Shows usage for the pending config

<ACTIVE_CONFIG> : Shows the usage for the active config

🔵 Returns

Active profile in use by MK Settings:

Return

Profile

0

HIP

1

ADS

2

AUX1

3

AUX2

4

AUX3

5

AUX4

⚙ int32



int32 is a brand new 32bit function that is used to create an array that holds values greater than 32767 and less than -32768.

GPC
|
const int32 array [][] = {
	{ 111111, 222222, 333333},		
	{-444444,-555555,-666666},
	{ 777777, 888888, 999999}
};

main {

    set_val(TRACE_1,array[0][1]);
}


⚙ 32bit Traces



Traces are commonly used for debugging a script and viewing information from a script or game.

There is six TRACE debug fields found in Device Monitor that can be used by a GPC script for feedback information, flow control checking, and variables monitoring. TRACE_1 to TRACE_3 are for 32bit values, TRACE_4 to TRACE_6 are for 16bit values.

Trace Number

Integer Value

TRACE_1

32bit

TRACE_2

32bit

TRACE_3

32bit

TRACE_4

16bit

TRACE_5

16bit

TRACE_6

16bit

For example, if you wanted to see the current value of a variable that was over the 16bit limit you could set a trace using TRACE_1, TRACE_2, or TRACE_3 for the variable to see its value:

GPC
|
int value;

main {

    set_val(TRACE_1,value);
    
    value = 1000 * get_ival(XB1_RT);

}


⚙ 32bit SPVARS



With the use of int32 and the 32bit update, you can save much higher values to SPVAR than ever before.

Each 32bit SPVAR can hold 1 x 32bit(4 bytes) value of −2,147,483,648 to 2,147,483,647. Whereas the previous 16bit SPVARs were only 16bit(2bytes) of -32,767 to 32,767. This can be extremely useful if you need to scale and save values for more advanced movements such as Anti Recoil and Aim Assist.

Additionally, advanced developers who use bit packing in their GPC scripts are now able to store twice as much information in a SPVAR as they were before. With 16bit you were only able to store 2 x 8bit values with a range of -32768 to 32767; with 32bit you can store double that amount with 4 x 8bit values.

Bitpacking SPVARs

32bit Examples



⚙ get_polar

Here is an example of a Strafe Mod not being possible using 16bit. The new get_polar function is used to return the current radius of the left analog stick. This value is then multiplied by a set number or 50 in this example, then once more by 100 to scale input. Then to scale the value back down it is divided by 20000. The resulting value is then used as a strength that is applied to the left stick to strafe left and right.

Info: While GPC does not support float, a far higher degree of accuracy is achieved by first scaling up and then back down.

GPC
|
int strafe_value = 50;
int strafe_val;

main {

    strafe_val = (get_polar(POLAR_LS,POLAR_RADIUS) * strafe_value * 100) / 20000;
    
    if(get_val(XB1_LT)){
        combo_run(strafe);
    }

}

combo strafe{
    set_val(POLAR_LX, inv(strafe_val));
    wait(250);
    set_val(POLAR_LX, strafe_val);
    wait(250);
}


Scaling with 32bit

Here's an example of scaling a recoil value though this time it is for 32bit. Here the value is much higher which leads to much greater accuracy when calculating a value. The value seen in TRACE_3 could be applied to either stick as a polar value leading to much greater results. In the example, the recoil value is scaled up based on sensitivity, deadzone, and a modifier (accounts for attachments).

GPC
|
int original_recoil_value = 20;
int mod_sensitivity,mod_deadzone,part_1,part_2,applied_recoil,val;
int rightStickDeadzone = 5;
int rightStickSensitivity = 20;
int recoil_adjustment = 25;
main {

    set_val(TRACE_1,part_1);
    set_val(TRACE_2,part_2);
    set_val(TRACE_3,applied_recoil);
    
    if(event_press(XB1_UP)){
    	rightStickDeadzone++;
    }
    if(event_press(XB1_DOWN)){
    	rightStickDeadzone--;
    }
    if(event_press(XB1_LEFT)){
    	rightStickSensitivity++;
    }
    if(event_press(XB1_RIGHT)){
    	rightStickSensitivity--;
    }
	part_1 = (((((original_recoil_value * 327) + (mod_sensitivity + mod_deadzone)) * 327) / 327));
	part_2 = part_1 * (100 + recoil_adjustment);
	applied_recoil = part_2 / 100;
	mod_deadzone = ((((original_recoil_value * 327) * 25) * (rightStickDeadzone - 5)) / 1000);
	mod_sensitivity = ((((original_recoil_value * 327) * (25 + val)) * (20 - rightStickSensitivity)) / 1000);
	if(rightStickSensitivity >= 5){
	   	val = 0;
	}
    if(rightStickSensitivity < 5){
	    val = ((rightStickSensitivity - 5) * -4);
	}

}


Scaling with 16bit

Here's an example of how you could scale an Anti-Recoil value using 16bit. Though due to value limitations and truncation you do lose a little accuracy.

GPC
|
int original_recoil_value = 20;
int mod_sensitivity,mod_deadzone,part_1,part_2,applied_recoil,val;
int rightStickDeadzone = 5;
int rightStickSensitivity = 20;
main {

    set_val(TRACE_1,applied_recoil);
    
    if(event_press(XB1_UP)){
    	rightStickDeadzone++;
    }
    if(event_press(XB1_DOWN)){
    	rightStickDeadzone--;
    }
    if(event_press(XB1_LEFT)){
    	rightStickSensitivity++;
    }
    if(event_press(XB1_RIGHT)){
    	rightStickSensitivity--;
    }
	part_1 = (((((original_recoil_value * 327) + (mod_sensitivity + mod_deadzone)) * 327) / 327));
	part_2 = (part_1 * 100) / 100;
	applied_recoil = part_2 / 327;
	mod_deadzone = ((((original_recoil_value * 327) * 25) * (rightStickDeadzone - 5)) / 1000);
	mod_sensitivity = ((((original_recoil_value * 327) * (25 + val)) * (20 - rightStickSensitivity)) / 1000);
	if(rightStickSensitivity >= 5){
	   	val = 0;
	}
    if(rightStickSensitivity < 5){
	    val = ((rightStickSensitivity - 5) * -4);
	}

}


16bit vs 32bit



Here's an example of Anti-Recoil using a 16bit GamePack vs Anti-Recoil using a 32bit GamePack.




Legacy 16bit Compiler



The 16bit compiler is still available for older scripts not designed for 32bit. If you get an error while compiling a script, it's likely because you're trying to compile a 16bit script in the 32bit compiler - or the script has deprecated functions that no longer work and needs to be updated.

Document image


Introduction



PREVIOUS
GPC SCRIPTING
NEXT
Introduction
Docs powered by archbee 
TABLE OF CONTENTS
What is 32bit?
New Functions
⚙ get_ipolar
🔴 Syntax
⚪ Parameters
🔵 Returns
⚙ get_polar
🔴 Syntax
⚪ Parameters
🔵 Returns
⚙ set_polar2
⚙ get_info
🔴 Syntax
⚪ Parameters
🔵 Returns
⚙ int32
⚙ 32bit Traces
⚙ 32bit SPVARS
32bit Examples
⚙ get_polar
Scaling with 32bit
Scaling with 16bit
16bit vs 32bit
Legacy 16bit Compiler