Advertisement
Janilabo

RSCR Text development #9

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