SRL Archive - SRL Positioning System

[SPS2] Help me build the new plugin!


marpis

2011-12-04 06:01:18

I'm really not good with plugins really. Could someone build this for me?
I hope it doesn't have too many errors.

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_MakeColorBoxEx(bmp, X * SideLength, Y * SideLength);
end;
end;
end;

function SPS_FindMapInMap(out fx, fy: integer; LargeMap: T4DIntegerArray; SmallMap: T3DIntegerArray; tol: extended; out FoundMatches: integer): integer; register;
var
x, y, HighX, HighY, cm, L: integer;
xx, yy: integer;
Matching, BestMatch: integer;
BoxesLeftInView, SideLength: integer;
BoxesInViewRow, TotBoxesInView: integer;
b: Boolean;
begin
fX := -1;
fY := -1;
BestMatch := 0;
SideLength := 100 / Length(SmallMap);
BoxesInViewRow := 100 / SideLength;
TotBoxesInView := sqr(BoxesInViewRow);
L := Length(LargeMap);
Result := -1;

for cm := 0 to L-1 do
begin
HighX := High(LargeMap[cm]) - BoxesInViewRow - 1;
HighY := High(LargeMap[cm][0]) - BoxesInViewRow - 1;
for x := 0 to HighX do
for y := 0 to HighY do
begin
// Reset these in the beginning of every view (100x100 pixels)
Matching := 0;
BoxesLeftInView := TotBoxesInView;

for xx := (BoxesInViewRow - 1) downto 0 do
for yy := (BoxesInViewRow - 1) downto 0 do
begin
// added 26.11.2011 to improve speed
// will stop going through the area if it's not possibly better than
// the best one found.

if (BoxesLeftInView + Matching) <= BestMatch 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 > BestMatch) then
begin
BestMatch := Matching;
Result := cm;
fX := x;
fY := y;
end;
end;
end;

if (Result > -1) then
begin
// moved outside to remove uncessary calculations in interations.
fX := fX * SideLength + 50; // +50 cause we want the center
fy := fY * SideLength + 50;
FoundMatches := BestMatch;
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 SPS_GetMyPosEx(ViewBitmap: TMufasaBitmap; AreaBitmaps: array of TMufasaBitmap; tol: extended; out FoundMatches, AreaIndex: integer): TPoint; register;
var
x, y, i, L: integer;
MaxW, MaxHH: integer;
Minimap: T3DIntegerArray;
WorldMap: T4DIntegerArray;
NewTargetArea: T3DIntegerArray;
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]);

NewTargetArea := SPS_CropArea(Max(0, x - 125), Max(0, y - 125),
Min(MaxW, x + 125), Min(MaxH, y + 125));

SPS_FindMapInMap(Result.x, Result.y, NewTargetArea, Minimap, tol, FoundMatches);
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.


Harry

2011-12-04 07:23:42

sps.lpr(81,41) Error: Identifier not found "SPS_MakeColorBoxEx"
sps.lpr(98,39) Hint: use DIV instead to get an integer result
sps.lpr(98,21) Error: Incompatible types: got "Extended" expected "LongInt"
sps.lpr(99,37) Hint: use DIV instead to get an integer result
sps.lpr(99,25) Error: Incompatible types: got "Extended" expected "LongInt"
sps.lpr(191,8) Error: Identifier not found "MaxH"
sps.lpr(193,36) Error: Identifier not found "Max"
sps.lpr(193,53) Error: Identifier not found "Max"
sps.lpr(194,36) Error: Identifier not found "Min"
sps.lpr(194,56) Error: Identifier not found "Min"
sps.lpr(194,61) Error: Identifier not found "MaxH"
sps.lpr(196,53) Error: Incompatible type for arg no. 3: Got "T3DIntegerArray", expected "T4DIntegerArray"
sps.lpr(86,10) Hint: Found declaration: SPS_FindMapInMap(out LongInt,out LongInt,T4DIntegerArray,T3DIntegerArray,Extended,out LongInt):LongInt; Register;
sps.lpr(278,4) Fatal: There were 10 errors compiling module, stopping


Seems to have a few small issues.

marpis

2011-12-05 01:22:44

From: Harry
Seems to have a few small issues.


Ok how about now:
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);
end;
end;
end;

