ZGameEditor Preset Files and Folders
ZGameEditor presets:
FL Studio Visualizer presets (zgeproj files) are created with the ZGameEditor game engine. You can download it from here:
http://www.zgameeditor.org
User zgeproj-files for FL Studio are stored in folders in the ZGameEditor shared folder.
In order for your effect to show up in FL Studio, they must be saved in a the right folder or FL Studio will not find it.
This folder is often located in Documents\Image-Line\ZGameEditor Visualizer\Effects
Locating the ZgameEditor Shared folder:
The shared folder can be also found in Fl Studio by expanding the browser label "IL Shared Data"-->"ZGameEditor Visualizer" Right click here and select "open".
Setting up a user folder:
Create a folder named "Effects" if it does not exist. Create new Category folders here to organize your own effects.
The path of a user effect folder should look like this:
Documents\Image-Line\ZGameEditor Visualizer\Effects\My Stuff
"My Stuff" is a category folder that can be named anything and there can be more catagory folders if needed.
User effects saved in category folders will be found in the visualizers layer effect menu dropdown.
Opening User Effects in the visualizer:
Open the ZgameEditor Visualizer in FL Studio and your effects will be found in the effect dropdown category called "My Stuff". Keep in mind if the visualizer was opened before you created the effect, you will need to restart the visualizer to get it to show up.
Installed zgeproj-files for FL Studio are stored in this directory.
Program Files-->Program Files\Image-Line\FL Studio\Plugins\Fruity\Effects\ZGameEditor Visualizer\Effects
Examining or editing these files is a great way to learn.
User Effects can also be stored in Program Files, but it's not recommended:
Be aware that user effects located here might get lost with updates. Modified effects that are not renamed can get over written as well. If editing existing effects, copy them to your user folder.
Most Visualizer development topics not documented. The rest of this post is an unofficial reference.
FL Studio Visualizer variables
SpecBandArray
Type: Array float
This array is filled with the amount of audio at different frequencies. The values range from -1 to 1. Note that when the effect is loaded the actual length will be set by ZgeViz.
AudioArray
Type: Array float
This array is filled with the audio pcm data that is currently playing. The values range from -1 to 1. The actual size of this array is set at runtime. **The 1D array uses interlaced values for stereo channels. **Like the SpecBandArray it can be configured by the user, but in the FL Studio Audio settings dialog(sample rate), so effects should be written with this in mind.
SongPositionInBeats
Type: float
This variable holds the current position in beats. An example use of this variable is to take the fraction part and modify camera Z position to make the scene pulse in sync with the music.
SongPositionInSeconds
Type: Array float
This variable holds the current position in seconds.
SongLengthInSeconds
Type: Array float
This variable Keeps track of the length of a song in FL Studio.
Parameters
Type: Array float
This is an array that hold values that range from 0 to 1 and are controlled by the sliders in the ZgeViz interface. They can be used freely (or ignored) in the effect to modify visuals. **Set default start values by setting the array component to persistent and editing the values. The default value can be restored by the user by right clicking over the parameter.
ParamHelpConst
Constant String
This is a string (**constant variable type) that is used to hold the names of the parameters the effect is using. So if you have an effect with two parameters that controls shape and color, this property could hold the names "Shape" and "Color" separated with a carriage return. The names of the parameters are shown as labels in the ZgeViz user interface.
UserTextArray
Typre: String
Add a DefineArray component of string type named "UserTextArray" if you want to use the strings that the user can enter in the custom content dialog.
AuthorInfo
Type: const string
A variable that adds the script author's name at the top of top of the ZGE visualizer Layer.
NoClearScreen
Type: const float
This variable disables clearing the screen per frame with the background color (black by default) in the visualizer.
If needed, clear can be enabled during runtime with the OpenGL external library.
Example:
Code: Select all
glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
Classes in scripting
New Feature » Thu May 27, 2021
http://www.emix8.org/forum/viewtopic.php?f=1&t=1559
Demo project that use classes.
Creating help for Effect Presets
Use the comment property of the ZApplication-component to write some help text about your effect that will be displayed in ZgeViz when you right-click and choose "Show help for this effect".
Visualizer 2.0 user interface Check Box and Dropdown: list, checkbox, list1000
Used with the ParamHelpConst string: The ParamHelpConst is used to set the names of parameters with a default control slider. These tags were added to use toggle switches and dropdown menus.
Examples:
Menu @list: first,second,"last item" : Creates a drop down menu Named "Menu" with four items.
Toggle @checkbox : Creates a check box named "Toggle"
Menu @list1000 : Creates a drop down menu Named "Menu" with four items.
Tip:
@list1000 is to be preferred to use instead of "@list:" because it makes it easy to add items later without breaking automations in existing flps. Simply use "int item=Parameters[x]*1000".
MIDI Input
OnMidiMessage
Instructions
Copy/paste the following into the Content-node of a new ZGE-project: Code:
Code: Select all
ZZDC<?xml version="1.0" encoding="iso-8859-1" ?>
<ZLibrary Name="FL_Library">
<Source>
<![CDATA[void OnMidiMessage(int status, int data1, int data2) {
}]]>
</Source>
</ZLibrary>
Write code that acts on midi-input.
Note: For performance reasons please only include the above FL_Library-component in effects that act on midi input. This avoids redundant data copying in ZgeViz.
Table of Midi Messages :
http://www.midi.org/techspecs/midimessages.php
In the ZgeViz user interface you can select which Midi-port to use.
Example Project:
IDE/Visualizer "meta" scripting functions
Postby VilleK » http://www.emix8.org/forum/viewtopic.php?f=2&t=1315&p=8548&hilit=findComponent#p8548
I added a few functions to the scripting language that can only be used from the IDE and Visualizer. The reason for this is that in the minimal binary version of the code all component names have been removed.
Functions:
- findComponent(name) -- Returns the component with that name if it exists, or null otherwise.
- createComponent(owner,propertylistName,componentclassname) -- Creates a new component as child to an existing component, and returns the new component.
- setNumericProperty(component,propertyName,index,value) -- Set value of a numeric property. The "index" is used with multi-value properties such as Color.
- setStringProperty(component,propertyName,value) -- Set value of a string property.
- setObjectProperty(component,propertyName,value) -- Set value of a object property (example: "Texture" property of MaterialTexture is a object property).
Examples:
Suppose you have 10 bitmaps named "Bitmap1" to "Bitmap10". And you want to modify one of them depending on the value of an integer. Then you can simply do this:
Code: Select all
Bitmap b=findComponent("bitmap" + intToStr(i));
if(b!=null)
//do something with b
Creating components:
In the attached example I have code that creates 10 bitmaps, set properties, and also create child producer component to each bitmap.
Code: Select all
for(int i=1; i<10; i++) {
Component c=createComponent(App,"Content","bitmap");
setStringProperty(c,"Name","Bitmap" + intToStr(i));
setNumericProperty(c,"Width",0,512);
setNumericProperty(c,"Height",0,512);
Component nested;
if(i & 1) {
nested=createComponent(c,"Producers","BitmapExpression");
setStringProperty(nested,"Expression",
"Pixel=vector4(1.0," +
"abs(cos(Y*" + intToStr(random(4,3)) + ")) * ." + intToStr(rnd()*1000) + "," +
"abs(sin(X*" + intToStr(random(4,3)) + ")) * ." + intToStr(rnd()*1000) + "," +
"1.0);");
} else {
for(int j=0; j<3; j++) {
nested=createComponent(c,"Producers","BitmapRect");
setNumericProperty(nested,"Color",0,rnd());
setNumericProperty(nested,"Color",1,rnd());
setNumericProperty(nested,"Size",0,rnd());
setNumericProperty(nested,"Size",1,rnd());
setNumericProperty(nested,"Size",2,rnd());
setNumericProperty(nested,"Size",3,rnd());
}
}
}
Some suggestions on how these new functions can be used:
- Debug/support routines in the IDE when creating projects
- Useful in Visualizer scripts
- Generate code. For instance, in a visualizer script it could create custom Expression components, MeshExpression, BitmapExpression etc, could be powerful for generated content.
Private Data
Private Data allows you to store data that is saved in the users project file.
There are several components required to set it up. It's not easy to explain:
Here is a simple test project example:
External Library Variables
Variable: LayerNr
Type: int
variable that indicates what layer the current effect is loaded on.
Variable: FLPluginHandle
Type: xptr
A ZGE visualizer specific variable that returns the window handle to the visualizer plugin.
External Library Functions
string ZgeVizGetEffectName(xptr Handle, int Layer) { }
ModuleName : ZGameEditor Visualizer
Calling convention : StdCall
This function returns the name of an effect from any layer.
void ParamsChangeName(xptr Handle,int Layer, int Parameters, string NewName) { }
ModuleName : ZGameEditor Visualizer
Calling convention : StdCall
This function allows script developers to change the names of parameter labels.
void ParamsWriteValueForLayer(xptr Handle, int Layer,int Param, float NewValue) { }
ModuleName : ZGameEditor Visualizer
Calling convention : StdCall
This function allows script developers to automate any layer parameter with ZGE Script.
void ParamsReadValueForLayer(xptr Handle, int Layer, int Param, ref float Value) {}
ModuleName : ZGameEditor Visualizer
Calling convention : StdCall
This function allows script developers to read any layer parameter value with ZGE Script.
void ZgeVizSetEnablePostProcess(xptr Handle,int Layer, int Value) { }
ModuleName : ZGameEditor Visualizer
Calling convention : StdCall
This function allows script developers to toggle post processing in effect presets.
void ParamsNotifyChanged(xptr Handle,int Layer) { }
ModuleName : ZGameEditor Visualizer
Calling convention : StdCall
This function allows automation of the current "LayerNr" parameters with ZGE Script. This This allows users to set parameter values and update the values when "ParamsNotifyChanged" is called. This function only works for one "LayerNr". Alternatively, The previous function "ParamsWriteValueForLayer" can write values to any other layers and parameters.
Example:
This code block sets parameters 2-5 of the script to a random value.
Code: Select all
Parameters[2] = rnd();
ParamsNotifyChanged(FLPluginHandle,LayerNr);
Parameters[3] = rnd();
ParamsNotifyChanged(FLPluginHandle,LayerNr);
Parameters[4] = rnd();
ParamsNotifyChanged(FLPluginHandle,LayerNr);
Parameters[5] = rnd();
ParamsNotifyChanged(FLPluginHandle,LayerNr);
void ParamsUpdateComboItems(xptr Handle, int Layer,int Param, string[] NewItems) { }
ModuleName : ZGameEditor Visualizer
Calling convention : StdCall
Use this to update combo box items at runtime.
void ZgeVizGetFileNames(string path, string pattern, string[] list) { }
ModuleName : ZGameEditor Visualizer
Calling convention : StdCall
Use to get a list of filenames from a path.
Code: Select all
string[] items;
//either fill it from code
items.SizeDim1=4;
items[0]="Hello";
items[1]="World";
items[2]="Hej";
items[3]="Hopp";
...
//or get a list of files
ZgeVizGetFileNames("c:\\temp\\", "*.*", items);
ParamsUpdateComboItems(FLPluginHandle,LayerNr,ParameterIndex,items);
Misc. Topics
Read from text file into array
A recent update makes it easier to read text files:
example from http://www.emix8.org/forum/viewtopic.php?f=2&t=1238&p=8025&hilit=write+file#p8025:
Code: Select all
string[] lines; //Declare array
@FileAction( File : @File(FileName : "test.txt", TargetArray:lines) ); //Read from text file into array
for(int i=0; i<lines.SizeDim1-1; i++) //And just print out the lines
trace(lines[i]);
Image copy Buffer
Module Name: ZgameEditor Visualizer
Functions:
Code: Select all
int ClipboardGetBitmapWidth() { }
int ClipboardGetBitmapHeight() { }
int ClipboardGetBitmapPixel(int x,int y) { }
Code: Select all
//get from clipboard
int pix=ClipboardGetBitmapPixel(x,y);
int r=(pix >> 16) & 255;
int g=(pix >> 8) & 255;
int b=pix & 255;
NoCustom Bitmap Component Comment
Use the comment "NoCustom" on the bitmap component to prevent image imports from replacing the default bitmap.
Example Bitmap component properties with No custom option:
Host message ID
It works just like the midi messages that you declare a library function that responds to messages.
Code: Select all
void OnHostMessage(int id, int index, int value) {
trace("hostmessage id: " + intToStr(id) + " index: " + intToStr(index) + " value: " + intToStr(value));
if(id==12) { //12 = FPD_SetPlaying message
if(value==0)
trace("stopped");
else
trace("started");
}
}
"ref" syntax
This allows you to return more than one value from a function.
Example 1:
Code:
Code: Select all
//notice the "ref" word in front of the arguments that are passed by reference
void splitColor(int color,ref int r, ref int g, ref int b) {
//..separate r,g,b from color and return back to caller
}
//call this function
int r,g,b;
splitColor(0xff8020,r,g,b);
Example 2:
Code: Select all
//OpenGL-function, generate a texture id and return it into the second argument
void glGenTextures(int n, ref int textureid) { }
//Delete a texture, pass the id using a reference
void glDeleteTextures(int n, ref int textureid) { }
"xptr" datatype
At the moment only DefineArray components are valid xptr but other components may be added too if needed.
Example:
Code: Select all
//OpenGL external library definitions, notice the last parameter "xptr pixels"
void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int atype, xptr pixels) {}
void glGetTexImage(int target, int level, int format, int atype, xptr pixels) {}
ShaderVariable new ValueArrayRef
If you have a ShaderVariable:
<ShaderVariable VariableName="array1" ValueArrayRef="MyArray"/>
Then "MyArray" is your DefineArray component and in your fragment shader you declare the array like this:
Code: Select all
"uniform sampler2D array1;"
Use the GLSL-functions "texture" to read values from the array.
Script based Component invocation
Introducing "Script based Component invocation"
Syntax:
@ <component> ( [ <property> : <value> ] ... );
This will declare and execute a component with the properties set to the desired values.
Examples:
Code: Select all
@RemoveModel(); //A component that does not need any properties
//Components with a single property
@SetAppState(State : AppState_TitleScreen);
@SpawnModel(Model : TitleScreenModel);
@UseMaterial(Material : PlayerMaterial);
@RenderMesh(Mesh : PlayerMesh);
//Several properties
@RenderText(Text : "Hello" + intToStr(i), X : -0.5, Y : -1 + (0.1*i));
@PlaySound(Sound : Sound1, NoteNr : 85);
Arrays as parameters:
Code:
Code: Select all
//Add item to end of array
void addItem(int item, int[] ar) {
ar.SizeDim1++;
ar[ ar.SizeDim1-1 ] = item;
}
This function can be called like this:
Code: Select all
addItem(42, MyArray);
Local arrays
A function can declare local arrays. Examples:
Code: Select all
int x[]; //Declare a one-dimensional int array
int xx[ , ]; //Declare a two-dimensional int array
int xx[ , , ]; //Declare a three-dimensional int array
x.SizeDim1=10; //Set array to hold 10 items
The arrays are automatically created on entry and freed on exit of the function.
The local arrays can now have specified default size:
Code: Select all
float[4,4] m; //A 4x4 array
string[10] lines; //Holds 10 items
Function getModels(items, category) :
This can be used for looping through models at runtime and do things like custom collision detection etc.
Code: Select all
//Get all model instances of category zero
model[] models;
getModels(models,0)
//Loop through the list
for(int i=0; i<models.SizeDim1; i++) {
model m = models[i];
//do something
}
FLPluginPath
If a string variable with this name exist in effect, then it will be set to the path of the visualizer plugin."FLPluginPath".
**Video cue points can use midi input to set the video playback to a specific time. Input cue points in the visualizer settings by selecting the Video texture cue points tab. Units are in seconds with decimal values. For ease of use you can also import a .wav file with marker information to add cue points automatically. Markers can be added to a .wav file with Edison or SliceX. A third party app can be used to extract the audio track from the video, if needed. Cue points are triggered by midi input(the first cue point is mapped to c0, second=c#0, third=d0...). Cue point Midi key assignment cycles, so that cue points can be triggered from any octave.