Jump to content
MarkD

Make Scar find/read/save text

Recommended Posts

Well, that worked pretty good :-)

 

[scar]program FindTextBox;

var

TxtBox,x,y,t,length: Integer;

List: TPointArray;

Bmp: TSCARBitmap;

Cl: TSCARClient;

 

Procedure InitDTM;

Begin

TxtBox := DTMFromString('78DA6334666260D807C448606F3E2F986684F' +

'219CD81F21750D5945AB1A1AA0903CAEF4755F3EB58148A1A007F' +

'110728');

End;

 

Procedure InitBMP;

Begin

Bmp := TSCARBitmap.Create('');

Bmp := GetClient.Capture;

Cl := SetClient(TSCARBitmapClient.Create(Bmp));

end;

 

begin

ClearDebug;

InitDTM; //Load DTM

InitBMP; //Load BMP

SetLength(List, 40); //reserve some playground

List[0] := Point(0,0); //make sure there is at least something

//to prevent issues when searching

for t := 0 to 19 do

begin

if(FindDTM(TxtBox,x,y,0,0,1680,1050))

then begin

WriteLn(x);

WriteLn(y);

//MoveMouse(x,y); //point to match

//ClickMouse(x,y,False);

Wait(200); //for debug

Bmp.Pixels[x,y] := clRed; //paint it

List[t] := Point(x,y); //add to list

//ClickMouse(715,949,False);

end;

end;

SetClient(Cl).Free;

Bmp.Free;

length := SizeOf(List);

for t := 0 to length do

begin

// WriteLn(List[t]);

end;

end.[/scar]

 

I have been looking for a TPointToStr function, but it isn't really necessary. I'll probably erase that bit in the future.

Mouse actions don't work on canvas, so I guess I'll have to find the DTMs first, set the client back to my browser and start clicking there. Shouldn't be to much of a problem.

 

The problems with OCR still persist, so I'll try to put things together first (implement DTM in main program and do a little clean up) and give OCR another try. Perhaps OCR gives less trouble when reading from canvas then directly from screen, we'll see.

Link to comment
Share on other sites

Well, that worked pretty good :-)

 

[scar]program FindTextBox;

var

TxtBox,x,y,t,length: Integer;

List: TPointArray;

Bmp: TSCARBitmap;

Cl: TSCARClient;

 

Procedure InitDTM;

Begin

TxtBox := DTMFromString('78DA6334666260D807C448606F3E2F986684F' +

'219CD81F21750D5945AB1A1AA0903CAEF4755F3EB58148A1A007F' +

'110728');

End;

 

Procedure InitBMP;

Begin

Bmp := TSCARBitmap.Create('');

Bmp := GetClient.Capture;

Cl := SetClient(TSCARBitmapClient.Create(Bmp));

end;

 

begin

ClearDebug;

InitDTM; //Load DTM

InitBMP; //Load BMP

SetLength(List, 40); //reserve some playground

List[0] := Point(0,0); //make sure there is at least something

//to prevent issues when searching

for t := 0 to 19 do

begin

if(FindDTM(TxtBox,x,y,0,0,1680,1050))

then begin

WriteLn(x);

WriteLn(y);

//MoveMouse(x,y); //point to match

//ClickMouse(x,y,False);

Wait(200); //for debug

Bmp.Pixels[x,y] := clRed; //paint it

List[t] := Point(x,y); //add to list

//ClickMouse(715,949,False);

end;

end;

SetClient(Cl).Free;

Bmp.Free;

length := SizeOf(List);

for t := 0 to length do

begin

// WriteLn(List[t]);

end;

end.[/scar]

 

I have been looking for a TPointToStr function, but it isn't really necessary.

That's really simple to do, here:

 

[scar]function PointToStr(pt: TPoint): string;

begin

Result := (IntToStr(pt.X) + ',' + IntToStr(pt.Y));

end;

 

function CoordsToStr(X, Y: Integer): string;

begin

Result := (IntToStr(X) + ',' + IntToStr(Y));

end;

 

begin

WriteLn(PointToStr(Point(Random(101), Random(101))));

