SRL Archive - S.M.A.R.T.

SMART API/Plugins?


slushpuppy

2014-04-27 03:18:48

I noticed that new versions of SMART have the ability to load personal plugins. Does this mean if I have my own methods of screen scraping, I would make my own plugin and have SMART read from the set methods/functions?

If so, is there any documentation or API for the a/m matters?

CynicRus

2014-04-27 03:29:39

I think, this is undocummented API. But, I assume you can ask Brandon, or just look at the Smart source code.

Cheers,
Cynic.

slushpuppy

2014-04-27 10:23:27

Thanks. Found it in SMARTPlugin.h in SMART src directory

Brandon

2014-04-27 17:19:38

From: CynicRus
I think, this is undocummented API. But, I assume you can ask Brandon, or just look at the Smart source code.

Cheers,
Cynic.


From: slushpuppy
Thanks. Found it in SMARTPlugin.h in SMART src directory



Most of it is pretty much undocumented yeah.

Pascal Example:
https://github.com/Brandon-T/PascalDXI/blob/master/smartplugin.pas


You specifically need:


type
SMARTGetMousePos = procedure(var X, Y: Integer); //Returns the position of the Smart mouse.
SMARTSetCapture = procedure(Enabled: Boolean); //Smart will be calling this when capture button is pressed.
SMARTButtonPressed = procedure(ID: Integer; State: Boolean); //Called when a custom button on smart is pressed.

PSMARTButtonPressed = ^SMARTButtonPressed;
PPChar = ^PChar;
PPPChar = ^PPChar;
PInt = ^Integer;
PPInt = ^PInt;
PBool = ^Boolean;

SMARTInfo = packed record //C-style structure that holds information about your plugin AND information from SMART.
Version: Integer; //What version is SMART? You do not touch this. It is for SMART's use only.
Img, Dbg: Pointer; //Img is a pointer to Smart's image buffer. It is passed to Simba. You may fill it with pixels to feed Simba. Dbg is a pointer to SMART's debug buffer. If you fill it, that will be drawn on SMART's overlay when debug is enabled.
Width, Height: Integer; //Width and Height of both buffers above.
GetMousePos: SMARTGetMousePos; //Call this function when you want to get Smart's mouse position.
SetCapture: SMARTSetCapture; //Call this function when you want to enable Smart's capturing. Smart will NOT use your buffers if you don't want it to.
end;

PSmartInfo = ^SmartInfo;



{* Called by smart when a plugin is first loaded *}

Procedure SMARTPluginInit(ptr: PSmartInfo; ReplaceButtons: PBool; ButtonCount: PInt; ButtonText: PPPChar; ButtonIDs: PPInt; ButtonCallback: PSMARTButtonPressed) cdecl;



implementation


Procedure SMARTPluginInit(ptr: PSmartInfo; ReplaceButtons: PBool; ButtonCount: PInt; ButtonText: PPPChar; ButtonIDs: PPInt; ButtonCallback: PSMARTButtonPressed) cdecl;
var
ButtonTexts: PPChar;
IDs: PInt;
begin
SmartGlobal := ptr;

if (ptr <> nil) then //If the pointer SMART gives us is legit and not null..
begin
ReplaceButtons^ := True; //Are we going to be replacing some buttons on smart? Yes we are..
ButtonTexts := AllocMem(SizeOf(PChar) * 2); //Allocate memory for 2 buttons.
ButtonTexts[0] := 'Disable Direct-X_Enable Direct-X'; //Initial State of the button *space* ButtonName_SecondStateName *space* ButtonName
ButtonTexts[1] := 'Enable Debug_Disable dxDebug'; //Initial State of the button *space* ButtonName_SecondStateName *space* ButtonName

IDs := AllocMem(Sizeof(Integer) * 2); //Allocate memory for 2 IDs. 2 Buttons = 2 IDs.
IDs[0] := 100; //ID for the first button will be 100.
IDs[1] := 101; //ID for the second button will be 101.

ButtonCount^ := 2; //Number of buttons allocated.
ButtonText^ := ButtonTexts;
ButtonIDs^ := IDs;
ButtonCallback^ := @SMART_ButtonPressed; //Function to be called when a button is pressed.. As shown below.
end;
end;


{* Called when a button on SMART is pressed *}

