From 5000060b04bed23cbbd88ba43ed546220c4b7c69 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Tue, 2 Nov 2010 12:51:22 +0000 Subject: create experimental songmanagement branch - nicer abstraction of songs - split songloading from handling songs - cleanup singscreen git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2706 b956fd51-792f-4845-bead-9b4dfca2ff2c --- songmanagement/src/lua/UHookableEvent.pas | 380 ++++++++ songmanagement/src/lua/ULuaCore.pas | 1021 +++++++++++++++++++ songmanagement/src/lua/ULuaGl.pas | 1513 +++++++++++++++++++++++++++++ songmanagement/src/lua/ULuaLog.pas | 167 ++++ songmanagement/src/lua/ULuaParty.pas | 391 ++++++++ songmanagement/src/lua/ULuaScreenSing.pas | 489 ++++++++++ songmanagement/src/lua/ULuaTextGL.pas | 148 +++ songmanagement/src/lua/ULuaTexture.pas | 63 ++ songmanagement/src/lua/ULuaUsdx.pas | 145 +++ songmanagement/src/lua/ULuaUtils.pas | 186 ++++ 10 files changed, 4503 insertions(+) create mode 100644 songmanagement/src/lua/UHookableEvent.pas create mode 100644 songmanagement/src/lua/ULuaCore.pas create mode 100644 songmanagement/src/lua/ULuaGl.pas create mode 100644 songmanagement/src/lua/ULuaLog.pas create mode 100644 songmanagement/src/lua/ULuaParty.pas create mode 100644 songmanagement/src/lua/ULuaScreenSing.pas create mode 100644 songmanagement/src/lua/ULuaTextGL.pas create mode 100644 songmanagement/src/lua/ULuaTexture.pas create mode 100644 songmanagement/src/lua/ULuaUsdx.pas create mode 100644 songmanagement/src/lua/ULuaUtils.pas (limited to 'songmanagement/src/lua') diff --git a/songmanagement/src/lua/UHookableEvent.pas b/songmanagement/src/lua/UHookableEvent.pas new file mode 100644 index 00000000..8ad7ea9c --- /dev/null +++ b/songmanagement/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/songmanagement/src/lua/ULuaCore.pas b/songmanagement/src/lua/ULuaCore.pas new file mode 100644 index 00000000..ea9fd991 --- /dev/null +++ b/songmanagement/src/lua/ULuaCore.pas @@ -0,0 +1,1021 @@ +{* 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 any 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.LogStatus(Format('%3s %-30s %-8s %-10s %-7s %-6s', [ + '#', 'Name', 'Version', 'Status', 'Paused', '#Errors' + ]), 'LuaCore Plugins'); + + for I := 0 to High(Plugins) do + Log.LogStatus(Format('%3d %-30s %-8s %-10s %-7s %-6d', [ + Plugins[I].Id, Plugins[I].Name, Plugins[I].Version, + PluginStatusToString(Plugins[I].Status), + BoolToStr(Plugins[I].Paused, true), + Plugins[I].CountErrors + ]), 'LuaCore Plugins'); + if (High(Plugins) < 0) then + Log.LogError(' no plugins loaded ', 'LuaCore Plugins'); +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/songmanagement/src/lua/ULuaGl.pas b/songmanagement/src/lua/ULuaGl.pas new file mode 100644 index 00000000..178853b6 --- /dev/null +++ b/songmanagement/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/songmanagement/src/lua/ULuaLog.pas b/songmanagement/src/lua/ULuaLog.pas new file mode 100644 index 00000000..95efaa19 --- /dev/null +++ b/songmanagement/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/songmanagement/src/lua/ULuaParty.pas b/songmanagement/src/lua/ULuaParty.pas new file mode 100644 index 00000000..69096e97 --- /dev/null +++ b/songmanagement/src/lua/ULuaParty.pas @@ -0,0 +1,391 @@ +{* 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+1)); + lua_gettable(L, 1); + + R[I].Rank := Length(R); + R[I].Team := I; + 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/songmanagement/src/lua/ULuaScreenSing.pas b/songmanagement/src/lua/ULuaScreenSing.pas new file mode 100644 index 00000000..7e17224c --- /dev/null +++ b/songmanagement/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/songmanagement/src/lua/ULuaTextGL.pas b/songmanagement/src/lua/ULuaTextGL.pas new file mode 100644 index 00000000..2e70a2c1 --- /dev/null +++ b/songmanagement/src/lua/ULuaTextGL.pas @@ -0,0 +1,148 @@ +{* 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, + SysUtils, + 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 < Length(Fonts)) then + SetFontStyle(Style) + else + luaL_ArgError(L, 1, PChar('number from 0 to ' + IntToStr(High(Fonts)) + ' 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/songmanagement/src/lua/ULuaTexture.pas b/songmanagement/src/lua/ULuaTexture.pas new file mode 100644 index 00000000..931c0405 --- /dev/null +++ b/songmanagement/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/songmanagement/src/lua/ULuaUsdx.pas b/songmanagement/src/lua/ULuaUsdx.pas new file mode 100644 index 00000000..d92289b1 --- /dev/null +++ b/songmanagement/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/songmanagement/src/lua/ULuaUtils.pas b/songmanagement/src/lua/ULuaUtils.pas new file mode 100644 index 00000000..143b34d4 --- /dev/null +++ b/songmanagement/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 -- cgit v1.2.3