WriteLn(CoordsToStr(Random(101), Random(101)));

end.[/scar]

 

-Jani

Link to comment
Share on other sites

So, the current version of the project:

[scar]//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//

// Title: TBRPG gatherer (Ikariam version) //

// Purpose: Gathering information from TBRPGs //

// Status: Work In Progress //

// Author: MarkD aka MatVis //

// //

// To do: //

// - after DTM, switch back to client, click//

// coords, read data and return to BMP //

// - OCR //

// //

// Thanks to all who've helped! //

//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//

 

program TBRPGgIV;

 

var

x_a,y_a : array [0..5] of Integer;

xi,yi,watercheck,water,TxtBox,x,y,t,a_i,length : Integer;

List: TPointArray;

Bmp: TSCARBitmap;

Cl: TSCARClient;

 

//list of procedures

procedure MoveNClick(mx,my : integer);

begin

Wait(632);

MoveMouse(mx,my);

Wait(221);

MouseBtnDown(mx,my, False);

Wait(198);

MouseBtnUp(mx + 38, my + 2, False);

end;

 

Procedure InitDTM;

Begin

TxtBox := DTMFromString('78DA6334666260D807C448606F3E2F986684F' +

'219CD81F21750D5945AB1A1AA0903CAEF4755F3EB58148A1A007F' +

'110728');

End;

 

procedure InitXYArrays;

begin

for a_i := 0 to 5 do

begin

x_a[a_i] := a_i+1;

y_a[a_i] := a_i+1;

end;

end;

 

Procedure InitBMP;

Begin

Bmp := TSCARBitmap.Create('');

Bmp := GetClient.Capture;

Cl := SetClient(TSCARBitmapClient.Create(Bmp));

end;

 

Procedure FreeBMP;

Begin

SetClient(Cl).Free;

Bmp.Free;

end;

 

function PointToStr(pt: TPoint): string;

begin

Result := (IntToStr(pt.X) + ',' + IntToStr(pt.Y));

end;

 

//main program

begin

ClearDebug;

InitDTM;

InitXYArrays;

SetLength(List, 30); //reserve some playground

List[0] := Point(0,0); //make sure there is at least something

//to prevent issues when searching

water := 12418074; //define water

//var 12288039 11564307 12222763

 

for xi := 0 to 1 do

begin

Wait(697);

 

for yi := 0 to 2 do

begin

MoveNClick(594,949);

TypeText(IntToStr(x_a[xi])); //give new coords for left box

 

MoveNClick(658,949);

TypeText(IntToStr(y_a[yi])); //give new coords for right box

 

Wait(818);

MoveMouse(715,949);

Wait(557);

ClickMouse(715,949,False); //click go

Wait(567);

watercheck := GetColor(945,600);

WriteLn(IntToStr(watercheck));

if ((watercheck = water)) then //if there is water instead of an island,

Continue; //skip to next coordinate

Wait(121);

MoveMouse(945,600); //move mouse to island

Wait(420);

ClickMouse(945,600,False); //click island

 

//switching to island view

 

InitBMP;

for t := 0 to 19 do

begin

if(FindDTM(TxtBox,x,y,0,0,1680,1050))

then begin

WriteLn(x);

WriteLn(y);

Bmp.Pixels[x,y] := clRed; //paint it

List[t] := Point(x,y); //add to list

end;

 

end;

 

FreeBMP; //destruct

 

length := (SizeOf(List) - 1);

for t := 0 to length do

begin

WriteLn(PointToStr(List[t]));

end;

WriteLn(IntToStr(length));

 

Wait(884);

MoveMouse(80,220);

ClickMouse(80,225,False); //return to world screen

 

//switching to world view

 

end;

 

end;

 

WriteLn('Done');

end.

[/scar]

 

Perhaps OCR isn't even necessary. All characters are selectable, so if there is any way to make SCAR use ctrl+c and store this into a string, it's fine as well. If the storing part is a problem but ctrl+c works, I could copy the text to an instance of notepad and read from there. If ctrl+c doesn't work, I could even try it with the Right mouse button.