function SPS_FindMapInMap(out fx, fy: integer; LargeMap: T4DIntegerArray; SmallMap: T3DIntegerArray; tol: extended; out FoundMatches: integer): integer; register;
var
x, y, HighX, HighY, cm, L: integer;
xx, yy: integer;
Matching, BestMatch: integer;
BoxesLeftInView, SideLength: integer;
BoxesInViewRow, TotBoxesInView: integer;
b: Boolean;
begin
fX := -1;
fY := -1;
BestMatch := 0;
SideLength := 100 div Length(SmallMap);
BoxesInViewRow := 100 div SideLength;
TotBoxesInView := Round(sqr(BoxesInViewRow)*1.0);
L := Length(LargeMap);
Result := -1;

for cm := 0 to L-1 do
begin
HighX := High(LargeMap[cm]) - BoxesInViewRow - 1;
HighY := High(LargeMap[cm][0]) - BoxesInViewRow - 1;
for x := 0 to HighX do
for y := 0 to HighY do
begin
// Reset these in the beginning of every view (100x100 pixels)
Matching := 0;
BoxesLeftInView := TotBoxesInView;

for xx := (BoxesInViewRow - 1) downto 0 do
for yy := (BoxesInViewRow - 1) downto 0 do
begin
// added 26.11.2011 to improve speed
// will stop going through the area if it's not possibly better than
// the best one found.

if (BoxesLeftInView + Matching) <= BestMatch 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 > BestMatch) then
begin
BestMatch := Matching;
Result := cm;
fX := x;
fY := y;
end;
end;
end;

if (Result > -1) then
begin
// moved outside to remove uncessary calculations in interations.
fX := fX * SideLength + 50; // +50 cause we want the center
fy := fY * SideLength + 50;
FoundMatches := BestMatch;
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);
NewTargetArea[0] := SPS_CropArea(marpis_Max(0, x - 125), marpis_Max(0, y - 125),
marpis_Min(MaxW, x + 125), marpis_Min(MaxH, y + 125));

SPS_FindMapInMap(Result.x, Result.y, NewTargetArea, Minimap, tol, FoundMatches);
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.

Harry

2011-12-05 01:26:03

sps.lpr(81,23) Error: Wrong number of parameters specified for call to "SPS_MakeColorBox"
sps.lpr(28,10) Hint: Found declaration: SPS_MakeColorBox(TMufasaBitmap,LongInt,LongInt,LongInt):Dynamic Array Of LongInt;
sps.lpr(210,23) Error: Wrong number of parameters specified for call to "SPS_CropArea"
sps.lpr(151,10) Hint: Found declaration: SPS_CropArea(LongInt,LongInt,LongInt,LongInt,T3DIntegerArray):Dynamic Array Of T2DIntArray;
sps.lpr(296) Fatal: There were 2 errors compiling module, stopping
The message you have entered is too short. Please lengthen your message to at least 3 characters.

marpis

2011-12-05 02:59:16

How about now :p

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; out FoundMatches: integer): integer; register;
var
x, y, HighX, HighY, cm, L: integer;
xx, yy: integer;
Matching, BestMatch: integer;
BoxesLeftInView, SideLength: integer;
BoxesInViewRow, TotBoxesInView: integer;
b: Boolean;
begin
fX := -1;
fY := -1;
BestMatch := 0;
SideLength := 100 div Length(SmallMap);
BoxesInViewRow := 100 div SideLength;
TotBoxesInView := Round(sqr(BoxesInViewRow)*1.0);
L := Length(LargeMap);
Result := -1;

for cm := 0 to L-1 do
begin
HighX := High(LargeMap[cm]) - BoxesInViewRow - 1;
HighY := High(LargeMap[cm][0]) - BoxesInViewRow - 1;
for x := 0 to HighX do
for y := 0 to HighY do
begin
// Reset these in the beginning of every view (100x100 pixels)
Matching := 0;
BoxesLeftInView := TotBoxesInView;

for xx := (BoxesInViewRow - 1) downto 0 do
for yy := (BoxesInViewRow - 1) downto 0 do
begin
// added 26.11.2011 to improve speed
// will stop going through the area if it's not possibly better than
// the best one found.

if (BoxesLeftInView + Matching) <= BestMatch 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 > BestMatch) then
begin
BestMatch := Matching;
Result := cm;
fX := x;
fY := y;
end;
end;
end;

if (Result > -1) then
begin
// moved outside to remove uncessary calculations in interations.
fX := fX * SideLength + 50; // +50 cause we want the center
fy := fY * SideLength + 50;
FoundMatches := BestMatch;
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);
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);
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.

KingKong

2011-12-05 03:42:10

http://fileape.com/dl/KzDNWXi1LRJBnhcL

Thats the plugin, cant upload on here, its too big(i probably added some extra stuff i think?)

Harry

2011-12-05 04:36:12

