PDA

View Full Version : A way to find the mismatching parameter?



marpis
12-09-2011, 11:29 PM
Check this post:
http://villavu.com/forum/showpost.php?p=855981&postcount=16

I've been looking and looking and I just can't see what parameter gives me that type mismatch.

The weird thing is, if I run the test script without targeting the RS window, it does not give any errors, just results (-1, -1) as the position. But when I target RS, it gives me a type mismatch error on this line:
P := SPS_GetMyPosEx(Minimap, AreaBitmaps, SPS_Tolerance, FoundMatches, map);

So I'm guessing there's some problems with Simba and the plugin dealing with TMufasaBitmaps, but I don't know what. Here's the source to the plugin:
library sps;

{$mode objfpc}{$H+}

uses
Classes, sysutils, FileUtil, Interfaces, mufasatypes, bitmaps;

type
T3DIntegerArray = array of T2DIntegerArray;
T4DIntegerArray = array of T3DIntegerArray;

function SPS_ColorBoxesMatchInline(B1, B2: TIntegerArray; tol: extended): boolean; inline;
var
oneMinusTol, tolPlusOne: extended;
begin
oneMinusTol := 1 - tol;
tolPlusOne := tol + 1;
Result := ((B1[0] >= Round(B2[0] * oneMinusTol)) and
(B1[0] <= Round(B2[0] * tolPlusOne))) and
((B1[1] >= Round(B2[1] * oneMinusTol)) and
(B1[1] <= Round(B2[1] * tolPlusOne))) and
((B1[2] >= Round(B2[2] * oneMinusTol)) and
(B1[2] <= Round(B2[2] * tolPlusOne)));
end;


// Edited for SPS2
function SPS_MakeColorBox(bmp: TMufasaBitmap; x1, y1, SideLength: integer): TIntegerArray;
var
x, y, width: integer;
C: TRGB32;
begin
SetLength(Result, 3);
width := bmp.Width; // may not be necessary, but should help a bit.

for x := (x1 + SideLength - 1) downto x1 do // flipped these to downto since order is irrelevant
for y := (y1 + SideLength - 1) downto y1 do // downto will calc the initial only once rather than each time.
begin
try
C := bmp.FData[y * width + x];
Result[0] := Result[0] + C.R;
Result[1] := Result[1] + C.G;
Result[2] := Result[2] + C.B;
except end;
end;
end;

function SPS_GetProfile(View: TMufasaBitmap): integer; register;
var
i, ii: integer;
ProfileAsArray: Array [0..2] of integer;
TIA: TIntegerArray;
begin
TIA := SPS_MakeColorBox(View, 0, 0, 100);

for i := 0 to 2 do
for ii := 1 to 10 do
if (TIA[i] / 10000.0) <= (25.5*ii) then
begin
ProfileAsArray[i] := ii - 1;
Break;
end;

Result := ProfileAsArray[0] + ProfileAsArray[1]*10 + ProfileAsArray[2]*100;
end;


function SPS_BitmapToMap(bmp: TMufasaBitmap; SideLength: integer): T3DIntegerArray; register;
var
X, Y, HighX, HighY: integer;
begin
HighX := Trunc(bmp.Width / (SideLength*1.0));
HighY := Trunc(bmp.Height / (SideLength*1.0));

SetLength(Result, HighX);
for X := 0 to HighX - 1 do
begin
SetLength(Result[X], HighY);
for Y := 0 to HighY - 1 do
begin
Result[X][Y] := SPS_MakeColorBox(bmp, X * SideLength, Y * SideLength, SideLength);
end;
end;
end;

function SPS_FindMapInMap(out fx, fy: integer; LargeMap: T4DIntegerArray; SmallMap: T3DIntegerArray; tol: extended; var FoundMatches: integer): integer; register;
var
x, y, HighX, HighY, cm, L: integer;
xx, yy: integer;
Matching: integer;
BoxesLeftInView: integer;
BoxesInViewX, BoxesInViewY, TotBoxesInView: integer;
b: Boolean;
begin
fX := -1;
fY := -1;
Result := -1;
FoundMathces := 0;
L := Length(LargeMap);
BoxesInViewX := Length(SmallMap);
BoxesInViewY := Length(SmallMap[0]);
TotBoxesInView := BoxesInViewX * BoxesInViewY;