Link to comment
Share on other sites

Nice work, MarkD!

 

Btw, replace:

 

[scar]Procedure InitBMP;

Begin

Bmp := TSCARBitmap.Create('');

Bmp := GetClient.Capture;

Cl := SetClient(TSCARBitmapClient.Create(Bmp));

end;[/scar]

 

..with this:

 

[scar]Procedure InitBMP;

Begin

Bmp := GetClient.Capture;

Cl := SetClient(TSCARBitmapClient.Create(Bmp));

end;[/scar]

 

Sorry, it was my bad I used that TSCARBitmap.Create('') there, even though its not needed at all (and actually SHOULDN'T be used, because GetClient.Capture builds the TSCARBitmap)

 

Also, remember to add that FreeDTM to the end of the script, as it is a good habbit to free everything that you have loaded with SCAR.

Link to comment
Share on other sites

The text that you have entered is too long (481238 characters). Please shorten it to 25000 characters long.

So the result is missing.

 

Couldn't figure out why Bmp should be filled twice, now I know why. It shouldn't :-)

 

I've been trying to get some reading done. So I started Notepad (not the ++ version, redefining fonts is a pain in the * there) and typed ' More text! ' in Verdana 12.

[scar]begin

ClearDebug;

c := LoadCharsFromFont2('Verdana', 12, False, False, False, False);

s := 'More text!'

for x := 1 to 400 do

begin

for y := 1 to 400 do

begin

WriteLn(IsTextAtEx(x,y,s,50,c,false,false,0,0,0));

end;

end;

end.[/scar]

 

I really DON'T recommend you to try this at home. Why?

Successfully executed (2798028,5084 ms)

 

Output (removed).

 

Summary: 0's till ln 110110, 1's till 110145, 0's till 110451, 1's till 132673, 0's till 132898, 1's till 132936, 0's till 133007, a lone zero at 133008 (?), 1's till 133030, 0's till 113111, more like that.

Next question: Is there any usefulness in these numbers? The text was on the first line of notepad, why does it take 275 to the right to find something? Is this because of the tolerance? Are there quicker ways to detect text?

 

And yes, I know it would've been clearer to switch x and y in the increment process (it's in a way reading top to bottom now).

Link to comment
Share on other sites

So, I'm pretty much stuck here.

If I type a simple text in Notepad and use IsTextAt at the upper left coordinate of the first letter, it just says no. Whatever the tolerance is I give, whatever the color is, it just says no.

GetTextAt only gives rubbish.

 

I've tried both with SetFontSmoothing(false) in the script, the darn thing just doesn't give me any clues where to look for the problem.

Is there anyone with experience in SCAR OCR that DID produce a working script? I haven't seen any of them so far.

 

Eventually, I could hack my way around OCR (just click and copy about anything that looks like something valuable, paste it and sort it out later). But I won't. At least not until I've run out of options, but the OCR thingy should be working. So why isn't it?

Link to comment
Share on other sites

you have to disable font smoothing before you start notepad or it won't always update. It's best to just disable font smoothing globally before working with SCAR. On a side-note, you can get the content of the notepad window without OCR with 3.35 :P

 

Yeah that window api again! xD...

 

Remember that FindTextTPA, or w/e. You can use TPA's and other things for text too. You can create a bitmap FROM a font!

 

So if say, we wanted to write our own GetTextAt. I would go about it like this: Get the font's one letter bitmap into memory. Then at (x, y) search from there and all the way to the right as well. So it would be like...while not findbitmap(W); x := x + Width(W). This function would get a lot more complex with all its options though...for like the font's bitmap width and height. At X, Y search in a box with x until the end of the screen or you can set. Then Y would be the font bitmaps height. Then it could try to find the bitmap in the full box or w/e....if you get my idea

 

We could make like a box function for it. FindBitmapBox for x, y for width and height of bitmap, etc, etc.

Edited by LordJashin
Link to comment
Share on other sites

The font smoothing was updated. My entire computer had font smoothing disabled the moment I ran the script (hard not to notice).

 

