Advertisement
Janilabo

RSCR Text development #7

Aug 2nd, 2014
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 11.24 KB | None | 0 0
  1. const
  2.   BUFFER = 1; // 1-3!
  3.   TEXT_LENGTH = 700; // Maximum length to use for GetText..
  4.   SCAN_SHADOW = True; // Look for shadow pixels in GetText matching?
  5.  
  6. type
  7.   TCharset = record
  8.     chars: array[32..126] of record
  9.       shape: record
  10.         pixels: TPointArray;
  11.         size, width, height: Integer;
  12.         bounds: TBox;
  13.       end;
  14.       shadow: record
  15.         pixels: TPointArray;
  16.         size: Integer;
  17.       end;
  18.       width, height: Integer;
  19.     end;
  20.     max_width, max_height: Integer;
  21.     offset: TPoint;
  22.     loaded: TIntegerArray;
  23.   end;
  24.  
  25. procedure InsertTIA(var arr: TIntegerArray; index: Integer; item: Integer);
  26. var
  27.   i, l, j, k: Integer;
  28. begin
  29.   l := (Length(arr) - 1);
  30.   SetLength(arr, (l + 2));
  31.   j := index;
  32.   k := (l + 1);
  33.   if (j < 0) then
  34.     j := 0
  35.   else
  36.     if (j > k) then
  37.       j := k;
  38.   if (k > j) then
  39.   for i := l downto j do
  40.     arr[(i + 1)] := arr[i];
  41.   arr[j] := item;
  42. end;
  43.  
  44. procedure AppendTIA(var arr: TIntegerArray; item: Integer);
  45. var
  46.   l: Integer;
  47. begin
  48.   l := (Length(arr) + 1);
  49.   SetLength(arr, l);
  50.   arr[(l - 1)] := item;
  51. end;
  52.  
  53. function LoadCharset(path: string): TCharset;
  54. var
  55.   h, i, j, k, g, v, l, w, s, p: Integer;
  56.   b: TStringArray;
  57.   n: string;
  58.   d: Integer;
  59. begin
  60.   b := GetFiles(path, 'bmp');
  61.   h := High(b);
  62.   l := 0;
  63.   Result.max_width := 0;
  64.   Result.max_height := 0;
  65.   Result.offset := Point(0, 0);
  66.   SetLength(Result.loaded, 0);
  67.   for i := 0 to h do
  68.   begin
  69.     n := Copy(b[i], 1, (Length(b[i]) - 4));
  70.     if (n = ExtractFromStr(b[i], Numbers)) then
  71.     begin
  72.       v := StrToInt(n);
  73.       if InRange(v, 32, 126) then
  74.       begin
  75.         d := LoadBitmap(path + b[i]);
  76.         GetBitmapSize(d, Result.chars[v].width, Result.chars[v].height);
  77.         if (Result.chars[v].width > Result.max_width) then
  78.           Result.max_width := Result.chars[v].width;
  79.         if (Result.chars[v].height > Result.max_height) then
  80.           Result.max_height := Result.chars[v].height;
  81.         if (v <> 32) then
  82.         begin
  83.           FindColorsBitmap(d, Result.chars[v].shape.pixels, 16777215);
  84.           FindColorsBitmap(d, Result.chars[v].shadow.pixels, 255);
  85.           Result.chars[v].shape.bounds := GetTPABounds(Result.chars[v].shape.pixels);
  86.           if (Result.chars[v].shape.bounds.X1 > Result.offset.X) then
  87.             Result.offset.X := Result.chars[v].shape.bounds.X1;
  88.           if (Result.chars[v].shape.bounds.Y1 > Result.offset.Y) then
  89.             Result.offset.Y := Result.chars[v].shape.bounds.Y1;
  90.           Result.chars[v].shape.width := ((Result.chars[v].shape.bounds.X2 - Result.chars[v].shape.bounds.X1) + 1);
  91.           Result.chars[v].shape.height := ((Result.chars[v].shape.bounds.Y2 - Result.chars[v].shape.bounds.Y1) + 1);
  92.           Result.chars[v].shape.size := Length(Result.chars[v].shape.pixels);
  93.           Result.chars[v].shadow.size := Length(Result.chars[v].shadow.pixels);
  94.           w := Result.chars[v].shape.width;
  95.           s := Result.chars[v].shape.size;
  96.           p := -1;
  97.           k := (l - 1);
  98.           for j := 0 to k do
  99.           begin
  100.             g := Result.loaded[j];
  101.             if ((w > Result.chars[g].shape.width) or ((w = Result.chars[g].shape.width) and (s > Result.chars[g].shape.size))) then
  102.             begin
  103.               p := j;
  104.               Break;
  105.             end;
  106.           end;
  107.           if (p = -1) then
  108.             AppendTIA(Result.loaded, v)
  109.           else
  110.             InsertTIA(Result.loaded, p, v);
  111.         end else
  112.         begin
  113.           Result.chars[v].shape.size := 0;
  114.           AppendTIA(Result.loaded, v);
  115.         end;
  116.         l := (l + 1);
  117.         FreeBitmap(d);
  118.       end;
  119.     end;
  120.   end;
  121.   SetLength(b, 0);
  122. end;
  123.  
  124. function Percentage(percent, source: Extended): Extended;
  125. begin
  126.   case (percent = 0) of
  127.     False: Result := ((percent / 100.0) * source);
  128.     True: Result := 0.0;
  129.   end;
  130. end;
  131.  
  132. function FindColorEx(var TPA: TPointArray; colors: TIntegerArray; XS, YS, XE, YE: Integer): Boolean;
  133. var
  134.   c: TIntegerArray;
  135.   t: TPointArray;
  136.   h, i, j, l, r: Integer;
  137. begin
  138.   h := High(colors);
  139.   if not (h = 0) then
  140.   begin
  141.     r := 0;
  142.     if (h > -1) then
  143.     begin
  144.       t := TPAFromBox(IntToBox(XS, YS, XE, YE));
  145.       l := (Length(t) - 1);
  146.       if (l > -1) then
  147.       begin
  148.         c := GetColors(t);
  149.         SetLength(TPA, (l + 1));
  150.         for i := 0 to l do
  151.           for j := 0 to h do
  152.             if (c[i] = colors[j]) then
  153.             begin
  154.               TPA[r] := t[i];
  155.               r := (r + 1);
  156.               Break;
  157.             end;
  158.       end;
  159.     end;
  160.     SetLength(TPA, r);
  161.     Result := (r > 0);
  162.   end else
  163.     Result := FindColors(TPA, colors[0], XS, YS, XE, YE);
  164. end;
  165.  
  166. {==============================================================================]
  167.   Returns position of item or value that is closest to item in TIA.
  168.   As this method is Binary Searching algorithm, it ONLY works with sorted arrays!
  169.   0 method finds position of either item OR value that is smaller than item.
  170.   1 method finds position of either item OR value that is bigger than item.
  171. [==============================================================================}
  172. function TIABinaryLocateEx(TIA: TIntegerArray; item: Integer; method: Integer): Integer;
  173. var
  174.   i, l, r: Integer;
  175. begin
  176.   Result := High(TIA);
  177.   if (Result > -1) then
  178.   begin
  179.     l := -1;
  180.     while ((Result - l) > 1) do
  181.     begin
  182.       i := ((Result + l) div 2);
  183.       if (item <= TIA[i]) then
  184.         Result := i
  185.       else
  186.         l := i;
  187.     end;
  188.     if not (TIA[Result] = item) then
  189.       if not (method = 1) then
  190.       begin
  191.         r := Result;
  192.         if (TIA[Result] > item) then
  193.         while (Result > -1) do
  194.           if (TIA[Result] > item) then
  195.             Result := (Result - 1)
  196.           else
  197.             Break;
  198.         if not (method = 0) then
  199.           if (Result = -1) then
  200.             Result := r
  201.           else
  202.             if (Abs(TIA[Result] - item) > Abs(TIA[r] - item)) then
  203.               Result := r;
  204.       end else
  205.         if (Result > -1) then
  206.           if (TIA[Result] < item) then
  207.             Result := -1;
  208.   end;
  209. end;
  210.  
  211. function GetTextTPA(pixels, shadow: TPointArray; len: Integer; buffer: Integer; charset: TCharset): string;
  212.   function MatrixMatches(matrix: array of TBoolArray; TPA: TPointArray; offset: TPoint; needed: Integer): Boolean;
  213.   var
  214.     i, l, r: Integer;
  215.   begin
  216.     l := (Length(TPA) - 1);
  217.     r := 0;
  218.     for i := 0 to l do
  219.       if matrix[(TPA[i].X + offset.X)][(TPA[i].Y + offset.Y)] then
  220.       begin
  221.         r := (r + 1);
  222.         if (r >= needed) then
  223.           Break;
  224.       end;
  225.     Result := (r >= needed);
  226.   end;
  227.   function MatrixMatch(matrix: array of TBoolArray; TPA: TPointArray; offset: TPoint): Boolean;
  228.   var
  229.     i, l: Integer;
  230.   begin
  231.     l := (Length(TPA) - 1);
  232.     for i := 0 to l do
  233.       if not matrix[(TPA[i].X + offset.X)][(TPA[i].Y + offset.Y)] then
  234.         Exit(False);
  235.     Result := True;
  236.   end;
  237. var
  238.   b, o, g, q, m, j, d, e, f, t, s, w, h, i, l, k, x, z: Integer;
  239.   matrix: array[0..1] of array of TBoolArray;
  240.   required, columns: TIntegerArray;
  241.   scan, found: Boolean;
  242.   offset: TPoint;
  243.   bounds: TBox;
  244.   listed: TBoolArray;
  245. begin
  246.   Result := '';
  247.   if (High(pixels) > -1) then
  248.   begin
  249.     bounds := GetTPABounds(pixels);
  250.     d := charset.chars[32].width;
  251.     w := (((bounds.X2 + charset.max_width) + 3));
  252.     h := (charset.max_height + 1);
  253.     SetLength(matrix[0], w, h);
  254.     SetLength(listed, w);
  255.     l := (Length(pixels) - 1);
  256.     for i := 0 to l do
  257.     begin
  258.       matrix[0][pixels[i].X][pixels[i].Y] := True;
  259.       listed[pixels[i].X] := True;
  260.     end;
  261.     l := (w - 1);
  262.     z := 0;
  263.     SetLength(columns, w);
  264.     for i := 0 to l do
  265.       if listed[i] then
  266.       begin
  267.         columns[z] := i;
  268.         z := (z + 1);
  269.       end;
  270.     SetLength(listed, 0);
  271.     SetLength(columns, z);
  272.     l := (Length(shadow) - 1);
  273.     scan := (l > -1);
  274.     z := (w - 1);
  275.     s := (Length(charset.loaded) - 1);
  276.     q := 0;
  277.     o := 0;
  278.     b := Max((buffer - 1), 0);
  279.     if scan then
  280.     begin
  281.       SetLength(matrix[1], w, h);
  282.       for i := 0 to l do
  283.         if ((shadow[i].X < w) and (shadow[i].Y < h)) then
  284.           matrix[1][shadow[i].X][shadow[i].Y] := True;
  285.       SetLength(required, (s + 1));
  286.       for i := 0 to s do
  287.       begin
  288.         g := charset.loaded[i];
  289.         required[i] := Round(Percentage(75.0, charset.chars[g].shadow.size));
  290.       end;
  291.     end;
  292.     x := 0;
  293.     while (x < z) do
  294.     begin
  295.       o := x;
  296.       t := -1;
  297.       f := -1;
  298.       j := s;
  299.       for e := 0 to b do
  300.       begin
  301.         i := -1;
  302.         if ((f > -1) or (e = 0)) then
  303.         while (i < j) do
  304.         begin
  305.           i := (i + 1);
  306.           g := charset.loaded[i];
  307.           q := (x + e);
  308.           if not ((q + charset.chars[g].width) > w) then
  309.           begin
  310.             offset := Point(q, 0);
  311.             found := not scan;
  312.             if not found then
  313.               found := MatrixMatches(matrix[1], charset.chars[g].shadow.pixels, offset, required[i]);
  314.             if found then
  315.               if MatrixMatch(matrix[0], charset.chars[g].shape.pixels, offset) then
  316.               begin
  317.                 f := e;
  318.                 t := g;
  319.                 j := i;
  320.                 Break;
  321.               end;
  322.           end;
  323.         end;
  324.       end;
  325.       if (t > -1) then
  326.       begin
  327.         q := (((x + f) - o) + 1);
  328.         if (q > d) then
  329.           Result := (Result + StringOfChar(' ', (q div d)));
  330.         x := ((x + f) + charset.chars[g].width);
  331.         Result := (Result + Chr(t));
  332.         if (Length(Result) >= len) then
  333.         begin
  334.           SetLength(Result, len);
  335.           Exit;
  336.         end;
  337.       end else
  338.         x := (x + 1);
  339.       q := TIABinaryLocateEx(columns, x, 1);
  340.       if (q < 0) then
  341.         Exit;
  342.       x := Max((q - charset.offset.X), x);
  343.     end;
  344.   end;
  345. end;
  346.  
  347. var
  348.   chars: TCharset;
  349.   new, old: string;
  350.   pixels, shadow: TPointArray;
  351.   found: Boolean;
  352.  
  353. function PickTextTPA(var TPA: TPointArray; position: TPoint; colors: TIntegerArray; charset: TCharset): Boolean;
  354. var
  355.   a: TBox;
  356.   w, h: Integer;
  357. begin
  358.   SetLength(TPA, 0);
  359.   Result := False;
  360.   GetClientDimensions(w, h);
  361.   if PointInBox(position, IntToBox(0, 0, (w - 1), (h - 1))) then
  362.   begin
  363.     a := IntToBox(position.X, position.Y, (w - 1), (position.Y + charset.max_height));
  364.     if (a.Y2 < h) then
  365.       Result := FindColorEx(TPA, colors, a.X1, a.Y1, a.X2, a.Y2);
  366.   end;
  367.   if Result then
  368.     OffsetTPA(TPA, Point(-position.X, -position.Y));
  369. end;
  370.  
  371. var
  372.   t, m: Integer;
  373.  
  374. begin
  375.   chars := LoadCharset(ScriptPath + 'RSCR_Main\');
  376.   ActivateClient;
  377.   Wait(1000);
  378.   SetLength(shadow, 0);
  379.   repeat
  380.     found := not SCAN_SHADOW;
  381.     if not found then
  382.       found := PickTextTPA(shadow, Point(6, 5), [0], chars);
  383.     if found then
  384.     begin
  385.       t := GetSystemTime;
  386.       if PickTextTPA(pixels, Point(6, 5), [65535, 16777215, 16776960, 4231423, 255], chars) then
  387.       begin
  388.         m := (GetSystemTime - t);
  389.         new := GetTextTPA(pixels, shadow, TEXT_LENGTH, BUFFER, chars);
  390.         if (new <> '') then
  391.           if (new <> old) then
  392.           begin
  393.             ClearDebug;
  394.             WriteLn(new + ' [' + IntToStr(m) + ' ms.]');
  395.             old := new;
  396.           end;
  397.       end;
  398.     end;
  399.   until IsKeyDown(VK_F12);
  400. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement