Jump to content
shadowrecon

SCAR Type Exports in Delphi XE3

Recommended Posts

I'm back and a bit rusty. I've been trying lately to report SPS to SCAR starting from scratch. Everything as far as bitmaps goes and etc. is going good minus the fact I cant seem to properly export types to SCAR from the DLL file. I am trying to create a type called "T3DIntArray" which is an array of T2DIntArray. Seeing as SCAR already has a type predefined as T2DIntArray I am just exporting the type T3DIntArray. I am used the sample code directly from the samples Freddy provided for the new DLL architecture. The only lines of code I changed where the ones dealing directly with the type's name and deff. here is the only code I modified with the type export system.

 

[scar] TypeExports: array[0..0] of TTypeExport = (

(Name: 'T3DIntArray'; Def: 'T3DIntArray = array of T2DIntArray;')

);[/scar]

 

Here is my type declaration

[scar]type

TIntArray = array of Integer;

T2DIntArray = array of TIntArray;

T3DIntArray = array of T2DIntArray;[/scar]

 

Error from scar states:

Unable to register function array of T2DIntArray;

 

Does anyone see any mistakes or problems?

 

Thanks

 

-ShadowRecon

 

Heres the entire source code of the DLL

[scar]library SCAR_SPS;

 

//**

// License:

// Credits:

//**

 

{$R *.res}

 

uses

FastShareMem in 'Units\FastShareMem.pas',

SCARApi in 'Units\SCARApi.pas',

SCARLibSetup in 'Units\SCARLibSetup.pas',

SCARUtils in 'Units\SCARUtils.pas',

SysUtils, Math;

 

type

TIntArray = array of Integer;

T2DIntArray = array of TIntArray;

T3DIntArray = array of T2DIntArray;

 

(**

* Retruns the RGB values of a color.

*)

procedure ColorToRGB(Color : Integer;out r,g,b : Integer); stdcall;

begin

R := Color and $ff;

G := Color shr 8 and $ff;

B := Color shr 16 and $ff;

end;

 

(**

* Retruns true if the color boxes (B1 and B2) match within the tolerance (tol).

*)

function SPS_ColorBoxesMatchInline(B1, B2: TIntArray; tol: extended): boolean; stdcall;

begin

Result := False;

 

// B[0] = Red; B[1] = Green, B[2] = Blue (see SPS_MakeColorBox)

if ((B2[0] + B2[1] + B2[2]) = 0) then

Exit;

 

// if the difference between the two 'color boxes' RGB values are less than the tolerance

if (abs(B1[0] - B2[0]) < tol) then

if (abs(B1[1] - B2[1]) < tol) then

if (abs(B1[2] - B2[2]) < tol) then

Result := True;

end;

 

(**

* Returns the TOTAL RGB values of each pixel in a box (starting at x1, y1 with

* side lengths 'SideLength') on the bitmap (bmp).

*

* Result[0] = Red

* Result[1] = Green

* Result[2] = Blue

*)

procedure SPS_MakeColorBox(const Bmp: Pointer; const x1, y1, SideLength: integer; var res: TIntArray); stdcall;

var

x, y, C, R, G, B: integer;

Wrapper: TSCARBitmapWrapper;

begin

Wrapper := TSCARBitmapWrapper.Create(Bmp);

try

SetLength(Res, 3);

 

for x := (x1 + SideLength - 1) downto x1 do

for y := (y1 + SideLength - 1) downto y1 do

begin

C := Wrapper.Pixels[x, y];

ColorToRGB(C, R, G, B);

 

Res[0] := Res[0] + R;

Res[1] := Res[1] + G;

Res[2] := Res[2] + B;

end;

finally

Wrapper.Free;

end;

end;

 

(**

* Filters the edges of the minimap so only the circle appears as colors.

*)

procedure SPS_FilterMinimap(const Bmp: Pointer); stdcall;

var

W, H, x, y: integer;

Wrapper: TSCARBitmapWrapper;

begin

Wrapper := TSCARBitmapWrapper.Create(Bmp);

try

W := Wrapper.width;

H := Wrapper.height;

 

for x := W - 1 downto 0 do

for y := H - 1 downto 0 do

if hypot(abs(75.0 - x), abs(75.0 - y)) > 75 then

begin

Wrapper.Pixels[x, y] := 0;

continue;

end;

finally

Wrapper.Free;

end;

end;

 

(**

* Converts the bitmap (bmp) to a 'grid' of color boxes.

*)

procedure SPS_BitmapToMap(const Bmp: Pointer; SideLength: integer; var res: T3DIntArray); stdcall;

var

X, Y, HighX, HighY: integer;

Wrapper: TSCARBitmapWrapper;