procedure SMART_ButtonPressed(ID: Integer; State: Boolean);
begin
case ID of
100: if (State) Then //ID of the first button.. Do something.. State is true if the button was in State-1. False if in State-2.
begin
SmartGlobal^.SetCapture(False);
SmartDirectXEnabled := True;
end else
begin
SmartGlobal^.SetCapture(False);
SmartDirectXEnabled := False;
end;
101: if (State) Then //ID of the second button..
SmartDebugEnabled := False
Else
SmartDebugEnabled := True;
end;
end;

and export it:


exports SMARTPluginInit;

You must not rename any of the above functions. ButtonPress can be renamed but not SMARTPluginInit. Calling convention MUST be cdecl.

slushpuppy

2014-05-03 07:59:44

From: Brandon
Most of it is pretty much undocumented yeah.

Pascal Example:
https://github.com/Brandon-T/PascalDXI/blob/master/smartplugin.pas



You specifically need:


type
SMARTGetMousePos = procedure(var X, Y: Integer); //Returns the position of the Smart mouse.
SMARTSetCapture = procedure(Enabled: Boolean); //Smart will be calling this when capture button is pressed.
SMARTButtonPressed = procedure(ID: Integer; State: Boolean); //Called when a custom button on smart is pressed.

PSMARTButtonPressed = ^SMARTButtonPressed;
PPChar = ^PChar;
PPPChar = ^PPChar;
PInt = ^Integer;
PPInt = ^PInt;
PBool = ^Boolean;

SMARTInfo = packed record //C-style structure that holds information about your plugin AND information from SMART.
Version: Integer; //What version is SMART? You do not touch this. It is for SMART's use only.
Img, Dbg: Pointer; //Img is a pointer to Smart's image buffer. It is passed to Simba. You may fill it with pixels to feed Simba. Dbg is a pointer to SMART's debug buffer. If you fill it, that will be drawn on SMART's overlay when debug is enabled.
Width, Height: Integer; //Width and Height of both buffers above.
GetMousePos: SMARTGetMousePos; //Call this function when you want to get Smart's mouse position.
SetCapture: SMARTSetCapture; //Call this function when you want to enable Smart's capturing. Smart will NOT use your buffers if you don't want it to.
end;

PSmartInfo = ^SmartInfo;



{* Called by smart when a plugin is first loaded *}

Procedure SMARTPluginInit(ptr: PSmartInfo; ReplaceButtons: PBool; ButtonCount: PInt; ButtonText: PPPChar; ButtonIDs: PPInt; ButtonCallback: PSMARTButtonPressed) cdecl;



implementation


Procedure SMARTPluginInit(ptr: PSmartInfo; ReplaceButtons: PBool; ButtonCount: PInt; ButtonText: PPPChar; ButtonIDs: PPInt; ButtonCallback: PSMARTButtonPressed) cdecl;
var
ButtonTexts: PPChar;
IDs: PInt;
begin
SmartGlobal := ptr;

if (ptr <> nil) then //If the pointer SMART gives us is legit and not null..
begin
ReplaceButtons^ := True; //Are we going to be replacing some buttons on smart? Yes we are..
ButtonTexts := AllocMem(SizeOf(PChar) * 2); //Allocate memory for 2 buttons.
ButtonTexts[0] := 'Disable Direct-X_Enable Direct-X'; //Initial State of the button *space* ButtonName_SecondStateName *space* ButtonName
ButtonTexts[1] := 'Enable Debug_Disable dxDebug'; //Initial State of the button *space* ButtonName_SecondStateName *space* ButtonName

IDs := AllocMem(Sizeof(Integer) * 2); //Allocate memory for 2 IDs. 2 Buttons = 2 IDs.
IDs[0] := 100; //ID for the first button will be 100.
IDs[1] := 101; //ID for the second button will be 101.

ButtonCount^ := 2; //Number of buttons allocated.
ButtonText^ := ButtonTexts;
ButtonIDs^ := IDs;
ButtonCallback^ := @SMART_ButtonPressed; //Function to be called when a button is pressed.. As shown below.
end;
end;


{* Called when a button on SMART is pressed *}

procedure SMART_ButtonPressed(ID: Integer; State: Boolean);
begin
case ID of
100: if (State) Then //ID of the first button.. Do something.. State is true if the button was in State-1. False if in State-2.
begin
SmartGlobal^.SetCapture(False);
SmartDirectXEnabled := True;
end else
begin
SmartGlobal^.SetCapture(False);
SmartDirectXEnabled := False;
end;
101: if (State) Then //ID of the second button..
SmartDebugEnabled := False
Else
SmartDebugEnabled := True;
end;
end;