That one worked, have fun.

KingKong

2011-12-05 05:11:14

From: Harry
That one worked, have fun.


how come mine was bigger than yours?

Harry

2011-12-05 05:11:50

From: KingKong
how come mine was bigger than yours?

Your compiler probably didn't strip the debug symbols or something.

marpis

2011-12-05 08:37:34

Edit: it compiles but I get weird type mismatch errors.

I also noticed a maths error in SPS_FindMapInMap that could cause out of range errors in certain cases.
FindMapInMap can now also process other rectangles too, not only squares.
Here's a fixed source:


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; out FoundMatches: integer): integer; register;
var
x, y, HighX, HighY, cm, L: integer;
xx, yy: integer;
Matching, BestMatch: integer;
BoxesLeftInView: integer;
BoxesInViewX, BoxesInViewY, TotBoxesInView: integer;
b: Boolean;
begin
fX := -1;
fY := -1;
Result := -1;
BestMatch := 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) <= BestMatch 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 > BestMatch) then
begin
BestMatch := Matching;
Result := cm;
fX := x;
fY := y;
end;
end;
end;

if (Result > -1) then
begin
fX := fX * SideLength + 50; // +50 cause we want the center
fy := fY * SideLength + 50;
FoundMatches := BestMatch;
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);
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);
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

2011-12-05 12:40:43

To anyone compiling, make sure you strip the .dll.

http://sourceware.org/binutils/docs-2.16/binutils/strip.html

Harry

2011-12-05 12:59:57

sps.lpr(139,27) Error: Identifier not found "SideLength"
sps.lpr(140,27) Error: Identifier not found "SideLength"
sps.lpr(290,4) Fatal: There were 2 errors compiling module, stopping

Newest one.

marpis

2011-12-05 23:56:55


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; out 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.

Harry

2011-12-06 00:19:19

sps.lpr(98,16) Error: Identifier not found "FoundMathces"
sps.lpr(118,48) Warning: Variable "FoundMatches" does not seem to be initialized
sps.lpr(287,4) Fatal: There were 1 errors compiling module, stopping

Typo I guess. Changed it to Matches and here you go, compiles.

marpis

2011-12-06 12:40:38

From: Harry
Typo I guess. Changed it to Matches and here you go, compiles.


Thanks for trying to solve the problem but if you replace FoundMatches with Matching, it messes up the algorithm. I guess the problem was that I had FoundMatches as an "out" parameter rather than a "var".

Let's try changing that parameter in SPS_FindMapInMap.
Here's a fixed version (only change is "out" -> "var")


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.

Harry

2011-12-06 12:45:14

sps.lpr(189,75) Hint: Variable "FoundMatches" does not seem to be initialized

Still compiles fine (still had typo in it) but I bet that hint isn't good.

marpis

2011-12-06 13:36:33

Ok, well… In the beginning of SPS_FindMapInMap I see this:
FoundMathces := 0; :rolleyes:

Oh dear me. Weird that it compiled anyway.

Harry

2011-12-07 03:00:12

Yeah, I changed that when I compiled it. Just bump again if you have new stuff needing to be compiled :)

marpis

2011-12-07 04:56:07

I'd like everyone to try this
http://villavu.com/forum/showpost.php?p=855981&postcount=16
and tell me if they get the same error, and try to figure out where it spawns from.

Thanks! :)

marpis

2011-12-14 09:52:20

BLA BLA BLA BLA


I made another one, let's try if it works.
I'm also making SPS support the whole round minimap, not only a 100x100 pixel square from the center of it, that's just too small.

library sps;

{$mode objfpc}{$H+}

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

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

function SPS_ColorBoxesMatchInline(B1, B2: TIntegerArray; tol: extended): boolean; inline;
var
oneMinusTol, tolPlusOne: extended;
begin
Result := False;

if (B1[0] = -1) or (B2[0] = -1) then
Exit;

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;

for x := (x1 + SideLength - 1) downto x1 do
for y := (y1 + SideLength - 1) downto y1 do
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;

procedure SPS_FilterMinimap(var Minimap: T3DIntegerArray);
var
Hi: integer;
x, y: integer;
SL: extended;
begin
Hi := High(Minimap);
case Hi of
6: SL := 20.0;
69: SL := 2.0;
end;