Perhaps Janilabo has some good idea's, he's the one who wrote GetTextAt. I don't remember a FindTextTPA and I can't find anything like it on the TPA wiki. Yes, we can create bitmaps from fonts (pretty obvious, a font is actually a collection of bitmaps in some way). I'm not entirely sure what you're trying to do though. Are you suggesting to locate the coordinate of the first letter and read it by trial and error (compare it to every character in the alfabet available)?

Link to comment
Share on other sites

Well, not sure if these will help with your problem here, but anyways, I rewrote today my GetTextAt & IsTextAt.

They are now based on GetTextAtEx2, which is a fixed version of GetTextAtEx (with fix for that good ol' width problem of the OCR)

 

Here:

 

function GetTextAtEx2(x, y, Tolerance, Chars: Integer; CheckShadow, CheckOutline: Boolean; MinSpacing, MaxSpacing, TextColor, TextLength: Integer; Strict: Boolean; Range: TCharRange): string;
var
 e, l, t: Integer;
 b: TSCARBitmap;
 s: string;
begin
 if (TextLength < 1) then
   Exit;
 t := TextLength;
 if (t > 9) then
   t := 10;
 while (l < TextLength) do
 begin
   s := GetTextAtEx((x + e), y, Tolerance, Chars, CheckShadow, CheckOutline, MinSpacing, MaxSpacing, TextColor, t, Strict, Range);
   Result := (Result + s);
   l := (l + Length(s));
   if ((l + t) > TextLength) then
     t := (TextLength - l);
   b := CreateBitmapFromText(s, Chars, TextColor);
   e := (e + b.Width);
   b.Free;
 end;
end;

function GetTextAt(x, y, Tolerance, Chars, MinSpacing, MaxSpacing, TextColor, TextLength: Integer; Strict: Boolean; Range: TCharRange): string;
begin
 Result := GetTextAtEx2(x, y, Tolerance, Chars, False, False, MinSpacing, MaxSpacing, TextColor, TextLength, Strict, Range);
end;

function IsTextAt(x, y: Integer; S: string; Tolerance, Chars, MinSpacing, MaxSpacing, TextColor: Integer): Boolean;
begin
 Result := (S = GetTextAtEx2(x, y, Tolerance, Chars, False, False, MinSpacing, MaxSpacing, TextColor, Length(S), True, tr_AllChars));
end;

 

NOTE: I added MinSpacing / MaxSpacing to both of em (GetTextAt / IsTextAt)

Link to comment
Share on other sites

The font smoothing was updated. My entire computer had font smoothing disabled the moment I ran the script (hard not to notice).

 

Perhaps Janilabo has some good idea's, he's the one who wrote GetTextAt. I don't remember a FindTextTPA and I can't find anything like it on the TPA wiki. Yes, we can create bitmaps from fonts (pretty obvious, a font is actually a collection of bitmaps in some way). I'm not entirely sure what you're trying to do though. Are you suggesting to locate the coordinate of the first letter and read it by trial and error (compare it to every character in the alfabet available)?

 

I'm not sure either. But I think fonts are collections of glyphs*, and idk how that works I forget. Janilabo's is good! I remember lols!

 

GetTextAt, uses X, Y position. For the X pos, to the end of the screen on the X-axis or width provided GetTextAt will try to get the text. Now does GetTextAt use the Y efficient enough? For the Y, I think you should do it like this. For the highest height of the bitmaps for the font put in to GetTextAT, use that as a variable. Lets say the highest height is 60.

 

Idk how GetTextAt works exactly. But I imagine that it just moves X over and searchs for the bitmap again. There is no changes in Y? So i think there should be. Because when I use GetTextAt, or EX or W/E I want it to do a BOX. Not just at that particular Y value. What if the text is one pixel higher?

 

Scenario: All the text you are trying to get is at Y: 300. But you search at 299. So nothing shows up. BUT if you said like: from 300-400. BOOM box, and we get the text magically somehow...

 

Something like that...

 

tldr;

 

Bring in xs, ys, xe, ye for the searching!!! Or just for the Y axis

Link to comment
Share on other sites

I'm not sure either. But I think fonts are collections of glyphs*, and idk how that works I forget. Janilabo's is good! I remember lols!

 

GetTextAt, uses X, Y position. For the X pos, to the end of the screen on the X-axis or width provided GetTextAt will try to get the text. Now does GetTextAt use the Y efficient enough? For the Y, I think you should do it like this. For the highest height of the bitmaps for the font put in to GetTextAT, use that as a variable. Lets say the highest height is 60.

 

Idk how GetTextAt works exactly. But I imagine that it just moves X over and searchs for the bitmap again. There is no changes in Y? So i think there should be. Because when I use GetTextAt, or EX or W/E I want it to do a BOX. Not just at that particular Y value. What if the text is one pixel higher?

 

Scenario: All the text you are trying to get is at Y: 300. But you search at 299. So nothing shows up. BUT if you said like: from 300-400. BOOM box, and we get the text magically somehow...

 

Something like that...

 

tldr;

 

Bring in xs, ys, xe, ye for the searching!!! Or just for the Y axis

Mate, the function you are thinking/dreaming about would be GetTextIn.. :P GetTextAt[Ex] means getting the text from exact coordinate.. And yes, GetTextAt uses extra X in it, but that's for dealing with the problem of current OCR's width problems, which is limited to RuneScape bounds (I think). Freddy will change that in the future with new OCR (the current OCR is still the same old from ancient SCAR versions, IIRC)

 

I'll see what I can come up with GetTextIn.. But I think it is a function that should be built-in to SCAR instead (future OCR), because it really requires as fast speed as possible.

Link to comment
Share on other sites

Mate, the function you are thinking/dreaming about would be GetTextIn.. :P GetTextAt[Ex] means getting the text from exact coordinate.. And yes, GetTextAt uses extra X in it, but that's for dealing with the problem of current OCR's width problems, which is limited to RuneScape bounds (I think). Freddy will change that in the future with new OCR (the current OCR is still the same old from ancient SCAR versions, IIRC)

 

I'll see what I can come up with GetTextIn.. But I think it is a function that should be built-in to SCAR instead (future OCR), because it really requires as fast speed as possible.

 

Yeah! I think GetTextIn might solve problems that people have with GetTextAt(ex)! Thanks for creating these Janilabo!

Link to comment
Share on other sites

Yeah! I think GetTextIn might solve problems that people have with GetTextAt(ex)! Thanks for creating these Janilabo!
Hey mate,

 

I have been thinking about ways to build the function.. But it's not the easiest thing to create, AT ALL... :S

 

This is what I have came up with so far (uses currently SCAR's bugged GetTextAtEx to keep at least somekind of a speed with it):

 

function GetText(XS, YS, XE, YE: Integer; var x, y: Integer; Tolerance, Chars, MinSpacing, MaxSpacing, TextColor, TextLength: Integer; Strict: Boolean; Range: Byte): string;
var
 a: TBox;
 h, i: Integer;
 p: TPointArray;
 b: TSCARBitmap;
 c: TSCARClient;
 o: TPoint;
 t: string;
begin
 if ((XS > XE) or (YS > YE) or (TextColor < 0) or (TextColor > 16777215)) then // To make sure coordinates are somewhat correct and also, the text color is valid. -1 color (all colors) doesn't work with this.. It would make this function very slow, but also hard to develop...
   Exit;
 if FindColorTolEx(p, TextColor, XS, YS, XE, YE, Tolerance) then // If any points matched with TextColor + Tolerance from XS, YS, XE, YE, then we CONTINUE...
 begin            
   if ((XS <> 0) or (YS <> 0)) then
     o := Point((0 - XS), (0 - YS)); // We create an offset point, if XS or YS <> 0.
   a := TPABounds(p); // Area where the points were found..
   if ((a.X1 - 10) > XS) then
     XS := (a.X1 - 10); // We do this just to gain some speed for searching/matching process.
   if ((a.Y1 - 10) > YS) then
     YS := (a.Y1 - 10); // We do this just to gain some speed for searching/matching process.
   b := TSCARBitmap.Create('');
   try
     b.SetSize(((XE + o.X) + 1), ((YE + o.Y) + 1)); // Creating the bitmap for area to look for text. Background of the bitmap is black, matched points will be clWhite.
     h := High(p);
     for i := 0 to h do // We set all the matched points clWhite, that were found using TextColor + Tolerance. 
       b.Pixels[(p[i].X + o.X), (p[i].Y + o.Y)] := clWhite; 
     c := SetClient(TSCARBitmapClient.Create(b)); // We create a bitmap client for SCAR to look the text from..
     try
       for x := XS to XE do
       begin                  
         for y := YS to YE do
         begin
           t := GetTextAtEx((x + o.X), (y + o.Y), Tolerance, Chars, False, False, MinSpacing, MaxSpacing, clWhite, TextLength, Strict, Range);
           if not StartsWith(' ', t) then // We make sure the text found at current position does NOT start with empty space.
             if (Length(Replace(t, ' ', '')) > (TextLength div 2)) then // To check that at least 50% of the matched text characters ARE NOT empty spaces.
               Result := t; // Result was found. 
           if (Result <> '') then
             Break; // Breaking out when the text has been found.
         end;
         if (Result <> '') then
           Break; // Breaking out when the text has been found.
       end;       
       if (Result = '') then
       begin
         x := -1;
         y := -1;
       end;    
     finally
       SetClient(c).Free; // To free the bitmap client
     end; 
     SetLength(p, 0); // Setting the p to 0, just so any memory wont leak.     
   finally          
     b.Free; // Freeing the area bitmap 
   end;     
 end;
end; 

var
 x, y, SWFont: Integer;
 s: string;  

begin
 ClearDebug;
 GetClient.Activate;
 SWFont := LoadChars2(FontsPath + 'SWFont\'); 
 s := GetText(0, 21, 500, 561, x, y, 0, SWFont, 0, 0, 16253176, 10, True, tr_AllChars); 
 WriteLn('s: ' + s + ' [' + IntToStr(x) + ', ' + IntToStr(y) + ']');
 FreeChars2(SWFont);
end.

 

Have fun with it guys! But do note that, it is not perfect at all... But at least it's a start, I guess.

We can always improve it. ;)

Edited by Janilabo
Link to comment
Share on other sites

Hey mate,

 

I have been thinking about ways to build the function.. But it's not the easiest thing to create, AT ALL... :S

 

This is what I have came up with so far (uses currently SCAR's bugged GetTextAtEx to keep at least somekind of a speed with it):

 

function GetText(XS, YS, XE, YE: Integer; var x, y: Integer; Tolerance, Chars, MinSpacing, MaxSpacing, TextColor, TextLength: Integer; Strict: Boolean; Range: Byte): string;
var
 a: TBox;
 h, i: Integer;
 p: TPointArray;
 b: TSCARBitmap;
 c: TSCARClient;
 o: TPoint;
 t: string;
begin
 if ((XS > XE) or (YS > YE) or (TextColor < 0) or (TextColor > 16777215)) then // To make sure coordinates are somewhat correct and also, the text color is valid. -1 color (all colors) doesn't work with this.. It would make this function very slow, but also hard to develop...
   Exit;
 if FindColorTolEx(p, TextColor, XS, YS, XE, YE, Tolerance) then // If any points matched with TextColor + Tolerance from XS, YS, XE, YE, then we CONTINUE...
 begin            
   if ((XS <> 0) or (YS <> 0)) then
     o := Point((0 - XS), (0 - YS)); // We create an offset point, if XS or YS <> 0.
   a := TPABounds(p); // Area where the points were found..
   if ((a.X1 - 10) > XS) then
     XS := (a.X1 - 10); // We do this just to gain some speed for searching/matching process.
   if ((a.Y1 - 10) > YS) then
     YS := (a.Y1 - 10); // We do this just to gain some speed for searching/matching process.
   b := TSCARBitmap.Create('');
   try
     b.SetSize(((XE + o.X) + 1), ((YE + o.Y) + 1)); // Creating the bitmap for area to look for text. Background of the bitmap is black, matched points will be clWhite.
     h := High(p);
     for i := 0 to h do // We set all the matched points clWhite, that were found using TextColor + Tolerance. 
       b.Pixels[(p[i].X + o.X), (p[i].Y + o.Y)] := clWhite; 
     c := SetClient(TSCARBitmapClient.Create(b)); // We create a bitmap client for SCAR to look the text from..
     try
       for x := XS to XE do
       begin                  
         for y := YS to YE do
         begin
           t := GetTextAtEx((x + o.X), (y + o.Y), Tolerance, Chars, False, False, MinSpacing, MaxSpacing, clWhite, TextLength, Strict, Range);
           if not StartsWith(' ', t) then // We make sure the text found at current position does NOT start with empty space.
             if (Length(Replace(t, ' ', '')) > (TextLength div 2)) then // To check that at least 50% of the matched text characters ARE NOT empty spaces.
               Result := t; // Result was found. 
           if (Result <> '') then
             Break; // Breaking out when the text has been found.
         end;
         if (Result <> '') then
           Break; // Breaking out when the text has been found.
       end;       
       if (Result = '') then
       begin
         x := -1;
         y := -1;
       end;    
     finally
       SetClient(c).Free; // To free the bitmap client
     end; 
     SetLength(p, 0); // Setting the p to 0, just so any memory wont leak.     
   finally          
     b.Free; // Freeing the area bitmap 
   end;     
 end;
end; 

var
 x, y, SWFont: Integer;
 s: string;  

begin
 ClearDebug;
 GetClient.Activate;
 SWFont := LoadChars2(FontsPath + 'SWFont\'); 
 s := GetText(0, 21, 500, 561, x, y, 0, SWFont, 0, 0, 16253176, 10, True, tr_AllChars); 
 WriteLn('s: ' + s + ' [' + IntToStr(x) + ', ' + IntToStr(y) + ']');
 FreeChars2(SWFont);
end.

 

Have fun with it guys! But do note that, it is not perfect at all... But at least it's a start, I guess.

We can always improve it. ;)

 

Wow nice!!! You did a great job, lots of code written!

 

I think I want to make some new bitmap functions, and etc for games. I'm tired of writing if FindBitmap lines. I need to learn how OSI's wait function works. Can some one explain that to me again. In the function that it is waiting on, does it wait until it returns true? I don't understand exactly...

Link to comment
Share on other sites

I need to learn how OSI's wait function works. Can some one explain that to me again. In the function that it is waiting on, does it wait until it returns true? I don't understand exactly...
Are you talking about WaitFunction?

 

It's actually pretty straight forward once you get your head wrapped around it:

 

[sCAR]function WaitFunc(Func: function: Boolean; DesiredResult: Boolean; MinWait, MaxWait, MinTotalWait, MaxTotalWait: LongInt): Boolean;[/sCAR]

You pass in a function that takes no arguments and returns a Boolean result. You tell it what you are result waiting for (True or False) and every so often it will run the function, check the result, and if it matches yippee we are done! It will continue to do this periodically until the total time is reached, in which case it returns failure.

 

MinWait and MaxWait are used to generate a randomized WaitTime of how often to execute the function and check it's result. If you don't want randomization make MinWait and MaxWait the same.

 

Similar idea for MinTotalWait and MaxTotalWait are used to generate a random TotalWait (total time before giving up returning failure).

 

Think of it something like this:

repeat
 if Func() = DesiredResult then
   Success!
 otherwise
   Wait RandomRange(MinWait, MaxWait)
until elapsed time = RandomRange(MinTotalWait, MaxTotalWait)

 

So...WaitFunc(@LoginScreen, True, 25, 50, 5000, 6000) would execute the function LoginScreen() every 25..50 milliseconds. This will continue until LoginScreen() returns our desired result of True or 5000..6000 milliseconds have elapsed.

 

Edit: WaitFuncEx allows you to call a function that takes parameters, but afaik it does not work.

Edited by Bixby Sayz
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...