You have the choice between C-Script, lite-C, C, or C++. Other languages like Basic, Delphi, or C# are not directly supported, but can be used through a 'wrapper'. C-Script was the standard scripting language of Gamestudio. A new script language, lite-C, will be additionally available in future versions. It is extremely similar to C-Script - in fact you won't see a difference at a first glance. However at a second glance it offers far more possibilities, so this will your language of choice for new projects as soon as it's available.
Unlike C-Script, lite-C can be used in two modes: Pure Mode and Legacy Mode. Pure mode code is a lot simpler and shorter. It uses the functions of the acknex engine, and does not require programming a window and a message loop. In Windows mode the engine functions are not available. Windows mode code however can be compiled with any C++ compiler as long as only standard C features are not used.
Feature |
C-Script |
lite-C Pure |
lite-C Legacy |
C |
C++ |
---|---|---|---|---|---|
Standard extension |
.wdl |
.c |
.c |
.c |
.cpp |
Main function |
main() |
main() |
WINAPI WinMain(...) | WINAPI WinMain(...) |
WINAPI WinMain(...) |
Case sensitive | no | yes | yes | yes | yes |
Standard variables |
var |
var, int, long, short, char, float, double |
var, int, long, short, char, float, double |
int, long, short, char, float, double |
int, long, short, char, float, double |
Structs |
predefined only |
yes |
yes |
yes |
yes |
Classes |
no |
no |
no |
no |
yes |
Function overloading |
no |
yes |
yes |
no |
yes |
COM+ support | no | yes |
yes |
yes |
yes |
DLL support | plugins only | yes |
yes |
yes |
yes |
Struct autoinitialisation* |
yes |
yes |
yes |
no |
no |
Pointer autodetection* |
yes |
yes |
yes |
no |
no |
Control functions | if, while | if, while, for, do, switch | if, while, for, do, switch | if, while, for, do, switch | if, while, for, do, switch |
Code compilation | on-the-fly | on-the-fly and in advance | on-the-fly and in advance | in advance only | in advance only |
* Struct autoinitialisation and pointer autodetection are features that greatly simplify program code. The compiler automatically deals with object creation and memory allocation, and handles pointers just like their contents. This removes most complicated and formal stuff from the language.
Below you'll find two examples of a Mandelbrot script written in Pure and Legacy mode. As you see, in Pure Mode the program consists almost only of the functions that draw the Mandelbrot fractal. All stuff unrelated to the program goal, like creating a window and handling a message loop, is automatically dealt with by the compiler.
lite-C Pure Mode | lite-C Legacy Mode, C, or C++ |
#include <acknex.h> // Pure Mode |
#include <litec.h> // Legacy Mode ///////////////////////////////////////////////////////// // Draw a Mandelbrot fractal. double m_x = 0.344142, m_y = 0.075094, m_width = 0.017813; long JetColor(double v) { double d = 25.0; v = v/d + 0.5; int i = (int)v; int f = (int)(255*(v-i)); int r=0, g=0, b=0; switch(i) { case 0: r=0; g=0; b=f; break; case 1: r=0; g=f; b=255; break; case 2: r=f; g=255; b=255-f; break; case 3: r=255; g=255-f;b=0; break; case 4: r=255-f;g=0; b=0; break; } return r|(g<<8)|(b<<16); } void Draw(HDC hdc,long vw,long vh) { long w = vw; long h = vh; long i,j; long times,inset; double x,y,zx,zy,zxs,zys; long detail=100; for(i=0;i<w;i++) for(j=0;j<h;j++) { x = m_x+((double)i)*m_width/w; y = m_y+((double)(h-j))*m_width/w; zx = 0; zy = 0; inset = 1; times = 0; while(inset && times<detail) { times++; zxs = zx*zx; zys = zy*zy; zy = 2*zx*zy+y; zx = zxs-zys+x; if (zxs+zys >= 4.0) inset=0; } if(inset) SetPixel(hdc,i,j,0); else SetPixel(hdc,i,j,JetColor(times)); } } //////////////////////////////////////////////////////// // message loop function LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch(message) { case WM_LBUTTONDOWN: // zoom in at cursor position { RECT rect; GetClientRect(hWnd,&rect); long x = ((long)lParam)&0xffff; long y = (((long)lParam)&0xffff0000)>>16; double a; a = x; a /= rect.right; m_x += m_width*(a-0.5); a = y; a /= rect.bottom; m_y += m_width*(0.5-a); m_width *= 0.5; InvalidateRect(hWnd,0,0); } break; case WM_DESTROY: PostQuitMessage(0); break; case WM_COMMAND: switch(wParam){ case 1: m_x=-2.5; m_y=-2; m_width=4.0; InvalidateRect(hWnd,0,0); break; case 2: break; case 3: PostMessage(hWnd, WM_CLOSE,0,0); break; } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT rect; GetClientRect(hWnd,&rect); Draw(hdc,rect.right,rect.bottom); EndPaint(hWnd, &ps); break; case WM_KEYDOWN: switch( wParam ) { case VK_ESCAPE: case VK_F12: PostMessage(hWnd, WM_CLOSE,0,0); break; } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } int WINAPI WinMain (WINARGS) { //Create a window char *szClass = "liteCWindowClass"; HINSTANCE hi = GetModuleHandle(NULL); UnregisterClass(szClass,hi); WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW|CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hi; wcex.hIcon = LoadIcon(hi,(LPCSTR)128); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szClass; |