Jump to content
Janilabo

Attention all plugin developers!

Recommended Posts

Ello all,

 

So... I have recently started moving stuff from MSSL include files to plugins, just to gain some speed that I have been really dreaming off of lately.

 

While doing this process, I came up with a new way to export those functions/procedures/types, because I really got annoyed/tired of repeating the same copy+replace+increase (function/type count) task over and over and over again, for each and every command/type that I wanted to add in plugin and then export to SCAR!

It's painful to add shitloads of commands in (for example added 51 yesterday for integer_.dll)...

 

I can guarantee this "method" will make your life MUCH easier - especially when/if you are developing huge plugins with plenty of stuff in em.

 

Worked it out with Delphi 7.2, but I haven't been able to test it with other versions, so... I just hope its compatible with newer editions aswell. :)

I don't see any reason why wouldn't it be, though?

 

Attached the integer_dpr source file, also posted the code from it to pastebin (for those of you who want to view it without Delphi).

Version 1.1 of this methods @pastebin

 

The new method things are between lines 1257 and 1366, so at the bottom part of the source code.

 

EDIT: Couldn't upload .dpr file, because forums targeted it as "invalid file", so I changed that to .txt file. :\

 

Regards,

-Jani

integer_.txt

exports.txt

convert v1.1.scar

convert.scar

integer_v1.1.txt

Edited by Janilabo
Tweaked convert.scar a little more - added in possibility for automatically to set clipboard as SetupCommands data.
Link to comment
Share on other sites

Nice! I wonder how much faster those functions are now?

 

We need to make a program to auto-make libraries for SCAR lols. E.g.: Put in function here, then do all the exporting, ; stdcall; or whatever for us and make a plugin template...

Well, a LOT faster.

 

Timing:

 

{$I MSSL\MSSL.scar}

const
 START = -1000000;
 FINISH = 1000000;

procedure ScriptTerminate;
begin
 MSSL_Unsetup;
end;

{==============================================================================]   
 Explanation: Returns a TIA that contains all the value from start value (aStart)
              to finishing value (aFinish)..                   
[==============================================================================}
function old_MSSL_TIAByRange(aStart, aFinish: Integer): TIntArray;
var
 i, s, f: Integer;
begin
 if (aStart <> aFinish) then
 begin 
   s := Integer(aStart);
   f := Integer(aFinish); 
   SetLength(Result, (IAbs(aStart - aFinish) + 1));
   case (aStart > aFinish) of
     True:
     for i := s downto f do
       Result[(s - i)] := i;
     False: 
     for i := s to f do
       Result[(i - s)] := i;
   end;
 end else
   Result := [integer(aStart)];
end;

var
 TIA: TIntArray;
 t: Integer;

begin
 MSSL_Setup;    
 t := GetSystemTime;
 TIA := MSSL_TIAByRange(START, FINISH);
 WriteLn('NEW: ' + MD5(TIAToStr(TIA)) + ' [' + IntToStr(GetSystemTime - t) + ' ms.]');
 SetLength(TIA, 0);
 t := GetSystemTime;
 TIA := old_MSSL_TIAByRange(START, FINISH);
 WriteLn('OLD: ' + MD5(TIAToStr(TIA)) + ' [' + IntToStr(GetSystemTime - t) + ' ms.]');
 SetLength(TIA, 0);
end.

 

Make sure MSSL is up to date (v1.12).

 

Results for me:

*** [21:03:24(:461)] Massive SCAR Scripting Library v1.12-1 STARTED - process took 16 msec! ***
NEW: c4ef2015a84a89a355911a24021280f5 [265 ms.]
OLD: c4ef2015a84a89a355911a24021280f5 [8019 ms.]
*** [21:03:32(:783)] Massive SCAR Scripting Library v1.12-1 STOPPED - process took 0 msec! ***
Successfully executed (8332.4163 ms)

 

So... :P Thats just 1 example.

But yeah, its really big difference - notable at least!

 

Anyways, about your idea.. It's quite not that easy to create program that would convert functions to Delphi code (from SCAR's PascalScript code, that is)

 

The problem is, that Delphi doesn't accept some styles that PascalScript offers (<3), such as dynamic arrays caused troubles for me..

 

Like, Delphi couldn't setup arrays like this:

 

var
 TIA: TIntArray;

begin
 TIA := [1, 2, 3, 4];
end.

 

At least, 7.2 version wouldn't accept that kind of array setupment. So, I had to replace those kind of parts (some similar ones) with SetLength() + TIA[*] := x; combination.

 

Also, obviously because some functions are built-in in to SCAR's source, you would have to recreate em, like I did for TIAReplaceEx() and TIAContains() in integer_.dll.

 

So, for now it's just better stick with manual way of doing these things really... :)

Although I really would love to have somekind of converter - but with converter I wouldn't learn as much as I do now, that I am doing things manually myself. ;)

Link to comment
Share on other sites

Wow

 

[scar]

NEW: c4ef2015a84a89a355911a24021280f5 [265 ms.]

OLD: c4ef2015a84a89a355911a24021280f5 [8019 ms.]

[/scar]

 

Not a "converter", but a "template" maker thingy, wouldn't have to work at that level of detail (e.g. Delphi vs. Pascal script conventions). But would be cool to have, since every time any of us goes and makes a plugin we have to do this:

 

function Funct1; Stdcall

Exports: Funct1; stdcall/whatever;

Types: Funker1

 

LIKE THAT RIGHT THERE, MUST'VE TAKEN AGESS:

 

[scar]

procedure SetupCommands;

begin

AddCommand(@MSSL_TIAByRange, 'function MSSL_TIAByRange(aStart, aFinish: Integer): TIntArray;');

AddCommand(@MSSL_TIAByRange2Bit, 'function MSSL_TIAByRange2Bit(aStart, aFinish: Integer): TIntArray;');

AddCommand(@MSSL_TIAOfInteger, 'function MSSL_TIAOfInteger(x, count: Integer): TIntArray;');

AddCommand(@MSSL_IntDigits, 'function MSSL_IntDigits(int: Integer): TIntArray;');