for cm := 0 to L-1 do
begin
HighX := High(LargeMap[cm]) - BoxesInViewX - 1;
HighY := High(LargeMap[cm][0]) - BoxesInViewY - 1;
for x := 0 to HighX do
for y := 0 to HighY do
begin
Matching := 0;
BoxesLeftInView := TotBoxesInView;

for xx := (BoxesInViewX - 1) downto 0 do
for yy := (BoxesInViewY - 1) downto 0 do
begin
if (BoxesLeftInView + Matching) <= FoundMatches then
Break;

Dec(BoxesLeftInView);

b:= SPS_ColorBoxesMatchInline(LargeMap[cm][x+xx][y+yy], SmallMap[xx][yy], tol);
if (b) then Inc(Matching);
end;

if (Matching > FoundMatches) then
begin
FoundMatches := Matching;
Result := cm;
fX := x;
fY := y;
end;
end;
end;
end;


function SPS_CropArea(x1, y1, x2, y2: integer; Area: T3DIntegerArray): T3DIntegerArray;
var
x, y, i: integer;
begin
SetLength(Result, x2 - x1 + 1);
for x := (x2 - x1) downto 0 do
begin
SetLength(Result[x], y2 - y1 + 1);

for y := (y2 - y1) downto 0 do
begin
SetLength(Result[x][y], 3);
for i := 0 to 2 do
Result[x][y][i] := Area[x1 + x][y1 + y][i];
end;
end;
end;

function marpis_Max(a, b: integer): integer;
begin
if a >= b then
result := a
else
result := b;
end;

function marpis_Min(a, b: integer): integer;
begin
if a <= b then
result := a
else
result := b;
end;

function SPS_GetMyPosEx(ViewBitmap: TMufasaBitmap; AreaBitmaps: array of TMufasaBitmap; tol: extended; out FoundMatches, AreaIndex: integer): TPoint; register;
var
x, y, i, L: integer;
MaxW, MaxH: integer;
Minimap: T3DIntegerArray;
WorldMap: T4DIntegerArray;
NewTargetArea: T4DIntegerArray;
begin
L := Length(AreaBitmaps);
SetLength(Worldmap, L);
Dec(L);

Minimap := SPS_BitmapToMap(ViewBitmap, 25);
for i := 0 to L do
Worldmap[i] := SPS_BitmapToMap(AreaBitmaps[i], 25);

AreaIndex := SPS_FindMapInMap(x, y, Worldmap, Minimap, tol, FoundMatches);
SetLength(Worldmap, 1);
Worldmap[0] := SPS_BitmapToMap(AreaBitmaps[AreaIndex], 2);
Minimap := SPS_BitmapToMap(ViewBitmap, 2);

MaxW := High(Worldmap[0]);
MaxH := High(Worldmap[0][0]);

SetLength(NewTargetArea, 1);
x := x*25 + 50;
y := y*25 + 50;
NewTargetArea[0] := SPS_CropArea(marpis_Max(0, x - 125), marpis_Max(0, y - 125),
marpis_Min(MaxW, x + 125), marpis_Min(MaxH, y + 125), Worldmap[0]);

SPS_FindMapInMap(Result.x, Result.y, NewTargetArea, Minimap, tol, FoundMatches);
Result.x := Result.x*5 + 50;
Result.y := Result.y*5 + 50;
end;

////// EXPORTING /////////////////////////////////////////////////////////////

procedure SetPluginMemoryManager(MemMgr : TMemoryManager); stdcall; export;
begin
SetMemoryManager(MemMgr);
end;

function GetTypeCount(): Integer; stdcall; export;
begin
Result := 2;
end;

function GetTypeInfo(x: Integer; var sType, sTypeDef: string): integer; stdcall; export;
begin
case x of
0: begin
sType := 'T3DIntegerArray';
sTypeDef := 'array of T2DIntegerArray;';
end;
1: begin
sType := 'T4DIntegerArray';
sTypeDef := 'array of T3DIntegerArray;';
end;
else
x := -1;
end;
Result := x;
end;

