aboutsummaryrefslogtreecommitdiffstats
path: root/src/lua
diff options
context:
space:
mode:
authors_alexander <s_alexander@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-01-12 17:42:41 +0000
committers_alexander <s_alexander@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-01-12 17:42:41 +0000
commit4711217f127aa0c10fa52755fd567c570277a1a1 (patch)
tree4d1ea2d4d749aa9abe6ba752a2db1b4d06598fea /src/lua
parent6688ce51e94517e13f99035c8214b2c5f05af79b (diff)
downloadusdx-4711217f127aa0c10fa52755fd567c570277a1a1.tar.gz
usdx-4711217f127aa0c10fa52755fd567c570277a1a1.tar.xz
usdx-4711217f127aa0c10fa52755fd567c570277a1a1.zip
merged lua into trunk
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2071 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'src/lua')
-rw-r--r--src/lua/UHookableEvent.pas380
-rw-r--r--src/lua/ULuaCore.pas1014
-rw-r--r--src/lua/ULuaGl.pas1513
-rw-r--r--src/lua/ULuaLog.pas167
-rw-r--r--src/lua/ULuaParty.pas389
-rw-r--r--src/lua/ULuaScreenSing.pas489
-rw-r--r--src/lua/ULuaTextGL.pas147
-rw-r--r--src/lua/ULuaTexture.pas63
-rw-r--r--src/lua/ULuaUsdx.pas145
-rw-r--r--src/lua/ULuaUtils.pas186
10 files changed, 4493 insertions, 0 deletions
diff --git a/src/lua/UHookableEvent.pas b/src/lua/UHookableEvent.pas
new file mode 100644
index 00000000..8ad7ea9c
--- /dev/null
+++ b/src/lua/UHookableEvent.pas
@@ -0,0 +1,380 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UHookableEvent;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses ULua;
+
+type
+ { Record holding information about a hook of an event }
+ PHook = ^THook;
+ THook = record
+ Handle: Integer; //< Handle to identify the hook, e.g. for unhooking by plugin
+ Parent: Integer; //< Lua Core Handle this hook belongs to
+
+ Func: String; //< Name of the global that holds the function
+
+ Next: PHook; //< Next Hook in list (nil for the first)
+ end;
+
+ { procedure is called before each call to the hooking lua functions, to push values on stack
+ returns the number of pushed arguments}
+ PrepareStackProc = Function(L: PLua_State): Integer;
+
+ { class representing a hookable event }
+ THookableEvent = class
+ private
+ iHandle: Integer; //< used to unregister at lua core
+ LastHook: PHook; //< last hook in hook list, first to be called
+ NextHookHandle: Integer; //< handle to identify next hook
+
+ sName: String; //< the events name
+
+ PrepareStack: PrepareStackProc; //< prepare stack procedure passed to constructor
+ CallinProcess: boolean; //< true if a chain call is in process, to prepare unhooking during calls
+ HooksToRemove: array of PHook; // hooks to delete after chaincall
+
+ procedure RemoveWaitingHooks;
+ public
+ constructor Create(Name: String; const Proc: PrepareStackProc = nil);
+
+ property Name: String read sName; //< returns the events name
+ property Handle: Integer read iHandle; //< returns the events name
+
+ procedure Hook(L: Plua_State; Parent: Integer; Func: String); //< pushes hook object/table to the lua stack
+ procedure UnHook(L: Plua_State; hHook: Integer); //< unhook by plugin. push true or error string to lua stack
+
+ procedure UnHookByParent(Parent: Integer); //< deletes all hooks by a specified parent (unhook by core)
+
+ function CallHookChain(Breakable: Boolean): PLua_State; //< calls the events hookchain. if breakable, plugin can breake the chain by returning a value != 0 or false or nil
+
+ destructor Destroy; override;
+ end;
+
+{ the default function for THookableEvent.PrepareStack it don't pass any arguments }
+function PrepareStack_Dummy(L: PLua_State): Integer;
+
+{ function in resulting hook table. it calls the unhook command of the event on plugins demand }
+function LuaHook_UnHook(L: Plua_State): Integer; cdecl;
+
+implementation
+uses ULuaCore;
+
+constructor THookableEvent.Create(Name: String; const Proc: PrepareStackProc);
+begin
+ inherited Create;
+
+ Self.sName := Name;
+
+ if (@Proc = nil) then
+ Self.PrepareStack := @PrepareStack_Dummy
+ else
+ Self.PrepareStack := Proc;
+
+ //init LastHook pointer w/ nil
+ LastHook := nil;
+ NextHookHandle := 1;
+
+ iHandle := LuaCore.RegisterEvent(Self);
+end;
+
+destructor THookableEvent.Destroy;
+var
+ Prev: PHook;
+ Cur: PHook;
+begin
+ //delete all hooks
+ Cur := LastHook;
+ While (Cur <> nil) do
+ begin
+ Prev := Cur;
+ Cur := Prev.Next;
+
+ Dispose(Prev);
+ end;
+
+ //remove from luacores list
+ LuaCore.UnRegisterEvent(iHandle);
+
+ inherited;
+end;
+
+{ adds hook to events list and pushes hook object/table to the lua stack }
+procedure THookableEvent.Hook(L: PLua_State; Parent: Integer; Func: String);
+ var
+ Item: PHook;
+ P: TLuaPlugin;
+begin
+ P := LuaCore.GetPluginById(Parent);
+ if (P <> nil) then
+ begin
+ // get mem and fill it w/ data
+ New(Item);
+ Item.Handle := NextHookHandle;
+ Inc(NextHookHandle);
+
+ Item.Parent := Parent;
+ Item.Func := Func;
+
+ // add at front of the hook chain
+ Item.Next := LastHook;
+ LastHook := Item;
+
+ //we need 2 free stack slots
+ lua_checkstack(L, 2);
+
+ //create the hook table, we need 2 elements (event name and unhook function)
+ lua_createtable(L, 0, 2);
+
+ //push events name
+ lua_pushstring(L, PAnsiChar(Name));
+
+ //add the name to the table
+ lua_setfield(L, -2, 'Event');
+
+ //push hook id to the stack
+ lua_pushinteger(L, Item.Handle);
+
+ //create a c closure, append one value from stack(the id)
+ //this will pop both, the function and the id
+ lua_pushcclosure(L, LuaHook_UnHook, 1);
+
+ //add the function to our table
+ lua_setfield(L, -2, 'Unhook');
+
+ //the table is left on the stack, it is our result
+ end;
+end;
+
+{ removes hooks in HookstoRemove array from chain }
+procedure THookableEvent.RemoveWaitingHooks;
+ function IsInArray(Cur: PHook): boolean;
+ var I: Integer;
+ begin
+ Result := false;
+ for I := 0 to high(HooksToRemove) do
+ if (HooksToRemove[I] = Cur) then
+ begin
+ Result := true;
+ Break;
+ end;
+ end;
+
+ var
+ Cur, Prev: PHook;
+begin
+ Prev := nil;
+ Cur := LastHook;
+
+ while (Cur <> nil) do
+ begin
+ if (IsInArray(Cur)) then
+ begin //we found the hook
+ if (prev <> nil) then
+ Prev.Next := Cur.Next
+ else //last hook found
+ LastHook := Cur.Next;
+
+ //free hooks memory
+ Dispose(Cur);
+
+ if (prev <> nil) then
+ Cur := Prev.Next
+ else
+ Cur := LastHook;
+ end
+ else
+ begin
+ Prev := Cur;
+ Cur := Prev.Next;
+ end;
+ end;
+
+ SetLength(HooksToRemove, 0);
+end;
+
+{ unhook by plugin. push true or error string to lua stack }
+procedure THookableEvent.UnHook(L: Plua_State; hHook: Integer);
+ var
+ Cur, Prev: PHook;
+ Len: integer;
+begin
+ if (hHook < NextHookHandle) and (hHook > 0) then
+ begin
+ //Search for the Hook
+ Prev := nil;
+ Cur := LastHook;
+
+ while (Cur <> nil) do
+ begin
+ if (Cur.Handle = hHook) then
+ begin //we found the hook
+ if not CallinProcess then
+ begin // => remove it
+ if (prev <> nil) then
+ Prev.Next := Cur.Next
+ else //last hook found
+ LastHook := Cur.Next;
+
+ //free hooks memory
+ Dispose(Cur);
+ end
+ else
+ begin // add to list of hooks to remove
+ Len := Length(HooksToRemove);
+ SetLength(HooksToRemove, Len + 1);
+ HooksToRemove[Len] := Cur;
+ end;
+
+ //indicate success
+ lua_pushboolean(L, True);
+ exit; //break the chain and exit the function
+ end;
+ Prev := Cur;
+ Cur := Prev.Next;
+ end;
+
+ lua_pushstring(L, PAnsiChar('handle already unhooked')); //the error description
+ end
+ else
+ lua_pushstring(L, PAnsiChar('undefined hook handle')); //the error description
+end;
+
+{ deletes all hooks by a specified parent (unhook by core) }
+procedure THookableEvent.UnHookByParent(Parent: Integer);
+ var
+ Cur, Prev: PHook;
+begin
+ Prev := nil;
+ Cur := LastHook;
+
+ While (Cur <> nil) do
+ begin
+ if (Cur.Parent = Parent) then
+ begin //found a hook from parent => remove it
+ if (Prev <> nil) then
+ Prev.Next := Cur.Next
+ Else
+ LastHook := Cur.Next;
+
+ Dispose(Cur);
+
+ if (Prev <> nil) then
+ Cur := Prev.Next
+ else
+ Cur := LastHook;
+ end
+ else //move through the chain
+ begin
+ Prev := Cur;
+ Cur := Prev.Next;
+ end;
+ end;
+end;
+
+{ calls the events hookchain. if breakable, plugin can breake the chain
+ by returning a value
+ breakable is pushed as the first parameter to the hooking functions
+ if chain is broken the LuaStack is returned, with all results left
+ you may call lua_clearstack }
+function THookableEvent.CallHookChain(Breakable: Boolean): Plua_State;
+ var
+ Cur: PHook;
+ P: TLuaPlugin;
+begin
+ Result := nil;
+
+ CallinProcess := true;
+
+ Cur := LastHook;
+ While (Cur <> nil) do
+ begin
+ P := LuaCore.GetPluginById(Cur.Parent);
+ lua_pushboolean(P.LuaState, Breakable);
+
+ if (P.CallFunctionByName(Cur.Func, 1 + PrepareStack(P.LuaState), LUA_MULTRET))
+ and Breakable
+ and (lua_gettop(P.LuaState) > 0) then
+ begin //Chain Broken
+ Result := P.LuaState;
+ Break;
+ end;
+
+ Cur := Cur.Next;
+ end;
+
+ RemoveWaitingHooks;
+ CallinProcess := false;
+end;
+
+{ the default function for THookableEvent.PrepareStack it don't pass any arguments }
+function PrepareStack_Dummy(L: PLua_State): Integer;
+begin
+ Result := 0;
+end;
+
+{ function in resulting hook table. it calls the unhook command of the event on plugins demand }
+function LuaHook_UnHook(L: Plua_State): Integer; cdecl;
+ var
+ Name: string;
+ Event: THookableEvent;
+ hHook: integer;
+begin
+ Result := 0;
+
+ if not lua_isTable(L, 1) then
+ LuaL_Error(L, 'Can''t find hook table in LuaHook_Unhook. Please call Unhook with method seperator (colon) instead of a point.');
+
+ // get event name
+ Lua_GetField(L, 1, 'Event');
+ if not lua_isString(L, -1) then
+ LuaL_Error(L, 'Can''t get event name in LuaHook_Unhook');
+
+ Name := Lua_ToString(L, -1);
+
+ // get event by name
+ Event := LuaCore.GetEventbyName(Name);
+
+ // free stack slots
+ Lua_pop(L, Lua_GetTop(L));
+
+ if (Event = nil) then
+ LuaL_Error(L, PAnsiChar('event ' + Name + ' does not exist (anymore?) in LuaHook_Unhook'));
+
+ // get the hookid
+ hHook := lua_ToInteger(L, lua_upvalueindex(1));
+
+ Event.UnHook(L, hHook);
+end;
+
+end. \ No newline at end of file
diff --git a/src/lua/ULuaCore.pas b/src/lua/ULuaCore.pas
new file mode 100644
index 00000000..9b2e08c6
--- /dev/null
+++ b/src/lua/ULuaCore.pas
@@ -0,0 +1,1014 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit ULuaCore;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses SysUtils, ULua, UHookableEvent, UPath;
+
+type
+ { this exception is raised when the lua panic function
+ is called. Only in case we use call instead of pcall.
+ it has the lua error string in its message attribute }
+ ELuaException = class(Exception);
+
+ { record represents item of Eventlist of TLuaCore }
+ PEventListItem = ^TEventListItem;
+ TEventListItem = record
+ Event: THookableEvent;
+ Next: PEventListItem;
+ end;
+
+ { record represents a module }
+ TLuaModule = record
+ Name: String;
+ Functions: Array of luaL_reg; //modules functions, w/ trailing nils this time
+ end;
+
+ TLuaPlugin_Status = (psNone, psRunning, psClosed, psErrorOnLoad, psErrorOnCall, psErrorInInit, psErrorOnRun);
+ { class represents a loaded plugin }
+ TLuaPlugin = class
+ private
+ iId: Integer;
+ Filename: IPath;
+ State: Plua_State; //< all functions of this plugin are called with this Lua state
+ bPaused: Boolean; //< If true no lua functions from this state are called
+ ErrorCount: Integer; //< counts the errors that occured during function calls of this plugin
+ ShutDown: Boolean; //< for self shutdown by plugin. true if plugin wants to be unloaded after execution of current function
+
+ sName: String;
+ sVersion: String;
+ sAuthor: String;
+ sURL: String;
+
+ sStatus: TLuaPlugin_Status;
+ public
+ constructor Create(Filename: IPath; Id: Integer);
+
+ property Id: Integer read iId;
+ property Name: String read sName;
+ property Version: String read sVersion;
+ property Author: String read sAuthor;
+ property Url: String read sUrl;
+
+ property Status: TLuaPlugin_Status read sStatus;
+ property CountErrors: Integer read ErrorCount;
+
+ property LuaState: Plua_State read State;
+
+ procedure Load;
+
+ procedure Register(Name, Version, Author, Url: String);
+ function HasRegistred: Boolean;
+
+ procedure PausePlugin(doPause: Boolean);
+ property Paused: boolean read bPaused write PausePlugin;
+
+ procedure ShutMeDown;
+
+ { calls the lua function in the global w/ the given name.
+ the arguments to the function have to be pushed to the stack
+ before calling this function.
+ the arguments and the function will be removed from stack
+ results will not be removed.
+ if result is false there was an error calling the function
+ if ReportErrors is true the errorstring is popped from stack
+ and written to error.log otherwise it is left on stack}
+ function CallFunctionByName(Name: String; const nArgs: Integer = 0; const nResults: Integer = 0; const ReportErrors: Boolean = True): Boolean;
+ procedure ClearStack;
+
+ procedure Unload; //< Destroys the Luastate, and frees as much mem as possible, w/o destroying the class and important information
+
+ destructor Destroy; override;
+ end;
+
+ { class managing the plugins w/ their LuaStates, the events and modules
+ it also offers the usdx table to the plugins w/ some basic functionality
+ like self unload or hook getting}
+ TLuaCore = class
+ private
+ EventList: PEventListItem; //< pointer to first registred Event, ordered by name
+ EventHandles: Array of String; //< Index is Events handle, value is events name. if length(value) is 0 handle is considered unregistred
+
+ Plugins: Array of TLuaPlugin;
+
+ eLoadingFinished: THookableEvent;
+ protected
+ Modules: Array of TLuaModule; //< modules that has been registred, has to be proctected because fucntions of this unit need to get access
+
+ function GetModuleIdByName(Name: String): Integer; //returns id of given module, or -1 if module is not found
+ public
+ constructor Create;
+ destructor Destroy; override;
+
+ procedure LoadPlugins; //< calls LoadPlugin w/ Plugindir and LoadingFinished Eventchain
+
+ procedure BrowseDir(Dir: IPath); //< searches for files w/ extension .usdx in the specified dir and tries to load them w/ lua
+ procedure LoadPlugin(Filename: IPath); //< tries to load filename w/ lua and creates the default usdx lua environment for the plugins state
+
+ function GetPluginByName(Name: String): TLuaPlugin;
+ function GetPluginById(Id: Integer): TLuaPlugin;
+
+ { this function adds a module loader for your functions
+ name is the name the script needs to write in its require()
+ Functions is an array of lua calling compatible functions
+ w/o trailing nils! }
+ procedure RegisterModule(Name: String; const Functions: Array of luaL_reg);
+
+ function RegisterEvent(Event: THookableEvent): Integer; //< adds the event to eventlist and returns its handle
+ procedure UnRegisterEvent(hEvent: Integer); //< removes the event from eventlist by handle
+
+ function GetEventbyName(Name: String): THookableEvent; //< tries to find the event w/ the given name in the list
+ function GetEventbyHandle(hEvent: Integer): THookableEvent; //< tries to find the event w/ the given handle
+
+ procedure UnHookByParent(Parent: Integer); //< remove all hooks by given parent id from all events
+
+ procedure PrepareState(L: Plua_State);
+
+ procedure DumpPlugins; //< prints plugin runtime information w/ Log.LogStatus
+ end;
+
+//some luastyle functions to call from lua scripts
+{ register global, used by plugins to identify
+ register(plugin name, plugin version, [plugin author], [plugin homepage])
+ can only be called once since the global "register" is niled by the function
+ returns true on success. (name does not exist)}
+function TLuaPlugin_Register (L: Plua_State): Integer; cdecl;
+
+{ moduleloader for usdx.* modules
+ stored in package.loaders[3]
+ package.loaders[3] (module name)
+ returns a function to load the requested module or a error
+ description(string) when the module is not found }
+function TLuaCore_ModuleLoader (L: Plua_State): Integer; cdecl;
+
+{ loads module specified by a cfunction upvalue to
+ usdx.modulename and returns it.
+ loadmodule(module name) }
+function TLuaCore_LoadModule (L: Plua_State): Integer; cdecl;
+
+{ custom lua panic function
+ it writes error string to error.log and raises an ELuaException
+ that may be caught }
+function TLua_CustomPanic (L: Plua_State): Integer; cdecl;
+
+{ replacement for luas require function
+ can be called with more than one parameter to require
+ some modules at once. e.g.: require('math', 'Usdx.Log')
+ modules are loaded from right to left
+ unlike standard require the module tables are not returned
+ the standard require function in _require is called by
+ this function }
+function TLua_CustomRequire(L: PLua_State): Integer; cdecl;
+
+
+var
+ LuaCore: TLuaCore;
+
+implementation
+uses
+ StrUtils,
+ ULog,
+ UFilesystem,
+ ULuaUsdx,
+ UPathUtils,
+ ULuaUtils;
+
+constructor TLuaCore.Create;
+begin
+ inherited;
+
+ //init EventList w/ nil
+ EventList := nil;
+
+ eLoadingFinished := nil;
+end;
+
+destructor TLuaCore.Destroy;
+var
+ Cur: PEventListItem;
+ Prev: PEventListItem;
+begin
+ SetLength(EventHandles, 0);
+
+ //delete event list
+ Cur := EventList;
+
+ While(Cur <> nil) do
+ begin
+ Prev := Cur;
+ Cur := Prev.Next;
+
+ Dispose(Prev);
+ end;
+
+ inherited;
+end;
+
+{ calls BrowseDir w/ plugin dir and LoadingFinished eventchain }
+procedure TLuaCore.LoadPlugins;
+begin
+ // we have to create event here, because in create it can
+ // not be registred, because LuaCore is no assigned
+ if (not Assigned(eLoadingFinished)) then
+ eLoadingFinished := THookableEvent.Create('Usdx.LoadingFinished');
+
+ BrowseDir(PluginPath);
+ eLoadingFinished.CallHookChain(false);
+end;
+
+{ searches for files w/ extension .usdx in the specified
+ dir and tries to load them w/ lua }
+procedure TLuaCore.BrowseDir(Dir: IPath);
+ var
+ Iter: IFileIterator;
+ FileInfo: TFileInfo;
+ FileName: IPath;
+ Ext: IPath;
+begin
+ Ext := Path('.usdx');
+
+ // search for all files and directories
+ Iter := FileSystem.FileFind(Dir.Append('*'), faAnyFile);
+ while (Iter.HasNext) do
+ begin
+ FileInfo := Iter.Next;
+ FileName := FileInfo.Name;
+ if ((FileInfo.Attr and faDirectory) <> 0) then
+ begin
+ if (not FileName.Equals('.')) and (not FileName.Equals('..')) then
+ BrowseDir(Dir.Append(FileName));
+ end
+ else
+ begin
+ if (Ext.Equals(FileName.GetExtension(), true)) then
+ begin
+ LoadPlugin(Dir.Append(FileName));
+ end;
+ end;
+ end;
+end;
+
+{ tries to load filename w/ lua and creates the default
+ usdx lua environment for the plugins state }
+procedure TLuaCore.LoadPlugin(Filename: IPath);
+ var
+ Len: Integer;
+begin
+ Len := Length(Plugins);
+ SetLength(Plugins, Len + 1);
+ Plugins[Len] := TLuaPlugin.Create(Filename, Len);
+ Plugins[Len].Load;
+end;
+
+{ returns Plugin on success nil on failure }
+function TLuaCore.GetPluginByName(Name: String): TLuaPlugin;
+ var
+ I: Integer;
+begin
+ Result := nil;
+ Name := lowercase(Name);
+
+ For I := 0 to High(Plugins) do
+ If (lowercase(Plugins[I].Name) = Name) then
+ begin
+ Result := GetPluginById(I);
+ Exit;
+ end;
+end;
+
+{ returns Plugin on success nil on failure }
+function TLuaCore.GetPluginById(Id: Integer): TLuaPlugin;
+begin
+ If (Id >= 0) AND (Id <= High(Plugins)) then
+ Result := Plugins[Id]
+ Else
+ Result := nil;
+end;
+
+{ this function adds a module loader for your functions
+ name is the name the script needs to write in its require()
+ Functions is an array of lua calling compatible functions
+ w/o trailing nils! }
+procedure TLuaCore.RegisterModule(Name: String; const Functions: Array of luaL_reg);
+ var
+ Len: Integer;
+ FuncLen: Integer;
+ I: Integer;
+begin
+ Len := Length(Modules);
+ SetLength(Modules, Len + 1);
+ Modules[Len].Name := Name;
+
+ FuncLen := Length(Functions);
+ SetLength(Modules[Len].Functions, FuncLen + 1);
+
+ For I := 0 to FuncLen-1 do
+ Modules[Len].Functions[I] := Functions[I];
+
+ Modules[Len].Functions[FuncLen].name := nil;
+ Modules[Len].Functions[FuncLen].func := nil;
+end;
+
+{ adds the event to eventlist and returns its handle
+ called by THookableEvent on creation }
+function TLuaCore.RegisterEvent(Event: THookableEvent): Integer;
+var
+ Cur, Prev, Item: PEventListItem;
+begin
+ If (Event <> nil) and (Length(Event.Name) > 0) then
+ begin
+ Result := Length(EventHandles);
+ SetLength(EventHandles, Result + 1); //get Handle and copy it to result
+
+ EventHandles[Result] := Event.Name;
+
+ //create eventlist item
+ New(Item);
+ Item.Event := Event;
+
+ //search for a place for this event in alphabetical order
+ Prev := nil;
+ Cur := EventList;
+
+ While (Cur <> nil) and (CompareStr(Cur.Event.Name, EventHandles[Result]) < 0) do
+ begin
+ Prev := Cur;
+ Cur := Prev.Next;
+ end;
+
+ //found the place => add new item
+ if (Prev <> nil) then
+ Prev.Next := Item
+ else //first item
+ EventList := Item;
+
+ Item.Next := Cur;
+ end
+ else
+ Result := -1;
+end;
+
+{ removes the event from eventlist by handle }
+procedure TLuaCore.UnRegisterEvent(hEvent: Integer);
+ var
+ Cur, Prev: PEventListItem;
+begin
+ If (hEvent >= 0) AND (hEvent <= High(EventHandles)) AND (Length(EventHandles[hEvent]) > 0) then
+ begin //hEvent in bounds and not already deleted
+ //delete from eventlist
+ Prev := nil;
+ Cur := EventList;
+
+ While (Cur <> nil) and (CompareStr(Cur.Event.Name, EventHandles[hEvent]) < 0) do
+ begin
+ Prev := Cur;
+ Cur := Prev.Next;
+ end;
+
+ If (Cur <> nil) and (Cur.Event.Name = EventHandles[hEvent]) then
+ begin //delete if found
+ Prev.Next := Cur.Next; // remove from list
+ Dispose(Cur); // free memory
+ end;
+
+ //delete from handle array
+ EventHandles[hEvent] := '';
+ end;
+end;
+
+{ tries to find the event w/ the given name in the list
+ to-do : use binary search algorithm instead of linear search here
+ check whether this is possible (events are saved in a pointer list) }
+function TLuaCore.GetEventbyName(Name: String): THookableEvent;
+ var
+ Cur: PEventListItem;
+begin
+ Result := nil;
+
+ if (Length(Name) > 0) then
+ begin
+ //search in eventlist
+ Cur := EventList;
+
+ While (Cur <> nil) and (CompareStr(Cur.Event.Name, Name) < 0) do
+ begin
+ Cur := Cur.Next;
+ end;
+
+ If (Cur <> nil) and (Cur.Event.Name = Name) then
+ begin //we found what we want to find
+ Result := Cur.Event;
+ end;
+ end;
+end;
+
+{ tries to find the event w/ the given handle }
+function TLuaCore.GetEventbyHandle(hEvent: Integer): THookableEvent;
+begin
+ If (hEvent >= 0) AND (hEvent <= High(EventHandles)) AND (Length(EventHandles[hEvent]) > 0) then
+ begin //hEvent in bounds and not already deleted
+ Result := GetEventByName(EventHandles[hEvent]);
+ end
+ else
+ Result := nil;
+end;
+
+{ remove all hooks by given parent id from all events }
+procedure TLuaCore.UnHookByParent(Parent: Integer);
+ var
+ Cur: PEventListItem;
+begin
+ if (Parent >= 0) and (Parent <= High(Plugins)) then
+ begin
+ // go through event list
+ Cur := EventList;
+
+ While (Cur <> nil) do
+ begin
+ Cur.Event.UnHookByParent(Parent);
+ Cur := Cur.Next;
+ end;
+ end;
+end;
+
+{ prepares the given already opened Lua state with the
+ basic usdx environment, e.g.: base and package Modules,
+ usdx moduleloader and usdx table }
+procedure TLuaCore.PrepareState(L: Plua_State);
+begin
+ //load basic lib functionality
+ lua_pushcfunction(L, luaopen_base);
+ lua_call(L, 0, 0);
+ lua_pop(L, lua_gettop(L)); //pop the results
+
+ //load module functionality
+ lua_pushcfunction(L, luaopen_package);
+ lua_call(L, 0, 0);
+ lua_pop(L, lua_gettop(L)); //pop the results
+
+ { adds the loader for the other standard lib to package.preload table
+ plugins can call e.g. require('math') if they need math functionality }
+
+ // we need 3 free stack slots
+ lua_checkstack(L, 3);
+
+ // get package table
+ lua_getglobal (L, PChar('package'));
+
+ // get package.preload table
+ lua_getfield (L, -1, PChar('preload'));
+
+ {**** add string lib }
+
+ // push loader function
+ lua_pushcfunction(L, luaopen_string);
+
+ // set package.preload.x loader
+ lua_setfield (L, -2, PChar('string'));
+
+ {**** add table lib }
+
+ // push loader function
+ lua_pushcfunction(L, luaopen_table);
+
+ // set package.preload.x loader
+ lua_setfield (L, -2, PChar('table'));
+
+ {**** add math lib }
+
+ // push loader function
+ lua_pushcfunction(L, luaopen_math);
+
+ // set package.preload.x loader
+ lua_setfield (L, -2, PChar('math'));
+
+ {**** add os lib }
+
+ // push loader function
+ lua_pushcfunction(L, luaopen_os);
+
+ // set package.preload.x loader
+ lua_setfield (L, -2, PChar('os'));
+
+ //pop package.preload table from stack
+ lua_pop(L, 1);
+
+ // get package.loaders table
+ lua_getfield (L, -1, PChar('loaders'));
+
+ {**** Move C-Library and all-in-one module loader backwards,
+ slot 3 is free now }
+ // get package.loaders[4] function
+ lua_pushinteger(L, 5); //push new index
+ lua_pushinteger(L, 4); //push old index
+ lua_gettable (L, -3);
+
+ // and move it to package.loaders[5]
+ lua_settable (L, -3);
+
+ // get package.loaders[3] function
+ lua_pushinteger(L, 4); //push new index
+ lua_pushinteger(L, 3); //push old index
+ lua_gettable (L, -3);
+
+ // and move it to package.loaders[4]
+ lua_settable (L, -3);
+
+ {**** now we add the core module to package.loaders[3] }
+ lua_pushinteger(L, 3); //push new loaders index
+ lua_pushcfunction(L, TLuaCore_ModuleLoader);
+
+ // and move it to package.loaders[3]
+ lua_settable (L, -3);
+
+ //pop both package and package.loaders tables from stack
+ lua_pop(L, 2);
+
+ {**** replace the standard require w/ our custom require function }
+ // first move standard require function to _require
+ lua_getfield(L, LUA_GLOBALSINDEX, PChar('require'));
+ lua_setfield(L, LUA_GLOBALSINDEX, PChar('_require'));
+
+ // then save custom require function to require
+ lua_pushcfunction(L, TLua_CustomRequire);
+ lua_setfield(L, LUA_GLOBALSINDEX, PChar('require'));
+
+ {**** now we create the usdx table }
+ //at first functions from ULuaUsdx
+ luaL_register(L, 'Usdx', @ULuaUsdx_Lib_f[0]);
+end;
+
+{ returns id of given module, or -1 if module is not found }
+function TLuaCore.GetModuleIdByName(Name: String): Integer;
+ var
+ I: Integer;
+begin
+ Result := -1;
+
+ for I := 0 to High(Modules) do
+ if (Modules[I].Name = Name) then
+ begin
+ Result := I;
+ Exit;
+ end;
+end;
+
+{ moduleloader for usdx.* modules
+ stored in package.loaders[3]
+ package.loaders[3] (module name)
+ returns a function to load the requested module or an error
+ description(string) when the module is not found }
+function TLuaCore_ModuleLoader (L: Plua_State): Integer; cdecl;
+ var
+ Name: String;
+ ID: Integer;
+begin
+ Result := 1; //we will return one value in every case (or never return in case of an error)
+
+ if (lua_gettop(L) >= 1) then
+ begin
+ // pop all arguments but the first
+ if (lua_gettop(L) > 1) then
+ lua_pop(L, lua_gettop(L)-1);
+
+
+ if (lua_IsString(L, 1)) then
+ begin //we got the name => go get it
+ Name := lua_toString(L, 1);
+
+ //we need at least 6 letters
+ //and first 5 letters have to be usdx.
+ if (Length(Name) > 5) and (lowercase(copy(Name, 1, 5))='usdx.') then
+ begin
+ ID := LuaCore.GetModuleIdByName(copy(Name, 6, Length(Name) - 5));
+ If (ID >= 0) then
+ begin //found the module -> return loader function
+ lua_pushinteger(L, Id);
+ lua_pushcclosure(L, TLuaCore_LoadModule, 1);
+ //the function is the result, so we leave it on stack
+ end
+ else
+ lua_pushString(L, PChar('usdx module "' + Name + '" couldn''t be found'));
+ end
+ else
+ lua_pushString(L, PChar('module doesn''t have "Usdx." prefix'));
+
+ end
+ else
+ luaL_argerror(L, 1, PChar('string expected'));
+ end
+ else
+ luaL_error(L, PChar('no modulename specified in usdx moduleloader'));
+end;
+
+{ loads module specified by a cfunction upvalue to
+ usdx.modulename and returns it.
+ loadmodule(module name) }
+function TLuaCore_LoadModule (L: Plua_State): Integer; cdecl;
+ var
+ Id: Integer;
+begin
+ if (not lua_isnoneornil(L, lua_upvalueindex(1))) then
+ begin
+ Id := lua_ToInteger(L, lua_upvalueindex(1));
+
+ luaL_register(L, PChar('Usdx.' + LuaCore.Modules[Id].Name), @LuaCore.Modules[Id].Functions[0]);
+
+ // set the modules table as global "modulename"
+ // so it can be accessed either by Usdx.modulename.x() or
+ // by modulename.x()
+ lua_setglobal(L, PChar(LuaCore.Modules[Id].Name));
+
+ // no we net to push the table again to return it
+ lua_getglobal(L, PChar(LuaCore.Modules[Id].Name));
+
+ Result := 1; //return table
+ end
+ else
+ luaL_error(L, PChar('no upvalue found in LuaCore_LoadModule'));
+end;
+
+{ prints plugin runtime information w/ Log.LogStatus }
+procedure TLuaCore.DumpPlugins;
+ function PluginStatusToString(Status: TLuaPlugin_Status): String;
+ begin
+ Case Status of
+ psNone: Result := 'not loaded';
+ psRunning: Result := 'running';
+ psClosed: Result := 'closed';
+ psErrorOnLoad: Result := 'error during load';
+ psErrorOnCall: Result := 'error during call';
+ psErrorInInit: Result := 'error in plugin_init()';
+ psErrorOnRun: Result := 'error on function call';
+ else Result := 'unknown';
+ end;
+ end;
+ var
+ I: Integer;
+begin
+ //print table header
+ Log.LogError(' # ' + #09 + ' name ' + #09 + ' version ' + #09 + ' status ' + #09 + ' paused ' + #09 + ' #errors ', 'plugins');
+
+
+ For I := 0 to High(Plugins) do
+ Log.LogError(' ' + IntToStr(Plugins[I].Id) + ' ' + #09 +
+ ' ' + Plugins[I].Name + ' ' + #09 +
+ ' ' + Plugins[I].Version + ' ' + #09 +
+ ' ' + PluginStatusToString(Plugins[I].Status) + ' ' + #09 +
+ ' ' + BoolToStr(Plugins[I].Paused, true) + ' ' + #09 +
+ ' ' + IntToStr(Plugins[I].CountErrors) + ' ', 'plugins');
+
+ If (High(Plugins)<0) then
+ Log.LogError(' no plugins loaded ');
+end;
+
+// Implementation of TLuaPlugin
+//--------
+constructor TLuaPlugin.Create(Filename: IPath; Id: Integer);
+begin
+ inherited Create;
+ Self.iId := Id;
+ Self.Filename := Filename;
+
+ // set some default attributes
+ Self.bPaused := False;
+ Self.ErrorCount := 0;
+ Self.sName := 'not registred';
+ Self.sStatus := psNone;
+ Self.ShutDown := False;
+
+ State := nil; //< to prevent calls to unopened state
+end;
+
+destructor TLuaPlugin.Destroy;
+begin
+ Unload;
+ inherited;
+end;
+
+{ does the main loading part
+ can not be called by create, because Plugins[Id] isn't defined there }
+procedure TLuaPlugin.Load;
+begin
+ // create Lua state for this plugin
+ State := luaL_newstate;
+
+ //set our custom panic function if s/t went wrong along the init
+ //we don't expect
+ lua_atPanic(State, TLua_CustomPanic);
+
+ if (LuaL_LoadFile(State, PChar(Filename.ToNative)) = 0) then
+ begin // file loaded successful
+ { note: we run the file here, but the environment isn't
+ set up now. it just causes the functions to
+ register in globals and runs the code in the file
+ body. At least there should be no code, it could
+ neither use functions from baselibs nor load libs
+ with require, this code would be useless. }
+ if (lua_pcall(State, 0, 0, 0) = 0) then
+ begin // file called successful
+
+ //let the core prepare our state
+ LuaCore.PrepareState(State);
+
+ // set register function
+ lua_checkstack(State, 2);
+ lua_pushinteger(State, Id);
+ lua_pushcclosure(State, TLuaPlugin_Register, 1);
+ lua_setglobal(State, PChar('register'));
+
+ // write plugin id to registry
+ lua_pushinteger(State, iId);
+ lua_setfield (State, LUA_REGISTRYINDEX, '_USDX_STATE_ID');
+ lua_pop(State, Lua_GetTop(State));
+
+ // now run the plugin_init function
+ // plugin_init() if false or nothing is returned plugin init is aborted
+ if (CallFunctionByName('plugin_init', 0, 1)) then
+ begin
+ If (HasRegistred) AND (sStatus = psNone) AND (lua_toBoolean(State, 1)) then
+ begin
+ sStatus := psRunning;
+ ClearStack;
+ end
+ else
+ Unload;
+ end
+ else
+ begin
+ sStatus := psErrorInInit;
+ Log.LogError('error in plugin_init: ' + Self.Filename.ToNative, 'lua');
+ Unload;
+ end;
+ end
+ else
+ begin
+ sStatus := psErrorOnLoad;
+ Log.LogError(String(lua_toString(State, 1)), 'lua');
+ Log.LogError('unable to call file: ' + Self.Filename.ToNative, 'lua');
+ Unload;
+ end;
+
+ end
+ else
+ begin
+ sStatus := psErrorOnLoad;
+ Log.LogError(String(lua_toString(State, 1)), 'lua');
+ Log.LogError('unable to load file: ' + Self.Filename.ToNative, 'lua');
+ Unload;
+ end;
+end;
+
+procedure TLuaPlugin.Register(Name, Version, Author, Url: String);
+begin
+ sName := Name;
+ sVersion := Version;
+ sAuthor := Author;
+ sURL := Url;
+end;
+
+{ returns true if plugin has called register }
+function TLuaPlugin.HasRegistred: Boolean;
+begin
+ Result := (Self.sName <> 'not registred');
+end;
+
+procedure TLuaPlugin.PausePlugin(doPause: Boolean);
+begin
+ bPaused := doPause;
+end;
+
+{ unload plugin after execution of the current function }
+procedure TLuaPlugin.ShutMeDown;
+begin
+ ShutDown := True;
+end;
+
+{ calls the lua function in the global w/ the given name.
+ the arguments to the function have to be pushed to the stack
+ before calling this function.
+ the arguments and the function will be removed from stack
+ results will not be removed.
+ if result is false there was an error calling the function,
+ if ReportErrors is true the errorstring is popped from stack
+ and written to error.log otherwise it is left on stack}
+function TLuaPlugin.CallFunctionByName(Name: String; const nArgs: Integer; const nResults: Integer; const ReportErrors: Boolean): Boolean;
+begin
+ Result := false;
+ if (State <> nil) then
+ begin
+ if (not bPaused) then
+ begin
+ // we need at least one stack slot free
+ lua_checkstack(State, 1);
+
+ // lua_getglobal(State, PChar(Name)); //this is just a macro:
+ lua_getfield(State, LUA_GLOBALSINDEX, PChar(Name));
+
+ if (lua_isfunction(State, -1)) then
+ begin //we got a function
+ // move function in front of the arguments (if any)
+ if (nArgs > 0) then
+ lua_insert(State, -(nArgs + 1));
+
+ // call it!
+ if (lua_pcall(State, nArgs, nResults, 0) = 0) then
+ Result := true //called w/o errors
+ else //increase error counter
+ Inc (ErrorCount);
+ end
+ else
+ begin //we have to pop the args and the field we pushed from stack
+ lua_pop(State, nArgs + 1);
+ //leave an errormessage on stack
+ lua_pushstring(State, Pchar('could not find function named ' + Name));
+ end;
+ end
+ else
+ begin //we have to pop the args from stack
+ lua_pop(State, nArgs);
+ //leave an errormessage on stack
+ lua_pushstring(State, PChar('plugin paused'));
+ end;
+
+ if (not Result) AND (ReportErrors) then
+ Log.LogError(lua_toString(State, -1), 'lua/' + sName);
+
+ if ShutDown then
+ begin // plugin indicates self shutdown
+ ShutDown := False;
+ Unload;
+ Result := False;
+ end
+ end
+ else
+ begin
+ Log.LogError('trying to call function of closed or not opened lua state', IfThen(HasRegistred, Name, Filename.ToUTF8));
+ end;
+end;
+
+{ removes all values from stack }
+procedure TLuaPlugin.ClearStack;
+begin
+ if (State <> nil) and (lua_gettop(State) > 0) then
+ lua_pop(State, lua_gettop(State));
+end;
+
+{ destroys the lua state, and frees as much mem as possible,
+ w/o destroying the class and important information }
+procedure TLuaPlugin.Unload;
+begin
+ if (State <> nil) then
+ begin
+ if (Status in [psRunning, psErrorOnRun]) then
+ CallFunctionByName('plugin_unload');
+
+ ClearStack;
+ lua_close(State);
+ State := nil; //don't forget to nil it ;)
+
+ LuaCore.UnHookByParent(iId);
+
+ if (sStatus = psRunning) then
+ sStatus := psClosed;
+ end;
+end;
+
+function TLuaPlugin_Register (L: Plua_State): Integer; cdecl;
+ var
+ Id: Integer;
+ P: TLuaPlugin;
+ Name, Version, Author, Url: String;
+begin
+ if (lua_gettop(L) >= 2) then
+ begin // we got at least name and version
+ if (not lua_isNumber(L, lua_upvalueindex(1))) then
+ luaL_Error(L, PChar('upvalue missing'));
+
+ if (not lua_isString(L, 1)) then
+ luaL_ArgError(L, 1, 'string expected');
+
+ if (not lua_isString(L, 2)) then
+ luaL_ArgError(L, 1, 'string expected');
+
+ Id := lua_ToInteger(L, lua_upvalueindex(1));
+
+ //get version and name
+ Name := lua_tostring(L, 1);
+ Version := lua_tostring(L, 2);
+
+ //get optional parameters
+ if (lua_isString(L, 3)) then //author
+ Author := lua_toString(L, 3)
+ else
+ begin
+ Author := 'unknown';
+ end;
+
+ // homepage
+ if (lua_isString(L, 4)) then
+ Url := lua_toString(L, 4)
+ else
+ begin
+ Url := '';
+ end;
+
+ //clear stack
+ if (lua_gettop(L) > 0) then
+ lua_pop(L, lua_gettop(L));
+
+ //call register
+ P := LuaCore.GetPluginById(Id);
+ if (P <> nil) then
+ P.Register(Name, Version, Author, Url)
+ Else
+ luaL_error(L, PChar('wrong id in upstream'));
+
+ // remove function from global register
+ lua_pushnil(L);
+ lua_setglobal(L, PChar('register'));
+
+ // return true
+ Result := 1;
+ lua_pushboolean(L, True);
+ end
+ else
+ luaL_error(L, PChar('not enough arguments, at least 2 expected. in TLuaPlugin_Register'));
+end;
+
+{ custom lua panic function
+ it writes error string to error.log and raises an ELuaException
+ that may be caught }
+function TLua_CustomPanic (L: Plua_State): Integer; cdecl;
+ var
+ Msg: String;
+begin
+ if (lua_isString(L, -1)) then
+ Msg := lua_toString(L, -1)
+ else
+ Msg := 'undefined lua panic';
+
+ Log.LogError(Msg, 'lua');
+
+ raise ELuaException.Create(Msg);;
+
+ Result := 0;
+end;
+
+{ replacement for luas require function
+ can be called with more than one parameter to require
+ some modules at once. e.g.: require('math', 'Usdx.Log')
+ modules are loaded from right to left
+ unlike standard require the module tables are not returned
+ the standard require function in _require is called by
+ this function }
+function TLua_CustomRequire(L: PLua_State): Integer; cdecl;
+begin
+ // no results
+ Result := 0;
+
+ // move through parameters
+ while (lua_getTop(L) >= 1) do
+ begin
+ // get luas require function
+ lua_getfield(L, LUA_GLOBALSINDEX, PChar('_require'));
+
+ // move it under the top param
+ lua_insert(L, -2);
+
+ // call it w/ next param (function + param are poped from stack)
+ lua_call(L, 1, 0);
+ end;
+end;
+
+end. \ No newline at end of file
diff --git a/src/lua/ULuaGl.pas b/src/lua/ULuaGl.pas
new file mode 100644
index 00000000..178853b6
--- /dev/null
+++ b/src/lua/ULuaGl.pas
@@ -0,0 +1,1513 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit ULuaGl;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ gl,
+ ULua;
+
+function luaopen_gl (L: Plua_State): Integer; cdecl;
+function ULuaGl_StringToEnum(Str: String): GLenum;
+
+{ lua lib functions }
+function ULuaGl_Begin(L: Plua_State): Integer; cdecl;
+function ULuaGl_BindTexture(L: Plua_State): Integer; cdecl;
+function ULuaGl_BlendFunc(L: Plua_State): Integer; cdecl;
+function ULuaGl_Clear(L: Plua_State): Integer; cdecl;
+function ULuaGl_ClearAccum(L: Plua_State): Integer; cdecl;
+function ULuaGl_ClearColor(L: Plua_State): Integer; cdecl;
+function ULuaGl_Color(L: Plua_State): Integer; cdecl;
+function ULuaGl_CullFace(L: Plua_State): Integer; cdecl;
+function ULuaGl_DepthFunc(L: Plua_State): Integer; cdecl;
+function ULuaGl_DepthRange(L: Plua_State): Integer; cdecl;
+function ULuaGl_Disable(L: Plua_State): Integer; cdecl;
+function ULuaGl_DisableClientState(L: Plua_State): Integer; cdecl;
+function ULuaGl_DrawBuffer(L: Plua_State): Integer; cdecl;
+function ULuaGl_Enable(L: Plua_State): Integer; cdecl;
+function ULuaGl_EnableClientState(L: Plua_State): Integer; cdecl;
+function ULuaGl_End(L: Plua_State): Integer; cdecl;
+function ULuaGl_EndList(L: Plua_State): Integer; cdecl;
+function ULuaGl_Finish(L: Plua_State): Integer; cdecl;
+function ULuaGl_Flush(L: Plua_State): Integer; cdecl;
+function ULuaGl_FrontFace(L: Plua_State): Integer; cdecl;
+function ULuaGl_InitNames(L: Plua_State): Integer; cdecl;
+function ULuaGl_LoadIdentity(L: Plua_State): Integer; cdecl;
+function ULuaGl_LogicOp(L: Plua_State): Integer; cdecl;
+function ULuaGl_MatrixMode(L: Plua_State): Integer; cdecl;
+function ULuaGl_Ortho(L: Plua_State): Integer; cdecl;
+function ULuaGl_PopAttrib(L: Plua_State): Integer; cdecl;
+function ULuaGl_PopClientAttrib(L: Plua_State): Integer; cdecl;
+function ULuaGl_PopMatrix(L: Plua_State): Integer; cdecl;
+function ULuaGl_PopName(L: Plua_State): Integer; cdecl;
+function ULuaGl_PushMatrix(L: Plua_State): Integer; cdecl;
+function ULuaGl_RasterPos(L: Plua_State): Integer; cdecl;
+function ULuaGl_ReadBuffer(L: Plua_State): Integer; cdecl;
+function ULuaGl_Rect(L: Plua_State): Integer; cdecl;
+function ULuaGl_Rotate(L: Plua_State): Integer; cdecl;
+function ULuaGl_Scale(L: Plua_State): Integer; cdecl;
+function ULuaGl_ShadeModel(L: Plua_State): Integer; cdecl;
+function ULuaGl_TexCoord(L: Plua_State): Integer; cdecl;
+function ULuaGl_Translate(L: Plua_State): Integer; cdecl;
+function ULuaGl_Vertex(L: Plua_State): Integer; cdecl;
+function ULuaGl_Viewport(L: Plua_State): Integer; cdecl;
+function ULuaGl_Dummy(L: Plua_State): Integer; cdecl;
+
+const
+ ULuaGl_Lib_f: array [0..40] of lual_reg = (
+ (name:'Begin';func:ULuaGl_Begin),
+ (name:'BindTexture';func:ULuaGl_BindTexture),
+ (name:'BlendFunc';func:ULuaGl_BlendFunc),
+ (name:'Clear';func:ULuaGl_Clear),
+ (name:'ClearAccum';func:ULuaGl_ClearAccum),
+ (name:'ClearColor';func:ULuaGl_ClearColor),
+ (name:'Color';func:ULuaGl_Color),
+ (name:'CullFace';func:ULuaGl_CullFace),
+ (name:'DepthFunc';func:ULuaGl_DepthFunc),
+ (name:'DepthRange';func:ULuaGl_DepthRange),
+ (name:'Disable';func:ULuaGl_Disable),
+ (name:'DisableClientState';func:ULuaGl_DisableClientState),
+ (name:'DrawBuffer';func:ULuaGl_DrawBuffer),
+ (name:'Enable';func:ULuaGl_Enable),
+ (name:'EnableClientState';func:ULuaGl_EnableClientState),
+ (name:'End';func:ULuaGl_End),
+ (name:'EndList';func:ULuaGl_EndList),
+ (name:'Finish';func:ULuaGl_Finish),
+ (name:'Flush';func:ULuaGl_Flush),
+ (name:'FrontFace';func:ULuaGl_FrontFace),
+ (name:'InitNames';func:ULuaGl_InitNames),
+ (name:'LoadIdentity';func:ULuaGl_LoadIdentity),
+ (name:'LogicOp';func:ULuaGl_LogicOp),
+ (name:'MatrixMode';func:ULuaGl_MatrixMode),
+ (name:'Ortho';func:ULuaGl_Ortho),
+ (name:'PopAttrib';func:ULuaGl_PopAttrib),
+ (name:'PopClientAttrib';func:ULuaGl_PopClientAttrib),
+ (name:'PopMatrix';func:ULuaGl_PopMatrix),
+ (name:'PopName';func:ULuaGl_PopName),
+ (name:'PushMatrix';func:ULuaGl_PushMatrix),
+ (name:'RasterPos';func:ULuaGl_RasterPos),
+ (name:'ReadBuffer';func:ULuaGl_ReadBuffer),
+ (name:'Rotate';func:ULuaGl_Rotate),
+ (name:'Rect';func:ULuaGl_Rect),
+ (name:'Scale';func:ULuaGl_Scale),
+ (name:'ShadeModel';func:ULuaGl_ShadeModel),
+ (name:'TexCoord';func:ULuaGl_TexCoord),
+ (name:'Translate';func:ULuaGl_Translate),
+ (name:'Vertex';func:ULuaGl_Vertex),
+ (name:'Viewport';func:ULuaGl_Viewport),
+ (name:nil;func:nil)
+ );
+
+implementation
+
+uses
+ ULog;
+
+type
+ TULuaGl_Enums = record
+ Text: string;
+ Value: GLenum;
+ end;
+const
+ ULuaGl_EnumERROR = $fffffffe;
+
+function ULuaGl_Begin(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.Begin''');
+
+ glBegin(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_BindTexture(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.BindTexture''');
+
+ glBindTexture(e,lual_checkinteger(L,2));
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_BlendFunc(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+ f : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+ f := ULuaGl_StringToEnum(lual_checkstring(L,2));
+
+ if (e = ULuaGl_EnumERROR) or (f = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.BlendFunc''');
+
+ glBlendFunc(e,f);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_Clear(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.Clear''');
+
+ glClear(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_ClearAccum(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) then
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 4)) or (lua_gettop(L) = 4) then
+ glClearAccum(lual_checknumber(L,-4),
+ lual_checknumber(L,-3),
+ lual_checknumber(L,-2),
+ lual_checknumber(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.ClearAccum''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_ClearColor(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) then
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 4)) or (lua_gettop(L) = 4) then
+ glClearColor(lual_checknumber(L,-4),
+ lual_checknumber(L,-3),
+ lual_checknumber(L,-2),
+ lual_checknumber(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.ClearColor''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_Color(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) then
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 3)) or (lua_gettop(L) = 3) then
+ glColor3d(GLdouble(lual_checknumber(L,-3)),
+ GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else if (lua_istable(L, 1) and (lua_objlen(L,1) = 4)) or (lua_gettop(L) = 4) then
+ glColor4d(GLdouble(lual_checknumber(L,-4)),
+ GLdouble(lual_checknumber(L,-3)),
+ GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.Color''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_CullFace(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.CullFace''');
+
+ glCullFace(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_DepthFunc(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.DepthFunc''');
+
+ glDepthFunc(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_DepthRange(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) then
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 2))
+ or (lua_gettop(L) = 2) then
+ glDepthRange(lual_checkinteger(L,-2),
+ lual_checkinteger(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.DepthRange''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_Disable(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.Disable''');
+
+ glDisable(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_DisableClientState(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.DisableClientState''');
+
+ glDisableClientState(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_DrawBuffer(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.DrawBuffer''');
+
+ glDrawBuffer(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_Enable(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.Enable''');
+
+ glEnable(e);
+ result:=0; // number of results
+end;
+
+function ULuaGl_EnableClientState(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.EnableClientState''');
+
+ glEnableClientState(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_End(L: Plua_State): Integer; cdecl;
+begin
+ glEnd();
+ result:=0; // number of results
+end;
+
+function ULuaGl_EndList(L: Plua_State): Integer; cdecl;
+begin
+ glEndList();
+ result:=0; // number of results
+end;
+
+function ULuaGl_Finish(L: Plua_State): Integer; cdecl;
+begin
+ glFinish();
+ result:=0; // number of results
+end;
+
+function ULuaGl_Flush(L: Plua_State): Integer; cdecl;
+begin
+ glFlush();
+ result:=0; // number of results
+end;
+
+function ULuaGl_FrontFace(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.FrontFace''');
+
+ glFrontFace(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_InitNames(L: Plua_State): Integer; cdecl;
+begin
+ glInitNames();
+ result:=0; // number of results
+end;
+
+function ULuaGl_LoadIdentity(L: Plua_State): Integer; cdecl;
+begin
+ glLoadIdentity();
+ result:=0; // number of results
+end;
+
+function ULuaGl_LogicOp(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.LogicOp''');
+
+ glLogicOp(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_MatrixMode(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.MatrixMode''');
+
+ glMatrixMode(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_Ortho(L: Plua_State): Integer; cdecl;
+begin
+ if (lua_gettop(L) = 6) then
+ glOrtho(lual_checkinteger(L,-6),
+ lual_checkinteger(L,-5),
+ lual_checkinteger(L,-4),
+ lual_checkinteger(L,-3),
+ lual_checkinteger(L,-2),
+ lual_checkinteger(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.Ortho''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_PopAttrib(L: Plua_State): Integer; cdecl;
+begin
+ glPopAttrib();
+ result:=0; // number of results
+end;
+
+function ULuaGl_PopClientAttrib(L: Plua_State): Integer; cdecl;
+begin
+ glPopClientAttrib();
+ result:=0; // number of results
+end;
+
+function ULuaGl_PopMatrix(L: Plua_State): Integer; cdecl;
+begin
+ glPopMatrix();
+ result:=0; // number of results
+end;
+
+function ULuaGl_PopName(L: Plua_State): Integer; cdecl;
+begin
+ glPopName();
+ result:=0; // number of results
+end;
+
+function ULuaGl_PushMatrix(L: Plua_State): Integer; cdecl;
+begin
+ glPopName();
+ result:=0; // number of results
+end;
+
+function ULuaGl_RasterPos(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) then
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 2)) or (lua_gettop(L) = 2) then
+ glRasterPos2d(GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else if (lua_istable(L, 1) and (lua_objlen(L,1) = 3)) or (lua_gettop(L) = 3) then
+ glRasterPos3d(GLdouble(lual_checknumber(L,-3)),
+ GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else if (lua_istable(L, 1) and (lua_objlen(L,1) = 4)) or (lua_gettop(L) = 4) then
+ glRasterPos4d(GLdouble(lual_checknumber(L,-4)),
+ GLdouble(lual_checknumber(L,-3)),
+ GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.RasterPos''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_ReadBuffer(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.ReadBuffer''');
+
+ glReadBuffer(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_Rect(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) and lua_istable(L, 2) then
+ begin
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+ for i := 1 to lua_objlen(L,2) do
+ lua_rawgeti(L,2,i);
+ end;
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 2))
+ and (lua_istable(L, 2) and (lua_objlen(L,2) = 2))
+ or (lua_gettop(L) = 4) then
+ glRectD(lual_checknumber(L,-4),
+ lual_checknumber(L,-3),
+ lual_checknumber(L,-2),
+ lual_checknumber(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.Rect''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_Rotate(L: Plua_State): Integer; cdecl;
+begin
+ if (lua_gettop(L) = 3) then
+ glRotated(lual_checkinteger(L,-4),
+ lual_checkinteger(L,-3),
+ lual_checkinteger(L,-2),
+ lual_checkinteger(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.Rotate''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_Scale(L: Plua_State): Integer; cdecl;
+begin
+ if (lua_gettop(L) = 3) then
+ glScaled(lual_checkinteger(L,-3),
+ lual_checkinteger(L,-2),
+ lual_checkinteger(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.Scale''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_ShadeModel(L: Plua_State): Integer; cdecl;
+var
+ e : GLenum;
+begin
+ e := ULuaGl_StringToEnum(lual_checkstring(L,1));
+
+ if (e = ULuaGl_EnumERROR) then
+ luaL_error(L, 'incorrect string argument to function ''gl.ShadeModel''');
+
+ glShadeModel(e);
+
+ result:=0; // number of results
+end;
+
+function ULuaGl_TexCoord(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) then
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 1)) or (lua_gettop(L) = 1) then
+ glTexCoord1d(GLdouble(lual_checknumber(L,-1)))
+ else if (lua_istable(L, 1) and (lua_objlen(L,1) = 2)) or (lua_gettop(L) = 2) then
+ glTexCoord2d(GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else if (lua_istable(L, 1) and (lua_objlen(L,1) = 3)) or (lua_gettop(L) = 3) then
+ glTexCoord3d(GLdouble(lual_checknumber(L,-3)),
+ GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else if (lua_istable(L, 1) and (lua_objlen(L,1) = 4)) or (lua_gettop(L) = 4) then
+ glTexCoord4d(GLdouble(lual_checknumber(L,-4)),
+ GLdouble(lual_checknumber(L,-3)),
+ GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.TexCoord''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_Translate(L: Plua_State): Integer; cdecl;
+begin
+ if (lua_gettop(L) = 3) then
+ glTranslated(lual_checkinteger(L,-3),
+ lual_checkinteger(L,-2),
+ lual_checkinteger(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.Translate''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_Vertex(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) then
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 2)) or (lua_gettop(L) = 2) then
+ glVertex2d(GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else if (lua_istable(L, 1) and (lua_objlen(L,1) = 3)) or (lua_gettop(L) = 3) then
+ glVertex3d(GLdouble(lual_checknumber(L,-3)),
+ GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else if (lua_istable(L, 1) and (lua_objlen(L,1) = 4)) or (lua_gettop(L) = 4) then
+ glVertex4d(GLdouble(lual_checknumber(L,-4)),
+ GLdouble(lual_checknumber(L,-3)),
+ GLdouble(lual_checknumber(L,-2)),
+ GLdouble(lual_checknumber(L,-1)))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.Vertex''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_Viewport(L: Plua_State): Integer; cdecl;
+var
+ i: Integer;
+begin
+ if lua_istable(L, 1) and lua_istable(L, 2) then
+ begin
+ for i := 1 to lua_objlen(L,1) do
+ lua_rawgeti(L,1,i);
+ for i := 1 to lua_objlen(L,2) do
+ lua_rawgeti(L,2,i);
+ end;
+
+ if (lua_istable(L, 1) and (lua_objlen(L,1) = 2))
+ and (lua_istable(L, 2) and (lua_objlen(L,2) = 2))
+ or (lua_gettop(L) = 4) then
+ glViewport(lual_checkinteger(L,-4),
+ lual_checkinteger(L,-3),
+ lual_checkinteger(L,-2),
+ lual_checkinteger(L,-1))
+ else
+ luaL_error(L, 'incorrect argument to function ''gl.Viewport''');
+ result:=0; // number of results
+end;
+
+function ULuaGl_Dummy(L: Plua_State): Integer; cdecl;
+begin
+ result:=0; // number of results
+end;
+
+function luaopen_gl (L: Plua_State): Integer; cdecl;
+begin
+ luaL_register(L,'gl',@ULuaGl_Lib_f[0]);
+ result:=1;
+end;
+
+(*
+ glAccum: procedure(op: GLenum; value: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAlphaFunc: procedure(func: GLenum; ref: GLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glAreTexturesResident: function (n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glArrayElement: procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glBitmap: procedure (width, height: GLsizei; xorig, yorig: GLfloat; xmove, ymove: GLfloat; const bitmap: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCallList: procedure(list: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCallLists: procedure(n: GLsizei; atype: GLenum; const lists: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClearDepth: procedure(depth: GLclampd); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClearIndex: procedure(c: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClearStencil: procedure(s: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glClipPlane: procedure(plane: GLenum; const equation: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ glColorMask: procedure(red, green, blue, alpha: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorMaterial: procedure(face, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glColorPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyPixels: procedure(x, y: GLint; width, height: GLsizei; atype: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexImage1D: procedure (target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width: GLsizei; border: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexImage2D: procedure(target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width, height: GLsizei; border: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexSubImage1D: procedure(target: GLenum; level, xoffset, x, y: GLint; width: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glCopyTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset, x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteLists: procedure(list: GLuint; range: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDeleteTextures: procedure(n: GLsizei; const textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDepthMask: procedure(flag: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawArrays: procedure(mode: GLenum; first: GLint; count: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawElements: procedure(mode: GLenum; count: GLsizei; atype: GLenum; const indices: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glDrawPixels: procedure(width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEdgeFlag: procedure(flag: GLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEdgeFlagPointer: procedure(stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEdgeFlagv: procedure(const flag: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ glEvalCoord1d: procedure(u: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord1dv: procedure(const u: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord1f: procedure(u: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord1fv: procedure(const u: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord2d: procedure(u, v: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord2dv: procedure(const u: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord2f: procedure(u, v: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalCoord2fv: procedure(const u: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ glEvalMesh1: procedure(mode: GLenum; i1, i2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalMesh2: procedure(mode: GLenum; i1, i2, j1, j2: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalPoint1: procedure(i: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glEvalPoint2: procedure(i, j: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFeedbackBuffer: procedure(size: GLsizei; atype: GLenum; buffer: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogfv: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogi: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFogiv: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glFrustum: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenLists: function(range: GLsizei): GLuint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGenTextures: procedure(n: GLsizei; textures: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetBooleanv: procedure(pname: GLenum; params: PGLboolean); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetClipPlane: procedure(plane: GLenum; equation: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetDoublev: procedure(pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+// glGetError: function: GLenum; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetFloatv: procedure(pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetIntegerv: procedure(pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetLightfv: procedure(light, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetLightiv: procedure(light, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapdv: procedure(target, query: GLenum; v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapfv: procedure(target, query: GLenum; v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMapiv: procedure(target, query: GLenum; v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMaterialfv: procedure(face, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetMaterialiv: procedure(face, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPixelMapfv: procedure(map: GLenum; values: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPixelMapuiv: procedure(map: GLenum; values: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPixelMapusv: procedure(map: GLenum; values: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPointerv: procedure(pname: GLenum; params: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetPolygonStipple: procedure(mask: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+/ glGetString: function(name: GLenum): PChar; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexEnvfv: procedure(target, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexEnviv: procedure(target, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexGendv: procedure(coord, pname: GLenum; params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexGenfv: procedure(coord, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexGeniv: procedure(coord, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexImage: procedure(target: GLenum; level: GLint; format: GLenum; atype: GLenum; pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexLevelParameterfv: procedure(target: GLenum; level: GLint; pname: GLenum; params: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexLevelParameteriv: procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexParameterfv: procedure(target, pname: GLenum; params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glGetTexParameteriv: procedure(target, pname: GLenum; params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glHint: procedure(target, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexMask: procedure(mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ glIndexPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexd: procedure(c: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexdv: procedure(const c: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexf: procedure(c: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexfv: procedure(const c: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexi: procedure(c: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexiv: procedure(const c: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexs: procedure(c: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexsv: procedure(const c: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexub: procedure(c: GLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIndexubv: procedure(const c: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ glInterleavedArrays: procedure(format: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+/ glIsEnabled: function(cap: GLenum): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsList: function(list: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glIsTexture: function(texture: GLuint): GLboolean; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightModelf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightModelfv: procedure(pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightModeli: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightModeliv: procedure(pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightf: procedure(light, pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightfv: procedure(light, pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLighti: procedure(light, pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLightiv: procedure(light, pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLineStipple: procedure(factor: GLint; pattern: GLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLineWidth: procedure(width: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glListBase: procedure(base: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glLoadName: procedure(name: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMap1d: procedure(target: GLenum; u1, u2: GLdouble; stride, order: GLint; const points: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMap1f: procedure(target: GLenum; u1, u2: GLfloat; stride, order: GLint; const points: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMap2d: procedure(target: GLenum; u1, u2: GLdouble; ustride, uorder: GLint; v1, v2: GLdouble; vstride, vorder: GLint; const points: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMap2f: procedure(target: GLenum; u1, u2: GLfloat; ustride, uorder: GLint; v1, v2: GLfloat; vstride, vorder: GLint; const points: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapGrid1d: procedure(un: GLint; u1, u2: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapGrid1f: procedure(un: GLint; u1, u2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapGrid2d: procedure(un: GLint; u1, u2: GLdouble; vn: GLint; v1, v2: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMapGrid2f: procedure(un: GLint; u1, u2: GLfloat; vn: GLint; v1, v2: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMaterialf: procedure(face, pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMaterialfv: procedure(face, pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMateriali: procedure(face, pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMaterialiv: procedure(face, pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultMatrixd: procedure(const m: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glMultMatrixf: procedure(const m: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNewList: procedure(list: GLuint; mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3b: procedure(nx, ny, nz: GLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3bv: procedure(const v: PGLbyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3d: procedure(nx, ny, nz: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3dv: procedure(const v: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3f: procedure(nx, ny, nz: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3fv: procedure(const v: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3i: procedure(nx, ny, nz: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3iv: procedure(const v: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3s: procedure(nx, ny, nz: GLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormal3sv: procedure(const v: PGLshort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glNormalPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPassThrough: procedure(token: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelMapfv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelMapuiv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelMapusv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLushort); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelStoref: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelStorei: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelTransferf: procedure(pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelTransferi: procedure(pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPixelZoom: procedure(xfactor, yfactor: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPointSize: procedure(size: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPolygonMode: procedure(face, mode: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPolygonOffset: procedure(factor, units: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPolygonStipple: procedure(const mask: PGLubyte); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPrioritizeTextures: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPushAttrib: procedure(mask: GLbitfield); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPushClientAttrib: procedure(mask: GLbitfield); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glPushName: procedure(name: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glReadPixels: procedure(x, y: GLint; width, height: GLsizei; format, atype: GLenum; pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ glRenderMode: function(mode: GLint): GLint; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glScissor: procedure(x, y: GLint; width, height: GLsizei); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glSelectBuffer: procedure(size: GLsizei; buffer: PGLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilFunc: procedure(func: GLenum; ref: GLint; mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilMask: procedure(mask: GLuint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glStencilOp: procedure(fail, zfail, zpass: GLenum); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+
+ glTexCoordPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexEnvf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexEnvfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexEnvi: procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexEnviv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGend: procedure(coord: GLenum; pname: GLenum; param: GLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGendv: procedure(coord: GLenum; pname: GLenum; const params: PGLdouble); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGenf: procedure(coord: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGenfv: procedure(coord: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGeni: procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexGeniv: procedure(coord: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexImage1D: procedure(target: GLenum; level, internalformat: GLint; width: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexImage2D: procedure(target: GLenum; level, internalformat: GLint; width, height: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexParameterf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexParameteri: procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexSubImage1D: procedure(target: GLenum; level, xoffset: GLint; width: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset: GLint; width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ glVertexPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ {$IFDEF WINDOWS}
+ ChoosePixelFormat: function(DC: HDC; p2: PPixelFormatDescriptor): Integer; {$IFDEF WINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ {$ENDIF}
+ *)
+
+ const
+ ULuaGl_Enum: array [0..579] of TULuaGl_Enums = (
+ (Text:'GL_VERSION_1_1';Value:GL_VERSION_1_1),
+ (Text:'GL_ACCUM';Value:GL_ACCUM),
+ (Text:'GL_LOAD';Value:GL_LOAD),
+ (Text:'GL_RETURN';Value:GL_RETURN),
+ (Text:'GL_MULT';Value:GL_MULT),
+ (Text:'GL_ADD';Value:GL_ADD),
+ (Text:'GL_NEVER';Value:GL_NEVER),
+ (Text:'GL_LESS';Value:GL_LESS),
+ (Text:'GL_EQUAL';Value:GL_EQUAL),
+ (Text:'GL_LEQUAL';Value:GL_LEQUAL),
+ (Text:'GL_GREATER';Value:GL_GREATER),
+ (Text:'GL_NOTEQUAL';Value:GL_NOTEQUAL),
+ (Text:'GL_GEQUAL';Value:GL_GEQUAL),
+ (Text:'GL_ALWAYS';Value:GL_ALWAYS),
+ (Text:'GL_CURRENT_BIT';Value:GL_CURRENT_BIT),
+ (Text:'GL_POINT_BIT';Value:GL_POINT_BIT),
+ (Text:'GL_LINE_BIT';Value:GL_LINE_BIT),
+ (Text:'GL_POLYGON_BIT';Value:GL_POLYGON_BIT),
+ (Text:'GL_POLYGON_STIPPLE_BIT';Value:GL_POLYGON_STIPPLE_BIT),
+ (Text:'GL_PIXEL_MODE_BIT';Value:GL_PIXEL_MODE_BIT),
+ (Text:'GL_LIGHTING_BIT';Value:GL_LIGHTING_BIT),
+ (Text:'GL_FOG_BIT';Value:GL_FOG_BIT),
+ (Text:'GL_DEPTH_BUFFER_BIT';Value:GL_DEPTH_BUFFER_BIT),
+ (Text:'GL_ACCUM_BUFFER_BIT';Value:GL_ACCUM_BUFFER_BIT),
+ (Text:'GL_STENCIL_BUFFER_BIT';Value:GL_STENCIL_BUFFER_BIT),
+ (Text:'GL_VIEWPORT_BIT';Value:GL_VIEWPORT_BIT),
+ (Text:'GL_TRANSFORM_BIT';Value:GL_TRANSFORM_BIT),
+ (Text:'GL_ENABLE_BIT';Value:GL_ENABLE_BIT),
+ (Text:'GL_COLOR_BUFFER_BIT';Value:GL_COLOR_BUFFER_BIT),
+ (Text:'GL_HINT_BIT';Value:GL_HINT_BIT),
+ (Text:'GL_EVAL_BIT';Value:GL_EVAL_BIT),
+ (Text:'GL_LIST_BIT';Value:GL_LIST_BIT),
+ (Text:'GL_TEXTURE_BIT';Value:GL_TEXTURE_BIT),
+ (Text:'GL_SCISSOR_BIT';Value:GL_SCISSOR_BIT),
+ (Text:'GL_ALL_ATTRIB_BITS';Value:GL_ALL_ATTRIB_BITS),
+ (Text:'GL_POINTS';Value:GL_POINTS),
+ (Text:'GL_LINES';Value:GL_LINES),
+ (Text:'GL_LINE_LOOP';Value:GL_LINE_LOOP),
+ (Text:'GL_LINE_STRIP';Value:GL_LINE_STRIP),
+ (Text:'GL_TRIANGLES';Value:GL_TRIANGLES),
+ (Text:'GL_TRIANGLE_STRIP';Value:GL_TRIANGLE_STRIP),
+ (Text:'GL_TRIANGLE_FAN';Value:GL_TRIANGLE_FAN),
+ (Text:'GL_QUADS';Value:GL_QUADS),
+ (Text:'GL_QUAD_STRIP';Value:GL_QUAD_STRIP),
+ (Text:'GL_POLYGON';Value:GL_POLYGON),
+ (Text:'GL_ZERO';Value:GL_ZERO),
+ (Text:'GL_ONE';Value:GL_ONE),
+ (Text:'GL_SRC_COLOR';Value:GL_SRC_COLOR),
+ (Text:'GL_ONE_MINUS_SRC_COLOR';Value:GL_ONE_MINUS_SRC_COLOR),
+ (Text:'GL_SRC_ALPHA';Value:GL_SRC_ALPHA),
+ (Text:'GL_ONE_MINUS_SRC_ALPHA';Value:GL_ONE_MINUS_SRC_ALPHA),
+ (Text:'GL_DST_ALPHA';Value:GL_DST_ALPHA),
+ (Text:'GL_ONE_MINUS_DST_ALPHA';Value:GL_ONE_MINUS_DST_ALPHA),
+ (Text:'GL_DST_COLOR';Value:GL_DST_COLOR),
+ (Text:'GL_ONE_MINUS_DST_COLOR';Value:GL_ONE_MINUS_DST_COLOR),
+ (Text:'GL_SRC_ALPHA_SATURATE';Value:GL_SRC_ALPHA_SATURATE),
+ (Text:'GL_TRUE';Value:GL_TRUE),
+ (Text:'GL_FALSE';Value:GL_FALSE),
+ (Text:'GL_CLIP_PLANE0';Value:GL_CLIP_PLANE0),
+ (Text:'GL_CLIP_PLANE1';Value:GL_CLIP_PLANE1),
+ (Text:'GL_CLIP_PLANE2';Value:GL_CLIP_PLANE2),
+ (Text:'GL_CLIP_PLANE3';Value:GL_CLIP_PLANE3),
+ (Text:'GL_CLIP_PLANE4';Value:GL_CLIP_PLANE4),
+ (Text:'GL_CLIP_PLANE5';Value:GL_CLIP_PLANE5),
+ (Text:'GL_BYTE';Value:GL_BYTE),
+ (Text:'GL_UNSIGNED_BYTE';Value:GL_UNSIGNED_BYTE),
+ (Text:'GL_SHORT';Value:GL_SHORT),
+ (Text:'GL_UNSIGNED_SHORT';Value:GL_UNSIGNED_SHORT),
+ (Text:'GL_INT';Value:GL_INT),
+ (Text:'GL_UNSIGNED_INT';Value:GL_UNSIGNED_INT),
+ (Text:'GL_FLOAT';Value:GL_FLOAT),
+ (Text:'GL_2_BYTES';Value:GL_2_BYTES),
+ (Text:'GL_3_BYTES';Value:GL_3_BYTES),
+ (Text:'GL_4_BYTES';Value:GL_4_BYTES),
+ (Text:'GL_DOUBLE';Value:GL_DOUBLE),
+ (Text:'GL_NONE';Value:GL_NONE),
+ (Text:'GL_FRONT_LEFT';Value:GL_FRONT_LEFT),
+ (Text:'GL_FRONT_RIGHT';Value:GL_FRONT_RIGHT),
+ (Text:'GL_BACK_LEFT';Value:GL_BACK_LEFT),
+ (Text:'GL_BACK_RIGHT';Value:GL_BACK_RIGHT),
+ (Text:'GL_FRONT';Value:GL_FRONT),
+ (Text:'GL_BACK';Value:GL_BACK),
+ (Text:'GL_LEFT';Value:GL_LEFT),
+ (Text:'GL_RIGHT';Value:GL_RIGHT),
+ (Text:'GL_FRONT_AND_BACK';Value:GL_FRONT_AND_BACK),
+ (Text:'GL_AUX0';Value:GL_AUX0),
+ (Text:'GL_AUX1';Value:GL_AUX1),
+ (Text:'GL_AUX2';Value:GL_AUX2),
+ (Text:'GL_AUX3';Value:GL_AUX3),
+ (Text:'GL_NO_ERROR';Value:GL_NO_ERROR),
+ (Text:'GL_INVALID_ENUM';Value:GL_INVALID_ENUM),
+ (Text:'GL_INVALID_VALUE';Value:GL_INVALID_VALUE),
+ (Text:'GL_INVALID_OPERATION';Value:GL_INVALID_OPERATION),
+ (Text:'GL_STACK_OVERFLOW';Value:GL_STACK_OVERFLOW),
+ (Text:'GL_STACK_UNDERFLOW';Value:GL_STACK_UNDERFLOW),
+ (Text:'GL_OUT_OF_MEMORY';Value:GL_OUT_OF_MEMORY),
+ (Text:'GL_2D';Value:GL_2D),
+ (Text:'GL_3D';Value:GL_3D),
+ (Text:'GL_3D_COLOR';Value:GL_3D_COLOR),
+ (Text:'GL_3D_COLOR_TEXTURE';Value:GL_3D_COLOR_TEXTURE),
+ (Text:'GL_4D_COLOR_TEXTURE';Value:GL_4D_COLOR_TEXTURE),
+ (Text:'GL_PASS_THROUGH_TOKEN';Value:GL_PASS_THROUGH_TOKEN),
+ (Text:'GL_POINT_TOKEN';Value:GL_POINT_TOKEN),
+ (Text:'GL_LINE_TOKEN';Value:GL_LINE_TOKEN),
+ (Text:'GL_POLYGON_TOKEN';Value:GL_POLYGON_TOKEN),
+ (Text:'GL_BITMAP_TOKEN';Value:GL_BITMAP_TOKEN),
+ (Text:'GL_DRAW_PIXEL_TOKEN';Value:GL_DRAW_PIXEL_TOKEN),
+ (Text:'GL_COPY_PIXEL_TOKEN';Value:GL_COPY_PIXEL_TOKEN),
+ (Text:'GL_LINE_RESET_TOKEN';Value:GL_LINE_RESET_TOKEN),
+ (Text:'GL_EXP';Value:GL_EXP),
+ (Text:'GL_EXP2';Value:GL_EXP2),
+ (Text:'GL_CW';Value:GL_CW),
+ (Text:'GL_CCW';Value:GL_CCW),
+ (Text:'GL_COEFF';Value:GL_COEFF),
+ (Text:'GL_ORDER';Value:GL_ORDER),
+ (Text:'GL_DOMAIN';Value:GL_DOMAIN),
+ (Text:'GL_CURRENT_COLOR';Value:GL_CURRENT_COLOR),
+ (Text:'GL_CURRENT_INDEX';Value:GL_CURRENT_INDEX),
+ (Text:'GL_CURRENT_NORMAL';Value:GL_CURRENT_NORMAL),
+ (Text:'GL_CURRENT_TEXTURE_COORDS';Value:GL_CURRENT_TEXTURE_COORDS),
+ (Text:'GL_CURRENT_RASTER_COLOR';Value:GL_CURRENT_RASTER_COLOR),
+ (Text:'GL_CURRENT_RASTER_INDEX';Value:GL_CURRENT_RASTER_INDEX),
+ (Text:'GL_CURRENT_RASTER_TEXTURE_COORDS';Value:GL_CURRENT_RASTER_TEXTURE_COORDS),
+ (Text:'GL_CURRENT_RASTER_POSITION';Value:GL_CURRENT_RASTER_POSITION),
+ (Text:'GL_CURRENT_RASTER_POSITION_VALID';Value:GL_CURRENT_RASTER_POSITION_VALID),
+ (Text:'GL_CURRENT_RASTER_DISTANCE';Value:GL_CURRENT_RASTER_DISTANCE),
+ (Text:'GL_POINT_SMOOTH';Value:GL_POINT_SMOOTH),
+ (Text:'GL_POINT_SIZE';Value:GL_POINT_SIZE),
+ (Text:'GL_POINT_SIZE_RANGE';Value:GL_POINT_SIZE_RANGE),
+ (Text:'GL_POINT_SIZE_GRANULARITY';Value:GL_POINT_SIZE_GRANULARITY),
+ (Text:'GL_LINE_SMOOTH';Value:GL_LINE_SMOOTH),
+ (Text:'GL_LINE_WIDTH';Value:GL_LINE_WIDTH),
+ (Text:'GL_LINE_WIDTH_RANGE';Value:GL_LINE_WIDTH_RANGE),
+ (Text:'GL_LINE_WIDTH_GRANULARITY';Value:GL_LINE_WIDTH_GRANULARITY),
+ (Text:'GL_LINE_STIPPLE';Value:GL_LINE_STIPPLE),
+ (Text:'GL_LINE_STIPPLE_PATTERN';Value:GL_LINE_STIPPLE_PATTERN),
+ (Text:'GL_LINE_STIPPLE_REPEAT';Value:GL_LINE_STIPPLE_REPEAT),
+ (Text:'GL_LIST_MODE';Value:GL_LIST_MODE),
+ (Text:'GL_MAX_LIST_NESTING';Value:GL_MAX_LIST_NESTING),
+ (Text:'GL_LIST_BASE';Value:GL_LIST_BASE),
+ (Text:'GL_LIST_INDEX';Value:GL_LIST_INDEX),
+ (Text:'GL_POLYGON_MODE';Value:GL_POLYGON_MODE),
+ (Text:'GL_POLYGON_SMOOTH';Value:GL_POLYGON_SMOOTH),
+ (Text:'GL_POLYGON_STIPPLE';Value:GL_POLYGON_STIPPLE),
+ (Text:'GL_EDGE_FLAG';Value:GL_EDGE_FLAG),
+ (Text:'GL_CULL_FACE';Value:GL_CULL_FACE),
+ (Text:'GL_CULL_FACE_MODE';Value:GL_CULL_FACE_MODE),
+ (Text:'GL_FRONT_FACE';Value:GL_FRONT_FACE),
+ (Text:'GL_LIGHTING';Value:GL_LIGHTING),
+ (Text:'GL_LIGHT_MODEL_LOCAL_VIEWER';Value:GL_LIGHT_MODEL_LOCAL_VIEWER),
+ (Text:'GL_LIGHT_MODEL_TWO_SIDE';Value:GL_LIGHT_MODEL_TWO_SIDE),
+ (Text:'GL_LIGHT_MODEL_AMBIENT';Value:GL_LIGHT_MODEL_AMBIENT),
+ (Text:'GL_SHADE_MODEL';Value:GL_SHADE_MODEL),
+ (Text:'GL_COLOR_MATERIAL_FACE';Value:GL_COLOR_MATERIAL_FACE),
+ (Text:'GL_COLOR_MATERIAL_PARAMETER';Value:GL_COLOR_MATERIAL_PARAMETER),
+ (Text:'GL_COLOR_MATERIAL';Value:GL_COLOR_MATERIAL),
+ (Text:'GL_FOG';Value:GL_FOG),
+ (Text:'GL_FOG_INDEX';Value:GL_FOG_INDEX),
+ (Text:'GL_FOG_DENSITY';Value:GL_FOG_DENSITY),
+ (Text:'GL_FOG_START';Value:GL_FOG_START),
+ (Text:'GL_FOG_END';Value:GL_FOG_END),
+ (Text:'GL_FOG_MODE';Value:GL_FOG_MODE),
+ (Text:'GL_FOG_COLOR';Value:GL_FOG_COLOR),
+ (Text:'GL_DEPTH_RANGE';Value:GL_DEPTH_RANGE),
+ (Text:'GL_DEPTH_TEST';Value:GL_DEPTH_TEST),
+ (Text:'GL_DEPTH_WRITEMASK';Value:GL_DEPTH_WRITEMASK),
+ (Text:'GL_DEPTH_CLEAR_VALUE';Value:GL_DEPTH_CLEAR_VALUE),
+ (Text:'GL_DEPTH_FUNC';Value:GL_DEPTH_FUNC),
+ (Text:'GL_ACCUM_CLEAR_VALUE';Value:GL_ACCUM_CLEAR_VALUE),
+ (Text:'GL_STENCIL_TEST';Value:GL_STENCIL_TEST),
+ (Text:'GL_STENCIL_CLEAR_VALUE';Value:GL_STENCIL_CLEAR_VALUE),
+ (Text:'GL_STENCIL_FUNC';Value:GL_STENCIL_FUNC),
+ (Text:'GL_STENCIL_VALUE_MASK';Value:GL_STENCIL_VALUE_MASK),
+ (Text:'GL_STENCIL_FAIL';Value:GL_STENCIL_FAIL),
+ (Text:'GL_STENCIL_PASS_DEPTH_FAIL';Value:GL_STENCIL_PASS_DEPTH_FAIL),
+ (Text:'GL_STENCIL_PASS_DEPTH_PASS';Value:GL_STENCIL_PASS_DEPTH_PASS),
+ (Text:'GL_STENCIL_REF';Value:GL_STENCIL_REF),
+ (Text:'GL_STENCIL_WRITEMASK';Value:GL_STENCIL_WRITEMASK),
+ (Text:'GL_MATRIX_MODE';Value:GL_MATRIX_MODE),
+ (Text:'GL_NORMALIZE';Value:GL_NORMALIZE),
+ (Text:'GL_VIEWPORT';Value:GL_VIEWPORT),
+ (Text:'GL_MODELVIEW_STACK_DEPTH';Value:GL_MODELVIEW_STACK_DEPTH),
+ (Text:'GL_PROJECTION_STACK_DEPTH';Value:GL_PROJECTION_STACK_DEPTH),
+ (Text:'GL_TEXTURE_STACK_DEPTH';Value:GL_TEXTURE_STACK_DEPTH),
+ (Text:'GL_MODELVIEW_MATRIX';Value:GL_MODELVIEW_MATRIX),
+ (Text:'GL_PROJECTION_MATRIX';Value:GL_PROJECTION_MATRIX),
+ (Text:'GL_TEXTURE_MATRIX';Value:GL_TEXTURE_MATRIX),
+ (Text:'GL_ATTRIB_STACK_DEPTH';Value:GL_ATTRIB_STACK_DEPTH),
+ (Text:'GL_CLIENT_ATTRIB_STACK_DEPTH';Value:GL_CLIENT_ATTRIB_STACK_DEPTH),
+ (Text:'GL_ALPHA_TEST';Value:GL_ALPHA_TEST),
+ (Text:'GL_ALPHA_TEST_FUNC';Value:GL_ALPHA_TEST_FUNC),
+ (Text:'GL_ALPHA_TEST_REF';Value:GL_ALPHA_TEST_REF),
+ (Text:'GL_DITHER';Value:GL_DITHER),
+ (Text:'GL_BLEND_DST';Value:GL_BLEND_DST),
+ (Text:'GL_BLEND_SRC';Value:GL_BLEND_SRC),
+ (Text:'GL_BLEND';Value:GL_BLEND),
+ (Text:'GL_LOGIC_OP_MODE';Value:GL_LOGIC_OP_MODE),
+ (Text:'GL_INDEX_LOGIC_OP';Value:GL_INDEX_LOGIC_OP),
+ (Text:'GL_COLOR_LOGIC_OP';Value:GL_COLOR_LOGIC_OP),
+ (Text:'GL_AUX_BUFFERS';Value:GL_AUX_BUFFERS),
+ (Text:'GL_DRAW_BUFFER';Value:GL_DRAW_BUFFER),
+ (Text:'GL_READ_BUFFER';Value:GL_READ_BUFFER),
+ (Text:'GL_SCISSOR_BOX';Value:GL_SCISSOR_BOX),
+ (Text:'GL_SCISSOR_TEST';Value:GL_SCISSOR_TEST),
+ (Text:'GL_INDEX_CLEAR_VALUE';Value:GL_INDEX_CLEAR_VALUE),
+ (Text:'GL_INDEX_WRITEMASK';Value:GL_INDEX_WRITEMASK),
+ (Text:'GL_COLOR_CLEAR_VALUE';Value:GL_COLOR_CLEAR_VALUE),
+ (Text:'GL_COLOR_WRITEMASK';Value:GL_COLOR_WRITEMASK),
+ (Text:'GL_INDEX_MODE';Value:GL_INDEX_MODE),
+ (Text:'GL_RGBA_MODE';Value:GL_RGBA_MODE),
+ (Text:'GL_DOUBLEBUFFER';Value:GL_DOUBLEBUFFER),
+ (Text:'GL_STEREO';Value:GL_STEREO),
+ (Text:'GL_RENDER_MODE';Value:GL_RENDER_MODE),
+ (Text:'GL_PERSPECTIVE_CORRECTION_HINT';Value:GL_PERSPECTIVE_CORRECTION_HINT),
+ (Text:'GL_POINT_SMOOTH_HINT';Value:GL_POINT_SMOOTH_HINT),
+ (Text:'GL_LINE_SMOOTH_HINT';Value:GL_LINE_SMOOTH_HINT),
+ (Text:'GL_POLYGON_SMOOTH_HINT';Value:GL_POLYGON_SMOOTH_HINT),
+ (Text:'GL_FOG_HINT';Value:GL_FOG_HINT),
+ (Text:'GL_TEXTURE_GEN_S';Value:GL_TEXTURE_GEN_S),
+ (Text:'GL_TEXTURE_GEN_T';Value:GL_TEXTURE_GEN_T),
+ (Text:'GL_TEXTURE_GEN_R';Value:GL_TEXTURE_GEN_R),
+ (Text:'GL_TEXTURE_GEN_Q';Value:GL_TEXTURE_GEN_Q),
+ (Text:'GL_PIXEL_MAP_I_TO_I';Value:GL_PIXEL_MAP_I_TO_I),
+ (Text:'GL_PIXEL_MAP_S_TO_S';Value:GL_PIXEL_MAP_S_TO_S),
+ (Text:'GL_PIXEL_MAP_I_TO_R';Value:GL_PIXEL_MAP_I_TO_R),
+ (Text:'GL_PIXEL_MAP_I_TO_G';Value:GL_PIXEL_MAP_I_TO_G),
+ (Text:'GL_PIXEL_MAP_I_TO_B';Value:GL_PIXEL_MAP_I_TO_B),
+ (Text:'GL_PIXEL_MAP_I_TO_A';Value:GL_PIXEL_MAP_I_TO_A),
+ (Text:'GL_PIXEL_MAP_R_TO_R';Value:GL_PIXEL_MAP_R_TO_R),
+ (Text:'GL_PIXEL_MAP_G_TO_G';Value:GL_PIXEL_MAP_G_TO_G),
+ (Text:'GL_PIXEL_MAP_B_TO_B';Value:GL_PIXEL_MAP_B_TO_B),
+ (Text:'GL_PIXEL_MAP_A_TO_A';Value:GL_PIXEL_MAP_A_TO_A),
+ (Text:'GL_PIXEL_MAP_I_TO_I_SIZE';Value:GL_PIXEL_MAP_I_TO_I_SIZE),
+ (Text:'GL_PIXEL_MAP_S_TO_S_SIZE';Value:GL_PIXEL_MAP_S_TO_S_SIZE),
+ (Text:'GL_PIXEL_MAP_I_TO_R_SIZE';Value:GL_PIXEL_MAP_I_TO_R_SIZE),
+ (Text:'GL_PIXEL_MAP_I_TO_G_SIZE';Value:GL_PIXEL_MAP_I_TO_G_SIZE),
+ (Text:'GL_PIXEL_MAP_I_TO_B_SIZE';Value:GL_PIXEL_MAP_I_TO_B_SIZE),
+ (Text:'GL_PIXEL_MAP_I_TO_A_SIZE';Value:GL_PIXEL_MAP_I_TO_A_SIZE),
+ (Text:'GL_PIXEL_MAP_R_TO_R_SIZE';Value:GL_PIXEL_MAP_R_TO_R_SIZE),
+ (Text:'GL_PIXEL_MAP_G_TO_G_SIZE';Value:GL_PIXEL_MAP_G_TO_G_SIZE),
+ (Text:'GL_PIXEL_MAP_B_TO_B_SIZE';Value:GL_PIXEL_MAP_B_TO_B_SIZE),
+ (Text:'GL_PIXEL_MAP_A_TO_A_SIZE';Value:GL_PIXEL_MAP_A_TO_A_SIZE),
+ (Text:'GL_UNPACK_SWAP_BYTES';Value:GL_UNPACK_SWAP_BYTES),
+ (Text:'GL_UNPACK_LSB_FIRST';Value:GL_UNPACK_LSB_FIRST),
+ (Text:'GL_UNPACK_ROW_LENGTH';Value:GL_UNPACK_ROW_LENGTH),
+ (Text:'GL_UNPACK_SKIP_ROWS';Value:GL_UNPACK_SKIP_ROWS),
+ (Text:'GL_UNPACK_SKIP_PIXELS';Value:GL_UNPACK_SKIP_PIXELS),
+ (Text:'GL_UNPACK_ALIGNMENT';Value:GL_UNPACK_ALIGNMENT),
+ (Text:'GL_PACK_SWAP_BYTES';Value:GL_PACK_SWAP_BYTES),
+ (Text:'GL_PACK_LSB_FIRST';Value:GL_PACK_LSB_FIRST),
+ (Text:'GL_PACK_ROW_LENGTH';Value:GL_PACK_ROW_LENGTH),
+ (Text:'GL_PACK_SKIP_ROWS';Value:GL_PACK_SKIP_ROWS),
+ (Text:'GL_PACK_SKIP_PIXELS';Value:GL_PACK_SKIP_PIXELS),
+ (Text:'GL_PACK_ALIGNMENT';Value:GL_PACK_ALIGNMENT),
+ (Text:'GL_MAP_COLOR';Value:GL_MAP_COLOR),
+ (Text:'GL_MAP_STENCIL';Value:GL_MAP_STENCIL),
+ (Text:'GL_INDEX_SHIFT';Value:GL_INDEX_SHIFT),
+ (Text:'GL_INDEX_OFFSET';Value:GL_INDEX_OFFSET),
+ (Text:'GL_RED_SCALE';Value:GL_RED_SCALE),
+ (Text:'GL_RED_BIAS';Value:GL_RED_BIAS),
+ (Text:'GL_ZOOM_X';Value:GL_ZOOM_X),
+ (Text:'GL_ZOOM_Y';Value:GL_ZOOM_Y),
+ (Text:'GL_GREEN_SCALE';Value:GL_GREEN_SCALE),
+ (Text:'GL_GREEN_BIAS';Value:GL_GREEN_BIAS),
+ (Text:'GL_BLUE_SCALE';Value:GL_BLUE_SCALE),
+ (Text:'GL_BLUE_BIAS';Value:GL_BLUE_BIAS),
+ (Text:'GL_ALPHA_SCALE';Value:GL_ALPHA_SCALE),
+ (Text:'GL_ALPHA_BIAS';Value:GL_ALPHA_BIAS),
+ (Text:'GL_DEPTH_SCALE';Value:GL_DEPTH_SCALE),
+ (Text:'GL_DEPTH_BIAS';Value:GL_DEPTH_BIAS),
+ (Text:'GL_MAX_EVAL_ORDER';Value:GL_MAX_EVAL_ORDER),
+ (Text:'GL_MAX_LIGHTS';Value:GL_MAX_LIGHTS),
+ (Text:'GL_MAX_CLIP_PLANES';Value:GL_MAX_CLIP_PLANES),
+ (Text:'GL_MAX_TEXTURE_SIZE';Value:GL_MAX_TEXTURE_SIZE),
+ (Text:'GL_MAX_PIXEL_MAP_TABLE';Value:GL_MAX_PIXEL_MAP_TABLE),
+ (Text:'GL_MAX_ATTRIB_STACK_DEPTH';Value:GL_MAX_ATTRIB_STACK_DEPTH),
+ (Text:'GL_MAX_MODELVIEW_STACK_DEPTH';Value:GL_MAX_MODELVIEW_STACK_DEPTH),
+ (Text:'GL_MAX_NAME_STACK_DEPTH';Value:GL_MAX_NAME_STACK_DEPTH),
+ (Text:'GL_MAX_PROJECTION_STACK_DEPTH';Value:GL_MAX_PROJECTION_STACK_DEPTH),
+ (Text:'GL_MAX_TEXTURE_STACK_DEPTH';Value:GL_MAX_TEXTURE_STACK_DEPTH),
+ (Text:'GL_MAX_VIEWPORT_DIMS';Value:GL_MAX_VIEWPORT_DIMS),
+ (Text:'GL_MAX_CLIENT_ATTRIB_STACK_DEPTH';Value:GL_MAX_CLIENT_ATTRIB_STACK_DEPTH),
+ (Text:'GL_SUBPIXEL_BITS';Value:GL_SUBPIXEL_BITS),
+ (Text:'GL_INDEX_BITS';Value:GL_INDEX_BITS),
+ (Text:'GL_RED_BITS';Value:GL_RED_BITS),
+ (Text:'GL_GREEN_BITS';Value:GL_GREEN_BITS),
+ (Text:'GL_BLUE_BITS';Value:GL_BLUE_BITS),
+ (Text:'GL_ALPHA_BITS';Value:GL_ALPHA_BITS),
+ (Text:'GL_DEPTH_BITS';Value:GL_DEPTH_BITS),
+ (Text:'GL_STENCIL_BITS';Value:GL_STENCIL_BITS),
+ (Text:'GL_ACCUM_RED_BITS';Value:GL_ACCUM_RED_BITS),
+ (Text:'GL_ACCUM_GREEN_BITS';Value:GL_ACCUM_GREEN_BITS),
+ (Text:'GL_ACCUM_BLUE_BITS';Value:GL_ACCUM_BLUE_BITS),
+ (Text:'GL_ACCUM_ALPHA_BITS';Value:GL_ACCUM_ALPHA_BITS),
+ (Text:'GL_NAME_STACK_DEPTH';Value:GL_NAME_STACK_DEPTH),
+ (Text:'GL_AUTO_NORMAL';Value:GL_AUTO_NORMAL),
+ (Text:'GL_MAP1_COLOR_4';Value:GL_MAP1_COLOR_4),
+ (Text:'GL_MAP1_INDEX';Value:GL_MAP1_INDEX),
+ (Text:'GL_MAP1_NORMAL';Value:GL_MAP1_NORMAL),
+ (Text:'GL_MAP1_TEXTURE_COORD_1';Value:GL_MAP1_TEXTURE_COORD_1),
+ (Text:'GL_MAP1_TEXTURE_COORD_2';Value:GL_MAP1_TEXTURE_COORD_2),
+ (Text:'GL_MAP1_TEXTURE_COORD_3';Value:GL_MAP1_TEXTURE_COORD_3),
+ (Text:'GL_MAP1_TEXTURE_COORD_4';Value:GL_MAP1_TEXTURE_COORD_4),
+ (Text:'GL_MAP1_VERTEX_3';Value:GL_MAP1_VERTEX_3),
+ (Text:'GL_MAP1_VERTEX_4';Value:GL_MAP1_VERTEX_4),
+ (Text:'GL_MAP2_COLOR_4';Value:GL_MAP2_COLOR_4),
+ (Text:'GL_MAP2_INDEX';Value:GL_MAP2_INDEX),
+ (Text:'GL_MAP2_NORMAL';Value:GL_MAP2_NORMAL),
+ (Text:'GL_MAP2_TEXTURE_COORD_1';Value:GL_MAP2_TEXTURE_COORD_1),
+ (Text:'GL_MAP2_TEXTURE_COORD_2';Value:GL_MAP2_TEXTURE_COORD_2),
+ (Text:'GL_MAP2_TEXTURE_COORD_3';Value:GL_MAP2_TEXTURE_COORD_3),
+ (Text:'GL_MAP2_TEXTURE_COORD_4';Value:GL_MAP2_TEXTURE_COORD_4),
+ (Text:'GL_MAP2_VERTEX_3';Value:GL_MAP2_VERTEX_3),
+ (Text:'GL_MAP2_VERTEX_4';Value:GL_MAP2_VERTEX_4),
+ (Text:'GL_MAP1_GRID_DOMAIN';Value:GL_MAP1_GRID_DOMAIN),
+ (Text:'GL_MAP1_GRID_SEGMENTS';Value:GL_MAP1_GRID_SEGMENTS),
+ (Text:'GL_MAP2_GRID_DOMAIN';Value:GL_MAP2_GRID_DOMAIN),
+ (Text:'GL_MAP2_GRID_SEGMENTS';Value:GL_MAP2_GRID_SEGMENTS),
+ (Text:'GL_TEXTURE_1D';Value:GL_TEXTURE_1D),
+ (Text:'GL_TEXTURE_2D';Value:GL_TEXTURE_2D),
+ (Text:'GL_FEEDBACK_BUFFER_POINTER';Value:GL_FEEDBACK_BUFFER_POINTER),
+ (Text:'GL_FEEDBACK_BUFFER_SIZE';Value:GL_FEEDBACK_BUFFER_SIZE),
+ (Text:'GL_FEEDBACK_BUFFER_TYPE';Value:GL_FEEDBACK_BUFFER_TYPE),
+ (Text:'GL_SELECTION_BUFFER_POINTER';Value:GL_SELECTION_BUFFER_POINTER),
+ (Text:'GL_SELECTION_BUFFER_SIZE';Value:GL_SELECTION_BUFFER_SIZE),
+ (Text:'GL_TEXTURE_WIDTH';Value:GL_TEXTURE_WIDTH),
+ (Text:'GL_TEXTURE_HEIGHT';Value:GL_TEXTURE_HEIGHT),
+ (Text:'GL_TEXTURE_INTERNAL_FORMAT';Value:GL_TEXTURE_INTERNAL_FORMAT),
+ (Text:'GL_TEXTURE_BORDER_COLOR';Value:GL_TEXTURE_BORDER_COLOR),
+ (Text:'GL_TEXTURE_BORDER';Value:GL_TEXTURE_BORDER),
+ (Text:'GL_DONT_CARE';Value:GL_DONT_CARE),
+ (Text:'GL_FASTEST';Value:GL_FASTEST),
+ (Text:'GL_NICEST';Value:GL_NICEST),
+ (Text:'GL_LIGHT0';Value:GL_LIGHT0),
+ (Text:'GL_LIGHT1';Value:GL_LIGHT1),
+ (Text:'GL_LIGHT2';Value:GL_LIGHT2),
+ (Text:'GL_LIGHT3';Value:GL_LIGHT3),
+ (Text:'GL_LIGHT4';Value:GL_LIGHT4),
+ (Text:'GL_LIGHT5';Value:GL_LIGHT5),
+ (Text:'GL_LIGHT6';Value:GL_LIGHT6),
+ (Text:'GL_LIGHT7';Value:GL_LIGHT7),
+ (Text:'GL_AMBIENT';Value:GL_AMBIENT),
+ (Text:'GL_DIFFUSE';Value:GL_DIFFUSE),
+ (Text:'GL_SPECULAR';Value:GL_SPECULAR),
+ (Text:'GL_POSITION';Value:GL_POSITION),
+ (Text:'GL_SPOT_DIRECTION';Value:GL_SPOT_DIRECTION),
+ (Text:'GL_SPOT_EXPONENT';Value:GL_SPOT_EXPONENT),
+ (Text:'GL_SPOT_CUTOFF';Value:GL_SPOT_CUTOFF),
+ (Text:'GL_CONSTANT_ATTENUATION';Value:GL_CONSTANT_ATTENUATION),
+ (Text:'GL_LINEAR_ATTENUATION';Value:GL_LINEAR_ATTENUATION),
+ (Text:'GL_QUADRATIC_ATTENUATION';Value:GL_QUADRATIC_ATTENUATION),
+ (Text:'GL_COMPILE';Value:GL_COMPILE),
+ (Text:'GL_COMPILE_AND_EXECUTE';Value:GL_COMPILE_AND_EXECUTE),
+ (Text:'GL_CLEAR';Value:GL_CLEAR),
+ (Text:'GL_AND';Value:GL_AND),
+ (Text:'GL_AND_REVERSE';Value:GL_AND_REVERSE),
+ (Text:'GL_COPY';Value:GL_COPY),
+ (Text:'GL_AND_INVERTED';Value:GL_AND_INVERTED),
+ (Text:'GL_NOOP';Value:GL_NOOP),
+ (Text:'GL_XOR';Value:GL_XOR),
+ (Text:'GL_OR';Value:GL_OR),
+ (Text:'GL_NOR';Value:GL_NOR),
+ (Text:'GL_EQUIV';Value:GL_EQUIV),
+ (Text:'GL_INVERT';Value:GL_INVERT),
+ (Text:'GL_OR_REVERSE';Value:GL_OR_REVERSE),
+ (Text:'GL_COPY_INVERTED';Value:GL_COPY_INVERTED),
+ (Text:'GL_OR_INVERTED';Value:GL_OR_INVERTED),
+ (Text:'GL_NAND';Value:GL_NAND),
+ (Text:'GL_SET';Value:GL_SET),
+ (Text:'GL_EMISSION';Value:GL_EMISSION),
+ (Text:'GL_SHININESS';Value:GL_SHININESS),
+ (Text:'GL_AMBIENT_AND_DIFFUSE';Value:GL_AMBIENT_AND_DIFFUSE),
+ (Text:'GL_COLOR_INDEXES';Value:GL_COLOR_INDEXES),
+ (Text:'GL_MODELVIEW';Value:GL_MODELVIEW),
+ (Text:'GL_PROJECTION';Value:GL_PROJECTION),
+ (Text:'GL_TEXTURE';Value:GL_TEXTURE),
+ (Text:'GL_COLOR';Value:GL_COLOR),
+ (Text:'GL_DEPTH';Value:GL_DEPTH),
+ (Text:'GL_STENCIL';Value:GL_STENCIL),
+ (Text:'GL_COLOR_INDEX';Value:GL_COLOR_INDEX),
+ (Text:'GL_STENCIL_INDEX';Value:GL_STENCIL_INDEX),
+ (Text:'GL_DEPTH_COMPONENT';Value:GL_DEPTH_COMPONENT),
+ (Text:'GL_RED';Value:GL_RED),
+ (Text:'GL_GREEN';Value:GL_GREEN),
+ (Text:'GL_BLUE';Value:GL_BLUE),
+ (Text:'GL_ALPHA';Value:GL_ALPHA),
+ (Text:'GL_RGB';Value:GL_RGB),
+ (Text:'GL_RGBA';Value:GL_RGBA),
+ (Text:'GL_LUMINANCE';Value:GL_LUMINANCE),
+ (Text:'GL_LUMINANCE_ALPHA';Value:GL_LUMINANCE_ALPHA),
+ (Text:'GL_BITMAP';Value:GL_BITMAP),
+ (Text:'GL_POINT';Value:GL_POINT),
+ (Text:'GL_LINE';Value:GL_LINE),
+ (Text:'GL_FILL';Value:GL_FILL),
+ (Text:'GL_RENDER';Value:GL_RENDER),
+ (Text:'GL_FEEDBACK';Value:GL_FEEDBACK),
+ (Text:'GL_SELECT';Value:GL_SELECT),
+ (Text:'GL_FLAT';Value:GL_FLAT),
+ (Text:'GL_SMOOTH';Value:GL_SMOOTH),
+ (Text:'GL_KEEP';Value:GL_KEEP),
+ (Text:'GL_REPLACE';Value:GL_REPLACE),
+ (Text:'GL_INCR';Value:GL_INCR),
+ (Text:'GL_DECR';Value:GL_DECR),
+ (Text:'GL_VENDOR';Value:GL_VENDOR),
+ (Text:'GL_RENDERER';Value:GL_RENDERER),
+ (Text:'GL_VERSION';Value:GL_VERSION),
+ (Text:'GL_EXTENSIONS';Value:GL_EXTENSIONS),
+ (Text:'GL_S';Value:GL_S),
+ (Text:'GL_T';Value:GL_T),
+ (Text:'GL_R';Value:GL_R),
+ (Text:'GL_Q';Value:GL_Q),
+ (Text:'GL_MODULATE';Value:GL_MODULATE),
+ (Text:'GL_DECAL';Value:GL_DECAL),
+ (Text:'GL_TEXTURE_ENV_MODE';Value:GL_TEXTURE_ENV_MODE),
+ (Text:'GL_TEXTURE_ENV_COLOR';Value:GL_TEXTURE_ENV_COLOR),
+ (Text:'GL_TEXTURE_ENV';Value:GL_TEXTURE_ENV),
+ (Text:'GL_EYE_LINEAR';Value:GL_EYE_LINEAR),
+ (Text:'GL_OBJECT_LINEAR';Value:GL_OBJECT_LINEAR),
+ (Text:'GL_SPHERE_MAP';Value:GL_SPHERE_MAP),
+ (Text:'GL_TEXTURE_GEN_MODE';Value:GL_TEXTURE_GEN_MODE),
+ (Text:'GL_OBJECT_PLANE';Value:GL_OBJECT_PLANE),
+ (Text:'GL_EYE_PLANE';Value:GL_EYE_PLANE),
+ (Text:'GL_NEAREST';Value:GL_NEAREST),
+ (Text:'GL_LINEAR';Value:GL_LINEAR),
+ (Text:'GL_NEAREST_MIPMAP_NEAREST';Value:GL_NEAREST_MIPMAP_NEAREST),
+ (Text:'GL_LINEAR_MIPMAP_NEAREST';Value:GL_LINEAR_MIPMAP_NEAREST),
+ (Text:'GL_NEAREST_MIPMAP_LINEAR';Value:GL_NEAREST_MIPMAP_LINEAR),
+ (Text:'GL_LINEAR_MIPMAP_LINEAR';Value:GL_LINEAR_MIPMAP_LINEAR),
+ (Text:'GL_TEXTURE_MAG_FILTER';Value:GL_TEXTURE_MAG_FILTER),
+ (Text:'GL_TEXTURE_MIN_FILTER';Value:GL_TEXTURE_MIN_FILTER),
+ (Text:'GL_TEXTURE_WRAP_S';Value:GL_TEXTURE_WRAP_S),
+ (Text:'GL_TEXTURE_WRAP_T';Value:GL_TEXTURE_WRAP_T),
+ (Text:'GL_CLAMP';Value:GL_CLAMP),
+ (Text:'GL_REPEAT';Value:GL_REPEAT),
+ (Text:'GL_CLIENT_PIXEL_STORE_BIT';Value:GL_CLIENT_PIXEL_STORE_BIT),
+ (Text:'GL_CLIENT_VERTEX_ARRAY_BIT';Value:GL_CLIENT_VERTEX_ARRAY_BIT),
+ (Text:'GL_CLIENT_ALL_ATTRIB_BITS';Value:GL_CLIENT_ALL_ATTRIB_BITS),
+ (Text:'GL_POLYGON_OFFSET_FACTOR';Value:GL_POLYGON_OFFSET_FACTOR),
+ (Text:'GL_POLYGON_OFFSET_UNITS';Value:GL_POLYGON_OFFSET_UNITS),
+ (Text:'GL_POLYGON_OFFSET_POINT';Value:GL_POLYGON_OFFSET_POINT),
+ (Text:'GL_POLYGON_OFFSET_LINE';Value:GL_POLYGON_OFFSET_LINE),
+ (Text:'GL_POLYGON_OFFSET_FILL';Value:GL_POLYGON_OFFSET_FILL),
+ (Text:'GL_ALPHA4';Value:GL_ALPHA4),
+ (Text:'GL_ALPHA8';Value:GL_ALPHA8),
+ (Text:'GL_ALPHA12';Value:GL_ALPHA12),
+ (Text:'GL_ALPHA16';Value:GL_ALPHA16),
+ (Text:'GL_LUMINANCE4';Value:GL_LUMINANCE4),
+ (Text:'GL_LUMINANCE8';Value:GL_LUMINANCE8),
+ (Text:'GL_LUMINANCE12';Value:GL_LUMINANCE12),
+ (Text:'GL_LUMINANCE16';Value:GL_LUMINANCE16),
+ (Text:'GL_LUMINANCE4_ALPHA4';Value:GL_LUMINANCE4_ALPHA4),
+ (Text:'GL_LUMINANCE6_ALPHA2';Value:GL_LUMINANCE6_ALPHA2),
+ (Text:'GL_LUMINANCE8_ALPHA8';Value:GL_LUMINANCE8_ALPHA8),
+ (Text:'GL_LUMINANCE12_ALPHA4';Value:GL_LUMINANCE12_ALPHA4),
+ (Text:'GL_LUMINANCE12_ALPHA12';Value:GL_LUMINANCE12_ALPHA12),
+ (Text:'GL_LUMINANCE16_ALPHA16';Value:GL_LUMINANCE16_ALPHA16),
+ (Text:'GL_INTENSITY';Value:GL_INTENSITY),
+ (Text:'GL_INTENSITY4';Value:GL_INTENSITY4),
+ (Text:'GL_INTENSITY8';Value:GL_INTENSITY8),
+ (Text:'GL_INTENSITY12';Value:GL_INTENSITY12),
+ (Text:'GL_INTENSITY16';Value:GL_INTENSITY16),
+ (Text:'GL_R3_G3_B2';Value:GL_R3_G3_B2),
+ (Text:'GL_RGB4';Value:GL_RGB4),
+ (Text:'GL_RGB5';Value:GL_RGB5),
+ (Text:'GL_RGB8';Value:GL_RGB8),
+ (Text:'GL_RGB10';Value:GL_RGB10),
+ (Text:'GL_RGB12';Value:GL_RGB12),
+ (Text:'GL_RGB16';Value:GL_RGB16),
+ (Text:'GL_RGBA2';Value:GL_RGBA2),
+ (Text:'GL_RGBA4';Value:GL_RGBA4),
+ (Text:'GL_RGB5_A1';Value:GL_RGB5_A1),
+ (Text:'GL_RGBA8';Value:GL_RGBA8),
+ (Text:'GL_RGB10_A2';Value:GL_RGB10_A2),
+ (Text:'GL_RGBA12';Value:GL_RGBA12),
+ (Text:'GL_RGBA16';Value:GL_RGBA16),
+ (Text:'GL_TEXTURE_RED_SIZE';Value:GL_TEXTURE_RED_SIZE),
+ (Text:'GL_TEXTURE_GREEN_SIZE';Value:GL_TEXTURE_GREEN_SIZE),
+ (Text:'GL_TEXTURE_BLUE_SIZE';Value:GL_TEXTURE_BLUE_SIZE),
+ (Text:'GL_TEXTURE_ALPHA_SIZE';Value:GL_TEXTURE_ALPHA_SIZE),
+ (Text:'GL_TEXTURE_LUMINANCE_SIZE';Value:GL_TEXTURE_LUMINANCE_SIZE),
+ (Text:'GL_TEXTURE_INTENSITY_SIZE';Value:GL_TEXTURE_INTENSITY_SIZE),
+ (Text:'GL_PROXY_TEXTURE_1D';Value:GL_PROXY_TEXTURE_1D),
+ (Text:'GL_PROXY_TEXTURE_2D';Value:GL_PROXY_TEXTURE_2D),
+ (Text:'GL_TEXTURE_PRIORITY';Value:GL_TEXTURE_PRIORITY),
+ (Text:'GL_TEXTURE_RESIDENT';Value:GL_TEXTURE_RESIDENT),
+ (Text:'GL_TEXTURE_BINDING_1D';Value:GL_TEXTURE_BINDING_1D),
+ (Text:'GL_TEXTURE_BINDING_2D';Value:GL_TEXTURE_BINDING_2D),
+ (Text:'GL_VERTEX_ARRAY';Value:GL_VERTEX_ARRAY),
+ (Text:'GL_NORMAL_ARRAY';Value:GL_NORMAL_ARRAY),
+ (Text:'GL_COLOR_ARRAY';Value:GL_COLOR_ARRAY),
+ (Text:'GL_INDEX_ARRAY';Value:GL_INDEX_ARRAY),
+ (Text:'GL_TEXTURE_COORD_ARRAY';Value:GL_TEXTURE_COORD_ARRAY),
+ (Text:'GL_EDGE_FLAG_ARRAY';Value:GL_EDGE_FLAG_ARRAY),
+ (Text:'GL_VERTEX_ARRAY_SIZE';Value:GL_VERTEX_ARRAY_SIZE),
+ (Text:'GL_VERTEX_ARRAY_TYPE';Value:GL_VERTEX_ARRAY_TYPE),
+ (Text:'GL_VERTEX_ARRAY_STRIDE';Value:GL_VERTEX_ARRAY_STRIDE),
+ (Text:'GL_NORMAL_ARRAY_TYPE';Value:GL_NORMAL_ARRAY_TYPE),
+ (Text:'GL_NORMAL_ARRAY_STRIDE';Value:GL_NORMAL_ARRAY_STRIDE),
+ (Text:'GL_COLOR_ARRAY_SIZE';Value:GL_COLOR_ARRAY_SIZE),
+ (Text:'GL_COLOR_ARRAY_TYPE';Value:GL_COLOR_ARRAY_TYPE),
+ (Text:'GL_COLOR_ARRAY_STRIDE';Value:GL_COLOR_ARRAY_STRIDE),
+ (Text:'GL_INDEX_ARRAY_TYPE';Value:GL_INDEX_ARRAY_TYPE),
+ (Text:'GL_INDEX_ARRAY_STRIDE';Value:GL_INDEX_ARRAY_STRIDE),
+ (Text:'GL_TEXTURE_COORD_ARRAY_SIZE';Value:GL_TEXTURE_COORD_ARRAY_SIZE),
+ (Text:'GL_TEXTURE_COORD_ARRAY_TYPE';Value:GL_TEXTURE_COORD_ARRAY_TYPE),
+ (Text:'GL_TEXTURE_COORD_ARRAY_STRIDE';Value:GL_TEXTURE_COORD_ARRAY_STRIDE),
+ (Text:'GL_EDGE_FLAG_ARRAY_STRIDE';Value:GL_EDGE_FLAG_ARRAY_STRIDE),
+ (Text:'GL_VERTEX_ARRAY_POINTER';Value:GL_VERTEX_ARRAY_POINTER),
+ (Text:'GL_NORMAL_ARRAY_POINTER';Value:GL_NORMAL_ARRAY_POINTER),
+ (Text:'GL_COLOR_ARRAY_POINTER';Value:GL_COLOR_ARRAY_POINTER),
+ (Text:'GL_INDEX_ARRAY_POINTER';Value:GL_INDEX_ARRAY_POINTER),
+ (Text:'GL_TEXTURE_COORD_ARRAY_POINTER';Value:GL_TEXTURE_COORD_ARRAY_POINTER),
+ (Text:'GL_EDGE_FLAG_ARRAY_POINTER';Value:GL_EDGE_FLAG_ARRAY_POINTER),
+ (Text:'GL_V2F';Value:GL_V2F),
+ (Text:'GL_V3F';Value:GL_V3F),
+ (Text:'GL_C4UB_V2F';Value:GL_C4UB_V2F),
+ (Text:'GL_C4UB_V3F';Value:GL_C4UB_V3F),
+ (Text:'GL_C3F_V3F';Value:GL_C3F_V3F),
+ (Text:'GL_N3F_V3F';Value:GL_N3F_V3F),
+ (Text:'GL_C4F_N3F_V3F';Value:GL_C4F_N3F_V3F),
+ (Text:'GL_T2F_V3F';Value:GL_T2F_V3F),
+ (Text:'GL_T4F_V4F';Value:GL_T4F_V4F),
+ (Text:'GL_T2F_C4UB_V3F';Value:GL_T2F_C4UB_V3F),
+ (Text:'GL_T2F_C3F_V3F';Value:GL_T2F_C3F_V3F),
+ (Text:'GL_T2F_N3F_V3F';Value:GL_T2F_N3F_V3F),
+ (Text:'GL_T2F_C4F_N3F_V3F';Value:GL_T2F_C4F_N3F_V3F),
+ (Text:'GL_T4F_C4F_N3F_V4F';Value:GL_T4F_C4F_N3F_V4F),
+ (Text:'GL_EXT_vertex_array';Value:GL_EXT_vertex_array),
+ (Text:'GL_WIN_swap_hint';Value:GL_WIN_swap_hint),
+ (Text:'GL_EXT_bgra';Value:GL_EXT_bgra),
+ (Text:'GL_EXT_paletted_texture';Value:GL_EXT_paletted_texture),
+ (Text:'GL_VERTEX_ARRAY_EXT';Value:GL_VERTEX_ARRAY_EXT),
+ (Text:'GL_NORMAL_ARRAY_EXT';Value:GL_NORMAL_ARRAY_EXT),
+ (Text:'GL_COLOR_ARRAY_EXT';Value:GL_COLOR_ARRAY_EXT),
+ (Text:'GL_INDEX_ARRAY_EXT';Value:GL_INDEX_ARRAY_EXT),
+ (Text:'GL_TEXTURE_COORD_ARRAY_EXT';Value:GL_TEXTURE_COORD_ARRAY_EXT),
+ (Text:'GL_EDGE_FLAG_ARRAY_EXT';Value:GL_EDGE_FLAG_ARRAY_EXT),
+ (Text:'GL_VERTEX_ARRAY_SIZE_EXT';Value:GL_VERTEX_ARRAY_SIZE_EXT),
+ (Text:'GL_VERTEX_ARRAY_TYPE_EXT';Value:GL_VERTEX_ARRAY_TYPE_EXT),
+ (Text:'GL_VERTEX_ARRAY_STRIDE_EXT';Value:GL_VERTEX_ARRAY_STRIDE_EXT),
+ (Text:'GL_VERTEX_ARRAY_COUNT_EXT';Value:GL_VERTEX_ARRAY_COUNT_EXT),
+ (Text:'GL_NORMAL_ARRAY_TYPE_EXT';Value:GL_NORMAL_ARRAY_TYPE_EXT),
+ (Text:'GL_NORMAL_ARRAY_STRIDE_EXT';Value:GL_NORMAL_ARRAY_STRIDE_EXT),
+ (Text:'GL_NORMAL_ARRAY_COUNT_EXT';Value:GL_NORMAL_ARRAY_COUNT_EXT),
+ (Text:'GL_COLOR_ARRAY_SIZE_EXT';Value:GL_COLOR_ARRAY_SIZE_EXT),
+ (Text:'GL_COLOR_ARRAY_TYPE_EXT';Value:GL_COLOR_ARRAY_TYPE_EXT),
+ (Text:'GL_COLOR_ARRAY_STRIDE_EXT';Value:GL_COLOR_ARRAY_STRIDE_EXT),
+ (Text:'GL_COLOR_ARRAY_COUNT_EXT';Value:GL_COLOR_ARRAY_COUNT_EXT),
+ (Text:'GL_INDEX_ARRAY_TYPE_EXT';Value:GL_INDEX_ARRAY_TYPE_EXT),
+ (Text:'GL_INDEX_ARRAY_STRIDE_EXT';Value:GL_INDEX_ARRAY_STRIDE_EXT),
+ (Text:'GL_INDEX_ARRAY_COUNT_EXT';Value:GL_INDEX_ARRAY_COUNT_EXT),
+ (Text:'GL_TEXTURE_COORD_ARRAY_SIZE_EXT';Value:GL_TEXTURE_COORD_ARRAY_SIZE_EXT),
+ (Text:'GL_TEXTURE_COORD_ARRAY_TYPE_EXT';Value:GL_TEXTURE_COORD_ARRAY_TYPE_EXT),
+ (Text:'GL_TEXTURE_COORD_ARRAY_STRIDE_EXT';Value:GL_TEXTURE_COORD_ARRAY_STRIDE_EXT),
+ (Text:'GL_TEXTURE_COORD_ARRAY_COUNT_EXT';Value:GL_TEXTURE_COORD_ARRAY_COUNT_EXT),
+ (Text:'GL_EDGE_FLAG_ARRAY_STRIDE_EXT';Value:GL_EDGE_FLAG_ARRAY_STRIDE_EXT),
+ (Text:'GL_EDGE_FLAG_ARRAY_COUNT_EXT';Value:GL_EDGE_FLAG_ARRAY_COUNT_EXT),
+ (Text:'GL_VERTEX_ARRAY_POINTER_EXT';Value:GL_VERTEX_ARRAY_POINTER_EXT),
+ (Text:'GL_NORMAL_ARRAY_POINTER_EXT';Value:GL_NORMAL_ARRAY_POINTER_EXT),
+ (Text:'GL_COLOR_ARRAY_POINTER_EXT';Value:GL_COLOR_ARRAY_POINTER_EXT),
+ (Text:'GL_INDEX_ARRAY_POINTER_EXT';Value:GL_INDEX_ARRAY_POINTER_EXT),
+ (Text:'GL_TEXTURE_COORD_ARRAY_POINTER_EXT';Value:GL_TEXTURE_COORD_ARRAY_POINTER_EXT),
+ (Text:'GL_EDGE_FLAG_ARRAY_POINTER_EXT';Value:GL_EDGE_FLAG_ARRAY_POINTER_EXT),
+ (Text:'GL_DOUBLE_EXT';Value:GL_DOUBLE_EXT),
+ (Text:'GL_BGR_EXT';Value:GL_BGR_EXT),
+ (Text:'GL_BGRA_EXT';Value:GL_BGRA_EXT),
+ (Text:'GL_COLOR_TABLE_FORMAT_EXT';Value:GL_COLOR_TABLE_FORMAT_EXT),
+ (Text:'GL_COLOR_TABLE_WIDTH_EXT';Value:GL_COLOR_TABLE_WIDTH_EXT),
+ (Text:'GL_COLOR_TABLE_RED_SIZE_EXT';Value:GL_COLOR_TABLE_RED_SIZE_EXT),
+ (Text:'GL_COLOR_TABLE_GREEN_SIZE_EXT';Value:GL_COLOR_TABLE_GREEN_SIZE_EXT),
+ (Text:'GL_COLOR_TABLE_BLUE_SIZE_EXT';Value:GL_COLOR_TABLE_BLUE_SIZE_EXT),
+ (Text:'GL_COLOR_TABLE_ALPHA_SIZE_EXT';Value:GL_COLOR_TABLE_ALPHA_SIZE_EXT),
+ (Text:'GL_COLOR_TABLE_LUMINANCE_SIZE_EXT';Value:GL_COLOR_TABLE_LUMINANCE_SIZE_EXT),
+ (Text:'GL_COLOR_TABLE_INTENSITY_SIZE_EXT';Value:GL_COLOR_TABLE_INTENSITY_SIZE_EXT),
+ (Text:'GL_COLOR_INDEX1_EXT';Value:GL_COLOR_INDEX1_EXT),
+ (Text:'GL_COLOR_INDEX2_EXT';Value:GL_COLOR_INDEX2_EXT),
+ (Text:'GL_COLOR_INDEX4_EXT';Value:GL_COLOR_INDEX4_EXT),
+ (Text:'GL_COLOR_INDEX8_EXT';Value:GL_COLOR_INDEX8_EXT),
+ (Text:'GL_COLOR_INDEX12_EXT';Value:GL_COLOR_INDEX12_EXT),
+ (Text:'GL_COLOR_INDEX16_EXT';Value:GL_COLOR_INDEX16_EXT)
+ );
+
+function ULuaGl_StringToEnum(Str: String): GLenum;
+ function GetEnum(const Str: String): GLenum;
+ var
+ i : Integer;
+ begin
+ for i := 0 to high(ULuaGl_Enum) do
+ begin
+ if 0 = AnsiCompareText(Str, ULuaGl_Enum[i].Text) then
+ begin
+ Result := ULuaGl_Enum[i].Value;
+ Exit;
+ end;
+ end;
+ Result := ULuaGl_EnumERROR;
+ end;
+ var
+ i : Integer;
+ j : Integer;
+ temp : GLenum;
+begin
+ Result := 0;
+ j := 1;
+ for i := 1 to Length(Str) do
+ begin
+ if Str[i] = ',' then
+ begin
+ temp := GetEnum(Copy(Str,j,i-j));
+ if temp <> ULuaGl_EnumERROR then
+ Result := Result or temp;
+ j := i + 1;
+ end;
+ end;
+
+ temp := GetEnum(Copy(Str,j,MaxInt));
+ if (temp = ULuaGl_EnumERROR) then
+ begin
+ if Result = 0 then
+ Result := ULuaGl_EnumERROR;
+ exit;
+ end;
+ Result := Result or temp;
+end;
+end.
+
diff --git a/src/lua/ULuaLog.pas b/src/lua/ULuaLog.pas
new file mode 100644
index 00000000..95efaa19
--- /dev/null
+++ b/src/lua/ULuaLog.pas
@@ -0,0 +1,167 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit ULuaLog;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ ULog,
+ ULua;
+
+function luaopen_Log (L: Plua_State): Integer; cdecl;
+
+function ULuaLog_LogError(L: Plua_State): Integer; cdecl;
+function ULuaLog_LogMsg(L: Plua_State): Integer; cdecl;
+function ULuaLog_BenchmarkStart(L: Plua_State): Integer; cdecl;
+function ULuaLog_BenchmarkEnd(L: Plua_State): Integer; cdecl;
+function ULuaLog_LogBenchmark(L: Plua_State): Integer; cdecl;
+function ULuaLog_LogDebug(L: Plua_State): Integer; cdecl;
+function ULuaLog_LogInfo(L: Plua_State): Integer; cdecl;
+function ULuaLog_LogStatus(L: Plua_State): Integer; cdecl;
+function ULuaLog_LogWarn(L: Plua_State): Integer; cdecl;
+function ULuaLog_LogCritical(L: Plua_State): Integer; cdecl;
+function ULuaLog_CriticalError(L: Plua_State): Integer; cdecl;
+function ULuaLog_GetLogLevel(L: Plua_State): Integer; cdecl;
+function ULuaLog_SetLogLevel(L: Plua_State): Integer; cdecl;
+
+
+const
+ ULuaLog_Lib_f: array [0..13] of lual_reg = (
+ (name:'LogError';func:ULuaLog_LogError),
+ (name:'LogMsg';func:ULuaLog_LogMsg),
+ (name:'BenchmarkStart';func:ULuaLog_BenchmarkStart),
+ (name:'BenchmarkEnd';func:ULuaLog_BenchmarkEnd),
+ (name:'LogBenchmark';func:ULuaLog_LogBenchmark),
+ (name:'LogDebug';func:ULuaLog_LogDebug),
+ (name:'LogInfo';func:ULuaLog_LogInfo),
+ (name:'LogStatus';func:ULuaLog_LogStatus),
+ (name:'LogWarn';func:ULuaLog_LogWarn),
+ (name:'LogCritical';func:ULuaLog_LogCritical),
+ (name:'CriticalError';func:ULuaLog_CriticalError),
+ (name:'SetLogLevel';func:ULuaLog_GetLogLevel),
+ (name:'GetLogLevel';func:ULuaLog_SetLogLevel),
+ (name:nil;func:nil)
+ );
+
+implementation
+
+function ULuaLog_LogError(L: Plua_State): Integer; cdecl;
+begin
+ if (lua_gettop(L) > 1) then
+ Log.LogError(luaL_checkstring(L,-2),luaL_checkstring(L,-1))
+ else
+ Log.LogError(luaL_checkstring(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_LogMsg(L: Plua_State): Integer; cdecl;
+begin
+ if (lua_gettop(L) > 2) then
+ Log.LogMsg(luaL_checkstring(L,-3),luaL_checkstring(L,-1),luaL_checkinteger(L,-2))
+ else
+ Log.LogMsg(luaL_checkstring(L,-2),luaL_checkinteger(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_BenchmarkStart(L: Plua_State): Integer; cdecl;
+begin
+ Log.BenchmarkStart(luaL_checkinteger(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_BenchmarkEnd(L: Plua_State): Integer; cdecl;
+begin
+ Log.BenchmarkEnd(luaL_checkinteger(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_LogBenchmark(L: Plua_State): Integer; cdecl;
+begin
+ Log.LogBenchmark(luaL_checkstring(L,-2),luaL_checkinteger(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_LogDebug(L: Plua_State): Integer; cdecl;
+begin
+ Log.LogDebug(luaL_checkstring(L,-2),luaL_checkstring(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_LogInfo(L: Plua_State): Integer; cdecl;
+begin
+ Log.LogInfo(luaL_checkstring(L,-2),luaL_checkstring(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_LogStatus(L: Plua_State): Integer; cdecl;
+begin
+ Log.LogStatus(luaL_checkstring(L,-2),luaL_checkstring(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_LogWarn(L: Plua_State): Integer; cdecl;
+begin
+ Log.LogWarn(luaL_checkstring(L,-2),luaL_checkstring(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_LogCritical(L: Plua_State): Integer; cdecl;
+begin
+ Log.LogCritical(luaL_checkstring(L,-2),luaL_checkstring(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_CriticalError(L: Plua_State): Integer; cdecl;
+begin
+ Log.CriticalError(luaL_checkstring(L,-1));
+ result:=0; // number of results
+end;
+
+function ULuaLog_GetLogLevel(L: Plua_State): Integer; cdecl;
+begin
+ lua_pushinteger(L,Log.GetLogLevel());
+ result:=1; // number of results
+end;
+
+function ULuaLog_SetLogLevel(L: Plua_State): Integer; cdecl;
+begin
+ Log.SetLogLevel(luaL_checkinteger(L,-1));
+ result:=0; // number of results
+end;
+
+function luaopen_Log (L: Plua_State): Integer; cdecl;
+begin
+ luaL_register(L,'Log',@ULuaLog_Lib_f[0]);
+ result:=1;
+end;
+end.
diff --git a/src/lua/ULuaParty.pas b/src/lua/ULuaParty.pas
new file mode 100644
index 00000000..883c3aec
--- /dev/null
+++ b/src/lua/ULuaParty.pas
@@ -0,0 +1,389 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit ULuaParty;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses ULua;
+
+{ lua c functions from Party table. Enables creating of party modes w/ lua scripts }
+
+{ Party.Register - register party mode at party manager
+ arguments: info: table
+ Name: String; //< Name used as identifier (language strings, etc.). Has to be set.
+ CanNonParty: Boolean //< mode is playable when not in party mode. defaulted to false if not set
+ CanParty: Boolean //< mode is playable in party mode. defaulted to false if not set
+ PlayerCount: Table //< playable with one, two, three etc. players per team. defaulted to no restrictions if not set. (use table constructor e.g. {1, 2, 3) means playable w/ 1, 2 or three players)
+ TeamCount: Table //< playable with one, two, three etc. different teams. defaulted to no restrictions if not set. (use table constructor e.g. {1, 2, 3) means playable w/ 1, 2 or three players)
+
+ BeforeSongSelect: String //< name of global that will be called before song select screen is shown (if nil, not callable or returns true, default action will be executed)
+ AfterSongSelect: String //< name of global that will be called after song is selected (if nil, not callable or returns true, default action will be executed)
+
+ BeforeSing: String //< name of global that will be called before song select screen is shown (if nil, not callable or returns true, default action will be executed)
+ OnSing: String //< name of global that will be called before song select screen is shown (if nil, not callable or returns true, default action will be executed)
+ AfterSing: String //< name of global that will be called before song select screen is shown (if nil, not callable or returns true, default action will be executed)}
+function ULuaParty_Register(L: Plua_State): Integer; cdecl;
+
+{ Party.GameFinished - returns true if no party game is running or all rounds
+ of current game were played }
+function ULuaParty_GameFinished(L: Plua_State): Integer; cdecl;
+
+(* Party.SetRoundRanking - sets ranking of current party round,
+ arguments: Ranking: table
+ ranking of team i is the value (integer from 1 to number of teams) of the
+ table with index [i: number].
+ you may call this function in the following way:
+ Party.SetRoundRanking({3, 1, 2});
+ this means: team 1 is ranked third, team 2 is ranked first and team 3 is
+ ranked second.
+ if no party game is started or party game is finished
+ it will raise an error *)
+function ULuaParty_SetRoundRanking(L: Plua_State): Integer; cdecl;
+
+{ Party.GetTeams - returns a table with all information and structure as
+ in the TPartyGame.Teams array }
+function ULuaParty_GetTeams(L: Plua_State): Integer; cdecl;
+
+{ Party.SetTeams - changes all fields from TPartyGame.Teams that have been
+ set in the table given as first argument}
+function ULuaParty_SetTeams(L: Plua_State): Integer; cdecl;
+
+const
+ ULuaParty_Lib_f: array [0..4] of lual_reg = (
+ (name:'Register'; func:ULuaParty_Register),
+ (name:'GameFinished'; func:ULuaParty_GameFinished),
+ (name:'SetRoundRanking'; func:ULuaParty_SetRoundRanking),
+ (name:'GetTeams'; func:ULuaParty_GetTeams),
+ (name:'SetTeams'; func:ULuaParty_SetTeams)
+ );
+
+implementation
+uses ULuaCore, ULuaUtils, UParty, SysUtils;
+
+
+{ Party.Register - register party mode at party manager
+ arguments: info: table
+ Name: String; //< Name used as identifier (language strings, etc.). Has to be set.
+ CanNonParty: Boolean //< mode is playable when not in party mode. defaulted to false if not set
+ CanParty: Boolean //< mode is playable in party mode. defaulted to false if not set
+ PlayerCount: Table //< playable with one, two, three etc. players per team. defaulted to no restrictions if not set. (use table constructor e.g. {1, 2, 3) means playable w/ 1, 2 or three players)
+ TeamCount: Table //< playable with one, two, three etc. different teams. defaulted to no restrictions if not set. (use table constructor e.g. {1, 2, 3) means playable w/ 1, 2 or three players)
+
+ BeforeSongSelect: String //< name of global that will be called before song select screen is shown (if nil, not callable or returns true, default action will be executed)
+ AfterSongSelect: String //< name of global that will be called after song is selected (if nil, not callable or returns true, default action will be executed)
+
+ BeforeSing: String //< name of global that will be called before song select screen is shown (if nil, not callable or returns true, default action will be executed)
+ OnSing: String //< name of global that will be called before song select screen is shown (if nil, not callable or returns true, default action will be executed)
+ AfterSing: String //< name of global that will be called before song select screen is shown (if nil, not callable or returns true, default action will be executed)}
+function ULuaParty_Register(L: Plua_State): Integer; cdecl;
+ var
+ Info: TParty_ModeInfo;
+ Key: String;
+ P: TLuaPlugin;
+begin
+ Result := 0;
+
+ // check for table on stack
+ luaL_checkType(L, 1, LUA_TTABLE);
+
+ // get parent id
+ P := Lua_GetOwner(L);
+
+
+ // set mode info to default
+ Party.DefaultModeInfo(Info);
+
+
+ // set parent in info rec and pop it from stack
+ Info.Parent := P.Id;
+
+ // go through table elements
+ lua_pushNil(L);
+ while (lua_Next(L, 1) <> 0) do
+ begin
+ Key := lowercase(lua_ToString(L, -2));
+
+ if (Key = 'name') and lua_isString(L, -1) then
+ Info.Name := lua_toString(L, -1)
+ else if (Key = 'cannonparty') and lua_isBoolean(L, -1) then
+ Info.CanNonParty := lua_toBoolean(L, -1)
+ else if (Key = 'canparty') and lua_isBoolean(L, -1) then
+ Info.CanParty := lua_toBoolean(L, -1)
+ else if (Key = 'playercount') and lua_isTable(L, -1) then
+ Info.PlayerCount := lua_toBinInt(L, -1)
+ else if (Key = 'teamcount') and lua_isTable(L, -1) then
+ Info.TeamCount := lua_toBinInt(L, -1)
+ else if (Key = 'beforesongselect') and lua_isString(L, -1) then
+ Info.Functions.BeforeSongSelect := lua_toString(L, -1)
+ else if (Key = 'aftersongselect') and lua_isString(L, -1) then
+ Info.Functions.AfterSongSelect := lua_toString(L, -1)
+ else if (Key = 'beforesing') and lua_isString(L, -1) then
+ Info.Functions.BeforeSing := lua_toString(L, -1)
+ else if (Key = 'onsing') and lua_isString(L, -1) then
+ Info.Functions.OnSing := lua_toString(L, -1)
+ else if (Key = 'aftersing') and lua_isString(L, -1) then
+ Info.Functions.AfterSing := lua_toString(L, -1);
+
+ // pop value from stack so key is on top
+ lua_pop(L, 1);
+ end;
+
+ // clear stack from table
+ lua_pop(L, lua_gettop(L));
+
+ if not Party.RegisterMode(Info) then
+ luaL_error(L, PChar('can''t register party mode at party manager in Party.Register. Is Info.Name defined or is there another mode with this name?'));
+end;
+
+{ Party.GameFinished - returns true if no party game is running or all rounds
+ of current game were played }
+function ULuaParty_GameFinished(L: Plua_State): Integer; cdecl;
+begin
+ // clear stack
+ lua_pop(L, lua_gettop(L));
+
+ // push result
+ lua_pushBoolean(L, Party.GameFinished);
+
+ //we return one value
+ Result := 1;
+end;
+
+{ Party.SetRoundRanking - sets ranking of current party round,
+ if no party game is started or party game is finished
+ it will raise an error }
+function ULuaParty_SetRoundRanking(L: Plua_State): Integer; cdecl;
+var
+ R: AParty_TeamRanking;
+ I: Integer;
+ Rank: Integer;
+begin
+ Result := 0;
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_checkstack(L, 1);
+
+ SetLength(R, Length(Party.Teams));
+
+ for I := 0 to High(R) do
+ begin
+ lua_pushInteger(L, I);
+ lua_gettable(L, 1);
+
+ R[I].Rank := Length(R);
+ if (lua_isnumber(L, -1)) then
+ begin
+ Rank := lua_toInteger(L, -1);
+ if (Rank >= 1) and (Rank <= Length(R)) then
+ R[I].Rank := Rank;
+ end;
+
+ lua_pop(L, 1);
+ end;
+
+ // pop table
+ lua_pop(L, 1);
+
+ if (not Party.SetRanking(R)) then
+ luaL_error(L, PChar('cann''t set party round ranking. Is party started and not finished yet?'));
+end;
+
+{ Party.GetTeams - returns a table with all information and structure as
+ in the TPartyGame.Teams array }
+function ULuaParty_GetTeams(L: Plua_State): Integer; cdecl;
+ var
+ Team: Integer;
+ Player: Integer;
+begin
+ // clear stack
+ lua_pop(L, lua_gettop(L));
+
+ // ensure we have enough stack slots left
+ lua_checkstack(L, 7);
+
+ // create the table we want to return
+ lua_createtable(L, Length(Party.Teams), 0);
+
+ // add the teams
+ for Team := 0 to High(Party.Teams) do
+ begin
+ // push key for current teams value. lua array beggins at 1
+ lua_pushInteger(L, Team + 1);
+
+ // push table containing team info and players table
+ lua_createtable(L, 0, 5);
+
+ // team name
+ lua_pushString(L, PChar(Party.Teams[Team].Name));
+ lua_setField(L, -2, 'Name');
+
+ // team score
+ lua_pushInteger(L, Party.Teams[Team].Score);
+ lua_setField(L, -2, 'Score');
+
+ // team jokers left
+ lua_pushInteger(L, Party.Teams[Team].JokersLeft);
+ lua_setField(L, -2, 'JokersLeft');
+
+ // team nextPlayer
+ lua_pushInteger(L, Party.Teams[Team].NextPlayer);
+ lua_setField(L, -2, 'NextPlayer');
+
+ // team players table
+ lua_createtable(L, Length(Party.Teams[Team].Players), 0);
+
+ //add players
+ for Player := 0 to High(Party.Teams[Team].Players) do
+ begin
+ // push key for current players value. lua array beggins at 1
+ lua_pushInteger(L, Player + 1);
+
+ // push table containing player info
+ lua_createTable(L, 0, 2);
+
+ // player name
+ lua_PushString(L, PChar(Party.Teams[Team].Players[Player].Name));
+ lua_SetField(L, -2, 'Name');
+
+ // players times played
+ lua_PushInteger(L, Party.Teams[Team].Players[Player].TimesPlayed);
+ lua_SetField(L, -2, 'TimesPlayed');
+
+ // add value - key - pair to teams player table
+ lua_setTable(L, -3);
+ end;
+
+ lua_setField(L, -2, 'Players');
+
+ // add value - key - pair to returned table
+ lua_setTable(L, -3);
+ end;
+
+ // we return 1 value (the first table)
+ Result := 1;
+end;
+
+{ Party.SetTeams - changes all fields from TPartyGame.Teams that have been
+ set in the table given as first argument}
+function ULuaParty_SetTeams(L: Plua_State): Integer; cdecl;
+
+ procedure Do_Player(Team, Player: Integer);
+ var
+ Key: String;
+ begin
+ if (Player >= 0) and (Player <= High(Party.Teams[Team].Players)) then
+ begin
+ // go through table elements
+ lua_pushNil(L);
+ while (lua_Next(L, -2) <> 0) do
+ begin
+ Key := lowercase(lua_ToString(L, -2));
+
+ if (Key = 'name') and lua_isString(L, -1) then
+ Party.Teams[Team].Players[Player].Name := lua_toString(L, -1)
+ else if (Key = 'timesplayed') and lua_isNumber(L, -1) then
+ Party.Teams[Team].Players[Player].TimesPlayed := lua_toInteger(L, -1);
+
+ // pop value from stack so key is on top
+ lua_pop(L, 1);
+ end;
+ end;
+ end;
+
+ procedure Do_Players(Team: Integer);
+ begin
+ // go through table elements
+ lua_pushNil(L);
+ while (lua_Next(L, -2) <> 0) do
+ begin
+ // check if key is a number and value is a table
+ if (lua_isNumber(L, -2)) and (lua_isTable(L, -1)) then
+ Do_Player(Team, lua_toInteger(L, -2));
+
+ // pop value from stack so key is on top
+ lua_pop(L, 1);
+ end;
+ end;
+
+ procedure Do_Team(Team: Integer);
+ var
+ Key: String;
+ begin
+ if (Team >= 0) and (Team <= High(Party.Teams)) then
+ begin
+ // go through table elements
+ lua_pushNil(L);
+ while (lua_Next(L, -2) <> 0) do
+ begin
+ Key := lowercase(lua_ToString(L, -2));
+
+ if (Key = 'name') and lua_isString(L, -1) then
+ Party.Teams[Team].Name := lua_toString(L, -1)
+ else if (Key = 'score') and lua_isNumber(L, -1) then
+ Party.Teams[Team].Score := lua_toInteger(L, -1)
+ else if (Key = 'jokersleft') and lua_isNumber(L, -1) then
+ Party.Teams[Team].JokersLeft := lua_toInteger(L, -1)
+ else if (Key = 'currentplayer') and lua_isNumber(L, -1) then
+ Party.Teams[Team].NextPlayer := lua_toInteger(L, -1)
+ else if (Key = 'players') and lua_isTable(L, -1) then
+ Do_Players(Team);
+
+ // pop value from stack so key is on top
+ lua_pop(L, 1);
+ end;
+ end;
+ end;
+begin
+ Result := 0;
+
+ // check for table on stack
+ luaL_checkType(L, 1, LUA_TTABLE);
+
+
+ // go through table elements
+ lua_pushNil(L);
+ while (lua_Next(L, 1) <> 0) do
+ begin
+ // check if key is a number and value is a table
+ if (lua_isNumber(L, -2)) and (lua_isTable(L, -1)) then
+ Do_Team(lua_toInteger(L, -2));
+
+ // pop value from stack so key is on top
+ lua_pop(L, 1);
+ end;
+
+ // clear stack from table
+ lua_pop(L, lua_gettop(L));
+end;
+
+end. \ No newline at end of file
diff --git a/src/lua/ULuaScreenSing.pas b/src/lua/ULuaScreenSing.pas
new file mode 100644
index 00000000..7e17224c
--- /dev/null
+++ b/src/lua/ULuaScreenSing.pas
@@ -0,0 +1,489 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://ultrastardx.svn.sourceforge.net/svnroot/ultrastardx/branches/experimental/Lua/src/lua/ULuaTexture.pas $
+ * $Id: ULuaTexture.pas 1551 2009-01-04 14:08:33Z Hawkear $
+ *}
+
+unit ULuaScreenSing;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ ULua;
+
+{ returns a table with following structure:
+ t[1..playercount] = score of player i }
+function ULuaScreenSing_GetScores(L: Plua_State): Integer; cdecl;
+
+{ returns a table with following structure:
+ t[1..playercount] = rating of player i range: [0..1] }
+function ULuaScreenSing_GetRating(L: Plua_State): Integer; cdecl;
+
+{ returns a table with following structure:
+ t[1..playercount] = rect of players score background: table(x, y, w, h) }
+function ULuaScreenSing_GetScoreBGRect(L: Plua_State): Integer; cdecl;
+
+{ returns a table with following structure:
+ t[1..playercount] = rect of players rating bar: table(x, y, w, h) }
+function ULuaScreenSing_GetRBRect(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.GetBPM - no arguments
+ returns the beats per minutes of the current song in quarts }
+function ULuaScreenSing_GetBPM(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.BeatsToSeconds(Beats: float)
+ returns the time in seconds that the given number of beats (in quarts) last }
+function ULuaScreenSing_BeatsToSeconds(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.SecondsToBeats(Seconds: float)
+ returns the Beats in quarts that the given seconds last }
+function ULuaScreenSing_SecondsToBeats(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.GetBeat() - returns current beat of lyricstate (in quarts) }
+function ULuaScreenSing_GetBeat(L: Plua_State): Integer; cdecl;
+
+{ finishes current song, if sing screen is not shown it will raise
+ an error }
+function ULuaScreenSing_Finish(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.GetSettings - no arguments
+ returns a table filled with the data of TScreenSing.Settings }
+function ULuaScreenSing_GetSettings(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.SetSettings - arguments: Table
+ sets all attributes of TScreenSing.Settings that are
+ unequal to nil in Table }
+function ULuaScreenSing_SetSettings(L: Plua_State): Integer; cdecl;
+
+{ ScreenSing.GetSongLines - no arguments
+ returns a table filled with lines of the loaded song or
+ nil if no song is loaded (singscreen is not displayed)
+ structure of returned table:
+ array [1.."count of lines"]
+ \
+ | Start: integer - beat the line is displayed at (on top of lyrics display)
+ | Lyric: string - full lyric of the line
+ | Notes: array [1.."count notes of this line"]
+ \
+ | Start: integer - beat the note starts at
+ | Length: integer - length in beats
+ | Tone: integer - pitch that has to be sung, full range
+ | NoteType: integer - 0 for freestyle, 1 for normal, 2 for golden
+ | Text: string - text of this fragment }
+function ULuaScreenSing_GetSongLines(L: Plua_State): Integer; cdecl;
+
+const
+ ULuaScreenSing_Lib_f: array [0..11] of lual_reg = (
+ (name:'GetScores';func:ULuaScreenSing_GetScores),
+ (name:'GetRating';func:ULuaScreenSing_GetRating),
+ (name:'GetBPM';func:ULuaScreenSing_GetBPM),
+ (name:'BeatsToSeconds';func:ULuaScreenSing_BeatsToSeconds),
+ (name:'SecondsToBeats';func:ULuaScreenSing_SecondsToBeats),
+ (name:'GetBeat';func:ULuaScreenSing_GetBeat),
+ (name:'GetScoreBGRect';func:ULuaScreenSing_GetScoreBGRect),
+ (name:'GetRBRect';func:ULuaScreenSing_GetRBRect),
+ (name:'Finish';func:ULuaScreenSing_Finish),
+ (name:'GetSettings';func:ULuaScreenSing_GetSettings),
+ (name:'SetSettings';func:ULuaScreenSing_SetSettings),
+ (name:'GetSongLines';func:ULuaScreenSing_GetSongLines)
+ );
+
+implementation
+uses UScreenSing, UNote, UDisplay, UGraphic, UMusic, ULuaUtils, SysUtils;
+
+{ returns a table with following structure:
+ t[1..playercount] = score of player i }
+function ULuaScreenSing_GetScores(L: Plua_State): Integer; cdecl;
+ var
+ Top: Integer;
+ I: Integer;
+begin
+ Result := 1;
+
+ // pop arguments
+ Top := lua_getTop(L);
+ if (Top > 0) then
+ lua_pop(L, Top);
+
+ // create table
+ lua_createtable(L, Length(Player), 0);
+
+ // fill w/ values
+ for I := 0 to High(Player) do
+ begin
+ lua_pushInteger(L, I + 1);
+ lua_pushInteger(L, Player[I].ScoreTotalInt);
+
+ lua_settable(L, -3);
+ end;
+
+ // leave table on stack, it is our result
+end;
+
+{ returns a table with following structure:
+ t[1..playercount] = rating of player i range: [0..1] }
+function ULuaScreenSing_GetRating(L: Plua_State): Integer; cdecl;
+ var
+ Top: Integer;
+ I: Integer;
+begin
+ Result := 1;
+
+ // pop arguments
+ Top := lua_getTop(L);
+ if (Top > 0) then
+ lua_pop(L, Top);
+
+ // create table
+ lua_createtable(L, Length(Player), 0);
+
+ // fill w/ values
+ for I := 0 to High(ScreenSing.Scores.Players) do
+ begin
+ lua_pushInteger(L, I + 1);
+ lua_pushNumber(L, ScreenSing.Scores.Players[I].RBPos);
+
+ lua_settable(L, -3);
+ end;
+
+ // leave table on stack, it is our result
+end;
+
+{ ScreenSing.GetBPM - no arguments
+ returns the beats per minutes of the current song in quarts }
+function ULuaScreenSing_GetBPM(L: Plua_State): Integer; cdecl;
+begin
+ lua_ClearStack(L);
+ Result := 1;
+
+ if (CurrentSong = nil) or (Length(CurrentSong.BPM) = 0) or (Display.CurrentScreen <> @ScreenSing) then
+ lua_PushNumber(L, 0) // in case of error
+ else if (Length(CurrentSong.BPM) = 1) then
+ lua_PushNumber(L, CurrentSong.BPM[0].BPM)
+ else
+ begin
+ // to-do: do this for songs w/ BPM changes
+ // or drop support for BPM changes?!
+ end;
+end;
+
+{ ScreenSing.BeatsToSeconds(Beats: float)
+ returns the time in seconds that the given number of beats (in quarts) last }
+function ULuaScreenSing_BeatsToSeconds(L: Plua_State): Integer; cdecl;
+begin
+ Result := 1;
+
+ if (CurrentSong = nil) or (Length(CurrentSong.BPM) = 0) or (Display.CurrentScreen <> @ScreenSing) then
+ lua_PushNumber(L, 0) // in case of error
+ else if (Length(CurrentSong.BPM) = 1) then
+ lua_PushNumber(L, luaL_CheckNumber(L, 1) * 60 / CurrentSong.BPM[0].BPM)
+ else
+ begin
+ // to-do: do this for songs w/ BPM changes
+ // or drop support for BPM changes?!
+ end;
+end;
+
+{ ScreenSing.BeatsToSeconds(Seconds: float)
+ returns the Beats in quarts that the given seconds last }
+function ULuaScreenSing_SecondsToBeats(L: Plua_State): Integer; cdecl;
+begin
+ Result := 1;
+
+ if (CurrentSong = nil) or (Length(CurrentSong.BPM) = 0) or (Display.CurrentScreen <> @ScreenSing) then
+ lua_PushNumber(L, 0)
+ else if (Length(CurrentSong.BPM) = 1) then
+ lua_PushNumber(L, luaL_CheckNumber(L, 1) * CurrentSong.BPM[0].BPM / 60)
+ else
+ begin
+ // to-do: do this for songs w/ BPM changes
+ // or drop support for BPM changes?!
+ end;
+end;
+
+{ ScreenSing.GetBeat() - returns current beat of lyricstate (in quarts) }
+function ULuaScreenSing_GetBeat(L: Plua_State): Integer; cdecl;
+var top: Integer;
+begin
+ //remove arguments (if any)
+ top := lua_gettop(L);
+
+ if (top > 0) then
+ lua_pop(L, top);
+
+ //push result
+ lua_pushnumber(L, LyricsState.MidBeat);
+ Result := 1; //one result
+end;
+
+{ returns a table with following structure:
+ t[1..playercount] = rect of players ScoreBG: table(x, y, w, h) }
+function ULuaScreenSing_GetScoreBGRect(L: Plua_State): Integer; cdecl;
+ var
+ Top: Integer;
+ I: Integer;
+begin
+ Result := 1;
+
+ // pop arguments
+ Top := lua_getTop(L);
+ if (Top > 0) then
+ lua_pop(L, Top);
+
+ // create table
+ lua_createtable(L, Length(ScreenSing.Scores.Players), 0);
+
+ // fill w/ values
+ for I := 0 to High(ScreenSing.Scores.Players) do
+ begin
+ lua_pushInteger(L, I + 1);
+
+ if (ScreenSing.Scores.Players[I].Position = High(Byte)) then
+ // player has no position, prevent crash by pushing nil
+ lua_pushNil(L)
+ else
+ with ScreenSing.Scores.Positions[ScreenSing.Scores.Players[I].Position] do
+ lua_PushRect(L, BGX, BGY, BGW, BGH);
+
+
+ lua_settable(L, -3);
+ end;
+
+ // leave table on stack, it is our result
+end;
+
+{ returns a table with following structure:
+ t[1..playercount] = rect of players rating bar: table(x, y, w, h) }
+function ULuaScreenSing_GetRBRect(L: Plua_State): Integer; cdecl;
+ var
+ Top: Integer;
+ I: Integer;
+begin
+ Result := 1;
+
+ // pop arguments
+ Top := lua_getTop(L);
+ if (Top > 0) then
+ lua_pop(L, Top);
+
+ // create table
+ lua_createtable(L, Length(ScreenSing.Scores.Players), 0);
+
+ // fill w/ values
+ for I := 0 to High(ScreenSing.Scores.Players) do
+ begin
+ lua_pushInteger(L, I + 1);
+
+ if (ScreenSing.Scores.Players[I].Position = High(Byte)) then
+ // player has no position, prevent crash by pushing nil
+ lua_pushNil(L)
+ else
+ with ScreenSing.Scores.Positions[ScreenSing.Scores.Players[I].Position] do
+ lua_PushRect(L, RBX, RBY, RBW, RBH);
+
+
+ lua_settable(L, -3);
+ end;
+
+ // leave table on stack, it is our result
+end;
+
+{ finishes current song, if sing screen is not shown it will raise
+ an error }
+function ULuaScreenSing_Finish(L: Plua_State): Integer; cdecl;
+ var Top: Integer;
+begin
+ Result := 0;
+
+ // pop arguments
+ Top := lua_getTop(L);
+ if (Top > 0) then
+ lua_pop(L, Top);
+
+ if (Display.CurrentScreen^ = ScreenSing) then
+ begin
+ ScreenSing.EndSong;
+ end
+ else
+ LuaL_error(L, 'Usdx.ScreenSing.Finish is called, but sing screen is not shown.');
+end;
+
+{ ScreenSing.GetSettings - no arguments
+ returns a table filled with the data of TScreenSing }
+function ULuaScreenSing_GetSettings(L: Plua_State): Integer; cdecl;
+ var Top: Integer;
+begin
+ // pop arguments
+ Top := lua_getTop(L);
+ if (Top > 0) then
+ lua_pop(L, Top);
+
+ lua_createtable(L, 0, 3);
+
+ //fill table w/ info
+ lua_pushBoolean(L, ScreenSing.Settings.LyricsVisible);
+ lua_setField(L, -2, 'LyricsVisible');
+
+ lua_pushBinInt(L, ScreenSing.Settings.NotesVisible);
+ lua_setField(L, -2, 'NotesVisible');
+
+ lua_pushBinInt(L, ScreenSing.Settings.PlayerEnabled);
+ lua_setField(L, -2, 'PlayerEnabled');
+
+
+ Result := 1;
+end;
+
+{ ScreenSing.SetSettings - arguments: Table
+ sets all attributes of TScreenSing.Settings that are
+ unequal to nil in Table }
+function ULuaScreenSing_SetSettings(L: Plua_State): Integer; cdecl;
+ var
+ Key: String;
+begin
+ Result := 0;
+
+ // check for table on stack
+ luaL_checkType(L, 1, LUA_TTABLE);
+
+ // go through table elements
+ lua_pushNil(L);
+ while (lua_Next(L, 1) <> 0) do
+ begin
+ Key := lowercase(lua_ToString(L, -2));
+
+ if (Key = 'lyricsvisible') and (lua_isBoolean(L, -1)) then
+ ScreenSing.settings.LyricsVisible := lua_toBoolean(L, -1)
+ else if (Key = 'notesvisible') and (lua_isTable(L, -1)) then
+ ScreenSing.settings.NotesVisible := lua_toBinInt(L, -1)
+ else if (Key = 'playerenabled') and (lua_isTable(L, -1)) then
+ ScreenSing.settings.PlayerEnabled := lua_toBinInt(L, -1);
+
+ // pop value from stack so key is on top
+ lua_pop(L, 1);
+ end;
+
+ // clear stack from table
+ lua_pop(L, lua_gettop(L));
+
+ ScreenSing.ApplySettings;
+end;
+
+{ ScreenSing.GetSongLines - no arguments
+ returns a table filled with lines of the loaded song or
+ nil if no song is loaded (singscreen is not displayed)
+ structure of returned table:
+ array [1.."count of lines"]
+ \
+ | Start: integer - beat the line is displayed at (on top of lyrics display)
+ | Lyric: string - full lyric of the line
+ | Notes: array [1.."count notes of this line"]
+ \
+ | Start: integer - beat the note starts at
+ | Length: integer - length in beats
+ | Tone: integer - pitch that has to be sung, full range
+ | NoteType: integer - 0 for freestyle, 1 for normal, 2 for golden
+ | Text: string - text of this fragment }
+function ULuaScreenSing_GetSongLines(L: Plua_State): Integer; cdecl;
+ var
+ I, J: Integer;
+begin
+ Result := 1;
+ if (Length(Lines) >= 1) then
+ begin
+ lua_ClearStack(L);
+
+ if not lua_CheckStack(L, 7) then
+ luaL_Error(L, PChar('can''t allocate enough stack space in ULuaScreenSing_GetSongLines'));
+
+ // lines array table
+ lua_CreateTable(L, Length(Lines[0].Line), 0);
+
+ for I := 0 to High(Lines[0].Line) do
+ with Lines[0].Line[I] do
+ begin
+ lua_pushInteger(L, I+1);
+
+ // line struct table
+ lua_CreateTable(L, 0, 3);
+
+ // line start
+ lua_PushInteger(L, Start);
+ lua_SetField(L, -2, PChar('Start'));
+
+ // line lyric
+ lua_PushString(L, PChar(Lyric));
+ lua_SetField(L, -2, PChar('Lyric'));
+
+ //line notes array table
+ lua_CreateTable(L, Length(Note), 0);
+
+ for J := 0 to High(Note) do
+ begin
+ lua_PushInteger(L, J + 1);
+
+ // note struct table
+ lua_CreateTable(L, 0, 5);
+
+ // Notes[J+1].Start
+ lua_PushInteger(L, Note[J].Start);
+ lua_SetField(L, -2, PChar('Start'));
+
+ // Notes[J+1].Length
+ lua_PushInteger(L, Note[J].Length);
+ lua_SetField(L, -2, PChar('Length'));
+
+ // Notes[J+1].Tone
+ lua_PushInteger(L, Note[J].Tone);
+ lua_SetField(L, -2, PChar('Tone'));
+
+ // Notes[J+1].NoteType
+ lua_PushInteger(L, Integer(Note[J].NoteType));
+ lua_SetField(L, -2, PChar('NoteType'));
+
+ // Notes[J+1].Text
+ lua_PushString(L, PChar(Note[J].Text));
+ lua_SetField(L, -2, PChar('Text'));
+
+ lua_SetTable(L, -3);
+ end;
+
+ lua_SetField(L, -2, PChar('Notes'));
+
+ // save line to array table
+ lua_setTable(L, -3);
+ end;
+ end
+ else
+ begin
+ lua_ClearStack(L);
+ lua_pushNil(L);
+ end;
+end;
+
+end. \ No newline at end of file
diff --git a/src/lua/ULuaTextGL.pas b/src/lua/ULuaTextGL.pas
new file mode 100644
index 00000000..1db41b21
--- /dev/null
+++ b/src/lua/ULuaTextGL.pas
@@ -0,0 +1,147 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit ULuaTextGL;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ TextGL,
+ ULua;
+
+{ TextGl.Pos(X, Y: Float) : sets font position }
+function ULuaTextGL_Pos(L: Plua_State): Integer; cdecl;
+
+{ TextGl.Size(Size: Float) : sets font size }
+function ULuaTextGL_Size(L: Plua_State): Integer; cdecl;
+
+{ TextGl.Style(Style: int) : sets font style (from 0 to 3) }
+function ULuaTextGL_Style(L: Plua_State): Integer; cdecl;
+
+{ TextGl.Italic(isItalic: boolean) : sets if font is italic }
+function ULuaTextGL_Italic(L: Plua_State): Integer; cdecl;
+
+{ TextGl.Width(Text: String) : returns width of Text if printed
+ w/ current settings in pixels }
+function ULuaTextGL_Width(L: Plua_State): Integer; cdecl;
+
+{ TextGl.Print(Text: String) : prints text to screen w/ current
+ settings}
+function ULuaTextGL_Print(L: Plua_State): Integer; cdecl;
+
+const
+ ULuaTextGl_Lib_f: array [0..5] of lual_reg = (
+ (name:'Pos'; func:ULuaTextGl_Pos),
+ (name:'Size'; func:ULuaTextGl_Size),
+ (name:'Style'; func:ULuaTextGl_Style),
+ (name:'Italic'; func:ULuaTextGl_Italic),
+ (name:'Width'; func:ULuaTextGl_Width),
+ (name:'Print'; func:ULuaTextGl_Print)
+ );
+
+
+implementation
+
+{ TextGl.Pos(X, Y: Float) : sets font position }
+function ULuaTextGL_Pos(L: Plua_State): Integer; cdecl;
+ var X, Y: Double;
+begin
+ X := luaL_checknumber(L, 1);
+ Y := luaL_checknumber(L, 2);
+
+ SetFontPos(X, Y);
+
+ Result := 0;
+end;
+
+{ TextGl.Size(Size: Float) : sets font size }
+function ULuaTextGL_Size(L: Plua_State): Integer; cdecl;
+ var Size: Double;
+begin
+ Size := luaL_checknumber(L, 1);
+
+ SetFontSize(Size);
+
+ Result := 0;
+end;
+
+{ TextGl.Style(Style: int) : sets font style (from 0 to 3) }
+function ULuaTextGL_Style(L: Plua_State): Integer; cdecl;
+ var Style: Integer;
+begin
+ Style := luaL_checkinteger(L, 1);
+
+ if (Style >= 0) and (Style <= 3) then
+ SetFontStyle(Style)
+ else
+ luaL_ArgError(L, 1, PChar('number from 0 to 3 expected'));
+
+ Result := 0;
+end;
+
+{ TextGl.Italic(isItalic: boolean) : sets if font is italic }
+function ULuaTextGL_Italic(L: Plua_State): Integer; cdecl;
+ var isItalic: Boolean;
+begin
+ luaL_checkany(L, 1);
+ isItalic := lua_toBoolean(L, 1);
+
+ SetFontItalic(isItalic);
+
+ Result := 0;
+end;
+
+{ TextGl.Width(Text: String) : returns width of Text if printed
+ w/ current settings in pixels }
+function ULuaTextGL_Width(L: Plua_State): Integer; cdecl;
+ var Text: String;
+begin
+ Text := luaL_checkstring(L, 1);
+ lua_pop(L, lua_gettop(L));
+
+ lua_PushNumber(L, glTextWidth(Text));
+
+ Result := 1;
+end;
+
+{ TextGl.Print(Text: String) : prints text to screen w/ current
+ settings}
+function ULuaTextGL_Print(L: Plua_State): Integer; cdecl;
+ var Text: String;
+begin
+ Text := luaL_checkstring(L, 1);
+
+ glPrint(Text);
+
+ Result := 0;
+end;
+
+end.
diff --git a/src/lua/ULuaTexture.pas b/src/lua/ULuaTexture.pas
new file mode 100644
index 00000000..931c0405
--- /dev/null
+++ b/src/lua/ULuaTexture.pas
@@ -0,0 +1,63 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit ULuaTexture;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ ULua,
+ UTexture;
+
+function luaopen_Texture (L: Plua_State): Integer; cdecl;
+
+function ULuaTexture_Dummy(L: Plua_State): Integer; cdecl;
+
+implementation
+
+function ULuaTexture_Dummy(L: Plua_State): Integer; cdecl;
+begin
+ result:=0; // number of results
+end;
+
+const
+ ULuaTexture_Lib_f: array [0..1] of lual_reg = (
+ (name:'Add';func:ULuaTexture_Dummy),
+ (name:nil;func:nil)
+ );
+
+function luaopen_Texture (L: Plua_State): Integer; cdecl;
+begin
+ luaL_register(L,'Texture',@ULuaTexture_Lib_f[0]);
+ result:=1;
+end;
+end.
diff --git a/src/lua/ULuaUsdx.pas b/src/lua/ULuaUsdx.pas
new file mode 100644
index 00000000..d92289b1
--- /dev/null
+++ b/src/lua/ULuaUsdx.pas
@@ -0,0 +1,145 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit ULuaUsdx;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses ULua;
+
+{ some basic lua c functions from usdx table }
+
+{ Usdx.Time - returns sdl_time to have time numbers comparable with
+ ultrastar deluxe ones. no arguments }
+function ULuaUsdx_Time(L: Plua_State): Integer; cdecl;
+
+{ Usdx.Version - returns Usdx version string (the same that US_Version
+ language-constant does). no arguments }
+function ULuaUsdx_Version(L: Plua_State): Integer; cdecl;
+
+{ Usdx.Hook - returns an hook table with name and Unhook function
+ arguments: event_name: string }
+function ULuaUsdx_Hook(L: Plua_State): Integer; cdecl;
+
+{ Usdx.ShutMeDown - no results, no arguments
+ unloads the calling plugin }
+function ULuaUsdx_ShutMeDown(L: Plua_State): Integer; cdecl;
+
+const
+ ULuaUsdx_Lib_f: array [0..4] of lual_reg = (
+ (name:'Version'; func:ULuaUsdx_Version),
+ (name:'Time'; func:ULuaUsdx_Time),
+ (name:'Hook'; func:ULuaUsdx_Hook),
+ (name:'ShutMeDown'; func:ULuaUsdx_ShutMeDown),
+ (name:nil;func:nil)
+ );
+
+implementation
+uses SDL, ULuaCore, ULuaUtils, UHookableEvent, UConfig;
+
+{ Usdx.Time - returns sdl_time to have time numbers comparable with
+ ultrastar deluxe ones. no arguments }
+function ULuaUsdx_Time(L: Plua_State): Integer; cdecl;
+ var top: Integer;
+begin
+ //remove arguments (if any)
+ top := lua_gettop(L);
+
+ if (top > 0) then
+ lua_pop(L, top);
+
+ //push result
+ lua_pushinteger(L, SDL_GetTicks);
+ Result := 1; //one result
+end;
+
+{ Usdx.Version - returns Usdx version string (the same that US_Version
+ language-constant does). no arguments }
+function ULuaUsdx_Version(L: Plua_State): Integer; cdecl;
+ var top: Integer;
+begin
+ //remove arguments (if any)
+ top := lua_gettop(L);
+
+ if (top > 0) then
+ lua_pop(L, top);
+
+ //push result
+ lua_pushstring(L, PChar(USDXVersionStr()));
+ Result := 1; //one result
+end;
+
+{ Usdx.Hook - returns an hook table with name and Unhook function
+ arguments: event_name: string; function_name: string }
+function ULuaUsdx_Hook(L: Plua_State): Integer; cdecl;
+var
+ EventName: String;
+ FunctionName: String;
+ P: TLuaPlugin;
+ Event: THookableEvent;
+begin
+ EventName := luaL_checkstring(L, 1);
+ FunctionName := luaL_checkstring(L, 2);
+
+ P := Lua_GetOwner(L);
+
+ lua_pop(L, lua_gettop(L)); //clear stack
+
+ Result := 1;
+
+ Event := LuaCore.GetEventByName(EventName);
+ if (Event <> nil) then
+ begin
+ Event.Hook(L, P.Id, FunctionName);
+ end
+ else
+ luaL_error(L, PChar('event does not exist: ' + EventName));
+end;
+
+function ULuaUsdx_ShutMeDown(L: Plua_State): Integer; cdecl;
+ var
+ top: Integer;
+ P: TLuaPlugin;
+begin
+ Result := 0;
+
+ //remove arguments (if any)
+ top := lua_gettop(L);
+
+ if (top > 0) then
+ lua_pop(L, top);
+
+ P := Lua_GetOwner(L);
+
+ P.ShutMeDown;
+end;
+
+end. \ No newline at end of file
diff --git a/src/lua/ULuaUtils.pas b/src/lua/ULuaUtils.pas
new file mode 100644
index 00000000..143b34d4
--- /dev/null
+++ b/src/lua/ULuaUtils.pas
@@ -0,0 +1,186 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit ULuaUtils;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses ULua, ULuaCore;
+
+{ converts a lua table with a structure like:
+ * = 1 , * = 4 , * = 5
+ to an integer with the value:
+ 0b11001
+ does not pop anything }
+function Lua_ToBinInt(L: PLua_State; idx: Integer): Integer;
+
+{ converts an integer with the value:
+ 0b11001
+ to a lua table with a structure like:
+ * = 1 , * = 4 , * = 5
+ and pushed the table onto the stack }
+procedure Lua_PushBinInt(L: PLua_State; BinInt: Integer);
+
+{ pushes a table with position and size of a rectangle
+ t.x => position of the rectangle in pixels at x-axis
+ t.y => position of the rectangle in pixels at y-axis
+ t.w => width of the rectangle
+ t.h => height of the rectangle }
+procedure Lua_PushRect(L: PLua_State; X, Y, W, H: Double);
+
+{ returns plugin that is the owner of the given state
+ may raise a lua error if the parent id is not found
+ in states registry, if state owner does not exists
+ or is not loaded. So a check for a nil value is not
+ necessary }
+function Lua_GetOwner(L: PLua_State): TLuaPlugin;
+
+{ this is a helper in case an evenet owner don't has no use for the results
+ returns number of popped elements }
+function Lua_ClearStack(L: Plua_State): Integer;
+
+
+implementation
+
+{ converts a lua table with a structure like:
+ * = 1 , * = 4 , * = 5
+ to an integer with the value:
+ 0b11001
+ does not pop anything }
+function Lua_ToBinInt(L: PLua_State; idx: Integer): Integer;
+ var
+ I: Integer;
+begin
+ // default: no bits set
+ Result := 0;
+
+ lua_checkstack(L, 2);
+
+ if (idx < 0) then
+ dec(idx); // we will push one value before using this
+
+ lua_PushNil(L);
+ while (lua_next(L, idx) <> 0) do
+ begin
+ if (lua_isNumber(L, -1)) then
+ begin //check if we got an integer value from 1 to 32
+ I := lua_toInteger(L, -1);
+ if (I >= 1) and (I <= 32) then
+ Result := Result or 1 shl (I - 1);
+ end;
+
+ // pop value, so key is on top
+ lua_pop(L, 1);
+ end;
+end;
+
+{ converts an integer with the value:
+ 0b11001
+ to a lua table with a structure like:
+ * = 1 , * = 4 , * = 5
+ and pushed the table onto the stack }
+procedure Lua_PushBinInt(L: PLua_State; BinInt: Integer);
+var
+ I, Index: Integer;
+begin
+ lua_newTable(L);
+
+
+ Index := 1; //< lua starts w/ index 1
+ for I := 0 to 31 do
+ if (BinInt and (1 shl I) <> 0) then
+ begin
+ lua_pushInteger(L, Index);
+ lua_pushInteger(L, I);
+ lua_settable(L, -3);
+
+ Inc(Index);
+ end;
+end;
+
+{ pushes a table with position and size of a rectangle
+ t.x => position of the rectangle in pixels at x-axis
+ t.y => position of the rectangle in pixels at y-axis
+ t.w => width of the rectangle
+ t.h => height of the rectangle }
+procedure Lua_PushRect(L: PLua_State; X, Y, W, H: Double);
+begin
+ lua_createtable(L, 0, 4); // table w/ 4 record fields
+
+ // x pos
+ lua_pushNumber(L, X);
+ lua_setField(L, -2, 'x');
+
+ // y pos
+ lua_pushNumber(L, Y);
+ lua_setField(L, -2, 'y');
+
+ // width
+ lua_pushNumber(L, W);
+ lua_setField(L, -2, 'w');
+
+ // height
+ lua_pushNumber(L, H);
+ lua_setField(L, -2, 'h');
+end;
+
+{ returns plugin that is the owner of the given state
+ may raise a lua error if the parent id is not found
+ in states registry, if state owner does not exists
+ or is not loaded. So a check for a nil value is not
+ necessary }
+function Lua_GetOwner(L: PLua_State): TLuaPlugin;
+begin
+ lua_checkstack(L, 1);
+
+ lua_getfield (L, LUA_REGISTRYINDEX, '_USDX_STATE_ID');
+ if (not lua_isNumber(L, -1)) then
+ luaL_error(L, 'unable to get _USDX_STATE_ID');
+
+ Result := LuaCore.GetPluginById(lua_toInteger(L, -1));
+
+ lua_pop(L, 1); //< remove state id from stack
+
+ if (Result = nil) then
+ luaL_error(L, '_USDX_STATE_ID has invalid value')
+ else if (Result.Status > psRunning) then
+ luaL_error(L, 'owning plugin is not loaded or already unloaded in Lua_GetOwner');
+end;
+
+{ this is a helper in case an evenet owner don't has no use for the results
+ returns number of popped elements }
+function Lua_ClearStack(L: Plua_State): Integer;
+begin
+ Result := lua_gettop(L);
+ lua_pop(L, Result);
+end;
+
+end. \ No newline at end of file