begin

Wrapper := TSCARBitmapWrapper.Create(Bmp);

try

HighX := Trunc(Wrapper.Width / (SideLength * 1.0));

HighY := Trunc(Wrapper.Height / (SideLength * 1.0));

SetLength(Res, HighX);

for X := 0 to HighX - 1 do

begin

SetLength(Res[X], HighY);

for Y := 0 to HighY - 1 do

begin

SPS_MakeColorBox(bmp, X * SideLength, Y * SideLength, SideLength, Res[X][Y]);

end;

end;

finally

Wrapper.Free;

end;

end;

 

(**

* Returns 3 variables:

* fx, fy: The X and Y of the grid piece in SmallMap that best matches the LargeMap.

* Result: The number of color box matches found.

*)

function SPS_FindMapInMap(out fx, fy: integer; LargeMap, SmallMap: T3DIntArray; tol: extended): integer; stdcall;

var

x, y, HighX, HighY: integer;

xx, yy: integer;

Matching: integer;

BoxesInViewX, BoxesInViewY: integer;

begin

fX := -1;

fY := -1;

Result := 0;

 

 

BoxesInViewX := Length(SmallMap); // columns in the grid

BoxesInViewY := Length(SmallMap[0]); // rows in the grid

 

 

//SCAR_DebugLn('SPS_FindMapInMap: BoxesInViewX: '+intToStr(BoxesInViewX));

//SCAR_DebugLn('SPS_FindMapInMap: BoxesInViewY: '+intToStr(BoxesInViewY));

 

 

HighX := High(LargeMap) - BoxesInViewX;

HighY := High(LargeMap[0]) - BoxesInViewY;

 

 

//SCAR_DebugLn('SPS_FindMapInMap: HighX: '+intToStr(HighX));

//SCAR_DebugLn('SPS_FindMapInMap: HighY: '+intToStr(HighY));

 

 

for x := 0 to HighX do

for y := 0 to HighY do

begin

Matching := 0;

 

 

// compares the minimap to a chunch of the SPS_Area

for xx := (BoxesInViewX - 1) downto 0 do

for yy := (BoxesInViewY - 1) downto 0 do

if (SPS_ColorBoxesMatchInline(LargeMap[x+xx][y+yy], SmallMap[xx][yy], tol)) then

Matching := (Matching + 1);

 

 

if (Matching > Result) then

begin

Result := Matching;

fX := x;

fY := y;

end;

end;

end;

 

const

FunctionExports: array[0..3] of TFunctionExport = (

(Ref: @SPS_MakeColorBox; Def: 'procedure SPS_MakeColorBox(const Bmp: TSCARBitmap; const x1, y1, SideLength: integer; var res: TIntArray);'; Conv: ccStdCall),

(Ref: @SPS_FilterMinimap; Def: 'procedure SPS_FilterMinimap(const Bmp: TSCARBitmap);'; Conv: ccStdCall),

(Ref: @SPS_BitmapToMap; Def: 'procedure SPS_BitmapToMap(const Bmp: TSCARBitmap; SideLength: integer; var res: T3DIntArray);'; Conv: ccStdCall),

(Ref: @SPS_FindMapInMap; Def: 'function SPS_FindMapInMap(out fx, fy: integer; LargeMap, SmallMap: T3DIntArray; tol: extended): integer;'; Conv: ccStdCall)

);

 

TypeExports: array[0..0] of TTypeExport = (

(Name: 'T3DIntArray'; Def: 'T3DIntArray = array of T2DIntArray;')

);

 

procedure OnLoadLib(const SCARExports: PExports); stdcall;

begin

Exp := SCARExports; // Do NOT remove this line!

// Called when the library is loaded

end;

 

procedure OnUnloadLib; stdcall;

begin

// Called when the library is unloaded

end;

 

// - Function exports

// Do NOT change this! (unless you're not exporting functions, then you can remove this part)

function OnGetFuncCount: Integer; stdcall;

begin

Result := High(FunctionExports) - Low(FunctionExports) + 1;

end;

 

function OnGetFuncInfo(const Idx: Integer; out ProcAddr: Pointer; out ProcDef: PAnsiChar;

out CallConv: TCallConv): Integer; stdcall;

var

FuncExp: TFunctionExport;

begin

if (Idx >= Low(FunctionExports)) and (Idx <= High(FunctionExports)) then

begin

FuncExp := FunctionExports[idx + Low(FunctionExports)];

ProcAddr := FuncExp.Ref;

ProcDef := PAnsiChar(FuncExp.Def);

CallConv := FuncExp.Conv;

Result := Idx;

end else

Result := -1;

end;

 

// - Type exports