function GetFunctionCount(): Integer; stdcall; export;
begin
Result := 4;
end;

function GetFunctionCallingConv(x : Integer) : Integer; stdcall; export;
begin
Result := 0;
case x of
0..3: Result := 1;
end;
end;

function GetFunctionInfo(x: Integer; var ProcAddr: Pointer; var ProcDef: PChar): Integer; stdcall; export;
begin
case x of
0:
begin
ProcAddr := @SPS_FindMapInMap;
StrPCopy(ProcDef, 'function SPS_FindMapInMap(out fx, fy: integer; LargeMap: T4DIntegerArray; SmallMap: T3DIntegerArray; tol: extended; out FoundMatches: integer): integer;');
end;
1:
begin
ProcAddr := @SPS_BitmapToMap;
StrPCopy(ProcDef, 'function SPS_BitmapToMap(bmp: TMufasaBitmap; SideLength: integer): T3DIntegerArray;');
end;
2:
begin
ProcAddr := @SPS_GetProfile;
StrPCopy(ProcDef, 'function SPS_GetProfile(View: TMufasaBitmap): integer;');
end;
3:
begin
ProcAddr := @SPS_GetMyPosEx;
StrPCopy(ProcDef, 'function SPS_GetMyPosEx(ViewBitmap: TMufasaBitmap; AreaBitmaps: array of TMufasaBitmap; tol: extended; out FoundMatches, AreaIndex: integer): TPoint;');
end;
else
x := -1;
end;
Result := x;
end;

exports SetPluginMemoryManager;
exports GetTypeCount;
exports GetTypeInfo;
exports GetFunctionCount;
exports GetFunctionInfo;
exports GetFunctionCallingConv;

begin
end.

Nava2
12-09-2011, 11:59 PM
Not sure on the actual post. But you could just add "math" to the uses, by the way. :)

marpis
12-10-2011, 12:12 AM
Not sure on the actual post. But you could just add "math" to the uses, by the way. :)

Well, Harry compiled the plugin.

marpis
12-10-2011, 11:16 AM
And by the way, I have pretty much written all the code for SPS2, so now I just need to make it work.
So the faster we solve this bug, the faster we all get to enjoy from the benefits of SPS 2.0.

Coh3n
12-10-2011, 07:42 PM
Try using var instead of out in GetMyPosEx. Also, can you post the whole procedure where you call

P := SPS_GetMyPosEx(Minimap, AreaBitmaps, SPS_Tolerance, FoundMatches, map);

marpis
12-10-2011, 10:09 PM
Try using var instead of out in GetMyPosEx. Also, can you post the whole procedure where you call

P := SPS_GetMyPosEx(Minimap, AreaBitmaps, SPS_Tolerance, FoundMatches, map);


Hmm now I see that, it actually is var in the most recent compiled dll.
I think you should inspect the whole sps2.simba, found behind the link in the first post.

But, here is SPS_GetMyPos: TPoint; function
// SPS2
function SPS_GetMyPos: TPoint;
var
Minimap: TMufasaBitmap;
AreaBitmaps: array of TMufasaBitmap;
AreaNames: TStringArray;
t, map, FoundMatches, i: integer;
P: TPoint;
begin
Result := Point(-1, -1);

if (SPS_Tolerance = 0) then
SPS_Tolerance := 0.3;

if (SPS_MinimumMatches = 0) then
SPS_MinimumMatches := 0.5;

if not LoggedIn then
Exit;

{
// we should just rotate the minimap according to the minimap angle.
if (inRange(round(rs_GetCompassAngleDegrees), 10, 350)) then
ClickNorth(True);
}

t := getSystemTime;
Minimap := SPS_GatherMinimap;

if Length(SPS_Areas) = 0 then
SPS_UseProfiledAreas(Minimap);

try
AreaBitmaps := SPS_GetAllAreasTMufasaBitmap;
AreaNames := SPS_GetAllAreasString;
P := SPS_GetMyPosEx(Minimap, AreaBitmaps, SPS_Tolerance, FoundMatches, map);