AddCommand(@MSSL_StrIsInt, 'function MSSL_StrIsInt(str: string): Boolean;');

AddCommand(@MSSL_IntSetMin, 'procedure MSSL_IntSetMin(var val: Integer; x: Integer);');

AddCommand(@MSSL_IntSetMax, 'procedure MSSL_IntSetMax(var val: Integer; x: Integer);');

AddCommand(@MSSL_IntSetRange, 'procedure MSSL_IntSetRange(var val: Integer; mn, mx: Integer);');

AddCommand(@MSSL_TIASetMin, 'procedure MSSL_TIASetMin(var TIA: TIntArray; x: Integer);');

AddCommand(@MSSL_TIASetMax, 'procedure MSSL_TIASetMax(var TIA: TIntArray; x: Integer);');

AddCommand(@MSSL_TIASetRange, 'procedure MSSL_TIASetRange(var TIA: TIntArray; mn, mx: Integer);');

AddCommand(@MSSL_TIAControlByRange, 'procedure MSSL_TIAControlByRange(var TIA: TIntArray; minimum, maximum: Integer; method: MSSL_TControlMethod);');

AddCommand(@MSSL_TIABuiltWith, 'function MSSL_TIABuiltWith(TIA, allowed: TIntArray): Boolean;');

AddCommand(@MSSL_TIARandomizeEx, 'procedure MSSL_TIARandomizeEx(var TIA: TIntArray; shuffles: Integer);');

AddCommand(@MSSL_TIARandomize, 'procedure MSSL_TIARandomize(var TIA: TIntArray);');

AddCommand(@MSSL_TIADelete, 'function MSSL_TIADelete(var TIA: TIntArray; x: Integer): Boolean;');

AddCommand(@MSSL_TIARemove, 'procedure MSSL_TIARemove(var TIA: TIntArray; x: TIntArray);');

AddCommand(@MSSL_TIAAdd, 'function MSSL_TIAAdd(var TIA: TIntArray; addTIA: TIntArray): Integer;');

AddCommand(@MSSL_TIAPositions, 'function MSSL_TIAPositions(TIA: TIntArray; x: Integer): TIntArray;');