and export it:


exports SMARTPluginInit;

You must not rename any of the above functions. ButtonPress can be renamed but not SMARTPluginInit. Calling convention MUST be cdecl.

Hm, where does it specify the PID?

If you want to know, I am attempting to screen scrape using winapi HDC, so that my scripts can work on environments where dx or ogl is not available

Brandon

2014-05-03 11:24:39

From: slushpuppy
Hm, where does it specify the PID?

If you want to know, I am attempting to screen scrape using winapi HDC, so that my scripts can work on environments where dx or ogl is not available


The difference between SMART plugins and Simba plugins is that SMART plugins rarely ever need the PID.

Doesn't SMART already screen-scrape in safe-mode? Are you trying to make it work for other games?

Either way, you may use:


function GetPid: LongInt;

to get SMART's PID. I'm not sure what use you have for the PID other than mapping shared memory.

slushpuppy

2014-05-03 22:09:09

From: Brandon
The difference between SMART plugins and Simba plugins is that SMART plugins rarely ever need the PID.

Doesn't SMART already screen-scrape in safe-mode? Are you trying to make it work for other games?

Either way, you may use:


function GetPid: LongInt;

to get SMART's PID. I'm not sure what use you have for the PID other than mapping shared memory.

It does screen scrape in safe mode?! How would i enable that in srl6?

Olly

2014-05-03 23:38:35

From: slushpuppy
It does screen scrape in safe mode?! How would i enable that in srl6?


SRL-6 Won't work.

Olly

2014-05-03 23:39:35

From: Olly
SRL-6 Won't work.


We changed to a graphics mode to look less bot like, It's a debatable switch but eh, we did it.

Brandon

2014-05-04 01:09:29

From: slushpuppy
It does screen scrape in safe mode?! How would i enable that in srl6?



SRL-6 has nothing to do with SMART itself. SRL-6 uses SMART but does not force it to do anything and does not limit it from doing anything. Plugins are just a bridge between:

Simba and the OS.
Simba and SMART.
SMART and the OS.

The include uses one of these systems. SMART can still operate in safe-mode. The thing is that you will need different colours or a different include to utilize that mode. I was actually going to port SRL-6 to safe-mode so that we had three options: Direct-X, OpenGL, Safemode.

Not sure it's worth it to port but meh.. Options.. It just seems like a step backwards? Don't know. Maybe integration would be an option in the future..


Again, SMART itself can still run and function 100% perfectly fine in safemode. Whether we utilize this or not is up to us/you.

slushpuppy

2014-05-04 04:09:26

From: Olly
We changed to a graphics mode to look less bot like, It's a debatable switch but eh, we did it.


I have this impression that SMART handled all the screen scraping side of things, while Simba just simply calls the various SMART functions to obtain the image buffer? Are they that intertwined?

Brandon

2014-05-04 14:13:32

From: slushpuppy
I have this impression that SMART handled all the screen scraping side of things, while Simba just simply calls the various SMART functions to obtain the image buffer? Are they that intertwined?



That impression is right. SMART grabs all information and just feeds it to Simba or whatever host needs it. Simba only reads and manipulates it.

That being said, SMART can screen scrape in safe mode still and feed it to Simba. Simba just needs an include that uses that information/colours.

slushpuppy

2014-05-06 09:49:03

From: Brandon
That impression is right. SMART grabs all information and just feeds it to Simba or whatever host needs it. Simba only reads and manipulates it.

That being said, SMART can screen scrape in safe mode still and feed it to Simba. Simba just needs an include that uses that information/colours.

@Olly What changes are needed for a safe mode include? I'd imagine it wouldn't be much.. like changing the load plugin or am I mistaken?

Olly

2014-05-06 11:13:05

From: slushpuppy
@Olly What changes are needed for a safe mode include? I'd imagine it wouldn't be much.. like changing the load plugin or am I mistaken?


No, alot of colours are different not only the mainscreen/minimap but the static interfaces.

Olly

2014-05-06 12:15:07

From: Olly
No, alot of colours are different not only the mainscreen/minimap but the static interfaces.


But to load SMART in safe mode would iirc be

SmartPlugins := [];
SmartInitSeq := 's';