// Do NOT change this! (unless you're not exporting types, then you can remove this part)

function OnGetTypeCount: Integer; stdcall;

begin

Result := High(TypeExports) - Low(TypeExports) + 1;

end;

 

function OnGetTypeInfo(const Idx: Integer; out TypeName, TypeDef: PAnsiChar): Integer; stdcall;

var

TypeExp: TTypeExport;

begin

if (Idx >= Low(TypeExports)) and (Idx <= High(TypeExports)) then

begin

TypeExp := TypeExports[idx + Low(TypeExports)];

TypeName := PAnsiChar(TypeExp.Name);

TypeDef := PAnsiChar(TypeExp.Def);

Result := Idx;

end else

Result := -1;

end;

 

// - Library architecture

// Do NOT change this!

const

LIBRARY_ARCHITECTURE_LEGACY = 1;

LIBRARY_ARCHITECTURE_MAIN = 2;

 

function LibArch: Integer; stdcall;

begin

Result := LIBRARY_ARCHITECTURE_MAIN;

end;

 

exports OnLoadLib;

exports OnUnloadLib;

exports OnGetFuncCount;

exports OnGetFuncInfo;

exports OnGetTypeCount;

exports OnGetTypeInfo;

exports LibArch;

 

end.[/scar]

Edited by shadowrecon
Link to comment
Share on other sites

Ive tried that, along with adding more types including the ones already in SCAR with no luck. Im sure Freddy has a simple explanation of what im doing wrong. I believe I had this issue before at some point I just cant seem to find a reference on here.

 

- - - Updated - - -

 

Im starting to wonder if since the functions use the type in there definition that maybe the type exports need to be exported first before the functions.

Link to comment
Share on other sites

With some luck I happened to catch the error.. Of course like always it was a mistake I made. BUT now im having other issues with exporting functions that use the types or it could be the fact the the functions that use the types use the "var" keyword in there declaration =/. The "SPS_FilterMinimap" function exports just fine along with the T3DIntArray type now.

 

Here is the corrected form of how it should look:

[scar]TypeExports: array[0..0] of TTypeExport = (

(Name: 'T3DIntArray'; Def: 'array of T2DIntArray;')

);[/scar]

 

instead of:

[scar]TypeExports: array[0..0] of TTypeExport = (

(Name: 'T3DIntArray'; Def: 'T3DIntArray = array of T2DIntArray;')

);[/scar]

 

 

Heres how I managed to locate the problem:

 

[scar]const

FunctionExports: array[0..0] of TFunctionExport = (

//(Ref: @SPS_MakeColorBox; Def: 'procedure SPS_MakeColorBox(const Bmp: TSCARBitmap; const x1, y1, SideLength: integer; var res: TIntArray);'; Conv: ccStdCall),

(Ref: @SPS_FilterMinimap; Def: 'procedure SPS_FilterMinimap(const Bmp: TSCARBitmap);'; Conv: ccStdCall)//,

//(Ref: @SPS_BitmapToMap; Def: 'procedure SPS_BitmapToMap(const Bmp: TSCARBitmap; SideLength: integer; var res: T3DIntArray);'; Conv: ccStdCall),

//(Ref: @SPS_FindMapInMap; Def: 'function SPS_FindMapInMap(out fx, fy: integer; LargeMap, SmallMap: T3DIntArray; const tol: extended): integer;'; Conv: ccStdCall)

);[/scar]

 

By commenting out all the functions that use the type and the single function that has the TIntArray type I no can load the DLL and the type "T3DIntArray but when I uncomment the other functions and try to load them in scar I get errors.

 

Does anyone have any ideas?

 

- - - Updated - - -

 

Well after some testing I have concluded the new DLL architecture needss work Freddy.............. Seriously bro... I had SPS working just fine before all these new improvements which has driven this community down.. SPS worked before your updates and now it doesn't.. Its the DLL architecture.... Because ive tried using the old DLL since it is supposedly supported but it returns blank bitmaps and the DLL you supposedly fixed does the same thing. There is a bug some where in the architecture. I don't want to spend 3 months finding your ERROR's.. id like to actually be able to make some sort of program do something. I spent over 3 months porting SPS to SCAR and a month after I finished you changed the system. WTF? Anyways back on topic...

 

For some reason now when I try to use the type after the DLL is loaded if I type "TIA3D : T3DIntArray" it says it is an unknown type EVEN tho it is listed in the drop down list of available types from scar.... This is racking my brains just like it did last year. Its driving me to the point of just going to use samba to write scripts just so I can use SPS... I wish I could find the problem but the problem doesn't seem to be any of my coding. It seems to be SCAR!

 