AddCommand(@MSSL_TIAPositionsMulti, 'function MSSL_TIAPositionsMulti(TIA, ints: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAPositionsEx, 'function MSSL_TIAPositionsEx(TIA, ints: TIntArray): TIntArray;');

AddCommand(@MSSL_TIACopyEx, 'function MSSL_TIACopyEx(TIA: TIntArray; pos1, pos2: Integer): TIntArray;');

AddCommand(@MSSL_TIAMove, 'function MSSL_TIAMove(var TIA: TIntArray; oldIndex, newIndex: Integer): Boolean;');

AddCommand(@MSSL_TIAToParts, 'function MSSL_TIAToParts(TIA: TIntArray; method: MSSL_TPartitionMethod; x: Integer): T2DIntArray;');

AddCommand(@MSSL_TIARangeFrom, 'function MSSL_TIARangeFrom(start, step, count: Integer): TIntArray;');

AddCommand(@MSSL_TIAGetEx, 'function MSSL_TIAGetEx(TIA, IDs: TIntArray; var iIDs: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAGet, 'function MSSL_TIAGet(TIA, IDs: TIntArray): TIntArray;');

AddCommand(@MSSL_TIARemoveEx, 'procedure MSSL_TIARemoveEx(var TIA: TIntArray; x: TIntArray);');

AddCommand(@MSSL_TIACopy, 'procedure MSSL_TIACopy(source: TIntArray; var target: TIntArray; resetTarget: Boolean);');

AddCommand(@MSSL_TIATransferEx, 'procedure MSSL_TIATransferEx(var source, target: TIntArray; resetTarget: Boolean);');

AddCommand(@MSSL_TIATransfer, 'procedure MSSL_TIATransfer(var source, target: TIntArray);');

AddCommand(@MSSL_TIAPlant, 'function MSSL_TIAPlant(var TIA: TIntArray; index: Integer; ints: TIntArray): Integer;');

AddCommand(@MSSL_TIAPick, 'function MSSL_TIAPick(var TIA: TIntArray; pick_ID: Integer): Integer;');

AddCommand(@MSSL_TIAPickEx, 'function MSSL_TIAPickEx(var TIA: TIntArray; pick_IDs: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAMatchEx, 'function MSSL_TIAMatchEx(TIA1, TIA2, specialMatches: TIntArray): Integer;');

AddCommand(@MSSL_TIAMatch2, 'function MSSL_TIAMatch2(TIA1, TIA2: TIntArray; specialMatch: Integer): Integer;');

AddCommand(@MSSL_TIAMatch, 'function MSSL_TIAMatch(TIA1, TIA2: TIntArray): Integer;');

AddCommand(@MSSL_TIAMatchesEx, 'function MSSL_TIAMatchesEx(TIA1, TIA2, specialMatches: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAMatches2, 'function MSSL_TIAMatches2(TIA1, TIA2: TIntArray; specialMatch: Integer): TIntArray;');

AddCommand(@MSSL_TIAMatches, 'function MSSL_TIAMatches(TIA1, TIA2: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAUnmatch, 'function MSSL_TIAUnmatch(TIA1, TIA2: TIntArray): Integer;');

AddCommand(@MSSL_TIAUnmatches, 'function MSSL_TIAUnmatches(TIA1, TIA2: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAGetUniques, 'function MSSL_TIAGetUniques(TIA: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAEquals, 'function MSSL_TIAEquals(TIA1, TIA2: TIntArray; specialMatch: Integer): Boolean;');

AddCommand(@MSSL_TIAEqualsEx, 'function MSSL_TIAEqualsEx(TIA1, TIA2, specialMatches: TIntArray): Boolean;');

AddCommand(@MSSL_TIAAllValuesSame, 'function MSSL_TIAAllValuesSame(arr: TIntArray): Boolean;');

AddCommand(@MSSL_TIAAllValuesUnique, 'function MSSL_TIAAllValuesUnique(arr: TIntArray): Boolean;');

AddCommand(@MSSL_TIASplitEx, 'function MSSL_TIASplitEx(TIA: TIntArray; minDifference, maxDifference: Integer): T2DIntArray;');

AddCommand(@MSSL_TIASplit, 'function MSSL_TIASplit(TIA: TIntArray; difference: Integer): T2DIntArray;');

AddCommand(@MSSL_TIAGroupEx, 'function MSSL_TIAGroupEx(TIA: TIntArray; minDifference, maxDifference: Integer): T2DIntArray;');

AddCommand(@MSSL_TIAGroup, 'function MSSL_TIAGroup(TIA: TIntArray; difference: Integer): T2DIntArray;');

commandsLoaded := True;

end;

[/scar]

 

Like...AddCommand(@FunctName, 'funct prototype');

 

And get a whole list of those, just by pasting the source code into a program and hitting a button.

 

^

 

I'd do THAT before even attempting to put MSSL in a DLL, or parts of it, or ANY big SCAR library lol. Take forever to copy and paste those function prototypes and names in to the AddCommands.

Link to comment
Share on other sites

Wow

 

[scar]

NEW: c4ef2015a84a89a355911a24021280f5 [265 ms.]

OLD: c4ef2015a84a89a355911a24021280f5 [8019 ms.]

[/scar]

 

Not a "converter", but a "template" maker thingy, wouldn't have to work at that level of detail (e.g. Delphi vs. Pascal script conventions). But would be cool to have, since every time any of us goes and makes a plugin we have to do this:

 

function Funct1; Stdcall

Exports: Funct1; stdcall/whatever;

Types: Funker1

 

LIKE THAT RIGHT THERE, MUST'VE TAKEN AGESS:

 

[scar]

procedure SetupCommands;

begin

AddCommand(@MSSL_TIAByRange, 'function MSSL_TIAByRange(aStart, aFinish: Integer): TIntArray;');

AddCommand(@MSSL_TIAByRange2Bit, 'function MSSL_TIAByRange2Bit(aStart, aFinish: Integer): TIntArray;');

AddCommand(@MSSL_TIAOfInteger, 'function MSSL_TIAOfInteger(x, count: Integer): TIntArray;');

AddCommand(@MSSL_IntDigits, 'function MSSL_IntDigits(int: Integer): TIntArray;');

AddCommand(@MSSL_StrIsInt, 'function MSSL_StrIsInt(str: string): Boolean;');

AddCommand(@MSSL_IntSetMin, 'procedure MSSL_IntSetMin(var val: Integer; x: Integer);');

AddCommand(@MSSL_IntSetMax, 'procedure MSSL_IntSetMax(var val: Integer; x: Integer);');

AddCommand(@MSSL_IntSetRange, 'procedure MSSL_IntSetRange(var val: Integer; mn, mx: Integer);');

AddCommand(@MSSL_TIASetMin, 'procedure MSSL_TIASetMin(var TIA: TIntArray; x: Integer);');

AddCommand(@MSSL_TIASetMax, 'procedure MSSL_TIASetMax(var TIA: TIntArray; x: Integer);');

AddCommand(@MSSL_TIASetRange, 'procedure MSSL_TIASetRange(var TIA: TIntArray; mn, mx: Integer);');

AddCommand(@MSSL_TIAControlByRange, 'procedure MSSL_TIAControlByRange(var TIA: TIntArray; minimum, maximum: Integer; method: MSSL_TControlMethod);');

AddCommand(@MSSL_TIABuiltWith, 'function MSSL_TIABuiltWith(TIA, allowed: TIntArray): Boolean;');

AddCommand(@MSSL_TIARandomizeEx, 'procedure MSSL_TIARandomizeEx(var TIA: TIntArray; shuffles: Integer);');

AddCommand(@MSSL_TIARandomize, 'procedure MSSL_TIARandomize(var TIA: TIntArray);');

AddCommand(@MSSL_TIADelete, 'function MSSL_TIADelete(var TIA: TIntArray; x: Integer): Boolean;');

AddCommand(@MSSL_TIARemove, 'procedure MSSL_TIARemove(var TIA: TIntArray; x: TIntArray);');

AddCommand(@MSSL_TIAAdd, 'function MSSL_TIAAdd(var TIA: TIntArray; addTIA: TIntArray): Integer;');

AddCommand(@MSSL_TIAPositions, 'function MSSL_TIAPositions(TIA: TIntArray; x: Integer): TIntArray;');

AddCommand(@MSSL_TIAPositionsMulti, 'function MSSL_TIAPositionsMulti(TIA, ints: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAPositionsEx, 'function MSSL_TIAPositionsEx(TIA, ints: TIntArray): TIntArray;');

AddCommand(@MSSL_TIACopyEx, 'function MSSL_TIACopyEx(TIA: TIntArray; pos1, pos2: Integer): TIntArray;');

AddCommand(@MSSL_TIAMove, 'function MSSL_TIAMove(var TIA: TIntArray; oldIndex, newIndex: Integer): Boolean;');

AddCommand(@MSSL_TIAToParts, 'function MSSL_TIAToParts(TIA: TIntArray; method: MSSL_TPartitionMethod; x: Integer): T2DIntArray;');

AddCommand(@MSSL_TIARangeFrom, 'function MSSL_TIARangeFrom(start, step, count: Integer): TIntArray;');

AddCommand(@MSSL_TIAGetEx, 'function MSSL_TIAGetEx(TIA, IDs: TIntArray; var iIDs: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAGet, 'function MSSL_TIAGet(TIA, IDs: TIntArray): TIntArray;');

AddCommand(@MSSL_TIARemoveEx, 'procedure MSSL_TIARemoveEx(var TIA: TIntArray; x: TIntArray);');

AddCommand(@MSSL_TIACopy, 'procedure MSSL_TIACopy(source: TIntArray; var target: TIntArray; resetTarget: Boolean);');

AddCommand(@MSSL_TIATransferEx, 'procedure MSSL_TIATransferEx(var source, target: TIntArray; resetTarget: Boolean);');

AddCommand(@MSSL_TIATransfer, 'procedure MSSL_TIATransfer(var source, target: TIntArray);');

AddCommand(@MSSL_TIAPlant, 'function MSSL_TIAPlant(var TIA: TIntArray; index: Integer; ints: TIntArray): Integer;');

AddCommand(@MSSL_TIAPick, 'function MSSL_TIAPick(var TIA: TIntArray; pick_ID: Integer): Integer;');

AddCommand(@MSSL_TIAPickEx, 'function MSSL_TIAPickEx(var TIA: TIntArray; pick_IDs: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAMatchEx, 'function MSSL_TIAMatchEx(TIA1, TIA2, specialMatches: TIntArray): Integer;');

AddCommand(@MSSL_TIAMatch2, 'function MSSL_TIAMatch2(TIA1, TIA2: TIntArray; specialMatch: Integer): Integer;');

AddCommand(@MSSL_TIAMatch, 'function MSSL_TIAMatch(TIA1, TIA2: TIntArray): Integer;');

AddCommand(@MSSL_TIAMatchesEx, 'function MSSL_TIAMatchesEx(TIA1, TIA2, specialMatches: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAMatches2, 'function MSSL_TIAMatches2(TIA1, TIA2: TIntArray; specialMatch: Integer): TIntArray;');

AddCommand(@MSSL_TIAMatches, 'function MSSL_TIAMatches(TIA1, TIA2: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAUnmatch, 'function MSSL_TIAUnmatch(TIA1, TIA2: TIntArray): Integer;');

AddCommand(@MSSL_TIAUnmatches, 'function MSSL_TIAUnmatches(TIA1, TIA2: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAGetUniques, 'function MSSL_TIAGetUniques(TIA: TIntArray): TIntArray;');

AddCommand(@MSSL_TIAEquals, 'function MSSL_TIAEquals(TIA1, TIA2: TIntArray; specialMatch: Integer): Boolean;');

AddCommand(@MSSL_TIAEqualsEx, 'function MSSL_TIAEqualsEx(TIA1, TIA2, specialMatches: TIntArray): Boolean;');

AddCommand(@MSSL_TIAAllValuesSame, 'function MSSL_TIAAllValuesSame(arr: TIntArray): Boolean;');

AddCommand(@MSSL_TIAAllValuesUnique, 'function MSSL_TIAAllValuesUnique(arr: TIntArray): Boolean;');

AddCommand(@MSSL_TIASplitEx, 'function MSSL_TIASplitEx(TIA: TIntArray; minDifference, maxDifference: Integer): T2DIntArray;');

AddCommand(@MSSL_TIASplit, 'function MSSL_TIASplit(TIA: TIntArray; difference: Integer): T2DIntArray;');

AddCommand(@MSSL_TIAGroupEx, 'function MSSL_TIAGroupEx(TIA: TIntArray; minDifference, maxDifference: Integer): T2DIntArray;');

AddCommand(@MSSL_TIAGroup, 'function MSSL_TIAGroup(TIA: TIntArray; difference: Integer): T2DIntArray;');

commandsLoaded := True;

end;

[/scar]

 

Like...AddCommand(@FunctName, 'funct prototype');

 

And get a whole list of those, just by pasting the source code into a program and hitting a button.

 

^

 

I'd do THAT before even attempting to put MSSL in a DLL, or parts of it, or ANY big SCAR library lol.

Well, I am adding those commands to that list 1-by-1. :P It's not hard anymore.

 

But, it used to be pain with that old way, the same way you used in Bass plugin where you had to add new case section with ID for each and every command.

You also had to manually increase the amount of commands/types you are exporting to SCAR Divi, this is now dynamic, as you can see @pastebin link I provided. :)

Link to comment
Share on other sites

Still applies to yours too lol. That BASS one, your right, would take even longer!
I quickly wrote a small and basic converter - attached "convert.scar" and "exports.txt"

 

Works only with functions & procedures, though.

However, that isn't really a problem, because most of the time we are exporting commands anyways, only rarely types.

 

P.S. I know it's not exactly what you were after, you were after something that picks up those commands directly from the source file (.dpr), not from a text file like this.

But anyways, this could/might be useful. At least it makes it 1 step easier, I guess, haha. :P

 

EDIT: These utilities can be found from original/main post from now on. :)

 

-Jani

Edited by Janilabo
Tweaked convert.scar
Link to comment
Share on other sites

[sCAR]

procedure SetupCommands;

begin

AddCommand(@, '');

end;

 

INVALID LINES:

"" [Line 0]

[/sCAR]

 

Hmm?

 

Well, looks sexy anyway. Saved.

 

Does anyone know what function gets the difference between two numbers..but keeps the negatives?

Edited by LordJashin
Link to comment
Share on other sites

[sCAR]

procedure SetupCommands;

begin

AddCommand(@, '');

end;

 

INVALID LINES:

"" [Line 0]

[/sCAR]

 

Hmm?

You'll need that exports.txt aswell.

 

- - - Updated - - -

 

Added small tweak, now it wont include those incorrect file lines:

 

{$I MSSL\MSSL.scar}

procedure ScriptTerminate;
begin
 MSSL_Unsetup;
end;

var
 theFile: string;

procedure Setup;
begin
 theFile := (ScriptPath + 'exports.txt')
end;

procedure Convert;
var
 lines: TStrArray;
 h, i: Integer;
 procAddr, procDef, nameStarts, nameEnds: string; 
 invalid: TIntArray; 
begin
 WriteLn('procedure SetupCommands;');
 WriteLn('begin');
 lines := MSSL_StrExplodeMulti([#13#10, #13, #10], MSSL_GrabFileData(theFile));
 h := High(lines);
 for i := 0 to h do
 begin               
   lines[i] := Trim(lines[i]);
   nameStarts := PregMatch('/(procedure|function)\s+/i', lines[i]);
   nameEnds := Pregmatch('/\s*(\(|;)/', lines[i]);
   case ((nameStarts = '') or (nameEnds = '')) of
     False:
     begin
       procDef := ('''' + lines[i] + '''');
       procAddr := Between(nameStarts, nameEnds, lines[i]);
       WriteLn('  AddCommand(@' + procAddr + ', ' + procDef + ');');  
     end;
     True: TIAAppend(invalid, i); 
   end;
 end; 
 WriteLn('end;');
 h := High(invalid);
 if (h > -1) then
 begin
   WriteLn('');
   WriteLn('INVALID LINES:');
   for i := 0 to h do
     WriteLn('"' + lines[invalid[i]] + '" [Line ' + IntToStr(invalid[i]) + ']');
   SetLength(invalid, 0);
 end;                    
 SetLength(lines, 0);
end;

begin
 MSSL_Setup;
 Setup
 Convert;  
end.

Link to comment
Share on other sites

LFcAXCUl.jpg

 

Idk, I'm using SCAR 3.38.01 with Latest MSSL from include. Tried restarting SCAR, and reinstalling include.

Change the Setup procedure in that convert.scar script, if you don't use the exports.txt file in same folder with script file. :)

 

NOTE: ScriptPath <> ScriptsPath (Scripts Folder).

ScriptPath means the SAME path where script is located at.

Edited by Janilabo
Link to comment
Share on other sites

Noob mistake lol. an 's' makes all the difference! Speaking of which:

 

Anyone got a function for this:

what function gets the difference between two numbers..but keeps the negatives? e.g. NO Abs

 

Lately I've just been doing (val1 - val2) for it, and i remember we had a function that does this somewherez, or maybe in the past...

 

Geronimo!

5jV5A4il.jpg

Link to comment
Share on other sites

Noob mistake lol. an 's' makes all the difference! Speaking of which:

 

Anyone got a function for this:

 

Lately I've just been doing (val1 - val2) for it, and i remember we had a function that does this somewherez, or maybe in the past...

 

Geronimo!

5jV5A4il.jpg

Not exactly sure what you mean...

 

Do you mean something like this:

 

{==============================================================================]   
 Explanation: Returns the difference between value1 and value2.
[==============================================================================}
function Difference(value1, value2: Integer): Integer;
begin
 Result := iAbs(value2 - value1);
end;

{==============================================================================]
 Explanation: Returns the difference between value1 and value2.
[==============================================================================}
function DifferenceE(value1, value2: Extended): Extended;
begin
 Result := Abs(value2 - value1);
end;

begin
 WriteLn(Difference(-1, 1));
 WriteLn(DifferenceE(-1.2345, -0.5));
end.

Link to comment
Share on other sites

Nvm I figured it out. FINALLY a working DTM system! Rawrz. Will be making a thread in a little bit. But here's a sneak peek. However trying to figure out why the Angle returned isn't like 90 degrees when i flip the image side ways. Prolly, a dumb moment for me again lols.

 

HFFMA9yl.jpg

 

Supports: Rotated DTM finding. Also can add in (if i wanted) Tolerance.

 

OoO

Link to comment
Share on other sites

Kk Jani, gonna post the source, try not to freak out, its pretty crazy looking.

 

This is in pre-alpha stage :P. I need to noob proof it. But here's some warnings so far:

1. Can't Detect HALF a DTM, e.g. if half the DTM is off your screen. This will not find it!

2. NEGATIVE VALUES will probably mess it up, hence OFF SCREEN things too (will not find them).

3. Searches Rotated points using (0.1) basis. Meaning that...(enter stupidity for jashin here)...If the DTM is actually at 0.153569 degrees or something...it might not be found? (probably a misconception for me, and I could be wrong about this)

4. Tons of stuff must be Manually entered...I don't have some amazing DTM tools for this for you (yet)

5. Make sure EVERYTHING ADDS UP...you can't have Points that Don't have colors, etc. Error checking bla bla isn't there yet

6. Will probably run for 2-3 seconds for FINDING THE DTM

7. If it finds the DTM, will be found probably within 1-3 seconds. note i tested it on a good sized client.

 

Supports rotation! Infact...there isn't a way to opt out of it, for now. Much needs to be done here...hoopla!

 

[scar]

{**************************************************************

* LordJashin's latest works, JashDTM Overhaul *

* Started: 5/20/13 *

* Last Updated: 5/29/13 *

* *

* Goal: Make an effeciant rotatable DTM finder of sorts. Or *

* deviations with the same concept in mind. Find bugs *

* or errors in code, and complete the project once *

* and for all. To Explore all possibilities. *

* *

* Methods found so far: FindColor(Tol)(Ex) *

* FindColorSpiral(Tol)(Ex) *

* FindColorTPA(Tol)(Ex) *

* *

* Methods Tried and Results: *

* *

* FindColor = *

* *

* *

**************************************************************}

 

program JDTM;

{$DEFINE OSIDebug}

{$I OSI/OSI.scar}

 

// Support functions <START> **********************************

 

const

DefaultDir = 'C:\Users\LordJashin\Desktop';

 

type

TJashDTMPoint = record

Point: TPoint;

Color, Tolerance: Integer;

end;

 

TJashDTMPointArray = array of TJashDTMPoint;

 

TJashDTM = record

MainPoint: TJashDTMPoint;

SubPoints: TJashDTMPointArray;

Internals: record

SPnts: TPointArray;

ColorsArr: TIntArray;

RotateATPA: array of TPointArray;

DiffATPA: array of TPointArray;

end;

end;

 

procedure JashSetupJDTMArrays(var JDTM: TJashDTM);

var

i, e, h: Integer;

j: Extended;

begin

with JDTM.Internals do

begin

h := high(JDTM.SubPoints);

if (h = -1) then

Exit;

for i := 0 to h do

begin

TIAAppend(ColorsArr, JDTM.SubPoints.Color);

TPAAppend(SPnts, JDTM.SubPoints.Point);

end;

SetLength(RotateATPA, 3600);

SetLength(DiffATPA, 3600);

j := 0.0;

for i := 0 to 3599 do

begin

RotateATPA := CopyTPA(SPnts);

if (i <> 0) then

RotateTPA(RotateATPA, JDTM.MainPoint.Point, j);

DiffATPA := CopyTPA(RotateATPA);

for e := 0 to h do

begin

DiffATPA[e].x := DiffATPA[e].x - JDTM.MainPoint.Point.x;

DiffATPA[e].y := DiffATPA[e].y - JDTM.MainPoint.Point.y;

end;

j := j + 0.1;

end;

end;

end;

 

// Support functions <END> ************************************

 

// Find functions <START> *************************************

 

function FindJDTM(out X, Y: Integer; JDTM: TJashDTM; XS, YS, XE, YE: Integer; out FoundAng: Extended): Boolean;

var

i, e, z, h: Integer;

MPoints: TPointArray;

ColorsATPA, SubsATPA: array of TPointArray;

begin

Result := False;

if not FindColorEx(MPoints, JDTM.MainPoint.Color, XS, YS, XE, YE) then

Exit;

WriteLn('MPoint found: ' + TPAToStr(MPoints));

h := high(JDTM.Internals.ColorsArr);

SetLength(ColorsATPA, h + 1);

for i := 0 to h do

if not FindColorEx(ColorsATPA, JDTM.Internals.ColorsArr, XS, YS, XE, YE) then

Exit;

WriteLn('Points where ColorsArr[1] was found: ' + TPAToStr(ColorsATPA[1]));

SetLength(SubsATPA, 3600);

for z := 0 to high(MPoints) do

for i := 0 to 3599 do

begin

SubsATPA := CopyTPA(JDTM.Internals.DiffATPA);

for e := 0 to high(JDTM.Internals.SPnts) do

begin

SubsATPA[e].x := MPoints[z].x + JDTM.Internals.DiffATPA[e].x;

SubsATPA[e].y := MPoints[z].y + JDTM.Internals.DiffATPA[e].y;

if not TPAContains(ColorsATPA[e], SubsATPA[e]) then

Break;

if (e = h) then

begin

Result := True;

X := MPoints[z].x;

Y := MPoints[z].y;

FoundAng := i / 10;

Exit;

end;

end;

 

end;

end;

 

// Find functions <END> ***************************************

 

var

Jashin: TJashDTM;

JashinMain: TJashDTMPoint;

JashinSub: TJashDTMPointArray;

 

procedure DebugItAll;

var

i, e: Integer;

begin

for i := 0 to 359 do

for e := 0 to high(Jashin.Internals.RotateATPA) do

begin

if Jashin.Internals.RotateATPA[e].x < 0 then

Jashin.Internals.RotateATPA[e].x := 0;

if Jashin.Internals.RotateATPA[e].y < 0 then

Jashin.Internals.RotateATPA[e].y := 0;

end;

for i := 0 to 359 do

for e := 0 to high(Jashin.Internals.DiffATPA) do

begin

if Jashin.Internals.DiffATPA[e].x < 0 then

Jashin.Internals.DiffATPA[e].x := 0;

if Jashin.Internals.DiffATPA[e].y < 0 then

Jashin.Internals.DiffATPA[e].y := 0;

end;

{ for i := 0 to 359 do

Jashin.Internals.RotateATPA := CombineTPA(Jashin.Internals.RotateATPA, Jashin.Internals.DiffATPA);}

DebugATPABoundsEx([Jashin.Internals.RotateATPA[157], Jashin.Internals.RotateATPA[0]], false, true, false, false, false, '');

//DebugATPABoundsEx([Jashin.Internals.RotateATPA[2], Jashin.Internals.RotateATPA[3]], false, true, false, false, false, '');

end;

 

procedure SetupJashDtm;

var

X, Y, w, h: Integer;

FAng: Extended;

begin

JashinMain.Point := Point(332, 404);

JashinMain.Color := 233;

SetLength(JashinSub, 6);

JashinSub[0].Point := Point(323, 380);

JashinSub[0].Color := 1394728;

JashinSub[1].Point := Point(336, 371);

JashinSub[1].Color := 1792817;

JashinSub[2].Point := Point(367, 420);

JashinSub[2].Color := 1792817;

JashinSub[3].Point := Point(336, 417);

JashinSub[3].Color := 15854054;

JashinSub[4].Point := Point(351, 437);

JashinSub[4].Color := 1394728;

JashinSub[5].Point := Point(336, 447);

JashinSub[5].Color := 1188127;

Jashin.MainPoint := JashinMain;

Jashin.SubPoints := JashinSub;

JashSetupJDTMArrays(Jashin);

WriteLn(PointToStr(Jashin.MainPoint.Point));

WriteLn(TPAToStr(Jashin.Internals.SPnts));

WriteLn(TIAToStr(Jashin.Internals.ColorsArr));

WriteLn(TPAToStr(Jashin.Internals.RotateATPA[1]));

WriteLn(TPAToStr(Jashin.Internals.DiffATPA[1]));

GetClient.Activate;

wait(1000);

GetBoxSize(GetClient.ImageArea, w, h);

if FindJDTM(X, Y, Jashin, 0, 0, w - 1, h - 1, FAng) then

begin

WriteLn('Found JDTM at: (' + IntToStr(X) + ', ' + IntToStr(Y) + ') at angle: ' + FloatToStr(FAng));

end;

DebugItAll;

end;

 

procedure MainLoop;

begin

ClearDebug;

SetupOSI;

SetupJashDtm;

end;

 

begin

MainLoop;

end.

 

[/scar]

 

Another interesting Pic:

mMbsWEFl.jpg

 

Updated:

Seems the current DTM system works fine on this image, but the angles man can't figure em out. Why are mine so different for JDTMs?

I'll try it with RS, but I remember distinctly, it not working cuz I tried to use it many times. Really fast though for this image.

 

Hey Freddy, do you think, it might have to do with the AngStep precision?

Edited by LordJashin
Link to comment
Share on other sites

I like your way but the way Freddy deisgned actually is alot easier and neater that doing that way. That adds extra functions ect. Here is how Freddy recomended me to do it along with everyone else.

 

[scar]const

FunctionExports: array[0..2] of TFunctionExport = (

(Ref: @HelloWorld; Def: 'procedure HelloWorld;'; Conv: ccStdCall),

(Ref: @SaveBitmapToPng; Def: 'procedure SaveBitmapToPng(const Bmp: TSCARBitmap; const Path: string);'; Conv: ccStdCall),

(Ref: @BmpToPng; Def: 'procedure BmpToPng(const BmpPath, PngPath: string);'; Conv: ccStdCall)

);

 

TypeExports: array[0..0] of TTypeExport = (

(Name: 'T3DPoint'; Def: 'record X, Y, Z: Integer; end;')

);

 

procedure OnLoadLib(const SCARExports: PExports); stdcall;

begin

Exp := SCARExports; // Do NOT remove this line!

// Called when the library is loaded

end;

 

procedure OnUnloadLib; stdcall;

begin

// Called when the library is unloaded

end;

 

// - Function exports

// Do NOT change this! (unless you're not exporting functions, then you can remove this part)

function OnGetFuncCount: Integer; stdcall;

begin

Result := High(FunctionExports) - Low(FunctionExports) + 1;

end;

 

function OnGetFuncInfo(const Idx: Integer; out ProcAddr: Pointer; out ProcDef: PAnsiChar;

out CallConv: TCallConv): Integer; stdcall;

var

FuncExp: TFunctionExport;

begin

if (Idx >= Low(FunctionExports)) and (Idx <= High(FunctionExports)) then

begin

FuncExp := FunctionExports[idx + Low(FunctionExports)];

ProcAddr := FuncExp.Ref;

ProcDef := PAnsiChar(FuncExp.Def);

CallConv := FuncExp.Conv;

Result := Idx;

end else

Result := -1;

end;

 

// - Type exports

// Do NOT change this! (unless you're not exporting types, then you can remove this part)

function OnGetTypeCount: Integer; stdcall;

begin

Result := High(TypeExports) - Low(TypeExports) + 1;

end;

 

function OnGetTypeInfo(const Idx: Integer; out TypeName, TypeDef: PAnsiChar): Integer; stdcall;

var

TypeExp: TTypeExport;

begin

if (Idx >= Low(TypeExports)) and (Idx <= High(TypeExports)) then

begin

TypeExp := TypeExports[idx + Low(TypeExports)];

TypeName := PAnsiChar(TypeExp.Name);

TypeDef := PAnsiChar(TypeExp.Def);

Result := Idx;

end else

Result := -1;

end;

[/scar]

 

This way the only part you have to change is this

[scar] FunctionExports: array[0..2] of TFunctionExport = ( // Change the array to match the number of functions

(Ref: @HelloWorld; Def: 'procedure HelloWorld;'; Conv: ccStdCall),

(Ref: @SaveBitmapToPng; Def: 'procedure SaveBitmapToPng(const Bmp: TSCARBitmap; const Path: string);'; Conv: ccStdCall),

(Ref: @BmpToPng; Def: 'procedure BmpToPng(const BmpPath, PngPath: string);'; Conv: ccStdCall) // add each function in a set of ()

);

 

TypeExports: array[0..0] of TTypeExport = ( // Same for this

(Name: 'T3DPoint'; Def: 'record X, Y, Z: Integer; end;')

);[/scar]

Link to comment
Share on other sites

I'm still not sure where you got the notion that SCAR's DTM system isn't working...

 

The notion came from DTM's not working correctly in SMART I believe starting with SMART v7. and newer.

 

http://forums.scar-divi.com/osi-updates/2118-osi-2-underway-divi-rs2-massive-restructure-rs07-introduction-3.html#post12400

 

The problem was resolved long ago

 

http://forums.scar-divi.com/osi-updates/2180-osi-2-rs07-ported-optional-smart-7-2-a

https://github.com/OfficialSCARInclude/OSI2/commit/0309ffd8861d71b9bfbb665290f8471cf0db7014

 

The DTM system has worked fine in SMART since then and before SMART 7.

 

- - - Updated - - -

 

Does anyone know what function gets the difference between two numbers..but keeps the negatives?

 

Please show examples.

 

-3 - -3 = -6?

-3 - -3 = 0?

 

etc

Edited by Wanted
Link to comment
Share on other sites

@Wanted: Don't worry, i figured it out, about the function.

 

That or Jani's way is pretty sexy. Well I think I know why DTM's don't work on Runescape or maybe in everything. Here's what I found out (Used SMART):

MuuBbA4l.jpg

 

I made that DTM, and I couldn't even find it with Compass in same position (clicked compass to make DTM, and again to find it). But yeah the problem is, that AngStep can only be so precise, and RS compass angle can be like 2.45439543095809435 or crazy shit (as shown by GetCompassAngle...etc). So the FindDTMRotated function has trouble finding the DTM rotated because it only AngSteps so precisely, e.g. 0.1 angstep from 0-359 degrees. But then you have RS with their angles at like 2.45439543095809435 degrees.

 

And Thus, I give up on DTM's for Runescape or gaming. Be useful if someone could get it to work with crazy precision.

Proud I made that DTM system anyhow. It has the same problems with this aswell. Tested it, and SCAR's FindDTMRotated on SMART.

 

Note: This DTM system I made works, and so does SCAR's. SCAR's is faster, but BOTH do NOT work with Runescape Minimap. But they do work with Inventory items, etc. I'd advise using SCAR's, they are much much faster!

 

This might also explain the inaccuracies with the Minimap. Maybe even with SPS. You can set the angle to north, and the angle will be different then it was before sometimes, when you call GetCompassAngle.

Edited by LordJashin
Link to comment
Share on other sites

That or Jani's way is pretty sexy. Well I think I know why DTM's don't work on Runescape or maybe in everything. Here's what I found out (Used SMART):

MuuBbA4l.jpg

 

I made that DTM, and I couldn't even find it with Compass in same position (clicked compass to make DTM, and again to find it). But yeah the problem is, that AngStep can only be so precise, and RS compass angle can be like 2.45439543095809435 or crazy shit (as shown by GetCompassAngle...etc). So the FindDTMRotated function has trouble finding the DTM rotated because it only AngSteps so precisely, e.g. 0.1 angstep from 0-359 degrees. But then you have RS with their angles at like 2.45439543095809435 degrees.

 

And Thus, I give up on DTM's for Runescape or gaming. Be useful if someone could get it to work with crazy precision.

 

Proud I made that DTM system anyhow.

 

I've been successfully using rotated string DTMs in RS07 in SMART with OSI2 for some time now. Perhaps elaborate your issues and we can isolate the problem and determine whether it's user and/or client side.

 

In other words, show us your DTM settings as well as a test script showing how you utilize it and where it is failing.

Edited by Wanted
Link to comment
Share on other sites

I've been successfully using rotated string DTMs in RS07 in SMART with OSI2 for some time now. Perhaps elaborate your issues and we can isolate the problem and determine whether it's user and/or client side.

 

In other words, show us your DTM settings as well as a test script showing how you utilize it and where it is failing.

 

Have you tried it with the Minimap?

 

Testscript 1:

 

[scar]

program New;

 

{$DEFINE RS2}

{$DEFINE OSI_Color_Anti_Randoms}

{$DEFINE SMART} // Comment out to disable SMART

// and use browser instead

{$I OSI\OSI.scar}

 

procedure ScriptTerminate;

begin

FreeOSI;

end;

 

procedure SetupPlayers;

begin

SetLength(Players, 1);

with Players[0] do

begin

Login := 'Test';

Pass := 'Test';

Member := False;

Active := True; // Puts in Active player list (used for login function)

end;

end;

var

TestDTM, x, y: Integer;

FAng: Extended;

begin

SetupPlayers;

SetUpOSI;

if Login then

WriteLn('Congratz!');

TestDTM := DTMFromString('78DA63EC616260D8C88002FE7F87D08C503E6' +

'31750CD5A54359F7FBE4755D30F54730455CD97A3BAA86A1A806A' +

'26A3AA0937E041555381E91E061676143500E5510D6D');

if FindDTMRotated(TestDTM, x, y, 0, 0, RSX2, RSY2, 0, 359, 0.1, FAng) then

WriteLn('FOUND ET. at: (' + IntToStr(x) +', ' + IntToStr(y) + ') FAng: ' + FloatToStr(FAng));

FreeDTM(TestDTM);

 

end.

[/scar]

 

You can switch the angle step for: 1, 0.1, 0.01, but ain't gonna fix nothing. Just try it. Make a DTM, then rotate your Minimap, and try to find it. Keep doing it, rotate it again. IF you have it working 24/7 when your rotating the minimap, then maybe I'm just the unlucky one here...

 

SCAR: 3.38.01, OSI(legacy) latest (reinstalled too)

Edited by LordJashin
Link to comment
Share on other sites

Have you tried it with the Minimap?

 

Testscript 1:

 

[scar]

program New;

 

{$DEFINE RS2}

{$DEFINE OSI_Color_Anti_Randoms}

{$DEFINE SMART} // Comment out to disable SMART

// and use browser instead

{$I OSI\OSI.scar}

 

procedure ScriptTerminate;

begin

FreeOSI;

end;

 

procedure SetupPlayers;

begin

SetLength(Players, 1);

with Players[0] do

begin

Login := 'Test';

Pass := 'Test';

Member := False;

Active := True; // Puts in Active player list (used for login function)

end;

end;

var

TestDTM, x, y: Integer;

FAng: Extended;

begin

SetupPlayers;

SetUpOSI;

if Login then

WriteLn('Congratz!');

TestDTM := DTMFromString('78DA63EC616260D8C88002FE7F87D08C503E6' +

'31750CD5A54359F7FBE4755D30F54730455CD97A3BAA86A1A806A' +

'26A3AA0937E041555381E91E061676143500E5510D6D');

if FindDTMRotated(TestDTM, x, y, 0, 0, RSX2, RSY2, 0, 359, 0.1, FAng) then

WriteLn('FOUND ET. at: (' + IntToStr(x) +', ' + IntToStr(y) + ') FAng: ' + FloatToStr(FAng));

FreeDTM(TestDTM);

 

end.

[/scar]

 

You can switch the angle step for: 1, 0.1, 0.01, but ain't gonna fix nothing. Just try it. Make a DTM, then rotate your Minimap, and try to find it. Keep doing it, rotate it again. IF you have it working 24/7 when your rotating the minimap, then maybe I'm just the unlucky one here...

 

SCAR: 3.38.01, OSI(legacy) latest (reinstalled too)

 

I don't what else you would use a rotated DTM for other than minimap detection. I have successfully used rotated string DTM detection in SMART 7.2 for RS07 with OSI 2 on the minimap.

 

What are you using for your subpoint areas/ tolerances etc.? Show me your DTM settings.

 

If you're having trouble with it not detecting at other angles in an environment like the runescape minimap than you are most likely not using great enough area tolerance.

Link to comment
Share on other sites

Why do you even need tolerances? You have the colors right there! Why isn't the DTM being found? You need tolerance if the colors could be different, but they ain't, I picked it right out of there, and I don't see them changing colors or anything, ingame.

 

IIVT7u1.png

 

Settings: No area, no area tol, no tol

 

That and there's no tutorials on how the Area tol/area stuff works afaik.

 

But hey look at this O_O Black square ._. :

 

UvnLtr9.png

 

Should I just use Black squares + Tol on them, and put them around objects for DTM's then? Why can't the simple ones work rawrz.

Edited by LordJashin
Link to comment
Share on other sites

Why do you even need tolerances? You have the colors right there! Why isn't the DTM being found? You need tolerance if the colors could be different, but they ain't, I picked it right out of there, and I don't see them changing colors or anything, ingame.

 

IIVT7u1.png

 

Settings: No area, no area tol, no tol

 

Colors might be static, but Area *size (sorry I've been away for a while) is pretty important. The pixels don't rotated perfectly and they aren't even being rotated around the same point most of the time so your rotated DTM isn't going to pick up exact pixel location when looking at user-end runescape.

 

Try increasing your Area size on just (EACH) subpoint to 2-4. You might need more (or less) experiment for best results.

 

With DDTMs you can actually variable area size.

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