替同事做了个洛奇英雄传自动染色程序,关于屏幕取色的.因为里面他对颜色的要求比较复杂,改动也比较大,于是我让他把逻辑写在 lua 脚本里面.
- uses LUA, LUALIB;
- function lua_CheckColor(r,g,b:Integer):Boolean;
- var
- Lua : TLua;
- begin
- Lua := TLua.Create;
- luaopen_debug(LuaInstance); //如果要使用debug库
- // luaopen_io(LuaInstance);
- luaopen_math(LuaInstance);// 如果要使用math库 不然就会attempt to index global 'math' (a nil value)
- luaopen_os(LuaInstance);
- // luaopen_package(LuaInstance);
- luaopen_string(LuaInstance);
- luaopen_table(LuaInstance);
- Lua.DoFile('lua_GetColor.lua');
- lua_getglobal(Lua.LuaInstance,'nogi_GetColor');
- lua_pushnumber(Lua.LuaInstance, r); //将脚本中add函数使用的参数压栈
- lua_pushnumber(Lua.LuaInstance, g); //将脚本中add函数使用的参数压栈
- lua_pushnumber(Lua.LuaInstance, b); //将脚本中add函数使用的参数压栈
- lua_pcall(Lua.LuaInstance, 3, 1,0) ;
- Result := (lua_toInteger(Lua.LuaInstance,-1) = 1);
- Lua.Free;
- end;
LUA 里面的内容是这样的
- function nogi_GetColor(nR,nG,nB)
- if nR <= 25 and nG <= 25 and nB <= 25 then -- 取出25以下黑色
- return 1;
- end;
- return 0;
- end
附上我这里带的 LUA.PAS 和 LUALIB.PAS
lua.pas
- {
- /**
- * @package Delphi Lua
- * @copyright Copyright (c) 2009 Dennis D. Spreen (http://www.spreendigital.de/blog)
- * @license http://opensource.org/licenses/gpl-license.php GNU Public License
- * @author Dennis D. Spreen <dennis@spreendigital.de>
- * @version 1.3
- * @revision $Id: Lua.pas 102 2009-09-30 11:39:41Z dennis.spreen $
- */
- History
- 1.3 DS Improved Callback, now uses pointer instead of object index
- Modified RegisterFunctions to allow methods from other class
- to be registered, moved object table into TLua class
- 1.2 DS Added example on how to extend lua with a delphi dll
- 1.1 DS Improved global object table, this optimizes the delphi
- function calls
- 1.0 DS Initial Release
- Copyright 2009 Dennis D. Spreen (email : dennis@spreendigital.de)
- 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; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- }
- unit Lua;
- interface
- uses
- Classes,
- LuaLib;
- type
- TLuaState = Lua_State;
- TLua = class(TObject)
- private
- fAutoRegister: Boolean;
- CallbackList: TList; // internal callback list
- public
- LuaInstance: TLuaState; // Lua instance
- constructor Create(AutoRegister: Boolean = True); overload; virtual;
- destructor Destroy; override;
- function DoFile(Filename: String): Integer; virtual;// load file and execute
- procedure RegisterFunction(FuncName: AnsiString; MethodName: AnsiString = ''; Obj: TObject = NIL); virtual; //register function
- procedure AutoRegisterFunctions(Obj: TObject); // register all published functions
- procedure UnregisterFunctions(Obj: TObject); // unregister all object functions
- end;
- implementation
- type
- TProc = function(L: TLuaState): Integer of object; // Lua Function
- TCallback = class
- Routine: TMethod; // Code and Data for the method
- Exec: TProc; // Resulting execution function
- end;
- //
- // This function is called by Lua, it extracts the object by
- // pointer to the objects method by name, which is then called.
- //
- // @param Lua_State L Pointer to Lua instance
- // @return Integer Number of result arguments on stack
- //
- function LuaCallBack(L: Lua_State): Integer; cdecl;
- var
- CallBack: TCallBack; // The Object stored in the Object Table
- begin
- // Retrieve first Closure Value (=Object Pointer)
- CallBack := lua_topointer(L, lua_upvalueindex(1));
- // Execute only if Object is valid
- if (assigned(CallBack) and assigned(CallBack.Exec)) then
- Result := CallBack.Exec(L)
- else
- Result := 0;
- end;
- { TLua }
- //
- // Create a new Lua instance and optionally create Lua functions
- //
- // @param Boolean AutoRegister (optional)
- // @return TLua Lua Instance
- //
- constructor TLua.Create(AutoRegister: Boolean = True);
- begin
- inherited Create;
- // Load Lua Lib if not already done
- if (not LuaLibLoaded) then
- LoadLuaLib;
- // Open Library
- LuaInstance := Lua_Open();
- luaopen_base(LuaInstance);
- fAutoRegister := AutoRegister;
- // Create Object List on initialization
- CallBackList := TList.Create;
- // if set then register published functions
- if (AutoRegister) then
- AutoRegisterFunctions(self);
- end;
- //
- // Dispose Lua instance
- //
- destructor TLua.Destroy;
- begin
- // Unregister all functions if previously autoregistered
- if (fAutoRegister) then
- UnregisterFunctions(Self);
- // dispose Object List on finalization
- CallBackList.Free;
- // Close instance
- Lua_Close(LuaInstance);
- inherited;
- end;
- //
- // Wrapper for Lua File load and Execution
- //
- // @param String Filename Lua Script file name
- // @return Integer
- //
- function TLua.DoFile(Filename: String): Integer;
- begin
- Result := lual_dofile(LuaInstance, PAnsiChar(AnsiString(Filename)));
- end;
- //
- // Register a new Lua Function and map it to the Objects method name
- //
- // @param AnsiString FuncName Lua Function Name
- // @param AnsiString MethodName (optional) Objects Method name
- //
- procedure TLua.RegisterFunction(FuncName: AnsiString; MethodName: AnsiString = ''; Obj: TObject = NIL);
- var
- CallBack: TCallBack; // Callback Object
- begin
- // if method name not specified use Lua function name
- if (MethodName = '') then
- MethodName := FuncName;
- // if not object specified use this object
- if (Obj = NIL) then
- Obj := Self;
- // Add Callback Object to the Object Index
- CallBack := TCallBack.Create;
- CallBack.Routine.Data := Obj;
- CallBack.Routine.Code := Obj.MethodAddress(String(MethodName));
- CallBack.Exec := TProc(CallBack.Routine);
- CallbackList.Add(CallBack);
- // prepare Closure value (Method Name)
- lua_pushstring(LuaInstance, PAnsiChar(FuncName));
- // prepare Closure value (CallBack Object Pointer)
- lua_pushlightuserdata(LuaInstance, CallBack);
- // set new Lua function with Closure value
- lua_pushcclosure(LuaInstance, LuaCallBack, 1);
- lua_settable(LuaInstance, LUA_GLOBALSINDEX);
- end;
- //
- // UnRegister all new Lua Function
- //
- // @param TObject Object Object with prev registered lua functions
- //
- procedure TLua.UnregisterFunctions(Obj: TObject);
- var
- I: Integer;
- CallBack: TCallBack;
- begin
- // remove obj from object list
- for I := CallBackList.Count downto 1 do
- begin
- CallBack := CallBackList[I-1];
- if (assigned(CallBack)) and (CallBack.Routine.Data = Obj) then
- begin
- CallBack.Free;
- CallBackList.Items[I-1] := NIL;
- CallBackList.Delete(I-1);
- end;
- end;
- end;
- //
- // Register all published methods as Lua Functions
- //
- procedure TLua.AutoRegisterFunctions(Obj: TObject);
- type
- PPointer = ^Pointer;
- PMethodRec = ^TMethodRec;
- TMethodRec = packed record
- wSize: Word;
- pCode: Pointer;
- sName: ShortString;
- end;
- var
- MethodTable: PAnsiChar;
- MethodRec: PMethodRec;
- wCount: Word;
- nMethod: Integer;
- begin
- // Get a pointer to the class's published method table
- MethodTable := PAnsiChar(Pointer(PAnsiChar(Obj.ClassType) + vmtMethodTable)^);
- if (MethodTable <> Nil) then
- begin
- // Get the count of the methods in the table
- Move(MethodTable^, wCount, 2);
- // Position the MethodRec pointer at the first method in the table
- // (skip over the 2-byte method count)
- MethodRec := PMethodRec(MethodTable + 2);
- // Iterate through all the published methods of this class
- for nMethod := 0 to wCount - 1 do
- begin
- // Add the method name to the lua functions
- RegisterFunction(MethodRec.sName, MethodRec.sName, Obj);
- // Skip to the next method
- MethodRec := PMethodRec(PAnsiChar(MethodRec) + MethodRec.wSize);
- end;
- end;
- end;
- end.
lualib.pas
- (******************************************************************************
- * Original copyright for the lua source and headers:
- * 1994-2004 Tecgraf, PUC-Rio.
- * www.lua.org.
- *
- * Copyright for the Delphi adaptation:
- * 2005 Rolf Meyerhoff
- * www.matrix44.de
- *
- * Copyright for the Lua 5.1 adaptation:
- * 2007 Marco Antonio Abreu
- * www.marcoabreu.eti.br
- *
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- ******************************************************************************)
- unit LuaLib;
- interface
- const
- LUA_VERSION = 'Lua 5.1';
- LUA_RELEASE = 'Lua 5.1.2';
- LUA_COPYRIGHT = 'Copyright (C) 1994-2004 Tecgraf, PUC-Rio';
- LUA_AUTHORS = 'R. Ierusalimschy, L. H. de Figueiredo & W. Celes';
- LUA_PASCAL_51_AUTHOR = 'Marco Antonio Abreu';
- LUA_PASCAL_51_COPYRIGHT = 'Copyright (C) 2007 Marco Antonio Abreu';
- (* mark for precompiled code (`<esc>Lua') *)
- LUA_SIGNATURE = #27'Lua';
- (* option for multiple returns in `lua_pcall' and `lua_call' *)
- LUA_MULTRET = -1;
- (*
- ** pseudo-indices
- *)
- LUA_REGISTRYINDEX = -10000;
- LUA_ENVIRONINDEX = -10001;
- LUA_GLOBALSINDEX = -10002;
- (* thread status; 0 is OK *)
- LUA_TRD_YIELD = 1;
- LUA_ERRRUN = 2;
- LUA_ERRSYNTAX = 3;
- LUA_ERRMEM = 4;
- LUA_ERRERR = 5;
- (* extra error code for `luaL_load' *)
- LUA_ERRFILE = LUA_ERRERR + 1;
- (*
- ** basic types
- *)
- LUA_TNONE = -1;
- LUA_TNIL = 0;
- LUA_TBOOLEAN = 1;
- LUA_TLIGHTUSERDATA = 2;
- LUA_TNUMBER = 3;
- LUA_TSTRING = 4;
- LUA_TTABLE = 5;
- LUA_TFUNCTION = 6;
- LUA_TUSERDATA = 7;
- LUA_TTHREAD = 8;
- (* minimum Lua stack available to a C function *)
- LUA_MINSTACK = 20;
- (*
- ** garbage-collection function and options
- *)
- LUA_GCSTOP = 0;
- LUA_GCRESTART = 1;
- LUA_GCCOLLECT = 2;
- LUA_GCCOUNT = 3;
- LUA_GCCOUNTB = 4;
- LUA_GCSTEP = 5;
- LUA_GCSETPAUSE = 6;
- LUA_GCSETSTEPMUL = 7;
- (*
- ** {======================================================================
- ** Debug API
- ** =======================================================================
- *)
- (*
- ** Event codes
- *)
- LUA_HOOKCALL = 0;
- LUA_HOOKRET = 1;
- LUA_HOOKLINE = 2;
- LUA_HOOKCOUNT = 3;
- LUA_HOOKTAILRET = 4;
- (*
- ** Event masks
- *)
- LUA_MASKCALL = (1 shl LUA_HOOKCALL);
- LUA_MASKRET = (1 shl LUA_HOOKRET);
- LUA_MASKLINE = (1 shl LUA_HOOKLINE);
- LUA_MASKCOUNT = (1 shl LUA_HOOKCOUNT);
- (*
- ** {======================================================================
- ** useful definitions for Lua kernel and libraries
- ** =======================================================================
- *)
- (*
- @@ LUA_NUMBER_SCAN is the format for reading numbers.
- @@ LUA_NUMBER_FMT is the format for writing numbers.
- @@ lua_number2str converts a number to a string.
- @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
- @@ lua_str2number converts a string to a number.
- *)
- LUA_NUMBER_SCAN = '%lf';
- LUA_NUMBER_FMT = '%.14g';
- LUAI_MAXNUMBER2STR = 32; (* 16 digits, sign, point, and