I appreciate the features but damn can we get something that works. Soon this community is going to fall completely apart because right now with all these rapid changes in the programming environment your causing the newbies and etc to fall off and jump over to samba because there are working scripts. We cant keep our scripts working longer than a month without you changing something and everything falling apart!

Link to comment
Share on other sites

In order to get the type to work properly I went and used the old form instead of the new system you laid out in the "Basic_Exports" example.

 

[scar]function OnGetTypeCount: Integer; stdcall;

begin

Result := 1;

end;

 

function OnGetTypeInfo(const Idx: Integer; out TypeName, TypeDef: PAnsiChar): Integer; stdcall;

begin

Result := Idx;

case Idx of

0: begin

TypeName := 'T3DIntArray';

TypeDef := 'array of T2DIntArray;';

end

else Result := -1;

end;

end;[/scar]

 

instead of

 

[scar]

TypeExports: array[0..0] of TTypeExport = (

(Name: 'T3DIntArray'; Def: 'array of T2DIntArray;')

);

 

// - Type exports

// Do NOT change this! (unless you're not exporting types, then you can remove this part)

function OnGetTypeCount: Integer; stdcall;

begin

Result := High(TypeExports) - Low(TypeExports) + 1;

end;

 

function OnGetTypeInfo(const Idx: Integer; out TypeName, TypeDef: PAnsiChar): Integer; stdcall;

var

TypeExp: TTypeExport;

begin

if (Idx >= Low(TypeExports)) and (Idx <= High(TypeExports)) then

begin

TypeExp := TypeExports[idx + Low(TypeExports)];

TypeName := PAnsiChar(TypeExp.Name);

TypeDef := PAnsiChar(TypeExp.Def);

Result := Idx;

end else

Result := -1;

end;

[/scar]

Link to comment
Share on other sites

Welcome back! :)

 

Once up on a time, there was a post here... But then I read the source, and found that this post was not to any help.

 

But I will leave one thought: fuzzy feature comparison, instead of the super sensitive image comparison used now! :-)

Edited by slacky
Link to comment
Share on other sites

Well i have rewritten all of the library's to comply with the new Library architecture along with complying with SCAR 3.38. If there are major breaking changes again with scar i give up! lol. SPS is now working. The only thing i have to solve now is the camera-Angle functions from OSI. If anyone has a working camera angle detection function please share. Soon as i get that solved SPS will be back for everyone to use. Im going to remove most of the GMRL include as most of the functions in there are not that useful. SPS will be about the only set of functions i keep in there. Thanks for the help guys. Sorry about the ranting a raven ive just been frustrated with SPS for a year.. but its fixed and im happy.

Link to comment
Share on other sites

as soon as i get a few functions like getcompassangle, mouse and findflag working the entire system will be posted but right now only the function getmypos works but thats the core function of SPSn the rest is RS dependent. It does work though i hope to have everything working soon. Does OSI work right now with RS? i havent tried it just assumed it was broke. Im trying to make SPS independent so no other includes are required to run it.

Link to comment
Share on other sites

as soon as i get a few functions like getcompassangle, mouse and findflag working the entire system will be posted but right now only the function getmypos works but thats the core function of SPSn the rest is RS dependent. It does work though i hope to have everything working soon. Does OSI work right now with RS? i havent tried it just assumed it was broke. Im trying to make SPS independent so no other includes are required to run it.

 

OSI2 works with RS07. I'm uncertain what condition OSI1 w/ RS2 is in.

Link to comment
Share on other sites

Well i found the problem. I was trying to use the constants from the RS07 global s but i think they are either different for the map or they are wrong in OSI2 because the X value for MMX1 i believe was to far over to the right and something else i cant remember. I dont have a RS07 account so i couldnt check i just assumed that was the condition. After i found out that i managed to get all the RS functions from OSI1 to work with no problem. So OSI 1 is still in good working order as far as all the functions i borrowed from OSI1.

Link to comment
Share on other sites

Ah, well if you could get me the global's id gladly work on making it compatible but would not be able to test it. I would also need to make new maps, LordJashin ported the map maker from Simba to SCAR for SCAR 3.34 so i would also just need someone to log in and let the map maker do its thing to make the map pieces if it fails to use the new map pieces.

Link to comment
Share on other sites

Ah, well if you could get me the global's id gladly work on making it compatible but would not be able to test it. I would also need to make new maps, LordJashin ported the map maker from Simba to SCAR for SCAR 3.34 so i would also just need someone to log in and let the map maker do its thing to make the map pieces if it fails to use the new map pieces.

 

RS07 globals are in OSI2 \RS07\Core\Globals.scar

 

As for an account try creating a new thread somewhere.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
  • Create New...