for x := 0 to Hi do
for y := 0 to Hi do
if Hypot(Abs(70 - x * SL), Abs(70 - y * SL)) > 70 then
Minimap[x][y] := [-1, -1, -1];
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 FilterMinimap(

function SPS_FindMapInMap(var 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 SPS_GetMyPosEx(ViewBitmap: TMufasaBitmap; AreaBitmaps: TMufasaBitmapArray; tol: extended; var 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, 20);
SPS_FilterMinimap(Minimap);

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

AreaIndex := SPS_FindMapInMap(x, y, Worldmap, Minimap, tol, FoundMatches);

SetLength(Worldmap, 1);
Worldmap[0] := SPS_BitmapToMap(AreaBitmaps[AreaIndex], 2);

Minimap := SPS_BitmapToMap(ViewBitmap, 2);
SPS_FilterMinimap(Minimap);

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

SetLength(NewTargetArea, 1);
x := x*20 + 50;
y := y*20 + 50;
NewTargetArea[0] := SPS_CropArea(Max(0, x - 100), Max(0, y - 100),
Min(MaxW, x + 100), Min(MaxH, y + 100), Worldmap[0]);

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

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

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

function GetTypeCount(): Integer; stdcall; export;
begin
Result := 3;
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;
2: begin
sType := 'TMufasaBitmapArray';
sTypeDef := 'array of TMufasaBitmap';
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(var fx, fy: integer; LargeMap: T4DIntegerArray; SmallMap: T3DIntegerArray; tol: extended; var 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.

KingKong

2011-12-14 16:52:04

sps.lpr(70,27) Warning: range check error while evaluating constants
sps.lpr(70,31) Warning: range check error while evaluating constants
sps.lpr(70,31) Error: range check error in set constructor or duplicate set element
sps.lpr(70,35) Warning: range check error while evaluating constants
sps.lpr(70,35) Error: range check error in set constructor or duplicate set element
sps.lpr(70,26) Error: Incompatible types: got "Set Of Byte" expected "TIntegerArray"
sps.lpr(203,37) Hint: Local variable "y" does not seem to be initialized
sps.lpr(203,34) Hint: Local variable "x" does not seem to be initialized
sps.lpr(309) Fatal: There were 3 errors compiling module, stopping

Harry

2011-12-14 16:59:55

sps.lpr(70,27) Warning: range check error while evaluating constants
sps.lpr(70,31) Warning: range check error while evaluating constants
sps.lpr(70,31) Error: range check error in set constructor or duplicate set element
sps.lpr(70,35) Warning: range check error while evaluating constants
sps.lpr(70,35) Error: range check error in set constructor or duplicate set element
sps.lpr(70,26) Error: Incompatible types: got "Set Of Byte" expected "TIntegerArray"
sps.lpr(125,16) Error: Identifier not found "FoundMathces"
sps.lpr(203,37) Hint: Local variable "y" does not seem to be initialized
sps.lpr(203,34) Hint: Local variable "x" does not seem to be initialized
sps.lpr(308,4) Fatal: There were 4 errors compiling module, stopping

The most recent one still has the dyslexic typo in it :p Not sure why kingkong didn't get that error.

KingKong

2011-12-14 20:27:34

From: Harry

sps.lpr(125,16) Error: Identifier not found "FoundMathces"
The most recent one still has the dyslexic typo in it :p Not sure why kingkong didn't get that error.


That one? I changed it to FoundMatches thats why :sasmokin:

marpis

2011-12-16 16:53:32

I have no idea what those errors mean. Here I tried to fix the "Set of byte <> TIntegerArray" problem, but I'd be very happy if you guys could help me out with this one!


library sps;

{$mode objfpc}{$H+}

uses
Classes, sysutils, FileUtil, Interfaces, mufasatypes, bitmaps, math; // btw note that I've added math to uses, is this ok??

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

function SPS_ColorBoxesMatchInline(B1, B2: TIntegerArray; tol: extended): boolean; inline;
var
oneMinusTol, tolPlusOne: extended;
begin
Result := False;

if (B1[0] = -1) or (B2[0] = -1) then
Exit;

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;

for x := (x1 + SideLength - 1) downto x1 do
for y := (y1 + SideLength - 1) downto y1 do
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;

procedure SPS_FilterMinimap(var Minimap: T3DIntegerArray);
var
Hi: integer;
x, y: integer;
SL: extended;
NullArray: TIntegerArray;
begin
Hi := High(Minimap);
SetLength(NullArray, 3);
NullArray[0] := -1;
NullArray[1] := -1;
NullArray[2] := -1;

case Hi of
6: SL := 20.0;
69: SL := 2.0;
end;

for x := 0 to Hi do
for y := 0 to Hi do
if Hypot(Abs(70 - x * SL), Abs(70 - y * SL)) > 70 then
Minimap[x][y] := NullArray;
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(var 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;
FoundMatches := 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 SPS_GetMyPosEx(ViewBitmap: TMufasaBitmap; AreaBitmaps: TMufasaBitmapArray; tol: extended; var FoundMatches, AreaIndex: integer): TPoint; register;
var
x, y, i, L: integer;
MaxW, MaxH: integer;
Minimap: T3DIntegerArray;
WorldMap: T4DIntegerArray;
NewTargetArea: T4DIntegerArray;
begin
x := 0;
y := 0;
L := Length(AreaBitmaps);
SetLength(Worldmap, L);
Dec(L);

Minimap := SPS_BitmapToMap(ViewBitmap, 20);
SPS_FilterMinimap(Minimap);

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

AreaIndex := SPS_FindMapInMap(x, y, Worldmap, Minimap, tol, FoundMatches);

SetLength(Worldmap, 1);
Worldmap[0] := SPS_BitmapToMap(AreaBitmaps[AreaIndex], 2);

Minimap := SPS_BitmapToMap(ViewBitmap, 2);
SPS_FilterMinimap(Minimap);

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

SetLength(NewTargetArea, 1);
x := x*20 + 50;
y := y*20 + 50;
NewTargetArea[0] := SPS_CropArea(Max(0, x - 100), Max(0, y - 100),
Min(MaxW, x + 100), Min(MaxH, y + 100), Worldmap[0]);

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

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

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

function GetTypeCount(): Integer; stdcall; export;
begin
Result := 3;
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;
2: begin
sType := 'TMufasaBitmapArray';
sTypeDef := 'array of TMufasaBitmap';
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(var fx, fy: integer; LargeMap: T4DIntegerArray; SmallMap: T3DIntegerArray; tol: extended; var 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

2011-12-16 17:36:46

 if Hypot(Abs(70 - x * SL), Abs(70 - y * SL)) > 70 then
->

var
...
const
70sqr = 70*70;
...
if (sqr(70 - x * SL) + sqr(70 - y * SL) > 70sqr) then

Also, "profiles" should really be stored as bits in an integer.. rather than the current way. Its much faster for converting each time. :)

nielsie95

2011-12-16 17:57:51

You should really just get Lazarus yourself :p

marpis

2011-12-16 18:06:46

From: nielsie95
You should really just get Lazarus yourself :p


I will as soon as I have enough time :D Which will be in January.
But thanks!

Nava2

2011-12-16 18:37:53

function SPS_GetProfile(View: TMufasaBitmap): integer; register;
var
i, ii: 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
{ Creates result like:
000000000000b
if first profile is 1 (profile 2)
000100000000b ( == 0x100)
if first is 10, second is 5, third is 9
101001011001 ( == 0xA59)

To extract profile :
p1 = (profile and 0x0F0) shr (1*4)
p2 = (profile and 0xF00) shr (2*4)
}
Result := Result or (ii shl (i*4));
Break;
end;
end;


:>

E: this implementation allows for up to 16 profiles/number.. but each Int can technically store 8 different profile numbers.

Oh, and this is faster!

marpis

2011-12-16 18:48:50

From: Nava2
function SPS_GetProfile(View: TMufasaBitmap): integer; register;
var
i, ii: 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
{ Creates result like:
000000000000b
if first profile is 1 (profile 2)
000100000000b ( == 0x100)
if first is 10, second is 5, third is 9
101001011001 ( == 0xA59)

To extract profile :
p1 = (profile and 0x0F0) shr (1*4)
p2 = (profile and 0xF00) shr (2*4)
}
Result := Result or (ii shl (i*4));
Break;
end;
end;


:>

E: this implementation allows for up to 16 profiles/number.. but each Int can technically store 8 different profile numbers.

Oh, and this is faster!


I have no clue of that shit :) Other than that it's kinda messy and future developers would have to spend years to solve what it does.
Speed is not important at all in that function, since it's only called once every SPS_GetMyPos.

Nava2

2011-12-16 19:01:12

From: marpis
I have no clue of that shit :) Other than that it's kinda messy and future developers would have to spend years to solve what it does.
Speed is not important at all in that function, since it's only called once every SPS_GetMyPos.


Its not messy.. also thats why I put in the explaination.

Its very straight forward, it just stores the numbers in the bits rather than in base 10. :/

Allows for like FFFFFFFF as a profile, AKA 16^8 different possible profiles. Flexibility much?

Harry

2011-12-16 19:19:30

From: nielsie95
You should really just get Lazarus yourself :p

Why's yours so small compared to mine? I used best compression and I think I have debug symbols turned off.