if (FoundMatches / 2500.0) >= SPS_MinimumMatches then
begin
SPS_Failures := 0;
P := SPS_LocalToGlobal(AreaNames[map], Result.X, Result.Y);
Result := P;
SPS_LastPos := P;
SPS_LastArea := AreaNames[map];

// make the current area the first one to search next time
swap(SPS_Areas[0], SPS_Areas[map]);
SPS_PredictNextAreas;
end else
begin
// position not found, look from the whole world or quit
writeln('[SPS] Lost track of location! Trying to relocate...');
SPS_ClearAllAreas;
Inc(SPS_Failures);
if SPS_Failures > 2 then
begin
Writeln('sps failzzz?');
Minimap.Free;
TerminateScript;
end;
Result := SPS_GetMyPos; // awezome recursive! Will call UseProfiledAreas
end;

except
Writeln('[SPS] ERROR in SPS_GetMyPos: ' + ExceptionToString(ExceptionType, ExceptionParam));

finally
for i := high(AreaBitmaps) downto 0 do
AreaBitmaps[i].Free;

if (SPS_Debug) then
writeln(format('[SPS] GetMyPos: Finished in %d ms. Location = %s',
[getSystemTime - t, toStr(result)]));
end;
end;

Coh3n
12-11-2011, 12:28 AM
Did you add SPS_Tolerance and SPS_MinimumMatches as globals vars? I think they should be part of the TSurface type, unless you removed that altogether? I can't see what the type mismatch would be from. I'll try to look at it more when I have time.

marpis
12-11-2011, 01:31 PM
Did you add SPS_Tolerance and SPS_MinimumMatches as globals vars? I think they should be part of the TSurface type, unless you removed that altogether? I can't see what the type mismatch would be from. I'll try to look at it more when I have time.

Yep, in SPS2 there's no such thing as TSurface.

Coh3n
12-11-2011, 06:47 PM
Yep, in SPS2 there's no such thing as TSurface.I see. How do you use different maps? Will have to look at SPS2 I guess. :)

Narcle
12-11-2011, 08:35 PM
Only thing that I see could cause a problem is
if (SPS_Tolerance = 0) then
SPS_Tolerance := 0.3;

maybe
(SPS_Tolerance = 0.0)
instead?

Either that or something with getting TMufasaBitmap.

marpis
12-12-2011, 09:59 PM
Only thing that I see could cause a problem is
if (SPS_Tolerance = 0) then
SPS_Tolerance := 0.3;

maybe
(SPS_Tolerance = 0.0)
instead?

Either that or something with getting TMufasaBitmap.

Nopes, wasn't the integer/extended thing :-\
I'm really frustrated! I wanna get this solved...

Coh3n
12-12-2011, 10:27 PM
Can someone build the plugin from the first post. I still can't get Laz to work properly, and it's too frustrating trying anymore.

marpis
12-13-2011, 09:45 AM
Can someone build the plugin from the first post. I still can't get Laz to work properly, and it's too frustrating trying anymore.

Harry has built it already, it can be found behind the link in the first post.

Wizzup?
12-13-2011, 10:17 AM
Just a suggestion:




function GetTypeInfo(x: Integer; var sType, sTypeDef: string): integer; stdcall; export;
begin
case x of
0: begin
sType := 'T3DIntegerArray';
sTypeDef := 'array of array of array of integer;';
end;
1: begin
sType := 'T4DIntegerArray';
sTypeDef := 'array of array of array of array of integer;';
end;
else
x := -1;
end;
Result := x;
end;


E: That's probably not it. What about adding TMufasaBitmapArray?

marpis
12-13-2011, 01:25 PM
Just a suggestion:




function GetTypeInfo(x: Integer; var sType, sTypeDef: string): integer; stdcall; export;
begin
case x of
0: begin
sType := 'T3DIntegerArray';
sTypeDef := 'array of array of array of integer;';
end;
1: begin
sType := 'T4DIntegerArray';
sTypeDef := 'array of array of array of array of integer;';
end;
else
x := -1;
end;
Result := x;
end;


E: That's probably not it. What about adding TMufasaBitmapArray?


Worth the try I guess. I'll do that later this week.